diff --git a/.all-contributorsrc b/.all-contributorsrc
index d9fba3b00f..9bc4df0f96 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -1166,7 +1166,9 @@
"avatar_url": "https://avatars.githubusercontent.com/u/1112056?v=4",
"profile": "https://ansgar.dev",
"contributions": [
- "maintenance"
+ "maintenance",
+ "code",
+ "bug"
]
},
{
@@ -1300,6 +1302,16 @@
"contributions": [
"doc"
]
+ },
+ {
+ "login": "arnogeurts-sqills",
+ "name": "arnogeurts-sqills",
+ "avatar_url": "https://avatars.githubusercontent.com/u/79304871?v=4",
+ "profile": "https://github.com/arnogeurts-sqills",
+ "contributions": [
+ "bug",
+ "code"
+ ]
}
],
"repoType": "github",
diff --git a/.devcontainer.json b/.devcontainer.json
new file mode 100644
index 0000000000..96182dcfe2
--- /dev/null
+++ b/.devcontainer.json
@@ -0,0 +1,21 @@
+{
+ "name": "Dev Container Definition - AWS JSII",
+ "build": {
+ "dockerfile": "superchain/Dockerfile",
+ "context": ".",
+ "target": "superchain",
+ "args": {
+ "BUILDPLATFORM": "linux/amd64",
+ "TARGETPLATFORM": "linux/amd64",
+ "BUILD_TIMESTAMP": "unknown",
+ "REGISTRY": "docker.io/library",
+ "COMMIT_ID": "head"
+ }
+ },
+ "containerUser": "root",
+ "remoteUser": "root",
+ "postCreateCommand": "yarn install && yarn build",
+ "extensions": [
+ "dbaeumer.vscode-eslint@2.1.5"
+ ]
+}
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000..f53c86acbe
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,3 @@
+node_modules
+.env
+maven-repo
diff --git a/.github/workflows/auto-approve.yml b/.github/workflows/auto-approve.yml
index 1206e3fe61..8f7497006d 100644
--- a/.github/workflows/auto-approve.yml
+++ b/.github/workflows/auto-approve.yml
@@ -14,9 +14,10 @@ jobs:
auto-approve:
if: contains(github.event.pull_request.labels.*.name, 'auto-approve')
permissions:
+ actions: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- - uses: hmarr/auto-approve-action@v2.1.0
- with:
- github-token: "${{ secrets.GITHUB_TOKEN }}"
\ No newline at end of file
+ - run: gh pr review --approve ${{ github.event.pull_request.number }} -R ${{ github.repository }}
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index fab3dfd957..d5754248f3 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -213,7 +213,7 @@ jobs:
dotnet: ['3.1.x']
go: ['1.16']
java: ['8']
- node: ['12', '14', '16']
+ node: ['12', '14', '16', '17']
os: [ubuntu-latest]
python: ['3.6']
# Add specific combinations to be tested against "node 12" (to restrict cardinality)
diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml
index 1619f8bc4c..71d3d0842b 100644
--- a/.github/workflows/pr-labeler.yml
+++ b/.github/workflows/pr-labeler.yml
@@ -10,9 +10,10 @@ jobs:
if: github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'dependabot-preview[bot]'
runs-on: ubuntu-latest
permissions:
- pull-requests: write
+ actions: write
issues: write
+ pull-requests: write
steps:
- run: gh pr edit ${{ github.event.pull_request.number }} --add-label "auto-approve" -R ${{ github.repository }}
env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.AUTO_APPROVE_GITHUB_TOKEN }}
diff --git a/.mergify/config.yml b/.mergify/config.yml
index 8c6c3f928b..87f4fabe87 100644
--- a/.mergify/config.yml
+++ b/.mergify/config.yml
@@ -11,6 +11,7 @@ queue_rules:
- status-success~=^Test \(.* node 12 .*$
- status-success~=^Test \(.* node 14 .*$
- status-success~=^Test \(.* node 16 .*$
+ - status-success~=^Test \(.* node 17 .*$
# One test for each supported dotnet version
- status-success~=^Test \(.* dotnet 3\.1\.x .*$
- status-success~=^Test \(.* dotnet 5\.0\.x .*$
@@ -60,6 +61,7 @@ pull_request_rules:
- status-success~=^Test \(.* node 12 .*$
- status-success~=^Test \(.* node 14 .*$
- status-success~=^Test \(.* node 16 .*$
+ - status-success~=^Test \(.* node 17 .*$
# One test for each supported dotnet version
- status-success~=^Test \(.* dotnet 3\.1\.x .*$
- status-success~=^Test \(.* dotnet 5\.0\.x .*$
@@ -109,6 +111,7 @@ pull_request_rules:
- status-success~=^Test \(.* node 12 .*$
- status-success~=^Test \(.* node 14 .*$
- status-success~=^Test \(.* node 16 .*$
+ - status-success~=^Test \(.* node 17 .*$
# One test for each supported dotnet version
- status-success~=^Test \(.* dotnet 3\.1\.x .*$
- status-success~=^Test \(.* dotnet 5\.0\.x .*$
@@ -158,6 +161,7 @@ pull_request_rules:
- status-success~=^Test \(.* node 12 .*$
- status-success~=^Test \(.* node 14 .*$
- status-success~=^Test \(.* node 16 .*$
+ - status-success~=^Test \(.* node 17 .*$
# One test for each supported dotnet version
- status-success~=^Test \(.* dotnet 3\.1\.x .*$
- status-success~=^Test \(.* dotnet 5\.0\.x .*$
@@ -202,4 +206,4 @@ pull_request_rules:
[Conventional Commits]: https://www.conventionalcommits.org
conditions:
- - -status-success=Semantic Pull Request
+ - status-failure=Semantic Pull Request
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f5acad7315..138090c7b8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,32 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+## [1.53.0](https://github.com/aws/jsii/compare/v1.52.1...v1.53.0) (2022-02-09)
+
+
+### Features
+
+* add configuration for Visual Studio Code ([#3309](https://github.com/aws/jsii/issues/3309)) ([3edf74c](https://github.com/aws/jsii/commit/3edf74cdc6486f35352aec5c98bf5a01657a1209))
+* **go:** add UnsafeCast function ([#3316](https://github.com/aws/jsii/issues/3316)) ([19da85e](https://github.com/aws/jsii/commit/19da85e57e544761b83c6c0dfc4bc3432ce4a2b3))
+* **go:** Use type registry to find the correct target type for JSII Proxy ([#3354](https://github.com/aws/jsii/issues/3354)) ([75d94ef](https://github.com/aws/jsii/commit/75d94effb71bcbdb0ab30c9b468024e0939d2084)), closes [#3353](https://github.com/aws/jsii/issues/3353) [#2819](https://github.com/aws/jsii/issues/2819)
+* **rosetta:** Rosetta manages dependencies automatically ([#3269](https://github.com/aws/jsii/issues/3269)) ([f0b811b](https://github.com/aws/jsii/commit/f0b811b5642e1093a0b59b170a70df258df39fab))
+
+
+### Bug Fixes
+
+* **dontet:** excessive overrides generated ([#3355](https://github.com/aws/jsii/issues/3355)) ([5460d66](https://github.com/aws/jsii/commit/5460d66f2db6441f7d8cfc849d16f89d3548b82a))
+* **go:** replace uses of CanConvert to Type.AssignableTo ([#3373](https://github.com/aws/jsii/issues/3373)) ([ae4ea62](https://github.com/aws/jsii/commit/ae4ea624ad4bcac7da90734ed385b0716375ee5d))
+* **go:** unable to reuse instances between child/parent interfaces ([#3321](https://github.com/aws/jsii/issues/3321)) ([70be636](https://github.com/aws/jsii/commit/70be636e2eb3e5144dab16cae62162420a4fe5a8))
+* **jsii:** breaks due to faulty version of `colors` ([#3328](https://github.com/aws/jsii/issues/3328)) ([13c0737](https://github.com/aws/jsii/commit/13c073793a9fc5b45cad93801634ce6397a2e007))
+* **jsii:** compiler allows inheriting interface-violating members ([#3343](https://github.com/aws/jsii/issues/3343)) ([b5037b9](https://github.com/aws/jsii/commit/b5037b9adf74c1978f1fd940921ce6c2050c297b)), closes [#3342](https://github.com/aws/jsii/issues/3342)
+* **jsii:** excessive overrides declarations registered ([#3375](https://github.com/aws/jsii/issues/3375)) ([64a5984](https://github.com/aws/jsii/commit/64a598487f81339e63a0aec5f7428eb99b6c7eb1))
+* **jsii:** submodule READMEs don't have literate examples ([#3347](https://github.com/aws/jsii/issues/3347)) ([5769771](https://github.com/aws/jsii/commit/576977133bd9ea0997d9bc1dd114c9407d9b5b12)), closes [aws/aws-cdk#18589](https://github.com/aws/aws-cdk/issues/18589)
+* **kernel:** kernel's private object annotations are enumerable ([#3339](https://github.com/aws/jsii/issues/3339)) ([d361c7b](https://github.com/aws/jsii/commit/d361c7bdb2d269e6fcc9c06e55d23e8fe19859a5))
+* **pacmak:** greatly reduce go code-gen memory footprint ([#3362](https://github.com/aws/jsii/issues/3362)) ([77b520f](https://github.com/aws/jsii/commit/77b520fb47989bd0dbc0c5af53a17eba0c54a439))
+* **python:** cannot call a method that takes an empty struct ([#3372](https://github.com/aws/jsii/issues/3372)) ([c36b67c](https://github.com/aws/jsii/commit/c36b67cbcd125f6b89bedf7be4ebc8fa30e1ba90)), closes [#2846](https://github.com/aws/jsii/issues/2846)
+* remove the "comments rewriter" ([#3368](https://github.com/aws/jsii/issues/3368)) ([50dd3b0](https://github.com/aws/jsii/commit/50dd3b051727a64950165efc191d554831812447))
+* **superchain:** failure to download PowerShell ([#3340](https://github.com/aws/jsii/issues/3340)) ([59eaaa3](https://github.com/aws/jsii/commit/59eaaa33734bc44d31c483cb81dc5c70b1e24dd8))
+
## [1.52.1](https://github.com/aws/jsii/compare/v1.52.0...v1.52.1) (2022-01-09)
diff --git a/README.md b/README.md
index 68acb33c44..f0785ac458 100644
--- a/README.md
+++ b/README.md
@@ -64,7 +64,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Andy Slezak 💻 |
- Ansgar Mertens 🚧 |
+ Ansgar Mertens 🚧 💻 🐛 |
Anshul Guleria 🤔 |
Ari Palo 🤔 |
Armaan Tobaccowalla 🐛 |
@@ -208,15 +208,16 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
aniljava 💻 |
+ arnogeurts-sqills 🐛 💻 |
deccy-mcc 🐛 |
dependabot-preview[bot] 🐛 🚧 |
dependabot[bot] 🚧 |
dheffx 🐛 |
gregswdl 🐛 |
guyroberts21 📖 |
- mattBrzezinski 📖 |
+ mattBrzezinski 📖 |
mergify 🚧 |
mergify[bot] 🚧 |
seiyashima42 🐛 💻 📖 |
diff --git a/gh-pages/content/specification/6-compliance-report.md b/gh-pages/content/specification/6-compliance-report.md
index 82aec9f08e..ee54cee7a2 100644
--- a/gh-pages/content/specification/6-compliance-report.md
+++ b/gh-pages/content/specification/6-compliance-report.md
@@ -5,7 +5,7 @@
This section details the current state of each language binding with respect to our standard compliance suite.
-| number | test | java (99.16%) | golang (78.15%) | Dotnet | Python |
+| number | test | java (98.33%) | golang (79.17%) | Dotnet | Python |
| ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -------------------------------------------- | ------ | ------ |
| 1 | asyncOverrides_overrideCallsSuper | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | ⭕ | ⭕ |
| 2 | [arrayReturnedByMethodCanBeRead]("Array created in the kernel can be queried for its elements") | 🟢 | 🟢 | ⭕ | ⭕ |
@@ -42,7 +42,7 @@ This section details the current state of each language binding with respect to
| 33 | testLiteralInterface | 🟢 | 🟢 | ⭕ | ⭕ |
| 34 | structs_nonOptionalhashCode | 🟢 | ⚪ | ⭕ | ⭕ |
| 35 | propertyOverrides_set_throws | 🟢 | 🟢 | ⭕ | ⭕ |
-| 36 | canLeverageIndirectInterfacePolymorphism | 🟢 | [🔴](https://github.com/aws/jsii/issues/2688) | ⭕ | ⭕ |
+| 36 | canLeverageIndirectInterfacePolymorphism | 🟢 | 🟢 | ⭕ | ⭕ |
| 37 | fluentApi | 🟢 | ⚪ | ⭕ | ⭕ |
| 38 | staticListInClassCanBeReadCorrectly | 🟢 | 🟢 | ⭕ | ⭕ |
| 39 | mapReturnedByMethodCannotBeModified | 🟢 | ⚪ | ⭕ | ⭕ |
@@ -126,3 +126,4 @@ This section details the current state of each language binding with respect to
| 117 | testInterfaces | 🟢 | 🟢 | ⭕ | ⭕ |
| 118 | [callbackParameterIsInterface]("Validates pure interfaces can be passed to callbacks") | ⭕ | 🟢 | ⭕ | ⭕ |
| 119 | [classCanBeUsedWhenNotExpressedlyLoaded]("Validates that types not explicitly loaded by the user can safely be returned by JS code") | 🟢 | 🟢 | ⭕ | ⭕ |
+| 120 | [downcasting]("Ensures unsafe-cast features work as expected") | ⭕ | 🟢 | ⭕ | ⭕ |
diff --git a/gh-pages/content/user-guides/lib-user/language-specific/go.md b/gh-pages/content/user-guides/lib-user/language-specific/go.md
index 137632ffaf..fefc82d2ac 100644
--- a/gh-pages/content/user-guides/lib-user/language-specific/go.md
+++ b/gh-pages/content/user-guides/lib-user/language-specific/go.md
@@ -198,3 +198,62 @@ func (c *childClass) SetConcreteProperty(v string) {
c.AbstractBaseClass.SetConcreteProperty(strings.ToUpper(v))
}
```
+
+## Unchecked conversions using `UnsafeCast`
+
+Developers may occasionally need to down-cast a value in order to leverage some
+other interface it implements. This happens in cases where the runtime is unable
+to determine the complete dynamic type of a value returned by a function, which
+happens for example when the TypeScript version of that function returns `any`,
+`unknown`, or a union of several types (which cannot be represented in go).
+
+In such cases, traditional go type assertions may not always produce the
+expected result. Instead, the library that exposes these functions should also
+expose type-checking utilities (e.g: `Stack.isStack(thing: any): boolean`) that
+developers can use to guard an unchecked conversion, which in Go is performed
+using `UnsafeCast`.
+
+The `UnsafeCast` function expects two arguments the original value, and a
+pointer to a variable of the desired interface type.
+
+!!! warning
+ The `UnsafeCast` function may **panic** if:
+
+ - the provided original value was not obtained through a function exported
+ from a jsii package.
+ - the provided pointer is not to a value typed as an interface exported from
+ a jsii package.
+
+ If the original value does, in fact, not implement the target interface
+ type, undefined behavior will occur as a result of using functions of that
+ interface.
+
+An example use of the `UnsafeCast` feature is when using [AWS CDK escape hatches]:
+
+```go hl_lines="15-20"
+package main
+
+import (
+ "github.com/aws/aws-cdk-go/awscdk/v2"
+ "github.com/aws/aws-cdk-go/awscdk/v2/awssns"
+ "github.com/aws/jsii-runtime-go"
+)
+
+func main() {
+ app := awscdk.NewApp(nil)
+ stack := awscdk.NewStack(app, jsii.String("TestStack"), nil)
+
+ topic := awssns.NewTopic(stack, jsii.String("MyTopic"), nil)
+
+ // We know that topic.Node().DefaultChild() is a awssns.CfnTopic
+ var cfn_topic awssns.CfnTopic
+ // We perform the conversion into cfn_topic
+ jsii.UnsafeCast(topic.Node().DefaultChild(), &cfn_topic)
+ // Then we use the conversion result
+ cfn_topic.SetDisplayName(jsii.String("Overridden Display Name"))
+
+ app.Synth(nil)
+}
+```
+
+[AWS CDK escape hatches]: https://docs.aws.amazon.com/cdk/v2/guide/cfn_layer.html
diff --git a/gh-pages/requirements-dev.txt b/gh-pages/requirements-dev.txt
index c82f2e4ced..552a0d7832 100644
--- a/gh-pages/requirements-dev.txt
+++ b/gh-pages/requirements-dev.txt
@@ -1,4 +1,4 @@
mkdocs~=1.2.3
mkdocs-awesome-pages-plugin~=2.6.0
-mkdocs-material~=8.1.4
+mkdocs-material~=8.1.10
mkdocs-git-revision-date-plugin~=0.3.1
diff --git a/lerna.json b/lerna.json
index 523be48e3b..c3c86a8445 100644
--- a/lerna.json
+++ b/lerna.json
@@ -10,5 +10,5 @@
"rejectCycles": true
}
},
- "version": "1.52.1"
+ "version": "1.53.0"
}
diff --git a/package.json b/package.json
index de84acee6b..294ed1a8c5 100644
--- a/package.json
+++ b/package.json
@@ -16,21 +16,21 @@
},
"devDependencies": {
"@jest/types": "^27.4.2",
- "@typescript-eslint/eslint-plugin": "^5.8.1",
- "@typescript-eslint/parser": "^5.8.1",
+ "@typescript-eslint/eslint-plugin": "^5.10.2",
+ "@typescript-eslint/parser": "^5.10.2",
"all-contributors-cli": "^6.20.0",
- "eslint": "^8.5.0",
+ "eslint": "^8.8.0",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-node": "^0.3.6",
"eslint-import-resolver-typescript": "^2.5.0",
- "eslint-plugin-import": "^2.25.3",
+ "eslint-plugin-import": "^2.25.4",
"eslint-plugin-prettier": "^4.0.0",
- "jest-circus": "^27.4.5",
- "jest-config": "^27.4.5",
+ "jest-circus": "^27.4.6",
+ "jest-config": "^27.4.7",
"lerna": "^4.0.0",
"prettier": "^2.5.1",
"standard-version": "^9.3.2",
- "ts-jest": "^27.1.2",
+ "ts-jest": "^27.1.3",
"ts-node": "^10.4.0",
"typescript": "~3.9.10"
},
diff --git a/packages/@jsii/Directory.Build.targets b/packages/@jsii/Directory.Build.targets
index b2b6ca0bf2..184b8c3538 100644
--- a/packages/@jsii/Directory.Build.targets
+++ b/packages/@jsii/Directory.Build.targets
@@ -11,7 +11,7 @@
-
+
diff --git a/packages/@jsii/check-node/package.json b/packages/@jsii/check-node/package.json
index 465df1906e..e0e540e143 100644
--- a/packages/@jsii/check-node/package.json
+++ b/packages/@jsii/check-node/package.json
@@ -41,8 +41,8 @@
},
"devDependencies": {
"@types/chalk": "^2.2.0",
- "@types/jest": "^27.0.3",
- "@types/node": "^12.20.39",
- "jest": "^27.4.5"
+ "@types/jest": "^27.4.0",
+ "@types/node": "^12.20.43",
+ "jest": "^27.4.7"
}
}
diff --git a/packages/@jsii/check-node/src/constants.ts b/packages/@jsii/check-node/src/constants.ts
index 9b634ff7c7..a0a3e84306 100644
--- a/packages/@jsii/check-node/src/constants.ts
+++ b/packages/@jsii/check-node/src/constants.ts
@@ -63,5 +63,7 @@ export const VERSION_SUPPORT: { readonly [range: string]: SupportLevel } = {
'^15.0.0-0': SupportLevel.END_OF_LIFE,
'<16.3.0': SupportLevel.UNSUPPORTED,
'^16.3.0': SupportLevel.SUPPORTED,
+ '<17.3.0': SupportLevel.UNSUPPORTED,
+ '^17.3.0': SupportLevel.SUPPORTED,
// Anything else will be treated as SupportLevel.UNTESTED.
};
diff --git a/packages/@jsii/dotnet-runtime-test/package.json b/packages/@jsii/dotnet-runtime-test/package.json
index 177351a629..91b3165ef8 100644
--- a/packages/@jsii/dotnet-runtime-test/package.json
+++ b/packages/@jsii/dotnet-runtime-test/package.json
@@ -31,7 +31,7 @@
},
"devDependencies": {
"@jsii/dotnet-runtime": "^0.0.0",
- "@types/node": "^12.20.39",
+ "@types/node": "^12.20.43",
"jsii-calc": "^3.20.120",
"jsii-pacmak": "^0.0.0",
"typescript": "~3.9.10"
diff --git a/packages/@jsii/dotnet-runtime/package.json b/packages/@jsii/dotnet-runtime/package.json
index ee61ce23dd..325ce1bce3 100644
--- a/packages/@jsii/dotnet-runtime/package.json
+++ b/packages/@jsii/dotnet-runtime/package.json
@@ -39,7 +39,7 @@
},
"devDependencies": {
"@jsii/runtime": "^0.0.0",
- "@types/node": "^12.20.39",
+ "@types/node": "^12.20.43",
"@types/semver": "^7.3.9",
"jsii-build-tools": "^0.0.0",
"semver": "^7.3.5",
diff --git a/packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/DeputyBase.cs b/packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/DeputyBase.cs
index 5d77f36cb5..99d9e3c1f8 100644
--- a/packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/DeputyBase.cs
+++ b/packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/DeputyBase.cs
@@ -76,7 +76,7 @@ IEnumerable GetMethodOverrides()
var inheritedAttribute = method.GetAttribute();
var uninheritedAttribute = method.GetAttribute(false);
- if ((inheritedAttribute != null && uninheritedAttribute == null) || uninheritedAttribute?.IsOverride == true)
+ if (inheritedAttribute != null && uninheritedAttribute == null)
{
yield return new Override(method: (inheritedAttribute ?? uninheritedAttribute)!.Name);
}
@@ -93,7 +93,7 @@ IEnumerable GetPropertyOverrides()
var inheritedAttribute = property.GetAttribute();
var uninheritedAttribute = property.GetAttribute(false);
- if ((inheritedAttribute != null && uninheritedAttribute == null) || uninheritedAttribute?.IsOverride == true)
+ if (inheritedAttribute != null && uninheritedAttribute == null)
{
yield return new Override(property: (inheritedAttribute ?? uninheritedAttribute)!.Name);
}
diff --git a/packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiMethodAttribute.cs b/packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiMethodAttribute.cs
index f757f657c8..19d8537d37 100644
--- a/packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiMethodAttribute.cs
+++ b/packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiMethodAttribute.cs
@@ -12,6 +12,7 @@ public JsiiMethodAttribute(
string? returnsJson = null,
string? parametersJson = null,
bool isAsync = false,
+ // Unused, retained for backwards-compatibility
bool isOverride = false)
{
Name = name ?? throw new ArgumentNullException(nameof(name));
@@ -23,7 +24,6 @@ public JsiiMethodAttribute(
: JsonConvert.DeserializeObject(parametersJson)
?? throw new ArgumentException("Invalid JSON descriptor", nameof(parametersJson));
IsAsync = isAsync;
- IsOverride = isOverride;
}
public string Name { get; }
@@ -34,7 +34,5 @@ public JsiiMethodAttribute(
public bool IsAsync { get; }
-
- public bool IsOverride { get; }
}
-}
\ No newline at end of file
+}
diff --git a/packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiPropertyAttribute.cs b/packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiPropertyAttribute.cs
index dfddd5233b..9d451d853c 100644
--- a/packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiPropertyAttribute.cs
+++ b/packages/@jsii/dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiPropertyAttribute.cs
@@ -7,14 +7,18 @@ namespace Amazon.JSII.Runtime.Deputy
[AttributeUsage(AttributeTargets.Property)]
public sealed class JsiiPropertyAttribute : Attribute, IOptionalValue
{
- public JsiiPropertyAttribute(string name, string typeJson, bool isOptional = false, bool isOverride = false)
+ public JsiiPropertyAttribute(
+ string name,
+ string typeJson,
+ bool isOptional = false,
+ // Unused, retained for backwards-compatibility
+ bool isOverride = false)
{
Name = name ?? throw new ArgumentNullException(nameof(name));
Type = JsonConvert.DeserializeObject(typeJson ??
throw new ArgumentNullException(nameof(typeJson)))
?? throw new ArgumentException("Invalid JSON descriptor", nameof(typeJson));
IsOptional = isOptional;
- IsOverride = isOverride;
}
public string Name { get; }
@@ -22,7 +26,5 @@ public JsiiPropertyAttribute(string name, string typeJson, bool isOptional = fal
public TypeReference Type { get; }
public bool IsOptional { get; }
-
- public bool IsOverride { get; }
}
-}
\ No newline at end of file
+}
diff --git a/packages/@jsii/go-runtime-test/project/compliance_test.go b/packages/@jsii/go-runtime-test/project/compliance_test.go
index bc2f1c1247..529f596476 100644
--- a/packages/@jsii/go-runtime-test/project/compliance_test.go
+++ b/packages/@jsii/go-runtime-test/project/compliance_test.go
@@ -1462,7 +1462,6 @@ func (suite *ComplianceSuite) TestCanLeverageIndirectInterfacePolymorphism() {
require := suite.Require()
require.Equal(float64(1337), *provider.ProvideAsClass().Value())
- suite.FailTest("Unable to reuse instances between parent/child interfaces", "https://github.com/aws/jsii/issues/2688")
require.Equal(float64(1337), *provider.ProvideAsInterface().Value())
require.Equal("to implement", *provider.ProvideAsInterface().Verb())
}
@@ -1645,6 +1644,16 @@ func (suite *ComplianceSuite) TestClassCanBeUsedWhenNotExpressedlyLoaded() {
cdk16625.New().Test()
}
+func (suite *ComplianceSuite) TestDownCasting() {
+ require := suite.Require()
+
+ anyValue := calc.SomeTypeJsii976_ReturnAnonymous()
+ var realValue calc.IReturnJsii976
+
+ jsii.UnsafeCast(anyValue, &realValue)
+
+ require.Equal(realValue.Foo(), jsii.Number(1337))
+}
// required to make `go test` recognize the suite.
func TestComplianceSuite(t *testing.T) {
diff --git a/packages/@jsii/go-runtime-test/project/go.mod b/packages/@jsii/go-runtime-test/project/go.mod
index a71db58144..739b059c53 100644
--- a/packages/@jsii/go-runtime-test/project/go.mod
+++ b/packages/@jsii/go-runtime-test/project/go.mod
@@ -1,6 +1,6 @@
module github.com/aws/jsii/go-runtime-test
-go 1.15
+go 1.17
require (
github.com/aws/jsii-runtime-go v0.0.0
@@ -12,6 +12,17 @@ require (
golang.org/x/tools v0.1.0
)
+require (
+ github.com/Masterminds/semver/v3 v3.1.1 // indirect
+ github.com/aws/jsii/jsii-calc/go/scopejsiicalcbaseofbase/v2 v2.1.1 // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ golang.org/x/mod v0.3.0 // indirect
+ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect
+ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+)
+
replace (
github.com/aws/jsii-runtime-go => ../../go-runtime/jsii-runtime-go
github.com/aws/jsii/jsii-calc/go/jcb => ../jsii-calc/go/jcb
diff --git a/packages/@jsii/go-runtime-test/project/go.sum b/packages/@jsii/go-runtime-test/project/go.sum
index ceb0e37170..57ec351287 100644
--- a/packages/@jsii/go-runtime-test/project/go.sum
+++ b/packages/@jsii/go-runtime-test/project/go.sum
@@ -1,7 +1,8 @@
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -39,5 +40,6 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1N
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/packages/@jsii/go-runtime-test/project/internal/cdk16625/cdk16625.go b/packages/@jsii/go-runtime-test/project/internal/cdk16625/cdk16625.go
index aef3945a2a..05452a537d 100644
--- a/packages/@jsii/go-runtime-test/project/internal/cdk16625/cdk16625.go
+++ b/packages/@jsii/go-runtime-test/project/internal/cdk16625/cdk16625.go
@@ -11,7 +11,7 @@ func New() abc.Cdk16625 {
return c
}
-type cdk16625 struct{
+type cdk16625 struct {
abc.Cdk16625
}
diff --git a/packages/@jsii/go-runtime-test/project/tools.go b/packages/@jsii/go-runtime-test/project/tools.go
index c8bdab1fff..73d81778ef 100644
--- a/packages/@jsii/go-runtime-test/project/tools.go
+++ b/packages/@jsii/go-runtime-test/project/tools.go
@@ -1,3 +1,4 @@
+//go:build tools
// +build tools
// Package tools contains the necessary statements to ensure tool dependencies
diff --git a/packages/@jsii/go-runtime/go.mod b/packages/@jsii/go-runtime/go.mod
index 7230730946..5099e3a5fb 100644
--- a/packages/@jsii/go-runtime/go.mod
+++ b/packages/@jsii/go-runtime/go.mod
@@ -1,8 +1,8 @@
module github.com/aws/jsii
-go 1.15
+go 1.16
require (
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5
- golang.org/x/tools v0.1.8
+ golang.org/x/tools v0.1.9
)
diff --git a/packages/@jsii/go-runtime/go.sum b/packages/@jsii/go-runtime/go.sum
index aa8273a5d7..b50c26931b 100644
--- a/packages/@jsii/go-runtime/go.sum
+++ b/packages/@jsii/go-runtime/go.sum
@@ -26,8 +26,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
-golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
+golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
+golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/cast.go b/packages/@jsii/go-runtime/jsii-runtime-go/cast.go
new file mode 100644
index 0000000000..102e4bfba4
--- /dev/null
+++ b/packages/@jsii/go-runtime/jsii-runtime-go/cast.go
@@ -0,0 +1,59 @@
+package jsii
+
+import (
+ "fmt"
+ "reflect"
+
+ "github.com/aws/jsii-runtime-go/internal/kernel"
+)
+
+// UnsafeCast converts the given interface value to the desired target interface
+// pointer. Panics if the from value is not a jsii proxy object, or if the to
+// value is not a pointer to an interface type.
+func UnsafeCast(from interface{}, into interface{}) {
+ rinto := reflect.ValueOf(into)
+ if rinto.Kind() != reflect.Ptr {
+ panic(fmt.Errorf("Second argument to UnsafeCast must be a pointer to an interface. Received %s", rinto.Type().String()))
+ }
+ rinto = rinto.Elem()
+ if rinto.Kind() != reflect.Interface {
+ panic(fmt.Errorf("Second argument to UnsafeCast must be a pointer to an interface. Received pointer to %s", rinto.Type().String()))
+ }
+
+ rfrom := reflect.ValueOf(from)
+
+ // If rfrom is essentially nil, set into to nil and return.
+ if !rfrom.IsValid() || rfrom.IsZero() {
+ null := reflect.Zero(rinto.Type())
+ rinto.Set(null)
+ return
+ }
+ // Interfaces may present as a pointer to an implementing struct, and that's fine...
+ if rfrom.Kind() != reflect.Interface && rfrom.Kind() != reflect.Ptr {
+ panic(fmt.Errorf("First argument to UnsafeCast must be an interface value. Received %s", rfrom.Type().String()))
+ }
+
+ // If rfrom can be directly converted to rinto, just do it.
+ if rfrom.Type().AssignableTo(rinto.Type()) {
+ rfrom = rfrom.Convert(rinto.Type())
+ rinto.Set(rfrom)
+ return
+ }
+
+ client := kernel.GetClient()
+ if objID, found := client.FindObjectRef(rfrom); found {
+ // Ensures the value is initialized properly. Panics if the target value is not a jsii interface type.
+ client.Types().InitJsiiProxy(rinto, rinto.Type())
+
+ // If the target type is a behavioral interface, add it to the ObjectRef.Interfaces list.
+ if fqn, found := client.Types().InterfaceFQN(rinto.Type()); found {
+ objID.Interfaces = append(objID.Interfaces, fqn)
+ }
+
+ // Make the new value an alias to the old value.
+ client.RegisterInstance(rinto, objID)
+ return
+ }
+
+ panic(fmt.Errorf("First argument to UnsafeCast must be a jsii proxy value. Received %s", rfrom.String()))
+}
diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/cast_test.go b/packages/@jsii/go-runtime/jsii-runtime-go/cast_test.go
new file mode 100644
index 0000000000..09ff1ffeef
--- /dev/null
+++ b/packages/@jsii/go-runtime/jsii-runtime-go/cast_test.go
@@ -0,0 +1,101 @@
+package jsii
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/aws/jsii-runtime-go/internal/api"
+ "github.com/aws/jsii-runtime-go/internal/kernel"
+)
+
+type MockInterfaceABase interface {
+ MockMethodABase(_ float64)
+}
+
+type mockABase struct {
+ _ int // padding
+}
+
+func (m *mockABase) MockMethodABase(_ float64) {}
+
+type MockInterfaceA interface {
+ MockInterfaceABase
+ MockMethodA(_ string)
+}
+
+func NewMockInterfaceA() MockInterfaceA {
+ return &mockA{mockABase{}}
+}
+
+type mockA struct {
+ mockABase
+}
+
+func (m *mockA) MockMethodA(_ string) {}
+
+type MockInterfaceB interface {
+ MockMethodB(_ int)
+}
+
+func NewMockInterfaceB() MockInterfaceB {
+ return &mockB{}
+}
+
+type mockB struct {
+ _ int // Padding
+}
+
+func (m *mockB) MockMethodB(_ int) {}
+
+func TestNilSource(t *testing.T) {
+ // Make "into" not nil to ensure the cast function overwrites it.
+ into := NewMockInterfaceB()
+ UnsafeCast(nil, &into)
+
+ if into != nil {
+ t.Fail()
+ }
+}
+
+func TestSourceAndTargetAreTheSame(t *testing.T) {
+ into := NewMockInterfaceB()
+ original := into
+ UnsafeCast(into, &into)
+
+ if into != original {
+ t.Fail()
+ }
+}
+
+func TestTargetIsSubclassOfSource(t *testing.T) {
+ from := NewMockInterfaceA()
+ var into MockInterfaceABase
+ UnsafeCast(from, &into)
+
+ if into != from {
+ t.Fail()
+ }
+}
+
+func TestRegistersAlias(t *testing.T) {
+ client := kernel.GetClient()
+
+ objid := api.ObjectRef{InstanceID: "Object@1337#42"}
+ from := NewMockInterfaceA()
+ client.RegisterInstance(reflect.ValueOf(from), objid)
+
+ var into MockInterfaceB
+ client.Types().RegisterInterface(api.FQN("mock.InterfaceB"), reflect.TypeOf(&into).Elem(), []api.Override{}, func() interface{} { return NewMockInterfaceB() })
+
+ UnsafeCast(from, &into)
+
+ if into == nil {
+ t.Fail()
+ }
+
+ if refid, found := client.FindObjectRef(reflect.ValueOf(into)); !found {
+ t.Fail()
+ } else if refid.InstanceID != objid.InstanceID {
+ t.Fail()
+ }
+}
diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/go.mod b/packages/@jsii/go-runtime/jsii-runtime-go/go.mod
index 4545261637..e406443fa2 100644
--- a/packages/@jsii/go-runtime/jsii-runtime-go/go.mod
+++ b/packages/@jsii/go-runtime/jsii-runtime-go/go.mod
@@ -7,4 +7,9 @@ require (
github.com/stretchr/testify v1.7.0
)
+require (
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+)
+
retract v1.27.0
diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/go.sum b/packages/@jsii/go-runtime/jsii-runtime-go/go.sum
index 46621f39b3..34dd278f55 100644
--- a/packages/@jsii/go-runtime/jsii-runtime-go/go.sum
+++ b/packages/@jsii/go-runtime/jsii-runtime-go/go.sum
@@ -1,14 +1,15 @@
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/client.go b/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/client.go
index d0f4eeeec7..944e420644 100644
--- a/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/client.go
+++ b/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/client.go
@@ -95,29 +95,35 @@ func (c *Client) Types() *typeregistry.TypeRegistry {
return types
}
-func (c *Client) RegisterInstance(instance reflect.Value, instanceID string) error {
- return c.objects.Register(instance, instanceID)
+func (c *Client) RegisterInstance(instance reflect.Value, objectRef api.ObjectRef) error {
+ return c.objects.Register(instance, objectRef)
}
func (c *Client) request(req kernelRequester, res kernelResponder) error {
return c.process.Request(req, res)
}
-func (c *Client) FindObjectRef(obj reflect.Value) (string, bool) {
+func (c *Client) FindObjectRef(obj reflect.Value) (ref api.ObjectRef, found bool) {
+ ref = api.ObjectRef{}
+ found = false
+
switch obj.Kind() {
case reflect.Struct:
// Structs can be checked only if they are addressable, meaning
// they are obtained from fields of an addressable struct.
if !obj.CanAddr() {
- return "", false
+ return
}
obj = obj.Addr()
fallthrough
case reflect.Interface, reflect.Ptr:
- return c.objects.InstanceID(obj)
+ if ref.InstanceID, found = c.objects.InstanceID(obj); found {
+ ref.Interfaces = c.objects.Interfaces(ref.InstanceID)
+ }
+ return
default:
// Other types cannot possibly be object references!
- return "", false
+ return
}
}
diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/conversions.go b/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/conversions.go
index 97be302f36..2897f89efa 100644
--- a/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/conversions.go
+++ b/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/conversions.go
@@ -63,15 +63,21 @@ func (c *Client) castAndSetToPtr(ptr reflect.Value, data reflect.Value) {
return
}
+ targetType := ptr.Type()
+ if typ, ok := c.Types().FindType(ref.TypeFQN()); ok && typ.AssignableTo(ptr.Type()) {
+ // Specialize the return type to be the dynamic value type
+ targetType = typ
+ }
+
// If it's currently tracked, return the current instance
- if object, ok := c.objects.GetObject(ref.InstanceID); ok {
+ if object, ok := c.objects.GetObjectAs(ref.InstanceID, targetType); ok {
ptr.Set(object)
return
}
// If return data is jsii object references, add to objects table.
- if err := c.Types().InitJsiiProxy(ptr); err == nil {
- if err = c.RegisterInstance(ptr, ref.InstanceID); err != nil {
+ if err := c.Types().InitJsiiProxy(ptr, targetType); err == nil {
+ if err = c.RegisterInstance(ptr, ref); err != nil {
panic(err)
}
} else {
@@ -157,7 +163,7 @@ func (c *Client) CastPtrToRef(dataVal reflect.Value) interface{} {
case reflect.Interface, reflect.Ptr:
if valref, valHasRef := c.FindObjectRef(dataVal); valHasRef {
- return api.ObjectRef{InstanceID: valref}
+ return valref
}
// In case we got a pointer to a map, slice, enum, ...
diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/manage-object.go b/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/manage-object.go
index c755c83cb1..7c0e6416ab 100644
--- a/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/manage-object.go
+++ b/packages/@jsii/go-runtime/jsii-runtime-go/internal/kernel/manage-object.go
@@ -26,7 +26,7 @@ func (c *Client) ManageObject(v reflect.Value) (ref api.ObjectRef, err error) {
})
if err == nil {
- if err = c.objects.Register(v, resp.InstanceID); err == nil {
+ if err = c.objects.Register(v, api.ObjectRef{InstanceID: resp.InstanceID, Interfaces: interfaces}); err == nil {
ref.InstanceID = resp.InstanceID
}
}
diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/internal/objectstore/objectstore.go b/packages/@jsii/go-runtime/jsii-runtime-go/internal/objectstore/objectstore.go
index 6944056a7f..0fae5652a4 100644
--- a/packages/@jsii/go-runtime/jsii-runtime-go/internal/objectstore/objectstore.go
+++ b/packages/@jsii/go-runtime/jsii-runtime-go/internal/objectstore/objectstore.go
@@ -3,8 +3,14 @@ package objectstore
import (
"fmt"
"reflect"
+
+ "github.com/aws/jsii-runtime-go/internal/api"
)
+// stringSet is a set of strings, implemented as a map from string to an
+// arbitrary 0-width value.
+type stringSet map[string]struct{}
+
// ObjectStore tracks object instances for which an identifier has been
// associated. Object to instanceID association is tracked using the object
// memory address (aka pointer value) in order to not have issues with go's
@@ -16,17 +22,31 @@ type ObjectStore struct {
// passed to the Register method.
objectToID map[uintptr]string
- // idToObject associates an instanceID with the reflect.Value that
- // represents the top-level object that was registered with the instanceID
- // via the Register method.
+ // idToObject associates an instanceID with the first reflect.Value instance
+ // that represents the top-level object that was registered with the
+ // instanceID first via the Register method.
idToObject map[string]reflect.Value
+
+ // idToObjects associates an instanceID with the reflect.Value instances that
+ // represent the top-level objects that were registered with the instanceID
+ // via the Register method.
+ idToObjects map[string]map[reflect.Value]struct{}
+
+ // idToInterfaces associates an instanceID with the set of interfaces that it
+ // is known to implement.
+ //
+ // Incorrect use of the UnsafeCast function may result in an instance's
+ // interface list containing interfaces that it does not actually implement.
+ idToInterfaces map[string]stringSet
}
// New initializes a new ObjectStore.
func New() *ObjectStore {
return &ObjectStore{
- objectToID: make(map[uintptr]string),
- idToObject: make(map[string]reflect.Value),
+ objectToID: make(map[uintptr]string),
+ idToObject: make(map[string]reflect.Value),
+ idToObjects: make(map[string]map[reflect.Value]struct{}),
+ idToInterfaces: make(map[string]stringSet),
}
}
@@ -42,7 +62,7 @@ func New() *ObjectStore {
//
// The call is idempotent: calling Register again with the same value and
// instanceID does not result in an error.
-func (o *ObjectStore) Register(value reflect.Value, instanceID string) error {
+func (o *ObjectStore) Register(value reflect.Value, objectRef api.ObjectRef) error {
var err error
if value, err = canonicalValue(value); err != nil {
return err
@@ -50,40 +70,77 @@ func (o *ObjectStore) Register(value reflect.Value, instanceID string) error {
ptr := value.Pointer()
if existing, found := o.objectToID[ptr]; found {
- if existing == instanceID {
+ if existing == objectRef.InstanceID {
+ o.mergeInterfaces(objectRef)
return nil
}
- return fmt.Errorf("attempting to register %s as %s, but it was already registered as %s", value, instanceID, existing)
+ return fmt.Errorf("attempting to register %s as %s, but it was already registered as %s", value, objectRef.InstanceID, existing)
}
aliases := findAliases(value)
- if existing, found := o.idToObject[instanceID]; found {
- if existing == value {
+ if existing, found := o.idToObjects[objectRef.InstanceID]; found {
+ if _, found := existing[value]; found {
+ o.mergeInterfaces(objectRef)
return nil
}
// Value already exists (e.g: a constructor made a callback with "this"
- // passed as an argument). We make the current value an alias of the new
+ // passed as an argument). We make the current value(s) an alias of the new
// one.
- aliases = append(aliases, existing)
+ for existing := range existing {
+ aliases = append(aliases, existing)
+ }
}
for _, alias := range aliases {
ptr := alias.Pointer()
- if existing, found := o.objectToID[ptr]; found && existing != instanceID {
- return fmt.Errorf("value %s is embedded in %s which has ID %s, but was already assigned %s", alias.String(), value.String(), instanceID, existing)
+ if existing, found := o.objectToID[ptr]; found && existing != objectRef.InstanceID {
+ return fmt.Errorf("value %s is embedded in %s which has ID %s, but was already assigned %s", alias.String(), value.String(), objectRef.InstanceID, existing)
}
}
- o.objectToID[ptr] = instanceID
- o.idToObject[instanceID] = value
+ o.objectToID[ptr] = objectRef.InstanceID
+ // Only add to idToObject if this is the first time this InstanceID is registered
+ if _, found := o.idToObject[objectRef.InstanceID]; !found {
+ o.idToObject[objectRef.InstanceID] = value
+ }
+ if _, found := o.idToObjects[objectRef.InstanceID]; !found {
+ o.idToObjects[objectRef.InstanceID] = make(map[reflect.Value]struct{})
+ }
+ o.idToObjects[objectRef.InstanceID][value] = struct{}{}
for _, alias := range aliases {
- o.objectToID[alias.Pointer()] = instanceID
+ o.objectToID[alias.Pointer()] = objectRef.InstanceID
}
+ o.mergeInterfaces(objectRef)
+
return nil
}
+// mergeInterfaces adds all interfaces carried by the provided objectRef to the
+// tracking set for the objectRef's InstanceID. Does nothing if no interfaces
+// are designated on the objectRef.
+func (o *ObjectStore) mergeInterfaces(objectRef api.ObjectRef) {
+ // If we don't have interfaces, we have nothing to do...
+ if objectRef.Interfaces == nil {
+ return
+ }
+
+ // Find or create the interface list for the relevant InstanceID
+ var interfaces stringSet
+ if list, found := o.idToInterfaces[objectRef.InstanceID]; found {
+ interfaces = list
+ } else {
+ interfaces = make(stringSet)
+ o.idToInterfaces[objectRef.InstanceID] = interfaces
+ }
+
+ // Add any missing interface to the list.
+ for _, iface := range objectRef.Interfaces {
+ interfaces[string(iface)] = struct{}{}
+ }
+}
+
// InstanceID attempts to determine the instanceID associated with the provided
// value, if any. Returns the existing instanceID and a boolean informing
// whether an instanceID was already found or not.
@@ -99,6 +156,23 @@ func (o *ObjectStore) InstanceID(value reflect.Value) (instanceID string, found
return
}
+// Interfaces returns the set of interfaces associated with the provided
+// instanceID.
+//
+// It returns a nil slice in case the instancceID is invalid, or if it does not
+// have any associated interfaces.
+func (o *ObjectStore) Interfaces(instanceID string) []api.FQN {
+ if set, found := o.idToInterfaces[instanceID]; found {
+ interfaces := make([]api.FQN, 0, len(set))
+ for iface := range set {
+ interfaces = append(interfaces, api.FQN(iface))
+ }
+ return interfaces
+ } else {
+ return nil
+ }
+}
+
// GetObject attempts to retrieve the object value associated with the given
// instanceID. Returns the existing value and a boolean informing whether a
// value was associated with this instanceID or not.
@@ -110,6 +184,27 @@ func (o *ObjectStore) GetObject(instanceID string) (value reflect.Value, found b
return
}
+// GetObjectAs attempts to retrieve the object value associated with the given
+// instanceID, compatible with the given type. Returns the existing value and a
+// boolean informing whether a value was associated with this instanceID and
+// compatible with this type or not.
+//
+// The GetObjectAs method is safe to call with an instanceID that was never
+// registered with the ObjectStore.
+func (o *ObjectStore) GetObjectAs(instanceID string, typ reflect.Type) (value reflect.Value, found bool) {
+ found = false
+ if values, exists := o.idToObjects[instanceID]; exists {
+ for value = range values {
+ if value.Type().AssignableTo(typ) {
+ value = value.Convert(typ)
+ found = true
+ return
+ }
+ }
+ }
+ return
+}
+
// canonicalValue ensures the same reference is always considered for object
// identity (especially in maps), so that we don't get surprised by pointer to
// struct versus struct value versus opaque interface value, etc...
diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/registration.go b/packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/registration.go
index aab2ab3d9b..c1245762ca 100644
--- a/packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/registration.go
+++ b/packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/registration.go
@@ -96,7 +96,12 @@ func (t *TypeRegistry) RegisterInterface(fqn api.FQN, iface reflect.Type, overri
return fmt.Errorf("another type was already registered with %s: %v", fqn, existing)
}
+ if existing, exists := t.typeToInterfaceFQN[iface]; exists && existing != fqn {
+ return fmt.Errorf("anoter FQN was already registered with %v: %s", iface, existing)
+ }
+
t.fqnToType[fqn] = registeredType{iface, interfaceType}
+ t.typeToInterfaceFQN[iface] = fqn
t.proxyMakers[iface] = maker
// Skipping registration if there are no members, as this would have no use.
diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/typeregistry.go b/packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/typeregistry.go
index 50d969e25d..98af846ec3 100644
--- a/packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/typeregistry.go
+++ b/packages/@jsii/go-runtime/jsii-runtime-go/internal/typeregistry/typeregistry.go
@@ -26,6 +26,10 @@ type TypeRegistry struct {
// enum FQN (e.g. "jsii-calc.StringEnum")
typeToEnumFQN map[reflect.Type]api.FQN
+ // typeToInterfaceFQN maps Go interface type ("SomeInterface") to the
+ // corresponding jsii interface FQN (e.g: "jsii-calc.SomeInterface")
+ typeToInterfaceFQN map[reflect.Type]api.FQN
+
// structInfo maps registered struct types to all their fields.
structInfo map[reflect.Type]registeredStruct
@@ -39,14 +43,23 @@ type TypeRegistry struct {
// New creates a new type registry.
func New() *TypeRegistry {
- return &TypeRegistry{
- fqnToType: make(map[api.FQN]registeredType),
- fqnToEnumMember: make(map[string]interface{}),
- typeToEnumFQN: make(map[reflect.Type]api.FQN),
- structInfo: make(map[reflect.Type]registeredStruct),
- proxyMakers: make(map[reflect.Type]func() interface{}),
- typeMembers: make(map[api.FQN][]api.Override),
+ registry := TypeRegistry{
+ fqnToType: make(map[api.FQN]registeredType),
+ fqnToEnumMember: make(map[string]interface{}),
+ typeToEnumFQN: make(map[reflect.Type]api.FQN),
+ typeToInterfaceFQN: make(map[reflect.Type]api.FQN),
+ structInfo: make(map[reflect.Type]registeredStruct),
+ proxyMakers: make(map[reflect.Type]func() interface{}),
+ typeMembers: make(map[api.FQN][]api.Override),
+ }
+
+ // Ensure we can initialize proxies for `interface{}` when a method returns `any`.
+ registry.proxyMakers[reflect.TypeOf((*interface{})(nil)).Elem()] = func() interface{} {
+ type object struct{ _ int } // Padded so it's not 0-sized
+ return &object{}
}
+
+ return ®istry
}
// StructFields returns the list of fields associated with a jsii struct type,
@@ -76,9 +89,7 @@ func (t *TypeRegistry) FindType(fqn api.FQN) (typ reflect.Type, ok bool) {
// InitJsiiProxy initializes a jsii proxy value at the provided pointer. It
// returns an error if the pointer does not have a value of a registered
// proxyable type (that is, a class or interface type).
-func (t *TypeRegistry) InitJsiiProxy(val reflect.Value) error {
- valType := val.Type()
-
+func (t *TypeRegistry) InitJsiiProxy(val reflect.Value, valType reflect.Type) error {
switch valType.Kind() {
case reflect.Interface:
if maker, ok := t.proxyMakers[valType]; ok {
@@ -102,7 +113,7 @@ func (t *TypeRegistry) InitJsiiProxy(val reflect.Value) error {
if !field.Anonymous {
return fmt.Errorf("refusing to initialize non-anonymous field %s of %v", field.Name, val)
}
- if err := t.InitJsiiProxy(val.Field(i)); err != nil {
+ if err := t.InitJsiiProxy(val.Field(i), field.Type); err != nil {
return err
}
}
@@ -146,3 +157,8 @@ func (t *TypeRegistry) TryRenderEnumRef(value reflect.Value) (ref *api.EnumRef,
return
}
+
+func (t *TypeRegistry) InterfaceFQN(typ reflect.Type) (fqn api.FQN, found bool) {
+ fqn, found = t.typeToInterfaceFQN[typ]
+ return
+}
diff --git a/packages/@jsii/go-runtime/jsii-runtime-go/runtime/runtime.go b/packages/@jsii/go-runtime/jsii-runtime-go/runtime/runtime.go
index 94ef2c2ba2..00878c4ccd 100644
--- a/packages/@jsii/go-runtime/jsii-runtime-go/runtime/runtime.go
+++ b/packages/@jsii/go-runtime/jsii-runtime-go/runtime/runtime.go
@@ -2,10 +2,11 @@ package runtime
import (
"fmt"
- "github.com/aws/jsii-runtime-go/internal/api"
- "github.com/aws/jsii-runtime-go/internal/kernel"
"reflect"
"strings"
+
+ "github.com/aws/jsii-runtime-go/internal/api"
+ "github.com/aws/jsii-runtime-go/internal/kernel"
)
// FQN represents a fully-qualified type name in the jsii type system.
@@ -101,7 +102,7 @@ func RegisterStruct(fqn FQN, strct reflect.Type) {
// element of it is not a registered jsii interface or class type).
func InitJsiiProxy(ptr interface{}) {
ptrVal := reflect.ValueOf(ptr).Elem()
- if err := kernel.GetClient().Types().InitJsiiProxy(ptrVal); err != nil {
+ if err := kernel.GetClient().Types().InitJsiiProxy(ptrVal, ptrVal.Type()); err != nil {
panic(err)
}
}
@@ -126,7 +127,7 @@ func Create(fqn FQN, args []interface{}, inst interface{}) {
if !fieldVal.IsNil() {
continue
}
- if err := client.Types().InitJsiiProxy(fieldVal); err != nil {
+ if err := client.Types().InitJsiiProxy(fieldVal, fieldVal.Type()); err != nil {
panic(err)
}
@@ -135,7 +136,7 @@ func Create(fqn FQN, args []interface{}, inst interface{}) {
if !fieldVal.IsZero() {
continue
}
- if err := client.Types().InitJsiiProxy(fieldVal); err != nil {
+ if err := client.Types().InitJsiiProxy(fieldVal, fieldVal.Type()); err != nil {
panic(err)
}
}
@@ -185,7 +186,7 @@ func Create(fqn FQN, args []interface{}, inst interface{}) {
panic(err)
}
- if err = client.RegisterInstance(instVal, res.InstanceID); err != nil {
+ if err = client.RegisterInstance(instVal, api.ObjectRef{InstanceID: res.InstanceID, Interfaces: interfaces}); err != nil {
panic(err)
}
}
@@ -196,7 +197,7 @@ func Invoke(obj interface{}, method string, args []interface{}, ret interface{})
client := kernel.GetClient()
// Find reference to class instance in client
- refid, found := client.FindObjectRef(reflect.ValueOf(obj))
+ ref, found := client.FindObjectRef(reflect.ValueOf(obj))
if !found {
panic("No Object Found")
@@ -205,9 +206,7 @@ func Invoke(obj interface{}, method string, args []interface{}, ret interface{})
res, err := client.Invoke(kernel.InvokeProps{
Method: method,
Arguments: convertArguments(args),
- ObjRef: api.ObjectRef{
- InstanceID: refid,
- },
+ ObjRef: ref,
})
if err != nil {
@@ -222,7 +221,7 @@ func InvokeVoid(obj interface{}, method string, args []interface{}) {
client := kernel.GetClient()
// Find reference to class instance in client
- refid, found := client.FindObjectRef(reflect.ValueOf(obj))
+ ref, found := client.FindObjectRef(reflect.ValueOf(obj))
if !found {
panic("No Object Found")
@@ -231,7 +230,7 @@ func InvokeVoid(obj interface{}, method string, args []interface{}) {
_, err := client.Invoke(kernel.InvokeProps{
Method: method,
Arguments: convertArguments(args),
- ObjRef: api.ObjectRef{InstanceID: refid},
+ ObjRef: ref,
})
if err != nil {
@@ -278,7 +277,7 @@ func Get(obj interface{}, property string, ret interface{}) {
client := kernel.GetClient()
// Find reference to class instance in client
- refid, found := client.FindObjectRef(reflect.ValueOf(obj))
+ ref, found := client.FindObjectRef(reflect.ValueOf(obj))
if !found {
panic(fmt.Errorf("no object reference found for %v", obj))
@@ -286,9 +285,7 @@ func Get(obj interface{}, property string, ret interface{}) {
res, err := client.Get(kernel.GetProps{
Property: property,
- ObjRef: api.ObjectRef{
- InstanceID: refid,
- },
+ ObjRef: ref,
})
if err != nil {
@@ -321,7 +318,7 @@ func Set(obj interface{}, property string, value interface{}) {
client := kernel.GetClient()
// Find reference to class instance in client
- refid, found := client.FindObjectRef(reflect.ValueOf(obj))
+ ref, found := client.FindObjectRef(reflect.ValueOf(obj))
if !found {
panic("No Object Found")
@@ -330,9 +327,7 @@ func Set(obj interface{}, property string, value interface{}) {
_, err := client.Set(kernel.SetProps{
Property: property,
Value: client.CastPtrToRef(reflect.ValueOf(value)),
- ObjRef: api.ObjectRef{
- InstanceID: refid,
- },
+ ObjRef: ref,
})
if err != nil {
diff --git a/packages/@jsii/go-runtime/package.json b/packages/@jsii/go-runtime/package.json
index 210c9cb84b..cc3c38ca84 100644
--- a/packages/@jsii/go-runtime/package.json
+++ b/packages/@jsii/go-runtime/package.json
@@ -24,9 +24,9 @@
},
"devDependencies": {
"@types/fs-extra": "^9.0.13",
- "@types/node": "^12.20.39",
+ "@types/node": "^12.20.43",
"codemaker": "^0.0.0",
- "eslint": "^8.5.0",
+ "eslint": "^8.8.0",
"fs-extra": "^9.1.0",
"jsii-build-tools": "^0.0.0",
"jsii-calc": "^3.20.120",
diff --git a/packages/@jsii/integ-test/package.json b/packages/@jsii/integ-test/package.json
index c16d5a23cb..6531bc4071 100644
--- a/packages/@jsii/integ-test/package.json
+++ b/packages/@jsii/integ-test/package.json
@@ -20,7 +20,7 @@
"@octokit/rest": "^18.12.0",
"dotenv": "^8.6.0",
"fs-extra": "^9.1.0",
- "jest": "^27.4.5",
+ "jest": "^27.4.7",
"jsii": "^0.0.0",
"jsii-pacmak": "^0.0.0",
"jsii-rosetta": "^0.0.0",
@@ -29,10 +29,10 @@
"devDependencies": {
"@types/dotenv": "^8.2.0",
"@types/fs-extra": "^9.0.13",
- "@types/jest": "^27.0.3",
- "@types/node": "^12.20.39",
+ "@types/jest": "^27.4.0",
+ "@types/node": "^12.20.43",
"@types/tar": "^6.1.1",
- "eslint": "^8.5.0",
+ "eslint": "^8.8.0",
"prettier": "^2.5.1",
"typescript": "~3.9.10"
}
diff --git a/packages/@jsii/java-runtime/package.json b/packages/@jsii/java-runtime/package.json
index c5d61198e4..9739c5b49e 100644
--- a/packages/@jsii/java-runtime/package.json
+++ b/packages/@jsii/java-runtime/package.json
@@ -33,7 +33,7 @@
},
"devDependencies": {
"@jsii/runtime": "^0.0.0",
- "@types/node": "^12.20.39",
+ "@types/node": "^12.20.43",
"jsii-build-tools": "^0.0.0",
"typescript": "~3.9.10"
}
diff --git a/packages/@jsii/kernel/lib/api.ts b/packages/@jsii/kernel/lib/api.ts
index 44b9cb488a..b339a4716b 100644
--- a/packages/@jsii/kernel/lib/api.ts
+++ b/packages/@jsii/kernel/lib/api.ts
@@ -7,9 +7,6 @@ export const TOKEN_STRUCT = '$jsii.struct';
export interface ObjRef {
readonly [TOKEN_REF]: string;
-}
-
-export interface AnnotatedObjRef extends ObjRef {
[TOKEN_INTERFACES]?: readonly string[];
}
@@ -138,8 +135,7 @@ export interface CreateRequest {
readonly overrides?: Override[];
}
-// eslint-disable-next-line @typescript-eslint/no-empty-interface
-export interface CreateResponse extends AnnotatedObjRef {}
+export type CreateResponse = ObjRef;
export interface DelRequest {
readonly objref: ObjRef;
diff --git a/packages/@jsii/kernel/lib/kernel.ts b/packages/@jsii/kernel/lib/kernel.ts
index d6f5f220d8..de6518ec5b 100644
--- a/packages/@jsii/kernel/lib/kernel.ts
+++ b/packages/@jsii/kernel/lib/kernel.ts
@@ -965,7 +965,7 @@ export class Kernel {
interfaces: string[] = [],
): spec.Method | undefined {
for (const fqn of [classFqn, ...interfaces]) {
- if (fqn === 'Object') {
+ if (fqn === wire.EMPTY_OBJECT_FQN) {
continue;
}
const typeinfo = this._typeInfoForFqn(fqn);
diff --git a/packages/@jsii/kernel/lib/objects.ts b/packages/@jsii/kernel/lib/objects.ts
index 305d93ccb3..a72ee20d4b 100644
--- a/packages/@jsii/kernel/lib/objects.ts
+++ b/packages/@jsii/kernel/lib/objects.ts
@@ -34,7 +34,7 @@ export function jsiiTypeFqn(obj: any): string | undefined {
*
* This is to retain object identity across invocations.
*/
-export function objectReference(obj: unknown): api.AnnotatedObjRef | undefined {
+export function objectReference(obj: unknown): api.ObjRef | undefined {
// If this object as already returned
if ((obj as any)[OBJID_SYMBOL]) {
return {
@@ -52,9 +52,35 @@ type ManagedObject = {
};
function tagObject(obj: unknown, objid: string, interfaces?: string[]) {
- const managed = obj as ManagedObject;
- managed[OBJID_SYMBOL] = objid;
- managed[IFACES_SYMBOL] = interfaces;
+ const privateField: Omit = {
+ // Make sure the field does not show in `JSON.stringify` outputs, and is not
+ // copied by splat expressions (`{...obj}`), as this would be problematic.
+ // See https://github.com/aws/aws-cdk/issues/17876 for an example of the
+ // consequences this could have.
+ enumerable: false,
+ // Probably not necessary, but allow the property to be re-configured (it
+ // would be good to make this `false` in the future, but might cause weird
+ // bugs, so not doing it now...)
+ configurable: true,
+ writable: true,
+ };
+
+ // Log a warning in case we are re-tagging this value, so we can hopefully
+ // discover about the bugs we'd have if we did not make it configurable nor
+ // writable.
+ if (Object.prototype.hasOwnProperty.call(obj, OBJID_SYMBOL)) {
+ console.error(
+ `[jsii/kernel] WARNING: object ${JSON.stringify(
+ obj as any,
+ )} was already tagged as ${(obj as any)[OBJID_SYMBOL]}!`,
+ );
+ }
+
+ Object.defineProperty(obj, OBJID_SYMBOL, { ...privateField, value: objid });
+ Object.defineProperty(obj, IFACES_SYMBOL, {
+ ...privateField,
+ value: interfaces,
+ });
}
/**
@@ -92,7 +118,7 @@ export class ObjectTable {
obj: unknown,
fqn: string,
interfaces?: string[],
- ): api.AnnotatedObjRef {
+ ): api.ObjRef {
if (fqn === undefined) {
throw new Error('FQN cannot be undefined');
}
@@ -104,6 +130,16 @@ export class ObjectTable {
for (const iface of existingRef[api.TOKEN_INTERFACES] ?? []) {
allIfaces.add(iface);
}
+ // Note - obj[INTERFACES_SYMBOL] should already have been declared as a
+ // private property by a previous call to tagObject at this stage.
+ if (!Object.prototype.hasOwnProperty.call(obj, IFACES_SYMBOL)) {
+ console.error(
+ `[jsii/kernel] WARNING: referenced object ${
+ existingRef[api.TOKEN_REF]
+ } does not have the ${String(IFACES_SYMBOL)} property!`,
+ );
+ }
+
this.objects[existingRef[api.TOKEN_REF]].interfaces =
(obj as any)[IFACES_SYMBOL] =
existingRef[api.TOKEN_INTERFACES] =
@@ -135,6 +171,26 @@ export class ObjectTable {
if (!obj) {
throw new Error(`Object ${objid} not found`);
}
+
+ // If there are "additional" interfaces declared on the objref, merge them
+ // into the returned object. This is used to support client-side forced
+ // down-casting (a.k.a: unsafe casting). We do NOT register the extra
+ // interfaces here so that if the client provided an interface that is
+ // actually not implemented, we aren't "poisoning" our state with that
+ // incorrect information.
+ const additionalInterfaces = objref[api.TOKEN_INTERFACES];
+ if (additionalInterfaces != null && additionalInterfaces.length > 0) {
+ return {
+ ...obj,
+ interfaces: [
+ ...(obj.interfaces ?? []),
+ // We append at the end so "registered" interface information has
+ // precedence over client-declared ones.
+ ...additionalInterfaces,
+ ],
+ };
+ }
+
return obj;
}
diff --git a/packages/@jsii/kernel/lib/serialization.ts b/packages/@jsii/kernel/lib/serialization.ts
index c1295613d6..caec15fdc0 100644
--- a/packages/@jsii/kernel/lib/serialization.ts
+++ b/packages/@jsii/kernel/lib/serialization.ts
@@ -420,7 +420,7 @@ export const SERIALIZERS: { [k: string]: Serializer } = {
*/
host.debug('Returning value type by reference');
- return host.objects.registerObject(value, 'Object', [
+ return host.objects.registerObject(value, EMPTY_OBJECT_FQN, [
(optionalValue.type as spec.NamedTypeReference).fqn,
]);
},
@@ -520,7 +520,7 @@ export const SERIALIZERS: { [k: string]: Serializer } = {
: undefined;
const jsiiType =
jsiiTypeFqn(value) ??
- (spec.isClassType(expectedType) ? expectedType.fqn : 'Object');
+ (spec.isClassType(expectedType) ? expectedType.fqn : EMPTY_OBJECT_FQN);
return host.objects.registerObject(value, jsiiType, interfaces);
},
diff --git a/packages/@jsii/kernel/package.json b/packages/@jsii/kernel/package.json
index 45df2bb1f7..8188dbba33 100644
--- a/packages/@jsii/kernel/package.json
+++ b/packages/@jsii/kernel/package.json
@@ -39,16 +39,16 @@
"@scope/jsii-calc-base": "^0.0.0",
"@scope/jsii-calc-lib": "^0.0.0",
"@types/fs-extra": "^9.0.13",
- "@types/jest": "^27.0.3",
- "@types/node": "^12.20.39",
+ "@types/jest": "^27.4.0",
+ "@types/node": "^12.20.43",
"@types/tar": "^6.1.1",
- "eslint": "^8.5.0",
- "jest": "^27.4.5",
+ "eslint": "^8.8.0",
+ "jest": "^27.4.7",
"jest-expect-message": "^1.0.2",
"jsii-build-tools": "^0.0.0",
"jsii-calc": "^3.20.120",
"prettier": "^2.5.1",
- "ts-jest": "^27.1.2",
+ "ts-jest": "^27.1.3",
"typescript": "~3.9.10"
}
}
diff --git a/packages/@jsii/kernel/test/objects.test.ts b/packages/@jsii/kernel/test/objects.test.ts
new file mode 100644
index 0000000000..2d11966e1c
--- /dev/null
+++ b/packages/@jsii/kernel/test/objects.test.ts
@@ -0,0 +1,26 @@
+import { ObjectTable } from '../lib/objects';
+
+const mockResolve = jest.fn();
+
+test('can spread registered objects without consequences', () => {
+ const subject = new ObjectTable(mockResolve);
+
+ const obj = { foo: 'bar', baz: 1337 };
+ const objRef = subject.registerObject(obj, 'Object');
+
+ const copy = { ...obj, foo: undefined, baz: undefined };
+ const copyRef = subject.registerObject(copy, 'Object');
+
+ expect(objRef).not.toEqual(copyRef);
+});
+
+test('registered objects have clean JSON.Stringify', () => {
+ const subject = new ObjectTable(mockResolve);
+
+ const obj = { foo: 'bar', baz: 1337 };
+ const expected = JSON.stringify(obj);
+
+ subject.registerObject(obj, 'Object');
+
+ expect(JSON.stringify(obj)).toEqual(expected);
+});
diff --git a/packages/@jsii/python-runtime/requirements.txt b/packages/@jsii/python-runtime/requirements.txt
index 1f0bcade04..23f655542c 100644
--- a/packages/@jsii/python-runtime/requirements.txt
+++ b/packages/@jsii/python-runtime/requirements.txt
@@ -1,8 +1,9 @@
-black~=21.12b0
+black~=22.1
mypy==0.812
-pip~=21.3
-pytest~=6.2
-pytest-mypy~=0.8
+pip~=21.3 ; python_version < '3.7'
+pip~=22.0 ; python_version >= '3.7'
+pytest~=7.0
+pytest-mypy~=0.9
setuptools~=59.6
wheel~=0.37
diff --git a/packages/@jsii/python-runtime/src/jsii/__init__.py b/packages/@jsii/python-runtime/src/jsii/__init__.py
index 108813ac3d..4d8e0c8f28 100644
--- a/packages/@jsii/python-runtime/src/jsii/__init__.py
+++ b/packages/@jsii/python-runtime/src/jsii/__init__.py
@@ -1,3 +1,4 @@
+import sys
from typing import Union
from .__meta__ import __version__, __jsii_runtime_version__
@@ -35,6 +36,15 @@
stats = kernel.stats
+if sys.version_info < (3, 7):
+ from platform import python_version
+ import warnings
+
+ warnings.warn(
+ f"WARNING: You are using python release {python_version()}, which has reached end-of-life! Support for EOL Python releases may be dropped in the future. Please consider upgrading to Python >= 3.7 as soon as possible.",
+ )
+
+
__all__ = [
"__version__",
"__jsii_runtime_version__",
diff --git a/packages/@jsii/python-runtime/src/jsii/_kernel/__init__.py b/packages/@jsii/python-runtime/src/jsii/_kernel/__init__.py
index 95959e7f62..0d41d13b28 100644
--- a/packages/@jsii/python-runtime/src/jsii/_kernel/__init__.py
+++ b/packages/@jsii/python-runtime/src/jsii/_kernel/__init__.py
@@ -169,7 +169,7 @@ def _make_reference_for_native(kernel, d):
from .._runtime import python_jsii_mapping
mapping = python_jsii_mapping(d)
- if mapping: # This means we are handling a data_type (aka Struct)
+ if mapping is not None: # This means we are handling a data_type (aka Struct)
return {
"$jsii.struct": {
"fqn": typeFqn,
diff --git a/packages/@jsii/python-runtime/tests/test_compliance.py b/packages/@jsii/python-runtime/tests/test_compliance.py
index 28f2ddf590..df52bfbe58 100644
--- a/packages/@jsii/python-runtime/tests/test_compliance.py
+++ b/packages/@jsii/python-runtime/tests/test_compliance.py
@@ -338,7 +338,7 @@ def test_getSetPrimitiveProperties():
assert number.double_value == 40
assert Negate(Add(Number(20), Number(10))).value == -30
assert Multiply(Add(Number(5), Number(5)), Number(2)).value == 20
- assert Power(Number(3), Number(4)).value == 3 ** 4
+ assert Power(Number(3), Number(4)).value == 3**4
assert Power(Number(999), Number(1)).value == 999
assert Power(Number(999), Number(0)).value == 1
@@ -353,7 +353,7 @@ def test_callMethods():
assert calc.value == 20
calc.pow(5)
- assert calc.value == 20 ** 5
+ assert calc.value == 20**5
calc.neg()
assert calc.value == -3_200_000
@@ -451,7 +451,7 @@ def test_unionProperties():
calc3.union_property = Power(Number(10), Number(3))
assert isinstance(calc3.union_property, Power)
- assert calc3.read_union_value() == 10 ** 3
+ assert calc3.read_union_value() == 10**3
def test_subclassing():
diff --git a/packages/@jsii/runtime/package.json b/packages/@jsii/runtime/package.json
index 55095f6ca5..252d001b26 100644
--- a/packages/@jsii/runtime/package.json
+++ b/packages/@jsii/runtime/package.json
@@ -41,17 +41,17 @@
"devDependencies": {
"@scope/jsii-calc-base": "^0.0.0",
"@scope/jsii-calc-lib": "^0.0.0",
- "@types/jest": "^27.0.3",
- "@types/node": "^12.20.39",
- "eslint": "^8.5.0",
- "jest": "^27.4.5",
+ "@types/jest": "^27.4.0",
+ "@types/node": "^12.20.43",
+ "eslint": "^8.8.0",
+ "jest": "^27.4.7",
"jsii-build-tools": "^0.0.0",
"jsii-calc": "^3.20.120",
"prettier": "^2.5.1",
- "source-map-loader": "^3.0.0",
- "ts-jest": "^27.1.2",
+ "source-map-loader": "^3.0.1",
+ "ts-jest": "^27.1.3",
"typescript": "~3.9.10",
- "webpack": "^5.65.0",
- "webpack-cli": "^4.9.1"
+ "webpack": "^5.68.0",
+ "webpack-cli": "^4.9.2"
}
}
diff --git a/packages/@jsii/spec/lib/configuration.ts b/packages/@jsii/spec/lib/configuration.ts
index ca5e9fffec..16355fea82 100644
--- a/packages/@jsii/spec/lib/configuration.ts
+++ b/packages/@jsii/spec/lib/configuration.ts
@@ -171,5 +171,9 @@ export interface PackageJson {
*/
devDependencies?: Record;
+ bundleDependencies?: string[];
+
+ bundledDependencies?: string[];
+
[key: string]: unknown;
}
diff --git a/packages/@jsii/spec/package.json b/packages/@jsii/spec/package.json
index 3347248ef9..3eaacc3c70 100644
--- a/packages/@jsii/spec/package.json
+++ b/packages/@jsii/spec/package.json
@@ -34,13 +34,13 @@
"jsonschema": "^1.4.0"
},
"devDependencies": {
- "@types/jest": "^27.0.3",
- "@types/node": "^12.20.39",
- "eslint": "^8.5.0",
- "jest": "^27.4.5",
+ "@types/jest": "^27.4.0",
+ "@types/node": "^12.20.43",
+ "eslint": "^8.8.0",
+ "jest": "^27.4.7",
"jsii-build-tools": "^0.0.0",
"prettier": "^2.5.1",
"typescript": "~3.9.10",
- "typescript-json-schema": "^0.52.0"
+ "typescript-json-schema": "^0.53.0"
}
}
diff --git a/packages/@scope/jsii-calc-base-of-base/package.json b/packages/@scope/jsii-calc-base-of-base/package.json
index ac98f4d102..edd5ec374e 100644
--- a/packages/@scope/jsii-calc-base-of-base/package.json
+++ b/packages/@scope/jsii-calc-base-of-base/package.json
@@ -30,7 +30,7 @@
"test:update": "npm run build && UPDATE_DIFF=1 npm run test"
},
"devDependencies": {
- "@types/node": "^12.20.39",
+ "@types/node": "^12.20.43",
"jsii": "^0.0.0",
"jsii-build-tools": "^0.0.0",
"jsii-rosetta": "^0.0.0",
diff --git a/packages/@scope/jsii-calc-base/package.json b/packages/@scope/jsii-calc-base/package.json
index ed0747078d..3df53b4a32 100644
--- a/packages/@scope/jsii-calc-base/package.json
+++ b/packages/@scope/jsii-calc-base/package.json
@@ -35,7 +35,7 @@
"@scope/jsii-calc-base-of-base": "^2.1.1"
},
"devDependencies": {
- "@types/node": "^12.20.39",
+ "@types/node": "^12.20.43",
"jsii": "^0.0.0",
"jsii-build-tools": "^0.0.0",
"jsii-rosetta": "^0.0.0",
diff --git a/packages/@scope/jsii-calc-lib/package.json b/packages/@scope/jsii-calc-lib/package.json
index 0134988c7c..9a8f0b0423 100644
--- a/packages/@scope/jsii-calc-lib/package.json
+++ b/packages/@scope/jsii-calc-lib/package.json
@@ -39,7 +39,7 @@
"@scope/jsii-calc-base-of-base": "^2.1.1"
},
"devDependencies": {
- "@types/node": "^12.20.39",
+ "@types/node": "^12.20.43",
"jsii": "^0.0.0",
"jsii-build-tools": "^0.0.0",
"jsii-rosetta": "^0.0.0",
diff --git a/packages/codemaker/package.json b/packages/codemaker/package.json
index dd1865963a..ec665fbbc6 100644
--- a/packages/codemaker/package.json
+++ b/packages/codemaker/package.json
@@ -31,16 +31,16 @@
"package": "rm -fr dist/js && mkdir -p dist/js && mv $(npm pack) dist/js"
},
"dependencies": {
- "camelcase": "^6.2.1",
+ "camelcase": "^6.3.0",
"decamelize": "^5.0.1",
"fs-extra": "^9.1.0"
},
"devDependencies": {
"@types/fs-extra": "^9.0.13",
- "@types/jest": "^27.0.3",
- "@types/node": "^12.20.39",
- "eslint": "^8.5.0",
- "jest": "^27.4.5",
+ "@types/jest": "^27.4.0",
+ "@types/node": "^12.20.43",
+ "eslint": "^8.8.0",
+ "jest": "^27.4.7",
"prettier": "^2.5.1",
"typescript": "~3.9.10"
}
diff --git a/packages/jsii-calc/lib/index.ts b/packages/jsii-calc/lib/index.ts
index 397ce7a103..663b1aa0b8 100644
--- a/packages/jsii-calc/lib/index.ts
+++ b/packages/jsii-calc/lib/index.ts
@@ -8,6 +8,7 @@ export * from './nested-class';
export * from './stability';
export * from './submodules';
export * from './container-types';
+export * from './indirect-implementation';
export * as submodule from './submodule';
export * as onlystatic from './only-static';
diff --git a/packages/jsii-calc/lib/indirect-implementation.ts b/packages/jsii-calc/lib/indirect-implementation.ts
new file mode 100644
index 0000000000..e8ed2b4948
--- /dev/null
+++ b/packages/jsii-calc/lib/indirect-implementation.ts
@@ -0,0 +1,22 @@
+export interface IIndirectlyImplemented {
+ readonly property: string;
+ method(): number;
+}
+
+export abstract class BaseClass {
+ public readonly property = 'YES';
+
+ protected constructor() {}
+
+ public method(): number {
+ return 1337;
+ }
+}
+
+export class FullCombo extends BaseClass implements IIndirectlyImplemented {
+ private constructor() {
+ super();
+ }
+
+ // Obtains implementation of IIndirectlyImplemented from BaseClass
+}
diff --git a/packages/jsii-calc/package.json b/packages/jsii-calc/package.json
index 45c610370d..452e158d81 100644
--- a/packages/jsii-calc/package.json
+++ b/packages/jsii-calc/package.json
@@ -33,7 +33,7 @@
"main": "lib/index.js",
"types": "lib/index.d.ts",
"scripts": {
- "build": "jsii --project-references --silence-warnings reserved-word && npm run lint && jsii-rosetta --compile",
+ "build": "jsii --project-references --silence-warnings reserved-word && npm run lint && jsii-rosetta --compile --verbose",
"watch": "jsii --project-references -w",
"lint": "eslint . --ext .js,.ts --ignore-path=.gitignore",
"lint:fix": "yarn lint --fix",
@@ -51,8 +51,8 @@
"@scope/jsii-calc-lib": "^0.0.0"
},
"devDependencies": {
- "@types/node": "^12.20.39",
- "eslint": "^8.5.0",
+ "@types/node": "^12.20.43",
+ "eslint": "^8.8.0",
"jsii": "^0.0.0",
"jsii-build-tools": "^0.0.0",
"jsii-rosetta": "^0.0.0",
diff --git a/packages/jsii-calc/test/assembly.jsii b/packages/jsii-calc/test/assembly.jsii
index 213c90a2fd..fa9482fec6 100644
--- a/packages/jsii-calc/test/assembly.jsii
+++ b/packages/jsii-calc/test/assembly.jsii
@@ -208,7 +208,7 @@
"jsii-calc.cdk16625": {
"locationInModule": {
"filename": "lib/index.ts",
- "line": 23
+ "line": 24
},
"symbolId": "lib/cdk16625/index:"
},
@@ -229,28 +229,28 @@
"jsii-calc.module2530": {
"locationInModule": {
"filename": "lib/index.ts",
- "line": 20
+ "line": 21
},
"symbolId": "lib/module2530/index:"
},
"jsii-calc.module2617": {
"locationInModule": {
"filename": "lib/index.ts",
- "line": 16
+ "line": 17
},
"symbolId": "lib/module2617/index:"
},
"jsii-calc.module2647": {
"locationInModule": {
"filename": "lib/index.ts",
- "line": 15
+ "line": 16
},
"symbolId": "lib/module2647/index:"
},
"jsii-calc.module2689": {
"locationInModule": {
"filename": "lib/index.ts",
- "line": 17
+ "line": 18
},
"symbolId": "lib/module2689/index:"
},
@@ -285,7 +285,7 @@
"jsii-calc.module2692": {
"locationInModule": {
"filename": "lib/index.ts",
- "line": 19
+ "line": 20
},
"symbolId": "lib/module2692/index:"
},
@@ -306,21 +306,21 @@
"jsii-calc.module2700": {
"locationInModule": {
"filename": "lib/index.ts",
- "line": 21
+ "line": 22
},
"symbolId": "lib/module2700/index:"
},
"jsii-calc.module2702": {
"locationInModule": {
"filename": "lib/index.ts",
- "line": 18
+ "line": 19
},
"symbolId": "lib/module2702/index:"
},
"jsii-calc.nodirect": {
"locationInModule": {
"filename": "lib/index.ts",
- "line": 14
+ "line": 15
},
"symbolId": "lib/no-direct-types/index:"
},
@@ -341,14 +341,14 @@
"jsii-calc.onlystatic": {
"locationInModule": {
"filename": "lib/index.ts",
- "line": 13
+ "line": 14
},
"symbolId": "lib/only-static/index:"
},
"jsii-calc.submodule": {
"locationInModule": {
"filename": "lib/index.ts",
- "line": 12
+ "line": 13
},
"readme": {
"markdown": "Read you, read me\n=================\n\nThis is the readme of the `jsii-calc.submodule` module.\n"
@@ -761,7 +761,7 @@
{
"docs": {
"stability": "stable",
- "summary": "(deprecated) String representation of the value."
+ "summary": "String representation of the value."
},
"locationInModule": {
"filename": "lib/calculator.ts",
@@ -781,7 +781,7 @@
{
"docs": {
"stability": "stable",
- "summary": "(deprecated) The value."
+ "summary": "The value."
},
"immutable": true,
"locationInModule": {
@@ -1652,6 +1652,63 @@
"name": "AugmentableClass",
"symbolId": "lib/compliance:AugmentableClass"
},
+ "jsii-calc.BaseClass": {
+ "abstract": true,
+ "assembly": "jsii-calc",
+ "docs": {
+ "stability": "stable"
+ },
+ "fqn": "jsii-calc.BaseClass",
+ "initializer": {
+ "docs": {
+ "stability": "stable"
+ },
+ "locationInModule": {
+ "filename": "lib/indirect-implementation.ts",
+ "line": 9
+ }
+ },
+ "kind": "class",
+ "locationInModule": {
+ "filename": "lib/indirect-implementation.ts",
+ "line": 6
+ },
+ "methods": [
+ {
+ "docs": {
+ "stability": "stable"
+ },
+ "locationInModule": {
+ "filename": "lib/indirect-implementation.ts",
+ "line": 11
+ },
+ "name": "method",
+ "returns": {
+ "type": {
+ "primitive": "number"
+ }
+ }
+ }
+ ],
+ "name": "BaseClass",
+ "properties": [
+ {
+ "docs": {
+ "stability": "stable"
+ },
+ "immutable": true,
+ "locationInModule": {
+ "filename": "lib/indirect-implementation.ts",
+ "line": 7
+ },
+ "name": "property",
+ "type": {
+ "primitive": "string"
+ }
+ }
+ ],
+ "symbolId": "lib/indirect-implementation:BaseClass"
+ },
"jsii-calc.BaseJsii976": {
"assembly": "jsii-calc",
"docs": {
@@ -1772,7 +1829,7 @@
{
"docs": {
"stability": "stable",
- "summary": "(deprecated) Say hello!"
+ "summary": "Say hello!"
},
"locationInModule": {
"filename": "lib/calculator.ts",
@@ -4764,7 +4821,7 @@
{
"docs": {
"stability": "stable",
- "summary": "(deprecated) Say hello!"
+ "summary": "Say hello!"
},
"locationInModule": {
"filename": "lib/compliance.ts",
@@ -5652,6 +5709,24 @@
],
"symbolId": "lib/stability:ExternalStruct"
},
+ "jsii-calc.FullCombo": {
+ "assembly": "jsii-calc",
+ "base": "jsii-calc.BaseClass",
+ "docs": {
+ "stability": "stable"
+ },
+ "fqn": "jsii-calc.FullCombo",
+ "interfaces": [
+ "jsii-calc.IIndirectlyImplemented"
+ ],
+ "kind": "class",
+ "locationInModule": {
+ "filename": "lib/indirect-implementation.ts",
+ "line": 16
+ },
+ "name": "FullCombo",
+ "symbolId": "lib/indirect-implementation:FullCombo"
+ },
"jsii-calc.GiveMeStructs": {
"assembly": "jsii-calc",
"docs": {
@@ -6335,6 +6410,55 @@
"name": "IFriendlyRandomGenerator",
"symbolId": "lib/calculator:IFriendlyRandomGenerator"
},
+ "jsii-calc.IIndirectlyImplemented": {
+ "assembly": "jsii-calc",
+ "docs": {
+ "stability": "stable"
+ },
+ "fqn": "jsii-calc.IIndirectlyImplemented",
+ "kind": "interface",
+ "locationInModule": {
+ "filename": "lib/indirect-implementation.ts",
+ "line": 1
+ },
+ "methods": [
+ {
+ "abstract": true,
+ "docs": {
+ "stability": "stable"
+ },
+ "locationInModule": {
+ "filename": "lib/indirect-implementation.ts",
+ "line": 3
+ },
+ "name": "method",
+ "returns": {
+ "type": {
+ "primitive": "number"
+ }
+ }
+ }
+ ],
+ "name": "IIndirectlyImplemented",
+ "properties": [
+ {
+ "abstract": true,
+ "docs": {
+ "stability": "stable"
+ },
+ "immutable": true,
+ "locationInModule": {
+ "filename": "lib/indirect-implementation.ts",
+ "line": 2
+ },
+ "name": "property",
+ "type": {
+ "primitive": "string"
+ }
+ }
+ ],
+ "symbolId": "lib/indirect-implementation:IIndirectlyImplemented"
+ },
"jsii-calc.IInterfaceImplementedByAbstractClass": {
"assembly": "jsii-calc",
"docs": {
@@ -9364,7 +9488,7 @@
{
"docs": {
"stability": "stable",
- "summary": "(deprecated) String representation of the value."
+ "summary": "String representation of the value."
},
"locationInModule": {
"filename": "lib/calculator.ts",
@@ -9384,7 +9508,7 @@
{
"docs": {
"stability": "stable",
- "summary": "(deprecated) The value."
+ "summary": "The value."
},
"immutable": true,
"locationInModule": {
@@ -9471,7 +9595,7 @@
{
"docs": {
"stability": "stable",
- "summary": "(deprecated) Say hello!"
+ "summary": "Say hello!"
},
"locationInModule": {
"filename": "lib/calculator.ts",
@@ -9488,7 +9612,7 @@
{
"docs": {
"stability": "stable",
- "summary": "(deprecated) String representation of the value."
+ "summary": "String representation of the value."
},
"locationInModule": {
"filename": "lib/calculator.ts",
@@ -9508,7 +9632,7 @@
{
"docs": {
"stability": "stable",
- "summary": "(deprecated) The value."
+ "summary": "The value."
},
"immutable": true,
"locationInModule": {
@@ -14787,7 +14911,7 @@
{
"docs": {
"stability": "stable",
- "summary": "(deprecated) String representation of the value."
+ "summary": "String representation of the value."
},
"locationInModule": {
"filename": "lib/calculator.ts",
@@ -14825,7 +14949,7 @@
{
"docs": {
"stability": "stable",
- "summary": "(deprecated) The value."
+ "summary": "The value."
},
"immutable": true,
"locationInModule": {
@@ -15075,7 +15199,7 @@
{
"docs": {
"stability": "stable",
- "summary": "(deprecated) Say hello!"
+ "summary": "Say hello!"
},
"locationInModule": {
"filename": "lib/module2647/index.ts",
@@ -16807,5 +16931,5 @@
}
},
"version": "3.20.120",
- "fingerprint": "w6AJ35Nh9lBusQyMGP28WJp5MNbg527uO9TsHaP+DiE="
+ "fingerprint": "sqJBfFAp4Hg5OgntWB3IRyRS7mpPF7G3qoh4NYSDeSw="
}
diff --git a/packages/jsii-config/package.json b/packages/jsii-config/package.json
index 19e2fd15ef..96cef65cfb 100644
--- a/packages/jsii-config/package.json
+++ b/packages/jsii-config/package.json
@@ -19,12 +19,12 @@
"jsii-config": "bin/jsii-config"
},
"devDependencies": {
- "@types/inquirer": "^8.1.3",
- "@types/jest": "^27.0.3",
- "@types/node": "^12.20.39",
+ "@types/inquirer": "^8.2.0",
+ "@types/jest": "^27.4.0",
+ "@types/node": "^12.20.43",
"@types/yargs": "^17.0.8",
- "eslint": "^8.5.0",
- "jest": "^27.4.5",
+ "eslint": "^8.8.0",
+ "jest": "^27.4.7",
"jest-expect-message": "^1.0.2",
"prettier": "^2.5.1",
"typescript": "~3.9.10"
diff --git a/packages/jsii-diff/package.json b/packages/jsii-diff/package.json
index 728bc74242..6bf7233948 100644
--- a/packages/jsii-diff/package.json
+++ b/packages/jsii-diff/package.json
@@ -37,17 +37,17 @@
"@jsii/spec": "^0.0.0",
"fs-extra": "^9.1.0",
"jsii-reflect": "^0.0.0",
- "log4js": "^6.3.0",
+ "log4js": "^6.4.1",
"typescript": "~3.9.10",
"yargs": "^16.2.0"
},
"devDependencies": {
"@types/fs-extra": "^9.0.13",
- "@types/jest": "^27.0.3",
- "@types/node": "^12.20.39",
+ "@types/jest": "^27.4.0",
+ "@types/node": "^12.20.43",
"@types/tar-fs": "^2.0.1",
- "eslint": "^8.5.0",
- "jest": "^27.4.5",
+ "eslint": "^8.8.0",
+ "jest": "^27.4.7",
"jest-expect-message": "^1.0.2",
"jsii": "^0.0.0",
"jsii-build-tools": "^0.0.0",
diff --git a/packages/jsii-pacmak/lib/targets/dotnet/dotnetgenerator.ts b/packages/jsii-pacmak/lib/targets/dotnet/dotnetgenerator.ts
index fa15aa74ed..b781fa6551 100644
--- a/packages/jsii-pacmak/lib/targets/dotnet/dotnetgenerator.ts
+++ b/packages/jsii-pacmak/lib/targets/dotnet/dotnetgenerator.ts
@@ -942,7 +942,7 @@ export class DotNetGenerator extends Generator {
if (prop.optional) {
this.code.line('[JsiiOptional]');
}
- this.dotnetRuntimeGenerator.emitAttributesForProperty(prop, datatype);
+ this.dotnetRuntimeGenerator.emitAttributesForProperty(prop);
let isOverrideKeyWord = '';
let isVirtualKeyWord = '';
diff --git a/packages/jsii-pacmak/lib/targets/dotnet/dotnetruntimegenerator.ts b/packages/jsii-pacmak/lib/targets/dotnet/dotnetruntimegenerator.ts
index df0e5244c1..ce16482130 100644
--- a/packages/jsii-pacmak/lib/targets/dotnet/dotnetruntimegenerator.ts
+++ b/packages/jsii-pacmak/lib/targets/dotnet/dotnetruntimegenerator.ts
@@ -78,8 +78,6 @@ export class DotNetRuntimeGenerator {
cls: spec.ClassType | spec.InterfaceType,
method: spec.Method /*, emitForProxyOrDatatype: boolean = false*/,
): void {
- const isOverride =
- spec.isClassType(cls) && method.overrides ? ', isOverride: true' : '';
const isAsync =
spec.isClassType(cls) && method.async ? ', isAsync: true' : '';
const parametersJson = method.parameters
@@ -92,7 +90,7 @@ export class DotNetRuntimeGenerator {
.replace(/"/g, '\\"')
.replace(/\\{2}"/g, 'test')}"`
: '';
- const jsiiAttribute = `[JsiiMethod(name: "${method.name}"${returnsJson}${parametersJson}${isAsync}${isOverride})]`;
+ const jsiiAttribute = `[JsiiMethod(name: "${method.name}"${returnsJson}${parametersJson}${isAsync})]`;
this.code.line(jsiiAttribute);
this.emitDeprecatedAttributeIfNecessary(method);
}
@@ -100,20 +98,15 @@ export class DotNetRuntimeGenerator {
/**
* Emits the proper jsii .NET attribute for a property
*
- * Ex: [JsiiProperty(name: "foo", typeJson: "{\"fqn\":\"@scope/jsii-calc-base-of-base.Very\"}", isOptional: true, isOverride: true)]
+ * Ex: [JsiiProperty(name: "foo", typeJson: "{\"fqn\":\"@scope/jsii-calc-base-of-base.Very\"}", isOptional: true)]
*/
- public emitAttributesForProperty(
- prop: spec.Property,
- datatype = false,
- ): void {
- // If we are on a datatype then we want the property to override in Jsii
- const isJsiiOverride = datatype ? ', isOverride: true' : '';
+ public emitAttributesForProperty(prop: spec.Property): void {
const isOptionalJsii = prop.optional ? ', isOptional: true' : '';
const jsiiAttribute =
`[JsiiProperty(name: "${prop.name}", ` +
`typeJson: "${JSON.stringify(prop.type)
.replace(/"/g, '\\"')
- .replace(/\\{2}"/g, 'test')}"${isOptionalJsii}${isJsiiOverride})]`;
+ .replace(/\\{2}"/g, 'test')}"${isOptionalJsii})]`;
this.code.line(jsiiAttribute);
this.emitDeprecatedAttributeIfNecessary(prop);
}
diff --git a/packages/jsii-pacmak/lib/targets/go/package.ts b/packages/jsii-pacmak/lib/targets/go/package.ts
index 7cd7759a64..d5acbe5972 100644
--- a/packages/jsii-pacmak/lib/targets/go/package.ts
+++ b/packages/jsii-pacmak/lib/targets/go/package.ts
@@ -41,7 +41,7 @@ export abstract class Package {
public readonly submodules: InternalPackage[];
public readonly types: GoType[];
- private readonly embeddedTypes: { [fqn: string]: EmbeddedType } = {};
+ private readonly embeddedTypes = new Map();
public constructor(
private readonly typeSpec: readonly Type[],
@@ -158,7 +158,7 @@ export abstract class Package {
};
}
- const exists = this.embeddedTypes[type.fqn];
+ const exists = this.embeddedTypes.get(type.fqn);
if (exists) {
return exists;
}
@@ -169,14 +169,15 @@ export abstract class Package {
const slug = original.replace(/[^A-Za-z0-9]/g, '');
const aliasName = `Type__${slug}`;
- this.embeddedTypes[type.fqn] = {
+ const embeddedType: EmbeddedType = {
foriegnTypeName: original,
foriegnType: typeref,
fieldName: aliasName,
embed: `${INTERNAL_PACKAGE_NAME}.${aliasName}`,
};
+ this.embeddedTypes.set(type.fqn, embeddedType);
- return this.resolveEmbeddedType(type);
+ return embeddedType;
}
protected emitHeader(code: CodeMaker) {
@@ -272,9 +273,7 @@ export abstract class Package {
}
private emitInternal(context: EmitContext) {
- const aliases = Object.values(this.embeddedTypes);
-
- if (aliases.length === 0) {
+ if (this.embeddedTypes.size === 0) {
return;
}
@@ -287,7 +286,7 @@ export abstract class Package {
const imports = new Set();
- for (const alias of aliases) {
+ for (const alias of this.embeddedTypes.values()) {
if (!alias.foriegnType) {
continue;
}
@@ -303,7 +302,7 @@ export abstract class Package {
}
code.close(')');
- for (const alias of aliases) {
+ for (const alias of this.embeddedTypes.values()) {
code.line(`type ${alias.fieldName} = ${alias.foriegnTypeName}`);
}
@@ -322,7 +321,13 @@ export class RootPackage extends Package {
private readonly readme?: ReadmeFile;
private readonly versionFile: VersionFile;
- public constructor(assembly: Assembly) {
+ // This cache of root packages is shared across all root packages derived created by this one (via dependencies).
+ private readonly rootPackageCache: Map;
+
+ public constructor(
+ assembly: Assembly,
+ rootPackageCache = new Map(),
+ ) {
const goConfig = assembly.targets?.go ?? {};
const packageName = goPackageNameForAssembly(assembly);
const filePath = '';
@@ -338,6 +343,9 @@ export class RootPackage extends Package {
version,
);
+ this.rootPackageCache = rootPackageCache;
+ this.rootPackageCache.set(assembly.name, this);
+
this.assembly = assembly;
this.version = version;
this.versionFile = new VersionFile(this.version);
@@ -423,7 +431,9 @@ export class RootPackage extends Package {
*/
public get packageDependencies(): RootPackage[] {
return this.assembly.dependencies.map(
- (dep) => new RootPackage(dep.assembly),
+ (dep) =>
+ this.rootPackageCache.get(dep.assembly.name) ??
+ new RootPackage(dep.assembly, this.rootPackageCache),
);
}
diff --git a/packages/jsii-pacmak/lib/targets/go/runtime/emit-arguments.ts b/packages/jsii-pacmak/lib/targets/go/runtime/emit-arguments.ts
index a83e0e8b24..7a88e05d28 100644
--- a/packages/jsii-pacmak/lib/targets/go/runtime/emit-arguments.ts
+++ b/packages/jsii-pacmak/lib/targets/go/runtime/emit-arguments.ts
@@ -19,7 +19,7 @@ export function emitArguments(
if (argsList.length === 0) {
return undefined;
}
- if (parameters[parameters.length - 1].parameter.variadic) {
+ if (parameters[parameters.length - 1].isVariadic) {
// For variadic methods, we must build up the []interface{} slice by hand,
// as there would not be any implicit conversion happening when passing
// the variadic argument as a splat to the append function...
diff --git a/packages/jsii-pacmak/lib/targets/go/types/class.ts b/packages/jsii-pacmak/lib/targets/go/types/class.ts
index 142bd1edd4..95c9371038 100644
--- a/packages/jsii-pacmak/lib/targets/go/types/class.ts
+++ b/packages/jsii-pacmak/lib/targets/go/types/class.ts
@@ -23,7 +23,7 @@ import { GoMethod, GoProperty, GoTypeMember } from './type-member';
/*
* GoClass wraps a Typescript class as a Go custom struct type
*/
-export class GoClass extends GoType {
+export class GoClass extends GoType {
public readonly methods: ClassMethod[];
public readonly staticMethods: StaticMethod[];
public readonly properties: GoProperty[];
@@ -34,7 +34,7 @@ export class GoClass extends GoType {
private readonly initializer?: GoClassConstructor;
- public constructor(pkg: Package, public type: ClassType) {
+ public constructor(pkg: Package, type: ClassType) {
super(pkg, type);
const methods = new Array();
diff --git a/packages/jsii-pacmak/lib/targets/go/types/enum.ts b/packages/jsii-pacmak/lib/targets/go/types/enum.ts
index ea5ff70c5a..d98dd058d1 100644
--- a/packages/jsii-pacmak/lib/targets/go/types/enum.ts
+++ b/packages/jsii-pacmak/lib/targets/go/types/enum.ts
@@ -7,10 +7,10 @@ import { Package } from '../package';
import { JSII_RT_ALIAS } from '../runtime';
import { GoType } from './go-type';
-export class Enum extends GoType {
+export class Enum extends GoType {
private readonly members: readonly GoEnumMember[];
- public constructor(pkg: Package, public type: EnumType) {
+ public constructor(pkg: Package, type: EnumType) {
super(pkg, type);
this.members = type.members.map((mem) => new GoEnumMember(this, mem));
diff --git a/packages/jsii-pacmak/lib/targets/go/types/go-type-reference.ts b/packages/jsii-pacmak/lib/targets/go/types/go-type-reference.ts
index 6f3d0c9dda..c163bd5109 100644
--- a/packages/jsii-pacmak/lib/targets/go/types/go-type-reference.ts
+++ b/packages/jsii-pacmak/lib/targets/go/types/go-type-reference.ts
@@ -47,6 +47,7 @@ type TypeMap =
*/
export class GoTypeRef {
private _typeMap?: TypeMap;
+
public constructor(
public readonly root: Package,
public readonly reference: TypeReference,
@@ -126,18 +127,18 @@ export class GoTypeRef {
switch (this.typeMap.type) {
case 'interface':
if (this.type?.pkg) {
- ret.push(this.type?.pkg);
+ ret.push(this.type.pkg);
}
break;
case 'array':
case 'map':
- ret.push(...(this.typeMap.value.dependencies ?? []));
+ ret.push(...this.typeMap.value.dependencies);
break;
case 'union':
for (const t of this.typeMap.value) {
- ret.push(...(t.dependencies ?? []));
+ ret.push(...t.dependencies);
}
break;
diff --git a/packages/jsii-pacmak/lib/targets/go/types/go-type.ts b/packages/jsii-pacmak/lib/targets/go/types/go-type.ts
index 7ccbe2f9c8..fc33aa968d 100644
--- a/packages/jsii-pacmak/lib/targets/go/types/go-type.ts
+++ b/packages/jsii-pacmak/lib/targets/go/types/go-type.ts
@@ -8,12 +8,12 @@ import { JSII_RT_ALIAS } from '../runtime';
import { GoClass } from './class';
import { GoInterface } from './interface';
-export abstract class GoType {
+export abstract class GoType {
public readonly name: string;
public readonly fqn: string;
public readonly proxyName: string;
- public constructor(public pkg: Package, public type: Type) {
+ public constructor(public readonly pkg: Package, public readonly type: T) {
this.name = type.name;
// Prefix with the nesting parent name(s), using an _ delimiter.
diff --git a/packages/jsii-pacmak/lib/targets/go/types/interface.ts b/packages/jsii-pacmak/lib/targets/go/types/interface.ts
index bd24c151d0..f2e6db9e52 100644
--- a/packages/jsii-pacmak/lib/targets/go/types/interface.ts
+++ b/packages/jsii-pacmak/lib/targets/go/types/interface.ts
@@ -11,13 +11,13 @@ import { GoType } from './go-type';
import { GoTypeRef } from './go-type-reference';
import { GoMethod, GoProperty } from './type-member';
-export class GoInterface extends GoType {
+export class GoInterface extends GoType {
public readonly methods: InterfaceMethod[];
public readonly reimplementedMethods?: readonly InterfaceMethod[];
public readonly properties: InterfaceProperty[];
public readonly reimplementedProperties?: readonly InterfaceProperty[];
- public constructor(pkg: Package, public type: InterfaceType) {
+ public constructor(pkg: Package, type: InterfaceType) {
super(pkg, type);
this.methods = type.ownMethods
@@ -191,8 +191,6 @@ export class GoInterface extends GoType {
}
class InterfaceProperty extends GoProperty {
- public readonly reference?: GoTypeRef;
-
public constructor(
public readonly parent: GoInterface,
public readonly property: Property,
@@ -201,10 +199,7 @@ class InterfaceProperty extends GoProperty {
}
public get returnType(): string {
- return (
- this.reference?.scopedReference(this.parent.pkg) ??
- this.property.type.toString()
- );
+ return this.reference.scopedReference(this.parent.pkg);
}
public emit({ code, documenter }: EmitContext) {
diff --git a/packages/jsii-pacmak/lib/targets/go/types/struct.ts b/packages/jsii-pacmak/lib/targets/go/types/struct.ts
index a1424b9497..5bf17162d0 100644
--- a/packages/jsii-pacmak/lib/targets/go/types/struct.ts
+++ b/packages/jsii-pacmak/lib/targets/go/types/struct.ts
@@ -13,10 +13,10 @@ import { GoProperty } from './type-member';
/*
* Struct wraps a JSII datatype interface aka, structs
*/
-export class Struct extends GoType {
+export class Struct extends GoType {
private readonly properties: readonly GoProperty[];
- public constructor(parent: Package, public readonly type: InterfaceType) {
+ public constructor(parent: Package, type: InterfaceType) {
super(parent, type);
assert(
diff --git a/packages/jsii-pacmak/lib/targets/go/types/type-member.ts b/packages/jsii-pacmak/lib/targets/go/types/type-member.ts
index 78c61dc69b..bf4930a588 100644
--- a/packages/jsii-pacmak/lib/targets/go/types/type-member.ts
+++ b/packages/jsii-pacmak/lib/targets/go/types/type-member.ts
@@ -1,8 +1,15 @@
-import { Callable, Method, Parameter, Property } from 'jsii-reflect';
+import {
+ Callable,
+ Method,
+ Parameter,
+ Property,
+ TypeReference,
+} from 'jsii-reflect';
import { jsiiToPascalCase } from '../../../naming-util';
import { SpecialDependencies } from '../dependencies';
import { EmitContext } from '../emit-context';
+import { Package } from '../package';
import { GetProperty, JSII_RT_ALIAS, SetProperty } from '../runtime';
import { substituteReservedWords } from '../util';
@@ -26,7 +33,6 @@ export interface GoTypeMember {
*/
export class GoProperty implements GoTypeMember {
public readonly name: string;
- public readonly reference?: GoTypeRef;
public readonly immutable: boolean;
public constructor(
@@ -35,10 +41,10 @@ export class GoProperty implements GoTypeMember {
) {
this.name = jsiiToPascalCase(this.property.name);
this.immutable = property.immutable;
+ }
- if (property.type) {
- this.reference = new GoTypeRef(parent.pkg.root, property.type);
- }
+ public get reference(): GoTypeRef {
+ return new GoTypeRef(this.parent.pkg.root, this.property.type);
}
public get specialDependencies(): SpecialDependencies {
@@ -143,7 +149,6 @@ export class GoProperty implements GoTypeMember {
export abstract class GoMethod implements GoTypeMember {
public readonly name: string;
- public readonly reference?: GoTypeRef;
public readonly parameters: GoParameter[];
public constructor(
@@ -151,9 +156,6 @@ export abstract class GoMethod implements GoTypeMember {
public readonly method: Callable,
) {
this.name = jsiiToPascalCase(method.name);
- if (Method.isMethod(method) && method.returns.type) {
- this.reference = new GoTypeRef(parent.pkg.root, method.returns.type);
- }
this.parameters = this.method.parameters.map(
(param) => new GoParameter(parent, param),
);
@@ -163,6 +165,13 @@ export abstract class GoMethod implements GoTypeMember {
public abstract get specialDependencies(): SpecialDependencies;
+ public get reference(): GoTypeRef | undefined {
+ if (Method.isMethod(this.method) && this.method.returns.type) {
+ return new GoTypeRef(this.parent.pkg.root, this.method.returns.type);
+ }
+ return undefined;
+ }
+
public get returnsRef(): boolean {
if (
this.reference?.type?.type.isClassType() ||
@@ -197,18 +206,23 @@ export abstract class GoMethod implements GoTypeMember {
export class GoParameter {
public readonly name: string;
- public readonly reference: GoTypeRef;
+ public readonly isVariadic: boolean;
+ private readonly type: TypeReference;
+ private readonly pkg: Package;
- public constructor(
- public parent: GoClass | GoInterface,
- public readonly parameter: Parameter,
- ) {
+ public constructor(parent: GoClass | GoInterface, parameter: Parameter) {
this.name = substituteReservedWords(parameter.name);
- this.reference = new GoTypeRef(parent.pkg.root, parameter.type);
+ this.isVariadic = parameter.variadic;
+ this.type = parameter.type;
+ this.pkg = parent.pkg;
+ }
+
+ public get reference(): GoTypeRef {
+ return new GoTypeRef(this.pkg.root, this.type);
}
public toString(): string {
- const paramType = this.reference.scopedReference(this.parent.pkg);
- return `${this.name} ${this.parameter.variadic ? '...' : ''}${paramType}`;
+ const paramType = this.reference.scopedReference(this.pkg);
+ return `${this.name} ${this.isVariadic ? '...' : ''}${paramType}`;
}
}
diff --git a/packages/jsii-pacmak/lib/targets/python/requirements-dev.txt b/packages/jsii-pacmak/lib/targets/python/requirements-dev.txt
index 028ff319b4..530b8a4098 100644
--- a/packages/jsii-pacmak/lib/targets/python/requirements-dev.txt
+++ b/packages/jsii-pacmak/lib/targets/python/requirements-dev.txt
@@ -6,4 +6,4 @@
setuptools~=59.6.0 # build-system
wheel~=0.37.1 # build-system
-twine~=3.7.1
+twine~=3.8.0
diff --git a/packages/jsii-pacmak/package.json b/packages/jsii-pacmak/package.json
index 33332db349..bf49dfac7b 100644
--- a/packages/jsii-pacmak/package.json
+++ b/packages/jsii-pacmak/package.json
@@ -59,16 +59,16 @@
"@types/clone": "^2.1.1",
"@types/commonmark": "^0.27.5",
"@types/fs-extra": "^9.0.13",
- "@types/jest": "^27.0.3",
- "@types/node": "^12.20.39",
+ "@types/jest": "^27.4.0",
+ "@types/node": "^12.20.43",
"@types/semver": "^7.3.9",
- "eslint": "^8.5.0",
- "jest": "^27.4.5",
+ "eslint": "^8.8.0",
+ "jest": "^27.4.7",
"jsii": "^0.0.0",
"jsii-build-tools": "^0.0.0",
"jsii-calc": "^3.20.120",
"prettier": "^2.5.1",
- "ts-jest": "^27.1.2",
+ "ts-jest": "^27.1.3",
"typescript": "~3.9.10"
},
"keywords": [
diff --git a/packages/jsii-pacmak/test/generated-code/__snapshots__/examples.test.ts.snap b/packages/jsii-pacmak/test/generated-code/__snapshots__/examples.test.ts.snap
index 24cd0361f9..ba54e825bd 100644
--- a/packages/jsii-pacmak/test/generated-code/__snapshots__/examples.test.ts.snap
+++ b/packages/jsii-pacmak/test/generated-code/__snapshots__/examples.test.ts.snap
@@ -114,14 +114,14 @@ namespace Example.Test.Demo
[JsiiByValue(fqn: "testpkg.Baz")]
public class Baz_ : Example.Test.Demo.IBaz
{
- [JsiiProperty(name: "baz", typeJson: "{\\"primitive\\":\\"boolean\\"}", isOverride: true)]
+ [JsiiProperty(name: "baz", typeJson: "{\\"primitive\\":\\"boolean\\"}")]
public bool Baz
{
get;
set;
}
- [JsiiProperty(name: "foo", typeJson: "{\\"primitive\\":\\"number\\"}", isOverride: true)]
+ [JsiiProperty(name: "foo", typeJson: "{\\"primitive\\":\\"number\\"}")]
public double Foo
{
get;
@@ -129,7 +129,7 @@ namespace Example.Test.Demo
}
[JsiiOptional]
- [JsiiProperty(name: "bar", typeJson: "{\\"primitive\\":\\"string\\"}", isOptional: true, isOverride: true)]
+ [JsiiProperty(name: "bar", typeJson: "{\\"primitive\\":\\"string\\"}", isOptional: true)]
public string? Bar
{
get;
@@ -186,7 +186,7 @@ namespace Example.Test.Demo
[JsiiByValue(fqn: "testpkg.Foo")]
public class Foo_ : Example.Test.Demo.IFoo
{
- [JsiiProperty(name: "foo", typeJson: "{\\"primitive\\":\\"number\\"}", isOverride: true)]
+ [JsiiProperty(name: "foo", typeJson: "{\\"primitive\\":\\"number\\"}")]
public double Foo
{
get;
@@ -209,7 +209,7 @@ namespace Example.Test.Demo
[JsiiByValue(fqn: "testpkg.FooBar")]
public class FooBar : Example.Test.Demo.IFooBar
{
- [JsiiProperty(name: "foo", typeJson: "{\\"primitive\\":\\"number\\"}", isOverride: true)]
+ [JsiiProperty(name: "foo", typeJson: "{\\"primitive\\":\\"number\\"}")]
public double Foo
{
get;
@@ -217,7 +217,7 @@ namespace Example.Test.Demo
}
[JsiiOptional]
- [JsiiProperty(name: "bar", typeJson: "{\\"primitive\\":\\"string\\"}", isOptional: true, isOverride: true)]
+ [JsiiProperty(name: "bar", typeJson: "{\\"primitive\\":\\"string\\"}", isOptional: true)]
public string? Bar
{
get;
@@ -1592,7 +1592,7 @@ namespace Example.Test.Demo
[JsiiByValue(fqn: "testpkg.Namespace1.Foo")]
public class Foo : Example.Test.Demo.Namespace1.IFoo
{
- [JsiiProperty(name: "bar", typeJson: "{\\"primitive\\":\\"string\\"}", isOverride: true)]
+ [JsiiProperty(name: "bar", typeJson: "{\\"primitive\\":\\"string\\"}")]
public string Bar
{
get;
diff --git a/packages/jsii-pacmak/test/generated-code/__snapshots__/target-dotnet.test.ts.snap b/packages/jsii-pacmak/test/generated-code/__snapshots__/target-dotnet.test.ts.snap
index 48f7cdd035..0706c2d65d 100644
--- a/packages/jsii-pacmak/test/generated-code/__snapshots__/target-dotnet.test.ts.snap
+++ b/packages/jsii-pacmak/test/generated-code/__snapshots__/target-dotnet.test.ts.snap
@@ -127,14 +127,14 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace
[JsiiByValue(fqn: "@scope/jsii-calc-base.BaseProps")]
public class BaseProps : Amazon.JSII.Tests.CalculatorNamespace.BaseNamespace.IBaseProps
{
- [JsiiProperty(name: "bar", typeJson: "{\\"primitive\\":\\"string\\"}", isOverride: true)]
+ [JsiiProperty(name: "bar", typeJson: "{\\"primitive\\":\\"string\\"}")]
public string Bar
{
get;
set;
}
- [JsiiProperty(name: "foo", typeJson: "{\\"fqn\\":\\"@scope/jsii-calc-base-of-base.Very\\"}", isOverride: true)]
+ [JsiiProperty(name: "foo", typeJson: "{\\"fqn\\":\\"@scope/jsii-calc-base-of-base.Very\\"}")]
public Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace.Very Foo
{
get;
@@ -733,7 +733,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace
[JsiiByValue(fqn: "@scope/jsii-calc-base-of-base.VeryBaseProps")]
public class VeryBaseProps : Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace.IVeryBaseProps
{
- [JsiiProperty(name: "foo", typeJson: "{\\"fqn\\":\\"@scope/jsii-calc-base-of-base.Very\\"}", isOverride: true)]
+ [JsiiProperty(name: "foo", typeJson: "{\\"fqn\\":\\"@scope/jsii-calc-base-of-base.Very\\"}")]
public Amazon.JSII.Tests.CalculatorNamespace.BaseOfBaseNamespace.Very Foo
{
get;
@@ -1125,7 +1125,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace
/// Stability: Deprecated
///
[JsiiOptional]
- [JsiiProperty(name: "hoistedTop", typeJson: "{\\"primitive\\":\\"string\\"}", isOptional: true, isOverride: true)]
+ [JsiiProperty(name: "hoistedTop", typeJson: "{\\"primitive\\":\\"string\\"}", isOptional: true)]
[System.Obsolete()]
public string? HoistedTop
{
@@ -1137,7 +1137,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace
/// Stability: Deprecated
///
[JsiiOptional]
- [JsiiProperty(name: "left", typeJson: "{\\"primitive\\":\\"number\\"}", isOptional: true, isOverride: true)]
+ [JsiiProperty(name: "left", typeJson: "{\\"primitive\\":\\"number\\"}", isOptional: true)]
[System.Obsolete()]
public double? Left
{
@@ -1166,7 +1166,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace
/// Stability: Deprecated
///
[JsiiOptional]
- [JsiiProperty(name: "hoistedTop", typeJson: "{\\"primitive\\":\\"string\\"}", isOptional: true, isOverride: true)]
+ [JsiiProperty(name: "hoistedTop", typeJson: "{\\"primitive\\":\\"string\\"}", isOptional: true)]
[System.Obsolete()]
public string? HoistedTop
{
@@ -1178,7 +1178,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace
/// Stability: Deprecated
///
[JsiiOptional]
- [JsiiProperty(name: "right", typeJson: "{\\"primitive\\":\\"boolean\\"}", isOptional: true, isOverride: true)]
+ [JsiiProperty(name: "right", typeJson: "{\\"primitive\\":\\"boolean\\"}", isOptional: true)]
[System.Obsolete()]
public bool? Right
{
@@ -1808,7 +1808,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace
///
/// Stability: Deprecated
///
- [JsiiProperty(name: "anumber", typeJson: "{\\"primitive\\":\\"number\\"}", isOverride: true)]
+ [JsiiProperty(name: "anumber", typeJson: "{\\"primitive\\":\\"number\\"}")]
[System.Obsolete()]
public double Anumber
{
@@ -1820,7 +1820,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace
///
/// Stability: Deprecated
///
- [JsiiProperty(name: "astring", typeJson: "{\\"primitive\\":\\"string\\"}", isOverride: true)]
+ [JsiiProperty(name: "astring", typeJson: "{\\"primitive\\":\\"string\\"}")]
[System.Obsolete()]
public string Astring
{
@@ -1832,7 +1832,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace
/// Stability: Deprecated
///
[JsiiOptional]
- [JsiiProperty(name: "firstOptional", typeJson: "{\\"collection\\":{\\"elementtype\\":{\\"primitive\\":\\"string\\"},\\"kind\\":\\"array\\"}}", isOptional: true, isOverride: true)]
+ [JsiiProperty(name: "firstOptional", typeJson: "{\\"collection\\":{\\"elementtype\\":{\\"primitive\\":\\"string\\"},\\"kind\\":\\"array\\"}}", isOptional: true)]
[System.Obsolete()]
public string[]? FirstOptional
{
@@ -2031,7 +2031,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace
///
/// Stability: Deprecated
///
- [JsiiMethod(name: "toString", returnsJson: "{\\"type\\":{\\"primitive\\":\\"string\\"}}", isOverride: true)]
+ [JsiiMethod(name: "toString", returnsJson: "{\\"type\\":{\\"primitive\\":\\"string\\"}}")]
[System.Obsolete()]
public override abstract string ToString();
@@ -2063,7 +2063,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace
///
/// Stability: Deprecated
///
- [JsiiMethod(name: "toString", returnsJson: "{\\"type\\":{\\"primitive\\":\\"string\\"}}", isOverride: true)]
+ [JsiiMethod(name: "toString", returnsJson: "{\\"type\\":{\\"primitive\\":\\"string\\"}}")]
[System.Obsolete()]
public override string ToString()
{
@@ -2094,7 +2094,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace
/// Stability: Deprecated
///
[JsiiOptional]
- [JsiiProperty(name: "optional1", typeJson: "{\\"primitive\\":\\"string\\"}", isOptional: true, isOverride: true)]
+ [JsiiProperty(name: "optional1", typeJson: "{\\"primitive\\":\\"string\\"}", isOptional: true)]
[System.Obsolete()]
public string? Optional1
{
@@ -2106,7 +2106,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace
/// Stability: Deprecated
///
[JsiiOptional]
- [JsiiProperty(name: "optional2", typeJson: "{\\"primitive\\":\\"number\\"}", isOptional: true, isOverride: true)]
+ [JsiiProperty(name: "optional2", typeJson: "{\\"primitive\\":\\"number\\"}", isOptional: true)]
[System.Obsolete()]
public double? Optional2
{
@@ -2118,7 +2118,7 @@ namespace Amazon.JSII.Tests.CalculatorNamespace.LibNamespace
/// Stability: Deprecated
///
[JsiiOptional]
- [JsiiProperty(name: "optional3", typeJson: "{\\"primitive\\":\\"boolean\\"}", isOptional: true, isOverride: true)]
+ [JsiiProperty(name: "optional3", typeJson: "{\\"primitive\\":\\"boolean\\"}", isOptional: true)]
[System.Obsolete()]
public bool? Optional3
{
@@ -2397,7 +2397,7 @@ namespace Amazon.JSII.Tests.CustomSubmoduleName
///
/// Stability: Deprecated
///
- [JsiiProperty(name: "name", typeJson: "{\\"primitive\\":\\"string\\"}", isOverride: true)]
+ [JsiiProperty(name: "name", typeJson: "{\\"primitive\\":\\"string\\"}")]
[System.Obsolete()]
public string Name
{
@@ -2428,7 +2428,7 @@ namespace Amazon.JSII.Tests.CustomSubmoduleName
///
/// Stability: Deprecated
///
- [JsiiProperty(name: "key", typeJson: "{\\"primitive\\":\\"string\\"}", isOverride: true)]
+ [JsiiProperty(name: "key", typeJson: "{\\"primitive\\":\\"string\\"}")]
[System.Obsolete()]
public string Key
{
@@ -2439,7 +2439,7 @@ namespace Amazon.JSII.Tests.CustomSubmoduleName
///
/// Stability: Deprecated
///
- [JsiiProperty(name: "value", typeJson: "{\\"primitive\\":\\"any\\"}", isOverride: true)]
+ [JsiiProperty(name: "value", typeJson: "{\\"primitive\\":\\"any\\"}")]
[System.Obsolete()]
public object Value
{
@@ -2743,6 +2743,7 @@ exports[`Generated code for "jsii-calc": / 1`] = `
┃ ┣━ 📄 AnonymousImplementationProvider.cs
┃ ┣━ 📄 AsyncVirtualMethods.cs
┃ ┣━ 📄 AugmentableClass.cs
+ ┃ ┣━ 📄 BaseClass.cs
┃ ┣━ 📄 BaseJsii976.cs
┃ ┣━ 📄 Bell.cs
┃ ┣━ 📄 BinaryOperation.cs
@@ -2809,6 +2810,7 @@ exports[`Generated code for "jsii-calc": / 1`] = `
┃ ┣━ 📄 ExternalClass.cs
┃ ┣━ 📄 ExternalEnum.cs
┃ ┣━ 📄 ExternalStruct.cs
+ ┃ ┣━ 📄 FullCombo.cs
┃ ┣━ 📄 GiveMeStructs.cs
┃ ┣━ 📄 Greetee.cs
┃ ┣━ 📄 GreetingAugmenter.cs
@@ -2842,6 +2844,7 @@ exports[`Generated code for "jsii-calc": / 1`] = `
┃ ┣━ 📄 IFriendlyRandomGenerator.cs
┃ ┣━ 📄 IGreetee.cs
┃ ┣━ 📄 IImplictBaseOfBase.cs
+ ┃ ┣━ 📄 IIndirectlyImplemented.cs
┃ ┣━ 📄 IInterfaceImplementedByAbstractClass.cs
┃ ┣━ 📄 IInterfaceThatShouldNotBeADataType.cs
┃ ┣━ 📄 IInterfaceWithInternal.cs
@@ -3411,14 +3414,14 @@ namespace Amazon.JSII.Tests.CalculatorNamespace
{
}
- /// (deprecated) String representation of the value.
- [JsiiMethod(name: "toString", returnsJson: "{\\"type\\":{\\"primitive\\":\\"string\\"}}", isOverride: true)]
+ /// String representation of the value.
+ [JsiiMethod(name: "toString", returnsJson: "{\\"type\\":{\\"primitive\\":\\"string\\"}}")]
public override string ToString()
{
return InvokeInstanceMethod(new System.Type[]{}, new object[]{})!;
}
- /// (deprecated) The value.
+ /// The value.
[JsiiProperty(name: "value", typeJson: "{\\"primitive\\":\\"number\\"}")]
public override double Value
{
@@ -3769,13 +3772,13 @@ namespace Amazon.JSII.Tests.CalculatorNamespace
{
}
- [JsiiMethod(name: "provideAsClass", returnsJson: "{\\"type\\":{\\"fqn\\":\\"jsii-calc.Implementation\\"}}", isOverride: true)]
+ [JsiiMethod(name: "provideAsClass", returnsJson: "{\\"type\\":{\\"fqn\\":\\"jsii-calc.Implementation\\"}}")]
public virtual Amazon.JSII.Tests.CalculatorNamespace.Implementation ProvideAsClass()
{
return InvokeInstanceMethod(new System.Type[]{}, new object[]{})!;
}
- [JsiiMethod(name: "provideAsInterface", returnsJson: "{\\"type\\":{\\"fqn\\":\\"jsii-calc.IAnonymouslyImplementMe\\"}}", isOverride: true)]
+ [JsiiMethod(name: "provideAsInterface", returnsJson: "{\\"type\\":{\\"fqn\\":\\"jsii-calc.IAnonymouslyImplementMe\\"}}")]
public virtual Amazon.JSII.Tests.CalculatorNamespace.IAnonymouslyImplementMe ProvideAsInterface()
{
return InvokeInstanceMethod(new System.Type[]{}, new object[]{})!;
@@ -3904,6 +3907,58 @@ namespace Amazon.JSII.Tests.CalculatorNamespace
`;
+exports[`Generated code for "jsii-calc": /dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/BaseClass.cs 1`] = `
+using Amazon.JSII.Runtime.Deputy;
+
+#pragma warning disable CS0672,CS0809,CS1591
+
+namespace Amazon.JSII.Tests.CalculatorNamespace
+{
+ [JsiiClass(nativeType: typeof(Amazon.JSII.Tests.CalculatorNamespace.BaseClass), fullyQualifiedName: "jsii-calc.BaseClass")]
+ public abstract class BaseClass : DeputyBase
+ {
+ protected BaseClass(): base(new DeputyProps(System.Array.Empty