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): Return object literals as references #249

Merged
merged 5 commits into from
Sep 28, 2018
Merged
Show file tree
Hide file tree
Changes from 2 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
8 changes: 8 additions & 0 deletions packages/jsii-calc/lib/compliance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -887,3 +887,11 @@ export class AbstractClassReturner {
}
}
}

export interface MutableObjectLiteral {
value: string;
}

export class ClassWithMutableObjectLiteralProperty {
public mutableObject: MutableObjectLiteral = { value: 'default' };
}
35 changes: 34 additions & 1 deletion packages/jsii-calc/test/assembly.jsii
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,23 @@
}
]
},
"jsii-calc.ClassWithMutableObjectLiteralProperty": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.ClassWithMutableObjectLiteralProperty",
"initializer": {
"initializer": true
},
"kind": "class",
"name": "ClassWithMutableObjectLiteralProperty",
"properties": [
{
"name": "mutableObject",
"type": {
"fqn": "jsii-calc.MutableObjectLiteral"
}
}
]
},
"jsii-calc.DefaultedConstructorArgument": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.DefaultedConstructorArgument",
Expand Down Expand Up @@ -1883,6 +1900,22 @@
}
]
},
"jsii-calc.MutableObjectLiteral": {
"assembly": "jsii-calc",
"datatype": true,
"fqn": "jsii-calc.MutableObjectLiteral",
"kind": "interface",
"name": "MutableObjectLiteral",
"properties": [
{
"abstract": true,
"name": "value",
"type": {
"primitive": "string"
}
}
]
},
"jsii-calc.Negate": {
"assembly": "jsii-calc",
"base": {
Expand Down Expand Up @@ -3230,5 +3263,5 @@
}
},
"version": "0.7.6",
"fingerprint": "ecDtx3DHVZi7UjyCDhGncg4jbSRaD536bUyh6YzAxlY="
"fingerprint": "DFShLmIJQmPjTv5Dmz4JoBKqoCtAyifD1RpCuHo+sEc="
}
18 changes: 12 additions & 6 deletions packages/jsii-kernel/lib/kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { TOKEN_DATE, TOKEN_ENUM, TOKEN_REF } from './api';
*/
const OBJID_PROP = '$__jsii__objid__$';
const FQN_PROP = '$__jsii__fqn__$';
const PROXIES_PROP = '$__jsii__proxies__$';

/**
* A special FQN that can be used to create empty javascript objects.
Expand Down Expand Up @@ -923,12 +924,17 @@ export class Kernel {
// so the client receives a real object.
if (typeof(v) === 'object' && targetType && spec.isNamedTypeReference(targetType)) {
this._debug('coalescing to', targetType);
const newObjRef = this._create({ fqn: targetType.fqn });
const newObj = this._findObject(newObjRef);
for (const k of Object.keys(v)) {
newObj[k] = v[k];
}
return newObjRef;
const proxies = v[PROXIES_PROP] = v[PROXIES_PROP] || {};
RomainMuller marked this conversation as resolved.
Show resolved Hide resolved
if (proxies[targetType.fqn]) { return proxies[targetType.fqn]; }
const proxy = new Proxy(v, {
has(target: any, propertyKey: string) {
return propertyKey in target || propertyKey === FQN_PROP;
RomainMuller marked this conversation as resolved.
Show resolved Hide resolved
},
get(target: any, propertyKey: string) {
return propertyKey === FQN_PROP ? targetType.fqn : target[propertyKey];
}
});
return this._createObjref(proxy, targetType.fqn);
}

// date (https://stackoverflow.com/a/643827/737957)
Expand Down
15 changes: 15 additions & 0 deletions packages/jsii-kernel/test/test.kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,21 @@ defineTest('node.js standard library', async (test, sandbox) => {
{ result: "6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50" });
});

// @see awslabs/jsii#248
defineTest('object literals are returned by reference', async (test, sandbox) => {
const objref = sandbox.create({ fqn: 'jsii-calc.ClassWithMutableObjectLiteralProperty' });
const property = sandbox.get({ objref, property: 'mutableObject' }).value;

const newValue = 'Bazinga!1!';
sandbox.set({ objref: property, property: 'value', value: newValue });

test.equal(newValue,
sandbox.get({
objref: sandbox.get({ objref, property: 'mutableObject' }).value,
property: 'value'
}).value);
});

const testNames: { [name: string]: boolean } = { };

async function createCalculatorSandbox(name: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,23 @@
}
]
},
"jsii-calc.ClassWithMutableObjectLiteralProperty": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.ClassWithMutableObjectLiteralProperty",
"initializer": {
"initializer": true
},
"kind": "class",
"name": "ClassWithMutableObjectLiteralProperty",
"properties": [
{
"name": "mutableObject",
"type": {
"fqn": "jsii-calc.MutableObjectLiteral"
}
}
]
},
"jsii-calc.DefaultedConstructorArgument": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.DefaultedConstructorArgument",
Expand Down Expand Up @@ -1883,6 +1900,22 @@
}
]
},
"jsii-calc.MutableObjectLiteral": {
"assembly": "jsii-calc",
"datatype": true,
"fqn": "jsii-calc.MutableObjectLiteral",
"kind": "interface",
"name": "MutableObjectLiteral",
"properties": [
{
"abstract": true,
"name": "value",
"type": {
"primitive": "string"
}
}
]
},
"jsii-calc.Negate": {
"assembly": "jsii-calc",
"base": {
Expand Down Expand Up @@ -3230,5 +3263,5 @@
}
},
"version": "0.7.6",
"fingerprint": "ecDtx3DHVZi7UjyCDhGncg4jbSRaD536bUyh6YzAxlY="
"fingerprint": "DFShLmIJQmPjTv5Dmz4JoBKqoCtAyifD1RpCuHo+sEc="
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Amazon.JSII.Runtime.Deputy;

namespace Amazon.JSII.Tests.CalculatorNamespace
{
[JsiiClass(typeof(ClassWithMutableObjectLiteralProperty), "jsii-calc.ClassWithMutableObjectLiteralProperty", "[]")]
public class ClassWithMutableObjectLiteralProperty : DeputyBase
{
public ClassWithMutableObjectLiteralProperty(): base(new DeputyProps(new object[]{}))
{
}

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

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

[JsiiProperty("mutableObject", "{\"fqn\":\"jsii-calc.MutableObjectLiteral\"}")]
public virtual IMutableObjectLiteral MutableObject
{
get => GetInstanceProperty<IMutableObjectLiteral>();
set => SetInstanceProperty(value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Amazon.JSII.Runtime.Deputy;

namespace Amazon.JSII.Tests.CalculatorNamespace
{
[JsiiInterface(typeof(IMutableObjectLiteral), "jsii-calc.MutableObjectLiteral")]
public interface IMutableObjectLiteral
{
[JsiiProperty("value", "{\"primitive\":\"string\"}")]
string Value
{
get;
set;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Amazon.JSII.Runtime.Deputy;

namespace Amazon.JSII.Tests.CalculatorNamespace
{
public class MutableObjectLiteral : DeputyBase, IMutableObjectLiteral
{
[JsiiProperty("value", "{\"primitive\":\"string\"}", true)]
public string Value
{
get;
set;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Amazon.JSII.Runtime.Deputy;

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

[JsiiProperty("value", "{\"primitive\":\"string\"}")]
public string Value
{
get => GetInstanceProperty<string>();
set => SetInstanceProperty(value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ protected Class<?> resolveClass(final String fqn) throws ClassNotFoundException
case "jsii-calc.BinaryOperation": return software.amazon.jsii.tests.calculator.BinaryOperation.class;
case "jsii-calc.Calculator": return software.amazon.jsii.tests.calculator.Calculator.class;
case "jsii-calc.CalculatorProps": return software.amazon.jsii.tests.calculator.CalculatorProps.class;
case "jsii-calc.ClassWithMutableObjectLiteralProperty": return software.amazon.jsii.tests.calculator.ClassWithMutableObjectLiteralProperty.class;
case "jsii-calc.DefaultedConstructorArgument": return software.amazon.jsii.tests.calculator.DefaultedConstructorArgument.class;
case "jsii-calc.DerivedClassHasNoProperties.Base": return software.amazon.jsii.tests.calculator.DerivedClassHasNoProperties.Base.class;
case "jsii-calc.DerivedClassHasNoProperties.Derived": return software.amazon.jsii.tests.calculator.DerivedClassHasNoProperties.Derived.class;
Expand All @@ -51,6 +52,7 @@ protected Class<?> resolveClass(final String fqn) throws ClassNotFoundException
case "jsii-calc.JSObjectLiteralToNativeClass": return software.amazon.jsii.tests.calculator.JSObjectLiteralToNativeClass.class;
case "jsii-calc.JavaReservedWords": return software.amazon.jsii.tests.calculator.JavaReservedWords.class;
case "jsii-calc.Multiply": return software.amazon.jsii.tests.calculator.Multiply.class;
case "jsii-calc.MutableObjectLiteral": return software.amazon.jsii.tests.calculator.MutableObjectLiteral.class;
case "jsii-calc.Negate": return software.amazon.jsii.tests.calculator.Negate.class;
case "jsii-calc.NodeStandardLibrary": return software.amazon.jsii.tests.calculator.NodeStandardLibrary.class;
case "jsii-calc.NumberGenerator": return software.amazon.jsii.tests.calculator.NumberGenerator.class;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package software.amazon.jsii.tests.calculator;

@javax.annotation.Generated(value = "jsii-pacmak")
@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.ClassWithMutableObjectLiteralProperty")
public class ClassWithMutableObjectLiteralProperty extends software.amazon.jsii.JsiiObject {
protected ClassWithMutableObjectLiteralProperty(final software.amazon.jsii.JsiiObject.InitializationMode mode) {
super(mode);
}
public ClassWithMutableObjectLiteralProperty() {
super(software.amazon.jsii.JsiiObject.InitializationMode.Jsii);
software.amazon.jsii.JsiiEngine.getInstance().createNewObject(this);
}

public software.amazon.jsii.tests.calculator.MutableObjectLiteral getMutableObject() {
return this.jsiiGet("mutableObject", software.amazon.jsii.tests.calculator.MutableObjectLiteral.class);
}

public void setMutableObject(final software.amazon.jsii.tests.calculator.MutableObjectLiteral value) {
this.jsiiSet("mutableObject", java.util.Objects.requireNonNull(value, "mutableObject is required"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package software.amazon.jsii.tests.calculator;

@javax.annotation.Generated(value = "jsii-pacmak")
public interface MutableObjectLiteral extends software.amazon.jsii.JsiiSerializable {
java.lang.String getValue();
void setValue(final java.lang.String value);

/**
* @return a {@link Builder} of {@link MutableObjectLiteral}
*/
static Builder builder() {
return new Builder();
}

/**
* A builder for {@link MutableObjectLiteral}
*/
final class Builder {
private java.lang.String _value;

/**
* Sets the value of Value
* @param value the value to be set
* @return {@code this}
*/
public Builder withValue(final java.lang.String value) {
this._value = java.util.Objects.requireNonNull(value, "value is required");
return this;
}

/**
* Builds the configured instance.
* @return a new instance of {@link MutableObjectLiteral}
* @throws NullPointerException if any required attribute was not provided
*/
public MutableObjectLiteral build() {
return new MutableObjectLiteral() {
private java.lang.String $value = java.util.Objects.requireNonNull(_value, "value is required");

@Override
public java.lang.String getValue() {
return this.$value;
}

@Override
public void setValue(final java.lang.String value) {
this.$value = java.util.Objects.requireNonNull(value, "value is required");
}

};
}
}

/**
* 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.MutableObjectLiteral {
protected Jsii$Proxy(final software.amazon.jsii.JsiiObject.InitializationMode mode) {
super(mode);
}

@Override
public java.lang.String getValue() {
return this.jsiiGet("value", java.lang.String.class);
}

@Override
public void setValue(final java.lang.String value) {
this.jsiiSet("value", java.util.Objects.requireNonNull(value, "value is required"));
}
}
}
Loading