Skip to content

Commit a4e2095

Browse files
RomainMullermergify[bot]
authored andcommitted
feat(kernel): annotate implemented interfaces on "ObjRef"s (#825)
* feat: annotate implemented interfaces on "ObjRef"s Annotating the interfaces implemented by an object instance with the outbound Object Reference, and allowing the kernel's "create" call to receive a list of interfaces allows the kernel to use more run-time type information and operate safer. * WIP * WIP progress * finished fixing java * fixup regression test expectations * fix python runtime * fixup licensing info in NuGet packages * improve NuGet package metadata * fix dotnet runtime * fixup unit tests * minor style fixes * some minor tuning * fixup expecations * stop using deprecated API * add some test coverage * fix test I forgot to update as I changed the code
1 parent f9c1335 commit a4e2095

339 files changed

Lines changed: 2804 additions & 1213 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"bump": "bash scripts/bump.sh",
77
"fetch-dotnet-snk": "bash scripts/fetch-dotnet-snk.sh",
88
"package": "bash scripts/package.sh",
9-
"test": "lerna run test --stream"
9+
"test": "lerna run test --stream",
10+
"test:update": "UPDATE_DIFF=1 lerna run test --stream"
1011
},
1112
"devDependencies": {
1213
"@types/node": "^10.17.0",

packages/jsii-calc-base-of-base/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
"types": "lib/index.d.ts",
2626
"scripts": {
2727
"build": "jsii",
28-
"test": "diff-test test/assembly.jsii .jsii"
28+
"test": "diff-test test/assembly.jsii .jsii",
29+
"test:update": "npm run build && UPDATE_DIFF=1 npm run test"
2930
},
3031
"devDependencies": {
3132
"jsii": "^0.19.0",

packages/jsii-calc-base/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
"types": "lib/index.d.ts",
2626
"scripts": {
2727
"build": "jsii",
28-
"test": "diff-test test/assembly.jsii .jsii"
28+
"test": "diff-test test/assembly.jsii .jsii",
29+
"test:update": "npm run build && UPDATE_DIFF=1 npm run test"
2930
},
3031
"dependencies": {
3132
"@scope/jsii-calc-base-of-base": "^0.19.0"

packages/jsii-calc-lib/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"types": "lib/index.d.ts",
2828
"scripts": {
2929
"build": "jsii",
30-
"test": "diff-test test/assembly.jsii .jsii"
30+
"test": "diff-test test/assembly.jsii .jsii",
31+
"test:update": "npm run build && UPDATE_DIFF=1 npm run test"
3132
},
3233
"dependencies": {
3334
"@scope/jsii-calc-base": "^0.19.0"

packages/jsii-calc/lib/compliance.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,7 +1438,7 @@ export class EraseUndefinedHashValues {
14381438
/**
14391439
* We expect "prop2" to be erased
14401440
*/
1441-
public static prop2IsUndefined(): any {
1441+
public static prop2IsUndefined(): { [key: string]: any } {
14421442
return {
14431443
prop1: 'value1',
14441444
prop2: undefined
@@ -1448,7 +1448,7 @@ export class EraseUndefinedHashValues {
14481448
/**
14491449
* We expect "prop1" to be erased
14501450
*/
1451-
public static prop1IsNull(): any {
1451+
public static prop1IsNull(): { [key: string]: any } {
14521452
return {
14531453
prop1: null,
14541454
prop2: 'value2'
@@ -1944,3 +1944,35 @@ export interface SupportsNiceJavaBuilderProps {
19441944
*/
19451945
readonly bar: number;
19461946
}
1947+
1948+
/**
1949+
* We can return an anonymous interface implementation from an override without losing the interface
1950+
* declarations.
1951+
*/
1952+
export interface IAnonymousImplementationProvider {
1953+
provideAsInterface(): IAnonymouslyImplementMe;
1954+
provideAsClass(): Implementation;
1955+
}
1956+
export class AnonymousImplementationProvider implements IAnonymousImplementationProvider {
1957+
private readonly instance = new PrivateType();
1958+
1959+
public provideAsClass(): Implementation {
1960+
return this.instance;
1961+
}
1962+
1963+
public provideAsInterface(): IAnonymouslyImplementMe {
1964+
return this.instance;
1965+
}
1966+
}
1967+
export class Implementation {
1968+
readonly value = 1337;
1969+
}
1970+
export interface IAnonymouslyImplementMe {
1971+
readonly value: number;
1972+
verb(): string;
1973+
}
1974+
class PrivateType extends Implementation implements IAnonymouslyImplementMe {
1975+
public verb() {
1976+
return 'to implement';
1977+
}
1978+
}

packages/jsii-calc/test/assembly.jsii

Lines changed: 190 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,57 @@
10271027
],
10281028
"name": "AllowedMethodNames"
10291029
},
1030+
"jsii-calc.AnonymousImplementationProvider": {
1031+
"assembly": "jsii-calc",
1032+
"docs": {
1033+
"stability": "experimental"
1034+
},
1035+
"fqn": "jsii-calc.AnonymousImplementationProvider",
1036+
"initializer": {},
1037+
"interfaces": [
1038+
"jsii-calc.IAnonymousImplementationProvider"
1039+
],
1040+
"kind": "class",
1041+
"locationInModule": {
1042+
"filename": "lib/compliance.ts",
1043+
"line": 1956
1044+
},
1045+
"methods": [
1046+
{
1047+
"docs": {
1048+
"stability": "experimental"
1049+
},
1050+
"locationInModule": {
1051+
"filename": "lib/compliance.ts",
1052+
"line": 1959
1053+
},
1054+
"name": "provideAsClass",
1055+
"overrides": "jsii-calc.IAnonymousImplementationProvider",
1056+
"returns": {
1057+
"type": {
1058+
"fqn": "jsii-calc.Implementation"
1059+
}
1060+
}
1061+
},
1062+
{
1063+
"docs": {
1064+
"stability": "experimental"
1065+
},
1066+
"locationInModule": {
1067+
"filename": "lib/compliance.ts",
1068+
"line": 1963
1069+
},
1070+
"name": "provideAsInterface",
1071+
"overrides": "jsii-calc.IAnonymousImplementationProvider",
1072+
"returns": {
1073+
"type": {
1074+
"fqn": "jsii-calc.IAnonymouslyImplementMe"
1075+
}
1076+
}
1077+
}
1078+
],
1079+
"name": "AnonymousImplementationProvider"
1080+
},
10301081
"jsii-calc.AsyncVirtualMethods": {
10311082
"assembly": "jsii-calc",
10321083
"docs": {
@@ -3318,7 +3369,12 @@
33183369
"name": "prop1IsNull",
33193370
"returns": {
33203371
"type": {
3321-
"primitive": "any"
3372+
"collection": {
3373+
"elementtype": {
3374+
"primitive": "any"
3375+
},
3376+
"kind": "map"
3377+
}
33223378
}
33233379
},
33243380
"static": true
@@ -3335,7 +3391,12 @@
33353391
"name": "prop2IsUndefined",
33363392
"returns": {
33373393
"type": {
3338-
"primitive": "any"
3394+
"collection": {
3395+
"elementtype": {
3396+
"primitive": "any"
3397+
},
3398+
"kind": "map"
3399+
}
33393400
}
33403401
},
33413402
"static": true
@@ -3790,6 +3851,102 @@
37903851
],
37913852
"name": "GreetingAugmenter"
37923853
},
3854+
"jsii-calc.IAnonymousImplementationProvider": {
3855+
"assembly": "jsii-calc",
3856+
"docs": {
3857+
"stability": "experimental",
3858+
"summary": "We can return an anonymous interface implementation from an override without losing the interface declarations."
3859+
},
3860+
"fqn": "jsii-calc.IAnonymousImplementationProvider",
3861+
"kind": "interface",
3862+
"locationInModule": {
3863+
"filename": "lib/compliance.ts",
3864+
"line": 1952
3865+
},
3866+
"methods": [
3867+
{
3868+
"abstract": true,
3869+
"docs": {
3870+
"stability": "experimental"
3871+
},
3872+
"locationInModule": {
3873+
"filename": "lib/compliance.ts",
3874+
"line": 1954
3875+
},
3876+
"name": "provideAsClass",
3877+
"returns": {
3878+
"type": {
3879+
"fqn": "jsii-calc.Implementation"
3880+
}
3881+
}
3882+
},
3883+
{
3884+
"abstract": true,
3885+
"docs": {
3886+
"stability": "experimental"
3887+
},
3888+
"locationInModule": {
3889+
"filename": "lib/compliance.ts",
3890+
"line": 1953
3891+
},
3892+
"name": "provideAsInterface",
3893+
"returns": {
3894+
"type": {
3895+
"fqn": "jsii-calc.IAnonymouslyImplementMe"
3896+
}
3897+
}
3898+
}
3899+
],
3900+
"name": "IAnonymousImplementationProvider"
3901+
},
3902+
"jsii-calc.IAnonymouslyImplementMe": {
3903+
"assembly": "jsii-calc",
3904+
"docs": {
3905+
"stability": "experimental"
3906+
},
3907+
"fqn": "jsii-calc.IAnonymouslyImplementMe",
3908+
"kind": "interface",
3909+
"locationInModule": {
3910+
"filename": "lib/compliance.ts",
3911+
"line": 1970
3912+
},
3913+
"methods": [
3914+
{
3915+
"abstract": true,
3916+
"docs": {
3917+
"stability": "experimental"
3918+
},
3919+
"locationInModule": {
3920+
"filename": "lib/compliance.ts",
3921+
"line": 1972
3922+
},
3923+
"name": "verb",
3924+
"returns": {
3925+
"type": {
3926+
"primitive": "string"
3927+
}
3928+
}
3929+
}
3930+
],
3931+
"name": "IAnonymouslyImplementMe",
3932+
"properties": [
3933+
{
3934+
"abstract": true,
3935+
"docs": {
3936+
"stability": "experimental"
3937+
},
3938+
"immutable": true,
3939+
"locationInModule": {
3940+
"filename": "lib/compliance.ts",
3941+
"line": 1971
3942+
},
3943+
"name": "value",
3944+
"type": {
3945+
"primitive": "number"
3946+
}
3947+
}
3948+
]
3949+
},
37933950
"jsii-calc.IAnotherPublicInterface": {
37943951
"assembly": "jsii-calc",
37953952
"docs": {
@@ -4740,6 +4897,36 @@
47404897
}
47414898
]
47424899
},
4900+
"jsii-calc.Implementation": {
4901+
"assembly": "jsii-calc",
4902+
"docs": {
4903+
"stability": "experimental"
4904+
},
4905+
"fqn": "jsii-calc.Implementation",
4906+
"initializer": {},
4907+
"kind": "class",
4908+
"locationInModule": {
4909+
"filename": "lib/compliance.ts",
4910+
"line": 1967
4911+
},
4912+
"name": "Implementation",
4913+
"properties": [
4914+
{
4915+
"docs": {
4916+
"stability": "experimental"
4917+
},
4918+
"immutable": true,
4919+
"locationInModule": {
4920+
"filename": "lib/compliance.ts",
4921+
"line": 1968
4922+
},
4923+
"name": "value",
4924+
"type": {
4925+
"primitive": "number"
4926+
}
4927+
}
4928+
]
4929+
},
47434930
"jsii-calc.ImplementsInterfaceWithInternal": {
47444931
"assembly": "jsii-calc",
47454932
"docs": {
@@ -9932,5 +10119,5 @@
993210119
}
993310120
},
993410121
"version": "0.19.0",
9935-
"fingerprint": "98k0qPH9S801EvX681aTDIxgufKA90iJ4SlfZKrm90c="
10122+
"fingerprint": "MZT68aeJ7MEeDJORDPKkIyqOqOLC+Yb3LcDU7XrxgCQ="
993610123
}

packages/jsii-dotnet-jsonmodel/src/Amazon.JSII.JsonModel/Api/ObjectReference.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace Amazon.JSII.JsonModel.Api
44
{
55
[JsonDictionary]
6-
public class ObjectReference : JsonDictionaryBase<string, string>
6+
public class ObjectReference : JsonDictionaryBase<string, object>
77
{
88
}
99
}

packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/Amazon.JSII.Runtime.IntegrationTests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>netcoreapp3.0</TargetFramework>

packages/jsii-dotnet-runtime-test/test/Amazon.JSII.Runtime.IntegrationTests/ComplianceTests.cs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111

1212
[assembly: CollectionBehavior(DisableTestParallelization = true)]
1313

14+
#pragma warning disable CS0612
15+
1416
namespace Amazon.JSII.Runtime.IntegrationTests
1517
{
1618
/// <summary>
1719
/// Ported from packages/jsii-java-runtime/src/test/java/org/jsii/testing/ComplianceTest.java.
1820
/// </summary>
19-
public class ComplianceTests : IClassFixture<ServiceContainerFixture>
21+
public sealed class ComplianceTests : IClassFixture<ServiceContainerFixture>
2022
{
2123
class RuntimeException : Exception
2224
{
@@ -127,12 +129,18 @@ public void DynamicTypes()
127129
Assert.Equal(UnixEpoch.AddSeconds(1234), types.AnyProperty);
128130

129131
// json (notice that when deserialized, it is deserialized as a map).
130-
types.AnyProperty = new JObject(new JProperty("Goo",
131-
new JArray(
132-
"Hello",
133-
new JObject(new JProperty("World", 123))
134-
)
135-
));
132+
types.AnyProperty = new Dictionary<string, object>
133+
{
134+
{ "Goo", new object[]
135+
{
136+
"Hello",
137+
new Dictionary<string, object>
138+
{
139+
{ "World", 123 }
140+
}
141+
}
142+
}
143+
};
136144
var @object = (IDictionary<string, object>) types.AnyProperty;
137145
var array = (object[]) @object["Goo"];
138146
var innerObject = (IDictionary<string, object>) array[1];
@@ -999,6 +1007,15 @@ public void MethodCanReturnArraysOfInterfaces()
9991007
Assert.Equal(4, interfaces.Length);
10001008
}
10011009

1010+
[Fact(DisplayName = Prefix + nameof(CanLeverageIndirectInterfacePolymorphism))]
1011+
public void CanLeverageIndirectInterfacePolymorphism()
1012+
{
1013+
var provider = new AnonymousImplementationProvider();
1014+
Assert.Equal(1337d, provider.ProvideAsClass().Value);
1015+
Assert.Equal(1337d, provider.ProvideAsInterface().Value);
1016+
Assert.Equal("to implement", provider.ProvideAsInterface().Verb());
1017+
}
1018+
10021019
class DataRendererSubclass : DataRenderer
10031020
{
10041021
[JsiiMethod("renderMap", returnsJson: "{\"type\":{\"primitive\":\"string\"}}", parametersJson: "[{\"name\":\"map\",\"type\":{\"collection\":{\"kind\":\"map\",\"elementtype\":{\"primitive\":\"any\"}}}}]", isOverride: true)]

0 commit comments

Comments
 (0)