From 828a26f9892052a6028c9d3ea7feb15b87984177 Mon Sep 17 00:00:00 2001 From: Aaron Costley Date: Fri, 21 Sep 2018 21:33:01 -0700 Subject: [PATCH] fix(dotnet): abstract classes should have proxy implementations (#241) Abstract classes have can implementations that are not shared thorugh jsii. When trying to instantiate one for these types as a return value, the runtime crashes. This change creates proxy class types for abstract classes. These types can be instantiated, and have implementations for any methods/properties marked as abstract. Fixes #223 Add the ReturnsAbstract test to the complaince suite. This test ensures that proxy implementations are returned from methods that return a abstract class or interface. * Add .DS_Store to .gitignore * Rename JsiiInterfaceProxyAttribute to JsiiTypeProxy * Proxy implementations are sealed * Removed redundant checks for proxy resolution in runtime. --- .gitignore | 3 + .../Class/AbstractClassProxyGeneratorTests.cs | 188 ++++++++++++++++++ .../Class/ClassGeneratorTests.cs | 36 ++-- .../Interface/InterfaceProxyGeneratorTests.cs | 71 +++---- .../InterfaceProxyMethodGeneratorTests.cs | 15 +- .../SymbolMapExtensions.cs | 10 +- .../AssemblyGenerator.cs | 34 +++- .../Class/AbstractClassProxyGenerator.cs | 174 ++++++++++++++++ .../AbstractClassProxyMethodGenerator.cs | 40 ++++ .../AbstractClassProxyPropertyGenerator.cs | 26 +++ .../Class/ClassMethodGenerator.cs | 16 +- .../Class/ClassPropertyGenerator.cs | 9 +- .../src/Amazon.JSII.Generator/ISymbolMap.cs | 2 + .../Interface/InterfaceProxyGenerator.cs | 88 +------- .../InterfaceProxyMethodGenerator.cs | 7 +- .../InterfaceProxyPropertyGenerator.cs | 8 +- .../src/Amazon.JSII.Generator/SymbolMap.cs | 38 +++- .../src/Amazon.JSII.Generator/TypeMetadata.cs | 26 ++- .../TypeProxyGeneratorBase.cs | 101 ++++++++++ .../jsii-dotnet-generator/src/NuGet.config | 2 +- .../ComplianceTests.cs | 26 ++- ...Attribute.cs => JsiiTypeProxyAttribute.cs} | 4 +- .../Converters/FrameworkToJsiiConverter.cs | 2 +- .../Services/Converters/ValueConverter.cs | 2 +- .../Services/ITypeCache.cs | 2 +- .../Services/ReferenceMap.cs | 23 ++- .../Amazon.JSII.Runtime/Services/TypeCache.cs | 20 +- .../BaseNamespace/BasePropsProxy.cs | 8 +- .../BaseNamespace/BaseProxy.cs | 13 ++ .../LibNamespace/IFriendlyProxy.cs | 6 +- .../LibNamespace/MyFirstStructProxy.cs | 10 +- .../LibNamespace/OperationProxy.cs | 27 +++ .../StructWithOnlyOptionalsProxy.cs | 10 +- .../LibNamespace/ValueProxy.cs | 20 ++ .../AbstractClassBaseProxy.cs | 18 ++ .../CalculatorNamespace/AbstractClassProxy.cs | 24 +++ .../BinaryOperationProxy.cs | 27 +++ .../CalculatorPropsProxy.cs | 8 +- .../CalculatorNamespace/DerivedStructProxy.cs | 22 +- .../CalculatorNamespace/IFriendlierProxy.cs | 10 +- .../IFriendlyRandomGeneratorProxy.cs | 8 +- .../IInterfaceWithPropertiesExtensionProxy.cs | 10 +- .../IInterfaceWithPropertiesProxy.cs | 8 +- .../IRandomNumberGeneratorProxy.cs | 6 +- .../ImplictBaseOfBaseProxy.cs | 10 +- ...nterfaceImplementedByAbstractClassProxy.cs | 6 +- .../HelloProxy.cs | 6 +- .../HelloProxy.cs | 6 +- ...terfaceWithOptionalMethodArgumentsProxy.cs | 6 +- .../CalculatorNamespace/ReturnsNumberProxy.cs | 8 +- .../UnaryOperationProxy.cs | 27 +++ .../UnionPropertiesProxy.cs | 8 +- .../composition/CompositeOperationProxy.cs | 24 +++ 53 files changed, 1022 insertions(+), 287 deletions(-) create mode 100644 packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Class/AbstractClassProxyGeneratorTests.cs create mode 100644 packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/AbstractClassProxyGenerator.cs create mode 100644 packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/AbstractClassProxyMethodGenerator.cs create mode 100644 packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/AbstractClassProxyPropertyGenerator.cs create mode 100644 packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/TypeProxyGeneratorBase.cs rename packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/{JsiiInterfaceProxyAttribute.cs => JsiiTypeProxyAttribute.cs} (56%) create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/BaseProxy.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/OperationProxy.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/ValueProxy.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AbstractClassBaseProxy.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AbstractClassProxy.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/BinaryOperationProxy.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnaryOperationProxy.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/composition/CompositeOperationProxy.cs diff --git a/.gitignore b/.gitignore index b7615a96eb..3afdbc282d 100644 --- a/.gitignore +++ b/.gitignore @@ -368,3 +368,6 @@ jspm_packages/ # that NuGet uses for external packages. We don't want to ignore the # lerna packages. !/packages/* + +#MacOS metadata +.DS_Store \ No newline at end of file diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Class/AbstractClassProxyGeneratorTests.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Class/AbstractClassProxyGeneratorTests.cs new file mode 100644 index 0000000000..bedc10ab15 --- /dev/null +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Class/AbstractClassProxyGeneratorTests.cs @@ -0,0 +1,188 @@ +using Amazon.JSII.Generator.Class; +using Amazon.JSII.JsonModel.Spec; +using Xunit; + +namespace Amazon.JSII.Generator.UnitTests.Class +{ + public class AbstractClassProxyGeneratorTests : GeneratorTestBase + { + private const string Prefix = nameof(Generator) + "." + nameof(AbstractClassProxyGenerator) + "."; + + private string Render(ClassType classType) + { + Symbols.MapTypeToPackage("myFqn", classType.Assembly); + Symbols.MapNamespace(classType.QualifiedNamespace, "MyNamespace"); + Symbols.MapTypeName("myFqn", "MyClass", TypeKind.Class); + + var generator = new AbstractClassProxyGenerator(classType.Assembly, classType, Symbols, Namespaces); + + var syntaxTree = generator.CreateSyntaxTree(); + return syntaxTree.ToString(); + } + + [Fact(DisplayName = Prefix + nameof(IncludesAttribute))] + public void IncludesAttribute() + { + var classType = new ClassType + ( + "myFqn", + "myPackage", + "myClass", + true, + initializer: new Method(true, false, false) + ); + + var actual = Render(classType); + var expected = + @"namespace MyNamespace +{ + [JsiiTypeProxy(typeof(MyClass), ""myFqn"")] + internal sealed class MyClassProxy : MyClass + { + private MyClassProxy(ByRefValue reference): base(reference) + { + } + } +}"; + Assert.Equal(expected, actual, ignoreLineEndingDifferences: true); + } + + [Fact(DisplayName = Prefix + nameof(IncludesDocs))] + public void IncludesDocs() + { + // Docs are not currently generated as part of the C# code. + ClassType classType = new ClassType + ( + fullyQualifiedName: "myFqn", + assembly: "myPackage", + name: "myClass", + isAbstract: true, + initializer: new Method(true, false, false), + docs: new Docs {{"foo", "bar"}} + ); + + string actual = Render(classType); + string expected = + @"namespace MyNamespace +{ + /// foo: bar + [JsiiTypeProxy(typeof(MyClass), ""myFqn"")] + internal sealed class MyClassProxy : MyClass + { + private MyClassProxy(ByRefValue reference): base(reference) + { + } + } +}"; + Assert.Equal(expected, actual, ignoreLineEndingDifferences: true); + } + + [Fact(DisplayName = Prefix + nameof(IncludesProperties))] + public void IncludesProperties() + { + ClassType classType = new ClassType + ( + fullyQualifiedName: "myFqn", + assembly: "myPackage", + name: "myClass", + isAbstract: true, + initializer: new Method(true, false, false), + properties: new[] + { + new Property + ( + name: "myProp", + type: new TypeReference("myPropTypeFqn"), + isImmutable: false, + isAbstract: true, + isProtected: false + ), + new Property + ( + name: "notMyProp", + type: new TypeReference("myPropTypeFqn"), + isImmutable: false, + isAbstract: false, + isProtected: false + ) + } + ); + + Symbols.MapTypeName("myPropTypeFqn", "MyPropType", TypeKind.Class); + Symbols.MapPropertyName("myFqn", "myProp", "MyProp"); + + string actual = Render(classType); + string expected = + @"namespace MyNamespace +{ + [JsiiTypeProxy(typeof(MyClass), ""myFqn"")] + internal sealed class MyClassProxy : MyClass + { + private MyClassProxy(ByRefValue reference): base(reference) + { + } + + [JsiiProperty(""myProp"", ""{\""fqn\"":\""myPropTypeFqn\""}"")] + public override MyPropType MyProp + { + get => GetInstanceProperty(); + set => SetInstanceProperty(value); + } + } +}"; + Assert.Equal(expected, actual, ignoreLineEndingDifferences: true); + } + + [Fact(DisplayName = Prefix + nameof(IncludesMethods))] + public void IncludesMethods() + { + ClassType classType = new ClassType + ( + fullyQualifiedName: "myFqn", + assembly: "myPackage", + name: "myClass", + isAbstract: true, + initializer: new Method(true, false, false), + methods: new[] + { + new Method + ( + false, + false, + true, + name: "myMethod" + ), + new Method + ( + false, + false, + false, + name: "notMyMethod" + ) + } + ); + + Symbols.MapMethodName("myFqn", "myMethod", "MyMethod"); + + string actual = Render(classType); + string expected = + @"namespace MyNamespace +{ + [JsiiTypeProxy(typeof(MyClass), ""myFqn"")] + internal sealed class MyClassProxy : MyClass + { + private MyClassProxy(ByRefValue reference): base(reference) + { + } + + [JsiiMethod(""myMethod"", null, ""[]"")] + public override void MyMethod() + { + InvokeInstanceVoidMethod(new object[]{}); + } + } +}"; + Assert.Equal(expected, actual, ignoreLineEndingDifferences: true); + } + } +} \ No newline at end of file diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Class/ClassGeneratorTests.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Class/ClassGeneratorTests.cs index 7c463047aa..f430a9b358 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Class/ClassGeneratorTests.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Class/ClassGeneratorTests.cs @@ -1,20 +1,20 @@ using Amazon.JSII.Generator.Class; -using Amazon.JSII.Generator.Interface; using Amazon.JSII.JsonModel.Spec; using Microsoft.CodeAnalysis; using Xunit; +using TypeKind = Amazon.JSII.JsonModel.Spec.TypeKind; namespace Amazon.JSII.Generator.UnitTests.Class { public class ClassGeneratorTests : GeneratorTestBase { - const string Prefix = nameof(Generator) + "." + nameof(InterfaceGenerator) + "."; + const string Prefix = nameof(Generator) + "." + nameof(ClassGenerator) + "."; - string Render(ClassType classType) + private string Render(ClassType classType) { Symbols.MapTypeToPackage("myFqn", classType.Assembly); Symbols.MapNamespace(classType.QualifiedNamespace, "MyNamespace"); - Symbols.MapTypeName("myFqn", "MyClass", JsonModel.Spec.TypeKind.Class); + Symbols.MapTypeName("myFqn", "MyClass", TypeKind.Class); ClassGenerator generator = new ClassGenerator(classType.Assembly, classType, Symbols, Namespaces); @@ -36,7 +36,7 @@ public void IncludesAttribute() string actual = Render(classType); string expected = -@"namespace MyNamespace + @"namespace MyNamespace { [JsiiClass(typeof(MyClass), ""myFqn"", ""[]"")] public class MyClass : DeputyBase @@ -71,7 +71,7 @@ public void IncludesAbstractKeyword() string actual = Render(classType); string expected = -@"namespace MyNamespace + @"namespace MyNamespace { [JsiiClass(typeof(MyClass), ""myFqn"", ""[]"")] public abstract class MyClass : DeputyBase @@ -103,12 +103,12 @@ public void IncludesDocs() name: "myClass", isAbstract: false, initializer: new Method(true, false, false), - docs: new Docs { { "foo", "bar" } } + docs: new Docs {{"foo", "bar"}} ); string actual = Render(classType); string expected = -@"namespace MyNamespace + @"namespace MyNamespace { /// foo: bar [JsiiClass(typeof(MyClass), ""myFqn"", ""[]"")] @@ -144,7 +144,7 @@ public void IncludesProperties() { new Property ( - name: "myProp", + name: "myProp", type: new TypeReference("myPropTypeFqn"), isImmutable: false, isAbstract: false, @@ -153,12 +153,12 @@ public void IncludesProperties() } ); - Symbols.MapTypeName("myPropTypeFqn", "MyPropType", JsonModel.Spec.TypeKind.Class); + Symbols.MapTypeName("myPropTypeFqn", "MyPropType", TypeKind.Class); Symbols.MapPropertyName("myFqn", "myProp", "MyProp"); string actual = Render(classType); string expected = -@"namespace MyNamespace + @"namespace MyNamespace { [JsiiClass(typeof(MyClass), ""myFqn"", ""[]"")] public class MyClass : DeputyBase @@ -212,7 +212,7 @@ public void IncludesMethods() string actual = Render(classType); string expected = -@"namespace MyNamespace + @"namespace MyNamespace { [JsiiClass(typeof(MyClass), ""myFqn"", ""[]"")] public class MyClass : DeputyBase @@ -252,11 +252,11 @@ public void IncludesBase() @base: new TypeReference("myBaseTypeFqn") ); - Symbols.MapTypeName("myBaseTypeFqn", "MyBaseType", JsonModel.Spec.TypeKind.Class); + Symbols.MapTypeName("myBaseTypeFqn", "MyBaseType", TypeKind.Class); string actual = Render(classType); string expected = -@"namespace MyNamespace + @"namespace MyNamespace { [JsiiClass(typeof(MyClass), ""myFqn"", ""[]"")] public class MyClass : MyBaseType @@ -294,12 +294,12 @@ public void IncludesInterfaces() } ); - Symbols.MapTypeName("myInterfaceFqn1", "MyInterface1", JsonModel.Spec.TypeKind.Interface); - Symbols.MapTypeName("myInterfaceFqn2", "MyInterface2", JsonModel.Spec.TypeKind.Interface); + Symbols.MapTypeName("myInterfaceFqn1", "MyInterface1", TypeKind.Interface); + Symbols.MapTypeName("myInterfaceFqn2", "MyInterface2", TypeKind.Interface); string actual = Render(classType); string expected = -@"namespace MyNamespace + @"namespace MyNamespace { [JsiiClass(typeof(MyClass), ""myFqn"", ""[]"")] public class MyClass : DeputyBase, IMyInterface1, IMyInterface2 @@ -320,4 +320,4 @@ protected MyClass(DeputyProps props): base(props) Assert.Equal(expected, actual, ignoreLineEndingDifferences: true); } } -} +} \ No newline at end of file diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Interface/InterfaceProxyGeneratorTests.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Interface/InterfaceProxyGeneratorTests.cs index 37f0b11dc6..b0555c034b 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Interface/InterfaceProxyGeneratorTests.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Interface/InterfaceProxyGeneratorTests.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Xunit; +using TypeKind = Amazon.JSII.JsonModel.Spec.TypeKind; namespace Amazon.JSII.Generator.UnitTests.Interface { @@ -10,12 +11,13 @@ public class InterfaceProxyGeneratorTests : GeneratorTestBase { const string Prefix = nameof(Generator) + "." + nameof(InterfaceProxyGenerator) + "."; - string Render(InterfaceType interfaceType, string package = "myPackage", string @namespace = "MyNamespace", string typeName = "MyInterface") + string Render(InterfaceType interfaceType, string package = "myPackage", string @namespace = "MyNamespace", + string typeName = "MyInterface") { Symbols.MapTypeToPackage(interfaceType.FullyQualifiedName, package); string suffix = interfaceType.Namespace != null ? "." + interfaceType.Namespace : ""; Symbols.MapNamespace(interfaceType.Assembly + suffix, @namespace); - Symbols.MapTypeName(interfaceType.FullyQualifiedName, typeName, JsonModel.Spec.TypeKind.Interface); + Symbols.MapTypeName(interfaceType.FullyQualifiedName, typeName, TypeKind.Interface); var generator = new InterfaceProxyGenerator(package, interfaceType, Symbols, Namespaces); @@ -37,10 +39,10 @@ public void IncludesAttribute() string actual = Render(interfaceType); string expected = -@"namespace MyNamespace + @"namespace MyNamespace { - [JsiiInterfaceProxy(typeof(IMyInterface), ""myInterfaceFqn"")] - internal class MyInterfaceProxy : DeputyBase, IMyInterface + [JsiiTypeProxy(typeof(IMyInterface), ""myInterfaceFqn"")] + internal sealed class MyInterfaceProxy : DeputyBase, IMyInterface { private MyInterfaceProxy(ByRefValue reference): base(reference) { @@ -59,24 +61,24 @@ public void IncludesMethods() "myPackage", "myInterface", "myNamespace", - methods: new Method[] { new Method(false, false, true, name: "myMethod") } + methods: new Method[] {new Method(false, false, true, name: "myMethod")} ); Symbols.MapMethodName("myInterfaceFqn", "myMethod", "MyMethod"); string actual = Render(interfaceType); string expected = -@"namespace MyNamespace + @"namespace MyNamespace { - [JsiiInterfaceProxy(typeof(IMyInterface), ""myInterfaceFqn"")] - internal class MyInterfaceProxy : DeputyBase, IMyInterface + [JsiiTypeProxy(typeof(IMyInterface), ""myInterfaceFqn"")] + internal sealed class MyInterfaceProxy : DeputyBase, IMyInterface { private MyInterfaceProxy(ByRefValue reference): base(reference) { } [JsiiMethod(""myMethod"", null, ""[]"")] - public virtual void MyMethod() + public void MyMethod() { InvokeInstanceVoidMethod(new object[]{}); } @@ -94,7 +96,7 @@ public void IncludesAncestorInterfaceMethods() "myPackage", "myAncestorInterface", "myNamespace", - methods: new [] { new Method(false, false, true, name: "myAncestorMethod") } + methods: new[] {new Method(false, false, true, name: "myAncestorMethod")} ); InterfaceType baseInterface = new InterfaceType ( @@ -102,8 +104,8 @@ public void IncludesAncestorInterfaceMethods() "myPackage", "myBaseInterface", "myNamespace", - methods: new[] { new Method(false, false, true, name: "myBaseMethod") }, - interfaces: new[] { new TypeReference("myAncestorInterfaceFqn") } + methods: new[] {new Method(false, false, true, name: "myBaseMethod")}, + interfaces: new[] {new TypeReference("myAncestorInterfaceFqn")} ); InterfaceType interfaceType = new InterfaceType ( @@ -111,36 +113,36 @@ public void IncludesAncestorInterfaceMethods() "myPackage", "myInterface", "myNamespace", - interfaces: new[] { new TypeReference("myBaseInterfaceFqn") } + interfaces: new[] {new TypeReference("myBaseInterfaceFqn")} ); - Symbols.MapTypeName("myAncestorInterfaceFqn", "MyAncestorInterface", JsonModel.Spec.TypeKind.Interface); + Symbols.MapTypeName("myAncestorInterfaceFqn", "MyAncestorInterface", TypeKind.Interface); Symbols.MapFullyQualifiedNameToType("myAncestorInterfaceFqn", ancestorInterface); Symbols.MapMethodName("myInterfaceFqn", "myAncestorMethod", "MyAncestorMethod"); - Symbols.MapTypeName("myBaseInterfaceFqn", "MyBaseInterface", JsonModel.Spec.TypeKind.Interface); + Symbols.MapTypeName("myBaseInterfaceFqn", "MyBaseInterface", TypeKind.Interface); Symbols.MapFullyQualifiedNameToType("myBaseInterfaceFqn", baseInterface); Symbols.MapMethodName("myInterfaceFqn", "myBaseMethod", "MyBaseMethod"); string actual = Render(interfaceType); string expected = -@"namespace MyNamespace + @"namespace MyNamespace { - [JsiiInterfaceProxy(typeof(IMyInterface), ""myInterfaceFqn"")] - internal class MyInterfaceProxy : DeputyBase, IMyInterface + [JsiiTypeProxy(typeof(IMyInterface), ""myInterfaceFqn"")] + internal sealed class MyInterfaceProxy : DeputyBase, IMyInterface { private MyInterfaceProxy(ByRefValue reference): base(reference) { } [JsiiMethod(""myBaseMethod"", null, ""[]"")] - public virtual void MyBaseMethod() + public void MyBaseMethod() { InvokeInstanceVoidMethod(new object[]{}); } [JsiiMethod(""myAncestorMethod"", null, ""[]"")] - public virtual void MyAncestorMethod() + public void MyAncestorMethod() { InvokeInstanceVoidMethod(new object[]{}); } @@ -158,16 +160,16 @@ public void IncludesDocs() "myPackage", "myInterface", "myNamespace", - docs: new Docs { { "foo", "bar" } } + docs: new Docs {{"foo", "bar"}} ); string actual = Render(interfaceType); string expected = -@"namespace MyNamespace + @"namespace MyNamespace { /// foo: bar - [JsiiInterfaceProxy(typeof(IMyInterface), ""myInterfaceFqn"")] - internal class MyInterfaceProxy : DeputyBase, IMyInterface + [JsiiTypeProxy(typeof(IMyInterface), ""myInterfaceFqn"")] + internal sealed class MyInterfaceProxy : DeputyBase, IMyInterface { private MyInterfaceProxy(ByRefValue reference): base(reference) { @@ -181,7 +183,7 @@ private MyInterfaceProxy(ByRefValue reference): base(reference) public void EnvironmentRegression() { const string json = -@" { + @" { ""docs"": { ""comment"": ""Models an AWS execution environment, for use within the CDK toolkit."" }, @@ -231,13 +233,14 @@ public void EnvironmentRegression() Symbols.MapPropertyName("jsii$aws_cdk_cx_api$.Environment", "account", "Account"); Symbols.MapPropertyName("jsii$aws_cdk_cx_api$.Environment", "region", "Region"); - string actual = Render(interfaceType, package: "aws-cdk-cx-api", @namespace: "Aws.Cdk.CxApi", typeName: "Environment"); + string actual = Render(interfaceType, package: "aws-cdk-cx-api", @namespace: "Aws.Cdk.CxApi", + typeName: "Environment"); string expected = -@"namespace Aws.Cdk.CxApi + @"namespace Aws.Cdk.CxApi { /// Models an AWS execution environment, for use within the CDK toolkit. - [JsiiInterfaceProxy(typeof(IEnvironment), ""jsii$aws_cdk_cx_api$.Environment"")] - internal class EnvironmentProxy : DeputyBase, IEnvironment + [JsiiTypeProxy(typeof(IEnvironment), ""jsii$aws_cdk_cx_api$.Environment"")] + internal sealed class EnvironmentProxy : DeputyBase, IEnvironment { private EnvironmentProxy(ByRefValue reference): base(reference) { @@ -245,7 +248,7 @@ private EnvironmentProxy(ByRefValue reference): base(reference) /// The arbitrary name of this environment (user-set, or at least user-meaningful) [JsiiProperty(""name"", ""{\""primitive\"":\""string\""}"")] - public virtual string Name + public string Name { get => GetInstanceProperty(); set => SetInstanceProperty(value); @@ -253,7 +256,7 @@ public virtual string Name /// The 12-digit AWS account ID for the account this environment deploys into [JsiiProperty(""account"", ""{\""primitive\"":\""string\""}"")] - public virtual string Account + public string Account { get => GetInstanceProperty(); set => SetInstanceProperty(value); @@ -261,7 +264,7 @@ public virtual string Account /// The AWS region name where this environment deploys into [JsiiProperty(""region"", ""{\""primitive\"":\""string\""}"")] - public virtual string Region + public string Region { get => GetInstanceProperty(); set => SetInstanceProperty(value); @@ -271,4 +274,4 @@ public virtual string Region Assert.Equal(expected, actual, ignoreLineEndingDifferences: true); } } -} +} \ No newline at end of file diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Interface/InterfaceProxyMethodGeneratorTests.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Interface/InterfaceProxyMethodGeneratorTests.cs index d33f6cc9c9..76851dd603 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Interface/InterfaceProxyMethodGeneratorTests.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/Interface/InterfaceProxyMethodGeneratorTests.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Xunit; +using TypeKind = Amazon.JSII.JsonModel.Spec.TypeKind; namespace Amazon.JSII.Generator.UnitTests.Interface { @@ -23,7 +24,7 @@ string Render(Method method) Symbols.MapTypeToPackage("myInterfaceFqn", "myPackage"); Symbols.MapNamespace("", "MyNamespace"); - Symbols.MapTypeName("myInterfaceFqn", "MyInterface", JsonModel.Spec.TypeKind.Interface); + Symbols.MapTypeName("myInterfaceFqn", "MyInterface", TypeKind.Interface); var generator = new InterfaceProxyMethodGenerator(interfaceType, method, Symbols, Namespaces); @@ -41,7 +42,7 @@ public void IncludesAttribute() string actual = Render(method); string expected = @"[JsiiMethod(""myMethod"", null, ""[]"")] -public virtual void MyMethod() +public void MyMethod() { InvokeInstanceVoidMethod(new object[]{}); }"; @@ -62,14 +63,14 @@ public void IncluesParameters() ); Symbols.MapMethodName("myInterfaceFqn", "myMethod", "MyMethod"); - Symbols.MapTypeName("myParamTypeFqn", "MyParamType", JsonModel.Spec.TypeKind.Class); + Symbols.MapTypeName("myParamTypeFqn", "MyParamType", TypeKind.Class); Symbols.MapParameterName("myParam", "myParam"); Symbols.MapParameterName("event", "@event"); string actual = Render(method); string expected = @"[JsiiMethod(""myMethod"", null, ""[{\""name\"":\""myParam\"",\""type\"":{\""fqn\"":\""myParamTypeFqn\""}},{\""name\"":\""event\"",\""type\"":{\""primitive\"":\""string\""}}]"")] -public virtual void MyMethod(MyParamType myParam, string @event) +public void MyMethod(MyParamType myParam, string @event) { InvokeInstanceVoidMethod(new object[]{myParam, @event}); }"; @@ -90,7 +91,7 @@ public void DoesNotIncludeDocs() string actual = Render(method); string expected = @"[JsiiMethod(""myMethod"", null, ""[]"")] -public virtual void MyMethod() +public void MyMethod() { InvokeInstanceVoidMethod(new object[]{}); }"; @@ -107,12 +108,12 @@ public void IncludesReturnTypeForNonVoid() ); Symbols.MapMethodName("myInterfaceFqn", "myMethod", "MyMethod"); - Symbols.MapTypeName("myReturnTypeFqn", "MyReturnType", JsonModel.Spec.TypeKind.Class); + Symbols.MapTypeName("myReturnTypeFqn", "MyReturnType", TypeKind.Class); string actual = Render(method); string expected = @"[JsiiMethod(""myMethod"", ""{\""fqn\"":\""myReturnTypeFqn\""}"", ""[]"")] -public virtual MyReturnType MyMethod() +public MyReturnType MyMethod() { return InvokeInstanceMethod(new object[]{}); }"; diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/SymbolMapExtensions.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/SymbolMapExtensions.cs index 4d2bd4cb2d..ed6093e7fa 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/SymbolMapExtensions.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator.UnitTests/SymbolMapExtensions.cs @@ -1,7 +1,6 @@ using Amazon.JSII.JsonModel.Spec; using NSubstitute; using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory; -using Type = Amazon.JSII.JsonModel.Spec.Type; namespace Amazon.JSII.Generator.UnitTests { @@ -91,6 +90,15 @@ public static void MapTypeName(this ISymbolMap symbols, string fullyQualifiedNam frameworkName = $"I{frameworkName}"; } + if (kind == TypeKind.Class) + { + string proxyName = $"{frameworkName}Proxy"; + + symbols + .GetAbstractClassProxyName(Arg.Is(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any()) + .Returns(proxyName); + } + symbols .GetName(Arg.Is(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any()) .Returns(frameworkName); diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/AssemblyGenerator.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/AssemblyGenerator.cs index d05786067c..6e087b8d45 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/AssemblyGenerator.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/AssemblyGenerator.cs @@ -281,25 +281,47 @@ void SaveType(Type type) switch (type.Kind) { case TypeKind.Class: - SaveTypeFile($"{symbols.GetName(type)}.cs", new ClassGenerator(assembly.Name, (ClassType)type, symbols).CreateSyntaxTree()); + { + var classType = (ClassType) type; + + if (classType.IsAbstract) + { + SaveTypeFile($"{symbols.GetAbstractClassProxyName(classType)}.cs", + new AbstractClassProxyGenerator(assembly.Name, classType, symbols).CreateSyntaxTree()); + } + + SaveTypeFile($"{symbols.GetName(type)}.cs", + new ClassGenerator(assembly.Name, classType, symbols).CreateSyntaxTree()); return; + } case TypeKind.Enum: - SaveTypeFile($"{symbols.GetName(type)}.cs", new EnumGenerator(assembly.Name, (EnumType)type, symbols).CreateSyntaxTree()); + { + SaveTypeFile($"{symbols.GetName(type)}.cs", + new EnumGenerator(assembly.Name, (EnumType) type, symbols).CreateSyntaxTree()); return; + } case TypeKind.Interface: - InterfaceType interfaceType = (InterfaceType)type; + { + InterfaceType interfaceType = (InterfaceType) type; - SaveTypeFile($"{symbols.GetName(interfaceType)}.cs", new InterfaceGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree()); - SaveTypeFile($"{symbols.GetInterfaceProxyName(interfaceType)}.cs", new InterfaceProxyGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree()); + SaveTypeFile($"{symbols.GetName(interfaceType)}.cs", + new InterfaceGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree()); + SaveTypeFile($"{symbols.GetInterfaceProxyName(interfaceType)}.cs", + new InterfaceProxyGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree()); if (interfaceType.IsDataType == true) { - SaveTypeFile($"{symbols.GetInterfaceDefaultName(interfaceType)}.cs", new InterfaceDefaultGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree()); + SaveTypeFile($"{symbols.GetInterfaceDefaultName(interfaceType)}.cs", + new InterfaceDefaultGenerator(assembly.Name, interfaceType, symbols) + .CreateSyntaxTree()); } return; + } default: + { throw new ArgumentException($"Unkown type kind: {type.Kind}", nameof(type)); + } } void SaveTypeFile(string filename, SyntaxTree syntaxTree) diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/AbstractClassProxyGenerator.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/AbstractClassProxyGenerator.cs new file mode 100644 index 0000000000..3e12ed352f --- /dev/null +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/AbstractClassProxyGenerator.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Amazon.JSII.JsonModel.Spec; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory; +using Type = Amazon.JSII.JsonModel.Spec.Type; + +namespace Amazon.JSII.Generator.Class +{ + public class AbstractClassProxyGenerator : TypeProxyGeneratorBase + { + public AbstractClassProxyGenerator(string package, ClassType type, ISymbolMap symbols, + INamespaceSet namespaces = null) + : base(package, type, symbols, namespaces) + { + if (!type.IsAbstract) + { + throw new ArgumentException("Class type must be abstract.", nameof(type)); + } + } + + protected override SyntaxToken GetProxyTypeNameSyntax() + { + return SF.Identifier(Symbols.GetAbstractClassProxyName(Type)); + } + + protected override IEnumerable CreateProperties() + { + foreach (Property property in GetAllProperties(Type)) + { + var generator = new AbstractClassProxyPropertyGenerator(Type, property, Symbols, Namespaces); + yield return generator.CreateProperty(); + } + } + + protected override IEnumerable CreateMethods() + { + foreach (Method method in GetAllMethods(Type)) + { + var generator = new AbstractClassProxyMethodGenerator(Type, method, Symbols, Namespaces); + yield return generator.CreateMethod(); + } + } + + private IEnumerable GetAllMethods(Type type) + { + IEnumerable GetAllMethodsRecurse(Type currentType, IEnumerable methods) + { + if (currentType is InterfaceType interfaceType) + { + // Get all properties from the interface. + methods = methods.Concat(interfaceType.Methods ?? Enumerable.Empty()); + + // Interfaces can have superinterfaces. Run through them too. + if (interfaceType.Interfaces != null) + { + var superinterfaceMethods = interfaceType.Interfaces.Select(r => + Symbols.GetTypeFromFullyQualifiedName(r.FullyQualifiedName) as + InterfaceType) + .SelectMany(i => GetAllMethodsRecurse(i, methods)) + .ToList(); + + methods = methods.Concat(superinterfaceMethods); + } + } + else if (currentType is ClassType classType) + { + // Get all methods from the interface + methods = methods.Concat(classType.Methods ?? Enumerable.Empty()); + + if (classType.Interfaces != null) + { + // Run through all the interfaces. + var superinterfaceMethods = classType.Interfaces.Select(r => + Symbols.GetTypeFromFullyQualifiedName(r.FullyQualifiedName) as + InterfaceType) + .SelectMany(i => GetAllMethodsRecurse(i, methods)) + .ToList(); + + methods = methods.Concat(superinterfaceMethods); + } + + // Run through the superclass. + if (classType.Base != null) + { + methods = methods.Concat(GetAllMethodsRecurse( + Symbols.GetTypeFromFullyQualifiedName(classType.Base.FullyQualifiedName) as ClassType, + methods)); + } + } + + return methods; + } + + /* + Only get the first declaration encountered, and keep it if it is abstract. The list contains ALL + methods and properties encountered, in the order encountered. An abstract class can have concrete + implementations. Therefore, we only generate methods/properties if the first member encountered + is unimplemented. + */ + return GetAllMethodsRecurse(type, Enumerable.Empty()) + .GroupBy(m => (m.Name, + string.Join("", + m.Parameters?.Select(p => p.Name + p.Type.FullyQualifiedName) ?? Enumerable.Empty()))) + .Select(g => g.First()) + .Where(m => m.IsAbstract ?? false); + } + + private IEnumerable GetAllProperties(Type type) + { + IEnumerable GetAllPropertiesRecurse(Type currentType, IEnumerable properties) + { + if (currentType is InterfaceType interfaceType) + { + // Get all properties from the interface. + properties = properties.Concat(interfaceType.Properties ?? Enumerable.Empty()); + + // Interfaces can have superinterfaces. Run through them too. + if (interfaceType.Interfaces != null) + { + var superinterfaceMethods = interfaceType.Interfaces.Select(r => + Symbols.GetTypeFromFullyQualifiedName(r.FullyQualifiedName) as + InterfaceType) + .SelectMany(i => GetAllPropertiesRecurse(i, properties)) + .ToList(); + + properties = properties.Concat(superinterfaceMethods); + } + } + else if (currentType is ClassType classType) + { + // Add the properties from the class. + properties = + properties.Concat(classType.Properties ?? Enumerable.Empty()); + + // Run through all the interfaces. + if (classType.Interfaces != null) + { + var superinterfaceMethods = classType.Interfaces.Select(r => + Symbols.GetTypeFromFullyQualifiedName(r.FullyQualifiedName) as + InterfaceType) + .SelectMany(i => GetAllPropertiesRecurse(i, properties)) + .ToList(); + + properties = properties.Concat(superinterfaceMethods); + } + + // Run through the superclass. + if (classType.Base != null) + { + properties = properties.Concat(GetAllPropertiesRecurse( + Symbols.GetTypeFromFullyQualifiedName(classType.Base.FullyQualifiedName) as ClassType, + properties)); + } + } + + return properties; + } + + /* + Only get the first declaration encountered, and keep it if it is abstract. The list contains ALL + methods and properties encountered, in the order encountered. An abstract class can have concrete + implementations. Therefore, we only generate methods/properties if the first member encountered + is unimplemented. + */ + return GetAllPropertiesRecurse(type, Enumerable.Empty()) + .GroupBy(p => p.Name) + .Select(g => g.First()) + .Where(p => p.IsAbstract ?? false); + } + } +} \ No newline at end of file diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/AbstractClassProxyMethodGenerator.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/AbstractClassProxyMethodGenerator.cs new file mode 100644 index 0000000000..68c9e870c0 --- /dev/null +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/AbstractClassProxyMethodGenerator.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using System.Linq; +using Amazon.JSII.JsonModel.Spec; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory; + +namespace Amazon.JSII.Generator.Class +{ + public class AbstractClassProxyMethodGenerator : ClassMethodGenerator + { + public AbstractClassProxyMethodGenerator(ClassType type, Method method, ISymbolMap symbols, + INamespaceSet namespaces) : base(type, method, symbols, namespaces) + { + } + + protected override IEnumerable GetModifierKeywords() + { + yield return Method.IsProtected ? SyntaxKind.ProtectedKeyword : SyntaxKind.PublicKeyword; + + // Type is the abstract class, so we need to check it as well as ancestors. + if (IsDefinedOnAncestor || Type.Methods.Any(m => m.Name == Method.Name)) + { + yield return SyntaxKind.OverrideKeyword; + } + } + + protected override BlockSyntax GetBody() + { + if (Method.Returns == null) + { + return SF.Block(SF.ExpressionStatement(CreateInvocationExpression())); + } + + return SF.Block(SF.ReturnStatement(CreateInvocationExpression())); + } + + protected override bool HasSemicolon => false; + } +} \ No newline at end of file diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/AbstractClassProxyPropertyGenerator.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/AbstractClassProxyPropertyGenerator.cs new file mode 100644 index 0000000000..d3c8e97f0d --- /dev/null +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/AbstractClassProxyPropertyGenerator.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Linq; +using Amazon.JSII.JsonModel.Spec; +using Microsoft.CodeAnalysis.CSharp; + +namespace Amazon.JSII.Generator.Class +{ + public class AbstractClassProxyPropertyGenerator : ClassPropertyGenerator + { + public AbstractClassProxyPropertyGenerator(ClassType type, Property property, ISymbolMap symbols, + INamespaceSet namespaces) : base(type, property, symbols, namespaces) + { + } + + protected override IEnumerable GetModifierKeywords() + { + yield return Property.IsProtected == true ? SyntaxKind.ProtectedKeyword : SyntaxKind.PublicKeyword; + + // Type is the abstract class, so we need to check it as well as ancestors. + if (IsDefinedOnAncestor || Type.Properties.Any(p => p.Name == Property.Name)) + { + yield return SyntaxKind.OverrideKeyword; + } + } + } +} \ No newline at end of file diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/ClassMethodGenerator.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/ClassMethodGenerator.cs index 8108c3d091..8e8e80edf0 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/ClassMethodGenerator.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/ClassMethodGenerator.cs @@ -1,10 +1,8 @@ -using Amazon.JSII.JsonModel.Spec; -using Microsoft.CodeAnalysis; +using System.Collections.Generic; +using System.Linq; +using Amazon.JSII.JsonModel.Spec; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using System; -using System.Collections.Generic; -using System.Linq; using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace Amazon.JSII.Generator.Class @@ -16,15 +14,15 @@ public ClassMethodGenerator(ClassType type, Method method, ISymbolMap symbols, I { } - bool IsDefinedOnAncestor + protected bool IsDefinedOnAncestor { get { - string[] objectMethods = new[] + string[] objectMethods = { "ToString", "GetHashCode", - "Equals", + "Equals" }; if (objectMethods.Contains(NameUtils.ConvertMethodName(Method.Name))) @@ -79,4 +77,4 @@ protected override BlockSyntax GetBody() protected override bool HasSemicolon => Method.IsAbstract == true; } -} +} \ No newline at end of file diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/ClassPropertyGenerator.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/ClassPropertyGenerator.cs index 5558566fda..76bb7e79bc 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/ClassPropertyGenerator.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Class/ClassPropertyGenerator.cs @@ -1,10 +1,9 @@ -using Amazon.JSII.JsonModel.Spec; +using System.Collections.Generic; +using System.Linq; +using Amazon.JSII.JsonModel.Spec; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using System; -using System.Collections.Generic; -using System.Linq; using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace Amazon.JSII.Generator.Class @@ -16,7 +15,7 @@ public ClassPropertyGenerator(ClassType type, Property property, ISymbolMap symb { } - bool IsDefinedOnAncestor => Type.AnyAncestor(Symbols, t => t.Properties?.Any(p => p.Name == Property.Name) == true); + protected bool IsDefinedOnAncestor => Type.AnyAncestor(Symbols, t => t.Properties?.Any(p => p.Name == Property.Name) == true); protected override IEnumerable GetModifierKeywords() { diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/ISymbolMap.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/ISymbolMap.cs index d60230587f..030170385a 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/ISymbolMap.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/ISymbolMap.cs @@ -15,6 +15,8 @@ public interface ISymbolMap string GetName(Type type, bool disambiguate = false); string GetName(string fullyQualifiedName, bool disambiguate = false); + + string GetAbstractClassProxyName(ClassType type, bool disambiguate = false); string GetInterfaceProxyName(InterfaceType type, bool disambiguate = false); diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Interface/InterfaceProxyGenerator.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Interface/InterfaceProxyGenerator.cs index 9935708ce0..d4b806f0cf 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Interface/InterfaceProxyGenerator.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Interface/InterfaceProxyGenerator.cs @@ -1,98 +1,24 @@ -using Amazon.JSII.JsonModel.Spec; +using System.Collections.Generic; +using Amazon.JSII.JsonModel.Spec; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using System; -using System.Collections.Generic; -using System.Linq; using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace Amazon.JSII.Generator.Interface { - public class InterfaceProxyGenerator : TypeGeneratorBase + public class InterfaceProxyGenerator : TypeProxyGeneratorBase { public InterfaceProxyGenerator(string package, InterfaceType type, ISymbolMap symbols, INamespaceSet namespaces = null) : base(package, type, symbols, namespaces) { } - - protected override MemberDeclarationSyntax CreateType() - { - return SF.ClassDeclaration - ( - CreateAttributes(), - SF.TokenList(SF.Token(SyntaxKind.InternalKeyword)), - GetProxyTypeNameSyntax(), - null, - CreateBaseList(), - SF.List(), - SF.List(CreateMembers()) - ); - - SyntaxList CreateAttributes() - { - TypeOfExpressionSyntax typeOfExpression = SF.TypeOfExpression(Symbols.GetNameSyntax(Type)); - SyntaxToken fullyQualifiedNameLiteral = SF.Literal(Type.FullyQualifiedName); - - return SF.List(new[] { - SF.AttributeList(SF.SeparatedList(new[] { - SF.Attribute( - SF.ParseName("JsiiInterfaceProxy"), - SF.ParseAttributeArgumentList($"({typeOfExpression}, {fullyQualifiedNameLiteral})") - ) - })) - }); - } - - BaseListSyntax CreateBaseList() - { - return SF.BaseList(SF.SeparatedList(GetBaseTypes())); - - IEnumerable GetBaseTypes() - { - yield return SF.SimpleBaseType(SF.ParseTypeName("DeputyBase")); - - Namespaces.Add(Type); - yield return SF.SimpleBaseType(Symbols.GetNameSyntax(Type, disambiguate: true)); - } - } - - IEnumerable CreateMembers() - { - return CreateConstructors() - .Concat(CreateProperties()) - .Concat(CreateMethods()); - } - } - - SyntaxToken GetProxyTypeNameSyntax() + + protected override SyntaxToken GetProxyTypeNameSyntax() { return SF.Identifier(Symbols.GetInterfaceProxyName(Type)); } - IEnumerable CreateConstructors() - { - yield return SF.ConstructorDeclaration - ( - SF.List(), - - // Only Amazon.JSII.Runtime should create interface proxies, - // so we make the constructor private. - SF.TokenList(SF.Token(SyntaxKind.PrivateKeyword)), - - GetProxyTypeNameSyntax(), - SF.ParseParameterList("(ByRefValue reference)"), - SF.ConstructorInitializer - ( - SyntaxKind.BaseConstructorInitializer, - SF.ParseArgumentList("(reference)") - ), - SF.Block(), - null - ); - } - - IEnumerable CreateProperties() + protected override IEnumerable CreateProperties() { foreach (Property property in Type.GetAllProperties(Symbols)) { @@ -101,7 +27,7 @@ IEnumerable CreateProperties() } } - IEnumerable CreateMethods() + protected override IEnumerable CreateMethods() { foreach (Method method in Type.GetAllMethods(Symbols)) { diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Interface/InterfaceProxyMethodGenerator.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Interface/InterfaceProxyMethodGenerator.cs index 29c53e7db7..68c63f1768 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Interface/InterfaceProxyMethodGenerator.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Interface/InterfaceProxyMethodGenerator.cs @@ -1,8 +1,8 @@ -using Amazon.JSII.JsonModel.Spec; +using System; +using System.Collections.Generic; +using Amazon.JSII.JsonModel.Spec; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using System; -using System.Collections.Generic; using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace Amazon.JSII.Generator.Interface @@ -34,7 +34,6 @@ public InterfaceProxyMethodGenerator(InterfaceType type, Method method, ISymbolM protected override IEnumerable GetModifierKeywords() { yield return SyntaxKind.PublicKeyword; - yield return SyntaxKind.VirtualKeyword; } protected override BlockSyntax GetBody() diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Interface/InterfaceProxyPropertyGenerator.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Interface/InterfaceProxyPropertyGenerator.cs index ff6c8af620..bde2cdb839 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Interface/InterfaceProxyPropertyGenerator.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/Interface/InterfaceProxyPropertyGenerator.cs @@ -1,9 +1,9 @@ -using Amazon.JSII.JsonModel.Spec; +using System; +using System.Collections.Generic; +using Amazon.JSII.JsonModel.Spec; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using System; -using System.Collections.Generic; using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace Amazon.JSII.Generator.Interface @@ -35,8 +35,6 @@ public InterfaceProxyPropertyGenerator(InterfaceType type, Property property, IS protected override IEnumerable GetModifierKeywords() { yield return SyntaxKind.PublicKeyword; - - yield return SyntaxKind.VirtualKeyword; } protected override SyntaxToken GetIdentifier() diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/SymbolMap.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/SymbolMap.cs index f00914887b..eb5a9a3175 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/SymbolMap.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/SymbolMap.cs @@ -54,16 +54,26 @@ TypeMetadata GetMetadata(Type type) switch (type.Kind) { case JsonModel.Spec.TypeKind.Class: + { + var classType = (ClassType) type; + if (classType.IsAbstract) + { + return new AbstractClassTypeMetadata(classType, assembly); + } return new ClassTypeMetadata((ClassType)type, assembly); - + } case JsonModel.Spec.TypeKind.Enum: - return new EnumTypeMetadata((EnumType)type, assembly); - + { + return new EnumTypeMetadata((EnumType)type, assembly); + } case JsonModel.Spec.TypeKind.Interface: - return new InterfaceTypeMetadata((InterfaceType)type, assembly); - + { + return new InterfaceTypeMetadata((InterfaceType)type, assembly); + } default: - throw new ArgumentException($"Type {type.Name} has unrecognized kind {type.Kind}", nameof(type)); + { + throw new ArgumentException($"Type {type.Name} has unrecognized kind {type.Kind}", nameof(type)); + } } } } @@ -101,6 +111,18 @@ public string GetName(string fullyQualifiedName, bool disambiguate = false) return GetName(GetTypeFromFullyQualifiedName(fullyQualifiedName), disambiguate); } + public string GetAbstractClassProxyName(ClassType type, bool disambiguate = false) + { + type = type ?? throw new ArgumentNullException(nameof(type)); + + if (_types[type.FullyQualifiedName] is AbstractClassTypeMetadata metadata) + { + return metadata.ProxyName; + } + + throw new ArgumentException($"Cannot get proxy name for '{type.FullyQualifiedName}' because it is not an abstract class."); + } + public string GetInterfaceProxyName(InterfaceType type, bool disambiguate = false) { type = type ?? throw new ArgumentNullException(nameof(type)); @@ -110,7 +132,7 @@ public string GetInterfaceProxyName(InterfaceType type, bool disambiguate = fals return metadata.ProxyName; } - throw new ArgumentException($"Cannot get proxy name for '{type.FullyQualifiedName}' because it is not an interface"); + throw new ArgumentException($"Cannot get proxy name for '{type.FullyQualifiedName}' because it is not an interface."); } public string GetInterfaceDefaultName(InterfaceType type, bool disambiguate = false) @@ -122,7 +144,7 @@ public string GetInterfaceDefaultName(InterfaceType type, bool disambiguate = fa return metadata.DefaultName; } - throw new ArgumentException($"Cannot get default name for '{type.FullyQualifiedName}' because it is not an interface"); + throw new ArgumentException($"Cannot get default name for '{type.FullyQualifiedName}' because it is not an interface."); } public string GetName(Type type, Method method) diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/TypeMetadata.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/TypeMetadata.cs index 462930882e..f6f7af256b 100644 --- a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/TypeMetadata.cs +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/TypeMetadata.cs @@ -67,6 +67,31 @@ public ClassTypeMetadata(ClassType type, Assembly assembly) } } + public class AbstractClassTypeMetadata : ClassTypeMetadata + { + public string ProxyName { get; private set; } + + public string FrameworkFullyQualifiedProxyName => $"{Namespace}.{ProxyName}"; + + public AbstractClassTypeMetadata(ClassType type, Assembly assembly) + : base(type, assembly) + { + ProxyName = $"{Name}Proxy"; + } + + public override void ResolveTypeNameConflicts(ISet namespaceNames) + { + base.ResolveTypeNameConflicts(namespaceNames); + + ISet memberNames = new HashSet(MemberNames.Values); + + while (memberNames.Contains(ProxyName) || namespaceNames.Contains(FrameworkFullyQualifiedProxyName)) + { + ProxyName += "_"; + } + } + } + public class EnumTypeMetadata : TypeMetadata { public EnumTypeMetadata(EnumType type, Assembly assembly) @@ -82,7 +107,6 @@ public EnumTypeMetadata(EnumType type, Assembly assembly) MemberNames = new ReadOnlyDictionary(memberNames); Name = NameUtils.ConvertTypeName(type.Name); } - } public class InterfaceTypeMetadata : TypeMetadata diff --git a/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/TypeProxyGeneratorBase.cs b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/TypeProxyGeneratorBase.cs new file mode 100644 index 0000000000..62a3a1b658 --- /dev/null +++ b/packages/jsii-dotnet-generator/src/Amazon.JSII.Generator/TypeProxyGeneratorBase.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using System.Linq; +using Amazon.JSII.JsonModel.Spec; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using SF = Microsoft.CodeAnalysis.CSharp.SyntaxFactory; + +namespace Amazon.JSII.Generator +{ + public abstract class TypeProxyGeneratorBase : TypeGeneratorBase where T : Type + { + protected TypeProxyGeneratorBase(string package, T type, ISymbolMap symbols, INamespaceSet namespaces) + : base(package, type, symbols, namespaces) + { + } + + protected override MemberDeclarationSyntax CreateType() + { + return SF.ClassDeclaration + ( + CreateAttributes(), + SF.TokenList( + SF.Token(SyntaxKind.InternalKeyword), + SF.Token(SyntaxKind.SealedKeyword)), + GetProxyTypeNameSyntax(), + null, + CreateBaseList(), + SF.List(), + SF.List(CreateMembers()) + ); + + SyntaxList CreateAttributes() + { + var typeOfExpression = SF.TypeOfExpression(Symbols.GetNameSyntax(Type)); + var fullyQualifiedNameLiteral = SF.Literal(Type.FullyQualifiedName); + + return SF.List(new[] + { + SF.AttributeList(SF.SeparatedList(new[] + { + SF.Attribute( + SF.ParseName("JsiiTypeProxy"), + SF.ParseAttributeArgumentList($"({typeOfExpression}, {fullyQualifiedNameLiteral})") + ) + })) + }); + } + + BaseListSyntax CreateBaseList() + { + return SF.BaseList(SF.SeparatedList(GetBaseTypes())); + + IEnumerable GetBaseTypes() + { + if (Type is InterfaceType) + { + yield return SF.SimpleBaseType(SF.ParseTypeName("DeputyBase")); + } + + Namespaces.Add(Type); + yield return SF.SimpleBaseType(Symbols.GetNameSyntax(Type, disambiguate: true)); + } + } + + IEnumerable CreateMembers() + { + return CreateConstructors() + .Concat(CreateProperties()) + .Concat(CreateMethods()); + } + } + + protected virtual IEnumerable CreateConstructors() + { + yield return SF.ConstructorDeclaration + ( + SF.List(), + + // Only Amazon.JSII.Runtime should create interface proxies, + // so we make the constructor private. + SF.TokenList(SF.Token(SyntaxKind.PrivateKeyword)), + GetProxyTypeNameSyntax(), + SF.ParseParameterList("(ByRefValue reference)"), + SF.ConstructorInitializer + ( + SyntaxKind.BaseConstructorInitializer, + SF.ParseArgumentList("(reference)") + ), + SF.Block(), + null + ); + } + + protected abstract SyntaxToken GetProxyTypeNameSyntax(); + + protected abstract IEnumerable CreateProperties(); + + protected abstract IEnumerable CreateMethods(); + } +} \ No newline at end of file diff --git a/packages/jsii-dotnet-generator/src/NuGet.config b/packages/jsii-dotnet-generator/src/NuGet.config index c84bdd28da..b5fb4a92ff 100644 --- a/packages/jsii-dotnet-generator/src/NuGet.config +++ b/packages/jsii-dotnet-generator/src/NuGet.config @@ -1,4 +1,4 @@ - + diff --git a/packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/ComplianceTests.cs b/packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/ComplianceTests.cs index 5425aa009b..a9dca0351f 100644 --- a/packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/ComplianceTests.cs +++ b/packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/ComplianceTests.cs @@ -1,13 +1,10 @@ +using System; +using System.Collections.Generic; using Amazon.JSII.Runtime.Deputy; -using Amazon.JSII.Runtime.Services; using Amazon.JSII.Tests.CalculatorNamespace; -using Amazon.JSII.Tests.CalculatorNamespace.composition; using Amazon.JSII.Tests.CalculatorNamespace.composition.CompositeOperation; using Amazon.JSII.Tests.CalculatorNamespace.LibNamespace; using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.IO; using Xunit; using Xunit.Abstractions; @@ -784,7 +781,8 @@ public void ReservedKeywordsAreSlugifiedInMethodNames() } [Fact(DisplayName = Prefix + nameof(NodeStandardLibrary))] - public void NodeStandardLibrary() { + public void NodeStandardLibrary() + { NodeStandardLibrary obj = new NodeStandardLibrary(); Assert.Equal("Hello, resource!", obj.FsReadFile()); Assert.Equal("Hello, resource! SYNC!", obj.FsReadFileSync()); @@ -792,6 +790,22 @@ public void NodeStandardLibrary() { Assert.Equal("6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50", obj.CryptoSha256()); } + + [Fact(DisplayName = Prefix + nameof(ReturnAbstract))] + public void ReturnAbstract() + { + var obj = new AbstractClassReturner(); + var obj2 = obj.GiveMeAbstract(); + + Assert.Equal("Hello, John!!", obj2.AbstractMethod("John")); + Assert.Equal("propFromInterfaceValue", obj2.PropFromInterface); + Assert.Equal(42, obj2.NonAbstractMethod()); + + var iface = obj.GiveMeInterface(); + Assert.Equal("propFromInterfaceValue", iface.PropFromInterface); + + Assert.Equal("hello-abstract-property", obj.ReturnAbstractFromProperty.AbstractProperty); + } class MulTen : Multiply diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiInterfaceProxyAttribute.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiTypeProxyAttribute.cs similarity index 56% rename from packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiInterfaceProxyAttribute.cs rename to packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiTypeProxyAttribute.cs index 05761f8213..c6a98143a5 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiInterfaceProxyAttribute.cs +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiTypeProxyAttribute.cs @@ -3,9 +3,9 @@ namespace Amazon.JSII.Runtime.Deputy { [AttributeUsage(AttributeTargets.Class, Inherited = false)] - public class JsiiInterfaceProxyAttribute : JsiiTypeAttributeBase + public class JsiiTypeProxyAttribute : JsiiTypeAttributeBase { - public JsiiInterfaceProxyAttribute(Type nativeType, string fullyQualifiedName) + public JsiiTypeProxyAttribute(Type nativeType, string fullyQualifiedName) : base(nativeType, fullyQualifiedName) { } diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/FrameworkToJsiiConverter.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/FrameworkToJsiiConverter.cs index 02ac1e6e3e..9dabadcb95 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/FrameworkToJsiiConverter.cs +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/FrameworkToJsiiConverter.cs @@ -35,7 +35,7 @@ protected override bool TryConvertClass(IReferenceMap referenceMap, object value System.Type type = value.GetType(); - if (type.GetCustomAttribute() != null) + if (type.GetCustomAttribute() != null) { throw new ArgumentException ( diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/ValueConverter.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/ValueConverter.cs index 58a14fc5dd..af5e834506 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/ValueConverter.cs +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/Converters/ValueConverter.cs @@ -115,7 +115,7 @@ bool IsReferenceType() return _types.GetClassType(fullyQualifiedName) != null || _types.GetInterfaceType(fullyQualifiedName) != null || - _types.GetInterfaceProxyType(fullyQualifiedName) != null; + _types.GetProxyType(fullyQualifiedName) != null; } } diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/ITypeCache.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/ITypeCache.cs index 3d6d3cfbf9..b5c86bb9b1 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/ITypeCache.cs +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/ITypeCache.cs @@ -10,7 +10,7 @@ public interface ITypeCache Type GetInterfaceType(string fullyQualifiedName); - Type GetInterfaceProxyType(string fullyQualifiedName); + Type GetProxyType(string fullyQualifiedName); Type GetFrameworkType(JsonModel.Spec.TypeReference reference); } diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/ReferenceMap.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/ReferenceMap.cs index 0b8c171906..609ab784fb 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/ReferenceMap.cs +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/ReferenceMap.cs @@ -1,8 +1,8 @@ -using Amazon.JSII.JsonModel.Api; -using Amazon.JSII.Runtime.Deputy; -using System; +using System; using System.Collections.Generic; using System.Reflection; +using Amazon.JSII.JsonModel.Api; +using Amazon.JSII.Runtime.Deputy; namespace Amazon.JSII.Runtime.Services { @@ -20,7 +20,9 @@ public void AddNativeReference(ByRefValue reference, DeputyBase nativeReference) { if (_references.ContainsKey(reference.Value)) { - throw new ArgumentException($"Cannot add reference for {reference.Value}: A reference with this name already exists", nameof(reference)); + throw new ArgumentException( + $"Cannot add reference for {reference.Value}: A reference with this name already exists", + nameof(reference)); } _references[reference.Value] = nativeReference; @@ -36,7 +38,7 @@ public DeputyBase GetOrCreateNativeReference(ByRefValue byRefValue) if (!_references.ContainsKey(byRefValue.Value)) { ConstructorInfo constructorInfo = GetByRefConstructor(); - _references[byRefValue.Value] = (DeputyBase)constructorInfo.Invoke(new object[] { byRefValue }); + _references[byRefValue.Value] = (DeputyBase) constructorInfo.Invoke(new object[] {byRefValue}); } return _references[byRefValue.Value]; @@ -44,10 +46,13 @@ public DeputyBase GetOrCreateNativeReference(ByRefValue byRefValue) ConstructorInfo GetByRefConstructor() { Type type = _types.GetClassType(byRefValue.FullyQualifiedName); - if (type == null) + + // If type is an interface or abstract class + if (type == null || type.IsAbstract) { - type = _types.GetInterfaceProxyType(byRefValue.FullyQualifiedName); + type = _types.GetProxyType(byRefValue.FullyQualifiedName); } + if (type == null) { throw new ArgumentException( @@ -58,8 +63,8 @@ ConstructorInfo GetByRefConstructor() BindingFlags constructorFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; - return type.GetConstructor(constructorFlags, null, new[] { typeof(ByRefValue) }, null); + return type.GetConstructor(constructorFlags, null, new[] {typeof(ByRefValue)}, null); } } } -} +} \ No newline at end of file diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/TypeCache.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/TypeCache.cs index b0a5fac060..932df17336 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/TypeCache.cs +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Services/TypeCache.cs @@ -1,11 +1,13 @@ -using Microsoft.Extensions.Logging; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reflection; -using PrimitiveType = Amazon.JSII.JsonModel.Spec.PrimitiveType; -using CollectionKind = Amazon.JSII.JsonModel.Spec.CollectionKind; +using Amazon.JSII.JsonModel.Spec; using Amazon.JSII.Runtime.Deputy; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; +using Assembly = System.Reflection.Assembly; +using Type = System.Type; namespace Amazon.JSII.Runtime.Services { @@ -42,12 +44,12 @@ public Type GetInterfaceType(string fullyQualifiedName) return GetType(fullyQualifiedName); } - public Type GetInterfaceProxyType(string fullyQualifiedName) + public Type GetProxyType(string fullyQualifiedName) { - return GetType(fullyQualifiedName + ProxySuffix); + return GetType(fullyQualifiedName + ProxySuffix); } - public Type GetFrameworkType(JsonModel.Spec.TypeReference reference) + public Type GetFrameworkType(TypeReference reference) { bool isOptional = reference.IsOptional == true; @@ -79,7 +81,7 @@ public Type GetFrameworkType(JsonModel.Spec.TypeReference reference) case PrimitiveType.Date: return MakeNullableIfOptional(typeof(DateTime)); case PrimitiveType.Json: - return typeof(Newtonsoft.Json.Linq.JObject); + return typeof(JObject); case PrimitiveType.Number: return MakeNullableIfOptional(typeof(double)); case PrimitiveType.String: @@ -158,7 +160,7 @@ void CacheTypes(Assembly assembly) if (attribute != null) { string fullyQualifiedName = attribute.FullyQualifiedName; - if (attribute is JsiiInterfaceProxyAttribute) + if (attribute is JsiiTypeProxyAttribute) { fullyQualifiedName += ProxySuffix; } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/BasePropsProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/BasePropsProxy.cs index 5a291279e5..afbeecf9b7 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/BasePropsProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/BasePropsProxy.cs @@ -3,22 +3,22 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace { - [JsiiInterfaceProxy(typeof(IBaseProps), "@scope/jsii-calc-base.BaseProps")] - internal class BasePropsProxy : DeputyBase, IBaseProps + [JsiiTypeProxy(typeof(IBaseProps), "@scope/jsii-calc-base.BaseProps")] + internal sealed class BasePropsProxy : DeputyBase, IBaseProps { private BasePropsProxy(ByRefValue reference): base(reference) { } [JsiiProperty("bar", "{\"primitive\":\"string\"}")] - public virtual string Bar + public string Bar { get => GetInstanceProperty(); set => SetInstanceProperty(value); } [JsiiProperty("foo", "{\"fqn\":\"@scope/jsii-calc-base-of-base.Very\"}")] - public virtual Very Foo + public Very Foo { get => GetInstanceProperty(); set => SetInstanceProperty(value); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/BaseProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/BaseProxy.cs new file mode 100644 index 0000000000..032ef8a878 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/BaseProxy.cs @@ -0,0 +1,13 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace +{ + /// A base class. + [JsiiTypeProxy(typeof(Base), "@scope/jsii-calc-base.Base")] + internal sealed class BaseProxy : Base + { + private BaseProxy(ByRefValue reference): base(reference) + { + } + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/IFriendlyProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/IFriendlyProxy.cs index 95ac50beeb..de8c7ddfb5 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/IFriendlyProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/IFriendlyProxy.cs @@ -6,8 +6,8 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace /// Applies to classes that are considered friendly. These classes can be greeted with /// a "hello" or "goodbye" blessing and they will respond back in a fun and friendly manner. /// - [JsiiInterfaceProxy(typeof(IIFriendly), "@scope/jsii-calc-lib.IFriendly")] - internal class IFriendlyProxy : DeputyBase, IIFriendly + [JsiiTypeProxy(typeof(IIFriendly), "@scope/jsii-calc-lib.IFriendly")] + internal sealed class IFriendlyProxy : DeputyBase, IIFriendly { private IFriendlyProxy(ByRefValue reference): base(reference) { @@ -15,7 +15,7 @@ private IFriendlyProxy(ByRefValue reference): base(reference) /// Say hello! [JsiiMethod("hello", "{\"primitive\":\"string\"}", "[]")] - public virtual string Hello() + public string Hello() { return InvokeInstanceMethod(new object[]{}); } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/MyFirstStructProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/MyFirstStructProxy.cs index 10ed352430..42231e2055 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/MyFirstStructProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/MyFirstStructProxy.cs @@ -3,8 +3,8 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace { /// This is the first struct we have created in jsii - [JsiiInterfaceProxy(typeof(IMyFirstStruct), "@scope/jsii-calc-lib.MyFirstStruct")] - internal class MyFirstStructProxy : DeputyBase, IMyFirstStruct + [JsiiTypeProxy(typeof(IMyFirstStruct), "@scope/jsii-calc-lib.MyFirstStruct")] + internal sealed class MyFirstStructProxy : DeputyBase, IMyFirstStruct { private MyFirstStructProxy(ByRefValue reference): base(reference) { @@ -12,7 +12,7 @@ private MyFirstStructProxy(ByRefValue reference): base(reference) /// An awesome number value [JsiiProperty("anumber", "{\"primitive\":\"number\"}")] - public virtual double Anumber + public double Anumber { get => GetInstanceProperty(); set => SetInstanceProperty(value); @@ -20,14 +20,14 @@ public virtual double Anumber /// A string value [JsiiProperty("astring", "{\"primitive\":\"string\"}")] - public virtual string Astring + public string Astring { get => GetInstanceProperty(); set => SetInstanceProperty(value); } [JsiiProperty("firstOptional", "{\"collection\":{\"kind\":\"array\",\"elementtype\":{\"primitive\":\"string\"}},\"optional\":true}")] - public virtual string[] FirstOptional + public string[] FirstOptional { get => GetInstanceProperty(); set => SetInstanceProperty(value); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/OperationProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/OperationProxy.cs new file mode 100644 index 0000000000..d12a386669 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/OperationProxy.cs @@ -0,0 +1,27 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace +{ + /// Represents an operation on values. + [JsiiTypeProxy(typeof(Operation), "@scope/jsii-calc-lib.Operation")] + internal sealed class OperationProxy : Operation + { + private OperationProxy(ByRefValue reference): base(reference) + { + } + + /// The value. + [JsiiProperty("value", "{\"primitive\":\"number\"}")] + public override double Value + { + get => GetInstanceProperty(); + } + + /// String representation of the value. + [JsiiMethod("toString", "{\"primitive\":\"string\"}", "[]")] + public override string ToString() + { + return InvokeInstanceMethod(new object[]{}); + } + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/StructWithOnlyOptionalsProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/StructWithOnlyOptionalsProxy.cs index da65e4918b..8b6ba827ce 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/StructWithOnlyOptionalsProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/StructWithOnlyOptionalsProxy.cs @@ -3,8 +3,8 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace { /// This is a struct with only optional properties. - [JsiiInterfaceProxy(typeof(IStructWithOnlyOptionals), "@scope/jsii-calc-lib.StructWithOnlyOptionals")] - internal class StructWithOnlyOptionalsProxy : DeputyBase, IStructWithOnlyOptionals + [JsiiTypeProxy(typeof(IStructWithOnlyOptionals), "@scope/jsii-calc-lib.StructWithOnlyOptionals")] + internal sealed class StructWithOnlyOptionalsProxy : DeputyBase, IStructWithOnlyOptionals { private StructWithOnlyOptionalsProxy(ByRefValue reference): base(reference) { @@ -12,21 +12,21 @@ private StructWithOnlyOptionalsProxy(ByRefValue reference): base(reference) /// The first optional! [JsiiProperty("optional1", "{\"primitive\":\"string\",\"optional\":true}")] - public virtual string Optional1 + public string Optional1 { get => GetInstanceProperty(); set => SetInstanceProperty(value); } [JsiiProperty("optional2", "{\"primitive\":\"number\",\"optional\":true}")] - public virtual double? Optional2 + public double? Optional2 { get => GetInstanceProperty(); set => SetInstanceProperty(value); } [JsiiProperty("optional3", "{\"primitive\":\"boolean\",\"optional\":true}")] - public virtual bool? Optional3 + public bool? Optional3 { get => GetInstanceProperty(); set => SetInstanceProperty(value); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/ValueProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/ValueProxy.cs new file mode 100644 index 0000000000..8dbda90606 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/ValueProxy.cs @@ -0,0 +1,20 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace +{ + /// Abstract class which represents a numeric value. + [JsiiTypeProxy(typeof(Value_), "@scope/jsii-calc-lib.Value")] + internal sealed class ValueProxy : Value_ + { + private ValueProxy(ByRefValue reference): base(reference) + { + } + + /// The value. + [JsiiProperty("value", "{\"primitive\":\"number\"}")] + public override double Value + { + get => GetInstanceProperty(); + } + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AbstractClassBaseProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AbstractClassBaseProxy.cs new file mode 100644 index 0000000000..d12f04de48 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AbstractClassBaseProxy.cs @@ -0,0 +1,18 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + [JsiiTypeProxy(typeof(AbstractClassBase), "jsii-calc.AbstractClassBase")] + internal sealed class AbstractClassBaseProxy : AbstractClassBase + { + private AbstractClassBaseProxy(ByRefValue reference): base(reference) + { + } + + [JsiiProperty("abstractProperty", "{\"primitive\":\"string\"}")] + public override string AbstractProperty + { + get => GetInstanceProperty(); + } + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AbstractClassProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AbstractClassProxy.cs new file mode 100644 index 0000000000..97918b1966 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AbstractClassProxy.cs @@ -0,0 +1,24 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + [JsiiTypeProxy(typeof(AbstractClass), "jsii-calc.AbstractClass")] + internal sealed class AbstractClassProxy : AbstractClass + { + private AbstractClassProxy(ByRefValue reference): base(reference) + { + } + + [JsiiProperty("abstractProperty", "{\"primitive\":\"string\"}")] + public override string AbstractProperty + { + get => GetInstanceProperty(); + } + + [JsiiMethod("abstractMethod", "{\"primitive\":\"string\"}", "[{\"name\":\"name\",\"type\":{\"primitive\":\"string\"}}]")] + public override string AbstractMethod(string name) + { + return InvokeInstanceMethod(new object[]{name}); + } + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/BinaryOperationProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/BinaryOperationProxy.cs new file mode 100644 index 0000000000..46799d122d --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/BinaryOperationProxy.cs @@ -0,0 +1,27 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + /// Represents an operation with two operands. + [JsiiTypeProxy(typeof(BinaryOperation), "jsii-calc.BinaryOperation")] + internal sealed class BinaryOperationProxy : BinaryOperation + { + private BinaryOperationProxy(ByRefValue reference): base(reference) + { + } + + /// The value. + [JsiiProperty("value", "{\"primitive\":\"number\"}")] + public override double Value + { + get => GetInstanceProperty(); + } + + /// String representation of the value. + [JsiiMethod("toString", "{\"primitive\":\"string\"}", "[]")] + public override string ToString() + { + return InvokeInstanceMethod(new object[]{}); + } + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/CalculatorPropsProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/CalculatorPropsProxy.cs index 3d8ba2c089..931e805cde 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/CalculatorPropsProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/CalculatorPropsProxy.cs @@ -3,22 +3,22 @@ namespace Amazon.JSII.Tests.CalculatorNamespace { /// Properties for Calculator. - [JsiiInterfaceProxy(typeof(ICalculatorProps), "jsii-calc.CalculatorProps")] - internal class CalculatorPropsProxy : DeputyBase, ICalculatorProps + [JsiiTypeProxy(typeof(ICalculatorProps), "jsii-calc.CalculatorProps")] + internal sealed class CalculatorPropsProxy : DeputyBase, ICalculatorProps { private CalculatorPropsProxy(ByRefValue reference): base(reference) { } [JsiiProperty("initialValue", "{\"primitive\":\"number\",\"optional\":true}")] - public virtual double? InitialValue + public double? InitialValue { get => GetInstanceProperty(); set => SetInstanceProperty(value); } [JsiiProperty("maximumValue", "{\"primitive\":\"number\",\"optional\":true}")] - public virtual double? MaximumValue + public double? MaximumValue { get => GetInstanceProperty(); set => SetInstanceProperty(value); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DerivedStructProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DerivedStructProxy.cs index 59adc06210..67004f86bc 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DerivedStructProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DerivedStructProxy.cs @@ -6,22 +6,22 @@ namespace Amazon.JSII.Tests.CalculatorNamespace { /// A struct which derives from another struct. - [JsiiInterfaceProxy(typeof(IDerivedStruct), "jsii-calc.DerivedStruct")] - internal class DerivedStructProxy : DeputyBase, IDerivedStruct + [JsiiTypeProxy(typeof(IDerivedStruct), "jsii-calc.DerivedStruct")] + internal sealed class DerivedStructProxy : DeputyBase, IDerivedStruct { private DerivedStructProxy(ByRefValue reference): base(reference) { } [JsiiProperty("anotherRequired", "{\"primitive\":\"date\"}")] - public virtual DateTime AnotherRequired + public DateTime AnotherRequired { get => GetInstanceProperty(); set => SetInstanceProperty(value); } [JsiiProperty("bool", "{\"primitive\":\"boolean\"}")] - public virtual bool Bool + public bool Bool { get => GetInstanceProperty(); set => SetInstanceProperty(value); @@ -29,7 +29,7 @@ public virtual bool Bool /// An example of a non primitive property. [JsiiProperty("nonPrimitive", "{\"fqn\":\"jsii-calc.DoubleTrouble\"}")] - public virtual DoubleTrouble NonPrimitive + public DoubleTrouble NonPrimitive { get => GetInstanceProperty(); set => SetInstanceProperty(value); @@ -37,21 +37,21 @@ public virtual DoubleTrouble NonPrimitive /// This is optional. [JsiiProperty("anotherOptional", "{\"collection\":{\"kind\":\"map\",\"elementtype\":{\"fqn\":\"@scope/jsii-calc-lib.Value\"}},\"optional\":true}")] - public virtual IDictionary AnotherOptional + public IDictionary AnotherOptional { get => GetInstanceProperty>(); set => SetInstanceProperty(value); } [JsiiProperty("optionalAny", "{\"primitive\":\"any\",\"optional\":true}")] - public virtual object OptionalAny + public object OptionalAny { get => GetInstanceProperty(); set => SetInstanceProperty(value); } [JsiiProperty("optionalArray", "{\"collection\":{\"kind\":\"array\",\"elementtype\":{\"primitive\":\"string\"}},\"optional\":true}")] - public virtual string[] OptionalArray + public string[] OptionalArray { get => GetInstanceProperty(); set => SetInstanceProperty(value); @@ -59,7 +59,7 @@ public virtual string[] OptionalArray /// An awesome number value [JsiiProperty("anumber", "{\"primitive\":\"number\"}")] - public virtual double Anumber + public double Anumber { get => GetInstanceProperty(); set => SetInstanceProperty(value); @@ -67,14 +67,14 @@ public virtual double Anumber /// A string value [JsiiProperty("astring", "{\"primitive\":\"string\"}")] - public virtual string Astring + public string Astring { get => GetInstanceProperty(); set => SetInstanceProperty(value); } [JsiiProperty("firstOptional", "{\"collection\":{\"kind\":\"array\",\"elementtype\":{\"primitive\":\"string\"}},\"optional\":true}")] - public virtual string[] FirstOptional + public string[] FirstOptional { get => GetInstanceProperty(); set => SetInstanceProperty(value); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IFriendlierProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IFriendlierProxy.cs index 6ad94be5e6..220edef048 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IFriendlierProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IFriendlierProxy.cs @@ -3,8 +3,8 @@ namespace Amazon.JSII.Tests.CalculatorNamespace { /// Even friendlier classes can implement this interface. - [JsiiInterfaceProxy(typeof(IIFriendlier), "jsii-calc.IFriendlier")] - internal class IFriendlierProxy : DeputyBase, IIFriendlier + [JsiiTypeProxy(typeof(IIFriendlier), "jsii-calc.IFriendlier")] + internal sealed class IFriendlierProxy : DeputyBase, IIFriendlier { private IFriendlierProxy(ByRefValue reference): base(reference) { @@ -12,7 +12,7 @@ private IFriendlierProxy(ByRefValue reference): base(reference) /// Say farewell. [JsiiMethod("farewell", "{\"primitive\":\"string\"}", "[]")] - public virtual string Farewell() + public string Farewell() { return InvokeInstanceMethod(new object[]{}); } @@ -20,14 +20,14 @@ public virtual string Farewell() /// Say goodbye. /// A goodbye blessing. [JsiiMethod("goodbye", "{\"primitive\":\"string\"}", "[]")] - public virtual string Goodbye() + public string Goodbye() { return InvokeInstanceMethod(new object[]{}); } /// Say hello! [JsiiMethod("hello", "{\"primitive\":\"string\"}", "[]")] - public virtual string Hello() + public string Hello() { return InvokeInstanceMethod(new object[]{}); } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IFriendlyRandomGeneratorProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IFriendlyRandomGeneratorProxy.cs index bbeda0eae5..f179d26ab6 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IFriendlyRandomGeneratorProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IFriendlyRandomGeneratorProxy.cs @@ -2,8 +2,8 @@ namespace Amazon.JSII.Tests.CalculatorNamespace { - [JsiiInterfaceProxy(typeof(IIFriendlyRandomGenerator), "jsii-calc.IFriendlyRandomGenerator")] - internal class IFriendlyRandomGeneratorProxy : DeputyBase, IIFriendlyRandomGenerator + [JsiiTypeProxy(typeof(IIFriendlyRandomGenerator), "jsii-calc.IFriendlyRandomGenerator")] + internal sealed class IFriendlyRandomGeneratorProxy : DeputyBase, IIFriendlyRandomGenerator { private IFriendlyRandomGeneratorProxy(ByRefValue reference): base(reference) { @@ -12,14 +12,14 @@ private IFriendlyRandomGeneratorProxy(ByRefValue reference): base(reference) /// Returns another random number. /// A random number. [JsiiMethod("next", "{\"primitive\":\"number\"}", "[]")] - public virtual double Next() + public double Next() { return InvokeInstanceMethod(new object[]{}); } /// Say hello! [JsiiMethod("hello", "{\"primitive\":\"string\"}", "[]")] - public virtual string Hello() + public string Hello() { return InvokeInstanceMethod(new object[]{}); } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IInterfaceWithPropertiesExtensionProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IInterfaceWithPropertiesExtensionProxy.cs index 3be85b6c5f..805ef19457 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IInterfaceWithPropertiesExtensionProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IInterfaceWithPropertiesExtensionProxy.cs @@ -2,28 +2,28 @@ namespace Amazon.JSII.Tests.CalculatorNamespace { - [JsiiInterfaceProxy(typeof(IIInterfaceWithPropertiesExtension), "jsii-calc.IInterfaceWithPropertiesExtension")] - internal class IInterfaceWithPropertiesExtensionProxy : DeputyBase, IIInterfaceWithPropertiesExtension + [JsiiTypeProxy(typeof(IIInterfaceWithPropertiesExtension), "jsii-calc.IInterfaceWithPropertiesExtension")] + internal sealed class IInterfaceWithPropertiesExtensionProxy : DeputyBase, IIInterfaceWithPropertiesExtension { private IInterfaceWithPropertiesExtensionProxy(ByRefValue reference): base(reference) { } [JsiiProperty("foo", "{\"primitive\":\"number\"}")] - public virtual double Foo + public double Foo { get => GetInstanceProperty(); set => SetInstanceProperty(value); } [JsiiProperty("readOnlyString", "{\"primitive\":\"string\"}")] - public virtual string ReadOnlyString + public string ReadOnlyString { get => GetInstanceProperty(); } [JsiiProperty("readWriteString", "{\"primitive\":\"string\"}")] - public virtual string ReadWriteString + public string ReadWriteString { get => GetInstanceProperty(); set => SetInstanceProperty(value); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IInterfaceWithPropertiesProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IInterfaceWithPropertiesProxy.cs index 010dc62dcf..c2afae727e 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IInterfaceWithPropertiesProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IInterfaceWithPropertiesProxy.cs @@ -2,21 +2,21 @@ namespace Amazon.JSII.Tests.CalculatorNamespace { - [JsiiInterfaceProxy(typeof(IIInterfaceWithProperties), "jsii-calc.IInterfaceWithProperties")] - internal class IInterfaceWithPropertiesProxy : DeputyBase, IIInterfaceWithProperties + [JsiiTypeProxy(typeof(IIInterfaceWithProperties), "jsii-calc.IInterfaceWithProperties")] + internal sealed class IInterfaceWithPropertiesProxy : DeputyBase, IIInterfaceWithProperties { private IInterfaceWithPropertiesProxy(ByRefValue reference): base(reference) { } [JsiiProperty("readOnlyString", "{\"primitive\":\"string\"}")] - public virtual string ReadOnlyString + public string ReadOnlyString { get => GetInstanceProperty(); } [JsiiProperty("readWriteString", "{\"primitive\":\"string\"}")] - public virtual string ReadWriteString + public string ReadWriteString { get => GetInstanceProperty(); set => SetInstanceProperty(value); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IRandomNumberGeneratorProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IRandomNumberGeneratorProxy.cs index 8bccac1c90..b5618dda28 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IRandomNumberGeneratorProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IRandomNumberGeneratorProxy.cs @@ -3,8 +3,8 @@ namespace Amazon.JSII.Tests.CalculatorNamespace { /// Generates random numbers. - [JsiiInterfaceProxy(typeof(IIRandomNumberGenerator), "jsii-calc.IRandomNumberGenerator")] - internal class IRandomNumberGeneratorProxy : DeputyBase, IIRandomNumberGenerator + [JsiiTypeProxy(typeof(IIRandomNumberGenerator), "jsii-calc.IRandomNumberGenerator")] + internal sealed class IRandomNumberGeneratorProxy : DeputyBase, IIRandomNumberGenerator { private IRandomNumberGeneratorProxy(ByRefValue reference): base(reference) { @@ -13,7 +13,7 @@ private IRandomNumberGeneratorProxy(ByRefValue reference): base(reference) /// Returns another random number. /// A random number. [JsiiMethod("next", "{\"primitive\":\"number\"}", "[]")] - public virtual double Next() + public double Next() { return InvokeInstanceMethod(new object[]{}); } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ImplictBaseOfBaseProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ImplictBaseOfBaseProxy.cs index 28bcc86414..1237d49015 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ImplictBaseOfBaseProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ImplictBaseOfBaseProxy.cs @@ -4,29 +4,29 @@ namespace Amazon.JSII.Tests.CalculatorNamespace { - [JsiiInterfaceProxy(typeof(IImplictBaseOfBase), "jsii-calc.ImplictBaseOfBase")] - internal class ImplictBaseOfBaseProxy : DeputyBase, IImplictBaseOfBase + [JsiiTypeProxy(typeof(IImplictBaseOfBase), "jsii-calc.ImplictBaseOfBase")] + internal sealed class ImplictBaseOfBaseProxy : DeputyBase, IImplictBaseOfBase { private ImplictBaseOfBaseProxy(ByRefValue reference): base(reference) { } [JsiiProperty("goo", "{\"primitive\":\"date\"}")] - public virtual DateTime Goo + public DateTime Goo { get => GetInstanceProperty(); set => SetInstanceProperty(value); } [JsiiProperty("bar", "{\"primitive\":\"string\"}")] - public virtual string Bar + public string Bar { get => GetInstanceProperty(); set => SetInstanceProperty(value); } [JsiiProperty("foo", "{\"fqn\":\"@scope/jsii-calc-base-of-base.Very\"}")] - public virtual Very Foo + public Very Foo { get => GetInstanceProperty(); set => SetInstanceProperty(value); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceImplementedByAbstractClassProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceImplementedByAbstractClassProxy.cs index 5440d7618a..117c49e27d 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceImplementedByAbstractClassProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceImplementedByAbstractClassProxy.cs @@ -6,15 +6,15 @@ namespace Amazon.JSII.Tests.CalculatorNamespace /// awslabs/jsii#220 /// Abstract return type /// - [JsiiInterfaceProxy(typeof(IInterfaceImplementedByAbstractClass), "jsii-calc.InterfaceImplementedByAbstractClass")] - internal class InterfaceImplementedByAbstractClassProxy : DeputyBase, IInterfaceImplementedByAbstractClass + [JsiiTypeProxy(typeof(IInterfaceImplementedByAbstractClass), "jsii-calc.InterfaceImplementedByAbstractClass")] + internal sealed class InterfaceImplementedByAbstractClassProxy : DeputyBase, IInterfaceImplementedByAbstractClass { private InterfaceImplementedByAbstractClassProxy(ByRefValue reference): base(reference) { } [JsiiProperty("propFromInterface", "{\"primitive\":\"string\"}")] - public virtual string PropFromInterface + public string PropFromInterface { get => GetInstanceProperty(); } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/HelloProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/HelloProxy.cs index 0f9fe1639d..db1be87e57 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/HelloProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/HelloProxy.cs @@ -2,15 +2,15 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceIncludesClasses { - [JsiiInterfaceProxy(typeof(IHello), "jsii-calc.InterfaceInNamespaceIncludesClasses.Hello")] - internal class HelloProxy : DeputyBase, Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceIncludesClasses.IHello + [JsiiTypeProxy(typeof(IHello), "jsii-calc.InterfaceInNamespaceIncludesClasses.Hello")] + internal sealed class HelloProxy : DeputyBase, Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceIncludesClasses.IHello { private HelloProxy(ByRefValue reference): base(reference) { } [JsiiProperty("foo", "{\"primitive\":\"number\"}")] - public virtual double Foo + public double Foo { get => GetInstanceProperty(); set => SetInstanceProperty(value); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/HelloProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/HelloProxy.cs index 129132b37c..a4be597f08 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/HelloProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/HelloProxy.cs @@ -2,15 +2,15 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceOnlyInterface { - [JsiiInterfaceProxy(typeof(IHello), "jsii-calc.InterfaceInNamespaceOnlyInterface.Hello")] - internal class HelloProxy : DeputyBase, Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceOnlyInterface.IHello + [JsiiTypeProxy(typeof(IHello), "jsii-calc.InterfaceInNamespaceOnlyInterface.Hello")] + internal sealed class HelloProxy : DeputyBase, Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceOnlyInterface.IHello { private HelloProxy(ByRefValue reference): base(reference) { } [JsiiProperty("foo", "{\"primitive\":\"number\"}")] - public virtual double Foo + public double Foo { get => GetInstanceProperty(); set => SetInstanceProperty(value); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceWithOptionalMethodArgumentsProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceWithOptionalMethodArgumentsProxy.cs index 790775190f..bc3fc3c77e 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceWithOptionalMethodArgumentsProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceWithOptionalMethodArgumentsProxy.cs @@ -6,15 +6,15 @@ namespace Amazon.JSII.Tests.CalculatorNamespace /// awslabs/jsii#175 /// Interface proxies (and builders) do not respect optional arguments in methods /// - [JsiiInterfaceProxy(typeof(IInterfaceWithOptionalMethodArguments), "jsii-calc.InterfaceWithOptionalMethodArguments")] - internal class InterfaceWithOptionalMethodArgumentsProxy : DeputyBase, IInterfaceWithOptionalMethodArguments + [JsiiTypeProxy(typeof(IInterfaceWithOptionalMethodArguments), "jsii-calc.InterfaceWithOptionalMethodArguments")] + internal sealed class InterfaceWithOptionalMethodArgumentsProxy : DeputyBase, IInterfaceWithOptionalMethodArguments { private InterfaceWithOptionalMethodArgumentsProxy(ByRefValue reference): base(reference) { } [JsiiMethod("hello", null, "[{\"name\":\"arg1\",\"type\":{\"primitive\":\"string\"}},{\"name\":\"arg2\",\"type\":{\"primitive\":\"number\",\"optional\":true}}]")] - public virtual void Hello(string arg1, double? arg2) + public void Hello(string arg1, double? arg2) { InvokeInstanceVoidMethod(new object[]{arg1, arg2}); } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ReturnsNumberProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ReturnsNumberProxy.cs index 1abd7f0a89..f8fba91891 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ReturnsNumberProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ReturnsNumberProxy.cs @@ -2,21 +2,21 @@ namespace Amazon.JSII.Tests.CalculatorNamespace { - [JsiiInterfaceProxy(typeof(IReturnsNumber), "jsii-calc.ReturnsNumber")] - internal class ReturnsNumberProxy : DeputyBase, IReturnsNumber + [JsiiTypeProxy(typeof(IReturnsNumber), "jsii-calc.ReturnsNumber")] + internal sealed class ReturnsNumberProxy : DeputyBase, IReturnsNumber { private ReturnsNumberProxy(ByRefValue reference): base(reference) { } [JsiiProperty("numberProp", "{\"primitive\":\"number\"}")] - public virtual double NumberProp + public double NumberProp { get => GetInstanceProperty(); } [JsiiMethod("obtainNumber", "{\"primitive\":\"number\"}", "[]")] - public virtual double ObtainNumber() + public double ObtainNumber() { return InvokeInstanceMethod(new object[]{}); } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnaryOperationProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnaryOperationProxy.cs new file mode 100644 index 0000000000..83928a7ef3 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnaryOperationProxy.cs @@ -0,0 +1,27 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + /// An operation on a single operand. + [JsiiTypeProxy(typeof(UnaryOperation), "jsii-calc.UnaryOperation")] + internal sealed class UnaryOperationProxy : UnaryOperation + { + private UnaryOperationProxy(ByRefValue reference): base(reference) + { + } + + /// The value. + [JsiiProperty("value", "{\"primitive\":\"number\"}")] + public override double Value + { + get => GetInstanceProperty(); + } + + /// String representation of the value. + [JsiiMethod("toString", "{\"primitive\":\"string\"}", "[]")] + public override string ToString() + { + return InvokeInstanceMethod(new object[]{}); + } + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnionPropertiesProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnionPropertiesProxy.cs index 1266146265..a8fe7bd1fd 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnionPropertiesProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnionPropertiesProxy.cs @@ -2,21 +2,21 @@ namespace Amazon.JSII.Tests.CalculatorNamespace { - [JsiiInterfaceProxy(typeof(IUnionProperties), "jsii-calc.UnionProperties")] - internal class UnionPropertiesProxy : DeputyBase, IUnionProperties + [JsiiTypeProxy(typeof(IUnionProperties), "jsii-calc.UnionProperties")] + internal sealed class UnionPropertiesProxy : DeputyBase, IUnionProperties { private UnionPropertiesProxy(ByRefValue reference): base(reference) { } [JsiiProperty("bar", "{\"union\":{\"types\":[{\"primitive\":\"string\"},{\"primitive\":\"number\"},{\"fqn\":\"jsii-calc.AllTypes\"}]}}")] - public virtual object Bar + public object Bar { get => GetInstanceProperty(); } [JsiiProperty("foo", "{\"union\":{\"types\":[{\"primitive\":\"string\"},{\"primitive\":\"number\"}]},\"optional\":true}")] - public virtual object Foo + public object Foo { get => GetInstanceProperty(); set => SetInstanceProperty(value); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/composition/CompositeOperationProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/composition/CompositeOperationProxy.cs new file mode 100644 index 0000000000..1d25141ca3 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/composition/CompositeOperationProxy.cs @@ -0,0 +1,24 @@ +using Amazon.JSII.Runtime.Deputy; +using Amazon.JSII.Tests.CalculatorNamespace.LibNamespace; + +namespace Amazon.JSII.Tests.CalculatorNamespace.composition +{ + /// Abstract operation composed from an expression of other operations. + [JsiiTypeProxy(typeof(CompositeOperation_), "jsii-calc.composition.CompositeOperation")] + internal sealed class CompositeOperationProxy : CompositeOperation_ + { + private CompositeOperationProxy(ByRefValue reference): base(reference) + { + } + + /// + /// The expression that this operation consists of. + /// Must be implemented by derived classes. + /// + [JsiiProperty("expression", "{\"fqn\":\"@scope/jsii-calc-lib.Value\"}")] + public override Value_ Expression + { + get => GetInstanceProperty(); + } + } +} \ No newline at end of file