diff --git a/package.json b/package.json index e53f10afa4..606110fa2b 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,15 @@ { - "private": true, - "license": "Apache-2.0", - "devDependencies": { - "lerna": "^3.13.1", - "nodeunit": "^0.11.3", - "nyc": "^13.3.0", - "tslint": "^5.15.0", - "typescript": "^3.4.2" - } + "private": true, + "license": "Apache-2.0", + "devDependencies": { + "lerna": "^3.13.1", + "nodeunit": "^0.11.3", + "nyc": "^13.3.0", + "tslint": "^5.15.0", + "typescript": "^3.4.2" + }, + "repository": { + "type": "git", + "url": "https://github.com/awslabs/jsii.git" + } } diff --git a/packages/jsii-calc-base-of-base/lib/index.ts b/packages/jsii-calc-base-of-base/lib/index.ts index aa560c4725..f197d78cdc 100644 --- a/packages/jsii-calc-base-of-base/lib/index.ts +++ b/packages/jsii-calc-base-of-base/lib/index.ts @@ -1,3 +1,7 @@ +export interface IVeryBaseInterface { + foo(): void; +} + export interface VeryBaseProps { readonly foo: Very; } diff --git a/packages/jsii-calc-base-of-base/test/assembly.jsii b/packages/jsii-calc-base-of-base/test/assembly.jsii index c5d0c563c3..6882cf9a35 100644 --- a/packages/jsii-calc-base-of-base/test/assembly.jsii +++ b/packages/jsii-calc-base-of-base/test/assembly.jsii @@ -39,6 +39,26 @@ "sphinx": {} }, "types": { + "@scope/jsii-calc-base-of-base.IVeryBaseInterface": { + "assembly": "@scope/jsii-calc-base-of-base", + "fqn": "@scope/jsii-calc-base-of-base.IVeryBaseInterface", + "kind": "interface", + "locationInModule": { + "filename": "lib/index.ts", + "line": 1 + }, + "methods": [ + { + "abstract": true, + "locationInModule": { + "filename": "lib/index.ts", + "line": 2 + }, + "name": "foo" + } + ], + "name": "IVeryBaseInterface" + }, "@scope/jsii-calc-base-of-base.Very": { "assembly": "@scope/jsii-calc-base-of-base", "fqn": "@scope/jsii-calc-base-of-base.Very", @@ -46,13 +66,13 @@ "kind": "class", "locationInModule": { "filename": "lib/index.ts", - "line": 5 + "line": 9 }, "methods": [ { "locationInModule": { "filename": "lib/index.ts", - "line": 6 + "line": 10 }, "name": "hey", "returns": { @@ -71,7 +91,7 @@ "kind": "interface", "locationInModule": { "filename": "lib/index.ts", - "line": 1 + "line": 5 }, "name": "VeryBaseProps", "properties": [ @@ -80,7 +100,7 @@ "immutable": true, "locationInModule": { "filename": "lib/index.ts", - "line": 2 + "line": 6 }, "name": "foo", "type": { @@ -91,5 +111,5 @@ } }, "version": "0.9.0", - "fingerprint": "1O+di7RZanglLmeCs57JLdO5m98kRnkL4uLPnDbm/z4=" + "fingerprint": "ENFUcMchPwpuq+F97Ft6h/qSsOv03zzW/rOn+EpnPkM=" } diff --git a/packages/jsii-calc-base/lib/index.ts b/packages/jsii-calc-base/lib/index.ts index 2d76415436..284de8c438 100644 --- a/packages/jsii-calc-base/lib/index.ts +++ b/packages/jsii-calc-base/lib/index.ts @@ -1,4 +1,4 @@ -import { VeryBaseProps } from '@scope/jsii-calc-base-of-base'; +import { IVeryBaseInterface, VeryBaseProps } from '@scope/jsii-calc-base-of-base'; /** * A base class. @@ -15,3 +15,7 @@ export abstract class Base { export interface BaseProps extends VeryBaseProps { readonly bar: string; } + +export interface IBaseInterface extends IVeryBaseInterface { + bar(): void; +} \ No newline at end of file diff --git a/packages/jsii-calc-base/test/assembly.jsii b/packages/jsii-calc-base/test/assembly.jsii index 13a139704e..fadd1b5c46 100644 --- a/packages/jsii-calc-base/test/assembly.jsii +++ b/packages/jsii-calc-base/test/assembly.jsii @@ -33,6 +33,32 @@ "version": "0.9.0" } }, + "dependencyClosure": { + "@scope/jsii-calc-base-of-base": { + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-base-of-base", + "groupId": "software.amazon.jsii.tests" + }, + "package": "software.amazon.jsii.tests.calculator.baseofbase" + }, + "js": { + "npm": "@scope/jsii-calc-base-of-base" + }, + "python": { + "distName": "scope.jsii-calc-base-of-base", + "module": "scope.jsii_calc_base_of_base" + }, + "sphinx": {} + }, + "version": "0.9.0" + } + }, "description": "An example direct dependency for jsii-calc.", "homepage": "https://github.com/awslabs/jsii.git", "jsiiVersion": "0.9.0", @@ -124,8 +150,31 @@ } } ] + }, + "@scope/jsii-calc-base.IBaseInterface": { + "assembly": "@scope/jsii-calc-base", + "fqn": "@scope/jsii-calc-base.IBaseInterface", + "interfaces": [ + "@scope/jsii-calc-base-of-base.IVeryBaseInterface" + ], + "kind": "interface", + "locationInModule": { + "filename": "lib/index.ts", + "line": 19 + }, + "methods": [ + { + "abstract": true, + "locationInModule": { + "filename": "lib/index.ts", + "line": 20 + }, + "name": "bar" + } + ], + "name": "IBaseInterface" } }, "version": "0.9.0", - "fingerprint": "iWT7GmFaVPERM/zg8WXtKv7ydudD28ixjJDVfms7DJ4=" + "fingerprint": "8qBW6Salzbq8ies06F/P6IebT87rHy8zDsbL8JqBrvI=" } diff --git a/packages/jsii-calc-lib/lib/index.ts b/packages/jsii-calc-lib/lib/index.ts index 414f81d788..c1e1a616aa 100644 --- a/packages/jsii-calc-lib/lib/index.ts +++ b/packages/jsii-calc-lib/lib/index.ts @@ -98,3 +98,13 @@ export enum EnumFromScopedModule { Value1, Value2 } + +/** + * Interface that inherits from packages 2 levels up the tree + * + * Their presence validates that .NET/Java/jsii-reflect can track all fields + * far enough up the tree. + */ +export interface IThreeLevelsInterface extends base.IBaseInterface { + baz(): void; +} \ No newline at end of file diff --git a/packages/jsii-calc-lib/test/assembly.jsii b/packages/jsii-calc-lib/test/assembly.jsii index 471b302e03..e6645d0a0a 100644 --- a/packages/jsii-calc-lib/test/assembly.jsii +++ b/packages/jsii-calc-lib/test/assembly.jsii @@ -9,32 +9,32 @@ }, "dependencies": { "@scope/jsii-calc-base": { - "dependencies": { - "@scope/jsii-calc-base-of-base": { - "targets": { - "dotnet": { - "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", - "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" - }, - "java": { - "maven": { - "artifactId": "calculator-base-of-base", - "groupId": "software.amazon.jsii.tests" - }, - "package": "software.amazon.jsii.tests.calculator.baseofbase" - }, - "js": { - "npm": "@scope/jsii-calc-base-of-base" - }, - "python": { - "distName": "scope.jsii-calc-base-of-base", - "module": "scope.jsii_calc_base_of_base" - }, - "sphinx": {} + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BasePackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-base", + "groupId": "software.amazon.jsii.tests" }, - "version": "0.9.0" - } + "package": "software.amazon.jsii.tests.calculator.base" + }, + "js": { + "npm": "@scope/jsii-calc-base" + }, + "python": { + "distName": "scope.jsii-calc-base", + "module": "scope.jsii_calc_base" + }, + "sphinx": {} }, + "version": "0.9.0" + } + }, + "dependencyClosure": { + "@scope/jsii-calc-base": { "targets": { "dotnet": { "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace", @@ -57,6 +57,30 @@ "sphinx": {} }, "version": "0.9.0" + }, + "@scope/jsii-calc-base-of-base": { + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-base-of-base", + "groupId": "software.amazon.jsii.tests" + }, + "package": "software.amazon.jsii.tests.calculator.baseofbase" + }, + "js": { + "npm": "@scope/jsii-calc-base-of-base" + }, + "python": { + "distName": "scope.jsii-calc-base-of-base", + "module": "scope.jsii_calc_base_of_base" + }, + "sphinx": {} + }, + "version": "0.9.0" } }, "description": "A simple calcuator library built on JSII.", @@ -171,6 +195,33 @@ ], "name": "IFriendly" }, + "@scope/jsii-calc-lib.IThreeLevelsInterface": { + "assembly": "@scope/jsii-calc-lib", + "docs": { + "remarks": "Their presence validates that .NET/Java/jsii-reflect can track all fields\nfar enough up the tree.", + "summary": "Interface that inherits from packages 2 levels up the tree." + }, + "fqn": "@scope/jsii-calc-lib.IThreeLevelsInterface", + "interfaces": [ + "@scope/jsii-calc-base.IBaseInterface" + ], + "kind": "interface", + "locationInModule": { + "filename": "lib/index.ts", + "line": 108 + }, + "methods": [ + { + "abstract": true, + "locationInModule": { + "filename": "lib/index.ts", + "line": 109 + }, + "name": "baz" + } + ], + "name": "IThreeLevelsInterface" + }, "@scope/jsii-calc-lib.MyFirstStruct": { "assembly": "@scope/jsii-calc-lib", "datatype": true, @@ -445,5 +496,5 @@ } }, "version": "0.9.0", - "fingerprint": "/aA8aq2OBJL26oZOAhZj4Gi1QaKDqfEKQj3ONPxmbBM=" + "fingerprint": "bBNOrdlsau3qqxF1iTo055PjEb8RSSExF6rQNNnIwAY=" } diff --git a/packages/jsii-calc/test/assembly.jsii b/packages/jsii-calc/test/assembly.jsii index fa4dfbcaee..658c2d8cf7 100644 --- a/packages/jsii-calc/test/assembly.jsii +++ b/packages/jsii-calc/test/assembly.jsii @@ -35,32 +35,6 @@ ], "dependencies": { "@scope/jsii-calc-base": { - "dependencies": { - "@scope/jsii-calc-base-of-base": { - "targets": { - "dotnet": { - "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", - "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" - }, - "java": { - "maven": { - "artifactId": "calculator-base-of-base", - "groupId": "software.amazon.jsii.tests" - }, - "package": "software.amazon.jsii.tests.calculator.baseofbase" - }, - "js": { - "npm": "@scope/jsii-calc-base-of-base" - }, - "python": { - "distName": "scope.jsii-calc-base-of-base", - "module": "scope.jsii_calc_base_of_base" - }, - "sphinx": {} - }, - "version": "0.9.0" - } - }, "targets": { "dotnet": { "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace", @@ -109,58 +83,80 @@ "version": "0.9.0" }, "@scope/jsii-calc-lib": { - "dependencies": { - "@scope/jsii-calc-base": { - "dependencies": { - "@scope/jsii-calc-base-of-base": { - "targets": { - "dotnet": { - "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", - "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" - }, - "java": { - "maven": { - "artifactId": "calculator-base-of-base", - "groupId": "software.amazon.jsii.tests" - }, - "package": "software.amazon.jsii.tests.calculator.baseofbase" - }, - "js": { - "npm": "@scope/jsii-calc-base-of-base" - }, - "python": { - "distName": "scope.jsii-calc-base-of-base", - "module": "scope.jsii_calc_base_of_base" - }, - "sphinx": {} - }, - "version": "0.9.0" - } + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.LibNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.LibPackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-lib", + "groupId": "software.amazon.jsii.tests" }, - "targets": { - "dotnet": { - "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace", - "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BasePackageId" - }, - "java": { - "maven": { - "artifactId": "calculator-base", - "groupId": "software.amazon.jsii.tests" - }, - "package": "software.amazon.jsii.tests.calculator.base" - }, - "js": { - "npm": "@scope/jsii-calc-base" - }, - "python": { - "distName": "scope.jsii-calc-base", - "module": "scope.jsii_calc_base" - }, - "sphinx": {} + "package": "software.amazon.jsii.tests.calculator.lib" + }, + "js": { + "npm": "@scope/jsii-calc-lib" + }, + "python": { + "distName": "scope.jsii-calc-lib", + "module": "scope.jsii_calc_lib" + }, + "sphinx": {} + }, + "version": "0.9.0" + } + }, + "dependencyClosure": { + "@scope/jsii-calc-base": { + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BasePackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-base", + "groupId": "software.amazon.jsii.tests" }, - "version": "0.9.0" - } + "package": "software.amazon.jsii.tests.calculator.base" + }, + "js": { + "npm": "@scope/jsii-calc-base" + }, + "python": { + "distName": "scope.jsii-calc-base", + "module": "scope.jsii_calc_base" + }, + "sphinx": {} }, + "version": "0.9.0" + }, + "@scope/jsii-calc-base-of-base": { + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-base-of-base", + "groupId": "software.amazon.jsii.tests" + }, + "package": "software.amazon.jsii.tests.calculator.baseofbase" + }, + "js": { + "npm": "@scope/jsii-calc-base-of-base" + }, + "python": { + "distName": "scope.jsii-calc-base-of-base", + "module": "scope.jsii_calc_base_of_base" + }, + "sphinx": {} + }, + "version": "0.9.0" + }, + "@scope/jsii-calc-lib": { "targets": { "dotnet": { "namespace": "Amazon.JSII.Tests.CalculatorNamespace.LibNamespace", @@ -6659,5 +6655,5 @@ } }, "version": "0.9.0", - "fingerprint": "F319lrdZvWrVwdgKTX3nSjnYs1YghHSnYqGopWs2N+0=" + "fingerprint": "rheLw7bhMAmuMfbnzQ4tXZyQTSYIydCp59wiBfA8Gpo=" } diff --git a/packages/jsii-pacmak/lib/generator.ts b/packages/jsii-pacmak/lib/generator.ts index a08e791a5e..0291c0d2b7 100644 --- a/packages/jsii-pacmak/lib/generator.ts +++ b/packages/jsii-pacmak/lib/generator.ts @@ -501,43 +501,20 @@ export abstract class Generator implements IGenerator { * Looks up a jsii module in the dependency tree. * @param name The name of the jsii module to look up */ - protected findModule(name: string) { + protected findModule(name: string): spec.PackageVersion { // if this is the current module, return it if (this.assembly.name === name) { return this.assembly; } - // look up in all deps, recursively - const found = lookupModule(this.assembly); - if (!found) { - throw new Error(`Unable to find module ${name} as a direct or indirect dependency of ${this.assembly.name}`); - } - - return found; - - function lookupModule(parent: spec.PackageVersion): spec.PackageVersion | undefined { - const indirect = parent.dependencies && parent.dependencies[name]; - if (indirect) { - return indirect; - } - - for (const depName of Object.keys(parent.dependencies || { })) { - const dep = parent.dependencies![depName]; + const found = (this.assembly.dependencyClosure || {})[name]; - if (depName === name) { - return dep; - } - - const transitive = lookupModule(dep); - if (transitive) { - return transitive; - } - } - - return undefined; + if (found) { + return found; } + throw new Error(`Unable to find module ${name} as a direct or indirect dependency of ${this.assembly.name}`); } protected findType(fqn: string) { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/.jsii b/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/.jsii index 13a139704e..fadd1b5c46 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/.jsii +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/.jsii @@ -33,6 +33,32 @@ "version": "0.9.0" } }, + "dependencyClosure": { + "@scope/jsii-calc-base-of-base": { + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-base-of-base", + "groupId": "software.amazon.jsii.tests" + }, + "package": "software.amazon.jsii.tests.calculator.baseofbase" + }, + "js": { + "npm": "@scope/jsii-calc-base-of-base" + }, + "python": { + "distName": "scope.jsii-calc-base-of-base", + "module": "scope.jsii_calc_base_of_base" + }, + "sphinx": {} + }, + "version": "0.9.0" + } + }, "description": "An example direct dependency for jsii-calc.", "homepage": "https://github.com/awslabs/jsii.git", "jsiiVersion": "0.9.0", @@ -124,8 +150,31 @@ } } ] + }, + "@scope/jsii-calc-base.IBaseInterface": { + "assembly": "@scope/jsii-calc-base", + "fqn": "@scope/jsii-calc-base.IBaseInterface", + "interfaces": [ + "@scope/jsii-calc-base-of-base.IVeryBaseInterface" + ], + "kind": "interface", + "locationInModule": { + "filename": "lib/index.ts", + "line": 19 + }, + "methods": [ + { + "abstract": true, + "locationInModule": { + "filename": "lib/index.ts", + "line": 20 + }, + "name": "bar" + } + ], + "name": "IBaseInterface" } }, "version": "0.9.0", - "fingerprint": "iWT7GmFaVPERM/zg8WXtKv7ydudD28ixjJDVfms7DJ4=" + "fingerprint": "8qBW6Salzbq8ies06F/P6IebT87rHy8zDsbL8JqBrvI=" } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/IBaseInterfaceProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/IBaseInterfaceProxy.cs new file mode 100644 index 0000000000..ddd7a3cc98 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/IBaseInterfaceProxy.cs @@ -0,0 +1,24 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace +{ + [JsiiTypeProxy(nativeType: typeof(IIBaseInterface), fullyQualifiedName: "@scope/jsii-calc-base.IBaseInterface")] + internal sealed class IBaseInterfaceProxy : DeputyBase, IIBaseInterface + { + private IBaseInterfaceProxy(ByRefValue reference): base(reference) + { + } + + [JsiiMethod(name: "bar")] + public void Bar() + { + InvokeInstanceVoidMethod(new object[]{}); + } + + [JsiiMethod(name: "foo")] + public void Foo() + { + InvokeInstanceVoidMethod(new object[]{}); + } + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/IIBaseInterface.cs b/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/IIBaseInterface.cs new file mode 100644 index 0000000000..a20025b3f2 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/dotnet/Amazon.JSII.Tests.CalculatorPackageId.BasePackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseNamespace/IIBaseInterface.cs @@ -0,0 +1,12 @@ +using Amazon.JSII.Runtime.Deputy; +using Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace; + +namespace Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace +{ + [JsiiInterface(nativeType: typeof(IIBaseInterface), fullyQualifiedName: "@scope/jsii-calc-base.IBaseInterface")] + public interface IIBaseInterface : IIVeryBaseInterface + { + [JsiiMethod(name: "bar")] + void Bar(); + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/$Module.java b/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/$Module.java index a9fc3cc96a..cba66e1007 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/$Module.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/$Module.java @@ -20,6 +20,7 @@ protected Class resolveClass(final String fqn) throws ClassNotFoundException switch (fqn) { case "@scope/jsii-calc-base.Base": return software.amazon.jsii.tests.calculator.base.Base.class; case "@scope/jsii-calc-base.BaseProps": return software.amazon.jsii.tests.calculator.base.BaseProps.class; + case "@scope/jsii-calc-base.IBaseInterface": return software.amazon.jsii.tests.calculator.base.IBaseInterface.class; default: throw new ClassNotFoundException("Unknown JSII type: " + fqn); } } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/IBaseInterface.java b/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/IBaseInterface.java new file mode 100644 index 0000000000..dec0576d21 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/IBaseInterface.java @@ -0,0 +1,25 @@ +package software.amazon.jsii.tests.calculator.base; + +@javax.annotation.Generated(value = "jsii-pacmak") +public interface IBaseInterface extends software.amazon.jsii.JsiiSerializable, software.amazon.jsii.tests.calculator.baseofbase.IVeryBaseInterface { + void bar(); + + /** + * 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.base.IBaseInterface { + protected Jsii$Proxy(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + + @Override + public void bar() { + this.jsiiCall("bar", Void.class); + } + + @Override + public void foo() { + this.jsiiCall("foo", Void.class); + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/python/src/scope/jsii_calc_base/__init__.py b/packages/jsii-pacmak/test/expected.jsii-calc-base/python/src/scope/jsii_calc_base/__init__.py index 3f26ac76b7..3aee598c07 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-base/python/src/scope/jsii_calc_base/__init__.py +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/python/src/scope/jsii_calc_base/__init__.py @@ -31,6 +31,24 @@ class _BaseProxy(Base): class BaseProps(scope.jsii_calc_base_of_base.VeryBaseProps, jsii.compat.TypedDict): bar: str -__all__ = ["Base", "BaseProps", "__jsii_assembly__"] +@jsii.interface(jsii_type="@scope/jsii-calc-base.IBaseInterface") +class IBaseInterface(scope.jsii_calc_base_of_base.IVeryBaseInterface, jsii.compat.Protocol): + @staticmethod + def __jsii_proxy_class__(): + return _IBaseInterfaceProxy + + @jsii.member(jsii_name="bar") + def bar(self) -> None: + ... + + +class _IBaseInterfaceProxy(jsii.proxy_for(scope.jsii_calc_base_of_base.IVeryBaseInterface)): + __jsii_type__ = "@scope/jsii-calc-base.IBaseInterface" + @jsii.member(jsii_name="bar") + def bar(self) -> None: + return jsii.invoke(self, "bar", []) + + +__all__ = ["Base", "BaseProps", "IBaseInterface", "__jsii_assembly__"] publication.publish() diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/sphinx/_scope_jsii-calc-base.rst b/packages/jsii-pacmak/test/expected.jsii-calc-base/sphinx/_scope_jsii-calc-base.rst index dd547fb8fc..de80129226 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-base/sphinx/_scope_jsii-calc-base.rst +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/sphinx/_scope_jsii-calc-base.rst @@ -204,3 +204,45 @@ BaseProps (interface) :type: :py:class:`@scope/jsii-calc-base-of-base.Very`\ *(readonly)* +IBaseInterface (interface) +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. py:class:: IBaseInterface + + **Language-specific names:** + + .. tabs:: + + .. code-tab:: c# + + using Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace; + + .. code-tab:: java + + import software.amazon.jsii.tests.calculator.base.IBaseInterface; + + .. code-tab:: javascript + + // IBaseInterface is an interface + + .. code-tab:: typescript + + import { IBaseInterface } from '@scope/jsii-calc-base'; + + + + :extends: :py:class:`@scope/jsii-calc-base-of-base.IVeryBaseInterface`\ + + + .. py:method:: bar() + + :abstract: Yes + + + .. py:method:: foo() + + *Inherited from* :py:meth:`@scope/jsii-calc-base-of-base.IVeryBaseInterface <@scope/jsii-calc-base-of-base.IVeryBaseInterface.foo>` + + :abstract: Yes + + diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/.jsii b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/.jsii index 471b302e03..e6645d0a0a 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/.jsii +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/.jsii @@ -9,32 +9,32 @@ }, "dependencies": { "@scope/jsii-calc-base": { - "dependencies": { - "@scope/jsii-calc-base-of-base": { - "targets": { - "dotnet": { - "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", - "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" - }, - "java": { - "maven": { - "artifactId": "calculator-base-of-base", - "groupId": "software.amazon.jsii.tests" - }, - "package": "software.amazon.jsii.tests.calculator.baseofbase" - }, - "js": { - "npm": "@scope/jsii-calc-base-of-base" - }, - "python": { - "distName": "scope.jsii-calc-base-of-base", - "module": "scope.jsii_calc_base_of_base" - }, - "sphinx": {} + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BasePackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-base", + "groupId": "software.amazon.jsii.tests" }, - "version": "0.9.0" - } + "package": "software.amazon.jsii.tests.calculator.base" + }, + "js": { + "npm": "@scope/jsii-calc-base" + }, + "python": { + "distName": "scope.jsii-calc-base", + "module": "scope.jsii_calc_base" + }, + "sphinx": {} }, + "version": "0.9.0" + } + }, + "dependencyClosure": { + "@scope/jsii-calc-base": { "targets": { "dotnet": { "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace", @@ -57,6 +57,30 @@ "sphinx": {} }, "version": "0.9.0" + }, + "@scope/jsii-calc-base-of-base": { + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-base-of-base", + "groupId": "software.amazon.jsii.tests" + }, + "package": "software.amazon.jsii.tests.calculator.baseofbase" + }, + "js": { + "npm": "@scope/jsii-calc-base-of-base" + }, + "python": { + "distName": "scope.jsii-calc-base-of-base", + "module": "scope.jsii_calc_base_of_base" + }, + "sphinx": {} + }, + "version": "0.9.0" } }, "description": "A simple calcuator library built on JSII.", @@ -171,6 +195,33 @@ ], "name": "IFriendly" }, + "@scope/jsii-calc-lib.IThreeLevelsInterface": { + "assembly": "@scope/jsii-calc-lib", + "docs": { + "remarks": "Their presence validates that .NET/Java/jsii-reflect can track all fields\nfar enough up the tree.", + "summary": "Interface that inherits from packages 2 levels up the tree." + }, + "fqn": "@scope/jsii-calc-lib.IThreeLevelsInterface", + "interfaces": [ + "@scope/jsii-calc-base.IBaseInterface" + ], + "kind": "interface", + "locationInModule": { + "filename": "lib/index.ts", + "line": 108 + }, + "methods": [ + { + "abstract": true, + "locationInModule": { + "filename": "lib/index.ts", + "line": 109 + }, + "name": "baz" + } + ], + "name": "IThreeLevelsInterface" + }, "@scope/jsii-calc-lib.MyFirstStruct": { "assembly": "@scope/jsii-calc-lib", "datatype": true, @@ -445,5 +496,5 @@ } }, "version": "0.9.0", - "fingerprint": "/aA8aq2OBJL26oZOAhZj4Gi1QaKDqfEKQj3ONPxmbBM=" + "fingerprint": "bBNOrdlsau3qqxF1iTo055PjEb8RSSExF6rQNNnIwAY=" } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId.csproj b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId.csproj index 6ef87acaa4..ca29a2487b 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId.csproj +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId.csproj @@ -18,6 +18,5 @@ - \ 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/IIThreeLevelsInterface.cs b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/IIThreeLevelsInterface.cs new file mode 100644 index 0000000000..49bc1dac70 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/IIThreeLevelsInterface.cs @@ -0,0 +1,17 @@ +using Amazon.JSII.Runtime.Deputy; +using Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace; + +namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace +{ + /// Interface that inherits from packages 2 levels up the tree. + /// + /// Their presence validates that .NET/Java/jsii-reflect can track all fields + /// far enough up the tree. + /// + [JsiiInterface(nativeType: typeof(IIThreeLevelsInterface), fullyQualifiedName: "@scope/jsii-calc-lib.IThreeLevelsInterface")] + public interface IIThreeLevelsInterface : IIBaseInterface + { + [JsiiMethod(name: "baz")] + void Baz(); + } +} \ 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/IThreeLevelsInterfaceProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/IThreeLevelsInterfaceProxy.cs new file mode 100644 index 0000000000..63c08992e6 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/IThreeLevelsInterfaceProxy.cs @@ -0,0 +1,35 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace +{ + /// Interface that inherits from packages 2 levels up the tree. + /// + /// Their presence validates that .NET/Java/jsii-reflect can track all fields + /// far enough up the tree. + /// + [JsiiTypeProxy(nativeType: typeof(IIThreeLevelsInterface), fullyQualifiedName: "@scope/jsii-calc-lib.IThreeLevelsInterface")] + internal sealed class IThreeLevelsInterfaceProxy : DeputyBase, IIThreeLevelsInterface + { + private IThreeLevelsInterfaceProxy(ByRefValue reference): base(reference) + { + } + + [JsiiMethod(name: "baz")] + public void Baz() + { + InvokeInstanceVoidMethod(new object[]{}); + } + + [JsiiMethod(name: "bar")] + public void Bar() + { + InvokeInstanceVoidMethod(new object[]{}); + } + + [JsiiMethod(name: "foo")] + public void Foo() + { + InvokeInstanceVoidMethod(new object[]{}); + } + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/$Module.java b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/$Module.java index 33031da6bd..c61429487f 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/$Module.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/$Module.java @@ -21,6 +21,7 @@ protected Class resolveClass(final String fqn) throws ClassNotFoundException case "@scope/jsii-calc-lib.EnumFromScopedModule": return software.amazon.jsii.tests.calculator.lib.EnumFromScopedModule.class; case "@scope/jsii-calc-lib.IDoublable": return software.amazon.jsii.tests.calculator.lib.IDoublable.class; case "@scope/jsii-calc-lib.IFriendly": return software.amazon.jsii.tests.calculator.lib.IFriendly.class; + case "@scope/jsii-calc-lib.IThreeLevelsInterface": return software.amazon.jsii.tests.calculator.lib.IThreeLevelsInterface.class; case "@scope/jsii-calc-lib.MyFirstStruct": return software.amazon.jsii.tests.calculator.lib.MyFirstStruct.class; case "@scope/jsii-calc-lib.Number": return software.amazon.jsii.tests.calculator.lib.Number.class; case "@scope/jsii-calc-lib.Operation": return software.amazon.jsii.tests.calculator.lib.Operation.class; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/IThreeLevelsInterface.java b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/IThreeLevelsInterface.java new file mode 100644 index 0000000000..40ab6d50b2 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/IThreeLevelsInterface.java @@ -0,0 +1,36 @@ +package software.amazon.jsii.tests.calculator.lib; + +/** + * Interface that inherits from packages 2 levels up the tree. + * + * Their presence validates that .NET/Java/jsii-reflect can track all fields + * far enough up the tree. + */ +@javax.annotation.Generated(value = "jsii-pacmak") +public interface IThreeLevelsInterface extends software.amazon.jsii.JsiiSerializable, software.amazon.jsii.tests.calculator.base.IBaseInterface { + void baz(); + + /** + * 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.lib.IThreeLevelsInterface { + protected Jsii$Proxy(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + + @Override + public void baz() { + this.jsiiCall("baz", Void.class); + } + + @Override + public void bar() { + this.jsiiCall("bar", Void.class); + } + + @Override + public void foo() { + this.jsiiCall("foo", Void.class); + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/python/src/scope/jsii_calc_lib/__init__.py b/packages/jsii-pacmak/test/expected.jsii-calc-lib/python/src/scope/jsii_calc_lib/__init__.py index eb2036db6d..1127cb6a95 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/python/src/scope/jsii_calc_lib/__init__.py +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/python/src/scope/jsii_calc_lib/__init__.py @@ -54,6 +54,24 @@ def hello(self) -> str: return jsii.invoke(self, "hello", []) +@jsii.interface(jsii_type="@scope/jsii-calc-lib.IThreeLevelsInterface") +class IThreeLevelsInterface(scope.jsii_calc_base.IBaseInterface, jsii.compat.Protocol): + @staticmethod + def __jsii_proxy_class__(): + return _IThreeLevelsInterfaceProxy + + @jsii.member(jsii_name="baz") + def baz(self) -> None: + ... + + +class _IThreeLevelsInterfaceProxy(jsii.proxy_for(scope.jsii_calc_base.IBaseInterface)): + __jsii_type__ = "@scope/jsii-calc-lib.IThreeLevelsInterface" + @jsii.member(jsii_name="baz") + def baz(self) -> None: + return jsii.invoke(self, "baz", []) + + class _MyFirstStruct(jsii.compat.TypedDict, total=False): firstOptional: typing.List[str] @@ -130,6 +148,6 @@ def to_string(self) -> str: return jsii.invoke(self, "toString", []) -__all__ = ["EnumFromScopedModule", "IDoublable", "IFriendly", "MyFirstStruct", "Number", "Operation", "StructWithOnlyOptionals", "Value", "__jsii_assembly__"] +__all__ = ["EnumFromScopedModule", "IDoublable", "IFriendly", "IThreeLevelsInterface", "MyFirstStruct", "Number", "Operation", "StructWithOnlyOptionals", "Value", "__jsii_assembly__"] publication.publish() diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/sphinx/_scope_jsii-calc-lib.rst b/packages/jsii-pacmak/test/expected.jsii-calc-lib/sphinx/_scope_jsii-calc-lib.rst index 757f62005a..61bb17ad13 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/sphinx/_scope_jsii-calc-lib.rst +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/sphinx/_scope_jsii-calc-lib.rst @@ -246,6 +246,65 @@ IFriendly (interface) :abstract: Yes +IThreeLevelsInterface (interface) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. py:class:: IThreeLevelsInterface + + **Language-specific names:** + + .. tabs:: + + .. code-tab:: c# + + using Amazon.JSII.Tests.CalculatorNamespace.LibNamespace; + + .. code-tab:: java + + import software.amazon.jsii.tests.calculator.lib.IThreeLevelsInterface; + + .. code-tab:: javascript + + // IThreeLevelsInterface is an interface + + .. code-tab:: typescript + + import { IThreeLevelsInterface } from '@scope/jsii-calc-lib'; + + + + Interface that inherits from packages 2 levels up the tree. + + + + Their presence validates that .NET/Java/jsii-reflect can track all fields + + far enough up the tree. + + + + :extends: :py:class:`@scope/jsii-calc-base.IBaseInterface`\ + + + .. py:method:: baz() + + :abstract: Yes + + + .. py:method:: foo() + + *Inherited from* :py:meth:`@scope/jsii-calc-base-of-base.IVeryBaseInterface <@scope/jsii-calc-base-of-base.IVeryBaseInterface.foo>` + + :abstract: Yes + + + .. py:method:: bar() + + *Inherited from* :py:meth:`@scope/jsii-calc-base.IBaseInterface <@scope/jsii-calc-base.IBaseInterface.bar>` + + :abstract: Yes + + MyFirstStruct (interface) ^^^^^^^^^^^^^^^^^^^^^^^^^ 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 fa4dfbcaee..658c2d8cf7 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 @@ -35,32 +35,6 @@ ], "dependencies": { "@scope/jsii-calc-base": { - "dependencies": { - "@scope/jsii-calc-base-of-base": { - "targets": { - "dotnet": { - "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", - "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" - }, - "java": { - "maven": { - "artifactId": "calculator-base-of-base", - "groupId": "software.amazon.jsii.tests" - }, - "package": "software.amazon.jsii.tests.calculator.baseofbase" - }, - "js": { - "npm": "@scope/jsii-calc-base-of-base" - }, - "python": { - "distName": "scope.jsii-calc-base-of-base", - "module": "scope.jsii_calc_base_of_base" - }, - "sphinx": {} - }, - "version": "0.9.0" - } - }, "targets": { "dotnet": { "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace", @@ -109,58 +83,80 @@ "version": "0.9.0" }, "@scope/jsii-calc-lib": { - "dependencies": { - "@scope/jsii-calc-base": { - "dependencies": { - "@scope/jsii-calc-base-of-base": { - "targets": { - "dotnet": { - "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", - "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" - }, - "java": { - "maven": { - "artifactId": "calculator-base-of-base", - "groupId": "software.amazon.jsii.tests" - }, - "package": "software.amazon.jsii.tests.calculator.baseofbase" - }, - "js": { - "npm": "@scope/jsii-calc-base-of-base" - }, - "python": { - "distName": "scope.jsii-calc-base-of-base", - "module": "scope.jsii_calc_base_of_base" - }, - "sphinx": {} - }, - "version": "0.9.0" - } + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.LibNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.LibPackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-lib", + "groupId": "software.amazon.jsii.tests" }, - "targets": { - "dotnet": { - "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace", - "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BasePackageId" - }, - "java": { - "maven": { - "artifactId": "calculator-base", - "groupId": "software.amazon.jsii.tests" - }, - "package": "software.amazon.jsii.tests.calculator.base" - }, - "js": { - "npm": "@scope/jsii-calc-base" - }, - "python": { - "distName": "scope.jsii-calc-base", - "module": "scope.jsii_calc_base" - }, - "sphinx": {} + "package": "software.amazon.jsii.tests.calculator.lib" + }, + "js": { + "npm": "@scope/jsii-calc-lib" + }, + "python": { + "distName": "scope.jsii-calc-lib", + "module": "scope.jsii_calc_lib" + }, + "sphinx": {} + }, + "version": "0.9.0" + } + }, + "dependencyClosure": { + "@scope/jsii-calc-base": { + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BasePackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-base", + "groupId": "software.amazon.jsii.tests" }, - "version": "0.9.0" - } + "package": "software.amazon.jsii.tests.calculator.base" + }, + "js": { + "npm": "@scope/jsii-calc-base" + }, + "python": { + "distName": "scope.jsii-calc-base", + "module": "scope.jsii_calc_base" + }, + "sphinx": {} }, + "version": "0.9.0" + }, + "@scope/jsii-calc-base-of-base": { + "targets": { + "dotnet": { + "namespace": "Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace", + "packageId": "Amazon.JSII.Tests.CalculatorPackageId.BaseOfBasePackageId" + }, + "java": { + "maven": { + "artifactId": "calculator-base-of-base", + "groupId": "software.amazon.jsii.tests" + }, + "package": "software.amazon.jsii.tests.calculator.baseofbase" + }, + "js": { + "npm": "@scope/jsii-calc-base-of-base" + }, + "python": { + "distName": "scope.jsii-calc-base-of-base", + "module": "scope.jsii_calc_base_of_base" + }, + "sphinx": {} + }, + "version": "0.9.0" + }, + "@scope/jsii-calc-lib": { "targets": { "dotnet": { "namespace": "Amazon.JSII.Tests.CalculatorNamespace.LibNamespace", @@ -6659,5 +6655,5 @@ } }, "version": "0.9.0", - "fingerprint": "F319lrdZvWrVwdgKTX3nSjnYs1YghHSnYqGopWs2N+0=" + "fingerprint": "rheLw7bhMAmuMfbnzQ4tXZyQTSYIydCp59wiBfA8Gpo=" } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon.JSII.Tests.CalculatorPackageId.csproj b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon.JSII.Tests.CalculatorPackageId.csproj index 6b84db04ea..c28eaa7f9d 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon.JSII.Tests.CalculatorPackageId.csproj +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon.JSII.Tests.CalculatorPackageId.csproj @@ -19,9 +19,6 @@ - - - \ No newline at end of file diff --git a/packages/jsii-reflect/lib/docs.ts b/packages/jsii-reflect/lib/docs.ts index 247274d291..864af5b327 100644 --- a/packages/jsii-reflect/lib/docs.ts +++ b/packages/jsii-reflect/lib/docs.ts @@ -58,4 +58,12 @@ export class Docs { public customTag(tag: string): string | undefined { return this.docs.custom && this.docs.custom[tag]; } + + public get summary(): string { + return this.docs.summary || ''; + } + + public get remarks(): string { + return this.docs.remarks || ''; + } } \ No newline at end of file diff --git a/packages/jsii-reflect/lib/type-system.ts b/packages/jsii-reflect/lib/type-system.ts index e1bc80c8a2..2927eb5ec3 100644 --- a/packages/jsii-reflect/lib/type-system.ts +++ b/packages/jsii-reflect/lib/type-system.ts @@ -1,4 +1,5 @@ import fs = require('fs'); +import jsii = require('jsii-spec'); import path = require('path'); import { promisify } from 'util'; import { Assembly } from './assembly'; @@ -88,7 +89,7 @@ export class TypeSystem { public async loadFile(file: string, isRoot = true) { const spec = JSON.parse((await readFile(file)).toString()); - return this.addAssembly(new Assembly(this, spec), isRoot); + return this.addAssembly(new Assembly(this, jsii.validateAssembly(spec)), isRoot); } public addAssembly(asm: Assembly, isRoot = true) { 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 6ddbb65257..9bfbe206ef 100644 --- a/packages/jsii-reflect/test/jsii-tree.test.all.expected.txt +++ b/packages/jsii-reflect/test/jsii-tree.test.all.expected.txt @@ -1468,14 +1468,21 @@ assemblies │ │ ├── () initializer │ │ └─┬ typeName() method │ │ └── returns: any - │ └─┬ interface BaseProps + │ ├─┬ interface BaseProps + │ │ ├─┬ interfaces + │ │ │ └── VeryBaseProps + │ │ └─┬ members + │ │ └─┬ bar property + │ │ ├── abstract + │ │ ├── immutable + │ │ └── type: string + │ └─┬ interface IBaseInterface │ ├─┬ interfaces - │ │ └── VeryBaseProps + │ │ └── IVeryBaseInterface │ └─┬ members - │ └─┬ bar property + │ └─┬ bar() method │ ├── abstract - │ ├── immutable - │ └── type: string + │ └── returns: void ├─┬ @scope/jsii-calc-base-of-base │ └─┬ types │ ├─┬ class Very @@ -1483,6 +1490,11 @@ assemblies │ │ ├── () initializer │ │ └─┬ hey() method │ │ └── returns: number + │ ├─┬ interface IVeryBaseInterface + │ │ └─┬ members + │ │ └─┬ foo() method + │ │ ├── abstract + │ │ └── returns: void │ └─┬ interface VeryBaseProps │ └─┬ members │ └─┬ foo property @@ -1535,6 +1547,13 @@ assemblies │ └─┬ hello() method │ ├── abstract │ └── returns: string + ├─┬ interface IThreeLevelsInterface + │ ├─┬ interfaces + │ │ └── IBaseInterface + │ └─┬ members + │ └─┬ baz() method + │ ├── abstract + │ └── returns: void ├─┬ interface MyFirstStruct │ └─┬ members │ ├─┬ anumber property 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 fe802e2cfa..b7da2ff226 100644 --- a/packages/jsii-reflect/test/jsii-tree.test.inheritance.expected.txt +++ b/packages/jsii-reflect/test/jsii-tree.test.inheritance.expected.txt @@ -154,12 +154,16 @@ assemblies ├─┬ @scope/jsii-calc-base │ └─┬ types │ ├── class Base - │ └─┬ interface BaseProps + │ ├─┬ interface BaseProps + │ │ └─┬ interfaces + │ │ └── VeryBaseProps + │ └─┬ interface IBaseInterface │ └─┬ interfaces - │ └── VeryBaseProps + │ └── IVeryBaseInterface ├─┬ @scope/jsii-calc-base-of-base │ └─┬ types │ ├── class Very + │ ├── interface IVeryBaseInterface │ └── interface VeryBaseProps └─┬ @scope/jsii-calc-lib └─┬ types @@ -172,6 +176,9 @@ assemblies │ └── base: Base ├── interface IDoublable ├── interface IFriendly + ├─┬ interface IThreeLevelsInterface + │ └─┬ interfaces + │ └── IBaseInterface ├── interface MyFirstStruct ├── interface StructWithOnlyOptionals └── enum EnumFromScopedModule 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 4bfd49d3bb..dfc2fcdca2 100644 --- a/packages/jsii-reflect/test/jsii-tree.test.members.expected.txt +++ b/packages/jsii-reflect/test/jsii-tree.test.members.expected.txt @@ -652,15 +652,21 @@ assemblies │ │ └─┬ members │ │ ├── () initializer │ │ └── typeName() method - │ └─┬ interface BaseProps + │ ├─┬ interface BaseProps + │ │ └─┬ members + │ │ └── bar property + │ └─┬ interface IBaseInterface │ └─┬ members - │ └── bar property + │ └── bar() method ├─┬ @scope/jsii-calc-base-of-base │ └─┬ types │ ├─┬ class Very │ │ └─┬ members │ │ ├── () initializer │ │ └── hey() method + │ ├─┬ interface IVeryBaseInterface + │ │ └─┬ members + │ │ └── foo() method │ └─┬ interface VeryBaseProps │ └─┬ members │ └── foo property @@ -686,6 +692,9 @@ assemblies ├─┬ interface IFriendly │ └─┬ members │ └── hello() method + ├─┬ interface IThreeLevelsInterface + │ └─┬ members + │ └── baz() method ├─┬ interface MyFirstStruct │ └─┬ members │ ├── anumber property 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 2b325e63f3..36e05ae539 100644 --- a/packages/jsii-reflect/test/jsii-tree.test.types.expected.txt +++ b/packages/jsii-reflect/test/jsii-tree.test.types.expected.txt @@ -113,10 +113,12 @@ assemblies ├─┬ @scope/jsii-calc-base │ └─┬ types │ ├── class Base - │ └── interface BaseProps + │ ├── interface BaseProps + │ └── interface IBaseInterface ├─┬ @scope/jsii-calc-base-of-base │ └─┬ types │ ├── class Very + │ ├── interface IVeryBaseInterface │ └── interface VeryBaseProps └─┬ @scope/jsii-calc-lib └─┬ types @@ -125,6 +127,7 @@ assemblies ├── class Value ├── interface IDoublable ├── interface IFriendly + ├── interface IThreeLevelsInterface ├── interface MyFirstStruct ├── interface StructWithOnlyOptionals └── enum EnumFromScopedModule diff --git a/packages/jsii-reflect/test/typesystem.test.ts b/packages/jsii-reflect/test/typesystem.test.ts index c0ecea9892..07ade6d026 100644 --- a/packages/jsii-reflect/test/typesystem.test.ts +++ b/packages/jsii-reflect/test/typesystem.test.ts @@ -148,6 +148,13 @@ describe('Type', () => { }); }); +test('Three Inheritance Levels', () => { + const iface = typesys.findInterface('@scope/jsii-calc-lib.IThreeLevelsInterface'); + const methodnames = iface.allMethods.map(m => m.name); + methodnames.sort(); + expect(methodnames).toEqual(['bar', 'baz', 'foo']); +}); + describe('@deprecated', () => { test('can be read on an item', () => { const klass = typesys.findClass('jsii-calc.Old'); diff --git a/packages/jsii-spec/lib/spec.ts b/packages/jsii-spec/lib/spec.ts index ca1744acc8..f754332eda 100644 --- a/packages/jsii-spec/lib/spec.ts +++ b/packages/jsii-spec/lib/spec.ts @@ -97,13 +97,20 @@ export interface Assembly extends Documentable { targets?: AssemblyTargets; /** - * Dependencies on other assemblies (with semver), the key is the JSII + * Direct dependencies on other assemblies (with semver), the key is the JSII * assembly name. * * @default none */ dependencies?: { [assembly: string]: PackageVersion }; + /** + * Closure of all dependency assemblies, direct and transitive. + * + * @default none + */ + dependencyClosure?: { [assembly: string]: PackageVersion }; + /** * List if bundled dependencies (these are not expected to be jsii * assemblies). @@ -207,13 +214,6 @@ export interface PackageVersion { * @default none */ targets?: AssemblyTargets; - - /** - * Dependencies of this dependency - * - * @default none - */ - dependencies?: { [assembly: string]: PackageVersion }; } /** diff --git a/packages/jsii/lib/assembler.ts b/packages/jsii/lib/assembler.ts index 76dfb19c53..88a70aa9b4 100644 --- a/packages/jsii/lib/assembler.ts +++ b/packages/jsii/lib/assembler.ts @@ -5,10 +5,11 @@ import fs = require('fs-extra'); import spec = require('jsii-spec'); import log4js = require('log4js'); import path = require('path'); +import semver = require('semver'); import ts = require('typescript'); import { JSII_DIAGNOSTICS_CODE } from './compiler'; import { getReferencedDocParams, parseSymbolDocumentation } from './docs'; -import { Diagnostic, Emitter, EmitResult } from './emitter'; +import { Diagnostic, EmitResult, Emitter } from './emitter'; import literate = require('./literate'); import { ProjectInfo } from './project-info'; import { Validator } from './validator'; @@ -108,7 +109,8 @@ export class Assembler implements Emitter { author: this.projectInfo.author, contributors: this.projectInfo.contributors && [...this.projectInfo.contributors], repository: this.projectInfo.repository, - dependencies: _toDependencies(this.projectInfo.dependencies), + dependencies: this._toDependencies(this.projectInfo.dependencies), + dependencyClosure: this._buildDependencyClosure(this.projectInfo.dependencies), bundled: this.projectInfo.bundleDependencies, types: this._types, targets: this.projectInfo.targets, @@ -1239,6 +1241,72 @@ export class Assembler implements Emitter { } } } + + private _toDependencies(assemblies: ReadonlyArray): { [name: string]: spec.PackageVersion } | undefined { + const ret: { [name: string]: spec.PackageVersion } = {}; + + for (const a of assemblies) { + Object.assign(ret, assemblyToPackageVersionMap(a)); + } + + return noEmptyDict(ret); + } + + private _buildDependencyClosure(assemblies: ReadonlyArray): { [name: string]: spec.PackageVersion } | undefined { + // Merge the dependency closures of all dependencies and add the direct dependencies. + // There should not be version conflicts between them but we guard against it anyway. + + // Get an array of dependency maps + const dependencyBags = flatten(assemblies.map(a => [assemblyToPackageVersionMap(a), a.dependencies || {}])); + + const warned = new Set(); + const self = this; + const result: { [name: string]: spec.PackageVersion } = {}; + for (const bag of dependencyBags) { + for (const [name, packV] of Object.entries(bag)) { + maybeRecord(name, packV); + } + } + + return noEmptyDict(result); + + function maybeRecord(name: string, pack: spec.PackageVersion) { + let recordThisDependency = true; + + if (name in result) { + // Two dependencies on the same package, find the right version to use + const highestVersion = mostConstrainedVersion(result[name].version, pack.version); + + if (highestVersion === undefined) { + warnAboutVersionConflict(name, result[name].version, pack.version); + } + + recordThisDependency = pack.version === highestVersion; + } + + if (recordThisDependency) { + result[name] = { + version: pack.version, + targets: pack.targets, + }; + } + } + + function warnAboutVersionConflict(name: string, v1: string, v2: string) { + if (warned.has(name)) { return; } + self._diagnostic(null, ts.DiagnosticCategory.Error, `Conflicting dependencies on incompatible versions for package '${name}': ${v1} and ${v2}`); + warned.add(name); + } + } +} + +function assemblyToPackageVersionMap(a: spec.Assembly): {[key: string]: spec.PackageVersion} { + return { + [a.name]: { + version: a.version, + targets: a.targets + } + }; } function _fingerprint(assembly: spec.Assembly): spec.Assembly { @@ -1370,24 +1438,6 @@ function _sortMembers(type: spec.ClassType | spec.InterfaceType): spec.ClassType }; } -function _toDependencies(assemblies: ReadonlyArray): { [name: string]: spec.PackageVersion } | undefined { - if (assemblies.length === 0) { - return undefined; - } - - const result: { [name: string]: spec.PackageVersion } = {}; - - for (const assembly of assemblies) { - result[assembly.name] = { - version: assembly.version, - targets: assembly.targets, - dependencies: assembly.dependencies - }; - } - - return result; -} - /** * Deferred processing that needs to happen in a second, ordered pass */ @@ -1483,3 +1533,32 @@ function* intersect(xs: Set, ys: Set) { } } } + +/** + * Return the most constrained version given two versions + * + * Returns the highest version. Return undefined if the values are not pairwise + * comparable. + */ +function mostConstrainedVersion(version1: string, version2: string): string | undefined { + if (semver.satisfies(version1, `^${version2}`)) { + // If v1 satisifies v2, then either: + // - v2 also satisfies v1, in which case it doesn't matter which we return + // - v2 does not satisfy v1, in which it must be the case that v1 is higher + return version1; + } + + // Reverse logic + if (semver.satisfies(version2, `^${version1}`)) { return version2; } + + return undefined; +} + +function flatten(xs: T[][]): T[] { + return Array.prototype.concat.call([], ...xs); +} + +function noEmptyDict(xs: {[key: string]: T}): {[key: string]: T} | undefined { + if (Object.keys(xs).length === 0) { return undefined; } + return xs; +} diff --git a/packages/jsii/package.json b/packages/jsii/package.json index 995618b456..fdf3ff4682 100644 --- a/packages/jsii/package.json +++ b/packages/jsii/package.json @@ -52,5 +52,9 @@ "lcov", "text" ] + }, + "repository": { + "type": "git", + "url": "https://github.com/awslabs/jsii.git" } }