From bece04279bb73306e414588654bfbb090f845daa Mon Sep 17 00:00:00 2001 From: Hamza Assyad Date: Thu, 29 Aug 2019 05:32:29 -0700 Subject: [PATCH] feat(dotnet): [JsiiOptional] attribute on properties that are optionals + Roslyn Analyzer (#717) On properties that are optionals, we now add a [JsiiOptional] attribute. Ex: ``` [JsiiProperty(name: "optional1", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] [System.Obsolete()] [JsiiOptional] public string Optional1 { get; set; } ``` Also, This introduces a new package which needs to be pushed to NuGet: Amazon.Jsii.Analyzers. It includes a Roslyn Analyzer which makes sure that inside nested props object initializations, all required properties are passed by the developer, and are not passed as null (syntax check only). Example in Rider with a required property not passed: ![Screen Shot 2019-08-16 at 5 13 35 PM (2)](https://user-images.githubusercontent.com/4091730/63204171-e7771f00-c049-11e9-9896-b1e035272492.png) Whit a required property passed with a null value: ![Screen Shot 2019-08-16 at 5 14 12 PM (2)](https://user-images.githubusercontent.com/4091730/63204185-083f7480-c04a-11e9-87d4-decfdd808955.png) With the required property correctly passed: ![Screen Shot 2019-08-16 at 5 14 20 PM (2)](https://user-images.githubusercontent.com/4091730/63204188-142b3680-c04a-11e9-9019-bf8c9fe3b102.png) The idea here is to check inline initialization of data types within jsii classes. --- packages/jsii-dotnet-analyzers/.gitignore | 17 ++ .../Directory.Build.props.t.js | 9 + packages/jsii-dotnet-analyzers/LICENSE | 202 +++++++++++++ .../NuGet.Metadata.props.t.js | 19 ++ packages/jsii-dotnet-analyzers/build.sh | 6 + packages/jsii-dotnet-analyzers/generate.sh | 7 + packages/jsii-dotnet-analyzers/lib/index.ts | 3 + .../jsii-dotnet-analyzers/package-lock.json | 15 + packages/jsii-dotnet-analyzers/package.json | 32 +++ .../Amazon.JSII.Analyzers.UnitTests.csproj | 25 ++ .../Helpers/DiagnosticResult.cs | 87 ++++++ .../Helpers/DiagnosticVerifier.Helper.cs | 170 +++++++++++ .../JsiiOptionalAnalyzerTests.cs | 173 +++++++++++ .../Verifiers/DiagnosticVerifier.cs | 269 ++++++++++++++++++ .../src/Amazon.JSII.Analyzers.sln | 43 +++ .../Amazon.JSII.Analyzers.csproj | 21 ++ .../JsiiOptionalAnalyzer.cs | 139 +++++++++ .../Amazon.JSII.Analyzers/tools/install.ps1 | 58 ++++ .../Amazon.JSII.Analyzers/tools/uninstall.ps1 | 65 +++++ packages/jsii-dotnet-analyzers/test.sh | 6 + packages/jsii-dotnet-analyzers/tsconfig.json | 54 ++++ .../Amazon.JSII.Runtime.csproj | 3 +- .../Deputy/JsiiOptionalAttribute.cs | 14 + .../lib/targets/dotnet/dotnetgenerator.ts | 3 + .../LibNamespace/MyFirstStruct.cs | 1 + .../LibNamespace/MyFirstStructProxy.cs | 1 + .../LibNamespace/StructWithOnlyOptionals.cs | 3 + .../StructWithOnlyOptionalsProxy.cs | 3 + .../Tests/CalculatorNamespace/AllTypes.cs | 1 + .../Tests/CalculatorNamespace/Calculator.cs | 2 + .../CalculatorNamespace/CalculatorProps.cs | 2 + .../CalculatorPropsProxy.cs | 2 + .../DefaultedConstructorArgument.cs | 1 + .../CalculatorNamespace/DeprecatedClass.cs | 1 + .../CalculatorNamespace/DerivedStruct.cs | 4 + .../CalculatorNamespace/DerivedStructProxy.cs | 4 + .../EraseUndefinedHashValuesOptions.cs | 2 + .../EraseUndefinedHashValuesOptionsProxy.cs | 2 + .../CalculatorNamespace/ExperimentalClass.cs | 1 + .../JSII/Tests/CalculatorNamespace/Greetee.cs | 1 + .../Tests/CalculatorNamespace/GreeteeProxy.cs | 1 + .../IDeprecatedInterfaceProxy.cs | 1 + .../IExperimentalInterfaceProxy.cs | 1 + .../IStableInterfaceProxy.cs | 1 + .../Foo.cs | 1 + .../Tests/CalculatorNamespace/JsiiAgent_.cs | 1 + .../LoadBalancedFargateServiceProps.cs | 5 + .../LoadBalancedFargateServicePropsProxy.cs | 5 + .../NullShouldBeTreatedAsUndefined.cs | 1 + .../NullShouldBeTreatedAsUndefinedData.cs | 1 + ...NullShouldBeTreatedAsUndefinedDataProxy.cs | 1 + .../OptionalConstructorArgument.cs | 1 + .../CalculatorNamespace/OptionalStruct.cs | 1 + .../OptionalStructConsumer.cs | 1 + .../OptionalStructProxy.cs | 1 + .../ReferenceEnumFromScopedPackage.cs | 1 + .../CalculatorNamespace/SecondLevelStruct.cs | 1 + .../SecondLevelStructProxy.cs | 1 + .../Tests/CalculatorNamespace/StableClass.cs | 1 + .../StructWithJavaReservedWords.cs | 3 + .../StructWithJavaReservedWordsProxy.cs | 3 + .../CalculatorNamespace/TopLevelStruct.cs | 1 + .../TopLevelStructProxy.cs | 1 + .../CalculatorNamespace/UnionProperties.cs | 1 + .../UnionPropertiesProxy.cs | 1 + 65 files changed, 1506 insertions(+), 2 deletions(-) create mode 100644 packages/jsii-dotnet-analyzers/.gitignore create mode 100644 packages/jsii-dotnet-analyzers/Directory.Build.props.t.js create mode 100644 packages/jsii-dotnet-analyzers/LICENSE create mode 100644 packages/jsii-dotnet-analyzers/NuGet.Metadata.props.t.js create mode 100644 packages/jsii-dotnet-analyzers/build.sh create mode 100644 packages/jsii-dotnet-analyzers/generate.sh create mode 100644 packages/jsii-dotnet-analyzers/lib/index.ts create mode 100644 packages/jsii-dotnet-analyzers/package-lock.json create mode 100644 packages/jsii-dotnet-analyzers/package.json create mode 100755 packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Amazon.JSII.Analyzers.UnitTests.csproj create mode 100755 packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Helpers/DiagnosticResult.cs create mode 100755 packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Helpers/DiagnosticVerifier.Helper.cs create mode 100755 packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/JsiiOptionalAnalyzerTests.cs create mode 100755 packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Verifiers/DiagnosticVerifier.cs create mode 100644 packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.sln create mode 100644 packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/Amazon.JSII.Analyzers.csproj create mode 100644 packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/JsiiOptionalAnalyzer.cs create mode 100644 packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/tools/install.ps1 create mode 100644 packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/tools/uninstall.ps1 create mode 100644 packages/jsii-dotnet-analyzers/test.sh create mode 100644 packages/jsii-dotnet-analyzers/tsconfig.json create mode 100644 packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiOptionalAttribute.cs diff --git a/packages/jsii-dotnet-analyzers/.gitignore b/packages/jsii-dotnet-analyzers/.gitignore new file mode 100644 index 0000000000..65d6c8ce34 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/.gitignore @@ -0,0 +1,17 @@ +# generated by generate.sh +src/Amazon.JSII.Generator/JsiiVersion.cs +src/Directory.Build.props +src/NuGet.Metadata.props + +*.js +*.d.ts +node_modules/ +.nyc_output/ +coverage/ + + +*.nupkg +bin/ +cli/ +obj/ +*.DotSettings.user diff --git a/packages/jsii-dotnet-analyzers/Directory.Build.props.t.js b/packages/jsii-dotnet-analyzers/Directory.Build.props.t.js new file mode 100644 index 0000000000..77bca5d03c --- /dev/null +++ b/packages/jsii-dotnet-analyzers/Directory.Build.props.t.js @@ -0,0 +1,9 @@ +const version = require('./package.json').version.replace(/\+.+$/, ''); // omit "+build" suffix + +process.stdout.write(` + + ${version} + netstandard2.0 + + +`); diff --git a/packages/jsii-dotnet-analyzers/LICENSE b/packages/jsii-dotnet-analyzers/LICENSE new file mode 100644 index 0000000000..add725cd48 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/jsii-dotnet-analyzers/NuGet.Metadata.props.t.js b/packages/jsii-dotnet-analyzers/NuGet.Metadata.props.t.js new file mode 100644 index 0000000000..e0c50b6ad4 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/NuGet.Metadata.props.t.js @@ -0,0 +1,19 @@ +const package = require('./package.json'); + +process.stdout.write(` + + True + True + True + ..\\..\\bin\\$(Configuration)\\NuGet\\ + $(JsiiVersion) + ${package.description} + ${package.homepage} + https://spdx.org/licenses/${package.license}.html + ${package.author.name} + ${package.author.name} + key.snk + True + + +`); diff --git a/packages/jsii-dotnet-analyzers/build.sh b/packages/jsii-dotnet-analyzers/build.sh new file mode 100644 index 0000000000..93d1136aa6 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -euo pipefail + +dotnet build --force -c Release ./src/Amazon.JSII.Analyzers + +cp -f ./bin/Release/NuGet/*.nupkg . diff --git a/packages/jsii-dotnet-analyzers/generate.sh b/packages/jsii-dotnet-analyzers/generate.sh new file mode 100644 index 0000000000..5a5764b0d9 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/generate.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -euo pipefail +src="./src" + +# Generate metadata files based on package.json. +/usr/bin/env node ./Directory.Build.props.t.js > ${src}/Directory.Build.props +/usr/bin/env node ./NuGet.Metadata.props.t.js > ${src}/NuGet.Metadata.props diff --git a/packages/jsii-dotnet-analyzers/lib/index.ts b/packages/jsii-dotnet-analyzers/lib/index.ts new file mode 100644 index 0000000000..838fecdac4 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/lib/index.ts @@ -0,0 +1,3 @@ +import path = require('path'); + +export const repository = path.resolve(__dirname, path.join('..', 'bin', 'Release', 'NuGet')); diff --git a/packages/jsii-dotnet-analyzers/package-lock.json b/packages/jsii-dotnet-analyzers/package-lock.json new file mode 100644 index 0000000000..6b6d4d37f6 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/package-lock.json @@ -0,0 +1,15 @@ +{ + "name": "jsii-dotnet-analyzers", + "version": "0.15.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "jsii-build-tools": { + "version": "file:../jsii-build-tools", + "dev": true + }, + "jsii-dotnet-runtime": { + "version": "file:../jsii-dotnet-runtime" + } + } +} diff --git a/packages/jsii-dotnet-analyzers/package.json b/packages/jsii-dotnet-analyzers/package.json new file mode 100644 index 0000000000..df169759bc --- /dev/null +++ b/packages/jsii-dotnet-analyzers/package.json @@ -0,0 +1,32 @@ +{ + "name": "jsii-dotnet-analyzers", + "version": "0.15.0", + "description": ".NET Roslyn Analyzers for Jsii", + "main": "lib/index.js", + "private": true, + "types": "lib/index.d.ts", + "scripts": { + "gen": "/bin/bash ./generate.sh", + "build": "npm run gen && tsc --build && /bin/bash ./build.sh", + "test": "/bin/bash ./test.sh", + "package": "package-dotnet" + }, + "devDependencies": { + "jsii-build-tools": "file:../jsii-build-tools" + }, + "dependencies": { + "jsii-dotnet-runtime": "file:../jsii-dotnet-runtime" + }, + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "email": "aws-jsii@amazon.com" + }, + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/aws/jsii.git", + "directory": "packages/jsii-dotnet-analyzers" + }, + "homepage": "https://github.com/aws/jsii" +} diff --git a/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Amazon.JSII.Analyzers.UnitTests.csproj b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Amazon.JSII.Analyzers.UnitTests.csproj new file mode 100755 index 0000000000..7a61bc6c1a --- /dev/null +++ b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Amazon.JSII.Analyzers.UnitTests.csproj @@ -0,0 +1,25 @@ + + + + netcoreapp2.0 + false + Amazon.JSII.Analyzers.UnitTests + + + + + + + + + + + + + + + + + + + diff --git a/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Helpers/DiagnosticResult.cs b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Helpers/DiagnosticResult.cs new file mode 100755 index 0000000000..dde80c43f9 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Helpers/DiagnosticResult.cs @@ -0,0 +1,87 @@ +using Microsoft.CodeAnalysis; +using System; + +namespace TestHelper +{ + /// + /// Location where the diagnostic appears, as determined by path, line number, and column number. + /// + public struct DiagnosticResultLocation + { + public DiagnosticResultLocation(string path, int line, int column) + { + if (line < -1) + { + throw new ArgumentOutOfRangeException(nameof(line), "line must be >= -1"); + } + + if (column < -1) + { + throw new ArgumentOutOfRangeException(nameof(column), "column must be >= -1"); + } + + this.Path = path; + this.Line = line; + this.Column = column; + } + + public string Path { get; } + public int Line { get; } + public int Column { get; } + } + + /// + /// Struct that stores information about a Diagnostic appearing in a source + /// + public struct DiagnosticResult + { + private DiagnosticResultLocation[] locations; + + public DiagnosticResultLocation[] Locations + { + get + { + if (this.locations == null) + { + this.locations = new DiagnosticResultLocation[] { }; + } + return this.locations; + } + + set + { + this.locations = value; + } + } + + public DiagnosticSeverity Severity { get; set; } + + public string Id { get; set; } + + public string Message { get; set; } + + public string Path + { + get + { + return this.Locations.Length > 0 ? this.Locations[0].Path : ""; + } + } + + public int Line + { + get + { + return this.Locations.Length > 0 ? this.Locations[0].Line : -1; + } + } + + public int Column + { + get + { + return this.Locations.Length > 0 ? this.Locations[0].Column : -1; + } + } + } +} diff --git a/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Helpers/DiagnosticVerifier.Helper.cs b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Helpers/DiagnosticVerifier.Helper.cs new file mode 100755 index 0000000000..de72e54f8d --- /dev/null +++ b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Helpers/DiagnosticVerifier.Helper.cs @@ -0,0 +1,170 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Text; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; + +namespace TestHelper +{ + /// + /// Class for turning strings into documents and getting the diagnostics on them + /// All methods are static + /// + public abstract partial class DiagnosticVerifier + { + private static readonly MetadataReference CorlibReference = MetadataReference.CreateFromFile(typeof(object).Assembly.Location); + private static readonly MetadataReference SystemCoreReference = MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location); + private static readonly MetadataReference CSharpSymbolsReference = MetadataReference.CreateFromFile(typeof(CSharpCompilation).Assembly.Location); + private static readonly MetadataReference CodeAnalysisReference = MetadataReference.CreateFromFile(typeof(Compilation).Assembly.Location); + + internal static string DefaultFilePathPrefix = "Test"; + internal static string CSharpDefaultFileExt = "cs"; + internal static string VisualBasicDefaultExt = "vb"; + internal static string TestProjectName = "TestProject"; + + #region Get Diagnostics + + /// + /// Given classes in the form of strings, their language, and an IDiagnosticAnalyzer to apply to it, return the diagnostics found in the string after converting it to a document. + /// + /// Classes in the form of strings + /// The language the source classes are in + /// The analyzer to be run on the sources + /// An IEnumerable of Diagnostics that surfaced in the source code, sorted by Location + private static Diagnostic[] GetSortedDiagnostics(string[] sources, string language, DiagnosticAnalyzer analyzer) + { + return GetSortedDiagnosticsFromDocuments(analyzer, GetDocuments(sources, language)); + } + + /// + /// Given an analyzer and a document to apply it to, run the analyzer and gather an array of diagnostics found in it. + /// The returned diagnostics are then ordered by location in the source document. + /// + /// The analyzer to run on the documents + /// The Documents that the analyzer will be run on + /// An IEnumerable of Diagnostics that surfaced in the source code, sorted by Location + protected static Diagnostic[] GetSortedDiagnosticsFromDocuments(DiagnosticAnalyzer analyzer, Document[] documents) + { + var projects = new HashSet(); + foreach (var document in documents) + { + projects.Add(document.Project); + } + + var diagnostics = new List(); + foreach (var project in projects) + { + var compilationWithAnalyzers = project.GetCompilationAsync().Result.WithAnalyzers(ImmutableArray.Create(analyzer)); + var diags = compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result; + foreach (var diag in diags) + { + if (diag.Location == Location.None || diag.Location.IsInMetadata) + { + diagnostics.Add(diag); + } + else + { + for (int i = 0; i < documents.Length; i++) + { + var document = documents[i]; + var tree = document.GetSyntaxTreeAsync().Result; + if (tree == diag.Location.SourceTree) + { + diagnostics.Add(diag); + } + } + } + } + } + + var results = SortDiagnostics(diagnostics); + diagnostics.Clear(); + return results; + } + + /// + /// Sort diagnostics by location in source document + /// + /// The list of Diagnostics to be sorted + /// An IEnumerable containing the Diagnostics in order of Location + private static Diagnostic[] SortDiagnostics(IEnumerable diagnostics) + { + return diagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray(); + } + + #endregion + + #region Set up compilation and documents + /// + /// Given an array of strings as sources and a language, turn them into a project and return the documents and spans of it. + /// + /// Classes in the form of strings + /// The language the source code is in + /// A Tuple containing the Documents produced from the sources and their TextSpans if relevant + private static Document[] GetDocuments(string[] sources, string language) + { + if (language != LanguageNames.CSharp && language != LanguageNames.VisualBasic) + { + throw new ArgumentException("Unsupported Language"); + } + + var project = CreateProject(sources, language); + var documents = project.Documents.ToArray(); + + if (sources.Length != documents.Length) + { + throw new InvalidOperationException("Amount of sources did not match amount of Documents created"); + } + + return documents; + } + + /// + /// Create a Document from a string through creating a project that contains it. + /// + /// Classes in the form of a string + /// The language the source code is in + /// A Document created from the source string + protected static Document CreateDocument(string source, string language = LanguageNames.CSharp) + { + return CreateProject(new[] { source }, language).Documents.First(); + } + + /// + /// Create a project using the inputted strings as sources. + /// + /// Classes in the form of strings + /// The language the source code is in + /// A Project created out of the Documents created from the source strings + private static Project CreateProject(string[] sources, string language = LanguageNames.CSharp) + { + string fileNamePrefix = DefaultFilePathPrefix; + string fileExt = language == LanguageNames.CSharp ? CSharpDefaultFileExt : VisualBasicDefaultExt; + + var projectId = ProjectId.CreateNewId(debugName: TestProjectName); + + var solution = new AdhocWorkspace() + .CurrentSolution + .AddProject(projectId, TestProjectName, TestProjectName, language) + .AddMetadataReference(projectId, CorlibReference) + .AddMetadataReference(projectId, SystemCoreReference) + .AddMetadataReference(projectId, CSharpSymbolsReference) + .AddMetadataReference(projectId, CodeAnalysisReference); + + int count = 0; + foreach (var source in sources) + { + var newFileName = fileNamePrefix + count + "." + fileExt; + var documentId = DocumentId.CreateNewId(projectId, debugName: newFileName); + solution = solution.AddDocument(documentId, newFileName, SourceText.From(source)); + count++; + } + return solution.GetProject(projectId); + } + #endregion + } +} + diff --git a/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/JsiiOptionalAnalyzerTests.cs b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/JsiiOptionalAnalyzerTests.cs new file mode 100755 index 0000000000..18a1de12bf --- /dev/null +++ b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/JsiiOptionalAnalyzerTests.cs @@ -0,0 +1,173 @@ +using System.Collections.Generic; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Xunit; +using TestHelper; + +namespace Amazon.JSII.Analyzers.UnitTests +{ + public class JsiiOptionalAnalyzerTests : DiagnosticVerifier + { + [Fact] + public void TestGivenSomeEmptyCodeThenRoslynDoesNotComplain() + { + var test = @""; + + VerifyCSharpDiagnostic(test); + } + + [Fact] + public void TestGivenSomeCodeWithAMissingRequiredPropertyThenRoslynComplains() + { + var test = @" + using System; + namespace Amazon.JSII.Analyzers.UnitTests + { + public class JsiiByValueAttribute : Attribute + { + } + + public class JsiiClassAttribute : Attribute + { + } + + public class JsiiOptionalAttribute : Attribute + { + } + + [JsiiByValue] + public class SampleProps + { + [JsiiOptional] + public string OptionalProperty1 { get; set; } + + [JsiiOptional] + public string OptionalProperty2 { get; set; } + + public string RequiredProperty1 { get; set; } + + public string RequiredProperty2 { get; set; } + } + + [JsiiClass] + public class SampleClass + { + public SampleClass(SampleProps props) + { + props = null; + } + } + + class Test + { + // This should fail because there is missing required properties and it is a nested instruction + var result1 = new SampleClass(new SampleProps()); + + // This should fail because RequiredProperty1 is passed as null + var result2 = new SampleClass(new SampleProps() + { + RequiredProperty1 = null, + OptionalProperty2 = ""test"", + RequiredProperty2 = ""test"" + }); + + // This is OK, the properties might be passed later, we don't want to enforce it + var result3 = new SampleProps(); + + // This is not OK, if you start passing properties, you should pass all of the required ones + var result4 = new SampleProps() + { + RequiredProperty1 = null, + OptionalProperty2 = ""test"" + }; + + // This is not OK, RequiredProperty1 is null + var result5 = new SampleProps() + { + RequiredProperty1 = null, + OptionalProperty2 = ""test"", + RequiredProperty2 = ""test"" + }; + + // This is OK, all required properties are passed and not null. + var result6 = new SampleProps() + { + RequiredProperty1 = ""test"", + OptionalProperty2 = ""test"", + RequiredProperty2 = ""test"" + }; + } + }"; + var expected = new List() + { + new DiagnosticResult() + { + Id = "JSII001", + Message = "The property RequiredProperty1 is required and cannot be null", + Severity = DiagnosticSeverity.Error, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 43, 51) + } + }, + new DiagnosticResult() + { + Id = "JSII001", + Message = "The property RequiredProperty2 is required and cannot be null", + Severity = DiagnosticSeverity.Error, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 43, 51) + } + }, + new DiagnosticResult() + { + Id = "JSII001", + Message = "The property RequiredProperty1 is required and cannot be null", + Severity = DiagnosticSeverity.Error, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 46, 51) + } + }, + new DiagnosticResult() + { + Id = "JSII001", + Message = "The property RequiredProperty1 is required and cannot be null", + Severity = DiagnosticSeverity.Error, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 57, 35) + } + }, + new DiagnosticResult() + { + Id = "JSII001", + Message = "The property RequiredProperty2 is required and cannot be null", + Severity = DiagnosticSeverity.Error, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 57, 35) + } + }, + new DiagnosticResult() + { + Id = "JSII001", + Message = "The property RequiredProperty1 is required and cannot be null", + Severity = DiagnosticSeverity.Error, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 64, 35) + } + } + }; + + VerifyCSharpDiagnostic(test, expected.ToArray()); + } + + protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer() + { + return new JsiiOptionalAnalyzer(); + } + } +} diff --git a/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Verifiers/DiagnosticVerifier.cs b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Verifiers/DiagnosticVerifier.cs new file mode 100755 index 0000000000..8a66157221 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.UnitTests/Verifiers/DiagnosticVerifier.cs @@ -0,0 +1,269 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace TestHelper +{ + /// + /// Superclass of all Unit Tests for DiagnosticAnalyzers + /// + public abstract partial class DiagnosticVerifier + { + #region To be implemented by Test classes + /// + /// Get the CSharp analyzer being tested - to be implemented in non-abstract class + /// + protected virtual DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer() + { + return null; + } + + /// + /// Get the Visual Basic analyzer being tested (C#) - to be implemented in non-abstract class + /// + protected virtual DiagnosticAnalyzer GetBasicDiagnosticAnalyzer() + { + return null; + } + #endregion + + #region Verifier wrappers + + /// + /// Called to test a C# DiagnosticAnalyzer when applied on the single inputted string as a source + /// Note: input a DiagnosticResult for each Diagnostic expected + /// + /// A class in the form of a string to run the analyzer on + /// DiagnosticResults that should appear after the analyzer is run on the source + protected void VerifyCSharpDiagnostic(string source, params DiagnosticResult[] expected) + { + VerifyDiagnostics(new[] { source }, LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), expected); + } + + /// + /// Called to test a VB DiagnosticAnalyzer when applied on the single inputted string as a source + /// Note: input a DiagnosticResult for each Diagnostic expected + /// + /// A class in the form of a string to run the analyzer on + /// DiagnosticResults that should appear after the analyzer is run on the source + protected void VerifyBasicDiagnostic(string source, params DiagnosticResult[] expected) + { + VerifyDiagnostics(new[] { source }, LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), expected); + } + + /// + /// Called to test a C# DiagnosticAnalyzer when applied on the inputted strings as a source + /// Note: input a DiagnosticResult for each Diagnostic expected + /// + /// An array of strings to create source documents from to run the analyzers on + /// DiagnosticResults that should appear after the analyzer is run on the sources + protected void VerifyCSharpDiagnostic(string[] sources, params DiagnosticResult[] expected) + { + VerifyDiagnostics(sources, LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), expected); + } + + /// + /// Called to test a VB DiagnosticAnalyzer when applied on the inputted strings as a source + /// Note: input a DiagnosticResult for each Diagnostic expected + /// + /// An array of strings to create source documents from to run the analyzers on + /// DiagnosticResults that should appear after the analyzer is run on the sources + protected void VerifyBasicDiagnostic(string[] sources, params DiagnosticResult[] expected) + { + VerifyDiagnostics(sources, LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), expected); + } + + /// + /// General method that gets a collection of actual diagnostics found in the source after the analyzer is run, + /// then verifies each of them. + /// + /// An array of strings to create source documents from to run the analyzers on + /// The language of the classes represented by the source strings + /// The analyzer to be run on the source code + /// DiagnosticResults that should appear after the analyzer is run on the sources + private void VerifyDiagnostics(string[] sources, string language, DiagnosticAnalyzer analyzer, params DiagnosticResult[] expected) + { + var diagnostics = GetSortedDiagnostics(sources, language, analyzer); + VerifyDiagnosticResults(diagnostics, analyzer, expected); + } + + #endregion + + #region Actual comparisons and verifications + /// + /// Checks each of the actual Diagnostics found and compares them with the corresponding DiagnosticResult in the array of expected results. + /// Diagnostics are considered equal only if the DiagnosticResultLocation, Id, Severity, and Message of the DiagnosticResult match the actual diagnostic. + /// + /// The Diagnostics found by the compiler after running the analyzer on the source code + /// The analyzer that was being run on the sources + /// Diagnostic Results that should have appeared in the code + private static void VerifyDiagnosticResults(IEnumerable actualResults, DiagnosticAnalyzer analyzer, params DiagnosticResult[] expectedResults) + { + int expectedCount = expectedResults.Count(); + int actualCount = actualResults.Count(); + + if (expectedCount != actualCount) + { + string diagnosticsOutput = actualResults.Any() ? FormatDiagnostics(analyzer, actualResults.ToArray()) : " NONE."; + + Assert.True(false, + string.Format("Mismatch between number of diagnostics returned, expected \"{0}\" actual \"{1}\"\r\n\r\nDiagnostics:\r\n{2}\r\n", expectedCount, actualCount, diagnosticsOutput)); + } + + for (int i = 0; i < expectedResults.Length; i++) + { + var actual = actualResults.ElementAt(i); + var expected = expectedResults[i]; + + if (expected.Line == -1 && expected.Column == -1) + { + if (actual.Location != Location.None) + { + Assert.True(false, + string.Format("Expected:\nA project diagnostic with No location\nActual:\n{0}", + FormatDiagnostics(analyzer, actual))); + } + } + else + { + VerifyDiagnosticLocation(analyzer, actual, actual.Location, expected.Locations.First()); + var additionalLocations = actual.AdditionalLocations.ToArray(); + + if (additionalLocations.Length != expected.Locations.Length - 1) + { + Assert.True(false, + string.Format("Expected {0} additional locations but got {1} for Diagnostic:\r\n {2}\r\n", + expected.Locations.Length - 1, additionalLocations.Length, + FormatDiagnostics(analyzer, actual))); + } + + for (int j = 0; j < additionalLocations.Length; ++j) + { + VerifyDiagnosticLocation(analyzer, actual, additionalLocations[j], expected.Locations[j + 1]); + } + } + + if (actual.Id != expected.Id) + { + Assert.True(false, + string.Format("Expected diagnostic id to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", + expected.Id, actual.Id, FormatDiagnostics(analyzer, actual))); + } + + if (actual.Severity != expected.Severity) + { + Assert.True(false, + string.Format("Expected diagnostic severity to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", + expected.Severity, actual.Severity, FormatDiagnostics(analyzer, actual))); + } + + if (actual.GetMessage() != expected.Message) + { + Assert.True(false, + string.Format("Expected diagnostic message to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", + expected.Message, actual.GetMessage(), FormatDiagnostics(analyzer, actual))); + } + } + } + + /// + /// Helper method to VerifyDiagnosticResult that checks the location of a diagnostic and compares it with the location in the expected DiagnosticResult. + /// + /// The analyzer that was being run on the sources + /// The diagnostic that was found in the code + /// The Location of the Diagnostic found in the code + /// The DiagnosticResultLocation that should have been found + private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, DiagnosticResultLocation expected) + { + var actualSpan = actual.GetLineSpan(); + + Assert.True(actualSpan.Path == expected.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Path.Contains("Test.")), + string.Format("Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", + expected.Path, actualSpan.Path, FormatDiagnostics(analyzer, diagnostic))); + + var actualLinePosition = actualSpan.StartLinePosition; + + // Only check line position if there is an actual line in the real diagnostic + if (actualLinePosition.Line > 0) + { + if (actualLinePosition.Line + 1 != expected.Line) + { + Assert.True(false, + string.Format("Expected diagnostic to be on line \"{0}\" was actually on line \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", + expected.Line, actualLinePosition.Line + 1, FormatDiagnostics(analyzer, diagnostic))); + } + } + + // Only check column position if there is an actual column position in the real diagnostic + if (actualLinePosition.Character > 0) + { + if (actualLinePosition.Character + 1 != expected.Column) + { + Assert.True(false, + string.Format("Expected diagnostic to start at column \"{0}\" was actually at column \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", + expected.Column, actualLinePosition.Character + 1, FormatDiagnostics(analyzer, diagnostic))); + } + } + } + #endregion + + #region Formatting Diagnostics + /// + /// Helper method to format a Diagnostic into an easily readable string + /// + /// The analyzer that this verifier tests + /// The Diagnostics to be formatted + /// The Diagnostics formatted as a string + private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics) + { + var builder = new StringBuilder(); + for (int i = 0; i < diagnostics.Length; ++i) + { + builder.AppendLine("// " + diagnostics[i].ToString()); + + var analyzerType = analyzer.GetType(); + var rules = analyzer.SupportedDiagnostics; + + foreach (var rule in rules) + { + if (rule != null && rule.Id == diagnostics[i].Id) + { + var location = diagnostics[i].Location; + if (location == Location.None) + { + builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id); + } + else + { + Assert.True(location.IsInSource, + $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[i]}\r\n"); + + string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs") ? "GetCSharpResultAt" : "GetBasicResultAt"; + var linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition; + + builder.AppendFormat("{0}({1}, {2}, {3}.{4})", + resultMethodName, + linePosition.Line + 1, + linePosition.Character + 1, + analyzerType.Name, + rule.Id); + } + + if (i != diagnostics.Length - 1) + { + builder.Append(','); + } + + builder.AppendLine(); + break; + } + } + } + return builder.ToString(); + } + #endregion + } +} diff --git a/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.sln b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.sln new file mode 100644 index 0000000000..a905ad7c35 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers.sln @@ -0,0 +1,43 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2026 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Amazon.JSII.Analyzers", "Amazon.JSII.Analyzers\Amazon.JSII.Analyzers.csproj", "{E7BFF0E9-D8BF-4996-98B7-58334EA276D1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{B88CEA39-359B-45A0-86D6-0BC1FD284BBE}" + ProjectSection(SolutionItems) = preProject + Directory.Build.props = Directory.Build.props + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Amazon.JSII.Analyzers.UnitTests", "Amazon.JSII.Analyzers.UnitTests\Amazon.JSII.Analyzers.UnitTests.csproj", "{96CC0C0B-1D90-448F-9BFC-07CE93D2CE29}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E7BFF0E9-D8BF-4996-98B7-58334EA276D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E7BFF0E9-D8BF-4996-98B7-58334EA276D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E7BFF0E9-D8BF-4996-98B7-58334EA276D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E7BFF0E9-D8BF-4996-98B7-58334EA276D1}.Release|Any CPU.Build.0 = Release|Any CPU + {96CC0C0B-1D90-448F-9BFC-07CE93D2CE29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96CC0C0B-1D90-448F-9BFC-07CE93D2CE29}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96CC0C0B-1D90-448F-9BFC-07CE93D2CE29}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96CC0C0B-1D90-448F-9BFC-07CE93D2CE29}.Release|Any CPU.Build.0 = Release|Any CPU + {7BD15A18-BE3A-4729-9B8C-570BF214C4CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7BD15A18-BE3A-4729-9B8C-570BF214C4CE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7BD15A18-BE3A-4729-9B8C-570BF214C4CE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7BD15A18-BE3A-4729-9B8C-570BF214C4CE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {96CC0C0B-1D90-448F-9BFC-07CE93D2CE29} = {1F4EEFB5-9E4C-4464-9C3B-6729ABB0511E} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C5094D14-EAB4-4A0A-80A2-14748C28C057} + EndGlobalSection +EndGlobal diff --git a/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/Amazon.JSII.Analyzers.csproj b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/Amazon.JSII.Analyzers.csproj new file mode 100644 index 0000000000..8e4ff80347 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/Amazon.JSII.Analyzers.csproj @@ -0,0 +1,21 @@ + + + + + Amazon.JSII.Analyzers + .NET Roslyn Analyzers for JSII + netstandard2.0 + true + + + + + + + + + + + + + diff --git a/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/JsiiOptionalAnalyzer.cs b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/JsiiOptionalAnalyzer.cs new file mode 100644 index 0000000000..957a093d44 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/JsiiOptionalAnalyzer.cs @@ -0,0 +1,139 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Amazon.JSII.Analyzers +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public class JsiiOptionalAnalyzer : DiagnosticAnalyzer + { + private const string DiagnosticId = "JSII001"; + private const string Title = "A required property is missing or null"; + private const string MessageFormat = "The property is required and cannot be null"; + private const string MessageFormatWithPropertyName = "The property {0} is required and cannot be null"; + private const string Description = "The property is required and cannot be null"; + private const string DescriptionWitPropertyName = "The property {0} is required and cannot be null"; + private const string Category = "Jsii.Usage"; + + private static readonly DiagnosticDescriptor Rule = + new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Error, isEnabledByDefault: true, description: Description); + + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(Rule); + + public override void Initialize(AnalysisContext context) + { + context.EnableConcurrentExecution(); + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze); + context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.ObjectCreationExpression); + } + + private static void AnalyzeNode(SyntaxNodeAnalysisContext context) + { + var objectCreation = (ObjectCreationExpressionSyntax)context.Node; + var typeInfo = context.SemanticModel.GetTypeInfo(objectCreation); + if (IsJsiiDatatype(typeInfo)) + { + // If the newly created instance is a Jsii datatype [JsiiByValue] + // Get all the properties passed + var passedProperties = new HashSet(); + foreach (var child in objectCreation.ChildNodes()) + { + if (child.Kind() == SyntaxKind.ObjectInitializerExpression) + { + // This is an inline initialization + // Saving all the properties that are passed when initializing the props object + foreach (var passedProperty in child.ChildNodes().Where(n => n.Kind() == SyntaxKind.SimpleAssignmentExpression)) + { + var props = passedProperty.ChildNodes().ToArray(); + if (props.Length >= 2) + { + // Property = value + if (props[1].ToString() != "null") // value != null ? + { + var propName = props[0].ToString(); + passedProperties.Add(propName); + } + } + } + } + } + + // Parent.Parent.Parent = new Construct() instruction. + // #1 Parent = Argument + // #2 Parent = ArgumentList + // #3 Parent = ObjectCreationExpressionSyntax (if it exists). + var parentType = context.SemanticModel.GetTypeInfo(objectCreation.Parent.Parent.Parent); + + // If the object initialization was an empty newProps() outside of a JsiiClass - We don't fail + if (passedProperties.Count == 0 && (parentType.Type == null || !IsJsiiClass(parentType))) + return; + + // Get all the required properties on the prop object + var requiredProperties = typeInfo.Type.GetMembers() + .Where(m => m.Kind == SymbolKind.Property + && !IsJsiiOptionalProperty(m)); + foreach (var requiredProperty in requiredProperties) + { + // The property in the props class IS NOT optional, check if it is passed as an argument. + if (!passedProperties.Contains(requiredProperty.Name)) + { + // This property IS REQUIRED and was not passed in the arguments. Raising an error + var rule = new DiagnosticDescriptor(DiagnosticId, + Title, + string.Format(MessageFormatWithPropertyName, requiredProperty.Name), + Category, + DiagnosticSeverity.Error, + isEnabledByDefault: true, + description: string.Format(DescriptionWitPropertyName, requiredProperty.Name)); + context.ReportDiagnostic(Diagnostic.Create(rule, context.Node.GetLocation())); + } + } + } + } + + /// + /// Checks if the TypeInfo is related to a Jsii class + /// + /// + /// This is done by checking for the [JsiiClass] attribute + /// + /// The TypeInfo object to check for + /// true if the TypeInfo is related to a Jsii class, false otherwise + private static bool IsJsiiClass(TypeInfo typeInfo) + { + var typeAttributes = typeInfo.Type.GetAttributes().ToArray(); + return typeAttributes.Any(a => a.AttributeClass.Name == "JsiiClassAttribute"); + } + + /// + /// Checks if the TypeInfo is related to a Jsii datatype + /// + /// + /// This is done by checking for the [JsiiByValueAttribute] attribute + /// + /// The TypeInfo object to check for + /// true if the TypeInfo is related to a Jsii datatype, false otherwise + private static bool IsJsiiDatatype(TypeInfo typeInfo) + { + var typeAttributes = typeInfo.Type.GetAttributes().ToArray(); + return typeAttributes.Any(a => a.AttributeClass.Name == "JsiiByValueAttribute"); + } + + /// + /// Checks if the property is optional for jsii + /// + /// + /// This is done by checking for the [JsiiOptionalAttribute] attribute + /// + /// The property to check for + /// true if the property is optional, false otherwise + private static bool IsJsiiOptionalProperty(ISymbol property) + { + return property.GetAttributes().Any(a => a.AttributeClass.Name == "JsiiOptionalAttribute"); + } + } +} \ No newline at end of file diff --git a/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/tools/install.ps1 b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/tools/install.ps1 new file mode 100644 index 0000000000..c1c3d88223 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/tools/install.ps1 @@ -0,0 +1,58 @@ +param($installPath, $toolsPath, $package, $project) + +if($project.Object.SupportsPackageDependencyResolution) +{ + if($project.Object.SupportsPackageDependencyResolution()) + { + # Do not install analyzers via install.ps1, instead let the project system handle it. + return + } +} + +$analyzersPaths = Join-Path (Join-Path (Split-Path -Path $toolsPath -Parent) "analyzers") * -Resolve + +foreach($analyzersPath in $analyzersPaths) +{ + if (Test-Path $analyzersPath) + { + # Install the language agnostic analyzers. + foreach ($analyzerFilePath in Get-ChildItem -Path "$analyzersPath\*.dll" -Exclude *.resources.dll) + { + if($project.Object.AnalyzerReferences) + { + $project.Object.AnalyzerReferences.Add($analyzerFilePath.FullName) + } + } + } +} + +# $project.Type gives the language name like (C# or VB.NET) +$languageFolder = "" +if($project.Type -eq "C#") +{ + $languageFolder = "cs" +} +if($project.Type -eq "VB.NET") +{ + $languageFolder = "vb" +} +if($languageFolder -eq "") +{ + return +} + +foreach($analyzersPath in $analyzersPaths) +{ + # Install language specific analyzers. + $languageAnalyzersPath = join-path $analyzersPath $languageFolder + if (Test-Path $languageAnalyzersPath) + { + foreach ($analyzerFilePath in Get-ChildItem -Path "$languageAnalyzersPath\*.dll" -Exclude *.resources.dll) + { + if($project.Object.AnalyzerReferences) + { + $project.Object.AnalyzerReferences.Add($analyzerFilePath.FullName) + } + } + } +} \ No newline at end of file diff --git a/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/tools/uninstall.ps1 b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/tools/uninstall.ps1 new file mode 100644 index 0000000000..829d26efa9 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/src/Amazon.JSII.Analyzers/tools/uninstall.ps1 @@ -0,0 +1,65 @@ +param($installPath, $toolsPath, $package, $project) + +if($project.Object.SupportsPackageDependencyResolution) +{ + if($project.Object.SupportsPackageDependencyResolution()) + { + # Do not uninstall analyzers via uninstall.ps1, instead let the project system handle it. + return + } +} + +$analyzersPaths = Join-Path (Join-Path (Split-Path -Path $toolsPath -Parent) "analyzers") * -Resolve + +foreach($analyzersPath in $analyzersPaths) +{ + # Uninstall the language agnostic analyzers. + if (Test-Path $analyzersPath) + { + foreach ($analyzerFilePath in Get-ChildItem -Path "$analyzersPath\*.dll" -Exclude *.resources.dll) + { + if($project.Object.AnalyzerReferences) + { + $project.Object.AnalyzerReferences.Remove($analyzerFilePath.FullName) + } + } + } +} + +# $project.Type gives the language name like (C# or VB.NET) +$languageFolder = "" +if($project.Type -eq "C#") +{ + $languageFolder = "cs" +} +if($project.Type -eq "VB.NET") +{ + $languageFolder = "vb" +} +if($languageFolder -eq ""), +{ + return +} + +foreach($analyzersPath in $analyzersPaths) +{ + # Uninstall language specific analyzers. + $languageAnalyzersPath = join-path $analyzersPath $languageFolder + if (Test-Path $languageAnalyzersPath) + { + foreach ($analyzerFilePath in Get-ChildItem -Path "$languageAnalyzersPath\*.dll" -Exclude *.resources.dll) + { + if($project.Object.AnalyzerReferences) + { + try + { + $project.Object.AnalyzerReferences.Remove($analyzerFilePath.FullName) + } + catch + { + + } + } + } + } +} \ No newline at end of file diff --git a/packages/jsii-dotnet-analyzers/test.sh b/packages/jsii-dotnet-analyzers/test.sh new file mode 100644 index 0000000000..5338fc26dc --- /dev/null +++ b/packages/jsii-dotnet-analyzers/test.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -euo pipefail + +# Run unit tests +echo "Running library unit tests" +dotnet test -c Release ./src/Amazon.JSII.Analyzers.UnitTests diff --git a/packages/jsii-dotnet-analyzers/tsconfig.json b/packages/jsii-dotnet-analyzers/tsconfig.json new file mode 100644 index 0000000000..6f8f29cf64 --- /dev/null +++ b/packages/jsii-dotnet-analyzers/tsconfig.json @@ -0,0 +1,54 @@ +{ + "compilerOptions": { + /* Basic Options */ + "target": "ES2018", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + "lib": ["es2016", "es2017.object", "es2017.string"], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + "strictNullChecks": true, /* Enable strict null checks. */ + "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + "strictPropertyInitialization": false, /* DO NOT Raise error on class attribute not initialized by constructor. */ + + /* Additional Checks */ + "noUnusedLocals": true, /* Report errors on unused locals. */ + "noUnusedParameters": true, /* Report errors on unused parameters. */ + "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + + /* Source Map Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": false, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": false, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + } +} diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Amazon.JSII.Runtime.csproj b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Amazon.JSII.Runtime.csproj index a157ba16b6..761a89bc56 100644 --- a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Amazon.JSII.Runtime.csproj +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Amazon.JSII.Runtime.csproj @@ -14,10 +14,9 @@ - + - diff --git a/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiOptionalAttribute.cs b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiOptionalAttribute.cs new file mode 100644 index 0000000000..1102879073 --- /dev/null +++ b/packages/jsii-dotnet-runtime/src/Amazon.JSII.Runtime/Deputy/JsiiOptionalAttribute.cs @@ -0,0 +1,14 @@ +using System; + +namespace Amazon.JSII.Runtime.Deputy +{ + /// + /// Flags a property as optional. + /// This is used by the jsii-dotnet-analyzers package to emit errors + /// on required properties that are missing. + /// + [AttributeUsage(AttributeTargets.Property)] + public class JsiiOptionalAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/lib/targets/dotnet/dotnetgenerator.ts b/packages/jsii-pacmak/lib/targets/dotnet/dotnetgenerator.ts index e3e6061256..ff4a2ff95a 100644 --- a/packages/jsii-pacmak/lib/targets/dotnet/dotnetgenerator.ts +++ b/packages/jsii-pacmak/lib/targets/dotnet/dotnetgenerator.ts @@ -644,6 +644,9 @@ export class DotNetGenerator extends Generator { const propName = this.nameutils.convertPropertyName(prop.name); this.dotnetDocGenerator.emitDocs(prop); + if (prop.optional) { + this.code.line('[JsiiOptional]'); + } this.dotnetRuntimeGenerator.emitAttributesForProperty(prop, datatype); let isOverrideKeyWord = ''; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/MyFirstStruct.cs b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/MyFirstStruct.cs index c36847573d..2c2b7cdecb 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/MyFirstStruct.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/MyFirstStruct.cs @@ -36,6 +36,7 @@ public string Astring /// /// stability: Deprecated /// + [JsiiOptional] [JsiiProperty(name: "firstOptional", typeJson: "{\"collection\":{\"elementtype\":{\"primitive\":\"string\"},\"kind\":\"array\"}}", isOptional: true, isOverride: true)] [System.Obsolete()] public string[] FirstOptional diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/MyFirstStructProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/MyFirstStructProxy.cs index 8c15dae980..f0ac0931da 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/MyFirstStructProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/MyFirstStructProxy.cs @@ -39,6 +39,7 @@ public string Astring /// /// stability: Deprecated /// + [JsiiOptional] [JsiiProperty(name: "firstOptional", typeJson: "{\"collection\":{\"elementtype\":{\"primitive\":\"string\"},\"kind\":\"array\"}}", isOptional: true)] [System.Obsolete()] public string[] FirstOptional diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/StructWithOnlyOptionals.cs b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/StructWithOnlyOptionals.cs index d82c4b4553..2635cc9ab5 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/StructWithOnlyOptionals.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/StructWithOnlyOptionals.cs @@ -13,6 +13,7 @@ public class StructWithOnlyOptionals : Amazon.JSII.Tests.CalculatorNamespace.Lib /// /// stability: Deprecated /// + [JsiiOptional] [JsiiProperty(name: "optional1", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] [System.Obsolete()] public string Optional1 @@ -24,6 +25,7 @@ public string Optional1 /// /// stability: Deprecated /// + [JsiiOptional] [JsiiProperty(name: "optional2", typeJson: "{\"primitive\":\"number\"}", isOptional: true, isOverride: true)] [System.Obsolete()] public double? Optional2 @@ -35,6 +37,7 @@ public double? Optional2 /// /// stability: Deprecated /// + [JsiiOptional] [JsiiProperty(name: "optional3", typeJson: "{\"primitive\":\"boolean\"}", isOptional: true, isOverride: true)] [System.Obsolete()] public bool? Optional3 diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/StructWithOnlyOptionalsProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/StructWithOnlyOptionalsProxy.cs index 2034bc7b4c..3074e21fbe 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/StructWithOnlyOptionalsProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/dotnet/Amazon.JSII.Tests.CalculatorPackageId.LibPackageId/Amazon/JSII/Tests/CalculatorNamespace/LibNamespace/StructWithOnlyOptionalsProxy.cs @@ -18,6 +18,7 @@ private StructWithOnlyOptionalsProxy(ByRefValue reference): base(reference) /// /// stability: Deprecated /// + [JsiiOptional] [JsiiProperty(name: "optional1", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] [System.Obsolete()] public string Optional1 @@ -28,6 +29,7 @@ public string Optional1 /// /// stability: Deprecated /// + [JsiiOptional] [JsiiProperty(name: "optional2", typeJson: "{\"primitive\":\"number\"}", isOptional: true)] [System.Obsolete()] public double? Optional2 @@ -38,6 +40,7 @@ public double? Optional2 /// /// stability: Deprecated /// + [JsiiOptional] [JsiiProperty(name: "optional3", typeJson: "{\"primitive\":\"boolean\"}", isOptional: true)] [System.Obsolete()] public bool? Optional3 diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AllTypes.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AllTypes.cs index b5b70f1476..3fa26cb700 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AllTypes.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/AllTypes.cs @@ -232,6 +232,7 @@ public virtual object UnknownProperty /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "optionalEnumValue", typeJson: "{\"fqn\":\"jsii-calc.StringEnum\"}", isOptional: true)] public virtual Amazon.JSII.Tests.CalculatorNamespace.StringEnum? OptionalEnumValue { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Calculator.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Calculator.cs index 3b38368237..27f02c06ab 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Calculator.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Calculator.cs @@ -121,6 +121,7 @@ public virtual Amazon.JSII.Tests.CalculatorNamespace.LibNamespace.Value_ Curr /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "maxValue", typeJson: "{\"primitive\":\"number\"}", isOptional: true)] public virtual double? MaxValue { @@ -132,6 +133,7 @@ public virtual double? MaxValue /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "unionProperty", typeJson: "{\"union\":{\"types\":[{\"fqn\":\"jsii-calc.Add\"},{\"fqn\":\"jsii-calc.Multiply\"},{\"fqn\":\"jsii-calc.Power\"}]}}", isOptional: true)] public virtual object UnionProperty { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/CalculatorProps.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/CalculatorProps.cs index e6fe4c9cab..d9ee88181e 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/CalculatorProps.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/CalculatorProps.cs @@ -12,6 +12,7 @@ public class CalculatorProps : Amazon.JSII.Tests.CalculatorNamespace.ICalculator /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "initialValue", typeJson: "{\"primitive\":\"number\"}", isOptional: true, isOverride: true)] public double? InitialValue { @@ -22,6 +23,7 @@ public double? InitialValue /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "maximumValue", typeJson: "{\"primitive\":\"number\"}", isOptional: true, isOverride: true)] public double? MaximumValue { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/CalculatorPropsProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/CalculatorPropsProxy.cs index 9582baa158..f6d967c1e1 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/CalculatorPropsProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/CalculatorPropsProxy.cs @@ -16,6 +16,7 @@ private CalculatorPropsProxy(ByRefValue reference): base(reference) /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "initialValue", typeJson: "{\"primitive\":\"number\"}", isOptional: true)] public double? InitialValue { @@ -25,6 +26,7 @@ public double? InitialValue /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "maximumValue", typeJson: "{\"primitive\":\"number\"}", isOptional: true)] public double? MaximumValue { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DefaultedConstructorArgument.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DefaultedConstructorArgument.cs index 15798beccd..929d118bf4 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DefaultedConstructorArgument.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DefaultedConstructorArgument.cs @@ -44,6 +44,7 @@ public virtual System.DateTime Arg3 /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "arg2", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public virtual string Arg2 { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DeprecatedClass.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DeprecatedClass.cs index eb025e0de6..b9c7382590 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DeprecatedClass.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DeprecatedClass.cs @@ -50,6 +50,7 @@ public virtual string ReadonlyProperty /// /// stability: Deprecated /// + [JsiiOptional] [JsiiProperty(name: "mutableProperty", typeJson: "{\"primitive\":\"number\"}", isOptional: true)] [System.Obsolete("shouldn't have been mutable")] public virtual double? MutableProperty diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DerivedStruct.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DerivedStruct.cs index 5d82d1ad0a..2b4a1ada28 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DerivedStruct.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DerivedStruct.cs @@ -44,6 +44,7 @@ public Amazon.JSII.Tests.CalculatorNamespace.DoubleTrouble NonPrimitive /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "anotherOptional", typeJson: "{\"collection\":{\"elementtype\":{\"fqn\":\"@scope/jsii-calc-lib.Value\"},\"kind\":\"map\"}}", isOptional: true, isOverride: true)] public System.Collections.Generic.IDictionary AnotherOptional { @@ -54,6 +55,7 @@ public Amazon.JSII.Tests.CalculatorNamespace.DoubleTrouble NonPrimitive /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "optionalAny", typeJson: "{\"primitive\":\"any\"}", isOptional: true, isOverride: true)] public object OptionalAny { @@ -64,6 +66,7 @@ public object OptionalAny /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "optionalArray", typeJson: "{\"collection\":{\"elementtype\":{\"primitive\":\"string\"},\"kind\":\"array\"}}", isOptional: true, isOverride: true)] public string[] OptionalArray { @@ -98,6 +101,7 @@ public string Astring /// /// stability: Deprecated /// + [JsiiOptional] [JsiiProperty(name: "firstOptional", typeJson: "{\"collection\":{\"elementtype\":{\"primitive\":\"string\"},\"kind\":\"array\"}}", isOptional: true, isOverride: true)] [System.Obsolete()] public string[] FirstOptional diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DerivedStructProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DerivedStructProxy.cs index da0836ab8f..0b16f241bd 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DerivedStructProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/DerivedStructProxy.cs @@ -45,6 +45,7 @@ public Amazon.JSII.Tests.CalculatorNamespace.DoubleTrouble NonPrimitive /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "anotherOptional", typeJson: "{\"collection\":{\"elementtype\":{\"fqn\":\"@scope/jsii-calc-lib.Value\"},\"kind\":\"map\"}}", isOptional: true)] public System.Collections.Generic.IDictionary AnotherOptional { @@ -54,6 +55,7 @@ public Amazon.JSII.Tests.CalculatorNamespace.DoubleTrouble NonPrimitive /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "optionalAny", typeJson: "{\"primitive\":\"any\"}", isOptional: true)] public object OptionalAny { @@ -63,6 +65,7 @@ public object OptionalAny /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "optionalArray", typeJson: "{\"collection\":{\"elementtype\":{\"primitive\":\"string\"},\"kind\":\"array\"}}", isOptional: true)] public string[] OptionalArray { @@ -94,6 +97,7 @@ public string Astring /// /// stability: Deprecated /// + [JsiiOptional] [JsiiProperty(name: "firstOptional", typeJson: "{\"collection\":{\"elementtype\":{\"primitive\":\"string\"},\"kind\":\"array\"}}", isOptional: true)] [System.Obsolete()] public string[] FirstOptional diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/EraseUndefinedHashValuesOptions.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/EraseUndefinedHashValuesOptions.cs index 4ed1aa61a3..fbbd4264a9 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/EraseUndefinedHashValuesOptions.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/EraseUndefinedHashValuesOptions.cs @@ -11,6 +11,7 @@ public class EraseUndefinedHashValuesOptions : Amazon.JSII.Tests.CalculatorNames /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "option1", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] public string Option1 { @@ -21,6 +22,7 @@ public string Option1 /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "option2", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] public string Option2 { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/EraseUndefinedHashValuesOptionsProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/EraseUndefinedHashValuesOptionsProxy.cs index 84dc19301f..9faeb33e5d 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/EraseUndefinedHashValuesOptionsProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/EraseUndefinedHashValuesOptionsProxy.cs @@ -15,6 +15,7 @@ private EraseUndefinedHashValuesOptionsProxy(ByRefValue reference): base(referen /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "option1", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public string Option1 { @@ -24,6 +25,7 @@ public string Option1 /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "option2", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public string Option2 { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ExperimentalClass.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ExperimentalClass.cs index 47db920320..9a87527611 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ExperimentalClass.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ExperimentalClass.cs @@ -44,6 +44,7 @@ public virtual string ReadonlyProperty /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "mutableProperty", typeJson: "{\"primitive\":\"number\"}", isOptional: true)] public virtual double? MutableProperty { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Greetee.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Greetee.cs index ccd8effa38..19d064df54 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Greetee.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/Greetee.cs @@ -15,6 +15,7 @@ public class Greetee : Amazon.JSII.Tests.CalculatorNamespace.IGreetee /// world /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "name", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] public string Name { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/GreeteeProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/GreeteeProxy.cs index bf9232f9ab..181ebd82c7 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/GreeteeProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/GreeteeProxy.cs @@ -19,6 +19,7 @@ private GreeteeProxy(ByRefValue reference): base(reference) /// world /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "name", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public string Name { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IDeprecatedInterfaceProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IDeprecatedInterfaceProxy.cs index cca4d9bd98..f1d60e948c 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IDeprecatedInterfaceProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IDeprecatedInterfaceProxy.cs @@ -16,6 +16,7 @@ private IDeprecatedInterfaceProxy(ByRefValue reference): base(reference) /// /// stability: Deprecated /// + [JsiiOptional] [JsiiProperty(name: "mutableProperty", typeJson: "{\"primitive\":\"number\"}", isOptional: true)] [System.Obsolete("could be better")] public double? MutableProperty diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IExperimentalInterfaceProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IExperimentalInterfaceProxy.cs index 5480a314be..09b159632b 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IExperimentalInterfaceProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IExperimentalInterfaceProxy.cs @@ -15,6 +15,7 @@ private IExperimentalInterfaceProxy(ByRefValue reference): base(reference) /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "mutableProperty", typeJson: "{\"primitive\":\"number\"}", isOptional: true)] public double? MutableProperty { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IStableInterfaceProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IStableInterfaceProxy.cs index d951e4593f..5b7b4f6f98 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IStableInterfaceProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IStableInterfaceProxy.cs @@ -15,6 +15,7 @@ private IStableInterfaceProxy(ByRefValue reference): base(reference) /// /// stability: Stable /// + [JsiiOptional] [JsiiProperty(name: "mutableProperty", typeJson: "{\"primitive\":\"number\"}", isOptional: true)] public double? MutableProperty { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/Foo.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/Foo.cs index 4f9fab38a5..50e5611192 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/Foo.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/InterfaceInNamespaceIncludesClasses/Foo.cs @@ -23,6 +23,7 @@ protected Foo(DeputyProps props): base(props) /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "bar", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public virtual string Bar { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/JsiiAgent_.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/JsiiAgent_.cs index 2759a17388..9208e398f1 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/JsiiAgent_.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/JsiiAgent_.cs @@ -25,6 +25,7 @@ protected JsiiAgent_(DeputyProps props): base(props) /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "jsiiAgent", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public static string JsiiAgent { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/LoadBalancedFargateServiceProps.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/LoadBalancedFargateServiceProps.cs index 25c3f9f42f..3f4ad3c875 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/LoadBalancedFargateServiceProps.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/LoadBalancedFargateServiceProps.cs @@ -16,6 +16,7 @@ public class LoadBalancedFargateServiceProps : Amazon.JSII.Tests.CalculatorNames /// 80 /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "containerPort", typeJson: "{\"primitive\":\"number\"}", isOptional: true, isOverride: true)] public double? ContainerPort { @@ -30,6 +31,7 @@ public double? ContainerPort /// 256 /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "cpu", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] public string Cpu { @@ -57,6 +59,7 @@ public string Cpu /// 512 /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "memoryMiB", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] public string MemoryMiB { @@ -70,6 +73,7 @@ public string MemoryMiB /// true /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "publicLoadBalancer", typeJson: "{\"primitive\":\"boolean\"}", isOptional: true, isOverride: true)] public bool? PublicLoadBalancer { @@ -83,6 +87,7 @@ public bool? PublicLoadBalancer /// false /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "publicTasks", typeJson: "{\"primitive\":\"boolean\"}", isOptional: true, isOverride: true)] public bool? PublicTasks { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/LoadBalancedFargateServicePropsProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/LoadBalancedFargateServicePropsProxy.cs index 56607197f6..c68b635314 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/LoadBalancedFargateServicePropsProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/LoadBalancedFargateServicePropsProxy.cs @@ -20,6 +20,7 @@ private LoadBalancedFargateServicePropsProxy(ByRefValue reference): base(referen /// 80 /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "containerPort", typeJson: "{\"primitive\":\"number\"}", isOptional: true)] public double? ContainerPort { @@ -33,6 +34,7 @@ public double? ContainerPort /// 256 /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "cpu", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public string Cpu { @@ -59,6 +61,7 @@ public string Cpu /// 512 /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "memoryMiB", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public string MemoryMiB { @@ -71,6 +74,7 @@ public string MemoryMiB /// true /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "publicLoadBalancer", typeJson: "{\"primitive\":\"boolean\"}", isOptional: true)] public bool? PublicLoadBalancer { @@ -83,6 +87,7 @@ public bool? PublicLoadBalancer /// false /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "publicTasks", typeJson: "{\"primitive\":\"boolean\"}", isOptional: true)] public bool? PublicTasks { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NullShouldBeTreatedAsUndefined.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NullShouldBeTreatedAsUndefined.cs index 897d15eda1..4b3cd58211 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NullShouldBeTreatedAsUndefined.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NullShouldBeTreatedAsUndefined.cs @@ -54,6 +54,7 @@ public virtual void VerifyPropertyIsUndefined() /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "changeMeToUndefined", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public virtual string ChangeMeToUndefined { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NullShouldBeTreatedAsUndefinedData.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NullShouldBeTreatedAsUndefinedData.cs index 9bf866fef9..a88fd52f43 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NullShouldBeTreatedAsUndefinedData.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NullShouldBeTreatedAsUndefinedData.cs @@ -21,6 +21,7 @@ public object[] ArrayWithThreeElementsAndUndefinedAsSecondArgument /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "thisShouldBeUndefined", typeJson: "{\"primitive\":\"any\"}", isOptional: true, isOverride: true)] public object ThisShouldBeUndefined { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NullShouldBeTreatedAsUndefinedDataProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NullShouldBeTreatedAsUndefinedDataProxy.cs index f409bb3aac..591bd0cf89 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NullShouldBeTreatedAsUndefinedDataProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NullShouldBeTreatedAsUndefinedDataProxy.cs @@ -24,6 +24,7 @@ public object[] ArrayWithThreeElementsAndUndefinedAsSecondArgument /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "thisShouldBeUndefined", typeJson: "{\"primitive\":\"any\"}", isOptional: true)] public object ThisShouldBeUndefined { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalConstructorArgument.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalConstructorArgument.cs index 3cbbc1ac03..8a36aa1250 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalConstructorArgument.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalConstructorArgument.cs @@ -44,6 +44,7 @@ public virtual string Arg2 /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "arg3", typeJson: "{\"primitive\":\"date\"}", isOptional: true)] public virtual System.DateTime? Arg3 { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalStruct.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalStruct.cs index 685ed0bc75..0e55a0c4af 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalStruct.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalStruct.cs @@ -11,6 +11,7 @@ public class OptionalStruct : Amazon.JSII.Tests.CalculatorNamespace.IOptionalStr /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "field", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] public string Field { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalStructConsumer.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalStructConsumer.cs index 7dac995a47..c473601635 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalStructConsumer.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalStructConsumer.cs @@ -35,6 +35,7 @@ public virtual bool ParameterWasUndefined /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "fieldValue", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public virtual string FieldValue { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalStructProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalStructProxy.cs index d831d90c68..9f26565881 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalStructProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/OptionalStructProxy.cs @@ -15,6 +15,7 @@ private OptionalStructProxy(ByRefValue reference): base(reference) /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "field", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public string Field { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ReferenceEnumFromScopedPackage.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ReferenceEnumFromScopedPackage.cs index d0822350e9..f9aa6e4946 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ReferenceEnumFromScopedPackage.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/ReferenceEnumFromScopedPackage.cs @@ -42,6 +42,7 @@ public virtual void SaveFoo(Amazon.JSII.Tests.CalculatorNamespace.LibNamespace.E /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "foo", typeJson: "{\"fqn\":\"@scope/jsii-calc-lib.EnumFromScopedModule\"}", isOptional: true)] public virtual Amazon.JSII.Tests.CalculatorNamespace.LibNamespace.EnumFromScopedModule? Foo { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/SecondLevelStruct.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/SecondLevelStruct.cs index 3dbc4c062b..7c40a353be 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/SecondLevelStruct.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/SecondLevelStruct.cs @@ -23,6 +23,7 @@ public string DeeperRequiredProp /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "deeperOptionalProp", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] public string DeeperOptionalProp { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/SecondLevelStructProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/SecondLevelStructProxy.cs index fa23095a8f..79d73c80f6 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/SecondLevelStructProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/SecondLevelStructProxy.cs @@ -26,6 +26,7 @@ public string DeeperRequiredProp /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "deeperOptionalProp", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public string DeeperOptionalProp { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/StableClass.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/StableClass.cs index eea996a83f..606e61050a 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/StableClass.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/StableClass.cs @@ -44,6 +44,7 @@ public virtual string ReadonlyProperty /// /// stability: Stable /// + [JsiiOptional] [JsiiProperty(name: "mutableProperty", typeJson: "{\"primitive\":\"number\"}", isOptional: true)] public virtual double? MutableProperty { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/StructWithJavaReservedWords.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/StructWithJavaReservedWords.cs index 3067e8e87e..438bb39094 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/StructWithJavaReservedWords.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/StructWithJavaReservedWords.cs @@ -21,6 +21,7 @@ public string Default /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "assert", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] public string Assert { @@ -31,6 +32,7 @@ public string Assert /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "result", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] public string Result { @@ -41,6 +43,7 @@ public string Result /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "that", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] public string That { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/StructWithJavaReservedWordsProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/StructWithJavaReservedWordsProxy.cs index 4ea4f6fa23..b705625b0d 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/StructWithJavaReservedWordsProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/StructWithJavaReservedWordsProxy.cs @@ -24,6 +24,7 @@ public string Default /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "assert", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public string Assert { @@ -33,6 +34,7 @@ public string Assert /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "result", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public string Result { @@ -42,6 +44,7 @@ public string Result /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "that", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public string That { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/TopLevelStruct.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/TopLevelStruct.cs index 107d1c91e6..41725b0da4 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/TopLevelStruct.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/TopLevelStruct.cs @@ -34,6 +34,7 @@ public object SecondLevel /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "optional", typeJson: "{\"primitive\":\"string\"}", isOptional: true, isOverride: true)] public string Optional { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/TopLevelStructProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/TopLevelStructProxy.cs index 274ccb3ce9..7d683eb598 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/TopLevelStructProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/TopLevelStructProxy.cs @@ -36,6 +36,7 @@ public object SecondLevel /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "optional", typeJson: "{\"primitive\":\"string\"}", isOptional: true)] public string Optional { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnionProperties.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnionProperties.cs index 71b5875699..606c4ac6b5 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnionProperties.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnionProperties.cs @@ -21,6 +21,7 @@ public object Bar /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "foo", typeJson: "{\"union\":{\"types\":[{\"primitive\":\"string\"},{\"primitive\":\"number\"}]}}", isOptional: true, isOverride: true)] public object Foo { diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnionPropertiesProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnionPropertiesProxy.cs index 41c79d7eea..cb853c0301 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnionPropertiesProxy.cs +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/UnionPropertiesProxy.cs @@ -24,6 +24,7 @@ public object Bar /// /// stability: Experimental /// + [JsiiOptional] [JsiiProperty(name: "foo", typeJson: "{\"union\":{\"types\":[{\"primitive\":\"string\"},{\"primitive\":\"number\"}]}}", isOptional: true)] public object Foo {