Skip to content

Commit

Permalink
fix(jsii): Correctly handle singleton enums (#535)
Browse files Browse the repository at this point in the history
When an enum has only one option, TypeScript handles it in a special way
and tries very hard to hide the enum declaration in favor of the sole
member. This caused incorrect type names and kinds to be emitted in the
JSII assembly, resulting in incorrect behavior.

This uses a non-public part of the TSC API (possibly an omission from
the hand-written type model), so it includes an additional guard check
to fail explicitly in case the API's behavior happens to change in a
breaking way.

Fixes #231
  • Loading branch information
RomainMuller authored Jun 14, 2019
1 parent e804cab commit 01aed03
Show file tree
Hide file tree
Showing 20 changed files with 748 additions and 9 deletions.
34 changes: 34 additions & 0 deletions packages/jsii-calc/lib/compliance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1692,3 +1692,37 @@ export class WithPrivatePropertyInConstructor {
return this.privateField === 'Success!';
}
}

/**
* Verifies that singleton enums are handled correctly
*
* https://github.com/awslabs/jsii/issues/231
*/
export class SingletonString {
private constructor() { }

public isSingletonString(value: string): boolean {
return value === SingletonStringEnum.SingletonString;
}
}
/** A singleton string */
export enum SingletonStringEnum {
/** 1337 */
SingletonString = '3L1T3!'
}
/**
* Verifies that singleton enums are handled correctly
*
* https://github.com/awslabs/jsii/issues/231
*/
export class SingletonInt {
private constructor() { }
public isSingletonInt(value: number): boolean {
return value === SingletonIntEnum.SingletonInt;
}
}
/** A singleton integer. */
export enum SingletonIntEnum {
/** Elite! */
SingletonInt = 1337
}
128 changes: 127 additions & 1 deletion packages/jsii-calc/test/assembly.jsii
Original file line number Diff line number Diff line change
Expand Up @@ -7121,6 +7121,132 @@
],
"name": "SingleInstanceTwoTypes"
},
"jsii-calc.SingletonInt": {
"assembly": "jsii-calc",
"docs": {
"remarks": "https://github.com/awslabs/jsii/issues/231",
"stability": "experimental",
"summary": "Verifies that singleton enums are handled correctly."
},
"fqn": "jsii-calc.SingletonInt",
"kind": "class",
"locationInModule": {
"filename": "lib/compliance.ts",
"line": 1718
},
"methods": [
{
"docs": {
"stability": "experimental"
},
"locationInModule": {
"filename": "lib/compliance.ts",
"line": 1720
},
"name": "isSingletonInt",
"parameters": [
{
"name": "value",
"type": {
"primitive": "number"
}
}
],
"returns": {
"type": {
"primitive": "boolean"
}
}
}
],
"name": "SingletonInt"
},
"jsii-calc.SingletonIntEnum": {
"assembly": "jsii-calc",
"docs": {
"stability": "experimental",
"summary": "A singleton integer."
},
"fqn": "jsii-calc.SingletonIntEnum",
"kind": "enum",
"locationInModule": {
"filename": "lib/compliance.ts",
"line": 1725
},
"members": [
{
"docs": {
"stability": "experimental",
"summary": "Elite!"
},
"name": "SingletonInt"
}
],
"name": "SingletonIntEnum"
},
"jsii-calc.SingletonString": {
"assembly": "jsii-calc",
"docs": {
"remarks": "https://github.com/awslabs/jsii/issues/231",
"stability": "experimental",
"summary": "Verifies that singleton enums are handled correctly."
},
"fqn": "jsii-calc.SingletonString",
"kind": "class",
"locationInModule": {
"filename": "lib/compliance.ts",
"line": 1701
},
"methods": [
{
"docs": {
"stability": "experimental"
},
"locationInModule": {
"filename": "lib/compliance.ts",
"line": 1704
},
"name": "isSingletonString",
"parameters": [
{
"name": "value",
"type": {
"primitive": "string"
}
}
],
"returns": {
"type": {
"primitive": "boolean"
}
}
}
],
"name": "SingletonString"
},
"jsii-calc.SingletonStringEnum": {
"assembly": "jsii-calc",
"docs": {
"stability": "experimental",
"summary": "A singleton string."
},
"fqn": "jsii-calc.SingletonStringEnum",
"kind": "enum",
"locationInModule": {
"filename": "lib/compliance.ts",
"line": 1709
},
"members": [
{
"docs": {
"stability": "experimental",
"summary": "1337."
},
"name": "SingletonString"
}
],
"name": "SingletonStringEnum"
},
"jsii-calc.StableClass": {
"assembly": "jsii-calc",
"docs": {
Expand Down Expand Up @@ -8648,5 +8774,5 @@
}
},
"version": "0.11.2",
"fingerprint": "eQpFH3EHC2GlCSnThymTxnuO9HyZBFvsvddZqu1Fy+8="
"fingerprint": "5TwMNffhxUueZQEAGZG6+JIfS6jcTwCJWc9vixH5aLc="
}
Original file line number Diff line number Diff line change
Expand Up @@ -7121,6 +7121,132 @@
],
"name": "SingleInstanceTwoTypes"
},
"jsii-calc.SingletonInt": {
"assembly": "jsii-calc",
"docs": {
"remarks": "https://github.com/awslabs/jsii/issues/231",
"stability": "experimental",
"summary": "Verifies that singleton enums are handled correctly."
},
"fqn": "jsii-calc.SingletonInt",
"kind": "class",
"locationInModule": {
"filename": "lib/compliance.ts",
"line": 1718
},
"methods": [
{
"docs": {
"stability": "experimental"
},
"locationInModule": {
"filename": "lib/compliance.ts",
"line": 1720
},
"name": "isSingletonInt",
"parameters": [
{
"name": "value",
"type": {
"primitive": "number"
}
}
],
"returns": {
"type": {
"primitive": "boolean"
}
}
}
],
"name": "SingletonInt"
},
"jsii-calc.SingletonIntEnum": {
"assembly": "jsii-calc",
"docs": {
"stability": "experimental",
"summary": "A singleton integer."
},
"fqn": "jsii-calc.SingletonIntEnum",
"kind": "enum",
"locationInModule": {
"filename": "lib/compliance.ts",
"line": 1725
},
"members": [
{
"docs": {
"stability": "experimental",
"summary": "Elite!"
},
"name": "SingletonInt"
}
],
"name": "SingletonIntEnum"
},
"jsii-calc.SingletonString": {
"assembly": "jsii-calc",
"docs": {
"remarks": "https://github.com/awslabs/jsii/issues/231",
"stability": "experimental",
"summary": "Verifies that singleton enums are handled correctly."
},
"fqn": "jsii-calc.SingletonString",
"kind": "class",
"locationInModule": {
"filename": "lib/compliance.ts",
"line": 1701
},
"methods": [
{
"docs": {
"stability": "experimental"
},
"locationInModule": {
"filename": "lib/compliance.ts",
"line": 1704
},
"name": "isSingletonString",
"parameters": [
{
"name": "value",
"type": {
"primitive": "string"
}
}
],
"returns": {
"type": {
"primitive": "boolean"
}
}
}
],
"name": "SingletonString"
},
"jsii-calc.SingletonStringEnum": {
"assembly": "jsii-calc",
"docs": {
"stability": "experimental",
"summary": "A singleton string."
},
"fqn": "jsii-calc.SingletonStringEnum",
"kind": "enum",
"locationInModule": {
"filename": "lib/compliance.ts",
"line": 1709
},
"members": [
{
"docs": {
"stability": "experimental",
"summary": "1337."
},
"name": "SingletonString"
}
],
"name": "SingletonStringEnum"
},
"jsii-calc.StableClass": {
"assembly": "jsii-calc",
"docs": {
Expand Down Expand Up @@ -8648,5 +8774,5 @@
}
},
"version": "0.11.2",
"fingerprint": "eQpFH3EHC2GlCSnThymTxnuO9HyZBFvsvddZqu1Fy+8="
"fingerprint": "5TwMNffhxUueZQEAGZG6+JIfS6jcTwCJWc9vixH5aLc="
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Amazon.JSII.Runtime.Deputy;

namespace Amazon.JSII.Tests.CalculatorNamespace
{
/// <summary>Verifies that singleton enums are handled correctly.</summary>
/// <remarks>
/// https://github.com/awslabs/jsii/issues/231
/// stability: Experimental
/// </remarks>
[JsiiClass(nativeType: typeof(SingletonInt), fullyQualifiedName: "jsii-calc.SingletonInt")]
public class SingletonInt : DeputyBase
{
protected SingletonInt(ByRefValue reference): base(reference)
{
}

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

/// <remarks>stability: Experimental</remarks>
[JsiiMethod(name: "isSingletonInt", returnsJson: "{\"type\":{\"primitive\":\"boolean\"}}", parametersJson: "[{\"name\":\"value\",\"type\":{\"primitive\":\"number\"}}]")]
public virtual bool IsSingletonInt(double value)
{
return InvokeInstanceMethod<bool>(new object[]{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
{
/// <summary>A singleton integer.</summary>
/// <remarks>stability: Experimental</remarks>
[JsiiEnum(nativeType: typeof(SingletonIntEnum), fullyQualifiedName: "jsii-calc.SingletonIntEnum")]
public enum SingletonIntEnum
{
/// <summary>Elite!</summary>
/// <remarks>stability: Experimental</remarks>
[JsiiEnumMember(name: "SingletonInt")]
SingletonInt
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Amazon.JSII.Runtime.Deputy;

namespace Amazon.JSII.Tests.CalculatorNamespace
{
/// <summary>Verifies that singleton enums are handled correctly.</summary>
/// <remarks>
/// https://github.com/awslabs/jsii/issues/231
/// stability: Experimental
/// </remarks>
[JsiiClass(nativeType: typeof(SingletonString), fullyQualifiedName: "jsii-calc.SingletonString")]
public class SingletonString : DeputyBase
{
protected SingletonString(ByRefValue reference): base(reference)
{
}

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

/// <remarks>stability: Experimental</remarks>
[JsiiMethod(name: "isSingletonString", returnsJson: "{\"type\":{\"primitive\":\"boolean\"}}", parametersJson: "[{\"name\":\"value\",\"type\":{\"primitive\":\"string\"}}]")]
public virtual bool IsSingletonString(string value)
{
return InvokeInstanceMethod<bool>(new object[]{value});
}
}
}
Loading

0 comments on commit 01aed03

Please sign in to comment.