Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(kernel): Correctly return instances of un-exported types #321

Merged
merged 2 commits into from
Nov 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/jsii-build-tools/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions packages/jsii-calc/lib/compliance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1196,3 +1196,28 @@ export interface LoadBalancedFargateServiceProps {
*/
publicTasks?: boolean;
}

/**
* Helps ensure the JSII kernel & runtime cooperate correctly when an un-exported instance of a class is returned with
* a declared type that is an exported interface, and the instance inherits from an exported class.
*
* @returns an instance of an un-exported class that extends ``ExportedBaseClass``, declared as ``IPrivatelyImplemented``.
*
* @see https://github.com/awslabs/jsii/issues/320
*/
export class ReturnsPrivateImplementationOfInterface {
public get privateImplementation(): IPrivatelyImplemented {
return new PrivateImplementation();
}
}
export interface IPrivatelyImplemented {
readonly success: boolean;
}
export class ExportedBaseClass {
constructor(public readonly success: boolean) {}
}
class PrivateImplementation extends ExportedBaseClass implements IPrivatelyImplemented {
constructor() {
super(true);
}
}
67 changes: 66 additions & 1 deletion packages/jsii-calc/test/assembly.jsii
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,32 @@
],
"name": "DoubleTrouble"
},
"jsii-calc.ExportedBaseClass": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.ExportedBaseClass",
"initializer": {
"initializer": true,
"parameters": [
{
"name": "success",
"type": {
"primitive": "boolean"
}
}
]
},
"kind": "class",
"name": "ExportedBaseClass",
"properties": [
{
"immutable": true,
"name": "success",
"type": {
"primitive": "boolean"
}
}
]
},
"jsii-calc.GiveMeStructs": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.GiveMeStructs",
Expand Down Expand Up @@ -1633,6 +1659,22 @@
],
"name": "IInterfaceWithOptionalMethodArguments"
},
"jsii-calc.IPrivatelyImplemented": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.IPrivatelyImplemented",
"kind": "interface",
"name": "IPrivatelyImplemented",
"properties": [
{
"abstract": true,
"immutable": true,
"name": "success",
"type": {
"primitive": "boolean"
}
}
]
},
"jsii-calc.IRandomNumberGenerator": {
"assembly": "jsii-calc",
"docs": {
Expand Down Expand Up @@ -2825,6 +2867,29 @@
}
]
},
"jsii-calc.ReturnsPrivateImplementationOfInterface": {
"assembly": "jsii-calc",
"docs": {
"comment": "Helps ensure the JSII kernel & runtime cooperate correctly when an un-exported instance of a class is returned with\na declared type that is an exported interface, and the instance inherits from an exported class.",
"return": "an instance of an un-exported class that extends ``ExportedBaseClass``, declared as ``IPrivatelyImplemented``.",
"see": "https://github.com/awslabs/jsii/issues/320"
},
"fqn": "jsii-calc.ReturnsPrivateImplementationOfInterface",
"initializer": {
"initializer": true
},
"kind": "class",
"name": "ReturnsPrivateImplementationOfInterface",
"properties": [
{
"immutable": true,
"name": "privateImplementation",
"type": {
"fqn": "jsii-calc.IPrivatelyImplemented"
}
}
]
},
"jsii-calc.RuntimeTypeChecking": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.RuntimeTypeChecking",
Expand Down Expand Up @@ -3671,5 +3736,5 @@
}
},
"version": "0.7.11",
"fingerprint": "2o7FtEirv0LpuaJ1G+wAxoHTW7FHr4U1taZ5GcVYt2o="
"fingerprint": "Nw3vyHfzec4IFe674buqsgL3x8QgvKP0lUC3csRIW7g="
}
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,12 @@ public void NullShouldBeTreatedAsUndefined()
obj.VerifyPropertyIsUndefined();
}

[Fact(DisplayName = Prefix + nameof(ReceiveInstanceOfPrivateClass))]
public void ReceiveInstanceOfPrivateClass()
{
Assert.True(new ReturnsPrivateImplementationOfInterface().PrivateImplementation.Success);
}

class NumberReturner : DeputyBase, IIReturnsNumber
{
public NumberReturner(double number)
Expand Down
7 changes: 5 additions & 2 deletions packages/jsii-java-runtime-test/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import software.amazon.jsii.tests.calculator.Polymorphism;
import software.amazon.jsii.tests.calculator.Power;
import software.amazon.jsii.tests.calculator.ReferenceEnumFromScopedPackage;
import software.amazon.jsii.tests.calculator.ReturnsPrivateImplementationOfInterface;
import software.amazon.jsii.tests.calculator.Statics;
import software.amazon.jsii.tests.calculator.Sum;
import software.amazon.jsii.tests.calculator.SyncVirtualMethods;
Expand Down Expand Up @@ -953,6 +954,14 @@ public void nullShouldBeTreatedAsUndefined() {
obj.verifyPropertyIsUndefined();
}

/**
* @see https://github.com/awslabs/jsii/issues/320
*/
@Test
public void receiveInstanceOfPrivateClass() {
assertTrue(new ReturnsPrivateImplementationOfInterface().getPrivateImplementation().getSuccess());
}

static class MulTen extends Multiply {
public MulTen(final int value) {
super(new Number(value), new Number(10));
Expand Down
2 changes: 1 addition & 1 deletion packages/jsii-java-runtime/pom.xml.t.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ process.stdout.write(`<?xml version="1.0" encoding="UTF-8"?>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>[1.2,)</version>
<version>[1.3.2,)</version>
<scope>provided</scope>
</dependency>
</dependencies>
Expand Down
11 changes: 9 additions & 2 deletions packages/jsii-kernel/lib/kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,12 @@ export class Kernel {
case spec.TypeKind.Class:
case spec.TypeKind.Enum:
const constructor = this._findSymbol(fqn);
constructor.__jsii__ = { fqn };
Object.defineProperty(constructor, '__jsii__', {
configurable: false,
enumerable: false,
writable: false,
value: { fqn }
});
}
}
}
Expand Down Expand Up @@ -956,7 +961,9 @@ export class Kernel {
// have an object id, so we need to allocate one for it.
this._debug('creating objref for', v);
const fqn = this._fqnForObject(v);
return this._createObjref(v, fqn);
if (!targetType || !spec.isNamedTypeReference(targetType) || fqn === targetType.fqn) {
return this._createObjref(v, fqn);
}
}

// if the method/property returns an object literal and the return type
Expand Down
2 changes: 1 addition & 1 deletion packages/jsii-pacmak/lib/targets/java.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ class JavaGenerator extends Generator {

'properties': { 'project.build.sourceEncoding': 'UTF-8' },

'dependencies': { dependency: mavenDependencies() },
'dependencies': { dependency: mavenDependencies() },

'build': {
plugins: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,32 @@
],
"name": "DoubleTrouble"
},
"jsii-calc.ExportedBaseClass": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.ExportedBaseClass",
"initializer": {
"initializer": true,
"parameters": [
{
"name": "success",
"type": {
"primitive": "boolean"
}
}
]
},
"kind": "class",
"name": "ExportedBaseClass",
"properties": [
{
"immutable": true,
"name": "success",
"type": {
"primitive": "boolean"
}
}
]
},
"jsii-calc.GiveMeStructs": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.GiveMeStructs",
Expand Down Expand Up @@ -1633,6 +1659,22 @@
],
"name": "IInterfaceWithOptionalMethodArguments"
},
"jsii-calc.IPrivatelyImplemented": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.IPrivatelyImplemented",
"kind": "interface",
"name": "IPrivatelyImplemented",
"properties": [
{
"abstract": true,
"immutable": true,
"name": "success",
"type": {
"primitive": "boolean"
}
}
]
},
"jsii-calc.IRandomNumberGenerator": {
"assembly": "jsii-calc",
"docs": {
Expand Down Expand Up @@ -2825,6 +2867,29 @@
}
]
},
"jsii-calc.ReturnsPrivateImplementationOfInterface": {
"assembly": "jsii-calc",
"docs": {
"comment": "Helps ensure the JSII kernel & runtime cooperate correctly when an un-exported instance of a class is returned with\na declared type that is an exported interface, and the instance inherits from an exported class.",
"return": "an instance of an un-exported class that extends ``ExportedBaseClass``, declared as ``IPrivatelyImplemented``.",
"see": "https://github.com/awslabs/jsii/issues/320"
},
"fqn": "jsii-calc.ReturnsPrivateImplementationOfInterface",
"initializer": {
"initializer": true
},
"kind": "class",
"name": "ReturnsPrivateImplementationOfInterface",
"properties": [
{
"immutable": true,
"name": "privateImplementation",
"type": {
"fqn": "jsii-calc.IPrivatelyImplemented"
}
}
]
},
"jsii-calc.RuntimeTypeChecking": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.RuntimeTypeChecking",
Expand Down Expand Up @@ -3671,5 +3736,5 @@
}
},
"version": "0.7.11",
"fingerprint": "2o7FtEirv0LpuaJ1G+wAxoHTW7FHr4U1taZ5GcVYt2o="
"fingerprint": "Nw3vyHfzec4IFe674buqsgL3x8QgvKP0lUC3csRIW7g="
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Amazon.JSII.Runtime.Deputy;

namespace Amazon.JSII.Tests.CalculatorNamespace
{
[JsiiClass(typeof(ExportedBaseClass), "jsii-calc.ExportedBaseClass", "[{\"name\":\"success\",\"type\":{\"primitive\":\"boolean\"}}]")]
public class ExportedBaseClass : DeputyBase
{
public ExportedBaseClass(bool success): base(new DeputyProps(new object[]{success}))
{
}

protected ExportedBaseClass(ByRefValue reference): base(reference)
{
}

protected ExportedBaseClass(DeputyProps props): base(props)
{
}

[JsiiProperty("success", "{\"primitive\":\"boolean\"}")]
public virtual bool Success
{
get => GetInstanceProperty<bool>();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Amazon.JSII.Runtime.Deputy;

namespace Amazon.JSII.Tests.CalculatorNamespace
{
[JsiiInterface(typeof(IIPrivatelyImplemented), "jsii-calc.IPrivatelyImplemented")]
public interface IIPrivatelyImplemented
{
[JsiiProperty("success", "{\"primitive\":\"boolean\"}")]
bool Success
{
get;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Amazon.JSII.Runtime.Deputy;

namespace Amazon.JSII.Tests.CalculatorNamespace
{
[JsiiTypeProxy(typeof(IIPrivatelyImplemented), "jsii-calc.IPrivatelyImplemented")]
internal sealed class IPrivatelyImplementedProxy : DeputyBase, IIPrivatelyImplemented
{
private IPrivatelyImplementedProxy(ByRefValue reference): base(reference)
{
}

[JsiiProperty("success", "{\"primitive\":\"boolean\"}")]
public bool Success
{
get => GetInstanceProperty<bool>();
}
}
}
Loading