From b37101f317f4de5fa2b6b3581187ff97b1627283 Mon Sep 17 00:00:00 2001 From: Romain Marcadier-Muller Date: Wed, 5 Sep 2018 11:57:33 +0200 Subject: [PATCH] fix: Missing types in JSII assembly, invalid Java code, confusing docs (#208) * The new `jsii` would omit interfaces defined within namespaces because of the way namespaces were processed (using members instead of listing all exports). * Some `jsii` type validations could, in some rare cases, happen too early, attempting to dereference types that hadn't been processed yet. * The `jsii-pacmak` generator for Java could generate property names that were reserved words (e.g: `assert`). * the `jsii-pacmak` generator for Sphinx would generate confusing (or incorrect) type documentation for entities of array types, and particularly so for arrays of unions. * Fixes #175: interface proxies do not respect optional method arguments Testing gaps: - [ ] Test surface in `jsii-calc` or its dependencies that exercise reserved words of various languages. --- packages/jsii-calc/lib/compliance.ts | 32 +++ packages/jsii-calc/test/assembly.jsii | 82 +++++++- packages/jsii-pacmak/lib/generator.ts | 11 +- packages/jsii-pacmak/lib/targets/java.ts | 10 +- packages/jsii-pacmak/lib/targets/sphinx.ts | 21 +- .../jsii/tests/calculator/base/BaseProps.java | 12 +- .../tests/calculator/lib/MyFirstStruct.java | 18 +- .../lib/StructWithOnlyOptionals.java | 18 +- .../sphinx/_scope_jsii-calc-lib.rst | 2 +- .../.jsii | 82 +++++++- .../IInterfaceWithOptionalMethodArguments.cs | 15 ++ .../Foo.cs | 27 +++ .../Hello.cs | 14 ++ .../HelloProxy.cs | 19 ++ .../IHello.cs | 15 ++ .../Hello.cs | 14 ++ .../HelloProxy.cs | 19 ++ .../IHello.cs | 15 ++ ...terfaceWithOptionalMethodArgumentsProxy.cs | 22 ++ .../amazon/jsii/tests/calculator/$Module.java | 4 + .../tests/calculator/CalculatorProps.java | 12 +- .../jsii/tests/calculator/DerivedStruct.java | 48 ++--- .../calculator/IInterfaceWithProperties.java | 10 +- .../IInterfaceWithPropertiesExtension.java | 16 +- .../tests/calculator/ImplictBaseOfBase.java | 18 +- .../Foo.java | 22 ++ .../Hello.java | 72 +++++++ .../Hello.java | 72 +++++++ .../InterfaceWithOptionalMethodArguments.java | 30 +++ .../tests/calculator/UnionProperties.java | 12 +- .../expected.jsii-calc/sphinx/jsii-calc.rst | 195 ++++++++++++++++-- packages/jsii-pacmak/tsconfig.json | 4 +- packages/jsii/lib/assembler.ts | 67 +++--- packages/jsii/lib/project-info.ts | 3 +- 34 files changed, 888 insertions(+), 145 deletions(-) create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IInterfaceWithOptionalMethodArguments.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/Foo.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/Hello.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/HelloProxy.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/IHello.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/Hello.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/HelloProxy.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/IHello.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceWithOptionalMethodArgumentsProxy.cs create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceIncludesClasses/Foo.java create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceIncludesClasses/Hello.java create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceOnlyInterface/Hello.java create mode 100644 packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceWithOptionalMethodArguments.java diff --git a/packages/jsii-calc/lib/compliance.ts b/packages/jsii-calc/lib/compliance.ts index 0a0c56b7fa..fe430235d1 100644 --- a/packages/jsii-calc/lib/compliance.ts +++ b/packages/jsii-calc/lib/compliance.ts @@ -782,3 +782,35 @@ export class ReferenceEnumFromScopedPackage { this.foo = value; } } + +/** + * awslabs/jsii#208 + * Interface within a namespace + */ +export namespace InterfaceInNamespaceOnlyInterface { + + // it's a special case when only an interface is exported from a namespace + export interface Hello { + foo: number + } + +} + +export namespace InterfaceInNamespaceIncludesClasses { + + export class Foo { + public bar?: string; + } + + export interface Hello { + foo: number + } +} + +/** + * awslabs/jsii#175 + * Interface proxies (and builders) do not respect optional arguments in methods + */ +export interface InterfaceWithOptionalMethodArguments { + hello(arg1: string, arg2?: number): void +} \ No newline at end of file diff --git a/packages/jsii-calc/test/assembly.jsii b/packages/jsii-calc/test/assembly.jsii index 835f8170ad..bc2b44b47b 100644 --- a/packages/jsii-calc/test/assembly.jsii +++ b/packages/jsii-calc/test/assembly.jsii @@ -1244,6 +1244,86 @@ } ] }, + "jsii-calc.InterfaceInNamespaceIncludesClasses.Foo": { + "assembly": "jsii-calc", + "fqn": "jsii-calc.InterfaceInNamespaceIncludesClasses.Foo", + "initializer": { + "initializer": true + }, + "kind": "class", + "name": "Foo", + "namespace": "InterfaceInNamespaceIncludesClasses", + "properties": [ + { + "name": "bar", + "type": { + "optional": true, + "primitive": "string" + } + } + ] + }, + "jsii-calc.InterfaceInNamespaceIncludesClasses.Hello": { + "assembly": "jsii-calc", + "datatype": true, + "fqn": "jsii-calc.InterfaceInNamespaceIncludesClasses.Hello", + "kind": "interface", + "name": "Hello", + "namespace": "InterfaceInNamespaceIncludesClasses", + "properties": [ + { + "name": "foo", + "type": { + "primitive": "number" + } + } + ] + }, + "jsii-calc.InterfaceInNamespaceOnlyInterface.Hello": { + "assembly": "jsii-calc", + "datatype": true, + "fqn": "jsii-calc.InterfaceInNamespaceOnlyInterface.Hello", + "kind": "interface", + "name": "Hello", + "namespace": "InterfaceInNamespaceOnlyInterface", + "properties": [ + { + "name": "foo", + "type": { + "primitive": "number" + } + } + ] + }, + "jsii-calc.InterfaceWithOptionalMethodArguments": { + "assembly": "jsii-calc", + "docs": { + "comment": "awslabs/jsii#175\nInterface proxies (and builders) do not respect optional arguments in methods" + }, + "fqn": "jsii-calc.InterfaceWithOptionalMethodArguments", + "kind": "interface", + "methods": [ + { + "name": "hello", + "parameters": [ + { + "name": "arg1", + "type": { + "primitive": "string" + } + }, + { + "name": "arg2", + "type": { + "optional": true, + "primitive": "number" + } + } + ] + } + ], + "name": "InterfaceWithOptionalMethodArguments" + }, "jsii-calc.JSObjectLiteralForInterface": { "assembly": "jsii-calc", "fqn": "jsii-calc.JSObjectLiteralForInterface", @@ -2844,5 +2924,5 @@ } }, "version": "0.7.1", - "fingerprint": "xRKsZzmRl0yM7EYcHnUbf691eFzAupWFIvCbEqWcUuA=" + "fingerprint": "3uROoDToOcKIpYs9haAGnS37Iebz1/+ldcknrh37qDQ=" } diff --git a/packages/jsii-pacmak/lib/generator.ts b/packages/jsii-pacmak/lib/generator.ts index 0ee809598b..f038dd432e 100644 --- a/packages/jsii-pacmak/lib/generator.ts +++ b/packages/jsii-pacmak/lib/generator.ts @@ -302,7 +302,16 @@ export abstract class Generator implements IGenerator { return this.excludeTypes.includes(name); } - private createOverloadsForOptionals(method: spec.Method) { + /** + * Returns all the method overloads needed to satisfy optional arguments. + * For example, for the method `foo(bar: string, hello?: number, world?: number)` + * this method will return: + * - foo(bar: string) + * - foo(bar: string, hello: number) + * + * Notice that the method that contains all the arguments will not be returned. + */ + protected createOverloadsForOptionals(method: spec.Method) { const methods = new Array(); // if option disabled, just return the empty array. diff --git a/packages/jsii-pacmak/lib/targets/java.ts b/packages/jsii-pacmak/lib/targets/java.ts index 9113475930..710b43468d 100644 --- a/packages/jsii-pacmak/lib/targets/java.ts +++ b/packages/jsii-pacmak/lib/targets/java.ts @@ -652,6 +652,10 @@ class JavaGenerator extends Generator { for (const methodName of Object.keys(methods)) { const method = methods[methodName]; this.emitMethod(ifc, method, /* overrides: */ true); + + for (const overloadedMethod of this.createOverloadsForOptionals(method)) { + this.emitMethod(ifc, overloadedMethod, /* overrides: */ true); + } } this.code.closeBlock(); @@ -754,20 +758,20 @@ class JavaGenerator extends Generator { for (const prop of props) { if (prop.optional) { this.code.line(JSR305_NULLABLE); } // tslint:disable-next-line:max-line-length - this.code.line(`private${prop.immutable ? ' final' : ''} ${prop.fieldJavaType} ${prop.fieldName} = ${_validateIfNonOptional(`_${prop.fieldName}`, prop)};`); + this.code.line(`private${prop.immutable ? ' final' : ''} ${prop.fieldJavaType} $${prop.fieldName} = ${_validateIfNonOptional(`_${prop.fieldName}`, prop)};`); } for (const prop of props) { this.code.line(); this.code.line('@Override'); this.code.openBlock(`public ${prop.fieldJavaType} get${prop.propName}()`); - this.code.line(`return this.${prop.fieldName};`); + this.code.line(`return this.$${prop.fieldName};`); this.code.closeBlock(); if (!prop.immutable) { for (const type of prop.javaTypes) { this.code.line(); this.code.line('@Override'); this.code.openBlock(`public void set${prop.propName}(${prop.optional ? `${JSR305_NULLABLE} ` : ''}final ${type} value)`); - this.code.line(`this.${prop.fieldName} = ${_validateIfNonOptional('value', prop)};`); + this.code.line(`this.$${prop.fieldName} = ${_validateIfNonOptional('value', prop)};`); this.code.closeBlock(); } } diff --git a/packages/jsii-pacmak/lib/targets/sphinx.ts b/packages/jsii-pacmak/lib/targets/sphinx.ts index ac661b0f50..496accc54b 100644 --- a/packages/jsii-pacmak/lib/targets/sphinx.ts +++ b/packages/jsii-pacmak/lib/targets/sphinx.ts @@ -517,33 +517,42 @@ class SphinxDocsGenerator extends Generator { }; } else if (spec.isCollectionTypeReference(type)) { const elementType = this.renderTypeRef(type.collection.elementtype); + const ref = wrap(elementType.ref); + const display = wrap(elementType.display); switch (type.collection.kind) { case spec.CollectionKind.Array: result = { - ref: elementType.ref, - display: `${elementType.display}[]` + ref: `${ref}[]`, + display: `${display}[]` }; break; case spec.CollectionKind.Map: result = { - ref: elementType.ref, - display: `string => ${elementType.display}` + ref: `string => ${ref}`, + display: `string => ${display}` }; break; default: throw new Error(`Unexpected collection kind: ${type.collection.kind}`); } } else if (spec.isUnionTypeReference(type)) { + const mappedTypes = type.union.types.map(t => this.renderTypeRef(t)); result = { - display: type.union.types.map(t => this.renderTypeRef(t).display).join(' or '), - ref: type.union.types.map(t => this.renderTypeRef(t).ref).join(' or '), + display: mappedTypes.map(t => t.display).join(' or '), + ref: mappedTypes.map(t => t.ref).join(' or '), }; } else { throw new Error('Unexpected type ref'); } if (type.optional) { result.ref = `${result.ref} or undefined`; } return result; + + // Wrap a string between parenthesis if it contains " or " + function wrap(str: string): string { + if (str.indexOf(' or ') === -1) { return str; } + return `(${str})`; + } } private renderProperty(prop: spec.Property) { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/BaseProps.java b/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/BaseProps.java index f7980c0c20..1e047bffb8 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/BaseProps.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/java/src/main/java/software/amazon/jsii/tests/calculator/base/BaseProps.java @@ -45,27 +45,27 @@ public Builder withFoo(final software.amazon.jsii.tests.calculator.baseofbase.Ve */ public BaseProps build() { return new BaseProps() { - private java.lang.String bar = java.util.Objects.requireNonNull(_bar, "bar is required"); - private software.amazon.jsii.tests.calculator.baseofbase.Very foo = java.util.Objects.requireNonNull(_foo, "foo is required"); + private java.lang.String $bar = java.util.Objects.requireNonNull(_bar, "bar is required"); + private software.amazon.jsii.tests.calculator.baseofbase.Very $foo = java.util.Objects.requireNonNull(_foo, "foo is required"); @Override public java.lang.String getBar() { - return this.bar; + return this.$bar; } @Override public void setBar(final java.lang.String value) { - this.bar = java.util.Objects.requireNonNull(value, "bar is required"); + this.$bar = java.util.Objects.requireNonNull(value, "bar is required"); } @Override public software.amazon.jsii.tests.calculator.baseofbase.Very getFoo() { - return this.foo; + return this.$foo; } @Override public void setFoo(final software.amazon.jsii.tests.calculator.baseofbase.Very value) { - this.foo = java.util.Objects.requireNonNull(value, "foo is required"); + this.$foo = java.util.Objects.requireNonNull(value, "foo is required"); } }; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/MyFirstStruct.java b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/MyFirstStruct.java index 1931195261..b6c1dc12c8 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/MyFirstStruct.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/MyFirstStruct.java @@ -75,39 +75,39 @@ public Builder withFirstOptional(@javax.annotation.Nullable final java.util.List */ public MyFirstStruct build() { return new MyFirstStruct() { - private java.lang.Number anumber = java.util.Objects.requireNonNull(_anumber, "anumber is required"); - private java.lang.String astring = java.util.Objects.requireNonNull(_astring, "astring is required"); + private java.lang.Number $anumber = java.util.Objects.requireNonNull(_anumber, "anumber is required"); + private java.lang.String $astring = java.util.Objects.requireNonNull(_astring, "astring is required"); @javax.annotation.Nullable - private java.util.List firstOptional = _firstOptional; + private java.util.List $firstOptional = _firstOptional; @Override public java.lang.Number getAnumber() { - return this.anumber; + return this.$anumber; } @Override public void setAnumber(final java.lang.Number value) { - this.anumber = java.util.Objects.requireNonNull(value, "anumber is required"); + this.$anumber = java.util.Objects.requireNonNull(value, "anumber is required"); } @Override public java.lang.String getAstring() { - return this.astring; + return this.$astring; } @Override public void setAstring(final java.lang.String value) { - this.astring = java.util.Objects.requireNonNull(value, "astring is required"); + this.$astring = java.util.Objects.requireNonNull(value, "astring is required"); } @Override public java.util.List getFirstOptional() { - return this.firstOptional; + return this.$firstOptional; } @Override public void setFirstOptional(@javax.annotation.Nullable final java.util.List value) { - this.firstOptional = value; + this.$firstOptional = value; } }; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/StructWithOnlyOptionals.java b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/StructWithOnlyOptionals.java index 69b23dbc86..fea2008bb5 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/StructWithOnlyOptionals.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/java/src/main/java/software/amazon/jsii/tests/calculator/lib/StructWithOnlyOptionals.java @@ -72,40 +72,40 @@ public Builder withOptional3(@javax.annotation.Nullable final java.lang.Boolean public StructWithOnlyOptionals build() { return new StructWithOnlyOptionals() { @javax.annotation.Nullable - private java.lang.String optional1 = _optional1; + private java.lang.String $optional1 = _optional1; @javax.annotation.Nullable - private java.lang.Number optional2 = _optional2; + private java.lang.Number $optional2 = _optional2; @javax.annotation.Nullable - private java.lang.Boolean optional3 = _optional3; + private java.lang.Boolean $optional3 = _optional3; @Override public java.lang.String getOptional1() { - return this.optional1; + return this.$optional1; } @Override public void setOptional1(@javax.annotation.Nullable final java.lang.String value) { - this.optional1 = value; + this.$optional1 = value; } @Override public java.lang.Number getOptional2() { - return this.optional2; + return this.$optional2; } @Override public void setOptional2(@javax.annotation.Nullable final java.lang.Number value) { - this.optional2 = value; + this.$optional2 = value; } @Override public java.lang.Boolean getOptional3() { - return this.optional3; + return this.$optional3; } @Override public void setOptional3(@javax.annotation.Nullable final java.lang.Boolean value) { - this.optional3 = value; + this.$optional3 = value; } }; 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 042eeefab2..42d41edbf8 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 @@ -248,7 +248,7 @@ MyFirstStruct (interface) .. py:attribute:: firstOptional - :type: string or undefined + :type: string[] or undefined Number 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 835f8170ad..bc2b44b47b 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 @@ -1244,6 +1244,86 @@ } ] }, + "jsii-calc.InterfaceInNamespaceIncludesClasses.Foo": { + "assembly": "jsii-calc", + "fqn": "jsii-calc.InterfaceInNamespaceIncludesClasses.Foo", + "initializer": { + "initializer": true + }, + "kind": "class", + "name": "Foo", + "namespace": "InterfaceInNamespaceIncludesClasses", + "properties": [ + { + "name": "bar", + "type": { + "optional": true, + "primitive": "string" + } + } + ] + }, + "jsii-calc.InterfaceInNamespaceIncludesClasses.Hello": { + "assembly": "jsii-calc", + "datatype": true, + "fqn": "jsii-calc.InterfaceInNamespaceIncludesClasses.Hello", + "kind": "interface", + "name": "Hello", + "namespace": "InterfaceInNamespaceIncludesClasses", + "properties": [ + { + "name": "foo", + "type": { + "primitive": "number" + } + } + ] + }, + "jsii-calc.InterfaceInNamespaceOnlyInterface.Hello": { + "assembly": "jsii-calc", + "datatype": true, + "fqn": "jsii-calc.InterfaceInNamespaceOnlyInterface.Hello", + "kind": "interface", + "name": "Hello", + "namespace": "InterfaceInNamespaceOnlyInterface", + "properties": [ + { + "name": "foo", + "type": { + "primitive": "number" + } + } + ] + }, + "jsii-calc.InterfaceWithOptionalMethodArguments": { + "assembly": "jsii-calc", + "docs": { + "comment": "awslabs/jsii#175\nInterface proxies (and builders) do not respect optional arguments in methods" + }, + "fqn": "jsii-calc.InterfaceWithOptionalMethodArguments", + "kind": "interface", + "methods": [ + { + "name": "hello", + "parameters": [ + { + "name": "arg1", + "type": { + "primitive": "string" + } + }, + { + "name": "arg2", + "type": { + "optional": true, + "primitive": "number" + } + } + ] + } + ], + "name": "InterfaceWithOptionalMethodArguments" + }, "jsii-calc.JSObjectLiteralForInterface": { "assembly": "jsii-calc", "fqn": "jsii-calc.JSObjectLiteralForInterface", @@ -2844,5 +2924,5 @@ } }, "version": "0.7.1", - "fingerprint": "xRKsZzmRl0yM7EYcHnUbf691eFzAupWFIvCbEqWcUuA=" + "fingerprint": "3uROoDToOcKIpYs9haAGnS37Iebz1/+ldcknrh37qDQ=" } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IInterfaceWithOptionalMethodArguments.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IInterfaceWithOptionalMethodArguments.cs new file mode 100644 index 0000000000..c57ab841ae --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IInterfaceWithOptionalMethodArguments.cs @@ -0,0 +1,15 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + /// + /// awslabs/jsii#175 + /// Interface proxies (and builders) do not respect optional arguments in methods + /// + [JsiiInterface(typeof(IInterfaceWithOptionalMethodArguments), "jsii-calc.InterfaceWithOptionalMethodArguments")] + public interface IInterfaceWithOptionalMethodArguments + { + [JsiiMethod("hello", null, "[{\"name\":\"arg1\",\"type\":{\"primitive\":\"string\"}},{\"name\":\"arg2\",\"type\":{\"primitive\":\"number\",\"optional\":true}}]")] + void Hello(string arg1, double? arg2); + } +} \ 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/InterfaceInNamespaceIncludesClasses/Foo.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/Foo.cs new file mode 100644 index 0000000000..f6f6278df2 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/Foo.cs @@ -0,0 +1,27 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceIncludesClasses +{ + [JsiiClass(typeof(Foo), "jsii-calc.InterfaceInNamespaceIncludesClasses.Foo", "[]")] + public class Foo : DeputyBase + { + public Foo(): base(new DeputyProps(new object[]{})) + { + } + + protected Foo(ByRefValue reference): base(reference) + { + } + + protected Foo(DeputyProps props): base(props) + { + } + + [JsiiProperty("bar", "{\"primitive\":\"string\",\"optional\":true}")] + public virtual string Bar + { + get => GetInstanceProperty(); + set => SetInstanceProperty(value); + } + } +} \ 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/InterfaceInNamespaceIncludesClasses/Hello.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/Hello.cs new file mode 100644 index 0000000000..00a8334cbe --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/Hello.cs @@ -0,0 +1,14 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceIncludesClasses +{ + public class Hello : DeputyBase, Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceIncludesClasses.IHello + { + [JsiiProperty("foo", "{\"primitive\":\"number\"}", true)] + public double Foo + { + get; + set; + } + } +} \ 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/InterfaceInNamespaceIncludesClasses/HelloProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/HelloProxy.cs new file mode 100644 index 0000000000..0f9fe1639d --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/HelloProxy.cs @@ -0,0 +1,19 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceIncludesClasses +{ + [JsiiInterfaceProxy(typeof(IHello), "jsii-calc.InterfaceInNamespaceIncludesClasses.Hello")] + internal class HelloProxy : DeputyBase, Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceIncludesClasses.IHello + { + private HelloProxy(ByRefValue reference): base(reference) + { + } + + [JsiiProperty("foo", "{\"primitive\":\"number\"}")] + public virtual double Foo + { + get => GetInstanceProperty(); + set => SetInstanceProperty(value); + } + } +} \ 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/InterfaceInNamespaceIncludesClasses/IHello.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/IHello.cs new file mode 100644 index 0000000000..fd29cc6ae1 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/IHello.cs @@ -0,0 +1,15 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceIncludesClasses +{ + [JsiiInterface(typeof(IHello), "jsii-calc.InterfaceInNamespaceIncludesClasses.Hello")] + public interface IHello + { + [JsiiProperty("foo", "{\"primitive\":\"number\"}")] + double Foo + { + get; + set; + } + } +} \ 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/InterfaceInNamespaceOnlyInterface/Hello.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/Hello.cs new file mode 100644 index 0000000000..de433215ce --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/Hello.cs @@ -0,0 +1,14 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceOnlyInterface +{ + public class Hello : DeputyBase, Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceOnlyInterface.IHello + { + [JsiiProperty("foo", "{\"primitive\":\"number\"}", true)] + public double Foo + { + get; + set; + } + } +} \ 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/InterfaceInNamespaceOnlyInterface/HelloProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/HelloProxy.cs new file mode 100644 index 0000000000..129132b37c --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/HelloProxy.cs @@ -0,0 +1,19 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceOnlyInterface +{ + [JsiiInterfaceProxy(typeof(IHello), "jsii-calc.InterfaceInNamespaceOnlyInterface.Hello")] + internal class HelloProxy : DeputyBase, Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceOnlyInterface.IHello + { + private HelloProxy(ByRefValue reference): base(reference) + { + } + + [JsiiProperty("foo", "{\"primitive\":\"number\"}")] + public virtual double Foo + { + get => GetInstanceProperty(); + set => SetInstanceProperty(value); + } + } +} \ 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/InterfaceInNamespaceOnlyInterface/IHello.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/IHello.cs new file mode 100644 index 0000000000..70cb9473fe --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceOnlyInterface/IHello.cs @@ -0,0 +1,15 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace.InterfaceInNamespaceOnlyInterface +{ + [JsiiInterface(typeof(IHello), "jsii-calc.InterfaceInNamespaceOnlyInterface.Hello")] + public interface IHello + { + [JsiiProperty("foo", "{\"primitive\":\"number\"}")] + double Foo + { + get; + set; + } + } +} \ 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/InterfaceWithOptionalMethodArgumentsProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceWithOptionalMethodArgumentsProxy.cs new file mode 100644 index 0000000000..790775190f --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceWithOptionalMethodArgumentsProxy.cs @@ -0,0 +1,22 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + /// + /// awslabs/jsii#175 + /// Interface proxies (and builders) do not respect optional arguments in methods + /// + [JsiiInterfaceProxy(typeof(IInterfaceWithOptionalMethodArguments), "jsii-calc.InterfaceWithOptionalMethodArguments")] + internal class InterfaceWithOptionalMethodArgumentsProxy : DeputyBase, IInterfaceWithOptionalMethodArguments + { + private InterfaceWithOptionalMethodArgumentsProxy(ByRefValue reference): base(reference) + { + } + + [JsiiMethod("hello", null, "[{\"name\":\"arg1\",\"type\":{\"primitive\":\"string\"}},{\"name\":\"arg2\",\"type\":{\"primitive\":\"number\",\"optional\":true}}]")] + public virtual void Hello(string arg1, double? arg2) + { + InvokeInstanceVoidMethod(new object[]{arg1, arg2}); + } + } +} \ 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 513b994361..a193148d52 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 @@ -37,6 +37,10 @@ protected Class resolveClass(final String fqn) throws ClassNotFoundException case "jsii-calc.IInterfaceWithPropertiesExtension": return software.amazon.jsii.tests.calculator.IInterfaceWithPropertiesExtension.class; case "jsii-calc.IRandomNumberGenerator": return software.amazon.jsii.tests.calculator.IRandomNumberGenerator.class; case "jsii-calc.ImplictBaseOfBase": return software.amazon.jsii.tests.calculator.ImplictBaseOfBase.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; + case "jsii-calc.InterfaceInNamespaceOnlyInterface.Hello": return software.amazon.jsii.tests.calculator.InterfaceInNamespaceOnlyInterface.Hello.class; + case "jsii-calc.InterfaceWithOptionalMethodArguments": return software.amazon.jsii.tests.calculator.InterfaceWithOptionalMethodArguments.class; case "jsii-calc.JSObjectLiteralForInterface": return software.amazon.jsii.tests.calculator.JSObjectLiteralForInterface.class; case "jsii-calc.JSObjectLiteralToNative": return software.amazon.jsii.tests.calculator.JSObjectLiteralToNative.class; case "jsii-calc.JSObjectLiteralToNativeClass": return software.amazon.jsii.tests.calculator.JSObjectLiteralToNativeClass.class; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/CalculatorProps.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/CalculatorProps.java index 3b119669f4..3df8db7fe4 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/CalculatorProps.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/CalculatorProps.java @@ -53,28 +53,28 @@ public Builder withMaximumValue(@javax.annotation.Nullable final java.lang.Numbe public CalculatorProps build() { return new CalculatorProps() { @javax.annotation.Nullable - private java.lang.Number initialValue = _initialValue; + private java.lang.Number $initialValue = _initialValue; @javax.annotation.Nullable - private java.lang.Number maximumValue = _maximumValue; + private java.lang.Number $maximumValue = _maximumValue; @Override public java.lang.Number getInitialValue() { - return this.initialValue; + return this.$initialValue; } @Override public void setInitialValue(@javax.annotation.Nullable final java.lang.Number value) { - this.initialValue = value; + this.$initialValue = value; } @Override public java.lang.Number getMaximumValue() { - return this.maximumValue; + return this.$maximumValue; } @Override public void setMaximumValue(@javax.annotation.Nullable final java.lang.Number value) { - this.maximumValue = value; + this.$maximumValue = value; } }; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/DerivedStruct.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/DerivedStruct.java index 6cd133372d..dca89e423b 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/DerivedStruct.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/DerivedStruct.java @@ -131,96 +131,96 @@ public Builder withFirstOptional(@javax.annotation.Nullable final java.util.List */ public DerivedStruct build() { return new DerivedStruct() { - private java.time.Instant anotherRequired = java.util.Objects.requireNonNull(_anotherRequired, "anotherRequired is required"); - private java.lang.Boolean bool = java.util.Objects.requireNonNull(_bool, "bool is required"); - private software.amazon.jsii.tests.calculator.DoubleTrouble nonPrimitive = java.util.Objects.requireNonNull(_nonPrimitive, "nonPrimitive is required"); + private java.time.Instant $anotherRequired = java.util.Objects.requireNonNull(_anotherRequired, "anotherRequired is required"); + private java.lang.Boolean $bool = java.util.Objects.requireNonNull(_bool, "bool is required"); + private software.amazon.jsii.tests.calculator.DoubleTrouble $nonPrimitive = java.util.Objects.requireNonNull(_nonPrimitive, "nonPrimitive is required"); @javax.annotation.Nullable - private java.util.Map anotherOptional = _anotherOptional; + private java.util.Map $anotherOptional = _anotherOptional; @javax.annotation.Nullable - private java.util.List optionalArray = _optionalArray; - private java.lang.Number anumber = java.util.Objects.requireNonNull(_anumber, "anumber is required"); - private java.lang.String astring = java.util.Objects.requireNonNull(_astring, "astring is required"); + private java.util.List $optionalArray = _optionalArray; + private java.lang.Number $anumber = java.util.Objects.requireNonNull(_anumber, "anumber is required"); + private java.lang.String $astring = java.util.Objects.requireNonNull(_astring, "astring is required"); @javax.annotation.Nullable - private java.util.List firstOptional = _firstOptional; + private java.util.List $firstOptional = _firstOptional; @Override public java.time.Instant getAnotherRequired() { - return this.anotherRequired; + return this.$anotherRequired; } @Override public void setAnotherRequired(final java.time.Instant value) { - this.anotherRequired = java.util.Objects.requireNonNull(value, "anotherRequired is required"); + this.$anotherRequired = java.util.Objects.requireNonNull(value, "anotherRequired is required"); } @Override public java.lang.Boolean getBool() { - return this.bool; + return this.$bool; } @Override public void setBool(final java.lang.Boolean value) { - this.bool = java.util.Objects.requireNonNull(value, "bool is required"); + this.$bool = java.util.Objects.requireNonNull(value, "bool is required"); } @Override public software.amazon.jsii.tests.calculator.DoubleTrouble getNonPrimitive() { - return this.nonPrimitive; + return this.$nonPrimitive; } @Override public void setNonPrimitive(final software.amazon.jsii.tests.calculator.DoubleTrouble value) { - this.nonPrimitive = java.util.Objects.requireNonNull(value, "nonPrimitive is required"); + this.$nonPrimitive = java.util.Objects.requireNonNull(value, "nonPrimitive is required"); } @Override public java.util.Map getAnotherOptional() { - return this.anotherOptional; + return this.$anotherOptional; } @Override public void setAnotherOptional(@javax.annotation.Nullable final java.util.Map value) { - this.anotherOptional = value; + this.$anotherOptional = value; } @Override public java.util.List getOptionalArray() { - return this.optionalArray; + return this.$optionalArray; } @Override public void setOptionalArray(@javax.annotation.Nullable final java.util.List value) { - this.optionalArray = value; + this.$optionalArray = value; } @Override public java.lang.Number getAnumber() { - return this.anumber; + return this.$anumber; } @Override public void setAnumber(final java.lang.Number value) { - this.anumber = java.util.Objects.requireNonNull(value, "anumber is required"); + this.$anumber = java.util.Objects.requireNonNull(value, "anumber is required"); } @Override public java.lang.String getAstring() { - return this.astring; + return this.$astring; } @Override public void setAstring(final java.lang.String value) { - this.astring = java.util.Objects.requireNonNull(value, "astring is required"); + this.$astring = java.util.Objects.requireNonNull(value, "astring is required"); } @Override public java.util.List getFirstOptional() { - return this.firstOptional; + return this.$firstOptional; } @Override public void setFirstOptional(@javax.annotation.Nullable final java.util.List value) { - this.firstOptional = value; + this.$firstOptional = value; } }; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/IInterfaceWithProperties.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/IInterfaceWithProperties.java index 0418d35bc3..c1cdea95c7 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/IInterfaceWithProperties.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/IInterfaceWithProperties.java @@ -46,22 +46,22 @@ public Builder withReadWriteString(final java.lang.String value) { */ public IInterfaceWithProperties build() { return new IInterfaceWithProperties() { - private final java.lang.String readOnlyString = java.util.Objects.requireNonNull(_readOnlyString, "readOnlyString is required"); - private java.lang.String readWriteString = java.util.Objects.requireNonNull(_readWriteString, "readWriteString is required"); + private final java.lang.String $readOnlyString = java.util.Objects.requireNonNull(_readOnlyString, "readOnlyString is required"); + private java.lang.String $readWriteString = java.util.Objects.requireNonNull(_readWriteString, "readWriteString is required"); @Override public java.lang.String getReadOnlyString() { - return this.readOnlyString; + return this.$readOnlyString; } @Override public java.lang.String getReadWriteString() { - return this.readWriteString; + return this.$readWriteString; } @Override public void setReadWriteString(final java.lang.String value) { - this.readWriteString = java.util.Objects.requireNonNull(value, "readWriteString is required"); + this.$readWriteString = java.util.Objects.requireNonNull(value, "readWriteString is required"); } }; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/IInterfaceWithPropertiesExtension.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/IInterfaceWithPropertiesExtension.java index 0ff8bf4feb..a1338fca65 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/IInterfaceWithPropertiesExtension.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/IInterfaceWithPropertiesExtension.java @@ -55,33 +55,33 @@ public Builder withReadWriteString(final java.lang.String value) { */ public IInterfaceWithPropertiesExtension build() { return new IInterfaceWithPropertiesExtension() { - private java.lang.Number foo = java.util.Objects.requireNonNull(_foo, "foo is required"); - private final java.lang.String readOnlyString = java.util.Objects.requireNonNull(_readOnlyString, "readOnlyString is required"); - private java.lang.String readWriteString = java.util.Objects.requireNonNull(_readWriteString, "readWriteString is required"); + private java.lang.Number $foo = java.util.Objects.requireNonNull(_foo, "foo is required"); + private final java.lang.String $readOnlyString = java.util.Objects.requireNonNull(_readOnlyString, "readOnlyString is required"); + private java.lang.String $readWriteString = java.util.Objects.requireNonNull(_readWriteString, "readWriteString is required"); @Override public java.lang.Number getFoo() { - return this.foo; + return this.$foo; } @Override public void setFoo(final java.lang.Number value) { - this.foo = java.util.Objects.requireNonNull(value, "foo is required"); + this.$foo = java.util.Objects.requireNonNull(value, "foo is required"); } @Override public java.lang.String getReadOnlyString() { - return this.readOnlyString; + return this.$readOnlyString; } @Override public java.lang.String getReadWriteString() { - return this.readWriteString; + return this.$readWriteString; } @Override public void setReadWriteString(final java.lang.String value) { - this.readWriteString = java.util.Objects.requireNonNull(value, "readWriteString is required"); + this.$readWriteString = java.util.Objects.requireNonNull(value, "readWriteString is required"); } }; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ImplictBaseOfBase.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ImplictBaseOfBase.java index 04f8272149..0eedd87b05 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ImplictBaseOfBase.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/ImplictBaseOfBase.java @@ -55,38 +55,38 @@ public Builder withFoo(final software.amazon.jsii.tests.calculator.baseofbase.Ve */ public ImplictBaseOfBase build() { return new ImplictBaseOfBase() { - private java.time.Instant goo = java.util.Objects.requireNonNull(_goo, "goo is required"); - private java.lang.String bar = java.util.Objects.requireNonNull(_bar, "bar is required"); - private software.amazon.jsii.tests.calculator.baseofbase.Very foo = java.util.Objects.requireNonNull(_foo, "foo is required"); + private java.time.Instant $goo = java.util.Objects.requireNonNull(_goo, "goo is required"); + private java.lang.String $bar = java.util.Objects.requireNonNull(_bar, "bar is required"); + private software.amazon.jsii.tests.calculator.baseofbase.Very $foo = java.util.Objects.requireNonNull(_foo, "foo is required"); @Override public java.time.Instant getGoo() { - return this.goo; + return this.$goo; } @Override public void setGoo(final java.time.Instant value) { - this.goo = java.util.Objects.requireNonNull(value, "goo is required"); + this.$goo = java.util.Objects.requireNonNull(value, "goo is required"); } @Override public java.lang.String getBar() { - return this.bar; + return this.$bar; } @Override public void setBar(final java.lang.String value) { - this.bar = java.util.Objects.requireNonNull(value, "bar is required"); + this.$bar = java.util.Objects.requireNonNull(value, "bar is required"); } @Override public software.amazon.jsii.tests.calculator.baseofbase.Very getFoo() { - return this.foo; + return this.$foo; } @Override public void setFoo(final software.amazon.jsii.tests.calculator.baseofbase.Very value) { - this.foo = java.util.Objects.requireNonNull(value, "foo is required"); + this.$foo = java.util.Objects.requireNonNull(value, "foo is required"); } }; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceIncludesClasses/Foo.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceIncludesClasses/Foo.java new file mode 100644 index 0000000000..2852ed0d71 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceIncludesClasses/Foo.java @@ -0,0 +1,22 @@ +package software.amazon.jsii.tests.calculator.InterfaceInNamespaceIncludesClasses; + +@javax.annotation.Generated(value = "jsii-pacmak") +@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.InterfaceInNamespaceIncludesClasses.Foo") +public class Foo extends software.amazon.jsii.JsiiObject { + protected Foo(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + public Foo() { + super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii); + software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this); + } + + @javax.annotation.Nullable + public java.lang.String getBar() { + return this.jsiiGet("bar", java.lang.String.class); + } + + public void setBar(@javax.annotation.Nullable final java.lang.String value) { + this.jsiiSet("bar", value); + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceIncludesClasses/Hello.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceIncludesClasses/Hello.java new file mode 100644 index 0000000000..62660862ae --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceIncludesClasses/Hello.java @@ -0,0 +1,72 @@ +package software.amazon.jsii.tests.calculator.InterfaceInNamespaceIncludesClasses; + +@javax.annotation.Generated(value = "jsii-pacmak") +public interface Hello extends software.amazon.jsii.JsiiSerializable { + java.lang.Number getFoo(); + void setFoo(final java.lang.Number value); + + /** + * @return a {@link Builder} of {@link Hello} + */ + static Builder builder() { + return new Builder(); + } + + /** + * A builder for {@link Hello} + */ + final class Builder { + private java.lang.Number _foo; + + /** + * Sets the value of Foo + * @param value the value to be set + * @return {@code this} + */ + public Builder withFoo(final java.lang.Number value) { + this._foo = java.util.Objects.requireNonNull(value, "foo is required"); + return this; + } + + /** + * Builds the configured instance. + * @return a new instance of {@link Hello} + * @throws NullPointerException if any required attribute was not provided + */ + public Hello build() { + return new Hello() { + private java.lang.Number $foo = java.util.Objects.requireNonNull(_foo, "foo is required"); + + @Override + public java.lang.Number getFoo() { + return this.$foo; + } + + @Override + public void setFoo(final java.lang.Number value) { + this.$foo = java.util.Objects.requireNonNull(value, "foo is required"); + } + + }; + } + } + + /** + * A proxy class which for javascript object literal which adhere to this interface. + */ + final class Jsii$Proxy extends software.amazon.jsii.JsiiObject implements software.amazon.jsii.tests.calculator.InterfaceInNamespaceIncludesClasses.Hello { + protected Jsii$Proxy(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + + @Override + public java.lang.Number getFoo() { + return this.jsiiGet("foo", java.lang.Number.class); + } + + @Override + public void setFoo(final java.lang.Number value) { + this.jsiiSet("foo", java.util.Objects.requireNonNull(value, "foo is required")); + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceOnlyInterface/Hello.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceOnlyInterface/Hello.java new file mode 100644 index 0000000000..748b424f1e --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceInNamespaceOnlyInterface/Hello.java @@ -0,0 +1,72 @@ +package software.amazon.jsii.tests.calculator.InterfaceInNamespaceOnlyInterface; + +@javax.annotation.Generated(value = "jsii-pacmak") +public interface Hello extends software.amazon.jsii.JsiiSerializable { + java.lang.Number getFoo(); + void setFoo(final java.lang.Number value); + + /** + * @return a {@link Builder} of {@link Hello} + */ + static Builder builder() { + return new Builder(); + } + + /** + * A builder for {@link Hello} + */ + final class Builder { + private java.lang.Number _foo; + + /** + * Sets the value of Foo + * @param value the value to be set + * @return {@code this} + */ + public Builder withFoo(final java.lang.Number value) { + this._foo = java.util.Objects.requireNonNull(value, "foo is required"); + return this; + } + + /** + * Builds the configured instance. + * @return a new instance of {@link Hello} + * @throws NullPointerException if any required attribute was not provided + */ + public Hello build() { + return new Hello() { + private java.lang.Number $foo = java.util.Objects.requireNonNull(_foo, "foo is required"); + + @Override + public java.lang.Number getFoo() { + return this.$foo; + } + + @Override + public void setFoo(final java.lang.Number value) { + this.$foo = java.util.Objects.requireNonNull(value, "foo is required"); + } + + }; + } + } + + /** + * A proxy class which for javascript object literal which adhere to this interface. + */ + final class Jsii$Proxy extends software.amazon.jsii.JsiiObject implements software.amazon.jsii.tests.calculator.InterfaceInNamespaceOnlyInterface.Hello { + protected Jsii$Proxy(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + + @Override + public java.lang.Number getFoo() { + return this.jsiiGet("foo", java.lang.Number.class); + } + + @Override + public void setFoo(final java.lang.Number value) { + this.jsiiSet("foo", java.util.Objects.requireNonNull(value, "foo is required")); + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceWithOptionalMethodArguments.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceWithOptionalMethodArguments.java new file mode 100644 index 0000000000..f21c69022a --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/InterfaceWithOptionalMethodArguments.java @@ -0,0 +1,30 @@ +package software.amazon.jsii.tests.calculator; + +/** + * awslabs/jsii#175 + * Interface proxies (and builders) do not respect optional arguments in methods + */ +@javax.annotation.Generated(value = "jsii-pacmak") +public interface InterfaceWithOptionalMethodArguments extends software.amazon.jsii.JsiiSerializable { + void hello(final java.lang.String arg1, @javax.annotation.Nullable final java.lang.Number arg2); + void hello(final java.lang.String arg1); + + /** + * A proxy class which for javascript object literal which adhere to this interface. + */ + final class Jsii$Proxy extends software.amazon.jsii.JsiiObject implements software.amazon.jsii.tests.calculator.InterfaceWithOptionalMethodArguments { + protected Jsii$Proxy(final software.amazon.jsii.JsiiObject.InitializationMode mode) { + super(mode); + } + + @Override + public void hello(final java.lang.String arg1, @javax.annotation.Nullable final java.lang.Number arg2) { + this.jsiiCall("hello", Void.class, java.util.stream.Stream.concat(java.util.stream.Stream.of(java.util.Objects.requireNonNull(arg1, "arg1 is required")), java.util.stream.Stream.of(arg2)).toArray()); + } + + @Override + public void hello(final java.lang.String arg1) { + this.jsiiCall("hello", Void.class, java.util.stream.Stream.of(java.util.Objects.requireNonNull(arg1, "arg1 is required")).toArray()); + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/UnionProperties.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/UnionProperties.java index 8acbd477a6..8ed0ae233c 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/UnionProperties.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/UnionProperties.java @@ -75,28 +75,28 @@ public Builder withFoo(@javax.annotation.Nullable final java.lang.Number value) */ public UnionProperties build() { return new UnionProperties() { - private final java.lang.Object bar = java.util.Objects.requireNonNull(_bar, "bar is required"); + private final java.lang.Object $bar = java.util.Objects.requireNonNull(_bar, "bar is required"); @javax.annotation.Nullable - private java.lang.Object foo = _foo; + private java.lang.Object $foo = _foo; @Override public java.lang.Object getBar() { - return this.bar; + return this.$bar; } @Override public java.lang.Object getFoo() { - return this.foo; + return this.$foo; } @Override public void setFoo(@javax.annotation.Nullable final java.lang.String value) { - this.foo = value; + this.$foo = value; } @Override public void setFoo(@javax.annotation.Nullable final java.lang.Number value) { - this.foo = value; + this.$foo = value; } }; 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 7052fc58fc..03839d4628 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 @@ -222,12 +222,12 @@ AllTypes .. py:attribute:: anyArrayProperty - :type: any + :type: any[] .. py:attribute:: anyMapProperty - :type: any + :type: string => any .. py:attribute:: anyProperty @@ -237,7 +237,7 @@ AllTypes .. py:attribute:: arrayProperty - :type: string + :type: string[] .. py:attribute:: booleanProperty @@ -262,7 +262,7 @@ AllTypes .. py:attribute:: mapProperty - :type: number + :type: string => number .. py:attribute:: numberProperty @@ -277,12 +277,12 @@ AllTypes .. py:attribute:: unionArrayProperty - :type: number or :py:class:`~jsii-calc.composition.CompositeOperation` + :type: (number or :py:class:`~jsii-calc.composition.CompositeOperation`)[] .. py:attribute:: unionMapProperty - :type: string or number + :type: string => (string or number) .. py:attribute:: unionProperty @@ -292,12 +292,12 @@ AllTypes .. py:attribute:: unknownArrayProperty - :type: any + :type: any[] .. py:attribute:: unknownMapProperty - :type: any + :type: string => any .. py:attribute:: unknownProperty @@ -628,7 +628,7 @@ Calculator A log of all operations. - :type: :py:class:`@scope/jsii-calc-lib.Value` *(readonly)* + :type: :py:class:`@scope/jsii-calc-lib.Value`[] *(readonly)* .. py:attribute:: operationsMap @@ -636,7 +636,7 @@ Calculator A map of per operation name of all operations performed. - :type: :py:class:`@scope/jsii-calc-lib.Value` *(readonly)* + :type: string => :py:class:`@scope/jsii-calc-lib.Value`[] *(readonly)* .. py:attribute:: curr @@ -831,12 +831,12 @@ DerivedStruct (interface) This is optional. - :type: :py:class:`@scope/jsii-calc-lib.Value` or undefined + :type: string => :py:class:`@scope/jsii-calc-lib.Value` or undefined .. py:attribute:: optionalArray - :type: string or undefined + :type: string[] or undefined DoubleTrouble @@ -1178,6 +1178,163 @@ ImplictBaseOfBase (interface) :type: date + +InterfaceInNamespaceIncludesClasses +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. py:module:: jsii-calc.InterfaceInNamespaceIncludesClasses + +Foo +~~~ + +.. py:class:: Foo() + + **Language-specific names:** + + .. tabs:: + + .. code-tab:: c# + + using Amazon.JSII.Tests.CalculatorNamespace; + + .. code-tab:: java + + import software.amazon.jsii.tests.calculator.InterfaceInNamespaceIncludesClasses.Foo; + + .. code-tab:: javascript + + const { InterfaceInNamespaceIncludesClasses.Foo } = require('jsii-calc'); + + .. code-tab:: typescript + + import { InterfaceInNamespaceIncludesClasses.Foo } from 'jsii-calc'; + + + + + .. py:attribute:: bar + + :type: string or undefined + + +Hello (interface) +~~~~~~~~~~~~~~~~~ + +.. py:class:: Hello + + **Language-specific names:** + + .. tabs:: + + .. code-tab:: c# + + using Amazon.JSII.Tests.CalculatorNamespace; + + .. code-tab:: java + + import software.amazon.jsii.tests.calculator.InterfaceInNamespaceIncludesClasses.Hello; + + .. code-tab:: javascript + + // InterfaceInNamespaceIncludesClasses.Hello is an interface + + .. code-tab:: typescript + + import { InterfaceInNamespaceIncludesClasses.Hello } from 'jsii-calc'; + + + + + + .. py:attribute:: foo + + :type: number + + + +.. py:currentmodule:: jsii-calc + + +InterfaceInNamespaceOnlyInterface +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. py:module:: jsii-calc.InterfaceInNamespaceOnlyInterface + +Hello (interface) +~~~~~~~~~~~~~~~~~ + +.. py:class:: Hello + + **Language-specific names:** + + .. tabs:: + + .. code-tab:: c# + + using Amazon.JSII.Tests.CalculatorNamespace; + + .. code-tab:: java + + import software.amazon.jsii.tests.calculator.InterfaceInNamespaceOnlyInterface.Hello; + + .. code-tab:: javascript + + // InterfaceInNamespaceOnlyInterface.Hello is an interface + + .. code-tab:: typescript + + import { InterfaceInNamespaceOnlyInterface.Hello } from 'jsii-calc'; + + + + + + .. py:attribute:: foo + + :type: number + + + +.. py:currentmodule:: jsii-calc + +InterfaceWithOptionalMethodArguments (interface) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. py:class:: InterfaceWithOptionalMethodArguments + + **Language-specific names:** + + .. tabs:: + + .. code-tab:: c# + + using Amazon.JSII.Tests.CalculatorNamespace; + + .. code-tab:: java + + import software.amazon.jsii.tests.calculator.InterfaceWithOptionalMethodArguments; + + .. code-tab:: javascript + + // InterfaceWithOptionalMethodArguments is an interface + + .. code-tab:: typescript + + import { InterfaceWithOptionalMethodArguments } from 'jsii-calc'; + + + + awslabs/jsii#175 Interface proxies (and builders) do not respect optional arguments in methods + + + + + .. py:method:: hello(arg1, [arg2]) + + :param arg1: + :type arg1: string + :param arg2: + :type arg2: number or undefined + + JSObjectLiteralForInterface ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1834,7 +1991,7 @@ ObjectRefsInCollections :param values: - :type values: :py:class:`@scope/jsii-calc-lib.Value` + :type values: :py:class:`@scope/jsii-calc-lib.Value`[] :rtype: number @@ -1844,7 +2001,7 @@ ObjectRefsInCollections :param values: - :type values: :py:class:`@scope/jsii-calc-lib.Value` + :type values: string => :py:class:`@scope/jsii-calc-lib.Value` :rtype: number @@ -2176,7 +2333,7 @@ Statics Constants can also use camelCase. - :type: string *(readonly)* *(static)* + :type: string => string *(readonly)* *(static)* .. py:attribute:: instance @@ -2276,7 +2433,7 @@ Sum The parts to sum. - :type: :py:class:`@scope/jsii-calc-lib.Value` + :type: :py:class:`@scope/jsii-calc-lib.Value`[] SyncVirtualMethods @@ -2662,7 +2819,7 @@ VariadicMethod :type first: number :param \*others: other elements to be included in the array. :type \*others: number - :rtype: number + :rtype: number[] VirtualMethodPlayground @@ -2795,7 +2952,7 @@ CompositeOperation A set of postfixes to include in a decorated .toString(). - :type: string + :type: string[] .. py:attribute:: decorationPrefixes @@ -2803,7 +2960,7 @@ CompositeOperation A set of prefixes to include in a decorated .toString(). - :type: string + :type: string[] .. py:attribute:: stringStyle diff --git a/packages/jsii-pacmak/tsconfig.json b/packages/jsii-pacmak/tsconfig.json index 6f8f29cf64..3f968d60b3 100644 --- a/packages/jsii-pacmak/tsconfig.json +++ b/packages/jsii-pacmak/tsconfig.json @@ -44,8 +44,8 @@ /* Source Map Options */ // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": false, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": false, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ /* Experimental Options */ "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */ diff --git a/packages/jsii/lib/assembler.ts b/packages/jsii/lib/assembler.ts index 9c1b4126b9..672db268af 100644 --- a/packages/jsii/lib/assembler.ts +++ b/packages/jsii/lib/assembler.ts @@ -243,17 +243,18 @@ export class Assembler implements Emitter { } else if (ts.isEnumDeclaration(node) && _isExported(node)) { jsiiType = await this._visitEnum(this._typeChecker.getTypeAtLocation(node), namePrefix); } else if (ts.isModuleDeclaration(node)) { - const moduleType = this._typeChecker.getTypeAtLocation(node); - if (LOG.isTraceEnabled()) { - LOG.trace(`Entering namespace: ${colors.cyan([...namePrefix, moduleType.symbol.name].join('.'))}`); - } + const moduleDecl = node as ts.ModuleDeclaration; + const name = node.name.getText(); + const symbol = (moduleDecl as any).symbol; + + if (LOG.isTraceEnabled()) { LOG.trace(`Entering namespace: ${colors.cyan([...namePrefix, name].join('.'))}`); } + const allTypes = new Array(); - for (const prop of moduleType.getProperties()) { - allTypes.push(...await this._visitNode(prop.valueDeclaration, namePrefix.concat(node.name.getText()))); - } - if (LOG.isTraceEnabled()) { - LOG.trace(`Leaving namespace: ${colors.cyan([...namePrefix, moduleType.symbol.name].join('.'))}`); + for (const prop of this._typeChecker.getExportsOfModule(symbol)) { + allTypes.push(...await this._visitNode(prop.declarations[0], namePrefix.concat(node.name.getText()))); } + + if (LOG.isTraceEnabled()) { LOG.trace(`Leaving namespace: ${colors.cyan([...namePrefix, name].join('.'))}`); } return allTypes; } else { this._diagnostic(node, ts.DiagnosticCategory.Message, `Skipping ${ts.SyntaxKind[node.kind]} node`); @@ -382,7 +383,7 @@ export class Assembler implements Emitter { jsiiType.initializer.parameters = jsiiType.initializer.parameters || []; jsiiType.initializer.parameters.push(await this._toParameter(param)); if (ts.isParameterPropertyDeclaration(param.valueDeclaration)) { - this._visitProperty(param, jsiiType); + await this._visitProperty(param, jsiiType); } jsiiType.initializer.variadic = jsiiType.initializer.parameters && jsiiType.initializer.parameters.find(p => !!p.variadic) != null; @@ -391,18 +392,20 @@ export class Assembler implements Emitter { this._visitDocumentation(constructor, jsiiType.initializer); } } else if (jsiiType.base) { - const baseType = this._dereference(jsiiType.base); - if (!baseType) { - this._diagnostic(type.symbol.valueDeclaration, - ts.DiagnosticCategory.Error, - `Unable to resolve type ${jsiiType.base.fqn} (base type of ${jsiiType.fqn})`); - } else if (spec.isClassType(baseType)) { - jsiiType.initializer = baseType.initializer; - } else { - this._diagnostic(type.symbol.valueDeclaration, - ts.DiagnosticCategory.Error, - `Base type of ${jsiiType.fqn} (${jsiiType.base.fqn}) is not a class`); - } + this._defer(() => { + const baseType = this._dereference(jsiiType.base!); + if (!baseType) { + this._diagnostic(type.symbol.valueDeclaration, + ts.DiagnosticCategory.Error, + `Unable to resolve type ${jsiiType.base!.fqn} (base type of ${jsiiType.fqn})`); + } else if (spec.isClassType(baseType)) { + jsiiType.initializer = baseType.initializer; + } else { + this._diagnostic(type.symbol.valueDeclaration, + ts.DiagnosticCategory.Error, + `Base type of ${jsiiType.fqn} (${jsiiType.base!.fqn}) is not a class`); + } + }); } else { jsiiType.initializer = { initializer: true }; } @@ -495,12 +498,20 @@ export class Assembler implements Emitter { `Base type of ${jsiiType.fqn} is not a named type (${spec.describeTypeReference(ref)})`); continue; } - if (!spec.isInterfaceType(this._dereference(ref))) { - this._diagnostic(base.symbol.valueDeclaration, - ts.DiagnosticCategory.Error, - `Base type of ${jsiiType.fqn} is not an interface (${spec.describeTypeReference(ref)})`); - continue; - } + this._defer(() => { + if (!spec.isInterfaceType(this._dereference(ref))) { + const baseType = this._dereference(ref); + if (baseType) { + this._diagnostic(base.symbol.valueDeclaration, + ts.DiagnosticCategory.Error, + `Base type of ${jsiiType.fqn} is not an interface (${baseType.kind} ${spec.describeTypeReference(ref)})`); + } else { + this._diagnostic(base.symbol.valueDeclaration, + ts.DiagnosticCategory.Error, + `Base type of ${jsiiType.fqn} could not be resolved (${spec.describeTypeReference(ref)})`); + } + } + }); if (jsiiType.interfaces) { jsiiType.interfaces.push(ref); } else { diff --git a/packages/jsii/lib/project-info.ts b/packages/jsii/lib/project-info.ts index 729d9615c6..380743acd3 100644 --- a/packages/jsii/lib/project-info.ts +++ b/packages/jsii/lib/project-info.ts @@ -141,7 +141,8 @@ function _toPerson(value: any, field: string, defaultRole: string = field): spec function _tryResolve(mod: string, searchPath: string): string { try { - return require.resolve(mod, { paths: [searchPath] }); + const paths = [ searchPath, path.join(searchPath, 'node_modules') ]; + return require.resolve(mod, { paths }); } catch (e) { throw new Error(`Unable to locate module: ${mod}`); }