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(jsii-runtime): treat "null" as "undefined" #297

Merged
merged 4 commits into from
Nov 7, 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
3 changes: 1 addition & 2 deletions packages/jsii-calc-base/test/assembly.jsii
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@
},
"name": "typeName",
"returns": {
"optional": true,
"primitive": "any"
}
}
Expand Down Expand Up @@ -103,5 +102,5 @@
}
},
"version": "0.7.8",
"fingerprint": "K1rAUs6WiQ5lF08T46B8v/5UL8T8Ot59e0Nc8rh2jiQ="
"fingerprint": "FbKHAP60R40tOOnvhCeDrZDrNlgzIypOfAdWPed+Jog="
}
55 changes: 55 additions & 0 deletions packages/jsii-calc/lib/compliance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -939,3 +939,58 @@ export interface IInterfaceWithMethods {
export interface IInterfaceThatShouldNotBeADataType extends IInterfaceWithMethods {
readonly otherValue: string;
}

/**
* jsii#284: do not recognize "any" as an optional argument
*/
export class DoNotRecognizeAnyAsOptional {
public method(_requiredAny: any, _optionalAny?: any, _optionalString?: string) {

}
}

/**
* jsii#282, aws-cdk#157: null should be treated as "undefined"
*/
export class NullShouldBeTreatedAsUndefined {
public changeMeToUndefined? = "hello";

constructor(_param1: string, optional?: any) {
if (optional !== undefined) {
throw new Error('Expecting second constructor argument to be "undefined"');
}
}

public giveMeUndefined(value?: any) {
if (value !== undefined) {
throw new Error('I am disappointed. I expected undefined and got: ' + JSON.stringify(value));
}
}

public giveMeUndefinedInsideAnObject(input: NullShouldBeTreatedAsUndefinedData) {
if (input.thisShouldBeUndefined !== undefined) {
throw new Error('I am disappointed. I expected undefined in "thisShouldBeUndefined" and got: ' + JSON.stringify(input));
}

const array = input.arrayWithThreeElementsAndUndefinedAsSecondArgument;
if (array.length !== 3) {
throw new Error('Expecting "arrayWithThreeElementsAndUndefinedAsSecondArgument" to have three elements: ' + JSON.stringify(input));
}

if (array[1] !== undefined) {
throw new Error('Expected arrayWithThreeElementsAndUndefinedAsSecondArgument[1] to be undefined: ' + JSON.stringify(input))
}
}

public verifyPropertyIsUndefined() {
if (this.changeMeToUndefined !== undefined) {
throw new Error('Expecting property "changeMeToUndefined" to be undefined, and it is: ' + this.changeMeToUndefined);
}
}
}

export interface NullShouldBeTreatedAsUndefinedData {
thisShouldBeUndefined?: any;
arrayWithThreeElementsAndUndefinedAsSecondArgument: any[];
}

156 changes: 141 additions & 15 deletions packages/jsii-calc/test/assembly.jsii
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,6 @@
"type": {
"collection": {
"elementtype": {
"optional": true,
"primitive": "any"
},
"kind": "array"
Expand All @@ -394,13 +393,18 @@
"type": {
"collection": {
"elementtype": {
"optional": true,
"primitive": "any"
},
"kind": "map"
}
}
},
{
"name": "anyProperty",
"type": {
"primitive": "any"
}
},
{
"name": "arrayProperty",
"type": {
Expand Down Expand Up @@ -528,7 +532,6 @@
"type": {
"collection": {
"elementtype": {
"optional": true,
"primitive": "any"
},
"kind": "array"
Expand All @@ -540,17 +543,15 @@
"type": {
"collection": {
"elementtype": {
"optional": true,
"primitive": "any"
},
"kind": "map"
}
}
},
{
"name": "anyProperty",
"name": "unknownProperty",
"type": {
"optional": true,
"primitive": "any"
}
},
Expand All @@ -560,13 +561,6 @@
"fqn": "jsii-calc.StringEnum",
"optional": true
}
},
{
"name": "unknownProperty",
"type": {
"optional": true,
"primitive": "any"
}
}
]
},
Expand Down Expand Up @@ -1301,6 +1295,45 @@
],
"name": "DoNotOverridePrivates"
},
"jsii-calc.DoNotRecognizeAnyAsOptional": {
"assembly": "jsii-calc",
"docs": {
"comment": "jsii#284: do not recognize \"any\" as an optional argument"
},
"fqn": "jsii-calc.DoNotRecognizeAnyAsOptional",
"initializer": {
"initializer": true
},
"kind": "class",
"methods": [
{
"name": "method",
"parameters": [
{
"name": "_requiredAny",
"type": {
"primitive": "any"
}
},
{
"name": "_optionalAny",
"type": {
"optional": true,
"primitive": "any"
}
},
{
"name": "_optionalString",
"type": {
"optional": true,
"primitive": "string"
}
}
]
}
],
"name": "DoNotRecognizeAnyAsOptional"
},
"jsii-calc.DoubleTrouble": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.DoubleTrouble",
Expand Down Expand Up @@ -2240,6 +2273,100 @@
}
]
},
"jsii-calc.NullShouldBeTreatedAsUndefined": {
"assembly": "jsii-calc",
"docs": {
"comment": "jsii#282, aws-cdk#157: null should be treated as \"undefined\""
},
"fqn": "jsii-calc.NullShouldBeTreatedAsUndefined",
"initializer": {
"initializer": true,
"parameters": [
{
"name": "_param1",
"type": {
"primitive": "string"
}
},
{
"name": "optional",
"type": {
"optional": true,
"primitive": "any"
}
}
]
},
"kind": "class",
"methods": [
{
"name": "giveMeUndefined",
"parameters": [
{
"name": "value",
"type": {
"optional": true,
"primitive": "any"
}
}
]
},
{
"name": "giveMeUndefinedInsideAnObject",
"parameters": [
{
"name": "input",
"type": {
"fqn": "jsii-calc.NullShouldBeTreatedAsUndefinedData"
}
}
]
},
{
"name": "verifyPropertyIsUndefined"
}
],
"name": "NullShouldBeTreatedAsUndefined",
"properties": [
{
"name": "changeMeToUndefined",
"type": {
"optional": true,
"primitive": "string"
}
}
]
},
"jsii-calc.NullShouldBeTreatedAsUndefinedData": {
"assembly": "jsii-calc",
"datatype": true,
"fqn": "jsii-calc.NullShouldBeTreatedAsUndefinedData",
"kind": "interface",
"name": "NullShouldBeTreatedAsUndefinedData",
"properties": [
{
"abstract": true,
"name": "arrayWithThreeElementsAndUndefinedAsSecondArgument",
"type": {
"collection": {
"elementtype": {
"optional": true,
"primitive": "any"
},
"kind": "array"
}
}
},
{
"abstract": true,
"name": "thisShouldBeUndefined",
"type": {
"optional": true,
"primitive": "any"
}
}
]
},
"jsii-calc.NumberGenerator": {
"assembly": "jsii-calc",
"docs": {
Expand Down Expand Up @@ -3062,7 +3189,6 @@
{
"name": "value",
"returns": {
"optional": true,
"primitive": "any"
}
}
Expand Down Expand Up @@ -3412,5 +3538,5 @@
}
},
"version": "0.7.8",
"fingerprint": "Xn7Rk17rqR3AaMx3+ssxT0GR1sCWwz0OGC+C8QuLI3A="
"fingerprint": "2BaszImarh4WChl9DFUcygfTpEfXU17fHQT2wgEptfM="
}
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,27 @@ public void TestReturnInterfaceFromOverride()
Assert.Equal(4 * n, obj.Test(arg));
}

[Fact(DisplayName = Prefix + nameof(NullShouldBeTreatedAsUndefined))]
public void NullShouldBeTreatedAsUndefined()
{
// ctor
var obj = new NullShouldBeTreatedAsUndefined("param1", null);

// method argument
obj.GiveMeUndefined(null);

// inside object
obj.GiveMeUndefinedInsideAnObject(new NullShouldBeTreatedAsUndefinedData
{
ThisShouldBeUndefined = null,
ArrayWithThreeElementsAndUndefinedAsSecondArgument = new[] { "hello", null, "world" }
});

// property
obj.ChangeMeToUndefined = null;
obj.VerifyPropertyIsUndefined();
}

class NumberReturner : DeputyBase, IIReturnsNumber
{
public NumberReturner(double number)
Expand Down
2 changes: 2 additions & 0 deletions packages/jsii-java-runtime-test/project/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
bin/

!index.js
.idea
pom.xml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import software.amazon.jsii.tests.calculator.Multiply;
import software.amazon.jsii.tests.calculator.Negate;
import software.amazon.jsii.tests.calculator.NodeStandardLibrary;
import software.amazon.jsii.tests.calculator.NullShouldBeTreatedAsUndefined;
import software.amazon.jsii.tests.calculator.NullShouldBeTreatedAsUndefinedData;
import software.amazon.jsii.tests.calculator.NumberGenerator;
import software.amazon.jsii.tests.calculator.Polymorphism;
import software.amazon.jsii.tests.calculator.Power;
Expand Down Expand Up @@ -927,6 +929,18 @@ public void classWithPrivateConstructorAndAutomaticProperties() {
assertEquals("Hello", obj.getReadOnlyString());
}

@Test
public void nullShouldBeTreatedAsUndefined() {
NullShouldBeTreatedAsUndefined obj = new NullShouldBeTreatedAsUndefined("hello", null);
eladb marked this conversation as resolved.
Show resolved Hide resolved
obj.giveMeUndefined(null);
obj.giveMeUndefinedInsideAnObject(NullShouldBeTreatedAsUndefinedData.builder()
.withThisShouldBeUndefined(null)
.withArrayWithThreeElementsAndUndefinedAsSecondArgument(Arrays.asList("hello", null, "boom"))
.build());
obj.setChangeMeToUndefined(null);
obj.verifyPropertyIsUndefined();
}

static class MulTen extends Multiply {
public MulTen(final int value) {
super(new Number(value), new Number(10));
Expand Down
2 changes: 2 additions & 0 deletions packages/jsii-java-runtime/project/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
bin/

!index.js
.idea
pom.xml
Expand Down
5 changes: 3 additions & 2 deletions packages/jsii-kernel/lib/kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -877,9 +877,10 @@ export class Kernel {
return undefined;
}

// null
// null is treated as "undefined" because most languages do not have this distinction
// see awslabs/aws-cdk#157 and awslabs/jsii#282
if (v === null) {
return null;
return undefined;
}

// pointer
Expand Down
Loading