Fix C# modules with multi-parameter callback methods (#10735)
* Fix C# modules with multi-parameter callback methods * Change files * Change sln file to have VS 2019 formatting * Update vnext/Microsoft.ReactNative.Managed/ReactNotificationIdOf.cs Co-authored-by: Danny van Velzen <dannyvv@microsoft.com> * Address code review feedback Co-authored-by: Vladimir Morozov <vmoroz@users.noreply.github.com> Co-authored-by: Danny van Velzen <dannyvv@microsoft.com>
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"type": "prerelease",
|
||||
"comment": "Fix C# modules with multi-parameter callback methods",
|
||||
"packageName": "react-native-windows",
|
||||
"email": "vmoroz@users.noreply.github.com",
|
||||
"dependentChangeType": "patch"
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
import { NativeModules } from 'react-native';
|
||||
import { TurboModuleRegistry } from 'react-native';
|
||||
const testExecuteJsiModule = TurboModuleRegistry.getEnforcing('TestExecuteJsiModule');
|
||||
|
||||
const { TestExecuteJsiModule } = NativeModules;
|
||||
|
||||
TestExecuteJsiModule.testSimpleExecuteJsi();
|
||||
TestExecuteJsiModule.testHostFunction();
|
||||
TestExecuteJsiModule.testHostObject();
|
||||
TestExecuteJsiModule.testSameJsiRuntime();
|
||||
TestExecuteJsiModule.testExecuteJsiPromise();
|
||||
testExecuteJsiModule.testSimpleExecuteJsi();
|
||||
testExecuteJsiModule.testHostFunction();
|
||||
testExecuteJsiModule.testHostObject();
|
||||
testExecuteJsiModule.testSameJsiRuntime();
|
||||
testExecuteJsiModule.testExecuteJsiPromise();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as TurboModuleRegistry from '../Libraries/TurboModule/TurboModuleRegistry';
|
||||
import { TurboModuleRegistry } from 'react-native';
|
||||
const myTrivialTurboModule = TurboModuleRegistry.getEnforcing('MyTrivialTurboModule');
|
||||
|
||||
myTrivialTurboModule.startFromJS();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as TurboModuleRegistry from '../Libraries/TurboModule/TurboModuleRegistry';
|
||||
import { TurboModuleRegistry } from 'react-native';
|
||||
const mySimpleTurboModule = TurboModuleRegistry.getEnforcing('MySimpleTurboModule');
|
||||
|
||||
// The logging of the TurboModule functions is verified against the test action sequence.
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import { NativeModules } from 'react-native';
|
||||
|
||||
NativeModules.NotificationTestModule.runTest();
|
||||
import { TurboModuleRegistry } from 'react-native';
|
||||
const notificationTestModule = TurboModuleRegistry.getEnforcing('NotificationTestModule');
|
||||
notificationTestModule.runTest();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as TurboModuleRegistry from '../Libraries/TurboModule/TurboModuleRegistry';
|
||||
import { TurboModuleRegistry } from 'react-native';
|
||||
const CppTurboModule = TurboModuleRegistry.getEnforcing('CppTurboModule');
|
||||
|
||||
// Convert function with one callback to Promise
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System.Linq;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace Microsoft.ReactNative.Managed.CodeGen.UnitTests.Analysis
|
||||
{
|
||||
[TestClass]
|
||||
public class ModuleGetConstantsAnalysisTests : AnalysisTestBase
|
||||
{
|
||||
[TestMethod]
|
||||
public void SuccessReturnStruct()
|
||||
{
|
||||
var (codeAnalyzer, type) = AnalyzeModuleFile(@"
|
||||
[ReactGetConstants]
|
||||
public System.ValueTuple<string, int> GetMyConstants()
|
||||
{
|
||||
return new System.ValueTuple<string, int>(""Hello"", 42);
|
||||
}
|
||||
");
|
||||
var result = codeAnalyzer.TryExtractModule(type, out var module);
|
||||
Assert.IsTrue(result);
|
||||
|
||||
Assert.AreEqual(1, module.GetConstants.Count);
|
||||
Assert.AreEqual("GetMyConstants", module.GetConstants.First().Method.Name);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SuccessReturnClass()
|
||||
{
|
||||
var (codeAnalyzer, type) = AnalyzeModuleFile(@"
|
||||
[ReactGetConstants]
|
||||
public System.Tuple<string, int> GetMyConstants()
|
||||
{
|
||||
return new System.Tuple<string, int>(""Hello"", 42);
|
||||
}
|
||||
");
|
||||
var result = codeAnalyzer.TryExtractModule(type, out var module);
|
||||
Assert.IsTrue(result);
|
||||
|
||||
Assert.AreEqual(1, module.GetConstants.Count);
|
||||
Assert.AreEqual("GetMyConstants", module.GetConstants.First().Method.Name);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void NotPublic()
|
||||
{
|
||||
var (codeAnalyzer, type) = AnalyzeModuleFile(@"
|
||||
[ReactGetConstants]
|
||||
private System.ValueTuple<string, int> GetMyConstants(int x)
|
||||
{
|
||||
return new System.ValueTuple<string, int>(""Hello"", 42);
|
||||
}
|
||||
");
|
||||
codeAnalyzer.TryExtractModule(type, out _);
|
||||
ExpectSingleError(codeAnalyzer, DiagnosticDescriptors.GetConstantsMustBePublicOrInternal);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ReturnsVoid()
|
||||
{
|
||||
var (codeAnalyzer, type) = AnalyzeModuleFile(@"
|
||||
[ReactGetConstants]
|
||||
public void GetMyConstants()
|
||||
{
|
||||
}
|
||||
");
|
||||
codeAnalyzer.TryExtractModule(type, out _);
|
||||
ExpectSingleError(codeAnalyzer, DiagnosticDescriptors.GetConstantsMustNotReturnVoid);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ReturnsInt()
|
||||
{
|
||||
var (codeAnalyzer, type) = AnalyzeModuleFile(@"
|
||||
[ReactGetConstants]
|
||||
public int GetMyConstants()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
");
|
||||
codeAnalyzer.TryExtractModule(type, out _);
|
||||
ExpectSingleError(codeAnalyzer, DiagnosticDescriptors.GetConstantsMustReturnStructOrClass);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ExtraArg()
|
||||
{
|
||||
var (codeAnalyzer, type) = AnalyzeModuleFile(@"
|
||||
[ReactGetConstants]
|
||||
public System.ValueTuple<string, int> GetMyConstants(int x)
|
||||
{
|
||||
return new System.ValueTuple<string, int>(""Hello"", 42);
|
||||
}
|
||||
");
|
||||
codeAnalyzer.TryExtractModule(type, out _);
|
||||
ExpectSingleError(codeAnalyzer, DiagnosticDescriptors.GetConstantsMustNotHaveParameters);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -191,7 +191,8 @@ namespace Microsoft.ReactNative.Managed.CodeGen.UnitTests.Analysis
|
|||
var method = module.Methods.First();
|
||||
Assert.AreEqual("Test", method.Name);
|
||||
Assert.AreEqual(0, method.EffectiveParameters.Count);
|
||||
Assert.AreEqual("int", method.EffectiveReturnType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat));
|
||||
Assert.AreEqual("void", method.EffectiveReturnType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat));
|
||||
Assert.AreEqual(1, method.ResolveParameterCount);
|
||||
Assert.AreEqual(ReactMethod.MethodReturnStyle.Callback, method.ReturnStyle);
|
||||
}
|
||||
|
||||
|
@ -212,7 +213,30 @@ namespace Microsoft.ReactNative.Managed.CodeGen.UnitTests.Analysis
|
|||
var method = module.Methods.First();
|
||||
Assert.AreEqual("Test", method.Name);
|
||||
Assert.AreEqual(2, method.EffectiveParameters.Count);
|
||||
Assert.AreEqual("int", method.EffectiveReturnType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat));
|
||||
Assert.AreEqual("void", method.EffectiveReturnType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat));
|
||||
Assert.AreEqual(1, method.ResolveParameterCount);
|
||||
Assert.AreEqual(ReactMethod.MethodReturnStyle.Callback, method.ReturnStyle);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SingleCallbackMethodThreeCallbackArgs()
|
||||
{
|
||||
var (codeAnalyzer, type) = AnalyzeModuleFile(@"
|
||||
[ReactMethod]
|
||||
public string Test(int z, string a0, Action<int, string, int> callback)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
");
|
||||
var result = codeAnalyzer.TryExtractModule(type, out var module);
|
||||
Assert.IsTrue(result);
|
||||
|
||||
Assert.AreEqual(1, module.Methods.Count);
|
||||
var method = module.Methods.First();
|
||||
Assert.AreEqual("Test", method.Name);
|
||||
Assert.AreEqual(2, method.EffectiveParameters.Count);
|
||||
Assert.AreEqual("void", method.EffectiveReturnType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat));
|
||||
Assert.AreEqual(3, method.ResolveParameterCount);
|
||||
Assert.AreEqual(ReactMethod.MethodReturnStyle.Callback, method.ReturnStyle);
|
||||
}
|
||||
|
||||
|
@ -232,7 +256,9 @@ namespace Microsoft.ReactNative.Managed.CodeGen.UnitTests.Analysis
|
|||
var method = module.Methods.First();
|
||||
Assert.AreEqual("Test", method.Name);
|
||||
Assert.AreEqual(0, method.EffectiveParameters.Count);
|
||||
Assert.AreEqual("int", method.EffectiveReturnType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat));
|
||||
Assert.AreEqual("void", method.EffectiveReturnType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat));
|
||||
Assert.AreEqual(1, method.ResolveParameterCount);
|
||||
Assert.AreEqual(1, method.RejectParameterCount);
|
||||
Assert.AreEqual(ReactMethod.MethodReturnStyle.TwoCallbacks, method.ReturnStyle);
|
||||
}
|
||||
|
||||
|
@ -253,7 +279,32 @@ namespace Microsoft.ReactNative.Managed.CodeGen.UnitTests.Analysis
|
|||
var method = module.Methods.First();
|
||||
Assert.AreEqual("Test", method.Name);
|
||||
Assert.AreEqual(2, method.EffectiveParameters.Count);
|
||||
Assert.AreEqual("int", method.EffectiveReturnType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat));
|
||||
Assert.AreEqual("void", method.EffectiveReturnType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat));
|
||||
Assert.AreEqual(1, method.ResolveParameterCount);
|
||||
Assert.AreEqual(1, method.RejectParameterCount);
|
||||
Assert.AreEqual(ReactMethod.MethodReturnStyle.TwoCallbacks, method.ReturnStyle);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DoubleCallbackMethodMoreCallbackArgs()
|
||||
{
|
||||
var (codeAnalyzer, type) = AnalyzeModuleFile(@"
|
||||
[ReactMethod]
|
||||
public string Test(int z, string a0, Action<int, string> callback, Action<string, int, int> reject)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
");
|
||||
var result = codeAnalyzer.TryExtractModule(type, out var module);
|
||||
Assert.IsTrue(result);
|
||||
|
||||
Assert.AreEqual(1, module.Methods.Count);
|
||||
var method = module.Methods.First();
|
||||
Assert.AreEqual("Test", method.Name);
|
||||
Assert.AreEqual(2, method.EffectiveParameters.Count);
|
||||
Assert.AreEqual("void", method.EffectiveReturnType.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat));
|
||||
Assert.AreEqual(2, method.ResolveParameterCount);
|
||||
Assert.AreEqual(3, method.RejectParameterCount);
|
||||
Assert.AreEqual(ReactMethod.MethodReturnStyle.TwoCallbacks, method.ReturnStyle);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.ReactNative.Managed.CodeGen.Model;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace Microsoft.ReactNative.Managed.CodeGen.UnitTests.CodeGen
|
||||
{
|
||||
[TestClass]
|
||||
public class CodeGenGetConstantsTests : CodeGenTestBase
|
||||
{
|
||||
[TestMethod]
|
||||
public void RegularCase()
|
||||
{
|
||||
TestCodeGen<IMethodSymbol>(
|
||||
@"public System.ValueTuple<string,int> MyMethod() { return new System.ValueTuple<string,int>(""Hello"", 42); }",
|
||||
(codeGen, symbol) =>
|
||||
codeGen.AddGetConstants(new ReactGetConstants(symbol)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -115,6 +115,12 @@ namespace Microsoft.ReactNative.Managed.CodeGen.UnitTests.CodeGen
|
|||
TestMethod("public void Method(int x, Action<int> cb1) { }", ReactMethod.MethodReturnStyle.Callback);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IntParamAndSingleThreeArgCallbackParamReturnVoid()
|
||||
{
|
||||
TestMethod("public void Method(int x, Action<int, string, double> cb1) { }", ReactMethod.MethodReturnStyle.Callback);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DoubleArgCallbackParamReturnVoid()
|
||||
{
|
||||
|
@ -127,6 +133,13 @@ namespace Microsoft.ReactNative.Managed.CodeGen.UnitTests.CodeGen
|
|||
TestMethod("public void Method(int x, Action<int> cb1, Action<int> cb2) { }", ReactMethod.MethodReturnStyle.TwoCallbacks);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void IntParamAndDoubleMultipleArgCallbackParamReturnVoid()
|
||||
{
|
||||
TestMethod("public void Method(int x, Action<int, string, double> cb1, Action<int, string> cb2) { }", ReactMethod.MethodReturnStyle.TwoCallbacks);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ZeroArgTask()
|
||||
{
|
||||
|
@ -159,8 +172,15 @@ namespace Microsoft.ReactNative.Managed.CodeGen.UnitTests.CodeGen
|
|||
|
||||
private void TestMethod(string methodDecl, ReactMethod.MethodReturnStyle returnStyle)
|
||||
{
|
||||
TestMethod(methodDecl, returnStyle, isSynchronous: true);
|
||||
TestMethod(methodDecl, returnStyle, isSynchronous: false);
|
||||
if (returnStyle == ReactMethod.MethodReturnStyle.ReturnValue)
|
||||
{
|
||||
TestMethod(methodDecl, returnStyle, isSynchronous: true);
|
||||
TestMethod(methodDecl, returnStyle, isSynchronous: false);
|
||||
}
|
||||
else
|
||||
{
|
||||
TestMethod(methodDecl, returnStyle, isSynchronous: false);
|
||||
}
|
||||
}
|
||||
|
||||
private void TestMethod(string methodDecl, ReactMethod.MethodReturnStyle returnStyle, bool isSynchronous)
|
||||
|
@ -171,21 +191,27 @@ namespace Microsoft.ReactNative.Managed.CodeGen.UnitTests.CodeGen
|
|||
{
|
||||
var returnType = symbol.ReturnType;
|
||||
var parameters = new List<IParameterSymbol>(symbol.Parameters);
|
||||
int resolveParameterCount = 0;
|
||||
int rejectParameterCount = 0;
|
||||
switch (returnStyle)
|
||||
{
|
||||
case ReactMethod.MethodReturnStyle.Promise:
|
||||
case ReactMethod.MethodReturnStyle.Callback:
|
||||
returnType = ((INamedTypeSymbol)parameters[parameters.Count - 1].Type).TypeArguments[0];
|
||||
parameters.RemoveAt(parameters.Count - 1);
|
||||
break;
|
||||
case ReactMethod.MethodReturnStyle.Callback:
|
||||
resolveParameterCount = ((INamedTypeSymbol)parameters[parameters.Count - 1].Type).TypeArguments.Count();
|
||||
parameters.RemoveAt(parameters.Count - 1);
|
||||
break;
|
||||
case ReactMethod.MethodReturnStyle.TwoCallbacks:
|
||||
returnType = ((INamedTypeSymbol)parameters[parameters.Count - 2].Type).TypeArguments[0];
|
||||
resolveParameterCount = ((INamedTypeSymbol)parameters[parameters.Count - 2].Type).TypeArguments.Count();
|
||||
rejectParameterCount = ((INamedTypeSymbol)parameters[parameters.Count - 1].Type).TypeArguments.Count();
|
||||
parameters.RemoveRange(parameters.Count - 2, 2);
|
||||
break;
|
||||
case ReactMethod.MethodReturnStyle.Task:
|
||||
var namedReturnType = ((INamedTypeSymbol) returnType);
|
||||
var namedReturnType = ((INamedTypeSymbol)returnType);
|
||||
returnType = namedReturnType.TypeArguments.Any()
|
||||
? ((INamedTypeSymbol) returnType).TypeArguments[0]
|
||||
? ((INamedTypeSymbol)returnType).TypeArguments[0]
|
||||
: codeGen.ReactTypes.SystemVoid;
|
||||
break;
|
||||
}
|
||||
|
@ -195,7 +221,9 @@ namespace Microsoft.ReactNative.Managed.CodeGen.UnitTests.CodeGen
|
|||
isSynchronous: isSynchronous,
|
||||
returnStyle: returnStyle,
|
||||
effectiveReturnType: returnType,
|
||||
effectiveParameters: parameters));
|
||||
effectiveParameters: parameters,
|
||||
resolveParameterCount: resolveParameterCount,
|
||||
rejectParameterCount: rejectParameterCount));
|
||||
},
|
||||
lkgName: isSynchronous ? "Sync" : "Async");
|
||||
}
|
||||
|
|
|
@ -56,6 +56,37 @@ namespace Microsoft.ReactNative.Managed.CodeGen.UnitTests.CodeGen
|
|||
);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void AllFieldTypesWithReactPropertyAttribute()
|
||||
{
|
||||
TestCodeGen<INamedTypeSymbol>(@"
|
||||
public struct MyStruct
|
||||
{
|
||||
[ReactProperty(""x1"")]
|
||||
public readonly int X1;
|
||||
|
||||
[ReactProperty(""y1"")]
|
||||
public const int Y1 = 42;
|
||||
|
||||
[ReactProperty(""z1"")]
|
||||
public int Z1;
|
||||
|
||||
[ReactProperty(""x2"")]
|
||||
public int X2 => 42;
|
||||
|
||||
[ReactProperty(""y2"")]
|
||||
public int Y2 { set {} }
|
||||
|
||||
[ReactProperty(""z2"")]
|
||||
public int Z2 { get; set; }
|
||||
|
||||
private int B2;
|
||||
}
|
||||
",
|
||||
(codeGen, symbol) => { return codeGen.CreateObjectSerializers(new[] { symbol }); }
|
||||
);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void NoStatics()
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
internal void CreateObjectSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyClass>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyClass value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyClass>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyClass value) =>
|
||||
{
|
||||
value = new global::TestClass.MyClass();
|
||||
if (reader.ValueType == global::Microsoft.ReactNative.JSValueType.Object)
|
||||
|
@ -18,7 +18,7 @@ internal void CreateObjectSerializers()
|
|||
}
|
||||
|
||||
;
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyClass>.WriteValue = (writer, value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyClass>.WriteValue = (writer, value) =>
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
internal void CreateObjectSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyClass>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyClass value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyClass>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyClass value) =>
|
||||
{
|
||||
value = new global::TestClass.MyClass();
|
||||
if (reader.ValueType == global::Microsoft.ReactNative.JSValueType.Object)
|
||||
|
@ -21,7 +21,7 @@ internal void CreateObjectSerializers()
|
|||
}
|
||||
|
||||
;
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyClass>.WriteValue = (writer, value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyClass>.WriteValue = (writer, value) =>
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
internal void CreateObjectSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyClass>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyClass value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyClass>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyClass value) =>
|
||||
{
|
||||
value = new global::TestClass.MyClass();
|
||||
if (reader.ValueType == global::Microsoft.ReactNative.JSValueType.Object)
|
||||
|
@ -15,7 +15,7 @@ internal void CreateObjectSerializers()
|
|||
}
|
||||
|
||||
;
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyClass>.WriteValue = (writer, value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyClass>.WriteValue = (writer, value) =>
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
internal void CreateObjectSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyClass>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyClass value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyClass>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyClass value) =>
|
||||
{
|
||||
value = new global::TestClass.MyClass();
|
||||
if (reader.ValueType == global::Microsoft.ReactNative.JSValueType.Object)
|
||||
|
@ -15,7 +15,7 @@ internal void CreateObjectSerializers()
|
|||
}
|
||||
|
||||
;
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyClass>.WriteValue = (writer, value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyClass>.WriteValue = (writer, value) =>
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
internal void CreateObjectSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyClass>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyClass value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyClass>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyClass value) =>
|
||||
{
|
||||
value = new global::TestClass.MyClass();
|
||||
if (reader.ValueType == global::Microsoft.ReactNative.JSValueType.Object)
|
||||
|
@ -15,7 +15,7 @@ internal void CreateObjectSerializers()
|
|||
}
|
||||
|
||||
;
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyClass>.WriteValue = (writer, value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyClass>.WriteValue = (writer, value) =>
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
internal void CreateEnumSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyEnum>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyEnum value) => value = (global::TestClass.MyEnum)global::Microsoft.ReactNative.Managed.JSValueReader.ReadValue<byte>(reader);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyEnum>.WriteValue = (writer, value) => global::Microsoft.ReactNative.Managed.JSValueWriter.WriteValue<byte>(writer, (byte)value);
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyEnum>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyEnum value) => value = (global::TestClass.MyEnum)global::Microsoft.ReactNative.Managed.JSValueReader.ReadValue<byte>(reader);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyEnum>.WriteValue = (writer, value) => global::Microsoft.ReactNative.Managed.JSValueWriter.WriteValue<byte>(writer, (byte)value);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
internal void CreateEnumSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyEnum>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyEnum value) => value = (global::TestClass.MyEnum)global::Microsoft.ReactNative.Managed.JSValueReader.ReadValue<int>(reader);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyEnum>.WriteValue = (writer, value) => global::Microsoft.ReactNative.Managed.JSValueWriter.WriteValue<int>(writer, (int)value);
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyEnum>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyEnum value) => value = (global::TestClass.MyEnum)global::Microsoft.ReactNative.Managed.JSValueReader.ReadValue<int>(reader);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyEnum>.WriteValue = (writer, value) => global::Microsoft.ReactNative.Managed.JSValueWriter.WriteValue<int>(writer, (int)value);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
internal void CreateEnumSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyEnum>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyEnum value) => value = (global::TestClass.MyEnum)global::Microsoft.ReactNative.Managed.JSValueReader.ReadValue<int>(reader);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyEnum>.WriteValue = (writer, value) => global::Microsoft.ReactNative.Managed.JSValueWriter.WriteValue<int>(writer, (int)value);
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyEnum>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyEnum value) => value = (global::TestClass.MyEnum)global::Microsoft.ReactNative.Managed.JSValueReader.ReadValue<int>(reader);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyEnum>.WriteValue = (writer, value) => global::Microsoft.ReactNative.Managed.JSValueWriter.WriteValue<int>(writer, (int)value);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
internal void CreateEnumSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyEnum>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyEnum value) => value = (global::TestClass.MyEnum)global::Microsoft.ReactNative.Managed.JSValueReader.ReadValue<int>(reader);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyEnum>.WriteValue = (writer, value) => global::Microsoft.ReactNative.Managed.JSValueWriter.WriteValue<int>(writer, (int)value);
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyEnum>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyEnum value) => value = (global::TestClass.MyEnum)global::Microsoft.ReactNative.Managed.JSValueReader.ReadValue<int>(reader);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyEnum>.WriteValue = (writer, value) => global::Microsoft.ReactNative.Managed.JSValueWriter.WriteValue<int>(writer, (int)value);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
moduleBuilder.AddConstantProvider((global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.ReactConstantProvider provider = new global::Microsoft.ReactNative.Managed.ReactConstantProvider(writer);
|
||||
var constants = module.MyMethod();
|
||||
provider.WriteProperties(constants);
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +1,6 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.TwoCallbacks, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
module.Method((value) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)), (value) => reject(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)));
|
||||
module.Method((value0) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value0)), (value0) => reject(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value0)));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
module.Method((value) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)), (value) => reject(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out global::Microsoft.ReactNative.Managed.IReactPromise<string> arg0);
|
||||
module.Method(arg0, new global::Microsoft.ReactNative.Managed.ReactPromise<int>(writer, resolve, reject));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +1,7 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.TwoCallbacks, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out int arg0);
|
||||
module.Method(arg0, (value) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)), (value) => reject(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)));
|
||||
module.Method(arg0, (value0) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value0)), (value0) => reject(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value0)));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out int arg0);
|
||||
module.Method(arg0, (value) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)), (value) => reject(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)));
|
||||
}
|
||||
|
||||
);
|
|
@ -0,0 +1,7 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.TwoCallbacks, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out int arg0);
|
||||
module.Method(arg0, (value0, value1, value2) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value0, value1, value2)), (value0, value1) => reject(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value0, value1)));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out int arg0, out global::Microsoft.ReactNative.Managed.IReactPromise<string> arg1);
|
||||
module.Method(arg0, arg1, new global::Microsoft.ReactNative.Managed.ReactPromise<int>(writer, resolve, reject));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out int arg0);
|
||||
module.Method(arg0, new global::Microsoft.ReactNative.Managed.ReactPromise<int>(writer, resolve, reject));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +1,7 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.Callback, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out int arg0);
|
||||
module.Method(arg0, (value) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)));
|
||||
module.Method(arg0, (value0) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value0)));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out int arg0);
|
||||
module.Method(arg0, (value) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)));
|
||||
}
|
||||
|
||||
);
|
|
@ -0,0 +1,7 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.Callback, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out int arg0);
|
||||
module.Method(arg0, (value0, value1, value2) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value0, value1, value2)));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,6 +1,5 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.Callback, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
int result = module.Method();
|
||||
resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, result));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
int result = module.Method();
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteValue(writer, result);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.Void, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
module.Method();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
module.Method();
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out int arg0);
|
||||
module.Method(arg0);
|
||||
}
|
||||
|
||||
);
|
|
@ -1,6 +1,5 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.Promise, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
module.Method(new global::Microsoft.ReactNative.Managed.ReactPromise<int>(writer, resolve, reject));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
module.Method(new global::Microsoft.ReactNative.Managed.ReactPromise<int>(writer, resolve, reject));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out string arg0);
|
||||
module.Method(arg0, new global::Microsoft.ReactNative.Managed.ReactPromise<int>(writer, resolve, reject));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,6 +1,5 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.Promise, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
module.Method(new global::Microsoft.ReactNative.Managed.ReactPromise<int>(writer, resolve, reject));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
module.Method(new global::Microsoft.ReactNative.Managed.ReactPromise<int>(writer, resolve, reject));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out string arg0);
|
||||
module.Method(arg0, new global::Microsoft.ReactNative.Managed.ReactPromise<global::System.Collections.Generic.IReadOnlyList<string>>(writer, resolve, reject));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +1,6 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.Callback, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
module.Method((value) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)));
|
||||
module.Method((value0) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value0)));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
module.Method((value) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +1,6 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.Callback, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
module.Method((value) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)));
|
||||
module.Method((value0) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value0)));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
module.Method((value) => resolve(global::Microsoft.ReactNative.Managed.JSValueWriter.WriteArgs(writer, value)));
|
||||
}
|
||||
|
||||
);
|
|
@ -1,7 +0,0 @@
|
|||
moduleBuilder.AddSyncMethod("MyMethod", (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader, out int arg0, out string arg1, out double arg2);
|
||||
module.Method(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
);
|
|
@ -1,6 +1,5 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.Promise, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
global::System.Threading.Tasks.Task result = module.Method();
|
||||
global::Microsoft.ReactNative.Managed.ReactTaskExtensions.ContinueWith(result, writer, resolve, reject);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.Promise, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
global::System.Threading.Tasks.Task<int> result = module.Method();
|
||||
global::Microsoft.ReactNative.Managed.ReactTaskExtensions.ContinueWith(result, writer, resolve, reject);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
moduleBuilder.AddMethod("MyMethod", global::Microsoft.ReactNative.MethodReturnType.Promise, (global::Microsoft.ReactNative.IJSValueReader reader, global::Microsoft.ReactNative.IJSValueWriter writer, global::Microsoft.ReactNative.MethodResultCallback resolve, global::Microsoft.ReactNative.MethodResultCallback reject) =>
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReader.ReadArgs(reader);
|
||||
global::System.Threading.Tasks.Task<global::System.Collections.Generic.IReadOnlyList<string>> result = module.Method();
|
||||
global::Microsoft.ReactNative.Managed.ReactTaskExtensions.ContinueWith(result, writer, resolve, reject);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
internal void CreateObjectSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyStruct>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyStruct value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyStruct>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyStruct value) =>
|
||||
{
|
||||
value = new global::TestClass.MyStruct();
|
||||
if (reader.ValueType == global::Microsoft.ReactNative.JSValueType.Object)
|
||||
|
@ -18,19 +18,12 @@ internal void CreateObjectSerializers()
|
|||
}
|
||||
|
||||
;
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyStruct>.WriteValue = (writer, value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyStruct>.WriteValue = (writer, value) =>
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
writer.WriteObjectBegin();
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteObjectProperty<int>(writer, "X", value.X);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteObjectProperty<int>(writer, "Z", value.Z);
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteNull();
|
||||
}
|
||||
writer.WriteObjectBegin();
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteObjectProperty<int>(writer, "X", value.X);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteObjectProperty<int>(writer, "Z", value.Z);
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
|
||||
;
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
internal void CreateObjectSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyStruct>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyStruct value) =>
|
||||
{
|
||||
value = new global::TestClass.MyStruct();
|
||||
if (reader.ValueType == global::Microsoft.ReactNative.JSValueType.Object)
|
||||
{
|
||||
while (reader.GetNextObjectProperty(out string propertyName))
|
||||
{
|
||||
switch (propertyName)
|
||||
{
|
||||
case "z1":
|
||||
value.Z1 = global::Microsoft.ReactNative.Managed.JSValueReader.ReadValue<int>(reader);
|
||||
break;
|
||||
case "y2":
|
||||
value.Y2 = global::Microsoft.ReactNative.Managed.JSValueReader.ReadValue<int>(reader);
|
||||
break;
|
||||
case "z2":
|
||||
value.Z2 = global::Microsoft.ReactNative.Managed.JSValueReader.ReadValue<int>(reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
;
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyStruct>.WriteValue = (writer, value) =>
|
||||
{
|
||||
writer.WriteObjectBegin();
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteObjectProperty<int>(writer, "x1", value.X1);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteObjectProperty<int>(writer, "z1", value.Z1);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteObjectProperty<int>(writer, "x2", value.X2);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteObjectProperty<int>(writer, "z2", value.Z2);
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
|
||||
;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
internal void CreateObjectSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyStruct>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyStruct value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyStruct>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyStruct value) =>
|
||||
{
|
||||
value = new global::TestClass.MyStruct();
|
||||
if (reader.ValueType == global::Microsoft.ReactNative.JSValueType.Object)
|
||||
|
@ -21,19 +21,12 @@ internal void CreateObjectSerializers()
|
|||
}
|
||||
|
||||
;
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyStruct>.WriteValue = (writer, value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyStruct>.WriteValue = (writer, value) =>
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
writer.WriteObjectBegin();
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteObjectProperty<int>(writer, "X", value.X);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteObjectProperty<int>(writer, "Z", value.Z);
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteNull();
|
||||
}
|
||||
writer.WriteObjectBegin();
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteObjectProperty<int>(writer, "X", value.X);
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriter.WriteObjectProperty<int>(writer, "Z", value.Z);
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
|
||||
;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
internal void CreateObjectSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyStruct>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyStruct value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyStruct>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyStruct value) =>
|
||||
{
|
||||
value = new global::TestClass.MyStruct();
|
||||
if (reader.ValueType == global::Microsoft.ReactNative.JSValueType.Object)
|
||||
|
@ -15,17 +15,10 @@ internal void CreateObjectSerializers()
|
|||
}
|
||||
|
||||
;
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyStruct>.WriteValue = (writer, value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyStruct>.WriteValue = (writer, value) =>
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
writer.WriteObjectBegin();
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteNull();
|
||||
}
|
||||
writer.WriteObjectBegin();
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
|
||||
;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
internal void CreateObjectSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyStruct>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyStruct value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyStruct>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyStruct value) =>
|
||||
{
|
||||
value = new global::TestClass.MyStruct();
|
||||
if (reader.ValueType == global::Microsoft.ReactNative.JSValueType.Object)
|
||||
|
@ -15,17 +15,10 @@ internal void CreateObjectSerializers()
|
|||
}
|
||||
|
||||
;
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyStruct>.WriteValue = (writer, value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyStruct>.WriteValue = (writer, value) =>
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
writer.WriteObjectBegin();
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteNull();
|
||||
}
|
||||
writer.WriteObjectBegin();
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
|
||||
;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
internal void CreateObjectSerializers()
|
||||
{
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderCodeGen<global::TestClass.MyStruct>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyStruct value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueReaderOf<global::TestClass.MyStruct>.ReadValue = (global::Microsoft.ReactNative.IJSValueReader reader, out global::TestClass.MyStruct value) =>
|
||||
{
|
||||
value = new global::TestClass.MyStruct();
|
||||
if (reader.ValueType == global::Microsoft.ReactNative.JSValueType.Object)
|
||||
|
@ -15,17 +15,10 @@ internal void CreateObjectSerializers()
|
|||
}
|
||||
|
||||
;
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterCodeGen<global::TestClass.MyStruct>.WriteValue = (writer, value) =>
|
||||
global::Microsoft.ReactNative.Managed.JSValueWriterOf<global::TestClass.MyStruct>.WriteValue = (writer, value) =>
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
writer.WriteObjectBegin();
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteNull();
|
||||
}
|
||||
writer.WriteObjectBegin();
|
||||
writer.WriteObjectEnd();
|
||||
}
|
||||
|
||||
;
|
||||
|
|
|
@ -38,6 +38,11 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
addMemberStatements.Add(AddConstantProvider(constantProvider));
|
||||
}
|
||||
|
||||
foreach (var getConstants in module.GetConstants)
|
||||
{
|
||||
addMemberStatements.Add(AddGetConstants(getConstants));
|
||||
}
|
||||
|
||||
foreach (var method in module.Methods)
|
||||
{
|
||||
addMemberStatements.Add(AddMethod(method));
|
||||
|
@ -162,62 +167,98 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
);
|
||||
}
|
||||
|
||||
internal StatementSyntax AddGetConstants(ReactGetConstants getConstants)
|
||||
{
|
||||
// generates:
|
||||
// moduleBuilder.AddConstantProvider( (IJSValueWriter writer) => {
|
||||
// var provider = new ReactConstantProvider(writer);
|
||||
// var constants = module.GetConstantsName();
|
||||
// provider.WriteProperties(constants);
|
||||
// });
|
||||
|
||||
return InvocationStatement(
|
||||
MemberAccessExpression(ReactNativeNames.ModuleBuilder, ReactNativeNames.AddConstantProvider),
|
||||
|
||||
ParenthesizedLambdaExpression(
|
||||
parameterList: ParameterList(
|
||||
Parameter(ReactNativeNames.WriterLocalName)
|
||||
.WithType(ReactTypes.IJSValueWriter.ToTypeSyntax())),
|
||||
block: Block(
|
||||
LocalDeclarationStatement(
|
||||
ReactTypes.ReactConstantProvider,
|
||||
ReactNativeNames.ProviderLocalName,
|
||||
ObjectCreationExpression(
|
||||
ReactTypes.ReactConstantProvider,
|
||||
IdentifierName(ReactNativeNames.WriterLocalName))),
|
||||
LocalDeclarationStatement(
|
||||
ReactNativeNames.ConstantsLocalName,
|
||||
InvocationExpression(
|
||||
MemberAccessExpression(ReactNativeNames.Module, Identifier(getConstants.Method.Name)))),
|
||||
InvocationStatement(
|
||||
MemberAccessExpression(ReactNativeNames.ProviderLocalName, ReactNativeNames.WritePropertiesMethodName),
|
||||
IdentifierName(ReactNativeNames.ConstantsLocalName))),
|
||||
expressionBody: null
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
internal StatementSyntax AddMethod(ReactMethod method)
|
||||
{
|
||||
var statements = new List<StatementSyntax>();
|
||||
|
||||
var parameters = method.Method.Parameters;
|
||||
|
||||
var readArgsArguments = new List<ArgumentSyntax>(parameters.Length);
|
||||
readArgsArguments.Add(Argument(IdentifierName(ReactNativeNames.ReaderLocalName)));
|
||||
var args = new List<ExpressionSyntax>(parameters.Length);
|
||||
|
||||
// generates:
|
||||
// (out ArgType0 arg0, out ArgType1 arg1, ...);
|
||||
// as well as
|
||||
// (arg0, arg1, ... )
|
||||
for (int i = 0; i < method.EffectiveParameters.Count; i++)
|
||||
List<ArgumentSyntax>? readArgsArguments = null;
|
||||
if (method.EffectiveParameters.Count > 0)
|
||||
{
|
||||
var param = method.EffectiveParameters[i];
|
||||
var variableName = "arg" + i.ToString(CultureInfo.InvariantCulture);
|
||||
readArgsArguments = new List<ArgumentSyntax>(method.EffectiveParameters.Count + 1) {
|
||||
Argument(IdentifierName(ReactNativeNames.ReaderLocalName))
|
||||
};
|
||||
|
||||
readArgsArguments.Add(Argument(
|
||||
nameColon: null,
|
||||
refKindKeyword: Token(SyntaxKind.OutKeyword),
|
||||
expression: DeclarationExpression(
|
||||
param.Type.ToTypeSyntax(),
|
||||
SingleVariableDesignation(
|
||||
Identifier(variableName))
|
||||
)
|
||||
));
|
||||
// generates output arguments:
|
||||
// (..., out ArgType0 arg0, out ArgType1 arg1, ...);
|
||||
readArgsArguments.AddRange(method.EffectiveParameters.Select((param, i) => Argument(
|
||||
nameColon: null,
|
||||
refKindKeyword: Token(SyntaxKind.OutKeyword),
|
||||
expression: DeclarationExpression(
|
||||
param.Type.ToTypeSyntax(),
|
||||
SingleVariableDesignation(ReactNativeNames.ArgLocalNames[i])))));
|
||||
|
||||
args.Add(IdentifierName(variableName));
|
||||
// generates:
|
||||
// (arg0, arg1, ... )
|
||||
args.AddRange(method.EffectiveParameters.Select((_, i) => IdentifierName(ReactNativeNames.ArgLocalNames[i])));
|
||||
}
|
||||
|
||||
switch (method.ReturnStyle)
|
||||
{
|
||||
case ReactMethod.MethodReturnStyle.Promise:
|
||||
args.Add(ObjectCreationExpression(
|
||||
ReactTypes.ReactPromise.Construct(method.EffectiveReturnType),
|
||||
SymbolEqualityComparer.Default.Equals(method.EffectiveReturnType, ReactTypes.SystemVoid)
|
||||
? ReactTypes.ReactPromiseOfVoid
|
||||
: ReactTypes.ReactPromise.Construct(method.EffectiveReturnType),
|
||||
IdentifierName(ReactNativeNames.WriterLocalName),
|
||||
IdentifierName(ReactNativeNames.ResolveLocalName),
|
||||
IdentifierName(ReactNativeNames.RejectLocalName)
|
||||
));
|
||||
break;
|
||||
case ReactMethod.MethodReturnStyle.Callback:
|
||||
args.Add(GeneratePromiseInvocation(isReject: false));
|
||||
args.Add(GenerateCallbackInvocation(ReactNativeNames.ResolveLocalName, method.ResolveParameterCount));
|
||||
break;
|
||||
case ReactMethod.MethodReturnStyle.TwoCallbacks:
|
||||
args.Add(GeneratePromiseInvocation(isReject: false));
|
||||
args.Add(GeneratePromiseInvocation(isReject: true));
|
||||
args.Add(GenerateCallbackInvocation(ReactNativeNames.ResolveLocalName, method.ResolveParameterCount));
|
||||
args.Add(GenerateCallbackInvocation(ReactNativeNames.RejectLocalName, method.RejectParameterCount));
|
||||
break;
|
||||
}
|
||||
|
||||
// generates:
|
||||
// reader.ReadArgs( ... )
|
||||
statements.Add(InvocationStatement(
|
||||
MemberAccessExpression(ReactTypes.JSValueReader, ReactNativeNames.ReadArgsMethodName),
|
||||
readArgsArguments));
|
||||
// Generate reader call only if we have argumentes to read.
|
||||
if (readArgsArguments != null)
|
||||
{
|
||||
// generates:
|
||||
// reader.ReadArgs( ... )
|
||||
statements.Add(InvocationStatement(
|
||||
MemberAccessExpression(ReactTypes.JSValueReader, ReactNativeNames.ReadArgsMethodName),
|
||||
readArgsArguments));
|
||||
}
|
||||
|
||||
var methodCall = InvocationStatement(
|
||||
MemberAccessExpression(ReactNativeNames.Module, Identifier(method.Method.Name)),
|
||||
|
@ -255,7 +296,7 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
else
|
||||
{
|
||||
if (method.IsSynchronous)
|
||||
{
|
||||
{
|
||||
// generate:
|
||||
// writer.WriteValue(result);
|
||||
var writeValue = InvocationExpression(
|
||||
|
@ -349,26 +390,22 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
}
|
||||
}
|
||||
|
||||
internal ExpressionSyntax GeneratePromiseInvocation(bool isReject)
|
||||
internal ExpressionSyntax GenerateCallbackInvocation(SyntaxToken callbackName, int parameterCount)
|
||||
{
|
||||
// generates:
|
||||
// value1 => resolve|reject(JSValueWriter.WriteArgs(writer, value1)
|
||||
// (value0, value1, ...) => resolve|reject(JSValueWriter.WriteArgs(writer, value0, value1))
|
||||
return ParenthesizedLambdaExpression(
|
||||
parameterList: ParameterList(
|
||||
SeparatedList<ParameterSyntax>(
|
||||
new[]
|
||||
{
|
||||
Parameter(ReactNativeNames.ValueLocalName)
|
||||
})),
|
||||
SeparatedList(
|
||||
ReactNativeNames.ValueLocalNames.Take(parameterCount).Select(name => Parameter(name)).ToArray())),
|
||||
block: null,
|
||||
expressionBody: InvocationExpression(
|
||||
IdentifierName(isReject ? ReactNativeNames.RejectLocalName : ReactNativeNames.ResolveLocalName),
|
||||
IdentifierName(callbackName),
|
||||
InvocationExpression(
|
||||
MemberAccessExpression(ReactTypes.JSValueWriter, ReactNativeNames.WriteArgsMethodName),
|
||||
IdentifierName(ReactNativeNames.WriterLocalName),
|
||||
IdentifierName(ReactNativeNames.ValueLocalName))
|
||||
)
|
||||
);
|
||||
Enumerable.Concat(
|
||||
Enumerable.Repeat(IdentifierName(ReactNativeNames.WriterLocalName), 1),
|
||||
ReactNativeNames.ValueLocalNames.Take(parameterCount).Select(name => IdentifierName(name))))));
|
||||
}
|
||||
|
||||
internal StatementSyntax AddEvent(ReactEvent evnt)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.ContractsLight;
|
||||
using System.Linq;
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
@ -123,7 +124,6 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
|
||||
internal MemberDeclarationSyntax CreateObjectSerializers(IEnumerable<INamedTypeSymbol> symbols)
|
||||
{
|
||||
|
||||
var registrationCalls = new List<StatementSyntax>();
|
||||
|
||||
foreach (var symbol in symbols)
|
||||
|
@ -152,6 +152,7 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
}
|
||||
|
||||
string name;
|
||||
string jsonPropertyName;
|
||||
ISymbol type;
|
||||
bool emitRead;
|
||||
bool emitWrite;
|
||||
|
@ -160,6 +161,7 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
if (member is IFieldSymbol field)
|
||||
{
|
||||
name = field.Name;
|
||||
jsonPropertyName = TryGetJSNameFromAttribute(field, out var jsName) ? jsName : name;
|
||||
type = field.Type;
|
||||
emitRead = !field.IsConst && !field.IsReadOnly;
|
||||
emitWrite = true;
|
||||
|
@ -168,6 +170,7 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
(member is IPropertySymbol property)
|
||||
{
|
||||
name = property.Name;
|
||||
jsonPropertyName = TryGetJSNameFromAttribute(property, out var jsName) ? jsName : name;
|
||||
type = property.Type;
|
||||
emitRead = !property.IsReadOnly;
|
||||
emitWrite = !property.IsWriteOnly;
|
||||
|
@ -179,7 +182,7 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
|
||||
if (emitRead)
|
||||
{
|
||||
readOperations.Add(ReadSwitch(name, type));
|
||||
readOperations.Add(ReadSwitch(name, jsonPropertyName, type));
|
||||
}
|
||||
|
||||
if (emitWrite)
|
||||
|
@ -192,7 +195,7 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
ReactTypes.JSValueWriter.ToTypeSyntax(),
|
||||
GenericName(ReactNativeNames.WriteObjectPropertyMethodName, type.ToTypeSyntax())),
|
||||
IdentifierName(ReactNativeNames.WriterLocalName),
|
||||
LiteralExpression(name),
|
||||
LiteralExpression(jsonPropertyName),
|
||||
MemberAccessExpression(ReactNativeNames.ValueLocalName, Identifier(name)))
|
||||
)
|
||||
);
|
||||
|
@ -281,11 +284,21 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
// writer.WriteNull();
|
||||
// }
|
||||
// }
|
||||
registrationCalls.Add(
|
||||
CodeGenWrite(
|
||||
symbol,
|
||||
statements: new[]
|
||||
{
|
||||
if (symbol.TypeKind == TypeKind.Struct)
|
||||
{
|
||||
registrationCalls.Add(
|
||||
CodeGenWrite(
|
||||
symbol,
|
||||
statements: writeOperations.ToArray())
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
registrationCalls.Add(
|
||||
CodeGenWrite(
|
||||
symbol,
|
||||
statements: new[]
|
||||
{
|
||||
IfStatement(
|
||||
BinaryExpression(
|
||||
SyntaxKind.NotEqualsExpression,
|
||||
|
@ -302,8 +315,9 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
)
|
||||
)
|
||||
)
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return MethodDeclaration(
|
||||
|
@ -322,11 +336,36 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
symbol.DeclaredAccessibility == Accessibility.Internal;
|
||||
}
|
||||
|
||||
private SwitchSectionSyntax ReadSwitch(string fieldName, ISymbol fieldType)
|
||||
private bool TryGetJSNameFromAttribute(ISymbol member, [NotNullWhen(returnValue: true)] out string? jsName)
|
||||
{
|
||||
jsName = null;
|
||||
AttributeData attr = member.GetAttributes().FirstOrDefault(
|
||||
a => a.AttributeClass != null
|
||||
&& a.AttributeClass.Equals(ReactTypes.ReactPropertyAttribute, SymbolEqualityComparer.Default));
|
||||
if (attr != null)
|
||||
{
|
||||
if (attr.ConstructorArguments.Length > 0)
|
||||
{
|
||||
jsName = attr.ConstructorArguments[0].Value as string;
|
||||
}
|
||||
|
||||
foreach (var namedArgument in attr.NamedArguments)
|
||||
{
|
||||
if (namedArgument.Key == nameof(ReactPropertyAttribute.PropertyName))
|
||||
{
|
||||
jsName = namedArgument.Value.Value as string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return jsName != null;
|
||||
}
|
||||
|
||||
private SwitchSectionSyntax ReadSwitch(string fieldName, string jsonPropertyName, ISymbol fieldType)
|
||||
{
|
||||
return SwitchSection(
|
||||
new SyntaxList<SwitchLabelSyntax>(
|
||||
CaseSwitchLabel(LiteralExpression(fieldName))
|
||||
CaseSwitchLabel(LiteralExpression(jsonPropertyName))
|
||||
),
|
||||
new SyntaxList<StatementSyntax>(
|
||||
new StatementSyntax[]
|
||||
|
@ -360,13 +399,13 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
{
|
||||
Contract.Requires(expression != null ^ statements != null, "Only one of the args can be null.");
|
||||
// Generates:
|
||||
// JSValueReaderCodeGen<SymbolType>.ReadValue = (reader, out value) => value = ...readExpression...;
|
||||
// JSValueReaderOf<SymbolType>.ReadValue = (reader, out value) => value = ...readExpression...;
|
||||
return
|
||||
ExpressionStatement(
|
||||
AssignmentExpression(
|
||||
SyntaxKind.SimpleAssignmentExpression,
|
||||
MemberAccessExpression(
|
||||
ReactTypes.JSValueReaderCodeGen.Construct(symbol),
|
||||
ReactTypes.JSValueReaderOf.Construct(symbol),
|
||||
ReactNativeNames.ReadValueMethodName),
|
||||
ParenthesizedLambdaExpression(
|
||||
parameterList: ParameterList(
|
||||
|
@ -399,13 +438,13 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
Contract.Requires(expression != null ^ statements != null, "Only one of the args can be null.");
|
||||
|
||||
// Generates:
|
||||
// JSValueWriterCodeGen<SymbolType>.WriteValue = (writer, value) => ...writeExpression...;
|
||||
// JSValueWriterOf<SymbolType>.WriteValue = (writer, value) => ...writeExpression...;
|
||||
return
|
||||
ExpressionStatement(
|
||||
AssignmentExpression(
|
||||
SyntaxKind.SimpleAssignmentExpression,
|
||||
MemberAccessExpression(
|
||||
ReactTypes.JSValueWriterCodeGen.Construct(symbol),
|
||||
ReactTypes.JSValueWriterOf.Construct(symbol),
|
||||
ReactNativeNames.WriteValueMethodName),
|
||||
ParenthesizedLambdaExpression(
|
||||
parameterList: ParameterList(
|
||||
|
@ -443,7 +482,7 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
AssignmentExpression(
|
||||
SyntaxKind.SimpleAssignmentExpression,
|
||||
MemberAccessExpression(
|
||||
ReactTypes.JSValueReaderCodeGen.Construct(type),
|
||||
ReactTypes.JSValueReaderOf.Construct(type),
|
||||
ReactNativeNames.ReadValueMethodName),
|
||||
MemberAccessExpression(
|
||||
method.ContainingType,
|
||||
|
@ -485,7 +524,7 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
AssignmentExpression(
|
||||
SyntaxKind.SimpleAssignmentExpression,
|
||||
MemberAccessExpression(
|
||||
ReactTypes.JSValueWriterCodeGen.Construct(type),
|
||||
ReactTypes.JSValueWriterOf.Construct(type),
|
||||
ReactNativeNames.WriteValueMethodName),
|
||||
MemberAccessExpression(
|
||||
method.ContainingType,
|
||||
|
|
|
@ -123,7 +123,7 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
id: Invariant($"{ReactNativeNames.ErrorCodePrefix}1012"),
|
||||
category: ReactNativeNames.ErrorCategory,
|
||||
title: "ReactModule ConstantProviders must have one parameter of type ReactContext",
|
||||
messageFormat: "ConstantProviders of ReactModules must have one parameter of type '{0}'. Encountered '{1}' arguments on constantProvider '{2}' of module '{3}'.",
|
||||
messageFormat: "ConstantProviders of ReactModules must have one parameter of type '{0}'. Encountered '{1}' parameters on constantProvider '{2}' of module '{3}'.",
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true);
|
||||
|
||||
|
@ -150,5 +150,37 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
messageFormat: "Methods of ReactModules should not return a Task when they are synchronous. Change the attribute from '[ReactSyncMethod]' to '[ReactMethod]' for method '{0}' of module '{1}'.",
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true);
|
||||
|
||||
public static readonly DiagnosticDescriptor GetConstantsMustBePublicOrInternal = new DiagnosticDescriptor(
|
||||
id: Invariant($"{ReactNativeNames.ErrorCodePrefix}1016"),
|
||||
category: ReactNativeNames.ErrorCategory,
|
||||
title: "ReactModule GetConstants method must be public or internal",
|
||||
messageFormat: "GetConstants of ReactModules must be public or internal. Visibility of GetConstants '{0}' of module '{1}' is '{2}'.",
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true);
|
||||
|
||||
public static readonly DiagnosticDescriptor GetConstantsMustNotReturnVoid = new DiagnosticDescriptor(
|
||||
id: Invariant($"{ReactNativeNames.ErrorCodePrefix}1017"),
|
||||
category: ReactNativeNames.ErrorCategory,
|
||||
title: "ReactModule GetConstants must not return void",
|
||||
messageFormat: "GetConstants of ReactModules must not return void. Encountered type '{0}' as return type of GetConstants '{1}' of module '{2}'.",
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true);
|
||||
|
||||
public static readonly DiagnosticDescriptor GetConstantsMustReturnStructOrClass = new DiagnosticDescriptor(
|
||||
id: Invariant($"{ReactNativeNames.ErrorCodePrefix}1018"),
|
||||
category: ReactNativeNames.ErrorCategory,
|
||||
title: "ReactModule GetConstants must return struct or class instance",
|
||||
messageFormat: "GetConstants of ReactModules must return struct or class instance. Encountered type '{0}' as return type of GetConstants '{1}' of module '{2}'.",
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true);
|
||||
|
||||
public static readonly DiagnosticDescriptor GetConstantsMustNotHaveParameters = new DiagnosticDescriptor(
|
||||
id: Invariant($"{ReactNativeNames.ErrorCodePrefix}1019"),
|
||||
category: ReactNativeNames.ErrorCategory,
|
||||
title: "ReactModule GetConstants must not have parameters",
|
||||
messageFormat: "GetConstants of ReactModules must not have parameters. Encountered '{0}' parameters on GetConstants '{1}' of module '{2}'.",
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Microsoft.ReactNative.Managed.CodeGen.Model
|
||||
{
|
||||
public class ReactGetConstants
|
||||
{
|
||||
public IMethodSymbol Method { get; }
|
||||
|
||||
public ReactGetConstants(IMethodSymbol method)
|
||||
{
|
||||
Method = method;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,17 +19,26 @@ namespace Microsoft.ReactNative.Managed.CodeGen.Model
|
|||
|
||||
public ITypeSymbol EffectiveReturnType { get; }
|
||||
|
||||
public int ResolveParameterCount { get; }
|
||||
|
||||
public int RejectParameterCount { get; }
|
||||
|
||||
public IReadOnlyList<IParameterSymbol> EffectiveParameters { get; }
|
||||
|
||||
public ReactMethod(IMethodSymbol method, string name, MethodReturnStyle returnStyle, ITypeSymbol effectiveReturnType, IReadOnlyList<IParameterSymbol> effectiveParameters, bool isSynchronous)
|
||||
public ReactMethod(IMethodSymbol method, string name, MethodReturnStyle returnStyle,
|
||||
ITypeSymbol effectiveReturnType, IReadOnlyList<IParameterSymbol> effectiveParameters,
|
||||
bool isSynchronous, int resolveParameterCount, int rejectParameterCount)
|
||||
{
|
||||
Contract.Requires(!(IsSynchronous && returnStyle == MethodReturnStyle.Task), "Task style methods are required to be asynchronous");
|
||||
Contract.Requires(!(IsSynchronous && returnStyle == MethodReturnStyle.Task),
|
||||
"Task style methods are required to be asynchronous");
|
||||
Method = method;
|
||||
Name = name;
|
||||
ReturnStyle = returnStyle;
|
||||
EffectiveReturnType = effectiveReturnType;
|
||||
EffectiveParameters = effectiveParameters;
|
||||
IsSynchronous = isSynchronous;
|
||||
ResolveParameterCount = resolveParameterCount;
|
||||
RejectParameterCount = rejectParameterCount;
|
||||
}
|
||||
|
||||
public enum MethodReturnStyle
|
||||
|
|
|
@ -20,6 +20,8 @@ namespace Microsoft.ReactNative.Managed.CodeGen.Model
|
|||
|
||||
public ICollection<ReactConstantProvider> ConstantProviders { get; } = new List<ReactConstantProvider>();
|
||||
|
||||
public ICollection<ReactGetConstants> GetConstants { get; } = new List<ReactGetConstants>();
|
||||
|
||||
public ICollection<ReactMethod> Methods { get; } = new List<ReactMethod>();
|
||||
|
||||
public ICollection<ReactFunction> Functions { get; } = new List<ReactFunction>();
|
||||
|
|
|
@ -38,10 +38,11 @@ namespace Microsoft.ReactNative.Managed.CodeGen.Model
|
|||
public INamedTypeSymbol JSValueReader { get; }
|
||||
public INamedTypeSymbol JSValueWriterGenerator { get; }
|
||||
public INamedTypeSymbol JSValueReaderGenerator { get; }
|
||||
public INamedTypeSymbol JSValueWriterCodeGen { get; }
|
||||
public INamedTypeSymbol JSValueReaderCodeGen { get; }
|
||||
public INamedTypeSymbol JSValueWriterOf { get; }
|
||||
public INamedTypeSymbol JSValueReaderOf { get; }
|
||||
public INamedTypeSymbol IReactPromise { get; }
|
||||
public INamedTypeSymbol ReactPromise { get; }
|
||||
public INamedTypeSymbol ReactPromiseOfVoid { get; }
|
||||
public INamedTypeSymbol MethodReturnType { get; }
|
||||
public INamedTypeSymbol MethodResultCallback { get; }
|
||||
public INamedTypeSymbol ReactConstantProvider { get; }
|
||||
|
@ -49,10 +50,12 @@ namespace Microsoft.ReactNative.Managed.CodeGen.Model
|
|||
public INamedTypeSymbol ReactInitializerAttribute { get; }
|
||||
public INamedTypeSymbol ReactConstantAttribute { get; }
|
||||
public INamedTypeSymbol ReactConstantProviderAttribute { get; }
|
||||
public INamedTypeSymbol ReactGetConstantsAttribute { get; }
|
||||
public INamedTypeSymbol ReactMethodAttribute { get; }
|
||||
public INamedTypeSymbol ReactSyncMethodAttribute { get; }
|
||||
public INamedTypeSymbol ReactEventAttribute { get; }
|
||||
public INamedTypeSymbol ReactFunctionAttribute { get; }
|
||||
public INamedTypeSymbol ReactPropertyAttribute { get; }
|
||||
public INamedTypeSymbol ReactTaskExtensions { get; }
|
||||
|
||||
private readonly ICollection<Diagnostic> m_diagnostics = new List<Diagnostic>();
|
||||
|
@ -78,22 +81,25 @@ namespace Microsoft.ReactNative.Managed.CodeGen.Model
|
|||
ReactConstantProvider = FindReactNativeManagedType(compilation, "ReactConstantProvider");
|
||||
IReactPromise = FindReactNativeManagedType(compilation, "IReactPromise`1");
|
||||
ReactPromise = FindReactNativeManagedType(compilation, "ReactPromise`1");
|
||||
ReactPromiseOfVoid = FindReactNativeManagedType(compilation, "ReactPromise");
|
||||
JSValue = FindReactNativeManagedType(compilation, "JSValue");
|
||||
JSValueWriter = FindReactNativeManagedType(compilation, "JSValueWriter");
|
||||
JSValueReader = FindReactNativeManagedType(compilation, "JSValueReader");
|
||||
JSValueWriterGenerator = FindReactNativeManagedType(compilation, "JSValueWriterGenerator");
|
||||
JSValueReaderGenerator = FindReactNativeManagedType(compilation, "JSValueReaderGenerator");
|
||||
JSValueWriterCodeGen = FindReactNativeManagedType(compilation, "JSValueWriterCodeGen`1");
|
||||
JSValueReaderCodeGen = FindReactNativeManagedType(compilation, "JSValueReaderCodeGen`1");
|
||||
JSValueWriterOf = FindReactNativeManagedType(compilation, "JSValueWriterOf`1");
|
||||
JSValueReaderOf = FindReactNativeManagedType(compilation, "JSValueReaderOf`1");
|
||||
|
||||
ReactModuleAttribute = FindReactNativeManagedType(compilation, "ReactModuleAttribute");
|
||||
ReactInitializerAttribute = FindReactNativeManagedType(compilation, "ReactInitializerAttribute");
|
||||
ReactConstantAttribute = FindReactNativeManagedType(compilation, "ReactConstantAttribute");
|
||||
ReactConstantProviderAttribute = FindReactNativeManagedType(compilation, "ReactConstantProviderAttribute");
|
||||
ReactGetConstantsAttribute = FindReactNativeManagedType(compilation, "ReactGetConstantsAttribute");
|
||||
ReactMethodAttribute = FindReactNativeManagedType(compilation, "ReactMethodAttribute");
|
||||
ReactSyncMethodAttribute = FindReactNativeManagedType(compilation, "ReactSyncMethodAttribute");
|
||||
ReactEventAttribute = FindReactNativeManagedType(compilation, "ReactEventAttribute");
|
||||
ReactFunctionAttribute = FindReactNativeManagedType(compilation, "ReactFunctionAttribute");
|
||||
ReactPropertyAttribute = FindReactNativeManagedType(compilation, "ReactPropertyAttribute");
|
||||
ReactTaskExtensions = FindReactNativeManagedType(compilation, "ReactTaskExtensions");
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,9 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
public static readonly SyntaxToken GetNextObjectPropertyMethodName = Identifier("GetNextObjectProperty");
|
||||
public static readonly SyntaxToken ObjectEnumMemberName = Identifier("Object");
|
||||
public static readonly SyntaxToken RegisterCodeGeneratorGenericExtensionMethod = Identifier("RegisterCodeGeneratorGenericExtensionMethod");
|
||||
|
||||
public static readonly SyntaxToken WritePropertiesMethodName = Identifier("WriteProperties");
|
||||
|
||||
public static readonly SyntaxToken ConstantsLocalName = Identifier("constants");
|
||||
public static readonly SyntaxToken ProviderLocalName = Identifier("provider");
|
||||
public static readonly SyntaxToken WriterLocalName = Identifier("writer");
|
||||
public static readonly SyntaxToken ReaderLocalName = Identifier("reader");
|
||||
|
@ -76,7 +78,31 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
|
||||
public static readonly SyntaxToken ContinueWith = Identifier("ContinueWith");
|
||||
public static readonly SyntaxToken TaskLocalName = Identifier("task");
|
||||
}
|
||||
|
||||
|
||||
public static readonly SyntaxToken Arg0LocalName = Identifier("arg0");
|
||||
public static readonly SyntaxToken Arg1LocalName = Identifier("arg1");
|
||||
public static readonly SyntaxToken Arg2LocalName = Identifier("arg2");
|
||||
public static readonly SyntaxToken Arg3LocalName = Identifier("arg3");
|
||||
public static readonly SyntaxToken Arg4LocalName = Identifier("arg4");
|
||||
public static readonly SyntaxToken Arg5LocalName = Identifier("arg5");
|
||||
public static readonly SyntaxToken Arg6LocalName = Identifier("arg6");
|
||||
|
||||
public static readonly SyntaxToken[] ArgLocalNames = new SyntaxToken[] {
|
||||
Arg0LocalName, Arg1LocalName, Arg2LocalName, Arg3LocalName,
|
||||
Arg4LocalName, Arg5LocalName, Arg6LocalName,
|
||||
};
|
||||
|
||||
public static readonly SyntaxToken Value0LocalName = Identifier("value0");
|
||||
public static readonly SyntaxToken Value1LocalName = Identifier("value1");
|
||||
public static readonly SyntaxToken Value2LocalName = Identifier("value2");
|
||||
public static readonly SyntaxToken Value3LocalName = Identifier("value3");
|
||||
public static readonly SyntaxToken Value4LocalName = Identifier("value4");
|
||||
public static readonly SyntaxToken Value5LocalName = Identifier("value5");
|
||||
public static readonly SyntaxToken Value6LocalName = Identifier("value6");
|
||||
|
||||
public static readonly SyntaxToken[] ValueLocalNames = new SyntaxToken[] {
|
||||
Value0LocalName, Value1LocalName, Value2LocalName, Value3LocalName,
|
||||
Value4LocalName, Value5LocalName, Value6LocalName,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
@ -99,6 +100,11 @@ namespace Microsoft.ReactNative.Managed.CodeGen
|
|||
}
|
||||
|
||||
internal static ExpressionSyntax InvocationExpression(ExpressionSyntax method, params ExpressionSyntax[] arguments)
|
||||
{
|
||||
return InvocationExpression(method, arguments.AsEnumerable());
|
||||
}
|
||||
|
||||
internal static ExpressionSyntax InvocationExpression(ExpressionSyntax method, IEnumerable<ExpressionSyntax> arguments)
|
||||
{
|
||||
return InvocationExpression(method, arguments.Select(arg => SyntaxFactory.Argument(arg)));
|
||||
}
|
||||
|
|
Двоичные данные
vnext/Microsoft.ReactNative.Managed.IntegrationTests/Assets/LockScreenLogo.scale-200.png
Normal file
После Ширина: | Высота: | Размер: 1.4 KiB |
Двоичные данные
vnext/Microsoft.ReactNative.Managed.IntegrationTests/Assets/SplashScreen.scale-200.png
Normal file
После Ширина: | Высота: | Размер: 7.5 KiB |
Двоичные данные
vnext/Microsoft.ReactNative.Managed.IntegrationTests/Assets/Square150x150Logo.scale-200.png
Normal file
После Ширина: | Высота: | Размер: 2.9 KiB |
Двоичные данные
vnext/Microsoft.ReactNative.Managed.IntegrationTests/Assets/Square44x44Logo.scale-200.png
Normal file
После Ширина: | Высота: | Размер: 1.6 KiB |
Двоичные данные
vnext/Microsoft.ReactNative.Managed.IntegrationTests/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
Normal file
После Ширина: | Высота: | Размер: 1.2 KiB |
Двоичные данные
vnext/Microsoft.ReactNative.Managed.IntegrationTests/Assets/StoreLogo.png
Normal file
После Ширина: | Высота: | Размер: 1.4 KiB |
Двоичные данные
vnext/Microsoft.ReactNative.Managed.IntegrationTests/Assets/Wide310x150Logo.scale-200.png
Normal file
После Ширина: | Высота: | Размер: 3.1 KiB |
|
@ -0,0 +1,169 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{E2BE6630-21C7-43A4-AC90-8D2844C06617}</ProjectGuid>
|
||||
<OutputType>AppContainerExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.ReactNative.Managed.IntegrationTests</RootNamespace>
|
||||
<AssemblyName>Microsoft.ReactNative.Managed.IntegrationTests</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<UnitTestPlatformVersion Condition="'$(UnitTestPlatformVersion)' == ''">$(VisualStudioVersion)</UnitTestPlatformVersion>
|
||||
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
|
||||
<AppxGeneratePrisForPortableLibrariesEnabled>false</AppxGeneratePrisForPortableLibrariesEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>false</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>false</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>false</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>false</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>false</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>false</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<SDKReference Include="TestPlatform.Universal, Version=$(UnitTestPlatformVersion)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ReactNativeHostTests.cs" />
|
||||
<Compile Include="ReactPackageProvider.cs" />
|
||||
<Compile Include="TestEventService.cs" />
|
||||
<Compile Include="TestNotificationService.cs" />
|
||||
<Compile Include="TestReactNativeHostHolder.cs" />
|
||||
<Compile Include="TurboModuleTests.cs" />
|
||||
<Compile Include="UnitTestApp.xaml.cs">
|
||||
<DependentUpon>UnitTestApp.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="UnitTestApp.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Properties\Default.rd.xml" />
|
||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Content Include="Assets\StoreLogo.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<JsBundleEntry Include="ReactNativeHostTests.js" />
|
||||
<JsBundleEntry Include="TurboModuleTests.js" />
|
||||
</ItemGroup>
|
||||
<ImportGroup Label="ReactNativeWindowsPropertySheets">
|
||||
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CSharpLib.props" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CSharpLib.props')" />
|
||||
</ImportGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||
<Version>6.2.9</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestAdapter">
|
||||
<Version>2.1.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestFramework">
|
||||
<Version>2.1.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk">
|
||||
<Version>16.5.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json">
|
||||
<Version>13.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="$(WinUIPackageName)" Version="$(WinUIPackageVersion)" Condition="'$(UseWinUI3)'=='true'" />
|
||||
</ItemGroup>
|
||||
<ImportGroup Label="ReactNativeWindowsTargets">
|
||||
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CSharpLib.targets" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CSharpLib.targets')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<Import Project="TestBundle.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
IgnorableNamespaces="uap mp">
|
||||
|
||||
<Identity Name="ab8bf7d4-a8b7-4108-9eb4-f621b6f33b3a"
|
||||
Publisher="CN=react-native-windows-testing"
|
||||
Version="1.0.0.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="ab8bf7d4-a8b7-4108-9eb4-f621b6f33b3a" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>Microsoft.ReactNative.Managed.IntegrationTests</DisplayName>
|
||||
<PublisherDisplayName>react-native-windows-testing</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="vstest.executionengine.universal.App"
|
||||
Executable="$targetnametoken$.exe"
|
||||
EntryPoint="Microsoft.ReactNative.Managed.IntegrationTests.App">
|
||||
<uap:VisualElements
|
||||
DisplayName="Microsoft.ReactNative.Managed.IntegrationTests"
|
||||
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||
Square44x44Logo="Assets\Square44x44Logo.png"
|
||||
Description="Microsoft.ReactNative.Managed.IntegrationTests"
|
||||
BackgroundColor="transparent">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClientServer" />
|
||||
<Capability Name="privateNetworkClientServer" />
|
||||
</Capabilities>
|
||||
</Package>
|
|
@ -0,0 +1,18 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("Microsoft.ReactNative.Managed.IntegrationTests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Microsoft.ReactNative.Managed.IntegrationTests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2022")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: AssemblyMetadata("TargetPlatform","UAP")]
|
||||
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: ComVisible(false)]
|
|
@ -0,0 +1,29 @@
|
|||
<!--
|
||||
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
|
||||
developers. However, you can modify these parameters to modify the behavior of the .NET Native
|
||||
optimizer.
|
||||
|
||||
Runtime Directives are documented at https://go.microsoft.com/fwlink/?LinkID=391919
|
||||
|
||||
To fully enable reflection for App1.MyClass and all of its public/private members
|
||||
<Type Name="App1.MyClass" Dynamic="Required All"/>
|
||||
|
||||
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
|
||||
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
|
||||
|
||||
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
|
||||
<Namespace Name="DataClasses.ViewModels" Serialize="All" />
|
||||
-->
|
||||
|
||||
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||
<Application>
|
||||
<!--
|
||||
An Assembly element with Name="*Application*" applies to all assemblies in
|
||||
the application package. The asterisks are not wildcards.
|
||||
-->
|
||||
<Assembly Name="*Application*" Dynamic="Required All" />
|
||||
<!-- Add your application specific runtime directives here. -->
|
||||
|
||||
|
||||
</Application>
|
||||
</Directives>
|
|
@ -0,0 +1,204 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Microsoft.ReactNative.Managed.IntegrationTests
|
||||
{
|
||||
[ReactModule]
|
||||
class TestHostModule
|
||||
{
|
||||
[ReactInitializer]
|
||||
public void Initialize(ReactContext context)
|
||||
{
|
||||
TestEventService.LogEvent("TestHostModule.Initialize", JSValue.Null);
|
||||
}
|
||||
|
||||
[ReactFunction("addValues", ModuleName = "TestHostModuleFunctions")]
|
||||
public Action<int, int> AddValues { get; set; }
|
||||
|
||||
[ReactMethod("startTests")]
|
||||
public void StartTests()
|
||||
{
|
||||
TestEventService.LogEvent("TestHostModule.StartTests", JSValue.Null);
|
||||
|
||||
TestEventService.LogEvent("call addValues", new JSValueArray { 4, 7 });
|
||||
AddValues(4, 7);
|
||||
}
|
||||
|
||||
[ReactMethod("returnResult")]
|
||||
public void ReturnResult(JSValue value)
|
||||
{
|
||||
TestEventService.LogEvent("TestHostModule.ReturnResult", value);
|
||||
}
|
||||
}
|
||||
|
||||
[TestClass]
|
||||
public class ReactNativeHostTests
|
||||
{
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
TestEventService.Initialize();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Activation_Succeeds()
|
||||
{
|
||||
Assert.IsNotNull(new ReactNativeHost());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PackageProviders_AsConstructed_IsEmpty()
|
||||
{
|
||||
var host = new ReactNativeHost();
|
||||
Assert.AreEqual(0, host.PackageProviders.Count);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void PackageProviders_Append_ReflectsAddition()
|
||||
{
|
||||
var host = new ReactNativeHost();
|
||||
IReactPackageProvider packageProvider = new ReactPackageProvider();
|
||||
host.PackageProviders.Add(packageProvider);
|
||||
Assert.AreEqual(1, host.PackageProviders.Count);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InstanceSettings_BundleRootPathAsConstructed_IsEmpty()
|
||||
{
|
||||
var host = new ReactNativeHost();
|
||||
Assert.AreEqual(string.Empty, host.InstanceSettings.BundleRootPath);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InstanceSettings_BundleRootPathAsAssigned_MatchesAssignedValue()
|
||||
{
|
||||
const string path = "a/b/c";
|
||||
var host = new ReactNativeHost();
|
||||
host.InstanceSettings.BundleRootPath = path;
|
||||
Assert.AreEqual(path, host.InstanceSettings.BundleRootPath);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Run_JSDrivenTests()
|
||||
{
|
||||
var hostHolder = new TestReactNativeHostHolder("ReactNativeHostTests", host =>
|
||||
{
|
||||
host.PackageProviders.Add(new ReactPackageProvider());
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
TestEventService.ObserveEvents(new[]
|
||||
{
|
||||
new TestEvent("TestHostModule.Initialize"),
|
||||
new TestEvent("TestHostModule.StartTests"),
|
||||
new TestEvent("call addValues", new JSValueArray{ 4, 7 }),
|
||||
new TestEvent("TestHostModule.ReturnResult", 11)
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
hostHolder.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void HostReloadedAsyncActionCompletedEvent()
|
||||
{
|
||||
var hostHolder = new TestReactNativeHostHolder(
|
||||
"ReactNativeHostTests",
|
||||
host =>
|
||||
{
|
||||
host.ReloadInstance().Completed = (IAsyncAction _, AsyncStatus status) =>
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case AsyncStatus.Completed: TestEventService.LogEvent("InstanceLoaded.Completed"); break;
|
||||
case AsyncStatus.Canceled: TestEventService.LogEvent("InstanceLoaded.Canceled"); break;
|
||||
default: TestEventService.LogEvent("InstanceLoaded.Failed"); break;
|
||||
}
|
||||
};
|
||||
},
|
||||
new TestReactNativeHostHolder.Options(noInstanceLoad: true));
|
||||
|
||||
try
|
||||
{
|
||||
TestEventService.ObserveEvents(new[] { new TestEvent("InstanceLoaded.Completed") });
|
||||
}
|
||||
finally
|
||||
{
|
||||
hostHolder.Dispose();
|
||||
}
|
||||
}
|
||||
[TestMethod]
|
||||
public void LoadInstance_FiresInstanceLoaded_Success()
|
||||
{
|
||||
var hostHolder = new TestReactNativeHostHolder("ReactNativeHostTests", host =>
|
||||
{
|
||||
host.InstanceSettings.InstanceLoaded += (object _, InstanceLoadedEventArgs args) =>
|
||||
TestEventService.LogEvent($"InstanceLoaded.{(args.Failed ? "Failed" : "Success")}");
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
TestEventService.ObserveEvents(new[] { new TestEvent("InstanceLoaded.Success") });
|
||||
}
|
||||
finally
|
||||
{
|
||||
hostHolder.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LoadBundleWithError_FiresInstanceLoaded_Failed()
|
||||
{
|
||||
var hostHolder = new TestReactNativeHostHolder("SyntaxError", host =>
|
||||
{
|
||||
host.InstanceSettings.InstanceLoaded += (object _, InstanceLoadedEventArgs args) =>
|
||||
TestEventService.LogEvent($"InstanceLoaded.{(args.Failed ? "Failed" : "Success")}");
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
TestEventService.ObserveEvents(new[] { new TestEvent("InstanceLoaded.Failed") });
|
||||
}
|
||||
finally
|
||||
{
|
||||
hostHolder.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LoadBundleWithError_ReloadInstance_Fails()
|
||||
{
|
||||
var hostHolder = new TestReactNativeHostHolder(
|
||||
"SyntaxError",
|
||||
host =>
|
||||
{
|
||||
host.ReloadInstance().Completed = (IAsyncAction _, AsyncStatus status) =>
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case AsyncStatus.Completed: TestEventService.LogEvent("InstanceLoaded.Completed"); break;
|
||||
case AsyncStatus.Canceled: TestEventService.LogEvent("InstanceLoaded.Canceled"); break;
|
||||
default: TestEventService.LogEvent("InstanceLoaded.Failed"); break;
|
||||
}
|
||||
};
|
||||
},
|
||||
new TestReactNativeHostHolder.Options(noInstanceLoad: true));
|
||||
|
||||
try
|
||||
{
|
||||
TestEventService.ObserveEvents(new[] { new TestEvent("InstanceLoaded.Canceled") });
|
||||
}
|
||||
finally
|
||||
{
|
||||
hostHolder.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import { TurboModuleRegistry } from 'react-native';
|
||||
|
||||
class TestHostModuleFunctions {
|
||||
addValues(a, b) {
|
||||
TurboModuleRegistry.get('TestHostModule').returnResult(a + b);
|
||||
}
|
||||
}
|
||||
|
||||
// Accessing TestHostModule has a side effect of initializing global.__fbBatchedBridge
|
||||
if (TurboModuleRegistry.get('TestHostModule')) {
|
||||
global.__fbBatchedBridge.registerLazyCallableModule('TestHostModuleFunctions', () => new TestHostModuleFunctions());
|
||||
|
||||
// Start running tests.
|
||||
TurboModuleRegistry.get('TestHostModule').startTests();
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
namespace Microsoft.ReactNative.Managed.IntegrationTests
|
||||
{
|
||||
public partial class ReactPackageProvider : IReactPackageProvider
|
||||
{
|
||||
public void CreatePackage(IReactPackageBuilder packageBuilder)
|
||||
{
|
||||
CreatePackageImplementation(packageBuilder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is implemented by the C# code generator
|
||||
/// </summary>
|
||||
partial void CreatePackageImplementation(IReactPackageBuilder packageBuilder);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\Bundle.props" />
|
||||
<Target
|
||||
Name="MakeTestBundles"
|
||||
Condition="'$(DesignTimeBuild)' != 'true'"
|
||||
BeforeTargets="PrepareForBuild"
|
||||
Inputs="@(JsBundleEntry)"
|
||||
Outputs="@(JsBundleEntry->'$(OutputPath)%(Filename).bundle')">
|
||||
<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
|
||||
<Exec Command="$(BundleCliCommand) --platform windows --entry-file %(JsBundleEntry.FullPath) --bundle-output $(OutputPath)%(JsBundleEntry.Filename).bundle" ConsoleToMSBuild="true" />
|
||||
<ItemGroup>
|
||||
<Content Include="@(JsBundleEntry->'$(OutputPath)%(Filename).bundle')">
|
||||
<Link>JSBundles\%(Filename).bundle</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.ReactNative.Managed.IntegrationTests
|
||||
{
|
||||
internal struct TestEvent
|
||||
{
|
||||
public string EventName;
|
||||
public JSValue Value;
|
||||
|
||||
public TestEvent(string eventName, JSValue value = default)
|
||||
{
|
||||
EventName = eventName;
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Ordered test notifications
|
||||
internal static class TestEventService
|
||||
{
|
||||
private static readonly object s_mutex = new object();
|
||||
private static readonly Queue<TestEvent> s_eventQueue = new Queue<TestEvent>();
|
||||
|
||||
// Sets the service to the initial state.
|
||||
public static void Initialize()
|
||||
{
|
||||
lock (s_mutex)
|
||||
{
|
||||
s_eventQueue.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Logs new event in the queue and notifies queue observers to check it.
|
||||
public static void LogEvent(string eventName, JSValue value = default)
|
||||
{
|
||||
lock (s_mutex)
|
||||
{
|
||||
s_eventQueue.Enqueue(new TestEvent { EventName = eventName, Value = value });
|
||||
Monitor.PulseAll(s_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
// Blocks current thread and observes all incoming events in the queue until we see them all.
|
||||
public static void ObserveEvents(IList<TestEvent> expectedEvents)
|
||||
{
|
||||
lock (s_mutex)
|
||||
{
|
||||
int observeEventIndex = 0;
|
||||
while (observeEventIndex < expectedEvents.Count)
|
||||
{
|
||||
if (s_eventQueue.TryDequeue(out TestEvent loggedEvent))
|
||||
{
|
||||
// Check the event name and value
|
||||
var expectedEvent = expectedEvents[observeEventIndex];
|
||||
Assert.AreEqual(expectedEvent.EventName, loggedEvent.EventName);
|
||||
|
||||
if (expectedEvent.Value.TryGetDouble(out double d1) && loggedEvent.Value.TryGetDouble(out double d2))
|
||||
{
|
||||
// Comparison of doubles has special logic because NaN != NaN.
|
||||
Assert.AreEqual(double.IsNaN(d1), double.IsNaN(d2));
|
||||
if (!double.IsNaN(d1) && !double.IsNaN(d2))
|
||||
{
|
||||
Assert.AreEqual(d1, d2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.AreEqual(expectedEvent.Value, loggedEvent.Value);
|
||||
}
|
||||
|
||||
++observeEventIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
Monitor.Wait(s_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.ReactNative.Managed.IntegrationTests
|
||||
{
|
||||
// Unordered test events
|
||||
internal static class TestNotificationService
|
||||
{
|
||||
private static readonly object s_mutex = new object();
|
||||
private static readonly HashSet<string> s_eventSet = new HashSet<string>();
|
||||
|
||||
// Sets the service to the initial state.
|
||||
public static void Initialize()
|
||||
{
|
||||
lock (s_mutex)
|
||||
{
|
||||
s_eventSet.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Set a new notification.
|
||||
public static void Set(string eventName)
|
||||
{
|
||||
lock (s_mutex)
|
||||
{
|
||||
s_eventSet.Add(eventName);
|
||||
Monitor.PulseAll(s_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
// Blocks current thread and waits until expected event appears.
|
||||
public static void Wait(string eventName)
|
||||
{
|
||||
lock (s_mutex)
|
||||
{
|
||||
while (!s_eventSet.Contains(eventName))
|
||||
{
|
||||
Monitor.Wait(s_mutex);
|
||||
}
|
||||
s_eventSet.Remove(eventName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.System;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Xaml;
|
||||
|
||||
namespace Microsoft.ReactNative.Managed.IntegrationTests
|
||||
{
|
||||
internal class TestReactNativeHostHolder : IDisposable
|
||||
{
|
||||
public ReactNativeHost Host { get; }
|
||||
//private DispatcherQueueController m_queueController = null;
|
||||
private bool m_isDisposed;
|
||||
|
||||
public struct Options
|
||||
{
|
||||
public bool NoInstanceLoad { get; }
|
||||
|
||||
public Options(bool noInstanceLoad) { NoInstanceLoad = noInstanceLoad; }
|
||||
}
|
||||
|
||||
public TestReactNativeHostHolder(string jsBundle, Action<ReactNativeHost> hostInitializer, Options options = default)
|
||||
{
|
||||
Host = new ReactNativeHost();
|
||||
_ = CoreApplication.MainView.CoreWindow.DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
// bundle is assumed to be co-located with the test binary
|
||||
var testBinaryPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
|
||||
Host.InstanceSettings.BundleRootPath = Path.GetFullPath(testBinaryPath + "\\..\\JSBundles");
|
||||
Host.InstanceSettings.JavaScriptBundleFile = jsBundle;
|
||||
Host.InstanceSettings.UseDeveloperSupport = false;
|
||||
Host.InstanceSettings.UseWebDebugger = false;
|
||||
Host.InstanceSettings.UseFastRefresh = false;
|
||||
Host.InstanceSettings.UseDeveloperSupport = false;
|
||||
|
||||
hostInitializer(Host);
|
||||
|
||||
if (!options.NoInstanceLoad)
|
||||
{
|
||||
_ = Host.LoadInstance();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!m_isDisposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
Host.UnloadInstance().AsTask().Wait();
|
||||
// m_queueController.ShutdownQueueAsync().AsTask().Wait();
|
||||
}
|
||||
|
||||
m_isDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,555 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// TODO: Add tests for methods that throw exceptions
|
||||
// TODO: Remove reflection-based code gen for reader/writer
|
||||
|
||||
namespace Microsoft.ReactNative.Managed.IntegrationTests
|
||||
{
|
||||
public struct MyTurboModuleConstants
|
||||
{
|
||||
[ReactProperty("constantString3")]
|
||||
public string ConstantString3;
|
||||
// It must be passed as ConstantInt3
|
||||
public int ConstantInt3;
|
||||
}
|
||||
|
||||
public struct Point
|
||||
{
|
||||
[ReactProperty("x")]
|
||||
public int X;
|
||||
[ReactProperty("y")]
|
||||
public int Y;
|
||||
}
|
||||
|
||||
[ReactModule]
|
||||
public class MyTurboModule
|
||||
{
|
||||
private ReactContext m_reactContext;
|
||||
|
||||
public static ReactPropertyId<string> TestName = new ReactPropertyId<string>(nameof(MyTurboModule), "TestName");
|
||||
public static ReactPropertyId<IReactDispatcher> TestDispatcher = new ReactPropertyId<IReactDispatcher>(nameof(MyTurboModule), "TestDispatcher");
|
||||
|
||||
[ReactInitializer]
|
||||
public void Initialize(ReactContext reactContext)
|
||||
{
|
||||
m_reactContext = reactContext;
|
||||
}
|
||||
|
||||
[ReactSyncMethod("getTestName")]
|
||||
public string GetTestName()
|
||||
{
|
||||
return m_reactContext.Properties.Get(TestName);
|
||||
}
|
||||
|
||||
[ReactSyncMethod("logAction")]
|
||||
public int LogAction(string actionName, JSValue value)
|
||||
{
|
||||
TestEventService.LogEvent(actionName, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
[ReactConstant("constantString")]
|
||||
public string ConstantString => "myConstantString";
|
||||
|
||||
[ReactConstant("constantInt")]
|
||||
public int ConstantInt => 3;
|
||||
|
||||
[ReactConstantProvider]
|
||||
public void GetConstants(ReactConstantProvider provider)
|
||||
{
|
||||
provider.Add("constantString2", "Hello");
|
||||
provider.Add("constantInt2", 10);
|
||||
}
|
||||
|
||||
[ReactGetConstants]
|
||||
public MyTurboModuleConstants GetConstants2()
|
||||
{
|
||||
return new MyTurboModuleConstants
|
||||
{
|
||||
ConstantString3 = "strong-typed-constants!",
|
||||
ConstantInt3 = 20
|
||||
};
|
||||
}
|
||||
|
||||
[ReactMethod("add")]
|
||||
public int Add(int x, int y)
|
||||
{
|
||||
return x + y;
|
||||
}
|
||||
|
||||
[ReactMethod("negate")]
|
||||
public int Negate(int x)
|
||||
{
|
||||
return -x;
|
||||
}
|
||||
|
||||
[ReactMethod("sayHello")]
|
||||
public string SayHello()
|
||||
{
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
[ReactMethod("sayHello0")]
|
||||
public void SayHello0()
|
||||
{
|
||||
TestEventService.LogEvent("sayHello0", "Hello");
|
||||
}
|
||||
|
||||
[ReactMethod("printPoint")]
|
||||
public void PrintPoint(Point pt)
|
||||
{
|
||||
TestEventService.LogEvent("printPoint", $"Point: ({pt.X}, {pt.Y})");
|
||||
}
|
||||
|
||||
[ReactMethod("printLine")]
|
||||
public void PrintLine(Point start, Point end)
|
||||
{
|
||||
TestEventService.LogEvent("printLine", $"Line: ({start.X}, {start.Y})-({end.X}, {end.Y})");
|
||||
}
|
||||
|
||||
[ReactMethod("addCallback")]
|
||||
public void AddCallback(int x, int y, Action<int> resolve)
|
||||
{
|
||||
resolve(x + y);
|
||||
}
|
||||
|
||||
[ReactMethod("negateCallback")]
|
||||
public void NegateCallback(int x, Action<int> resolve)
|
||||
{
|
||||
resolve(-x);
|
||||
}
|
||||
|
||||
[ReactMethod("negateAsyncCallback")]
|
||||
public async void NegateAsyncCallback(int x, Action<int> resolve)
|
||||
{
|
||||
await Task.Run(() => resolve(-x));
|
||||
}
|
||||
|
||||
[ReactMethod("negateTaskRunCallback")]
|
||||
public void NegateTaskRunCallback(int x, Action<int> resolve)
|
||||
{
|
||||
Task.Run(() => resolve(-x));
|
||||
}
|
||||
|
||||
[ReactMethod("sayHelloCallback")]
|
||||
public void SayHelloCallback(Action<string> resolve)
|
||||
{
|
||||
resolve("Hello_2");
|
||||
}
|
||||
|
||||
[ReactMethod("callbackZeroArgs")]
|
||||
public void CallbackZeroArgs(Action resolve)
|
||||
{
|
||||
resolve();
|
||||
}
|
||||
|
||||
[ReactMethod("callbackTwoArgs")]
|
||||
public void CallbackTwoArgs(Action<int, int> resolve)
|
||||
{
|
||||
resolve(1, 2);
|
||||
}
|
||||
|
||||
[ReactMethod("callbackThreeArgs")]
|
||||
public void CallbackThreeArgs(Action<int, int, string> resolve)
|
||||
{
|
||||
resolve(1, 2, "Hello");
|
||||
}
|
||||
|
||||
[ReactMethod("divideCallbacks")]
|
||||
public void DivideCallbacks(
|
||||
int x,
|
||||
int y,
|
||||
Action<int> resolve,
|
||||
Action<string> reject)
|
||||
{
|
||||
if (y != 0)
|
||||
{
|
||||
resolve(x / y);
|
||||
}
|
||||
else
|
||||
{
|
||||
reject("Division by 0");
|
||||
}
|
||||
}
|
||||
|
||||
[ReactMethod("negateCallbacks")]
|
||||
public void NegateCallbacks(
|
||||
int x,
|
||||
Action<int> resolve,
|
||||
Action<string> reject)
|
||||
{
|
||||
if (x >= 0)
|
||||
{
|
||||
resolve(-x);
|
||||
}
|
||||
else
|
||||
{
|
||||
reject("Already negative");
|
||||
}
|
||||
}
|
||||
|
||||
[ReactMethod("negateAsyncCallbacks")]
|
||||
public async void NegateAsyncCallbacks(
|
||||
int x,
|
||||
Action<int> resolve,
|
||||
Action<string> reject)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (x >= 0)
|
||||
{
|
||||
resolve(-x);
|
||||
}
|
||||
else
|
||||
{
|
||||
reject("Already negative");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[ReactMethod("negateTaskRunCallbacks")]
|
||||
public void NegateTaskRunCallbacks(
|
||||
int x,
|
||||
Action<int> resolve,
|
||||
Action<string> reject)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
if (x >= 0)
|
||||
{
|
||||
resolve(-x);
|
||||
}
|
||||
else
|
||||
{
|
||||
reject("Already negative");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[ReactMethod("resolveSayHelloCallbacks")]
|
||||
public void ResolveSayHelloCallbacks(
|
||||
Action<string> resolve,
|
||||
Action<string> _)
|
||||
{
|
||||
resolve("Hello_3");
|
||||
}
|
||||
|
||||
[ReactMethod("rejectSayHelloCallbacks")]
|
||||
public void RejectSayHelloCallbacks(
|
||||
Action<string> _,
|
||||
Action<string> reject)
|
||||
{
|
||||
reject("Goodbye");
|
||||
}
|
||||
|
||||
[ReactMethod("twoCallbacksZeroArgs")]
|
||||
public void TwoCallbacksZeroArgs(
|
||||
bool useFirst,
|
||||
Action callback1,
|
||||
Action callback2)
|
||||
{
|
||||
if (useFirst)
|
||||
{
|
||||
callback1();
|
||||
}
|
||||
else
|
||||
{
|
||||
callback2();
|
||||
}
|
||||
}
|
||||
|
||||
[ReactMethod("twoCallbacksTwoArgs")]
|
||||
public void TwoCallbacksTwoArgs(
|
||||
bool useFirst,
|
||||
Action<int, int> callback1,
|
||||
Action<int, int> callback2)
|
||||
{
|
||||
if (useFirst)
|
||||
{
|
||||
callback1(1, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback2(3, 4);
|
||||
}
|
||||
}
|
||||
|
||||
[ReactMethod("twoCallbacksThreeArgs")]
|
||||
public void TwoCallbacksThreeArgs(
|
||||
bool useFirst,
|
||||
Action<int, int, string> callback1,
|
||||
Action<int, int, string> callback2)
|
||||
{
|
||||
if (useFirst)
|
||||
{
|
||||
callback1(1, 2, "Hello");
|
||||
}
|
||||
else
|
||||
{
|
||||
callback2(3, 4, "World");
|
||||
}
|
||||
}
|
||||
|
||||
[ReactMethod("dividePromise")]
|
||||
public void DividePromise(int x, int y, ReactPromise<int> result)
|
||||
{
|
||||
if (y != 0)
|
||||
{
|
||||
result.Resolve(x / y);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Reject("Division by 0");
|
||||
}
|
||||
}
|
||||
|
||||
[ReactMethod("negatePromise")]
|
||||
public void NegatePromise(int x, ReactPromise<int> result)
|
||||
{
|
||||
if (x >= 0)
|
||||
{
|
||||
result.Resolve(-x);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Reject("Already negative");
|
||||
}
|
||||
}
|
||||
|
||||
[ReactMethod("negateAsyncPromise")]
|
||||
public async void NegateAsyncPromise(int x, ReactPromise<int> result)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (x >= 0)
|
||||
{
|
||||
result.Resolve(-x);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Reject("Already negative");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[ReactMethod("negateTaskRunPromise")]
|
||||
public void NegateTaskRunPromise(int x, ReactPromise<int> result)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
if (x >= 0)
|
||||
{
|
||||
result.Resolve(-x);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Reject("Already negative");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[ReactMethod("voidPromise")]
|
||||
public void VoidPromise(int x, ReactPromise result)
|
||||
{
|
||||
if (x % 2 == 0)
|
||||
{
|
||||
result.Resolve();
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Reject("Odd unexpected");
|
||||
}
|
||||
}
|
||||
|
||||
[ReactMethod("resolveSayHelloPromise")]
|
||||
public void ResolveSayHelloPromise(ReactPromise<string> result)
|
||||
{
|
||||
result.Resolve("Hello_4");
|
||||
}
|
||||
|
||||
[ReactMethod("rejectSayHelloPromise")]
|
||||
public void RejectSayHelloPromise(ReactPromise<string> result)
|
||||
{
|
||||
result.Reject("Promise rejected");
|
||||
}
|
||||
|
||||
[ReactMethod("divideTask")]
|
||||
public Task<int> DivideTask(int x, int y)
|
||||
{
|
||||
if (y != 0)
|
||||
{
|
||||
return Task.FromResult(x / y);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Task.FromException<int>(new InvalidOperationException("Division by 0"));
|
||||
}
|
||||
}
|
||||
|
||||
[ReactMethod("divideAsyncTask")]
|
||||
public async Task<int> DivideAsyncTask(int x, int y)
|
||||
{
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
if (y != 0)
|
||||
{
|
||||
return x / y;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Async Division by 0");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[ReactMethod("voidTask")]
|
||||
public Task VoidTask(int x)
|
||||
{
|
||||
if (x % 2 == 0)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Task.FromException(new InvalidOperationException("Odd unexpected"));
|
||||
}
|
||||
}
|
||||
|
||||
[ReactMethod("voidAsyncTask")]
|
||||
public async Task VoidAsyncTask(int x)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (x % 2 != 0)
|
||||
{
|
||||
throw new InvalidOperationException("Async Odd unexpected");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[ReactSyncMethod("addSync")]
|
||||
public int AddSync(int x, int y)
|
||||
{
|
||||
return x + y;
|
||||
}
|
||||
|
||||
[ReactSyncMethod("negateSync")]
|
||||
public int NegateSync(int x)
|
||||
{
|
||||
return -x;
|
||||
}
|
||||
|
||||
[ReactSyncMethod("sayHelloSync")]
|
||||
public string SayHelloSync()
|
||||
{
|
||||
return "Hello";
|
||||
}
|
||||
}
|
||||
|
||||
[TestClass]
|
||||
public class TurboModuleTests
|
||||
{
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
TestEventService.Initialize();
|
||||
TestNotificationService.Initialize();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ExecuteSampleTurboModule()
|
||||
{
|
||||
var hostHolder = new TestReactNativeHostHolder("TurboModuleTests", host =>
|
||||
{
|
||||
host.PackageProviders.Add(new ReactPackageProvider());
|
||||
var properties = new ReactPropertyBag(host.InstanceSettings.Properties);
|
||||
properties.Set(MyTurboModule.TestName, "ExecuteSampleTurboModule");
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
TestEventService.ObserveEvents(new[]
|
||||
{
|
||||
new TestEvent("constantString", "myConstantString"),
|
||||
new TestEvent("constantInt", 3),
|
||||
new TestEvent("constantString2", "Hello"),
|
||||
new TestEvent("constantInt2", 10),
|
||||
new TestEvent("constantString3", "strong-typed-constants!"),
|
||||
new TestEvent("constantInt3", 20),
|
||||
|
||||
new TestEvent("add", 10),
|
||||
new TestEvent("negate", -10),
|
||||
new TestEvent("sayHello", "Hello"),
|
||||
|
||||
new TestEvent("sayHello0", "Hello"),
|
||||
new TestEvent("printPoint", "Point: (1, 2)"),
|
||||
new TestEvent("printLine", "Line: (1, 2)-(3, 4)"),
|
||||
|
||||
new TestEvent("addCallback", 15),
|
||||
new TestEvent("negateCallback", -15),
|
||||
new TestEvent("negateAsyncCallback", -16),
|
||||
new TestEvent("negateTaskRunCallback", -17),
|
||||
new TestEvent("sayHelloCallback", "Hello_2"),
|
||||
|
||||
new TestEvent("callbackZeroArgs"),
|
||||
new TestEvent("callbackTwoArgs", new JSValueObject{ { "x", 1}, { "y", 2} }),
|
||||
new TestEvent("callbackThreeArgs", new JSValueObject{ { "x", 1 }, { "y", 2 }, { "msg", "Hello" } }),
|
||||
|
||||
new TestEvent("divideCallbacks", 2),
|
||||
new TestEvent("divideCallbacks.error", "Division by 0"),
|
||||
new TestEvent("negateCallbacks", -10),
|
||||
new TestEvent("negateCallbacks.error", "Already negative"),
|
||||
new TestEvent("negateAsyncCallbacks", -10),
|
||||
new TestEvent("negateAsyncCallbacks.error", "Already negative"),
|
||||
new TestEvent("negateTaskRunCallbacks", -10),
|
||||
new TestEvent("negateTaskRunCallbacks.error", "Already negative"),
|
||||
new TestEvent("resolveSayHelloCallbacks", "Hello_3"),
|
||||
new TestEvent("rejectSayHelloCallbacks.error", "Goodbye"),
|
||||
|
||||
new TestEvent("twoCallbacksZeroArgs1", "success"),
|
||||
new TestEvent("twoCallbacksZeroArgs2", "failure"),
|
||||
new TestEvent("twoCallbacksTwoArgs1", new JSValueObject{ { "x", 1 }, { "y", 2 } }),
|
||||
new TestEvent("twoCallbacksTwoArgs2", new JSValueObject{ { "x", 3 }, { "y", 4 } }),
|
||||
new TestEvent("twoCallbacksThreeArgs1", new JSValueObject{ { "x", 1 }, { "y", 2 }, { "msg", "Hello" } }),
|
||||
new TestEvent("twoCallbacksThreeArgs2", new JSValueObject{ { "x", 3 }, { "y", 4 }, { "msg", "World" } }),
|
||||
|
||||
new TestEvent("dividePromise", 5),
|
||||
new TestEvent("dividePromise.error", "Division by 0"),
|
||||
new TestEvent("negatePromise", -10),
|
||||
new TestEvent("negatePromise.error", "Already negative"),
|
||||
new TestEvent("negateAsyncPromise", -10),
|
||||
new TestEvent("negateAsyncPromise.error", "Already negative"),
|
||||
new TestEvent("negateTaskRunPromise", -10),
|
||||
new TestEvent("negateTaskRunPromise.error", "Already negative"),
|
||||
new TestEvent("voidPromise", "success"),
|
||||
new TestEvent("voidPromise.error", "Odd unexpected"),
|
||||
new TestEvent("resolveSayHelloPromise", "Hello_4"),
|
||||
new TestEvent("rejectSayHelloPromise", "Promise rejected"),
|
||||
|
||||
new TestEvent("divideTask", 5),
|
||||
new TestEvent("divideTask.error", "Division by 0"),
|
||||
new TestEvent("divideAsyncTask", 2),
|
||||
new TestEvent("divideAsyncTask.error", "Async Division by 0"),
|
||||
new TestEvent("voidTask", "success"),
|
||||
new TestEvent("voidTask.error", "Odd unexpected"),
|
||||
new TestEvent("voidAsyncTask", "success"),
|
||||
new TestEvent("voidAsyncTask.error", "Async Odd unexpected"),
|
||||
|
||||
new TestEvent("addSync", 42),
|
||||
new TestEvent("negateSync", -12),
|
||||
new TestEvent("sayHelloSync", "Hello"),
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
hostHolder.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
import { TurboModuleRegistry } from 'react-native';
|
||||
const myTurboModule = TurboModuleRegistry.getEnforcing('MyTurboModule');
|
||||
|
||||
// Convert function with one callback to Promise
|
||||
const promisify1 = fn =>
|
||||
(...args) => new Promise(
|
||||
res => fn(...args, result => res(result)));
|
||||
|
||||
// Convert function with two callbacks to Promise
|
||||
const promisify2 = fn =>
|
||||
(...args) => new Promise(
|
||||
res => fn(...args, result => res(result), result => res(result)));
|
||||
|
||||
(async function runTests() {
|
||||
const testName = myTurboModule.getTestName();
|
||||
try {
|
||||
if (testName === "ExecuteSampleTurboModule") {
|
||||
const c = myTurboModule.getConstants();
|
||||
myTurboModule.logAction("constantString", c.constantString);
|
||||
myTurboModule.logAction("constantInt", c.constantInt);
|
||||
myTurboModule.logAction("constantString2", c.constantString2);
|
||||
myTurboModule.logAction("constantInt2", c.constantInt2);
|
||||
myTurboModule.logAction("constantString3", c.constantString3);
|
||||
myTurboModule.logAction("constantInt3", c.ConstantInt3);
|
||||
|
||||
let result;
|
||||
result = await promisify1(myTurboModule.add)(2, 8);
|
||||
myTurboModule.logAction("add", result);
|
||||
result = await promisify1(myTurboModule.negate)(10);
|
||||
myTurboModule.logAction("negate", result);
|
||||
result = await promisify1(myTurboModule.sayHello)();
|
||||
myTurboModule.logAction("sayHello", result);
|
||||
|
||||
myTurboModule.sayHello0();
|
||||
myTurboModule.printPoint({ x: 1, y: 2 });
|
||||
myTurboModule.printLine({ x: 1, y: 2 }, { x: 3, y: 4 });
|
||||
|
||||
result = await promisify1(myTurboModule.addCallback)(7, 8);
|
||||
myTurboModule.logAction("addCallback", result);
|
||||
result = await promisify1(myTurboModule.negateCallback)(15);
|
||||
myTurboModule.logAction("negateCallback", result);
|
||||
result = await promisify1(myTurboModule.negateAsyncCallback)(16);
|
||||
myTurboModule.logAction("negateAsyncCallback", result);
|
||||
result = await promisify1(myTurboModule.negateTaskRunCallback)(17);
|
||||
myTurboModule.logAction("negateTaskRunCallback", result);
|
||||
result = await promisify1(myTurboModule.sayHelloCallback)();
|
||||
myTurboModule.logAction("sayHelloCallback", result);
|
||||
|
||||
myTurboModule.callbackZeroArgs(() => myTurboModule.logAction("callbackZeroArgs", null));
|
||||
myTurboModule.callbackTwoArgs((x, y) => myTurboModule.logAction("callbackTwoArgs", { x, y }));
|
||||
myTurboModule.callbackThreeArgs((x, y, msg) => myTurboModule.logAction("callbackThreeArgs", { x, y, msg }));
|
||||
|
||||
result = await promisify2(myTurboModule.divideCallbacks)(10, 5);
|
||||
myTurboModule.logAction("divideCallbacks", result);
|
||||
result = await promisify2(myTurboModule.divideCallbacks)(10, 0);
|
||||
myTurboModule.logAction("divideCallbacks.error", result);
|
||||
result = await promisify2(myTurboModule.negateCallbacks)(10);
|
||||
myTurboModule.logAction("negateCallbacks", result);
|
||||
result = await promisify2(myTurboModule.negateCallbacks)(-10);
|
||||
myTurboModule.logAction("negateCallbacks.error", result);
|
||||
result = await promisify2(myTurboModule.negateAsyncCallbacks)(10);
|
||||
myTurboModule.logAction("negateAsyncCallbacks", result);
|
||||
result = await promisify2(myTurboModule.negateAsyncCallbacks)(-10);
|
||||
myTurboModule.logAction("negateAsyncCallbacks.error", result);
|
||||
result = await promisify2(myTurboModule.negateTaskRunCallbacks)(10);
|
||||
myTurboModule.logAction("negateTaskRunCallbacks", result);
|
||||
result = await promisify2(myTurboModule.negateTaskRunCallbacks)(-10);
|
||||
myTurboModule.logAction("negateTaskRunCallbacks.error", result);
|
||||
result = await promisify2(myTurboModule.resolveSayHelloCallbacks)();
|
||||
myTurboModule.logAction("resolveSayHelloCallbacks", result);
|
||||
result = await promisify2(myTurboModule.rejectSayHelloCallbacks)();
|
||||
myTurboModule.logAction("rejectSayHelloCallbacks.error", result);
|
||||
|
||||
const twoCallbacksZeroArgs = useFirst => myTurboModule.twoCallbacksZeroArgs(useFirst,
|
||||
() => myTurboModule.logAction("twoCallbacksZeroArgs1", "success"),
|
||||
() => myTurboModule.logAction("twoCallbacksZeroArgs2", "failure"));
|
||||
twoCallbacksZeroArgs(true);
|
||||
twoCallbacksZeroArgs(false);
|
||||
const twoCallbacksTwoArgs = useFirst => myTurboModule.twoCallbacksTwoArgs(useFirst,
|
||||
(x, y) => myTurboModule.logAction("twoCallbacksTwoArgs1", { x, y }),
|
||||
(x, y) => myTurboModule.logAction("twoCallbacksTwoArgs2", { x, y }));
|
||||
twoCallbacksTwoArgs(true);
|
||||
twoCallbacksTwoArgs(false);
|
||||
const twoCallbacksThreeArgs = useFirst => myTurboModule.twoCallbacksThreeArgs(useFirst,
|
||||
(x, y, msg) => myTurboModule.logAction("twoCallbacksThreeArgs1", { x, y, msg }),
|
||||
(x, y, msg) => myTurboModule.logAction("twoCallbacksThreeArgs2", { x, y, msg }));
|
||||
twoCallbacksThreeArgs(true);
|
||||
twoCallbacksThreeArgs(false);
|
||||
|
||||
await myTurboModule.dividePromise(10, 2)
|
||||
.then(r => myTurboModule.logAction("dividePromise", r));
|
||||
await myTurboModule.dividePromise(10, 0)
|
||||
.catch(e => myTurboModule.logAction("dividePromise.error", e.message));
|
||||
await myTurboModule.negatePromise(10)
|
||||
.then(r => myTurboModule.logAction("negatePromise", r));
|
||||
await myTurboModule.negatePromise(-10)
|
||||
.catch(e => myTurboModule.logAction("negatePromise.error", e.message));
|
||||
await myTurboModule.negateAsyncPromise(10)
|
||||
.then(r => myTurboModule.logAction("negateAsyncPromise", r));
|
||||
await myTurboModule.negateAsyncPromise(-10)
|
||||
.catch(e => myTurboModule.logAction("negateAsyncPromise.error", e.message));
|
||||
await myTurboModule.negateTaskRunPromise(10)
|
||||
.then(r => myTurboModule.logAction("negateTaskRunPromise", r));
|
||||
await myTurboModule.negateTaskRunPromise(-10)
|
||||
.catch(e => myTurboModule.logAction("negateTaskRunPromise.error", e.message));
|
||||
await myTurboModule.voidPromise(2)
|
||||
.then(() => myTurboModule.logAction("voidPromise", "success"));
|
||||
await myTurboModule.voidPromise(1)
|
||||
.catch(e => myTurboModule.logAction("voidPromise.error", e.message));
|
||||
await myTurboModule.resolveSayHelloPromise()
|
||||
.then(r => myTurboModule.logAction("resolveSayHelloPromise", r));
|
||||
await myTurboModule.rejectSayHelloPromise()
|
||||
.catch(e => myTurboModule.logAction("rejectSayHelloPromise", e.message));
|
||||
|
||||
await myTurboModule.divideTask(10, 2)
|
||||
.then(r => myTurboModule.logAction("divideTask", r));
|
||||
await myTurboModule.divideTask(10, 0)
|
||||
.catch(e => myTurboModule.logAction("divideTask.error", e.message));
|
||||
await myTurboModule.divideAsyncTask(10, 5)
|
||||
.then(r => myTurboModule.logAction("divideAsyncTask", r));
|
||||
await myTurboModule.divideAsyncTask(10, 0)
|
||||
.catch(e => myTurboModule.logAction("divideAsyncTask.error", e.message));
|
||||
await myTurboModule.voidTask(2)
|
||||
.then(() => myTurboModule.logAction("voidTask", "success"));
|
||||
await myTurboModule.voidTask(1)
|
||||
.catch(e => myTurboModule.logAction("voidTask.error", e.message));
|
||||
await myTurboModule.voidAsyncTask(2)
|
||||
.then(() => myTurboModule.logAction("voidAsyncTask", "success"));
|
||||
await myTurboModule.voidAsyncTask(1)
|
||||
.catch(e => myTurboModule.logAction("voidAsyncTask.error", e.message));
|
||||
|
||||
myTurboModule.logAction("addSync", myTurboModule.addSync(40, 2));
|
||||
myTurboModule.logAction("negateSync", myTurboModule.negateSync(12));
|
||||
myTurboModule.logAction("sayHelloSync", myTurboModule.sayHelloSync());
|
||||
}
|
||||
} catch (err) {
|
||||
myTurboModule.logAction("Error", err.message);
|
||||
}
|
||||
})();
|
|
@ -0,0 +1,7 @@
|
|||
<Application
|
||||
x:Class="Microsoft.ReactNative.Managed.IntegrationTests.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Microsoft.ReactNative.Managed.IntegrationTests">
|
||||
|
||||
</Application>
|
|
@ -0,0 +1,102 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace Microsoft.ReactNative.Managed.IntegrationTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides application-specific behavior to supplement the default Application class.
|
||||
/// </summary>
|
||||
sealed partial class App : Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Suspending += OnSuspending;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the application is launched normally by the end user. Other entry points
|
||||
/// will be used such as when the application is launched to open a specific file.
|
||||
/// </summary>
|
||||
/// <param name="e">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||
{
|
||||
|
||||
#if DEBUG
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
this.DebugSettings.EnableFrameRateCounter = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
Frame rootFrame = Window.Current.Content as Frame;
|
||||
|
||||
// Do not repeat app initialization when the Window already has content,
|
||||
// just ensure that the window is active
|
||||
if (rootFrame == null)
|
||||
{
|
||||
// Create a Frame to act as the navigation context and navigate to the first page
|
||||
rootFrame = new Frame();
|
||||
|
||||
rootFrame.NavigationFailed += OnNavigationFailed;
|
||||
|
||||
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
|
||||
{
|
||||
//TODO: Load state from previously suspended application
|
||||
}
|
||||
|
||||
// Place the frame in the current Window
|
||||
Window.Current.Content = rootFrame;
|
||||
}
|
||||
|
||||
Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI();
|
||||
|
||||
// Ensure the current window is active
|
||||
Window.Current.Activate();
|
||||
|
||||
Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.Run(e.Arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when Navigation to a certain page fails
|
||||
/// </summary>
|
||||
/// <param name="sender">The Frame which failed navigation</param>
|
||||
/// <param name="e">Details about the navigation failure</param>
|
||||
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
|
||||
{
|
||||
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when application execution is being suspended. Application state is saved
|
||||
/// without knowing whether the application will be terminated or resumed with the contents
|
||||
/// of memory still intact.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the suspend request.</param>
|
||||
/// <param name="e">Details about the suspend request.</param>
|
||||
private void OnSuspending(object sender, SuspendingEventArgs e)
|
||||
{
|
||||
var deferral = e.SuspendingOperation.GetDeferral();
|
||||
//TODO: Save application state and stop any background activity
|
||||
deferral.Complete();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,24 +30,4 @@ namespace Microsoft.ReactNative.Managed
|
|||
// Report an Error.
|
||||
void Reject(ReactError error);
|
||||
}
|
||||
|
||||
public class ReactError
|
||||
{
|
||||
public string Code = null;
|
||||
public string Message = null;
|
||||
public Exception Exception = null;
|
||||
public IReadOnlyDictionary<string, JSValue> UserInfo = null;
|
||||
}
|
||||
|
||||
internal class ReactErrorConstants
|
||||
{
|
||||
internal const string DefaultCode = "EUNSPECIFIED";
|
||||
internal const string DefaultMessage = "Error not specified.";
|
||||
|
||||
// Keys for m_reject's Error object
|
||||
internal const string Code = "code";
|
||||
internal const string Message = "message";
|
||||
internal const string UserInfo = "userInfo";
|
||||
internal const string NativeStack = "nativeStackWindows";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -254,7 +254,7 @@ namespace Microsoft.ReactNative.Managed
|
|||
// It does not implement GetHashCode() and must not be used as a key in a dictionary.
|
||||
public struct JSValue : IEquatable<JSValue>
|
||||
{
|
||||
public static readonly JSValue Null = new JSValue();
|
||||
public static readonly JSValue Null = default;
|
||||
public static readonly JSValue EmptyObject = new JSValueObject();
|
||||
public static readonly JSValue EmptyArray = new JSValueArray();
|
||||
public static readonly JSValue EmptyString = "";
|
||||
|
|
|
@ -539,13 +539,14 @@ namespace Microsoft.ReactNative.Managed
|
|||
}
|
||||
}
|
||||
|
||||
static class JSValueWriterOf<T>
|
||||
public static class JSValueWriterOf<T>
|
||||
{
|
||||
public static WriteValueDelegate<T> WriteValue = JSValueWriter.GetWriteValueDelegate<T>();
|
||||
}
|
||||
|
||||
public static class JSValueWriterCodeGen<T>
|
||||
{
|
||||
public static WriteValueDelegate<T> WriteValue { get; set; }
|
||||
private static WriteValueDelegate<T> s_writeValue = null;
|
||||
|
||||
public static WriteValueDelegate<T> WriteValue
|
||||
{
|
||||
get { return s_writeValue ?? (s_writeValue = JSValueWriter.GetWriteValueDelegate<T>()); }
|
||||
set { s_writeValue = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,6 +99,19 @@
|
|||
<Compile Include="ReactConstantProviderInfo.cs" />
|
||||
<Compile Include="ReactContext.cs" />
|
||||
<Compile Include="ReactContextGenerator.cs" />
|
||||
<Compile Include="ReactError.cs" />
|
||||
<Compile Include="ReactNotificationArgsOf.cs" />
|
||||
<Compile Include="ReactNotificationHandlerOf.cs" />
|
||||
<Compile Include="ReactNotificationService.cs" />
|
||||
<Compile Include="ReactNotificationSubscriptionRevoker.cs" />
|
||||
<Compile Include="ReactPropertyBag.cs" />
|
||||
<Compile Include="ReactNotificationIdOf.cs" />
|
||||
<Compile Include="ReactPropertyIdOf.cs" />
|
||||
<Compile Include="ReactDispatcher.cs" />
|
||||
<Compile Include="ReactNotificationSubscription.cs" />
|
||||
<Compile Include="ReactSettingsSnapshot.cs" />
|
||||
<Compile Include="ReactPropertyName.cs" />
|
||||
<Compile Include="ReactPropertyNamespace.cs" />
|
||||
<Compile Include="ReactTaskExtensions.cs" />
|
||||
<Compile Include="ReactEnumerableExtensions.cs" />
|
||||
<Compile Include="ReactEventInfo.cs" />
|
||||
|
@ -125,7 +138,7 @@
|
|||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||
<Version>6.2.9</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
<!--
|
||||
Visual Studio (but not MSBuild) will ignore Conditions applied directly to
|
||||
|
|
|
@ -42,6 +42,11 @@ namespace Microsoft.ReactNative.Managed
|
|||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class ReactGetConstantsAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class ReactMethodAttribute : Attribute
|
||||
{
|
||||
|
@ -89,4 +94,15 @@ namespace Microsoft.ReactNative.Managed
|
|||
|
||||
public string ModuleName { get; set; }
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
|
||||
public class ReactPropertyAttribute : Attribute
|
||||
{
|
||||
public ReactPropertyAttribute(string propertyName = null)
|
||||
{
|
||||
PropertyName = propertyName;
|
||||
}
|
||||
|
||||
public string PropertyName { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,5 +16,10 @@ namespace Microsoft.ReactNative.Managed
|
|||
{
|
||||
Writer.WriteObjectProperty(constantName, value);
|
||||
}
|
||||
|
||||
public void WriteProperties<T>(T value)
|
||||
{
|
||||
Writer.WriteObjectProperties(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
#if !USE_WINUI3
|
||||
using System.Reflection.Metadata;
|
||||
using Windows.UI.Xaml;
|
||||
#else
|
||||
using Microsoft.UI.Xaml;
|
||||
|
@ -11,13 +12,29 @@ namespace Microsoft.ReactNative.Managed
|
|||
{
|
||||
public struct ReactContext
|
||||
{
|
||||
public IReactContext Handle { get; }
|
||||
|
||||
public bool IsValid => Handle != null;
|
||||
|
||||
public static explicit operator bool(ReactContext context) => context.IsValid;
|
||||
|
||||
public ReactPropertyBag Properties => new ReactPropertyBag(Handle.Properties);
|
||||
|
||||
public ReactNotificationService Notifications => new ReactNotificationService(Handle.Notifications);
|
||||
|
||||
public ReactDispatcher UIDispatcher => new ReactDispatcher(Handle.UIDispatcher);
|
||||
|
||||
public ReactDispatcher JSDispatcher => new ReactDispatcher(Handle.JSDispatcher);
|
||||
|
||||
public LoadingState LoadingState => Handle.LoadingState;
|
||||
|
||||
public ReactSettingsSnapshot SettingsSnapshot => new ReactSettingsSnapshot(Handle.SettingsSnapshot);
|
||||
|
||||
public ReactContext(IReactContext handle)
|
||||
{
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
public IReactContext Handle { get; }
|
||||
|
||||
public void DispatchEvent<T>(FrameworkElement view, string eventName, T arg)
|
||||
{
|
||||
var argWriter = arg as JSValueArgWriter;
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
namespace Microsoft.ReactNative.Managed
|
||||
{
|
||||
public struct ReactDispatcher
|
||||
{
|
||||
public bool HasThreadAccess => IsValid ? Handle.HasThreadAccess : false;
|
||||
|
||||
public IReactDispatcher Handle { get; }
|
||||
|
||||
public bool IsValid => Handle != null;
|
||||
|
||||
public static explicit operator bool(ReactDispatcher dispatcher) => dispatcher.IsValid;
|
||||
|
||||
public ReactDispatcher(IReactDispatcher handle = null)
|
||||
{
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
public void Post(ReactDispatcherCallback callback)
|
||||
{
|
||||
if (IsValid)
|
||||
{
|
||||
Handle.Post(callback);
|
||||
}
|
||||
}
|
||||
|
||||
public static ReactDispatcher CreateSerialDispatcher()
|
||||
{
|
||||
return new ReactDispatcher(ReactDispatcherHelper.CreateSerialDispatcher());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.ReactNative.Managed
|
||||
{
|
||||
public struct ReactError
|
||||
{
|
||||
public string Code { get; set; }
|
||||
public string Message { get; set; }
|
||||
public Exception Exception { get; set; }
|
||||
public IReadOnlyDictionary<string, JSValue> UserInfo { get; set; }
|
||||
|
||||
public ReactError(string code, string message, Exception exception = null, IReadOnlyDictionary<string, JSValue> userInfo = null)
|
||||
{
|
||||
Code = code ?? DefaultCode;
|
||||
Message = message ?? DefaultMessage;
|
||||
Exception = exception;
|
||||
UserInfo = userInfo;
|
||||
}
|
||||
|
||||
public ReactError(string message, Exception exception = null, IReadOnlyDictionary<string, JSValue> userInfo = null)
|
||||
: this(null, message, exception, userInfo) { }
|
||||
|
||||
public static readonly string DefaultCode = "EUNSPECIFIED";
|
||||
public static readonly string DefaultMessage = "Error not specified.";
|
||||
|
||||
// Keys for m_reject's Error object
|
||||
public static readonly string CodeKey = "code";
|
||||
public static readonly string MessageKey = "message";
|
||||
public static readonly string UserInfoKey = "userInfo";
|
||||
public static readonly string NativeStackKey = "nativeStackWindows";
|
||||
}
|
||||
}
|