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>
This commit is contained in:
Vladimir Morozov 2022-10-25 21:23:09 -07:00 коммит произвёл GitHub
Родитель e7b60c3fde
Коммит 814ddb2398
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
115 изменённых файлов: 6273 добавлений и 1803 удалений

Просмотреть файл

@ -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)));
}

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 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)' &lt; '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";
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше