Skip to content

Commit 8ff9137

Browse files
authored
fix(jsii): Prohibit illegal uses of structs (aka data types) (#418)
Expected failure cases: - [X] An interface extending another one which is _not_ a struct, _cannot_ be a struct. - [x] A class may not implement a struct interface - [x] A regular interface may not implement a struct Fixes #287
1 parent a8ee954 commit 8ff9137

27 files changed

+275
-254
lines changed

packages/jsii-calc/lib/compliance.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,15 +1056,15 @@ export interface IInterfaceWithOptionalMethodArguments {
10561056
* Abstract return type
10571057
*/
10581058

1059-
export interface InterfaceImplementedByAbstractClass {
1059+
export interface IInterfaceImplementedByAbstractClass {
10601060
readonly propFromInterface: string;
10611061
}
10621062

10631063
export abstract class AbstractClassBase {
10641064
public abstract readonly abstractProperty: string;
10651065
}
10661066

1067-
export abstract class AbstractClass extends AbstractClassBase implements InterfaceImplementedByAbstractClass {
1067+
export abstract class AbstractClass extends AbstractClassBase implements IInterfaceImplementedByAbstractClass {
10681068
public nonAbstractMethod() {
10691069
return 42;
10701070
}
@@ -1091,7 +1091,7 @@ export class AbstractClassReturner {
10911091
return new ConcreteClass();
10921092
}
10931093

1094-
public giveMeInterface(): InterfaceImplementedByAbstractClass {
1094+
public giveMeInterface(): IInterfaceImplementedByAbstractClass {
10951095
return new ConcreteClass();
10961096
}
10971097

packages/jsii-calc/test/assembly.jsii

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@
230230
},
231231
"interfaces": [
232232
{
233-
"fqn": "jsii-calc.InterfaceImplementedByAbstractClass"
233+
"fqn": "jsii-calc.IInterfaceImplementedByAbstractClass"
234234
}
235235
],
236236
"kind": "class",
@@ -263,7 +263,7 @@
263263
"immutable": true,
264264
"name": "propFromInterface",
265265
"overrides": {
266-
"fqn": "jsii-calc.InterfaceImplementedByAbstractClass"
266+
"fqn": "jsii-calc.IInterfaceImplementedByAbstractClass"
267267
},
268268
"type": {
269269
"primitive": "string"
@@ -308,7 +308,7 @@
308308
{
309309
"name": "giveMeInterface",
310310
"returns": {
311-
"fqn": "jsii-calc.InterfaceImplementedByAbstractClass"
311+
"fqn": "jsii-calc.IInterfaceImplementedByAbstractClass"
312312
}
313313
}
314314
],
@@ -2032,6 +2032,25 @@
20322032
"kind": "interface",
20332033
"name": "IFriendlyRandomGenerator"
20342034
},
2035+
"jsii-calc.IInterfaceImplementedByAbstractClass": {
2036+
"assembly": "jsii-calc",
2037+
"docs": {
2038+
"comment": "awslabs/jsii#220\nAbstract return type"
2039+
},
2040+
"fqn": "jsii-calc.IInterfaceImplementedByAbstractClass",
2041+
"kind": "interface",
2042+
"name": "IInterfaceImplementedByAbstractClass",
2043+
"properties": [
2044+
{
2045+
"abstract": true,
2046+
"immutable": true,
2047+
"name": "propFromInterface",
2048+
"type": {
2049+
"primitive": "string"
2050+
}
2051+
}
2052+
]
2053+
},
20352054
"jsii-calc.IInterfaceThatShouldNotBeADataType": {
20362055
"assembly": "jsii-calc",
20372056
"docs": {
@@ -2409,26 +2428,6 @@
24092428
],
24102429
"name": "InbetweenClass"
24112430
},
2412-
"jsii-calc.InterfaceImplementedByAbstractClass": {
2413-
"assembly": "jsii-calc",
2414-
"datatype": true,
2415-
"docs": {
2416-
"comment": "awslabs/jsii#220\nAbstract return type"
2417-
},
2418-
"fqn": "jsii-calc.InterfaceImplementedByAbstractClass",
2419-
"kind": "interface",
2420-
"name": "InterfaceImplementedByAbstractClass",
2421-
"properties": [
2422-
{
2423-
"abstract": true,
2424-
"immutable": true,
2425-
"name": "propFromInterface",
2426-
"type": {
2427-
"primitive": "string"
2428-
}
2429-
}
2430-
]
2431-
},
24322431
"jsii-calc.InterfaceInNamespaceIncludesClasses.Foo": {
24332432
"assembly": "jsii-calc",
24342433
"fqn": "jsii-calc.InterfaceInNamespaceIncludesClasses.Foo",
@@ -4633,5 +4632,5 @@
46334632
}
46344633
},
46354634
"version": "0.8.2",
4636-
"fingerprint": "QQVEfUkkaxXMbXiD6wDVqdim8HdLW5L8CElwn+WdzUA="
4635+
"fingerprint": "CSV1TF9zK+8oZfXWIov5XOKrTmFIpov07DaTV3k1IfA="
46374636
}

packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/JsiiVersionTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import org.junit.Test;
44

5+
import static org.junit.Assert.assertNotEquals;
6+
import static org.junit.Assert.assertNotNull;
57
import static software.amazon.jsii.JsiiVersion.JSII_RUNTIME_VERSION;
68

79
public final class JsiiVersionTest {
@@ -27,4 +29,10 @@ public void incompatibleVersions_2() {
2729
public void incompatibleVersions_3() {
2830
JsiiRuntime.assertVersionCompatible("0.7.0+abcd", "1.2.0+abcd");
2931
}
32+
33+
@Test
34+
public void versionIsDefined() {
35+
assertNotNull(JSII_RUNTIME_VERSION);
36+
assertNotEquals("", JSII_RUNTIME_VERSION);
37+
}
3038
}

packages/jsii-java-runtime-test/project/src/test/java/software/amazon/jsii/testing/ComplianceTest.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import software.amazon.jsii.tests.calculator.IPublicInterface;
2828
import software.amazon.jsii.tests.calculator.IRandomNumberGenerator;
2929
import software.amazon.jsii.tests.calculator.InbetweenClass;
30-
import software.amazon.jsii.tests.calculator.InterfaceImplementedByAbstractClass;
30+
import software.amazon.jsii.tests.calculator.IInterfaceImplementedByAbstractClass;
3131
import software.amazon.jsii.tests.calculator.JSObjectLiteralForInterface;
3232
import software.amazon.jsii.tests.calculator.JSObjectLiteralToNative;
3333
import software.amazon.jsii.tests.calculator.JSObjectLiteralToNativeClass;
@@ -868,7 +868,7 @@ public void returnAbstract() {
868868
assertEquals("propFromInterfaceValue", obj2.getPropFromInterface());
869869
assertEquals(42, obj2.nonAbstractMethod());
870870

871-
InterfaceImplementedByAbstractClass iface = obj.giveMeInterface();
871+
IInterfaceImplementedByAbstractClass iface = obj.giveMeInterface();
872872
assertEquals("propFromInterfaceValue", iface.getPropFromInterface());
873873

874874
assertEquals("hello-abstract-property", obj.getReturnAbstractFromProperty().getAbstractProperty());
@@ -877,6 +877,7 @@ public void returnAbstract() {
877877
@Test
878878
public void doNotOverridePrivates_method_public() {
879879
DoNotOverridePrivates obj = new DoNotOverridePrivates() {
880+
@SuppressWarnings("unused")
880881
public String privateMethod() {
881882
return "privateMethod-Override";
882883
}
@@ -888,6 +889,7 @@ public String privateMethod() {
888889
@Test
889890
public void doNotOverridePrivates_method_private() {
890891
DoNotOverridePrivates obj = new DoNotOverridePrivates() {
892+
@SuppressWarnings("unused")
891893
private String privateMethod() {
892894
return "privateMethod-Override";
893895
}
@@ -899,6 +901,7 @@ private String privateMethod() {
899901
@Test
900902
public void doNotOverridePrivates_property_by_name_private() {
901903
DoNotOverridePrivates obj = new DoNotOverridePrivates() {
904+
@SuppressWarnings("unused")
902905
private String privateProperty() {
903906
return "privateProperty-Override";
904907
}
@@ -910,6 +913,7 @@ private String privateProperty() {
910913
@Test
911914
public void doNotOverridePrivates_property_by_name_public() {
912915
DoNotOverridePrivates obj = new DoNotOverridePrivates() {
916+
@SuppressWarnings("unused")
913917
public String privateProperty() {
914918
return "privateProperty-Override";
915919
}
@@ -921,9 +925,11 @@ public String privateProperty() {
921925
@Test
922926
public void doNotOverridePrivates_property_getter_public() {
923927
DoNotOverridePrivates obj = new DoNotOverridePrivates() {
928+
@SuppressWarnings("unused")
924929
public String getPrivateProperty() {
925930
return "privateProperty-Override";
926931
}
932+
@SuppressWarnings("unused")
927933
public void setPrivateProperty(String value) {
928934
throw new RuntimeException("Boom");
929935
}
@@ -939,9 +945,11 @@ public void setPrivateProperty(String value) {
939945
@Test
940946
public void doNotOverridePrivates_property_getter_private() {
941947
DoNotOverridePrivates obj = new DoNotOverridePrivates() {
948+
@SuppressWarnings("unused")
942949
private String getPrivateProperty() {
943950
return "privateProperty-Override";
944951
}
952+
@SuppressWarnings("unused")
945953
public void setPrivateProperty(String value) {
946954
throw new RuntimeException("Boom");
947955
}

packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@
230230
},
231231
"interfaces": [
232232
{
233-
"fqn": "jsii-calc.InterfaceImplementedByAbstractClass"
233+
"fqn": "jsii-calc.IInterfaceImplementedByAbstractClass"
234234
}
235235
],
236236
"kind": "class",
@@ -263,7 +263,7 @@
263263
"immutable": true,
264264
"name": "propFromInterface",
265265
"overrides": {
266-
"fqn": "jsii-calc.InterfaceImplementedByAbstractClass"
266+
"fqn": "jsii-calc.IInterfaceImplementedByAbstractClass"
267267
},
268268
"type": {
269269
"primitive": "string"
@@ -308,7 +308,7 @@
308308
{
309309
"name": "giveMeInterface",
310310
"returns": {
311-
"fqn": "jsii-calc.InterfaceImplementedByAbstractClass"
311+
"fqn": "jsii-calc.IInterfaceImplementedByAbstractClass"
312312
}
313313
}
314314
],
@@ -2032,6 +2032,25 @@
20322032
"kind": "interface",
20332033
"name": "IFriendlyRandomGenerator"
20342034
},
2035+
"jsii-calc.IInterfaceImplementedByAbstractClass": {
2036+
"assembly": "jsii-calc",
2037+
"docs": {
2038+
"comment": "awslabs/jsii#220\nAbstract return type"
2039+
},
2040+
"fqn": "jsii-calc.IInterfaceImplementedByAbstractClass",
2041+
"kind": "interface",
2042+
"name": "IInterfaceImplementedByAbstractClass",
2043+
"properties": [
2044+
{
2045+
"abstract": true,
2046+
"immutable": true,
2047+
"name": "propFromInterface",
2048+
"type": {
2049+
"primitive": "string"
2050+
}
2051+
}
2052+
]
2053+
},
20352054
"jsii-calc.IInterfaceThatShouldNotBeADataType": {
20362055
"assembly": "jsii-calc",
20372056
"docs": {
@@ -2409,26 +2428,6 @@
24092428
],
24102429
"name": "InbetweenClass"
24112430
},
2412-
"jsii-calc.InterfaceImplementedByAbstractClass": {
2413-
"assembly": "jsii-calc",
2414-
"datatype": true,
2415-
"docs": {
2416-
"comment": "awslabs/jsii#220\nAbstract return type"
2417-
},
2418-
"fqn": "jsii-calc.InterfaceImplementedByAbstractClass",
2419-
"kind": "interface",
2420-
"name": "InterfaceImplementedByAbstractClass",
2421-
"properties": [
2422-
{
2423-
"abstract": true,
2424-
"immutable": true,
2425-
"name": "propFromInterface",
2426-
"type": {
2427-
"primitive": "string"
2428-
}
2429-
}
2430-
]
2431-
},
24322431
"jsii-calc.InterfaceInNamespaceIncludesClasses.Foo": {
24332432
"assembly": "jsii-calc",
24342433
"fqn": "jsii-calc.InterfaceInNamespaceIncludesClasses.Foo",
@@ -4633,5 +4632,5 @@
46334632
}
46344633
},
46354634
"version": "0.8.2",
4636-
"fingerprint": "QQVEfUkkaxXMbXiD6wDVqdim8HdLW5L8CElwn+WdzUA="
4635+
"fingerprint": "CSV1TF9zK+8oZfXWIov5XOKrTmFIpov07DaTV3k1IfA="
46374636
}

packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AbstractClass.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace Amazon.JSII.Tests.CalculatorNamespace
44
{
55
[JsiiClass(typeof(AbstractClass), "jsii-calc.AbstractClass", "[]")]
6-
public abstract class AbstractClass : AbstractClassBase, IInterfaceImplementedByAbstractClass
6+
public abstract class AbstractClass : AbstractClassBase, IIInterfaceImplementedByAbstractClass
77
{
88
protected AbstractClass(): base(new DeputyProps(new object[]{}))
99
{

packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AbstractClassReturner.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ public virtual AbstractClass GiveMeAbstract()
2929
return InvokeInstanceMethod<AbstractClass>(new object[]{});
3030
}
3131

32-
[JsiiMethod("giveMeInterface", "{\"fqn\":\"jsii-calc.InterfaceImplementedByAbstractClass\"}", "[]")]
33-
public virtual IInterfaceImplementedByAbstractClass GiveMeInterface()
32+
[JsiiMethod("giveMeInterface", "{\"fqn\":\"jsii-calc.IInterfaceImplementedByAbstractClass\"}", "[]")]
33+
public virtual IIInterfaceImplementedByAbstractClass GiveMeInterface()
3434
{
35-
return InvokeInstanceMethod<IInterfaceImplementedByAbstractClass>(new object[]{});
35+
return InvokeInstanceMethod<IIInterfaceImplementedByAbstractClass>(new object[]{});
3636
}
3737
}
3838
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ namespace Amazon.JSII.Tests.CalculatorNamespace
66
/// awslabs/jsii#220
77
/// Abstract return type
88
/// </summary>
9-
[JsiiInterface(typeof(IInterfaceImplementedByAbstractClass), "jsii-calc.InterfaceImplementedByAbstractClass")]
10-
public interface IInterfaceImplementedByAbstractClass
9+
[JsiiInterface(typeof(IIInterfaceImplementedByAbstractClass), "jsii-calc.IInterfaceImplementedByAbstractClass")]
10+
public interface IIInterfaceImplementedByAbstractClass
1111
{
1212
[JsiiProperty("propFromInterface", "{\"primitive\":\"string\"}")]
1313
string PropFromInterface
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ namespace Amazon.JSII.Tests.CalculatorNamespace
66
/// awslabs/jsii#220
77
/// Abstract return type
88
/// </summary>
9-
[JsiiTypeProxy(typeof(IInterfaceImplementedByAbstractClass), "jsii-calc.InterfaceImplementedByAbstractClass")]
10-
internal sealed class InterfaceImplementedByAbstractClassProxy : DeputyBase, IInterfaceImplementedByAbstractClass
9+
[JsiiTypeProxy(typeof(IIInterfaceImplementedByAbstractClass), "jsii-calc.IInterfaceImplementedByAbstractClass")]
10+
internal sealed class IInterfaceImplementedByAbstractClassProxy : DeputyBase, IIInterfaceImplementedByAbstractClass
1111
{
12-
private InterfaceImplementedByAbstractClassProxy(ByRefValue reference): base(reference)
12+
private IInterfaceImplementedByAbstractClassProxy(ByRefValue reference): base(reference)
1313
{
1414
}
1515

packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceImplementedByAbstractClass.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.

packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ protected Class<?> resolveClass(final String fqn) throws ClassNotFoundException
5555
case "jsii-calc.IAnotherPublicInterface": return software.amazon.jsii.tests.calculator.IAnotherPublicInterface.class;
5656
case "jsii-calc.IFriendlier": return software.amazon.jsii.tests.calculator.IFriendlier.class;
5757
case "jsii-calc.IFriendlyRandomGenerator": return software.amazon.jsii.tests.calculator.IFriendlyRandomGenerator.class;
58+
case "jsii-calc.IInterfaceImplementedByAbstractClass": return software.amazon.jsii.tests.calculator.IInterfaceImplementedByAbstractClass.class;
5859
case "jsii-calc.IInterfaceThatShouldNotBeADataType": return software.amazon.jsii.tests.calculator.IInterfaceThatShouldNotBeADataType.class;
5960
case "jsii-calc.IInterfaceWithInternal": return software.amazon.jsii.tests.calculator.IInterfaceWithInternal.class;
6061
case "jsii-calc.IInterfaceWithMethods": return software.amazon.jsii.tests.calculator.IInterfaceWithMethods.class;
@@ -74,7 +75,6 @@ protected Class<?> resolveClass(final String fqn) throws ClassNotFoundException
7475
case "jsii-calc.ImplementsPrivateInterface": return software.amazon.jsii.tests.calculator.ImplementsPrivateInterface.class;
7576
case "jsii-calc.ImplictBaseOfBase": return software.amazon.jsii.tests.calculator.ImplictBaseOfBase.class;
7677
case "jsii-calc.InbetweenClass": return software.amazon.jsii.tests.calculator.InbetweenClass.class;
77-
case "jsii-calc.InterfaceImplementedByAbstractClass": return software.amazon.jsii.tests.calculator.InterfaceImplementedByAbstractClass.class;
7878
case "jsii-calc.InterfaceInNamespaceIncludesClasses.Foo": return software.amazon.jsii.tests.calculator.InterfaceInNamespaceIncludesClasses.Foo.class;
7979
case "jsii-calc.InterfaceInNamespaceIncludesClasses.Hello": return software.amazon.jsii.tests.calculator.InterfaceInNamespaceIncludesClasses.Hello.class;
8080
case "jsii-calc.InterfaceInNamespaceOnlyInterface.Hello": return software.amazon.jsii.tests.calculator.InterfaceInNamespaceOnlyInterface.Hello.class;

packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/AbstractClass.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
@javax.annotation.Generated(value = "jsii-pacmak")
44
@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.AbstractClass")
5-
public abstract class AbstractClass extends software.amazon.jsii.tests.calculator.AbstractClassBase implements software.amazon.jsii.tests.calculator.InterfaceImplementedByAbstractClass {
5+
public abstract class AbstractClass extends software.amazon.jsii.tests.calculator.AbstractClassBase implements software.amazon.jsii.tests.calculator.IInterfaceImplementedByAbstractClass {
66
protected AbstractClass(final software.amazon.jsii.JsiiObject.InitializationMode mode) {
77
super(mode);
88
}

0 commit comments

Comments
 (0)