From 94ac569f88d2eabc278aebd73bd90d00a2bf6ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=91=A8=F0=9F=8F=BC=E2=80=8D=F0=9F=92=BB=20Romain=20M?= =?UTF-8?q?arcadier-Muller?= Date: Fri, 11 Jan 2019 15:58:40 +0100 Subject: [PATCH 1/3] fix(kernel): Improve tagged type of wire values When passing references across the JSII language boundary, the static return type of a method is used instead of the runtime type of the object if they are not the same, even if they are compatible. This causes issues that make it impossible to up-cast from methods such as `IConstruct.findChild` that return a super-class that is expected to be up-casted to it's known dynamic type. Fixes #345 --- packages/jsii-kernel/lib/kernel.ts | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/jsii-kernel/lib/kernel.ts b/packages/jsii-kernel/lib/kernel.ts index f12933c7a5..0ebf8bcabf 100644 --- a/packages/jsii-kernel/lib/kernel.ts +++ b/packages/jsii-kernel/lib/kernel.ts @@ -961,7 +961,7 @@ export class Kernel { // have an object id, so we need to allocate one for it. this._debug('creating objref for', v); const fqn = this._fqnForObject(v); - if (!targetType || !spec.isNamedTypeReference(targetType) || fqn === targetType.fqn) { + if (!targetType || !spec.isNamedTypeReference(targetType) || this._isAssignable(fqn, targetType)) { return this._createObjref(v, fqn); } } @@ -1029,6 +1029,31 @@ export class Kernel { return v; } + /** + * Tests whether a given type (by it's FQN) can be assigned to a named type reference. + * + * @param actualTypeFqn the FQN of the type that is being tested. + * @param requiredType the required reference type. + * + * @returns true if ``requiredType`` is a super-type (base class or implemented interface) of the type designated by + * ``actualTypeFqn``. + */ + private _isAssignable(actualTypeFqn: string, requiredType: spec.NamedTypeReference): boolean { + if (requiredType.fqn === actualTypeFqn) { + return true; + } + const actualType = this._typeInfoForFqn(actualTypeFqn); + if (spec.isClassType(actualType) && actualType.base) { + if (this._isAssignable(actualType.base.fqn, requiredType)) { + return true; + } + } + if (spec.isClassOrInterfaceType(actualType) && actualType.interfaces) { + return actualType.interfaces.find(iface => this._isAssignable(iface.fqn, requiredType)) != null; + } + return false; + } + private _toSandboxValues(args: any[]) { return args.map(v => this._toSandbox(v)); } From 8c6d7957b4cc299d0f10290869ba1a1c988262b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=91=A8=F0=9F=8F=BC=E2=80=8D=F0=9F=92=BB=20Romain=20M?= =?UTF-8?q?arcadier-Muller?= Date: Mon, 14 Jan 2019 11:31:55 -0800 Subject: [PATCH 2/3] Add compliance test. --- packages/jsii-calc/lib/compliance.ts | 22 ++- packages/jsii-calc/test/assembly.jsii | 65 +++++++- .../ComplianceTests.cs | 12 +- .../amazon/jsii/testing/ComplianceTest.java | 16 +- packages/jsii-kernel/test/test.kernel.ts | 12 +- .../.jsii | 65 +++++++- .../Tests/CalculatorNamespace/Constructors.cs | 32 ++++ .../CalculatorNamespace/IIPublicInterface.cs | 11 ++ .../IPublicInterfaceProxy.cs | 18 +++ .../CalculatorNamespace/InbetweenClass.cs | 20 +++ .../Tests/CalculatorNamespace/PublicClass.cs | 26 ++++ .../amazon/jsii/tests/calculator/$Module.java | 4 + .../jsii/tests/calculator/Constructors.java | 21 +++ .../tests/calculator/IPublicInterface.java | 20 +++ .../jsii/tests/calculator/InbetweenClass.java | 13 ++ .../jsii/tests/calculator/PublicClass.java | 17 +++ .../expected.jsii-calc/sphinx/jsii-calc.rst | 139 ++++++++++++++++++ .../jsii-reflect/test/classes.expected.txt | 3 + .../test/jsii-tree.test.all.expected.txt | 26 ++++ .../jsii-tree.test.inheritance.expected.txt | 5 + .../test/jsii-tree.test.members.expected.txt | 15 ++ .../test/jsii-tree.test.types.expected.txt | 4 + 22 files changed, 560 insertions(+), 6 deletions(-) create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Constructors.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IIPublicInterface.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IPublicInterfaceProxy.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InbetweenClass.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/PublicClass.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/Constructors.java create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/IPublicInterface.java create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InbetweenClass.java create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/PublicClass.java diff --git a/packages/jsii-calc/lib/compliance.ts b/packages/jsii-calc/lib/compliance.ts index 25e223ab08..157f678aa6 100644 --- a/packages/jsii-calc/lib/compliance.ts +++ b/packages/jsii-calc/lib/compliance.ts @@ -1232,4 +1232,24 @@ export class JsiiAgent { public static get jsiiAgent(): string | undefined { return process.env.JSII_AGENT; } -}; \ No newline at end of file +}; + +// https://github.com/awslabs/jsii/issues/345 +export class PublicClass { + public hello(): void {} +} +export interface IPublicInterface { + bye(): void; +} +export class InbetweenClass extends PublicClass {} +class PrivateClass extends InbetweenClass implements IPublicInterface { + public bye(): void {} +} +export class Constructors { + public static makeClass(): PublicClass { + return new PrivateClass(); + } + public static makeInterface(): IPublicInterface { + return new PrivateClass(); + } +} diff --git a/packages/jsii-calc/test/assembly.jsii b/packages/jsii-calc/test/assembly.jsii index 53de34c5ba..4e3d859f91 100644 --- a/packages/jsii-calc/test/assembly.jsii +++ b/packages/jsii-calc/test/assembly.jsii @@ -1098,6 +1098,31 @@ } ] }, + "jsii-calc.Constructors": { + "assembly": "jsii-calc", + "fqn": "jsii-calc.Constructors", + "initializer": { + "initializer": true + }, + "kind": "class", + "methods": [ + { + "name": "makeClass", + "returns": { + "fqn": "jsii-calc.PublicClass" + }, + "static": true + }, + { + "name": "makeInterface", + "returns": { + "fqn": "jsii-calc.IPublicInterface" + }, + "static": true + } + ], + "name": "Constructors" + }, "jsii-calc.DefaultedConstructorArgument": { "assembly": "jsii-calc", "fqn": "jsii-calc.DefaultedConstructorArgument", @@ -1675,6 +1700,18 @@ } ] }, + "jsii-calc.IPublicInterface": { + "assembly": "jsii-calc", + "fqn": "jsii-calc.IPublicInterface", + "kind": "interface", + "methods": [ + { + "abstract": true, + "name": "bye" + } + ], + "name": "IPublicInterface" + }, "jsii-calc.IRandomNumberGenerator": { "assembly": "jsii-calc", "docs": { @@ -1743,6 +1780,18 @@ } ] }, + "jsii-calc.InbetweenClass": { + "assembly": "jsii-calc", + "base": { + "fqn": "jsii-calc.PublicClass" + }, + "fqn": "jsii-calc.InbetweenClass", + "initializer": { + "initializer": true + }, + "kind": "class", + "name": "InbetweenClass" + }, "jsii-calc.InterfaceImplementedByAbstractClass": { "assembly": "jsii-calc", "datatype": true, @@ -2852,6 +2901,20 @@ } ] }, + "jsii-calc.PublicClass": { + "assembly": "jsii-calc", + "fqn": "jsii-calc.PublicClass", + "initializer": { + "initializer": true + }, + "kind": "class", + "methods": [ + { + "name": "hello" + } + ], + "name": "PublicClass" + }, "jsii-calc.ReferenceEnumFromScopedPackage": { "assembly": "jsii-calc", "docs": { @@ -3762,5 +3825,5 @@ } }, "version": "0.7.13", - "fingerprint": "mc9Rni6GLgVDz8M6CGHapEiYbWsdEIl7CmBI0Qn+KXU=" + "fingerprint": "WNp0Sw1d2+3FaQD0Fn01K4wYQi7Ms3w+NQatOylD1kM=" } 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 a464ae836e..05f8f3230d 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 @@ -874,6 +874,16 @@ public void ReceiveInstanceOfPrivateClass() Assert.True(new ReturnsPrivateImplementationOfInterface().PrivateImplementation.Success); } + [Fact(DisplayName = Prefix + nameof(ObjRefsAreLabelledUsingWithTheMostCorrectType))] + public void ObjRefsAreLabelledUsingWithTheMostCorrectType() + { + var classRef = Constructors.MakeClass(); + var ifaceRef = Constructors.MakeInterface(); + + Assert.Equal(typeof(InbetweenClass), classRef.GetType()); + Assert.NotEqual(typeof(InbetweenClass), ifaceRef.GetType()); + } + class NumberReturner : DeputyBase, IIReturnsNumber { public NumberReturner(double number) @@ -1038,4 +1048,4 @@ public double Next() } } } -} \ No newline at end of file +} diff --git a/packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/ComplianceTest.java b/packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/ComplianceTest.java index 6840b63f31..c2dd9bb095 100644 --- a/packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/ComplianceTest.java +++ b/packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/ComplianceTest.java @@ -17,8 +17,10 @@ import software.amazon.jsii.tests.calculator.GreetingAugmenter; import software.amazon.jsii.tests.calculator.IFriendlier; import software.amazon.jsii.tests.calculator.IFriendlyRandomGenerator; +import software.amazon.jsii.tests.calculator.IPublicInterface; import software.amazon.jsii.tests.calculator.InterfaceWithProperties; import software.amazon.jsii.tests.calculator.IRandomNumberGenerator; +import software.amazon.jsii.tests.calculator.InbetweenClass; import software.amazon.jsii.tests.calculator.InterfaceImplementedByAbstractClass; import software.amazon.jsii.tests.calculator.JSObjectLiteralForInterface; import software.amazon.jsii.tests.calculator.JSObjectLiteralToNative; @@ -31,6 +33,7 @@ import software.amazon.jsii.tests.calculator.NumberGenerator; import software.amazon.jsii.tests.calculator.Polymorphism; import software.amazon.jsii.tests.calculator.Power; +import software.amazon.jsii.tests.calculator.PublicClass; import software.amazon.jsii.tests.calculator.ReferenceEnumFromScopedPackage; import software.amazon.jsii.tests.calculator.ReturnsPrivateImplementationOfInterface; import software.amazon.jsii.tests.calculator.Statics; @@ -48,6 +51,8 @@ import software.amazon.jsii.tests.calculator.lib.Value; import software.amazon.jsii.tests.calculator.JavaReservedWords; import software.amazon.jsii.tests.calculator.ClassWithPrivateConstructorAndAutomaticProperties; +import software.amazon.jsii.tests.calculator.Constructors; + import org.junit.Test; import java.io.IOException; @@ -954,7 +959,7 @@ public void nullShouldBeTreatedAsUndefined() { obj.setChangeMeToUndefined(null); obj.verifyPropertyIsUndefined(); } - + @Test public void testJsiiAgent() { assertEquals("Java/" + System.getProperty("java.version"), JsiiAgent.getJsiiAgent()); @@ -968,6 +973,15 @@ public void receiveInstanceOfPrivateClass() { assertTrue(new ReturnsPrivateImplementationOfInterface().getPrivateImplementation().getSuccess()); } + @Test + public void objRefsAreLabelledUsingWithTheMostCorrectType() { + final PublicClass classRef = Constructors.makeClass(); + final IPublicInterface ifaceRef = Constructors.makeInterface(); + + assertTrue(classRef instanceof InbetweenClass); + assertTrue(ifaceRef instanceof IPublicInterface); + } + static class MulTen extends Multiply { public MulTen(final int value) { super(new Number(value), new Number(10)); diff --git a/packages/jsii-kernel/test/test.kernel.ts b/packages/jsii-kernel/test/test.kernel.ts index 4b88f84187..e602fa1d6b 100644 --- a/packages/jsii-kernel/test/test.kernel.ts +++ b/packages/jsii-kernel/test/test.kernel.ts @@ -885,7 +885,7 @@ defineTest('object literals are returned by reference', async (test, sandbox) => test.equal(newValue, sandbox.get({ - objref: sandbox.get({ objref, property: 'mutableObject' }).value, + objref: sandbox.get({ objref, property: 'mutableObject' }).value, property: 'value' }).value); @@ -963,6 +963,16 @@ defineTest('JSII_AGENT is undefined in node.js', async (test, sandbox) => { test.equal(sandbox.sget({ fqn: 'jsii-calc.JsiiAgent', property: 'jsiiAgent' }).value, undefined); }); +defineTest('ObjRefs are labeled with the "most correct" type', async (test, sandbox) => { + const classRef = sandbox.sinvoke({ fqn: 'jsii-calc.Constructors', method: 'makeClass' }).result as api.ObjRef; + const ifaceRef = sandbox.sinvoke({ fqn: 'jsii-calc.Constructors', method: 'makeInterface' }).result as api.ObjRef; + + test.ok(classRef[api.TOKEN_REF].startsWith('jsii-calc.InbetweenClass'), + `${classRef[api.TOKEN_REF]} starts with jsii-calc.InbetweenClass`); + test.ok(ifaceRef[api.TOKEN_REF].startsWith('jsii-calc.IPublicInterface'), + `${ifaceRef[api.TOKEN_REF]} starts with jsii-calc.IPublicInterface`); +}); + // ================================================================================================= const testNames: { [name: string]: boolean } = { }; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii index 53de34c5ba..4e3d859f91 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii @@ -1098,6 +1098,31 @@ } ] }, + "jsii-calc.Constructors": { + "assembly": "jsii-calc", + "fqn": "jsii-calc.Constructors", + "initializer": { + "initializer": true + }, + "kind": "class", + "methods": [ + { + "name": "makeClass", + "returns": { + "fqn": "jsii-calc.PublicClass" + }, + "static": true + }, + { + "name": "makeInterface", + "returns": { + "fqn": "jsii-calc.IPublicInterface" + }, + "static": true + } + ], + "name": "Constructors" + }, "jsii-calc.DefaultedConstructorArgument": { "assembly": "jsii-calc", "fqn": "jsii-calc.DefaultedConstructorArgument", @@ -1675,6 +1700,18 @@ } ] }, + "jsii-calc.IPublicInterface": { + "assembly": "jsii-calc", + "fqn": "jsii-calc.IPublicInterface", + "kind": "interface", + "methods": [ + { + "abstract": true, + "name": "bye" + } + ], + "name": "IPublicInterface" + }, "jsii-calc.IRandomNumberGenerator": { "assembly": "jsii-calc", "docs": { @@ -1743,6 +1780,18 @@ } ] }, + "jsii-calc.InbetweenClass": { + "assembly": "jsii-calc", + "base": { + "fqn": "jsii-calc.PublicClass" + }, + "fqn": "jsii-calc.InbetweenClass", + "initializer": { + "initializer": true + }, + "kind": "class", + "name": "InbetweenClass" + }, "jsii-calc.InterfaceImplementedByAbstractClass": { "assembly": "jsii-calc", "datatype": true, @@ -2852,6 +2901,20 @@ } ] }, + "jsii-calc.PublicClass": { + "assembly": "jsii-calc", + "fqn": "jsii-calc.PublicClass", + "initializer": { + "initializer": true + }, + "kind": "class", + "methods": [ + { + "name": "hello" + } + ], + "name": "PublicClass" + }, "jsii-calc.ReferenceEnumFromScopedPackage": { "assembly": "jsii-calc", "docs": { @@ -3762,5 +3825,5 @@ } }, "version": "0.7.13", - "fingerprint": "mc9Rni6GLgVDz8M6CGHapEiYbWsdEIl7CmBI0Qn+KXU=" + "fingerprint": "WNp0Sw1d2+3FaQD0Fn01K4wYQi7Ms3w+NQatOylD1kM=" } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Constructors.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Constructors.cs new file mode 100644 index 0000000000..6b93bdf0f2 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Constructors.cs @@ -0,0 +1,32 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + [JsiiClass(typeof(Constructors), "jsii-calc.Constructors", "[]")] + public class Constructors : DeputyBase + { + public Constructors(): base(new DeputyProps(new object[]{})) + { + } + + protected Constructors(ByRefValue reference): base(reference) + { + } + + protected Constructors(DeputyProps props): base(props) + { + } + + [JsiiMethod("makeClass", "{\"fqn\":\"jsii-calc.PublicClass\"}", "[]")] + public static PublicClass MakeClass() + { + return InvokeStaticMethod(typeof(Constructors), new object[]{}); + } + + [JsiiMethod("makeInterface", "{\"fqn\":\"jsii-calc.IPublicInterface\"}", "[]")] + public static IIPublicInterface MakeInterface() + { + return InvokeStaticMethod(typeof(Constructors), 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/IIPublicInterface.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IIPublicInterface.cs new file mode 100644 index 0000000000..0c7b567757 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IIPublicInterface.cs @@ -0,0 +1,11 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + [JsiiInterface(typeof(IIPublicInterface), "jsii-calc.IPublicInterface")] + public interface IIPublicInterface + { + [JsiiMethod("bye", null, "[]")] + void Bye(); + } +} \ 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/IPublicInterfaceProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IPublicInterfaceProxy.cs new file mode 100644 index 0000000000..c06f7c1929 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IPublicInterfaceProxy.cs @@ -0,0 +1,18 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + [JsiiTypeProxy(typeof(IIPublicInterface), "jsii-calc.IPublicInterface")] + internal sealed class IPublicInterfaceProxy : DeputyBase, IIPublicInterface + { + private IPublicInterfaceProxy(ByRefValue reference): base(reference) + { + } + + [JsiiMethod("bye", null, "[]")] + public void Bye() + { + InvokeInstanceVoidMethod(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/InbetweenClass.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InbetweenClass.cs new file mode 100644 index 0000000000..6a678944a1 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InbetweenClass.cs @@ -0,0 +1,20 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + [JsiiClass(typeof(InbetweenClass), "jsii-calc.InbetweenClass", "[]")] + public class InbetweenClass : PublicClass + { + public InbetweenClass(): base(new DeputyProps(new object[]{})) + { + } + + protected InbetweenClass(ByRefValue reference): base(reference) + { + } + + protected InbetweenClass(DeputyProps props): base(props) + { + } + } +} \ 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/PublicClass.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/PublicClass.cs new file mode 100644 index 0000000000..d91fa137bf --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/PublicClass.cs @@ -0,0 +1,26 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + [JsiiClass(typeof(PublicClass), "jsii-calc.PublicClass", "[]")] + public class PublicClass : DeputyBase + { + public PublicClass(): base(new DeputyProps(new object[]{})) + { + } + + protected PublicClass(ByRefValue reference): base(reference) + { + } + + protected PublicClass(DeputyProps props): base(props) + { + } + + [JsiiMethod("hello", null, "[]")] + public virtual void Hello() + { + InvokeInstanceVoidMethod(new object[]{}); + } + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java index 9c05612367..15c00426a0 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java @@ -31,6 +31,7 @@ protected Class resolveClass(final String fqn) throws ClassNotFoundException case "jsii-calc.CalculatorProps": return software.amazon.jsii.tests.calculator.CalculatorProps.class; case "jsii-calc.ClassWithMutableObjectLiteralProperty": return software.amazon.jsii.tests.calculator.ClassWithMutableObjectLiteralProperty.class; case "jsii-calc.ClassWithPrivateConstructorAndAutomaticProperties": return software.amazon.jsii.tests.calculator.ClassWithPrivateConstructorAndAutomaticProperties.class; + case "jsii-calc.Constructors": return software.amazon.jsii.tests.calculator.Constructors.class; case "jsii-calc.DefaultedConstructorArgument": return software.amazon.jsii.tests.calculator.DefaultedConstructorArgument.class; case "jsii-calc.DerivedClassHasNoProperties.Base": return software.amazon.jsii.tests.calculator.DerivedClassHasNoProperties.Base.class; case "jsii-calc.DerivedClassHasNoProperties.Derived": return software.amazon.jsii.tests.calculator.DerivedClassHasNoProperties.Derived.class; @@ -48,9 +49,11 @@ protected Class resolveClass(final String fqn) throws ClassNotFoundException case "jsii-calc.IInterfaceWithMethods": return software.amazon.jsii.tests.calculator.IInterfaceWithMethods.class; case "jsii-calc.IInterfaceWithOptionalMethodArguments": return software.amazon.jsii.tests.calculator.IInterfaceWithOptionalMethodArguments.class; case "jsii-calc.IPrivatelyImplemented": return software.amazon.jsii.tests.calculator.IPrivatelyImplemented.class; + case "jsii-calc.IPublicInterface": return software.amazon.jsii.tests.calculator.IPublicInterface.class; case "jsii-calc.IRandomNumberGenerator": return software.amazon.jsii.tests.calculator.IRandomNumberGenerator.class; case "jsii-calc.IReturnsNumber": return software.amazon.jsii.tests.calculator.IReturnsNumber.class; case "jsii-calc.ImplictBaseOfBase": return software.amazon.jsii.tests.calculator.ImplictBaseOfBase.class; + case "jsii-calc.InbetweenClass": return software.amazon.jsii.tests.calculator.InbetweenClass.class; case "jsii-calc.InterfaceImplementedByAbstractClass": return software.amazon.jsii.tests.calculator.InterfaceImplementedByAbstractClass.class; case "jsii-calc.InterfaceInNamespaceIncludesClasses.Foo": return software.amazon.jsii.tests.calculator.InterfaceInNamespaceIncludesClasses.Foo.class; case "jsii-calc.InterfaceInNamespaceIncludesClasses.Hello": return software.amazon.jsii.tests.calculator.InterfaceInNamespaceIncludesClasses.Hello.class; @@ -75,6 +78,7 @@ protected Class resolveClass(final String fqn) throws ClassNotFoundException case "jsii-calc.OverrideReturnsObject": return software.amazon.jsii.tests.calculator.OverrideReturnsObject.class; case "jsii-calc.Polymorphism": return software.amazon.jsii.tests.calculator.Polymorphism.class; case "jsii-calc.Power": return software.amazon.jsii.tests.calculator.Power.class; + case "jsii-calc.PublicClass": return software.amazon.jsii.tests.calculator.PublicClass.class; case "jsii-calc.ReferenceEnumFromScopedPackage": return software.amazon.jsii.tests.calculator.ReferenceEnumFromScopedPackage.class; case "jsii-calc.ReturnsPrivateImplementationOfInterface": return software.amazon.jsii.tests.calculator.ReturnsPrivateImplementationOfInterface.class; case "jsii-calc.RuntimeTypeChecking": return software.amazon.jsii.tests.calculator.RuntimeTypeChecking.class; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/Constructors.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/Constructors.java new file mode 100644 index 0000000000..0e16462262 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/Constructors.java @@ -0,0 +1,21 @@ +package software.amazon.jsii.tests.calculator; + +@javax.annotation.Generated(value = "jsii-pacmak") +@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.Constructors") +public class Constructors extends software.amazon.jsii.JsiiObject { + protected Constructors(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + public Constructors() { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this); + } + + public static software.amazon.jsii.tests.calculator.PublicClass makeClass() { + return software.amazon.jsii.JsiiObject.jsiiStaticCall(software.amazon.jsii.tests.calculator.Constructors.class, "makeClass", software.amazon.jsii.tests.calculator.PublicClass.class); + } + + public static software.amazon.jsii.tests.calculator.IPublicInterface makeInterface() { + return software.amazon.jsii.JsiiObject.jsiiStaticCall(software.amazon.jsii.tests.calculator.Constructors.class, "makeInterface", software.amazon.jsii.tests.calculator.IPublicInterface.class); + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/IPublicInterface.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/IPublicInterface.java new file mode 100644 index 0000000000..1f18b22395 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/IPublicInterface.java @@ -0,0 +1,20 @@ +package software.amazon.jsii.tests.calculator; + +@javax.annotation.Generated(value = "jsii-pacmak") +public interface IPublicInterface extends software.amazon.jsii.JsiiSerializable { + void bye(); + + /** + * A proxy class which represents a concrete javascript instance of this type. + */ + final static class Jsii$Proxy extends software.amazon.jsii.JsiiObject implements software.amazon.jsii.tests.calculator.IPublicInterface { + protected Jsii$Proxy(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + + @Override + public void bye() { + this.jsiiCall("bye", Void.class); + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InbetweenClass.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InbetweenClass.java new file mode 100644 index 0000000000..c2ca0d34d8 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InbetweenClass.java @@ -0,0 +1,13 @@ +package software.amazon.jsii.tests.calculator; + +@javax.annotation.Generated(value = "jsii-pacmak") +@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.InbetweenClass") +public class InbetweenClass extends software.amazon.jsii.tests.calculator.PublicClass { + protected InbetweenClass(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + public InbetweenClass() { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this); + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/PublicClass.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/PublicClass.java new file mode 100644 index 0000000000..a9de73f34f --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/PublicClass.java @@ -0,0 +1,17 @@ +package software.amazon.jsii.tests.calculator; + +@javax.annotation.Generated(value = "jsii-pacmak") +@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.PublicClass") +public class PublicClass extends software.amazon.jsii.JsiiObject { + protected PublicClass(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + public PublicClass() { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this); + } + + public void hello() { + this.jsiiCall("hello", Void.class); + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/sphinx/jsii-calc.rst b/packages/jsii-pacmak/test/expected.jsii-calc/sphinx/jsii-calc.rst index 57c7963fc3..cdf334f411 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/sphinx/jsii-calc.rst +++ b/packages/jsii-pacmak/test/expected.jsii-calc/sphinx/jsii-calc.rst @@ -1105,6 +1105,44 @@ ClassWithPrivateConstructorAndAutomaticProperties :type: string +Constructors +^^^^^^^^^^^^ + +.. py:class:: Constructors() + + **Language-specific names:** + + .. tabs:: + + .. code-tab:: c# + + using Amazon.JSII.Tests.CalculatorNamespace; + + .. code-tab:: java + + import software.amazon.jsii.tests.calculator.Constructors; + + .. code-tab:: javascript + + const { Constructors } = require('jsii-calc'); + + .. code-tab:: typescript + + import { Constructors } from 'jsii-calc'; + + + + + .. py:staticmethod:: makeClass() -> jsii-calc.PublicClass + + :rtype: :py:class:`~jsii-calc.PublicClass`\ + + + .. py:staticmethod:: makeInterface() -> jsii-calc.IPublicInterface + + :rtype: :py:class:`~jsii-calc.IPublicInterface`\ + + DefaultedConstructorArgument ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1937,6 +1975,40 @@ IPrivatelyImplemented (interface) :type: boolean *(readonly)* +IPublicInterface (interface) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. py:class:: IPublicInterface + + **Language-specific names:** + + .. tabs:: + + .. code-tab:: c# + + using Amazon.JSII.Tests.CalculatorNamespace; + + .. code-tab:: java + + import software.amazon.jsii.tests.calculator.IPublicInterface; + + .. code-tab:: javascript + + // IPublicInterface is an interface + + .. code-tab:: typescript + + import { IPublicInterface } from 'jsii-calc'; + + + + + + .. py:method:: bye() + + :abstract: Yes + + IRandomNumberGenerator (interface) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -2070,6 +2142,41 @@ ImplictBaseOfBase (interface) :type: string +InbetweenClass +^^^^^^^^^^^^^^ + +.. py:class:: InbetweenClass() + + **Language-specific names:** + + .. tabs:: + + .. code-tab:: c# + + using Amazon.JSII.Tests.CalculatorNamespace; + + .. code-tab:: java + + import software.amazon.jsii.tests.calculator.InbetweenClass; + + .. code-tab:: javascript + + const { InbetweenClass } = require('jsii-calc'); + + .. code-tab:: typescript + + import { InbetweenClass } from 'jsii-calc'; + + + + :extends: :py:class:`~jsii-calc.PublicClass`\ + + .. py:method:: hello() + + *Inherited from* :py:meth:`jsii-calc.PublicClass ` + + + InterfaceImplementedByAbstractClass (interface) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -3634,6 +3741,38 @@ Power :type: :py:class:`~jsii-calc.composition.CompositeOperation.CompositionStringStyle`\ +PublicClass +^^^^^^^^^^^ + +.. py:class:: PublicClass() + + **Language-specific names:** + + .. tabs:: + + .. code-tab:: c# + + using Amazon.JSII.Tests.CalculatorNamespace; + + .. code-tab:: java + + import software.amazon.jsii.tests.calculator.PublicClass; + + .. code-tab:: javascript + + const { PublicClass } = require('jsii-calc'); + + .. code-tab:: typescript + + import { PublicClass } from 'jsii-calc'; + + + + + .. py:method:: hello() + + + ReferenceEnumFromScopedPackage ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/packages/jsii-reflect/test/classes.expected.txt b/packages/jsii-reflect/test/classes.expected.txt index 0b390d0325..4ec89be366 100644 --- a/packages/jsii-reflect/test/classes.expected.txt +++ b/packages/jsii-reflect/test/classes.expected.txt @@ -12,6 +12,7 @@ Calculator ClassWithMutableObjectLiteralProperty ClassWithPrivateConstructorAndAutomaticProperties CompositeOperation +Constructors DefaultedConstructorArgument Derived DoNotOverridePrivates @@ -22,6 +23,7 @@ ExportedBaseClass Foo GiveMeStructs GreetingAugmenter +InbetweenClass JSObjectLiteralForInterface JSObjectLiteralToNative JSObjectLiteralToNativeClass @@ -39,6 +41,7 @@ OptionalConstructorArgument OverrideReturnsObject Polymorphism Power +PublicClass ReferenceEnumFromScopedPackage ReturnsPrivateImplementationOfInterface RuntimeTypeChecking diff --git a/packages/jsii-reflect/test/jsii-tree.test.all.expected.txt b/packages/jsii-reflect/test/jsii-tree.test.all.expected.txt index 5a03f107e4..128b3d4780 100644 --- a/packages/jsii-reflect/test/jsii-tree.test.all.expected.txt +++ b/packages/jsii-reflect/test/jsii-tree.test.all.expected.txt @@ -237,6 +237,16 @@ assemblies │ │ │ └── type: primitive:string │ │ └─┬ readWriteString property │ │ └── type: primitive:string + │ ├─┬ class Constructors + │ │ └─┬ members + │ │ ├─┬ () method + │ │ │ └── returns: void + │ │ ├─┬ makeClass() method + │ │ │ ├── static + │ │ │ └── returns: class:jsii-calc.PublicClass + │ │ └─┬ makeInterface() method + │ │ ├── static + │ │ └── returns: interface:jsii-calc.IPublicInterface │ ├─┬ class DefaultedConstructorArgument │ │ └─┬ members │ │ ├─┬ (arg1,arg2,arg3) method @@ -357,6 +367,11 @@ assemblies │ │ │ └─┬ friendly │ │ │ └── type: interface:@scope/jsii-calc-lib.IFriendly │ │ └── returns: primitive:string + │ ├─┬ class InbetweenClass + │ │ ├── base: PublicClass + │ │ └─┬ members + │ │ └─┬ () method + │ │ └── returns: void │ ├─┬ class Foo │ │ └─┬ members │ │ ├─┬ () method @@ -668,6 +683,12 @@ assemblies │ │ └─┬ pow property │ │ ├── immutable │ │ └── type: class:@scope/jsii-calc-lib.Value + │ ├─┬ class PublicClass + │ │ └─┬ members + │ │ ├─┬ () method + │ │ │ └── returns: void + │ │ └─┬ hello() method + │ │ └── returns: void │ ├─┬ class ReferenceEnumFromScopedPackage │ │ └─┬ members │ │ ├─┬ () method @@ -1014,6 +1035,11 @@ assemblies │ │ ├── abstract │ │ ├── immutable │ │ └── type: primitive:boolean + │ ├─┬ interface IPublicInterface + │ │ └─┬ members + │ │ └─┬ bye() method + │ │ ├── abstract + │ │ └── returns: void │ ├─┬ interface IRandomNumberGenerator │ │ └─┬ members │ │ └─┬ next() method diff --git a/packages/jsii-reflect/test/jsii-tree.test.inheritance.expected.txt b/packages/jsii-reflect/test/jsii-tree.test.inheritance.expected.txt index e3ba77633d..10f971aaa2 100644 --- a/packages/jsii-reflect/test/jsii-tree.test.inheritance.expected.txt +++ b/packages/jsii-reflect/test/jsii-tree.test.inheritance.expected.txt @@ -19,6 +19,7 @@ assemblies │ ├── class ClassWithMutableObjectLiteralProperty │ ├─┬ class ClassWithPrivateConstructorAndAutomaticProperties │ │ └── interfaces: InterfaceWithProperties + │ ├── class Constructors │ ├── class DefaultedConstructorArgument │ ├── class Base │ ├─┬ class Derived @@ -31,6 +32,8 @@ assemblies │ ├── class ExportedBaseClass │ ├── class GiveMeStructs │ ├── class GreetingAugmenter + │ ├─┬ class InbetweenClass + │ │ └── base: PublicClass │ ├── class Foo │ ├── class JSObjectLiteralForInterface │ ├── class JSObjectLiteralToNative @@ -52,6 +55,7 @@ assemblies │ ├── class Polymorphism │ ├─┬ class Power │ │ └── base: CompositeOperation + │ ├── class PublicClass │ ├── class ReferenceEnumFromScopedPackage │ ├── class ReturnsPrivateImplementationOfInterface │ ├── class RuntimeTypeChecking @@ -86,6 +90,7 @@ assemblies │ ├── interface IInterfaceWithMethods │ ├── interface IInterfaceWithOptionalMethodArguments │ ├── interface IPrivatelyImplemented + │ ├── interface IPublicInterface │ ├── interface IRandomNumberGenerator │ ├── interface IReturnsNumber │ ├─┬ interface ImplictBaseOfBase diff --git a/packages/jsii-reflect/test/jsii-tree.test.members.expected.txt b/packages/jsii-reflect/test/jsii-tree.test.members.expected.txt index 24e6f4162c..1868fe0316 100644 --- a/packages/jsii-reflect/test/jsii-tree.test.members.expected.txt +++ b/packages/jsii-reflect/test/jsii-tree.test.members.expected.txt @@ -90,6 +90,11 @@ assemblies │ │ ├── create(readOnlyString,readWriteString) method │ │ ├── readOnlyString property │ │ └── readWriteString property + │ ├─┬ class Constructors + │ │ └─┬ members + │ │ ├── () method + │ │ ├── makeClass() method + │ │ └── makeInterface() method │ ├─┬ class DefaultedConstructorArgument │ │ └─┬ members │ │ ├── (arg1,arg2,arg3) method @@ -137,6 +142,9 @@ assemblies │ │ └─┬ members │ │ ├── () method │ │ └── betterGreeting(friendly) method + │ ├─┬ class InbetweenClass + │ │ └─┬ members + │ │ └── () method │ ├─┬ class Foo │ │ └─┬ members │ │ ├── () method @@ -276,6 +284,10 @@ assemblies │ │ ├── base property │ │ ├── expression property │ │ └── pow property + │ ├─┬ class PublicClass + │ │ └─┬ members + │ │ ├── () method + │ │ └── hello() method │ ├─┬ class ReferenceEnumFromScopedPackage │ │ └─┬ members │ │ ├── () method @@ -403,6 +415,9 @@ assemblies │ ├─┬ interface IPrivatelyImplemented │ │ └─┬ members │ │ └── success property + │ ├─┬ interface IPublicInterface + │ │ └─┬ members + │ │ └── bye() method │ ├─┬ interface IRandomNumberGenerator │ │ └─┬ members │ │ └── next() method diff --git a/packages/jsii-reflect/test/jsii-tree.test.types.expected.txt b/packages/jsii-reflect/test/jsii-tree.test.types.expected.txt index 9016018130..f63ab042d6 100644 --- a/packages/jsii-reflect/test/jsii-tree.test.types.expected.txt +++ b/packages/jsii-reflect/test/jsii-tree.test.types.expected.txt @@ -12,6 +12,7 @@ assemblies │ ├── class Calculator │ ├── class ClassWithMutableObjectLiteralProperty │ ├── class ClassWithPrivateConstructorAndAutomaticProperties + │ ├── class Constructors │ ├── class DefaultedConstructorArgument │ ├── class Base │ ├── class Derived @@ -22,6 +23,7 @@ assemblies │ ├── class ExportedBaseClass │ ├── class GiveMeStructs │ ├── class GreetingAugmenter + │ ├── class InbetweenClass │ ├── class Foo │ ├── class JSObjectLiteralForInterface │ ├── class JSObjectLiteralToNative @@ -38,6 +40,7 @@ assemblies │ ├── class OverrideReturnsObject │ ├── class Polymorphism │ ├── class Power + │ ├── class PublicClass │ ├── class ReferenceEnumFromScopedPackage │ ├── class ReturnsPrivateImplementationOfInterface │ ├── class RuntimeTypeChecking @@ -60,6 +63,7 @@ assemblies │ ├── interface IInterfaceWithMethods │ ├── interface IInterfaceWithOptionalMethodArguments │ ├── interface IPrivatelyImplemented + │ ├── interface IPublicInterface │ ├── interface IRandomNumberGenerator │ ├── interface IReturnsNumber │ ├── interface ImplictBaseOfBase From 4ad844f6f2b22f35234bc44450868392d648cc94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=91=A8=F0=9F=8F=BC=E2=80=8D=F0=9F=92=BB=20Romain=20M?= =?UTF-8?q?arcadier-Muller?= Date: Tue, 29 Jan 2019 09:37:47 +0100 Subject: [PATCH 3/3] Add explanation of compliance test use --- packages/jsii-calc/lib/compliance.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/jsii-calc/lib/compliance.ts b/packages/jsii-calc/lib/compliance.ts index 157f678aa6..6b8f984e6f 100644 --- a/packages/jsii-calc/lib/compliance.ts +++ b/packages/jsii-calc/lib/compliance.ts @@ -1234,7 +1234,10 @@ export class JsiiAgent { } }; -// https://github.com/awslabs/jsii/issues/345 +// Ensure the JSII kernel tags instances with the "most appropriate" FQN type label, so that runtimes are able to +// correctly choose the implementation proxy that should be used. Failure to do so could cause situations where userland +// needs to up-cast an instance to an incompatible type, which certain runtimes (such as Java) will prevent. +// @See https://github.com/awslabs/jsii/issues/345 export class PublicClass { public hello(): void {} }