diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2edc408dc4..cbb29cddd2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -52,6 +52,10 @@ jobs: cache: pip - name: Install python3-venv run: sudo apt install -y python3-venv + - name: Set up Ruby 3.3 + uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.3" - name: Cache uses: actions/cache@v6 with: @@ -136,6 +140,10 @@ jobs: cache: pip - name: Install python3-venv run: sudo apt install -y python3-venv + - name: Set up Ruby 3.3 + uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.3" - name: Cache uses: actions/cache@v6 with: @@ -201,6 +209,7 @@ jobs: node: ["20"] # EOS 2026-10-30 os: [ubuntu-latest] python: ["3.10"] + ruby: ["3.3"] # Add specific combinations to be tested against (to restrict cardinality) include: # Test using Windows @@ -211,6 +220,7 @@ jobs: java: "8" node: "20" python: "3.10" + ruby: "3.3" # Test using macOS - title: "macOS" os: macos-latest @@ -219,6 +229,7 @@ jobs: java: "8" node: "20" python: "3.10" + ruby: "3.3" # Test alternate Nodes - title: "Node 20" java: "8" @@ -227,6 +238,7 @@ jobs: node: "20" # EOL 2026-04-30 os: ubuntu-latest python: "3.10" + ruby: "3.3" - title: "Node 22" java: "8" dotnet: "6.0.x" @@ -234,6 +246,7 @@ jobs: node: "22" # EOL 2027-04-30 os: ubuntu-latest python: "3.10" + ruby: "3.3" - title: "Node 24" java: "8" dotnet: "6.0.x" @@ -241,6 +254,7 @@ jobs: node: "24" # EOL 2028-04-30 os: ubuntu-latest python: "3.10" + ruby: "3.3" # Test alternate .NETs - title: ".NET 7.0" java: "8" @@ -249,6 +263,7 @@ jobs: node: "20" os: ubuntu-latest python: "3.10" + ruby: "3.3" - title: ".NET 8.0" java: "8" dotnet: "7.0.x" @@ -256,6 +271,7 @@ jobs: node: "20" os: ubuntu-latest python: "3.10" + ruby: "3.3" - title: ".NET 9.0" java: "8" dotnet: "9.0.x" @@ -263,6 +279,7 @@ jobs: node: "20" os: ubuntu-latest python: "3.10" + ruby: "3.3" - title: ".NET 10.0" java: "8" dotnet: "10.0.x" @@ -270,6 +287,7 @@ jobs: node: "20" os: ubuntu-latest python: "3.10" + ruby: "3.3" # Test alternate Gos - title: "Go 1.25" java: "8" @@ -278,6 +296,7 @@ jobs: node: "20" os: ubuntu-latest python: "3.10" + ruby: "3.3" - title: "Go 1.26" java: "8" dotnet: "6.0.x" @@ -285,6 +304,7 @@ jobs: node: "20" os: ubuntu-latest python: "3.10" + ruby: "3.3" # Test alternate Javas - title: "Java 11" java: "11" @@ -293,6 +313,7 @@ jobs: node: "20" os: ubuntu-latest python: "3.10" + ruby: "3.3" # Test alternate Pythons - title: "Python 3.10" python: "3.10" @@ -301,6 +322,7 @@ jobs: java: "8" node: "20" os: ubuntu-latest + ruby: "3.3" - title: "Python 3.11" python: "3.11" dotnet: "6.0.x" @@ -308,6 +330,7 @@ jobs: java: "8" node: "20" os: ubuntu-latest + ruby: "3.3" - title: "Python 3.12" python: "3.12" dotnet: "6.0.x" @@ -315,6 +338,7 @@ jobs: java: "8" node: "20" os: ubuntu-latest + ruby: "3.3" - title: "Python 3.13" python: "3.13" dotnet: "6.0.x" @@ -322,6 +346,7 @@ jobs: java: "8" node: "20" os: ubuntu-latest + ruby: "3.3" - title: "Python 3.14" python: "3.14" dotnet: "6.0.x" @@ -329,6 +354,25 @@ jobs: java: "8" node: "20" os: ubuntu-latest + ruby: "3.3" + # Test alternate Rubies (3.1/3.2 are EOL and unsupported — + # required_ruby_version is >= 3.3.0; 3.3 itself is the baseline) + - title: "Ruby 3.4" + ruby: "3.4" + dotnet: "6.0.x" + go: "1.25" + java: "8" + node: "20" + os: ubuntu-latest + python: "3.10" + - title: "Ruby 4.0" + ruby: "4.0" + dotnet: "6.0.x" + go: "1.25" + java: "8" + node: "20" + os: ubuntu-latest + python: "3.10" runs-on: ${{ matrix.os }} steps: # Check out the code @@ -380,6 +424,10 @@ jobs: - name: "Linux: Install python3-venv" if: runner.os == 'Linux' run: sudo apt install -y python3-venv + - name: Set up Ruby ${{ matrix.ruby }} + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} - if: runner.os == 'Windows' name: Windows performance improvements run: |- @@ -470,6 +518,10 @@ jobs: python-version: "3.11" - name: Install python3-venv run: sudo apt install -y python3-venv + - name: Set up Ruby 3.3 + uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.3" # Show time! - name: Prepare Work Tree # 1) Install aws-cdk-lib, diff --git a/buildspec.yaml b/buildspec.yaml index 102a4fa941..02c7e274a3 100644 --- a/buildspec.yaml +++ b/buildspec.yaml @@ -2,6 +2,8 @@ version: 0.2 phases: install: + runtime-versions: + ruby: 3.3 commands: - corepack enable - yarn install --immutable diff --git a/gh-pages/content/specification/6-compliance-report.md b/gh-pages/content/specification/6-compliance-report.md index 52fa5f3828..696aee7b5e 100644 --- a/gh-pages/content/specification/6-compliance-report.md +++ b/gh-pages/content/specification/6-compliance-report.md @@ -5,128 +5,128 @@ This section details the current state of each language binding with respect to our standard compliance suite. -| number | test | java (97.56%) | golang (78.86%) | Dotnet | Python | -| ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -------------------------------------------- | ------ | ------ | -| 1 | asyncOverrides_overrideCallsSuper | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | ⭕ | ⭕ | -| 2 | [arrayReturnedByMethodCanBeRead]("Array created in the kernel can be queried for its elements") | 🟢 | 🟢 | ⭕ | ⭕ | -| 3 | [unionProperties]("Kernel values that accept a union type can be set, and are returned with the concrete type") | 🟢 | 🟢 | ⭕ | ⭕ | -| 4 | syncOverrides | 🟢 | 🟢 | ⭕ | ⭕ | -| 5 | [useEnumFromScopedModule]("Property that accepts an enum type from a third-party package can be set, and read") | 🟢 | 🟢 | ⭕ | ⭕ | -| 6 | [createObjectAndCtorOverloads]("Class can be instantiated with empty and non empty constructor") | 🟢 | ⚪ | ⭕ | ⭕ | -| 7 | fail_syncOverrides_callsDoubleAsync_method | 🟢 | 🟢 | ⭕ | ⭕ | -| 8 | collectionOfInterfaces_MapOfStructs | 🟢 | 🟢 | ⭕ | ⭕ | -| 9 | asyncOverrides_overrideAsyncMethod | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | ⭕ | ⭕ | -| 10 | [statics]("Static functions can be invoked and accept and return the correct type") | 🟢 | 🟢 | ⭕ | ⭕ | -| 11 | [structs_returnedLiteralEqualsNativeBuilt]("A struct returned from the kernel is not distinguishable from a struct created natively") | 🟢 | 🟢 | ⭕ | ⭕ | -| 12 | [classesCanSelfReferenceDuringClassInitialization]("Classes can reference other classes during initialization") | 🟢 | 🟢 | ⭕ | ⭕ | -| 13 | [canObtainStructReferenceWithOverloadedSetter]("A class with a settable property of a union type can be returned from the kernel") | 🟢 | 🟢 | ⭕ | ⭕ | -| 14 | [callbacksCorrectlyDeserializeArguments]("Runtime properly deserializes callback arguments from the kernel") | 🟢 | 🟢 | ⭕ | ⭕ | -| 15 | [canUseInterfaceSetters]("Read-write properties generate the corresponding setters in the target language") | 🟢 | 🟢 | ⭕ | ⭕ | -| 16 | [propertyOverrides_interfaces]("Target language can override properties of host interfaces") | 🟢 | 🟢 | ⭕ | ⭕ | -| 17 | syncOverrides_callsSuper | 🟢 | 🟢 | ⭕ | ⭕ | -| 18 | [testJsiiAgent]("Asserts the correct value of the JSII_AGENT env variable for the kernel process") | 🟢 | 🟢 | ⭕ | ⭕ | -| 19 | [doNotOverridePrivates_method_private]("Non public methods on the guest class do not override methods in the host class") | 🟢 | 🟢 | ⭕ | ⭕ | -| 20 | [pureInterfacesCanBeUsedTransparently]("Guest implementation of a pure host interface can be used by host consumers accepting that interface") | 🟢 | 🟢 | ⭕ | ⭕ | -| 21 | [nullShouldBeTreatedAsUndefined]("Null value of target language is treated as undefined by the host") | 🟢 | 🟢 | ⭕ | ⭕ | -| 22 | [primitiveTypes]("All Primitive types are set and read with their respective types") | 🟢 | 🟢 | ⭕ | ⭕ | -| 23 | [reservedKeywordsAreSlugifiedInClassProperties]("TS code that uses reserved words as class property names get slugified so it is usable in the target language") | 🟢 | ⚪ | ⭕ | ⭕ | -| 24 | [objectIdDoesNotGetReallocatedWhenTheConstructorPassesThisOut]("Ensure the JSII kernel can pass 'this' out to JSII remotes from within the constructor") | 🟢 | 🟢 | ⭕ | ⭕ | -| 25 | [interfaceBuilder]("Seems to be a duplicate of 'propertyOverrides_interfaces'?") | 🟢 | 🟢 | ⭕ | ⭕ | -| 26 | unionTypes | 🟢 | 🟢 | ⭕ | ⭕ | -| 27 | arrays | 🟢 | 🟢 | ⭕ | ⭕ | -| 28 | staticMapInClassCannotBeModified | 🟢 | ⚪ | ⭕ | ⭕ | -| 29 | consts | 🟢 | 🟢 | ⭕ | ⭕ | -| 30 | pureInterfacesCanBeUsedTransparently_WhenTransitivelyImplementing | 🟢 | 🟢 | ⭕ | ⭕ | -| 31 | reservedKeywordsAreSlugifiedInMethodNames | 🟢 | ⚪ | ⭕ | ⭕ | -| 32 | exceptions | 🟢 | 🟢 | ⭕ | ⭕ | -| 33 | testLiteralInterface | 🟢 | 🟢 | ⭕ | ⭕ | -| 34 | structs_nonOptionalhashCode | 🟢 | ⚪ | ⭕ | ⭕ | -| 35 | propertyOverrides_set_throws | 🟢 | 🟢 | ⭕ | ⭕ | -| 36 | canLeverageIndirectInterfacePolymorphism | 🟢 | 🟢 | ⭕ | ⭕ | -| 37 | fluentApi | 🟢 | ⚪ | ⭕ | ⭕ | -| 38 | staticListInClassCanBeReadCorrectly | 🟢 | 🟢 | ⭕ | ⭕ | -| 39 | mapReturnedByMethodCannotBeModified | 🟢 | ⚪ | ⭕ | ⭕ | -| 40 | receiveInstanceOfPrivateClass | 🟢 | 🟢 | ⭕ | ⭕ | -| 41 | staticMapInClassCanBeReadCorrectly | 🟢 | 🟢 | ⭕ | ⭕ | -| 42 | testNativeObjectsWithInterfaces | 🟢 | 🟢 | ⭕ | ⭕ | -| 43 | doNotOverridePrivates_property_getter_public | 🟢 | 🟢 | ⭕ | ⭕ | -| 44 | equalsIsResistantToPropertyShadowingResultVariable | 🟢 | 🟢 | ⭕ | ⭕ | -| 45 | listInClassCanBeReadCorrectly | 🟢 | 🟢 | ⭕ | ⭕ | -| 46 | useNestedStruct | 🟢 | 🟢 | ⭕ | ⭕ | -| 47 | testFluentApiWithDerivedClasses | 🟢 | 🟢 | ⭕ | ⭕ | -| 48 | interfacesCanBeUsedTransparently_WhenAddedToJsiiType | 🟢 | 🟢 | ⭕ | ⭕ | -| 49 | canOverrideProtectedGetter | 🟢 | 🟢 | ⭕ | ⭕ | -| 50 | getAndSetEnumValues | 🟢 | 🟢 | ⭕ | ⭕ | -| 51 | structs_nonOptionalequals | 🟢 | 🟢 | ⭕ | ⭕ | -| 52 | testInterfaceParameter | 🟢 | 🟢 | ⭕ | ⭕ | -| 53 | liftedKwargWithSameNameAsPositionalArg | 🟢 | 🟢 | ⭕ | ⭕ | -| 54 | creationOfNativeObjectsFromJavaScriptObjects | 🟢 | [🔴](??) | ⭕ | ⭕ | -| 55 | canOverrideProtectedMethod | 🟢 | 🟢 | ⭕ | ⭕ | -| 56 | canLoadEnumValues | 🟢 | 🟢 | ⭕ | ⭕ | -| 57 | eraseUnsetDataValues | 🟢 | 🟢 | ⭕ | ⭕ | -| 58 | maps | 🟢 | 🟢 | ⭕ | ⭕ | -| 59 | structs_containsNullChecks | 🟢 | [🔴](https://github.com/aws/jsii/issues/2672) | ⭕ | ⭕ | -| 60 | canOverrideProtectedSetter | 🟢 | 🟢 | ⭕ | ⭕ | -| 61 | asyncOverrides_callAsyncMethod | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | ⭕ | ⭕ | -| 62 | nodeStandardLibrary | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | ⭕ | ⭕ | -| 63 | dates | 🟢 | 🟢 | ⭕ | ⭕ | -| 64 | collectionOfInterfaces_ListOfStructs | 🟢 | 🟢 | ⭕ | ⭕ | -| 65 | objRefsAreLabelledUsingWithTheMostCorrectType | 🟢 | 🔴 | ⭕ | ⭕ | -| 66 | unionPropertiesWithBuilder | 🟢 | 🟢 | ⭕ | ⭕ | -| 67 | doNotOverridePrivates_property_getter_private | 🟢 | 🟢 | ⭕ | ⭕ | -| 68 | structs_withDiamondInheritance_correctlyDedupeProperties | 🟢 | 🟢 | ⭕ | ⭕ | -| 69 | abstractMembersAreCorrectlyHandled | 🟢 | 🟢 | ⭕ | ⭕ | -| 70 | doNotOverridePrivates_property_by_name_private | 🟢 | 🟢 | ⭕ | ⭕ | -| 71 | testNullIsAValidOptionalMap | 🟢 | 🟢 | ⭕ | ⭕ | -| 72 | mapReturnedByMethodCanBeRead | 🟢 | 🟢 | ⭕ | ⭕ | -| 73 | structs_multiplePropertiesEquals | 🟢 | 🟢 | ⭕ | ⭕ | -| 74 | mapInClassCanBeReadCorrectly | 🟢 | 🟢 | ⭕ | ⭕ | -| 75 | staticListInClassCannotBeModified | 🟢 | ⚪ | ⭕ | ⭕ | -| 76 | collectionOfInterfaces_MapOfInterfaces | 🟢 | 🟢 | ⭕ | ⭕ | -| 77 | asyncOverrides_overrideThrows | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | ⭕ | ⭕ | -| 78 | callMethods | 🟢 | 🟢 | ⭕ | ⭕ | -| 79 | returnAbstract | 🟢 | 🟢 | ⭕ | ⭕ | -| 80 | dynamicTypes | 🟢 | 🟢 | ⭕ | ⭕ | -| 81 | hashCodeIsResistantToPropertyShadowingResultVariable | 🟢 | ⚪ | ⭕ | ⭕ | -| 82 | returnSubclassThatImplementsInterface976 | 🟢 | 🟢 | ⭕ | ⭕ | -| 83 | structs_optionalEquals | 🟢 | ⚪ | ⭕ | ⭕ | -| 84 | propertyOverrides_get_calls_super | 🟢 | 🟢 | ⭕ | ⭕ | -| 85 | unmarshallIntoAbstractType | 🟢 | 🟢 | ⭕ | ⭕ | -| 86 | structs_multiplePropertiesHashCode | 🟢 | ⚪ | ⭕ | ⭕ | -| 87 | fail_syncOverrides_callsDoubleAsync_propertyGetter | 🟢 | 🟢 | ⭕ | ⭕ | -| 88 | propertyOverrides_get_set | 🟢 | 🟢 | ⭕ | ⭕ | -| 89 | variadicMethodCanBeInvoked | 🟢 | 🟢 | ⭕ | ⭕ | -| 90 | collectionTypes | 🟢 | 🟢 | ⭕ | ⭕ | -| 91 | asyncOverrides_overrideAsyncMethodByParentClass | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | ⭕ | ⭕ | -| 92 | structs_optionalHashCode | 🟢 | ⚪ | ⭕ | ⭕ | -| 93 | testStructsCanBeDowncastedToParentType | 🟢 | 🟢 | ⭕ | ⭕ | -| 94 | propertyOverrides_get_throws | 🟢 | 🟢 | ⭕ | ⭕ | -| 95 | getSetPrimitiveProperties | 🟢 | 🟢 | ⭕ | ⭕ | -| 96 | getAndSetNonPrimitiveProperties | 🟢 | 🟢 | ⭕ | ⭕ | -| 97 | reservedKeywordsAreSlugifiedInStructProperties | 🟢 | 🟢 | ⭕ | ⭕ | -| 98 | fail_syncOverrides_callsDoubleAsync_propertySetter | 🟢 | 🟢 | ⭕ | ⭕ | -| 99 | doNotOverridePrivates_method_public | 🟢 | 🟢 | ⭕ | ⭕ | -| 100 | testNullIsAValidOptionalList | 🟢 | 🟢 | ⭕ | ⭕ | -| 101 | mapInClassCannotBeModified | 🟢 | ⚪ | ⭕ | ⭕ | -| 102 | doNotOverridePrivates_property_by_name_public | 🟢 | 🟢 | ⭕ | ⭕ | -| 103 | asyncOverrides_twoOverrides | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | ⭕ | ⭕ | -| 104 | propertyOverrides_set_calls_super | 🟢 | 🟢 | ⭕ | ⭕ | -| 105 | iso8601DoesNotDeserializeToDate | 🟢 | 🟢 | ⭕ | ⭕ | -| 106 | collectionOfInterfaces_ListOfInterfaces | 🟢 | 🟢 | ⭕ | ⭕ | -| 107 | undefinedAndNull | 🟢 | 🟢 | ⭕ | ⭕ | -| 108 | structs_serializeToJsii | 🟢 | 🟢 | ⭕ | ⭕ | -| 109 | structsAreUndecoratedOntheWayToKernel | 🟢 | 🟢 | ⭕ | ⭕ | -| 110 | canObtainReferenceWithOverloadedSetter | 🟢 | 🟢 | ⭕ | ⭕ | -| 111 | testJSObjectLiteralToNative | 🟢 | 🟢 | ⭕ | ⭕ | -| 112 | structs_stepBuilders | 🟢 | ⚪ | ⭕ | ⭕ | -| 113 | classWithPrivateConstructorAndAutomaticProperties | 🟢 | 🟢 | ⭕ | ⭕ | -| 114 | arrayReturnedByMethodCannotBeModified | 🟢 | ⚪ | ⭕ | ⭕ | -| 115 | correctlyDeserializesStructUnions | 🟢 | 🟢 | ⭕ | ⭕ | -| 116 | subclassing | 🟢 | 🟢 | ⭕ | ⭕ | -| 117 | testInterfaces | 🟢 | 🟢 | ⭕ | ⭕ | -| 118 | [callbackParameterIsInterface]("Validates pure interfaces can be passed to callbacks") | ⭕ | 🟢 | ⭕ | ⭕ | -| 119 | [classCanBeUsedWhenNotExpressedlyLoaded]("Validates that types not explicitly loaded by the user can safely be returned by JS code") | 🟢 | 🟢 | ⭕ | ⭕ | -| 120 | [downcasting]("Ensures unsafe-cast features work as expected") | ⭕ | 🟢 | ⭕ | ⭕ | -| 121 | [strippedDeprecatedMemberCanBeReceived]("Ensures --strip-deprecated does not cause odd runtime errors") | 🟢 | 🟢 | ⭕ | ⭕ | -| 122 | [exceptionMessage]("Verifies that custom exception names are correctly forwarded") | 🟢 | 🟢 | ⭕ | ⭕ | -| 123 | [voidReturningAsync]("Verifies that returning Promise is correctly handled") | ⭕ | ⭕ | ⭕ | ⭕ | +| number | test | java (97.56%) | golang (78.86%) | dotnet (n/a) | python (n/a) | ruby (100.00%) | +| ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -------------------------------------------- | ------------ | ------------ | -------------- | +| 1 | asyncOverrides_overrideCallsSuper | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | n/a | n/a | 🟢 | +| 2 | [arrayReturnedByMethodCanBeRead]("Array created in the kernel can be queried for its elements") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 3 | [unionProperties]("Kernel values that accept a union type can be set, and are returned with the concrete type") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 4 | syncOverrides | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 5 | [useEnumFromScopedModule]("Property that accepts an enum type from a third-party package can be set, and read") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 6 | [createObjectAndCtorOverloads]("Class can be instantiated with empty and non empty constructor") | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 7 | fail_syncOverrides_callsDoubleAsync_method | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 8 | collectionOfInterfaces_MapOfStructs | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 9 | asyncOverrides_overrideAsyncMethod | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | n/a | n/a | 🟢 | +| 10 | [statics]("Static functions can be invoked and accept and return the correct type") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 11 | [structs_returnedLiteralEqualsNativeBuilt]("A struct returned from the kernel is not distinguishable from a struct created natively") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 12 | [classesCanSelfReferenceDuringClassInitialization]("Classes can reference other classes during initialization") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 13 | [canObtainStructReferenceWithOverloadedSetter]("A class with a settable property of a union type can be returned from the kernel") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 14 | [callbacksCorrectlyDeserializeArguments]("Runtime properly deserializes callback arguments from the kernel") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 15 | [canUseInterfaceSetters]("Read-write properties generate the corresponding setters in the target language") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 16 | [propertyOverrides_interfaces]("Target language can override properties of host interfaces") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 17 | syncOverrides_callsSuper | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 18 | [testJsiiAgent]("Asserts the correct value of the JSII_AGENT env variable for the kernel process") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 19 | [doNotOverridePrivates_method_private]("Non public methods on the guest class do not override methods in the host class") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 20 | [pureInterfacesCanBeUsedTransparently]("Guest implementation of a pure host interface can be used by host consumers accepting that interface") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 21 | [nullShouldBeTreatedAsUndefined]("Null value of target language is treated as undefined by the host") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 22 | [primitiveTypes]("All Primitive types are set and read with their respective types") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 23 | [reservedKeywordsAreSlugifiedInClassProperties]("TS code that uses reserved words as class property names get slugified so it is usable in the target language") | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 24 | [objectIdDoesNotGetReallocatedWhenTheConstructorPassesThisOut]("Ensure the JSII kernel can pass 'this' out to JSII remotes from within the constructor") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 25 | [interfaceBuilder]("Seems to be a duplicate of 'propertyOverrides_interfaces'?") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 26 | unionTypes | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 27 | arrays | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 28 | staticMapInClassCannotBeModified | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 29 | consts | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 30 | pureInterfacesCanBeUsedTransparently_WhenTransitivelyImplementing | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 31 | reservedKeywordsAreSlugifiedInMethodNames | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 32 | exceptions | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 33 | testLiteralInterface | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 34 | structs_nonOptionalhashCode | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 35 | propertyOverrides_set_throws | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 36 | canLeverageIndirectInterfacePolymorphism | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 37 | fluentApi | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 38 | staticListInClassCanBeReadCorrectly | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 39 | mapReturnedByMethodCannotBeModified | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 40 | receiveInstanceOfPrivateClass | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 41 | staticMapInClassCanBeReadCorrectly | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 42 | testNativeObjectsWithInterfaces | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 43 | doNotOverridePrivates_property_getter_public | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 44 | equalsIsResistantToPropertyShadowingResultVariable | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 45 | listInClassCanBeReadCorrectly | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 46 | useNestedStruct | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 47 | testFluentApiWithDerivedClasses | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 48 | interfacesCanBeUsedTransparently_WhenAddedToJsiiType | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 49 | canOverrideProtectedGetter | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 50 | getAndSetEnumValues | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 51 | structs_nonOptionalequals | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 52 | testInterfaceParameter | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 53 | liftedKwargWithSameNameAsPositionalArg | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 54 | creationOfNativeObjectsFromJavaScriptObjects | 🟢 | [🔴](??) | n/a | n/a | 🟢 | +| 55 | canOverrideProtectedMethod | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 56 | canLoadEnumValues | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 57 | eraseUnsetDataValues | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 58 | maps | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 59 | structs_containsNullChecks | 🟢 | [🔴](https://github.com/aws/jsii/issues/2672) | n/a | n/a | 🟢 | +| 60 | canOverrideProtectedSetter | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 61 | asyncOverrides_callAsyncMethod | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | n/a | n/a | 🟢 | +| 62 | nodeStandardLibrary | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | n/a | n/a | 🟢 | +| 63 | dates | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 64 | collectionOfInterfaces_ListOfStructs | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 65 | objRefsAreLabelledUsingWithTheMostCorrectType | 🟢 | 🔴 | n/a | n/a | 🟢 | +| 66 | unionPropertiesWithBuilder | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 67 | doNotOverridePrivates_property_getter_private | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 68 | structs_withDiamondInheritance_correctlyDedupeProperties | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 69 | abstractMembersAreCorrectlyHandled | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 70 | doNotOverridePrivates_property_by_name_private | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 71 | testNullIsAValidOptionalMap | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 72 | mapReturnedByMethodCanBeRead | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 73 | structs_multiplePropertiesEquals | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 74 | mapInClassCanBeReadCorrectly | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 75 | staticListInClassCannotBeModified | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 76 | collectionOfInterfaces_MapOfInterfaces | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 77 | asyncOverrides_overrideThrows | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | n/a | n/a | 🟢 | +| 78 | callMethods | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 79 | returnAbstract | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 80 | dynamicTypes | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 81 | hashCodeIsResistantToPropertyShadowingResultVariable | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 82 | returnSubclassThatImplementsInterface976 | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 83 | structs_optionalEquals | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 84 | propertyOverrides_get_calls_super | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 85 | unmarshallIntoAbstractType | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 86 | structs_multiplePropertiesHashCode | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 87 | fail_syncOverrides_callsDoubleAsync_propertyGetter | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 88 | propertyOverrides_get_set | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 89 | variadicMethodCanBeInvoked | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 90 | collectionTypes | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 91 | asyncOverrides_overrideAsyncMethodByParentClass | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | n/a | n/a | 🟢 | +| 92 | structs_optionalHashCode | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 93 | testStructsCanBeDowncastedToParentType | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 94 | propertyOverrides_get_throws | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 95 | getSetPrimitiveProperties | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 96 | getAndSetNonPrimitiveProperties | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 97 | reservedKeywordsAreSlugifiedInStructProperties | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 98 | fail_syncOverrides_callsDoubleAsync_propertySetter | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 99 | doNotOverridePrivates_method_public | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 100 | testNullIsAValidOptionalList | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 101 | mapInClassCannotBeModified | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 102 | doNotOverridePrivates_property_by_name_public | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 103 | asyncOverrides_twoOverrides | 🟢 | [🔴](https://github.com/aws/jsii/issues/2670) | n/a | n/a | 🟢 | +| 104 | propertyOverrides_set_calls_super | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 105 | iso8601DoesNotDeserializeToDate | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 106 | collectionOfInterfaces_ListOfInterfaces | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 107 | undefinedAndNull | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 108 | structs_serializeToJsii | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 109 | structsAreUndecoratedOntheWayToKernel | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 110 | canObtainReferenceWithOverloadedSetter | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 111 | testJSObjectLiteralToNative | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 112 | structs_stepBuilders | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 113 | classWithPrivateConstructorAndAutomaticProperties | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 114 | arrayReturnedByMethodCannotBeModified | 🟢 | ⚪ | n/a | n/a | 🟢 | +| 115 | correctlyDeserializesStructUnions | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 116 | subclassing | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 117 | testInterfaces | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 118 | [callbackParameterIsInterface]("Validates pure interfaces can be passed to callbacks") | ⭕ | 🟢 | n/a | n/a | 🟢 | +| 119 | [classCanBeUsedWhenNotExpressedlyLoaded]("Validates that types not explicitly loaded by the user can safely be returned by JS code") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 120 | [downcasting]("Ensures unsafe-cast features work as expected") | ⭕ | 🟢 | n/a | n/a | 🟢 | +| 121 | [strippedDeprecatedMemberCanBeReceived]("Ensures --strip-deprecated does not cause odd runtime errors") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 122 | [exceptionMessage]("Verifies that custom exception names are correctly forwarded") | 🟢 | 🟢 | n/a | n/a | 🟢 | +| 123 | [voidReturningAsync]("Verifies that returning Promise is correctly handled") | ⭕ | ⭕ | n/a | n/a | 🟢 | diff --git a/packages/@jsii/kernel/src/kernel.test.ts b/packages/@jsii/kernel/src/kernel.test.ts index 2ff90ab319..25cbc531f9 100644 --- a/packages/@jsii/kernel/src/kernel.test.ts +++ b/packages/@jsii/kernel/src/kernel.test.ts @@ -410,6 +410,10 @@ defineTest( module: 'jsii_calc', classifiers: ['Test :: Classifier :: Is Dummy'], }, + ruby: { + gem: 'jsii-calc', + module: 'JsiiCalc', + }, }); expect(sandbox.naming({ assembly: '@scope/jsii-calc-lib' }).naming).toEqual( { @@ -435,6 +439,10 @@ defineTest( distName: 'scope.jsii-calc-lib', module: 'scope.jsii_calc_lib', }, + ruby: { + gem: 'scope-jsii-calc-lib', + module: 'Scope::JsiiCalcLib', + }, }, ); }, diff --git a/packages/@jsii/ruby-runtime-test/.gitignore b/packages/@jsii/ruby-runtime-test/.gitignore new file mode 100644 index 0000000000..83375afa8c --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/.gitignore @@ -0,0 +1,2 @@ +lib/ +compliance-report.json diff --git a/packages/@jsii/ruby-runtime-test/Gemfile b/packages/@jsii/ruby-runtime-test/Gemfile new file mode 100644 index 0000000000..a0bf36b712 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/Gemfile @@ -0,0 +1,6 @@ +source 'https://rubygems.org' + +gem 'jsii-ruby-runtime', path: '../ruby-runtime' +gem 'rspec', '~> 3.12' +# Used by spec/unit/rbs_spec.rb to validate the generator's emitted `sig/*.rbs`. +gem 'rbs', '~> 3.4' diff --git a/packages/@jsii/ruby-runtime-test/Gemfile.lock b/packages/@jsii/ruby-runtime-test/Gemfile.lock new file mode 100644 index 0000000000..ac68e2af34 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/Gemfile.lock @@ -0,0 +1,54 @@ +PATH + remote: ../ruby-runtime + specs: + jsii-ruby-runtime (0.0.0) + base64 (~> 0.2) + +GEM + remote: https://rubygems.org/ + specs: + base64 (0.3.0) + diff-lcs (1.6.2) + logger (1.7.0) + rbs (3.10.4) + logger + tsort + rspec (3.13.2) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.6) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.8) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.7) + tsort (0.2.0) + +PLATFORMS + ruby + x86_64-linux + +DEPENDENCIES + jsii-ruby-runtime! + rbs (~> 3.4) + rspec (~> 3.12) + +CHECKSUMS + base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962 + jsii-ruby-runtime (0.0.0) + logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + rbs (3.10.4) sha256=b17d7c4be4bb31a11a3b529830f0aa206a807ca42f2e7921a3027dfc6b7e5ce8 + rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587 + rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d + rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836 + rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47 + rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c + tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f + +BUNDLED WITH + 2.6.9 diff --git a/packages/@jsii/ruby-runtime-test/generate.sh b/packages/@jsii/ruby-runtime-test/generate.sh new file mode 100644 index 0000000000..7b1ab9aeb6 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/generate.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# Generate the Ruby bindings for the jsii-calc fixture assemblies into ./lib, +# where spec/spec_helper.rb expects to find them. Invoked by `yarn build`. +# +# `yarn test` runs this every time, unconditionally — do NOT reintroduce a +# `test -d ./lib || ...` guard. lib/ is gitignored generated output; when it is +# present but stale (built by an older pacmak/rosetta) such a guard silently +# runs the specs against months-old bindings and reports phantom failures. This +# script is only a few seconds, so always regenerating is the safe default. +set -euo pipefail + +genRoot="./lib" + +# Clean up any previously-generated bindings so stale types don't linger when +# an assembly is removed or renamed upstream. +rm -rf "${genRoot}" + +# `--code-only` skips `gem build`, which would require Ruby + RubyGems to be +# present in every environment that runs `yarn build`. The runtime tests do +# not consume a built .gem — they load the generated sources under lib/ +# directly via $LOAD_PATH (see spec/spec_helper.rb). +# +# `--recurse` pacmaks jsii-calc *and* the whole dependency closure +# (@scope/jsii-calc-{lib,base,base-of-base}), so we only need to pass the +# top-level assembly here. +yarn jsii-pacmak -t ruby --code-only --recurse -o "${genRoot}" ../../jsii-calc diff --git a/packages/@jsii/ruby-runtime-test/package.json b/packages/@jsii/ruby-runtime-test/package.json new file mode 100644 index 0000000000..ce50bd4454 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/package.json @@ -0,0 +1,35 @@ +{ + "name": "@jsii/ruby-runtime-test", + "version": "0.0.0", + "private": true, + "description": "Tests for the Ruby client for jsii runtime", + "license": "Apache-2.0", + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com" + }, + "homepage": "https://github.com/aws/jsii", + "bugs": { + "url": "https://github.com/aws/jsii/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/jsii.git", + "directory": "packages/@jsii/ruby-runtime-test" + }, + "engines": { + "node": ">= 14.17.0" + }, + "scripts": { + "build": "bash ./generate.sh", + "test": "bash -c 'bash ./generate.sh && bundle install --quiet && bundle exec rspec --require ./spec/compliance_formatter.rb --format ComplianceFormatter --format progress'" + }, + "devDependencies": { + "@jsii/ruby-runtime": "^0.0.0", + "@scope/jsii-calc-base": "^0.0.0", + "@scope/jsii-calc-base-of-base": "^2.1.1", + "@scope/jsii-calc-lib": "^0.0.0", + "jsii-calc": "^3.20.120", + "jsii-pacmak": "^0.0.0" + } +} diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/abstract_types_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/abstract_types_spec.rb new file mode 100644 index 0000000000..7468e91732 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/abstract_types_spec.rb @@ -0,0 +1,130 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Suite tests: abstractMembersAreCorrectlyHandled, returnAbstract, +# unmarshallIntoAbstractType. +# +# Abstractness only exists at the TypeScript level — on the wire there are +# just object refs and member names, and the Ruby proxy generated for an +# abstract class has a concrete forwarding stub for *every* member (abstract +# or not). These tests verify both directions: a guest subclass supplying +# the abstract members to a host driver (abstractMembersAreCorrectlyHandled, +# via callbacks), and the kernel returning values *declared* as abstract +# types (returnAbstract, unmarshallIntoAbstractType). +RSpec.describe 'JSII compliance: abstract types' do + it 'handles abstract properties and methods correctly', compliance: 'abstractMembersAreCorrectlyHandled' do + klass = Class.new(JsiiCalc::AbstractSuite) do + def initialize + super + @property_val = nil + end + + def some_method(str) + "Wrapped<#{str}>" + end + + def property + @property_val + end + + def property=(value) + @property_val = "String<#{value}>" + end + end + + abstract_suite = klass.new + expect(abstract_suite.work_it_all('Oomf!')).to eq('Wrapped>') + end + + # The TS fixture (jsii-calc/lib/compliance.ts) behind this test: + # + # export abstract class AbstractClassBase { abstract readonly abstractProperty: string; } + # export abstract class AbstractClass extends AbstractClassBase + # implements IInterfaceImplementedByAbstractClass { ... } + # class ConcreteClass extends AbstractClass { ... } // NOT exported! + # export class AbstractClassReturner { + # giveMeAbstract(): AbstractClass { return new ConcreteClass(); } + # giveMeInterface(): IInterfaceImplementedByAbstractClass { return new ConcreteClass(); } + # get returnAbstractFromProperty(): AbstractClassBase { + # return { abstractProperty: 'hello-abstract-property' }; // plain object literal! + # } + # } + # + # This exercises three progressively nastier hydration cases — see the + # inline comments. In all of them the key trick is that + # Registry#build_uninitialized_instance hydrates refs with `klass.allocate` + # (NOT `klass.new`), so no constructor runs and "you cannot instantiate an + # abstract class" never comes up. + it 'returns abstract classes and interfaces from the kernel', compliance: 'returnAbstract' do + obj = JsiiCalc::AbstractClassReturner.new + + # Case 1: the kernel returns an instance of *unexported* ConcreteClass, + # declared as the *abstract* AbstractClass. ConcreteClass isn't in the + # assembly, so the kernel labels the ref with the nearest exported + # ancestor: `$jsii.byref: "jsii-calc.AbstractClass@..."`. The registry + # resolves that fqn to the generated JsiiCalc::AbstractClass proxy and + # allocates it without calling initialize. + obj2 = obj.give_me_abstract + + # Calls through the abstract proxy are plain virtual dispatch in JS: the + # kernel invokes the member on the *real* object, so ConcreteClass's + # implementation of the abstract method runs... + expect(obj2.abstract_method('John')).to eq('Hello, John!!') + # ...the interface-provided getter on AbstractClass answers a `get`... + expect(obj2.prop_from_interface).to eq('propFromInterfaceValue') + # ...and the inherited non-abstract base implementation works too. + expect(obj2.non_abstract_method).to eq(42) + + # Case 2: same ConcreteClass instance, but the declared return type is a + # pure interface. Interface fqns register as Ruby *modules*, which can't + # be allocated — the registry builds `Jsii::Object.allocate.extend(mod)` + # instead, so the module's forwarding stubs (and is_a? checks) work. + iface = obj.give_me_interface + expect(iface.prop_from_interface).to eq('propFromInterfaceValue') + + # Case 3: the JS getter returns a plain `{ abstractProperty: ... }` + # object literal — no class at all. The kernel still wraps it in a ref, + # but labels it "Object"; Registry#jsii_deserialize's fallback chain + # (`$jsii.interfaces`.first, then the ref's fqn prefix) picks the declared + # abstract type so the property read can be forwarded. + expect(obj.return_abstract_from_property.abstract_property).to eq('hello-abstract-property') + end + + it 'unmarshalls values into abstract types', compliance: 'unmarshallIntoAbstractType' do + calc = JsiiCalc::Calculator.new + calc.add(120) + expect(calc.curr.value).to eq(120) + end + + describe 'abstract types (extended)' do + # The jsii-relevant part of subclassing an abstract host class is + # construction: the kernel must instantiate an *abstract* fqn on behalf + # of the guest by synthesizing a JS subclass, with the guest's overrides + # registered (see object/overrides.rb). Calling the overridden members + # from Ruby would only exercise plain Ruby dispatch — host-driven + # callback dispatch is covered by abstractMembersAreCorrectlyHandled + # above — so instead we call the members the guest did NOT override: + # those go through the generated forwarding stubs to the kernel, proving + # the instance is live on the JS side. + it 'can construct native subclasses of abstract host classes' do + klass = Class.new(JsiiCalc::AbstractClass) do + def abstract_method(name) + "Hello, #{name}!" + end + + def abstract_property + 'native-abstract-property' + end + end + + obj = klass.new + expect(obj.jsii_ref).not_to be_nil + + # Non-overridden members dispatch through the kernel to the host + # implementations on AbstractClass. + expect(obj.non_abstract_method).to eq(42) + expect(obj.prop_from_interface).to eq('propFromInterfaceValue') + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/async_overrides_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/async_overrides_spec.rb new file mode 100644 index 0000000000..4b491f2e9e --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/async_overrides_spec.rb @@ -0,0 +1,156 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Suite tests: asyncOverrides_*, voidReturningAsync. +# +# Same callback dance as sync_overrides_spec.rb, but for `async` host +# methods, which use the kernel's begin/end API instead of `invoke`: `begin` +# starts the promise, callbacks for guest overrides are delivered while it's +# in flight, and `end` collects the settled result. From Ruby the whole +# thing still looks synchronous. Covered: plain override, override inherited +# from a parent class, override calling super, two overrides on one object, +# guest exceptions propagating back through the host promise +# (asyncOverrides_overrideThrows), and Promise resolving to nil. +# +# Every magic number below falls out of the host fixture +# (jsii-calc/lib/compliance.ts): +# +# export class AsyncVirtualMethods { +# async callMe() { +# return (await this.overrideMe(10)) + this.dontOverrideMe() +# + (await this.overrideMeToo()); +# } +# async overrideMe(mult) { return 12 * mult; } // default impl +# async overrideMeToo() { return 0; } // default impl +# dontOverrideMe() { return 8; } +# } +# +# i.e. call_me == overrideMe(10) + 8 + overrideMeToo() +# +# where each override* term is answered by the Ruby override (via callback) +# when one was registered at construction, and by the JS default when not. +# +# The OverrideAsyncMethodsByBaseClass, OverrideCallsSuper and TwoOverrides +# fixture classes are defined in spec/support/fixtures.rb. +RSpec.describe 'JSII compliance: async overrides' do + it 'calls async methods synchronously from Ruby', compliance: 'asyncOverrides_callAsyncMethod' do + # No subclass, no overrides: everything runs in JS with the defaults. + obj = JsiiCalc::AsyncVirtualMethods.new + # call_me = overrideMe(10) + 8 + overrideMeToo() = 120 + 8 + 0 + expect(obj.call_me()).to eq(128) + # Direct kernel invoke of the default implementation: 12 * 44. + expect(obj.override_me(44)).to eq(528) + end + + it 'invokes guest overrides of async methods', compliance: 'asyncOverrides_overrideAsyncMethod' do + class MyOverride < JsiiCalc::AsyncVirtualMethods + def override_me(mult) + mult * 2 + end + end + obj = MyOverride.new + # callMe runs in JS; its `await this.overrideMe(10)` is delivered back to + # Ruby as a callback (the override was registered with the kernel at + # construction), so the first term is 10 * 2 = 20 instead of the default + # 120: call_me = 20 + 8 + 0. + expect(obj.call_me()).to eq(28) + end + + it 'invokes async overrides inherited from a parent class', compliance: 'asyncOverrides_overrideAsyncMethodByParentClass' do + # The fixture's override ignores `mult` and delegates to a plain Ruby + # helper (`foo`, returning 2222) — proving the callback runs in a real + # Ruby context with access to the whole object, not some detached shim: + # call_me = (2222 * 2) + 8 + 0 = 4452. + obj = OverrideAsyncMethodsByBaseClass.new + expect(obj.call_me).to eq(4452) + end + + it 'lets async overrides call super', compliance: 'asyncOverrides_overrideCallsSuper' do + # The fixture's override is `super(mult) * 10 + 1`. `super` lands on the + # generated forwarding stub, i.e. a kernel invoke — and the kernel knows + # this client owns the override, so a client-initiated invoke of an + # overridden member runs the *original JS implementation* instead of + # bouncing back as a callback (that's how cross-boundary super avoids + # infinite ping-pong). + obj = OverrideCallsSuper.new + # Called directly from Ruby: super(12) = 144, then 144 * 10 + 1. + expect(obj.override_me(12)).to eq(1441) + # Driven by JS: callMe → callback overrideMe(10) → super(10) = 120 → + # 120 * 10 + 1 = 1201, then call_me = 1201 + 8 + 0. + expect(obj.call_me).to eq(1209) + end + + it 'supports two simultaneous async overrides', compliance: 'asyncOverrides_twoOverrides' do + # Both await-ed terms answered by Ruby callbacks within one `begin`/`end` + # cycle: call_me = 666 + 8 + 10. + obj = TwoOverrides.new + expect(obj.call_me).to eq(684) + end + + it 'propagates exceptions raised in async overrides', compliance: 'asyncOverrides_overrideThrows' do + klass = Class.new(JsiiCalc::AsyncVirtualMethods) do + def override_me(mult) + raise 'Thrown by native code' + end + end + + obj = klass.new + # The callback's failure is reported back to the kernel, which rejects + # the host-side callMe promise; `end` then surfaces the rejection as a + # Jsii::RuntimeError carrying the original message. + expect { obj.call_me }.to raise_error(Jsii::RuntimeError, /Thrown by native code/) + end + + it 'handles Promise-returning async methods', compliance: 'voidReturningAsync' do + # Promise resolves to `undefined`, which deserializes to nil. + expect(JsiiCalc::PromiseNothing.new.instance_promise_it).to be_nil + end + + describe 'async overrides (extended)' do + it 'can override async methods while keeping non-overridden ones intact' do + class OverrideAsyncMethods < JsiiCalc::AsyncVirtualMethods + def override_me(mult) + mult * 2 + end + + def dont_override_me + 8 + end + + def override_me_too + 0 + end + end + + obj = OverrideAsyncMethods.new + # call_me = (10 * 2) + 8 + 0 = 28. Note the Ruby dont_override_me also + # returns 8, so the sum is 28 whether or not the kernel (incorrectly) + # routed that term through the override — the middle term's *source* is + # not distinguishable here, only the override of overrideMe is. + expect(obj.call_me()).to eq(28) + # Plain Ruby dispatch (no kernel involved): 44 * 2. + expect(obj.override_me(44)).to eq(88) + end + + it 'propagates ArgumentError from an async override (not just StandardError)' do + klass = Class.new(JsiiCalc::AsyncVirtualMethods) do + def override_me(mult) + raise ArgumentError, 'argument blew up' + end + end + + expect { klass.new.call_me }.to raise_error(Jsii::RuntimeError, /argument blew up/) + end + + it 'propagates TypeError from an async override' do + klass = Class.new(JsiiCalc::AsyncVirtualMethods) do + def override_me(mult) + raise TypeError, 'wrong type' + end + end + + expect { klass.new.call_me }.to raise_error(Jsii::RuntimeError, /wrong type/) + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/classes_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/classes_spec.rb new file mode 100644 index 0000000000..053b4c9de3 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/classes_spec.rb @@ -0,0 +1,263 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'date' + +# Suite tests: createObjectAndCtorOverloads, getSetPrimitiveProperties, +# getAndSetNonPrimitiveProperties, callMethods, statics, consts, subclassing, +# classWithPrivateConstructorAndAutomaticProperties, +# classesCanSelfReferenceDuringClassInitialization, +# objectIdDoesNotGetReallocatedWhenTheConstructorPassesThisOut, +# objRefsAreLabelledUsingWithTheMostCorrectType, receiveInstanceOfPrivateClass, +# classCanBeUsedWhenNotExpressedlyLoaded, downcasting, +# variadicMethodCanBeInvoked, fluentApi, testFluentApiWithDerivedClasses. +# +# Object lifecycle. Constructor overloads, method calls, property get/set, +# statics/consts, native subclassing and factory methods for classes with +# private constructors. The deep-machinery tests stress the *pending-object +# window*: during a kernel `create` request, the JS constructor may call back +# into Ruby with a reference to an object that hasn't been registered yet — +# Registry#find_by_ref falls back to Kernel#pending_object so `self` +# identity holds (classesCanSelfReferenceDuringClassInitialization, +# objectIdDoesNotGetReallocated...). objRefsAreLabelledUsingWithTheMostCorrectType +# pins the kernel labelling rule for unexported types: a ref is tagged with +# the nearest *exported* ancestor class (or implemented interface), which is +# what makes the abstract-type tests possible at all. `downcasting` covers +# the explicit Jsii.downcast unsafe-cast escape hatch. +RSpec.describe 'JSII compliance: classes and objects' do + it 'instantiates classes with empty and non-empty constructors', compliance: 'createObjectAndCtorOverloads' do + JsiiCalc::Calculator.new + JsiiCalc::Calculator.new(maximum_value: 10) + end + + it 'gets and sets primitive properties', compliance: 'getSetPrimitiveProperties' do + number = Scope::JsiiCalcLib::Number.new(20) + expect(number.value).to eq(20) + expect(number.double_value).to eq(40) + + expect(JsiiCalc::Negate.new(JsiiCalc::Add.new(Scope::JsiiCalcLib::Number.new(20), Scope::JsiiCalcLib::Number.new(10))).value).to eq(-30) + end + + it 'gets and sets non-primitive properties', compliance: 'getAndSetNonPrimitiveProperties' do + calc = JsiiCalc::Calculator.new + calc.add(3_200_000) + calc.neg() + calc.curr = JsiiCalc::Multiply.new(Scope::JsiiCalcLib::Number.new(2), calc.curr) + expect(calc.value).to eq(-6_400_000) + end + + it 'calls methods on host objects', compliance: 'callMethods' do + calc = JsiiCalc::Calculator.new + calc.add(10) + expect(calc.value).to eq(10) + + calc.mul(2) + expect(calc.value).to eq(20) + + calc.pow(5) + expect(calc.value).to eq(20**5) + + calc.neg() + expect(calc.value).to eq(-(20**5)) + end + + it 'invokes static methods and mutates static properties', compliance: 'statics' do + expect(JsiiCalc::Statics.static_method('Yoyo')).to eq('hello ,Yoyo!') + expect(JsiiCalc::Statics.instance.value).to eq('default') + + new_statics = JsiiCalc::Statics.new('new value') + JsiiCalc::Statics.instance = new_statics + + expect(JsiiCalc::Statics.instance.value).to eq('new value') + expect(JsiiCalc::Statics.non_const_static).to eq(100) + + # reset back to default for other tests + JsiiCalc::Statics.instance = JsiiCalc::Statics.new('default') + end + + it 'exposes constants', compliance: 'consts' do + # const properties take an UPPER_SNAKE_CASE form in Ruby (matches Python's + # `toPythonPropertyName(name, constant=true)`) so they don't collide with + # a sibling snake_case property of the same lowercased name. + expect(JsiiCalc::Statics.FOO).to eq('hello') + expect(JsiiCalc::Statics.CONST_OBJ.hello).to eq('world') + expect(JsiiCalc::Statics.BAR).to eq(1234) + expect(JsiiCalc::Statics.ZOO_BAR['hello']).to eq('world') + end + + it 'supports native subclasses of host classes', compliance: 'subclassing' do + calc = JsiiCalc::Calculator.new + calc.curr = AddTen.new(33) + calc.neg + expect(calc.value).to eq(-43) + end + + it 'supports factory methods on classes with private constructors', compliance: 'classWithPrivateConstructorAndAutomaticProperties' do + obj = JsiiCalc::ClassWithPrivateConstructorAndAutomaticProperties.create('Hello', 'Bye') + expect(obj.read_write_string).to eq('Bye') + expect(obj.read_only_string).to eq('Hello') + end + + it 'lets classes reference themselves during initialization', compliance: 'classesCanSelfReferenceDuringClassInitialization' do + klass = Class.new(JsiiCalc::Isomorphism) do + include RSpec::Matchers + def initialize + super + expect(self).to be(self.myself) + end + end + klass.new + end + + it 'does not reallocate the object id when the constructor passes this out', compliance: 'objectIdDoesNotGetReallocatedWhenTheConstructorPassesThisOut' do + klass = Class.new(JsiiCalc::PartiallyInitializedThisConsumer) do + include RSpec::Matchers + def consume_partially_initialized_this(obj, dt, ev) + expect(obj).not_to be_nil + expect(dt).to be_a(DateTime) + expect(ev).to eq(JsiiCalc::AllTypesEnum::THIS_IS_GREAT) + 'OK' + end + end + + reflector = klass.new + obj = JsiiCalc::ConstructorPassesThisOut.new(reflector) + expect(obj).not_to be_nil + end + + # "Most correct" means: the most *derived* type that is still visible in + # the assembly. The fixture hierarchy (jsii-calc/lib/compliance.ts): + # + # PublicClass (exported) + # └── InbetweenClass (exported, implements IPublicInterface2) + # └── PrivateClass (NOT exported, implements IPublicInterface) + # + # `Constructors.makeClass()` is *declared* to return PublicClass but + # *actually* returns a PrivateClass. Neither end of the spectrum is a + # valid label for the ref: + # + # - the declared type (PublicClass) is too general — the proxy would + # lose capabilities the object really has (ciao(), from + # InbetweenClass/IPublicInterface2), and is_a? checks would lie; + # - the runtime type (PrivateClass) is too specific — it isn't in the + # assembly, so no client has a generated proxy for it. + # + # The kernel must therefore label the ref with the nearest *exported* + # ancestor, InbetweenClass, plus any exported interfaces the instance + # implements beyond it (IPublicInterface, which only PrivateClass adds). + # Ruby-side, Registry#jsii_deserialize trusts that label to pick the proxy + # class. + it 'labels object references with the most correct type', compliance: 'objRefsAreLabelledUsingWithTheMostCorrectType' do + class_ref = JsiiCalc::Constructors.make_class() + iface_ref = JsiiCalc::Constructors.make_interface() + + # Declared PublicClass, hydrated as the more-derived exported ancestor... + expect(class_ref).to be_a(JsiiCalc::InbetweenClass) + # ...which gives the proxy capabilities the declared type doesn't have. + expect(class_ref.ciao).to eq('ciao') + + # Declared IPublicInterface — a capability InbetweenClass does NOT + # carry, so the labelling must preserve the interface for the proxy to + # be able to dispatch bye(). + expect(iface_ref).not_to be_nil + expect(iface_ref.bye).to eq('bye') + end + + it 'receives instances of private classes', compliance: 'receiveInstanceOfPrivateClass' do + expect(JsiiCalc::ReturnsPrivateImplementationOfInterface.new.private_implementation.success).to be true + end + + it 'safely returns types not expressly loaded by the user', compliance: 'classCanBeUsedWhenNotExpressedlyLoaded' do + klass = Class.new(JsiiCalc::Cdk16625::Cdk16625) do + def unwrap(gen) + gen.next + end + end + # This should NOT throw + expect { klass.new.test }.not_to raise_error + end + + it 'supports unsafe casts via Jsii.downcast', compliance: 'downcasting' do + any_value = JsiiCalc::SomeTypeJsii976.return_anonymous + real_value = Jsii.downcast(any_value, JsiiCalc::IReturnJsii976) + expect(real_value.foo).to eq(1337) + end + + it 'invokes variadic methods', compliance: 'variadicMethodCanBeInvoked' do + variadic = JsiiCalc::VariadicMethod.new(1) + expect(variadic.as_array(3, 4, 5, 6)).to eq([1, 3, 4, 5, 6]) + end + + it 'supports fluent-style construction', compliance: 'fluentApi' do + calc3 = JsiiCalc::Calculator.new(initial_value: 20, maximum_value: 30) + calc3.add(3) + expect(calc3.value).to eq(23) + end + + it 'supports fluent API with derived classes', compliance: 'testFluentApiWithDerivedClasses' do + derived_from_all_types_class = Class.new(JsiiCalc::AllTypes) + obj = derived_from_all_types_class.new + obj.string_property = 'Hello' + obj.number_property = 12 + + expect(obj.string_property).to eq('Hello') + expect(obj.number_property).to eq(12) + end + + describe 'calculator behavior (extended)' do + it 'supports Power operations' do + expect(JsiiCalc::Power.new(Scope::JsiiCalcLib::Number.new(3), Scope::JsiiCalcLib::Number.new(4)).value).to eq(3**4) + expect(JsiiCalc::Power.new(Scope::JsiiCalcLib::Number.new(999), Scope::JsiiCalcLib::Number.new(1)).value).to eq(999) + expect(JsiiCalc::Power.new(Scope::JsiiCalcLib::Number.new(999), Scope::JsiiCalcLib::Number.new(0)).value).to eq(1) + end + + it 'supports Multiply' do + expect(JsiiCalc::Multiply.new( + JsiiCalc::Add.new(Scope::JsiiCalcLib::Number.new(5), Scope::JsiiCalcLib::Number.new(5)), + Scope::JsiiCalcLib::Number.new(2) + ).value).to eq(20) + end + end + + describe 'static inheritance (extended)' do + # jsii's StaticHello fixture documents the design fork: ES6 inherits + # statics through the class hierarchy, Java does not. Ruby naturally + # matches ES6 — singleton methods inherit — so the generator emits a + # static only on its *defining* class and lets Ruby inheritance (and the + # kernel's base-chain lookup) do the rest. + it 'resolves inherited statics through singleton-method inheritance' do + # makeInstance is defined on JSII417PublicBaseOfBase (two erased + # private classes up); JSII417Derived re-emits nothing — the call + # resolves to the base stub, carrying the base fqn to the kernel. + expect(JsiiCalc::JSII417Derived.make_instance).to be_a(JsiiCalc::JSII417PublicBaseOfBase) + end + + it 'lets a child override parent statics (ES6 semantics)' do + expect(JsiiCalc::StaticHelloParent.PROPERTY).to eq(1337) + expect(JsiiCalc::StaticHelloParent.property).to eq(1337) + + # The child's own stubs shadow the inherited ones and carry the + # child's fqn. + expect(JsiiCalc::StaticHelloChild.PROPERTY).to eq(42) + expect(JsiiCalc::StaticHelloChild.property).to eq(42) + expect { JsiiCalc::StaticHelloChild.method() }.not_to raise_error + end + end + + describe 'inheritance (extended)' do + it 'handles inheritance with no new properties' do + # DerivedClassHasNoProperties::Derived inherits from Base + # Base has 'prop' + obj = JsiiCalc::DerivedClassHasNoProperties::Derived.new + obj.prop = 'hello' + expect(obj.prop).to eq('hello') + end + + it 'handles cross-package inheritance' do + # JsiiCalc::Add inherits from Scope::JsiiCalcLib::Operation + add = JsiiCalc::Add.new(Scope::JsiiCalcLib::Number.new(1), Scope::JsiiCalcLib::Number.new(2)) + expect(add).to be_a(Scope::JsiiCalcLib::Operation) + expect(add.value).to eq(3) + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/collections_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/collections_spec.rb new file mode 100644 index 0000000000..57794e138e --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/collections_spec.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Suite tests: collectionTypes, arrays, maps, arrayReturnedByMethod*, +# mapReturnedByMethod*, listInClass*, mapInClass*, staticListInClass*, +# staticMapInClass*, collectionOfInterfaces_*. +# +# Arrays and maps in every position: typed properties, method return values, +# instance properties and static properties. The `*CannotBeModified` tests +# verify that the runtime *freezes* collections it hands out — the kernel +# returns value snapshots, so mutating one locally would silently diverge +# from the JS-side state; a FrozenError makes that mistake loud instead. +# The collectionOfInterfaces_* quartet checks that *elements* of returned +# collections hydrate correctly whether they are structs (value objects, +# eagerly hydrated) or interfaces (live byref proxies that forward calls). +RSpec.describe 'JSII compliance: collections' do + it 'sets and reads array and map properties', compliance: 'collectionTypes' do + types = JsiiCalc::AllTypes.new + + # array + types.array_property = ['Hello', 'World'] + expect(types.array_property[1]).to eq('World') + + # map + map = { 'Foo' => Scope::JsiiCalcLib::Number.new(123) } + types.map_property = map + # The map returned should have the hydrated objects + expect(types.map_property['Foo']).to be_a(Scope::JsiiCalcLib::Number) + expect(types.map_property['Foo'].value).to eq(123) + end + + it 'sets and reads arrays of host objects (Sum parts)', compliance: 'arrays' do + sum = JsiiCalc::Sum.new + sum.parts = [ + Scope::JsiiCalcLib::Number.new(5), + Scope::JsiiCalcLib::Number.new(10), + JsiiCalc::Multiply.new(Scope::JsiiCalcLib::Number.new(2), Scope::JsiiCalcLib::Number.new(3)) + ] + + expect(sum.value).to eq(5 + 10 + (2 * 3)) + expect(sum.parts[0].value).to eq(5) + expect(sum.parts[2].value).to eq(6) + expect(sum.to_string).to eq('(((0 + 5) + 10) + (2 * 3))') + end + + it 'reads maps of host object lists (operations_map)', compliance: 'maps' do + calc = JsiiCalc::Calculator.new + calc.add(10) + calc.add(20) + calc.mul(2) + + expect(calc.operations_map['add'].length).to eq(2) + expect(calc.operations_map['mul'].length).to eq(1) + expect(calc.operations_map['add'][1].value).to eq(30) + end + + it 'reads an array returned by a method', compliance: 'arrayReturnedByMethodCanBeRead' do + list = JsiiCalc::ClassWithCollections.create_a_list() + expect(list).to eq(['one', 'two']) + end + + it 'freezes arrays returned by methods', compliance: 'arrayReturnedByMethodCannotBeModified' do + list = JsiiCalc::ClassWithCollections.create_a_list() + expect(list).to be_frozen + expect { list << 'three' }.to raise_error(FrozenError) + end + + it 'reads a map returned by a method', compliance: 'mapReturnedByMethodCanBeRead' do + map = JsiiCalc::ClassWithCollections.create_a_map() + expect(map).to eq({ 'key1' => 'value1', 'key2' => 'value2' }) + end + + it 'freezes maps returned by methods', compliance: 'mapReturnedByMethodCannotBeModified' do + map = JsiiCalc::ClassWithCollections.create_a_map() + expect(map).to be_frozen + expect { map['keyThree'] = 'valueThree' }.to raise_error(FrozenError) + end + + it 'reads an instance list property', compliance: 'listInClassCanBeReadCorrectly' do + obj = JsiiCalc::ClassWithCollections.new({}, ['one', 'two']) + expect(obj.array).to eq(['one', 'two']) + end + + it 'reads an instance map property', compliance: 'mapInClassCanBeReadCorrectly' do + obj = JsiiCalc::ClassWithCollections.new({ 'key1' => 'value1', 'key2' => 'value2' }, []) + expect(obj.map).to eq({ 'key1' => 'value1', 'key2' => 'value2' }) + end + + it 'freezes instance map properties', compliance: 'mapInClassCannotBeModified' do + obj = JsiiCalc::ClassWithCollections.new({ 'key' => 'value' }, []) + expect(obj.map).to be_frozen + expect { obj.map['keyTwo'] = 'valueTwo' }.to raise_error(FrozenError) + end + + it 'reads a static list property', compliance: 'staticListInClassCanBeReadCorrectly' do + expect(JsiiCalc::ClassWithCollections.static_array).to eq(['one', 'two']) + end + + it 'freezes static list properties', compliance: 'staticListInClassCannotBeModified' do + list = JsiiCalc::ClassWithCollections.static_array + expect(list).to be_frozen + expect { list << 'three' }.to raise_error(FrozenError) + end + + it 'reads a static map property', compliance: 'staticMapInClassCanBeReadCorrectly' do + map = JsiiCalc::ClassWithCollections.static_map + expect(map).to eq({ 'key1' => 'value1', 'key2' => 'value2' }) + end + + it 'freezes static map properties', compliance: 'staticMapInClassCannotBeModified' do + map = JsiiCalc::ClassWithCollections.static_map + expect(map).to be_frozen + expect { map['keyTwo'] = 'valueTwo' }.to raise_error(FrozenError) + end + + describe 'collections of interfaces' do + it 'hydrates a list of structs', compliance: 'collectionOfInterfaces_ListOfStructs' do + JsiiCalc::InterfaceCollections.list_of_structs.each do |elt| + expect(elt.required_string).not_to be_nil + end + end + + it 'hydrates a list of interfaces', compliance: 'collectionOfInterfaces_ListOfInterfaces' do + JsiiCalc::InterfaceCollections.list_of_interfaces.each do |elt| + expect(elt).to respond_to(:ring) + end + end + + it 'hydrates a map of structs', compliance: 'collectionOfInterfaces_MapOfStructs' do + JsiiCalc::InterfaceCollections.map_of_structs.each_value do |elt| + expect(elt.required_string).not_to be_nil + end + end + + it 'hydrates a map of interfaces', compliance: 'collectionOfInterfaces_MapOfInterfaces' do + JsiiCalc::InterfaceCollections.map_of_interfaces.each_value do |elt| + expect(elt).to respond_to(:ring) + end + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/enums_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/enums_spec.rb new file mode 100644 index 0000000000..62fba0661c --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/enums_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Suite tests: getAndSetEnumValues, canLoadEnumValues, useEnumFromScopedModule. +# +# Enum members travel as `$jsii.enum` wire envelopes carrying the member's +# fully-qualified name (e.g. "jsii-calc.StringEnum/A"). Covered here: +# round-tripping members through properties, receiving arbitrary members +# from the kernel (including integer-backed enums), and enums defined in a +# *different* assembly — which exercises cross-assembly fqn resolution +# ("@scope/jsii-calc-lib.EnumFromScopedModule/VALUE1"). +RSpec.describe 'JSII compliance: enums' do + it 'gets and sets enum values', compliance: 'getAndSetEnumValues' do + calc = JsiiCalc::Calculator.new + calc.add(9) + calc.pow(3) + + expect(calc.string_style).to eq(JsiiCalc::Composition::CompositeOperation::CompositionStringStyle::NORMAL) + + calc.string_style = JsiiCalc::Composition::CompositeOperation::CompositionStringStyle::DECORATED + expect(calc.string_style).to eq(JsiiCalc::Composition::CompositeOperation::CompositionStringStyle::DECORATED) + expect(calc.to_string()).to eq('<<[[{{(((1 * (0 + 9)) * (0 + 9)) * (0 + 9))}}]]>>') + end + + it 'loads string-like and integer-like enum values from the kernel', compliance: 'canLoadEnumValues' do + expect(JsiiCalc::EnumDispenser.random_string_like_enum()).not_to be_nil + expect(JsiiCalc::EnumDispenser.random_integer_like_enum()).not_to be_nil + end + + it 'sets and reads an enum from a scoped third-party package', compliance: 'useEnumFromScopedModule' do + obj = JsiiCalc::ReferenceEnumFromScopedPackage.new + expect(obj.foo).to eq(Scope::JsiiCalcLib::EnumFromScopedModule::VALUE2) + obj.foo = Scope::JsiiCalcLib::EnumFromScopedModule::VALUE1 + expect(obj.load_foo).to eq(Scope::JsiiCalcLib::EnumFromScopedModule::VALUE1) + obj.save_foo(Scope::JsiiCalcLib::EnumFromScopedModule::VALUE2) + expect(obj.foo).to eq(Scope::JsiiCalcLib::EnumFromScopedModule::VALUE2) + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/interfaces_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/interfaces_spec.rb new file mode 100644 index 0000000000..08336c8a00 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/interfaces_spec.rb @@ -0,0 +1,362 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'time' + +# Suite tests: testInterfaces, canUseInterfaceSetters, testInterfaceParameter, +# testLiteralInterface, testJSObjectLiteralToNative, +# testNativeObjectsWithInterfaces, creationOfNativeObjectsFromJavaScriptObjects, +# pureInterfacesCanBeUsedTransparently (+_WhenTransitivelyImplementing), +# interfacesCanBeUsedTransparently_WhenAddedToJsiiType, +# canLeverageIndirectInterfacePolymorphism, callbackParameterIsInterface, +# interfaceBuilder, returnSubclassThatImplementsInterface976. +# +# Interfaces are a two-way street. Host→guest: consuming JS objects through +# interface-typed returns — interface fqns are registered as Ruby *modules*, +# so a ref that resolves to one hydrates as `Jsii::Object.allocate.extend(mod)` +# (see Registry#build_uninitialized_instance). Guest→host: Ruby classes that +# `include JsiiCalc::ISomething` and get passed to JS consumers; the runtime +# registers them with an *overrides list* so JS-side calls (e.g. `bell.ring`) +# come back as callbacks into the Ruby method. The guest direction also +# pins down *identity*: a native object passed into the kernel must come back +# `equal?`-identical, via the process-wide objects map +# (testNativeObjectsWithInterfaces, creationOfNativeObjectsFromJavaScriptObjects). +# +# Why interface modules exist at all in a duck-typed language: they are not +# Ruby typing, they are *wire-protocol declaration*. jsii is nominally +# typed, and the contract crosses a process boundary the duck can't swim: +# +# - Outbound (guest implements host interface): passing a native object to +# a host API sends a kernel `create` with an explicit `interfaces:` list +# of fqns, gathered by Object#jsii_interfaces from included modules that +# carry a jsii_fqn. The Node side builds its proxy from that list — it +# never probes the Ruby object for methods, so "responds to the right +# messages" is unserializable; `include IFoo` is the one-line nominal +# fact the protocol demands. (Python's binding needs @jsii.implements +# decorators for the same reason.) +# - Inbound (host returns an interface): refs labelled only with an +# interface fqn hydrate as Jsii::Object.allocate.extend(mod) — the +# module carries the forwarding stubs, camelCase↔snake_case mapping and +# reserved-name slugification (next ↔ _next). +# - Ergonomics: mixins make is_a?(IDoublable) behave like instanceof +# elsewhere, and required members are validated at construction (fail +# fast) instead of erroring later inside a Node-side callback. +# +# For merely *consuming* host objects the modules are nearly cosmetic; it is +# the guest-implements-host-interface (callback) direction where they are +# load-bearing. This mirrors Ruby's own Comparable/Enumerable idiom: +# modules as declared contracts. +RSpec.describe 'JSII compliance: interfaces' do + it 'supports the full interface hierarchy (IFriendly, IFriendlier, IRandomNumberGenerator)', compliance: 'testInterfaces' do + add = JsiiCalc::Add.new(Scope::JsiiCalcLib::Number.new(10), Scope::JsiiCalcLib::Number.new(20)) + expect(add.hello).to eq("Hello, I am a binary operation. What's your name?") + + # Multiply implements three interfaces at once — hello from IFriendly + # (via BinaryOperation), goodbye from IFriendlier, next from + # IRandomNumberGenerator — so each value below is a canary proving the + # member dispatched to the right interface's implementation. The 89 is + # not arithmetic: it's Multiply's hardcoded, deliberately fake "random + # number generator" (calculator.ts: `public next() { return 89; }`). + multiply = JsiiCalc::Multiply.new(Scope::JsiiCalcLib::Number.new(10), Scope::JsiiCalcLib::Number.new(30)) + expect(multiply.hello).to eq("Hello, I am a binary operation. What's your name?") + expect(multiply.goodbye).to eq('Goodbye from Multiply!') + expect(multiply.next).to eq(89) + + poly = JsiiCalc::Polymorphism.new + expect(poly.say_hello(multiply)).to eq("oh, Hello, I am a binary operation. What's your name?") + end + + it 'generates setters for read-write interface properties', compliance: 'canUseInterfaceSetters' do + obj = JsiiCalc::ObjectWithPropertyProvider.provide + obj.property = 'New Value' + expect(obj.was_set).to be true + end + + it 'passes interfaces as method parameters', compliance: 'testInterfaceParameter' do + obj = JsiiCalc::JSObjectLiteralForInterface.new + friendly = obj.give_me_friendly + augmenter = JsiiCalc::GreetingAugmenter.new + + expect(friendly.hello).to eq('I am literally friendly!') + expect(augmenter.better_greeting(friendly)).to eq('I am literally friendly! Let me buy you a drink!') + end + + it 'consumes JS object literals implementing an interface', compliance: 'testLiteralInterface' do + obj = JsiiCalc::JSObjectLiteralForInterface.new + friendly = obj.give_me_friendly + gen = obj.give_me_friendly_generator + + expect(friendly.hello).to eq('I am literally friendly!') + expect(gen.hello).to eq('giveMeFriendlyGenerator') + expect(gen.next).to eq(42) + end + + it 'unmarshals JS object literals to native objects', compliance: 'testJSObjectLiteralToNative' do + obj = JsiiCalc::JSObjectLiteralToNative.new + obj2 = obj.return_literal + expect(obj2.prop_a).to eq('Hello') + expect(obj2.prop_b).to eq(102) + end + + it 'preserves identity of native objects implementing host interfaces', compliance: 'testNativeObjectsWithInterfaces' do + pure_native = PureNativeFriendlyRandom.new + subclassed_native = SubclassNativeFriendlyRandom.new + + generator_bound_to_subclassed_object = JsiiCalc::NumberGenerator.new(subclassed_native) + expect(generator_bound_to_subclassed_object.generator).to be(subclassed_native) + generator_bound_to_subclassed_object.is_same_generator(subclassed_native) + expect(generator_bound_to_subclassed_object.next_times100()).to eq(10000) + expect(generator_bound_to_subclassed_object.next_times100()).to eq(20000) + + generator_bound_to_pure_native = JsiiCalc::NumberGenerator.new(pure_native) + expect(generator_bound_to_pure_native.generator).to be(pure_native) + generator_bound_to_pure_native.is_same_generator(pure_native) + expect(generator_bound_to_pure_native.next_times100()).to eq(100000) + expect(generator_bound_to_pure_native.next_times100()).to eq(200000) + end + + it 'creates native objects from JavaScript objects and back', compliance: 'creationOfNativeObjectsFromJavaScriptObjects' do + types = JsiiCalc::AllTypes.new + + js_obj = Scope::JsiiCalcLib::Number.new(44) + types.any_property = js_obj + unmarshalled_js_obj = types.any_property + expect(unmarshalled_js_obj.class).to eq(Scope::JsiiCalcLib::Number) + + native_obj = AddTen.new(10) + types.any_property = native_obj + result1 = types.any_property + expect(result1).to be(native_obj) + + native_obj2 = MulTen.new(20) + types.any_property = native_obj2 + unmarshalled_native_obj = types.any_property + expect(unmarshalled_native_obj.class).to eq(MulTen) + expect(unmarshalled_native_obj).to be(native_obj2) + end + + it 'lets host consumers use guest implementations of pure interfaces', compliance: 'pureInterfacesCanBeUsedTransparently' do + class MyFriendly < Jsii::Object + include Scope::JsiiCalcLib::IFriendly + def hello + "Greetings!" + end + end + + # Jsii requires a base class for creation. + # Since MyFriendly doesn't inherit from a proxy, we use JsiiCalc::AllTypes for testing. + class CustomFriendly < JsiiCalc::AllTypes + include Scope::JsiiCalcLib::IFriendly + def hello + "Custom!" + end + end + + friendly = CustomFriendly.new + poly = JsiiCalc::Polymorphism.new + expect(poly.say_hello(friendly)).to eq('oh, Custom!') + end + + it 'lets guest delegates return structs through pure interfaces', compliance: 'pureInterfacesCanBeUsedTransparently_WhenTransitivelyImplementing' do + expected = JsiiCalc::StructB.new(required_string: "It's Britney b**ch!") + + delegate_class = Class.new do + include JsiiCalc::IStructReturningDelegate + def return_struct + JsiiCalc::StructB.new(required_string: "It's Britney b**ch!") + end + end + + delegate = delegate_class.new + consumer = JsiiCalc::ConsumePureInterface.new(delegate) + result = consumer.work_it_baby + expect(result.required_string).to eq(expected.required_string) + end + + it 'supports implementing multiple host interfaces on one guest class', compliance: 'interfacesCanBeUsedTransparently_WhenAddedToJsiiType' do + class MultiInterfaceResource < JsiiCalc::AllTypes + include Scope::JsiiCalcLib::IFriendly + include Scope::JsiiCalcLib::IDoublable + + attr_reader :double_value + + def initialize(value) + super() + @double_value = value * 2 + end + + def hello + "I am multi-talented!" + end + end + + obj = MultiInterfaceResource.new(10) + + # Verify role 1: IFriendly + poly = JsiiCalc::Polymorphism.new + expect(poly.say_hello(obj)).to eq('oh, I am multi-talented!') + + # Verify role 2: IDoublable + expect(obj).to be_a(Scope::JsiiCalcLib::IDoublable) + expect(obj.double_value).to eq(20) + end + + it 'leverages indirect interface polymorphism', compliance: 'canLeverageIndirectInterfacePolymorphism' do + provider = JsiiCalc::AnonymousImplementationProvider.new + expect(provider.provide_as_class.value).to eq(1337) + expect(provider.provide_as_interface.value).to eq(1337) + expect(provider.provide_as_interface.verb).to eq('to implement') + end + + it 'passes pure interfaces to callbacks', compliance: 'callbackParameterIsInterface' do + bell_ringer_class = Class.new do + include JsiiCalc::IBellRinger + def your_turn(bell) + bell.ring + end + end + + concrete_bell_ringer_class = Class.new do + include JsiiCalc::IConcreteBellRinger + def your_turn(bell) + bell.ring + end + end + + bell_ringer = bell_ringer_class.new + concrete_bell_ringer = concrete_bell_ringer_class.new + + expect(JsiiCalc::ConsumerCanRingBell.static_implemented_by_object_literal(bell_ringer)).to be true + expect(JsiiCalc::ConsumerCanRingBell.static_implemented_by_public_class(bell_ringer)).to be true + expect(JsiiCalc::ConsumerCanRingBell.static_implemented_by_private_class(bell_ringer)).to be true + expect(JsiiCalc::ConsumerCanRingBell.static_when_typed_as_class(concrete_bell_ringer)).to be true + + consumer = JsiiCalc::ConsumerCanRingBell.new + expect(consumer.implemented_by_object_literal(bell_ringer)).to be true + expect(consumer.implemented_by_public_class(bell_ringer)).to be true + expect(consumer.implemented_by_private_class(bell_ringer)).to be true + expect(consumer.when_typed_as_class(concrete_bell_ringer)).to be true + end + + # Ruby-side ergonomics on top of the compliance surface above (deliberately + # NOT a suite-tagged case — the shared suite is upstream's to extend): the + # generated bindings coerce a bare closure into a single-abstract-method + # interface implementation at the call site, end-to-end through the kernel. + it 'coerces closures into single-method interfaces' do + consumer = JsiiCalc::ConsumerCanRingBell.new + + # Bare lambda where IBellRinger (single abstract method) is expected; + # the JS side calls back into it via the ordinary overrides path. + expect(consumer.implemented_by_object_literal(->(bell) { bell.ring })).to be true + + # Named single-entry hash form, equivalent to the lambda. + expect(consumer.implemented_by_object_literal({ your_turn: ->(bell) { bell.ring } })).to be true + + # Static call sites coerce the same way. + expect(JsiiCalc::ConsumerCanRingBell.static_implemented_by_object_literal(->(bell) { bell.ring })).to be true + end + + it 'builds guest objects implementing interface properties', compliance: 'interfaceBuilder' do + klass = Class.new do + include JsiiCalc::IInterfaceWithProperties + + attr_reader :read_only_string + + def initialize + @x = 'READ_WRITE' + @read_only_string = 'READ_ONLY' + end + + def read_write_string + @x + end + + def read_write_string=(value) + @x = value + end + end + + obj = klass.new + interact = JsiiCalc::UsesInterfaceWithProperties.new(obj) + expect(interact.just_read).to eq('READ_ONLY') + expect(interact.write_and_read('Hello')).to eq('Hello') + end + + it 'returns subclasses that implement an interface (jsii#976)', compliance: 'returnSubclassThatImplementsInterface976' do + obj = JsiiCalc::SomeTypeJsii976.return_return + expect(obj.foo).to eq(333) + end + + describe 'interface behavior (extended)' do + it 'returns anonymous implementations of interfaces' do + expect(JsiiCalc::SomeTypeJsii976.return_anonymous).not_to be_nil + end + + it 'handles diamond inheritance via interfaces' do + class DiamondImplementation < JsiiCalc::AllTypes + include Scope::JsiiCalcLib::IFriendly + include Scope::JsiiCalcLib::IDoublable + + def hello + "Diamond hello" + end + + def double_value + 42 + end + end + + obj = DiamondImplementation.new + poly = JsiiCalc::Polymorphism.new + expect(poly.say_hello(obj)).to eq('oh, Diamond hello') + expect(obj.double_value).to eq(42) + end + + it 'can use interfaces from submodules' do + class MyReflectable < JsiiCalc::AllTypes + include Scope::JsiiCalcLib::Submodule::IReflectable + def entries + [Scope::JsiiCalcLib::Submodule::ReflectableEntry.new(key: 'k', value: Scope::JsiiCalcLib::Number.new(123))] + end + end + + obj = MyReflectable.new + reflector = Scope::JsiiCalcLib::Submodule::Reflector.new + map = reflector.as_map(obj) + expect(map['k'].value).to eq(123) + end + + it 'enforces strict interface validation' do + class InvalidReflectable < JsiiCalc::AllTypes + include Scope::JsiiCalcLib::Submodule::IReflectable + # missing required `entries` method! + end + + expect { InvalidReflectable.new }.to raise_error(RuntimeError, /missing required method\/property: entries/) + end + + it 'can extend and implement from jsii' do + klass = Class.new(JsiiCalc::PythonSelf::ClassWithSelf) do + include JsiiCalc::IWallClock + def initialize(now) + super(now) + @now = now + end + def iso8601_now + @now + end + end + + mild_entropy_class = Class.new(JsiiCalc::Entropy) do + def repeat(word) + word + end + end + + now_str = Time.now.utc.iso8601 + wall_clock = klass.new(now_str) + entropy = mild_entropy_class.new(wall_clock) + expect(entropy.increase).to eq(now_str) + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/naming_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/naming_spec.rb new file mode 100644 index 0000000000..ed0416854e --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/naming_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Suite tests: reservedKeywordsAreSlugifiedIn{ClassProperties,MethodNames, +# StructProperties}, liftedKwargWithSameNameAsPositionalArg. +# +# Code-generation name mangling. TS members named `int`, `import`, +# `return`, `assert`, `default`, ... must be reachable from Ruby — slugified +# (e.g. `_return`) where they would otherwise be syntax errors or shadow +# runtime-critical methods (see Jsii::Utils.ruby_member_name). +# liftedKwargWithSameNameAsPositionalArg covers the trailing-struct +# "lifting" convention: when a struct parameter is expanded into keyword +# args and one keyword (scope:) collides with a positional parameter's name, +# both must still land in the right slot on the wire. +RSpec.describe 'JSII compliance: naming and reserved words' do + it 'slugifies reserved words used as class property names', compliance: 'reservedKeywordsAreSlugifiedInClassProperties' do + obj = JsiiCalc::ClassWithJavaReservedWords.new('one') + expect(obj.int).to eq('one') + expect(obj.import('two')).to eq('onetwo') + end + + it 'slugifies reserved words used as method names', compliance: 'reservedKeywordsAreSlugifiedInMethodNames' do + obj = JsiiCalc::PythonReservedWords.new + obj.import + obj._return + end + + it 'slugifies reserved words used as struct property names', compliance: 'reservedKeywordsAreSlugifiedInStructProperties' do + struct = JsiiCalc::StructWithJavaReservedWords.new( + assert: 'one', + default: 'two' + ) + expect(struct.assert).to eq('one') + expect(struct.default).to eq('two') + end + + it 'lifts kwargs sharing a name with a positional argument', compliance: 'liftedKwargWithSameNameAsPositionalArg' do + bell = JsiiCalc::Bell.new + amb = JsiiCalc::AmbiguousParameters.new(bell, scope: 'Driiiing!') + + expect(amb.scope).to eq(bell) + # Assuming struct equality works + expect(amb.props).to eq(JsiiCalc::StructParameterType.new(scope: 'Driiiing!')) + end + + describe 'naming (extended)' do + it 'handles parameters named self' do + subject = JsiiCalc::PythonSelf::ClassWithSelf.new('Howdy!') + expect(subject.self).to eq('Howdy!') + expect(subject.method(1337)).to eq('1337') + end + + it 'can override methods whose names are reserved words elsewhere' do + class RubyReservedWords < JsiiCalc::JavaReservedWords + # In Ruby, 'while' is a keyword. Our generator mapped it to '_while'. + # Let's see if we can override 'abstract' which is a method. + def abstract + "Overridden abstract" + end + end + + obj = RubyReservedWords.new + expect(obj.abstract).to eq("Overridden abstract") + end + + it 'lifts kwargs declared on a superinterface' do + expect(JsiiCalc::Submodule::Isolated::Kwargs.method(extra: 'ordinary', prop: JsiiCalc::Submodule::Child::SomeEnum::SOME)).to be_truthy + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/nullability_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/nullability_spec.rb new file mode 100644 index 0000000000..cb045dbc19 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/nullability_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Suite tests: undefinedAndNull, nullShouldBeTreatedAsUndefined, +# testNullIsAValidOptionalList, testNullIsAValidOptionalMap, +# eraseUnsetDataValues. +# +# The nil/undefined boundary. JavaScript distinguishes `null` from +# `undefined`; Ruby only has `nil`, so the runtime must map consistently: +# unset optionals read as nil, nil written to an optional must arrive as +# `undefined` (in arguments, struct members and array elements alike), and a +# host API legitimately returning `undefined` collections must surface nil. +# `eraseUnsetDataValues` is the subtle one: unset struct keys must be +# *absent* from the wire payload, not present-with-null — JS `'key' in obj` +# distinguishes the two, and host code relies on that. +RSpec.describe 'JSII compliance: null / undefined semantics' do + it 'reads unset optional values as nil and accepts nil assignment', compliance: 'undefinedAndNull' do + calc = JsiiCalc::Calculator.new + expect(calc.max_value).to be_nil + calc.max_value = nil + end + + it 'treats nil as undefined for optional args, struct members and properties', compliance: 'nullShouldBeTreatedAsUndefined' do + obj = JsiiCalc::NullShouldBeTreatedAsUndefined.new('hello', nil) + obj.give_me_undefined(nil) + obj.give_me_undefined_inside_an_object( + this_should_be_undefined: nil, + array_with_three_elements_and_undefined_as_second_argument: ['hello', nil, 'boom'] + ) + obj.change_me_to_undefined = nil + obj.verify_property_is_undefined + end + + it 'accepts nil as a valid optional list', compliance: 'testNullIsAValidOptionalList' do + expect(JsiiCalc::DisappointingCollectionSource.MAYBE_LIST).to be_nil + end + + it 'accepts nil as a valid optional map', compliance: 'testNullIsAValidOptionalMap' do + expect(JsiiCalc::DisappointingCollectionSource.MAYBE_MAP).to be_nil + end + + it 'erases unset optional data values on the way to the kernel', compliance: 'eraseUnsetDataValues' do + opts = JsiiCalc::EraseUndefinedHashValuesOptions.new(option1: 'option1') + expect(JsiiCalc::EraseUndefinedHashValues.does_key_exist(opts, 'option1')).to be true + expect(JsiiCalc::EraseUndefinedHashValues.does_key_exist(opts, 'option2')).to be false + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/primitive_types_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/primitive_types_spec.rb new file mode 100644 index 0000000000..b9c0d954a9 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/primitive_types_spec.rb @@ -0,0 +1,135 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'date' + +# Suite tests: primitiveTypes, dates, iso8601DoesNotDeserializeToDate, +# dynamicTypes. +# +# Value marshalling for scalars. `primitiveTypes` round-trips +# boolean/string/number/date/json through AllTypes properties. `dates` +# checks DateTime works in both a strongly-typed slot (date_property) and an +# `any` slot — exercising the `$jsii.date` wire envelope in Jsii::Serializer. +# `iso8601DoesNotDeserializeToDate` is the inverse trap: a *string* that +# happens to look like a date must come back as a string, not get eagerly +# coerced into a DateTime. `dynamicTypes` pushes every shape (scalars, +# arrays, maps, live objects) through a single `any`-typed property, so the +# serializer has to pick the right wire envelope per value with no type +# information to guide it. +RSpec.describe 'JSII compliance: primitive and dynamic types' do + it 'sets and reads all primitive types with their respective types', compliance: 'primitiveTypes' do + types = JsiiCalc::AllTypes.new + + # boolean + types.boolean_property = true + expect(types.boolean_property).to be true + + # string + types.string_property = 'foo' + expect(types.string_property).to eq('foo') + + # number + types.number_property = 1234 + expect(types.number_property).to eq(1234) + + # date + date = DateTime.new(1970, 1, 1, 0, 0, 0.123) + # JSII usually expects timestamps or ISO strings for dates + types.date_property = date + expect(types.date_property).to eq(date) + + # json + types.json_property = { 'Foo' => { 'bar' => 123 } } + expect(types.json_property['Foo']).to eq({ 'bar' => 123 }) + end + + it 'handles dates in both strong-typed and any context', compliance: 'dates' do + types = JsiiCalc::AllTypes.new + + # strong type + date = DateTime.new(1970, 1, 1, 0, 0, 0.123) + types.date_property = date + expect(types.date_property).to eq(date) + + # weak type (any_property) + date2 = DateTime.new(1970, 1, 1, 0, 0, 0.999) + types.any_property = date2 + expect(types.any_property).to eq(date2) + end + + it 'does not auto-deserialize ISO8601 strings as dates', compliance: 'iso8601DoesNotDeserializeToDate' do + wall_clock_class = Class.new do + include JsiiCalc::IWallClock + def initialize(now) + @now = now + end + + def iso8601_now + @now + end + end + + entropy_class = Class.new(JsiiCalc::Entropy) do + def repeat(word) + word + end + end + + now = DateTime.now.new_offset(0).iso8601(3).sub('+00:00', 'Z') + wall_clock = wall_clock_class.new(now) + entropy = entropy_class.new(wall_clock) + + expect(entropy.increase).to eq(now) + end + + it 'handles various types assigned to an any-typed property', compliance: 'dynamicTypes' do + types = JsiiCalc::AllTypes.new + + # boolean + types.any_property = false + expect(types.any_property).to be false + + # string + types.any_property = 'String' + expect(types.any_property).to eq('String') + + # number + types.any_property = 12 + expect(types.any_property).to eq(12) + + # json + types.any_property = { 'Goo' => ['Hello', { 'World' => 123 }] } + got = types.any_property['Goo'] + expect(got).not_to be_nil + expect(got[1]['World']).to eq(123) + + # array + types.any_property = ['Hello', 'World'] + expect(types.any_property[0]).to eq('Hello') + expect(types.any_property[1]).to eq('World') + + # array of any + types.any_array_property = ['Hybrid', Scope::JsiiCalcLib::Number.new(12), 123, false] + expect(types.any_array_property[2]).to eq(123) + expect(types.any_array_property[1]).to be_a(Scope::JsiiCalcLib::Number) + + # map + map = { 'MapKey' => 'MapValue' } + types.any_property = map + expect(types.any_property['MapKey']).to eq('MapValue') + + # classes + mult = JsiiCalc::Multiply.new(Scope::JsiiCalcLib::Number.new(10), Scope::JsiiCalcLib::Number.new(20)) + types.any_property = mult + expect(types.any_property.jsii_ref).to eq(mult.jsii_ref) + expect(types.any_property).to be_a(JsiiCalc::Multiply) + expect(types.any_property.value).to eq(200) + end + + it 'handles maps assigned to an any-typed map property' do + types = JsiiCalc::AllTypes.new + map = { 'MapKey' => 'MapValue', 'Goo' => 19_289_812 } + types.any_map_property = map + expect(types.any_map_property['Goo']).to eq(19_289_812) + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/property_overrides_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/property_overrides_spec.rb new file mode 100644 index 0000000000..0754a1b96f --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/property_overrides_spec.rb @@ -0,0 +1,235 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Suite tests: propertyOverrides_*, canOverrideProtected{Method,Getter,Setter}, +# doNotOverridePrivates_*. +# +# Virtual *properties*: guest getter/setter overrides invoked by host code, +# with and without `super`, with guest exceptions propagating back as +# Jsii::RuntimeError. canOverrideProtected* confirms TS-`protected` members +# are exposed in the assembly and overridable from Ruby. The six +# doNotOverridePrivates_* are the inverse guarantee: TS-`private` members +# are not in the assembly at all, so a guest method that merely *collides* +# by name must never be wired up as an override — checked for both public +# and `private` Ruby visibility, for methods and for properties. +# +# The SyncOverrides fixture class is defined in spec/support/fixtures.rb. +RSpec.describe 'JSII compliance: property overrides' do + it 'invokes guest overrides of property getters and setters', compliance: 'propertyOverrides_get_set' do + so = SyncOverrides.new + expect(so.retrieve_value_of_the_property).to eq('I am an override!') + so.modify_value_of_the_property('New Value') + expect(so.another_the_property).to eq('New Value') + end + + it 'lets property getter overrides call super', compliance: 'propertyOverrides_get_calls_super' do + klass = Class.new(JsiiCalc::SyncVirtualMethods) do + def the_property + "super:#{super}" + end + + def the_property=(value) + super(value) + end + end + + so = klass.new + expect(so.retrieve_value_of_the_property).to eq('super:initial value') + expect(so.the_property).to eq('super:initial value') + end + + it 'lets property setter overrides call super', compliance: 'propertyOverrides_set_calls_super' do + klass = Class.new(JsiiCalc::SyncVirtualMethods) do + def the_property + super + end + + def the_property=(value) + super("#{value}:by override") + end + end + + so = klass.new + so.modify_value_of_the_property('New Value') + expect(so.the_property).to eq('New Value:by override') + end + + it 'propagates exceptions raised in property getter overrides', compliance: 'propertyOverrides_get_throws' do + klass = Class.new(JsiiCalc::SyncVirtualMethods) do + def the_property + raise 'Oh no, this is bad' + end + + def the_property=(value) + super(value) + end + end + + so = klass.new + expect { so.retrieve_value_of_the_property }.to raise_error(Jsii::RuntimeError, /Oh no, this is bad/) + end + + it 'propagates exceptions raised in property setter overrides', compliance: 'propertyOverrides_set_throws' do + klass = Class.new(JsiiCalc::SyncVirtualMethods) do + def the_property + super + end + + def the_property=(value) + raise 'Exception from overloaded setter' + end + end + + so = klass.new + expect { so.modify_value_of_the_property('Hii') }.to raise_error(Jsii::RuntimeError, /Exception from overloaded setter/) + end + + it 'overrides properties of host interfaces', compliance: 'propertyOverrides_interfaces' do + klass = Class.new do + include JsiiCalc::IInterfaceWithProperties + + attr_reader :read_only_string + + def initialize + @x = nil + @read_only_string = 'READ_ONLY_STRING' + end + + def read_write_string + "#{@x}?" + end + + def read_write_string=(value) + @x = "#{value}!" + end + end + + obj = klass.new + interact = JsiiCalc::UsesInterfaceWithProperties.new(obj) + expect(interact.just_read).to eq('READ_ONLY_STRING') + expect(interact.write_and_read('Hello')).to eq('Hello!?') + end + + describe 'protected members' do + it 'overrides protected methods', compliance: 'canOverrideProtectedMethod' do + klass = Class.new(JsiiCalc::OverridableProtectedMember) do + def override_me + "Cthulhu Fhtagn!" + end + end + + overridden = klass.new + expect(overridden.value_from_protected()).to eq("Cthulhu Fhtagn!") + end + + it 'overrides protected getters', compliance: 'canOverrideProtectedGetter' do + klass = Class.new(JsiiCalc::OverridableProtectedMember) do + def override_read_only + "Cthulhu " + end + + def override_read_write + "Fhtagn!" + end + end + + overridden = klass.new + expect(overridden.value_from_protected()).to eq("Cthulhu Fhtagn!") + end + + it 'overrides protected setters', compliance: 'canOverrideProtectedSetter' do + klass = Class.new(JsiiCalc::OverridableProtectedMember) do + def override_read_write + super + end + + def override_read_write=(value) + super("zzzzzzzzz#{value}") + end + end + + overridden = klass.new + overridden.switch_modes() + expect(overridden.value_from_protected()).to eq("Bazzzzzzzzzzzaar...") + end + end + + describe 'private members are not overridable' do + it 'ignores a public guest method shadowing a private host method', compliance: 'doNotOverridePrivates_method_public' do + klass = Class.new(JsiiCalc::DoNotOverridePrivates) do + def private_method + 'privateMethod-Override' + end + end + obj = klass.new + expect(obj.private_method_value).to eq('privateMethod') + end + + it 'ignores a private guest method shadowing a private host method', compliance: 'doNotOverridePrivates_method_private' do + klass = Class.new(JsiiCalc::DoNotOverridePrivates) do + private def private_method + 'privateMethod-Override' + end + end + obj = klass.new + expect(obj.private_method_value).to eq('privateMethod') + end + + it 'ignores a public guest property shadowing a private host property (by name)', compliance: 'doNotOverridePrivates_property_by_name_public' do + klass = Class.new(JsiiCalc::DoNotOverridePrivates) do + def private_property + 'privateProperty-Override' + end + end + obj = klass.new + expect(obj.private_property_value).to eq('privateProperty') + end + + it 'ignores a private guest property shadowing a private host property (by name)', compliance: 'doNotOverridePrivates_property_by_name_private' do + klass = Class.new(JsiiCalc::DoNotOverridePrivates) do + private def private_property + 'privateProperty-Override' + end + end + obj = klass.new + expect(obj.private_property_value).to eq('privateProperty') + end + + it 'ignores public guest getter/setter shadowing a private host property', compliance: 'doNotOverridePrivates_property_getter_public' do + klass = Class.new(JsiiCalc::DoNotOverridePrivates) do + def private_property + 'privateProperty-Override' + end + + def private_property=(value) + raise 'Boom' + end + end + obj = klass.new + expect(obj.private_property_value).to eq('privateProperty') + + # setter override is also not invoked + obj.change_private_property_value('MyNewValue') + expect(obj.private_property_value).to eq('MyNewValue') + end + + it 'ignores private guest getter/setter shadowing a private host property', compliance: 'doNotOverridePrivates_property_getter_private' do + klass = Class.new(JsiiCalc::DoNotOverridePrivates) do + private def private_property + 'privateProperty-Override' + end + + private def private_property=(value) + raise 'Boom' + end + end + obj = klass.new + expect(obj.private_property_value).to eq('privateProperty') + + # setter override is also not invoked + obj.change_private_property_value('MyNewValue') + expect(obj.private_property_value).to eq('MyNewValue') + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/runtime_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/runtime_spec.rb new file mode 100644 index 0000000000..4eb370124c --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/runtime_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Suite tests: testJsiiAgent, nodeStandardLibrary, exceptions, exceptionMessage, +# strippedDeprecatedMemberCanBeReceived. +# +# Environment plumbing for the Node.js child process the kernel runs in: +# the JSII_AGENT env var must identify this runtime ("Ruby/") to +# host code, the child is a real Node so fs/os/crypto must work, JS `throw` +# must surface as Jsii::RuntimeError with the original message intact, and +# assemblies compiled with --strip-deprecated must not blow up at runtime +# when a stripped member's type is received. +RSpec.describe 'JSII compliance: runtime environment' do + it 'reports Ruby language and version in JSII_AGENT', compliance: 'testJsiiAgent' do + # The kernel sets JSII_AGENT=Ruby/ on spawn, so this should + # always be populated. If it's not, the runtime regressed and we want + # to know loudly — no `skip` fallback. + expect(JsiiCalc::JsiiAgent.value).to match(/^Ruby\/\d+\.\d+\.\d+/) + end + + it 'exposes the Node standard library (fs, os, crypto)', compliance: 'nodeStandardLibrary' do + obj = JsiiCalc::NodeStandardLibrary.new + expect(obj.fs_read_file).to eq('Hello, resource!') + expect(obj.fs_read_file_sync).to eq('Hello, resource! SYNC!') + expect(obj.os_platform.length).to be > 0 + expect(obj.crypto_sha256).to eq('6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50') + end + + it 'raises host errors as Jsii::RuntimeError', compliance: 'exceptions' do + calc = JsiiCalc::Calculator.new(initial_value: 20, maximum_value: 30) + calc.add(3) + expect(calc.value).to eq(23) + + expect { calc.add(10) }.to raise_error(Jsii::RuntimeError) + + calc.max_value = 40 + calc.add(10) + expect(calc.value).to eq(33) + end + + it 'forwards custom exception messages from JS', compliance: 'exceptionMessage' do + # AcceptsPath is in the cdk22369 submodule. The submodule is in the + # jsii-calc assembly, so a missing constant means the generator dropped + # it — fail loudly rather than silently passing. + expect { JsiiCalc::Cdk22369::AcceptsPath.new(source_path: 'A Bad Path') }.to raise_error(Jsii::RuntimeError, /Cannot find asset/) + end + + it 'receives members whose deprecated parts were stripped', compliance: 'strippedDeprecatedMemberCanBeReceived' do + expect(Scope::JsiiCalcLib::DeprecationRemoval::InterfaceFactory.create).not_to be_nil + end + + describe 'runtime behavior (extended)' do + it 'makes dependency submodule types usable' do + subject = JsiiCalc::UpcasingReflectable.new('foo' => 'bar') + expect(JsiiCalc::UpcasingReflectable.REFLECTOR.as_map(subject)).to eq('FOO' => 'bar') + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/structs_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/structs_spec.rb new file mode 100644 index 0000000000..fc817e0bed --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/structs_spec.rb @@ -0,0 +1,384 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'date' +require 'json' + +# Suite tests: structs_*, useNestedStruct, testStructsCanBeDowncastedToParentType, +# structsAreUndecoratedOntheWayToKernel, +# equals/hashCodeIsResistantToPropertyShadowingResultVariable. +# +# Structs are jsii's value types: pass-by-value data, constructed in Ruby +# with keyword arguments. The suite demands full value semantics — `==` and +# `#hash` by content across required, optional and diamond-inherited +# properties — plus required-member enforcement at construction +# (ArgumentError) and serialization in both directions. Two subtle ones: +# `structs_returnedLiteralEqualsNativeBuilt` (a JS object literal returned by +# the kernel must be indistinguishable from a natively-built struct — struct +# refs are eagerly hydrated into plain values on arrival, see +# Registry#hydrate_struct!) and `structsAreUndecoratedOntheWayToKernel` +# (when JS JSON.stringify's a struct we sent, no `$jsii.*` envelope keys may +# leak into the output). The shadowing-resistance pair guards against a +# generated property named `default`/`result` colliding with names the code +# generator uses internally in its == / #hash implementations. +RSpec.describe 'JSII compliance: structs' do + it 'compares non-optional structs by value', compliance: 'structs_nonOptionalequals' do + struct_a = JsiiCalc::StableStruct.new(readonly_property: 'one') + struct_b = JsiiCalc::StableStruct.new(readonly_property: 'one') + struct_c = JsiiCalc::StableStruct.new(readonly_property: 'two') + + expect(struct_a).to eq(struct_b) + expect(struct_b).to eq(struct_a) + expect(struct_a).not_to eq(struct_c) + end + + it 'hashes non-optional structs by value', compliance: 'structs_nonOptionalhashCode' do + struct_a = JsiiCalc::StableStruct.new(readonly_property: 'one') + struct_b = JsiiCalc::StableStruct.new(readonly_property: 'one') + struct_c = JsiiCalc::StableStruct.new(readonly_property: 'two') + + expect(struct_a.hash).to eq(struct_b.hash) + expect(struct_a.hash).not_to eq(struct_c.hash) + end + + it 'compares optional struct members by value', compliance: 'structs_optionalEquals' do + struct_a = JsiiCalc::OptionalStruct.new(field: 'one') + struct_b = JsiiCalc::OptionalStruct.new(field: 'one') + struct_c = JsiiCalc::OptionalStruct.new(field: 'two') + struct_d = JsiiCalc::OptionalStruct.new() + + expect(struct_a).to eq(struct_b) + expect(struct_a).not_to eq(struct_c) + expect(struct_a).not_to eq(struct_d) + end + + it 'hashes optional struct members by value', compliance: 'structs_optionalHashCode' do + struct_a = JsiiCalc::OptionalStruct.new(field: 'one') + struct_b = JsiiCalc::OptionalStruct.new(field: 'one') + struct_c = JsiiCalc::OptionalStruct.new(field: 'two') + struct_d = JsiiCalc::OptionalStruct.new() + + expect(struct_a.hash).to eq(struct_b.hash) + expect(struct_a.hash).not_to eq(struct_c.hash) + expect(struct_a.hash).not_to eq(struct_d.hash) + end + + it 'compares multi-property structs by value', compliance: 'structs_multiplePropertiesEquals' do + a = JsiiCalc::TopLevelStruct.new( + required: 'bye', + second_level: JsiiCalc::SecondLevelStruct.new(deeper_required_prop: 'ciao') + ) + b = JsiiCalc::TopLevelStruct.new(required: 'hello', second_level: 1) + c = JsiiCalc::TopLevelStruct.new(required: 'hello', second_level: 1) + d = JsiiCalc::SecondLevelStruct.new(deeper_required_prop: 'exists') + + expect(a).not_to eq(b) + expect(b).to eq(c) + expect(a).not_to eq(5) + expect(a).not_to eq(d) + end + + it 'hashes multi-property structs by value', compliance: 'structs_multiplePropertiesHashCode' do + struct_a = JsiiCalc::DiamondInheritanceTopLevelStruct.new( + base_level_property: 'one', + first_mid_level_property: 'two', + second_mid_level_property: 'three', + top_level_property: 'four' + ) + struct_b = JsiiCalc::DiamondInheritanceTopLevelStruct.new( + base_level_property: 'one', + first_mid_level_property: 'two', + second_mid_level_property: 'three', + top_level_property: 'four' + ) + struct_c = JsiiCalc::DiamondInheritanceTopLevelStruct.new( + base_level_property: 'one', + first_mid_level_property: 'two', + second_mid_level_property: 'different', + top_level_property: 'four' + ) + + expect(struct_a.hash).to eq(struct_b.hash) + expect(struct_a.hash).not_to eq(struct_c.hash) + end + + it 'enforces required struct members at construction', compliance: 'structs_containsNullChecks' do + # In Ruby, missing required keyword arguments raise ArgumentError + expect { Scope::JsiiCalcLib::MyFirstStruct.new }.to raise_error(ArgumentError) + end + + it 'serializes structs to the kernel', compliance: 'structs_serializeToJsii' do + first_struct = Scope::JsiiCalcLib::MyFirstStruct.new( + astring: 'FirstString', + anumber: 999, + first_optional: ['First', 'Optional'] + ) + + double_trouble = JsiiCalc::DoubleTrouble.new() + + derived_struct = JsiiCalc::DerivedStruct.new( + non_primitive: double_trouble, + bool: false, + another_required: DateTime.now, + astring: 'String', + anumber: 1234, + first_optional: ['one', 'two'] + ) + + gms = JsiiCalc::GiveMeStructs.new() + expect(gms.read_first_number(first_struct)).to eq(999) + expect(gms.read_first_number(derived_struct)).to eq(1234) + expect(gms.read_derived_non_primitive(derived_struct).class).to eq(JsiiCalc::DoubleTrouble) + + literal = gms.struct_literal + expect(literal.optional1).to eq('optional1FromStructLiteral') + expect(literal.optional3).to be false + expect(literal.optional2).to be_nil + end + + it 'constructs structs with keyword arguments (step builders)', compliance: 'structs_stepBuilders' do + # In Ruby, we use keyword arguments directly rather than generated step builders. + some_instant = DateTime.now + non_prim = JsiiCalc::DoubleTrouble.new() + + s = JsiiCalc::DerivedStruct.new( + non_primitive: non_prim, + bool: false, + another_required: some_instant, + astring: 'Hello', + anumber: 1234, + first_optional: ['Hello', 'World'] + ) + + expect(s.non_primitive.class).to eq(JsiiCalc::DoubleTrouble) + expect(s.bool).to be false + expect(s.another_required.to_s).to eq(some_instant.to_s) + expect(s.astring).to eq('Hello') + expect(s.anumber).to eq(1234) + expect(s.first_optional[1]).to eq('World') + expect(s.another_optional).to be_nil + expect(s.optional_array).to be_nil + + my_first_struct = Scope::JsiiCalcLib::MyFirstStruct.new( + astring: 'Hello', + anumber: 12 + ) + + expect(my_first_struct.astring).to eq('Hello') + expect(my_first_struct.anumber).to eq(12) + + only_options1 = Scope::JsiiCalcLib::StructWithOnlyOptionals.new( + optional1: 'Hello', + optional2: 1 + ) + + expect(only_options1.optional1).to eq('Hello') + expect(only_options1.optional2).to eq(1) + expect(only_options1.optional3).to be_nil + + only_options2 = Scope::JsiiCalcLib::StructWithOnlyOptionals.new() + expect(only_options2.optional1).to be_nil + expect(only_options2.optional2).to be_nil + expect(only_options2.optional3).to be_nil + end + + it 'dedupes properties inherited through a diamond', compliance: 'structs_withDiamondInheritance_correctlyDedupeProperties' do + struct = JsiiCalc::DiamondInheritanceTopLevelStruct.new( + base_level_property: 'base', + first_mid_level_property: 'mid1', + second_mid_level_property: 'mid2', + top_level_property: 'top' + ) + + expect(struct.base_level_property).to eq('base') + expect(struct.first_mid_level_property).to eq('mid1') + expect(struct.second_mid_level_property).to eq('mid2') + expect(struct.top_level_property).to eq('top') + end + + it 'makes a struct returned from the kernel indistinguishable from a native one', compliance: 'structs_returnedLiteralEqualsNativeBuilt' do + gms = JsiiCalc::GiveMeStructs.new + returned_literal = gms.struct_literal + native_built = Scope::JsiiCalcLib::StructWithOnlyOptionals.new( + optional1: 'optional1FromStructLiteral', + optional3: false + ) + expect(returned_literal.optional1).to eq(native_built.optional1) + expect(returned_literal.optional2).to eq(native_built.optional2) + expect(returned_literal.optional3).to eq(native_built.optional3) + end + + it 'round-trips nested structs through the kernel', compliance: 'useNestedStruct' do + struct = JsiiCalc::TopLevelStruct.new( + required: 'hello', + second_level: JsiiCalc::SecondLevelStruct.new(deeper_required_prop: 'exists') + ) + + result = JsiiCalc::StructPassing.round_trip(123, struct) + expect(result).to be_a(JsiiCalc::TopLevelStruct) + expect(result.required).to eq('hello') + expect(result.second_level).to be_a(JsiiCalc::SecondLevelStruct) + expect(result.second_level.deeper_required_prop).to eq('exists') + end + + it 'downcasts structs to a parent type', compliance: 'testStructsCanBeDowncastedToParentType' do + expect(JsiiCalc::Demonstrate982.take_this).not_to be_nil + expect(JsiiCalc::Demonstrate982.take_this_too).not_to be_nil + end + + it 'serializes structs undecorated to the kernel', compliance: 'structsAreUndecoratedOntheWayToKernel' do + json = JsiiCalc::JsonFormatter.stringify( + JsiiCalc::StructB.new(required_string: 'Bazinga!', optional_boolean: false) + ) + parsed = JSON.parse(json) + expect(parsed['requiredString']).to eq('Bazinga!') + expect(parsed['optionalBoolean']).to eq(false) + end + + # Where is "result"? It's a property *of the fixture struct* — a booby + # trap that is never set, whose mere existence at code-generation time is + # the test (compliance.ts): + # + # export interface StructWithJavaReservedWords { + # readonly default: string; + # readonly assert?: string; + # // These properties are designed to break the naive implementation + # // of equals() and hashcode() using the standard template + # readonly result?: string; + # readonly that?: string; + # } + # + # The classic Java equals/hashCode template declares locals named exactly + # `that` (the cast counterpart in equals) and `result` (the accumulator in + # hashCode). A naive generator emitting unqualified property reads for a + # struct that *also* declares members named result/that gets them shadowed + # by the template's own locals — miscompiles or wrong comparisons. Ruby + # has the same hazard in principle (local variables shadow receiver-less + # method calls), but the runtime sidesteps it entirely: Jsii::Struct#== + # compares serialized property maps (to_jsii == other.to_jsii) instead of + # emitting per-struct comparison code. This test guards that property. + it 'implements == resistant to a property named "result"', compliance: 'equalsIsResistantToPropertyShadowingResultVariable' do + first = JsiiCalc::StructWithJavaReservedWords.new(default: 'one') + second = JsiiCalc::StructWithJavaReservedWords.new(default: 'one') + third = JsiiCalc::StructWithJavaReservedWords.new(default: 'two') + + expect(first).to eq(second) + expect(first).not_to eq(third) + end + + # Same trap as above, aimed at hashCode's `int result = ...` accumulator; + # Jsii::Struct#hash delegates to to_jsii.hash, so no local can shadow. + it 'implements #hash resistant to a property named "result"', compliance: 'hashCodeIsResistantToPropertyShadowingResultVariable' do + first = JsiiCalc::StructWithJavaReservedWords.new(default: 'one') + second = JsiiCalc::StructWithJavaReservedWords.new(default: 'one') + third = JsiiCalc::StructWithJavaReservedWords.new(default: 'two') + + expect(first.hash).to eq(second.hash) + expect(first.hash).not_to eq(third.hash) + end + + describe 'Ruby-specific struct behavior' do + # JSII structs support multiple inheritance; Ruby classes don't. The + # generator subclasses the first declared parent and records the rest + # via jsii_extra_struct_bases, which is_a?/kind_of?/case honor. + it 'treats diamond structs as instances of every declared parent' do + struct = JsiiCalc::DiamondInheritanceTopLevelStruct.new( + base_level_property: 'base', + first_mid_level_property: 'mid1', + second_mid_level_property: 'mid2', + top_level_property: 'top' + ) + + # First parent: real Ruby ancestry. + expect(struct).to be_a(JsiiCalc::DiamondInheritanceFirstMidLevelStruct) + # Second parent: recorded extra base. + expect(struct).to be_a(JsiiCalc::DiamondInheritanceSecondMidLevelStruct) + expect(struct).to be_kind_of(JsiiCalc::DiamondInheritanceSecondMidLevelStruct) + # Shared grandparent (reached through either path). + expect(struct).to be_a(JsiiCalc::DiamondInheritanceBaseLevelStruct) + + # case/when dispatch honors the second parent too. + matched = case struct + when JsiiCalc::DiamondInheritanceSecondMidLevelStruct then :second + else :nope + end + expect(matched).to eq(:second) + + # Unrelated structs do not conform. + expect(struct).not_to be_a(JsiiCalc::StructA) + sibling = JsiiCalc::DiamondInheritanceSecondMidLevelStruct.new( + base_level_property: 'b', second_mid_level_property: 'm' + ) + expect(sibling).not_to be_a(JsiiCalc::DiamondInheritanceFirstMidLevelStruct) + expect(sibling).not_to be_a(JsiiCalc::DiamondInheritanceTopLevelStruct) + end + + it 'keeps struct equality symmetric across subclasses' do + child_class = Class.new(JsiiCalc::OptionalStruct) + parent = JsiiCalc::OptionalStruct.new(field: 'one') + child = child_class.new(field: 'one') + + expect(parent == child).to be false + expect(child == parent).to be false + end + + it 'accepts a scalar where a union-typed struct member allows it' do + result = JsiiCalc::StructPassing.round_trip(123, required: 'hello', second_level: 5) + expect(result.required).to eq('hello') + expect(result.optional).to be_nil + expect(result.second_level).to eq(5) + end + + it 'handles structs in variadic args' do + count = JsiiCalc::StructPassing.how_many_var_args_did_i_pass( + 123, + JsiiCalc::TopLevelStruct.new(required: 'hello', second_level: 1), + JsiiCalc::TopLevelStruct.new(required: 'bye', second_level: JsiiCalc::SecondLevelStruct.new(deeper_required_prop: 'ciao')) + ) + expect(count).to eq(2) + end + + it 'coerces plain hashes in variadic struct args' do + # Generator emits `.map!` coercion for variadic struct params; this + # exercises that path with raw hashes instead of explicit struct instances. + count = JsiiCalc::StructPassing.how_many_var_args_did_i_pass( + 7, + { required: 'one', second_level: 1 }, + { required: 'two', second_level: 2 } + ) + expect(count).to eq(2) + end + + it 'accepts a mix of struct instances and hashes for variadic args' do + count = JsiiCalc::StructPassing.how_many_var_args_did_i_pass( + 0, + JsiiCalc::TopLevelStruct.new(required: 'one', second_level: 1), + { required: 'two', second_level: 2 } + ) + expect(count).to eq(2) + end + + it 'can pass nested structs as plain hashes (RootStructValidator)' do + JsiiCalc::RootStructValidator.validate(string_prop: 'Pickle Rick!!!') + JsiiCalc::RootStructValidator.validate(string_prop: 'Pickle Rick!!!', nested_struct: nil) + JsiiCalc::RootStructValidator.validate(string_prop: 'Pickle Rick!!!', nested_struct: { number_prop: 1337 }) + end + + it 'hydrates structs passed to host validators' do + struct = JsiiCalc::RootStruct.new( + string_prop: 'hello', + nested_struct: JsiiCalc::NestedStruct.new(number_prop: 10) + ) + + # Should not raise error + JsiiCalc::RootStructValidator.validate(struct) + + # Test failure case + invalid_struct = JsiiCalc::RootStruct.new( + string_prop: 'hello', + nested_struct: JsiiCalc::NestedStruct.new(number_prop: -1) + ) + expect { JsiiCalc::RootStructValidator.validate(invalid_struct) }.to raise_error(Jsii::RuntimeError, /numberProp must be > 0/) + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/sync_overrides_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/sync_overrides_spec.rb new file mode 100644 index 0000000000..bcdae62ec2 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/sync_overrides_spec.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'json' + +# Suite tests: syncOverrides, syncOverrides_callsSuper, +# fail_syncOverrides_callsDoubleAsync_{method,propertyGetter,propertySetter}, +# callbacksCorrectlyDeserializeArguments. +# +# The re-entrant callback path. When a host method like `caller_is_method` +# synchronously invokes a guest override mid-request, the wire protocol nests +# a `callback` message inside the still-pending `invoke` — the Ruby kernel +# must answer the callback before its own request can complete. +# `callsSuper` goes one level deeper: the guest override re-enters the +# kernel *again* from inside the callback. The three fail_* tests assert the +# kernel correctly *refuses* an async call made from a sync callback context +# (it would deadlock the single request pipe), surfaced as Jsii::Error. +# +# The SyncOverrides fixture class is defined in spec/support/fixtures.rb. +RSpec.describe 'JSII compliance: sync overrides' do + it 'invokes guest overrides of sync virtual methods', compliance: 'syncOverrides' do + obj = SyncOverrides.new + expect(obj.caller_is_method).to eq(10 * 5) + + obj.multiplier = 5 + expect(obj.caller_is_method).to eq(10 * 5 * 5) + + # verify callbacks are invoked from a property + expect(obj.caller_is_property).to eq(10 * 5 * 5) + + # and from an async method + obj.multiplier = 3 + expect(obj.caller_is_async).to eq(10 * 5 * 3) + end + + it 'lets sync overrides call super', compliance: 'syncOverrides_callsSuper' do + obj = SyncOverrides.new + expect(obj.caller_is_property).to eq(10 * 5) + obj.return_super = true + expect(obj.caller_is_property).to eq(10 * 2) + end + + it 'raises when an async method is called from a sync override (method)', compliance: 'fail_syncOverrides_callsDoubleAsync_method' do + obj = SyncOverrides.new + obj.call_async = true + + expect { obj.caller_is_method }.to raise_error(Jsii::Error) + end + + it 'raises when an async method is called from a sync override (property getter)', compliance: 'fail_syncOverrides_callsDoubleAsync_propertyGetter' do + obj = SyncOverrides.new + obj.call_async = true + + expect { obj.caller_is_property }.to raise_error(Jsii::Error) + end + + it 'raises when an async method is called from a sync override (property setter)', compliance: 'fail_syncOverrides_callsDoubleAsync_propertySetter' do + obj = SyncOverrides.new + obj.call_async = true + + expect { obj.caller_is_property = 12 }.to raise_error(Jsii::Error) + end + + it 'correctly deserializes callback arguments', compliance: 'callbacksCorrectlyDeserializeArguments' do + klass = Class.new(JsiiCalc::DataRenderer) do + def render_map(map) + super(map) + end + end + renderer = klass.new + + result = renderer.render({ anumber: 42, astring: 'bazinga!' }) + # Compare structurally — the exact `JSON.stringify` formatting is a + # Node-implementation detail and can change across Node versions. + expect(JSON.parse(result)).to eq({ 'anumber' => 42, 'astring' => 'bazinga!' }) + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance/union_types_spec.rb b/packages/@jsii/ruby-runtime-test/spec/compliance/union_types_spec.rb new file mode 100644 index 0000000000..298bc89ad7 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance/union_types_spec.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Suite tests: unionTypes, unionProperties, unionPropertiesWithBuilder, +# correctlyDeserializesStructUnions, canObtainReferenceWithOverloadedSetter, +# canObtainStructReferenceWithOverloadedSetter. +# +# `A | B`-typed slots. Values set through a union-typed property must come +# back as their *concrete* type, not some boxed wrapper. +# `correctlyDeserializesStructUnions` is the interesting one: given a +# `StructA | StructB` parameter, the serialized form must let the JS side +# tell which struct it received (the set of keys present decides). The +# ConfusingToJackson tests are regressions for types whose setters accept +# unions — historically these broke code generation in other languages. +RSpec.describe 'JSII compliance: union types' do + it 'sets and reads union-typed properties with the concrete type', compliance: 'unionTypes' do + types = JsiiCalc::AllTypes.new + + # single valued property + types.union_property = 1234 + expect(types.union_property).to eq(1234) + + types.union_property = 'Hello' + expect(types.union_property).to eq('Hello') + + types.union_property = JsiiCalc::Multiply.new(Scope::JsiiCalcLib::Number.new(2), Scope::JsiiCalcLib::Number.new(12)) + expect(types.union_property.value).to eq(24) + + # array + types.union_array_property = [123, Scope::JsiiCalcLib::Number.new(33)] + expect(types.union_array_property[1].value).to eq(33) + end + + it 'round-trips union-typed values through the calculator', compliance: 'unionProperties' do + calc = JsiiCalc::Calculator.new + calc.union_property = JsiiCalc::Multiply.new(Scope::JsiiCalcLib::Number.new(9), Scope::JsiiCalcLib::Number.new(3)) + expect(calc.union_property).to be_a(JsiiCalc::Multiply) + expect(calc.read_union_value).to eq(9 * 3) + + calc.union_property = JsiiCalc::Power.new(Scope::JsiiCalcLib::Number.new(10), Scope::JsiiCalcLib::Number.new(3)) + expect(calc.union_property).to be_a(JsiiCalc::Power) + expect(calc.read_union_value).to eq(10**3) + end + + it 'constructs objects with union-typed struct properties', compliance: 'unionPropertiesWithBuilder' do + obj1 = JsiiCalc::UnionProperties.new(bar: 12, foo: 'Hello') + expect(obj1.bar).to eq(12) + expect(obj1.foo).to eq('Hello') + + obj2 = JsiiCalc::UnionProperties.new(bar: 'BarIsString') + expect(obj2.bar).to eq('BarIsString') + expect(obj2.foo).to be_nil + + all_types = JsiiCalc::AllTypes.new + obj3 = JsiiCalc::UnionProperties.new(bar: all_types, foo: 999) + expect(obj3.bar).to eq(all_types) + expect(obj3.foo).to eq(999) + end + + it 'disambiguates structs in a union by their properties', compliance: 'correctlyDeserializesStructUnions' do + a0 = JsiiCalc::StructA.new(required_string: 'Present!', optional_string: 'Bazinga!') + a1 = JsiiCalc::StructA.new(required_string: 'Present!', optional_number: 1337) + b0 = JsiiCalc::StructB.new(required_string: 'Present!', optional_boolean: true) + b1 = JsiiCalc::StructB.new(required_string: 'Present!', optional_struct_a: a1) + + expect(JsiiCalc::StructUnionConsumer.is_struct_a(a0)).to be true + expect(JsiiCalc::StructUnionConsumer.is_struct_a(a1)).to be true + expect(JsiiCalc::StructUnionConsumer.is_struct_a(b0)).to be false + expect(JsiiCalc::StructUnionConsumer.is_struct_a(b1)).to be false + + expect(JsiiCalc::StructUnionConsumer.is_struct_b(a0)).to be false + expect(JsiiCalc::StructUnionConsumer.is_struct_b(a1)).to be false + expect(JsiiCalc::StructUnionConsumer.is_struct_b(b0)).to be true + expect(JsiiCalc::StructUnionConsumer.is_struct_b(b1)).to be true + end + + it 'returns a class with an overloaded (union-typed) setter from the kernel', compliance: 'canObtainReferenceWithOverloadedSetter' do + expect(JsiiCalc::ConfusingToJackson.make_instance).not_to be_nil + end + + it 'returns a struct with an overloaded (union-typed) setter from the kernel', compliance: 'canObtainStructReferenceWithOverloadedSetter' do + expect(JsiiCalc::ConfusingToJackson.make_struct_instance).not_to be_nil + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/compliance_formatter.rb b/packages/@jsii/ruby-runtime-test/spec/compliance_formatter.rb new file mode 100644 index 0000000000..8b44b36388 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/compliance_formatter.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'rspec/core/formatters/base_formatter' +require 'json' + +# Collects the results of examples tagged with `compliance: ''` +# metadata and writes them to compliance-report.json, which is consumed by +# tools/jsii-compliance/report.ts to build the per-language compliance matrix +# (gh-pages/content/specification/6-compliance-report.md). +# +# The canonical test names are defined in tools/jsii-compliance/suite.ts. +# To mark a spec as implementing a suite test, tag it: +# +# it 'reads arrays returned by methods', compliance: 'arrayReturnedByMethodCanBeRead' do +# ... +# end +class ComplianceFormatter < RSpec::Core::Formatters::BaseFormatter + RSpec::Core::Formatters.register self, :example_passed, :example_failed, :close + + def initialize(output) + super(output) + @results = {} + end + + def example_passed(notification) + record(notification.example, 'success') + end + + def example_failed(notification) + record(notification.example, 'failure') + end + + def close(_notification) + # Sorted so the report is deterministic regardless of spec execution order. + File.write('compliance-report.json', JSON.pretty_generate(@results.sort.to_h)) + end + + private + + def record(example, status) + key = example.metadata[:compliance] + @results[key] = { status: status } if key + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/spec_helper.rb b/packages/@jsii/ruby-runtime-test/spec/spec_helper.rb new file mode 100644 index 0000000000..1d04c1e4fd --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/spec_helper.rb @@ -0,0 +1,63 @@ +require 'jsii' +require 'json' + +RSpec.configure do |config| + config.color = true + config.formatter = :documentation + + config.before(:suite) do + # Set NODE_PATH before anything else touches Jsii::Kernel + root_node_modules = File.expand_path('../../../../node_modules', __dir__) + if ENV['NODE_PATH'] + ENV['NODE_PATH'] = "#{root_node_modules}#{File::PATH_SEPARATOR}#{ENV['NODE_PATH']}" + else + ENV['NODE_PATH'] = root_node_modules + end + + # Add the generated lib to the load path + lib_path = File.expand_path('../lib/ruby/lib', __dir__) + $LOAD_PATH.unshift(lib_path) + $LOAD_PATH.unshift(File.join(lib_path, '@scope')) + + # Load the assemblies into the kernel + kernel = Jsii::Kernel.instance + + # Assembly order matters for dependencies + assemblies = [ + '@scope/jsii-calc-base-of-base', + '@scope/jsii-calc-base', + '@scope/jsii-calc-lib', + 'jsii-calc' + ] + + assemblies.each do |name| + # Extract base name from scoped name + base_name = name.split('/').last + # Find the tarball for this assembly + tarball_path = Dir.glob(File.join(lib_path, "**", "#{base_name}@*.jsii.tgz")).first + + if tarball_path + # Extract version from filename: name@version.jsii.tgz + version = File.basename(tarball_path).split('@').last.gsub('.jsii.tgz', '') + puts "DEBUG: Loading assembly #{name} version #{version} from #{tarball_path}" if ENV['JSII_DEBUG'] + kernel.load_assembly(name, version, tarball_path) + else + puts "WARN: Could not find tarball for assembly #{name}" if ENV['JSII_DEBUG'] + end + end + + # Require the generated code + require '@scope/jsii-calc-base-of-base' + require '@scope/jsii-calc-base' + require '@scope/jsii-calc-lib' + require 'jsii-calc' + end + + config.after(:suite) do + Jsii::Kernel.instance.shutdown + end +end + +# Shared native fixture classes (registers another before(:suite) hook, which +# runs after the assembly-loading hook above). +require_relative 'support/fixtures' diff --git a/packages/@jsii/ruby-runtime-test/spec/support/fixtures.rb b/packages/@jsii/ruby-runtime-test/spec/support/fixtures.rb new file mode 100644 index 0000000000..0739d9b6d1 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/support/fixtures.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +# Shared native fixture classes used across the compliance specs. +# +# These are defined in a `before(:suite)` hook (rather than at the top level) +# because the JsiiCalc constants only exist once spec_helper's assembly-loading +# `before(:suite)` hook has run. RSpec runs suite hooks in registration order, +# and spec_helper requires this file after registering its own hook. +RSpec.configure do |config| + config.before(:suite) do + # Subclass of AsyncVirtualMethods whose override delegates to another + # method on the same (base) class. + Object.const_set(:OverrideAsyncMethodsByBaseClass, Class.new(JsiiCalc::AsyncVirtualMethods) do + def override_me(mult) + foo * 2 + end + + def foo + 2222 + end + end) + + # Async override that calls super. + Object.const_set(:OverrideCallsSuper, Class.new(JsiiCalc::AsyncVirtualMethods) do + def override_me(mult) + super_ret = super(mult) + super_ret * 10 + 1 + end + end) + + # Two simultaneous async overrides. + Object.const_set(:TwoOverrides, Class.new(JsiiCalc::AsyncVirtualMethods) do + def override_me(mult) + 666 + end + + def override_me_too + 10 + end + end) + + # Native subclasses of host classes, used to verify that object identity + # is preserved when native objects round-trip through the kernel. + Object.const_set(:AddTen, Class.new(JsiiCalc::Add) do + def initialize(value) + super(Scope::JsiiCalcLib::Number.new(value), Scope::JsiiCalcLib::Number.new(10)) + end + end) + + Object.const_set(:MulTen, Class.new(JsiiCalc::Multiply) do + def initialize(value) + super(Scope::JsiiCalcLib::Number.new(value), Scope::JsiiCalcLib::Number.new(10)) + end + end) + + # A pure-native (no host base class) implementation of + # IFriendlyRandomGenerator. + Object.const_set(:PureNativeFriendlyRandom, Class.new do + include JsiiCalc::IFriendlyRandomGenerator + + def initialize + @next_number = 1000 + end + + def _next + n = @next_number + @next_number += 1000 + n + end + + def hello + 'I am a native!' + end + end) + + # A native subclass of a host class that also implements host interfaces. + Object.const_set(:SubclassNativeFriendlyRandom, Class.new(Scope::JsiiCalcLib::Number) do + include Scope::JsiiCalcLib::IFriendly + include JsiiCalc::IRandomNumberGenerator + + def initialize + super(908) + @next_number = 100 + end + + def hello + 'SubclassNativeFriendlyRandom' + end + + def _next + n = @next_number + @next_number += 100 + n + end + end) + + # Configurable sync-override harness for SyncVirtualMethods. + Object.const_set(:SyncOverrides, Class.new(JsiiCalc::SyncVirtualMethods) do + attr_accessor :multiplier, :return_super, :call_async, :another_the_property + + def initialize + super + @multiplier = 1 + @return_super = false + @call_async = false + @another_the_property = nil + end + + def virtual_method(n) + return super(n) if @return_super + + if @call_async + obj = JsiiCalc::AsyncVirtualMethods.new + return obj.call_me + end + + 5 * n * @multiplier + end + + def the_property + 'I am an override!' + end + + def the_property=(value) + @another_the_property = value + end + end) + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/autoload_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/autoload_spec.rb new file mode 100644 index 0000000000..a2dd985dd2 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/autoload_spec.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'open3' + +# Generated assemblies are emitted as a thin loader (`lib/.rb`) plus +# one file per namespace-direct type, wired together with `Module#autoload` +# (for constant references in user code) and `Jsii::Object.register_autoload` +# (for fqns the kernel hands back that the user never named — the pervasive +# case in CDK: `vpc.public_subnets`, `bucket.grant_read`, ...). +# +# The full compliance suite exercises both paths incidentally, but nothing in +# it would *fail loudly* if lazy loading silently reverted to eager `class` +# definitions, or if a load trigger regressed. These specs pin that behaviour. +# +# They run in a *fresh* Ruby process so referencing and load order are fully +# controlled — the aggregate suite loads types in an order that can mask +# forward-reference and "loaded too early" bugs. The kernel-touching +# `Jsii::Assembly.load` is neutralised in the child, so no node sidecar is +# needed and the checks are pure Ruby autoload mechanics. +describe 'lazy (autoload) code generation' do + # Run an assertion script against the generated jsii-calc in a clean + # interpreter; returns [stdout+stderr, success?]. + def run_in_fresh_process(body) + lib_path = File.expand_path('../../lib/ruby/lib', __dir__) + script = <<~RUBY + lib = #{lib_path.inspect} + $LOAD_PATH.unshift(lib, File.join(lib, '@scope')) + require 'jsii' + + # We're testing pure-Ruby autoload wiring; neutralise the kernel-touching + # assembly load so the child needs no node sidecar and stays deterministic. + Jsii::Assembly.define_singleton_method(:load) { |*| nil } + + require 'jsii-calc' + + $failures = [] + def check(cond, msg) = ($failures << msg unless cond) + + #{body} + + if $failures.empty? + puts 'AUTOLOAD_OK' + else + $failures.each { |m| warn "ASSERT FAILED: \#{m}" } + exit 1 + end + RUBY + + Open3.popen3('bundle', 'exec', 'ruby', '-') do |stdin, stdout, stderr, wait| + stdin.write(script) + stdin.close + out = stdout.read + stderr.read + [out, wait.value.success?] + end + end + + it 'defers type definitions instead of eager-loading them' do + out, ok = run_in_fresh_process(<<~RUBY) + total = Jsii::Object.autoload_paths.size + loaded = Jsii::Object.registry.keys.count { |k| k.start_with?('jsii-calc') } + check(total > 100, "expected many registered autoload paths, got \#{total}") + # Requiring the loader must not have defined the type bodies. + check(loaded < total / 4, "too many types eager-loaded: \#{loaded}/\#{total}") + RUBY + expect(out).to include('AUTOLOAD_OK'), out + expect(ok).to be(true), out + end + + it 'loads a type on first constant reference, resolving cross-file forward refs' do + out, ok = run_in_fresh_process(<<~RUBY) + check(JsiiCalc.autoload?(:Calculator), 'Calculator is not autoload-pending after require') + check(!Jsii::Object.registry.key?('jsii-calc.Calculator'), 'Calculator was loaded too early') + + klass = JsiiCalc::Calculator # triggers the autoload, and its forward refs + + check(Jsii::Object.registry['jsii-calc.Calculator'].equal?(klass), + 'Calculator did not self-register on load') + check(klass.jsii_fqn == 'jsii-calc.Calculator', + "Calculator fqn wrong: \#{klass.jsii_fqn.inspect}") + # Its superclass lives in a different generated file; touching Calculator + # must transitively autoload it without a NameError. + check(klass.superclass == JsiiCalc::Composition::CompositeOperation, + "forward-ref superclass not resolved: \#{klass.superclass}") + RUBY + expect(out).to include('AUTOLOAD_OK'), out + expect(ok).to be(true), out + end + + it 'hydrates a kernel-returned fqn the user never referenced (the CDK trap)' do + out, ok = run_in_fresh_process(<<~RUBY) + # Pick any registered type that has NOT been loaded — i.e. its constant + # was never referenced. This is exactly what the kernel hands back for + # the bulk of an object graph. + fqn = Jsii::Object.autoload_paths.keys.find { |f| !Jsii::Object.registry.key?(f) } + check(!fqn.nil?, 'no unreferenced type available to test the fallback') + + if fqn + resolved = Jsii::Object.find_class_by_fqn(fqn) + check(!resolved.nil?, "find_class_by_fqn(\#{fqn}) returned nil") + check(Jsii::Object.registry.key?(fqn), + "\#{fqn} not registered after load-on-miss") + end + RUBY + expect(out).to include('AUTOLOAD_OK'), out + expect(ok).to be(true), out + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/callbacks_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/callbacks_spec.rb new file mode 100644 index 0000000000..90de943657 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/callbacks_spec.rb @@ -0,0 +1,66 @@ +require 'spec_helper' + +describe Jsii::Kernel::Callbacks do + let(:callbacks_class) do + Class.new do + include Jsii::Kernel::Callbacks + end + end + let(:callbacks) { callbacks_class.new } + + before do + allow(Jsii::Kernel).to receive(:instance).and_return(double('kernel')) + end + + describe '#handle_callback_invoke' do + it 'escapes reserved words in method names correctly' do + objref = 'mock@123' + instance = double('JsiiObject') + allow(Jsii::Object).to receive(:find_by_ref).with(objref).and_return(instance) + + invoke_req = { + 'objref' => objref, + 'method' => 'send', # JS name is 'send' + 'args' => [] + } + + # We expect __send__ to be called with '_send' as the method name + expect(instance).to receive(:__send__).with('_send') + + callbacks.send(:handle_callback_invoke, invoke_req) + end + end + + describe '#handle_callback_get' do + it 'escapes reserved words in property names correctly' do + objref = 'mock@123' + instance = double('JsiiObject') + allow(Jsii::Object).to receive(:find_by_ref).with(objref).and_return(instance) + + get_req = { + 'objref' => objref, + 'property' => 'class' # JS name is 'class' + } + + expect(instance).to receive(:__send__).with('_class') + callbacks.send(:handle_callback_get, get_req) + end + end + + describe '#handle_callback_set' do + it 'escapes reserved words in property setters correctly' do + objref = 'mock@123' + instance = double('JsiiObject') + allow(Jsii::Object).to receive(:find_by_ref).with(objref).and_return(instance) + + set_req = { + 'objref' => objref, + 'property' => 'class', # JS name is 'class' + 'value' => 'new_value' + } + + expect(instance).to receive(:__send__).with('_class=', 'new_value') + callbacks.send(:handle_callback_set, set_req) + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/hash_coercion_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/hash_coercion_spec.rb new file mode 100644 index 0000000000..4a0d7ff64c --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/hash_coercion_spec.rb @@ -0,0 +1,152 @@ +require 'spec_helper' + +RSpec.describe 'JSII Compliance' do + describe 'Hash-to-Struct Coercion' do + it 'passes plain hashes to constructors expecting structs' do + # Calculator accepts a CalculatorProps struct - passing a plain Hash + # should be automatically coerced into a CalculatorProps instance + calc = JsiiCalc::Calculator.new(maximum_value: 100) + calc.add(50) + expect(calc.value).to eq(50) + + # Verify the max_value was actually applied by the coerced struct + expect(calc.max_value).to eq(100) + end + + it 'passes plain hashes to static methods expecting structs' do + # StructPassing.round_trip expects a TopLevelStruct - passing a plain Hash + result = JsiiCalc::StructPassing.round_trip( + 123, + required: 'hello_from_hash', + second_level: JsiiCalc::SecondLevelStruct.new(deeper_required_prop: 'nested_value') + ) + + expect(result).to be_a(JsiiCalc::TopLevelStruct) + expect(result.required).to eq('hello_from_hash') + expect(result.second_level).to be_a(JsiiCalc::SecondLevelStruct) + expect(result.second_level.deeper_required_prop).to eq('nested_value') + end + + it 'coerces hashes in union-typed struct members with a single struct arm' do + # second_level is union(number, SecondLevelStruct): exactly one struct + # arm and no map/any arm, so a Hash is unambiguous and gets coerced. + # Round-tripping through the kernel proves the wire form is correct + # (an uncoerced hash would serialize snake_case keys, not camelCase). + result = JsiiCalc::StructPassing.round_trip( + 7, + required: 'hello', + second_level: { deeper_required_prop: 'coerced!' } + ) + + expect(result.second_level).to be_a(JsiiCalc::SecondLevelStruct) + expect(result.second_level.deeper_required_prop).to eq('coerced!') + end + + it 'coerces hashes inside arrays and maps of structs (struct members)' do + props = JsiiCalc::ContainerProps.new( + array_prop: [{ example: 'one' }, JsiiCalc::DummyObj.new(example: 'two')], + obj_prop: { 'a' => { example: 'three' } }, + record_prop: { 'b' => { example: 'four' } } + ) + + expect(props.array_prop[0]).to be_a(JsiiCalc::DummyObj) + expect(props.array_prop[0].example).to eq('one') + expect(props.array_prop[1].example).to eq('two') + expect(props.obj_prop['a']).to be_a(JsiiCalc::DummyObj) + expect(props.obj_prop['a'].example).to eq('three') + expect(props.record_prop['b'].example).to eq('four') + end + + it 'coerces hashes inside collection-of-struct method/constructor parameters' do + obj = JsiiCalc::ClassWithContainerTypes.new( + [{ example: 'a' }], + { 'k' => { example: 'b' } }, + { 'j' => { example: 'c' } } + ) + + expect(obj.array.first.example).to eq('a') + expect(obj.record['k'].example).to eq('b') + expect(obj.obj['j'].example).to eq('c') + end + + it 'accepts string-keyed hashes (e.g. parsed JSON) wherever structs are coerced' do + # The keyword splat needs Symbol keys; coercion symbolizes them so a + # JSON-shaped hash works instead of raising a bare ArgumentError. + calc = JsiiCalc::Calculator.new({ 'maximum_value' => 100 }) + expect(calc.max_value).to eq(100) + + result = JsiiCalc::StructPassing.round_trip( + 1, + { 'required' => 'hi', 'second_level' => { 'deeper_required_prop' => 'deep' } } + ) + expect(result.second_level.deeper_required_prop).to eq('deep') + + props = JsiiCalc::ContainerProps.new( + array_prop: [{ 'example' => 'one' }], + obj_prop: { 'a' => { 'example' => 'two' } }, + record_prop: {} + ) + expect(props.array_prop[0].example).to eq('one') + expect(props.obj_prop['a'].example).to eq('two') + end + + it 'reports unknown struct keys as a clear ArgumentError' do + expect { JsiiCalc::CalculatorProps.new(bogus_key: 1) } + .to raise_error(ArgumentError, /unknown keyword.*bogus_key/) + end + + it 'still accepts explicit struct instances in constructors' do + # Ensure backwards compatibility - explicit struct instances should still work + props = JsiiCalc::CalculatorProps.new(maximum_value: 200) + calc = JsiiCalc::Calculator.new(props) + calc.add(150) + expect(calc.value).to eq(150) + expect(calc.max_value).to eq(200) + end + + it 'accepts keyword arguments directly for constructors' do + # The most idiomatic Ruby pattern: keyword args passed as a trailing hash + calc = JsiiCalc::Calculator.new(initial_value: 42, maximum_value: 1000) + expect(calc.value).to eq(42) + expect(calc.max_value).to eq(1000) + end + + it 'accepts keyword arguments directly for instance methods taking a trailing struct' do + # Ruby 3.x collapses keyword-syntax args into a final positional Hash + # when the method has no explicit kwargs params; the generator's + # `x = ::Struct.new(**x) if x.is_a?(Hash)` then coerces it. + giver = JsiiCalc::GiveMeStructs.new + expect(giver.read_first_number(astring: 'hello', anumber: 1337)).to eq(1337) + end + end + + describe 'Struct Deserialization' do + it 'deserializes $jsii.struct tokens into instantiated struct classes recursively' do + raw_struct = { + '$jsii.struct' => { + 'fqn' => 'jsii-calc.TopLevelStruct', + 'data' => { + 'required' => 'hello', + 'secondLevel' => { + '$jsii.struct' => { + 'fqn' => 'jsii-calc.SecondLevelStruct', + 'data' => { + 'deeperRequiredProp' => 'nested' + } + } + } + } + } + } + + hydrated = Jsii::Serializer.load(raw_struct) + + expect(hydrated).to be_a(JsiiCalc::TopLevelStruct) + expect(hydrated.required).to eq('hello') + + # Verifies recursive struct deserialization and JSII property mapping to Ruby keywords + expect(hydrated.second_level).to be_a(JsiiCalc::SecondLevelStruct) + expect(hydrated.second_level.deeper_required_prop).to eq('nested') + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/kernel_concurrency_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/kernel_concurrency_spec.rb new file mode 100644 index 0000000000..96192e1d46 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/kernel_concurrency_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Smoke tests for the kernel's threading invariants. These cannot catch +# every race, but they reliably catch regressions of the mutex / thread-local +# pending-object refactor by exercising the patterns those changes target. +RSpec.describe 'Kernel concurrency' do + it 'serializes concurrent requests without corrupting the response stream' do + # Without the kernel mutex, the JSON frames on stdin/stdout would + # interleave and JSON.parse would blow up (or the wrong thread would + # consume another thread's response). + threads = 8.times.map do |i| + Thread.new do + n = Scope::JsiiCalcLib::Number.new(i + 1) + expect(n.value).to eq(i + 1) + end + end + threads.each(&:join) + end + + it 'keeps `pending_object` per-thread across concurrent constructions' do + # Two threads constructing different objects simultaneously must not + # see each other's pending instances. With a shared @pending_object + # they would race; with a thread-local stack they don't. + seen = Queue.new + + threads = 4.times.map do |i| + Thread.new do + n = Scope::JsiiCalcLib::Number.new(i) + seen << [i, n.value] + end + end + threads.each(&:join) + + results = [] + results << seen.pop until seen.empty? + expect(results.sort).to eq([[0, 0], [1, 1], [2, 2], [3, 3]]) + end + + it 'supports re-entrant kernel calls from a single thread' do + # An override that itself calls back into the kernel exercises the + # Monitor's re-entrancy. Without re-entrancy, the second call would + # deadlock waiting on the lock the current thread already holds. + inner_values = Queue.new + klass = Class.new(JsiiCalc::SyncVirtualMethods) do + define_method(:virtual_method) do |n| + # During the kernel's callback dispatch we synchronously make another + # kernel call. Without a re-entrant lock this would deadlock. + inner = Scope::JsiiCalcLib::Number.new(n) + inner_values << inner.value + n * 3 + end + end + + expect(klass.new.caller_is_method).to eq(10 * 3) + expect(inner_values.pop).to eq(10) + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/missing_member_contract_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/missing_member_contract_spec.rb new file mode 100644 index 0000000000..be7ae076af --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/missing_member_contract_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# CONTRACT: Jsii::Error#missing_member? classifies "member not found" errors +# by string-matching the wording @jsii/kernel puts in its error messages — +# there is no structured error code on the wire to key off. +# DynamicInvocation#method_missing uses that classification to fall through +# to Ruby's normal method_missing chain (NoMethodError) instead of +# re-raising, so an upstream rewording would silently turn every dynamic +# dispatch fallback into a hard Jsii::Error raise. These examples trigger +# the real errors through the actual kernel sidecar (the same way the +# compliance specs drive it) so a wording change fails the suite instead. +# +# Wording pinned by the sidecar as of this writing: +# get / set -> "Type jsii-calc.Calculator doesn't have a property 'x'" +# invoke -> "Class jsii-calc.Calculator doesn't have a method 'x'" +RSpec.describe 'Jsii::Error#missing_member? kernel wording contract' do + let(:calculator) { JsiiCalc::Calculator.new } + + # Run the block, which must be rejected by the kernel, and return the error. + def kernel_error + yield + raise 'expected the kernel to reject the request with a Jsii::Error' + rescue Jsii::Error => e + e + end + + it 'classifies the kernel error for getting an unknown property' do + error = kernel_error do + Jsii::Kernel.instance.get_property(calculator.jsii_ref, 'definitelyNotAJsiiMember') + end + + expect(error.missing_member?) + .to be(true), "kernel rewording broke missing_member? for get: #{error.message.inspect}" + end + + it 'classifies the kernel error for setting an unknown property' do + error = kernel_error do + Jsii::Kernel.instance.set_property(calculator.jsii_ref, 'definitelyNotAJsiiMember', 42) + end + + expect(error.missing_member?) + .to be(true), "kernel rewording broke missing_member? for set: #{error.message.inspect}" + end + + it 'classifies the kernel error for invoking an unknown method' do + error = kernel_error do + Jsii::Kernel.instance.call_method(calculator.jsii_ref, 'definitelyNotAJsiiMember', []) + end + + expect(error.missing_member?) + .to be(true), "kernel rewording broke missing_member? for invoke: #{error.message.inspect}" + end + + it 'routes an unknown member through method_missing to NoMethodError end-to-end' do + # The no-arg dynamic path tries `get`, then `invoke`; BOTH kernel errors + # must classify as missing-member for the call to reach Ruby's + # NoMethodError instead of surfacing a Jsii::Error. + expect { calculator.definitely_not_a_jsii_member }.to raise_error(NoMethodError) + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/rbs_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/rbs_spec.rb new file mode 100644 index 0000000000..d92b8ac01e --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/rbs_spec.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'open3' +require 'tmpdir' +require 'fileutils' + +# The generator emits RBS type signatures (`sig/.rbs`) alongside the +# Ruby sources. Without a guard, nothing catches the generator emitting RBS that +# fails to parse/resolve — and the failure modes are real and easy to +# reintroduce (a bare `A | B` union collides with RBS's method-overload +# separator; a dangling superclass; a member whose signature drifts from the +# reserved-name mangling the `.rb` uses). +# +# These specs run `rbs validate` over the *actually generated* sigs for the +# jsii-calc closure, which exercises the tricky shapes (unions, optionals, +# variadics, DateTime, reserved-word members, structs, cross-assembly refs). +# The final example is a negative control proving the guard has teeth. +describe 'generated RBS signatures' do + # Generated assembly sigs reference the runtime gem's own classes + # (`::Jsii::Object`/`Struct`/`Enum`) as superclasses, so the runtime sig must + # be on the load path too; `DateTime` requires the stdlib `date` library. + runtime_sig = File.expand_path('../../../ruby-runtime/sig', __dir__) + generated_sig = File.expand_path('../../lib/ruby/sig', __dir__) + + def rbs_validate(*include_dirs) + cmd = ['bundle', 'exec', 'rbs', '-r', 'date'] + include_dirs.each { |d| cmd.push('-I', d) } + cmd.push('validate') + out, status = Open3.capture2e(*cmd) + [out, status.success?] + end + + it 'are emitted for the whole jsii-calc dependency closure' do + %w[jsii-calc.rbs @scope/jsii-calc-lib.rbs @scope/jsii-calc-base.rbs + @scope/jsii-calc-base-of-base.rbs].each do |rel| + expect(File.exist?(File.join(generated_sig, rel))).to be(true), "missing sig: #{rel}" + end + end + + it 'validate clean (runtime sig + generated sigs + the date library)' do + out, ok = rbs_validate(runtime_sig, generated_sig) + expect(ok).to be(true), "rbs validate failed:\n#{out}" + end + + # The validate above is only meaningful if it actually covers the hard cases; + # assert the tricky shapes are present in the emitted output (so a clean + # validate is a clean validate *of these*, not of a degenerate signature). + context 'the emitted jsii-calc sig' do + let(:sig) { File.read(File.join(generated_sig, 'jsii-calc.rbs')) } + + it 'parenthesizes unions (the overload-separator hazard)' do + # e.g. `Array[(Numeric | ::Scope::JsiiCalcLib::NumericValue)]` + expect(sig).to match(/\([^()\n]+ \| [^()\n]+\)/) + end + + it 'reflects reserved-word member mangling, matching the .rb' do + # `next` is a Ruby keyword → `_next` in both the source and the sig. + expect(sig).to match(/def _next:/) + end + + it 'maps optionals to nilable types and variadics to splats' do + expect(sig).to match(/\?\w+: [^,)]+\?/) # an optional kwarg with a nilable type + expect(sig).to match(/\(\*/) # a variadic parameter + end + + it 'maps jsii Date to DateTime (which is why the date library is required)' do + expect(sig).to match(/: DateTime/) + end + end + + it 'fail validation when a signature is malformed (negative control)' do + Dir.mktmpdir do |dir| + # A dangling superclass is exactly the class of error a generator + # regression would produce; rbs must reject it. + File.write(File.join(dir, 'broken.rbs'), <<~RBS) + class BrokenProxy < ::Jsii::ClassThatDoesNotExist + end + RBS + _out, ok = rbs_validate(runtime_sig, dir) + expect(ok).to be(false), 'rbs validate unexpectedly passed on a dangling superclass' + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/registry_pending_object_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/registry_pending_object_spec.rb new file mode 100644 index 0000000000..df8895501b --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/registry_pending_object_spec.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Unit coverage for the fqn-guarded pending-object fallback in +# Registry#find_by_ref. During a kernel `create`, the sidecar may fire +# callbacks that reference the object being constructed before its ref has +# been registered — that ref (and only that ref) must resolve to the +# in-flight instance. Refs are labelled `@`, so an unknown ref +# carrying a *different* fqn is some other object entirely and must not be +# misrouted to the pending instance (the pre-guard behavior). +# +# These specs drive the registry and the kernel's per-thread pending stack +# directly (no wire traffic), using fake `jsii-calc.Fake*` refs that are +# scrubbed from the process-wide instance map afterwards. +RSpec.describe 'Registry pending-object fallback' do + let(:kernel) { Jsii::Kernel.instance } + let(:fqn) { 'jsii-calc.FakePendingType' } + let(:ref) { "#{fqn}@990001" } + let(:instance) { Jsii::Object.allocate } + + after do + # Undo any eager ref binding so the process-wide registry stays clean + # for the other suites. + Jsii::Object.objects.delete_if { |key, _| key.start_with?('jsii-calc.Fake') } + end + + # Push an entry onto the per-thread pending stack for the duration of the + # block, exactly the way `Api#create_object` brackets its request. + def with_pending(pending_instance, pending_fqn) + kernel.push_pending_object(pending_instance, pending_fqn) + yield + ensure + kernel.pop_pending_object + end + + it 'resolves an unknown ref with the in-flight fqn to the pending instance' do + with_pending(instance, fqn) do + expect(Jsii::Object.find_by_ref(ref)).to be(instance) + end + end + + it 'accepts the wire-envelope Hash form of the ref' do + with_pending(instance, fqn) do + expect(Jsii::Object.find_by_ref({ '$jsii.byref' => ref })).to be(instance) + end + end + + it 'eagerly binds the ref so later lookups and re-registration agree' do + with_pending(instance, fqn) do + Jsii::Object.find_by_ref(ref) + end + + # Bound during the fallback, so the ref stays resolvable after the + # create window closes... + expect(Jsii::Object.objects[ref]).to be(instance) + + # ...and the post-create register_instance re-registers the same + # instance under the same ref without conflict. + instance.instance_variable_set(:@jsii_ref, ref) + Jsii::Object.register_instance(instance) + expect(Jsii::Object.objects[ref]).to be(instance) + end + + it 'does not resolve an unknown ref with a different fqn to the pending instance' do + with_pending(instance, fqn) do + expect(Jsii::Object.find_by_ref('jsii-calc.FakeOtherType@990002')).to be_nil + end + end + + it 'builds a fresh proxy for a different-fqn ref instead of misrouting it' do + with_pending(instance, fqn) do + other = Jsii::Object.from_jsii_ref('jsii-calc.FakeOtherType@990002', 'jsii-calc.FakeOtherType') + expect(other).not_to be(instance) + expect(other.jsii_ref).to eq('jsii-calc.FakeOtherType@990002') + end + end + + it 'resolves an outer in-flight instance from inside a nested create' do + inner = Jsii::Object.allocate + with_pending(instance, fqn) do + with_pending(inner, 'jsii-calc.FakeInnerType') do + expect(Jsii::Object.find_by_ref(ref)).to be(instance) + end + end + end + + it 'skips pending entries whose create carries no instance' do + with_pending(nil, fqn) do + expect(Jsii::Object.find_by_ref(ref)).to be_nil + end + end + + it 'returns nil for an unknown ref when no construction is in flight' do + expect(Jsii::Object.find_by_ref('jsii-calc.FakeAbsentType@990003')).to be_nil + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/reserved_name_callback_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/reserved_name_callback_spec.rb new file mode 100644 index 0000000000..e24a7f4803 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/reserved_name_callback_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +# Regression for: kernel callback dispatch must honor the generator's +# reserved-name rename, so a JSII member named `break` finds the +# generated `_break` method on the Ruby override. +RSpec.describe 'reserved-name callback dispatch' do + before(:all) do + Object.const_set(:ReservedWordImpl, Class.new do + include JsiiCalc::IJavaReservedWordsInAnInterface + attr_accessor :calls + def initialize; @calls = []; end + def _break; @calls << :break; nil; end + def _while; @calls << :while; 'w'; end + def _class; @calls << :class; nil; end + end) unless Object.const_defined?(:ReservedWordImpl) + end + + it "dispatches an invoke({ method: 'break' }) callback to the generated `_break`" do + obj = ReservedWordImpl.new + # Force JSII registration of the native object so the kernel can address it. + ref = Jsii::Kernel.instance.send(:serialize_native_implementations, obj) + expect(ref).to be_a(Hash) + objref = ref['$jsii.byref'] + + Jsii::Kernel.instance.send( + :handle_callback_invoke, + { 'objref' => { '$jsii.byref' => objref }, 'method' => 'break', 'args' => [] } + ) + expect(obj.calls).to eq([:break]) + end + + it "dispatches a get({ property: 'while' }) callback to the generated `_while`" do + obj = ReservedWordImpl.new + ref = Jsii::Kernel.instance.send(:serialize_native_implementations, obj) + objref = ref['$jsii.byref'] + result = Jsii::Kernel.instance.send( + :handle_callback_get, + { 'objref' => { '$jsii.byref' => objref }, 'property' => 'while' } + ) + expect(result).to eq('w') + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/respond_to_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/respond_to_spec.rb new file mode 100644 index 0000000000..ec937008af --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/respond_to_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +RSpec.describe 'respond_to?' do + it 'returns false for to_ary and other internal coercions' do + types = JsiiCalc::AllTypes.new + expect(types.respond_to?(:to_ary)).to be false + expect(types.respond_to?(:to_hash)).to be false + expect(types.respond_to?(:to_str)).to be false + expect(types.respond_to?(:to_proc)).to be false + expect(types.respond_to?(:to_int)).to be false + expect(types.respond_to?(:to_io)).to be false + end + + it 'does NOT blackhole jsii methods that happen to start with to_' do + # Earlier the dispatcher rejected anything `to_*`, which broke common JSII + # member names like `toString`, `toJSON`, `toArray` (all snake-cased to + # `to_string`, `to_json`, `to_array`). Now we should claim to respond + # to them so they dispatch to the kernel normally. + types = JsiiCalc::AllTypes.new + expect(types.respond_to?(:to_string)).to be true + expect(types.respond_to?(:to_json)).to be true + expect(types.respond_to?(:to_array)).to be true + end + + it 'returns true for dynamic methods forwarded to JSII' do + types = JsiiCalc::AllTypes.new + + # We should claim to respond to typical JSII properties/methods dynamically + expect(types.respond_to?(:dynamic_foo)).to be true + expect(types.respond_to?(:some_unknown_method)).to be true + end + + it 'returns false and raises NoMethodError for invalid JSII patterns (like operators)' do + types = JsiiCalc::AllTypes.new + + expect(types.respond_to?(:+)).to be false + expect { types + 1 }.to raise_error(NoMethodError) + + expect(types.respond_to?(:foo?)).to be false + expect { types.foo? }.to raise_error(NoMethodError) + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/sam_coercion_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/sam_coercion_spec.rb new file mode 100644 index 0000000000..18611f515e --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/sam_coercion_spec.rb @@ -0,0 +1,164 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# Jsii::Utils.coerce_callable — Proc/Hash coercion into single-abstract-method +# (SAM) interface implementations. This is Ruby-side ergonomics in front of +# the wire contract, exactly like hash-to-struct coercion: after the wrapper +# is built, everything downstream is the ordinary (compliance-tested) native +# interface implementation path. +RSpec.describe 'SAM callable coercion' do + let(:sam_interface) do + Module.new do + def self.jsii_fqn + 'fake.ISingleMethod' + end + + def self.jsii_overridable_methods + { your_turn: { kind: :method, name: 'yourTurn', is_optional: false } } + end + end + end + + let(:two_method_interface) do + Module.new do + def self.jsii_fqn + 'fake.ITwoMethods' + end + + def self.jsii_overridable_methods + { + first: { kind: :method, name: 'first', is_optional: false }, + second: { kind: :method, name: 'second', is_optional: false } + } + end + end + end + + let(:property_interface) do + Module.new do + def self.jsii_fqn + 'fake.IProperty' + end + + def self.jsii_overridable_methods + { value: { kind: :property, name: 'value', is_optional: false } } + end + end + end + + describe 'bare Proc form' do + it 'wraps a lambda into an implementing object' do + seen = nil + wrapped = Jsii::Utils.coerce_callable(->(bell) { seen = bell; :rang }, sam_interface) + + expect(wrapped).to be_a(sam_interface) + expect(wrapped.your_turn(:the_bell)).to eq(:rang) + expect(seen).to eq(:the_bell) + end + + it 'produces an object the serializer recognises as a native implementation' do + wrapped = Jsii::Utils.coerce_callable(-> {}, sam_interface) + expect(Jsii::Serializer.jsii_native_implementation?(wrapped)).to be true + end + + it 'wraps a zero-arity proc for a zero-arg member' do + wrapped = Jsii::Utils.coerce_callable(-> { 42 }, sam_interface) + expect(wrapped.your_turn).to eq(42) + end + end + + describe 'single-entry Hash form (the TypeScript object-literal mirror)' do + it 'wraps { member: proc }' do + wrapped = Jsii::Utils.coerce_callable({ your_turn: ->(x) { x * 2 } }, sam_interface) + expect(wrapped).to be_a(sam_interface) + expect(wrapped.your_turn(21)).to eq(42) + end + + it 'passes through a hash whose key is not the member name' do + value = { wrong_key: -> {} } + expect(Jsii::Utils.coerce_callable(value, sam_interface)).to equal(value) + end + + it 'passes through a multi-entry hash' do + value = { your_turn: -> {}, extra: 1 } + expect(Jsii::Utils.coerce_callable(value, sam_interface)).to equal(value) + end + + it 'passes through a hash whose value is not a proc' do + value = { your_turn: 42 } + expect(Jsii::Utils.coerce_callable(value, sam_interface)).to equal(value) + end + end + + describe 'non-SAM interfaces and non-coercible values pass through unchanged' do + it 'ignores procs aimed at a two-method interface' do + value = -> {} + expect(Jsii::Utils.coerce_callable(value, two_method_interface)).to equal(value) + end + + it 'ignores procs aimed at a single-property interface' do + value = -> {} + expect(Jsii::Utils.coerce_callable(value, property_interface)).to equal(value) + end + + it 'ignores plain values' do + expect(Jsii::Utils.coerce_callable(42, sam_interface)).to eq(42) + expect(Jsii::Utils.coerce_callable(nil, sam_interface)).to be_nil + end + + it 'ignores modules without override metadata' do + value = -> {} + expect(Jsii::Utils.coerce_callable(value, Module.new)).to equal(value) + end + end + + describe 'end to end through the kernel (jsii-calc)' do + it 'a coerced lambda rings the bell via a real callback round-trip' do + ringer = Jsii::Utils.coerce_callable(->(bell) { bell.ring }, JsiiCalc::IBellRinger) + + expect(JsiiCalc::ConsumerCanRingBell.static_implemented_by_object_literal(ringer)).to be true + expect(JsiiCalc::ConsumerCanRingBell.new.implemented_by_object_literal(ringer)).to be true + end + + it 'the hash form works identically' do + ringer = Jsii::Utils.coerce_callable({ your_turn: ->(bell) { bell.ring } }, JsiiCalc::IBellRinger) + expect(JsiiCalc::ConsumerCanRingBell.static_implemented_by_object_literal(ringer)).to be true + end + end + + describe 'generated code applies the coercion automatically' do + it 'accepts a raw lambda where a SAM interface parameter is expected' do + expect( + JsiiCalc::ConsumerCanRingBell.static_implemented_by_object_literal(->(bell) { bell.ring }) + ).to be true + expect( + JsiiCalc::ConsumerCanRingBell.new.implemented_by_object_literal(->(bell) { bell.ring }) + ).to be true + end + + it 'accepts the TypeScript-mirror hash form at the call site' do + expect( + JsiiCalc::ConsumerCanRingBell.static_implemented_by_object_literal( + { your_turn: ->(bell) { bell.ring } } + ) + ).to be true + end + + it 'ordinary implementing objects are unaffected' do + ringer = Class.new do + include JsiiCalc::IBellRinger + def your_turn(bell) + bell.ring + end + end.new + expect(JsiiCalc::ConsumerCanRingBell.static_implemented_by_object_literal(ringer)).to be true + end + + it 'a non-coercible value still fails ordinary type checking' do + expect do + JsiiCalc::ConsumerCanRingBell.static_implemented_by_object_literal(42) + end.to raise_error(TypeError) + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/serializer_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/serializer_spec.rb new file mode 100644 index 0000000000..7cfafb57c8 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/serializer_spec.rb @@ -0,0 +1,115 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'date' +require 'time' + +RSpec.describe Jsii::Serializer do + describe '.dump' do + it 'passes scalars through unchanged' do + [nil, true, false, 0, 1.5, 'hello', :sym].each do |scalar| + expect(described_class.dump(scalar)).to eq(scalar) + end + end + + it 'recursively dumps arrays' do + input = [1, 'two', [3, 4], { 'k' => 'v' }] + expect(described_class.dump(input)).to eq([1, 'two', [3, 4], { 'k' => 'v' }]) + end + + it 'recursively dumps hash values' do + input = { 'outer' => { 'inner' => 1 }, 'list' => [1, 2] } + expect(described_class.dump(input)).to eq(input) + end + + it 'wraps Date as a $jsii.date envelope' do + result = described_class.dump(Date.new(2024, 6, 15)) + expect(result).to include('$jsii.date') + expect(result['$jsii.date']).to start_with('2024-06-15T') + end + + it 'wraps Time as a UTC $jsii.date envelope' do + time = Time.utc(2024, 6, 15, 12, 30, 45) + result = described_class.dump(time) + expect(result).to eq({ '$jsii.date' => '2024-06-15T12:30:45.000Z' }) + end + + it 'wraps DateTime as a $jsii.date envelope' do + dt = DateTime.new(2024, 6, 15, 12, 30, 45, '+00:00') + result = described_class.dump(dt) + expect(result).to eq({ '$jsii.date' => '2024-06-15T12:30:45.000+00:00' }) + end + + it 'serializes Jsii::Enum to a $jsii.enum envelope' do + enum = Jsii::Enum.new('jsii-calc.Color', 'RED') + expect(described_class.dump(enum)).to eq({ '$jsii.enum' => 'jsii-calc.Color/RED' }) + end + + it 'raises TypeError for plain Ruby objects (does NOT walk or stringify host objects)' do + # The previous monkey-patched Object#jsii_serialize would have walked any + # object with an @jsii_ref ivar. Untyped host objects must not be walked + # — and must not silently pass through either, because JSON.generate + # would stringify them into "#" garbage on the wire. They + # fail fast with an error naming the class instead. + host_object = Object.new + host_object.instance_variable_set(:@jsii_ref, 'this is a host detail, not jsii state') + + expect { described_class.dump(host_object) } + .to raise_error(TypeError, /cannot serialize instance of Object to the jsii wire format/) + end + end + + describe '.load' do + it 'passes scalars through unchanged' do + [nil, true, false, 0, 1.5, 'hello'].each do |scalar| + expect(described_class.load(scalar)).to eq(scalar) + end + end + + it 'decodes a $jsii.date envelope into a DateTime' do + result = described_class.load({ '$jsii.date' => '2024-06-15T12:30:45.000Z' }) + expect(result).to be_a(DateTime) + expect(result.year).to eq(2024) + expect(result.month).to eq(6) + expect(result.day).to eq(15) + end + + it 'decodes a $jsii.enum envelope into a Jsii::Enum' do + result = described_class.load({ '$jsii.enum' => 'jsii-calc.Color/RED' }) + expect(result).to be_a(Jsii::Enum) + expect(result.fqn).to eq('jsii-calc.Color') + expect(result.value).to eq('RED') + end + + it 'recursively loads array elements' do + input = [{ '$jsii.enum' => 'foo/A' }, 'plain'] + result = described_class.load(input) + expect(result[0]).to be_a(Jsii::Enum) + expect(result[1]).to eq('plain') + end + + it 'recursively loads hash values that are not envelopes' do + input = { 'list' => [1, { '$jsii.enum' => 'foo/A' }] } + result = described_class.load(input) + expect(result['list'][1]).to be_a(Jsii::Enum) + end + + it 'unwraps $jsii.map envelopes by loading the inner hash' do + result = described_class.load({ '$jsii.map' => { 'a' => 1, 'b' => 2 } }) + expect(result).to eq({ 'a' => 1, 'b' => 2 }) + end + end + + describe 'round-trip' do + it 'dump/load is the identity for plain JSON-like values' do + value = { 'a' => 1, 'b' => [true, false, nil, 2.5], 'c' => 'hello' } + expect(described_class.load(described_class.dump(value))).to eq(value) + end + + it 'round-trips an enum' do + enum = Jsii::Enum.new('jsii-calc.Color', 'RED') + result = described_class.load(described_class.dump(enum)) + expect(result).to eq(enum) + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/type_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/type_spec.rb new file mode 100644 index 0000000000..600e911f92 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/type_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' + + +module Mock + class BaseStruct < Jsii::Struct + def self.jsii_fqn + 'mock.BaseStruct' + end + end + + class DerivedStruct < BaseStruct + def self.jsii_fqn + 'mock.DerivedStruct' + end + end + + class UnrelatedStruct < Jsii::Struct + def self.jsii_fqn + 'mock.UnrelatedStruct' + end + end +end + +RSpec.describe Jsii::Type do + describe '.check_fqn' do + before do + # Mock the registry to return our mock structs + allow(Jsii::Type).to receive(:resolve_fqn_to_ruby_class) do |fqn| + case fqn + when 'mock.BaseStruct' then Mock::BaseStruct + when 'mock.DerivedStruct' then Mock::DerivedStruct + when 'mock.UnrelatedStruct' then Mock::UnrelatedStruct + else nil + end + end + end + + it 'allows Hash for any struct' do + expect { + Jsii::Type.send(:check_fqn, {}, 'mock.BaseStruct', 'arg') + }.not_to raise_error + end + + it 'allows direct instances of the struct' do + expect { + Jsii::Type.send(:check_fqn, Mock::BaseStruct.new, 'mock.BaseStruct', 'arg') + }.not_to raise_error + end + + it 'allows subclass instances (normal inheritance)' do + expect { + Jsii::Type.send(:check_fqn, Mock::DerivedStruct.new, 'mock.BaseStruct', 'arg') + }.not_to raise_error + end + + it 'allows unrelated structs (duck typing for multiple inheritance)' do + expect { + Jsii::Type.send(:check_fqn, Mock::UnrelatedStruct.new, 'mock.BaseStruct', 'arg') + }.not_to raise_error + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/type_validation_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/type_validation_spec.rb new file mode 100644 index 0000000000..3e8e70ee7c --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/type_validation_spec.rb @@ -0,0 +1,130 @@ +require 'spec_helper' + +RSpec.describe 'Runtime Type Validation' do + it 'validates primitive types on property assignment' do + types = JsiiCalc::AllTypes.new + + expect { types.string_property = 123 }.to raise_error(TypeError, /Expected stringProperty to be a String/) + expect { types.number_property = "hello" }.to raise_error(TypeError, /Expected numberProperty to be a Numeric/) + expect { types.boolean_property = "true" }.to raise_error(TypeError, /Expected booleanProperty to be a Boolean/) + end + + it 'validates arrays and maps' do + types = JsiiCalc::AllTypes.new + + expect { types.array_property = "not an array" }.to raise_error(TypeError, /Expected arrayProperty to be an Array/) + expect { types.array_property = ["string", 123] }.to raise_error(TypeError, /Expected arrayProperty\[1\] to be a String/) + + expect { types.map_property = "not a hash" }.to raise_error(TypeError, /Expected mapProperty to be a Hash/) + expect { types.map_property = { "foo" => "not a number" } }.to raise_error(TypeError, /Expected mapProperty\["foo"\] to be of type/) + end + + it 'validates json property' do + types = JsiiCalc::AllTypes.new + + expect { types.json_property = ["array", "of", "json"] }.not_to raise_error + expect { types.json_property = { "foo" => "bar" } }.not_to raise_error + end + + it 'does not allow hashes for class types' do + expect { Jsii::Type.check_type({}, { 'fqn' => 'jsii-calc.Multiply' }, 'multiply_arg') }.to raise_error(TypeError, /Expected multiply_arg to be of type JsiiCalc::Multiply/) + end + + describe 'union types' do + let(:union_spec) do + { + 'union' => { + 'types' => [ + { 'primitive' => 'string' }, + { 'primitive' => 'number' } + ] + } + } + end + + it 'accepts a value matching any arm' do + expect { Jsii::Type.check_type('hello', union_spec, 'arg') }.not_to raise_error + expect { Jsii::Type.check_type(42, union_spec, 'arg') }.not_to raise_error + end + + it 'raises TypeError when no arm matches' do + expect do + Jsii::Type.check_type(true, union_spec, 'arg') + end.to raise_error(TypeError, /Expected arg to match one of the union types/) + end + + it 'raises TypeError when value is nil and union does not allow it' do + # The union type validator does not have an "optional" flag of its own; + # nil should fail every arm and surface as a union mismatch. + expect do + Jsii::Type.check_type(nil, union_spec, 'arg') + end.to raise_error(TypeError, /Expected arg to match one of the union types/) + end + end + + describe 'unknown type references' do + it 'raises TypeError on a bare {} type ref' do + expect { Jsii::Type.check_type('x', {}, 'arg') }.to raise_error(TypeError, /Unknown type reference/) + end + + it 'raises TypeError on an unknown primitive' do + expect do + Jsii::Type.check_type('x', { 'primitive' => 'bigint' }, 'arg') + end.to raise_error(TypeError, /Unknown primitive type/) + end + end + + describe 'struct member validation' do + it 'raises TypeError for a wrong-typed required member' do + expect { JsiiCalc::StructB.new(required_string: 123) } + .to raise_error(TypeError, /Expected requiredString to be a String/) + end + + it 'raises TypeError for a wrong-typed optional member' do + expect { JsiiCalc::StructB.new(required_string: 'ok', optional_boolean: 'nope') } + .to raise_error(TypeError, /Expected optionalBoolean to be a Boolean/) + end + + it 'accepts nil for optional members' do + expect { JsiiCalc::StructB.new(required_string: 'ok', optional_boolean: nil) } + .not_to raise_error + end + + it 'validates coerced hash members against the struct type' do + struct = JsiiCalc::StructB.new( + required_string: 'ok', + optional_struct_a: { required_string: 'inner' } + ) + expect(struct.optional_struct_a).to be_a(JsiiCalc::StructA) + end + end + + describe 'constructor parameter validation' do + it 'validates struct-typed constructor parameters' do + # Regression: initializer parameters carry raw spec type refs; the + # generator used to read `.spec` off them (undefined) and emit checks + # against {primitive: 'any'} — i.e. constructors validated nothing. + expect { JsiiCalc::Calculator.new('not props') } + .to raise_error(TypeError, /Expected props to be of type/) + end + + it 'enforces zero arity for parameterless constructors' do + # Previously a catch-all (*args) silently forwarded stray arguments + # to the kernel. + expect { JsiiCalc::AllTypes.new(123) }.to raise_error(ArgumentError) + expect { JsiiCalc::AllTypes.new }.not_to raise_error + end + + it 'raises a helpful error when constructing a private-constructor class' do + # Classes without an initializer entry in the assembly have private + # constructors: instances only come from factories (hydrated via + # allocate, which never calls #initialize). + expect { JsiiCalc::ClassWithPrivateConstructorAndAutomaticProperties.new('a', 'b') } + .to raise_error(NoMethodError, /does not have a visible constructor/) + + # The factory path is unaffected. + obj = JsiiCalc::ClassWithPrivateConstructorAndAutomaticProperties.create('Hello', 'Bye') + expect(obj.read_only_string).to eq('Hello') + end + end +end diff --git a/packages/@jsii/ruby-runtime-test/spec/unit/utils_spec.rb b/packages/@jsii/ruby-runtime-test/spec/unit/utils_spec.rb new file mode 100644 index 0000000000..6252d10ee4 --- /dev/null +++ b/packages/@jsii/ruby-runtime-test/spec/unit/utils_spec.rb @@ -0,0 +1,181 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Jsii::Utils do + describe '.underscore' do + it 'converts camelCase to snake_case' do + expect(described_class.underscore('camelCase')).to eq('camel_case') + expect(described_class.underscore('readOnlyString')).to eq('read_only_string') + end + + it 'converts PascalCase to snake_case' do + expect(described_class.underscore('PascalCase')).to eq('pascal_case') + expect(described_class.underscore('S3Bucket')).to eq('s3_bucket') + end + + it 'preserves trailing acronym groups' do + expect(described_class.underscore('parseHTML')).to eq('parse_html') + expect(described_class.underscore('HTTPRequest')).to eq('http_request') + end + + # The implementation is adapted from ActiveSupport's String#underscore + # and inherits two behaviors no jsii input can ever trigger: member names + # on the wire are plain camelCase identifiers (alphanumeric, see + # dynamic_invocation.rb), so they never contain '-' or '::'. These + # examples pin the inherited behavior so a future reimplementation that + # changes it does so knowingly. + it 'replaces hyphens with underscores (ActiveSupport heritage; unused by jsii)' do + expect(described_class.underscore('foo-bar')).to eq('foo_bar') + end + + it 'converts namespace separators to path separators, NOT underscores (ActiveSupport heritage; unused by jsii)' do + expect(described_class.underscore('Foo::Bar')).to eq('foo/bar') + end + + it 'is a no-op for already snake_case strings' do + expect(described_class.underscore('already_snake')).to eq('already_snake') + end + + it 'accepts symbols' do + expect(described_class.underscore(:fooBar)).to eq('foo_bar') + end + end + + describe '.camelize' do + it 'converts snake_case to camelCase' do + expect(described_class.camelize('snake_case')).to eq('snakeCase') + expect(described_class.camelize('read_only_string')).to eq('readOnlyString') + end + + it 'accepts symbols' do + expect(described_class.camelize(:foo_bar)).to eq('fooBar') + end + + it 'leaves single-word strings unchanged' do + expect(described_class.camelize('foo')).to eq('foo') + end + end + + describe '.ruby_member_name' do + it 'passes through non-reserved snake_case names' do + expect(described_class.ruby_member_name('fooBar')).to eq('foo_bar') + expect(described_class.ruby_member_name('hello')).to eq('hello') + end + + it 'prefixes Ruby keywords with an underscore' do + expect(described_class.ruby_member_name('break')).to eq('_break') + expect(described_class.ruby_member_name('class')).to eq('_class') + expect(described_class.ruby_member_name('while')).to eq('_while') + expect(described_class.ruby_member_name('end')).to eq('_end') + end + + it 'prefixes runtime-critical Object methods (send, __send__) with an underscore' do + # Without this remap, a callback for a JSII member named `send` would + # invoke `Object#send` and treat the first arg as a method name. + expect(described_class.ruby_member_name('send')).to eq('_send') + expect(described_class.ruby_member_name('__send__')).to eq('___send__') + end + + it 'prefixes names that start with a digit' do + expect(described_class.ruby_member_name('2fa')).to eq('_2fa') + end + + it 'mirrors the generator on names that snake_case into a keyword' do + # Generator path: toSnakeCase('While') === 'while' → reserved → '_while'. + expect(described_class.ruby_member_name('While')).to eq('_while') + end + + it 'prefixes constructor/allocation hooks (initialize, new, allocate)' do + # A JSII member named `initialize` would otherwise replace the + # generated constructor; `new`/`allocate` are the class methods used + # to instantiate proxies (the registry hydrates refs via + # `klass.allocate`). + expect(described_class.ruby_member_name('initialize')).to eq('_initialize') + expect(described_class.ruby_member_name('new')).to eq('_new') + expect(described_class.ruby_member_name('allocate')).to eq('_allocate') + end + + it 'prefixes runtime serialization/dispatch hooks (to_jsii, ruby_class)' do + expect(described_class.ruby_member_name('toJsii')).to eq('_to_jsii') + expect(described_class.ruby_member_name('rubyClass')).to eq('_ruby_class') + end + + it 'prefixes any name in the reserved jsii_ namespace' do + # The whole `jsii_` prefix is reserved for the runtime's API surface, + # present and future — jsii_ref, jsii_serialize, jsii_call_method, ... + expect(described_class.ruby_member_name('jsiiRef')).to eq('_jsii_ref') + expect(described_class.ruby_member_name('jsiiSerialize')).to eq('_jsii_serialize') + expect(described_class.ruby_member_name('jsiiSomeFutureApi')).to eq('_jsii_some_future_api') + end + end + + describe '.blank?' do + it 'returns true for nil' do + expect(described_class.blank?(nil)).to be true + end + + it 'returns true for empty strings and whitespace-only strings' do + expect(described_class.blank?('')).to be true + expect(described_class.blank?(' ')).to be true + expect(described_class.blank?("\t\n")).to be true + end + + it 'returns false for non-empty strings' do + expect(described_class.blank?('hello')).to be false + end + + it 'returns true for empty arrays/hashes' do + expect(described_class.blank?([])).to be true + expect(described_class.blank?({})).to be true + end + + it 'returns false for non-empty arrays/hashes' do + expect(described_class.blank?([1])).to be false + expect(described_class.blank?({ a: 1 })).to be false + end + + it 'returns false for any non-string non-collection non-nil value' do + expect(described_class.blank?(0)).to be false + expect(described_class.blank?(false)).to be false + end + end + + describe 'does not monkey-patch core classes' do + # Regression guard: jsii-ruby-runtime must coexist with ActiveSupport. + it 'does not define underscore on String' do + expect('Anything').not_to respond_to(:underscore) + end + + it 'does not define camelize on String or Symbol' do + expect('anything').not_to respond_to(:camelize) + expect(:anything).not_to respond_to(:camelize) + end + + it 'does not define blank? on Object' do + expect(Object.new).not_to respond_to(:blank?) + end + + it 'does not define jsii_serialize on Object' do + expect(Object.new).not_to respond_to(:jsii_serialize) + end + + it 'does not define jsii_deserialize on Hash' do + expect({}).not_to respond_to(:jsii_deserialize) + end + end + + describe 'RUBY_RESERVED_NAMES' do + it 'is consistent with jsii-pacmak' do + pacmak_ruby_ts = File.expand_path('../../../../jsii-pacmak/lib/targets/ruby.ts', __dir__) + expect(File.exist?(pacmak_ruby_ts)).to be(true), "Expected #{pacmak_ruby_ts} to exist" + + content = File.read(pacmak_ruby_ts) + match = content.match(/const RUBY_RESERVED_NAMES = new Set\(\[(.*?)\]\)/m) + expect(match).not_to be_nil + + pacmak_names = match[1].scan(/'([^']+)'/).flatten.to_set + expect(Jsii::Utils::RUBY_RESERVED_NAMES).to eq(pacmak_names) + end + end +end diff --git a/packages/@jsii/ruby-runtime/.gitignore b/packages/@jsii/ruby-runtime/.gitignore new file mode 100644 index 0000000000..da5b6f81ec --- /dev/null +++ b/packages/@jsii/ruby-runtime/.gitignore @@ -0,0 +1,2 @@ +/doc/ +/.yardoc/ diff --git a/packages/@jsii/ruby-runtime/.rubocop.yml b/packages/@jsii/ruby-runtime/.rubocop.yml new file mode 100644 index 0000000000..a83e1c8e60 --- /dev/null +++ b/packages/@jsii/ruby-runtime/.rubocop.yml @@ -0,0 +1,37 @@ +AllCops: + # Keep in sync with required_ruby_version in jsii-ruby-runtime.gemspec. + TargetRubyVersion: 3.3 + NewCops: disable + SuggestExtensions: false + +# This gem is an RPC bridge to a Node sidecar. The kernel naturally +# multiplexes many concerns in a few hot methods (popen3 setup, request +# loop, shutdown sequencing, type-dispatch serializers) and splitting them +# for the sake of the metric raises noise without making the code clearer. +# Bumped thresholds, not disabled, so a runaway method still trips. +Metrics/MethodLength: + Max: 25 + +Metrics/ClassLength: + Max: 200 + +Metrics/AbcSize: + Max: 22 + +Metrics/CyclomaticComplexity: + Max: 10 + +Metrics/PerceivedComplexity: + Max: 15 + +# `consistent` keeps multi-line hash literals at a stable 2-space indent +# from the line start, regardless of how deep the surrounding call sits. +# The default `special_inside_parentheses` style aligns to the column +# after the opening `(`, which produces very deep, hard-to-read indents +# for `send_payload({ complete: { ... } })`-style calls. +Layout/FirstHashElementIndentation: + EnforcedStyle: consistent + +# Same rationale for multi-line argument lists. +Layout/FirstArgumentIndentation: + EnforcedStyle: consistent diff --git a/packages/@jsii/ruby-runtime/.yardopts b/packages/@jsii/ruby-runtime/.yardopts new file mode 100644 index 0000000000..90104edf31 --- /dev/null +++ b/packages/@jsii/ruby-runtime/.yardopts @@ -0,0 +1,3 @@ +--markup markdown +--output-dir doc +lib/**/*.rb diff --git a/packages/@jsii/ruby-runtime/Gemfile b/packages/@jsii/ruby-runtime/Gemfile new file mode 100644 index 0000000000..7f4f5e950d --- /dev/null +++ b/packages/@jsii/ruby-runtime/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source 'https://rubygems.org' + +gemspec diff --git a/packages/@jsii/ruby-runtime/Gemfile.lock b/packages/@jsii/ruby-runtime/Gemfile.lock new file mode 100644 index 0000000000..4849ca31c4 --- /dev/null +++ b/packages/@jsii/ruby-runtime/Gemfile.lock @@ -0,0 +1,77 @@ +PATH + remote: . + specs: + jsii-ruby-runtime (0.0.0) + base64 (~> 0.2) + +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.3) + base64 (0.3.0) + json (2.21.1) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + parallel (1.28.0) + parser (3.3.11.1) + ast (~> 2.4.1) + racc + prism (1.9.0) + racc (1.8.1) + rainbow (3.1.1) + rake (13.4.2) + regexp_parser (2.12.0) + rubocop (1.86.2) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (>= 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.49.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.49.1) + parser (>= 3.3.7.2) + prism (~> 1.7) + ruby-progressbar (1.13.0) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.2.0) + yard (0.9.43) + +PLATFORMS + ruby + x86_64-linux-gnu + +DEPENDENCIES + jsii-ruby-runtime! + rake (~> 13.0) + rubocop (~> 1.86) + yard (~> 0.9) + +CHECKSUMS + ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + bundler (4.0.11) sha256=5bcec0fb78302e48d02ee46f10ee6e6942be647ba5b44a6d1ddfda9a240ce785 + jsii-ruby-runtime (0.0.0) + json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583 + language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc + lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 + parallel (1.28.0) sha256=33e6de1484baf2524792d178b0913fc8eb94c628d6cfe45599ad4458c638c970 + parser (3.3.11.1) sha256=d17ace7aabe3e72c3cc94043714be27cc6f852f104d81aa284c2281aecc65d54 + prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f + rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a + rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701 + regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb + rubocop (1.86.2) sha256=bb2e97f635eda42c448f2588f4a6ff78f221b8bdfdf65b1e9b07fbd57521b45d + rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035 + ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 + unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 + unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f + yard (0.9.43) sha256=cf8733a8f0485df2a162927e9b5f182215a61f6d22de096b8f402c726a1c5821 + +BUNDLED WITH + 4.0.11 diff --git a/packages/@jsii/ruby-runtime/Rakefile b/packages/@jsii/ruby-runtime/Rakefile new file mode 100644 index 0000000000..3fc0d963da --- /dev/null +++ b/packages/@jsii/ruby-runtime/Rakefile @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# The runtime's tests (unit and compliance) live in +# packages/@jsii/ruby-runtime-test — run them from there with +# `bundle exec rspec`. + +begin + require 'yard' + YARD::Rake::YardocTask.new(:doc) do |t| + t.files = ['lib/**/*.rb'] + end +rescue LoadError + # yard not installed; `rake doc` unavailable +end diff --git a/packages/@jsii/ruby-runtime/jsii-ruby-runtime.gemspec b/packages/@jsii/ruby-runtime/jsii-ruby-runtime.gemspec new file mode 100644 index 0000000000..eb372093d6 --- /dev/null +++ b/packages/@jsii/ruby-runtime/jsii-ruby-runtime.gemspec @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'json' +package = JSON.parse(File.read(File.expand_path('package.json', __dir__))) + +Gem::Specification.new do |s| + s.name = 'jsii-ruby-runtime' + s.version = package['version'] + s.summary = package['description'] || 'Official JSII core runtime engine for Ruby' + s.authors = [package['author'] || 'JSII Generator'] + s.license = package['license'] || 'Apache-2.0' + s.files = Dir['lib/**/*.rb'] + Dir['sig/**/*.rbs'] + s.required_ruby_version = '>= 3.3.0' + s.add_dependency 'base64', '~> 0.2' + + s.add_development_dependency 'rake', '~> 13.0' + s.add_development_dependency 'rubocop', '~> 1.86' + s.add_development_dependency 'yard', '~> 0.9' +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii.rb b/packages/@jsii/ruby-runtime/lib/jsii.rb new file mode 100644 index 0000000000..5fdc2404fa --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +# Top-level namespace for the JSII Ruby runtime. See {Jsii::Kernel} for the +# Node sidecar bridge, {Jsii::Object} for the proxy base class, {Jsii::Struct} +# for value-typed data classes, and {Jsii::Serializer} for the wire codec. +module Jsii + # Unsafely cast a JSII object proxy to a different JSII type/interface. + # + # @param obj [Jsii::Object] the object proxy to cast. + # @param klass [Class, Module] the target JSII class or interface module. + # @return [Jsii::Object] a new proxy instance representing the target type. + def self.downcast(obj, klass) + return nil if obj.nil? + raise TypeError, "Expected a Jsii::Object" unless obj.is_a?(Jsii::Object) + + if klass.is_a?(Class) + instance = klass.allocate + else + instance = Jsii::Object.allocate.extend(klass) + end + instance.instance_variable_set(:@jsii_ref, obj.jsii_ref) + Jsii::Object.register_instance(instance) + instance + end +end + +require_relative 'jsii/errors' +require_relative 'jsii/utils' +require_relative 'jsii/kernel' +require_relative 'jsii/object' +require_relative 'jsii/enum' +require_relative 'jsii/struct' +require_relative 'jsii/serializer' +require_relative 'jsii/assembly' +require_relative 'jsii/type' diff --git a/packages/@jsii/ruby-runtime/lib/jsii/assembly.rb b/packages/@jsii/ruby-runtime/lib/jsii/assembly.rb new file mode 100644 index 0000000000..31fbeb2d0c --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/assembly.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Jsii + # Represents a JSII assembly loaded into the runtime. + class Assembly + # @return [String] the npm-style package name of the assembly (e.g. `"jsii-calc"`). + attr_reader :name + + # @return [String] the assembly's semantic version (e.g. `"3.20.120"`). + attr_reader :version + + # @return [String] absolute filesystem path to the `.jsii.tgz` tarball backing this assembly. + attr_reader :tarball + + # @param name [String] the npm-style package name of the assembly. + # @param version [String] the assembly's semantic version. + # @param tarball [String] absolute filesystem path to the `.jsii.tgz` tarball. + # @return [Assembly] a new wrapper around the supplied metadata. + def initialize(name, version, tarball) + @name = name + @version = version + @tarball = tarball + end + + # Loads the given assembly into the JSII kernel and returns a wrapper. + # + # @param name [String] the npm-style package name of the assembly. + # @param version [String] the assembly's semantic version. + # @param tarball [String] absolute filesystem path to the `.jsii.tgz` tarball. + # @return [Assembly] a wrapper representing the loaded assembly. + # @raise [Jsii::RuntimeError] if the kernel rejects the load request. + def self.load(name, version, tarball) + # Trigger the loading of the given assembly in the JSII kernel. + Jsii::Kernel.instance.load_assembly(name, version, tarball) + new(name, version, tarball) + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/enum.rb b/packages/@jsii/ruby-runtime/lib/jsii/enum.rb new file mode 100644 index 0000000000..a7b2f6df27 --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/enum.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module Jsii + # Represents a JSII enumeration value passed by-reference. + class Enum + # @return [String] the fully-qualified name of the enum type (e.g. `"jsii-calc.StringEnum"`). + attr_reader :fqn + + # @return [String] the enum member name (e.g. `"A"`). + attr_reader :value + + class << self + # Decodes a `$jsii.enum` wire envelope into a {Jsii::Enum} instance. + # + # @param value [Hash{String=>String}] the wire envelope `{ "$jsii.enum" => "/" }`. + # @return [Jsii::Enum] the deserialized enum value. + def jsii_deserialize(value) + enum_ref = value['$jsii.enum'] + fqn, _, member = enum_ref.rpartition('/') + Jsii::Enum.new(fqn, member) + end + end + + # @param fqn [String] fully-qualified name of the enum type. + # @param value [String] enum member name. + # @return [Jsii::Enum] a new enum value. + def initialize(fqn, value) + @fqn = fqn + @value = value + end + + # Encodes this enum into the JSII wire envelope. + # + # @return [Hash{String=>String}] `{ "$jsii.enum" => "/" }`. + def jsii_serialize + { '$jsii.enum' => "#{fqn}/#{value}" } + end + + # @return [String] the enum member name. + def to_s + @value + end + + # @return [String] a human-readable representation including fqn and member. + def inspect + "#" + end + + # Two enums are equal when they share both fqn and member. + # + # @param other [Object] the value to compare against. + # @return [Boolean] `true` iff `other` is a {Jsii::Enum} with the same fqn and value. + def ==(other) + other.is_a?(Jsii::Enum) && other.fqn == @fqn && other.value == @value + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/errors.rb b/packages/@jsii/ruby-runtime/lib/jsii/errors.rb new file mode 100644 index 0000000000..bdb29307df --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/errors.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Jsii + # Base exception class for all errors generated natively by the Ruby JSII runtime wrapper. + class Error < StandardError + # Heuristic: does this error's message indicate that a property / method + # member was not found on the underlying JSII object? Used by the + # dynamic-dispatch path to decide whether to fall through to Ruby's + # `method_missing` chain instead of re-raising. + # + # @return [Boolean] `true` if the message matches a known "missing member" phrase. + def missing_member? + msg = message + msg.include?('not a property') || + msg.include?("doesn't have a property") || + msg.include?('does not exist') || + msg.include?('is not a method') || + msg.include?('not a function') || + msg.include?("doesn't have a method") + end + end + + # Represents protocol, serialization, and boundary-level errors encountered when interacting + # with the JSII kernel via standard IO pipes. + class JSIIError < Error; end + + # Represents a runtime exception emitted by the underlying JavaScript code that has been + # bubbled up and re-raised natively in Ruby, retaining the remote stack trace. + class RuntimeError < Error + # @return [String, nil] the remote (JavaScript-side) stack trace as a newline-delimited + # string, or `nil` when no stack was provided by the kernel. + attr_reader :stack + + # @param msg [String] the error message returned by the kernel. + # @param stack [String, nil] optional remote stack trace. + # @return [RuntimeError] a new error preserving the remote stack. + def initialize(msg, stack = nil) + super(msg) + @stack = stack + end + + # @return [String] the message, suffixed with the remote stack when one was captured. + def to_s + if @stack + "#{super}\nRemote Stack:\n#{@stack}" + else + super + end + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/kernel.rb b/packages/@jsii/ruby-runtime/lib/jsii/kernel.rb new file mode 100644 index 0000000000..ea3c4b15aa --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/kernel.rb @@ -0,0 +1,425 @@ +# frozen_string_literal: true + +require 'singleton' +require 'open3' +require 'json' +require 'date' +require 'monitor' + +require_relative 'kernel/async' +require_relative 'utils' +require_relative 'serializer' +require_relative 'kernel/api' +require_relative 'kernel/callbacks' + +module Jsii + # The Kernel is responsible for managing the child Node.js process containing + # the jsii-runtime. It orchestrates all cross-language RPC communication, + # enabling Ruby objects to transparently interact with JavaScript components, + # instantiate objects, and execute methods across the boundary. + # + # Thread-safety: the kernel multiplexes a single bidirectional JSON pipe to + # the Node sidecar. Concurrent requests from multiple threads cannot + # interleave on that pipe without corrupting the framing, so `request` is + # serialized via a re-entrant `Monitor`. Re-entrant because a request can + # receive a `{ callback }` response that calls back into Ruby, and the + # user's override may in turn make further jsii calls — the same thread + # must be allowed to re-enter the lock. + # + # ## Wire protocol + # + # Communication is line-delimited JSON over the sidecar's stdin/stdout. + # Each line is exactly one JSON object; stderr is drained separately and + # used only for crash diagnostics (see {#check_crash!}). + # + # On startup the sidecar emits one **handshake** line (an object identifying + # the runtime version) before accepting requests. {#initialize} reads and + # validates it; a `nil` (EOF) means the child died and is surfaced as + # {Jsii::RuntimeError} with the captured stderr. + # + # ### Request envelope + # + # Every request is `{ api: , ...verb-specific-fields }`. The verbs: + # + # | `api` | Fields | Purpose | + # | ------------ | --------------------------------------------------------------------- | ------------------------------------------- | + # | `load` | `name`, `version`, `tarball` | Load a JSII assembly tarball. | + # | `create` | `fqn`, `args`, `overrides`, `interfaces` | Construct a remote object. | + # | `invoke` | `objref`, `method`, `args` | Call an instance method. | + # | `get` | `objref`, `property` | Read an instance property. | + # | `set` | `objref`, `property`, `value` | Write an instance property. | + # | `sinvoke` | `fqn`, `method`, `args` | Call a static method. | + # | `sget` | `fqn`, `property` | Read a static property. | + # | `sset` | `fqn`, `property`, `value` | Write a static property. | + # | `begin` | `objref`, `method`, `args` | Start an async method, returns `promiseid`. | + # | `end` | `promiseid` | Resolve a previously-`begin`'d promise. | + # | `callbacks` | — | Poll the queue of pending Ruby callbacks. | + # | `complete` | `cbid`, `result` _or_ `err`+`name`+`stack` | Reply to a callback the sidecar requested. | + # + # ### Response envelope + # + # Each line the sidecar writes is one of: + # + # * `{ "ok": }` — success; `` shape depends on the verb (e.g. + # `create` returns `{ "$jsii.byref": ... }`, `invoke`/`sinvoke` returns + # `{ "result": }`, `get`/`sget` returns `{ "value": }`). + # * `{ "error": , "name": , "stack": }` — + # remote failure. `name == "@jsii/kernel.Fault"` raises {Jsii::JSIIError} + # (protocol/boundary error); any other name raises {Jsii::RuntimeError} + # preserving the JavaScript-side stack. + # * `{ "callback": { cbid, invoke | get | set: {...} } }` — mid-request the + # sidecar is asking Ruby to service an overridden method/property on a + # `create`d object. {#request} dispatches it via the {Callbacks} mixin + # and then resumes reading for the original reply. + # + # ### Value envelopes + # + # Composite values are serialized using a small set of tag keys. These can + # appear anywhere a value is expected (request args, return values, struct + # fields, etc.) and are encoded/decoded by {Jsii::Serializer}: + # + # * `{ "$jsii.byref": "" }` — by-reference object handle issued by + # the sidecar. May also carry `$jsii.fqn` and/or `$jsii.interfaces` so + # the decoder can pick the right Ruby proxy class (see {Jsii::Object::Registry#jsii_deserialize}). + # * `{ "$jsii.struct": { "fqn": "...", "data": { ... } } }` — by-value data + # class instance; the `data` map's keys are camelCase JSII property names. + # * `{ "$jsii.enum": "/" }` — enum value (see {Jsii::Enum}). + # * `{ "$jsii.date": "" }` — `Date` / `DateTime` / `Time`, always + # normalized to UTC with millisecond precision. + # * `{ "$jsii.map": { ... } }` — used only when the map's keys would + # otherwise be ambiguous with one of the tag keys above. + # + # Primitives (`nil`, booleans, numbers, strings) pass through unchanged. + class Kernel + include Singleton + include Async + include Api + include Callbacks + + # Key used to stash the per-thread "object currently being constructed" + # stack. See `pending_object` / `push_pending_object`. + PENDING_OBJECT_STACK_KEY = :__jsii_pending_object_stack__ + + # Spawn the Node.js sidecar process, perform the protocol handshake, and + # register an `at_exit` shutdown hook. Called by `Singleton` on first + # access — never construct a Kernel directly. + # + # @return [Kernel] the singleton instance. + # @raise [Jsii::RuntimeError] if the sidecar exits before sending its + # handshake line. + # @raise [StandardError] if the `jsii-runtime` executable cannot be located + # (see {#resolve_jsii_runtime}). + def initialize + node_path = begin + ENV['NODE_PATH'] || `npm root -g`.strip + rescue StandardError + nil + end + env = node_path ? { 'NODE_PATH' => node_path } : {} + env['JSII_AGENT'] = "Ruby/#{RUBY_VERSION}" + runtime_cmd = resolve_jsii_runtime + @stdin, @stdout, @stderr, @wait_thr = Open3.popen3(env, *runtime_cmd) + + @mutex = Monitor.new + @stderr_buffer = [] + @stderr_mutex = Mutex.new + @shutdown = false + start_stderr_drain + + @handshake = @stdout.gets + check_crash!(@handshake) + + # Best-effort: graceful shutdown so the child doesn't leak as a zombie + # if the Ruby process exits without an explicit `shutdown` call. + at_exit do + shutdown + rescue StandardError + nil + end + end + + # Send a single request payload over the JSON pipe and return the + # `ok` envelope from the sidecar. Re-entrant: a response containing a + # `{ callback }` envelope is dispatched back into Ruby (which may make + # further `request` calls on the same thread) before resuming the read + # loop for the original reply. + # + # @param payload [Hash{Symbol=>Object}] the request to send (e.g. + # `{ api: 'invoke', objref: ..., method: ..., args: ... }`). + # @return [Hash, Object] the `ok` field of the kernel's response. + # @raise [Jsii::JSIIError] for protocol-level (`@jsii/kernel.Fault`) errors. + # @raise [Jsii::RuntimeError] for sidecar crashes or remote (JS) exceptions. + def request(payload) + @mutex.synchronize do + send_payload(payload) + + loop do + response_line = @stdout.gets + warn "RECV: #{response_line.inspect}" if ENV['JSII_DEBUG'] + + check_crash!(response_line) + + response = JSON.parse(response_line) + check_error!(response) + + return response['ok'] unless response.key?('callback') + + process_callback_request(response['callback']) + end + end + end + + # Build the `create` request payload for a new JSII object. Used by + # `Api#create_object`; exposed so the payload can be inspected/logged + # without actually issuing the call. + # + # @param fqn [String] fully-qualified name of the class to instantiate. + # @param args [Array] positional constructor arguments (Ruby values). + # @param overrides [Array] override descriptors (`{ "method" => ... }` or `{ "property" => ... }`). + # @param interfaces [Array] additional interface FQNs the instance implements. + # @return [Hash{Symbol=>Object}] the `api: 'create'` request payload, with all + # nested values already passed through {Jsii::Serializer.dump}. + def create_object_payload(fqn, args, overrides: [], interfaces: []) + { + api: 'create', + fqn: fqn, + args: Jsii::Serializer.dump(args), + overrides: Jsii::Serializer.dump(overrides), + interfaces: interfaces + } + end + + # The "object currently being constructed" — looked up by `find_by_ref` + # so that the kernel's callback referring to an objref the registry hasn't + # learned about yet can resolve to the in-flight instance. + # + # Stored on Thread.current rather than an instance variable: with the + # kernel mutex in place we still need re-entrant create_object calls + # (constructor -> callback -> further create) on the same thread to push + # and pop without clobbering each other. + # + # @return [Jsii::Object, nil] the top of the per-thread pending-object stack. + def pending_object + instance, = pending_object_stack.last + instance + end + + # The in-flight instance whose `create` request was issued with the given + # fqn — the guard `find_by_ref` applies before falling back to a pending + # object. Kernel objrefs are labelled `@`, and the sidecar + # labels the object a `create` is constructing with the same fqn the + # request named (guest subclasses construct via their nearest *generated* + # base class fqn, which is also the nearest visible type the sidecar + # labels with), so an unknown ref whose fqn label matches no in-flight + # create cannot be the object under construction. Searches the whole + # per-thread stack (innermost create first) so a callback arriving during + # a nested create can still resolve an outer in-flight instance. + # + # @param fqn [String] the fqn label of an unresolved `$jsii.byref` handle. + # @return [Jsii::Object, nil] the innermost matching in-flight instance, or `nil`. + def pending_object_for(fqn) + instance, = pending_object_stack.reverse_each.find do |pending_instance, pending_fqn| + pending_instance && pending_fqn == fqn + end + instance + end + + # @api private + # @param instance [Jsii::Object, nil] the instance whose `create_object` call is in flight. + # @param fqn [String] the fqn the `create` request was issued with. + # @return [Array] the updated per-thread stack. + def push_pending_object(instance, fqn) + pending_object_stack.push([instance, fqn]) + end + + # @api private + # @return [Array(Jsii::Object, String), nil] the previously-pending entry, or `nil` if the stack was empty. + def pop_pending_object + pending_object_stack.pop + end + + # Idempotently shut down the sidecar: close stdin to signal EOF, wait for + # the child to exit (escalating to SIGTERM/SIGKILL if needed), then close + # the remaining pipes and join the stderr drain thread. Safe to call + # multiple times. + # + # @return [nil] + def shutdown + return if @shutdown + + @shutdown = true + close_stdin + reap_child + close_streams(@stdout, @stderr) + @stderr_drain_thread&.join(0.5) + end + + private + + # Closing stdin sends EOF to the jsii-runtime wrapper, which is its + # intended exit signal — the wrapper's SIGTERM handler only forwards + # the signal to its grandchild and does NOT exit the wrapper itself, + # so SIGTERM alone leaves the wrapper parented to us and `@wait_thr` + # hung forever. + def close_stdin + @stdin.close if @stdin && !@stdin.closed? + end + + # Wait for the child to exit on its own after stdin EOF; escalate to + # SIGTERM then SIGKILL if it doesn't. `@wait_thr.kill` only kills + # the Ruby bookkeeping thread, not the OS process, so it isn't a + # substitute. + # + # @return [Process::Status, nil] the child's exit status, or `nil` if + # the wait was already complete / the child had already been reaped. + def reap_child + return unless @wait_thr + + if @wait_thr.alive? && !@wait_thr.join(2) + signal_child('TERM') + signal_child('KILL') unless @wait_thr.join(2) + end + @wait_thr.value + rescue StandardError + nil + end + + def close_streams(*streams) + streams.compact.reject(&:closed?).each do |io| + io.close + rescue StandardError + nil + end + end + + def signal_child(name) + return unless @wait_thr&.alive? + + Process.kill(name, @wait_thr.pid) + rescue Errno::ESRCH, Errno::EPERM + # Already gone or no permission; nothing more to do. + end + + def pending_object_stack + Thread.current[PENDING_OBJECT_STACK_KEY] ||= [] + end + + # Drain the child's stderr in a background thread. Without this the + # stderr pipe's buffer fills (~64KB on macOS) when the child is chatty, + # the child blocks on its next write, and the JSON request loop on + # stdout deadlocks waiting for a response that will never arrive. + # + # @return [Thread] the drain thread (also stored in `@stderr_drain_thread`). + def start_stderr_drain + @stderr_drain_thread = Thread.new do + @stderr.each_line do |line| + @stderr_mutex.synchronize { @stderr_buffer << line } + end + rescue IOError, Errno::EBADF + # Pipe closed during shutdown; nothing to do. + end + @stderr_drain_thread.name = 'jsii-stderr-drain' if @stderr_drain_thread.respond_to?(:name=) + end + + # Locate the `jsii-runtime` executable. Resolution order: + # 1. `JSII_RUNTIME` env var (explicit override). + # 2. `jsii-runtime` on `PATH` (system install). + # 3. `require.resolve('@jsii/runtime/bin/jsii-runtime')` via `node`. + # 4. `$(npm root)/.bin/jsii-runtime` (local `node_modules`). + # + # @return [Array] the command and its arguments to run the executable. + # @raise [StandardError] if none of the four strategies finds it. + def resolve_jsii_runtime + if ENV.key?('JSII_RUNTIME') + runtime = ENV['JSII_RUNTIME'] + return [runtime] if File.exist?(runtime) + return runtime.split(' ') + end + + dev_null = Gem.win_platform? ? 'NUL' : '/dev/null' + path_checker = Gem.win_platform? ? 'where' : 'which' + return ['jsii-runtime'] if system("#{path_checker} jsii-runtime > #{dev_null} 2>&1") + + node_path = resolve_via_node + return ['node', node_path] if node_path + + npm_path = resolve_via_npm + return [npm_path] if npm_path + + raise StandardError, + 'Unable to locate jsii-runtime executable. ' \ + 'Please ensure @jsii/runtime is installed or set JSII_RUNTIME.' + end + + # Ask Node to resolve the `@jsii/runtime` package and return the + # absolute path to its `jsii-runtime` bin entry. + # + # @return [String, nil] the resolved path, or `nil` if Node is unavailable + # or the package can't be resolved. + def resolve_via_node + dev_null = Gem.win_platform? ? 'NUL' : '/dev/null' + node_path = `node -p "require.resolve('@jsii/runtime/bin/jsii-runtime')" 2>#{dev_null}`.strip + node_path unless node_path.empty? + rescue StandardError + nil + end + + # Locate `jsii-runtime` inside the local `node_modules/.bin` directory. + # + # @return [String, nil] the executable path, or `nil` if `npm root` + # yields nothing or the symlink isn't executable. + def resolve_via_npm + dev_null = Gem.win_platform? ? 'NUL' : '/dev/null' + npm_root = `npm root 2>#{dev_null}`.strip + return nil if npm_root.empty? + + bin_name = Gem.win_platform? ? 'jsii-runtime.cmd' : 'jsii-runtime' + bin_path = File.join(npm_root, '.bin', bin_name) + File.executable?(bin_path) ? bin_path : nil + rescue StandardError + nil + end + + def send_payload(payload) + warn "SEND: #{JSON.generate(payload)}" if ENV['JSII_DEBUG'] + @stdin.puts(JSON.generate(payload)) + @stdin.flush + end + + # Treat a `nil` (EOF) read from the sidecar's stdout as an unexpected + # crash: join the stderr drain briefly to flush any final output, then + # raise with whatever was captured so the user sees the underlying + # cause instead of a generic protocol error. + # + # @param response_line [String, nil] the line returned by `@stdout.gets`. + # @return [nil] when the line is non-nil (no-op). + # @raise [Jsii::RuntimeError] when the line is `nil` (child gone). + def check_crash!(response_line) + return if response_line + + # Let the drain thread flush whatever the child wrote on its way out, + # but cap the wait so a hung drain doesn't turn a crash into a hang. + @stderr_drain_thread&.join(0.5) + stderr_content = @stderr_mutex.synchronize { @stderr_buffer.dup }.join + raise Jsii::RuntimeError, "JSII Kernel crashed unexpectedly.\nStderr: #{stderr_content}" + end + + # Inspect a decoded response envelope and raise on protocol vs remote + # errors. `name == '@jsii/kernel.Fault'` indicates a kernel-side + # protocol fault (raised as {Jsii::JSIIError}); any other `error` + # indicates an exception from user JS code (raised as + # {Jsii::RuntimeError}, preserving the remote stack). + # + # @param response [Hash{String=>Object}] the parsed JSON response. + # @return [nil] when the response has no `error`. + # @raise [Jsii::JSIIError] for kernel protocol faults. + # @raise [Jsii::RuntimeError] for remote JavaScript exceptions. + def check_error!(response) + return unless response['error'] + + raise Jsii::JSIIError, response['error'] if response['name'] == '@jsii/kernel.Fault' + + raise Jsii::RuntimeError.new(response['error'], response['stack']) + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/kernel/api.rb b/packages/@jsii/ruby-runtime/lib/jsii/kernel/api.rb new file mode 100644 index 0000000000..26c6d38d33 --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/kernel/api.rb @@ -0,0 +1,160 @@ +# frozen_string_literal: true + +module Jsii + class Kernel + # Core public APIs exposed by the Kernel to interact with JSII + module Api + # Tell the sidecar to load a JSII assembly from a tarball. + # + # @param name [String] npm-style package name (e.g. `"jsii-calc"`). + # @param version [String] semantic version of the assembly. + # @param tarball [String] absolute path to the `.jsii.tgz` tarball. + # @return [Hash] the kernel's `ok` response envelope. + # @raise [Jsii::RuntimeError] if loading fails. + def load_assembly(name, version, tarball) + request({ + api: 'load', + name: name, + version: version, + tarball: tarball + }) + end + + # Instantiate a JSII object in the sidecar and return its by-reference id. + # The `instance:` argument (if provided) is pushed — together with the + # `fqn` the request is issued with — onto the per-thread pending-object + # stack for the duration of the call so that callbacks the kernel fires + # _during_ construction can resolve back to the Ruby instance even + # though the registry hasn't seen the new ref yet (the fqn lets + # `find_by_ref` reject unknown refs of unrelated types). + # + # @param fqn [String] fully-qualified name of the class to construct. + # @param args [Array] positional constructor arguments (Ruby values, serialized internally). + # @param overrides [Array] override descriptors emitted by the generator / discovered at runtime. + # @param interfaces [Array] additional interface FQNs the instance implements. + # @param instance [Jsii::Object, nil] the in-flight Ruby instance to expose to callbacks. + # @return [String] the `$jsii.byref` handle for the new object. + def create_object(fqn, args = [], overrides: [], interfaces: [], instance: nil) + push_pending_object(instance, fqn) + begin + payload = create_object_payload(fqn, args, overrides: overrides, interfaces: interfaces) + response = request(payload) + # The Node sidecar returns the true tracking ID, let's use it directly + response['$jsii.byref'] + ensure + pop_pending_object + end + end + + # Invoke an instance method on a previously-created JSII object. + # + # @param objref [String, Jsii::Object] the receiver or its `$jsii.byref` handle. + # @param method [String] the JSII method name (camelCase wire form). + # @param args [Array] positional arguments (Ruby values, serialized internally). + # @return [Object] the method's return value (deserialized to native Ruby). + def call_method(objref, method, args = []) + objref_payload = if objref.respond_to?(:jsii_serialize) + objref.jsii_serialize + else + { '$jsii.byref' => objref } + end + + response = request({ + api: 'invoke', + objref: objref_payload, + method: method, + args: Jsii::Serializer.dump(args) + }) + + # Unpack the actual returned value + Jsii::Serializer.load(response['result']) + end + + # Read an instance property on a JSII object. + # + # @param objref [String, Jsii::Object] the receiver or its `$jsii.byref` handle. + # @param property [String] the JSII property name (camelCase wire form). + # @return [Object] the property value (deserialized to native Ruby). + def get_property(objref, property) + objref_payload = if objref.respond_to?(:jsii_serialize) + objref.jsii_serialize + else + { '$jsii.byref' => objref } + end + + response = request({ + api: 'get', + objref: objref_payload, + property: property + }) + Jsii::Serializer.load(response['value']) + end + + # Write an instance property on a JSII object. + # + # @param objref [String, Jsii::Object] the receiver or its `$jsii.byref` handle. + # @param property [String] the JSII property name (camelCase wire form). + # @param value [Object] the value to assign (Ruby value, serialized internally). + # @return [Hash] the kernel's `ok` response envelope. + def set_property(objref, property, value) + objref_payload = if objref.respond_to?(:jsii_serialize) + objref.jsii_serialize + else + { '$jsii.byref' => objref } + end + + request({ + api: 'set', + objref: objref_payload, + property: property, + value: Jsii::Serializer.dump(value) + }) + end + + # Invoke a static method on a JSII class. + # + # @param fqn [String] fully-qualified name of the class. + # @param method [String] the JSII static method name. + # @param args [Array] positional arguments (Ruby values, serialized internally). + # @return [Object] the method's return value (deserialized to native Ruby). + def call_static(fqn, method, args = []) + response = request({ + api: 'sinvoke', + fqn: fqn, + method: method, + args: Jsii::Serializer.dump(args) + }) + Jsii::Serializer.load(response['result']) + end + + # Read a static property on a JSII class. + # + # @param fqn [String] fully-qualified name of the class. + # @param property [String] the JSII static property name. + # @return [Object] the property value (deserialized to native Ruby). + def get_static(fqn, property) + response = request({ + api: 'sget', + fqn: fqn, + property: property + }) + Jsii::Serializer.load(response['value']) + end + + # Write a static property on a JSII class. + # + # @param fqn [String] fully-qualified name of the class. + # @param property [String] the JSII static property name. + # @param value [Object] the value to assign (Ruby value, serialized internally). + # @return [Hash] the kernel's `ok` response envelope. + def set_static(fqn, property, value) + request({ + api: 'sset', + fqn: fqn, + property: property, + value: Jsii::Serializer.dump(value) + }) + end + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/kernel/async.rb b/packages/@jsii/ruby-runtime/lib/jsii/kernel/async.rb new file mode 100644 index 0000000000..0216e631a3 --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/kernel/async.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +module Jsii + class Kernel + # Handles async callbacks and promises across the JSII IPC boundary + module Async + # Invoke an async JSII method end-to-end: open the promise via `begin`, + # service any callbacks the sidecar requests while the promise is + # pending, then resolve the value via `end`. Synchronous from the + # caller's perspective. + # + # @param objref [String] the `$jsii.byref` handle of the receiver. + # @param method [String] the JSII async method name (camelCase wire form). + # @param args [Array] positional arguments (Ruby values, serialized internally). + # @return [Object] the resolved promise value (deserialized to native Ruby). + # @raise [Jsii::RuntimeError] if the promise rejects. + def call_async_method(objref, method, args = []) + promiseid = begin_async_call(objref, method, args) + process_async_callbacks + end_async_call(promiseid) + end + + private + + # Issue the `begin` half of the async pair and return the kernel's + # `promiseid` for later resolution via {#end_async_call}. + # + # @param objref [String, Jsii::Object] the receiver or its `$jsii.byref` handle. + # @param method [String] the JSII async method name. + # @param args [Array] positional arguments (serialized internally). + # @return [String] the opaque `promiseid` issued by the sidecar. + def begin_async_call(objref, method, args) + objref_payload = if objref.respond_to?(:jsii_serialize) + objref.jsii_serialize + else + { '$jsii.byref' => objref } + end + + response = request({ + api: 'begin', + objref: objref_payload, + method: method, + args: Jsii::Serializer.dump(args) + }) + response['promiseid'] + end + + # Resolve a previously-`begin`'d promise via the `end` verb. + # + # @param promiseid [String] the id returned by {#begin_async_call}. + # @return [Object] the resolved value (deserialized to native Ruby). + # @raise [Jsii::RuntimeError] if the promise rejects. + def end_async_call(promiseid) + end_response = request({ + api: 'end', + promiseid: promiseid + }) + Jsii::Serializer.load(end_response['result']) + end + + # Drain every pending Ruby-side callback the sidecar has queued up + # while a promise is in flight. Loops until the kernel reports the + # queue is empty — each completed callback can itself trigger further + # callbacks, so a single pass isn't sufficient. + # + # @return [nil] when the callback queue is finally empty. + def process_async_callbacks + callbacks_response = request({ api: 'callbacks' }) + callbacks = callbacks_response['callbacks'] || [] + until callbacks.empty? + callbacks.each do |callback| + complete_async_callback(callback) + end + callbacks_response = request({ api: 'callbacks' }) + callbacks = callbacks_response['callbacks'] || [] + end + end + + # Service one async callback by dispatching it into Ruby and sending + # the result (or error envelope) back via `complete`. Errors are + # converted to the wire's `{ err, name, stack }` shape rather than + # re-raised so the promise on the JS side can settle cleanly. + # + # @param callback [Hash{String=>Object}] the callback descriptor. + # @return [Hash] the kernel's `ok` response envelope for the `complete` call. + def complete_async_callback(callback) + template = { + api: 'complete', + cbid: callback['cbid'] + } + result = handle_callback(callback) + request({ **template, result: Jsii::Serializer.dump(result) }) + rescue StandardError => e + request({ + **template, + err: e.message, + name: e.class.name, + stack: e.backtrace&.join("\n") + }) + end + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/kernel/callbacks.rb b/packages/@jsii/ruby-runtime/lib/jsii/kernel/callbacks.rb new file mode 100644 index 0000000000..a217df57d6 --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/kernel/callbacks.rb @@ -0,0 +1,204 @@ +# frozen_string_literal: true + +module Jsii + class Kernel + # Handles executing callbacks from the JSII Node sidecar in the Ruby runtime + module Callbacks + private + + # Service one synchronous callback the sidecar emitted mid-request and + # send the `complete` envelope back over the pipe. Errors are + # converted to `{ err, name, stack }` rather than re-raised — see the + # inline comment for why re-raising would corrupt the read loop. + # + # @param callback [Hash{String=>Object}] the callback descriptor + # (`{ cbid, invoke | get | set: {...} }`). + # @return [nil] + def process_callback_request(callback) + result = handle_callback(callback) + + send_payload({ + complete: { + cbid: callback['cbid'], + result: Jsii::Serializer.dump(result) + } + }) + rescue StandardError => e + # Notify the kernel that this callback failed so it can unblock the + # pending request. Without this the Node sidecar waits forever for a + # { complete } envelope and the original Ruby call deadlocks. + # + # Do NOT re-raise here. The kernel will process the error envelope and + # reply with { error: "..." } as the final response for the original + # request. The normal request loop will read that reply and + # check_error! will raise Jsii::RuntimeError at the right time. + # Re-raising here would exit the loop early, leaving the kernel's + # { error } response unread and polluting the next request's read. + send_payload({ + complete: { + cbid: callback['cbid'], + err: e.message, + name: e.class.name, + stack: e.backtrace&.join("\n") + } + }) + end + + # Dispatch a callback descriptor to the right concrete handler based + # on which key it carries (`invoke` / `get` / `set`). + # + # @param callback [Hash{String=>Object}] the callback descriptor. + # @return [Object] the value to send back as the `result` field. + # @raise [RuntimeError] when the descriptor carries none of the + # expected keys. + def handle_callback(callback) + if callback['invoke'] + handle_callback_invoke(callback['invoke']) + elsif callback['get'] + handle_callback_get(callback['get']) + elsif callback['set'] + handle_callback_set(callback['set']) + else + raise "Unknown callback type: #{callback.inspect}" + end + end + + # Invoke a Ruby-side override the sidecar is requesting on a created + # object. Uses `ruby_member_name` so JSII members that collide with + # Ruby reserved words / `Object#send` route to the generator's + # `_break` / `_send` form instead of the wrong dispatch. + # + # @param invoke_req [Hash{String=>Object}] `{ objref, method, args }`. + # @return [Object] the value returned by the Ruby method (before serialization). + # @raise [RuntimeError] if no live instance is registered for `objref`. + def handle_callback_invoke(invoke_req) + objref = invoke_req['objref'] + method_name = invoke_req['method'] + args = invoke_req['args'] || [] + + instance = Jsii::Object.find_by_ref(objref) + raise "Object not found for ref: #{objref}" unless instance + + # `ruby_member_name` (not bare `underscore`) so reserved-name members + # like `break` / `send` route to the generator's `_break` / `_send` + # rather than `Object#send` or a NoMethodError. Use __send__ so a + # user override that happens to define `send` can't shadow dispatch. + ruby_method = Jsii::Utils.ruby_member_name(method_name) + instance.__send__(ruby_method, *Jsii::Serializer.load(args)) + end + + # Read a Ruby-side override property the sidecar is requesting. + # + # @param get_req [Hash{String=>Object}] `{ objref, property }`. + # @return [Object] the property value (before serialization). + # @raise [RuntimeError] if no live instance is registered for `objref`. + def handle_callback_get(get_req) + objref = get_req['objref'] + property = get_req['property'] + + instance = Jsii::Object.find_by_ref(objref) + raise "Object not found for ref: #{objref}" unless instance + + ruby_property = Jsii::Utils.ruby_member_name(property) + instance.__send__(ruby_property) + end + + # Write a Ruby-side override property the sidecar is requesting. + # + # @param set_req [Hash{String=>Object}] `{ objref, property, value }`. + # @return [nil] always; the `complete` envelope carries no result for setters. + # @raise [RuntimeError] if no live instance is registered for `objref`. + def handle_callback_set(set_req) + objref = set_req['objref'] + property = set_req['property'] + value = set_req['value'] + + instance = Jsii::Object.find_by_ref(objref) + raise "Object not found for ref: #{objref}" unless instance + + ruby_property_setter = "#{Jsii::Utils.ruby_member_name(property)}=" + instance.__send__(ruby_property_setter, Jsii::Serializer.load(value)) + nil + end + + # Collect every ancestor of `value`'s class that carries a JSII fqn — + # i.e. the included `IFoo` / extended struct modules the generator + # emitted. + # + # @param value [Object] the value to introspect. + # @return [Array] matching ancestor modules in order. + def value_ancestors(value) + value.class.ancestors.select do |m| + m.instance_of?(Module) && m.respond_to?(:jsii_fqn) + end + end + + # Materialize a plain Ruby object that implements JSII interfaces into + # a remote by-ref by registering it with the kernel as a freshly + # created `Object` with `overrides` + `interfaces` derived from the + # value's class. Mutates `value` to attach the resulting `@jsii_ref` + # and a `jsii_ref` reader so future serializations are by-ref. + # + # @param value [Object] the Ruby value to register remotely. + # @return [Object, Hash{String=>String}] either the original `value` + # (when no JSII interfaces are present, so nothing to do) or the + # `{ "$jsii.byref" => ref }` wire envelope. + def serialize_native_implementations(value) + jsii_interface_modules = value_ancestors(value) + return value if jsii_interface_modules.empty? + + overrides = extract_native_overrides(value, jsii_interface_modules) + jsii_interfaces = jsii_interface_modules.map(&:jsii_fqn) + ref = create_object('Object', [], overrides: overrides, interfaces: jsii_interfaces, instance: value) + value.instance_variable_set(:@jsii_ref, ref) + value.define_singleton_method(:jsii_ref) { @jsii_ref } + Jsii::Object.register_instance(value) if Jsii::Object.respond_to?(:register_instance) + { '$jsii.byref' => ref } + end + + # Walk every JSII interface module in the value's ancestor chain and + # accumulate the override descriptors the kernel needs to know about. + # + # @param value [Object] the implementing Ruby instance. + # @param jsii_interface_modules [Array] result of {#value_ancestors}. + # @return [Array] override descriptors (`{ "method" => ... }` / `{ "property" => ... }`). + # @raise [RuntimeError] if a required interface member isn't implemented. + def extract_native_overrides(value, jsii_interface_modules) + overrides = [] + jsii_interface_modules.each do |interface| + next unless interface.singleton_class.method_defined?(:jsii_overridable_methods, false) + + interface.jsii_overridable_methods.each do |ruby_name, metadata| + validate_override!(value, interface, ruby_name, metadata, overrides) + end + end + overrides.uniq + end + + # Verify that `value` implements one declared interface member, and + # — when it does and the implementation is user code (not the + # generator's own module) — push an override descriptor into + # `overrides`. + # + # @param value [Object] the implementing Ruby instance. + # @param interface [Module] the interface module declaring the member. + # @param ruby_name [Symbol] the snake_case Ruby method name. + # @param metadata [Hash] `{ kind: :method|:property, name: , is_optional: Boolean }`. + # @param overrides [Array] mutable accumulator; appended in place. + # @return [void] + # @raise [RuntimeError] when a required (non-optional) member is missing. + def validate_override!(value, interface, ruby_name, metadata, overrides) + unless value.class.method_defined?(ruby_name) + return if metadata[:is_optional] + + raise "Object of class #{value.class} is missing required method/property: " \ + "#{ruby_name} (from interface #{interface.name})" + end + + # If the owner is not a JSII generated class/module, it's a user override + owner = value.method(ruby_name).owner + overrides << { metadata[:kind].to_s => metadata[:name] } unless owner.respond_to?(:jsii_fqn) + end + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/object.rb b/packages/@jsii/ruby-runtime/lib/jsii/object.rb new file mode 100644 index 0000000000..ed77302049 --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/object.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +require 'jsii/object/registry' +require 'jsii/object/overrides' +require 'jsii/object/dynamic_invocation' +require 'jsii/object/kernel_forwarding' + +module Jsii + # Extension to allow modules (Interfaces/Structs) to have jsii_fqn + module FqnExtension + # @!attribute [rw] jsii_fqn + # @return [String, nil] the JSII fully-qualified name attached to this module/class. + attr_accessor :jsii_fqn + end + + # Base class for all Ruby proxy classes that map to JSII-managed objects. + class Object + extend FqnExtension + extend Registry + + include KernelForwarding + include Overrides + include DynamicInvocation + + # @return [String] the `$jsii.byref` handle for this proxied instance. + attr_reader :jsii_ref + + # Encodes this proxy as a `$jsii.byref` wire envelope. + # + # @return [Hash{String=>Object}] `{ "$jsii.byref" => "", "$jsii.interfaces" => [...] }`. + def jsii_serialize + res = { '$jsii.byref' => jsii_ref } + if (interfaces = jsii_interfaces) && !interfaces.empty? + res['$jsii.interfaces'] = interfaces + end + res + end + + # Allocate the corresponding object inside the JSII sidecar and store its + # ref locally. Subclasses do NOT typically override this — the pacmak + # generator emits a thin `initialize(arg1, arg2, ...)` that forwards via + # `super`, ultimately landing here. + # + # @param args [Array] positional constructor arguments (Ruby values). + # @yieldparam instance [Jsii::Object] the freshly-constructed instance, for caller post-init. + # @return [Jsii::Object] `self` (returned implicitly by `initialize`). + # @raise [Jsii::RuntimeError] if the kernel rejects the construction. + def initialize(*args) + # Ask the singleton to create the remote object and store its reference ID + @jsii_ref = Jsii::Kernel.instance.create_object(ruby_class.jsii_fqn, + args, + overrides: jsii_overrides, + interfaces: jsii_interfaces, + instance: self) + ruby_class.register_instance(self) + yield self if block_given? + end + + # The set of JSII interface FQNs this Ruby instance is declared to + # implement, gathered from every module in its ancestor chain that + # carries a `jsii_fqn`. + # + # @return [Array] de-duplicated list of interface FQNs. + def jsii_interfaces + # Find all included modules that have a jsii_fqn + singleton_class.ancestors + .select { |a| a.is_a?(Module) && !a.is_a?(Class) && a.respond_to?(:jsii_fqn) && a.jsii_fqn } + .map(&:jsii_fqn) + .uniq + end + + # Returns the *true* class of `self`, bypassing any user-defined `#class` + # override (the JSII method-missing path otherwise dispatches `class` + # over the wire when a remote member happens to be named `class`). + # + # @return [Class] the real Ruby class of this instance. + def ruby_class + ::Object.instance_method(:class).bind(self).call + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/object/dynamic_invocation.rb b/packages/@jsii/ruby-runtime/lib/jsii/object/dynamic_invocation.rb new file mode 100644 index 0000000000..16ba4d0076 --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/object/dynamic_invocation.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +module Jsii + class Object + # Handles dynamic invocation of methods and properties on JSII objects via method_missing + module DynamicInvocation + # Route unknown Ruby method calls to JSII members on the underlying + # object: setters (`name=`) become `set_property`, no-arg calls try + # `get_property` then fall back to `call_method`, and any other call + # is dispatched as `call_method`. + # + # @param symbol [Symbol] the method name being invoked on this proxy. + # @param args [Array] arguments passed to the method. + # @return [Object] the value returned by the kernel for that member. + # @raise [NoMethodError] if `symbol` cannot be a JSII member name (passes through to `super`). + # @raise [Jsii::Error] if the kernel rejects the call for reasons other than "missing member". + def method_missing(symbol, *args) + return super(symbol, *args) unless valid_jsii_method_name?(symbol) + + camel_name = Jsii::Utils.camelize(symbol) + fallback = -> { super(symbol, *args) } + + if camel_name.end_with?('=') + invoke_setter(camel_name.chomp('='), args.first, &fallback) + elsif args.empty? + invoke_getter_or_method(camel_name, args, &fallback) + else + invoke_method(camel_name, args, &fallback) + end + end + + # Reports `true` for any name that could legally be a JSII member, so + # that Ruby's `respond_to?` / duck-typing checks behave correctly for + # methods serviced via {#method_missing}. + # + # @param symbol [Symbol] the method name being probed. + # @param include_private [Boolean] passed through to `super` for non-JSII names. + # @return [Boolean] `true` if the name is a plausible JSII member, otherwise defers to `super`. + def respond_to_missing?(symbol, include_private = false) + return true if valid_jsii_method_name?(symbol) + + super + end + + private + + # Ruby implicit-conversion sentinels that the interpreter and stdlib + # probe via duck-typing. We must let `method_missing` fall through to + # `super` for these — otherwise we'll try to dispatch them as JSII + # members and either deadlock the kernel or return surprising values + # (e.g. `Array(obj)` calls `to_ary`). Note this list deliberately does + # NOT include `to_string` / `to_json` / `to_array` — those are common + # JSII member names that need to dispatch normally. + RUBY_COERCION_METHODS = %i[ + to_ary to_a to_hash to_h to_str to_proc to_int to_io to_path to_open to_regexp + ].freeze + + # Does the given symbol look like it could be a JSII member? Filters + # out Ruby's implicit-conversion sentinels (`to_ary`/`to_str`/etc.) so + # duck-typing probes in stdlib don't get dispatched over the wire. + # + # @param symbol [Symbol] the candidate method name. + # @return [Boolean] `true` if the name is a plausible JSII member. + def valid_jsii_method_name?(symbol) + return false if RUBY_COERCION_METHODS.include?(symbol) + + # JSII members are alphanumeric + underscores, with an optional trailing '=' for setters + !!symbol.to_s.match(/^[a-zA-Z_][a-zA-Z0-9_]*=?$/) + end + + # Forward a setter call to the kernel; on a "missing member" error + # yield to the supplied fallback (which lets Ruby's normal + # `method_missing` chain run) instead of re-raising. + # + # @param prop_name [String] the camelCase JSII property name. + # @param value [Object] the value to assign. + # @yieldreturn [Object] the fallback's return value when the property is unknown. + # @return [Object] the kernel's response, or the fallback's return value. + # @raise [Jsii::Error] for non-"missing member" errors. + def invoke_setter(prop_name, value) + jsii_set_property(prop_name, value) + rescue Jsii::Error => e + return yield if e.missing_member? + + raise e + end + + # Forward a method call to the kernel with the same "missing member + # → fallback" semantics as {#invoke_setter}. + # + # @param camel_name [String] the camelCase JSII method name. + # @param args [Array] positional arguments. + # @yieldreturn [Object] fallback value when the method is unknown. + # @return [Object] the method's return value (or the fallback's value). + # @raise [Jsii::Error] for non-"missing member" errors. + def invoke_method(camel_name, args) + jsii_call_method(camel_name, args) + rescue Jsii::Error => e + return yield if e.missing_member? + + raise e + end + + # No-arg call: try the JSII property first (since Ruby zero-arg method + # calls are ambiguous between methods and attribute reads), fall + # through to {#invoke_method} if the property is unknown. + # + # @param camel_name [String] the camelCase JSII member name. + # @param args [Array] always empty for this path; passed through. + # @yieldreturn [Object] fallback value when neither getter nor method matches. + # @return [Object] the resolved value (property, method, or fallback). + # @raise [Jsii::Error] for non-"missing member" errors. + def invoke_getter_or_method(camel_name, args, &fallback) + jsii_get_property(camel_name) + rescue Jsii::Error => e + raise e unless e.missing_member? + + invoke_method(camel_name, args, &fallback) + end + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/object/kernel_forwarding.rb b/packages/@jsii/ruby-runtime/lib/jsii/object/kernel_forwarding.rb new file mode 100644 index 0000000000..f98327bf5d --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/object/kernel_forwarding.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Jsii + class Object + # Direct forwarding of method and property invocations to the JSII kernel + module KernelForwarding + # Invoke an instance method on this proxy's underlying JSII object. + # + # @param method [String] the JSII method name (camelCase wire form). + # @param args [Array] positional arguments (Ruby values, serialized internally). + # @return [Object] the method's return value (deserialized to native Ruby). + def jsii_call_method(method, args = []) + Jsii::Kernel.instance.call_method(self, method, args) + end + + # Invoke an async instance method on this proxy's underlying JSII object, + # blocking until the remote promise settles. + # + # @param method [String] the JSII async method name (camelCase wire form). + # @param args [Array] positional arguments (Ruby values, serialized internally). + # @return [Object] the resolved promise value (deserialized to native Ruby). + # @raise [Jsii::RuntimeError] if the promise rejects. + def jsii_async_call_method(method, args = []) + Jsii::Kernel.instance.call_async_method(self, method, args) + end + + # Read an instance property on this proxy's underlying JSII object. + # + # @param property [String] the JSII property name (camelCase wire form). + # @return [Object] the property value (deserialized to native Ruby). + def jsii_get_property(property) + Jsii::Kernel.instance.get_property(self, property) + end + + # Write an instance property on this proxy's underlying JSII object. + # + # @param property [String] the JSII property name (camelCase wire form). + # @param value [Object] the value to assign (Ruby value, serialized internally). + # @return [Hash] the kernel's `ok` response envelope. + def jsii_set_property(property, value) + Jsii::Kernel.instance.set_property(self, property, value) + end + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/object/overrides.rb b/packages/@jsii/ruby-runtime/lib/jsii/object/overrides.rb new file mode 100644 index 0000000000..9b361f5bbd --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/object/overrides.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +module Jsii + class Object + # Introspects Ruby classes to discover and validate JSII overrides + module Overrides + # Discover the list of overrides this Ruby instance contributes to its + # underlying JSII object — both subclass overrides of generated + # methods/properties and interface implementations contributed via + # `include`d modules. Used by {Jsii::Object#initialize} when creating + # the remote instance so the kernel knows which calls to dispatch back. + # + # @return [ArrayString}>] de-duplicated override descriptors, + # each shaped like `{ "method" => "" }` or `{ "property" => "" }`. + # @raise [RuntimeError] if a required interface method is not implemented (see + # {Jsii::Object::Overrides#validate_interface_implementation!}). + def jsii_overrides + overrides = [] + + scan_class_overrides!(overrides) + + overrides.uniq + end + + private + + # Walk every ancestor class/module that declares + # `jsii_overridable_methods` (the generator emits it on each + # generated class) and check whether the receiving Ruby class + # provides an override for any of them. + # + # @param overrides [Array] mutable accumulator; appended in place. + # @return [void] + def scan_class_overrides!(overrides) + ruby_class.ancestors.each do |source| + next unless source.singleton_class.method_defined?(:jsii_overridable_methods, false) + + source.jsii_overridable_methods.each do |ruby_name, metadata| + validate_override!(source, ruby_name, metadata, overrides) + end + end + end + + # Decide whether the receiving class overrides one declared member, + # push the descriptor into `overrides` when it does, and raise when a + # non-optional interface member is missing. + # + # @param source [Class, Module] the class/module declaring the member. + # @param ruby_name [Symbol] the snake_case Ruby method name. + # @param metadata [Hash] `{ kind:, name:, is_optional: }` descriptor. + # @param overrides [Array] mutable accumulator. + # @return [void] + # @raise [RuntimeError] when a required interface member isn't implemented. + def validate_override!(source, ruby_name, metadata, overrides) + is_implemented = ruby_class.method_defined?(ruby_name) + owner = is_implemented ? ruby_class.instance_method(ruby_name).owner : nil + + overrides << { metadata[:kind].to_s => metadata[:name] } if is_implemented && native_override?(owner) + + validate_interface_implementation!(source, owner, ruby_name, metadata) + end + + # Is the method's owner a user-supplied Ruby class/module — i.e. + # _not_ a generated jsii class and _not_ a Ruby builtin? + # + # @param owner [Class, Module, nil] the `Method#owner` for the implementation. + # @return [Boolean] `true` if the override originates outside the jsii runtime. + def native_override?(owner) + return false if owner.nil? + + !ruby_class.registered_class?(owner) && + ![Jsii::Object, Jsii::Struct, Jsii::Enum, ::Object, ::Kernel, ::BasicObject].include?(owner) + end + + # Raise when an interface-declared required member is not implemented + # by the receiver. No-op for class-declared members, optional + # members, or members implemented by the user / by another interface. + # + # @param source [Class, Module] the declaring class/module. + # @param owner [Class, Module, nil] the resolved implementation owner. + # @param ruby_name [Symbol] the Ruby method name. + # @param metadata [Hash] `{ is_optional:, ... }` descriptor. + # @return [nil] + # @raise [RuntimeError] when a required interface member is missing. + def validate_interface_implementation!(source, owner, ruby_name, metadata) + return unless source.instance_of?(Module) + return if metadata[:is_optional] + return if native_override?(owner) + return unless owner.nil? || owner.instance_of?(Module) + + raise "Object of class #{ruby_class} is missing required method/property: " \ + "#{ruby_name} (from interface #{source.name})" + end + + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/object/registry.rb b/packages/@jsii/ruby-runtime/lib/jsii/object/registry.rb new file mode 100644 index 0000000000..88a13d4fd7 --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/object/registry.rb @@ -0,0 +1,282 @@ +# frozen_string_literal: true + +require 'monitor' + +module Jsii + class Object + # Internal registry for tracking active JSII instances and FQN mappings + module Registry + # Re-entrant lock guarding the three process-wide maps below + # ({#registry} / {#objects} / {#autoload_paths}). They are mutated on + # whichever thread happens to be deserializing a kernel response, which + # is only incidentally safe under MRI's GIL — real synchronization is + # needed for alternative runtimes and for compound check-then-write + # operations like {#find_by_ref}'s eager pending-ref binding. + # + # Lock ordering: kernel monitor OUTER, registry monitor INNER — never + # the reverse. Registry methods run while the kernel monitor is held: + # `Kernel#request` services `{ callback }` envelopes inline, and the + # callback handlers resolve refs and deserialize arguments + # (`Serializer.load` → {#jsii_deserialize} → {#find_by_ref}) without + # ever leaving the kernel monitor. To make an inversion impossible, + # nothing that can block on the kernel monitor may run while this one + # is held — no method below issues a kernel request (or `require`s + # generated code, which can construct objects at load time) inside a + # `MONITOR.synchronize` block. See {#find_class_by_fqn} (releases the + # lock around `require`) and {#build_and_register_instance} (hydrates + # structs only after registration released it). + MONITOR = Monitor.new + + # @return [Hash{String=>Class,Module}] the process-wide map from JSII fqn + # to the Ruby class/module that proxies it. The accessor synchronizes + # only the lazy initialization; compound read-modify-write sequences + # are synchronized by the Registry methods that perform them. + def registry + MONITOR.synchronize { @registry ||= {} } + end + + # The process-wide map from `$jsii.byref` handle to the live Ruby proxy + # instance. + # + # This is intentionally a *strong*-reference Hash, not a weak map, and + # the runtime deliberately never issues the kernel's `del` call when a + # proxy is garbage-collected. A jsii object is referenced from both + # sides of the boundary, and the guest (Ruby) cannot know how many + # references the host (the Node sidecar, and TypeScript code running in + # it) still holds. Deleting a kernel object that the host still + # references would create a dangling reference there — a use-after-free + # the guest has no way to rule out. + # + # Every reference runtime makes the same choice: the Python runtime uses + # a strong dict with the comment "we can never free the memory of JSII + # objects ever, because we have no idea how many references exist on the + # *other* side"; the Go runtime defines a `Del` request but never calls + # it per-object, attaching its only finalizer to the kernel client to + # close the child process. Wholesale cleanup happens the same way here: + # {Jsii::Kernel#shutdown} closes the sidecar, freeing all kernel objects + # at once. This suits jsii's `synth`-style, short-lived workloads. + # + # @return [Hash{String=>Jsii::Object}] the strong byref → proxy map. + def objects + MONITOR.synchronize { @objects ||= {} } + end + + # The JSII fqn attached to this class, walking up the superclass chain + # if it isn't set directly on the receiver. + # + # @return [String, nil] the inherited or own fqn, or `nil` if neither carries one. + def jsii_fqn + return @jsii_fqn if @jsii_fqn + return unless superclass.respond_to?(:jsii_fqn) + + superclass.jsii_fqn + end + + # Decode a `$jsii.byref` wire envelope into a live Ruby proxy, reusing + # any previously-registered instance for the same ref. Falls back to + # the first interface fqn (then the ref prefix) when the wire envelope + # only reports `"Object"` as the concrete type. + # + # @param value [Hash{String=>Object}] the wire envelope. + # @return [Jsii::Object] the (possibly newly-allocated) proxy instance. + def jsii_deserialize(value) + ref = value['$jsii.byref'] + fqn = value['$jsii.fqn'] + + if (Jsii::Utils.blank?(fqn) || fqn == 'Object') && value.key?('$jsii.interfaces') + fqn = value['$jsii.interfaces'].first + end + fqn = ref.rpartition('@').first if Jsii::Utils.blank?(fqn) || fqn == 'Object' + + from_jsii_ref(ref, fqn) + end + + # Register a Ruby class/module as the proxy for a given JSII fqn. + # Idempotent: re-registering the same fqn replaces the previous mapping. + # + # @param fqn [String] the JSII fully-qualified name. + # @param klass [Class, Module] the Ruby type that should proxy that fqn. + # @return [Class, Module] `klass`, for chaining. + def register_jsii_fqn(fqn, klass) + MONITOR.synchronize do + klass.extend(Jsii::FqnExtension) if klass.is_a?(Module) && !klass.respond_to?(:jsii_fqn=) + klass.jsii_fqn = fqn if klass.respond_to?(:jsii_fqn=) + Jsii::Object.registry[fqn] = klass + end + end + + # @return [Hash{String=>String}] process-wide map from JSII fqn to the + # `require` path of the file that defines (and self-registers) its + # Ruby proxy. Populated eagerly by a generated assembly's loader so + # that types can be loaded on demand — see {#find_class_by_fqn}. + def autoload_paths + MONITOR.synchronize { @autoload_paths ||= {} } + end + + # Record where a type's proxy can be loaded from, without loading it. + # Generated assembly loaders call this for every type alongside the + # Ruby `autoload` declaration, so the two load triggers stay in sync: + # Ruby `autoload` covers constant references in user code, while this + # map covers the case the kernel hands back an fqn the user never named + # (pervasive in CDK: `vpc.public_subnets`, `bucket.grant_read`, ...). + # + # @param fqn [String] the JSII fully-qualified name. + # @param path [String] the `require` path of the defining file. + # @return [void] + def register_autoload(fqn, path) + MONITOR.synchronize { autoload_paths[fqn] = path } + end + + # Look up the Ruby class/module registered for a given JSII fqn, + # loading its defining file on demand if it hasn't been required yet. + # + # The on-demand load is what makes lazy (autoload) code generation safe + # for hydration: when the kernel returns a `$jsii.byref` of a type the + # user never referenced by constant, the type's file hasn't been loaded + # and the registry is empty for it — so we `require` it here (which runs + # its `register_jsii_fqn`) before resolving. + # + # @param fqn [String] the JSII fully-qualified name. + # @return [Class, Module, nil] the registered proxy type, or `nil`. + def find_class_by_fqn(fqn) + path = MONITOR.synchronize do + return Jsii::Object.registry[fqn] if Jsii::Object.registry.key?(fqn) + + Jsii::Object.autoload_paths[fqn] + end + + # The `require` deliberately runs with MONITOR released: loading a + # generated file re-enters the registry (register_jsii_fqn — fine, + # the monitor is re-entrant on this thread) but can also run + # arbitrary load-time code that issues kernel requests, and holding + # the registry monitor across that would invert the kernel-outer / + # registry-inner lock ordering documented on MONITOR. + require path if path + + MONITOR.synchronize { Jsii::Object.registry[fqn] } + end + + # Is the given Ruby class/module registered against any JSII fqn? + # + # @param klass [Class, Module] the Ruby type to test. + # @return [Boolean] `true` if it appears in the registry. + def registered_class?(klass) + MONITOR.synchronize { Jsii::Object.registry.value?(klass) } + end + + # Look up a live proxy by its `$jsii.byref` handle (a raw string or a + # `{ '$jsii.byref' => ... }` wire envelope). Falls back to a pending + # in-flight instance when nothing has been registered yet, which can + # happen during constructor callbacks — but only when the ref's fqn + # label (refs are `@`) matches the fqn a `create` in flight on + # this thread was issued with; an unknown ref of any other type is NOT + # the object under construction and must not be misrouted to it. A + # successful fallback eagerly binds the ref to the pending instance so + # subsequent lookups agree (the post-create `register_instance` then + # re-registers the same instance under the same ref, a no-op). + # + # Residual limitation: when two same-fqn objects are simultaneously + # unregistered (e.g. a constructor creates a sibling of its own type + # and passes it out mid-create), the fqn label cannot tell them apart + # and the innermost pending instance still wins. Strictly narrower + # than the previous unconditional fallback, which captured *every* + # unknown ref during construction. + # + # @param ref [String, Hash] either a raw handle or a wire envelope. + # @return [Jsii::Object, nil] the registered (or pending) proxy, or `nil` if no match. + def find_by_ref(ref) + ref = ref['$jsii.byref'] if ref.is_a?(Hash) && ref.key?('$jsii.byref') + + MONITOR.synchronize do + instance = Jsii::Object.objects[ref] + return instance if instance + return unless ref.is_a?(String) + + # Safe under MONITOR: pending_object_for only reads this thread's + # pending-create stack (Thread.current) and takes no locks. + pending = Jsii::Kernel.instance.pending_object_for(ref.rpartition('@').first) + Jsii::Object.objects[ref] = pending if pending + pending + end + end + + # Add a freshly-constructed proxy to the process-wide instance map. + # No-op when the instance has no `jsii_ref` (e.g. value structs). + # + # @param instance [Jsii::Object] the proxy to record. + # @return [Jsii::Object, nil] the registered instance, or `nil` if `instance.jsii_ref` is nil. + def register_instance(instance) + return unless instance.jsii_ref + + MONITOR.synchronize { Jsii::Object.objects[instance.jsii_ref] = instance } + end + + # Resolve a ref to a proxy, allocating-and-registering a new one when + # no matching live instance exists. + # + # @param ref [String] the `$jsii.byref` handle. + # @param fqn [String] the JSII fqn to use when allocating a new proxy. + # @return [Jsii::Object] the existing or newly-built proxy instance. + def from_jsii_ref(ref, fqn) + find_by_ref(ref) || build_and_register_instance(ref, fqn) + end + + private + + # Allocate a brand-new proxy, attach the supplied ref, record it in + # the registry, and eagerly load fields when the type is a struct + # (so callers can read struct properties without a roundtrip). + # + # @param ref [String] the `$jsii.byref` handle. + # @param fqn [String] the fqn to instantiate. + # @return [Jsii::Object] the registered proxy. + def build_and_register_instance(ref, fqn) + instance = build_uninitialized_instance(fqn) + instance.instance_variable_set(:@jsii_ref, ref) + register_instance(instance) + + # Registered first, hydrated after — and outside MONITOR: hydration + # issues kernel `get` requests, which must never happen while the + # registry monitor is held (see the lock-ordering note on MONITOR). + hydrate_struct!(instance, ref) + + instance + end + + # Allocate an instance of the Ruby class registered for `fqn` (or + # plain {Jsii::Object} when nothing's registered). When the registry + # has a `Module` instead of a `Class` (interface), allocate a base + # `Jsii::Object` and `extend` the interface module onto it so type + # checks and method dispatch behave correctly. + # + # @param fqn [String] the fqn whose proxy should be built. + # @return [Jsii::Object] the freshly-allocated (uninitialized) instance. + def build_uninitialized_instance(fqn) + klass = find_class_by_fqn(fqn) || Jsii::Object + + if klass.is_a?(Class) + klass.allocate + else + Jsii::Object.allocate.extend(klass) + end + end + + # When `instance` is a struct, fetch every declared property over the + # wire and assign it as an instance variable, so subsequent reads + # don't need to go back to the kernel. + # + # @param instance [Jsii::Object] the proxy to hydrate (typically a {Jsii::Struct}). + # @param ref [String] the `$jsii.byref` handle. + # @return [void] + def hydrate_struct!(instance, ref) + klass = instance.class + return unless klass < Jsii::Struct && klass.respond_to?(:jsii_properties) + + klass.jsii_properties.each do |ruby_name, jsii_name| + val = Jsii::Kernel.instance.get_property(ref, jsii_name) + instance.instance_variable_set("@#{ruby_name}", val) + end + end + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/serializer.rb b/packages/@jsii/ruby-runtime/lib/jsii/serializer.rb new file mode 100644 index 0000000000..55dfa8c11b --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/serializer.rb @@ -0,0 +1,161 @@ +# frozen_string_literal: true + +require 'date' +require 'time' + +module Jsii + # Explicit, type-driven serializer for the JSII wire format. Replaces a + # previous design that monkey-patched `Object#jsii_serialize` / + # `Hash#jsii_deserialize` onto every Ruby object — the patches would walk + # arbitrary host application objects (ActiveRecord rows, Rails params, etc.) + # and could leak state via any `@jsii_ref` ivar that happened to exist. + # + # Always go through `Jsii::Serializer.dump(value)` and `Jsii::Serializer.load(value)` + # rather than calling `.jsii_serialize` / `.jsii_deserialize` on values. + module Serializer + module_function + + # Convert a Ruby value into the JSII wire form (a JSON-ready Ruby value). + # Primitives and `nil`/Booleans pass through; arrays/hashes are mapped + # recursively; `Date`/`Time`/`DateTime` are wrapped in `$jsii.date`; jsii + # types delegate to their own `jsii_serialize`; everything else falls + # through to {#dump_other}. + # + # @param value [Object] the Ruby value to encode. + # @return [Object] a JSON-ready value: primitive, Array, Hash, or jsii wire envelope. + def dump(value) + case value + when nil, true, false, Numeric, String, Symbol + value + when Array + value.map { |element| dump(element) } + when Jsii::Enum, Jsii::Struct, Jsii::Object + value.jsii_serialize + when Date, DateTime, Time + dump_date(value) + when Hash + value.transform_values { |element| dump(element) } + else + dump_other(value) + end + end + + # Inverse of {#dump}. Decodes any wire envelopes back into Ruby values: + # `$jsii.byref` → registered proxy, `$jsii.enum` → {Jsii::Enum}, + # `$jsii.date` → `DateTime`, `$jsii.map`/`$jsii.struct` → hydrated value, + # plain primitives/arrays/hashes pass through (recursively). + # + # @param value [Object] the wire value to decode. + # @return [Object] the native Ruby value. + def load(value) + case value + when nil, true, false, Numeric, String, Symbol + value + when Array + value.map { |element| load(element) }.freeze + when Hash + load_hash(value) + else + value + end + end + + # Encode a Ruby date/time-ish value as a `$jsii.date` wire envelope. + # + # @api private + # @param value [Time, DateTime, Date] the temporal value to encode. + # @return [Hash{String=>String}] `{ "$jsii.date" => "" }`. + def dump_date(value) + case value + when Time + { '$jsii.date' => value.utc.strftime('%Y-%m-%dT%H:%M:%S.%3NZ') } + when DateTime + { '$jsii.date' => value.new_offset(0).iso8601(3) } + when Date + { '$jsii.date' => DateTime.new(value.year, value.month, value.day).new_offset(0).iso8601(3) } + end + end + + # Fallback encoder for values that don't match the `dump` dispatch table: + # delegates to a `jsii_serialize` method if present, or falls back to the + # kernel's native-implementation serializer when the value carries a JSII + # interface module. Anything else has no jsii wire representation — + # passing it through would let `JSON.generate` stringify it into + # `"#"` garbage on the host side — so it raises instead. + # + # @api private + # @param value [Object] the value to encode. + # @return [Object] the wire form. + # @raise [TypeError] when the value has no jsii wire representation. + def dump_other(value) + if value.respond_to?(:jsii_serialize) + value.jsii_serialize + elsif jsii_native_implementation?(value) + Jsii::Kernel.instance.send(:serialize_native_implementations, value) + else + raise TypeError, + "cannot serialize instance of #{value.class} to the jsii wire format; supported " \ + 'values are nil, booleans, numerics, strings, symbols, Date/Time/DateTime, ' \ + 'arrays/hashes of supported values, jsii types (Jsii::Object / Jsii::Struct / ' \ + 'Jsii::Enum), and objects whose class includes a jsii interface module' + end + end + + # Decode a Hash that may carry a JSII wire envelope key (`$jsii.byref`, + # `$jsii.enum`, `$jsii.date`, `$jsii.map`, `$jsii.struct`). When no key + # matches, the Hash is decoded element-wise. + # + # @api private + # @param hash [Hash{String=>Object}] the wire Hash to decode. + # @return [Object] the decoded native Ruby value (proxy, enum, date, etc.). + def load_hash(hash) + return Jsii::Object.jsii_deserialize(hash) if hash.key?('$jsii.byref') + return Jsii::Enum.jsii_deserialize(hash) if hash.key?('$jsii.enum') + return DateTime.parse(hash['$jsii.date']) if hash.key?('$jsii.date') + return load(hash['$jsii.map']) if hash.key?('$jsii.map') + return load_struct(hash['$jsii.struct']) if hash.key?('$jsii.struct') + + hash.transform_values { |element| load(element) }.freeze + end + + # Detect whether a Ruby value is an instance of a class that includes a + # JSII interface module (i.e. it carries a `jsii_fqn` somewhere in its + # ancestor chain). + # + # @api private + # @param value [Object] the value to test. + # @return [Boolean] `true` if the value's class implements at least one JSII interface. + def jsii_native_implementation?(value) + return false unless value.respond_to?(:class) + + klass = value.class + return false unless klass.respond_to?(:ancestors) + + klass.ancestors.any? do |ancestor| + ancestor.instance_of?(Module) && ancestor.respond_to?(:jsii_fqn) && ancestor.jsii_fqn + end + end + + # Materialize a `$jsii.struct` payload into an instance of its registered + # Ruby class (when one exists), or return a plain Hash with values + # recursively loaded when the fqn is unknown. + # + # @api private + # @param struct_info [Hash{String=>Object}] the `{ 'fqn' => ..., 'data' => ... }` payload. + # @return [Jsii::Struct, Hash] a struct instance or a plain Hash, depending on registration. + def load_struct(struct_info) + klass = Jsii::Object.find_class_by_fqn(struct_info['fqn']) + + data = struct_info['data'] || {} + return data.transform_values { |element| load(element) } unless klass.respond_to?(:jsii_properties) + + jsii_to_ruby = klass.jsii_properties.invert + kwargs = data.to_h do |k, v| + ruby_key = jsii_to_ruby[k] || k.to_sym + [ruby_key, load(v)] + end + + klass.new(**kwargs) + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/struct.rb b/packages/@jsii/ruby-runtime/lib/jsii/struct.rb new file mode 100644 index 0000000000..16a31bef8d --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/struct.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +module Jsii + # Base class for all JSII data types (structs) which pass data by-value. + class Struct + extend Jsii::FqnExtension + + class << self + # JSII structs support multiple inheritance (a struct may extend + # several parent structs — "diamond" hierarchies), but Ruby classes + # carry a single superclass: the generator subclasses the *first* + # parent and records the rest here. {#is_a?} and {.===} consult this + # registry so type checks honor the full set of declared parents. + # + # @return [Array] additional parent struct classes beyond the + # Ruby superclass (set by generated code; empty for most structs). + def jsii_extra_struct_bases + @jsii_extra_struct_bases ||= [] + end + + # Whether this struct class conforms to `klass`: via real Ruby + # ancestry, via a recorded extra base (transitively), or via an + # ancestor's recorded extra bases. + # + # @param klass [Class] the struct class to test conformance against. + # @return [Boolean] + def jsii_struct_conforms_to?(klass) + return true if self <= klass + return true if jsii_extra_struct_bases.any? { |base| base.jsii_struct_conforms_to?(klass) } + + superclass.respond_to?(:jsii_struct_conforms_to?) && + superclass.jsii_struct_conforms_to?(klass) + end + + # Makes `case value when SomeParentStruct` honor extra (non-first) + # struct parents. `super` is Module#===, which covers real ancestry. + def ===(other) + super || (other.is_a?(Struct) && other.class.jsii_struct_conforms_to?(self)) + end + end + + # Honors the full set of declared struct parents, not just the single + # Ruby superclass chain (see {.jsii_extra_struct_bases}). + def is_a?(klass) + super || (klass.is_a?(Class) && klass <= Struct && self.class.jsii_struct_conforms_to?(klass)) + end + alias kind_of? is_a? + + # @return [String, nil] the by-reference handle for this struct, if any has been + # assigned (most structs are serialized purely by value and have no ref). + attr_accessor :jsii_ref + + # Returns the struct's field values keyed by JSII (camelCase) wire names. + # Always overridden by pacmak-generated subclasses; the base implementation + # returns an empty hash so structs with no fields still serialize cleanly. + # + # @return [Hash{String=>Object}] field values keyed by JSII property name. + def to_jsii + # This should be overridden by the generated class + {} + end + + # Encodes this struct as a `$jsii.struct` wire envelope (fqn + data). + # + # @return [Hash{String=>Hash}] `{ "$jsii.struct" => { "fqn" => ..., "data" => ... } }`. + def jsii_serialize + { + '$jsii.struct' => { + 'fqn' => self.class.jsii_fqn, + 'data' => Jsii::Serializer.dump(to_jsii) + } + } + end + + # Two structs are equal when they share a class and produce identical + # `to_jsii` payloads. + # + # @param other [Object] the value to compare against. + # @return [Boolean] `true` iff `other` is the same class and has equal field values. + def ==(other) + return false unless other.class == self.class + + to_jsii == other.to_jsii + end + alias eql? == + + # @return [Integer] a hash code derived from {#to_jsii}, consistent with {#==}. + def hash + to_jsii.hash + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/type.rb b/packages/@jsii/ruby-runtime/lib/jsii/type.rb new file mode 100644 index 0000000000..3b8d995941 --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/type.rb @@ -0,0 +1,131 @@ +# frozen_string_literal: true + +require 'date' +require 'time' + +module Jsii + # Provides runtime type validation and coercion for JSII primitives, collections, and structs. + module Type + # Validate `value` against a JSII type reference (the same shape used by + # the assembly metadata: `{ 'primitive' => 'string' }`, `{ 'fqn' => '...' }`, + # `{ 'collection' => { ... } }`, or `{ 'union' => { 'types' => [...] } }`). + # + # @param value [Object] the value to check. + # @param type_ref [Hash] the JSII type-reference description. + # @param argname [String] human-readable label used in error messages. + # @return [nil] when the value satisfies the type. + # @raise [TypeError] when the value does not match the type reference. + def self.check_type(value, type_ref, argname = 'argument') + return check_primitive(value, type_ref['primitive'], argname) if type_ref.key?('primitive') + return check_fqn(value, type_ref['fqn'], argname) if type_ref.key?('fqn') + return check_collection(value, type_ref['collection'], argname) if type_ref.key?('collection') + return check_union(value, type_ref['union'], argname) if type_ref.key?('union') + + raise TypeError, "Unknown type reference: #{type_ref.inspect}" + end + + class << self + private + + PRIMITIVE_VALIDATORS = { + 'string' => ->(v, arg) { Jsii::Type.send(:check_ruby_type!, v, String, arg, 'a String') }, + 'number' => ->(v, arg) { Jsii::Type.send(:check_ruby_type!, v, Numeric, arg, 'a Numeric') }, + 'boolean' => lambda do |v, arg| + raise TypeError, "Expected #{arg} to be a Boolean" unless v.is_a?(TrueClass) || v.is_a?(FalseClass) + end, + 'date' => lambda do |v, arg| + unless v.is_a?(Time) || v.is_a?(DateTime) || v.is_a?(Date) + raise TypeError, + "Expected #{arg} to be a Date/Time" + end + end, + 'json' => ->(v, arg) { Jsii::Type.send(:check_json_type, v, arg) }, + 'any' => ->(_v, _arg) { nil } + }.freeze + + def check_primitive(value, primitive, argname) + validator = PRIMITIVE_VALIDATORS[primitive] + raise TypeError, "Unknown primitive type: #{primitive}" unless validator + + validator.call(value, argname) + end + + def check_fqn(value, fqn, argname) + return if fqn == 'any' + + ruby_class = resolve_fqn_to_ruby_class(fqn) + return unless ruby_class + + if value.is_a?(Hash) || value.is_a?(Jsii::Struct) + # Hash is allowed for Structs and Interfaces (which are Ruby Modules) + return if ruby_class.instance_of?(Module) + return if ruby_class < Jsii::Struct + + raise TypeError, "Expected #{argname} to be of type #{ruby_class.name}" + end + + raise TypeError, "Expected #{argname} to be of type #{ruby_class.name}" unless value.is_a?(ruby_class) + end + + def check_collection(value, collection, argname) + case collection['kind'] + when 'array' + check_array_collection(value, collection, argname) + when 'map' + check_map_collection(value, collection, argname) + else + raise TypeError, "Unknown collection kind: #{collection['kind']}" + end + end + + def check_ruby_type!(value, expected_class, argname, type_name) + raise TypeError, "Expected #{argname} to be #{type_name}" unless value.is_a?(expected_class) + end + + def check_json_type(value, argname) + is_valid = value.is_a?(Hash) || value.is_a?(Array) || value.is_a?(String) || + value.is_a?(Numeric) || value.is_a?(TrueClass) || value.is_a?(FalseClass) + raise TypeError, "Expected #{argname} to be a JSON-serializable type" unless is_valid + end + + def check_array_collection(value, collection, argname) + check_ruby_type!(value, Array, argname, 'an Array') + + element_type = collection['elementtype'] + value.each_with_index do |item, index| + check_type(item, element_type, "#{argname}[#{index}]") + end + end + + def check_map_collection(value, collection, argname) + check_ruby_type!(value, Hash, argname, 'a Hash') + + element_type = collection['elementtype'] + value.each do |k, v| + check_type(v, element_type, "#{argname}[#{k.inspect}]") + end + end + + def check_union(value, union, argname) + types = union['types'] + is_valid = types.any? do |t| + check_type(value, t, argname) + true + rescue TypeError + false + end + raise TypeError, "Expected #{argname} to match one of the union types" unless is_valid + end + end + + # Resolves a JSII fully-qualified name to the Ruby class/module the pacmak + # target generated for it. + # + # @param fqn [String] the JSII fully-qualified name (e.g. `"jsii-calc.Calculator"`). + # @return [Class, Module, nil] the registered Ruby class/module, or `nil` if + # no class is registered for that fqn. + def self.resolve_fqn_to_ruby_class(fqn) + Jsii::Object.find_class_by_fqn(fqn) + end + end +end diff --git a/packages/@jsii/ruby-runtime/lib/jsii/utils.rb b/packages/@jsii/ruby-runtime/lib/jsii/utils.rb new file mode 100644 index 0000000000..6405bfd0b2 --- /dev/null +++ b/packages/@jsii/ruby-runtime/lib/jsii/utils.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +module Jsii + # String / Symbol / value utility functions used internally by the jsii + # runtime. Scoped under Jsii::Utils to avoid monkey-patching core classes — + # this means jsii-ruby-runtime can be loaded alongside ActiveSupport (or any + # other library that defines `String#underscore`, `String#camelize`, + # `Object#blank?`, etc.) without conflicts or surprising precedence. + module Utils + # Names that the pacmak ruby target rewrites by prepending an underscore + # before emitting the generated method/property. Must stay in sync with + # `RUBY_RESERVED_NAMES` in packages/jsii-pacmak/lib/targets/ruby.ts; the + # runtime side needs to apply the same renaming when dispatching kernel + # callbacks so a JSII member named `send` finds the generated `_send` + # method instead of falling through to `Object#send` (or `NoMethodError` + # for keyword names like `class` / `while`). + RUBY_RESERVED_NAMES = %w[ + alias and begin break case class def defined? do else elsif end ensure + false for if in module next nil not or redo rescue retry return self + super then true undef unless until when while yield + send __send__ + initialize new allocate to_jsii ruby_class + ].to_set.freeze + + module_function + + # Converts a camelCase or PascalCase string to snake_case. + # Implementation adapted from ActiveSupport's String#underscore. + # + # @param str [String, Symbol] the value to convert. + # @return [String] the snake_case form (a new String; the input is never mutated). + def underscore(str) + s = str.to_s + return s.dup unless /[A-Z-]/.match?(s) + + word = s.gsub('::', '/') + word.gsub!(/(?<=[A-Z])(?=[A-Z][a-z])|(?<=[a-z\d])(?=[A-Z])/, '_') + word.tr!('-', '_') + word.downcase! + word + end + + # Converts a snake_case string (or Symbol) to camelCase. + # + # @param str [String, Symbol] the value to convert. + # @return [String] the camelCase form. + def camelize(str) + str.to_s.gsub(/_([a-z\d])/) { ::Regexp.last_match(1).upcase } + end + + # Map a JSII member name (the wire form, e.g. `break`, `fooBar`, `2fa`) + # to the Ruby identifier the pacmak ruby target generates for it. Must + # mirror the generator's `rubyName` in jsii-pacmak/lib/targets/ruby.ts: + # snake_case the name, then prefix with `_` if the result is a Ruby + # reserved word or starts with a digit. + # + # Used by the kernel callback dispatcher so an override of a reserved- + # name interface method (e.g. `IJavaReservedWordsInAnInterface#break`, + # generated as `_break`) is actually called. Without this remapping + # the kernel would `__send__(:break, ...)` and raise NoMethodError, + # or — worse, for `send` itself — accidentally invoke `Object#send`. + # + # @param jsii_name [String] the JSII member name as it appears on the wire. + # @return [String] the Ruby identifier the generator emits for that member. + def ruby_member_name(jsii_name) + snake = underscore(jsii_name) + # `jsii_` is reserved for the runtime's own API surface (jsii_ref, + # jsii_serialize, ...) — the generator prefixes any member that would + # land in it, so callback dispatch must apply the same renaming. + return "_#{snake}" if RUBY_RESERVED_NAMES.include?(snake) || snake.start_with?('jsii_') || /\A\d/.match?(snake) + + snake + end + + # Returns true when the value is nil, empty, or — for strings — only + # whitespace. Mirrors ActiveSupport's `Object#blank?` semantics for the + # specific types this runtime actually encounters. + # + # @param value [Object] the value to test. + # @return [Boolean] `true` if blank, `false` otherwise. + def blank?(value) + return true if value.nil? + return value.empty? if value.respond_to?(:empty?) && !value.is_a?(String) + return value.empty? || value.match?(/\A[[:space:]]*\z/) if value.is_a?(String) + + false + end + + # Coerces a Proc (or a single-entry Hash holding one) into an anonymous + # object implementing a single-method jsii interface — the Ruby analogue + # of TypeScript passing `{ yourTurn: (bell) => ... }` where an interface + # is expected (structural typing), or Java passing a lambda to any + # single-method interface (javac SAM conversion). jsii's wire protocol + # has no function type — callbacks are always "object implementing an + # interface" — so the wrapper produced here rides the exact machinery + # ordinary interface implementations use: it `include`s the module, the + # override scanner discovers the method via `jsii_overridable_methods`, + # and the serializer ships it as a native implementation. + # + # Accepted forms, for an interface whose single abstract member is the + # method `your_turn`: + # + # coerce_callable(->(bell) { bell.ring }, IBellRinger) + # coerce_callable({ your_turn: ->(bell) { bell.ring } }, IBellRinger) + # + # Anything else — including any value aimed at an interface with more + # than one member, or with property members — is returned unchanged, so + # generated code can call this unconditionally and let ordinary type + # checking report non-coercible values. + # + # @param value [Object] the candidate value. + # @param interface_module [Module] the generated jsii interface module. + # @return [Object] an implementing object, or `value` unchanged. + def coerce_callable(value, interface_module) + return value unless interface_module.respond_to?(:jsii_overridable_methods) + + members = interface_module.jsii_overridable_methods + return value unless members.size == 1 + + ruby_name, metadata = members.first + return value unless metadata[:kind] == :method + + callable = + if value.is_a?(Proc) + value + elsif value.is_a?(Hash) && value.size == 1 && value[ruby_name].is_a?(Proc) + value[ruby_name] + end + return value if callable.nil? + + wrapper = Class.new do + include interface_module + define_method(ruby_name) { |*args| callable.call(*args) } + end + wrapper.new + end + end +end diff --git a/packages/@jsii/ruby-runtime/package.json b/packages/@jsii/ruby-runtime/package.json new file mode 100644 index 0000000000..582f4181ad --- /dev/null +++ b/packages/@jsii/ruby-runtime/package.json @@ -0,0 +1,48 @@ +{ + "name": "@jsii/ruby-runtime", + "version": "0.0.0", + "private": true, + "description": "Ruby client for jsii runtime", + "license": "Apache-2.0", + "author": "Amazon Web Services (https://aws.amazon.com)", + "scripts": { + "build": "gem build *.gemspec && mkdir -p dist/ruby && mv *.gem dist/ruby", + "doc": "bundle exec rake doc", + "package": "package-ruby && package-private" + }, + "homepage": "https://github.com/aws/jsii", + "bugs": { + "url": "https://github.com/aws/jsii" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/aws/jsii.git", + "directory": "packages/@jsii/ruby-runtime" + }, + "engines": { + "node": ">= 14.17.0" + }, + "dependencies": { + "@jsii/runtime": "^0.0.0" + }, + "devDependencies": { + "fs-extra": "^10.1.0", + "jsii-build-tools": "^0.0.0", + "jsii-calc": "^3.20.120", + "jsii-pacmak": "^0.0.0" + }, + "nx": { + "targets": { + "build": { + "outputs": [ + "{projectRoot}/dist/ruby/*.gem" + ] + } + } + }, + "directories": { + "lib": "lib" + }, + "keywords": [], + "type": "commonjs" +} diff --git a/packages/@jsii/ruby-runtime/sig/jsii-ruby-runtime.rbs b/packages/@jsii/ruby-runtime/sig/jsii-ruby-runtime.rbs new file mode 100644 index 0000000000..f9c898fcf4 --- /dev/null +++ b/packages/@jsii/ruby-runtime/sig/jsii-ruby-runtime.rbs @@ -0,0 +1,65 @@ +# Hand-written RBS for the jsii Ruby runtime base classes. Generated gem +# signatures (sig/.rbs) reference these as the superclasses of +# every proxy class, struct, and enum. + +module Jsii + # Base proxy class for all jsii object references. + class Object + extend _FqnExtension + + attr_accessor jsii_fqn: String + attr_reader jsii_ref: String? + + def initialize: (*untyped args) ?{ (instance) -> void } -> void + def jsii_serialize: () -> Hash[String, untyped] + def jsii_interfaces: () -> Array[String] + def ruby_class: () -> Class + + # Dynamic dispatch fallback for members without a generated stub + # (e.g. on anonymously-returned objects). Untyped by nature. + def method_missing: (Symbol name, *untyped args) -> untyped + def respond_to_missing?: (Symbol name, ?bool include_private) -> bool + + def self.register_jsii_fqn: (String fqn, (Class | Module) klass) -> void + def self.from_jsii_ref: (String ref, String fqn) -> Jsii::Object + end + + # Base class for jsii data types (structs), passed by value. + class Struct + extend _FqnExtension + + attr_accessor jsii_ref: String? + + def initialize: (**untyped kwargs) -> void + def to_jsii: () -> Hash[String, untyped] + def jsii_serialize: () -> Hash[String, untyped] + def ==: (untyped other) -> bool + def eql?: (untyped other) -> bool + def hash: () -> Integer + def is_a?: (Module klass) -> bool + def kind_of?: (Module klass) -> bool + + def self.jsii_extra_struct_bases: () -> Array[Class] + def self.jsii_struct_conforms_to?: (Class klass) -> bool + end + + # An enum member: a fully-qualified jsii enum value. + class Enum + attr_reader fqn: String + attr_reader value: String + + def initialize: (String fqn, String value) -> void + def jsii_serialize: () -> Hash[String, String] + def to_s: () -> String + def inspect: () -> String + def ==: (untyped other) -> bool + + def self.jsii_deserialize: (Hash[String, untyped] value) -> Jsii::Enum + end + + # Mixin providing the jsii_fqn class attribute on generated types. + interface _FqnExtension + def jsii_fqn: () -> String? + def jsii_fqn=: (String) -> String + end +end diff --git a/packages/@jsii/spec/src/configuration.ts b/packages/@jsii/spec/src/configuration.ts index 16355fea82..248317a665 100644 --- a/packages/@jsii/spec/src/configuration.ts +++ b/packages/@jsii/spec/src/configuration.ts @@ -78,6 +78,22 @@ export interface Config { */ versionSuffix?: string; }; + ruby?: { + /** + * name of the generated Ruby gem + */ + gem: string; + + /** + * name of generated Ruby module + */ + module: string; + + /** + * A list of acronyms used to enforce correct PascalCasing for Ruby module names + */ + acronyms?: string[]; + }; }; /** diff --git a/packages/@scope/jsii-calc-base-of-base/package.json b/packages/@scope/jsii-calc-base-of-base/package.json index 0686ff585f..7ad8089734 100644 --- a/packages/@scope/jsii-calc-base-of-base/package.json +++ b/packages/@scope/jsii-calc-base-of-base/package.json @@ -55,6 +55,10 @@ "python": { "distName": "scope.jsii-calc-base-of-base", "module": "scope.jsii_calc_base_of_base" + }, + "ruby": { + "gem": "scope-jsii-calc-base-of-base", + "module": "Scope::JsiiCalcBaseOfBase" } }, "tsc": { diff --git a/packages/@scope/jsii-calc-base/package.json b/packages/@scope/jsii-calc-base/package.json index b7d2075fba..9c01919cc6 100644 --- a/packages/@scope/jsii-calc-base/package.json +++ b/packages/@scope/jsii-calc-base/package.json @@ -72,6 +72,10 @@ "python": { "distName": "scope.jsii-calc-base", "module": "scope.jsii_calc_base" + }, + "ruby": { + "gem": "scope-jsii-calc-base", + "module": "Scope::JsiiCalcBase" } }, "tsc": { diff --git a/packages/@scope/jsii-calc-lib/package.json b/packages/@scope/jsii-calc-lib/package.json index 18128c6396..b1f6efa3e4 100644 --- a/packages/@scope/jsii-calc-lib/package.json +++ b/packages/@scope/jsii-calc-lib/package.json @@ -67,6 +67,10 @@ "python": { "distName": "scope.jsii-calc-lib", "module": "scope.jsii_calc_lib" + }, + "ruby": { + "gem": "scope-jsii-calc-lib", + "module": "Scope::JsiiCalcLib" } }, "tsc": { diff --git a/packages/jsii-calc/package.json b/packages/jsii-calc/package.json index db0e93bb12..2eeca51f4a 100644 --- a/packages/jsii-calc/package.json +++ b/packages/jsii-calc/package.json @@ -81,6 +81,10 @@ "classifiers": [ "Test :: Classifier :: Is Dummy" ] + }, + "ruby": { + "gem": "jsii-calc", + "module": "JsiiCalc" } }, "tsc": { diff --git a/packages/jsii-calc/update-all.sh b/packages/jsii-calc/update-all.sh index 8b677b699f..02c425271b 100755 --- a/packages/jsii-calc/update-all.sh +++ b/packages/jsii-calc/update-all.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash set -euo pipefail scriptdir=$(cd $(dirname $0) && pwd) cd ${scriptdir} diff --git a/packages/jsii-pacmak/lib/targets/index.ts b/packages/jsii-pacmak/lib/targets/index.ts index f404d02eb2..9146fad2a5 100644 --- a/packages/jsii-pacmak/lib/targets/index.ts +++ b/packages/jsii-pacmak/lib/targets/index.ts @@ -11,6 +11,7 @@ import { Golang } from './go'; import { JavaBuilder } from './java'; import JavaScript from './js'; import Python from './python'; +import Ruby from './ruby'; export enum TargetName { DOTNET = 'dotnet', @@ -18,6 +19,7 @@ export enum TargetName { JAVA = 'java', JAVASCRIPT = 'js', PYTHON = 'python', + RUBY = 'ruby', } export type BuilderFactory = ( @@ -33,6 +35,7 @@ export const ALL_BUILDERS: { [key in TargetName]: BuilderFactory } = { new IndependentPackageBuilder(TargetName.JAVASCRIPT, JavaScript, ms, o), python: (ms, o) => new IndependentPackageBuilder(TargetName.PYTHON, Python, ms, o), + ruby: (ms, o) => new IndependentPackageBuilder(TargetName.RUBY, Ruby, ms, o), }; export const INCOMPLETE_DISCLAIMER_NONCOMPILING = diff --git a/packages/jsii-pacmak/lib/targets/ruby.ts b/packages/jsii-pacmak/lib/targets/ruby.ts new file mode 100644 index 0000000000..109f5b6c43 --- /dev/null +++ b/packages/jsii-pacmak/lib/targets/ruby.ts @@ -0,0 +1,2368 @@ +import * as spec from '@jsii/spec'; +import { toSnakeCase, toPascalCase } from 'codemaker'; +import * as fs from 'fs-extra'; +import * as reflect from 'jsii-reflect'; +import { + ApiLocation, + enforcesStrictMode, + RosettaTabletReader, + TargetLanguage, +} from 'jsii-rosetta'; +import * as path from 'path'; + +import { Generator, Legalese } from '../generator'; +import { assertSpecIsRosettaCompatible } from '../rosetta-assembly'; +import { Target, TargetOptions } from '../target'; +import { subprocess } from '../util'; +import { VERSION } from '../version'; +import { toReleaseVersion, toRubyVersionRange } from './version-utils'; + +import { TargetName } from './index'; + +export class RubyTarget extends Target { + protected readonly generator: RubyGenerator; + + public constructor(options: TargetOptions) { + super(options); + this.generator = new RubyGenerator(options.rosetta, options); + } + + public async build(sourceDir: string, outDir: string): Promise { + const gemName = rubyGemName(this.assembly); + + // Package the generated files into a distributable .gem file + await subprocess('gem', ['build', `${gemName}.gemspec`], { + cwd: sourceDir, + }); + + // Copy compiled artifacts safely to the distribution directory + await this.copyFiles(sourceDir, outDir); + } +} + +function rubyGemName(assembly: { + name: string; + targets?: spec.AssemblyTargets; +}): string { + return ( + (assembly.targets?.ruby?.gem as string | undefined) ?? + assembly.name.replace(/@/g, '').replace(/\//g, '-') + ); +} + +/** + * Escape a string for use inside a Ruby double-quoted ("...") literal. + * Handles backslash, double-quote, and `#` (otherwise `#{...}` would trigger + * string interpolation). Apply at every interpolation site that embeds a + * jsii-supplied name into generated Ruby source. + */ +function rubyDq(s: string): string { + return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/#/g, '\\#'); +} + +/** + * Escape a string for use inside a Ruby single-quoted ('...') literal. + * Single-quoted strings only treat `\\` and `\'` specially. + */ +function rubySq(s: string): string { + return s.replace(/\\/g, '\\\\').replace(/'/g, "\\'"); +} + +/** + * Escape a string for literal use inside a RegExp pattern. + */ +function escapeRegExp(s: string): string { + return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + +/** + * Render a JS value as a Ruby expression that evaluates to JSON.parse of the + * value's canonical JSON encoding. Base64 keeps the embedded literal safe + * from any input — no backslashes, quotes, `#{...}`, or newlines to escape. + * Replaces the previous `%q{${JSON.stringify(...)}}` pattern, which silently + * mangled any backslash in the JSON (Ruby's `%q{}` does not preserve `\\`). + */ +function rubyJsonLiteral(value: any): string { + const json = JSON.stringify(value ?? { primitive: 'any' }); + const b64 = Buffer.from(json, 'utf-8').toString('base64'); + return `JSON.parse(Base64.strict_decode64("${b64}"))`; +} + +/** + * Whether a jsii member (method, property, or enum value) is marked + * `@deprecated` in the source assembly. Used by the collision-resolution + * pass to pick a winning member when multiple snake_case to the same name. + * + * The reflect API exposes two shapes: + * - Plain spec objects (used by enum members `typeSpec.members`): + * `docs?.deprecated` is `string | undefined`. + * - `Documentable.docs` instances (used by `allProperties` / `allMethods`): + * `.docs.deprecated` is a boolean that also reflects the parent type's + * deprecation status. + * We treat any truthy value on either shape as deprecated. + */ +function isDeprecated(member: { docs?: { deprecated?: unknown } }): boolean { + return !!member.docs?.deprecated; +} + +/** + * A type reference in either of the two shapes this generator handles: + * jsii-reflect wrappers (members coming off `allProperties`/`allMethods`) + * or raw spec objects (initializer parameters). Normalize with + * {@link RubyGenerator.typeRefSpec} before introspecting. + */ +type RubyTypeRef = reflect.TypeReference | spec.TypeReference; + +/** + * Minimal structural shape of a documentable, typed parameter — satisfied + * by `reflect.Parameter`, raw `spec.Parameter`, and `reflect.Property` + * (struct members doubling as constructor keyword arguments). + */ +interface ParamLike { + readonly name: string; + readonly type?: RubyTypeRef; + readonly optional?: boolean; + readonly variadic?: boolean; +} + +/** + * Minimal structural shape required by the member-collision passes — + * satisfied by reflect members (whose `docs.deprecated` is a boolean) and + * raw spec members (where it is a string reason). + */ +interface MemberLike { + readonly name: string; + readonly static?: boolean; + readonly docs?: { readonly deprecated?: unknown }; +} + +/** + * Names that must be renamed (with a leading underscore) when used as Ruby + * method/parameter identifiers. Includes: + * - Ruby keywords (`end`, `class`, `def`, ...). Using one as a method + * name produces a parse error. + * - The handful of Object methods the runtime hard-depends on + * (`send`, `__send__`) — without these the kernel can't dispatch back + * into a Ruby override. + * - Names the Ruby object model or the jsii runtime itself depends on: + * `initialize` (a member by that name would silently replace the + * generated constructor), `new` / `allocate` (class methods used to + * instantiate proxies — the registry hydrates refs via + * `klass.allocate`), `to_jsii` (struct serialization) and `ruby_class` + * (internal dispatch helper). + * - Additionally (not in this set — see `rubyName`): any name beginning + * with `jsii_` is prefixed, so generated members can never shadow the + * runtime's own API surface (`jsii_ref`, `jsii_serialize`, + * `jsii_call_method`, `jsii_properties`, ...), present or future. + * + * Other Object/Kernel methods (`method`, `methods`, `inspect`, `to_s`, + * `hash`, ...) are deliberately NOT renamed: jsii-calc and real-world + * assemblies use these names for legitimate JSII methods, and the + * shadowing cost is mild (those methods are still reachable via + * `Object.instance_method(:foo).bind(self).call(...)` or `__send__`). + * + * Must stay in sync with `Jsii::Utils::RUBY_RESERVED_NAMES` in + * packages/@jsii/ruby-runtime/lib/jsii/utils.rb (enforced by a spec in + * packages/@jsii/ruby-runtime-test/spec/unit/utils_spec.rb), so kernel + * callbacks dispatch to the renamed member. + */ +// A `require` / `require_relative` line in a rendered example. After import translation, +// several imports from one package collapse to duplicate `require 'aws-cdk-lib'` lines; +// these are de-duplicated before display so each require appears once. +const REQUIRE_LINE = /^\s*require(?:_relative)?\s+['"][^'"]+['"];?\s*$/; + +/** + * Some source READMEs put the first line of a fenced block onto the fence-open line — + * e.g. an ASCII diagram: "```text +---". CommonMark (what GitHub uses) + * treats everything after the ``` as the info string and opens the fence anyway, but + * redcarpet — which YARD uses so it can highlight the fenced blocks — treats the whole + * thing as a paragraph and prints the ``` literally. Split that trailing content onto + * its own line so the fence opens (and, unlike GitHub, the first line is preserved). + */ +function normalizeFences(markdown: string): string { + return markdown.replace( + /^([ \t]*`{3,}[ \t]*[\w.+#-]*)([ \t]{2,}\S.*)$/gm, + '$1\n$2', + ); +} + +/** De-duplicate `require` lines in a code snippet, keeping the first of each. */ +function dedupeRequires(code: string): string { + const seen = new Set(); + return code + .split('\n') + .filter((line) => { + if (!REQUIRE_LINE.test(line)) { + return true; + } + const key = line.trim(); + if (seen.has(key)) { + return false; + } + seen.add(key); + return true; + }) + .join('\n'); +} + +const RUBY_RESERVED_NAMES = new Set([ + // Keywords + 'alias', + 'and', + 'begin', + 'break', + 'case', + 'class', + 'def', + // NB: unreachable — toSnakeCase strips the question mark before lookup — + // kept so the list reads as the complete Ruby keyword set. + 'defined?', + 'do', + 'else', + 'elsif', + 'end', + 'ensure', + 'false', + 'for', + 'if', + 'in', + 'module', + 'next', + 'nil', + 'not', + 'or', + 'redo', + 'rescue', + 'retry', + 'return', + 'self', + 'super', + 'then', + 'true', + 'undef', + 'unless', + 'until', + 'when', + 'while', + 'yield', + // Hard runtime dependencies (callbacks use `__send__` for dispatch). + 'send', + '__send__', + // Ruby object-model / jsii-runtime hooks (see doc comment above). + 'initialize', + 'new', + 'allocate', + 'to_jsii', + 'ruby_class', +]); + +export class RubyGenerator extends Generator { + public constructor( + private readonly rosetta: RosettaTabletReader, + options: TargetOptions, + ) { + super({ runtimeTypeChecking: options.runtimeTypeChecking }); + // Ruby convention is 2-space indentation (CodeMaker defaults to 4). + this.code.indentation = 2; + } + + /** + * Translate a jsii `@example` (authored in TypeScript) into idiomatic Ruby + * via Rosetta. Falls back to the original text if translation fails, so a + * bad snippet degrades to a TypeScript example rather than breaking the + * build. + */ + private convertExample(example: string, apiLocation: ApiLocation): string { + assertSpecIsRosettaCompatible(this.assembly); + const translated = this.rosetta.translateExample( + apiLocation, + example, + TargetLanguage.RUBY, + enforcesStrictMode(this.assembly), + ); + return dedupeRequires(translated.source); + } + + /** + * Translate the TypeScript code samples embedded in a Markdown document (a + * module README) into Ruby via Rosetta, leaving the prose untouched. Mirror + * of `convertExample` but for whole documents, matching the Python target's + * `convertMarkdown`. + */ + private convertMarkdown(markdown: string, apiLocation: ApiLocation): string { + assertSpecIsRosettaCompatible(this.assembly); + // Strip HTML comments (e.g. CDK's `` / CFNONLY + // markers): YARD's Markdown renderer emits them as visible text instead of hiding + // them, so they'd otherwise show up verbatim in the rendered README. + const cleaned = normalizeFences(markdown.replace(//g, '')); + const translated = this.rosetta.translateSnippetsInMarkdown( + apiLocation, + cleaned, + TargetLanguage.RUBY, + enforcesStrictMode(this.assembly), + ); + return this.rubifyInlineRefs(translated); + } + + /** + * Rosetta translates fenced code blocks, but not inline `code` references in the + * prose (e.g. the `bucketArn` / `arnForObjects(pattern)` list in the S3 README). + * Rewrite those to Ruby: a bare camelCase identifier — optionally followed by a + * call's parentheses — becomes snake_case via the same `toSnakeCase` the member + * generator uses, so `bucketArn` -> `bucket_arn` and `arnForObjects(pattern)` -> + * `arn_for_objects(pattern)`. Everything else is left untouched: fenced blocks + * (already translated), and anything that isn't a bare identifier — ARNs, URLs and + * names (they carry `:` `/` `-` `.`), PascalCase type names, ALL_CAPS enum members. + */ + private rubifyInlineRefs(markdown: string): string { + let inFence = false; + let seenRequires = new Set(); + const out: string[] = []; + for (const line of markdown.split('\n')) { + if (/^\s*(```|~~~)/.test(line)) { + inFence = !inFence; + seenRequires = new Set(); // de-dup requires within each code block + out.push(line); + continue; + } + if (inFence) { + // Collapse duplicate `require` lines (e.g. several imports that all map to + // `require 'aws-cdk-lib'`) to a single one. + if (REQUIRE_LINE.test(line)) { + const key = line.trim(); + if (seenRequires.has(key)) { + continue; + } + seenRequires.add(key); + } + out.push(line); + continue; + } + out.push( + line.replace(/`([^`\n]+)`/g, (whole, inner: string) => { + const m = /^([a-z][A-Za-z0-9]*)(\([A-Za-z0-9_,\s]*\))?$/.exec(inner); + if (!m || !/[A-Z]/.test(m[1])) { + return whole; + } + const call = m[2] + ? m[2].replace(/[A-Za-z][A-Za-z0-9]*/g, (arg) => toSnakeCase(arg)) + : ''; + return `\`${toSnakeCase(m[1])}${call}\``; + }), + ); + } + return out.join('\n'); + } + + /** + * Normalize a type reference to its raw `spec.TypeReference` shape. + * Call sites hold two shapes: jsii-reflect `TypeReference` instances + * (which wrap the raw spec under `.spec`) for members coming off + * `allProperties` / `allMethods`, and raw spec objects for + * `typeSpec.spec.initializer.parameters`. Collection/union introspection + * only works on the raw shape. + */ + private typeRefSpec( + type: RubyTypeRef | undefined, + ): spec.TypeReference | undefined { + if (type instanceof reflect.TypeReference) { + return type.spec; + } + return type; + } + + private isStructFqn(fqn: string): boolean { + const type = this.reflectAssembly.system.tryFindFqn(fqn); + return !!(type?.isInterfaceType() && type?.isDataType()); + } + + /** + * A behavioral (non-datatype) interface whose flattened member surface is + * exactly one method and no properties — eligible for Proc coercion at + * call sites (see coercionExpr). Flattened deliberately, to match the + * runtime's own SAM check against the generated module's + * `jsii_overridable_methods` table, which is also flattened. + */ + private isSamInterfaceFqn(fqn: string): boolean { + const type = this.reflectAssembly.system.tryFindFqn(fqn); + if (type == null || !type.isInterfaceType()) { + return false; + } + // `.datatype` (not the isDataType() guard): negating a `this is + // InterfaceType` guard on an already-narrowed InterfaceType collapses the + // fall-through to `never`. + if (type.datatype) { + return false; + } + return type.allMethods.length === 1 && type.allProperties.length === 0; + } + + /** + * Extract the raw `spec.Docs` from either shape we hold: jsii-reflect + * objects wrap it under `.spec.docs`; plain spec objects (enum members, + * initializer parameters) carry `.docs` directly. Genuinely dual-shape, + * hence the `any` — reflect `Docs` instances also satisfy the returned + * type structurally (their getters mirror spec.Docs, except `deprecated` + * which is a boolean; emitDocs handles both). + */ + private rawDocs(obj: any): spec.Docs | undefined { + return obj?.spec?.docs ?? obj?.docs; + } + + /** + * Render a jsii type reference as a YARD type string for `@param` / + * `@return` tags. + */ + private rubyDocType(ref: spec.TypeReference | undefined): string { + if (!ref) { + return 'Object'; + } + if (spec.isPrimitiveTypeReference(ref)) { + switch (ref.primitive) { + case spec.PrimitiveType.String: + return 'String'; + case spec.PrimitiveType.Number: + return 'Numeric'; + case spec.PrimitiveType.Boolean: + return 'Boolean'; + case spec.PrimitiveType.Date: + return 'DateTime'; + case spec.PrimitiveType.Json: + return 'Hash'; + case spec.PrimitiveType.Any: + return 'Object'; + } + } + if (spec.isNamedTypeReference(ref)) { + return this.rubyFullTypeName(ref.fqn); + } + if (spec.isCollectionTypeReference(ref)) { + const elem = this.rubyDocType(ref.collection.elementtype); + return ref.collection.kind === spec.CollectionKind.Array + ? `Array<${elem}>` + : `Hash{String => ${elem}}`; + } + if (spec.isUnionTypeReference(ref)) { + return ref.union.types.map((t) => this.rubyDocType(t)).join(', '); + } + return 'Object'; + } + + /** + * Render a jsii type reference as an RBS type expression (for `sig/` + * declarations). Same recursion as {@link rubyDocType}, but RBS surface + * syntax and honest escape hatches: `any`/`json` become `untyped` (not a + * concrete class), booleans are the `bool` built-in, collections use + * `[...]`, unions use `|`. When `optional` is set, the result is wrapped + * nilable (`T?`). + */ + private rbsType( + ref: spec.TypeReference | undefined, + optional = false, + ): string { + const bare = this.rbsTypeBare(ref); + // `untyped` already admits nil; don't double-decorate. + return optional && bare !== 'untyped' ? `${bare}?` : bare; + } + + private rbsTypeBare(ref: spec.TypeReference | undefined): string { + if (!ref) { + return 'untyped'; + } + if (spec.isPrimitiveTypeReference(ref)) { + switch (ref.primitive) { + case spec.PrimitiveType.String: + return 'String'; + case spec.PrimitiveType.Number: + return 'Numeric'; + case spec.PrimitiveType.Boolean: + return 'bool'; + case spec.PrimitiveType.Date: + return 'DateTime'; + // `json` is recursively any-shaped and `any` is the escape hatch; + // both are honestly `untyped` rather than a flattened Hash/Object. + case spec.PrimitiveType.Json: + case spec.PrimitiveType.Any: + return 'untyped'; + } + } + if (spec.isNamedTypeReference(ref)) { + return `::${this.rubyFullTypeName(ref.fqn)}`; + } + if (spec.isCollectionTypeReference(ref)) { + const elem = this.rbsTypeBare(ref.collection.elementtype); + return ref.collection.kind === spec.CollectionKind.Array + ? `Array[${elem}]` + : `Hash[String, ${elem}]`; + } + if (spec.isUnionTypeReference(ref)) { + const arms = [ + ...new Set(ref.union.types.map((t) => this.rbsTypeBare(t))), + ]; + // A bare `A | B` collides with RBS's method-overload separator, so + // unions must be parenthesized to be valid in return/param position. + return arms.length === 1 ? arms[0] : `(${arms.join(' | ')})`; + } + return 'untyped'; + } + + /** + * RBS type for a *parameter* position. Struct-typed inputs also accept the + * idiomatic hash-literal form — the runtime coerces hashes into structs on + * serialization, recursively through arrays, maps and union arms — so the + * parameter surface widens struct references to `(Struct | Hash[Symbol, + * untyped])`. Output positions (returns, attribute readers) keep the bare + * struct type: values coming back from the kernel are always hydrated + * struct instances, never hashes. + */ + private rbsParamType( + ref: spec.TypeReference | undefined, + optional = false, + ): string { + const bare = this.rbsParamTypeBare(ref); + return optional && bare !== 'untyped' ? `${bare}?` : bare; + } + + private rbsParamTypeBare(ref: spec.TypeReference | undefined): string { + if (!ref) { + return 'untyped'; + } + if (spec.isNamedTypeReference(ref) && this.isStructFqn(ref.fqn)) { + return `(::${this.rubyFullTypeName(ref.fqn)} | Hash[Symbol, untyped])`; + } + if (spec.isCollectionTypeReference(ref)) { + const elem = this.rbsParamTypeBare(ref.collection.elementtype); + return ref.collection.kind === spec.CollectionKind.Array + ? `Array[${elem}]` + : `Hash[String, ${elem}]`; + } + if (spec.isUnionTypeReference(ref)) { + const arms = [ + ...new Set(ref.union.types.map((t) => this.rbsParamTypeBare(t))), + ]; + return arms.length === 1 ? arms[0] : `(${arms.join(' | ')})`; + } + return this.rbsTypeBare(ref); + } + + /** + * Emit a block of text as `#`-prefixed comment lines. + */ + private emitDocLines(text: string): void { + for (const line of text.split('\n')) { + const trimmed = line.trimEnd(); + this.code.line(trimmed === '' ? '#' : `# ${trimmed}`); + } + } + + /** + * Collapse text for interpolation into a single-line YARD tag. Doc text + * (e.g. `docs.returns`) may contain newlines, which would leak subsequent + * lines out of the comment and into generated code. + */ + private inlineDoc(text: string): string { + return text + .split('\n') + .map((l) => l.trim()) + .filter((l) => l !== '') + .join(' '); + } + + /** + * Emit a YARD documentation comment from jsii docs: summary and remarks + * as free text, followed by `@param` / `@return` / `@deprecated` / + * `@see` / `@example` tags as applicable. Silently emits nothing when + * there are no docs and no tags to write. + */ + private emitDocs( + docsSource: unknown, + opts: { + /** Parameters (raw spec or reflect) to render as @param tags. */ + params?: readonly ParamLike[]; + /** The method's raw `returns` OptionalValue; pass with isMethod. */ + returns?: spec.OptionalValue; + /** Emit `@return [void]` when a method declares no return type. */ + isMethod?: boolean; + /** Property getter: emit an @return of the property's type. */ + propertyType?: RubyTypeRef; + propertyOptional?: boolean; + /** + * The API location the docs belong to. When present, `@example` + * snippets are translated to Ruby via Rosetta; without it they are + * emitted verbatim (i.e. as the original TypeScript). + */ + apiLocation?: ApiLocation; + } = {}, + ): void { + const docs: spec.Docs = this.rawDocs(docsSource) ?? {}; + const tags: string[] = []; + + for (const p of opts.params ?? []) { + const pDocs: spec.Docs = this.rawDocs(p) ?? {}; + const baseType = this.rubyDocType(this.typeRefSpec(p.type)); + const rendered = p.variadic + ? `Array<${baseType}>` + : `${baseType}${p.optional ? ', nil' : ''}`; + const summary = pDocs.summary ? ` ${this.inlineDoc(pDocs.summary)}` : ''; + tags.push(`# @param ${this.rubyName(p.name)} [${rendered}]${summary}`); + } + + if (opts.returns?.type) { + const t = this.rubyDocType(this.typeRefSpec(opts.returns.type)); + const optional = opts.returns.optional ? ', nil' : ''; + const text = docs.returns ? ` ${this.inlineDoc(docs.returns)}` : ''; + tags.push(`# @return [${t}${optional}]${text}`); + } else if (opts.isMethod) { + tags.push('# @return [void]'); + } else if (opts.propertyType) { + const t = this.rubyDocType(this.typeRefSpec(opts.propertyType)); + tags.push(`# @return [${t}${opts.propertyOptional ? ', nil' : ''}]`); + } + + if (docs.default !== undefined) { + tags.push(`# @note Default: ${this.inlineDoc(docs.default)}`); + } + if (docs.deprecated !== undefined) { + const reason = + typeof docs.deprecated === 'string' + ? ` ${this.inlineDoc(docs.deprecated)}` + : ''; + tags.push(`# @deprecated${reason}`); + } + if (docs.see) { + tags.push(`# @see ${this.inlineDoc(docs.see)}`); + } + + const exampleText = + docs.example && opts.apiLocation + ? this.convertExample(docs.example, opts.apiLocation) + : docs.example; + const exampleLines = exampleText + ? [ + '# @example', + ...exampleText.split('\n').map((l) => `# ${l.trimEnd()}`.trimEnd()), + ] + : []; + + const hasText = !!docs.summary || !!docs.remarks; + if (!hasText && tags.length === 0 && exampleLines.length === 0) { + return; + } + + if (docs.summary) { + this.emitDocLines(docs.summary); + } + if (docs.remarks) { + this.code.line('#'); + // `remarks` is Markdown prose that often embeds fenced ```ts code samples + // (e.g. CfnResource#addOverride). Translate those to Ruby too, not just the + // `@example` tag — mirroring the Python target's convertMarkdown(remarks). + const remarks = opts.apiLocation + ? this.convertMarkdown(docs.remarks, opts.apiLocation) + : docs.remarks; + this.emitDocLines(remarks); + } + if (tags.length > 0 || exampleLines.length > 0) { + if (hasText) { + this.code.line('#'); + } + for (const tag of tags) { + this.code.line(tag); + } + for (const line of exampleLines) { + this.code.line(line); + } + } + } + + public async save(outdir: string, tarball: string, legalese: Legalese) { + const assembly = this.reflectAssembly; + + // Define the output path for the main Ruby library file + const srcFile = path.join('lib', `${assembly.name}.rb`); + this.code.openFile(srcFile); + + // Emit the core runtime dependency requirement + this.emitHeader(); + + // Pre-declare external dependencies to avoid NameErrors before opening our main module + const dependencies = Object.keys(assembly.spec.dependencies ?? {}); + this.emitDependencies(dependencies); + + const assemblyModule = this.rubyModuleForAssembly(assembly.name); + const moduleParts = assemblyModule.split('::'); + let currentModule = ''; + for (const part of moduleParts) { + currentModule = currentModule ? `${currentModule}::${part}` : part; + this.code.line(`module ${currentModule}; end`); + } + + this.code.open(`module ${assemblyModule}`); + + // Load assembly dynamically + const tarballName = this.getAssemblyFileName(); + this.code.line( + `Jsii::Assembly.load('${rubySq(assembly.name)}', '${rubySq(assembly.version)}', File.expand_path('${rubySq(tarballName)}', __dir__))`, + ); + this.code.line(''); + + // Pre-declare local JSII namespaces + const classRubyPaths = this.collectClassRubyPaths(); + this.emitLocalNamespacePredeclarations(classRubyPaths); + + // Topologically sort the assembly's types so that everything a type's + // *declaration line* references (superclass, included interface + // modules, lexically enclosing type) is emitted before the type itself. + const typesByFqn = new Map(assembly.allTypes.map((t) => [t.fqn, t])); + const sortedTypes: reflect.Type[] = []; + const visited = new Set(); + + const visit = (type: reflect.Type) => { + if (visited.has(type.fqn)) return; + visited.add(type.fqn); + + // Visit base class + if (type.isClassType() && type.spec.base) { + const base = typesByFqn.get(type.spec.base); + if (base) visit(base); + } + + // Visit implemented interfaces + const interfaces = + type.isClassType() || type.isInterfaceType() + ? (type.spec.interfaces ?? []) + : []; + for (const ifaceFqn of interfaces) { + const iface = typesByFqn.get(ifaceFqn); + if (iface) visit(iface); + } + + // Visit declaring parent for nested types + const fqnParts = type.fqn.split('.'); + if (fqnParts.length > 2) { + const parentType = typesByFqn.get(fqnParts.slice(0, -1).join('.')); + if (parentType) visit(parentType); + } + + sortedTypes.push(type); + }; + + for (const type of assembly.allTypes) { + visit(type); + } + + // Group types for lazy (autoload) emission: each *namespace-direct* type + // gets its own file; types nested under a class are bundled into that + // class's file (they can't be independently autoloaded — declaring the + // autoload would reference, and thus force-load, the enclosing class). + const ownerOf = (t: reflect.Type): reflect.Type => { + let cur = t; + for (;;) { + const parentFqn = cur.fqn.split('.').slice(0, -1).join('.'); + const parent = typesByFqn.get(parentFqn); + if (parent && parent.isClassType()) { + cur = parent; // nested under a class → bundle into it + continue; + } + return cur; + } + }; + const groups = new Map(); // owner fqn → members + for (const type of sortedTypes) { + const owner = ownerOf(type); + const bucket = groups.get(owner.fqn) ?? []; + bucket.push(type); + groups.set(owner.fqn, bucket); + } + + // The loader (lib/.rb) is required eagerly; it declares the + // module skeleton, loads the assembly into the kernel, and registers an + // `autoload` + runtime path for each owner type — but defines no bodies. + for (const [ownerFqn, members] of groups) { + const owner = typesByFqn.get(ownerFqn)!; + const requirePath = this.rubyRequirePath(owner.fqn); + const enclosing = this.rubyEnclosingModule(owner.fqn); + const constName = this.rubyModuleName(owner.name); + // A `Module#autoload` covers constant references in user code — but only + // for the namespace-direct owner: you can't autoload a constant nested + // under a class without referencing (and thus force-loading) that class. + this.code.line( + `${enclosing}.autoload(:${constName}, '${rubySq(requirePath)}')`, + ); + // `register_autoload` covers the kernel handing back an fqn the user + // never named. Register *every* member against the owner's file — + // including the nested-under-class types bundled into it — so a + // kernel-returned nested type still hydrates to its real proxy even when + // its owner was never referenced. + for (const member of members) { + this.code.line( + `Jsii::Object.register_autoload("${rubyDq(member.fqn)}", '${rubySq(requirePath)}')`, + ); + } + } + + this.code.close('end'); + this.code.closeFile(srcFile); + + // One file per owner, defining the owner type and any types nested under + // it, using fully-qualified (compact) headers — the loader has already + // declared the namespace modules, and is always required first. + for (const [ownerFqn, members] of groups) { + const owner = typesByFqn.get(ownerFqn)!; + const typeFile = path.join( + 'lib', + `${this.rubyRequirePath(owner.fqn)}.rb`, + ); + this.code.openFile(typeFile); + this.code.line("require 'jsii'"); + this.code.line(''); + for (const type of members) { + const prefix = `${this.rubyEnclosingModule(type.fqn)}::`; + if (type.isEnumType()) { + this.emitEnumType(type, prefix); + } else if (type.isInterfaceType()) { + this.emitInterfaceType(type, prefix); + } else if (type.isClassType()) { + this.emitClassType(type, prefix); + } + } + this.code.closeFile(typeFile); + } + + // Emit each submodule's README as its module docstring (samples translated + // to Ruby), so YARD renders it on the module page. + this.emitModuleReadmes(); + + // Generate the gemspec manifest file for package management + await this.generateGemspec(outdir); + + // Emit RBS type signatures alongside the generated code (sig/), giving + // Steep/TypeProf users static type checking and editor completion. + await this.generateRbs(outdir, sortedTypes); + + return super.save(outdir, tarball, legalese); + } + + /** + * Emit each submodule's (and the assembly's own) README as a Ruby module + * docstring, its TypeScript samples translated to Ruby — mirroring the Python + * target's `emitModuleDocumentation`. Each README goes in a doc-only + * `_readme.rb` inside the module's directory (alongside its type files) so a + * per-directory YARD run picks it up and renders it on the module page. The + * file is never `require`d at runtime. + */ + private emitModuleReadmes(): void { + const emit = (moduleFqn: string, markdown: string | undefined): void => { + if (!markdown) { + return; + } + const rubyModule = this.rubyFullTypeName(moduleFqn); + const translated = this.convertMarkdown(markdown, { + api: 'moduleReadme', + moduleFqn, + }); + const docFile = path.join( + 'lib', + this.rubyRequirePath(moduleFqn), + '_readme.rb', + ); + this.code.openFile(docFile); + for (const line of translated.split('\n')) { + this.code.line(line.length > 0 ? `# ${line}` : '#'); + } + this.code.line(`module ${rubyModule}; end`); + this.code.closeFile(docFile); + }; + + emit(this.assembly.name, this.assembly.readme?.markdown); + for (const [fqn, submodule] of Object.entries( + this.assembly.submodules ?? {}, + )) { + emit(fqn, submodule.readme?.markdown); + } + } + + private emitHeader(): void { + this.code.line("require 'jsii'"); + this.code.line("require 'json'"); + this.code.line("require 'base64'"); + this.code.line(''); + } + + private emitDependencies(dependencies: string[]): void { + for (const dep of dependencies) { + this.code.line(`require '${rubySq(dep)}'`); + } + if (dependencies.length > 0) { + this.code.line(''); + } + + const preDeclaredRubyModules = new Set(); + for (const dep of dependencies) { + const moduleName = this.rubyModuleForAssembly(dep); + let current = ''; + for (const part of moduleName.split('::')) { + current = current ? `${current}::${part}` : part; + preDeclaredRubyModules.add(current); + } + } + for (const mod of Array.from(preDeclaredRubyModules).sort( + (a, b) => a.split('::').length - b.split('::').length, + )) { + this.code.line(`module ${mod}; end`); + } + } + + private emitLocalNamespacePredeclarations(classRubyPaths: Set): void { + const pureRubyNamespaces = new Set(); + + for (const type of this.reflectAssembly.allTypes) { + if (!type.namespace) continue; + + const relNamespace = this.relativeRubyNamespace(type.fqn); + if (!relNamespace) continue; + + let current = ''; + for (const part of relNamespace.split('::')) { + current = current ? `${current}::${part}` : part; + if (classRubyPaths.has(current)) continue; + pureRubyNamespaces.add(current); + } + } + + const sortedNamespaces = Array.from(pureRubyNamespaces).sort( + (a, b) => a.split('::').length - b.split('::').length, + ); + + for (const ns of sortedNamespaces) { + this.code.line(`module ${ns}; end`); + } + this.code.line(''); + } + + private emitEnumType(typeSpec: reflect.EnumType, prefix: string): void { + const resolvedMembers = this.dedupByRubyName( + typeSpec.members, + (m) => this.rubyConstName(m.name), + typeSpec.fqn, + ); + this.emitDocs(typeSpec, { + apiLocation: { api: 'type', fqn: typeSpec.fqn }, + }); + this.code.open(`module ${prefix}${this.rubyModuleName(typeSpec.name)}`); + for (const member of resolvedMembers) { + this.emitDocs(member, { + apiLocation: { + api: 'member', + fqn: typeSpec.fqn, + memberName: member.name, + }, + }); + this.code.line( + `${this.rubyConstName(member.name)} = Jsii::Enum.new("${rubyDq(typeSpec.fqn)}", "${rubyDq(member.name)}")`, + ); + } + this.code.close('end'); + this.code.line(''); + } + + private emitInterfaceType( + typeSpec: reflect.InterfaceType, + prefix: string, + ): void { + // For datatype interfaces (structs) the methods list is empty by + // construction — the jsii compiler forbids methods on them — so the + // method side of the dedup below is a no-op in that branch. + const { props: resolvedAllProperties, methods: resolvedAllMethods } = + this.dedupCrossCategory( + this.dedupByRubyName( + typeSpec.allProperties, + (p) => this.rubyName(p.name), + typeSpec.fqn, + ), + this.dedupByRubyName( + typeSpec.allMethods, + (m) => this.rubyName(m.name), + typeSpec.fqn, + ), + (p) => this.rubyName(p.name), + (m) => this.rubyName(m.name), + typeSpec.fqn, + ); + const kind = typeSpec.datatype ? 'class' : 'module'; + const rubyName = this.rubyModuleName(typeSpec.name); + + const bases = typeSpec.spec.interfaces ?? []; + const baseMixins = bases.map((b) => `::${this.rubyFullTypeName(b)}`); + // JSII structs may extend several parents (diamond hierarchies), but a + // Ruby class has a single superclass: subclass the first parent and + // record the rest via `jsii_extra_struct_bases` so is_a?/kind_of?/case + // dispatch honor every declared parent (see Jsii::Struct). Members are + // unaffected either way — allProperties flattens the full hierarchy. + const baseString = + typeSpec.datatype && bases.length > 0 + ? ` < ${baseMixins[0]}` + : typeSpec.datatype + ? ' < Jsii::Struct' + : ''; + + this.emitDocs(typeSpec, { + apiLocation: { api: 'type', fqn: typeSpec.fqn }, + }); + this.code.open(`${kind} ${prefix}${rubyName}${baseString}`); + + if (!typeSpec.datatype) { + for (const mixin of baseMixins) { + this.code.line(`include ${mixin}`); + } + } + + this.code.line( + `Jsii::Object.register_jsii_fqn("${rubyDq(typeSpec.fqn)}", self)`, + ); + if (typeSpec.datatype && baseMixins.length > 1) { + this.code.line( + `jsii_extra_struct_bases.push(${baseMixins.slice(1).join(', ')})`, + ); + } + this.code.line(''); + + if (typeSpec.datatype) { + const props = resolvedAllProperties; + + const initArgs = props + .map((p) => { + const name = this.rubyName(p.name); + return p.optional ? `${name}: nil` : `${name}:`; + }) + .join(', '); + + // Struct members double as constructor keyword arguments — document + // them as @params (each carries its own summary/type/optionality). + this.emitDocs(undefined, { params: props }); + this.code.open(`def initialize(${initArgs})`); + for (const prop of props) { + const rubyName = this.rubyName(prop.name); + this.emitStructCoercion(rubyName, prop.type, { + assignment: `@${rubyName}`, + }); + // Validate the (coerced) member value — structs are the main + // vehicle for user-supplied data, so they get the same runtime + // type checking as method/constructor parameters. + this.emitTypeChecking(`@${rubyName}`, prop.type, prop.name, { + isOptional: prop.optional, + }); + } + this.code.close('end'); + this.code.line(''); + + for (const prop of props) { + this.emitDocs(prop, { + propertyType: prop.type, + propertyOptional: prop.optional, + apiLocation: { + api: 'member', + fqn: typeSpec.fqn, + memberName: prop.name, + }, + }); + this.code.line(`attr_reader :${this.rubyName(prop.name)}`); + } + this.code.line(''); + + this.code.open('def self.jsii_properties'); + this.code.open('{'); + for (const prop of props) { + this.code.line( + `:${this.rubyName(prop.name)} => "${rubyDq(prop.name)}",`, + ); + } + this.code.close('}'); + this.code.close('end'); + this.code.line(''); + + this.code.open('def to_jsii'); + this.code.line('result = {}'); + if (bases.length > 0) { + this.code.line('result.merge!(super)'); + } + this.code.open('result.merge!({'); + for (const prop of props) { + this.code.line( + `"${rubyDq(prop.name)}" => @${this.rubyName(prop.name)},`, + ); + } + this.code.close('})'); + this.code.line('result.compact'); + this.code.close('end'); + } else { + for (const prop of resolvedAllProperties) { + const propRubyName = this.rubyName(prop.name); + this.emitDocs(prop, { + propertyType: prop.type, + propertyOptional: prop.optional, + apiLocation: { + api: 'member', + fqn: typeSpec.fqn, + memberName: prop.name, + }, + }); + this.code.open(`def ${propRubyName}()`); + this.code.line(`jsii_get_property("${rubyDq(prop.name)}")`); + this.code.close(`end`); + this.code.line(''); + if (!prop.immutable) { + this.code.open(`def ${propRubyName}=(value)`); + this.emitStructCoercion('value', prop.type); + this.emitTypeChecking('value', prop.type, prop.name, { + isOptional: prop.optional, + }); + this.code.line(`jsii_set_property("${rubyDq(prop.name)}", value)`); + this.code.close('end'); + this.code.line(''); + } + } + + for (const method of resolvedAllMethods) { + const sigParams = method.parameters + .map((p) => { + const rubyParam = this.rubyName(p.name); + if (p.variadic) return `*${rubyParam}`; + return p.optional ? `${rubyParam} = nil` : rubyParam; + }) + .join(', '); + const callParams = method.parameters + .map((p) => { + const rubyParam = this.rubyName(p.name); + if (p.variadic) return `*${rubyParam}`; + return rubyParam; + }) + .join(', '); + this.emitDocs(method, { + params: method.parameters, + returns: method.spec?.returns, + isMethod: true, + apiLocation: { + api: 'member', + fqn: typeSpec.fqn, + memberName: method.name, + }, + }); + this.code.open(`def ${this.rubyName(method.name)}(${sigParams})`); + for (const p of method.parameters) { + const rubyParam = this.rubyName(p.name); + this.emitStructCoercion(rubyParam, p.type, { + variadic: p.variadic, + }); + this.emitTypeChecking(rubyParam, p.type, p.name, { + isOptional: p.optional, + isVariadic: p.variadic, + }); + } + if (method.async) { + this.code.line( + `jsii_async_call_method("${rubyDq(method.name)}", [${callParams}])`, + ); + } else { + this.code.line( + `jsii_call_method("${rubyDq(method.name)}", [${callParams}])`, + ); + } + this.code.close('end'); + this.code.line(''); + } + + this.code.open('def self.jsii_overridable_methods'); + this.code.open('{'); + for (const prop of resolvedAllProperties) { + const isOptional = prop.optional ? 'true' : 'false'; + this.code.line( + `:${this.rubyName(prop.name)} => { kind: :property, name: "${rubyDq(prop.name)}", is_optional: ${isOptional} },`, + ); + } + for (const method of resolvedAllMethods) { + this.code.line( + `:${this.rubyName(method.name)} => { kind: :method, name: "${rubyDq(method.name)}", is_optional: false },`, + ); + } + this.code.close('}'); + this.code.close('end'); + } + + this.code.close('end'); + this.code.line(''); + } + + private emitClassType(typeSpec: reflect.ClassType, prefix: string): void { + // Deliberately iterate the *flattened* member lists (allProperties / + // allMethods): every class re-emits inherited instance members, so each + // generated class carries its own forwarding stub for every member it + // exposes — which is what makes `super` work in guest overrides of + // inherited members. The output bloat (O(depth × members)) is the + // accepted cost; statics are the exception (emitted on their defining + // class only, see isOwnStatic below). + const { props: resolvedAllProperties, methods: resolvedAllMethods } = + this.dedupCrossCategory( + this.dedupByRubyName( + typeSpec.allProperties, + (p) => this.rubyPropertyName(p), + typeSpec.fqn, + ), + this.dedupByRubyName( + typeSpec.allMethods, + (m) => this.rubyMethodName(m), + typeSpec.fqn, + ), + (p) => this.rubyPropertyName(p), + (m) => this.rubyMethodName(m), + typeSpec.fqn, + ); + const rubyName = this.rubyModuleName(typeSpec.name); + + const baseFqn = typeSpec.spec.base; + let baseClass = 'Jsii::Object'; + if (baseFqn) { + baseClass = `::${this.rubyFullTypeName(baseFqn)}`; + } + + const interfaces = typeSpec.spec.interfaces ?? []; + const interfaceMixins = interfaces.map( + (i) => `::${this.rubyFullTypeName(i)}`, + ); + + this.emitDocs(typeSpec, { + apiLocation: { api: 'type', fqn: typeSpec.fqn }, + }); + this.code.open(`class ${prefix}${rubyName} < ${baseClass}`); + + for (const mixin of interfaceMixins) { + this.code.line(`include ${mixin}`); + } + this.code.line(`self.jsii_fqn = "${rubyDq(typeSpec.fqn)}"`); + this.code.line( + `Jsii::Object.register_jsii_fqn("${rubyDq(typeSpec.fqn)}", self)`, + ); + this.code.line(''); + + const initializer = typeSpec.spec.initializer; + if ( + initializer && + initializer.parameters && + initializer.parameters.length > 0 + ) { + const initParams = initializer.parameters + .map((p) => { + const rubyParam = this.rubyName(p.name); + if (p.variadic) return `*${rubyParam}`; + return p.optional ? `${rubyParam} = nil` : rubyParam; + }) + .join(', '); + + this.emitDocs(initializer, { + params: initializer.parameters, + apiLocation: { api: 'initializer', fqn: typeSpec.fqn }, + }); + this.code.open(`def initialize(${initParams})`); + for (const p of initializer.parameters) { + const rubyParam = this.rubyName(p.name); + this.emitStructCoercion(rubyParam, p.type); + } + const superArgs = initializer.parameters + .map((p) => { + const rubyParam = this.rubyName(p.name); + if (p.variadic) return `*${rubyParam}`; + return rubyParam; + }) + .join(', '); + + for (const p of initializer.parameters) { + const rubyParam = this.rubyName(p.name); + this.emitTypeChecking(rubyParam, p.type, p.name, { + isOptional: p.optional, + isVariadic: p.variadic, + }); + } + + this.code.line( + `Jsii::Object.instance_method(:initialize).bind(self).call(${superArgs})`, + ); + this.code.close('end'); + } else if (initializer) { + // Parameterless constructor (the jsii compiler propagates initializer + // entries onto instantiable subclasses, so a missing parameter list + // here really means "takes no arguments" — enforce that arity rather + // than silently forwarding stray args to the kernel). + this.code.open('def initialize'); + this.code.line( + 'Jsii::Object.instance_method(:initialize).bind(self).call', + ); + this.code.close('end'); + } else { + // No initializer entry at all: jsii emits this for classes whose + // constructor is not visible (private). Instances only ever come + // from factory methods and are hydrated via `allocate`, which never + // calls #initialize — so constructing one from Ruby is always a bug. + // Raise eagerly with a pointer to the factories instead of letting + // the kernel reject the create call with a less helpful error. + this.code.open('def initialize(*args)'); + this.code.line( + `raise NoMethodError, "${rubyDq(typeSpec.fqn)} does not have a visible constructor; use the provided factory methods"`, + ); + this.code.close('end'); + } + this.code.line(''); + + // Static members are emitted only on their *defining* class. Ruby + // inherits singleton methods, which matches the ES6 static-inheritance + // semantics the kernel implements (its method/property lookups walk the + // base chain, and the base's stub carries the base fqn). Re-emitting an + // inherited static here would bake the *derived* fqn into the kernel + // call instead. A child that overrides a static still gets its own + // stub, because allMethods/allProperties yield the most-derived + // declaration (see the StaticHelloParent/Child fixture in jsii-calc). + const isOwnStatic = (m: reflect.Property | reflect.Method) => + m.definingType.fqn === typeSpec.fqn; + + const overridableMethods = resolvedAllMethods.filter((m) => !m.static); + const overridableProps = resolvedAllProperties.filter((p) => !p.static); + + this.code.open('def self.jsii_overridable_methods'); + this.code.open('{'); + for (const prop of overridableProps) { + const rubyName = this.rubyName(prop.name); + const isOptional = prop.optional ? 'true' : 'false'; + this.code.line( + `:${rubyName} => { kind: :property, name: "${rubyDq(prop.name)}", is_optional: ${isOptional} },`, + ); + } + for (const method of overridableMethods) { + const rubyName = this.rubyName(method.name); + this.code.line( + `:${rubyName} => { kind: :method, name: "${rubyDq(method.name)}", is_optional: false },`, + ); + } + this.code.close('}'); + this.code.close('end'); + this.code.line(''); + + for (const method of resolvedAllMethods) { + if (!method.static || !isOwnStatic(method)) continue; + + const sigParams = method.parameters + .map((p) => { + const rubyParam = this.rubyName(p.name); + if (p.variadic) return `*${rubyParam}`; + return p.optional ? `${rubyParam} = nil` : rubyParam; + }) + .join(', '); + + const callParams = method.parameters + .map((p) => { + const rubyParam = this.rubyName(p.name); + if (p.variadic) return `*${rubyParam}`; + return rubyParam; + }) + .join(', '); + + this.emitDocs(method, { + params: method.parameters, + returns: method.spec?.returns, + isMethod: true, + apiLocation: { + api: 'member', + fqn: typeSpec.fqn, + memberName: method.name, + }, + }); + this.code.open(`def self.${this.rubyMethodName(method)}(${sigParams})`); + for (const p of method.parameters) { + const rubyParam = this.rubyName(p.name); + this.emitStructCoercion(rubyParam, p.type, { + variadic: p.variadic, + }); + this.emitTypeChecking(rubyParam, p.type, p.name, { + isOptional: p.optional, + isVariadic: p.variadic, + }); + } + this.code.line( + `Jsii::Kernel.instance.call_static("${rubyDq(typeSpec.fqn)}", "${rubyDq(method.name)}", [${callParams}])`, + ); + this.code.close('end'); + this.code.line(''); + } + + for (const prop of resolvedAllProperties) { + if (prop.static && !isOwnStatic(prop)) continue; + + const rubyName = this.rubyPropertyName(prop); + + if (prop.static) { + this.emitDocs(prop, { + propertyType: prop.type, + propertyOptional: prop.optional, + apiLocation: { + api: 'member', + fqn: typeSpec.fqn, + memberName: prop.name, + }, + }); + this.code.open(`def self.${rubyName}()`); + this.code.line( + `Jsii::Kernel.instance.get_static("${rubyDq(typeSpec.fqn)}", "${rubyDq(prop.name)}")`, + ); + this.code.close(`end`); + this.code.line(''); + + if (!prop.immutable) { + this.code.open(`def self.${rubyName}=(value)`); + this.emitStructCoercion('value', prop.type); + this.emitTypeChecking('value', prop.type, prop.name, { + isOptional: prop.optional, + }); + this.code.line( + `Jsii::Kernel.instance.set_static("${rubyDq(typeSpec.fqn)}", "${rubyDq(prop.name)}", value)`, + ); + this.code.close('end'); + this.code.line(''); + } + } else { + this.emitDocs(prop, { + propertyType: prop.type, + propertyOptional: prop.optional, + apiLocation: { + api: 'member', + fqn: typeSpec.fqn, + memberName: prop.name, + }, + }); + this.code.open(`def ${rubyName}()`); + this.code.line(`jsii_get_property("${rubyDq(prop.name)}")`); + this.code.close(`end`); + this.code.line(''); + + if (!prop.immutable) { + this.code.open(`def ${rubyName}=(value)`); + this.emitStructCoercion('value', prop.type); + this.emitTypeChecking('value', prop.type, prop.name, { + isOptional: prop.optional, + }); + this.code.line(`jsii_set_property("${rubyDq(prop.name)}", value)`); + this.code.close('end'); + this.code.line(''); + } + } + } + + for (const method of resolvedAllMethods) { + if (method.static) continue; + + const sigParams = method.parameters + .map((p) => { + const rubyParam = this.rubyName(p.name); + if (p.variadic) return `*${rubyParam}`; + return p.optional ? `${rubyParam} = nil` : rubyParam; + }) + .join(', '); + + const callParams = method.parameters + .map((p) => { + const rubyParam = this.rubyName(p.name); + if (p.variadic) return `*${rubyParam}`; + return rubyParam; + }) + .join(', '); + + this.emitDocs(method, { + params: method.parameters, + returns: method.spec?.returns, + isMethod: true, + apiLocation: { + api: 'member', + fqn: typeSpec.fqn, + memberName: method.name, + }, + }); + this.code.open(`def ${this.rubyMethodName(method)}(${sigParams})`); + for (const p of method.parameters) { + const rubyParam = this.rubyName(p.name); + this.emitStructCoercion(rubyParam, p.type, { + variadic: p.variadic, + }); + this.emitTypeChecking(rubyParam, p.type, p.name, { + isOptional: p.optional, + isVariadic: p.variadic, + }); + } + if (method.async) { + this.code.line( + `jsii_async_call_method("${rubyDq(method.name)}", [${callParams}])`, + ); + } else { + this.code.line( + `jsii_call_method("${rubyDq(method.name)}", [${callParams}])`, + ); + } + this.code.close('end'); + this.code.line(''); + } + + this.code.close('end'); + this.code.line(''); + } + + private rubyFullTypeName(fqn: string): string { + if (fqn === 'any') return 'Object'; + + const segments = fqn.split('.'); + const assemblyName = segments[0]; + const config = + assemblyName === this.assembly.name + ? this.assembly + : this.assembly.dependencyClosure?.[assemblyName]; + + if (!config) { + // Unknown assembly: no acronym configuration is available for it. + const assemblyModule = this.rubyModuleName(assemblyName, []); + return [ + assemblyModule, + ...segments.slice(1).map((p) => this.rubyModuleName(p, [])), + ].join('::'); + } + + // Names in this fqn belong to `config`'s assembly — apply *its* + // acronym configuration, not the pooled closure's. + const acronyms = this.assemblyAcronyms(config); + const assemblyModule = + config.targets?.ruby?.module ?? + this.rubyModuleName(assemblyName, acronyms); + const result = []; + + for (let len = segments.length; len > 0; len--) { + const submoduleFqn = segments.slice(0, len).join('.'); + + if (submoduleFqn === assemblyName) { + result.unshift(assemblyModule); + break; + } + + const submoduleConfig = config.submodules?.[submoduleFqn]; + const explicitModule = submoduleConfig?.targets?.ruby?.module; + + if (explicitModule) { + result.unshift(explicitModule); + break; + } + + result.unshift(this.rubyModuleName(segments[len - 1], acronyms)); + } + + return result.join('::'); + } + + /** + * The fully-qualified Ruby module that encloses a type — its full Ruby + * name minus the final segment (e.g. `JsiiCalc::Composition` for + * `CompositeOperation`). Used to declare an `autoload` on the right + * module and to emit compact `class A::B::C` headers in per-type files. + */ + private rubyEnclosingModule(fqn: string): string { + return this.rubyFullTypeName(fqn).split('::').slice(0, -1).join('::'); + } + + /** + * The `require` path of a type's generated file, relative to `lib/`: + * `/` — e.g. + * `jsii-calc/composition/composite_operation`. Used both as the file + * location and the argument to `autoload`/`register_autoload`, so the two + * always agree. + */ + private rubyRequirePath(fqn: string): string { + const full = this.rubyFullTypeName(fqn).split('::'); + const asm = this.rubyModuleForAssembly(this.assembly.name).split('::'); + const rel = full.slice(asm.length).map((s) => toSnakeCase(s)); + return [this.assembly.name, ...rel].join('/'); + } + + private relativeRubyNamespace(fqn: string): string { + const full = this.rubyFullTypeName(fqn).split('::'); + const asm = this.rubyModuleForAssembly(fqn.split('.')[0]).split('::'); + // Slicing the assembly-module prefix off the full path is only sound if + // the full path actually starts with it. An explicitly-configured + // submodule module that *replaces* the root (e.g. `module: 'Flat'`) + // would silently mis-slice — types would be emitted into the wrong + // namespace. Fail generation with a pointer at the config instead. + if (!asm.every((part, i) => full[i] === part)) { + throw new Error( + `Ruby module for '${fqn}' resolves to '${full.join('::')}', which ` + + `does not live under its assembly's module '${asm.join('::')}'. ` + + `Explicit submodule targets.ruby.module values must extend the ` + + `assembly module (e.g. '${asm.join('::')}::MySubmodule').`, + ); + } + return full.slice(asm.length, -1).join('::'); + } + + /** + * Compute the set of Ruby paths (relative to the assembly module) that + * will be declared as Ruby classes — jsii classes plus jsii interfaces + * marked `datatype: true` (which generate as Ruby classes inheriting from + * `Jsii::Struct`). Used to suppress conflicting `module X; end` + * pre-declarations of namespace fragments that share a Ruby name with a + * class. + */ + private collectClassRubyPaths(): Set { + const paths = new Set(); + for (const type of this.reflectAssembly.allTypes) { + const isClassEmit = + type.isClassType() || (type.isInterfaceType() && type.spec.datatype); + if (!isClassEmit) continue; + + const namespacePart = this.relativeRubyNamespace(type.fqn); + const namePart = this.rubyModuleName(type.name); + paths.add(namespacePart ? `${namespacePart}::${namePart}` : namePart); + } + return paths; + } + + private rubyName(name: string): string { + const snake = toSnakeCase(name); + if (RUBY_RESERVED_NAMES.has(snake)) { + return `_${snake}`; + } + // The `jsii_` prefix is reserved for the runtime's own API surface + // (`jsii_ref`, `jsii_serialize`, `jsii_call_method`, ...) — prefix any + // member that would land in it so generated code can never shadow a + // runtime method, present or future. + if (snake.startsWith('jsii_')) { + return `_${snake}`; + } + // Names starting with a digit are invalid Ruby identifiers. + if (/^\d/.test(snake)) { + return `_${snake}`; + } + return snake; + } + + /** + * Build a Ruby expression that coerces plain Hashes into struct instances + * anywhere a struct can appear inside `ref` — directly, as the element + * type of an array/map (recursively), or as the single unambiguous struct + * arm of a union. Returns `undefined` when `ref` cannot contain a + * coercible struct, so call sites can skip emission entirely. + * + * Coercion matters beyond ergonomics: an uncoerced Hash serializes with + * its literal (snake_case) keys, while the kernel expects the struct's + * camelCase wire form — so a Hash that misses coercion is silent wire + * corruption, not a graceful fallback. + * + * Union rule: coerce only when exactly one arm is a struct AND no other + * arm could legitimately be satisfied by a Hash (a map arm, or an + * any/json arm) — otherwise the Hash is ambiguous and is passed through + * unchanged for the runtime/kernel to interpret. + * + * Block parameters are named `jsii_v` — the `jsii_` prefix is + * reserved (see RUBY_RESERVED_NAMES), so they can never collide with or + * shadow a generated parameter name. + */ + private coercionExpr( + valueExpr: string, + ref: spec.TypeReference | undefined, + depth = 0, + ): string | undefined { + if (!ref) { + return undefined; + } + + if (spec.isNamedTypeReference(ref)) { + if (this.isStructFqn(ref.fqn)) { + return this.structFromHashExpr(valueExpr, ref.fqn); + } + // Single-abstract-method (SAM) interfaces accept a Proc — or the + // TypeScript-object-literal mirror `{ member: proc }` — which the + // runtime wraps into an implementing object (the Ruby analogue of + // javac's SAM conversion; jsii callbacks are always interfaces on the + // wire). coerce_callable re-derives SAM-ness from the module's own + // override table and passes every non-coercible value through + // untouched, so the runtime stays the authority and ordinary type + // checking still reports bad values. + if (this.isSamInterfaceFqn(ref.fqn)) { + return `Jsii::Utils.coerce_callable(${valueExpr}, ::${this.rubyFullTypeName(ref.fqn)})`; + } + return undefined; + } + + if (spec.isCollectionTypeReference(ref)) { + const blockVar = `jsii_v${depth}`; + const inner = this.coercionExpr( + blockVar, + ref.collection.elementtype, + depth + 1, + ); + if (!inner) { + return undefined; + } + if (ref.collection.kind === spec.CollectionKind.Array) { + return `${valueExpr}.is_a?(Array) ? ${valueExpr}.map { |${blockVar}| ${inner} } : ${valueExpr}`; + } + return `${valueExpr}.is_a?(Hash) ? ${valueExpr}.transform_values { |${blockVar}| ${inner} } : ${valueExpr}`; + } + + if (spec.isUnionTypeReference(ref)) { + const structArms = ref.union.types.filter( + (t) => spec.isNamedTypeReference(t) && this.isStructFqn(t.fqn), + ) as spec.NamedTypeReference[]; + const hashAmbiguous = ref.union.types.some( + (t) => + (spec.isCollectionTypeReference(t) && + t.collection.kind === spec.CollectionKind.Map) || + (spec.isPrimitiveTypeReference(t) && + (t.primitive === spec.PrimitiveType.Any || + t.primitive === spec.PrimitiveType.Json)), + ); + if (structArms.length === 1 && !hashAmbiguous) { + return this.structFromHashExpr(valueExpr, structArms[0].fqn); + } + return undefined; + } + + return undefined; + } + + /** + * Ruby expression coercing `valueExpr` into the struct `fqn` when it is a + * Hash, passing anything else through. Keys are symbolized before the + * keyword splat: `**` requires Symbol keys, and JSON-shaped hashes carry + * String keys — without `transform_keys` those raise a bare + * `ArgumentError: wrong number of arguments` instead of constructing the + * struct. (Symbol keys pass through `to_sym` unchanged; unknown keys + * still surface as Ruby's clear "unknown keyword" ArgumentError.) + */ + private structFromHashExpr(valueExpr: string, fqn: string): string { + const structType = this.rubyFullTypeName(fqn); + return `${valueExpr}.is_a?(Hash) ? ::${structType}.new(**${valueExpr}.transform_keys(&:to_sym)) : ${valueExpr}`; + } + + private emitStructCoercion( + variableName: string, + type: RubyTypeRef | undefined, + options: { variadic?: boolean; assignment?: string } = {}, + ): void { + const ref = this.typeRefSpec(type); + + if (options.variadic) { + // For variadic parameters, `ref` is the element type already. + const inner = this.coercionExpr('jsii_v0', ref, 1); + if (inner) { + this.code.line(`${variableName}.map! { |jsii_v0| ${inner} }`); + } + return; + } + + const expr = this.coercionExpr(variableName, ref); + if (!expr) { + if (options.assignment) { + this.code.line(`${options.assignment} = ${variableName}`); + } + return; + } + this.code.line(`${options.assignment ?? variableName} = ${expr}`); + } + + private emitTypeChecking( + variableName: string, + type: RubyTypeRef | undefined, + jsiiName: string, + options: { isOptional?: boolean; isVariadic?: boolean } = {}, + ): void { + if (!this.runtimeTypeChecking) { + return; + } + + // Normalize: initializer parameters carry raw spec type refs (no + // `.spec`); reflect members wrap theirs. Reading `.spec` + // unconditionally made every constructor check validate against + // `{primitive: 'any'}` — i.e. check nothing. + const refSpec = this.typeRefSpec(type); + + if (options.isVariadic) { + this.code.open(`${variableName}.each_with_index do |item, index|`); + this.code.line( + `Jsii::Type.check_type(item, ${rubyJsonLiteral( + refSpec, + )}, "${rubyDq(jsiiName)}[#{index}]")`, + ); + this.code.close(`end`); + } else { + this.code.line( + `Jsii::Type.check_type(${variableName}, ${rubyJsonLiteral( + refSpec, + )}, "${rubyDq(jsiiName)}")${options.isOptional ? ` unless ${variableName}.nil?` : ''}`, + ); + } + } + + /** + * Emit-name for a property, accounting for the JSII `const: true` flag. + * Const properties take an UPPER_SNAKE_CASE form (`maybeList` → `MAYBE_LIST`, + * `PROPERTY` stays `PROPERTY`) — both idiomatic for Ruby constants and + * distinct from any sibling snake_case property's lowercased name. + * This matches Python's `toPythonPropertyName(name, constant=true)` which + * uppercases the snake_case form for the same reason. + * + * Ruby parses `Foo.PROPERTY` and `Foo.property` as distinct method calls, + * so both can coexist on the same class without ambiguity. + */ + private rubyPropertyName(prop: { name: string; const?: boolean }): string { + if (prop.const) return this.rubyConstName(prop.name); + return this.rubyName(prop.name); + } + + private rubyMethodName(method: { name: string }): string { + return this.rubyName(method.name); + } + + /** + * Filter a member list to resolve Ruby-name collisions. When two members + * map to the same Ruby identifier, drop deprecated members; if exactly + * one non-deprecated member survives, use it. Throws if all colliding + * members are deprecated, or if more than one non-deprecated member + * remains (a generator bug — these cases shouldn't reach this point). + * + * Mirrors Python's `prepareMembers`. See + * https://github.com/aws/jsii/issues/2508 for the motivating fixture. + */ + /** + * Resolve *cross-category* Ruby-name collisions: a property and a method + * (merged onto one type from different interfaces or across the + * hierarchy) that map to the same Ruby identifier would otherwise emit + * two `def foo` — last definition silently wins. Runs after the + * per-category {@link dedupByRubyName} passes, with the same policy: + * deprecated members lose to non-deprecated ones; ambiguity throws. + * + * Statics and instance members live in different Ruby namespaces + * (`def self.foo` vs `def foo`), so collisions are only checked within + * the same staticness. + */ + private dedupCrossCategory

( + props: P[], + methods: M[], + propRubyName: (p: P) => string, + methodRubyName: (m: M) => string, + fqn: string, + ): { props: P[]; methods: M[] } { + const buckets = new Map< + string, + Array<{ member: P | M; isProp: boolean }> + >(); + const add = (member: P | M, isProp: boolean, name: string) => { + const key = `${member.static ? 'static' : 'instance'}:${name}`; + const bucket = buckets.get(key) ?? []; + bucket.push({ member, isProp }); + buckets.set(key, bucket); + }; + for (const p of props) add(p, true, propRubyName(p)); + for (const m of methods) add(m, false, methodRubyName(m)); + + const dropped = new Set(); + for (const [key, bucket] of buckets) { + if (bucket.length === 1) { + continue; + } + const rubyKey = key.split(':')[1]; + const nonDeprecated = bucket.filter((e) => !isDeprecated(e.member)); + if (nonDeprecated.length === 0) { + throw new Error( + `All members mapping to Ruby name '${rubyKey}' on ${fqn} are ` + + `deprecated; cannot pick a winner. jsii names: ${bucket + .map((e) => `'${e.member.name}'`) + .join(', ')}`, + ); + } + if (nonDeprecated.length > 1) { + throw new Error( + `A property and a method on ${fqn} both map to Ruby name ` + + `'${rubyKey}': ${nonDeprecated + .map( + (e) => `${e.isProp ? 'property' : 'method'} '${e.member.name}'`, + ) + .join( + ', ', + )}. Mark all but one deprecated (or rename) to disambiguate.`, + ); + } + for (const e of bucket) { + if (e !== nonDeprecated[0]) { + dropped.add(e.member); + } + } + } + + return { + props: props.filter((p) => !dropped.has(p)), + methods: methods.filter((m) => !dropped.has(m)), + }; + } + + private dedupByRubyName( + members: readonly T[], + rubyName: (m: T) => string, + fqn: string, + ): T[] { + const byName = new Map(); + for (const m of members) { + const key = rubyName(m); + const bucket = byName.get(key) ?? []; + bucket.push(m); + byName.set(key, bucket); + } + + const out: T[] = []; + for (const [rubyKey, bucket] of byName) { + if (bucket.length === 1) { + out.push(bucket[0]); + continue; + } + const nonDeprecated = bucket.filter((m) => !isDeprecated(m)); + if (nonDeprecated.length === 0) { + throw new Error( + `All members mapping to Ruby name '${rubyKey}' on ${fqn} are ` + + `deprecated; cannot pick a winner. jsii names: ${bucket + .map((m) => `'${m.name}'`) + .join(', ')}`, + ); + } + if (nonDeprecated.length > 1) { + throw new Error( + `Multiple non-deprecated members map to Ruby name '${rubyKey}' ` + + `on ${fqn}: ${nonDeprecated + .map((m) => `'${m.name}'`) + .join( + ', ', + )}. Mark all but one deprecated (or rename) to disambiguate.`, + ); + } + out.push(nonDeprecated[0]); + } + return out; + } + + private rubyModuleForAssembly(name: string): string { + if (name === this.assembly.name) { + return this.assembly.targets?.ruby?.module ?? this.rubyModuleName(name); + } + const depInfo = this.assembly.dependencyClosure?.[name]; + if (depInfo) { + return ( + depInfo.targets?.ruby?.module ?? + this.rubyModuleName(name, this.assemblyAcronyms(depInfo)) + ); + } + return this.rubyModuleName(name, []); + } + + /** + * The acronym list configured by a specific assembly + * (`targets.ruby.acronyms`). Acronyms are deliberately scoped to the + * assembly that declared them: a dependency capitalizing `RAM` must not + * rewrite an unrelated `RamUsage` type in the consuming assembly (or in + * a sibling dependency). + */ + private assemblyAcronyms( + config: { targets?: spec.AssemblyTargets } | undefined, + ): string[] { + return (config?.targets?.ruby?.acronyms ?? []).filter( + (a: unknown): a is string => typeof a === 'string' && a.length > 0, + ); + } + + private rubyModuleName(name: string, acronyms?: string[]): string { + // Default to the acronyms of the assembly being generated; callers + // converting names that belong to a *dependency* pass that assembly's + // own list (see rubyFullTypeName / rubyModuleForAssembly). + acronyms ??= this.assemblyAcronyms(this.assembly); + + // Handle scoped packages: @scope/package -> Scope::Package + if (name.startsWith('@')) { + const parts = name.slice(1).split('/'); + return parts.map((p) => this.rubyModuleName(p, acronyms)).join('::'); + } + + // Handle hyphens: jsii-calc -> JsiiCalc + if (name.includes('-')) { + const parts = name.split('-'); + return parts.map((p) => this.rubyModuleName(p, acronyms)).join(''); + } + + const sanitized = name.replace(/[^a-zA-Z0-9_]/g, ''); + let pascal = + sanitized.charAt(0) === sanitized.charAt(0).toUpperCase() + ? sanitized + : toPascalCase(sanitized); + + for (const acronym of acronyms) { + // Find the acronym case-insensitively. A match is only considered a valid + // word boundary if it starts with a capital letter and is followed by either + // another capital letter, a digit, an 's' (for plurals), or the end of the string. + // The acronym is config-supplied text, not a pattern — escape it. + const regex = new RegExp(`(${escapeRegExp(acronym)})`, 'ig'); + pascal = pascal.replace(regex, (match, _p1, offset) => { + if (match[0] !== match[0].toUpperCase()) return match; + + const nextChar = pascal[offset + match.length]; + if (nextChar) { + // Must be uppercase, digit, or 's' followed by uppercase, digit, or end of string + const isValid = + /^[A-Z0-9]$/.test(nextChar) || + (nextChar === 's' && + (!pascal[offset + match.length + 1] || + /^[A-Z0-9]$/.test(pascal[offset + match.length + 1]))); + if (!isValid) return match; + } + + return acronym; + }); + } + + // Ruby constants must start with an uppercase letter. npm allows + // package names like `3d-tools` (and leading underscores), which would + // otherwise produce invalid constants like `3dTools`. Prefix with `V_`, + // mirroring rubyConstName's treatment of digit-leading enum members. + if (!/^[A-Z]/.test(pascal)) { + pascal = `V_${pascal}`; + } + + return pascal; + } + + private rubyConstName(name: string): string { + const constName = toSnakeCase(name) + .toUpperCase() + .replace(/[^A-Z0-9_]/g, '_'); + if (/^[0-9]/.test(constName)) { + return `V_${constName}`; + } + return constName; + } + + private async generateGemspec(outdir: string) { + const assembly = this.reflectAssembly; + const assemblySpec = assembly.spec; + const gemName = rubyGemName(assemblySpec); + const gemspecPath = path.join(outdir, `${gemName}.gemspec`); + await fs.mkdir(outdir, { recursive: true }); + + // author, license, description and homepage are all required fields of + // a jsii assembly, so they can be emitted unconditionally; guards below + // are belt-and-braces for hand-crafted assemblies. + const gemspecContent = [ + `Gem::Specification.new do |s|`, + ` s.name = '${rubySq(gemName)}'`, + ` s.version = '${rubySq(toReleaseVersion(assembly.version, TargetName.RUBY))}'`, + ` s.summary = 'Ruby bindings for ${rubySq(assembly.name)}'`, + ]; + if (assemblySpec.description) { + gemspecContent.push( + ` s.description = '${rubySq(assemblySpec.description)}'`, + ); + } + gemspecContent.push( + ` s.authors = ['${rubySq(assemblySpec.author?.name ?? 'JSII Generator')}']`, + ); + if (assemblySpec.license) { + gemspecContent.push( + ` s.license = '${rubySq(assemblySpec.license)}'`, + ); + } + if (assemblySpec.homepage) { + gemspecContent.push( + ` s.homepage = '${rubySq(assemblySpec.homepage)}'`, + ); + } + gemspecContent.push( + ` s.files = Dir["lib/**/*"] + Dir["sig/**/*"]`, + ` s.required_ruby_version = '>= 3.3.0'`, + ` s.add_dependency 'jsii-ruby-runtime', ${toRubyVersionRange(`^${VERSION}`)}`, + ` s.add_dependency 'base64', '~> 0.2'`, + ); + + if (this.assembly.dependencies) { + for (const [depName, version] of Object.entries( + this.assembly.dependencies, + )) { + const depInfo = this.assembly.dependencyClosure?.[depName]; + const depGem = depInfo?.targets?.ruby?.gem as string | undefined; + if (depGem) { + gemspecContent.push( + ` s.add_dependency '${rubySq(depGem)}', ${toRubyVersionRange(version)}`, + ); + } + } + } + + gemspecContent.push(`end`); + + await fs.writeFile(gemspecPath, `${gemspecContent.join('\n')}\n`, 'utf-8'); + } + + /** + * Emit `sig/.rbs` — RBS type signatures mirroring the generated + * Ruby, so Steep/TypeProf users get static checking and editor completion. + * Uses fully-qualified declaration headers (`class A::B::C`) with empty + * namespace-module predeclarations, which keeps emission order-independent + * (RBS resolves a file as a whole). Names come from the same mappers the + * `.rb` emission uses, so signatures line up with the real methods. + */ + private async generateRbs(outdir: string, sortedTypes: reflect.Type[]) { + const assembly = this.reflectAssembly; + const lines: string[] = []; + + // Ruby paths that are emitted as classes (jsii classes + datatype + // interfaces) — we must NOT also predeclare them as namespace modules. + const classPaths = new Set(); + for (const type of sortedTypes) { + if ( + type.isClassType() || + (type.isInterfaceType() && type.spec.datatype) + ) { + classPaths.add(this.rubyFullTypeName(type.fqn)); + } + } + + // Predeclare every pure-namespace module fragment (every fqn prefix that + // isn't itself a class path). + const namespaces = new Set(); + for (const type of sortedTypes) { + const parts = this.rubyFullTypeName(type.fqn).split('::'); + let current = ''; + for (let i = 0; i < parts.length - 1; i++) { + current = current ? `${current}::${parts[i]}` : parts[i]; + if (!classPaths.has(current)) { + namespaces.add(current); + } + } + } + for (const ns of Array.from(namespaces).sort( + (a, b) => a.split('::').length - b.split('::').length, + )) { + lines.push(`module ${ns} end`); + } + if (namespaces.size > 0) { + lines.push(''); + } + + for (const type of sortedTypes) { + if (type.isEnumType()) { + this.emitRbsEnum(type, lines); + } else if (type.isInterfaceType()) { + this.emitRbsInterface(type, lines); + } else if (type.isClassType()) { + this.emitRbsClass(type, lines); + } + } + + const sigPath = path.join(outdir, 'sig', `${assembly.name}.rbs`); + await fs.mkdir(path.dirname(sigPath), { recursive: true }); + await fs.writeFile(sigPath, `${lines.join('\n')}\n`, 'utf-8'); + } + + /** RBS parameter list for a callable's parameters. */ + private rbsParams(params: readonly any[]): string { + return params + .map((p) => { + const name = this.rubyName(p.name); + if (p.variadic) { + return `*${this.rbsParamTypeBare(this.typeRefSpec(p.type))} ${name}`; + } + const t = this.rbsParamType(this.typeRefSpec(p.type), p.optional); + return p.optional ? `?${t} ${name}` : `${t} ${name}`; + }) + .join(', '); + } + + /** RBS return type for a method (`void` when it declares no return). */ + private rbsReturn(method: any): string { + const ret = method.spec?.returns; + return ret?.type + ? this.rbsType(this.typeRefSpec(ret.type), ret.optional) + : 'void'; + } + + private emitRbsEnum(typeSpec: reflect.EnumType, lines: string[]): void { + const members = this.dedupByRubyName( + typeSpec.members, + (m) => this.rubyConstName(m.name), + typeSpec.fqn, + ); + lines.push(`module ${this.rubyFullTypeName(typeSpec.fqn)}`); + for (const m of members) { + lines.push(` ${this.rubyConstName(m.name)}: ::Jsii::Enum`); + } + lines.push('end', ''); + } + + private emitRbsInterface( + typeSpec: reflect.InterfaceType, + lines: string[], + ): void { + const { props, methods } = this.dedupCrossCategory( + this.dedupByRubyName( + typeSpec.allProperties, + (p) => this.rubyName(p.name), + typeSpec.fqn, + ), + this.dedupByRubyName( + typeSpec.allMethods, + (m) => this.rubyName(m.name), + typeSpec.fqn, + ), + (p) => this.rubyName(p.name), + (m) => this.rubyName(m.name), + typeSpec.fqn, + ); + const full = this.rubyFullTypeName(typeSpec.fqn); + + if (typeSpec.datatype) { + // Struct → value class with a kwargs constructor + readers. + const bases = typeSpec.spec.interfaces ?? []; + const base = + bases.length > 0 + ? `::${this.rubyFullTypeName(bases[0])}` + : '::Jsii::Struct'; + lines.push(`class ${full} < ${base}`); + const kwargs = props + .map((p) => { + // Constructor kwargs are input positions too: nested struct values + // may be given as hashes (coerced at serialization). + const t = this.rbsParamType(this.typeRefSpec(p.type), p.optional); + return p.optional + ? `?${this.rubyName(p.name)}: ${t}` + : `${this.rubyName(p.name)}: ${t}`; + }) + .join(', '); + lines.push(` def initialize: (${kwargs}) -> void`); + for (const p of props) { + lines.push( + ` attr_reader ${this.rubyName(p.name)}: ${this.rbsType(this.typeRefSpec(p.type), p.optional)}`, + ); + } + lines.push('end', ''); + return; + } + + // Behavioral interface → module of method/property signatures. + lines.push(`module ${full}`); + for (const p of props) { + const t = this.rbsType(this.typeRefSpec(p.type), p.optional); + lines.push(` attr_reader ${this.rubyName(p.name)}: ${t}`); + if (!p.immutable) { + lines.push(` attr_writer ${this.rubyName(p.name)}: ${t}`); + } + } + for (const m of methods) { + lines.push( + ` def ${this.rubyName(m.name)}: (${this.rbsParams(m.parameters)}) -> ${this.rbsReturn(m)}`, + ); + } + lines.push('end', ''); + } + + private emitRbsClass(typeSpec: reflect.ClassType, lines: string[]): void { + const { props, methods } = this.dedupCrossCategory( + this.dedupByRubyName( + typeSpec.allProperties, + (p) => this.rubyPropertyName(p), + typeSpec.fqn, + ), + this.dedupByRubyName( + typeSpec.allMethods, + (m) => this.rubyMethodName(m), + typeSpec.fqn, + ), + (p) => this.rubyPropertyName(p), + (m) => this.rubyMethodName(m), + typeSpec.fqn, + ); + const full = this.rubyFullTypeName(typeSpec.fqn); + const base = typeSpec.spec.base + ? `::${this.rubyFullTypeName(typeSpec.spec.base)}` + : '::Jsii::Object'; + + lines.push(`class ${full} < ${base}`); + for (const iface of typeSpec.spec.interfaces ?? []) { + lines.push(` include ::${this.rubyFullTypeName(iface)}`); + } + + const init = typeSpec.spec.initializer; + if (init && init.parameters && init.parameters.length > 0) { + lines.push( + ` def initialize: (${this.rbsParams(init.parameters)}) -> void`, + ); + } else if (init) { + lines.push(' def initialize: () -> void'); + } + + for (const p of props) { + const t = this.rbsType(this.typeRefSpec(p.type), p.optional); + if (p.static) { + // Statics (incl. const props) are generated as singleton getter/ + // setter methods, not Ruby attributes — emit `def self.` sigs. + const name = this.rubyPropertyName(p); + lines.push(` def self.${name}: () -> ${t}`); + if (!p.immutable) { + lines.push(` def self.${name}=: (${t}) -> ${t}`); + } + continue; + } + lines.push(` attr_reader ${this.rubyName(p.name)}: ${t}`); + if (!p.immutable) { + lines.push(` attr_writer ${this.rubyName(p.name)}: ${t}`); + } + } + for (const m of methods) { + const recv = m.static ? 'self.' : ''; + lines.push( + ` def ${recv}${this.rubyMethodName(m)}: (${this.rbsParams(m.parameters)}) -> ${this.rbsReturn(m)}`, + ); + } + lines.push('end', ''); + } + + protected getAssemblyOutputDir(_mod: spec.Assembly) { + return path.join('lib', path.dirname(_mod.name)).replace(/\\/g, '/'); + } + + protected onBeginInterface(_ifc: spec.InterfaceType) {} // eslint-disable-line @typescript-eslint/no-empty-function + protected onEndInterface(_ifc: spec.InterfaceType) {} // eslint-disable-line @typescript-eslint/no-empty-function + protected onInterfaceMethod(_ifc: spec.InterfaceType, _method: spec.Method) {} // eslint-disable-line @typescript-eslint/no-empty-function + protected onInterfaceMethodOverload( + _ifc: spec.InterfaceType, + _overload: spec.Method, + _originalMethod: spec.Method, + ) {} // eslint-disable-line @typescript-eslint/no-empty-function + protected onInterfaceProperty( + _ifc: spec.InterfaceType, + _prop: spec.Property, + ) {} // eslint-disable-line @typescript-eslint/no-empty-function + protected onProperty(_cls: spec.ClassType, _prop: spec.Property) {} // eslint-disable-line @typescript-eslint/no-empty-function + protected onStaticProperty(_cls: spec.ClassType, _prop: spec.Property) {} // eslint-disable-line @typescript-eslint/no-empty-function + protected onUnionProperty( + _cls: spec.ClassType, + _prop: spec.Property, + _union: spec.UnionTypeReference, + ) {} // eslint-disable-line @typescript-eslint/no-empty-function + protected onMethod(_cls: spec.ClassType, _method: spec.Method) {} // eslint-disable-line @typescript-eslint/no-empty-function + protected onMethodOverload( + _cls: spec.ClassType, + _overload: spec.Method, + _originalMethod: spec.Method, + ) {} // eslint-disable-line @typescript-eslint/no-empty-function + protected onStaticMethod(_cls: spec.ClassType, _method: spec.Method) {} // eslint-disable-line @typescript-eslint/no-empty-function + protected onStaticMethodOverload( + _cls: spec.ClassType, + _overload: spec.Method, + _originalMethod: spec.Method, + ) {} // eslint-disable-line @typescript-eslint/no-empty-function +} + +export default RubyTarget; diff --git a/packages/jsii-pacmak/lib/targets/version-utils.ts b/packages/jsii-pacmak/lib/targets/version-utils.ts index 76e2dee47a..474f5e003b 100644 --- a/packages/jsii-pacmak/lib/targets/version-utils.ts +++ b/packages/jsii-pacmak/lib/targets/version-utils.ts @@ -68,6 +68,38 @@ export function toPythonVersionRange(semverRange: string): string { .join(', '); } +/** + * Converts a SemVer range expression to a Ruby gemspec compatible version + * constraint expression. + * + * @param semverRange the SemVer range expression to convert. + */ +export function toRubyVersionRange(semverRange: string): string { + const range = new Range(semverRange); + if (range.set.length > 1) { + throw new Error( + `RubyGems does not support OR (||) requirements natively in a single dependency. Unsupported/unrepresentable constraint: ${semverRange}`, + ); + } + return range.set[0] + .map((comp) => { + const versionId = toReleaseVersion( + comp.semver.raw?.replace(/-0$/, '') ?? '0.0.0', + TargetName.RUBY, + ); + // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check + switch (comp.operator) { + case '': + return comp.value === '' ? "'>= 0.0.0'" : `'= ${versionId}'`; + case '=': + return `'= ${versionId}'`; + default: + return `'${comp.operator} ${versionId}'`; + } + }) + .join(', '); +} + /** * Converts an original version number from the NPM convention to the target * language's convention for expressing the same. For versions that do not @@ -168,6 +200,118 @@ export function toReleaseVersion( return version.build.length > 0 ? `${baseVersion}.${prereleaseVersion}+${version.build.join('.')}` : `${baseVersion}.${prereleaseVersion}`; + case TargetName.RUBY: + const baseRuby = `${version.major}.${version.minor}.${version.patch}`; + + // Fallback for purely numeric prerelease (e.g. 0.0.0-1234) + if ( + version.prerelease.length > 0 && + version.prerelease.every( + (p) => typeof p === 'number' || !Number.isNaN(Number(p)), + ) + ) { + return `${baseRuby}.pre.${version.prerelease.join('.')}`; + } + + const rubyReleaseLabels: Record = { + alpha: 'alpha', + beta: 'beta', + rc: 'rc', + post: 'post', + dev: 'dev', + pre: 'pre', + }; + + const rubyValidationErrors: string[] = []; + + version.prerelease.forEach((elem, idx, arr) => { + const next: string | number | undefined = arr[idx + 1]; + if (typeof elem === 'string') { + if (!Object.keys(rubyReleaseLabels).includes(elem)) { + rubyValidationErrors.push( + `Label ${elem} is not one of ${Object.keys(rubyReleaseLabels).join(',')}`, + ); + } + if ( + next === undefined || + !Number.isSafeInteger(next) || + (next as number) <= 0 + ) { + rubyValidationErrors.push( + `Label ${elem} must be followed by a positive integer`, + ); + } + } + }); + + const rubyPostIdx = version.prerelease.findIndex( + (v) => v.toString() === 'post', + ); + const rubyDevIdx = version.prerelease.findIndex((v) => + ['dev', 'pre'].includes(v.toString()), + ); + const rubyPreReleaseIdx = version.prerelease.findIndex((v) => + ['alpha', 'beta', 'rc'].includes(v.toString()), + ); + + const unconsumed = version.prerelease.filter((_, idx) => { + if ( + rubyPreReleaseIdx > -1 && + (idx === rubyPreReleaseIdx || idx === rubyPreReleaseIdx + 1) + ) { + return false; + } + if ( + rubyPostIdx > -1 && + (idx === rubyPostIdx || idx === rubyPostIdx + 1) + ) { + return false; + } + if (rubyDevIdx > -1 && (idx === rubyDevIdx || idx === rubyDevIdx + 1)) { + return false; + } + return true; + }); + + if (unconsumed.some((v) => typeof v === 'string')) { + rubyValidationErrors.push( + `Contains multiple or unmappable prerelease labels: ${inspect(version.prerelease)}`, + ); + } + + if (rubyValidationErrors.length > 0) { + throw new Error( + `Unable to map prerelease identifier (in: ${assemblyVersion}) components to ruby: ${inspect( + version.prerelease, + )}. The format should be 'X.Y.Z-[label.sequence][.post.sequence][.(dev|pre).sequence]', where sequence is a positive integer and label is one of ${inspect( + Object.keys(rubyReleaseLabels), + )}. Validation errors encountered: ${rubyValidationErrors.join(', ')}`, + ); + } + + const rubyPrereleaseVersion = [ + rubyPreReleaseIdx > -1 + ? `${rubyReleaseLabels[version.prerelease[rubyPreReleaseIdx]]}.${ + version.prerelease[rubyPreReleaseIdx + 1] ?? 0 + }` + : undefined, + rubyPostIdx > -1 + ? `post.${version.prerelease[rubyPostIdx + 1] ?? 0}` + : undefined, + rubyDevIdx > -1 + ? `${version.prerelease[rubyDevIdx]}.${version.prerelease[rubyDevIdx + 1] ?? 0}` + : undefined, + ] + .filter((v) => v) + .join('.'); + + if (rubyPrereleaseVersion) { + return `${baseRuby}.${rubyPrereleaseVersion}`; + } + + throw new Error( + `Unable to map prerelease identifier (in: ${assemblyVersion}) components to ruby. The format should be 'X.Y.Z-[label.sequence][.post.sequence][.(dev|pre).sequence]'.`, + ); case TargetName.DOTNET: case TargetName.GO: case TargetName.JAVA: diff --git a/packages/jsii-pacmak/test/generated-code/__snapshots__/target-ruby.test.js.snap b/packages/jsii-pacmak/test/generated-code/__snapshots__/target-ruby.test.js.snap new file mode 100644 index 0000000000..81e9df4385 --- /dev/null +++ b/packages/jsii-pacmak/test/generated-code/__snapshots__/target-ruby.test.js.snap @@ -0,0 +1,23988 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Generated code for "@scope/jsii-calc-base": / 1`] = ` + + ┗━ 📁 ruby + ┣━ 📁 lib + ┃ ┗━ 📁 @scope + ┃ ┣━ 📁 jsii-calc-base + ┃ ┃ ┣━ 📄 _readme.rb + ┃ ┃ ┣━ 📄 base_props.rb + ┃ ┃ ┣━ 📄 base.rb + ┃ ┃ ┣━ 📄 i_base_interface.rb + ┃ ┃ ┗━ 📄 static_consumer.rb + ┃ ┣━ 📄 jsii-calc-base.rb + ┃ ┗━ 📄 jsii-calc-base@0.0.0.jsii.tgz + ┣━ 📄 LICENSE + ┣━ 📄 NOTICE + ┣━ 📄 scope-jsii-calc-base.gemspec + ┗━ 📁 sig + ┗━ 📁 @scope + ┗━ 📄 jsii-calc-base.rbs +`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/LICENSE 1`] = ` + + 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 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. +`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/NOTICE 1`] = ` +jsii +Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/lib/@scope/jsii-calc-base.rb 1`] = ` +require 'jsii' +require 'json' +require 'base64' + +require '@scope/jsii-calc-base-of-base' + +module Scope; end +module Scope::JsiiCalcBaseOfBase; end +module Scope; end +module Scope::JsiiCalcBase; end +module Scope::JsiiCalcBase + Jsii::Assembly.load('@scope/jsii-calc-base', '0.0.0', File.expand_path('jsii-calc-base@0.0.0.jsii.tgz', __dir__)) + + + Scope::JsiiCalcBase.autoload(:Base, '@scope/jsii-calc-base/base') + Jsii::Object.register_autoload("@scope/jsii-calc-base.Base", '@scope/jsii-calc-base/base') + Scope::JsiiCalcBase.autoload(:BaseProps, '@scope/jsii-calc-base/base_props') + Jsii::Object.register_autoload("@scope/jsii-calc-base.BaseProps", '@scope/jsii-calc-base/base_props') + Scope::JsiiCalcBase.autoload(:IBaseInterface, '@scope/jsii-calc-base/i_base_interface') + Jsii::Object.register_autoload("@scope/jsii-calc-base.IBaseInterface", '@scope/jsii-calc-base/i_base_interface') + Scope::JsiiCalcBase.autoload(:StaticConsumer, '@scope/jsii-calc-base/static_consumer') + Jsii::Object.register_autoload("@scope/jsii-calc-base.StaticConsumer", '@scope/jsii-calc-base/static_consumer') +end + +`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/lib/@scope/jsii-calc-base/_readme.rb 1`] = ` +# # @scope/jsii-calc-base +module Scope::JsiiCalcBase; end + +`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/lib/@scope/jsii-calc-base/base.rb 1`] = ` +require 'jsii' + +# A base class. +class Scope::JsiiCalcBase::Base < Jsii::Object + self.jsii_fqn = "@scope/jsii-calc-base.Base" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-base.Base", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :type_name => { kind: :method, name: "typeName", is_optional: false }, + } + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/lib/@scope/jsii-calc-base/base_props.rb 1`] = ` +require 'jsii' + +# @note Default: +# @deprecated +class Scope::JsiiCalcBase::BaseProps < ::Scope::JsiiCalcBaseOfBase::VeryBaseProps + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-base.BaseProps", self) + + # @param foo [Scope::JsiiCalcBaseOfBase::Very] + # @param bar [String] + def initialize(foo:, bar:) + @foo = foo + @bar = bar + end + + # @return [Scope::JsiiCalcBaseOfBase::Very] + # @note Default: + # @deprecated + attr_reader :foo + # @return [String] + # @note Default: + # @deprecated + attr_reader :bar + + def self.jsii_properties + { + :foo => "foo", + :bar => "bar", + } + end + + def to_jsii + result = {} + result.merge!(super) + result.merge!({ + "foo" => @foo, + "bar" => @bar, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/lib/@scope/jsii-calc-base/i_base_interface.rb 1`] = ` +require 'jsii' + +# @note Default: +# @deprecated +module Scope::JsiiCalcBase::IBaseInterface + include ::Scope::JsiiCalcBaseOfBase::IVeryBaseInterface + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-base.IBaseInterface", self) + + # @return [void] + # @note Default: + # @deprecated + def foo() + jsii_call_method("foo", []) + end + + # @return [void] + # @note Default: + # @deprecated + def bar() + jsii_call_method("bar", []) + end + + def self.jsii_overridable_methods + { + :foo => { kind: :method, name: "foo", is_optional: false }, + :bar => { kind: :method, name: "bar", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/lib/@scope/jsii-calc-base/static_consumer.rb 1`] = ` +require 'jsii' + +# Hides the transitive dependency of base-of-base. +class Scope::JsiiCalcBase::StaticConsumer < Jsii::Object + self.jsii_fqn = "@scope/jsii-calc-base.StaticConsumer" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-base.StaticConsumer", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + + # @param args [Array] + # @return [void] + # @note Default: + # @deprecated + def self.consume(*args) + Jsii::Kernel.instance.call_static("@scope/jsii-calc-base.StaticConsumer", "consume", [*args]) + end + +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/lib/@scope/jsii-calc-base@0.0.0.jsii.tgz 1`] = `ruby/lib/@scope/jsii-calc-base@0.0.0.jsii.tgz is a tarball`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/scope-jsii-calc-base.gemspec 1`] = ` +Gem::Specification.new do |s| + s.name = 'scope-jsii-calc-base' + s.version = '0.0.0' + s.summary = 'Ruby bindings for @scope/jsii-calc-base' + s.description = 'An example direct dependency for jsii-calc.' + s.authors = ['Amazon Web Services'] + s.license = 'Apache-2.0' + s.homepage = 'https://github.com/aws/jsii' + s.files = Dir["lib/**/*"] + Dir["sig/**/*"] + s.required_ruby_version = '>= 3.3.0' + s.add_dependency 'jsii-ruby-runtime', '< 0.0.1' + s.add_dependency 'base64', '~> 0.2' + s.add_dependency 'scope-jsii-calc-base-of-base', '>= 2.1.1', '< 3.0.0' +end + +`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/sig/@scope/jsii-calc-base.rbs 1`] = ` +module Scope end +module Scope::JsiiCalcBase end + +class Scope::JsiiCalcBase::Base < ::Jsii::Object + def initialize: () -> void + def type_name: () -> untyped +end + +class Scope::JsiiCalcBase::BaseProps < ::Scope::JsiiCalcBaseOfBase::VeryBaseProps + def initialize: (foo: ::Scope::JsiiCalcBaseOfBase::Very, bar: String) -> void + attr_reader foo: ::Scope::JsiiCalcBaseOfBase::Very + attr_reader bar: String +end + +module Scope::JsiiCalcBase::IBaseInterface + def foo: () -> void + def bar: () -> void +end + +class Scope::JsiiCalcBase::StaticConsumer < ::Jsii::Object + def initialize: () -> void + def self.consume: (*untyped args) -> void +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-base": / 1`] = ` + + ┗━ 📁 ruby + ┗━ 📁 lib + ┗━ 📁 @scope + ┗━ 📁 jsii-calc-base + ┣━ 📄 base_props.rb.diff + ┗━ 📄 static_consumer.rb.diff +`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/lib/@scope/jsii-calc-base/base_props.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-base/base_props.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-base/base_props.rb --runtime-type-checking +@@ -7,11 +7,13 @@ + + # @param foo [Scope::JsiiCalcBaseOfBase::Very] + # @param bar [String] + def initialize(foo:, bar:) + @foo = foo ++ Jsii::Type.check_type(@foo, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWJhc2Utb2YtYmFzZS5WZXJ5In0=")), "foo") + @bar = bar ++ Jsii::Type.check_type(@bar, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "bar") + end + + # @return [Scope::JsiiCalcBaseOfBase::Very] + # @note Default: + # @deprecated +`; + +exports[`Generated code for "@scope/jsii-calc-base": /ruby/lib/@scope/jsii-calc-base/static_consumer.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-base/static_consumer.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-base/static_consumer.rb --runtime-type-checking +@@ -17,10 +17,13 @@ + # @param args [Array] + # @return [void] + # @note Default: + # @deprecated + def self.consume(*args) ++ args.each_with_index do |item, index| ++ Jsii::Type.check_type(item, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "args[#{index}]") ++ end + Jsii::Kernel.instance.call_static("@scope/jsii-calc-base.StaticConsumer", "consume", [*args]) + end + + end +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": / 1`] = ` + + ┗━ 📁 ruby + ┣━ 📁 lib + ┃ ┗━ 📁 @scope + ┃ ┣━ 📁 jsii-calc-base-of-base + ┃ ┃ ┣━ 📄 _readme.rb + ┃ ┃ ┣━ 📄 i_very_base_interface.rb + ┃ ┃ ┣━ 📄 static_consumer.rb + ┃ ┃ ┣━ 📄 very_base_props.rb + ┃ ┃ ┗━ 📄 very.rb + ┃ ┣━ 📄 jsii-calc-base-of-base.rb + ┃ ┗━ 📄 jsii-calc-base-of-base@2.1.1.jsii.tgz + ┣━ 📄 LICENSE + ┣━ 📄 NOTICE + ┣━ 📄 scope-jsii-calc-base-of-base.gemspec + ┗━ 📁 sig + ┗━ 📁 @scope + ┗━ 📄 jsii-calc-base-of-base.rbs +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/LICENSE 1`] = ` + + 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 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. +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/NOTICE 1`] = ` +jsii +Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/lib/@scope/jsii-calc-base-of-base.rb 1`] = ` +require 'jsii' +require 'json' +require 'base64' + +module Scope; end +module Scope::JsiiCalcBaseOfBase; end +module Scope::JsiiCalcBaseOfBase + Jsii::Assembly.load('@scope/jsii-calc-base-of-base', '2.1.1', File.expand_path('jsii-calc-base-of-base@2.1.1.jsii.tgz', __dir__)) + + + Scope::JsiiCalcBaseOfBase.autoload(:IVeryBaseInterface, '@scope/jsii-calc-base-of-base/i_very_base_interface') + Jsii::Object.register_autoload("@scope/jsii-calc-base-of-base.IVeryBaseInterface", '@scope/jsii-calc-base-of-base/i_very_base_interface') + Scope::JsiiCalcBaseOfBase.autoload(:StaticConsumer, '@scope/jsii-calc-base-of-base/static_consumer') + Jsii::Object.register_autoload("@scope/jsii-calc-base-of-base.StaticConsumer", '@scope/jsii-calc-base-of-base/static_consumer') + Scope::JsiiCalcBaseOfBase.autoload(:Very, '@scope/jsii-calc-base-of-base/very') + Jsii::Object.register_autoload("@scope/jsii-calc-base-of-base.Very", '@scope/jsii-calc-base-of-base/very') + Scope::JsiiCalcBaseOfBase.autoload(:VeryBaseProps, '@scope/jsii-calc-base-of-base/very_base_props') + Jsii::Object.register_autoload("@scope/jsii-calc-base-of-base.VeryBaseProps", '@scope/jsii-calc-base-of-base/very_base_props') +end + +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/lib/@scope/jsii-calc-base-of-base/_readme.rb 1`] = ` +# # @scope/jsii-calc-base-of-base +module Scope::JsiiCalcBaseOfBase; end + +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/lib/@scope/jsii-calc-base-of-base/i_very_base_interface.rb 1`] = ` +require 'jsii' + +# @note Default: +# @deprecated +module Scope::JsiiCalcBaseOfBase::IVeryBaseInterface + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-base-of-base.IVeryBaseInterface", self) + + # @return [void] + # @note Default: + # @deprecated + def foo() + jsii_call_method("foo", []) + end + + def self.jsii_overridable_methods + { + :foo => { kind: :method, name: "foo", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/lib/@scope/jsii-calc-base-of-base/static_consumer.rb 1`] = ` +require 'jsii' + +# @note Default: +# @deprecated +class Scope::JsiiCalcBaseOfBase::StaticConsumer < Jsii::Object + self.jsii_fqn = "@scope/jsii-calc-base-of-base.StaticConsumer" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-base-of-base.StaticConsumer", self) + + def initialize(*args) + raise NoMethodError, "@scope/jsii-calc-base-of-base.StaticConsumer does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @param _args [Array] + # @return [void] + # @note Default: + # @deprecated + def self.consume(*_args) + Jsii::Kernel.instance.call_static("@scope/jsii-calc-base-of-base.StaticConsumer", "consume", [*_args]) + end + +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/lib/@scope/jsii-calc-base-of-base/very.rb 1`] = ` +require 'jsii' + +# Something here. +class Scope::JsiiCalcBaseOfBase::Very < Jsii::Object + self.jsii_fqn = "@scope/jsii-calc-base-of-base.Very" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-base-of-base.Very", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :hey => { kind: :method, name: "hey", is_optional: false }, + } + end + + # @return [Numeric] + def hey() + jsii_call_method("hey", []) + end + +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/lib/@scope/jsii-calc-base-of-base/very_base_props.rb 1`] = ` +require 'jsii' + +# @note Default: +# @deprecated +class Scope::JsiiCalcBaseOfBase::VeryBaseProps < Jsii::Struct + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-base-of-base.VeryBaseProps", self) + + # @param foo [Scope::JsiiCalcBaseOfBase::Very] + def initialize(foo:) + @foo = foo + end + + # @return [Scope::JsiiCalcBaseOfBase::Very] + # @note Default: + # @deprecated + attr_reader :foo + + def self.jsii_properties + { + :foo => "foo", + } + end + + def to_jsii + result = {} + result.merge!({ + "foo" => @foo, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/lib/@scope/jsii-calc-base-of-base@2.1.1.jsii.tgz 1`] = `ruby/lib/@scope/jsii-calc-base-of-base@2.1.1.jsii.tgz is a tarball`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/scope-jsii-calc-base-of-base.gemspec 1`] = ` +Gem::Specification.new do |s| + s.name = 'scope-jsii-calc-base-of-base' + s.version = '2.1.1' + s.summary = 'Ruby bindings for @scope/jsii-calc-base-of-base' + s.description = 'An example transitive dependency for jsii-calc.' + s.authors = ['Amazon Web Services'] + s.license = 'Apache-2.0' + s.homepage = 'https://github.com/aws/jsii' + s.files = Dir["lib/**/*"] + Dir["sig/**/*"] + s.required_ruby_version = '>= 3.3.0' + s.add_dependency 'jsii-ruby-runtime', '< 0.0.1' + s.add_dependency 'base64', '~> 0.2' +end + +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/sig/@scope/jsii-calc-base-of-base.rbs 1`] = ` +module Scope end +module Scope::JsiiCalcBaseOfBase end + +module Scope::JsiiCalcBaseOfBase::IVeryBaseInterface + def foo: () -> void +end + +class Scope::JsiiCalcBaseOfBase::StaticConsumer < ::Jsii::Object + def self.consume: (*untyped _args) -> void +end + +class Scope::JsiiCalcBaseOfBase::Very < ::Jsii::Object + def initialize: () -> void + def hey: () -> Numeric +end + +class Scope::JsiiCalcBaseOfBase::VeryBaseProps < ::Jsii::Struct + def initialize: (foo: ::Scope::JsiiCalcBaseOfBase::Very) -> void + attr_reader foo: ::Scope::JsiiCalcBaseOfBase::Very +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": / 1`] = ` + + ┗━ 📁 ruby + ┗━ 📁 lib + ┗━ 📁 @scope + ┗━ 📁 jsii-calc-base-of-base + ┣━ 📄 static_consumer.rb.diff + ┗━ 📄 very_base_props.rb.diff +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/lib/@scope/jsii-calc-base-of-base/static_consumer.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-base-of-base/static_consumer.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-base-of-base/static_consumer.rb --runtime-type-checking +@@ -18,10 +18,13 @@ + # @param _args [Array] + # @return [void] + # @note Default: + # @deprecated + def self.consume(*_args) ++ _args.each_with_index do |item, index| ++ Jsii::Type.check_type(item, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "_args[#{index}]") ++ end + Jsii::Kernel.instance.call_static("@scope/jsii-calc-base-of-base.StaticConsumer", "consume", [*_args]) + end + + end +`; + +exports[`Generated code for "@scope/jsii-calc-base-of-base": /ruby/lib/@scope/jsii-calc-base-of-base/very_base_props.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-base-of-base/very_base_props.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-base-of-base/very_base_props.rb --runtime-type-checking +@@ -6,10 +6,11 @@ + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-base-of-base.VeryBaseProps", self) + + # @param foo [Scope::JsiiCalcBaseOfBase::Very] + def initialize(foo:) + @foo = foo ++ Jsii::Type.check_type(@foo, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWJhc2Utb2YtYmFzZS5WZXJ5In0=")), "foo") + end + + # @return [Scope::JsiiCalcBaseOfBase::Very] + # @note Default: + # @deprecated +`; + +exports[`Generated code for "@scope/jsii-calc-lib": / 1`] = ` + + ┗━ 📁 ruby + ┣━ 📁 lib + ┃ ┗━ 📁 @scope + ┃ ┣━ 📁 jsii-calc-lib + ┃ ┃ ┣━ 📄 _readme.rb + ┃ ┃ ┣━ 📄 base_for2647.rb + ┃ ┃ ┣━ 📁 deprecation_removal + ┃ ┃ ┃ ┣━ 📄 i_interface.rb + ┃ ┃ ┃ ┣━ 📄 interface_factory.rb + ┃ ┃ ┃ ┗━ 📄 visible_base_class.rb + ┃ ┃ ┣━ 📄 diamond_left.rb + ┃ ┃ ┣━ 📄 diamond_right.rb + ┃ ┃ ┣━ 📄 enum_from_scoped_module.rb + ┃ ┃ ┣━ 📄 function_with_underscore_argument.rb + ┃ ┃ ┣━ 📄 i_doublable.rb + ┃ ┃ ┣━ 📄 i_friendly.rb + ┃ ┃ ┣━ 📄 i_three_levels_interface.rb + ┃ ┃ ┣━ 📄 my_first_struct.rb + ┃ ┃ ┣━ 📄 number.rb + ┃ ┃ ┣━ 📄 numeric_value.rb + ┃ ┃ ┣━ 📄 operation.rb + ┃ ┃ ┣━ 📄 struct_with_only_optionals.rb + ┃ ┃ ┗━ 📁 submodule + ┃ ┃ ┣━ 📄 _readme.rb + ┃ ┃ ┣━ 📄 class_with_nonpascalcased_name.rb + ┃ ┃ ┣━ 📄 i_reflectable.rb + ┃ ┃ ┣━ 📄 nesting_class.rb + ┃ ┃ ┣━ 📄 reflectable_entry.rb + ┃ ┃ ┗━ 📄 reflector.rb + ┃ ┣━ 📄 jsii-calc-lib.rb + ┃ ┗━ 📄 jsii-calc-lib@0.0.0.jsii.tgz + ┣━ 📄 LICENSE + ┣━ 📄 NOTICE + ┣━ 📄 scope-jsii-calc-lib.gemspec + ┗━ 📁 sig + ┗━ 📁 @scope + ┗━ 📄 jsii-calc-lib.rbs +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/LICENSE 1`] = ` + + 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 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. +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/NOTICE 1`] = ` +jsii +Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib.rb 1`] = ` +require 'jsii' +require 'json' +require 'base64' + +require '@scope/jsii-calc-base' +require '@scope/jsii-calc-base-of-base' + +module Scope; end +module Scope::JsiiCalcBase; end +module Scope::JsiiCalcBaseOfBase; end +module Scope; end +module Scope::JsiiCalcLib; end +module Scope::JsiiCalcLib + Jsii::Assembly.load('@scope/jsii-calc-lib', '0.0.0', File.expand_path('jsii-calc-lib@0.0.0.jsii.tgz', __dir__)) + + module DeprecationRemoval; end + module Submodule; end + + Scope::JsiiCalcLib.autoload(:BaseFor2647, '@scope/jsii-calc-lib/base_for2647') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.BaseFor2647", '@scope/jsii-calc-lib/base_for2647') + Scope::JsiiCalcLib.autoload(:DiamondLeft, '@scope/jsii-calc-lib/diamond_left') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.DiamondLeft", '@scope/jsii-calc-lib/diamond_left') + Scope::JsiiCalcLib.autoload(:DiamondRight, '@scope/jsii-calc-lib/diamond_right') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.DiamondRight", '@scope/jsii-calc-lib/diamond_right') + Scope::JsiiCalcLib.autoload(:EnumFromScopedModule, '@scope/jsii-calc-lib/enum_from_scoped_module') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.EnumFromScopedModule", '@scope/jsii-calc-lib/enum_from_scoped_module') + Scope::JsiiCalcLib.autoload(:FunctionWithUnderscoreArgument, '@scope/jsii-calc-lib/function_with_underscore_argument') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.FunctionWithUnderscoreArgument", '@scope/jsii-calc-lib/function_with_underscore_argument') + Scope::JsiiCalcLib.autoload(:IDoublable, '@scope/jsii-calc-lib/i_doublable') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.IDoublable", '@scope/jsii-calc-lib/i_doublable') + Scope::JsiiCalcLib.autoload(:IFriendly, '@scope/jsii-calc-lib/i_friendly') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.IFriendly", '@scope/jsii-calc-lib/i_friendly') + Scope::JsiiCalcLib.autoload(:IThreeLevelsInterface, '@scope/jsii-calc-lib/i_three_levels_interface') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.IThreeLevelsInterface", '@scope/jsii-calc-lib/i_three_levels_interface') + Scope::JsiiCalcLib.autoload(:MyFirstStruct, '@scope/jsii-calc-lib/my_first_struct') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.MyFirstStruct", '@scope/jsii-calc-lib/my_first_struct') + Scope::JsiiCalcLib.autoload(:NumericValue, '@scope/jsii-calc-lib/numeric_value') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.NumericValue", '@scope/jsii-calc-lib/numeric_value') + Scope::JsiiCalcLib.autoload(:Number, '@scope/jsii-calc-lib/number') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.Number", '@scope/jsii-calc-lib/number') + Scope::JsiiCalcLib.autoload(:Operation, '@scope/jsii-calc-lib/operation') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.Operation", '@scope/jsii-calc-lib/operation') + Scope::JsiiCalcLib.autoload(:StructWithOnlyOptionals, '@scope/jsii-calc-lib/struct_with_only_optionals') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.StructWithOnlyOptionals", '@scope/jsii-calc-lib/struct_with_only_optionals') + Scope::JsiiCalcLib::DeprecationRemoval.autoload(:IInterface, '@scope/jsii-calc-lib/deprecation_removal/i_interface') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.deprecationRemoval.IInterface", '@scope/jsii-calc-lib/deprecation_removal/i_interface') + Scope::JsiiCalcLib::DeprecationRemoval.autoload(:InterfaceFactory, '@scope/jsii-calc-lib/deprecation_removal/interface_factory') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.deprecationRemoval.InterfaceFactory", '@scope/jsii-calc-lib/deprecation_removal/interface_factory') + Scope::JsiiCalcLib::DeprecationRemoval.autoload(:VisibleBaseClass, '@scope/jsii-calc-lib/deprecation_removal/visible_base_class') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.deprecationRemoval.VisibleBaseClass", '@scope/jsii-calc-lib/deprecation_removal/visible_base_class') + Scope::JsiiCalcLib::Submodule.autoload(:ClassWithNONPASCALCASEDName, '@scope/jsii-calc-lib/submodule/class_with_nonpascalcased_name') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.submodule.ClassWithNONPASCALCASEDName", '@scope/jsii-calc-lib/submodule/class_with_nonpascalcased_name') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.submodule.ClassWithNONPASCALCASEDName.SomeType", '@scope/jsii-calc-lib/submodule/class_with_nonpascalcased_name') + Scope::JsiiCalcLib::Submodule.autoload(:IReflectable, '@scope/jsii-calc-lib/submodule/i_reflectable') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.submodule.IReflectable", '@scope/jsii-calc-lib/submodule/i_reflectable') + Scope::JsiiCalcLib::Submodule.autoload(:NestingClass, '@scope/jsii-calc-lib/submodule/nesting_class') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.submodule.NestingClass", '@scope/jsii-calc-lib/submodule/nesting_class') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.submodule.NestingClass.NestedClass", '@scope/jsii-calc-lib/submodule/nesting_class') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.submodule.NestingClass.NestedStruct", '@scope/jsii-calc-lib/submodule/nesting_class') + Scope::JsiiCalcLib::Submodule.autoload(:ReflectableEntry, '@scope/jsii-calc-lib/submodule/reflectable_entry') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.submodule.ReflectableEntry", '@scope/jsii-calc-lib/submodule/reflectable_entry') + Scope::JsiiCalcLib::Submodule.autoload(:Reflector, '@scope/jsii-calc-lib/submodule/reflector') + Jsii::Object.register_autoload("@scope/jsii-calc-lib.submodule.Reflector", '@scope/jsii-calc-lib/submodule/reflector') +end + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/_readme.rb 1`] = ` +# # @scope/jsii-calc-lib +module Scope::JsiiCalcLib; end + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/base_for2647.rb 1`] = ` +require 'jsii' + +# A base class for testing #2647. +# +# The method \`foo\` has a parameter that uses a type +# from a dependent module. Since Go "reimplments" this method, it will also need +# to include an "import" statement for the calc-base module. +# +# @see https://github.com/aws/jsii/issues/2647 +class Scope::JsiiCalcLib::BaseFor2647 < Jsii::Object + self.jsii_fqn = "@scope/jsii-calc-lib.BaseFor2647" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.BaseFor2647", self) + + # @param very [Scope::JsiiCalcBaseOfBase::Very] + def initialize(very) + Jsii::Object.instance_method(:initialize).bind(self).call(very) + end + + def self.jsii_overridable_methods + { + :foo => { kind: :method, name: "foo", is_optional: false }, + } + end + + # @param obj [Scope::JsiiCalcBase::IBaseInterface] + # @return [void] + def foo(obj) + jsii_call_method("foo", [obj]) + end + +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/deprecation_removal/i_interface.rb 1`] = ` +require 'jsii' + +module Scope::JsiiCalcLib::DeprecationRemoval::IInterface + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.deprecationRemoval.IInterface", self) + + # @return [void] + def method() + jsii_call_method("method", []) + end + + def self.jsii_overridable_methods + { + :method => { kind: :method, name: "method", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/deprecation_removal/interface_factory.rb 1`] = ` +require 'jsii' + +class Scope::JsiiCalcLib::DeprecationRemoval::InterfaceFactory < Jsii::Object + self.jsii_fqn = "@scope/jsii-calc-lib.deprecationRemoval.InterfaceFactory" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.deprecationRemoval.InterfaceFactory", self) + + def initialize(*args) + raise NoMethodError, "@scope/jsii-calc-lib.deprecationRemoval.InterfaceFactory does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @return [Scope::JsiiCalcLib::DeprecationRemoval::IInterface] + def self.create() + Jsii::Kernel.instance.call_static("@scope/jsii-calc-lib.deprecationRemoval.InterfaceFactory", "create", []) + end + +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/deprecation_removal/visible_base_class.rb 1`] = ` +require 'jsii' + +class Scope::JsiiCalcLib::DeprecationRemoval::VisibleBaseClass < Jsii::Object + self.jsii_fqn = "@scope/jsii-calc-lib.deprecationRemoval.VisibleBaseClass" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.deprecationRemoval.VisibleBaseClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :property_present => { kind: :property, name: "propertyPresent", is_optional: false }, + } + end + + # @return [Boolean] + def property_present() + jsii_get_property("propertyPresent") + end + +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/diamond_left.rb 1`] = ` +require 'jsii' + +class Scope::JsiiCalcLib::DiamondLeft < Jsii::Struct + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.DiamondLeft", self) + + # @param hoisted_top [String, nil] + # @param left [Numeric, nil] + def initialize(hoisted_top: nil, left: nil) + @hoisted_top = hoisted_top + @left = left + end + + # @return [String, nil] + attr_reader :hoisted_top + # @return [Numeric, nil] + attr_reader :left + + def self.jsii_properties + { + :hoisted_top => "hoistedTop", + :left => "left", + } + end + + def to_jsii + result = {} + result.merge!({ + "hoistedTop" => @hoisted_top, + "left" => @left, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/diamond_right.rb 1`] = ` +require 'jsii' + +class Scope::JsiiCalcLib::DiamondRight < Jsii::Struct + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.DiamondRight", self) + + # @param hoisted_top [String, nil] + # @param right [Boolean, nil] + def initialize(hoisted_top: nil, right: nil) + @hoisted_top = hoisted_top + @right = right + end + + # @return [String, nil] + attr_reader :hoisted_top + # @return [Boolean, nil] + attr_reader :right + + def self.jsii_properties + { + :hoisted_top => "hoistedTop", + :right => "right", + } + end + + def to_jsii + result = {} + result.merge!({ + "hoistedTop" => @hoisted_top, + "right" => @right, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/enum_from_scoped_module.rb 1`] = ` +require 'jsii' + +# Check that enums from \\@scoped packages can be references. +# +# See awslabs/jsii#138 +module Scope::JsiiCalcLib::EnumFromScopedModule + # @note Default: + # @deprecated + VALUE1 = Jsii::Enum.new("@scope/jsii-calc-lib.EnumFromScopedModule", "VALUE1") + # @note Default: + # @deprecated + VALUE2 = Jsii::Enum.new("@scope/jsii-calc-lib.EnumFromScopedModule", "VALUE2") +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/function_with_underscore_argument.rb 1`] = ` +require 'jsii' + +# For Java, test that an identifier that is just a _ is handled. +class Scope::JsiiCalcLib::FunctionWithUnderscoreArgument < Jsii::Object + self.jsii_fqn = "@scope/jsii-calc-lib.FunctionWithUnderscoreArgument" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.FunctionWithUnderscoreArgument", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :foo => { kind: :method, name: "foo", is_optional: false }, + } + end + + # @param _ [String] + # @return [String] + def foo(_) + jsii_call_method("foo", [_]) + end + +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/i_doublable.rb 1`] = ` +require 'jsii' + +# The general contract for a concrete number. +module Scope::JsiiCalcLib::IDoublable + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.IDoublable", self) + + # @return [Numeric] + def double_value() + jsii_get_property("doubleValue") + end + + def self.jsii_overridable_methods + { + :double_value => { kind: :property, name: "doubleValue", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/i_friendly.rb 1`] = ` +require 'jsii' + +# Applies to classes that are considered friendly. +# +# These classes can be greeted with +# a "hello" or "goodbye" blessing and they will respond back in a fun and friendly manner. +module Scope::JsiiCalcLib::IFriendly + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.IFriendly", self) + + # Say hello! + # + # @return [String] + def hello() + jsii_call_method("hello", []) + end + + def self.jsii_overridable_methods + { + :hello => { kind: :method, name: "hello", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/i_three_levels_interface.rb 1`] = ` +require 'jsii' + +# Interface that inherits from packages 2 levels up the tree. +# +# Their presence validates that .NET/Java/jsii-reflect can track all fields +# far enough up the tree. +module Scope::JsiiCalcLib::IThreeLevelsInterface + include ::Scope::JsiiCalcBase::IBaseInterface + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.IThreeLevelsInterface", self) + + # @return [void] + # @note Default: + # @deprecated + def foo() + jsii_call_method("foo", []) + end + + # @return [void] + # @note Default: + # @deprecated + def bar() + jsii_call_method("bar", []) + end + + # @return [void] + def baz() + jsii_call_method("baz", []) + end + + def self.jsii_overridable_methods + { + :foo => { kind: :method, name: "foo", is_optional: false }, + :bar => { kind: :method, name: "bar", is_optional: false }, + :baz => { kind: :method, name: "baz", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/my_first_struct.rb 1`] = ` +require 'jsii' + +# This is the first struct we have created in jsii. +class Scope::JsiiCalcLib::MyFirstStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.MyFirstStruct", self) + + # @param anumber [Numeric] An awesome number value. + # @param astring [String] A string value. + # @param first_optional [Array, nil] + def initialize(anumber:, astring:, first_optional: nil) + @anumber = anumber + @astring = astring + @first_optional = first_optional + end + + # An awesome number value. + # + # @return [Numeric] + attr_reader :anumber + # A string value. + # + # @return [String] + attr_reader :astring + # @return [Array, nil] + attr_reader :first_optional + + def self.jsii_properties + { + :anumber => "anumber", + :astring => "astring", + :first_optional => "firstOptional", + } + end + + def to_jsii + result = {} + result.merge!({ + "anumber" => @anumber, + "astring" => @astring, + "firstOptional" => @first_optional, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/number.rb 1`] = ` +require 'jsii' + +# Represents a concrete number. +class Scope::JsiiCalcLib::Number < ::Scope::JsiiCalcLib::NumericValue + include ::Scope::JsiiCalcLib::IDoublable + self.jsii_fqn = "@scope/jsii-calc-lib.Number" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.Number", self) + + # Creates a Number object. + # + # @param value [Numeric] The number. + def initialize(value) + Jsii::Object.instance_method(:initialize).bind(self).call(value) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :double_value => { kind: :property, name: "doubleValue", is_optional: false }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + } + end + + # The number. + # + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # The number multiplied by 2. + # + # @return [Numeric] + def double_value() + jsii_get_property("doubleValue") + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # String representation of the value. + # + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/numeric_value.rb 1`] = ` +require 'jsii' + +# Abstract class which represents a numeric value. +class Scope::JsiiCalcLib::NumericValue < ::Scope::JsiiCalcBase::Base + self.jsii_fqn = "@scope/jsii-calc-lib.NumericValue" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.NumericValue", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + } + end + + # The value. + # + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # String representation of the value. + # + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/operation.rb 1`] = ` +require 'jsii' + +# Represents an operation on values. +class Scope::JsiiCalcLib::Operation < ::Scope::JsiiCalcLib::NumericValue + self.jsii_fqn = "@scope/jsii-calc-lib.Operation" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.Operation", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + } + end + + # The value. + # + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # String representation of the value. + # + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/struct_with_only_optionals.rb 1`] = ` +require 'jsii' + +# This is a struct with only optional properties. +class Scope::JsiiCalcLib::StructWithOnlyOptionals < Jsii::Struct + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.StructWithOnlyOptionals", self) + + # @param optional1 [String, nil] The first optional! + # @param optional2 [Numeric, nil] + # @param optional3 [Boolean, nil] + def initialize(optional1: nil, optional2: nil, optional3: nil) + @optional1 = optional1 + @optional2 = optional2 + @optional3 = optional3 + end + + # The first optional! + # + # @return [String, nil] + attr_reader :optional1 + # @return [Numeric, nil] + attr_reader :optional2 + # @return [Boolean, nil] + attr_reader :optional3 + + def self.jsii_properties + { + :optional1 => "optional1", + :optional2 => "optional2", + :optional3 => "optional3", + } + end + + def to_jsii + result = {} + result.merge!({ + "optional1" => @optional1, + "optional2" => @optional2, + "optional3" => @optional3, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/submodule/_readme.rb 1`] = ` +# # Submodule Readme +# +# This is a submodule readme. +module Scope::JsiiCalcLib::Submodule; end + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/submodule/class_with_nonpascalcased_name.rb 1`] = ` +require 'jsii' + +# Test for classes with shouting-cased names that serve as a namespace, consumed from a different assembly than the current one. +class Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName < Jsii::Object + self.jsii_fqn = "@scope/jsii-calc-lib.submodule.ClassWithNONPASCALCASEDName" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.submodule.ClassWithNONPASCALCASEDName", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + +end + +class Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName::SomeType < Jsii::Struct + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.submodule.ClassWithNONPASCALCASEDName.SomeType", self) + + # @param name [String] + def initialize(name:) + @name = name + end + + # @return [String] + attr_reader :name + + def self.jsii_properties + { + :name => "name", + } + end + + def to_jsii + result = {} + result.merge!({ + "name" => @name, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/submodule/i_reflectable.rb 1`] = ` +require 'jsii' + +module Scope::JsiiCalcLib::Submodule::IReflectable + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.submodule.IReflectable", self) + + # @return [Array] + def entries() + jsii_get_property("entries") + end + + def self.jsii_overridable_methods + { + :entries => { kind: :property, name: "entries", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/submodule/nesting_class.rb 1`] = ` +require 'jsii' + +# This class is here to show we can use nested classes across module boundaries. +class Scope::JsiiCalcLib::Submodule::NestingClass < Jsii::Object + self.jsii_fqn = "@scope/jsii-calc-lib.submodule.NestingClass" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.submodule.NestingClass", self) + + def initialize(*args) + raise NoMethodError, "@scope/jsii-calc-lib.submodule.NestingClass does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + +end + +# This class is here to show we can use nested classes across module boundaries. +class Scope::JsiiCalcLib::Submodule::NestingClass::NestedClass < Jsii::Object + self.jsii_fqn = "@scope/jsii-calc-lib.submodule.NestingClass.NestedClass" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.submodule.NestingClass.NestedClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :property => { kind: :property, name: "property", is_optional: false }, + } + end + + # @return [String] + def property() + jsii_get_property("property") + end + +end + +# This is a struct, nested within a class. +# +# Normal. +class Scope::JsiiCalcLib::Submodule::NestingClass::NestedStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.submodule.NestingClass.NestedStruct", self) + + # @param name [String] + def initialize(name:) + @name = name + end + + # @return [String] + attr_reader :name + + def self.jsii_properties + { + :name => "name", + } + end + + def to_jsii + result = {} + result.merge!({ + "name" => @name, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/submodule/reflectable_entry.rb 1`] = ` +require 'jsii' + +class Scope::JsiiCalcLib::Submodule::ReflectableEntry < Jsii::Struct + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.submodule.ReflectableEntry", self) + + # @param key [String] + # @param value [Object] + def initialize(key:, value:) + @key = key + @value = value + end + + # @return [String] + attr_reader :key + # @return [Object] + attr_reader :value + + def self.jsii_properties + { + :key => "key", + :value => "value", + } + end + + def to_jsii + result = {} + result.merge!({ + "key" => @key, + "value" => @value, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/submodule/reflector.rb 1`] = ` +require 'jsii' + +class Scope::JsiiCalcLib::Submodule::Reflector < Jsii::Object + self.jsii_fqn = "@scope/jsii-calc-lib.submodule.Reflector" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.submodule.Reflector", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :as_map => { kind: :method, name: "asMap", is_optional: false }, + } + end + + # @param reflectable [Scope::JsiiCalcLib::Submodule::IReflectable] + # @return [Hash{String => Object}] + def as_map(reflectable) + jsii_call_method("asMap", [reflectable]) + end + +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib@0.0.0.jsii.tgz 1`] = `ruby/lib/@scope/jsii-calc-lib@0.0.0.jsii.tgz is a tarball`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/scope-jsii-calc-lib.gemspec 1`] = ` +Gem::Specification.new do |s| + s.name = 'scope-jsii-calc-lib' + s.version = '0.0.0' + s.summary = 'Ruby bindings for @scope/jsii-calc-lib' + s.description = 'A simple calcuator library built on JSII.' + s.authors = ['Amazon Web Services'] + s.license = 'Apache-2.0' + s.homepage = 'https://github.com/aws/jsii' + s.files = Dir["lib/**/*"] + Dir["sig/**/*"] + s.required_ruby_version = '>= 3.3.0' + s.add_dependency 'jsii-ruby-runtime', '< 0.0.1' + s.add_dependency 'base64', '~> 0.2' + s.add_dependency 'scope-jsii-calc-base', '< 0.0.1' + s.add_dependency 'scope-jsii-calc-base-of-base', '>= 2.1.1', '< 3.0.0' +end + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/sig/@scope/jsii-calc-lib.rbs 1`] = ` +module Scope end +module Scope::JsiiCalcLib end +module Scope::JsiiCalcLib::DeprecationRemoval end +module Scope::JsiiCalcLib::Submodule end + +class Scope::JsiiCalcLib::BaseFor2647 < ::Jsii::Object + def initialize: (::Scope::JsiiCalcBaseOfBase::Very very) -> void + def foo: (::Scope::JsiiCalcBase::IBaseInterface obj) -> void +end + +class Scope::JsiiCalcLib::DiamondLeft < ::Jsii::Struct + def initialize: (?hoisted_top: String?, ?left: Numeric?) -> void + attr_reader hoisted_top: String? + attr_reader left: Numeric? +end + +class Scope::JsiiCalcLib::DiamondRight < ::Jsii::Struct + def initialize: (?hoisted_top: String?, ?right: bool?) -> void + attr_reader hoisted_top: String? + attr_reader right: bool? +end + +module Scope::JsiiCalcLib::EnumFromScopedModule + VALUE1: ::Jsii::Enum + VALUE2: ::Jsii::Enum +end + +class Scope::JsiiCalcLib::FunctionWithUnderscoreArgument < ::Jsii::Object + def initialize: () -> void + def foo: (String _) -> String +end + +module Scope::JsiiCalcLib::IDoublable + attr_reader double_value: Numeric +end + +module Scope::JsiiCalcLib::IFriendly + def hello: () -> String +end + +module Scope::JsiiCalcLib::IThreeLevelsInterface + def foo: () -> void + def bar: () -> void + def baz: () -> void +end + +class Scope::JsiiCalcLib::MyFirstStruct < ::Jsii::Struct + def initialize: (anumber: Numeric, astring: String, ?first_optional: Array[String]?) -> void + attr_reader anumber: Numeric + attr_reader astring: String + attr_reader first_optional: Array[String]? +end + +class Scope::JsiiCalcLib::NumericValue < ::Scope::JsiiCalcBase::Base + def initialize: () -> void + attr_reader value: Numeric + def type_name: () -> untyped + def to_string: () -> String +end + +class Scope::JsiiCalcLib::Number < ::Scope::JsiiCalcLib::NumericValue + include ::Scope::JsiiCalcLib::IDoublable + def initialize: (Numeric value) -> void + attr_reader value: Numeric + attr_reader double_value: Numeric + def type_name: () -> untyped + def to_string: () -> String +end + +class Scope::JsiiCalcLib::Operation < ::Scope::JsiiCalcLib::NumericValue + def initialize: () -> void + attr_reader value: Numeric + def type_name: () -> untyped + def to_string: () -> String +end + +class Scope::JsiiCalcLib::StructWithOnlyOptionals < ::Jsii::Struct + def initialize: (?optional1: String?, ?optional2: Numeric?, ?optional3: bool?) -> void + attr_reader optional1: String? + attr_reader optional2: Numeric? + attr_reader optional3: bool? +end + +module Scope::JsiiCalcLib::DeprecationRemoval::IInterface + def method: () -> void +end + +class Scope::JsiiCalcLib::DeprecationRemoval::InterfaceFactory < ::Jsii::Object + def self.create: () -> ::Scope::JsiiCalcLib::DeprecationRemoval::IInterface +end + +class Scope::JsiiCalcLib::DeprecationRemoval::VisibleBaseClass < ::Jsii::Object + def initialize: () -> void + attr_reader property_present: bool +end + +class Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName < ::Jsii::Object + def initialize: () -> void +end + +class Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName::SomeType < ::Jsii::Struct + def initialize: (name: String) -> void + attr_reader name: String +end + +module Scope::JsiiCalcLib::Submodule::IReflectable + attr_reader entries: Array[::Scope::JsiiCalcLib::Submodule::ReflectableEntry] +end + +class Scope::JsiiCalcLib::Submodule::NestingClass < ::Jsii::Object +end + +class Scope::JsiiCalcLib::Submodule::NestingClass::NestedClass < ::Jsii::Object + def initialize: () -> void + attr_reader property: String +end + +class Scope::JsiiCalcLib::Submodule::NestingClass::NestedStruct < ::Jsii::Struct + def initialize: (name: String) -> void + attr_reader name: String +end + +class Scope::JsiiCalcLib::Submodule::ReflectableEntry < ::Jsii::Struct + def initialize: (key: String, value: untyped) -> void + attr_reader key: String + attr_reader value: untyped +end + +class Scope::JsiiCalcLib::Submodule::Reflector < ::Jsii::Object + def initialize: () -> void + def as_map: (::Scope::JsiiCalcLib::Submodule::IReflectable reflectable) -> Hash[String, untyped] +end + + +`; + +exports[`Generated code for "@scope/jsii-calc-lib": / 1`] = ` + + ┗━ 📁 ruby + ┗━ 📁 lib + ┗━ 📁 @scope + ┗━ 📁 jsii-calc-lib + ┣━ 📄 base_for2647.rb.diff + ┣━ 📄 diamond_left.rb.diff + ┣━ 📄 diamond_right.rb.diff + ┣━ 📄 function_with_underscore_argument.rb.diff + ┣━ 📄 my_first_struct.rb.diff + ┣━ 📄 number.rb.diff + ┣━ 📄 struct_with_only_optionals.rb.diff + ┗━ 📁 submodule + ┣━ 📄 class_with_nonpascalcased_name.rb.diff + ┣━ 📄 nesting_class.rb.diff + ┣━ 📄 reflectable_entry.rb.diff + ┗━ 📄 reflector.rb.diff +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/base_for2647.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-lib/base_for2647.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-lib/base_for2647.rb --runtime-type-checking +@@ -11,10 +11,11 @@ + self.jsii_fqn = "@scope/jsii-calc-lib.BaseFor2647" + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.BaseFor2647", self) + + # @param very [Scope::JsiiCalcBaseOfBase::Very] + def initialize(very) ++ Jsii::Type.check_type(very, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWJhc2Utb2YtYmFzZS5WZXJ5In0=")), "very") + Jsii::Object.instance_method(:initialize).bind(self).call(very) + end + + def self.jsii_overridable_methods + { +@@ -23,10 +24,11 @@ + end + + # @param obj [Scope::JsiiCalcBase::IBaseInterface] + # @return [void] + def foo(obj) ++ Jsii::Type.check_type(obj, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWJhc2UuSUJhc2VJbnRlcmZhY2UifQ==")), "obj") + jsii_call_method("foo", [obj]) + end + + end +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/diamond_left.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-lib/diamond_left.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-lib/diamond_left.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param hoisted_top [String, nil] + # @param left [Numeric, nil] + def initialize(hoisted_top: nil, left: nil) + @hoisted_top = hoisted_top ++ Jsii::Type.check_type(@hoisted_top, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "hoistedTop") unless @hoisted_top.nil? + @left = left ++ Jsii::Type.check_type(@left, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "left") unless @left.nil? + end + + # @return [String, nil] + attr_reader :hoisted_top + # @return [Numeric, nil] +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/diamond_right.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-lib/diamond_right.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-lib/diamond_right.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param hoisted_top [String, nil] + # @param right [Boolean, nil] + def initialize(hoisted_top: nil, right: nil) + @hoisted_top = hoisted_top ++ Jsii::Type.check_type(@hoisted_top, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "hoistedTop") unless @hoisted_top.nil? + @right = right ++ Jsii::Type.check_type(@right, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "right") unless @right.nil? + end + + # @return [String, nil] + attr_reader :hoisted_top + # @return [Boolean, nil] +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/function_with_underscore_argument.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-lib/function_with_underscore_argument.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-lib/function_with_underscore_argument.rb --runtime-type-checking +@@ -16,10 +16,11 @@ + end + + # @param _ [String] + # @return [String] + def foo(_) ++ Jsii::Type.check_type(_, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "_") + jsii_call_method("foo", [_]) + end + + end +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/my_first_struct.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-lib/my_first_struct.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-lib/my_first_struct.rb --runtime-type-checking +@@ -7,12 +7,15 @@ + # @param anumber [Numeric] An awesome number value. + # @param astring [String] A string value. + # @param first_optional [Array, nil] + def initialize(anumber:, astring:, first_optional: nil) + @anumber = anumber ++ Jsii::Type.check_type(@anumber, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "anumber") + @astring = astring ++ Jsii::Type.check_type(@astring, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "astring") + @first_optional = first_optional ++ Jsii::Type.check_type(@first_optional, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "firstOptional") unless @first_optional.nil? + end + + # An awesome number value. + # + # @return [Numeric] +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/number.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-lib/number.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-lib/number.rb --runtime-type-checking +@@ -8,10 +8,11 @@ + + # Creates a Number object. + # + # @param value [Numeric] The number. + def initialize(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "value") + Jsii::Object.instance_method(:initialize).bind(self).call(value) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/struct_with_only_optionals.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-lib/struct_with_only_optionals.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-lib/struct_with_only_optionals.rb --runtime-type-checking +@@ -7,12 +7,15 @@ + # @param optional1 [String, nil] The first optional! + # @param optional2 [Numeric, nil] + # @param optional3 [Boolean, nil] + def initialize(optional1: nil, optional2: nil, optional3: nil) + @optional1 = optional1 ++ Jsii::Type.check_type(@optional1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "optional1") unless @optional1.nil? + @optional2 = optional2 ++ Jsii::Type.check_type(@optional2, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "optional2") unless @optional2.nil? + @optional3 = optional3 ++ Jsii::Type.check_type(@optional3, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "optional3") unless @optional3.nil? + end + + # The first optional! + # + # @return [String, nil] +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/submodule/class_with_nonpascalcased_name.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-lib/submodule/class_with_nonpascalcased_name.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-lib/submodule/class_with_nonpascalcased_name.rb --runtime-type-checking +@@ -20,10 +20,11 @@ + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.submodule.ClassWithNONPASCALCASEDName.SomeType", self) + + # @param name [String] + def initialize(name:) + @name = name ++ Jsii::Type.check_type(@name, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "name") + end + + # @return [String] + attr_reader :name +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/submodule/nesting_class.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-lib/submodule/nesting_class.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-lib/submodule/nesting_class.rb --runtime-type-checking +@@ -45,10 +45,11 @@ + Jsii::Object.register_jsii_fqn("@scope/jsii-calc-lib.submodule.NestingClass.NestedStruct", self) + + # @param name [String] + def initialize(name:) + @name = name ++ Jsii::Type.check_type(@name, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "name") + end + + # @return [String] + attr_reader :name +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/submodule/reflectable_entry.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-lib/submodule/reflectable_entry.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-lib/submodule/reflectable_entry.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param key [String] + # @param value [Object] + def initialize(key:, value:) + @key = key ++ Jsii::Type.check_type(@key, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "key") + @value = value ++ Jsii::Type.check_type(@value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "value") + end + + # @return [String] + attr_reader :key + # @return [Object] +`; + +exports[`Generated code for "@scope/jsii-calc-lib": /ruby/lib/@scope/jsii-calc-lib/submodule/reflector.rb.diff 1`] = ` +--- ruby/lib/@scope/jsii-calc-lib/submodule/reflector.rb --no-runtime-type-checking ++++ ruby/lib/@scope/jsii-calc-lib/submodule/reflector.rb --runtime-type-checking +@@ -15,10 +15,11 @@ + end + + # @param reflectable [Scope::JsiiCalcLib::Submodule::IReflectable] + # @return [Hash{String => Object}] + def as_map(reflectable) ++ Jsii::Type.check_type(reflectable, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5zdWJtb2R1bGUuSVJlZmxlY3RhYmxlIn0=")), "reflectable") + jsii_call_method("asMap", [reflectable]) + end + + end +`; + +exports[`Generated code for "jsii-calc": / 1`] = ` + + ┗━ 📁 ruby + ┣━ 📄 jsii-calc.gemspec + ┣━ 📁 lib + ┃ ┣━ 📁 jsii-calc + ┃ ┃ ┣━ 📄 _readme.rb + ┃ ┃ ┣━ 📄 abstract_class_base.rb + ┃ ┃ ┣━ 📄 abstract_class_returner.rb + ┃ ┃ ┣━ 📄 abstract_class.rb + ┃ ┃ ┣━ 📄 abstract_suite.rb + ┃ ┃ ┣━ 📄 add.rb + ┃ ┃ ┣━ 📄 all_types_enum.rb + ┃ ┃ ┣━ 📄 all_types.rb + ┃ ┃ ┣━ 📄 allowed_method_names.rb + ┃ ┃ ┣━ 📄 ambiguous_parameters.rb + ┃ ┃ ┣━ 📁 anonymous + ┃ ┃ ┃ ┣━ 📄 i_option_a.rb + ┃ ┃ ┃ ┣━ 📄 i_option_b.rb + ┃ ┃ ┃ ┗━ 📄 use_options.rb + ┃ ┃ ┣━ 📄 anonymous_implementation_provider.rb + ┃ ┃ ┣━ 📄 any_property_access.rb + ┃ ┃ ┣━ 📄 async_virtual_methods.rb + ┃ ┃ ┣━ 📄 augmentable_class.rb + ┃ ┃ ┣━ 📄 base_class.rb + ┃ ┃ ┣━ 📄 base_jsii976.rb + ┃ ┃ ┣━ 📄 bell.rb + ┃ ┃ ┣━ 📄 binary_operation.rb + ┃ ┃ ┣━ 📄 burried_anonymous_object.rb + ┃ ┃ ┣━ 📄 calculator_props.rb + ┃ ┃ ┣━ 📄 calculator.rb + ┃ ┃ ┣━ 📁 cdk16625 + ┃ ┃ ┃ ┣━ 📄 cdk16625.rb + ┃ ┃ ┃ ┗━ 📁 donotimport + ┃ ┃ ┃ ┗━ 📄 unimported_submodule_type.rb + ┃ ┃ ┣━ 📁 cdk22369 + ┃ ┃ ┃ ┣━ 📄 accepts_path_props.rb + ┃ ┃ ┃ ┗━ 📄 accepts_path.rb + ┃ ┃ ┣━ 📄 child_struct982.rb + ┃ ┃ ┣━ 📄 class_that_implements_the_internal_interface.rb + ┃ ┃ ┣━ 📄 class_that_implements_the_private_interface.rb + ┃ ┃ ┣━ 📄 class_with_collection_of_unions.rb + ┃ ┃ ┣━ 📄 class_with_collections.rb + ┃ ┃ ┣━ 📄 class_with_container_types.rb + ┃ ┃ ┣━ 📄 class_with_docs.rb + ┃ ┃ ┣━ 📄 class_with_java_reserved_words.rb + ┃ ┃ ┣━ 📄 class_with_mutable_object_literal_property.rb + ┃ ┃ ┣━ 📄 class_with_nested_union.rb + ┃ ┃ ┣━ 📄 class_with_private_constructor_and_automatic_properties.rb + ┃ ┃ ┣━ 📁 composition + ┃ ┃ ┃ ┗━ 📄 composite_operation.rb + ┃ ┃ ┣━ 📄 confusing_to_jackson_struct.rb + ┃ ┃ ┣━ 📄 confusing_to_jackson.rb + ┃ ┃ ┣━ 📄 constructor_passes_this_out.rb + ┃ ┃ ┣━ 📄 constructors.rb + ┃ ┃ ┣━ 📄 consume_pure_interface.rb + ┃ ┃ ┣━ 📄 consumer_can_ring_bell.rb + ┃ ┃ ┣━ 📄 consumers_of_this_crazy_type_system.rb + ┃ ┃ ┣━ 📄 container_props.rb + ┃ ┃ ┣━ 📁 covariant_overrides + ┃ ┃ ┃ ┗━ 📁 class_overrides + ┃ ┃ ┃ ┣━ 📄 base.rb + ┃ ┃ ┃ ┣━ 📄 derived.rb + ┃ ┃ ┃ ┣━ 📄 i_base.rb + ┃ ┃ ┃ ┣━ 📄 middle.rb + ┃ ┃ ┃ ┣━ 📄 sub_subclass.rb + ┃ ┃ ┃ ┣━ 📄 subclass.rb + ┃ ┃ ┃ ┗━ 📄 superclass.rb + ┃ ┃ ┣━ 📄 data_renderer.rb + ┃ ┃ ┣━ 📄 default.rb + ┃ ┃ ┣━ 📄 defaulted_constructor_argument.rb + ┃ ┃ ┣━ 📄 demonstrate982.rb + ┃ ┃ ┣━ 📄 deprecated_class.rb + ┃ ┃ ┣━ 📄 deprecated_enum.rb + ┃ ┃ ┣━ 📄 deprecated_struct.rb + ┃ ┃ ┣━ 📁 derived_class_has_no_properties + ┃ ┃ ┃ ┣━ 📄 base.rb + ┃ ┃ ┃ ┗━ 📄 derived.rb + ┃ ┃ ┣━ 📄 derived_struct.rb + ┃ ┃ ┣━ 📄 diamond_bottom.rb + ┃ ┃ ┣━ 📄 diamond_inheritance_base_level_struct.rb + ┃ ┃ ┣━ 📄 diamond_inheritance_first_mid_level_struct.rb + ┃ ┃ ┣━ 📄 diamond_inheritance_second_mid_level_struct.rb + ┃ ┃ ┣━ 📄 diamond_inheritance_top_level_struct.rb + ┃ ┃ ┣━ 📄 disappointing_collection_source.rb + ┃ ┃ ┣━ 📄 do_not_override_privates.rb + ┃ ┃ ┣━ 📄 do_not_recognize_any_as_optional.rb + ┃ ┃ ┣━ 📄 documented_class.rb + ┃ ┃ ┣━ 📄 dont_complain_about_variadic_after_optional.rb + ┃ ┃ ┣━ 📄 dont_use_me.rb + ┃ ┃ ┣━ 📄 double_trouble.rb + ┃ ┃ ┣━ 📄 dummy_obj.rb + ┃ ┃ ┣━ 📄 dynamic_property_bearer_child.rb + ┃ ┃ ┣━ 📄 dynamic_property_bearer.rb + ┃ ┃ ┣━ 📄 entropy.rb + ┃ ┃ ┣━ 📄 enum_dispenser.rb + ┃ ┃ ┣━ 📄 erase_undefined_hash_values_options.rb + ┃ ┃ ┣━ 📄 erase_undefined_hash_values.rb + ┃ ┃ ┣━ 📄 experimental_class.rb + ┃ ┃ ┣━ 📄 experimental_enum.rb + ┃ ┃ ┣━ 📄 experimental_struct.rb + ┃ ┃ ┣━ 📄 exported_base_class.rb + ┃ ┃ ┣━ 📄 extends_internal_interface.rb + ┃ ┃ ┣━ 📄 external_class.rb + ┃ ┃ ┣━ 📄 external_enum.rb + ┃ ┃ ┣━ 📄 external_struct.rb + ┃ ┃ ┣━ 📄 full_combo.rb + ┃ ┃ ┣━ 📄 give_me_structs.rb + ┃ ┃ ┣━ 📄 greetee.rb + ┃ ┃ ┣━ 📄 greeting_augmenter.rb + ┃ ┃ ┣━ 📁 homonymous_forward_references + ┃ ┃ ┃ ┣━ 📄 _readme.rb + ┃ ┃ ┃ ┣━ 📁 bar + ┃ ┃ ┃ ┃ ┣━ 📄 consumer_props.rb + ┃ ┃ ┃ ┃ ┣━ 📄 consumer.rb + ┃ ┃ ┃ ┃ ┗━ 📄 homonymous.rb + ┃ ┃ ┃ ┗━ 📁 foo + ┃ ┃ ┃ ┣━ 📄 consumer_props.rb + ┃ ┃ ┃ ┣━ 📄 consumer.rb + ┃ ┃ ┃ ┗━ 📄 homonymous.rb + ┃ ┃ ┣━ 📄 i_anonymous_implementation_provider.rb + ┃ ┃ ┣━ 📄 i_anonymously_implement_me.rb + ┃ ┃ ┣━ 📄 i_another_public_interface.rb + ┃ ┃ ┣━ 📄 i_bell_ringer.rb + ┃ ┃ ┣━ 📄 i_bell.rb + ┃ ┃ ┣━ 📄 i_concrete_bell_ringer.rb + ┃ ┃ ┣━ 📄 i_deprecated_interface.rb + ┃ ┃ ┣━ 📄 i_experimental_interface.rb + ┃ ┃ ┣━ 📄 i_extends_private_interface.rb + ┃ ┃ ┣━ 📄 i_external_interface.rb + ┃ ┃ ┣━ 📄 i_friendlier.rb + ┃ ┃ ┣━ 📄 i_friendly_random_generator.rb + ┃ ┃ ┣━ 📄 i_indirectly_implemented.rb + ┃ ┃ ┣━ 📄 i_interface_implemented_by_abstract_class.rb + ┃ ┃ ┣━ 📄 i_interface_that_should_not_be_a_data_type.rb + ┃ ┃ ┣━ 📄 i_interface_with_internal.rb + ┃ ┃ ┣━ 📄 i_interface_with_methods.rb + ┃ ┃ ┣━ 📄 i_interface_with_optional_method_arguments.rb + ┃ ┃ ┣━ 📄 i_interface_with_properties_extension.rb + ┃ ┃ ┣━ 📄 i_interface_with_properties.rb + ┃ ┃ ┣━ 📄 i_java_reserved_words_in_an_interface.rb + ┃ ┃ ┣━ 📄 i_jsii487_external.rb + ┃ ┃ ┣━ 📄 i_jsii487_external2.rb + ┃ ┃ ┣━ 📄 i_jsii496.rb + ┃ ┃ ┣━ 📄 i_mutable_object_literal.rb + ┃ ┃ ┣━ 📄 i_non_internal_interface.rb + ┃ ┃ ┣━ 📄 i_object_with_property.rb + ┃ ┃ ┣━ 📄 i_optional_method.rb + ┃ ┃ ┣━ 📄 i_privately_implemented.rb + ┃ ┃ ┣━ 📄 i_public_interface.rb + ┃ ┃ ┣━ 📄 i_public_interface2.rb + ┃ ┃ ┣━ 📄 i_random_number_generator.rb + ┃ ┃ ┣━ 📄 i_return_jsii976.rb + ┃ ┃ ┣━ 📄 i_returns_number.rb + ┃ ┃ ┣━ 📄 i_stable_interface.rb + ┃ ┃ ┣━ 📄 i_stringable.rb + ┃ ┃ ┣━ 📄 i_struct_returning_delegate.rb + ┃ ┃ ┣━ 📄 i_wall_clock.rb + ┃ ┃ ┣━ 📄 ijsii417_derived.rb + ┃ ┃ ┣━ 📄 ijsii417_public_base_of_base.rb + ┃ ┃ ┣━ 📄 implement_internal_interface.rb + ┃ ┃ ┣━ 📄 implementation.rb + ┃ ┃ ┣━ 📄 implements_interface_with_internal_subclass.rb + ┃ ┃ ┣━ 📄 implements_interface_with_internal.rb + ┃ ┃ ┣━ 📄 implements_private_interface.rb + ┃ ┃ ┣━ 📄 implict_base_of_base.rb + ┃ ┃ ┣━ 📄 inbetween_class.rb + ┃ ┃ ┣━ 📄 interface_collections.rb + ┃ ┃ ┣━ 📁 interface_in_namespace_includes_classes + ┃ ┃ ┃ ┣━ 📄 foo.rb + ┃ ┃ ┃ ┗━ 📄 hello.rb + ┃ ┃ ┣━ 📁 interface_in_namespace_only_interface + ┃ ┃ ┃ ┗━ 📄 hello.rb + ┃ ┃ ┣━ 📄 interfaces_maker.rb + ┃ ┃ ┣━ 📁 intersection + ┃ ┃ ┃ ┣━ 📄 consumes_intersection.rb + ┃ ┃ ┃ ┣━ 📄 i_something.rb + ┃ ┃ ┃ ┗━ 📄 intersection_props.rb + ┃ ┃ ┣━ 📄 isomorphism.rb + ┃ ┃ ┣━ 📄 issue2638_b.rb + ┃ ┃ ┣━ 📄 issue2638.rb + ┃ ┃ ┣━ 📄 java_reserved_words.rb + ┃ ┃ ┣━ 📄 js_object_literal_for_interface.rb + ┃ ┃ ┣━ 📄 js_object_literal_to_native_class.rb + ┃ ┃ ┣━ 📄 js_object_literal_to_native.rb + ┃ ┃ ┣━ 📄 jsii_agent.rb + ┃ ┃ ┣━ 📁 jsii3656 + ┃ ┃ ┃ ┣━ 📄 implement_me_opts.rb + ┃ ┃ ┃ ┗━ 📄 override_me.rb + ┃ ┃ ┣━ 📄 jsii417_derived.rb + ┃ ┃ ┣━ 📄 jsii417_public_base_of_base.rb + ┃ ┃ ┣━ 📄 jsii487_derived.rb + ┃ ┃ ┣━ 📁 jsii4894 + ┃ ┃ ┃ ┣━ 📄 non_pascal_case_test_props.rb + ┃ ┃ ┃ ┗━ 📄 non_pascal_case_test.rb + ┃ ┃ ┣━ 📄 jsii496_derived.rb + ┃ ┃ ┣━ 📄 json_formatter.rb + ┃ ┃ ┣━ 📄 level_one_props.rb + ┃ ┃ ┣━ 📄 level_one.rb + ┃ ┃ ┣━ 📄 load_balanced_fargate_service_props.rb + ┃ ┃ ┣━ 📄 method_named_property.rb + ┃ ┃ ┣━ 📁 module2530 + ┃ ┃ ┃ ┗━ 📄 my_class.rb + ┃ ┃ ┣━ 📁 module2617 + ┃ ┃ ┃ ┗━ 📄 only_statics.rb + ┃ ┃ ┣━ 📁 module2647 + ┃ ┃ ┃ ┗━ 📄 extend_and_implement.rb + ┃ ┃ ┣━ 📁 module2689 + ┃ ┃ ┃ ┣━ 📁 methods + ┃ ┃ ┃ ┃ ┗━ 📄 my_class.rb + ┃ ┃ ┃ ┣━ 📁 props + ┃ ┃ ┃ ┃ ┗━ 📄 my_class.rb + ┃ ┃ ┃ ┣━ 📁 retval + ┃ ┃ ┃ ┃ ┗━ 📄 my_class.rb + ┃ ┃ ┃ ┗━ 📁 structs + ┃ ┃ ┃ ┗━ 📄 my_struct.rb + ┃ ┃ ┣━ 📁 module2692 + ┃ ┃ ┃ ┣━ 📁 submodule1 + ┃ ┃ ┃ ┃ ┗━ 📄 bar.rb + ┃ ┃ ┃ ┗━ 📁 submodule2 + ┃ ┃ ┃ ┣━ 📄 bar.rb + ┃ ┃ ┃ ┗━ 📄 foo.rb + ┃ ┃ ┣━ 📁 module2700 + ┃ ┃ ┃ ┣━ 📄 base.rb + ┃ ┃ ┃ ┣━ 📄 derived.rb + ┃ ┃ ┃ ┗━ 📄 i_foo.rb + ┃ ┃ ┣━ 📁 module2702 + ┃ ┃ ┃ ┣━ 📄 baz.rb + ┃ ┃ ┃ ┣━ 📄 class1.rb + ┃ ┃ ┃ ┣━ 📄 class2.rb + ┃ ┃ ┃ ┣━ 📄 class3.rb + ┃ ┃ ┃ ┣━ 📄 construct.rb + ┃ ┃ ┃ ┣━ 📄 i_baz.rb + ┃ ┃ ┃ ┣━ 📄 i_construct.rb + ┃ ┃ ┃ ┣━ 📄 i_foo.rb + ┃ ┃ ┃ ┣━ 📄 i_resource.rb + ┃ ┃ ┃ ┣━ 📄 i_vpc.rb + ┃ ┃ ┃ ┣━ 📄 resource.rb + ┃ ┃ ┃ ┗━ 📄 vpc.rb + ┃ ┃ ┣━ 📄 multiply.rb + ┃ ┃ ┣━ 📄 negate.rb + ┃ ┃ ┣━ 📄 nested_class_instance.rb + ┃ ┃ ┣━ 📄 nested_struct.rb + ┃ ┃ ┣━ 📄 node_standard_library.rb + ┃ ┃ ┣━ 📁 nodirect + ┃ ┃ ┃ ┣━ 📁 sub1 + ┃ ┃ ┃ ┃ ┗━ 📄 type_from_sub1.rb + ┃ ┃ ┃ ┗━ 📁 sub2 + ┃ ┃ ┃ ┗━ 📄 type_from_sub2.rb + ┃ ┃ ┣━ 📄 null_should_be_treated_as_undefined_data.rb + ┃ ┃ ┣━ 📄 null_should_be_treated_as_undefined.rb + ┃ ┃ ┣━ 📄 number_generator.rb + ┃ ┃ ┣━ 📄 object_refs_in_collections.rb + ┃ ┃ ┣━ 📄 object_with_property_provider.rb + ┃ ┃ ┣━ 📄 old.rb + ┃ ┃ ┣━ 📁 onlystatic + ┃ ┃ ┃ ┗━ 📄 only_static_methods.rb + ┃ ┃ ┣━ 📄 optional_argument_invoker.rb + ┃ ┃ ┣━ 📄 optional_constructor_argument.rb + ┃ ┃ ┣━ 📄 optional_struct_consumer.rb + ┃ ┃ ┣━ 📄 optional_struct.rb + ┃ ┃ ┣━ 📄 overridable_protected_member.rb + ┃ ┃ ┣━ 📄 override_returns_object.rb + ┃ ┃ ┣━ 📄 param_shadows_builtins_props.rb + ┃ ┃ ┣━ 📄 param_shadows_builtins.rb + ┃ ┃ ┣━ 📄 param_shadows_scope.rb + ┃ ┃ ┣━ 📄 parent_struct982.rb + ┃ ┃ ┣━ 📄 partially_initialized_this_consumer.rb + ┃ ┃ ┣━ 📁 pascal_case_name + ┃ ┃ ┃ ┣━ 📄 sub_subclass.rb + ┃ ┃ ┃ ┣━ 📄 subclass.rb + ┃ ┃ ┃ ┗━ 📄 superclass.rb + ┃ ┃ ┣━ 📄 polymorphism.rb + ┃ ┃ ┣━ 📄 power.rb + ┃ ┃ ┣━ 📄 promise_nothing.rb + ┃ ┃ ┣━ 📄 property_named_property.rb + ┃ ┃ ┣━ 📄 public_class.rb + ┃ ┃ ┣━ 📄 python_reserved_words.rb + ┃ ┃ ┣━ 📁 python_self + ┃ ┃ ┃ ┣━ 📄 class_with_self_kwarg.rb + ┃ ┃ ┃ ┣━ 📄 class_with_self.rb + ┃ ┃ ┃ ┣━ 📄 i_interface_with_self.rb + ┃ ┃ ┃ ┗━ 📄 struct_with_self.rb + ┃ ┃ ┣━ 📄 reference_enum_from_scoped_package.rb + ┃ ┃ ┣━ 📄 returns_private_implementation_of_interface.rb + ┃ ┃ ┣━ 📄 root_struct_validator.rb + ┃ ┃ ┣━ 📄 root_struct.rb + ┃ ┃ ┣━ 📄 runtime_type_checking.rb + ┃ ┃ ┣━ 📄 second_level_struct.rb + ┃ ┃ ┣━ 📄 single_instance_two_types.rb + ┃ ┃ ┣━ 📄 singleton_int_enum.rb + ┃ ┃ ┣━ 📄 singleton_int.rb + ┃ ┃ ┣━ 📄 singleton_string_enum.rb + ┃ ┃ ┣━ 📄 singleton_string.rb + ┃ ┃ ┣━ 📄 smelly_struct.rb + ┃ ┃ ┣━ 📄 some_containing_class.rb + ┃ ┃ ┣━ 📄 some_type_jsii976.rb + ┃ ┃ ┣━ 📄 stable_class.rb + ┃ ┃ ┣━ 📄 stable_enum.rb + ┃ ┃ ┣━ 📄 stable_struct.rb + ┃ ┃ ┣━ 📄 static_context.rb + ┃ ┃ ┣━ 📄 static_hello_child.rb + ┃ ┃ ┣━ 📄 static_hello_parent.rb + ┃ ┃ ┣━ 📄 statics.rb + ┃ ┃ ┣━ 📄 string_enum.rb + ┃ ┃ ┣━ 📄 stringable.rb + ┃ ┃ ┣━ 📄 strip_internal.rb + ┃ ┃ ┣━ 📄 struct_a.rb + ┃ ┃ ┣━ 📄 struct_b.rb + ┃ ┃ ┣━ 📄 struct_parameter_type.rb + ┃ ┃ ┣━ 📄 struct_passing.rb + ┃ ┃ ┣━ 📄 struct_union_consumer.rb + ┃ ┃ ┣━ 📄 struct_with_collection_of_unionts.rb + ┃ ┃ ┣━ 📄 struct_with_enum.rb + ┃ ┃ ┣━ 📄 struct_with_java_reserved_words.rb + ┃ ┃ ┣━ 📁 submodule + ┃ ┃ ┃ ┣━ 📄 _readme.rb + ┃ ┃ ┃ ┣━ 📁 back_references + ┃ ┃ ┃ ┃ ┗━ 📄 my_class_reference.rb + ┃ ┃ ┃ ┣━ 📁 child + ┃ ┃ ┃ ┃ ┣━ 📄 awesomeness.rb + ┃ ┃ ┃ ┃ ┣━ 📄 goodness.rb + ┃ ┃ ┃ ┃ ┣━ 📄 inner_class.rb + ┃ ┃ ┃ ┃ ┣━ 📄 kwargs_props.rb + ┃ ┃ ┃ ┃ ┣━ 📄 outer_class.rb + ┃ ┃ ┃ ┃ ┣━ 📄 some_enum.rb + ┃ ┃ ┃ ┃ ┣━ 📄 some_struct.rb + ┃ ┃ ┃ ┃ ┗━ 📄 structure.rb + ┃ ┃ ┃ ┣━ 📄 default.rb + ┃ ┃ ┃ ┣━ 📁 isolated + ┃ ┃ ┃ ┃ ┣━ 📄 _readme.rb + ┃ ┃ ┃ ┃ ┗━ 📄 kwargs.rb + ┃ ┃ ┃ ┣━ 📄 my_class.rb + ┃ ┃ ┃ ┣━ 📁 nested_submodule + ┃ ┃ ┃ ┃ ┣━ 📁 deeply_nested + ┃ ┃ ┃ ┃ ┃ ┗━ 📄 i_namespaced.rb + ┃ ┃ ┃ ┃ ┗━ 📄 namespaced.rb + ┃ ┃ ┃ ┣━ 📁 param + ┃ ┃ ┃ ┃ ┗━ 📄 special_parameter.rb + ┃ ┃ ┃ ┗━ 📁 returnsparam + ┃ ┃ ┃ ┗━ 📄 returns_special_parameter.rb + ┃ ┃ ┣━ 📄 sum.rb + ┃ ┃ ┣━ 📄 supports_nice_java_builder_props.rb + ┃ ┃ ┣━ 📄 supports_nice_java_builder_with_required_props.rb + ┃ ┃ ┣━ 📄 supports_nice_java_builder.rb + ┃ ┃ ┣━ 📄 sync_override_extra_args.rb + ┃ ┃ ┣━ 📄 sync_virtual_methods.rb + ┃ ┃ ┣━ 📄 test_struct_with_enum.rb + ┃ ┃ ┣━ 📄 thrower.rb + ┃ ┃ ┣━ 📄 top_level_struct.rb + ┃ ┃ ┣━ 📄 two_methods_with_similar_capitalization.rb + ┃ ┃ ┣━ 📄 umask_check.rb + ┃ ┃ ┣━ 📄 unary_operation.rb + ┃ ┃ ┣━ 📁 union + ┃ ┃ ┃ ┣━ 📄 consumes_union.rb + ┃ ┃ ┃ ┣━ 📄 i_resolvable.rb + ┃ ┃ ┃ ┗━ 📄 resolvable.rb + ┃ ┃ ┣━ 📄 union_properties.rb + ┃ ┃ ┣━ 📄 upcasing_reflectable.rb + ┃ ┃ ┣━ 📄 use_bundled_dependency.rb + ┃ ┃ ┣━ 📄 use_calc_base.rb + ┃ ┃ ┣━ 📄 uses_interface_with_properties.rb + ┃ ┃ ┣━ 📄 variadic_invoker.rb + ┃ ┃ ┣━ 📄 variadic_method.rb + ┃ ┃ ┣━ 📄 variadic_type_union.rb + ┃ ┃ ┣━ 📄 virtual_method_playground.rb + ┃ ┃ ┣━ 📄 void_callback.rb + ┃ ┃ ┣━ 📄 weird_docs.rb + ┃ ┃ ┗━ 📄 with_private_property_in_constructor.rb + ┃ ┣━ 📄 jsii-calc.rb + ┃ ┗━ 📄 jsii-calc@3.20.120.jsii.tgz + ┣━ 📄 LICENSE + ┣━ 📄 NOTICE + ┗━ 📁 sig + ┗━ 📄 jsii-calc.rbs +`; + +exports[`Generated code for "jsii-calc": /ruby/LICENSE 1`] = ` + + 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 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. +`; + +exports[`Generated code for "jsii-calc": /ruby/NOTICE 1`] = ` +jsii +Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +`; + +exports[`Generated code for "jsii-calc": /ruby/jsii-calc.gemspec 1`] = ` +Gem::Specification.new do |s| + s.name = 'jsii-calc' + s.version = '3.20.120' + s.summary = 'Ruby bindings for jsii-calc' + s.description = 'A simple calcuator built on JSII.' + s.authors = ['Amazon Web Services'] + s.license = 'Apache-2.0' + s.homepage = 'https://github.com/aws/jsii' + s.files = Dir["lib/**/*"] + Dir["sig/**/*"] + s.required_ruby_version = '>= 3.3.0' + s.add_dependency 'jsii-ruby-runtime', '< 0.0.1' + s.add_dependency 'base64', '~> 0.2' + s.add_dependency 'scope-jsii-calc-base', '< 0.0.1' + s.add_dependency 'scope-jsii-calc-lib', '< 0.0.1' +end + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc.rb 1`] = ` +require 'jsii' +require 'json' +require 'base64' + +require '@scope/jsii-calc-base' +require '@scope/jsii-calc-lib' + +module Scope; end +module Scope::JsiiCalcBase; end +module Scope::JsiiCalcLib; end +module JsiiCalc; end +module JsiiCalc + Jsii::Assembly.load('jsii-calc', '3.20.120', File.expand_path('jsii-calc@3.20.120.jsii.tgz', __dir__)) + + module DerivedClassHasNoProperties; end + module InterfaceInNamespaceIncludesClasses; end + module InterfaceInNamespaceOnlyInterface; end + module PythonSelf; end + module Anonymous; end + module Cdk16625; end + module Cdk22369; end + module Composition; end + module CovariantOverrides; end + module HomonymousForwardReferences; end + module Intersection; end + module Jsii3656; end + module Jsii4894; end + module Module2530; end + module Module2617; end + module Module2647; end + module Module2689; end + module Module2692; end + module Module2700; end + module Module2702; end + module Nodirect; end + module Onlystatic; end + module PascalCaseName; end + module Submodule; end + module Union; end + module Cdk16625::Donotimport; end + module CovariantOverrides::ClassOverrides; end + module HomonymousForwardReferences::Bar; end + module HomonymousForwardReferences::Foo; end + module Module2689::Methods; end + module Module2689::Props; end + module Module2689::Retval; end + module Module2689::Structs; end + module Module2692::Submodule1; end + module Module2692::Submodule2; end + module Nodirect::Sub1; end + module Nodirect::Sub2; end + module Submodule::BackReferences; end + module Submodule::Child; end + module Submodule::Isolated; end + module Submodule::NestedSubmodule; end + module Submodule::Param; end + module Submodule::Returnsparam; end + module Submodule::NestedSubmodule::DeeplyNested; end + + JsiiCalc.autoload(:AbstractClassBase, 'jsii-calc/abstract_class_base') + Jsii::Object.register_autoload("jsii-calc.AbstractClassBase", 'jsii-calc/abstract_class_base') + JsiiCalc.autoload(:IInterfaceImplementedByAbstractClass, 'jsii-calc/i_interface_implemented_by_abstract_class') + Jsii::Object.register_autoload("jsii-calc.IInterfaceImplementedByAbstractClass", 'jsii-calc/i_interface_implemented_by_abstract_class') + JsiiCalc.autoload(:AbstractClass, 'jsii-calc/abstract_class') + Jsii::Object.register_autoload("jsii-calc.AbstractClass", 'jsii-calc/abstract_class') + JsiiCalc.autoload(:AbstractClassReturner, 'jsii-calc/abstract_class_returner') + Jsii::Object.register_autoload("jsii-calc.AbstractClassReturner", 'jsii-calc/abstract_class_returner') + JsiiCalc.autoload(:AbstractSuite, 'jsii-calc/abstract_suite') + Jsii::Object.register_autoload("jsii-calc.AbstractSuite", 'jsii-calc/abstract_suite') + JsiiCalc.autoload(:BinaryOperation, 'jsii-calc/binary_operation') + Jsii::Object.register_autoload("jsii-calc.BinaryOperation", 'jsii-calc/binary_operation') + JsiiCalc.autoload(:Add, 'jsii-calc/add') + Jsii::Object.register_autoload("jsii-calc.Add", 'jsii-calc/add') + JsiiCalc.autoload(:AllTypes, 'jsii-calc/all_types') + Jsii::Object.register_autoload("jsii-calc.AllTypes", 'jsii-calc/all_types') + JsiiCalc.autoload(:AllTypesEnum, 'jsii-calc/all_types_enum') + Jsii::Object.register_autoload("jsii-calc.AllTypesEnum", 'jsii-calc/all_types_enum') + JsiiCalc.autoload(:AllowedMethodNames, 'jsii-calc/allowed_method_names') + Jsii::Object.register_autoload("jsii-calc.AllowedMethodNames", 'jsii-calc/allowed_method_names') + JsiiCalc.autoload(:AmbiguousParameters, 'jsii-calc/ambiguous_parameters') + Jsii::Object.register_autoload("jsii-calc.AmbiguousParameters", 'jsii-calc/ambiguous_parameters') + JsiiCalc.autoload(:IAnonymousImplementationProvider, 'jsii-calc/i_anonymous_implementation_provider') + Jsii::Object.register_autoload("jsii-calc.IAnonymousImplementationProvider", 'jsii-calc/i_anonymous_implementation_provider') + JsiiCalc.autoload(:AnonymousImplementationProvider, 'jsii-calc/anonymous_implementation_provider') + Jsii::Object.register_autoload("jsii-calc.AnonymousImplementationProvider", 'jsii-calc/anonymous_implementation_provider') + JsiiCalc.autoload(:AnyPropertyAccess, 'jsii-calc/any_property_access') + Jsii::Object.register_autoload("jsii-calc.AnyPropertyAccess", 'jsii-calc/any_property_access') + JsiiCalc.autoload(:AsyncVirtualMethods, 'jsii-calc/async_virtual_methods') + Jsii::Object.register_autoload("jsii-calc.AsyncVirtualMethods", 'jsii-calc/async_virtual_methods') + JsiiCalc.autoload(:AugmentableClass, 'jsii-calc/augmentable_class') + Jsii::Object.register_autoload("jsii-calc.AugmentableClass", 'jsii-calc/augmentable_class') + JsiiCalc.autoload(:BaseClass, 'jsii-calc/base_class') + Jsii::Object.register_autoload("jsii-calc.BaseClass", 'jsii-calc/base_class') + JsiiCalc.autoload(:BaseJsii976, 'jsii-calc/base_jsii976') + Jsii::Object.register_autoload("jsii-calc.BaseJsii976", 'jsii-calc/base_jsii976') + JsiiCalc.autoload(:IBell, 'jsii-calc/i_bell') + Jsii::Object.register_autoload("jsii-calc.IBell", 'jsii-calc/i_bell') + JsiiCalc.autoload(:Bell, 'jsii-calc/bell') + Jsii::Object.register_autoload("jsii-calc.Bell", 'jsii-calc/bell') + JsiiCalc.autoload(:BurriedAnonymousObject, 'jsii-calc/burried_anonymous_object') + Jsii::Object.register_autoload("jsii-calc.BurriedAnonymousObject", 'jsii-calc/burried_anonymous_object') + JsiiCalc::Composition.autoload(:CompositeOperation, 'jsii-calc/composition/composite_operation') + Jsii::Object.register_autoload("jsii-calc.composition.CompositeOperation", 'jsii-calc/composition/composite_operation') + Jsii::Object.register_autoload("jsii-calc.composition.CompositeOperation.CompositionStringStyle", 'jsii-calc/composition/composite_operation') + JsiiCalc.autoload(:Calculator, 'jsii-calc/calculator') + Jsii::Object.register_autoload("jsii-calc.Calculator", 'jsii-calc/calculator') + JsiiCalc.autoload(:CalculatorProps, 'jsii-calc/calculator_props') + Jsii::Object.register_autoload("jsii-calc.CalculatorProps", 'jsii-calc/calculator_props') + JsiiCalc.autoload(:ParentStruct982, 'jsii-calc/parent_struct982') + Jsii::Object.register_autoload("jsii-calc.ParentStruct982", 'jsii-calc/parent_struct982') + JsiiCalc.autoload(:ChildStruct982, 'jsii-calc/child_struct982') + Jsii::Object.register_autoload("jsii-calc.ChildStruct982", 'jsii-calc/child_struct982') + JsiiCalc.autoload(:IAnotherPublicInterface, 'jsii-calc/i_another_public_interface') + Jsii::Object.register_autoload("jsii-calc.IAnotherPublicInterface", 'jsii-calc/i_another_public_interface') + JsiiCalc.autoload(:INonInternalInterface, 'jsii-calc/i_non_internal_interface') + Jsii::Object.register_autoload("jsii-calc.INonInternalInterface", 'jsii-calc/i_non_internal_interface') + JsiiCalc.autoload(:ClassThatImplementsTheInternalInterface, 'jsii-calc/class_that_implements_the_internal_interface') + Jsii::Object.register_autoload("jsii-calc.ClassThatImplementsTheInternalInterface", 'jsii-calc/class_that_implements_the_internal_interface') + JsiiCalc.autoload(:ClassThatImplementsThePrivateInterface, 'jsii-calc/class_that_implements_the_private_interface') + Jsii::Object.register_autoload("jsii-calc.ClassThatImplementsThePrivateInterface", 'jsii-calc/class_that_implements_the_private_interface') + JsiiCalc.autoload(:ClassWithCollectionOfUnions, 'jsii-calc/class_with_collection_of_unions') + Jsii::Object.register_autoload("jsii-calc.ClassWithCollectionOfUnions", 'jsii-calc/class_with_collection_of_unions') + JsiiCalc.autoload(:ClassWithCollections, 'jsii-calc/class_with_collections') + Jsii::Object.register_autoload("jsii-calc.ClassWithCollections", 'jsii-calc/class_with_collections') + JsiiCalc.autoload(:ClassWithContainerTypes, 'jsii-calc/class_with_container_types') + Jsii::Object.register_autoload("jsii-calc.ClassWithContainerTypes", 'jsii-calc/class_with_container_types') + JsiiCalc.autoload(:ClassWithDocs, 'jsii-calc/class_with_docs') + Jsii::Object.register_autoload("jsii-calc.ClassWithDocs", 'jsii-calc/class_with_docs') + JsiiCalc.autoload(:ClassWithJavaReservedWords, 'jsii-calc/class_with_java_reserved_words') + Jsii::Object.register_autoload("jsii-calc.ClassWithJavaReservedWords", 'jsii-calc/class_with_java_reserved_words') + JsiiCalc.autoload(:ClassWithMutableObjectLiteralProperty, 'jsii-calc/class_with_mutable_object_literal_property') + Jsii::Object.register_autoload("jsii-calc.ClassWithMutableObjectLiteralProperty", 'jsii-calc/class_with_mutable_object_literal_property') + JsiiCalc.autoload(:ClassWithNestedUnion, 'jsii-calc/class_with_nested_union') + Jsii::Object.register_autoload("jsii-calc.ClassWithNestedUnion", 'jsii-calc/class_with_nested_union') + JsiiCalc.autoload(:IInterfaceWithProperties, 'jsii-calc/i_interface_with_properties') + Jsii::Object.register_autoload("jsii-calc.IInterfaceWithProperties", 'jsii-calc/i_interface_with_properties') + JsiiCalc.autoload(:ClassWithPrivateConstructorAndAutomaticProperties, 'jsii-calc/class_with_private_constructor_and_automatic_properties') + Jsii::Object.register_autoload("jsii-calc.ClassWithPrivateConstructorAndAutomaticProperties", 'jsii-calc/class_with_private_constructor_and_automatic_properties') + JsiiCalc.autoload(:ConfusingToJackson, 'jsii-calc/confusing_to_jackson') + Jsii::Object.register_autoload("jsii-calc.ConfusingToJackson", 'jsii-calc/confusing_to_jackson') + JsiiCalc.autoload(:ConfusingToJacksonStruct, 'jsii-calc/confusing_to_jackson_struct') + Jsii::Object.register_autoload("jsii-calc.ConfusingToJacksonStruct", 'jsii-calc/confusing_to_jackson_struct') + JsiiCalc.autoload(:ConstructorPassesThisOut, 'jsii-calc/constructor_passes_this_out') + Jsii::Object.register_autoload("jsii-calc.ConstructorPassesThisOut", 'jsii-calc/constructor_passes_this_out') + JsiiCalc.autoload(:Constructors, 'jsii-calc/constructors') + Jsii::Object.register_autoload("jsii-calc.Constructors", 'jsii-calc/constructors') + JsiiCalc.autoload(:ConsumePureInterface, 'jsii-calc/consume_pure_interface') + Jsii::Object.register_autoload("jsii-calc.ConsumePureInterface", 'jsii-calc/consume_pure_interface') + JsiiCalc.autoload(:ConsumerCanRingBell, 'jsii-calc/consumer_can_ring_bell') + Jsii::Object.register_autoload("jsii-calc.ConsumerCanRingBell", 'jsii-calc/consumer_can_ring_bell') + JsiiCalc.autoload(:ConsumersOfThisCrazyTypeSystem, 'jsii-calc/consumers_of_this_crazy_type_system') + Jsii::Object.register_autoload("jsii-calc.ConsumersOfThisCrazyTypeSystem", 'jsii-calc/consumers_of_this_crazy_type_system') + JsiiCalc.autoload(:ContainerProps, 'jsii-calc/container_props') + Jsii::Object.register_autoload("jsii-calc.ContainerProps", 'jsii-calc/container_props') + JsiiCalc.autoload(:DataRenderer, 'jsii-calc/data_renderer') + Jsii::Object.register_autoload("jsii-calc.DataRenderer", 'jsii-calc/data_renderer') + JsiiCalc.autoload(:Default, 'jsii-calc/default') + Jsii::Object.register_autoload("jsii-calc.Default", 'jsii-calc/default') + JsiiCalc.autoload(:DefaultedConstructorArgument, 'jsii-calc/defaulted_constructor_argument') + Jsii::Object.register_autoload("jsii-calc.DefaultedConstructorArgument", 'jsii-calc/defaulted_constructor_argument') + JsiiCalc.autoload(:Demonstrate982, 'jsii-calc/demonstrate982') + Jsii::Object.register_autoload("jsii-calc.Demonstrate982", 'jsii-calc/demonstrate982') + JsiiCalc.autoload(:DeprecatedClass, 'jsii-calc/deprecated_class') + Jsii::Object.register_autoload("jsii-calc.DeprecatedClass", 'jsii-calc/deprecated_class') + JsiiCalc.autoload(:DeprecatedEnum, 'jsii-calc/deprecated_enum') + Jsii::Object.register_autoload("jsii-calc.DeprecatedEnum", 'jsii-calc/deprecated_enum') + JsiiCalc.autoload(:DeprecatedStruct, 'jsii-calc/deprecated_struct') + Jsii::Object.register_autoload("jsii-calc.DeprecatedStruct", 'jsii-calc/deprecated_struct') + JsiiCalc.autoload(:DerivedStruct, 'jsii-calc/derived_struct') + Jsii::Object.register_autoload("jsii-calc.DerivedStruct", 'jsii-calc/derived_struct') + JsiiCalc.autoload(:DiamondBottom, 'jsii-calc/diamond_bottom') + Jsii::Object.register_autoload("jsii-calc.DiamondBottom", 'jsii-calc/diamond_bottom') + JsiiCalc.autoload(:DiamondInheritanceBaseLevelStruct, 'jsii-calc/diamond_inheritance_base_level_struct') + Jsii::Object.register_autoload("jsii-calc.DiamondInheritanceBaseLevelStruct", 'jsii-calc/diamond_inheritance_base_level_struct') + JsiiCalc.autoload(:DiamondInheritanceFirstMidLevelStruct, 'jsii-calc/diamond_inheritance_first_mid_level_struct') + Jsii::Object.register_autoload("jsii-calc.DiamondInheritanceFirstMidLevelStruct", 'jsii-calc/diamond_inheritance_first_mid_level_struct') + JsiiCalc.autoload(:DiamondInheritanceSecondMidLevelStruct, 'jsii-calc/diamond_inheritance_second_mid_level_struct') + Jsii::Object.register_autoload("jsii-calc.DiamondInheritanceSecondMidLevelStruct", 'jsii-calc/diamond_inheritance_second_mid_level_struct') + JsiiCalc.autoload(:DiamondInheritanceTopLevelStruct, 'jsii-calc/diamond_inheritance_top_level_struct') + Jsii::Object.register_autoload("jsii-calc.DiamondInheritanceTopLevelStruct", 'jsii-calc/diamond_inheritance_top_level_struct') + JsiiCalc.autoload(:DisappointingCollectionSource, 'jsii-calc/disappointing_collection_source') + Jsii::Object.register_autoload("jsii-calc.DisappointingCollectionSource", 'jsii-calc/disappointing_collection_source') + JsiiCalc.autoload(:DoNotOverridePrivates, 'jsii-calc/do_not_override_privates') + Jsii::Object.register_autoload("jsii-calc.DoNotOverridePrivates", 'jsii-calc/do_not_override_privates') + JsiiCalc.autoload(:DoNotRecognizeAnyAsOptional, 'jsii-calc/do_not_recognize_any_as_optional') + Jsii::Object.register_autoload("jsii-calc.DoNotRecognizeAnyAsOptional", 'jsii-calc/do_not_recognize_any_as_optional') + JsiiCalc.autoload(:DocumentedClass, 'jsii-calc/documented_class') + Jsii::Object.register_autoload("jsii-calc.DocumentedClass", 'jsii-calc/documented_class') + JsiiCalc.autoload(:DontComplainAboutVariadicAfterOptional, 'jsii-calc/dont_complain_about_variadic_after_optional') + Jsii::Object.register_autoload("jsii-calc.DontComplainAboutVariadicAfterOptional", 'jsii-calc/dont_complain_about_variadic_after_optional') + JsiiCalc.autoload(:DontUseMe, 'jsii-calc/dont_use_me') + Jsii::Object.register_autoload("jsii-calc.DontUseMe", 'jsii-calc/dont_use_me') + JsiiCalc.autoload(:IRandomNumberGenerator, 'jsii-calc/i_random_number_generator') + Jsii::Object.register_autoload("jsii-calc.IRandomNumberGenerator", 'jsii-calc/i_random_number_generator') + JsiiCalc.autoload(:IFriendlyRandomGenerator, 'jsii-calc/i_friendly_random_generator') + Jsii::Object.register_autoload("jsii-calc.IFriendlyRandomGenerator", 'jsii-calc/i_friendly_random_generator') + JsiiCalc.autoload(:DoubleTrouble, 'jsii-calc/double_trouble') + Jsii::Object.register_autoload("jsii-calc.DoubleTrouble", 'jsii-calc/double_trouble') + JsiiCalc.autoload(:DummyObj, 'jsii-calc/dummy_obj') + Jsii::Object.register_autoload("jsii-calc.DummyObj", 'jsii-calc/dummy_obj') + JsiiCalc.autoload(:DynamicPropertyBearer, 'jsii-calc/dynamic_property_bearer') + Jsii::Object.register_autoload("jsii-calc.DynamicPropertyBearer", 'jsii-calc/dynamic_property_bearer') + JsiiCalc.autoload(:DynamicPropertyBearerChild, 'jsii-calc/dynamic_property_bearer_child') + Jsii::Object.register_autoload("jsii-calc.DynamicPropertyBearerChild", 'jsii-calc/dynamic_property_bearer_child') + JsiiCalc.autoload(:Entropy, 'jsii-calc/entropy') + Jsii::Object.register_autoload("jsii-calc.Entropy", 'jsii-calc/entropy') + JsiiCalc.autoload(:EnumDispenser, 'jsii-calc/enum_dispenser') + Jsii::Object.register_autoload("jsii-calc.EnumDispenser", 'jsii-calc/enum_dispenser') + JsiiCalc.autoload(:EraseUndefinedHashValues, 'jsii-calc/erase_undefined_hash_values') + Jsii::Object.register_autoload("jsii-calc.EraseUndefinedHashValues", 'jsii-calc/erase_undefined_hash_values') + JsiiCalc.autoload(:EraseUndefinedHashValuesOptions, 'jsii-calc/erase_undefined_hash_values_options') + Jsii::Object.register_autoload("jsii-calc.EraseUndefinedHashValuesOptions", 'jsii-calc/erase_undefined_hash_values_options') + JsiiCalc.autoload(:ExperimentalClass, 'jsii-calc/experimental_class') + Jsii::Object.register_autoload("jsii-calc.ExperimentalClass", 'jsii-calc/experimental_class') + JsiiCalc.autoload(:ExperimentalEnum, 'jsii-calc/experimental_enum') + Jsii::Object.register_autoload("jsii-calc.ExperimentalEnum", 'jsii-calc/experimental_enum') + JsiiCalc.autoload(:ExperimentalStruct, 'jsii-calc/experimental_struct') + Jsii::Object.register_autoload("jsii-calc.ExperimentalStruct", 'jsii-calc/experimental_struct') + JsiiCalc.autoload(:ExportedBaseClass, 'jsii-calc/exported_base_class') + Jsii::Object.register_autoload("jsii-calc.ExportedBaseClass", 'jsii-calc/exported_base_class') + JsiiCalc.autoload(:ExtendsInternalInterface, 'jsii-calc/extends_internal_interface') + Jsii::Object.register_autoload("jsii-calc.ExtendsInternalInterface", 'jsii-calc/extends_internal_interface') + JsiiCalc.autoload(:ExternalClass, 'jsii-calc/external_class') + Jsii::Object.register_autoload("jsii-calc.ExternalClass", 'jsii-calc/external_class') + JsiiCalc.autoload(:ExternalEnum, 'jsii-calc/external_enum') + Jsii::Object.register_autoload("jsii-calc.ExternalEnum", 'jsii-calc/external_enum') + JsiiCalc.autoload(:ExternalStruct, 'jsii-calc/external_struct') + Jsii::Object.register_autoload("jsii-calc.ExternalStruct", 'jsii-calc/external_struct') + JsiiCalc.autoload(:IIndirectlyImplemented, 'jsii-calc/i_indirectly_implemented') + Jsii::Object.register_autoload("jsii-calc.IIndirectlyImplemented", 'jsii-calc/i_indirectly_implemented') + JsiiCalc.autoload(:FullCombo, 'jsii-calc/full_combo') + Jsii::Object.register_autoload("jsii-calc.FullCombo", 'jsii-calc/full_combo') + JsiiCalc.autoload(:GiveMeStructs, 'jsii-calc/give_me_structs') + Jsii::Object.register_autoload("jsii-calc.GiveMeStructs", 'jsii-calc/give_me_structs') + JsiiCalc.autoload(:Greetee, 'jsii-calc/greetee') + Jsii::Object.register_autoload("jsii-calc.Greetee", 'jsii-calc/greetee') + JsiiCalc.autoload(:GreetingAugmenter, 'jsii-calc/greeting_augmenter') + Jsii::Object.register_autoload("jsii-calc.GreetingAugmenter", 'jsii-calc/greeting_augmenter') + JsiiCalc.autoload(:IAnonymouslyImplementMe, 'jsii-calc/i_anonymously_implement_me') + Jsii::Object.register_autoload("jsii-calc.IAnonymouslyImplementMe", 'jsii-calc/i_anonymously_implement_me') + JsiiCalc.autoload(:IBellRinger, 'jsii-calc/i_bell_ringer') + Jsii::Object.register_autoload("jsii-calc.IBellRinger", 'jsii-calc/i_bell_ringer') + JsiiCalc.autoload(:IConcreteBellRinger, 'jsii-calc/i_concrete_bell_ringer') + Jsii::Object.register_autoload("jsii-calc.IConcreteBellRinger", 'jsii-calc/i_concrete_bell_ringer') + JsiiCalc.autoload(:IDeprecatedInterface, 'jsii-calc/i_deprecated_interface') + Jsii::Object.register_autoload("jsii-calc.IDeprecatedInterface", 'jsii-calc/i_deprecated_interface') + JsiiCalc.autoload(:IExperimentalInterface, 'jsii-calc/i_experimental_interface') + Jsii::Object.register_autoload("jsii-calc.IExperimentalInterface", 'jsii-calc/i_experimental_interface') + JsiiCalc.autoload(:IExtendsPrivateInterface, 'jsii-calc/i_extends_private_interface') + Jsii::Object.register_autoload("jsii-calc.IExtendsPrivateInterface", 'jsii-calc/i_extends_private_interface') + JsiiCalc.autoload(:IExternalInterface, 'jsii-calc/i_external_interface') + Jsii::Object.register_autoload("jsii-calc.IExternalInterface", 'jsii-calc/i_external_interface') + JsiiCalc.autoload(:IFriendlier, 'jsii-calc/i_friendlier') + Jsii::Object.register_autoload("jsii-calc.IFriendlier", 'jsii-calc/i_friendlier') + JsiiCalc.autoload(:IInterfaceWithMethods, 'jsii-calc/i_interface_with_methods') + Jsii::Object.register_autoload("jsii-calc.IInterfaceWithMethods", 'jsii-calc/i_interface_with_methods') + JsiiCalc.autoload(:IInterfaceThatShouldNotBeADataType, 'jsii-calc/i_interface_that_should_not_be_a_data_type') + Jsii::Object.register_autoload("jsii-calc.IInterfaceThatShouldNotBeADataType", 'jsii-calc/i_interface_that_should_not_be_a_data_type') + JsiiCalc.autoload(:IInterfaceWithInternal, 'jsii-calc/i_interface_with_internal') + Jsii::Object.register_autoload("jsii-calc.IInterfaceWithInternal", 'jsii-calc/i_interface_with_internal') + JsiiCalc.autoload(:IInterfaceWithOptionalMethodArguments, 'jsii-calc/i_interface_with_optional_method_arguments') + Jsii::Object.register_autoload("jsii-calc.IInterfaceWithOptionalMethodArguments", 'jsii-calc/i_interface_with_optional_method_arguments') + JsiiCalc.autoload(:IInterfaceWithPropertiesExtension, 'jsii-calc/i_interface_with_properties_extension') + Jsii::Object.register_autoload("jsii-calc.IInterfaceWithPropertiesExtension", 'jsii-calc/i_interface_with_properties_extension') + JsiiCalc.autoload(:IJSII417PublicBaseOfBase, 'jsii-calc/ijsii417_public_base_of_base') + Jsii::Object.register_autoload("jsii-calc.IJSII417PublicBaseOfBase", 'jsii-calc/ijsii417_public_base_of_base') + JsiiCalc.autoload(:IJSII417Derived, 'jsii-calc/ijsii417_derived') + Jsii::Object.register_autoload("jsii-calc.IJSII417Derived", 'jsii-calc/ijsii417_derived') + JsiiCalc.autoload(:IJavaReservedWordsInAnInterface, 'jsii-calc/i_java_reserved_words_in_an_interface') + Jsii::Object.register_autoload("jsii-calc.IJavaReservedWordsInAnInterface", 'jsii-calc/i_java_reserved_words_in_an_interface') + JsiiCalc.autoload(:IJsii487External, 'jsii-calc/i_jsii487_external') + Jsii::Object.register_autoload("jsii-calc.IJsii487External", 'jsii-calc/i_jsii487_external') + JsiiCalc.autoload(:IJsii487External2, 'jsii-calc/i_jsii487_external2') + Jsii::Object.register_autoload("jsii-calc.IJsii487External2", 'jsii-calc/i_jsii487_external2') + JsiiCalc.autoload(:IJsii496, 'jsii-calc/i_jsii496') + Jsii::Object.register_autoload("jsii-calc.IJsii496", 'jsii-calc/i_jsii496') + JsiiCalc.autoload(:IMutableObjectLiteral, 'jsii-calc/i_mutable_object_literal') + Jsii::Object.register_autoload("jsii-calc.IMutableObjectLiteral", 'jsii-calc/i_mutable_object_literal') + JsiiCalc.autoload(:IObjectWithProperty, 'jsii-calc/i_object_with_property') + Jsii::Object.register_autoload("jsii-calc.IObjectWithProperty", 'jsii-calc/i_object_with_property') + JsiiCalc.autoload(:IOptionalMethod, 'jsii-calc/i_optional_method') + Jsii::Object.register_autoload("jsii-calc.IOptionalMethod", 'jsii-calc/i_optional_method') + JsiiCalc.autoload(:IPrivatelyImplemented, 'jsii-calc/i_privately_implemented') + Jsii::Object.register_autoload("jsii-calc.IPrivatelyImplemented", 'jsii-calc/i_privately_implemented') + JsiiCalc.autoload(:IPublicInterface, 'jsii-calc/i_public_interface') + Jsii::Object.register_autoload("jsii-calc.IPublicInterface", 'jsii-calc/i_public_interface') + JsiiCalc.autoload(:IPublicInterface2, 'jsii-calc/i_public_interface2') + Jsii::Object.register_autoload("jsii-calc.IPublicInterface2", 'jsii-calc/i_public_interface2') + JsiiCalc.autoload(:IReturnJsii976, 'jsii-calc/i_return_jsii976') + Jsii::Object.register_autoload("jsii-calc.IReturnJsii976", 'jsii-calc/i_return_jsii976') + JsiiCalc.autoload(:IReturnsNumber, 'jsii-calc/i_returns_number') + Jsii::Object.register_autoload("jsii-calc.IReturnsNumber", 'jsii-calc/i_returns_number') + JsiiCalc.autoload(:IStableInterface, 'jsii-calc/i_stable_interface') + Jsii::Object.register_autoload("jsii-calc.IStableInterface", 'jsii-calc/i_stable_interface') + JsiiCalc.autoload(:IStringable, 'jsii-calc/i_stringable') + Jsii::Object.register_autoload("jsii-calc.IStringable", 'jsii-calc/i_stringable') + JsiiCalc.autoload(:IStructReturningDelegate, 'jsii-calc/i_struct_returning_delegate') + Jsii::Object.register_autoload("jsii-calc.IStructReturningDelegate", 'jsii-calc/i_struct_returning_delegate') + JsiiCalc.autoload(:IWallClock, 'jsii-calc/i_wall_clock') + Jsii::Object.register_autoload("jsii-calc.IWallClock", 'jsii-calc/i_wall_clock') + JsiiCalc.autoload(:ImplementInternalInterface, 'jsii-calc/implement_internal_interface') + Jsii::Object.register_autoload("jsii-calc.ImplementInternalInterface", 'jsii-calc/implement_internal_interface') + JsiiCalc.autoload(:Implementation, 'jsii-calc/implementation') + Jsii::Object.register_autoload("jsii-calc.Implementation", 'jsii-calc/implementation') + JsiiCalc.autoload(:ImplementsInterfaceWithInternal, 'jsii-calc/implements_interface_with_internal') + Jsii::Object.register_autoload("jsii-calc.ImplementsInterfaceWithInternal", 'jsii-calc/implements_interface_with_internal') + JsiiCalc.autoload(:ImplementsInterfaceWithInternalSubclass, 'jsii-calc/implements_interface_with_internal_subclass') + Jsii::Object.register_autoload("jsii-calc.ImplementsInterfaceWithInternalSubclass", 'jsii-calc/implements_interface_with_internal_subclass') + JsiiCalc.autoload(:ImplementsPrivateInterface, 'jsii-calc/implements_private_interface') + Jsii::Object.register_autoload("jsii-calc.ImplementsPrivateInterface", 'jsii-calc/implements_private_interface') + JsiiCalc.autoload(:ImplictBaseOfBase, 'jsii-calc/implict_base_of_base') + Jsii::Object.register_autoload("jsii-calc.ImplictBaseOfBase", 'jsii-calc/implict_base_of_base') + JsiiCalc.autoload(:PublicClass, 'jsii-calc/public_class') + Jsii::Object.register_autoload("jsii-calc.PublicClass", 'jsii-calc/public_class') + JsiiCalc.autoload(:InbetweenClass, 'jsii-calc/inbetween_class') + Jsii::Object.register_autoload("jsii-calc.InbetweenClass", 'jsii-calc/inbetween_class') + JsiiCalc.autoload(:InterfaceCollections, 'jsii-calc/interface_collections') + Jsii::Object.register_autoload("jsii-calc.InterfaceCollections", 'jsii-calc/interface_collections') + JsiiCalc.autoload(:InterfacesMaker, 'jsii-calc/interfaces_maker') + Jsii::Object.register_autoload("jsii-calc.InterfacesMaker", 'jsii-calc/interfaces_maker') + JsiiCalc.autoload(:Isomorphism, 'jsii-calc/isomorphism') + Jsii::Object.register_autoload("jsii-calc.Isomorphism", 'jsii-calc/isomorphism') + JsiiCalc.autoload(:Issue2638, 'jsii-calc/issue2638') + Jsii::Object.register_autoload("jsii-calc.Issue2638", 'jsii-calc/issue2638') + JsiiCalc.autoload(:Issue2638B, 'jsii-calc/issue2638_b') + Jsii::Object.register_autoload("jsii-calc.Issue2638B", 'jsii-calc/issue2638_b') + JsiiCalc.autoload(:JSII417PublicBaseOfBase, 'jsii-calc/jsii417_public_base_of_base') + Jsii::Object.register_autoload("jsii-calc.JSII417PublicBaseOfBase", 'jsii-calc/jsii417_public_base_of_base') + JsiiCalc.autoload(:JSII417Derived, 'jsii-calc/jsii417_derived') + Jsii::Object.register_autoload("jsii-calc.JSII417Derived", 'jsii-calc/jsii417_derived') + JsiiCalc.autoload(:JSObjectLiteralForInterface, 'jsii-calc/js_object_literal_for_interface') + Jsii::Object.register_autoload("jsii-calc.JSObjectLiteralForInterface", 'jsii-calc/js_object_literal_for_interface') + JsiiCalc.autoload(:JSObjectLiteralToNative, 'jsii-calc/js_object_literal_to_native') + Jsii::Object.register_autoload("jsii-calc.JSObjectLiteralToNative", 'jsii-calc/js_object_literal_to_native') + JsiiCalc.autoload(:JSObjectLiteralToNativeClass, 'jsii-calc/js_object_literal_to_native_class') + Jsii::Object.register_autoload("jsii-calc.JSObjectLiteralToNativeClass", 'jsii-calc/js_object_literal_to_native_class') + JsiiCalc.autoload(:JavaReservedWords, 'jsii-calc/java_reserved_words') + Jsii::Object.register_autoload("jsii-calc.JavaReservedWords", 'jsii-calc/java_reserved_words') + JsiiCalc.autoload(:Jsii487Derived, 'jsii-calc/jsii487_derived') + Jsii::Object.register_autoload("jsii-calc.Jsii487Derived", 'jsii-calc/jsii487_derived') + JsiiCalc.autoload(:Jsii496Derived, 'jsii-calc/jsii496_derived') + Jsii::Object.register_autoload("jsii-calc.Jsii496Derived", 'jsii-calc/jsii496_derived') + JsiiCalc.autoload(:JsiiAgent, 'jsii-calc/jsii_agent') + Jsii::Object.register_autoload("jsii-calc.JsiiAgent", 'jsii-calc/jsii_agent') + JsiiCalc.autoload(:JsonFormatter, 'jsii-calc/json_formatter') + Jsii::Object.register_autoload("jsii-calc.JsonFormatter", 'jsii-calc/json_formatter') + JsiiCalc.autoload(:LevelOne, 'jsii-calc/level_one') + Jsii::Object.register_autoload("jsii-calc.LevelOne", 'jsii-calc/level_one') + Jsii::Object.register_autoload("jsii-calc.LevelOne.PropBooleanValue", 'jsii-calc/level_one') + Jsii::Object.register_autoload("jsii-calc.LevelOne.PropProperty", 'jsii-calc/level_one') + JsiiCalc.autoload(:LevelOneProps, 'jsii-calc/level_one_props') + Jsii::Object.register_autoload("jsii-calc.LevelOneProps", 'jsii-calc/level_one_props') + JsiiCalc.autoload(:LoadBalancedFargateServiceProps, 'jsii-calc/load_balanced_fargate_service_props') + Jsii::Object.register_autoload("jsii-calc.LoadBalancedFargateServiceProps", 'jsii-calc/load_balanced_fargate_service_props') + JsiiCalc.autoload(:MethodNamedProperty, 'jsii-calc/method_named_property') + Jsii::Object.register_autoload("jsii-calc.MethodNamedProperty", 'jsii-calc/method_named_property') + JsiiCalc.autoload(:Multiply, 'jsii-calc/multiply') + Jsii::Object.register_autoload("jsii-calc.Multiply", 'jsii-calc/multiply') + JsiiCalc.autoload(:UnaryOperation, 'jsii-calc/unary_operation') + Jsii::Object.register_autoload("jsii-calc.UnaryOperation", 'jsii-calc/unary_operation') + JsiiCalc.autoload(:Negate, 'jsii-calc/negate') + Jsii::Object.register_autoload("jsii-calc.Negate", 'jsii-calc/negate') + JsiiCalc.autoload(:NestedClassInstance, 'jsii-calc/nested_class_instance') + Jsii::Object.register_autoload("jsii-calc.NestedClassInstance", 'jsii-calc/nested_class_instance') + JsiiCalc.autoload(:NestedStruct, 'jsii-calc/nested_struct') + Jsii::Object.register_autoload("jsii-calc.NestedStruct", 'jsii-calc/nested_struct') + JsiiCalc.autoload(:NodeStandardLibrary, 'jsii-calc/node_standard_library') + Jsii::Object.register_autoload("jsii-calc.NodeStandardLibrary", 'jsii-calc/node_standard_library') + JsiiCalc.autoload(:NullShouldBeTreatedAsUndefined, 'jsii-calc/null_should_be_treated_as_undefined') + Jsii::Object.register_autoload("jsii-calc.NullShouldBeTreatedAsUndefined", 'jsii-calc/null_should_be_treated_as_undefined') + JsiiCalc.autoload(:NullShouldBeTreatedAsUndefinedData, 'jsii-calc/null_should_be_treated_as_undefined_data') + Jsii::Object.register_autoload("jsii-calc.NullShouldBeTreatedAsUndefinedData", 'jsii-calc/null_should_be_treated_as_undefined_data') + JsiiCalc.autoload(:NumberGenerator, 'jsii-calc/number_generator') + Jsii::Object.register_autoload("jsii-calc.NumberGenerator", 'jsii-calc/number_generator') + JsiiCalc.autoload(:ObjectRefsInCollections, 'jsii-calc/object_refs_in_collections') + Jsii::Object.register_autoload("jsii-calc.ObjectRefsInCollections", 'jsii-calc/object_refs_in_collections') + JsiiCalc.autoload(:ObjectWithPropertyProvider, 'jsii-calc/object_with_property_provider') + Jsii::Object.register_autoload("jsii-calc.ObjectWithPropertyProvider", 'jsii-calc/object_with_property_provider') + JsiiCalc.autoload(:Old, 'jsii-calc/old') + Jsii::Object.register_autoload("jsii-calc.Old", 'jsii-calc/old') + JsiiCalc.autoload(:OptionalArgumentInvoker, 'jsii-calc/optional_argument_invoker') + Jsii::Object.register_autoload("jsii-calc.OptionalArgumentInvoker", 'jsii-calc/optional_argument_invoker') + JsiiCalc.autoload(:OptionalConstructorArgument, 'jsii-calc/optional_constructor_argument') + Jsii::Object.register_autoload("jsii-calc.OptionalConstructorArgument", 'jsii-calc/optional_constructor_argument') + JsiiCalc.autoload(:OptionalStruct, 'jsii-calc/optional_struct') + Jsii::Object.register_autoload("jsii-calc.OptionalStruct", 'jsii-calc/optional_struct') + JsiiCalc.autoload(:OptionalStructConsumer, 'jsii-calc/optional_struct_consumer') + Jsii::Object.register_autoload("jsii-calc.OptionalStructConsumer", 'jsii-calc/optional_struct_consumer') + JsiiCalc.autoload(:OverridableProtectedMember, 'jsii-calc/overridable_protected_member') + Jsii::Object.register_autoload("jsii-calc.OverridableProtectedMember", 'jsii-calc/overridable_protected_member') + JsiiCalc.autoload(:OverrideReturnsObject, 'jsii-calc/override_returns_object') + Jsii::Object.register_autoload("jsii-calc.OverrideReturnsObject", 'jsii-calc/override_returns_object') + JsiiCalc.autoload(:ParamShadowsBuiltins, 'jsii-calc/param_shadows_builtins') + Jsii::Object.register_autoload("jsii-calc.ParamShadowsBuiltins", 'jsii-calc/param_shadows_builtins') + JsiiCalc.autoload(:ParamShadowsBuiltinsProps, 'jsii-calc/param_shadows_builtins_props') + Jsii::Object.register_autoload("jsii-calc.ParamShadowsBuiltinsProps", 'jsii-calc/param_shadows_builtins_props') + JsiiCalc.autoload(:ParamShadowsScope, 'jsii-calc/param_shadows_scope') + Jsii::Object.register_autoload("jsii-calc.ParamShadowsScope", 'jsii-calc/param_shadows_scope') + JsiiCalc.autoload(:PartiallyInitializedThisConsumer, 'jsii-calc/partially_initialized_this_consumer') + Jsii::Object.register_autoload("jsii-calc.PartiallyInitializedThisConsumer", 'jsii-calc/partially_initialized_this_consumer') + JsiiCalc.autoload(:Polymorphism, 'jsii-calc/polymorphism') + Jsii::Object.register_autoload("jsii-calc.Polymorphism", 'jsii-calc/polymorphism') + JsiiCalc.autoload(:Power, 'jsii-calc/power') + Jsii::Object.register_autoload("jsii-calc.Power", 'jsii-calc/power') + JsiiCalc.autoload(:PromiseNothing, 'jsii-calc/promise_nothing') + Jsii::Object.register_autoload("jsii-calc.PromiseNothing", 'jsii-calc/promise_nothing') + JsiiCalc.autoload(:PropertyNamedProperty, 'jsii-calc/property_named_property') + Jsii::Object.register_autoload("jsii-calc.PropertyNamedProperty", 'jsii-calc/property_named_property') + JsiiCalc.autoload(:PythonReservedWords, 'jsii-calc/python_reserved_words') + Jsii::Object.register_autoload("jsii-calc.PythonReservedWords", 'jsii-calc/python_reserved_words') + JsiiCalc.autoload(:ReferenceEnumFromScopedPackage, 'jsii-calc/reference_enum_from_scoped_package') + Jsii::Object.register_autoload("jsii-calc.ReferenceEnumFromScopedPackage", 'jsii-calc/reference_enum_from_scoped_package') + JsiiCalc.autoload(:ReturnsPrivateImplementationOfInterface, 'jsii-calc/returns_private_implementation_of_interface') + Jsii::Object.register_autoload("jsii-calc.ReturnsPrivateImplementationOfInterface", 'jsii-calc/returns_private_implementation_of_interface') + JsiiCalc.autoload(:RootStruct, 'jsii-calc/root_struct') + Jsii::Object.register_autoload("jsii-calc.RootStruct", 'jsii-calc/root_struct') + JsiiCalc.autoload(:RootStructValidator, 'jsii-calc/root_struct_validator') + Jsii::Object.register_autoload("jsii-calc.RootStructValidator", 'jsii-calc/root_struct_validator') + JsiiCalc.autoload(:RuntimeTypeChecking, 'jsii-calc/runtime_type_checking') + Jsii::Object.register_autoload("jsii-calc.RuntimeTypeChecking", 'jsii-calc/runtime_type_checking') + JsiiCalc.autoload(:SecondLevelStruct, 'jsii-calc/second_level_struct') + Jsii::Object.register_autoload("jsii-calc.SecondLevelStruct", 'jsii-calc/second_level_struct') + JsiiCalc.autoload(:SingleInstanceTwoTypes, 'jsii-calc/single_instance_two_types') + Jsii::Object.register_autoload("jsii-calc.SingleInstanceTwoTypes", 'jsii-calc/single_instance_two_types') + JsiiCalc.autoload(:SingletonInt, 'jsii-calc/singleton_int') + Jsii::Object.register_autoload("jsii-calc.SingletonInt", 'jsii-calc/singleton_int') + JsiiCalc.autoload(:SingletonIntEnum, 'jsii-calc/singleton_int_enum') + Jsii::Object.register_autoload("jsii-calc.SingletonIntEnum", 'jsii-calc/singleton_int_enum') + JsiiCalc.autoload(:SingletonString, 'jsii-calc/singleton_string') + Jsii::Object.register_autoload("jsii-calc.SingletonString", 'jsii-calc/singleton_string') + JsiiCalc.autoload(:SingletonStringEnum, 'jsii-calc/singleton_string_enum') + Jsii::Object.register_autoload("jsii-calc.SingletonStringEnum", 'jsii-calc/singleton_string_enum') + JsiiCalc.autoload(:SmellyStruct, 'jsii-calc/smelly_struct') + Jsii::Object.register_autoload("jsii-calc.SmellyStruct", 'jsii-calc/smelly_struct') + JsiiCalc.autoload(:SomeContainingClass, 'jsii-calc/some_containing_class') + Jsii::Object.register_autoload("jsii-calc.SomeContainingClass", 'jsii-calc/some_containing_class') + Jsii::Object.register_autoload("jsii-calc.SomeContainingClass.ParentStruct", 'jsii-calc/some_containing_class') + Jsii::Object.register_autoload("jsii-calc.SomeContainingClass.ChildStruct", 'jsii-calc/some_containing_class') + JsiiCalc.autoload(:SomeTypeJsii976, 'jsii-calc/some_type_jsii976') + Jsii::Object.register_autoload("jsii-calc.SomeTypeJsii976", 'jsii-calc/some_type_jsii976') + JsiiCalc.autoload(:StableClass, 'jsii-calc/stable_class') + Jsii::Object.register_autoload("jsii-calc.StableClass", 'jsii-calc/stable_class') + JsiiCalc.autoload(:StableEnum, 'jsii-calc/stable_enum') + Jsii::Object.register_autoload("jsii-calc.StableEnum", 'jsii-calc/stable_enum') + JsiiCalc.autoload(:StableStruct, 'jsii-calc/stable_struct') + Jsii::Object.register_autoload("jsii-calc.StableStruct", 'jsii-calc/stable_struct') + JsiiCalc.autoload(:StaticContext, 'jsii-calc/static_context') + Jsii::Object.register_autoload("jsii-calc.StaticContext", 'jsii-calc/static_context') + JsiiCalc.autoload(:StaticHelloParent, 'jsii-calc/static_hello_parent') + Jsii::Object.register_autoload("jsii-calc.StaticHelloParent", 'jsii-calc/static_hello_parent') + JsiiCalc.autoload(:StaticHelloChild, 'jsii-calc/static_hello_child') + Jsii::Object.register_autoload("jsii-calc.StaticHelloChild", 'jsii-calc/static_hello_child') + JsiiCalc.autoload(:Statics, 'jsii-calc/statics') + Jsii::Object.register_autoload("jsii-calc.Statics", 'jsii-calc/statics') + JsiiCalc.autoload(:StringEnum, 'jsii-calc/string_enum') + Jsii::Object.register_autoload("jsii-calc.StringEnum", 'jsii-calc/string_enum') + JsiiCalc.autoload(:Stringable, 'jsii-calc/stringable') + Jsii::Object.register_autoload("jsii-calc.Stringable", 'jsii-calc/stringable') + JsiiCalc.autoload(:StripInternal, 'jsii-calc/strip_internal') + Jsii::Object.register_autoload("jsii-calc.StripInternal", 'jsii-calc/strip_internal') + JsiiCalc.autoload(:StructA, 'jsii-calc/struct_a') + Jsii::Object.register_autoload("jsii-calc.StructA", 'jsii-calc/struct_a') + JsiiCalc.autoload(:StructB, 'jsii-calc/struct_b') + Jsii::Object.register_autoload("jsii-calc.StructB", 'jsii-calc/struct_b') + JsiiCalc.autoload(:StructParameterType, 'jsii-calc/struct_parameter_type') + Jsii::Object.register_autoload("jsii-calc.StructParameterType", 'jsii-calc/struct_parameter_type') + JsiiCalc.autoload(:StructPassing, 'jsii-calc/struct_passing') + Jsii::Object.register_autoload("jsii-calc.StructPassing", 'jsii-calc/struct_passing') + JsiiCalc.autoload(:StructUnionConsumer, 'jsii-calc/struct_union_consumer') + Jsii::Object.register_autoload("jsii-calc.StructUnionConsumer", 'jsii-calc/struct_union_consumer') + JsiiCalc.autoload(:StructWithCollectionOfUnionts, 'jsii-calc/struct_with_collection_of_unionts') + Jsii::Object.register_autoload("jsii-calc.StructWithCollectionOfUnionts", 'jsii-calc/struct_with_collection_of_unionts') + JsiiCalc.autoload(:StructWithEnum, 'jsii-calc/struct_with_enum') + Jsii::Object.register_autoload("jsii-calc.StructWithEnum", 'jsii-calc/struct_with_enum') + JsiiCalc.autoload(:StructWithJavaReservedWords, 'jsii-calc/struct_with_java_reserved_words') + Jsii::Object.register_autoload("jsii-calc.StructWithJavaReservedWords", 'jsii-calc/struct_with_java_reserved_words') + JsiiCalc.autoload(:Sum, 'jsii-calc/sum') + Jsii::Object.register_autoload("jsii-calc.Sum", 'jsii-calc/sum') + JsiiCalc.autoload(:SupportsNiceJavaBuilderWithRequiredProps, 'jsii-calc/supports_nice_java_builder_with_required_props') + Jsii::Object.register_autoload("jsii-calc.SupportsNiceJavaBuilderWithRequiredProps", 'jsii-calc/supports_nice_java_builder_with_required_props') + JsiiCalc.autoload(:SupportsNiceJavaBuilder, 'jsii-calc/supports_nice_java_builder') + Jsii::Object.register_autoload("jsii-calc.SupportsNiceJavaBuilder", 'jsii-calc/supports_nice_java_builder') + JsiiCalc.autoload(:SupportsNiceJavaBuilderProps, 'jsii-calc/supports_nice_java_builder_props') + Jsii::Object.register_autoload("jsii-calc.SupportsNiceJavaBuilderProps", 'jsii-calc/supports_nice_java_builder_props') + JsiiCalc.autoload(:SyncOverrideExtraArgs, 'jsii-calc/sync_override_extra_args') + Jsii::Object.register_autoload("jsii-calc.SyncOverrideExtraArgs", 'jsii-calc/sync_override_extra_args') + JsiiCalc.autoload(:SyncVirtualMethods, 'jsii-calc/sync_virtual_methods') + Jsii::Object.register_autoload("jsii-calc.SyncVirtualMethods", 'jsii-calc/sync_virtual_methods') + JsiiCalc.autoload(:TestStructWithEnum, 'jsii-calc/test_struct_with_enum') + Jsii::Object.register_autoload("jsii-calc.TestStructWithEnum", 'jsii-calc/test_struct_with_enum') + JsiiCalc.autoload(:Thrower, 'jsii-calc/thrower') + Jsii::Object.register_autoload("jsii-calc.Thrower", 'jsii-calc/thrower') + JsiiCalc.autoload(:TopLevelStruct, 'jsii-calc/top_level_struct') + Jsii::Object.register_autoload("jsii-calc.TopLevelStruct", 'jsii-calc/top_level_struct') + JsiiCalc.autoload(:TwoMethodsWithSimilarCapitalization, 'jsii-calc/two_methods_with_similar_capitalization') + Jsii::Object.register_autoload("jsii-calc.TwoMethodsWithSimilarCapitalization", 'jsii-calc/two_methods_with_similar_capitalization') + JsiiCalc.autoload(:UmaskCheck, 'jsii-calc/umask_check') + Jsii::Object.register_autoload("jsii-calc.UmaskCheck", 'jsii-calc/umask_check') + JsiiCalc.autoload(:UnionProperties, 'jsii-calc/union_properties') + Jsii::Object.register_autoload("jsii-calc.UnionProperties", 'jsii-calc/union_properties') + JsiiCalc.autoload(:UpcasingReflectable, 'jsii-calc/upcasing_reflectable') + Jsii::Object.register_autoload("jsii-calc.UpcasingReflectable", 'jsii-calc/upcasing_reflectable') + JsiiCalc.autoload(:UseBundledDependency, 'jsii-calc/use_bundled_dependency') + Jsii::Object.register_autoload("jsii-calc.UseBundledDependency", 'jsii-calc/use_bundled_dependency') + JsiiCalc.autoload(:UseCalcBase, 'jsii-calc/use_calc_base') + Jsii::Object.register_autoload("jsii-calc.UseCalcBase", 'jsii-calc/use_calc_base') + JsiiCalc.autoload(:UsesInterfaceWithProperties, 'jsii-calc/uses_interface_with_properties') + Jsii::Object.register_autoload("jsii-calc.UsesInterfaceWithProperties", 'jsii-calc/uses_interface_with_properties') + JsiiCalc.autoload(:VariadicInvoker, 'jsii-calc/variadic_invoker') + Jsii::Object.register_autoload("jsii-calc.VariadicInvoker", 'jsii-calc/variadic_invoker') + JsiiCalc.autoload(:VariadicMethod, 'jsii-calc/variadic_method') + Jsii::Object.register_autoload("jsii-calc.VariadicMethod", 'jsii-calc/variadic_method') + JsiiCalc.autoload(:VariadicTypeUnion, 'jsii-calc/variadic_type_union') + Jsii::Object.register_autoload("jsii-calc.VariadicTypeUnion", 'jsii-calc/variadic_type_union') + JsiiCalc.autoload(:VirtualMethodPlayground, 'jsii-calc/virtual_method_playground') + Jsii::Object.register_autoload("jsii-calc.VirtualMethodPlayground", 'jsii-calc/virtual_method_playground') + JsiiCalc.autoload(:VoidCallback, 'jsii-calc/void_callback') + Jsii::Object.register_autoload("jsii-calc.VoidCallback", 'jsii-calc/void_callback') + JsiiCalc.autoload(:WeirdDocs, 'jsii-calc/weird_docs') + Jsii::Object.register_autoload("jsii-calc.WeirdDocs", 'jsii-calc/weird_docs') + JsiiCalc.autoload(:WithPrivatePropertyInConstructor, 'jsii-calc/with_private_property_in_constructor') + Jsii::Object.register_autoload("jsii-calc.WithPrivatePropertyInConstructor", 'jsii-calc/with_private_property_in_constructor') + JsiiCalc::DerivedClassHasNoProperties.autoload(:Base, 'jsii-calc/derived_class_has_no_properties/base') + Jsii::Object.register_autoload("jsii-calc.DerivedClassHasNoProperties.Base", 'jsii-calc/derived_class_has_no_properties/base') + JsiiCalc::DerivedClassHasNoProperties.autoload(:Derived, 'jsii-calc/derived_class_has_no_properties/derived') + Jsii::Object.register_autoload("jsii-calc.DerivedClassHasNoProperties.Derived", 'jsii-calc/derived_class_has_no_properties/derived') + JsiiCalc::InterfaceInNamespaceIncludesClasses.autoload(:Foo, 'jsii-calc/interface_in_namespace_includes_classes/foo') + Jsii::Object.register_autoload("jsii-calc.InterfaceInNamespaceIncludesClasses.Foo", 'jsii-calc/interface_in_namespace_includes_classes/foo') + JsiiCalc::InterfaceInNamespaceIncludesClasses.autoload(:Hello, 'jsii-calc/interface_in_namespace_includes_classes/hello') + Jsii::Object.register_autoload("jsii-calc.InterfaceInNamespaceIncludesClasses.Hello", 'jsii-calc/interface_in_namespace_includes_classes/hello') + JsiiCalc::InterfaceInNamespaceOnlyInterface.autoload(:Hello, 'jsii-calc/interface_in_namespace_only_interface/hello') + Jsii::Object.register_autoload("jsii-calc.InterfaceInNamespaceOnlyInterface.Hello", 'jsii-calc/interface_in_namespace_only_interface/hello') + JsiiCalc::PythonSelf.autoload(:ClassWithSelf, 'jsii-calc/python_self/class_with_self') + Jsii::Object.register_autoload("jsii-calc.PythonSelf.ClassWithSelf", 'jsii-calc/python_self/class_with_self') + JsiiCalc::PythonSelf.autoload(:ClassWithSelfKwarg, 'jsii-calc/python_self/class_with_self_kwarg') + Jsii::Object.register_autoload("jsii-calc.PythonSelf.ClassWithSelfKwarg", 'jsii-calc/python_self/class_with_self_kwarg') + JsiiCalc::PythonSelf.autoload(:IInterfaceWithSelf, 'jsii-calc/python_self/i_interface_with_self') + Jsii::Object.register_autoload("jsii-calc.PythonSelf.IInterfaceWithSelf", 'jsii-calc/python_self/i_interface_with_self') + JsiiCalc::PythonSelf.autoload(:StructWithSelf, 'jsii-calc/python_self/struct_with_self') + Jsii::Object.register_autoload("jsii-calc.PythonSelf.StructWithSelf", 'jsii-calc/python_self/struct_with_self') + JsiiCalc::Anonymous.autoload(:IOptionA, 'jsii-calc/anonymous/i_option_a') + Jsii::Object.register_autoload("jsii-calc.anonymous.IOptionA", 'jsii-calc/anonymous/i_option_a') + JsiiCalc::Anonymous.autoload(:IOptionB, 'jsii-calc/anonymous/i_option_b') + Jsii::Object.register_autoload("jsii-calc.anonymous.IOptionB", 'jsii-calc/anonymous/i_option_b') + JsiiCalc::Anonymous.autoload(:UseOptions, 'jsii-calc/anonymous/use_options') + Jsii::Object.register_autoload("jsii-calc.anonymous.UseOptions", 'jsii-calc/anonymous/use_options') + JsiiCalc::Cdk16625.autoload(:Cdk16625, 'jsii-calc/cdk16625/cdk16625') + Jsii::Object.register_autoload("jsii-calc.cdk16625.Cdk16625", 'jsii-calc/cdk16625/cdk16625') + JsiiCalc::Cdk16625::Donotimport.autoload(:UnimportedSubmoduleType, 'jsii-calc/cdk16625/donotimport/unimported_submodule_type') + Jsii::Object.register_autoload("jsii-calc.cdk16625.donotimport.UnimportedSubmoduleType", 'jsii-calc/cdk16625/donotimport/unimported_submodule_type') + JsiiCalc::Cdk22369.autoload(:AcceptsPath, 'jsii-calc/cdk22369/accepts_path') + Jsii::Object.register_autoload("jsii-calc.cdk22369.AcceptsPath", 'jsii-calc/cdk22369/accepts_path') + JsiiCalc::Cdk22369.autoload(:AcceptsPathProps, 'jsii-calc/cdk22369/accepts_path_props') + Jsii::Object.register_autoload("jsii-calc.cdk22369.AcceptsPathProps", 'jsii-calc/cdk22369/accepts_path_props') + JsiiCalc::CovariantOverrides::ClassOverrides.autoload(:IBase, 'jsii-calc/covariant_overrides/class_overrides/i_base') + Jsii::Object.register_autoload("jsii-calc.covariantOverrides.classOverrides.IBase", 'jsii-calc/covariant_overrides/class_overrides/i_base') + JsiiCalc::CovariantOverrides::ClassOverrides.autoload(:Base, 'jsii-calc/covariant_overrides/class_overrides/base') + Jsii::Object.register_autoload("jsii-calc.covariantOverrides.classOverrides.Base", 'jsii-calc/covariant_overrides/class_overrides/base') + JsiiCalc::CovariantOverrides::ClassOverrides.autoload(:Middle, 'jsii-calc/covariant_overrides/class_overrides/middle') + Jsii::Object.register_autoload("jsii-calc.covariantOverrides.classOverrides.Middle", 'jsii-calc/covariant_overrides/class_overrides/middle') + JsiiCalc::CovariantOverrides::ClassOverrides.autoload(:Derived, 'jsii-calc/covariant_overrides/class_overrides/derived') + Jsii::Object.register_autoload("jsii-calc.covariantOverrides.classOverrides.Derived", 'jsii-calc/covariant_overrides/class_overrides/derived') + JsiiCalc::CovariantOverrides::ClassOverrides.autoload(:Superclass, 'jsii-calc/covariant_overrides/class_overrides/superclass') + Jsii::Object.register_autoload("jsii-calc.covariantOverrides.classOverrides.Superclass", 'jsii-calc/covariant_overrides/class_overrides/superclass') + JsiiCalc::CovariantOverrides::ClassOverrides.autoload(:Subclass, 'jsii-calc/covariant_overrides/class_overrides/subclass') + Jsii::Object.register_autoload("jsii-calc.covariantOverrides.classOverrides.Subclass", 'jsii-calc/covariant_overrides/class_overrides/subclass') + JsiiCalc::CovariantOverrides::ClassOverrides.autoload(:SubSubclass, 'jsii-calc/covariant_overrides/class_overrides/sub_subclass') + Jsii::Object.register_autoload("jsii-calc.covariantOverrides.classOverrides.SubSubclass", 'jsii-calc/covariant_overrides/class_overrides/sub_subclass') + JsiiCalc::HomonymousForwardReferences::Bar.autoload(:Consumer, 'jsii-calc/homonymous_forward_references/bar/consumer') + Jsii::Object.register_autoload("jsii-calc.homonymousForwardReferences.bar.Consumer", 'jsii-calc/homonymous_forward_references/bar/consumer') + JsiiCalc::HomonymousForwardReferences::Bar.autoload(:ConsumerProps, 'jsii-calc/homonymous_forward_references/bar/consumer_props') + Jsii::Object.register_autoload("jsii-calc.homonymousForwardReferences.bar.ConsumerProps", 'jsii-calc/homonymous_forward_references/bar/consumer_props') + JsiiCalc::HomonymousForwardReferences::Bar.autoload(:Homonymous, 'jsii-calc/homonymous_forward_references/bar/homonymous') + Jsii::Object.register_autoload("jsii-calc.homonymousForwardReferences.bar.Homonymous", 'jsii-calc/homonymous_forward_references/bar/homonymous') + JsiiCalc::HomonymousForwardReferences::Foo.autoload(:Consumer, 'jsii-calc/homonymous_forward_references/foo/consumer') + Jsii::Object.register_autoload("jsii-calc.homonymousForwardReferences.foo.Consumer", 'jsii-calc/homonymous_forward_references/foo/consumer') + JsiiCalc::HomonymousForwardReferences::Foo.autoload(:ConsumerProps, 'jsii-calc/homonymous_forward_references/foo/consumer_props') + Jsii::Object.register_autoload("jsii-calc.homonymousForwardReferences.foo.ConsumerProps", 'jsii-calc/homonymous_forward_references/foo/consumer_props') + JsiiCalc::HomonymousForwardReferences::Foo.autoload(:Homonymous, 'jsii-calc/homonymous_forward_references/foo/homonymous') + Jsii::Object.register_autoload("jsii-calc.homonymousForwardReferences.foo.Homonymous", 'jsii-calc/homonymous_forward_references/foo/homonymous') + JsiiCalc::Intersection.autoload(:ConsumesIntersection, 'jsii-calc/intersection/consumes_intersection') + Jsii::Object.register_autoload("jsii-calc.intersection.ConsumesIntersection", 'jsii-calc/intersection/consumes_intersection') + JsiiCalc::Intersection.autoload(:ISomething, 'jsii-calc/intersection/i_something') + Jsii::Object.register_autoload("jsii-calc.intersection.ISomething", 'jsii-calc/intersection/i_something') + JsiiCalc::Intersection.autoload(:IntersectionProps, 'jsii-calc/intersection/intersection_props') + Jsii::Object.register_autoload("jsii-calc.intersection.IntersectionProps", 'jsii-calc/intersection/intersection_props') + JsiiCalc::Jsii3656.autoload(:ImplementMeOpts, 'jsii-calc/jsii3656/implement_me_opts') + Jsii::Object.register_autoload("jsii-calc.jsii3656.ImplementMeOpts", 'jsii-calc/jsii3656/implement_me_opts') + JsiiCalc::Jsii3656.autoload(:OverrideMe, 'jsii-calc/jsii3656/override_me') + Jsii::Object.register_autoload("jsii-calc.jsii3656.OverrideMe", 'jsii-calc/jsii3656/override_me') + JsiiCalc::Jsii4894.autoload(:NonPascalCaseTest, 'jsii-calc/jsii4894/non_pascal_case_test') + Jsii::Object.register_autoload("jsii-calc.jsii4894.NonPascalCaseTest", 'jsii-calc/jsii4894/non_pascal_case_test') + JsiiCalc::Jsii4894.autoload(:NonPascalCaseTestProps, 'jsii-calc/jsii4894/non_pascal_case_test_props') + Jsii::Object.register_autoload("jsii-calc.jsii4894.NonPascalCaseTestProps", 'jsii-calc/jsii4894/non_pascal_case_test_props') + JsiiCalc::Module2530.autoload(:MyClass, 'jsii-calc/module2530/my_class') + Jsii::Object.register_autoload("jsii-calc.module2530.MyClass", 'jsii-calc/module2530/my_class') + JsiiCalc::Module2617.autoload(:OnlyStatics, 'jsii-calc/module2617/only_statics') + Jsii::Object.register_autoload("jsii-calc.module2617.OnlyStatics", 'jsii-calc/module2617/only_statics') + JsiiCalc::Module2647.autoload(:ExtendAndImplement, 'jsii-calc/module2647/extend_and_implement') + Jsii::Object.register_autoload("jsii-calc.module2647.ExtendAndImplement", 'jsii-calc/module2647/extend_and_implement') + JsiiCalc::Module2689::Methods.autoload(:MyClass, 'jsii-calc/module2689/methods/my_class') + Jsii::Object.register_autoload("jsii-calc.module2689.methods.MyClass", 'jsii-calc/module2689/methods/my_class') + JsiiCalc::Module2689::Props.autoload(:MyClass, 'jsii-calc/module2689/props/my_class') + Jsii::Object.register_autoload("jsii-calc.module2689.props.MyClass", 'jsii-calc/module2689/props/my_class') + JsiiCalc::Module2689::Retval.autoload(:MyClass, 'jsii-calc/module2689/retval/my_class') + Jsii::Object.register_autoload("jsii-calc.module2689.retval.MyClass", 'jsii-calc/module2689/retval/my_class') + JsiiCalc::Module2689::Structs.autoload(:MyStruct, 'jsii-calc/module2689/structs/my_struct') + Jsii::Object.register_autoload("jsii-calc.module2689.structs.MyStruct", 'jsii-calc/module2689/structs/my_struct') + JsiiCalc::Module2692::Submodule1.autoload(:Bar, 'jsii-calc/module2692/submodule1/bar') + Jsii::Object.register_autoload("jsii-calc.module2692.submodule1.Bar", 'jsii-calc/module2692/submodule1/bar') + JsiiCalc::Module2692::Submodule2.autoload(:Bar, 'jsii-calc/module2692/submodule2/bar') + Jsii::Object.register_autoload("jsii-calc.module2692.submodule2.Bar", 'jsii-calc/module2692/submodule2/bar') + JsiiCalc::Module2692::Submodule2.autoload(:Foo, 'jsii-calc/module2692/submodule2/foo') + Jsii::Object.register_autoload("jsii-calc.module2692.submodule2.Foo", 'jsii-calc/module2692/submodule2/foo') + JsiiCalc::Module2700.autoload(:IFoo, 'jsii-calc/module2700/i_foo') + Jsii::Object.register_autoload("jsii-calc.module2700.IFoo", 'jsii-calc/module2700/i_foo') + JsiiCalc::Module2700.autoload(:Base, 'jsii-calc/module2700/base') + Jsii::Object.register_autoload("jsii-calc.module2700.Base", 'jsii-calc/module2700/base') + JsiiCalc::Module2700.autoload(:Derived, 'jsii-calc/module2700/derived') + Jsii::Object.register_autoload("jsii-calc.module2700.Derived", 'jsii-calc/module2700/derived') + JsiiCalc::Module2702.autoload(:Class3, 'jsii-calc/module2702/class3') + Jsii::Object.register_autoload("jsii-calc.module2702.Class3", 'jsii-calc/module2702/class3') + JsiiCalc::Module2702.autoload(:IBaz, 'jsii-calc/module2702/i_baz') + Jsii::Object.register_autoload("jsii-calc.module2702.IBaz", 'jsii-calc/module2702/i_baz') + JsiiCalc::Module2702.autoload(:Baz, 'jsii-calc/module2702/baz') + Jsii::Object.register_autoload("jsii-calc.module2702.Baz", 'jsii-calc/module2702/baz') + JsiiCalc::Module2702.autoload(:Class1, 'jsii-calc/module2702/class1') + Jsii::Object.register_autoload("jsii-calc.module2702.Class1", 'jsii-calc/module2702/class1') + JsiiCalc::Module2702.autoload(:Class2, 'jsii-calc/module2702/class2') + Jsii::Object.register_autoload("jsii-calc.module2702.Class2", 'jsii-calc/module2702/class2') + JsiiCalc::Module2702.autoload(:IConstruct, 'jsii-calc/module2702/i_construct') + Jsii::Object.register_autoload("jsii-calc.module2702.IConstruct", 'jsii-calc/module2702/i_construct') + JsiiCalc::Module2702.autoload(:Construct, 'jsii-calc/module2702/construct') + Jsii::Object.register_autoload("jsii-calc.module2702.Construct", 'jsii-calc/module2702/construct') + JsiiCalc::Module2702.autoload(:IFoo, 'jsii-calc/module2702/i_foo') + Jsii::Object.register_autoload("jsii-calc.module2702.IFoo", 'jsii-calc/module2702/i_foo') + JsiiCalc::Module2702.autoload(:IResource, 'jsii-calc/module2702/i_resource') + Jsii::Object.register_autoload("jsii-calc.module2702.IResource", 'jsii-calc/module2702/i_resource') + JsiiCalc::Module2702.autoload(:IVpc, 'jsii-calc/module2702/i_vpc') + Jsii::Object.register_autoload("jsii-calc.module2702.IVpc", 'jsii-calc/module2702/i_vpc') + JsiiCalc::Module2702.autoload(:Resource, 'jsii-calc/module2702/resource') + Jsii::Object.register_autoload("jsii-calc.module2702.Resource", 'jsii-calc/module2702/resource') + JsiiCalc::Module2702.autoload(:Vpc, 'jsii-calc/module2702/vpc') + Jsii::Object.register_autoload("jsii-calc.module2702.Vpc", 'jsii-calc/module2702/vpc') + JsiiCalc::Nodirect::Sub1.autoload(:TypeFromSub1, 'jsii-calc/nodirect/sub1/type_from_sub1') + Jsii::Object.register_autoload("jsii-calc.nodirect.sub1.TypeFromSub1", 'jsii-calc/nodirect/sub1/type_from_sub1') + JsiiCalc::Nodirect::Sub2.autoload(:TypeFromSub2, 'jsii-calc/nodirect/sub2/type_from_sub2') + Jsii::Object.register_autoload("jsii-calc.nodirect.sub2.TypeFromSub2", 'jsii-calc/nodirect/sub2/type_from_sub2') + JsiiCalc::Onlystatic.autoload(:OnlyStaticMethods, 'jsii-calc/onlystatic/only_static_methods') + Jsii::Object.register_autoload("jsii-calc.onlystatic.OnlyStaticMethods", 'jsii-calc/onlystatic/only_static_methods') + JsiiCalc::PascalCaseName.autoload(:Superclass, 'jsii-calc/pascal_case_name/superclass') + Jsii::Object.register_autoload("jsii-calc.pascalCaseName.Superclass", 'jsii-calc/pascal_case_name/superclass') + JsiiCalc::PascalCaseName.autoload(:Subclass, 'jsii-calc/pascal_case_name/subclass') + Jsii::Object.register_autoload("jsii-calc.pascalCaseName.Subclass", 'jsii-calc/pascal_case_name/subclass') + JsiiCalc::PascalCaseName.autoload(:SubSubclass, 'jsii-calc/pascal_case_name/sub_subclass') + Jsii::Object.register_autoload("jsii-calc.pascalCaseName.SubSubclass", 'jsii-calc/pascal_case_name/sub_subclass') + JsiiCalc::Submodule.autoload(:Default, 'jsii-calc/submodule/default') + Jsii::Object.register_autoload("jsii-calc.submodule.Default", 'jsii-calc/submodule/default') + JsiiCalc::Submodule::NestedSubmodule::DeeplyNested.autoload(:INamespaced, 'jsii-calc/submodule/nested_submodule/deeply_nested/i_namespaced') + Jsii::Object.register_autoload("jsii-calc.submodule.nested_submodule.deeplyNested.INamespaced", 'jsii-calc/submodule/nested_submodule/deeply_nested/i_namespaced') + JsiiCalc::Submodule.autoload(:MyClass, 'jsii-calc/submodule/my_class') + Jsii::Object.register_autoload("jsii-calc.submodule.MyClass", 'jsii-calc/submodule/my_class') + JsiiCalc::Submodule::BackReferences.autoload(:MyClassReference, 'jsii-calc/submodule/back_references/my_class_reference') + Jsii::Object.register_autoload("jsii-calc.submodule.back_references.MyClassReference", 'jsii-calc/submodule/back_references/my_class_reference') + JsiiCalc::Submodule::Child.autoload(:Awesomeness, 'jsii-calc/submodule/child/awesomeness') + Jsii::Object.register_autoload("jsii-calc.submodule.child.Awesomeness", 'jsii-calc/submodule/child/awesomeness') + JsiiCalc::Submodule::Child.autoload(:Goodness, 'jsii-calc/submodule/child/goodness') + Jsii::Object.register_autoload("jsii-calc.submodule.child.Goodness", 'jsii-calc/submodule/child/goodness') + JsiiCalc::Submodule::Child.autoload(:InnerClass, 'jsii-calc/submodule/child/inner_class') + Jsii::Object.register_autoload("jsii-calc.submodule.child.InnerClass", 'jsii-calc/submodule/child/inner_class') + JsiiCalc::Submodule::Child.autoload(:SomeStruct, 'jsii-calc/submodule/child/some_struct') + Jsii::Object.register_autoload("jsii-calc.submodule.child.SomeStruct", 'jsii-calc/submodule/child/some_struct') + JsiiCalc::Submodule::Child.autoload(:KwargsProps, 'jsii-calc/submodule/child/kwargs_props') + Jsii::Object.register_autoload("jsii-calc.submodule.child.KwargsProps", 'jsii-calc/submodule/child/kwargs_props') + JsiiCalc::Submodule::Child.autoload(:OuterClass, 'jsii-calc/submodule/child/outer_class') + Jsii::Object.register_autoload("jsii-calc.submodule.child.OuterClass", 'jsii-calc/submodule/child/outer_class') + JsiiCalc::Submodule::Child.autoload(:SomeEnum, 'jsii-calc/submodule/child/some_enum') + Jsii::Object.register_autoload("jsii-calc.submodule.child.SomeEnum", 'jsii-calc/submodule/child/some_enum') + JsiiCalc::Submodule::Child.autoload(:Structure, 'jsii-calc/submodule/child/structure') + Jsii::Object.register_autoload("jsii-calc.submodule.child.Structure", 'jsii-calc/submodule/child/structure') + JsiiCalc::Submodule::Isolated.autoload(:Kwargs, 'jsii-calc/submodule/isolated/kwargs') + Jsii::Object.register_autoload("jsii-calc.submodule.isolated.Kwargs", 'jsii-calc/submodule/isolated/kwargs') + JsiiCalc::Submodule::NestedSubmodule.autoload(:Namespaced, 'jsii-calc/submodule/nested_submodule/namespaced') + Jsii::Object.register_autoload("jsii-calc.submodule.nested_submodule.Namespaced", 'jsii-calc/submodule/nested_submodule/namespaced') + JsiiCalc::Submodule::Param.autoload(:SpecialParameter, 'jsii-calc/submodule/param/special_parameter') + Jsii::Object.register_autoload("jsii-calc.submodule.param.SpecialParameter", 'jsii-calc/submodule/param/special_parameter') + JsiiCalc::Submodule::Returnsparam.autoload(:ReturnsSpecialParameter, 'jsii-calc/submodule/returnsparam/returns_special_parameter') + Jsii::Object.register_autoload("jsii-calc.submodule.returnsparam.ReturnsSpecialParameter", 'jsii-calc/submodule/returnsparam/returns_special_parameter') + JsiiCalc::Union.autoload(:ConsumesUnion, 'jsii-calc/union/consumes_union') + Jsii::Object.register_autoload("jsii-calc.union.ConsumesUnion", 'jsii-calc/union/consumes_union') + JsiiCalc::Union.autoload(:IResolvable, 'jsii-calc/union/i_resolvable') + Jsii::Object.register_autoload("jsii-calc.union.IResolvable", 'jsii-calc/union/i_resolvable') + JsiiCalc::Union.autoload(:Resolvable, 'jsii-calc/union/resolvable') + Jsii::Object.register_autoload("jsii-calc.union.Resolvable", 'jsii-calc/union/resolvable') +end + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/_readme.rb 1`] = ` +# # jsii Calculator +# +# This library is used to demonstrate and test the features of JSII +# +# ## How to use running sum API: +# +# First, create a calculator: +# +# \`\`\`ruby +# const calculator = new calc.Calculator(); +# \`\`\` +# +# Then call some operations: +# +# \`\`\`ruby +# calculator.add(10); +# \`\`\` +# +# ## Code Samples +# +# \`\`\`ruby +# /* This is totes a magic comment in here, just you wait! */ +# const foo = 'bar'; +# \`\`\` +module JsiiCalc; end + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/abstract_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::AbstractClass < ::JsiiCalc::AbstractClassBase + include ::JsiiCalc::IInterfaceImplementedByAbstractClass + self.jsii_fqn = "jsii-calc.AbstractClass" + Jsii::Object.register_jsii_fqn("jsii-calc.AbstractClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :abstract_property => { kind: :property, name: "abstractProperty", is_optional: false }, + :prop_from_interface => { kind: :property, name: "propFromInterface", is_optional: false }, + :abstract_method => { kind: :method, name: "abstractMethod", is_optional: false }, + :non_abstract_method => { kind: :method, name: "nonAbstractMethod", is_optional: false }, + } + end + + # @return [String] + def abstract_property() + jsii_get_property("abstractProperty") + end + + # @return [String] + def prop_from_interface() + jsii_get_property("propFromInterface") + end + + # @param name [String] + # @return [String] + def abstract_method(name) + jsii_call_method("abstractMethod", [name]) + end + + # @return [Numeric] + def non_abstract_method() + jsii_call_method("nonAbstractMethod", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/abstract_class_base.rb 1`] = ` +require 'jsii' + +class JsiiCalc::AbstractClassBase < Jsii::Object + self.jsii_fqn = "jsii-calc.AbstractClassBase" + Jsii::Object.register_jsii_fqn("jsii-calc.AbstractClassBase", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :abstract_property => { kind: :property, name: "abstractProperty", is_optional: false }, + } + end + + # @return [String] + def abstract_property() + jsii_get_property("abstractProperty") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/abstract_class_returner.rb 1`] = ` +require 'jsii' + +class JsiiCalc::AbstractClassReturner < Jsii::Object + self.jsii_fqn = "jsii-calc.AbstractClassReturner" + Jsii::Object.register_jsii_fqn("jsii-calc.AbstractClassReturner", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :return_abstract_from_property => { kind: :property, name: "returnAbstractFromProperty", is_optional: false }, + :give_me_abstract => { kind: :method, name: "giveMeAbstract", is_optional: false }, + :give_me_interface => { kind: :method, name: "giveMeInterface", is_optional: false }, + } + end + + # @return [JsiiCalc::AbstractClassBase] + def return_abstract_from_property() + jsii_get_property("returnAbstractFromProperty") + end + + # @return [JsiiCalc::AbstractClass] + def give_me_abstract() + jsii_call_method("giveMeAbstract", []) + end + + # @return [JsiiCalc::IInterfaceImplementedByAbstractClass] + def give_me_interface() + jsii_call_method("giveMeInterface", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/abstract_suite.rb 1`] = ` +require 'jsii' + +# Ensures abstract members implementations correctly register overrides in various languages. +class JsiiCalc::AbstractSuite < Jsii::Object + self.jsii_fqn = "jsii-calc.AbstractSuite" + Jsii::Object.register_jsii_fqn("jsii-calc.AbstractSuite", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :property => { kind: :property, name: "property", is_optional: false }, + :some_method => { kind: :method, name: "someMethod", is_optional: false }, + :work_it_all => { kind: :method, name: "workItAll", is_optional: false }, + } + end + + # @return [String] + def property() + jsii_get_property("property") + end + + def property=(value) + jsii_set_property("property", value) + end + + # @param str [String] + # @return [String] + def some_method(str) + jsii_call_method("someMethod", [str]) + end + + # Sets \`seed\` to \`this.property\`, then calls \`someMethod\` with \`this.property\` and returns the result. + # + # @param seed [String] a \`string\`. + # @return [String] + def work_it_all(seed) + jsii_call_method("workItAll", [seed]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/add.rb 1`] = ` +require 'jsii' + +# The "+" binary operation. +class JsiiCalc::Add < ::JsiiCalc::BinaryOperation + self.jsii_fqn = "jsii-calc.Add" + Jsii::Object.register_jsii_fqn("jsii-calc.Add", self) + + # Creates a BinaryOperation. + # + # @param lhs [Scope::JsiiCalcLib::NumericValue] Left-hand side operand. + # @param rhs [Scope::JsiiCalcLib::NumericValue] Right-hand side operand. + def initialize(lhs, rhs) + Jsii::Object.instance_method(:initialize).bind(self).call(lhs, rhs) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :lhs => { kind: :property, name: "lhs", is_optional: false }, + :rhs => { kind: :property, name: "rhs", is_optional: false }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + :hello => { kind: :method, name: "hello", is_optional: false }, + } + end + + # The value. + # + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # Left-hand side operand. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def lhs() + jsii_get_property("lhs") + end + + # Right-hand side operand. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def rhs() + jsii_get_property("rhs") + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # String representation of the value. + # + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + + # Say hello! + # + # @return [String] + def hello() + jsii_call_method("hello", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/all_types.rb 1`] = ` +require 'jsii' + +# This class includes property for all types supported by jsii. +# +# The setters will validate +# that the value set is of the expected type and throw otherwise. +class JsiiCalc::AllTypes < Jsii::Object + self.jsii_fqn = "jsii-calc.AllTypes" + Jsii::Object.register_jsii_fqn("jsii-calc.AllTypes", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :enum_property_value => { kind: :property, name: "enumPropertyValue", is_optional: false }, + :any_array_property => { kind: :property, name: "anyArrayProperty", is_optional: false }, + :any_map_property => { kind: :property, name: "anyMapProperty", is_optional: false }, + :any_property => { kind: :property, name: "anyProperty", is_optional: false }, + :array_property => { kind: :property, name: "arrayProperty", is_optional: false }, + :boolean_property => { kind: :property, name: "booleanProperty", is_optional: false }, + :date_property => { kind: :property, name: "dateProperty", is_optional: false }, + :enum_property => { kind: :property, name: "enumProperty", is_optional: false }, + :json_property => { kind: :property, name: "jsonProperty", is_optional: false }, + :map_property => { kind: :property, name: "mapProperty", is_optional: false }, + :number_property => { kind: :property, name: "numberProperty", is_optional: false }, + :string_property => { kind: :property, name: "stringProperty", is_optional: false }, + :union_array_property => { kind: :property, name: "unionArrayProperty", is_optional: false }, + :union_map_property => { kind: :property, name: "unionMapProperty", is_optional: false }, + :union_property => { kind: :property, name: "unionProperty", is_optional: false }, + :unknown_array_property => { kind: :property, name: "unknownArrayProperty", is_optional: false }, + :unknown_map_property => { kind: :property, name: "unknownMapProperty", is_optional: false }, + :unknown_property => { kind: :property, name: "unknownProperty", is_optional: false }, + :optional_enum_value => { kind: :property, name: "optionalEnumValue", is_optional: true }, + :any_in => { kind: :method, name: "anyIn", is_optional: false }, + :any_out => { kind: :method, name: "anyOut", is_optional: false }, + :enum_method => { kind: :method, name: "enumMethod", is_optional: false }, + } + end + + # @return [Numeric] + def enum_property_value() + jsii_get_property("enumPropertyValue") + end + + # @return [Array] + def any_array_property() + jsii_get_property("anyArrayProperty") + end + + def any_array_property=(value) + jsii_set_property("anyArrayProperty", value) + end + + # @return [Hash{String => Object}] + def any_map_property() + jsii_get_property("anyMapProperty") + end + + def any_map_property=(value) + jsii_set_property("anyMapProperty", value) + end + + # @return [Object] + def any_property() + jsii_get_property("anyProperty") + end + + def any_property=(value) + jsii_set_property("anyProperty", value) + end + + # @return [Array] + def array_property() + jsii_get_property("arrayProperty") + end + + def array_property=(value) + jsii_set_property("arrayProperty", value) + end + + # @return [Boolean] + def boolean_property() + jsii_get_property("booleanProperty") + end + + def boolean_property=(value) + jsii_set_property("booleanProperty", value) + end + + # @return [DateTime] + def date_property() + jsii_get_property("dateProperty") + end + + def date_property=(value) + jsii_set_property("dateProperty", value) + end + + # @return [JsiiCalc::AllTypesEnum] + def enum_property() + jsii_get_property("enumProperty") + end + + def enum_property=(value) + jsii_set_property("enumProperty", value) + end + + # @return [Hash] + def json_property() + jsii_get_property("jsonProperty") + end + + def json_property=(value) + jsii_set_property("jsonProperty", value) + end + + # @return [Hash{String => Scope::JsiiCalcLib::Number}] + def map_property() + jsii_get_property("mapProperty") + end + + def map_property=(value) + jsii_set_property("mapProperty", value) + end + + # @return [Numeric] + def number_property() + jsii_get_property("numberProperty") + end + + def number_property=(value) + jsii_set_property("numberProperty", value) + end + + # @return [String] + def string_property() + jsii_get_property("stringProperty") + end + + def string_property=(value) + jsii_set_property("stringProperty", value) + end + + # @return [Array] + def union_array_property() + jsii_get_property("unionArrayProperty") + end + + def union_array_property=(value) + jsii_set_property("unionArrayProperty", value) + end + + # @return [Hash{String => String, Numeric, Scope::JsiiCalcLib::Number}] + def union_map_property() + jsii_get_property("unionMapProperty") + end + + def union_map_property=(value) + jsii_set_property("unionMapProperty", value) + end + + # @return [String, Numeric, Scope::JsiiCalcLib::Number, JsiiCalc::Multiply] + def union_property() + jsii_get_property("unionProperty") + end + + def union_property=(value) + jsii_set_property("unionProperty", value) + end + + # @return [Array] + def unknown_array_property() + jsii_get_property("unknownArrayProperty") + end + + def unknown_array_property=(value) + jsii_set_property("unknownArrayProperty", value) + end + + # @return [Hash{String => Object}] + def unknown_map_property() + jsii_get_property("unknownMapProperty") + end + + def unknown_map_property=(value) + jsii_set_property("unknownMapProperty", value) + end + + # @return [Object] + def unknown_property() + jsii_get_property("unknownProperty") + end + + def unknown_property=(value) + jsii_set_property("unknownProperty", value) + end + + # @return [JsiiCalc::StringEnum, nil] + def optional_enum_value() + jsii_get_property("optionalEnumValue") + end + + def optional_enum_value=(value) + jsii_set_property("optionalEnumValue", value) + end + + # @param inp [Object] + # @return [void] + def any_in(inp) + jsii_call_method("anyIn", [inp]) + end + + # @return [Object] + def any_out() + jsii_call_method("anyOut", []) + end + + # @param value [JsiiCalc::StringEnum] + # @return [JsiiCalc::StringEnum] + def enum_method(value) + jsii_call_method("enumMethod", [value]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/all_types_enum.rb 1`] = ` +require 'jsii' + +module JsiiCalc::AllTypesEnum + # @note Default: + # @deprecated + MY_ENUM_VALUE = Jsii::Enum.new("jsii-calc.AllTypesEnum", "MY_ENUM_VALUE") + # @note Default: + # @deprecated + YOUR_ENUM_VALUE = Jsii::Enum.new("jsii-calc.AllTypesEnum", "YOUR_ENUM_VALUE") + # @note Default: + # @deprecated + THIS_IS_GREAT = Jsii::Enum.new("jsii-calc.AllTypesEnum", "THIS_IS_GREAT") +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/allowed_method_names.rb 1`] = ` +require 'jsii' + +class JsiiCalc::AllowedMethodNames < Jsii::Object + self.jsii_fqn = "jsii-calc.AllowedMethodNames" + Jsii::Object.register_jsii_fqn("jsii-calc.AllowedMethodNames", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :get_bar => { kind: :method, name: "getBar", is_optional: false }, + :get_foo => { kind: :method, name: "getFoo", is_optional: false }, + :set_bar => { kind: :method, name: "setBar", is_optional: false }, + :set_foo => { kind: :method, name: "setFoo", is_optional: false }, + } + end + + # @param _p1 [String] + # @param _p2 [Numeric] + # @return [void] + def get_bar(_p1, _p2) + jsii_call_method("getBar", [_p1, _p2]) + end + + # getXxx() is not allowed (see negatives), but getXxx(a, ...) is okay. + # + # @param with_param [String] + # @return [String] + def get_foo(with_param) + jsii_call_method("getFoo", [with_param]) + end + + # @param _x [String] + # @param _y [Numeric] + # @param _z [Boolean] + # @return [void] + def set_bar(_x, _y, _z) + jsii_call_method("setBar", [_x, _y, _z]) + end + + # setFoo(x) is not allowed (see negatives), but setXxx(a, b, ...) is okay. + # + # @param _x [String] + # @param _y [Numeric] + # @return [void] + def set_foo(_x, _y) + jsii_call_method("setFoo", [_x, _y]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/ambiguous_parameters.rb 1`] = ` +require 'jsii' + +class JsiiCalc::AmbiguousParameters < Jsii::Object + self.jsii_fqn = "jsii-calc.AmbiguousParameters" + Jsii::Object.register_jsii_fqn("jsii-calc.AmbiguousParameters", self) + + # @param scope [JsiiCalc::Bell] + # @param props [JsiiCalc::StructParameterType] + def initialize(scope, props) + props = props.is_a?(Hash) ? ::JsiiCalc::StructParameterType.new(**props.transform_keys(&:to_sym)) : props + Jsii::Object.instance_method(:initialize).bind(self).call(scope, props) + end + + def self.jsii_overridable_methods + { + :props => { kind: :property, name: "props", is_optional: false }, + :scope => { kind: :property, name: "scope", is_optional: false }, + } + end + + # @return [JsiiCalc::StructParameterType] + def props() + jsii_get_property("props") + end + + # @return [JsiiCalc::Bell] + def scope() + jsii_get_property("scope") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/anonymous/i_option_a.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Anonymous::IOptionA + Jsii::Object.register_jsii_fqn("jsii-calc.anonymous.IOptionA", self) + + # @return [String] + def do_something() + jsii_call_method("doSomething", []) + end + + def self.jsii_overridable_methods + { + :do_something => { kind: :method, name: "doSomething", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/anonymous/i_option_b.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Anonymous::IOptionB + Jsii::Object.register_jsii_fqn("jsii-calc.anonymous.IOptionB", self) + + # @return [String] + def do_something_else() + jsii_call_method("doSomethingElse", []) + end + + def self.jsii_overridable_methods + { + :do_something_else => { kind: :method, name: "doSomethingElse", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/anonymous/use_options.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Anonymous::UseOptions < Jsii::Object + self.jsii_fqn = "jsii-calc.anonymous.UseOptions" + Jsii::Object.register_jsii_fqn("jsii-calc.anonymous.UseOptions", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.anonymous.UseOptions does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @param option [JsiiCalc::Anonymous::IOptionA, JsiiCalc::Anonymous::IOptionB] + # @return [String] + def self.consume(option) + Jsii::Kernel.instance.call_static("jsii-calc.anonymous.UseOptions", "consume", [option]) + end + + # @param which [String] + # @return [Object] + def self.privide_as_any(which) + Jsii::Kernel.instance.call_static("jsii-calc.anonymous.UseOptions", "privideAsAny", [which]) + end + + # @param which [String] + # @return [JsiiCalc::Anonymous::IOptionA, JsiiCalc::Anonymous::IOptionB] + def self.provide(which) + Jsii::Kernel.instance.call_static("jsii-calc.anonymous.UseOptions", "provide", [which]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/anonymous_implementation_provider.rb 1`] = ` +require 'jsii' + +class JsiiCalc::AnonymousImplementationProvider < Jsii::Object + include ::JsiiCalc::IAnonymousImplementationProvider + self.jsii_fqn = "jsii-calc.AnonymousImplementationProvider" + Jsii::Object.register_jsii_fqn("jsii-calc.AnonymousImplementationProvider", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :provide_as_class => { kind: :method, name: "provideAsClass", is_optional: false }, + :provide_as_interface => { kind: :method, name: "provideAsInterface", is_optional: false }, + } + end + + # @return [JsiiCalc::Implementation] + def provide_as_class() + jsii_call_method("provideAsClass", []) + end + + # @return [JsiiCalc::IAnonymouslyImplementMe] + def provide_as_interface() + jsii_call_method("provideAsInterface", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/any_property_access.rb 1`] = ` +require 'jsii' + +class JsiiCalc::AnyPropertyAccess < Jsii::Object + self.jsii_fqn = "jsii-calc.AnyPropertyAccess" + Jsii::Object.register_jsii_fqn("jsii-calc.AnyPropertyAccess", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.AnyPropertyAccess does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # Sets obj[resultProp] to \`\${obj[propA]}+\${obj[propB]}\`. + # + # @param obj [Object] the receiver object. + # @param prop_a [String] the first property to read. + # @param prop_b [String] the second property to read. + # @param result_prop [String] the property to write into. + # @return [void] + def self.mutate_properties(obj, prop_a, prop_b, result_prop) + Jsii::Kernel.instance.call_static("jsii-calc.AnyPropertyAccess", "mutateProperties", [obj, prop_a, prop_b, result_prop]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/async_virtual_methods.rb 1`] = ` +require 'jsii' + +class JsiiCalc::AsyncVirtualMethods < Jsii::Object + self.jsii_fqn = "jsii-calc.AsyncVirtualMethods" + Jsii::Object.register_jsii_fqn("jsii-calc.AsyncVirtualMethods", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :call_me => { kind: :method, name: "callMe", is_optional: false }, + :call_me2 => { kind: :method, name: "callMe2", is_optional: false }, + :call_me_double_promise => { kind: :method, name: "callMeDoublePromise", is_optional: false }, + :dont_override_me => { kind: :method, name: "dontOverrideMe", is_optional: false }, + :override_me => { kind: :method, name: "overrideMe", is_optional: false }, + :override_me_too => { kind: :method, name: "overrideMeToo", is_optional: false }, + } + end + + # @return [Numeric] + def call_me() + jsii_async_call_method("callMe", []) + end + + # Just calls "overrideMeToo". + # + # @return [Numeric] + def call_me2() + jsii_async_call_method("callMe2", []) + end + + # This method calls the "callMe" async method indirectly, which will then invoke a virtual method. + # + # This is a "double promise" situation, which + # means that callbacks are not going to be available immediate, but only + # after an "immediates" cycle. + # + # @return [Numeric] + def call_me_double_promise() + jsii_async_call_method("callMeDoublePromise", []) + end + + # @return [Numeric] + def dont_override_me() + jsii_call_method("dontOverrideMe", []) + end + + # @param mult [Numeric] + # @return [Numeric] + def override_me(mult) + jsii_async_call_method("overrideMe", [mult]) + end + + # @return [Numeric] + def override_me_too() + jsii_async_call_method("overrideMeToo", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/augmentable_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::AugmentableClass < Jsii::Object + self.jsii_fqn = "jsii-calc.AugmentableClass" + Jsii::Object.register_jsii_fqn("jsii-calc.AugmentableClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :method_one => { kind: :method, name: "methodOne", is_optional: false }, + :method_two => { kind: :method, name: "methodTwo", is_optional: false }, + } + end + + # @return [void] + def method_one() + jsii_call_method("methodOne", []) + end + + # @return [void] + def method_two() + jsii_call_method("methodTwo", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/base_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::BaseClass < Jsii::Object + self.jsii_fqn = "jsii-calc.BaseClass" + Jsii::Object.register_jsii_fqn("jsii-calc.BaseClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :property => { kind: :property, name: "property", is_optional: false }, + :method => { kind: :method, name: "method", is_optional: false }, + } + end + + # @return [String] + def property() + jsii_get_property("property") + end + + # @return [Numeric] + def method() + jsii_call_method("method", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/base_jsii976.rb 1`] = ` +require 'jsii' + +class JsiiCalc::BaseJsii976 < Jsii::Object + self.jsii_fqn = "jsii-calc.BaseJsii976" + Jsii::Object.register_jsii_fqn("jsii-calc.BaseJsii976", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/bell.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Bell < Jsii::Object + include ::JsiiCalc::IBell + self.jsii_fqn = "jsii-calc.Bell" + Jsii::Object.register_jsii_fqn("jsii-calc.Bell", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :rung => { kind: :property, name: "rung", is_optional: false }, + :ring => { kind: :method, name: "ring", is_optional: false }, + } + end + + # @return [Boolean] + def rung() + jsii_get_property("rung") + end + + def rung=(value) + jsii_set_property("rung", value) + end + + # @return [void] + def ring() + jsii_call_method("ring", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/binary_operation.rb 1`] = ` +require 'jsii' + +# Represents an operation with two operands. +class JsiiCalc::BinaryOperation < ::Scope::JsiiCalcLib::Operation + include ::Scope::JsiiCalcLib::IFriendly + self.jsii_fqn = "jsii-calc.BinaryOperation" + Jsii::Object.register_jsii_fqn("jsii-calc.BinaryOperation", self) + + # Creates a BinaryOperation. + # + # @param lhs [Scope::JsiiCalcLib::NumericValue] Left-hand side operand. + # @param rhs [Scope::JsiiCalcLib::NumericValue] Right-hand side operand. + def initialize(lhs, rhs) + Jsii::Object.instance_method(:initialize).bind(self).call(lhs, rhs) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :lhs => { kind: :property, name: "lhs", is_optional: false }, + :rhs => { kind: :property, name: "rhs", is_optional: false }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + :hello => { kind: :method, name: "hello", is_optional: false }, + } + end + + # The value. + # + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # Left-hand side operand. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def lhs() + jsii_get_property("lhs") + end + + # Right-hand side operand. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def rhs() + jsii_get_property("rhs") + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # String representation of the value. + # + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + + # Say hello! + # + # @return [String] + def hello() + jsii_call_method("hello", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/burried_anonymous_object.rb 1`] = ` +require 'jsii' + +# See https://github.com/aws/aws-cdk/issues/7977. +class JsiiCalc::BurriedAnonymousObject < Jsii::Object + self.jsii_fqn = "jsii-calc.BurriedAnonymousObject" + Jsii::Object.register_jsii_fqn("jsii-calc.BurriedAnonymousObject", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :check => { kind: :method, name: "check", is_optional: false }, + :give_it_back => { kind: :method, name: "giveItBack", is_optional: false }, + } + end + + # @return [Boolean] + def check() + jsii_call_method("check", []) + end + + # Implement this method and have it return it's parameter. + # + # @param value [Object] the value that should be returned. + # @return [Object] \`value\` + def give_it_back(value) + jsii_call_method("giveItBack", [value]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/calculator.rb 1`] = ` +require 'jsii' + +# A calculator which maintains a current value and allows adding operations. +# +# Here's how you use it: +# +# \`\`\`ruby +# const calculator = new calc.Calculator(); +# calculator.add(5); +# calculator.mul(3); +# // console.log(calculator.expression.value); +# \`\`\` +# +# I will repeat this example again, but in an +# +# @example +# const calculator = new calc.Calculator(); +# calculator.add(5); +# calculator.mul(3); +# // console.log(calculator.expression.value); +class JsiiCalc::Calculator < ::JsiiCalc::Composition::CompositeOperation + self.jsii_fqn = "jsii-calc.Calculator" + Jsii::Object.register_jsii_fqn("jsii-calc.Calculator", self) + + # Creates a Calculator object. + # + # @param props [JsiiCalc::CalculatorProps, nil] Initialization properties. + def initialize(props = nil) + props = props.is_a?(Hash) ? ::JsiiCalc::CalculatorProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :expression => { kind: :property, name: "expression", is_optional: false }, + :decoration_postfixes => { kind: :property, name: "decorationPostfixes", is_optional: false }, + :decoration_prefixes => { kind: :property, name: "decorationPrefixes", is_optional: false }, + :string_style => { kind: :property, name: "stringStyle", is_optional: false }, + :operations_log => { kind: :property, name: "operationsLog", is_optional: false }, + :operations_map => { kind: :property, name: "operationsMap", is_optional: false }, + :curr => { kind: :property, name: "curr", is_optional: false }, + :max_value => { kind: :property, name: "maxValue", is_optional: true }, + :union_property => { kind: :property, name: "unionProperty", is_optional: true }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + :add => { kind: :method, name: "add", is_optional: false }, + :mul => { kind: :method, name: "mul", is_optional: false }, + :neg => { kind: :method, name: "neg", is_optional: false }, + :pow => { kind: :method, name: "pow", is_optional: false }, + :read_union_value => { kind: :method, name: "readUnionValue", is_optional: false }, + } + end + + # The value. + # + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # Returns the expression. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def expression() + jsii_get_property("expression") + end + + # A set of postfixes to include in a decorated .toString(). + # + # @return [Array] + def decoration_postfixes() + jsii_get_property("decorationPostfixes") + end + + def decoration_postfixes=(value) + jsii_set_property("decorationPostfixes", value) + end + + # A set of prefixes to include in a decorated .toString(). + # + # @return [Array] + def decoration_prefixes() + jsii_get_property("decorationPrefixes") + end + + def decoration_prefixes=(value) + jsii_set_property("decorationPrefixes", value) + end + + # The .toString() style. + # + # @return [JsiiCalc::Composition::CompositeOperation::CompositionStringStyle] + def string_style() + jsii_get_property("stringStyle") + end + + def string_style=(value) + jsii_set_property("stringStyle", value) + end + + # A log of all operations. + # + # @return [Array] + def operations_log() + jsii_get_property("operationsLog") + end + + # A map of per operation name of all operations performed. + # + # @return [Hash{String => Array}] + def operations_map() + jsii_get_property("operationsMap") + end + + # The current value. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def curr() + jsii_get_property("curr") + end + + def curr=(value) + jsii_set_property("curr", value) + end + + # The maximum value allows in this calculator. + # + # @return [Numeric, nil] + def max_value() + jsii_get_property("maxValue") + end + + def max_value=(value) + jsii_set_property("maxValue", value) + end + + # Example of a property that accepts a union of types. + # + # @return [JsiiCalc::Add, JsiiCalc::Multiply, JsiiCalc::Power, nil] + def union_property() + jsii_get_property("unionProperty") + end + + def union_property=(value) + jsii_set_property("unionProperty", value) + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # String representation of the value. + # + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + + # Adds a number to the current value. + # + # @param value [Numeric] + # @return [void] + def add(value) + jsii_call_method("add", [value]) + end + + # Multiplies the current value by a number. + # + # @param value [Numeric] + # @return [void] + def mul(value) + jsii_call_method("mul", [value]) + end + + # Negates the current value. + # + # @return [void] + def neg() + jsii_call_method("neg", []) + end + + # Raises the current value by a power. + # + # @param value [Numeric] + # @return [void] + def pow(value) + jsii_call_method("pow", [value]) + end + + # Returns teh value of the union property (if defined). + # + # @return [Numeric] + def read_union_value() + jsii_call_method("readUnionValue", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/calculator_props.rb 1`] = ` +require 'jsii' + +# Properties for Calculator. +class JsiiCalc::CalculatorProps < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.CalculatorProps", self) + + # @param initial_value [Numeric, nil] The initial value of the calculator. + # @param maximum_value [Numeric, nil] The maximum value the calculator can store. + def initialize(initial_value: nil, maximum_value: nil) + @initial_value = initial_value + @maximum_value = maximum_value + end + + # The initial value of the calculator. + # + # NOTE: Any number works here, it's fine. + # + # @return [Numeric, nil] + # @note Default: 0 + attr_reader :initial_value + # The maximum value the calculator can store. + # + # @return [Numeric, nil] + # @note Default: none + attr_reader :maximum_value + + def self.jsii_properties + { + :initial_value => "initialValue", + :maximum_value => "maximumValue", + } + end + + def to_jsii + result = {} + result.merge!({ + "initialValue" => @initial_value, + "maximumValue" => @maximum_value, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/cdk16625/cdk16625.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Cdk16625::Cdk16625 < Jsii::Object + self.jsii_fqn = "jsii-calc.cdk16625.Cdk16625" + Jsii::Object.register_jsii_fqn("jsii-calc.cdk16625.Cdk16625", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :test => { kind: :method, name: "test", is_optional: false }, + :unwrap => { kind: :method, name: "unwrap", is_optional: false }, + } + end + + # Run this function to verify that everything is working as it should. + # + # @return [void] + def test() + jsii_call_method("test", []) + end + + # Implement this functin to return \`gen.next()\`. It is extremely important that the \`donotimport\` submodule is NEVER explicitly loaded in the testing application (otherwise this test is void). + # + # @param gen [JsiiCalc::IRandomNumberGenerator] a VERY pseudo random number generator. + # @return [Numeric] + def unwrap(gen) + gen = Jsii::Utils.coerce_callable(gen, ::JsiiCalc::IRandomNumberGenerator) + jsii_call_method("unwrap", [gen]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/cdk16625/donotimport/unimported_submodule_type.rb 1`] = ` +require 'jsii' + +# This type demonstrates the ability to receive a callback argument that has a type from a submodule not explicitly imported in the user's code. +# +# This checks +# that all types available in the assembly can be resolved by the runtime +# library, regardless of whether they were explicitly referenced or not. +# +# @see https://github.com/aws/aws-cdk/issues/16625 +class JsiiCalc::Cdk16625::Donotimport::UnimportedSubmoduleType < Jsii::Object + include ::JsiiCalc::IRandomNumberGenerator + self.jsii_fqn = "jsii-calc.cdk16625.donotimport.UnimportedSubmoduleType" + Jsii::Object.register_jsii_fqn("jsii-calc.cdk16625.donotimport.UnimportedSubmoduleType", self) + + # @param value [Numeric] + def initialize(value) + Jsii::Object.instance_method(:initialize).bind(self).call(value) + end + + def self.jsii_overridable_methods + { + :_next => { kind: :method, name: "next", is_optional: false }, + } + end + + # Not quite random, but it'll do. + # + # @return [Numeric] 1337 + def _next() + jsii_call_method("next", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/cdk22369/accepts_path.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Cdk22369::AcceptsPath < Jsii::Object + self.jsii_fqn = "jsii-calc.cdk22369.AcceptsPath" + Jsii::Object.register_jsii_fqn("jsii-calc.cdk22369.AcceptsPath", self) + + # @param props [JsiiCalc::Cdk22369::AcceptsPathProps] + def initialize(props) + props = props.is_a?(Hash) ? ::JsiiCalc::Cdk22369::AcceptsPathProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { + } + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/cdk22369/accepts_path_props.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Cdk22369::AcceptsPathProps < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.cdk22369.AcceptsPathProps", self) + + # @param source_path [String] A path that doesn't exist. + def initialize(source_path:) + @source_path = source_path + end + + # A path that doesn't exist. + # + # @return [String] + attr_reader :source_path + + def self.jsii_properties + { + :source_path => "sourcePath", + } + end + + def to_jsii + result = {} + result.merge!({ + "sourcePath" => @source_path, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/child_struct982.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ChildStruct982 < ::JsiiCalc::ParentStruct982 + Jsii::Object.register_jsii_fqn("jsii-calc.ChildStruct982", self) + + # @param foo [String] + # @param bar [Numeric] + def initialize(foo:, bar:) + @foo = foo + @bar = bar + end + + # @return [String] + attr_reader :foo + # @return [Numeric] + attr_reader :bar + + def self.jsii_properties + { + :foo => "foo", + :bar => "bar", + } + end + + def to_jsii + result = {} + result.merge!(super) + result.merge!({ + "foo" => @foo, + "bar" => @bar, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_that_implements_the_internal_interface.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ClassThatImplementsTheInternalInterface < Jsii::Object + include ::JsiiCalc::INonInternalInterface + self.jsii_fqn = "jsii-calc.ClassThatImplementsTheInternalInterface" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassThatImplementsTheInternalInterface", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :a => { kind: :property, name: "a", is_optional: false }, + :b => { kind: :property, name: "b", is_optional: false }, + :c => { kind: :property, name: "c", is_optional: false }, + :d => { kind: :property, name: "d", is_optional: false }, + } + end + + # @return [String] + def a() + jsii_get_property("a") + end + + def a=(value) + jsii_set_property("a", value) + end + + # @return [String] + def b() + jsii_get_property("b") + end + + def b=(value) + jsii_set_property("b", value) + end + + # @return [String] + def c() + jsii_get_property("c") + end + + def c=(value) + jsii_set_property("c", value) + end + + # @return [String] + def d() + jsii_get_property("d") + end + + def d=(value) + jsii_set_property("d", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_that_implements_the_private_interface.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ClassThatImplementsThePrivateInterface < Jsii::Object + include ::JsiiCalc::INonInternalInterface + self.jsii_fqn = "jsii-calc.ClassThatImplementsThePrivateInterface" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassThatImplementsThePrivateInterface", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :a => { kind: :property, name: "a", is_optional: false }, + :b => { kind: :property, name: "b", is_optional: false }, + :c => { kind: :property, name: "c", is_optional: false }, + :e => { kind: :property, name: "e", is_optional: false }, + } + end + + # @return [String] + def a() + jsii_get_property("a") + end + + def a=(value) + jsii_set_property("a", value) + end + + # @return [String] + def b() + jsii_get_property("b") + end + + def b=(value) + jsii_set_property("b", value) + end + + # @return [String] + def c() + jsii_get_property("c") + end + + def c=(value) + jsii_set_property("c", value) + end + + # @return [String] + def e() + jsii_get_property("e") + end + + def e=(value) + jsii_set_property("e", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_collection_of_unions.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ClassWithCollectionOfUnions < Jsii::Object + self.jsii_fqn = "jsii-calc.ClassWithCollectionOfUnions" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassWithCollectionOfUnions", self) + + # @param union_property [Array JsiiCalc::StructA, JsiiCalc::StructB}>] + def initialize(union_property) + Jsii::Object.instance_method(:initialize).bind(self).call(union_property) + end + + def self.jsii_overridable_methods + { + :union_property => { kind: :property, name: "unionProperty", is_optional: false }, + :method_with_map_of_unions_param => { kind: :method, name: "methodWithMapOfUnionsParam", is_optional: false }, + } + end + + # @param param [Hash{String => JsiiCalc::StructA, JsiiCalc::StructB}] + # @return [void] + def self.static_method_with_map_of_unions_param(param) + Jsii::Kernel.instance.call_static("jsii-calc.ClassWithCollectionOfUnions", "staticMethodWithMapOfUnionsParam", [param]) + end + + # @return [Array JsiiCalc::StructA, JsiiCalc::StructB}>] + def union_property() + jsii_get_property("unionProperty") + end + + def union_property=(value) + jsii_set_property("unionProperty", value) + end + + # @param param [Hash{String => JsiiCalc::StructA, JsiiCalc::StructB}] + # @return [void] + def method_with_map_of_unions_param(param) + jsii_call_method("methodWithMapOfUnionsParam", [param]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_collections.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ClassWithCollections < Jsii::Object + self.jsii_fqn = "jsii-calc.ClassWithCollections" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassWithCollections", self) + + # @param map [Hash{String => String}] + # @param array [Array] + def initialize(map, array) + Jsii::Object.instance_method(:initialize).bind(self).call(map, array) + end + + def self.jsii_overridable_methods + { + :array => { kind: :property, name: "array", is_optional: false }, + :map => { kind: :property, name: "map", is_optional: false }, + } + end + + # @return [Array] + def self.create_a_list() + Jsii::Kernel.instance.call_static("jsii-calc.ClassWithCollections", "createAList", []) + end + + # @return [Hash{String => String}] + def self.create_a_map() + Jsii::Kernel.instance.call_static("jsii-calc.ClassWithCollections", "createAMap", []) + end + + # @return [Array] + def self.static_array() + Jsii::Kernel.instance.get_static("jsii-calc.ClassWithCollections", "staticArray") + end + + def self.static_array=(value) + Jsii::Kernel.instance.set_static("jsii-calc.ClassWithCollections", "staticArray", value) + end + + # @return [Hash{String => String}] + def self.static_map() + Jsii::Kernel.instance.get_static("jsii-calc.ClassWithCollections", "staticMap") + end + + def self.static_map=(value) + Jsii::Kernel.instance.set_static("jsii-calc.ClassWithCollections", "staticMap", value) + end + + # @return [Array] + def array() + jsii_get_property("array") + end + + def array=(value) + jsii_set_property("array", value) + end + + # @return [Hash{String => String}] + def map() + jsii_get_property("map") + end + + def map=(value) + jsii_set_property("map", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_container_types.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ClassWithContainerTypes < Jsii::Object + self.jsii_fqn = "jsii-calc.ClassWithContainerTypes" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassWithContainerTypes", self) + + # @param array [Array] + # @param record [Hash{String => JsiiCalc::DummyObj}] + # @param obj [Hash{String => JsiiCalc::DummyObj}] + # @param props [JsiiCalc::ContainerProps, nil] + def initialize(array, record, obj, props = nil) + array = array.is_a?(Array) ? array.map { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::DummyObj.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : array + record = record.is_a?(Hash) ? record.transform_values { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::DummyObj.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : record + obj = obj.is_a?(Hash) ? obj.transform_values { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::DummyObj.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : obj + props = props.is_a?(Hash) ? ::JsiiCalc::ContainerProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Object.instance_method(:initialize).bind(self).call(array, record, obj, props) + end + + def self.jsii_overridable_methods + { + :array => { kind: :property, name: "array", is_optional: false }, + :obj => { kind: :property, name: "obj", is_optional: false }, + :record => { kind: :property, name: "record", is_optional: false }, + :props => { kind: :property, name: "props", is_optional: true }, + } + end + + # @return [Array] + def array() + jsii_get_property("array") + end + + # @return [Hash{String => JsiiCalc::DummyObj}] + def obj() + jsii_get_property("obj") + end + + # @return [Hash{String => JsiiCalc::DummyObj}] + def record() + jsii_get_property("record") + end + + # @return [JsiiCalc::ContainerProps, nil] + def props() + jsii_get_property("props") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_docs.rb 1`] = ` +require 'jsii' + +# This class has docs. +# +# The docs are great. They're a bunch of tags. +# +# @see https://aws.amazon.com/ +# @example +# function anExample() { +# } +class JsiiCalc::ClassWithDocs < Jsii::Object + self.jsii_fqn = "jsii-calc.ClassWithDocs" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassWithDocs", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_java_reserved_words.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ClassWithJavaReservedWords < Jsii::Object + self.jsii_fqn = "jsii-calc.ClassWithJavaReservedWords" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassWithJavaReservedWords", self) + + # @param int [String] + def initialize(int) + Jsii::Object.instance_method(:initialize).bind(self).call(int) + end + + def self.jsii_overridable_methods + { + :int => { kind: :property, name: "int", is_optional: false }, + :import => { kind: :method, name: "import", is_optional: false }, + } + end + + # @return [String] + def int() + jsii_get_property("int") + end + + # @param assert [String] + # @return [String] + def import(assert) + jsii_call_method("import", [assert]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_mutable_object_literal_property.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ClassWithMutableObjectLiteralProperty < Jsii::Object + self.jsii_fqn = "jsii-calc.ClassWithMutableObjectLiteralProperty" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassWithMutableObjectLiteralProperty", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :mutable_object => { kind: :property, name: "mutableObject", is_optional: false }, + } + end + + # @return [JsiiCalc::IMutableObjectLiteral] + def mutable_object() + jsii_get_property("mutableObject") + end + + def mutable_object=(value) + jsii_set_property("mutableObject", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_nested_union.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ClassWithNestedUnion < Jsii::Object + self.jsii_fqn = "jsii-calc.ClassWithNestedUnion" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassWithNestedUnion", self) + + # @param union_property [Array JsiiCalc::StructA, JsiiCalc::StructB}, Array>] + def initialize(union_property) + Jsii::Object.instance_method(:initialize).bind(self).call(union_property) + end + + def self.jsii_overridable_methods + { + :union_property => { kind: :property, name: "unionProperty", is_optional: false }, + } + end + + # @return [Array JsiiCalc::StructA, JsiiCalc::StructB}, Array>] + def union_property() + jsii_get_property("unionProperty") + end + + def union_property=(value) + jsii_set_property("unionProperty", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_private_constructor_and_automatic_properties.rb 1`] = ` +require 'jsii' + +# Class that implements interface properties automatically, but using a private constructor. +class JsiiCalc::ClassWithPrivateConstructorAndAutomaticProperties < Jsii::Object + include ::JsiiCalc::IInterfaceWithProperties + self.jsii_fqn = "jsii-calc.ClassWithPrivateConstructorAndAutomaticProperties" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassWithPrivateConstructorAndAutomaticProperties", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.ClassWithPrivateConstructorAndAutomaticProperties does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + :read_only_string => { kind: :property, name: "readOnlyString", is_optional: false }, + :read_write_string => { kind: :property, name: "readWriteString", is_optional: false }, + } + end + + # @param read_only_string [String] + # @param read_write_string [String] + # @return [JsiiCalc::ClassWithPrivateConstructorAndAutomaticProperties] + def self.create(read_only_string, read_write_string) + Jsii::Kernel.instance.call_static("jsii-calc.ClassWithPrivateConstructorAndAutomaticProperties", "create", [read_only_string, read_write_string]) + end + + # @return [String] + def read_only_string() + jsii_get_property("readOnlyString") + end + + # @return [String] + def read_write_string() + jsii_get_property("readWriteString") + end + + def read_write_string=(value) + jsii_set_property("readWriteString", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/composition/composite_operation.rb 1`] = ` +require 'jsii' + +# Abstract operation composed from an expression of other operations. +class JsiiCalc::Composition::CompositeOperation < ::Scope::JsiiCalcLib::Operation + self.jsii_fqn = "jsii-calc.composition.CompositeOperation" + Jsii::Object.register_jsii_fqn("jsii-calc.composition.CompositeOperation", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :expression => { kind: :property, name: "expression", is_optional: false }, + :decoration_postfixes => { kind: :property, name: "decorationPostfixes", is_optional: false }, + :decoration_prefixes => { kind: :property, name: "decorationPrefixes", is_optional: false }, + :string_style => { kind: :property, name: "stringStyle", is_optional: false }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + } + end + + # The value. + # + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # The expression that this operation consists of. + # + # Must be implemented by derived classes. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def expression() + jsii_get_property("expression") + end + + # A set of postfixes to include in a decorated .toString(). + # + # @return [Array] + def decoration_postfixes() + jsii_get_property("decorationPostfixes") + end + + def decoration_postfixes=(value) + jsii_set_property("decorationPostfixes", value) + end + + # A set of prefixes to include in a decorated .toString(). + # + # @return [Array] + def decoration_prefixes() + jsii_get_property("decorationPrefixes") + end + + def decoration_prefixes=(value) + jsii_set_property("decorationPrefixes", value) + end + + # The .toString() style. + # + # @return [JsiiCalc::Composition::CompositeOperation::CompositionStringStyle] + def string_style() + jsii_get_property("stringStyle") + end + + def string_style=(value) + jsii_set_property("stringStyle", value) + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # String representation of the value. + # + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + +end + +# Style of .toString() output for CompositeOperation. +module JsiiCalc::Composition::CompositeOperation::CompositionStringStyle + # Normal string expression. + # + # @note Default: + # @deprecated + NORMAL = Jsii::Enum.new("jsii-calc.composition.CompositeOperation.CompositionStringStyle", "NORMAL") + # Decorated string expression. + # + # @note Default: + # @deprecated + DECORATED = Jsii::Enum.new("jsii-calc.composition.CompositeOperation.CompositionStringStyle", "DECORATED") +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/confusing_to_jackson.rb 1`] = ` +require 'jsii' + +# This tries to confuse Jackson by having overloaded property setters. +# +# @see https://github.com/aws/aws-cdk/issues/4080 +class JsiiCalc::ConfusingToJackson < Jsii::Object + self.jsii_fqn = "jsii-calc.ConfusingToJackson" + Jsii::Object.register_jsii_fqn("jsii-calc.ConfusingToJackson", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.ConfusingToJackson does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + :union_property => { kind: :property, name: "unionProperty", is_optional: true }, + } + end + + # @return [JsiiCalc::ConfusingToJackson] + def self.make_instance() + Jsii::Kernel.instance.call_static("jsii-calc.ConfusingToJackson", "makeInstance", []) + end + + # @return [JsiiCalc::ConfusingToJacksonStruct] + def self.make_struct_instance() + Jsii::Kernel.instance.call_static("jsii-calc.ConfusingToJackson", "makeStructInstance", []) + end + + # @return [Scope::JsiiCalcLib::IFriendly, Array, nil] + def union_property() + jsii_get_property("unionProperty") + end + + def union_property=(value) + jsii_set_property("unionProperty", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/confusing_to_jackson_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ConfusingToJacksonStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.ConfusingToJacksonStruct", self) + + # @param union_property [Scope::JsiiCalcLib::IFriendly, Array, nil] + def initialize(union_property: nil) + @union_property = union_property + end + + # @return [Scope::JsiiCalcLib::IFriendly, Array, nil] + attr_reader :union_property + + def self.jsii_properties + { + :union_property => "unionProperty", + } + end + + def to_jsii + result = {} + result.merge!({ + "unionProperty" => @union_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/constructor_passes_this_out.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ConstructorPassesThisOut < Jsii::Object + self.jsii_fqn = "jsii-calc.ConstructorPassesThisOut" + Jsii::Object.register_jsii_fqn("jsii-calc.ConstructorPassesThisOut", self) + + # @param consumer [JsiiCalc::PartiallyInitializedThisConsumer] + def initialize(consumer) + Jsii::Object.instance_method(:initialize).bind(self).call(consumer) + end + + def self.jsii_overridable_methods + { + } + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/constructors.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Constructors < Jsii::Object + self.jsii_fqn = "jsii-calc.Constructors" + Jsii::Object.register_jsii_fqn("jsii-calc.Constructors", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + + # @return [JsiiCalc::IPublicInterface] + def self.hidden_interface() + Jsii::Kernel.instance.call_static("jsii-calc.Constructors", "hiddenInterface", []) + end + + # @return [Array] + def self.hidden_interfaces() + Jsii::Kernel.instance.call_static("jsii-calc.Constructors", "hiddenInterfaces", []) + end + + # @return [Array] + def self.hidden_sub_interfaces() + Jsii::Kernel.instance.call_static("jsii-calc.Constructors", "hiddenSubInterfaces", []) + end + + # @return [JsiiCalc::PublicClass] + def self.make_class() + Jsii::Kernel.instance.call_static("jsii-calc.Constructors", "makeClass", []) + end + + # @return [JsiiCalc::IPublicInterface] + def self.make_interface() + Jsii::Kernel.instance.call_static("jsii-calc.Constructors", "makeInterface", []) + end + + # @return [JsiiCalc::IPublicInterface2] + def self.make_interface2() + Jsii::Kernel.instance.call_static("jsii-calc.Constructors", "makeInterface2", []) + end + + # @return [Array] + def self.make_interfaces() + Jsii::Kernel.instance.call_static("jsii-calc.Constructors", "makeInterfaces", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/consume_pure_interface.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ConsumePureInterface < Jsii::Object + self.jsii_fqn = "jsii-calc.ConsumePureInterface" + Jsii::Object.register_jsii_fqn("jsii-calc.ConsumePureInterface", self) + + # @param delegate [JsiiCalc::IStructReturningDelegate] + def initialize(delegate) + delegate = Jsii::Utils.coerce_callable(delegate, ::JsiiCalc::IStructReturningDelegate) + Jsii::Object.instance_method(:initialize).bind(self).call(delegate) + end + + def self.jsii_overridable_methods + { + :work_it_baby => { kind: :method, name: "workItBaby", is_optional: false }, + } + end + + # @return [JsiiCalc::StructB] + def work_it_baby() + jsii_call_method("workItBaby", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/consumer_can_ring_bell.rb 1`] = ` +require 'jsii' + +# Test calling back to consumers that implement interfaces. +# +# Check that if a JSII consumer implements IConsumerWithInterfaceParam, they can call +# the method on the argument that they're passed... +class JsiiCalc::ConsumerCanRingBell < Jsii::Object + self.jsii_fqn = "jsii-calc.ConsumerCanRingBell" + Jsii::Object.register_jsii_fqn("jsii-calc.ConsumerCanRingBell", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :implemented_by_object_literal => { kind: :method, name: "implementedByObjectLiteral", is_optional: false }, + :implemented_by_private_class => { kind: :method, name: "implementedByPrivateClass", is_optional: false }, + :implemented_by_public_class => { kind: :method, name: "implementedByPublicClass", is_optional: false }, + :when_typed_as_class => { kind: :method, name: "whenTypedAsClass", is_optional: false }, + } + end + + # ...if the interface is implemented using an object literal. + # + # Returns whether the bell was rung. + # + # @param ringer [JsiiCalc::IBellRinger] + # @return [Boolean] + def self.static_implemented_by_object_literal(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IBellRinger) + Jsii::Kernel.instance.call_static("jsii-calc.ConsumerCanRingBell", "staticImplementedByObjectLiteral", [ringer]) + end + + # ...if the interface is implemented using a private class. + # + # Return whether the bell was rung. + # + # @param ringer [JsiiCalc::IBellRinger] + # @return [Boolean] + def self.static_implemented_by_private_class(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IBellRinger) + Jsii::Kernel.instance.call_static("jsii-calc.ConsumerCanRingBell", "staticImplementedByPrivateClass", [ringer]) + end + + # ...if the interface is implemented using a public class. + # + # Return whether the bell was rung. + # + # @param ringer [JsiiCalc::IBellRinger] + # @return [Boolean] + def self.static_implemented_by_public_class(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IBellRinger) + Jsii::Kernel.instance.call_static("jsii-calc.ConsumerCanRingBell", "staticImplementedByPublicClass", [ringer]) + end + + # If the parameter is a concrete class instead of an interface. + # + # Return whether the bell was rung. + # + # @param ringer [JsiiCalc::IConcreteBellRinger] + # @return [Boolean] + def self.static_when_typed_as_class(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IConcreteBellRinger) + Jsii::Kernel.instance.call_static("jsii-calc.ConsumerCanRingBell", "staticWhenTypedAsClass", [ringer]) + end + + # ...if the interface is implemented using an object literal. + # + # Returns whether the bell was rung. + # + # @param ringer [JsiiCalc::IBellRinger] + # @return [Boolean] + def implemented_by_object_literal(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IBellRinger) + jsii_call_method("implementedByObjectLiteral", [ringer]) + end + + # ...if the interface is implemented using a private class. + # + # Return whether the bell was rung. + # + # @param ringer [JsiiCalc::IBellRinger] + # @return [Boolean] + def implemented_by_private_class(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IBellRinger) + jsii_call_method("implementedByPrivateClass", [ringer]) + end + + # ...if the interface is implemented using a public class. + # + # Return whether the bell was rung. + # + # @param ringer [JsiiCalc::IBellRinger] + # @return [Boolean] + def implemented_by_public_class(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IBellRinger) + jsii_call_method("implementedByPublicClass", [ringer]) + end + + # If the parameter is a concrete class instead of an interface. + # + # Return whether the bell was rung. + # + # @param ringer [JsiiCalc::IConcreteBellRinger] + # @return [Boolean] + def when_typed_as_class(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IConcreteBellRinger) + jsii_call_method("whenTypedAsClass", [ringer]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/consumers_of_this_crazy_type_system.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ConsumersOfThisCrazyTypeSystem < Jsii::Object + self.jsii_fqn = "jsii-calc.ConsumersOfThisCrazyTypeSystem" + Jsii::Object.register_jsii_fqn("jsii-calc.ConsumersOfThisCrazyTypeSystem", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :consume_another_public_interface => { kind: :method, name: "consumeAnotherPublicInterface", is_optional: false }, + :consume_non_internal_interface => { kind: :method, name: "consumeNonInternalInterface", is_optional: false }, + } + end + + # @param obj [JsiiCalc::IAnotherPublicInterface] + # @return [String] + def consume_another_public_interface(obj) + jsii_call_method("consumeAnotherPublicInterface", [obj]) + end + + # @param obj [JsiiCalc::INonInternalInterface] + # @return [Object] + def consume_non_internal_interface(obj) + jsii_call_method("consumeNonInternalInterface", [obj]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/container_props.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ContainerProps < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.ContainerProps", self) + + # @param array_prop [Array] + # @param obj_prop [Hash{String => JsiiCalc::DummyObj}] + # @param record_prop [Hash{String => JsiiCalc::DummyObj}] + def initialize(array_prop:, obj_prop:, record_prop:) + @array_prop = array_prop.is_a?(Array) ? array_prop.map { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::DummyObj.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : array_prop + @obj_prop = obj_prop.is_a?(Hash) ? obj_prop.transform_values { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::DummyObj.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : obj_prop + @record_prop = record_prop.is_a?(Hash) ? record_prop.transform_values { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::DummyObj.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : record_prop + end + + # @return [Array] + attr_reader :array_prop + # @return [Hash{String => JsiiCalc::DummyObj}] + attr_reader :obj_prop + # @return [Hash{String => JsiiCalc::DummyObj}] + attr_reader :record_prop + + def self.jsii_properties + { + :array_prop => "arrayProp", + :obj_prop => "objProp", + :record_prop => "recordProp", + } + end + + def to_jsii + result = {} + result.merge!({ + "arrayProp" => @array_prop, + "objProp" => @obj_prop, + "recordProp" => @record_prop, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/covariant_overrides/class_overrides/base.rb 1`] = ` +require 'jsii' + +# Base class with methods and properties that will be overridden with covariant return types. +class JsiiCalc::CovariantOverrides::ClassOverrides::Base < Jsii::Object + include ::JsiiCalc::CovariantOverrides::ClassOverrides::IBase + self.jsii_fqn = "jsii-calc.covariantOverrides.classOverrides.Base" + Jsii::Object.register_jsii_fqn("jsii-calc.covariantOverrides.classOverrides.Base", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :list => { kind: :property, name: "list", is_optional: false }, + :something => { kind: :property, name: "something", is_optional: false }, + :create_something => { kind: :method, name: "createSomething", is_optional: false }, + } + end + + # @return [Array] + def list() + jsii_get_property("list") + end + + # @return [JsiiCalc::CovariantOverrides::ClassOverrides::Superclass] + def something() + jsii_get_property("something") + end + + # @return [JsiiCalc::CovariantOverrides::ClassOverrides::Superclass] + def create_something() + jsii_call_method("createSomething", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/covariant_overrides/class_overrides/derived.rb 1`] = ` +require 'jsii' + +# Derived class that demonstrates covariant overrides. +# +# Both property and method overrides are covariant and will work in C# 9.0+ +# when the covariant-overrides feature is enabled. +class JsiiCalc::CovariantOverrides::ClassOverrides::Derived < ::JsiiCalc::CovariantOverrides::ClassOverrides::Middle + self.jsii_fqn = "jsii-calc.covariantOverrides.classOverrides.Derived" + Jsii::Object.register_jsii_fqn("jsii-calc.covariantOverrides.classOverrides.Derived", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :list => { kind: :property, name: "list", is_optional: false }, + :something => { kind: :property, name: "something", is_optional: false }, + :add_unrelated_member => { kind: :property, name: "addUnrelatedMember", is_optional: false }, + :create_something => { kind: :method, name: "createSomething", is_optional: false }, + } + end + + # @return [Array] + def list() + jsii_get_property("list") + end + + # @return [JsiiCalc::CovariantOverrides::ClassOverrides::SubSubclass] + def something() + jsii_get_property("something") + end + + # @return [Numeric] + def add_unrelated_member() + jsii_get_property("addUnrelatedMember") + end + + def add_unrelated_member=(value) + jsii_set_property("addUnrelatedMember", value) + end + + # @return [JsiiCalc::CovariantOverrides::ClassOverrides::SubSubclass] + def create_something() + jsii_call_method("createSomething", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/covariant_overrides/class_overrides/i_base.rb 1`] = ` +require 'jsii' + +module JsiiCalc::CovariantOverrides::ClassOverrides::IBase + Jsii::Object.register_jsii_fqn("jsii-calc.covariantOverrides.classOverrides.IBase", self) + + # @return [JsiiCalc::CovariantOverrides::ClassOverrides::Superclass] + def something() + jsii_get_property("something") + end + + def self.jsii_overridable_methods + { + :something => { kind: :property, name: "something", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/covariant_overrides/class_overrides/middle.rb 1`] = ` +require 'jsii' + +# Middle class in the inheritance chain - doesn't override anything. +class JsiiCalc::CovariantOverrides::ClassOverrides::Middle < ::JsiiCalc::CovariantOverrides::ClassOverrides::Base + self.jsii_fqn = "jsii-calc.covariantOverrides.classOverrides.Middle" + Jsii::Object.register_jsii_fqn("jsii-calc.covariantOverrides.classOverrides.Middle", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :list => { kind: :property, name: "list", is_optional: false }, + :something => { kind: :property, name: "something", is_optional: false }, + :add_unrelated_member => { kind: :property, name: "addUnrelatedMember", is_optional: false }, + :create_something => { kind: :method, name: "createSomething", is_optional: false }, + } + end + + # @return [Array] + def list() + jsii_get_property("list") + end + + # @return [JsiiCalc::CovariantOverrides::ClassOverrides::Superclass] + def something() + jsii_get_property("something") + end + + # @return [Numeric] + def add_unrelated_member() + jsii_get_property("addUnrelatedMember") + end + + def add_unrelated_member=(value) + jsii_set_property("addUnrelatedMember", value) + end + + # @return [JsiiCalc::CovariantOverrides::ClassOverrides::Superclass] + def create_something() + jsii_call_method("createSomething", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/covariant_overrides/class_overrides/sub_subclass.rb 1`] = ` +require 'jsii' + +# Further derived class that extends Subclass. +class JsiiCalc::CovariantOverrides::ClassOverrides::SubSubclass < ::JsiiCalc::CovariantOverrides::ClassOverrides::Subclass + self.jsii_fqn = "jsii-calc.covariantOverrides.classOverrides.SubSubclass" + Jsii::Object.register_jsii_fqn("jsii-calc.covariantOverrides.classOverrides.SubSubclass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :name => { kind: :property, name: "name", is_optional: false }, + :unique => { kind: :property, name: "unique", is_optional: false }, + :say_hello => { kind: :method, name: "sayHello", is_optional: false }, + } + end + + # @return [String] + def name() + jsii_get_property("name") + end + + def name=(value) + jsii_set_property("name", value) + end + + # Ensures this class is different than its parent. + # + # @return [String] + def unique() + jsii_get_property("unique") + end + + def unique=(value) + jsii_set_property("unique", value) + end + + # @return [String] + def say_hello() + jsii_call_method("sayHello", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/covariant_overrides/class_overrides/subclass.rb 1`] = ` +require 'jsii' + +# Derived class that extends Superclass. +class JsiiCalc::CovariantOverrides::ClassOverrides::Subclass < ::JsiiCalc::CovariantOverrides::ClassOverrides::Superclass + self.jsii_fqn = "jsii-calc.covariantOverrides.classOverrides.Subclass" + Jsii::Object.register_jsii_fqn("jsii-calc.covariantOverrides.classOverrides.Subclass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :name => { kind: :property, name: "name", is_optional: false }, + :say_hello => { kind: :method, name: "sayHello", is_optional: false }, + } + end + + # @return [String] + def name() + jsii_get_property("name") + end + + def name=(value) + jsii_set_property("name", value) + end + + # @return [String] + def say_hello() + jsii_call_method("sayHello", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/covariant_overrides/class_overrides/superclass.rb 1`] = ` +require 'jsii' + +# Base class in the inheritance hierarchy. +class JsiiCalc::CovariantOverrides::ClassOverrides::Superclass < Jsii::Object + self.jsii_fqn = "jsii-calc.covariantOverrides.classOverrides.Superclass" + Jsii::Object.register_jsii_fqn("jsii-calc.covariantOverrides.classOverrides.Superclass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :name => { kind: :property, name: "name", is_optional: false }, + :say_hello => { kind: :method, name: "sayHello", is_optional: false }, + } + end + + # @return [String] + def name() + jsii_get_property("name") + end + + def name=(value) + jsii_set_property("name", value) + end + + # @return [String] + def say_hello() + jsii_call_method("sayHello", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/data_renderer.rb 1`] = ` +require 'jsii' + +# Verifies proper type handling through dynamic overrides. +class JsiiCalc::DataRenderer < Jsii::Object + self.jsii_fqn = "jsii-calc.DataRenderer" + Jsii::Object.register_jsii_fqn("jsii-calc.DataRenderer", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :render => { kind: :method, name: "render", is_optional: false }, + :render_arbitrary => { kind: :method, name: "renderArbitrary", is_optional: false }, + :render_map => { kind: :method, name: "renderMap", is_optional: false }, + } + end + + # @param data [Scope::JsiiCalcLib::MyFirstStruct, nil] + # @return [String] + def render(data = nil) + data = data.is_a?(Hash) ? ::Scope::JsiiCalcLib::MyFirstStruct.new(**data.transform_keys(&:to_sym)) : data + jsii_call_method("render", [data]) + end + + # @param data [Hash{String => Object}] + # @return [String] + def render_arbitrary(data) + jsii_call_method("renderArbitrary", [data]) + end + + # @param map [Hash{String => Object}] + # @return [String] + def render_map(map) + jsii_call_method("renderMap", [map]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/default.rb 1`] = ` +require 'jsii' + +# A class named "Default". +# +# @see https://github.com/aws/jsii/issues/2637 +class JsiiCalc::Default < Jsii::Object + self.jsii_fqn = "jsii-calc.Default" + Jsii::Object.register_jsii_fqn("jsii-calc.Default", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :please_compile => { kind: :method, name: "pleaseCompile", is_optional: false }, + } + end + + # @return [void] + def please_compile() + jsii_call_method("pleaseCompile", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/defaulted_constructor_argument.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DefaultedConstructorArgument < Jsii::Object + self.jsii_fqn = "jsii-calc.DefaultedConstructorArgument" + Jsii::Object.register_jsii_fqn("jsii-calc.DefaultedConstructorArgument", self) + + # @param arg1 [Numeric, nil] + # @param arg2 [String, nil] + # @param arg3 [DateTime, nil] + def initialize(arg1 = nil, arg2 = nil, arg3 = nil) + Jsii::Object.instance_method(:initialize).bind(self).call(arg1, arg2, arg3) + end + + def self.jsii_overridable_methods + { + :arg1 => { kind: :property, name: "arg1", is_optional: false }, + :arg3 => { kind: :property, name: "arg3", is_optional: false }, + :arg2 => { kind: :property, name: "arg2", is_optional: true }, + } + end + + # @return [Numeric] + def arg1() + jsii_get_property("arg1") + end + + # @return [DateTime] + def arg3() + jsii_get_property("arg3") + end + + # @return [String, nil] + def arg2() + jsii_get_property("arg2") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/demonstrate982.rb 1`] = ` +require 'jsii' + +# 1. +# +# call #takeThis() -> An ObjectRef will be provisioned for the value (it'll be re-used!) +# 2. call #takeThisToo() -> The ObjectRef from before will need to be down-cased to the ParentStruct982 type +class JsiiCalc::Demonstrate982 < Jsii::Object + self.jsii_fqn = "jsii-calc.Demonstrate982" + Jsii::Object.register_jsii_fqn("jsii-calc.Demonstrate982", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + + # It's dangerous to go alone! + # + # @return [JsiiCalc::ChildStruct982] + def self.take_this() + Jsii::Kernel.instance.call_static("jsii-calc.Demonstrate982", "takeThis", []) + end + + # It's dangerous to go alone! + # + # @return [JsiiCalc::ParentStruct982] + def self.take_this_too() + Jsii::Kernel.instance.call_static("jsii-calc.Demonstrate982", "takeThisToo", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/deprecated_class.rb 1`] = ` +require 'jsii' + +# @deprecated a pretty boring class +class JsiiCalc::DeprecatedClass < Jsii::Object + self.jsii_fqn = "jsii-calc.DeprecatedClass" + Jsii::Object.register_jsii_fqn("jsii-calc.DeprecatedClass", self) + + # @param readonly_string [String] + # @param mutable_number [Numeric, nil] + # @deprecated this constructor is "just" okay + def initialize(readonly_string, mutable_number = nil) + Jsii::Object.instance_method(:initialize).bind(self).call(readonly_string, mutable_number) + end + + def self.jsii_overridable_methods + { + :readonly_property => { kind: :property, name: "readonlyProperty", is_optional: false }, + :mutable_property => { kind: :property, name: "mutableProperty", is_optional: true }, + :method => { kind: :method, name: "method", is_optional: false }, + } + end + + # @return [String] + # @deprecated this is not always "wazoo", be ready to be disappointed + def readonly_property() + jsii_get_property("readonlyProperty") + end + + # @return [Numeric, nil] + # @deprecated shouldn't have been mutable + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) + jsii_set_property("mutableProperty", value) + end + + # @return [void] + # @deprecated it was a bad idea + def method() + jsii_call_method("method", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/deprecated_enum.rb 1`] = ` +require 'jsii' + +# @deprecated your deprecated selection of bad options +module JsiiCalc::DeprecatedEnum + # @note Default: + # @deprecated + OPTION_A = Jsii::Enum.new("jsii-calc.DeprecatedEnum", "OPTION_A") + # @note Default: + # @deprecated + OPTION_B = Jsii::Enum.new("jsii-calc.DeprecatedEnum", "OPTION_B") +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/deprecated_struct.rb 1`] = ` +require 'jsii' + +# @deprecated it just wraps a string +class JsiiCalc::DeprecatedStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.DeprecatedStruct", self) + + # @param readonly_property [String] + def initialize(readonly_property:) + @readonly_property = readonly_property + end + + # @return [String] + # @deprecated well, yeah + attr_reader :readonly_property + + def self.jsii_properties + { + :readonly_property => "readonlyProperty", + } + end + + def to_jsii + result = {} + result.merge!({ + "readonlyProperty" => @readonly_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/derived_class_has_no_properties/base.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DerivedClassHasNoProperties::Base < Jsii::Object + self.jsii_fqn = "jsii-calc.DerivedClassHasNoProperties.Base" + Jsii::Object.register_jsii_fqn("jsii-calc.DerivedClassHasNoProperties.Base", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :prop => { kind: :property, name: "prop", is_optional: false }, + } + end + + # @return [String] + def prop() + jsii_get_property("prop") + end + + def prop=(value) + jsii_set_property("prop", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/derived_class_has_no_properties/derived.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DerivedClassHasNoProperties::Derived < ::JsiiCalc::DerivedClassHasNoProperties::Base + self.jsii_fqn = "jsii-calc.DerivedClassHasNoProperties.Derived" + Jsii::Object.register_jsii_fqn("jsii-calc.DerivedClassHasNoProperties.Derived", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :prop => { kind: :property, name: "prop", is_optional: false }, + } + end + + # @return [String] + def prop() + jsii_get_property("prop") + end + + def prop=(value) + jsii_set_property("prop", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/derived_struct.rb 1`] = ` +require 'jsii' + +# A struct which derives from another struct. +class JsiiCalc::DerivedStruct < ::Scope::JsiiCalcLib::MyFirstStruct + Jsii::Object.register_jsii_fqn("jsii-calc.DerivedStruct", self) + + # @param anumber [Numeric] An awesome number value. + # @param astring [String] A string value. + # @param first_optional [Array, nil] + # @param another_required [DateTime] + # @param bool [Boolean] + # @param non_primitive [JsiiCalc::DoubleTrouble] An example of a non primitive property. + # @param another_optional [Hash{String => Scope::JsiiCalcLib::NumericValue}, nil] This is optional. + # @param optional_any [Object, nil] + # @param optional_array [Array, nil] + def initialize(anumber:, astring:, first_optional: nil, another_required:, bool:, non_primitive:, another_optional: nil, optional_any: nil, optional_array: nil) + @anumber = anumber + @astring = astring + @first_optional = first_optional + @another_required = another_required + @bool = bool + @non_primitive = non_primitive + @another_optional = another_optional + @optional_any = optional_any + @optional_array = optional_array + end + + # An awesome number value. + # + # @return [Numeric] + attr_reader :anumber + # A string value. + # + # @return [String] + attr_reader :astring + # @return [Array, nil] + attr_reader :first_optional + # @return [DateTime] + attr_reader :another_required + # @return [Boolean] + attr_reader :bool + # An example of a non primitive property. + # + # @return [JsiiCalc::DoubleTrouble] + attr_reader :non_primitive + # This is optional. + # + # @return [Hash{String => Scope::JsiiCalcLib::NumericValue}, nil] + attr_reader :another_optional + # @return [Object, nil] + attr_reader :optional_any + # @return [Array, nil] + attr_reader :optional_array + + def self.jsii_properties + { + :anumber => "anumber", + :astring => "astring", + :first_optional => "firstOptional", + :another_required => "anotherRequired", + :bool => "bool", + :non_primitive => "nonPrimitive", + :another_optional => "anotherOptional", + :optional_any => "optionalAny", + :optional_array => "optionalArray", + } + end + + def to_jsii + result = {} + result.merge!(super) + result.merge!({ + "anumber" => @anumber, + "astring" => @astring, + "firstOptional" => @first_optional, + "anotherRequired" => @another_required, + "bool" => @bool, + "nonPrimitive" => @non_primitive, + "anotherOptional" => @another_optional, + "optionalAny" => @optional_any, + "optionalArray" => @optional_array, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/diamond_bottom.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DiamondBottom < ::Scope::JsiiCalcLib::DiamondLeft + Jsii::Object.register_jsii_fqn("jsii-calc.DiamondBottom", self) + jsii_extra_struct_bases.push(::Scope::JsiiCalcLib::DiamondRight) + + # @param hoisted_top [String, nil] + # @param left [Numeric, nil] + # @param right [Boolean, nil] + # @param bottom [DateTime, nil] + def initialize(hoisted_top: nil, left: nil, right: nil, bottom: nil) + @hoisted_top = hoisted_top + @left = left + @right = right + @bottom = bottom + end + + # @return [String, nil] + attr_reader :hoisted_top + # @return [Numeric, nil] + attr_reader :left + # @return [Boolean, nil] + attr_reader :right + # @return [DateTime, nil] + attr_reader :bottom + + def self.jsii_properties + { + :hoisted_top => "hoistedTop", + :left => "left", + :right => "right", + :bottom => "bottom", + } + end + + def to_jsii + result = {} + result.merge!(super) + result.merge!({ + "hoistedTop" => @hoisted_top, + "left" => @left, + "right" => @right, + "bottom" => @bottom, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/diamond_inheritance_base_level_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DiamondInheritanceBaseLevelStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.DiamondInheritanceBaseLevelStruct", self) + + # @param base_level_property [String] + def initialize(base_level_property:) + @base_level_property = base_level_property + end + + # @return [String] + attr_reader :base_level_property + + def self.jsii_properties + { + :base_level_property => "baseLevelProperty", + } + end + + def to_jsii + result = {} + result.merge!({ + "baseLevelProperty" => @base_level_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/diamond_inheritance_first_mid_level_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DiamondInheritanceFirstMidLevelStruct < ::JsiiCalc::DiamondInheritanceBaseLevelStruct + Jsii::Object.register_jsii_fqn("jsii-calc.DiamondInheritanceFirstMidLevelStruct", self) + + # @param base_level_property [String] + # @param first_mid_level_property [String] + def initialize(base_level_property:, first_mid_level_property:) + @base_level_property = base_level_property + @first_mid_level_property = first_mid_level_property + end + + # @return [String] + attr_reader :base_level_property + # @return [String] + attr_reader :first_mid_level_property + + def self.jsii_properties + { + :base_level_property => "baseLevelProperty", + :first_mid_level_property => "firstMidLevelProperty", + } + end + + def to_jsii + result = {} + result.merge!(super) + result.merge!({ + "baseLevelProperty" => @base_level_property, + "firstMidLevelProperty" => @first_mid_level_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/diamond_inheritance_second_mid_level_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DiamondInheritanceSecondMidLevelStruct < ::JsiiCalc::DiamondInheritanceBaseLevelStruct + Jsii::Object.register_jsii_fqn("jsii-calc.DiamondInheritanceSecondMidLevelStruct", self) + + # @param base_level_property [String] + # @param second_mid_level_property [String] + def initialize(base_level_property:, second_mid_level_property:) + @base_level_property = base_level_property + @second_mid_level_property = second_mid_level_property + end + + # @return [String] + attr_reader :base_level_property + # @return [String] + attr_reader :second_mid_level_property + + def self.jsii_properties + { + :base_level_property => "baseLevelProperty", + :second_mid_level_property => "secondMidLevelProperty", + } + end + + def to_jsii + result = {} + result.merge!(super) + result.merge!({ + "baseLevelProperty" => @base_level_property, + "secondMidLevelProperty" => @second_mid_level_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/diamond_inheritance_top_level_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DiamondInheritanceTopLevelStruct < ::JsiiCalc::DiamondInheritanceFirstMidLevelStruct + Jsii::Object.register_jsii_fqn("jsii-calc.DiamondInheritanceTopLevelStruct", self) + jsii_extra_struct_bases.push(::JsiiCalc::DiamondInheritanceSecondMidLevelStruct) + + # @param base_level_property [String] + # @param first_mid_level_property [String] + # @param second_mid_level_property [String] + # @param top_level_property [String] + def initialize(base_level_property:, first_mid_level_property:, second_mid_level_property:, top_level_property:) + @base_level_property = base_level_property + @first_mid_level_property = first_mid_level_property + @second_mid_level_property = second_mid_level_property + @top_level_property = top_level_property + end + + # @return [String] + attr_reader :base_level_property + # @return [String] + attr_reader :first_mid_level_property + # @return [String] + attr_reader :second_mid_level_property + # @return [String] + attr_reader :top_level_property + + def self.jsii_properties + { + :base_level_property => "baseLevelProperty", + :first_mid_level_property => "firstMidLevelProperty", + :second_mid_level_property => "secondMidLevelProperty", + :top_level_property => "topLevelProperty", + } + end + + def to_jsii + result = {} + result.merge!(super) + result.merge!({ + "baseLevelProperty" => @base_level_property, + "firstMidLevelProperty" => @first_mid_level_property, + "secondMidLevelProperty" => @second_mid_level_property, + "topLevelProperty" => @top_level_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/disappointing_collection_source.rb 1`] = ` +require 'jsii' + +# Verifies that null/undefined can be returned for optional collections. +# +# This source of collections is disappointing - it'll always give you nothing :( +class JsiiCalc::DisappointingCollectionSource < Jsii::Object + self.jsii_fqn = "jsii-calc.DisappointingCollectionSource" + Jsii::Object.register_jsii_fqn("jsii-calc.DisappointingCollectionSource", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.DisappointingCollectionSource does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # Some List of strings, maybe? + # + # (Nah, just a billion dollars mistake!) + # + # @return [Array, nil] + def self.MAYBE_LIST() + Jsii::Kernel.instance.get_static("jsii-calc.DisappointingCollectionSource", "maybeList") + end + + # Some Map of strings to numbers, maybe? + # + # (Nah, just a billion dollars mistake!) + # + # @return [Hash{String => Numeric}, nil] + def self.MAYBE_MAP() + Jsii::Kernel.instance.get_static("jsii-calc.DisappointingCollectionSource", "maybeMap") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/do_not_override_privates.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DoNotOverridePrivates < Jsii::Object + self.jsii_fqn = "jsii-calc.DoNotOverridePrivates" + Jsii::Object.register_jsii_fqn("jsii-calc.DoNotOverridePrivates", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :change_private_property_value => { kind: :method, name: "changePrivatePropertyValue", is_optional: false }, + :private_method_value => { kind: :method, name: "privateMethodValue", is_optional: false }, + :private_property_value => { kind: :method, name: "privatePropertyValue", is_optional: false }, + } + end + + # @param new_value [String] + # @return [void] + def change_private_property_value(new_value) + jsii_call_method("changePrivatePropertyValue", [new_value]) + end + + # @return [String] + def private_method_value() + jsii_call_method("privateMethodValue", []) + end + + # @return [String] + def private_property_value() + jsii_call_method("privatePropertyValue", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/do_not_recognize_any_as_optional.rb 1`] = ` +require 'jsii' + +# jsii#284: do not recognize "any" as an optional argument. +class JsiiCalc::DoNotRecognizeAnyAsOptional < Jsii::Object + self.jsii_fqn = "jsii-calc.DoNotRecognizeAnyAsOptional" + Jsii::Object.register_jsii_fqn("jsii-calc.DoNotRecognizeAnyAsOptional", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :method => { kind: :method, name: "method", is_optional: false }, + } + end + + # @param _required_any [Object] + # @param _optional_any [Object, nil] + # @param _optional_string [String, nil] + # @return [void] + def method(_required_any, _optional_any = nil, _optional_string = nil) + jsii_call_method("method", [_required_any, _optional_any, _optional_string]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/documented_class.rb 1`] = ` +require 'jsii' + +# Here's the first line of the TSDoc comment. +# +# This is the meat of the TSDoc comment. It may contain +# multiple lines and multiple paragraphs. +# +# Multiple paragraphs are separated by an empty line. +# +# @example +# const x = 12 + 44; +# const s1 = "string"; +# const s2 = "string \\nwith new newlines"; // see https://github.com/aws/jsii/issues/2569 +# const s3 = \`string +# with +# new lines\`; +class JsiiCalc::DocumentedClass < Jsii::Object + self.jsii_fqn = "jsii-calc.DocumentedClass" + Jsii::Object.register_jsii_fqn("jsii-calc.DocumentedClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :greet => { kind: :method, name: "greet", is_optional: false }, + :hola => { kind: :method, name: "hola", is_optional: false }, + :moin => { kind: :method, name: "moin", is_optional: false }, + } + end + + # Greet the indicated person. + # + # This will print out a friendly greeting intended for the indicated person. + # + # @param greetee [JsiiCalc::Greetee, nil] The person to be greeted. + # @return [Numeric] A number that everyone knows very well and represents the answer to the ultimate question + def greet(greetee = nil) + greetee = greetee.is_a?(Hash) ? ::JsiiCalc::Greetee.new(**greetee.transform_keys(&:to_sym)) : greetee + jsii_call_method("greet", [greetee]) + end + + # Say ¡Hola! + # + # @return [void] + def hola() + jsii_call_method("hola", []) + end + + # Some comments have an escaped star backslash in them, ending the comment if left unescaped. + # + # For example: 'projects/*/global/networks/network-1'. + # + # @return [void] + def moin() + jsii_call_method("moin", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/dont_complain_about_variadic_after_optional.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DontComplainAboutVariadicAfterOptional < Jsii::Object + self.jsii_fqn = "jsii-calc.DontComplainAboutVariadicAfterOptional" + Jsii::Object.register_jsii_fqn("jsii-calc.DontComplainAboutVariadicAfterOptional", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :optional_and_variadic => { kind: :method, name: "optionalAndVariadic", is_optional: false }, + } + end + + # @param optional [String, nil] + # @param things [Array] + # @return [String] + def optional_and_variadic(optional = nil, *things) + jsii_call_method("optionalAndVariadic", [optional, *things]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/dont_use_me.rb 1`] = ` +require 'jsii' + +# > Don't use this interface An interface that shouldn't be used, with the annotation in a weird place. +class JsiiCalc::DontUseMe < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.DontUseMe", self) + + # @param dont_set_me [String, nil] > Don't set this parameter. + def initialize(dont_set_me: nil) + @dont_set_me = dont_set_me + end + + # > Don't set this parameter. + # + # A parameter that shouldn't be set, with the annotation in a weird place. + # + # @return [String, nil] + attr_reader :dont_set_me + + def self.jsii_properties + { + :dont_set_me => "dontSetMe", + } + end + + def to_jsii + result = {} + result.merge!({ + "dontSetMe" => @dont_set_me, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/double_trouble.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DoubleTrouble < Jsii::Object + include ::JsiiCalc::IFriendlyRandomGenerator + self.jsii_fqn = "jsii-calc.DoubleTrouble" + Jsii::Object.register_jsii_fqn("jsii-calc.DoubleTrouble", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :hello => { kind: :method, name: "hello", is_optional: false }, + :_next => { kind: :method, name: "next", is_optional: false }, + } + end + + # Say hello! + # + # @return [String] + def hello() + jsii_call_method("hello", []) + end + + # Returns another random number. + # + # @return [Numeric] + def _next() + jsii_call_method("next", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/dummy_obj.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DummyObj < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.DummyObj", self) + + # @param example [String] + def initialize(example:) + @example = example + end + + # @return [String] + attr_reader :example + + def self.jsii_properties + { + :example => "example", + } + end + + def to_jsii + result = {} + result.merge!({ + "example" => @example, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/dynamic_property_bearer.rb 1`] = ` +require 'jsii' + +# Ensures we can override a dynamic property that was inherited. +class JsiiCalc::DynamicPropertyBearer < Jsii::Object + self.jsii_fqn = "jsii-calc.DynamicPropertyBearer" + Jsii::Object.register_jsii_fqn("jsii-calc.DynamicPropertyBearer", self) + + # @param value_store [String] + def initialize(value_store) + Jsii::Object.instance_method(:initialize).bind(self).call(value_store) + end + + def self.jsii_overridable_methods + { + :dynamic_property => { kind: :property, name: "dynamicProperty", is_optional: false }, + :value_store => { kind: :property, name: "valueStore", is_optional: false }, + } + end + + # @return [String] + def dynamic_property() + jsii_get_property("dynamicProperty") + end + + def dynamic_property=(value) + jsii_set_property("dynamicProperty", value) + end + + # @return [String] + def value_store() + jsii_get_property("valueStore") + end + + def value_store=(value) + jsii_set_property("valueStore", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/dynamic_property_bearer_child.rb 1`] = ` +require 'jsii' + +class JsiiCalc::DynamicPropertyBearerChild < ::JsiiCalc::DynamicPropertyBearer + self.jsii_fqn = "jsii-calc.DynamicPropertyBearerChild" + Jsii::Object.register_jsii_fqn("jsii-calc.DynamicPropertyBearerChild", self) + + # @param original_value [String] + def initialize(original_value) + Jsii::Object.instance_method(:initialize).bind(self).call(original_value) + end + + def self.jsii_overridable_methods + { + :dynamic_property => { kind: :property, name: "dynamicProperty", is_optional: false }, + :value_store => { kind: :property, name: "valueStore", is_optional: false }, + :original_value => { kind: :property, name: "originalValue", is_optional: false }, + :override_value => { kind: :method, name: "overrideValue", is_optional: false }, + } + end + + # @return [String] + def dynamic_property() + jsii_get_property("dynamicProperty") + end + + def dynamic_property=(value) + jsii_set_property("dynamicProperty", value) + end + + # @return [String] + def value_store() + jsii_get_property("valueStore") + end + + def value_store=(value) + jsii_set_property("valueStore", value) + end + + # @return [String] + def original_value() + jsii_get_property("originalValue") + end + + # Sets \`this.dynamicProperty\` to the new value, and returns the old value. + # + # @param new_value [String] the new value to be set. + # @return [String] the old value that was set. + def override_value(new_value) + jsii_call_method("overrideValue", [new_value]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/entropy.rb 1`] = ` +require 'jsii' + +# This class is used to validate that serialization and deserialization does not interpret ISO-8601-formatted timestampts to the native date/time object, as the jsii protocol has a $jsii$date wrapper for this purpose (node's JSON parsing does *NOT* detect dates automatically in this way, so host libraries should not either). +class JsiiCalc::Entropy < Jsii::Object + self.jsii_fqn = "jsii-calc.Entropy" + Jsii::Object.register_jsii_fqn("jsii-calc.Entropy", self) + + # Creates a new instance of Entropy. + # + # @param clock [JsiiCalc::IWallClock] your implementation of \`WallClock\`. + def initialize(clock) + clock = Jsii::Utils.coerce_callable(clock, ::JsiiCalc::IWallClock) + Jsii::Object.instance_method(:initialize).bind(self).call(clock) + end + + def self.jsii_overridable_methods + { + :increase => { kind: :method, name: "increase", is_optional: false }, + :repeat => { kind: :method, name: "repeat", is_optional: false }, + } + end + + # Increases entropy by consuming time from the clock (yes, this is a long shot, please don't judge). + # + # @return [String] the time from the \`WallClock\`. + def increase() + jsii_call_method("increase", []) + end + + # Implement this method such that it returns \`word\`. + # + # @param word [String] the value to return. + # @return [String] \`word\`. + def repeat(word) + jsii_call_method("repeat", [word]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/enum_dispenser.rb 1`] = ` +require 'jsii' + +class JsiiCalc::EnumDispenser < Jsii::Object + self.jsii_fqn = "jsii-calc.EnumDispenser" + Jsii::Object.register_jsii_fqn("jsii-calc.EnumDispenser", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.EnumDispenser does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @return [JsiiCalc::AllTypesEnum] + def self.random_integer_like_enum() + Jsii::Kernel.instance.call_static("jsii-calc.EnumDispenser", "randomIntegerLikeEnum", []) + end + + # @return [JsiiCalc::StringEnum] + def self.random_string_like_enum() + Jsii::Kernel.instance.call_static("jsii-calc.EnumDispenser", "randomStringLikeEnum", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/erase_undefined_hash_values.rb 1`] = ` +require 'jsii' + +class JsiiCalc::EraseUndefinedHashValues < Jsii::Object + self.jsii_fqn = "jsii-calc.EraseUndefinedHashValues" + Jsii::Object.register_jsii_fqn("jsii-calc.EraseUndefinedHashValues", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + + # Returns \`true\` if \`key\` is defined in \`opts\`. + # + # Used to check that undefined/null hash values + # are being erased when sending values from native code to JS. + # + # @param opts [JsiiCalc::EraseUndefinedHashValuesOptions] + # @param key [String] + # @return [Boolean] + def self.does_key_exist(opts, key) + opts = opts.is_a?(Hash) ? ::JsiiCalc::EraseUndefinedHashValuesOptions.new(**opts.transform_keys(&:to_sym)) : opts + Jsii::Kernel.instance.call_static("jsii-calc.EraseUndefinedHashValues", "doesKeyExist", [opts, key]) + end + + # We expect "prop1" to be erased. + # + # @return [Hash{String => Object}] + def self.prop1_is_null() + Jsii::Kernel.instance.call_static("jsii-calc.EraseUndefinedHashValues", "prop1IsNull", []) + end + + # We expect "prop2" to be erased. + # + # @return [Hash{String => Object}] + def self.prop2_is_undefined() + Jsii::Kernel.instance.call_static("jsii-calc.EraseUndefinedHashValues", "prop2IsUndefined", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/erase_undefined_hash_values_options.rb 1`] = ` +require 'jsii' + +class JsiiCalc::EraseUndefinedHashValuesOptions < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.EraseUndefinedHashValuesOptions", self) + + # @param option1 [String, nil] + # @param option2 [String, nil] + def initialize(option1: nil, option2: nil) + @option1 = option1 + @option2 = option2 + end + + # @return [String, nil] + attr_reader :option1 + # @return [String, nil] + attr_reader :option2 + + def self.jsii_properties + { + :option1 => "option1", + :option2 => "option2", + } + end + + def to_jsii + result = {} + result.merge!({ + "option1" => @option1, + "option2" => @option2, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/experimental_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ExperimentalClass < Jsii::Object + self.jsii_fqn = "jsii-calc.ExperimentalClass" + Jsii::Object.register_jsii_fqn("jsii-calc.ExperimentalClass", self) + + # @param readonly_string [String] + # @param mutable_number [Numeric, nil] + def initialize(readonly_string, mutable_number = nil) + Jsii::Object.instance_method(:initialize).bind(self).call(readonly_string, mutable_number) + end + + def self.jsii_overridable_methods + { + :readonly_property => { kind: :property, name: "readonlyProperty", is_optional: false }, + :mutable_property => { kind: :property, name: "mutableProperty", is_optional: true }, + :method => { kind: :method, name: "method", is_optional: false }, + } + end + + # @return [String] + def readonly_property() + jsii_get_property("readonlyProperty") + end + + # @return [Numeric, nil] + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) + jsii_set_property("mutableProperty", value) + end + + # @return [void] + def method() + jsii_call_method("method", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/experimental_enum.rb 1`] = ` +require 'jsii' + +module JsiiCalc::ExperimentalEnum + # @note Default: + # @deprecated + OPTION_A = Jsii::Enum.new("jsii-calc.ExperimentalEnum", "OPTION_A") + # @note Default: + # @deprecated + OPTION_B = Jsii::Enum.new("jsii-calc.ExperimentalEnum", "OPTION_B") +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/experimental_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ExperimentalStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.ExperimentalStruct", self) + + # @param readonly_property [String] + def initialize(readonly_property:) + @readonly_property = readonly_property + end + + # @return [String] + attr_reader :readonly_property + + def self.jsii_properties + { + :readonly_property => "readonlyProperty", + } + end + + def to_jsii + result = {} + result.merge!({ + "readonlyProperty" => @readonly_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/exported_base_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ExportedBaseClass < Jsii::Object + self.jsii_fqn = "jsii-calc.ExportedBaseClass" + Jsii::Object.register_jsii_fqn("jsii-calc.ExportedBaseClass", self) + + # @param success [Boolean] + def initialize(success) + Jsii::Object.instance_method(:initialize).bind(self).call(success) + end + + def self.jsii_overridable_methods + { + :success => { kind: :property, name: "success", is_optional: false }, + } + end + + # @return [Boolean] + def success() + jsii_get_property("success") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/extends_internal_interface.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ExtendsInternalInterface < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.ExtendsInternalInterface", self) + + # @param boom [Boolean] + # @param prop [String] + def initialize(boom:, prop:) + @boom = boom + @prop = prop + end + + # @return [Boolean] + attr_reader :boom + # @return [String] + attr_reader :prop + + def self.jsii_properties + { + :boom => "boom", + :prop => "prop", + } + end + + def to_jsii + result = {} + result.merge!({ + "boom" => @boom, + "prop" => @prop, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/external_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ExternalClass < Jsii::Object + self.jsii_fqn = "jsii-calc.ExternalClass" + Jsii::Object.register_jsii_fqn("jsii-calc.ExternalClass", self) + + # @param readonly_string [String] + # @param mutable_number [Numeric, nil] + def initialize(readonly_string, mutable_number = nil) + Jsii::Object.instance_method(:initialize).bind(self).call(readonly_string, mutable_number) + end + + def self.jsii_overridable_methods + { + :readonly_property => { kind: :property, name: "readonlyProperty", is_optional: false }, + :mutable_property => { kind: :property, name: "mutableProperty", is_optional: true }, + :method => { kind: :method, name: "method", is_optional: false }, + } + end + + # @return [String] + def readonly_property() + jsii_get_property("readonlyProperty") + end + + # @return [Numeric, nil] + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) + jsii_set_property("mutableProperty", value) + end + + # @return [void] + def method() + jsii_call_method("method", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/external_enum.rb 1`] = ` +require 'jsii' + +module JsiiCalc::ExternalEnum + # @note Default: + # @deprecated + OPTION_A = Jsii::Enum.new("jsii-calc.ExternalEnum", "OPTION_A") + # @note Default: + # @deprecated + OPTION_B = Jsii::Enum.new("jsii-calc.ExternalEnum", "OPTION_B") +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/external_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ExternalStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.ExternalStruct", self) + + # @param readonly_property [String] + def initialize(readonly_property:) + @readonly_property = readonly_property + end + + # @return [String] + attr_reader :readonly_property + + def self.jsii_properties + { + :readonly_property => "readonlyProperty", + } + end + + def to_jsii + result = {} + result.merge!({ + "readonlyProperty" => @readonly_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/full_combo.rb 1`] = ` +require 'jsii' + +class JsiiCalc::FullCombo < ::JsiiCalc::BaseClass + include ::JsiiCalc::IIndirectlyImplemented + self.jsii_fqn = "jsii-calc.FullCombo" + Jsii::Object.register_jsii_fqn("jsii-calc.FullCombo", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.FullCombo does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + :property => { kind: :property, name: "property", is_optional: false }, + :method => { kind: :method, name: "method", is_optional: false }, + } + end + + # @return [String] + def property() + jsii_get_property("property") + end + + # @return [Numeric] + def method() + jsii_call_method("method", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/give_me_structs.rb 1`] = ` +require 'jsii' + +class JsiiCalc::GiveMeStructs < Jsii::Object + self.jsii_fqn = "jsii-calc.GiveMeStructs" + Jsii::Object.register_jsii_fqn("jsii-calc.GiveMeStructs", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :struct_literal => { kind: :property, name: "structLiteral", is_optional: false }, + :derived_to_first => { kind: :method, name: "derivedToFirst", is_optional: false }, + :read_derived_non_primitive => { kind: :method, name: "readDerivedNonPrimitive", is_optional: false }, + :read_first_number => { kind: :method, name: "readFirstNumber", is_optional: false }, + } + end + + # @return [Scope::JsiiCalcLib::StructWithOnlyOptionals] + def struct_literal() + jsii_get_property("structLiteral") + end + + # Accepts a struct of type DerivedStruct and returns a struct of type FirstStruct. + # + # @param derived [JsiiCalc::DerivedStruct] + # @return [Scope::JsiiCalcLib::MyFirstStruct] + def derived_to_first(derived) + derived = derived.is_a?(Hash) ? ::JsiiCalc::DerivedStruct.new(**derived.transform_keys(&:to_sym)) : derived + jsii_call_method("derivedToFirst", [derived]) + end + + # Returns the boolean from a DerivedStruct struct. + # + # @param derived [JsiiCalc::DerivedStruct] + # @return [JsiiCalc::DoubleTrouble] + def read_derived_non_primitive(derived) + derived = derived.is_a?(Hash) ? ::JsiiCalc::DerivedStruct.new(**derived.transform_keys(&:to_sym)) : derived + jsii_call_method("readDerivedNonPrimitive", [derived]) + end + + # Returns the "anumber" from a MyFirstStruct struct; + # + # @param first [Scope::JsiiCalcLib::MyFirstStruct] + # @return [Numeric] + def read_first_number(first) + first = first.is_a?(Hash) ? ::Scope::JsiiCalcLib::MyFirstStruct.new(**first.transform_keys(&:to_sym)) : first + jsii_call_method("readFirstNumber", [first]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/greetee.rb 1`] = ` +require 'jsii' + +# These are some arguments you can pass to a method. +class JsiiCalc::Greetee < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.Greetee", self) + + # @param name [String, nil] The name of the greetee. + def initialize(name: nil) + @name = name + end + + # The name of the greetee. + # + # @return [String, nil] + # @note Default: world + attr_reader :name + + def self.jsii_properties + { + :name => "name", + } + end + + def to_jsii + result = {} + result.merge!({ + "name" => @name, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/greeting_augmenter.rb 1`] = ` +require 'jsii' + +class JsiiCalc::GreetingAugmenter < Jsii::Object + self.jsii_fqn = "jsii-calc.GreetingAugmenter" + Jsii::Object.register_jsii_fqn("jsii-calc.GreetingAugmenter", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :better_greeting => { kind: :method, name: "betterGreeting", is_optional: false }, + } + end + + # @param friendly [Scope::JsiiCalcLib::IFriendly] + # @return [String] + def better_greeting(friendly) + friendly = Jsii::Utils.coerce_callable(friendly, ::Scope::JsiiCalcLib::IFriendly) + jsii_call_method("betterGreeting", [friendly]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/_readme.rb 1`] = ` +# Verifies homonymous forward references don't trip the Python type checker +# +# This has been an issue when stub functions were introduced to create a reliable source for type checking +# information, which was reported in https://github.com/aws/jsii/issues/3818. +module JsiiCalc::HomonymousForwardReferences; end + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/bar/consumer.rb 1`] = ` +require 'jsii' + +class JsiiCalc::HomonymousForwardReferences::Bar::Consumer < Jsii::Object + self.jsii_fqn = "jsii-calc.homonymousForwardReferences.bar.Consumer" + Jsii::Object.register_jsii_fqn("jsii-calc.homonymousForwardReferences.bar.Consumer", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.homonymousForwardReferences.bar.Consumer does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @param props [JsiiCalc::HomonymousForwardReferences::Bar::ConsumerProps] + # @return [JsiiCalc::HomonymousForwardReferences::Bar::Homonymous] + def self.consume(props) + props = props.is_a?(Hash) ? ::JsiiCalc::HomonymousForwardReferences::Bar::ConsumerProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Kernel.instance.call_static("jsii-calc.homonymousForwardReferences.bar.Consumer", "consume", [props]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/bar/consumer_props.rb 1`] = ` +require 'jsii' + +class JsiiCalc::HomonymousForwardReferences::Bar::ConsumerProps < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.homonymousForwardReferences.bar.ConsumerProps", self) + + # @param homonymous [JsiiCalc::HomonymousForwardReferences::Bar::Homonymous] + def initialize(homonymous:) + @homonymous = homonymous.is_a?(Hash) ? ::JsiiCalc::HomonymousForwardReferences::Bar::Homonymous.new(**homonymous.transform_keys(&:to_sym)) : homonymous + end + + # @return [JsiiCalc::HomonymousForwardReferences::Bar::Homonymous] + attr_reader :homonymous + + def self.jsii_properties + { + :homonymous => "homonymous", + } + end + + def to_jsii + result = {} + result.merge!({ + "homonymous" => @homonymous, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/bar/homonymous.rb 1`] = ` +require 'jsii' + +class JsiiCalc::HomonymousForwardReferences::Bar::Homonymous < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.homonymousForwardReferences.bar.Homonymous", self) + + # @param numeric_property [Numeric] + def initialize(numeric_property:) + @numeric_property = numeric_property + end + + # @return [Numeric] + attr_reader :numeric_property + + def self.jsii_properties + { + :numeric_property => "numericProperty", + } + end + + def to_jsii + result = {} + result.merge!({ + "numericProperty" => @numeric_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/foo/consumer.rb 1`] = ` +require 'jsii' + +class JsiiCalc::HomonymousForwardReferences::Foo::Consumer < Jsii::Object + self.jsii_fqn = "jsii-calc.homonymousForwardReferences.foo.Consumer" + Jsii::Object.register_jsii_fqn("jsii-calc.homonymousForwardReferences.foo.Consumer", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.homonymousForwardReferences.foo.Consumer does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @param props [JsiiCalc::HomonymousForwardReferences::Foo::ConsumerProps] + # @return [JsiiCalc::HomonymousForwardReferences::Foo::Homonymous] + def self.consume(props) + props = props.is_a?(Hash) ? ::JsiiCalc::HomonymousForwardReferences::Foo::ConsumerProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Kernel.instance.call_static("jsii-calc.homonymousForwardReferences.foo.Consumer", "consume", [props]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/foo/consumer_props.rb 1`] = ` +require 'jsii' + +class JsiiCalc::HomonymousForwardReferences::Foo::ConsumerProps < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.homonymousForwardReferences.foo.ConsumerProps", self) + + # @param homonymous [JsiiCalc::HomonymousForwardReferences::Foo::Homonymous] + def initialize(homonymous:) + @homonymous = homonymous.is_a?(Hash) ? ::JsiiCalc::HomonymousForwardReferences::Foo::Homonymous.new(**homonymous.transform_keys(&:to_sym)) : homonymous + end + + # @return [JsiiCalc::HomonymousForwardReferences::Foo::Homonymous] + attr_reader :homonymous + + def self.jsii_properties + { + :homonymous => "homonymous", + } + end + + def to_jsii + result = {} + result.merge!({ + "homonymous" => @homonymous, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/foo/homonymous.rb 1`] = ` +require 'jsii' + +class JsiiCalc::HomonymousForwardReferences::Foo::Homonymous < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.homonymousForwardReferences.foo.Homonymous", self) + + # @param string_property [String] + def initialize(string_property:) + @string_property = string_property + end + + # @return [String] + attr_reader :string_property + + def self.jsii_properties + { + :string_property => "stringProperty", + } + end + + def to_jsii + result = {} + result.merge!({ + "stringProperty" => @string_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_anonymous_implementation_provider.rb 1`] = ` +require 'jsii' + +# We can return an anonymous interface implementation from an override without losing the interface declarations. +module JsiiCalc::IAnonymousImplementationProvider + Jsii::Object.register_jsii_fqn("jsii-calc.IAnonymousImplementationProvider", self) + + # @return [JsiiCalc::Implementation] + def provide_as_class() + jsii_call_method("provideAsClass", []) + end + + # @return [JsiiCalc::IAnonymouslyImplementMe] + def provide_as_interface() + jsii_call_method("provideAsInterface", []) + end + + def self.jsii_overridable_methods + { + :provide_as_class => { kind: :method, name: "provideAsClass", is_optional: false }, + :provide_as_interface => { kind: :method, name: "provideAsInterface", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_anonymously_implement_me.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IAnonymouslyImplementMe + Jsii::Object.register_jsii_fqn("jsii-calc.IAnonymouslyImplementMe", self) + + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # @return [String] + def verb() + jsii_call_method("verb", []) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :verb => { kind: :method, name: "verb", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_another_public_interface.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IAnotherPublicInterface + Jsii::Object.register_jsii_fqn("jsii-calc.IAnotherPublicInterface", self) + + # @return [String] + def a() + jsii_get_property("a") + end + + def a=(value) + jsii_set_property("a", value) + end + + def self.jsii_overridable_methods + { + :a => { kind: :property, name: "a", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_bell.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IBell + Jsii::Object.register_jsii_fqn("jsii-calc.IBell", self) + + # @return [void] + def ring() + jsii_call_method("ring", []) + end + + def self.jsii_overridable_methods + { + :ring => { kind: :method, name: "ring", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_bell_ringer.rb 1`] = ` +require 'jsii' + +# Takes the object parameter as an interface. +module JsiiCalc::IBellRinger + Jsii::Object.register_jsii_fqn("jsii-calc.IBellRinger", self) + + # @param bell [JsiiCalc::IBell] + # @return [void] + def your_turn(bell) + bell = Jsii::Utils.coerce_callable(bell, ::JsiiCalc::IBell) + jsii_call_method("yourTurn", [bell]) + end + + def self.jsii_overridable_methods + { + :your_turn => { kind: :method, name: "yourTurn", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_concrete_bell_ringer.rb 1`] = ` +require 'jsii' + +# Takes the object parameter as a calss. +module JsiiCalc::IConcreteBellRinger + Jsii::Object.register_jsii_fqn("jsii-calc.IConcreteBellRinger", self) + + # @param bell [JsiiCalc::Bell] + # @return [void] + def your_turn(bell) + jsii_call_method("yourTurn", [bell]) + end + + def self.jsii_overridable_methods + { + :your_turn => { kind: :method, name: "yourTurn", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_deprecated_interface.rb 1`] = ` +require 'jsii' + +# @deprecated useless interface +module JsiiCalc::IDeprecatedInterface + Jsii::Object.register_jsii_fqn("jsii-calc.IDeprecatedInterface", self) + + # @return [Numeric, nil] + # @deprecated could be better + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) + jsii_set_property("mutableProperty", value) + end + + # @return [void] + # @deprecated services no purpose + def method() + jsii_call_method("method", []) + end + + def self.jsii_overridable_methods + { + :mutable_property => { kind: :property, name: "mutableProperty", is_optional: true }, + :method => { kind: :method, name: "method", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_experimental_interface.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IExperimentalInterface + Jsii::Object.register_jsii_fqn("jsii-calc.IExperimentalInterface", self) + + # @return [Numeric, nil] + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) + jsii_set_property("mutableProperty", value) + end + + # @return [void] + def method() + jsii_call_method("method", []) + end + + def self.jsii_overridable_methods + { + :mutable_property => { kind: :property, name: "mutableProperty", is_optional: true }, + :method => { kind: :method, name: "method", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_extends_private_interface.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IExtendsPrivateInterface + Jsii::Object.register_jsii_fqn("jsii-calc.IExtendsPrivateInterface", self) + + # @return [Array] + def more_things() + jsii_get_property("moreThings") + end + + # @return [String] + def private() + jsii_get_property("private") + end + + def private=(value) + jsii_set_property("private", value) + end + + def self.jsii_overridable_methods + { + :more_things => { kind: :property, name: "moreThings", is_optional: false }, + :private => { kind: :property, name: "private", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_external_interface.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IExternalInterface + Jsii::Object.register_jsii_fqn("jsii-calc.IExternalInterface", self) + + # @return [Numeric, nil] + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) + jsii_set_property("mutableProperty", value) + end + + # @return [void] + def method() + jsii_call_method("method", []) + end + + def self.jsii_overridable_methods + { + :mutable_property => { kind: :property, name: "mutableProperty", is_optional: true }, + :method => { kind: :method, name: "method", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_friendlier.rb 1`] = ` +require 'jsii' + +# Even friendlier classes can implement this interface. +module JsiiCalc::IFriendlier + include ::Scope::JsiiCalcLib::IFriendly + Jsii::Object.register_jsii_fqn("jsii-calc.IFriendlier", self) + + # Say hello! + # + # @return [String] + def hello() + jsii_call_method("hello", []) + end + + # Say farewell. + # + # @return [String] + def farewell() + jsii_call_method("farewell", []) + end + + # Say goodbye. + # + # @return [String] A goodbye blessing. + def goodbye() + jsii_call_method("goodbye", []) + end + + def self.jsii_overridable_methods + { + :hello => { kind: :method, name: "hello", is_optional: false }, + :farewell => { kind: :method, name: "farewell", is_optional: false }, + :goodbye => { kind: :method, name: "goodbye", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_friendly_random_generator.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IFriendlyRandomGenerator + include ::JsiiCalc::IRandomNumberGenerator + include ::Scope::JsiiCalcLib::IFriendly + Jsii::Object.register_jsii_fqn("jsii-calc.IFriendlyRandomGenerator", self) + + # Returns another random number. + # + # @return [Numeric] A random number. + def _next() + jsii_call_method("next", []) + end + + # Say hello! + # + # @return [String] + def hello() + jsii_call_method("hello", []) + end + + def self.jsii_overridable_methods + { + :_next => { kind: :method, name: "next", is_optional: false }, + :hello => { kind: :method, name: "hello", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_indirectly_implemented.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IIndirectlyImplemented + Jsii::Object.register_jsii_fqn("jsii-calc.IIndirectlyImplemented", self) + + # @return [String] + def property() + jsii_get_property("property") + end + + # @return [Numeric] + def method() + jsii_call_method("method", []) + end + + def self.jsii_overridable_methods + { + :property => { kind: :property, name: "property", is_optional: false }, + :method => { kind: :method, name: "method", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_interface_implemented_by_abstract_class.rb 1`] = ` +require 'jsii' + +# awslabs/jsii#220 Abstract return type. +module JsiiCalc::IInterfaceImplementedByAbstractClass + Jsii::Object.register_jsii_fqn("jsii-calc.IInterfaceImplementedByAbstractClass", self) + + # @return [String] + def prop_from_interface() + jsii_get_property("propFromInterface") + end + + def self.jsii_overridable_methods + { + :prop_from_interface => { kind: :property, name: "propFromInterface", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_interface_that_should_not_be_a_data_type.rb 1`] = ` +require 'jsii' + +# Even though this interface has only properties, it is disqualified from being a datatype because it inherits from an interface that is not a datatype. +module JsiiCalc::IInterfaceThatShouldNotBeADataType + include ::JsiiCalc::IInterfaceWithMethods + Jsii::Object.register_jsii_fqn("jsii-calc.IInterfaceThatShouldNotBeADataType", self) + + # @return [String] + def value() + jsii_get_property("value") + end + + # @return [String] + def other_value() + jsii_get_property("otherValue") + end + + # @return [void] + def do_things() + jsii_call_method("doThings", []) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :other_value => { kind: :property, name: "otherValue", is_optional: false }, + :do_things => { kind: :method, name: "doThings", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_interface_with_internal.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IInterfaceWithInternal + Jsii::Object.register_jsii_fqn("jsii-calc.IInterfaceWithInternal", self) + + # @return [void] + def visible() + jsii_call_method("visible", []) + end + + def self.jsii_overridable_methods + { + :visible => { kind: :method, name: "visible", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_interface_with_methods.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IInterfaceWithMethods + Jsii::Object.register_jsii_fqn("jsii-calc.IInterfaceWithMethods", self) + + # @return [String] + def value() + jsii_get_property("value") + end + + # @return [void] + def do_things() + jsii_call_method("doThings", []) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :do_things => { kind: :method, name: "doThings", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_interface_with_optional_method_arguments.rb 1`] = ` +require 'jsii' + +# awslabs/jsii#175 Interface proxies (and builders) do not respect optional arguments in methods. +module JsiiCalc::IInterfaceWithOptionalMethodArguments + Jsii::Object.register_jsii_fqn("jsii-calc.IInterfaceWithOptionalMethodArguments", self) + + # @param arg1 [String] + # @param arg2 [Numeric, nil] + # @return [void] + def hello(arg1, arg2 = nil) + jsii_call_method("hello", [arg1, arg2]) + end + + def self.jsii_overridable_methods + { + :hello => { kind: :method, name: "hello", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_interface_with_properties.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IInterfaceWithProperties + Jsii::Object.register_jsii_fqn("jsii-calc.IInterfaceWithProperties", self) + + # @return [String] + def read_only_string() + jsii_get_property("readOnlyString") + end + + # @return [String] + def read_write_string() + jsii_get_property("readWriteString") + end + + def read_write_string=(value) + jsii_set_property("readWriteString", value) + end + + def self.jsii_overridable_methods + { + :read_only_string => { kind: :property, name: "readOnlyString", is_optional: false }, + :read_write_string => { kind: :property, name: "readWriteString", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_interface_with_properties_extension.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IInterfaceWithPropertiesExtension + include ::JsiiCalc::IInterfaceWithProperties + Jsii::Object.register_jsii_fqn("jsii-calc.IInterfaceWithPropertiesExtension", self) + + # @return [String] + def read_only_string() + jsii_get_property("readOnlyString") + end + + # @return [String] + def read_write_string() + jsii_get_property("readWriteString") + end + + def read_write_string=(value) + jsii_set_property("readWriteString", value) + end + + # @return [Numeric] + def foo() + jsii_get_property("foo") + end + + def foo=(value) + jsii_set_property("foo", value) + end + + def self.jsii_overridable_methods + { + :read_only_string => { kind: :property, name: "readOnlyString", is_optional: false }, + :read_write_string => { kind: :property, name: "readWriteString", is_optional: false }, + :foo => { kind: :property, name: "foo", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_java_reserved_words_in_an_interface.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IJavaReservedWordsInAnInterface + Jsii::Object.register_jsii_fqn("jsii-calc.IJavaReservedWordsInAnInterface", self) + + # @return [String] + def _while() + jsii_get_property("while") + end + + # @return [void] + def abstract() + jsii_call_method("abstract", []) + end + + # @return [void] + def assert() + jsii_call_method("assert", []) + end + + # @return [void] + def boolean() + jsii_call_method("boolean", []) + end + + # @return [void] + def _break() + jsii_call_method("break", []) + end + + # @return [void] + def byte() + jsii_call_method("byte", []) + end + + # @return [void] + def _case() + jsii_call_method("case", []) + end + + # @return [void] + def catch() + jsii_call_method("catch", []) + end + + # @return [void] + def char() + jsii_call_method("char", []) + end + + # @return [void] + def _class() + jsii_call_method("class", []) + end + + # @return [void] + def const() + jsii_call_method("const", []) + end + + # @return [void] + def continue() + jsii_call_method("continue", []) + end + + # @return [void] + def default() + jsii_call_method("default", []) + end + + # @return [void] + def _do() + jsii_call_method("do", []) + end + + # @return [void] + def double() + jsii_call_method("double", []) + end + + # @return [void] + def _else() + jsii_call_method("else", []) + end + + # @return [void] + def enum() + jsii_call_method("enum", []) + end + + # @return [void] + def extends() + jsii_call_method("extends", []) + end + + # @return [void] + def _false() + jsii_call_method("false", []) + end + + # @return [void] + def final() + jsii_call_method("final", []) + end + + # @return [void] + def finally() + jsii_call_method("finally", []) + end + + # @return [void] + def float() + jsii_call_method("float", []) + end + + # @return [void] + def _for() + jsii_call_method("for", []) + end + + # @return [void] + def goto() + jsii_call_method("goto", []) + end + + # @return [void] + def _if() + jsii_call_method("if", []) + end + + # @return [void] + def implements() + jsii_call_method("implements", []) + end + + # @return [void] + def import() + jsii_call_method("import", []) + end + + # @return [void] + def instanceof() + jsii_call_method("instanceof", []) + end + + # @return [void] + def int() + jsii_call_method("int", []) + end + + # @return [void] + def interface() + jsii_call_method("interface", []) + end + + # @return [void] + def long() + jsii_call_method("long", []) + end + + # @return [void] + def native() + jsii_call_method("native", []) + end + + # @return [void] + def null() + jsii_call_method("null", []) + end + + # @return [void] + def package() + jsii_call_method("package", []) + end + + # @return [void] + def private() + jsii_call_method("private", []) + end + + # @return [void] + def protected() + jsii_call_method("protected", []) + end + + # @return [void] + def public() + jsii_call_method("public", []) + end + + # @return [void] + def _return() + jsii_call_method("return", []) + end + + # @return [void] + def short() + jsii_call_method("short", []) + end + + # @return [void] + def static() + jsii_call_method("static", []) + end + + # @return [void] + def strictfp() + jsii_call_method("strictfp", []) + end + + # @return [void] + def _super() + jsii_call_method("super", []) + end + + # @return [void] + def switch() + jsii_call_method("switch", []) + end + + # @return [void] + def synchronized() + jsii_call_method("synchronized", []) + end + + # @return [void] + def this() + jsii_call_method("this", []) + end + + # @return [void] + def throw() + jsii_call_method("throw", []) + end + + # @return [void] + def throws() + jsii_call_method("throws", []) + end + + # @return [void] + def transient() + jsii_call_method("transient", []) + end + + # @return [void] + def _true() + jsii_call_method("true", []) + end + + # @return [void] + def try() + jsii_call_method("try", []) + end + + # @return [void] + def void() + jsii_call_method("void", []) + end + + # @return [void] + def volatile() + jsii_call_method("volatile", []) + end + + def self.jsii_overridable_methods + { + :_while => { kind: :property, name: "while", is_optional: false }, + :abstract => { kind: :method, name: "abstract", is_optional: false }, + :assert => { kind: :method, name: "assert", is_optional: false }, + :boolean => { kind: :method, name: "boolean", is_optional: false }, + :_break => { kind: :method, name: "break", is_optional: false }, + :byte => { kind: :method, name: "byte", is_optional: false }, + :_case => { kind: :method, name: "case", is_optional: false }, + :catch => { kind: :method, name: "catch", is_optional: false }, + :char => { kind: :method, name: "char", is_optional: false }, + :_class => { kind: :method, name: "class", is_optional: false }, + :const => { kind: :method, name: "const", is_optional: false }, + :continue => { kind: :method, name: "continue", is_optional: false }, + :default => { kind: :method, name: "default", is_optional: false }, + :_do => { kind: :method, name: "do", is_optional: false }, + :double => { kind: :method, name: "double", is_optional: false }, + :_else => { kind: :method, name: "else", is_optional: false }, + :enum => { kind: :method, name: "enum", is_optional: false }, + :extends => { kind: :method, name: "extends", is_optional: false }, + :_false => { kind: :method, name: "false", is_optional: false }, + :final => { kind: :method, name: "final", is_optional: false }, + :finally => { kind: :method, name: "finally", is_optional: false }, + :float => { kind: :method, name: "float", is_optional: false }, + :_for => { kind: :method, name: "for", is_optional: false }, + :goto => { kind: :method, name: "goto", is_optional: false }, + :_if => { kind: :method, name: "if", is_optional: false }, + :implements => { kind: :method, name: "implements", is_optional: false }, + :import => { kind: :method, name: "import", is_optional: false }, + :instanceof => { kind: :method, name: "instanceof", is_optional: false }, + :int => { kind: :method, name: "int", is_optional: false }, + :interface => { kind: :method, name: "interface", is_optional: false }, + :long => { kind: :method, name: "long", is_optional: false }, + :native => { kind: :method, name: "native", is_optional: false }, + :null => { kind: :method, name: "null", is_optional: false }, + :package => { kind: :method, name: "package", is_optional: false }, + :private => { kind: :method, name: "private", is_optional: false }, + :protected => { kind: :method, name: "protected", is_optional: false }, + :public => { kind: :method, name: "public", is_optional: false }, + :_return => { kind: :method, name: "return", is_optional: false }, + :short => { kind: :method, name: "short", is_optional: false }, + :static => { kind: :method, name: "static", is_optional: false }, + :strictfp => { kind: :method, name: "strictfp", is_optional: false }, + :_super => { kind: :method, name: "super", is_optional: false }, + :switch => { kind: :method, name: "switch", is_optional: false }, + :synchronized => { kind: :method, name: "synchronized", is_optional: false }, + :this => { kind: :method, name: "this", is_optional: false }, + :throw => { kind: :method, name: "throw", is_optional: false }, + :throws => { kind: :method, name: "throws", is_optional: false }, + :transient => { kind: :method, name: "transient", is_optional: false }, + :_true => { kind: :method, name: "true", is_optional: false }, + :try => { kind: :method, name: "try", is_optional: false }, + :void => { kind: :method, name: "void", is_optional: false }, + :volatile => { kind: :method, name: "volatile", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_jsii487_external.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IJsii487External + Jsii::Object.register_jsii_fqn("jsii-calc.IJsii487External", self) + + def self.jsii_overridable_methods + { + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_jsii487_external2.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IJsii487External2 + Jsii::Object.register_jsii_fqn("jsii-calc.IJsii487External2", self) + + def self.jsii_overridable_methods + { + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_jsii496.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IJsii496 + Jsii::Object.register_jsii_fqn("jsii-calc.IJsii496", self) + + def self.jsii_overridable_methods + { + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_mutable_object_literal.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IMutableObjectLiteral + Jsii::Object.register_jsii_fqn("jsii-calc.IMutableObjectLiteral", self) + + # @return [String] + def value() + jsii_get_property("value") + end + + def value=(value) + jsii_set_property("value", value) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_non_internal_interface.rb 1`] = ` +require 'jsii' + +module JsiiCalc::INonInternalInterface + include ::JsiiCalc::IAnotherPublicInterface + Jsii::Object.register_jsii_fqn("jsii-calc.INonInternalInterface", self) + + # @return [String] + def a() + jsii_get_property("a") + end + + def a=(value) + jsii_set_property("a", value) + end + + # @return [String] + def b() + jsii_get_property("b") + end + + def b=(value) + jsii_set_property("b", value) + end + + # @return [String] + def c() + jsii_get_property("c") + end + + def c=(value) + jsii_set_property("c", value) + end + + def self.jsii_overridable_methods + { + :a => { kind: :property, name: "a", is_optional: false }, + :b => { kind: :property, name: "b", is_optional: false }, + :c => { kind: :property, name: "c", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_object_with_property.rb 1`] = ` +require 'jsii' + +# Make sure that setters are properly called on objects with interfaces. +module JsiiCalc::IObjectWithProperty + Jsii::Object.register_jsii_fqn("jsii-calc.IObjectWithProperty", self) + + # @return [String] + def property() + jsii_get_property("property") + end + + def property=(value) + jsii_set_property("property", value) + end + + # @return [Boolean] + def was_set() + jsii_call_method("wasSet", []) + end + + def self.jsii_overridable_methods + { + :property => { kind: :property, name: "property", is_optional: false }, + :was_set => { kind: :method, name: "wasSet", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_optional_method.rb 1`] = ` +require 'jsii' + +# Checks that optional result from interface method code generates correctly. +module JsiiCalc::IOptionalMethod + Jsii::Object.register_jsii_fqn("jsii-calc.IOptionalMethod", self) + + # @return [String, nil] + def optional() + jsii_call_method("optional", []) + end + + def self.jsii_overridable_methods + { + :optional => { kind: :method, name: "optional", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_privately_implemented.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IPrivatelyImplemented + Jsii::Object.register_jsii_fqn("jsii-calc.IPrivatelyImplemented", self) + + # @return [Boolean] + def success() + jsii_get_property("success") + end + + def self.jsii_overridable_methods + { + :success => { kind: :property, name: "success", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_public_interface.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IPublicInterface + Jsii::Object.register_jsii_fqn("jsii-calc.IPublicInterface", self) + + # @return [String] + def bye() + jsii_call_method("bye", []) + end + + def self.jsii_overridable_methods + { + :bye => { kind: :method, name: "bye", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_public_interface2.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IPublicInterface2 + Jsii::Object.register_jsii_fqn("jsii-calc.IPublicInterface2", self) + + # @return [String] + def ciao() + jsii_call_method("ciao", []) + end + + def self.jsii_overridable_methods + { + :ciao => { kind: :method, name: "ciao", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_random_number_generator.rb 1`] = ` +require 'jsii' + +# Generates random numbers. +module JsiiCalc::IRandomNumberGenerator + Jsii::Object.register_jsii_fqn("jsii-calc.IRandomNumberGenerator", self) + + # Returns another random number. + # + # @return [Numeric] A random number. + def _next() + jsii_call_method("next", []) + end + + def self.jsii_overridable_methods + { + :_next => { kind: :method, name: "next", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_return_jsii976.rb 1`] = ` +require 'jsii' + +# Returns a subclass of a known class which implements an interface. +module JsiiCalc::IReturnJsii976 + Jsii::Object.register_jsii_fqn("jsii-calc.IReturnJsii976", self) + + # @return [Numeric] + def foo() + jsii_get_property("foo") + end + + def self.jsii_overridable_methods + { + :foo => { kind: :property, name: "foo", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_returns_number.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IReturnsNumber + Jsii::Object.register_jsii_fqn("jsii-calc.IReturnsNumber", self) + + # @return [Scope::JsiiCalcLib::Number] + def number_prop() + jsii_get_property("numberProp") + end + + # @return [Scope::JsiiCalcLib::IDoublable] + def obtain_number() + jsii_call_method("obtainNumber", []) + end + + def self.jsii_overridable_methods + { + :number_prop => { kind: :property, name: "numberProp", is_optional: false }, + :obtain_number => { kind: :method, name: "obtainNumber", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_stable_interface.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IStableInterface + Jsii::Object.register_jsii_fqn("jsii-calc.IStableInterface", self) + + # @return [Numeric, nil] + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) + jsii_set_property("mutableProperty", value) + end + + # @return [void] + def method() + jsii_call_method("method", []) + end + + def self.jsii_overridable_methods + { + :mutable_property => { kind: :property, name: "mutableProperty", is_optional: true }, + :method => { kind: :method, name: "method", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_stringable.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IStringable + Jsii::Object.register_jsii_fqn("jsii-calc.IStringable", self) + + # @return [String] + def describe() + jsii_call_method("describe", []) + end + + # @return [String] + def native_to_string() + jsii_call_method("nativeToString", []) + end + + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + + def self.jsii_overridable_methods + { + :describe => { kind: :method, name: "describe", is_optional: false }, + :native_to_string => { kind: :method, name: "nativeToString", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_struct_returning_delegate.rb 1`] = ` +require 'jsii' + +# Verifies that a "pure" implementation of an interface works correctly. +module JsiiCalc::IStructReturningDelegate + Jsii::Object.register_jsii_fqn("jsii-calc.IStructReturningDelegate", self) + + # @return [JsiiCalc::StructB] + def return_struct() + jsii_call_method("returnStruct", []) + end + + def self.jsii_overridable_methods + { + :return_struct => { kind: :method, name: "returnStruct", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_wall_clock.rb 1`] = ` +require 'jsii' + +# Implement this interface. +module JsiiCalc::IWallClock + Jsii::Object.register_jsii_fqn("jsii-calc.IWallClock", self) + + # Returns the current time, formatted as an ISO-8601 string. + # + # @return [String] + def iso8601_now() + jsii_call_method("iso8601Now", []) + end + + def self.jsii_overridable_methods + { + :iso8601_now => { kind: :method, name: "iso8601Now", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/ijsii417_derived.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IJSII417Derived + include ::JsiiCalc::IJSII417PublicBaseOfBase + Jsii::Object.register_jsii_fqn("jsii-calc.IJSII417Derived", self) + + # @return [Boolean] + def has_root() + jsii_get_property("hasRoot") + end + + # @return [String] + def property() + jsii_get_property("property") + end + + # @return [void] + def foo() + jsii_call_method("foo", []) + end + + # @return [void] + def bar() + jsii_call_method("bar", []) + end + + # @return [void] + def baz() + jsii_call_method("baz", []) + end + + def self.jsii_overridable_methods + { + :has_root => { kind: :property, name: "hasRoot", is_optional: false }, + :property => { kind: :property, name: "property", is_optional: false }, + :foo => { kind: :method, name: "foo", is_optional: false }, + :bar => { kind: :method, name: "bar", is_optional: false }, + :baz => { kind: :method, name: "baz", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/ijsii417_public_base_of_base.rb 1`] = ` +require 'jsii' + +module JsiiCalc::IJSII417PublicBaseOfBase + Jsii::Object.register_jsii_fqn("jsii-calc.IJSII417PublicBaseOfBase", self) + + # @return [Boolean] + def has_root() + jsii_get_property("hasRoot") + end + + # @return [void] + def foo() + jsii_call_method("foo", []) + end + + def self.jsii_overridable_methods + { + :has_root => { kind: :property, name: "hasRoot", is_optional: false }, + :foo => { kind: :method, name: "foo", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/implement_internal_interface.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ImplementInternalInterface < Jsii::Object + self.jsii_fqn = "jsii-calc.ImplementInternalInterface" + Jsii::Object.register_jsii_fqn("jsii-calc.ImplementInternalInterface", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :prop => { kind: :property, name: "prop", is_optional: false }, + } + end + + # @return [String] + def prop() + jsii_get_property("prop") + end + + def prop=(value) + jsii_set_property("prop", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/implementation.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Implementation < Jsii::Object + self.jsii_fqn = "jsii-calc.Implementation" + Jsii::Object.register_jsii_fqn("jsii-calc.Implementation", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + } + end + + # @return [Numeric] + def value() + jsii_get_property("value") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/implements_interface_with_internal.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ImplementsInterfaceWithInternal < Jsii::Object + include ::JsiiCalc::IInterfaceWithInternal + self.jsii_fqn = "jsii-calc.ImplementsInterfaceWithInternal" + Jsii::Object.register_jsii_fqn("jsii-calc.ImplementsInterfaceWithInternal", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :visible => { kind: :method, name: "visible", is_optional: false }, + } + end + + # @return [void] + def visible() + jsii_call_method("visible", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/implements_interface_with_internal_subclass.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ImplementsInterfaceWithInternalSubclass < ::JsiiCalc::ImplementsInterfaceWithInternal + self.jsii_fqn = "jsii-calc.ImplementsInterfaceWithInternalSubclass" + Jsii::Object.register_jsii_fqn("jsii-calc.ImplementsInterfaceWithInternalSubclass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :visible => { kind: :method, name: "visible", is_optional: false }, + } + end + + # @return [void] + def visible() + jsii_call_method("visible", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/implements_private_interface.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ImplementsPrivateInterface < Jsii::Object + self.jsii_fqn = "jsii-calc.ImplementsPrivateInterface" + Jsii::Object.register_jsii_fqn("jsii-calc.ImplementsPrivateInterface", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :private => { kind: :property, name: "private", is_optional: false }, + } + end + + # @return [String] + def private() + jsii_get_property("private") + end + + def private=(value) + jsii_set_property("private", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/implict_base_of_base.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ImplictBaseOfBase < ::Scope::JsiiCalcBase::BaseProps + Jsii::Object.register_jsii_fqn("jsii-calc.ImplictBaseOfBase", self) + + # @param foo [Scope::JsiiCalcBaseOfBase::Very] + # @param bar [String] + # @param goo [DateTime] + def initialize(foo:, bar:, goo:) + @foo = foo + @bar = bar + @goo = goo + end + + # @return [Scope::JsiiCalcBaseOfBase::Very] + # @note Default: + # @deprecated + attr_reader :foo + # @return [String] + # @note Default: + # @deprecated + attr_reader :bar + # @return [DateTime] + attr_reader :goo + + def self.jsii_properties + { + :foo => "foo", + :bar => "bar", + :goo => "goo", + } + end + + def to_jsii + result = {} + result.merge!(super) + result.merge!({ + "foo" => @foo, + "bar" => @bar, + "goo" => @goo, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/inbetween_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::InbetweenClass < ::JsiiCalc::PublicClass + include ::JsiiCalc::IPublicInterface2 + self.jsii_fqn = "jsii-calc.InbetweenClass" + Jsii::Object.register_jsii_fqn("jsii-calc.InbetweenClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :hello => { kind: :method, name: "hello", is_optional: false }, + :ciao => { kind: :method, name: "ciao", is_optional: false }, + } + end + + # @return [void] + def hello() + jsii_call_method("hello", []) + end + + # @return [String] + def ciao() + jsii_call_method("ciao", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/interface_collections.rb 1`] = ` +require 'jsii' + +# Verifies that collections of interfaces or structs are correctly handled. +# +# See: https://github.com/aws/jsii/issues/1196 +class JsiiCalc::InterfaceCollections < Jsii::Object + self.jsii_fqn = "jsii-calc.InterfaceCollections" + Jsii::Object.register_jsii_fqn("jsii-calc.InterfaceCollections", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.InterfaceCollections does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @return [Array] + def self.list_of_interfaces() + Jsii::Kernel.instance.call_static("jsii-calc.InterfaceCollections", "listOfInterfaces", []) + end + + # @return [Array] + def self.list_of_structs() + Jsii::Kernel.instance.call_static("jsii-calc.InterfaceCollections", "listOfStructs", []) + end + + # @return [Hash{String => JsiiCalc::IBell}] + def self.map_of_interfaces() + Jsii::Kernel.instance.call_static("jsii-calc.InterfaceCollections", "mapOfInterfaces", []) + end + + # @return [Hash{String => JsiiCalc::StructA}] + def self.map_of_structs() + Jsii::Kernel.instance.call_static("jsii-calc.InterfaceCollections", "mapOfStructs", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/interface_in_namespace_includes_classes/foo.rb 1`] = ` +require 'jsii' + +class JsiiCalc::InterfaceInNamespaceIncludesClasses::Foo < Jsii::Object + self.jsii_fqn = "jsii-calc.InterfaceInNamespaceIncludesClasses.Foo" + Jsii::Object.register_jsii_fqn("jsii-calc.InterfaceInNamespaceIncludesClasses.Foo", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :bar => { kind: :property, name: "bar", is_optional: true }, + } + end + + # @return [String, nil] + def bar() + jsii_get_property("bar") + end + + def bar=(value) + jsii_set_property("bar", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/interface_in_namespace_includes_classes/hello.rb 1`] = ` +require 'jsii' + +class JsiiCalc::InterfaceInNamespaceIncludesClasses::Hello < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.InterfaceInNamespaceIncludesClasses.Hello", self) + + # @param foo [Numeric] + def initialize(foo:) + @foo = foo + end + + # @return [Numeric] + attr_reader :foo + + def self.jsii_properties + { + :foo => "foo", + } + end + + def to_jsii + result = {} + result.merge!({ + "foo" => @foo, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/interface_in_namespace_only_interface/hello.rb 1`] = ` +require 'jsii' + +class JsiiCalc::InterfaceInNamespaceOnlyInterface::Hello < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.InterfaceInNamespaceOnlyInterface.Hello", self) + + # @param foo [Numeric] + def initialize(foo:) + @foo = foo + end + + # @return [Numeric] + attr_reader :foo + + def self.jsii_properties + { + :foo => "foo", + } + end + + def to_jsii + result = {} + result.merge!({ + "foo" => @foo, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/interfaces_maker.rb 1`] = ` +require 'jsii' + +# We can return arrays of interfaces See aws/aws-cdk#2362. +class JsiiCalc::InterfacesMaker < Jsii::Object + self.jsii_fqn = "jsii-calc.InterfacesMaker" + Jsii::Object.register_jsii_fqn("jsii-calc.InterfacesMaker", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.InterfacesMaker does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @param count [Numeric] + # @return [Array] + def self.make_interfaces(count) + Jsii::Kernel.instance.call_static("jsii-calc.InterfacesMaker", "makeInterfaces", [count]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/intersection/consumes_intersection.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Intersection::ConsumesIntersection < Jsii::Object + self.jsii_fqn = "jsii-calc.intersection.ConsumesIntersection" + Jsii::Object.register_jsii_fqn("jsii-calc.intersection.ConsumesIntersection", self) + + # @param props [JsiiCalc::Intersection::IntersectionProps] + def initialize(props) + props = props.is_a?(Hash) ? ::JsiiCalc::Intersection::IntersectionProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { + } + end + + # @param param [Object] + # @return [void] + def self.accepts_intersection(param) + Jsii::Kernel.instance.call_static("jsii-calc.intersection.ConsumesIntersection", "acceptsIntersection", [param]) + end + + # @param props [JsiiCalc::Intersection::IntersectionProps] + # @return [void] + def self.accepts_prop_with_intersection(props) + props = props.is_a?(Hash) ? ::JsiiCalc::Intersection::IntersectionProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Kernel.instance.call_static("jsii-calc.intersection.ConsumesIntersection", "acceptsPropWithIntersection", [props]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/intersection/i_something.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Intersection::ISomething + Jsii::Object.register_jsii_fqn("jsii-calc.intersection.ISomething", self) + + # @return [Object] + def something() + jsii_call_method("something", []) + end + + def self.jsii_overridable_methods + { + :something => { kind: :method, name: "something", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/intersection/intersection_props.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Intersection::IntersectionProps < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.intersection.IntersectionProps", self) + + # @param param [Object] + def initialize(param:) + @param = param + end + + # @return [Object] + attr_reader :param + + def self.jsii_properties + { + :param => "param", + } + end + + def to_jsii + result = {} + result.merge!({ + "param" => @param, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/isomorphism.rb 1`] = ` +require 'jsii' + +# Checks the "same instance" isomorphism is preserved within the constructor. +# +# Create a subclass of this, and assert that \`this.myself()\` actually returns +# \`this\` from within the constructor. +class JsiiCalc::Isomorphism < Jsii::Object + self.jsii_fqn = "jsii-calc.Isomorphism" + Jsii::Object.register_jsii_fqn("jsii-calc.Isomorphism", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :myself => { kind: :method, name: "myself", is_optional: false }, + } + end + + # @return [JsiiCalc::Isomorphism] + def myself() + jsii_call_method("myself", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/issue2638.rb 1`] = ` +require 'jsii' + +# Docstrings with period. +# +# @see https://github.com/aws/jsii/issues/2638 +class JsiiCalc::Issue2638 < Jsii::Object + self.jsii_fqn = "jsii-calc.Issue2638" + Jsii::Object.register_jsii_fqn("jsii-calc.Issue2638", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/issue2638_b.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Issue2638B < Jsii::Object + self.jsii_fqn = "jsii-calc.Issue2638B" + Jsii::Object.register_jsii_fqn("jsii-calc.Issue2638B", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/java_reserved_words.rb 1`] = ` +require 'jsii' + +class JsiiCalc::JavaReservedWords < Jsii::Object + self.jsii_fqn = "jsii-calc.JavaReservedWords" + Jsii::Object.register_jsii_fqn("jsii-calc.JavaReservedWords", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :_while => { kind: :property, name: "while", is_optional: false }, + :abstract => { kind: :method, name: "abstract", is_optional: false }, + :assert => { kind: :method, name: "assert", is_optional: false }, + :boolean => { kind: :method, name: "boolean", is_optional: false }, + :_break => { kind: :method, name: "break", is_optional: false }, + :byte => { kind: :method, name: "byte", is_optional: false }, + :_case => { kind: :method, name: "case", is_optional: false }, + :catch => { kind: :method, name: "catch", is_optional: false }, + :char => { kind: :method, name: "char", is_optional: false }, + :_class => { kind: :method, name: "class", is_optional: false }, + :const => { kind: :method, name: "const", is_optional: false }, + :continue => { kind: :method, name: "continue", is_optional: false }, + :default => { kind: :method, name: "default", is_optional: false }, + :_do => { kind: :method, name: "do", is_optional: false }, + :double => { kind: :method, name: "double", is_optional: false }, + :_else => { kind: :method, name: "else", is_optional: false }, + :enum => { kind: :method, name: "enum", is_optional: false }, + :extends => { kind: :method, name: "extends", is_optional: false }, + :_false => { kind: :method, name: "false", is_optional: false }, + :final => { kind: :method, name: "final", is_optional: false }, + :finally => { kind: :method, name: "finally", is_optional: false }, + :float => { kind: :method, name: "float", is_optional: false }, + :_for => { kind: :method, name: "for", is_optional: false }, + :goto => { kind: :method, name: "goto", is_optional: false }, + :_if => { kind: :method, name: "if", is_optional: false }, + :implements => { kind: :method, name: "implements", is_optional: false }, + :import => { kind: :method, name: "import", is_optional: false }, + :instanceof => { kind: :method, name: "instanceof", is_optional: false }, + :int => { kind: :method, name: "int", is_optional: false }, + :interface => { kind: :method, name: "interface", is_optional: false }, + :long => { kind: :method, name: "long", is_optional: false }, + :native => { kind: :method, name: "native", is_optional: false }, + :_new => { kind: :method, name: "new", is_optional: false }, + :null => { kind: :method, name: "null", is_optional: false }, + :package => { kind: :method, name: "package", is_optional: false }, + :private => { kind: :method, name: "private", is_optional: false }, + :protected => { kind: :method, name: "protected", is_optional: false }, + :public => { kind: :method, name: "public", is_optional: false }, + :_return => { kind: :method, name: "return", is_optional: false }, + :short => { kind: :method, name: "short", is_optional: false }, + :static => { kind: :method, name: "static", is_optional: false }, + :strictfp => { kind: :method, name: "strictfp", is_optional: false }, + :_super => { kind: :method, name: "super", is_optional: false }, + :switch => { kind: :method, name: "switch", is_optional: false }, + :synchronized => { kind: :method, name: "synchronized", is_optional: false }, + :this => { kind: :method, name: "this", is_optional: false }, + :throw => { kind: :method, name: "throw", is_optional: false }, + :throws => { kind: :method, name: "throws", is_optional: false }, + :transient => { kind: :method, name: "transient", is_optional: false }, + :_true => { kind: :method, name: "true", is_optional: false }, + :try => { kind: :method, name: "try", is_optional: false }, + :void => { kind: :method, name: "void", is_optional: false }, + :volatile => { kind: :method, name: "volatile", is_optional: false }, + } + end + + # @return [String] + def _while() + jsii_get_property("while") + end + + def _while=(value) + jsii_set_property("while", value) + end + + # @return [void] + def abstract() + jsii_call_method("abstract", []) + end + + # @return [void] + def assert() + jsii_call_method("assert", []) + end + + # @return [void] + def boolean() + jsii_call_method("boolean", []) + end + + # @return [void] + def _break() + jsii_call_method("break", []) + end + + # @return [void] + def byte() + jsii_call_method("byte", []) + end + + # @return [void] + def _case() + jsii_call_method("case", []) + end + + # @return [void] + def catch() + jsii_call_method("catch", []) + end + + # @return [void] + def char() + jsii_call_method("char", []) + end + + # @return [void] + def _class() + jsii_call_method("class", []) + end + + # @return [void] + def const() + jsii_call_method("const", []) + end + + # @return [void] + def continue() + jsii_call_method("continue", []) + end + + # @return [void] + def default() + jsii_call_method("default", []) + end + + # @return [void] + def _do() + jsii_call_method("do", []) + end + + # @return [void] + def double() + jsii_call_method("double", []) + end + + # @return [void] + def _else() + jsii_call_method("else", []) + end + + # @return [void] + def enum() + jsii_call_method("enum", []) + end + + # @return [void] + def extends() + jsii_call_method("extends", []) + end + + # @return [void] + def _false() + jsii_call_method("false", []) + end + + # @return [void] + def final() + jsii_call_method("final", []) + end + + # @return [void] + def finally() + jsii_call_method("finally", []) + end + + # @return [void] + def float() + jsii_call_method("float", []) + end + + # @return [void] + def _for() + jsii_call_method("for", []) + end + + # @return [void] + def goto() + jsii_call_method("goto", []) + end + + # @return [void] + def _if() + jsii_call_method("if", []) + end + + # @return [void] + def implements() + jsii_call_method("implements", []) + end + + # @return [void] + def import() + jsii_call_method("import", []) + end + + # @return [void] + def instanceof() + jsii_call_method("instanceof", []) + end + + # @return [void] + def int() + jsii_call_method("int", []) + end + + # @return [void] + def interface() + jsii_call_method("interface", []) + end + + # @return [void] + def long() + jsii_call_method("long", []) + end + + # @return [void] + def native() + jsii_call_method("native", []) + end + + # @return [void] + def _new() + jsii_call_method("new", []) + end + + # @return [void] + def null() + jsii_call_method("null", []) + end + + # @return [void] + def package() + jsii_call_method("package", []) + end + + # @return [void] + def private() + jsii_call_method("private", []) + end + + # @return [void] + def protected() + jsii_call_method("protected", []) + end + + # @return [void] + def public() + jsii_call_method("public", []) + end + + # @return [void] + def _return() + jsii_call_method("return", []) + end + + # @return [void] + def short() + jsii_call_method("short", []) + end + + # @return [void] + def static() + jsii_call_method("static", []) + end + + # @return [void] + def strictfp() + jsii_call_method("strictfp", []) + end + + # @return [void] + def _super() + jsii_call_method("super", []) + end + + # @return [void] + def switch() + jsii_call_method("switch", []) + end + + # @return [void] + def synchronized() + jsii_call_method("synchronized", []) + end + + # @return [void] + def this() + jsii_call_method("this", []) + end + + # @return [void] + def throw() + jsii_call_method("throw", []) + end + + # @return [void] + def throws() + jsii_call_method("throws", []) + end + + # @return [void] + def transient() + jsii_call_method("transient", []) + end + + # @return [void] + def _true() + jsii_call_method("true", []) + end + + # @return [void] + def try() + jsii_call_method("try", []) + end + + # @return [void] + def void() + jsii_call_method("void", []) + end + + # @return [void] + def volatile() + jsii_call_method("volatile", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/js_object_literal_for_interface.rb 1`] = ` +require 'jsii' + +class JsiiCalc::JSObjectLiteralForInterface < Jsii::Object + self.jsii_fqn = "jsii-calc.JSObjectLiteralForInterface" + Jsii::Object.register_jsii_fqn("jsii-calc.JSObjectLiteralForInterface", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :give_me_friendly => { kind: :method, name: "giveMeFriendly", is_optional: false }, + :give_me_friendly_generator => { kind: :method, name: "giveMeFriendlyGenerator", is_optional: false }, + } + end + + # @return [Scope::JsiiCalcLib::IFriendly] + def give_me_friendly() + jsii_call_method("giveMeFriendly", []) + end + + # @return [JsiiCalc::IFriendlyRandomGenerator] + def give_me_friendly_generator() + jsii_call_method("giveMeFriendlyGenerator", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/js_object_literal_to_native.rb 1`] = ` +require 'jsii' + +class JsiiCalc::JSObjectLiteralToNative < Jsii::Object + self.jsii_fqn = "jsii-calc.JSObjectLiteralToNative" + Jsii::Object.register_jsii_fqn("jsii-calc.JSObjectLiteralToNative", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :return_literal => { kind: :method, name: "returnLiteral", is_optional: false }, + } + end + + # @return [JsiiCalc::JSObjectLiteralToNativeClass] + def return_literal() + jsii_call_method("returnLiteral", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/js_object_literal_to_native_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::JSObjectLiteralToNativeClass < Jsii::Object + self.jsii_fqn = "jsii-calc.JSObjectLiteralToNativeClass" + Jsii::Object.register_jsii_fqn("jsii-calc.JSObjectLiteralToNativeClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :prop_a => { kind: :property, name: "propA", is_optional: false }, + :prop_b => { kind: :property, name: "propB", is_optional: false }, + } + end + + # @return [String] + def prop_a() + jsii_get_property("propA") + end + + def prop_a=(value) + jsii_set_property("propA", value) + end + + # @return [Numeric] + def prop_b() + jsii_get_property("propB") + end + + def prop_b=(value) + jsii_set_property("propB", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii_agent.rb 1`] = ` +require 'jsii' + +# Host runtime version should be set via JSII_AGENT. +class JsiiCalc::JsiiAgent < Jsii::Object + self.jsii_fqn = "jsii-calc.JsiiAgent" + Jsii::Object.register_jsii_fqn("jsii-calc.JsiiAgent", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + + # Returns the value of the JSII_AGENT environment variable. + # + # @return [String, nil] + def self.value() + Jsii::Kernel.instance.get_static("jsii-calc.JsiiAgent", "value") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii417_derived.rb 1`] = ` +require 'jsii' + +class JsiiCalc::JSII417Derived < ::JsiiCalc::JSII417PublicBaseOfBase + self.jsii_fqn = "jsii-calc.JSII417Derived" + Jsii::Object.register_jsii_fqn("jsii-calc.JSII417Derived", self) + + # @param property [String] + def initialize(property) + Jsii::Object.instance_method(:initialize).bind(self).call(property) + end + + def self.jsii_overridable_methods + { + :has_root => { kind: :property, name: "hasRoot", is_optional: false }, + :property => { kind: :property, name: "property", is_optional: false }, + :foo => { kind: :method, name: "foo", is_optional: false }, + :bar => { kind: :method, name: "bar", is_optional: false }, + :baz => { kind: :method, name: "baz", is_optional: false }, + } + end + + # @return [Boolean] + def has_root() + jsii_get_property("hasRoot") + end + + # @return [String] + def property() + jsii_get_property("property") + end + + # @return [void] + def foo() + jsii_call_method("foo", []) + end + + # @return [void] + def bar() + jsii_call_method("bar", []) + end + + # @return [void] + def baz() + jsii_call_method("baz", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii417_public_base_of_base.rb 1`] = ` +require 'jsii' + +class JsiiCalc::JSII417PublicBaseOfBase < Jsii::Object + self.jsii_fqn = "jsii-calc.JSII417PublicBaseOfBase" + Jsii::Object.register_jsii_fqn("jsii-calc.JSII417PublicBaseOfBase", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :has_root => { kind: :property, name: "hasRoot", is_optional: false }, + :foo => { kind: :method, name: "foo", is_optional: false }, + } + end + + # @return [JsiiCalc::JSII417PublicBaseOfBase] + def self.make_instance() + Jsii::Kernel.instance.call_static("jsii-calc.JSII417PublicBaseOfBase", "makeInstance", []) + end + + # @return [Boolean] + def has_root() + jsii_get_property("hasRoot") + end + + # @return [void] + def foo() + jsii_call_method("foo", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii487_derived.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Jsii487Derived < Jsii::Object + include ::JsiiCalc::IJsii487External2 + include ::JsiiCalc::IJsii487External + self.jsii_fqn = "jsii-calc.Jsii487Derived" + Jsii::Object.register_jsii_fqn("jsii-calc.Jsii487Derived", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii496_derived.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Jsii496Derived < Jsii::Object + include ::JsiiCalc::IJsii496 + self.jsii_fqn = "jsii-calc.Jsii496Derived" + Jsii::Object.register_jsii_fqn("jsii-calc.Jsii496Derived", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii3656/implement_me_opts.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Jsii3656::ImplementMeOpts < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.jsii3656.ImplementMeOpts", self) + + # @param name [String] + # @param count [Numeric, nil] + def initialize(name:, count: nil) + @name = name + @count = count + end + + # @return [String] + attr_reader :name + # @return [Numeric, nil] + attr_reader :count + + def self.jsii_properties + { + :name => "name", + :count => "count", + } + end + + def to_jsii + result = {} + result.merge!({ + "name" => @name, + "count" => @count, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii3656/override_me.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Jsii3656::OverrideMe < Jsii::Object + self.jsii_fqn = "jsii-calc.jsii3656.OverrideMe" + Jsii::Object.register_jsii_fqn("jsii-calc.jsii3656.OverrideMe", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :implement_me => { kind: :method, name: "implementMe", is_optional: false }, + } + end + + # @param receiver [JsiiCalc::Jsii3656::OverrideMe] + # @return [Boolean] + def self.call_abstract(receiver) + Jsii::Kernel.instance.call_static("jsii-calc.jsii3656.OverrideMe", "callAbstract", [receiver]) + end + + # @param opts [JsiiCalc::Jsii3656::ImplementMeOpts] + # @return [Boolean] + def implement_me(opts) + opts = opts.is_a?(Hash) ? ::JsiiCalc::Jsii3656::ImplementMeOpts.new(**opts.transform_keys(&:to_sym)) : opts + jsii_call_method("implementMe", [opts]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii4894/non_pascal_case_test.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Jsii4894::NonPascalCaseTest < Jsii::Object + self.jsii_fqn = "jsii-calc.jsii4894.NonPascalCaseTest" + Jsii::Object.register_jsii_fqn("jsii-calc.jsii4894.NonPascalCaseTest", self) + + # @param props [JsiiCalc::Jsii4894::NonPascalCaseTestProps] + def initialize(props) + props = props.is_a?(Hash) ? ::JsiiCalc::Jsii4894::NonPascalCaseTestProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { + :props => { kind: :property, name: "props", is_optional: false }, + :some_type => { kind: :property, name: "someType", is_optional: false }, + } + end + + # @return [JsiiCalc::Jsii4894::NonPascalCaseTestProps] + def props() + jsii_get_property("props") + end + + # @return [Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName::SomeType] + def some_type() + jsii_get_property("someType") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii4894/non_pascal_case_test_props.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Jsii4894::NonPascalCaseTestProps < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.jsii4894.NonPascalCaseTestProps", self) + + # @param some_type [Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName::SomeType] + def initialize(some_type:) + @some_type = some_type.is_a?(Hash) ? ::Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName::SomeType.new(**some_type.transform_keys(&:to_sym)) : some_type + end + + # @return [Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName::SomeType] + attr_reader :some_type + + def self.jsii_properties + { + :some_type => "someType", + } + end + + def to_jsii + result = {} + result.merge!({ + "someType" => @some_type, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/json_formatter.rb 1`] = ` +require 'jsii' + +# Make sure structs are un-decorated on the way in. +# +# @see https://github.com/aws/aws-cdk/issues/5066 +class JsiiCalc::JsonFormatter < Jsii::Object + self.jsii_fqn = "jsii-calc.JsonFormatter" + Jsii::Object.register_jsii_fqn("jsii-calc.JsonFormatter", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.JsonFormatter does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @return [Object] + def self.any_array() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyArray", []) + end + + # @return [Object] + def self.any_boolean_false() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyBooleanFalse", []) + end + + # @return [Object] + def self.any_boolean_true() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyBooleanTrue", []) + end + + # @return [Object] + def self.any_date() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyDate", []) + end + + # @return [Object] + def self.any_empty_string() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyEmptyString", []) + end + + # @return [Object] + def self.any_function() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyFunction", []) + end + + # @return [Object] + def self.any_hash() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyHash", []) + end + + # @return [Object] + def self.any_null() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyNull", []) + end + + # @return [Object] + def self.any_number() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyNumber", []) + end + + # @return [Object] + def self.any_ref() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyRef", []) + end + + # @return [Object] + def self.any_string() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyString", []) + end + + # @return [Object] + def self.any_undefined() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyUndefined", []) + end + + # @return [Object] + def self.any_zero() + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "anyZero", []) + end + + # @param value [Object, nil] + # @return [String, nil] + def self.stringify(value = nil) + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "stringify", [value]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/level_one.rb 1`] = ` +require 'jsii' + +# Validates that nested classes get correct code generation for the occasional forward reference. +class JsiiCalc::LevelOne < Jsii::Object + self.jsii_fqn = "jsii-calc.LevelOne" + Jsii::Object.register_jsii_fqn("jsii-calc.LevelOne", self) + + # @param props [JsiiCalc::LevelOneProps] + def initialize(props) + props = props.is_a?(Hash) ? ::JsiiCalc::LevelOneProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { + :props => { kind: :property, name: "props", is_optional: false }, + } + end + + # @return [JsiiCalc::LevelOneProps] + def props() + jsii_get_property("props") + end + +end + +class JsiiCalc::LevelOne::PropBooleanValue < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.LevelOne.PropBooleanValue", self) + + # @param value [Boolean] + def initialize(value:) + @value = value + end + + # @return [Boolean] + attr_reader :value + + def self.jsii_properties + { + :value => "value", + } + end + + def to_jsii + result = {} + result.merge!({ + "value" => @value, + }) + result.compact + end +end + +class JsiiCalc::LevelOne::PropProperty < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.LevelOne.PropProperty", self) + + # @param prop [JsiiCalc::LevelOne::PropBooleanValue] + def initialize(prop:) + @prop = prop.is_a?(Hash) ? ::JsiiCalc::LevelOne::PropBooleanValue.new(**prop.transform_keys(&:to_sym)) : prop + end + + # @return [JsiiCalc::LevelOne::PropBooleanValue] + attr_reader :prop + + def self.jsii_properties + { + :prop => "prop", + } + end + + def to_jsii + result = {} + result.merge!({ + "prop" => @prop, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/level_one_props.rb 1`] = ` +require 'jsii' + +class JsiiCalc::LevelOneProps < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.LevelOneProps", self) + + # @param prop [JsiiCalc::LevelOne::PropProperty] + def initialize(prop:) + @prop = prop.is_a?(Hash) ? ::JsiiCalc::LevelOne::PropProperty.new(**prop.transform_keys(&:to_sym)) : prop + end + + # @return [JsiiCalc::LevelOne::PropProperty] + attr_reader :prop + + def self.jsii_properties + { + :prop => "prop", + } + end + + def to_jsii + result = {} + result.merge!({ + "prop" => @prop, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/load_balanced_fargate_service_props.rb 1`] = ` +require 'jsii' + +# jsii#298: show default values in sphinx documentation, and respect newlines. +class JsiiCalc::LoadBalancedFargateServiceProps < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.LoadBalancedFargateServiceProps", self) + + # @param container_port [Numeric, nil] The container port of the application load balancer attached to your Fargate service. + # @param cpu [String, nil] The number of cpu units used by the task. + # @param memory_mib [String, nil] The amount (in MiB) of memory used by the task. + # @param public_load_balancer [Boolean, nil] Determines whether the Application Load Balancer will be internet-facing. + # @param public_tasks [Boolean, nil] Determines whether your Fargate Service will be assigned a public IP address. + def initialize(container_port: nil, cpu: nil, memory_mib: nil, public_load_balancer: nil, public_tasks: nil) + @container_port = container_port + @cpu = cpu + @memory_mib = memory_mib + @public_load_balancer = public_load_balancer + @public_tasks = public_tasks + end + + # The container port of the application load balancer attached to your Fargate service. + # + # Corresponds to container port mapping. + # + # @return [Numeric, nil] + # @note Default: 80 + attr_reader :container_port + # The number of cpu units used by the task. + # + # Valid values, which determines your range of valid values for the memory parameter: + # 256 (.25 vCPU) - Available memory values: 0.5GB, 1GB, 2GB + # 512 (.5 vCPU) - Available memory values: 1GB, 2GB, 3GB, 4GB + # 1024 (1 vCPU) - Available memory values: 2GB, 3GB, 4GB, 5GB, 6GB, 7GB, 8GB + # 2048 (2 vCPU) - Available memory values: Between 4GB and 16GB in 1GB increments + # 4096 (4 vCPU) - Available memory values: Between 8GB and 30GB in 1GB increments + # + # This default is set in the underlying FargateTaskDefinition construct. + # + # @return [String, nil] + # @note Default: 256 + attr_reader :cpu + # The amount (in MiB) of memory used by the task. + # + # This field is required and you must use one of the following values, which determines your range of valid values + # for the cpu parameter: + # + # 0.5GB, 1GB, 2GB - Available cpu values: 256 (.25 vCPU) + # + # 1GB, 2GB, 3GB, 4GB - Available cpu values: 512 (.5 vCPU) + # + # 2GB, 3GB, 4GB, 5GB, 6GB, 7GB, 8GB - Available cpu values: 1024 (1 vCPU) + # + # Between 4GB and 16GB in 1GB increments - Available cpu values: 2048 (2 vCPU) + # + # Between 8GB and 30GB in 1GB increments - Available cpu values: 4096 (4 vCPU) + # + # This default is set in the underlying FargateTaskDefinition construct. + # + # @return [String, nil] + # @note Default: 512 + attr_reader :memory_mib + # Determines whether the Application Load Balancer will be internet-facing. + # + # @return [Boolean, nil] + # @note Default: true + attr_reader :public_load_balancer + # Determines whether your Fargate Service will be assigned a public IP address. + # + # @return [Boolean, nil] + # @note Default: false + attr_reader :public_tasks + + def self.jsii_properties + { + :container_port => "containerPort", + :cpu => "cpu", + :memory_mib => "memoryMiB", + :public_load_balancer => "publicLoadBalancer", + :public_tasks => "publicTasks", + } + end + + def to_jsii + result = {} + result.merge!({ + "containerPort" => @container_port, + "cpu" => @cpu, + "memoryMiB" => @memory_mib, + "publicLoadBalancer" => @public_load_balancer, + "publicTasks" => @public_tasks, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/method_named_property.rb 1`] = ` +require 'jsii' + +class JsiiCalc::MethodNamedProperty < Jsii::Object + self.jsii_fqn = "jsii-calc.MethodNamedProperty" + Jsii::Object.register_jsii_fqn("jsii-calc.MethodNamedProperty", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :elite => { kind: :property, name: "elite", is_optional: false }, + :property => { kind: :method, name: "property", is_optional: false }, + } + end + + # @return [Numeric] + def elite() + jsii_get_property("elite") + end + + # @return [String] + def property() + jsii_call_method("property", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2530/my_class.rb 1`] = ` +require 'jsii' + +# Verifies a method with parameters "_" can be generated. +# +# @see https://github.com/aws/jsii/issues/2530 +class JsiiCalc::Module2530::MyClass < Jsii::Object + self.jsii_fqn = "jsii-calc.module2530.MyClass" + Jsii::Object.register_jsii_fqn("jsii-calc.module2530.MyClass", self) + + # @param _ [Numeric] + def initialize(_) + Jsii::Object.instance_method(:initialize).bind(self).call(_) + end + + def self.jsii_overridable_methods + { + :foo => { kind: :method, name: "foo", is_optional: false }, + :multiple_underscores => { kind: :method, name: "multipleUnderscores", is_optional: false }, + } + end + + # @param _ [Boolean] + # @return [void] + def self.bar(_) + Jsii::Kernel.instance.call_static("jsii-calc.module2530.MyClass", "bar", [_]) + end + + # @param _ [String] + # @return [void] + def foo(_) + jsii_call_method("foo", [_]) + end + + # @param _ [String] + # @param __ [String] + # @param ___ [String] + # @return [void] + def multiple_underscores(_, __, ___) + jsii_call_method("multipleUnderscores", [_, __, ___]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2617/only_statics.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2617::OnlyStatics < Jsii::Object + self.jsii_fqn = "jsii-calc.module2617.OnlyStatics" + Jsii::Object.register_jsii_fqn("jsii-calc.module2617.OnlyStatics", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.module2617.OnlyStatics does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @return [void] + def self.bar() + Jsii::Kernel.instance.call_static("jsii-calc.module2617.OnlyStatics", "bar", []) + end + + # @return [void] + def self.foo() + Jsii::Kernel.instance.call_static("jsii-calc.module2617.OnlyStatics", "foo", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2647/extend_and_implement.rb 1`] = ` +require 'jsii' + +# This class falls into the category of "multiple bases" from a different module from a go code gen perspective. +# +# @see https://github.com/aws/jsii/issues/2647 +class JsiiCalc::Module2647::ExtendAndImplement < ::Scope::JsiiCalcLib::BaseFor2647 + include ::Scope::JsiiCalcLib::IFriendly + self.jsii_fqn = "jsii-calc.module2647.ExtendAndImplement" + Jsii::Object.register_jsii_fqn("jsii-calc.module2647.ExtendAndImplement", self) + + # @param very [Scope::JsiiCalcBaseOfBase::Very] + def initialize(very) + Jsii::Object.instance_method(:initialize).bind(self).call(very) + end + + def self.jsii_overridable_methods + { + :foo => { kind: :method, name: "foo", is_optional: false }, + :hello => { kind: :method, name: "hello", is_optional: false }, + :local_method => { kind: :method, name: "localMethod", is_optional: false }, + } + end + + # @param obj [Scope::JsiiCalcBase::IBaseInterface] + # @return [void] + def foo(obj) + jsii_call_method("foo", [obj]) + end + + # Say hello! + # + # @return [String] + def hello() + jsii_call_method("hello", []) + end + + # @return [String] + def local_method() + jsii_call_method("localMethod", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2689/methods/my_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2689::Methods::MyClass < Jsii::Object + self.jsii_fqn = "jsii-calc.module2689.methods.MyClass" + Jsii::Object.register_jsii_fqn("jsii-calc.module2689.methods.MyClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :bar => { kind: :method, name: "bar", is_optional: false }, + :foo => { kind: :method, name: "foo", is_optional: false }, + } + end + + # @param _bar [Hash{String => Scope::JsiiCalcBase::BaseProps}] + # @return [void] + def bar(_bar) + _bar = _bar.is_a?(Hash) ? _bar.transform_values { |jsii_v0| jsii_v0.is_a?(Hash) ? ::Scope::JsiiCalcBase::BaseProps.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : _bar + jsii_call_method("bar", [_bar]) + end + + # @param _values [Array] + # @return [void] + def foo(_values) + jsii_call_method("foo", [_values]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2689/props/my_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2689::Props::MyClass < Jsii::Object + self.jsii_fqn = "jsii-calc.module2689.props.MyClass" + Jsii::Object.register_jsii_fqn("jsii-calc.module2689.props.MyClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :bar => { kind: :property, name: "bar", is_optional: false }, + :foo => { kind: :property, name: "foo", is_optional: false }, + } + end + + # @return [Hash{String => Scope::JsiiCalcBase::BaseProps}] + def bar() + jsii_get_property("bar") + end + + # @return [Array] + def foo() + jsii_get_property("foo") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2689/retval/my_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2689::Retval::MyClass < Jsii::Object + self.jsii_fqn = "jsii-calc.module2689.retval.MyClass" + Jsii::Object.register_jsii_fqn("jsii-calc.module2689.retval.MyClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :bar => { kind: :method, name: "bar", is_optional: false }, + :foo => { kind: :method, name: "foo", is_optional: false }, + } + end + + # @return [Hash{String => Scope::JsiiCalcBase::BaseProps}] + def bar() + jsii_call_method("bar", []) + end + + # @return [Array] + def foo() + jsii_call_method("foo", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2689/structs/my_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2689::Structs::MyStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.module2689.structs.MyStruct", self) + + # @param base_map [Hash{String => Scope::JsiiCalcBase::BaseProps}] + # @param numbers [Array] + def initialize(base_map:, numbers:) + @base_map = base_map.is_a?(Hash) ? base_map.transform_values { |jsii_v0| jsii_v0.is_a?(Hash) ? ::Scope::JsiiCalcBase::BaseProps.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : base_map + @numbers = numbers + end + + # @return [Hash{String => Scope::JsiiCalcBase::BaseProps}] + attr_reader :base_map + # @return [Array] + attr_reader :numbers + + def self.jsii_properties + { + :base_map => "baseMap", + :numbers => "numbers", + } + end + + def to_jsii + result = {} + result.merge!({ + "baseMap" => @base_map, + "numbers" => @numbers, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2692/submodule1/bar.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2692::Submodule1::Bar < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.module2692.submodule1.Bar", self) + + # @param bar1 [String] + def initialize(bar1:) + @bar1 = bar1 + end + + # @return [String] + attr_reader :bar1 + + def self.jsii_properties + { + :bar1 => "bar1", + } + end + + def to_jsii + result = {} + result.merge!({ + "bar1" => @bar1, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2692/submodule2/bar.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2692::Submodule2::Bar < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.module2692.submodule2.Bar", self) + + # @param bar2 [String] + def initialize(bar2:) + @bar2 = bar2 + end + + # @return [String] + attr_reader :bar2 + + def self.jsii_properties + { + :bar2 => "bar2", + } + end + + def to_jsii + result = {} + result.merge!({ + "bar2" => @bar2, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2692/submodule2/foo.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2692::Submodule2::Foo < ::JsiiCalc::Module2692::Submodule2::Bar + Jsii::Object.register_jsii_fqn("jsii-calc.module2692.submodule2.Foo", self) + jsii_extra_struct_bases.push(::JsiiCalc::Module2692::Submodule1::Bar) + + # @param bar2 [String] + # @param bar1 [String] + # @param foo2 [String] + def initialize(bar2:, bar1:, foo2:) + @bar2 = bar2 + @bar1 = bar1 + @foo2 = foo2 + end + + # @return [String] + attr_reader :bar2 + # @return [String] + attr_reader :bar1 + # @return [String] + attr_reader :foo2 + + def self.jsii_properties + { + :bar2 => "bar2", + :bar1 => "bar1", + :foo2 => "foo2", + } + end + + def to_jsii + result = {} + result.merge!(super) + result.merge!({ + "bar2" => @bar2, + "bar1" => @bar1, + "foo2" => @foo2, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2700/base.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2700::Base < Jsii::Object + include ::JsiiCalc::Module2700::IFoo + self.jsii_fqn = "jsii-calc.module2700.Base" + Jsii::Object.register_jsii_fqn("jsii-calc.module2700.Base", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :baz => { kind: :property, name: "baz", is_optional: false }, + :bar => { kind: :method, name: "bar", is_optional: false }, + } + end + + # @return [Numeric] + def baz() + jsii_get_property("baz") + end + + # @return [String] + def bar() + jsii_call_method("bar", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2700/derived.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2700::Derived < ::JsiiCalc::Module2700::Base + include ::JsiiCalc::Module2700::IFoo + self.jsii_fqn = "jsii-calc.module2700.Derived" + Jsii::Object.register_jsii_fqn("jsii-calc.module2700.Derived", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :baz => { kind: :property, name: "baz", is_optional: false }, + :bar => { kind: :method, name: "bar", is_optional: false }, + :zoo => { kind: :method, name: "zoo", is_optional: false }, + } + end + + # @return [Numeric] + def baz() + jsii_get_property("baz") + end + + # @return [String] + def bar() + jsii_call_method("bar", []) + end + + # @return [String] + def zoo() + jsii_call_method("zoo", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2700/i_foo.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Module2700::IFoo + Jsii::Object.register_jsii_fqn("jsii-calc.module2700.IFoo", self) + + # @return [Numeric] + def baz() + jsii_get_property("baz") + end + + # @return [String] + def bar() + jsii_call_method("bar", []) + end + + def self.jsii_overridable_methods + { + :baz => { kind: :property, name: "baz", is_optional: false }, + :bar => { kind: :method, name: "bar", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2702/baz.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2702::Baz < ::JsiiCalc::Module2702::Class3 + include ::JsiiCalc::Module2702::IBaz + self.jsii_fqn = "jsii-calc.module2702.Baz" + Jsii::Object.register_jsii_fqn("jsii-calc.module2702.Baz", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :bar => { kind: :method, name: "bar", is_optional: false }, + :foo => { kind: :method, name: "foo", is_optional: false }, + :i_base_interface => { kind: :method, name: "iBaseInterface", is_optional: false }, + :baz_method => { kind: :method, name: "bazMethod", is_optional: false }, + } + end + + # @return [void] + def bar() + jsii_call_method("bar", []) + end + + # @return [void] + def foo() + jsii_call_method("foo", []) + end + + # @return [void] + def i_base_interface() + jsii_call_method("iBaseInterface", []) + end + + # @return [void] + def baz_method() + jsii_call_method("bazMethod", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2702/class1.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2702::Class1 < ::Scope::JsiiCalcBase::Base + self.jsii_fqn = "jsii-calc.module2702.Class1" + Jsii::Object.register_jsii_fqn("jsii-calc.module2702.Class1", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :base => { kind: :method, name: "base", is_optional: false }, + } + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # @return [void] + def base() + jsii_call_method("base", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2702/class2.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2702::Class2 < ::Scope::JsiiCalcBase::Base + self.jsii_fqn = "jsii-calc.module2702.Class2" + Jsii::Object.register_jsii_fqn("jsii-calc.module2702.Class2", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :base => { kind: :property, name: "base", is_optional: false }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + } + end + + # @return [String] + def base() + jsii_get_property("base") + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2702/class3.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2702::Class3 < Jsii::Object + include ::Scope::JsiiCalcBase::IBaseInterface + self.jsii_fqn = "jsii-calc.module2702.Class3" + Jsii::Object.register_jsii_fqn("jsii-calc.module2702.Class3", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :bar => { kind: :method, name: "bar", is_optional: false }, + :foo => { kind: :method, name: "foo", is_optional: false }, + :i_base_interface => { kind: :method, name: "iBaseInterface", is_optional: false }, + } + end + + # @return [void] + def bar() + jsii_call_method("bar", []) + end + + # @return [void] + def foo() + jsii_call_method("foo", []) + end + + # @return [void] + def i_base_interface() + jsii_call_method("iBaseInterface", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2702/construct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2702::Construct < Jsii::Object + include ::JsiiCalc::Module2702::IConstruct + self.jsii_fqn = "jsii-calc.module2702.Construct" + Jsii::Object.register_jsii_fqn("jsii-calc.module2702.Construct", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :construct_method => { kind: :method, name: "constructMethod", is_optional: false }, + } + end + + # @return [void] + def construct_method() + jsii_call_method("constructMethod", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2702/i_baz.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Module2702::IBaz + include ::Scope::JsiiCalcBase::IBaseInterface + Jsii::Object.register_jsii_fqn("jsii-calc.module2702.IBaz", self) + + # @return [void] + # @note Default: + # @deprecated + def foo() + jsii_call_method("foo", []) + end + + # @return [void] + # @note Default: + # @deprecated + def bar() + jsii_call_method("bar", []) + end + + # @return [void] + def baz_method() + jsii_call_method("bazMethod", []) + end + + def self.jsii_overridable_methods + { + :foo => { kind: :method, name: "foo", is_optional: false }, + :bar => { kind: :method, name: "bar", is_optional: false }, + :baz_method => { kind: :method, name: "bazMethod", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2702/i_construct.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Module2702::IConstruct + Jsii::Object.register_jsii_fqn("jsii-calc.module2702.IConstruct", self) + + # @return [void] + def construct_method() + jsii_call_method("constructMethod", []) + end + + def self.jsii_overridable_methods + { + :construct_method => { kind: :method, name: "constructMethod", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2702/i_foo.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Module2702::IFoo + include ::Scope::JsiiCalcBase::IBaseInterface + Jsii::Object.register_jsii_fqn("jsii-calc.module2702.IFoo", self) + + # @return [String] + def i_base_interface() + jsii_get_property("iBaseInterface") + end + + # @return [void] + # @note Default: + # @deprecated + def foo() + jsii_call_method("foo", []) + end + + # @return [void] + # @note Default: + # @deprecated + def bar() + jsii_call_method("bar", []) + end + + def self.jsii_overridable_methods + { + :i_base_interface => { kind: :property, name: "iBaseInterface", is_optional: false }, + :foo => { kind: :method, name: "foo", is_optional: false }, + :bar => { kind: :method, name: "bar", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2702/i_resource.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Module2702::IResource + include ::JsiiCalc::Module2702::IConstruct + Jsii::Object.register_jsii_fqn("jsii-calc.module2702.IResource", self) + + # @return [void] + def construct_method() + jsii_call_method("constructMethod", []) + end + + # @return [void] + def resource_method() + jsii_call_method("resourceMethod", []) + end + + def self.jsii_overridable_methods + { + :construct_method => { kind: :method, name: "constructMethod", is_optional: false }, + :resource_method => { kind: :method, name: "resourceMethod", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2702/i_vpc.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Module2702::IVpc + include ::JsiiCalc::Module2702::IResource + Jsii::Object.register_jsii_fqn("jsii-calc.module2702.IVpc", self) + + # @return [void] + def construct_method() + jsii_call_method("constructMethod", []) + end + + # @return [void] + def resource_method() + jsii_call_method("resourceMethod", []) + end + + # @return [void] + def vpc_method() + jsii_call_method("vpcMethod", []) + end + + def self.jsii_overridable_methods + { + :construct_method => { kind: :method, name: "constructMethod", is_optional: false }, + :resource_method => { kind: :method, name: "resourceMethod", is_optional: false }, + :vpc_method => { kind: :method, name: "vpcMethod", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2702/resource.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2702::Resource < ::JsiiCalc::Module2702::Construct + include ::JsiiCalc::Module2702::IResource + self.jsii_fqn = "jsii-calc.module2702.Resource" + Jsii::Object.register_jsii_fqn("jsii-calc.module2702.Resource", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :construct_method => { kind: :method, name: "constructMethod", is_optional: false }, + :resource_method => { kind: :method, name: "resourceMethod", is_optional: false }, + } + end + + # @return [void] + def construct_method() + jsii_call_method("constructMethod", []) + end + + # @return [void] + def resource_method() + jsii_call_method("resourceMethod", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2702/vpc.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Module2702::Vpc < ::JsiiCalc::Module2702::Resource + include ::JsiiCalc::Module2702::IVpc + self.jsii_fqn = "jsii-calc.module2702.Vpc" + Jsii::Object.register_jsii_fqn("jsii-calc.module2702.Vpc", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :construct_method => { kind: :method, name: "constructMethod", is_optional: false }, + :resource_method => { kind: :method, name: "resourceMethod", is_optional: false }, + :vpc_method => { kind: :method, name: "vpcMethod", is_optional: false }, + } + end + + # @return [void] + def construct_method() + jsii_call_method("constructMethod", []) + end + + # @return [void] + def resource_method() + jsii_call_method("resourceMethod", []) + end + + # @return [void] + def vpc_method() + jsii_call_method("vpcMethod", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/multiply.rb 1`] = ` +require 'jsii' + +# The "*" binary operation. +class JsiiCalc::Multiply < ::JsiiCalc::BinaryOperation + include ::JsiiCalc::IFriendlier + include ::JsiiCalc::IRandomNumberGenerator + self.jsii_fqn = "jsii-calc.Multiply" + Jsii::Object.register_jsii_fqn("jsii-calc.Multiply", self) + + # Creates a BinaryOperation. + # + # @param lhs [Scope::JsiiCalcLib::NumericValue] Left-hand side operand. + # @param rhs [Scope::JsiiCalcLib::NumericValue] Right-hand side operand. + def initialize(lhs, rhs) + Jsii::Object.instance_method(:initialize).bind(self).call(lhs, rhs) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :lhs => { kind: :property, name: "lhs", is_optional: false }, + :rhs => { kind: :property, name: "rhs", is_optional: false }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + :hello => { kind: :method, name: "hello", is_optional: false }, + :farewell => { kind: :method, name: "farewell", is_optional: false }, + :goodbye => { kind: :method, name: "goodbye", is_optional: false }, + :_next => { kind: :method, name: "next", is_optional: false }, + } + end + + # The value. + # + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # Left-hand side operand. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def lhs() + jsii_get_property("lhs") + end + + # Right-hand side operand. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def rhs() + jsii_get_property("rhs") + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # String representation of the value. + # + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + + # Say hello! + # + # @return [String] + def hello() + jsii_call_method("hello", []) + end + + # Say farewell. + # + # @return [String] + def farewell() + jsii_call_method("farewell", []) + end + + # Say goodbye. + # + # @return [String] + def goodbye() + jsii_call_method("goodbye", []) + end + + # Returns another random number. + # + # @return [Numeric] + def _next() + jsii_call_method("next", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/negate.rb 1`] = ` +require 'jsii' + +# The negation operation ("-value"). +class JsiiCalc::Negate < ::JsiiCalc::UnaryOperation + include ::JsiiCalc::IFriendlier + self.jsii_fqn = "jsii-calc.Negate" + Jsii::Object.register_jsii_fqn("jsii-calc.Negate", self) + + # @param operand [Scope::JsiiCalcLib::NumericValue] + def initialize(operand) + Jsii::Object.instance_method(:initialize).bind(self).call(operand) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :operand => { kind: :property, name: "operand", is_optional: false }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + :farewell => { kind: :method, name: "farewell", is_optional: false }, + :goodbye => { kind: :method, name: "goodbye", is_optional: false }, + :hello => { kind: :method, name: "hello", is_optional: false }, + } + end + + # The value. + # + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # @return [Scope::JsiiCalcLib::NumericValue] + def operand() + jsii_get_property("operand") + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # String representation of the value. + # + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + + # Say farewell. + # + # @return [String] + def farewell() + jsii_call_method("farewell", []) + end + + # Say goodbye. + # + # @return [String] + def goodbye() + jsii_call_method("goodbye", []) + end + + # Say hello! + # + # @return [String] + def hello() + jsii_call_method("hello", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/nested_class_instance.rb 1`] = ` +require 'jsii' + +class JsiiCalc::NestedClassInstance < Jsii::Object + self.jsii_fqn = "jsii-calc.NestedClassInstance" + Jsii::Object.register_jsii_fqn("jsii-calc.NestedClassInstance", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.NestedClassInstance does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @return [Scope::JsiiCalcLib::Submodule::NestingClass::NestedClass] + def self.make_instance() + Jsii::Kernel.instance.call_static("jsii-calc.NestedClassInstance", "makeInstance", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/nested_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::NestedStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.NestedStruct", self) + + # @param number_prop [Numeric] When provided, must be > 0. + def initialize(number_prop:) + @number_prop = number_prop + end + + # When provided, must be > 0. + # + # @return [Numeric] + attr_reader :number_prop + + def self.jsii_properties + { + :number_prop => "numberProp", + } + end + + def to_jsii + result = {} + result.merge!({ + "numberProp" => @number_prop, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/node_standard_library.rb 1`] = ` +require 'jsii' + +# Test fixture to verify that jsii modules can use the node standard library. +class JsiiCalc::NodeStandardLibrary < Jsii::Object + self.jsii_fqn = "jsii-calc.NodeStandardLibrary" + Jsii::Object.register_jsii_fqn("jsii-calc.NodeStandardLibrary", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :os_platform => { kind: :property, name: "osPlatform", is_optional: false }, + :crypto_sha256 => { kind: :method, name: "cryptoSha256", is_optional: false }, + :fs_read_file => { kind: :method, name: "fsReadFile", is_optional: false }, + :fs_read_file_sync => { kind: :method, name: "fsReadFileSync", is_optional: false }, + } + end + + # Returns the current os.platform() from the "os" node module. + # + # @return [String] + def os_platform() + jsii_get_property("osPlatform") + end + + # Uses node.js "crypto" module to calculate sha256 of a string. + # + # @return [String] "6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50" + def crypto_sha256() + jsii_call_method("cryptoSha256", []) + end + + # Reads a local resource file (resource.txt) asynchronously. + # + # @return [String] "Hello, resource!" + def fs_read_file() + jsii_async_call_method("fsReadFile", []) + end + + # Sync version of fsReadFile. + # + # @return [String] "Hello, resource! SYNC!" + def fs_read_file_sync() + jsii_call_method("fsReadFileSync", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/nodirect/sub1/type_from_sub1.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Nodirect::Sub1::TypeFromSub1 < Jsii::Object + self.jsii_fqn = "jsii-calc.nodirect.sub1.TypeFromSub1" + Jsii::Object.register_jsii_fqn("jsii-calc.nodirect.sub1.TypeFromSub1", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :sub1 => { kind: :method, name: "sub1", is_optional: false }, + } + end + + # @return [String] + def sub1() + jsii_call_method("sub1", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/nodirect/sub2/type_from_sub2.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Nodirect::Sub2::TypeFromSub2 < Jsii::Object + self.jsii_fqn = "jsii-calc.nodirect.sub2.TypeFromSub2" + Jsii::Object.register_jsii_fqn("jsii-calc.nodirect.sub2.TypeFromSub2", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :sub2 => { kind: :method, name: "sub2", is_optional: false }, + } + end + + # @return [String] + def sub2() + jsii_call_method("sub2", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/null_should_be_treated_as_undefined.rb 1`] = ` +require 'jsii' + +# jsii#282, aws-cdk#157: null should be treated as "undefined". +class JsiiCalc::NullShouldBeTreatedAsUndefined < Jsii::Object + self.jsii_fqn = "jsii-calc.NullShouldBeTreatedAsUndefined" + Jsii::Object.register_jsii_fqn("jsii-calc.NullShouldBeTreatedAsUndefined", self) + + # @param _param1 [String] + # @param optional [Object, nil] + def initialize(_param1, optional = nil) + Jsii::Object.instance_method(:initialize).bind(self).call(_param1, optional) + end + + def self.jsii_overridable_methods + { + :change_me_to_undefined => { kind: :property, name: "changeMeToUndefined", is_optional: true }, + :give_me_undefined => { kind: :method, name: "giveMeUndefined", is_optional: false }, + :give_me_undefined_inside_an_object => { kind: :method, name: "giveMeUndefinedInsideAnObject", is_optional: false }, + :verify_property_is_undefined => { kind: :method, name: "verifyPropertyIsUndefined", is_optional: false }, + } + end + + # @return [String, nil] + def change_me_to_undefined() + jsii_get_property("changeMeToUndefined") + end + + def change_me_to_undefined=(value) + jsii_set_property("changeMeToUndefined", value) + end + + # @param value [Object, nil] + # @return [void] + def give_me_undefined(value = nil) + jsii_call_method("giveMeUndefined", [value]) + end + + # @param input [JsiiCalc::NullShouldBeTreatedAsUndefinedData] + # @return [void] + def give_me_undefined_inside_an_object(input) + input = input.is_a?(Hash) ? ::JsiiCalc::NullShouldBeTreatedAsUndefinedData.new(**input.transform_keys(&:to_sym)) : input + jsii_call_method("giveMeUndefinedInsideAnObject", [input]) + end + + # @return [void] + def verify_property_is_undefined() + jsii_call_method("verifyPropertyIsUndefined", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/null_should_be_treated_as_undefined_data.rb 1`] = ` +require 'jsii' + +class JsiiCalc::NullShouldBeTreatedAsUndefinedData < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.NullShouldBeTreatedAsUndefinedData", self) + + # @param array_with_three_elements_and_undefined_as_second_argument [Array] + # @param this_should_be_undefined [Object, nil] + def initialize(array_with_three_elements_and_undefined_as_second_argument:, this_should_be_undefined: nil) + @array_with_three_elements_and_undefined_as_second_argument = array_with_three_elements_and_undefined_as_second_argument + @this_should_be_undefined = this_should_be_undefined + end + + # @return [Array] + attr_reader :array_with_three_elements_and_undefined_as_second_argument + # @return [Object, nil] + attr_reader :this_should_be_undefined + + def self.jsii_properties + { + :array_with_three_elements_and_undefined_as_second_argument => "arrayWithThreeElementsAndUndefinedAsSecondArgument", + :this_should_be_undefined => "thisShouldBeUndefined", + } + end + + def to_jsii + result = {} + result.merge!({ + "arrayWithThreeElementsAndUndefinedAsSecondArgument" => @array_with_three_elements_and_undefined_as_second_argument, + "thisShouldBeUndefined" => @this_should_be_undefined, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/number_generator.rb 1`] = ` +require 'jsii' + +# This allows us to test that a reference can be stored for objects that implement interfaces. +class JsiiCalc::NumberGenerator < Jsii::Object + self.jsii_fqn = "jsii-calc.NumberGenerator" + Jsii::Object.register_jsii_fqn("jsii-calc.NumberGenerator", self) + + # @param generator [JsiiCalc::IRandomNumberGenerator] + def initialize(generator) + generator = Jsii::Utils.coerce_callable(generator, ::JsiiCalc::IRandomNumberGenerator) + Jsii::Object.instance_method(:initialize).bind(self).call(generator) + end + + def self.jsii_overridable_methods + { + :generator => { kind: :property, name: "generator", is_optional: false }, + :is_same_generator => { kind: :method, name: "isSameGenerator", is_optional: false }, + :next_times100 => { kind: :method, name: "nextTimes100", is_optional: false }, + } + end + + # @return [JsiiCalc::IRandomNumberGenerator] + def generator() + jsii_get_property("generator") + end + + def generator=(value) + value = Jsii::Utils.coerce_callable(value, ::JsiiCalc::IRandomNumberGenerator) + jsii_set_property("generator", value) + end + + # @param gen [JsiiCalc::IRandomNumberGenerator] + # @return [Boolean] + def is_same_generator(gen) + gen = Jsii::Utils.coerce_callable(gen, ::JsiiCalc::IRandomNumberGenerator) + jsii_call_method("isSameGenerator", [gen]) + end + + # @return [Numeric] + def next_times100() + jsii_call_method("nextTimes100", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/object_refs_in_collections.rb 1`] = ` +require 'jsii' + +# Verify that object references can be passed inside collections. +class JsiiCalc::ObjectRefsInCollections < Jsii::Object + self.jsii_fqn = "jsii-calc.ObjectRefsInCollections" + Jsii::Object.register_jsii_fqn("jsii-calc.ObjectRefsInCollections", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :sum_from_array => { kind: :method, name: "sumFromArray", is_optional: false }, + :sum_from_map => { kind: :method, name: "sumFromMap", is_optional: false }, + } + end + + # Returns the sum of all values. + # + # @param values [Array] + # @return [Numeric] + def sum_from_array(values) + jsii_call_method("sumFromArray", [values]) + end + + # Returns the sum of all values in a map. + # + # @param values [Hash{String => Scope::JsiiCalcLib::NumericValue}] + # @return [Numeric] + def sum_from_map(values) + jsii_call_method("sumFromMap", [values]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/object_with_property_provider.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ObjectWithPropertyProvider < Jsii::Object + self.jsii_fqn = "jsii-calc.ObjectWithPropertyProvider" + Jsii::Object.register_jsii_fqn("jsii-calc.ObjectWithPropertyProvider", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.ObjectWithPropertyProvider does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @return [JsiiCalc::IObjectWithProperty] + def self.provide() + Jsii::Kernel.instance.call_static("jsii-calc.ObjectWithPropertyProvider", "provide", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/old.rb 1`] = ` +require 'jsii' + +# Old class. +# +# @deprecated Use the new class or the old class whatever you want because whatever you like is always the best +class JsiiCalc::Old < Jsii::Object + self.jsii_fqn = "jsii-calc.Old" + Jsii::Object.register_jsii_fqn("jsii-calc.Old", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :do_a_thing => { kind: :method, name: "doAThing", is_optional: false }, + } + end + + # Doo wop that thing. + # + # @return [void] + def do_a_thing() + jsii_call_method("doAThing", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/onlystatic/only_static_methods.rb 1`] = ` +require 'jsii' + +# Test for https://github.com/aws/jsii/issues/2617. +class JsiiCalc::Onlystatic::OnlyStaticMethods < Jsii::Object + self.jsii_fqn = "jsii-calc.onlystatic.OnlyStaticMethods" + Jsii::Object.register_jsii_fqn("jsii-calc.onlystatic.OnlyStaticMethods", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.onlystatic.OnlyStaticMethods does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @return [String] + def self.static_method() + Jsii::Kernel.instance.call_static("jsii-calc.onlystatic.OnlyStaticMethods", "staticMethod", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/optional_argument_invoker.rb 1`] = ` +require 'jsii' + +class JsiiCalc::OptionalArgumentInvoker < Jsii::Object + self.jsii_fqn = "jsii-calc.OptionalArgumentInvoker" + Jsii::Object.register_jsii_fqn("jsii-calc.OptionalArgumentInvoker", self) + + # @param delegate [JsiiCalc::IInterfaceWithOptionalMethodArguments] + def initialize(delegate) + delegate = Jsii::Utils.coerce_callable(delegate, ::JsiiCalc::IInterfaceWithOptionalMethodArguments) + Jsii::Object.instance_method(:initialize).bind(self).call(delegate) + end + + def self.jsii_overridable_methods + { + :invoke_with_optional => { kind: :method, name: "invokeWithOptional", is_optional: false }, + :invoke_without_optional => { kind: :method, name: "invokeWithoutOptional", is_optional: false }, + } + end + + # @return [void] + def invoke_with_optional() + jsii_call_method("invokeWithOptional", []) + end + + # @return [void] + def invoke_without_optional() + jsii_call_method("invokeWithoutOptional", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/optional_constructor_argument.rb 1`] = ` +require 'jsii' + +class JsiiCalc::OptionalConstructorArgument < Jsii::Object + self.jsii_fqn = "jsii-calc.OptionalConstructorArgument" + Jsii::Object.register_jsii_fqn("jsii-calc.OptionalConstructorArgument", self) + + # @param arg1 [Numeric] + # @param arg2 [String] + # @param arg3 [DateTime, nil] + def initialize(arg1, arg2, arg3 = nil) + Jsii::Object.instance_method(:initialize).bind(self).call(arg1, arg2, arg3) + end + + def self.jsii_overridable_methods + { + :arg1 => { kind: :property, name: "arg1", is_optional: false }, + :arg2 => { kind: :property, name: "arg2", is_optional: false }, + :arg3 => { kind: :property, name: "arg3", is_optional: true }, + } + end + + # @return [Numeric] + def arg1() + jsii_get_property("arg1") + end + + # @return [String] + def arg2() + jsii_get_property("arg2") + end + + # @return [DateTime, nil] + def arg3() + jsii_get_property("arg3") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/optional_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::OptionalStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.OptionalStruct", self) + + # @param field [String, nil] + def initialize(field: nil) + @field = field + end + + # @return [String, nil] + attr_reader :field + + def self.jsii_properties + { + :field => "field", + } + end + + def to_jsii + result = {} + result.merge!({ + "field" => @field, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/optional_struct_consumer.rb 1`] = ` +require 'jsii' + +class JsiiCalc::OptionalStructConsumer < Jsii::Object + self.jsii_fqn = "jsii-calc.OptionalStructConsumer" + Jsii::Object.register_jsii_fqn("jsii-calc.OptionalStructConsumer", self) + + # @param optional_struct [JsiiCalc::OptionalStruct, nil] + def initialize(optional_struct = nil) + optional_struct = optional_struct.is_a?(Hash) ? ::JsiiCalc::OptionalStruct.new(**optional_struct.transform_keys(&:to_sym)) : optional_struct + Jsii::Object.instance_method(:initialize).bind(self).call(optional_struct) + end + + def self.jsii_overridable_methods + { + :parameter_was_undefined => { kind: :property, name: "parameterWasUndefined", is_optional: false }, + :field_value => { kind: :property, name: "fieldValue", is_optional: true }, + } + end + + # @return [Boolean] + def parameter_was_undefined() + jsii_get_property("parameterWasUndefined") + end + + # @return [String, nil] + def field_value() + jsii_get_property("fieldValue") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/overridable_protected_member.rb 1`] = ` +require 'jsii' + +# @see https://github.com/aws/jsii/issues/903 +class JsiiCalc::OverridableProtectedMember < Jsii::Object + self.jsii_fqn = "jsii-calc.OverridableProtectedMember" + Jsii::Object.register_jsii_fqn("jsii-calc.OverridableProtectedMember", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :override_read_only => { kind: :property, name: "overrideReadOnly", is_optional: false }, + :override_read_write => { kind: :property, name: "overrideReadWrite", is_optional: false }, + :override_me => { kind: :method, name: "overrideMe", is_optional: false }, + :switch_modes => { kind: :method, name: "switchModes", is_optional: false }, + :value_from_protected => { kind: :method, name: "valueFromProtected", is_optional: false }, + } + end + + # @return [String] + def override_read_only() + jsii_get_property("overrideReadOnly") + end + + # @return [String] + def override_read_write() + jsii_get_property("overrideReadWrite") + end + + def override_read_write=(value) + jsii_set_property("overrideReadWrite", value) + end + + # @return [String] + def override_me() + jsii_call_method("overrideMe", []) + end + + # @return [void] + def switch_modes() + jsii_call_method("switchModes", []) + end + + # @return [String] + def value_from_protected() + jsii_call_method("valueFromProtected", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/override_returns_object.rb 1`] = ` +require 'jsii' + +class JsiiCalc::OverrideReturnsObject < Jsii::Object + self.jsii_fqn = "jsii-calc.OverrideReturnsObject" + Jsii::Object.register_jsii_fqn("jsii-calc.OverrideReturnsObject", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :test => { kind: :method, name: "test", is_optional: false }, + } + end + + # @param obj [JsiiCalc::IReturnsNumber] + # @return [Numeric] + def test(obj) + jsii_call_method("test", [obj]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/param_shadows_builtins.rb 1`] = ` +require 'jsii' + +# Validate that parameters named "str" or "builtins" do not shadow the actual type names in Python. +class JsiiCalc::ParamShadowsBuiltins < Jsii::Object + self.jsii_fqn = "jsii-calc.ParamShadowsBuiltins" + Jsii::Object.register_jsii_fqn("jsii-calc.ParamShadowsBuiltins", self) + + # @param builtins [String] should be set to something that is NOT a valid expression in Python (e.g: "\${NOPE}""). + # @param str [String] should be set to something that is NOT a valid expression in Python (e.g: "\${NOPE}""). + # @param props [JsiiCalc::ParamShadowsBuiltinsProps] should be set to valid values. + def initialize(builtins, str, props) + props = props.is_a?(Hash) ? ::JsiiCalc::ParamShadowsBuiltinsProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Object.instance_method(:initialize).bind(self).call(builtins, str, props) + end + + def self.jsii_overridable_methods + { + } + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/param_shadows_builtins_props.rb 1`] = ` +require 'jsii' + +class JsiiCalc::ParamShadowsBuiltinsProps < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.ParamShadowsBuiltinsProps", self) + + # @param boolean_property [Boolean] + # @param string_property [String] + # @param struct_property [JsiiCalc::StructA] + def initialize(boolean_property:, string_property:, struct_property:) + @boolean_property = boolean_property + @string_property = string_property + @struct_property = struct_property.is_a?(Hash) ? ::JsiiCalc::StructA.new(**struct_property.transform_keys(&:to_sym)) : struct_property + end + + # @return [Boolean] + attr_reader :boolean_property + # @return [String] + attr_reader :string_property + # @return [JsiiCalc::StructA] + attr_reader :struct_property + + def self.jsii_properties + { + :boolean_property => "booleanProperty", + :string_property => "stringProperty", + :struct_property => "structProperty", + } + end + + def to_jsii + result = {} + result.merge!({ + "booleanProperty" => @boolean_property, + "stringProperty" => @string_property, + "structProperty" => @struct_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/param_shadows_scope.rb 1`] = ` +require 'jsii' + +# Validate that namespaces being shadowed by local variables does not cause type checking issues. +# +# @see https://github.com/aws/aws-cdk/issues/22975 +class JsiiCalc::ParamShadowsScope < Jsii::Object + self.jsii_fqn = "jsii-calc.ParamShadowsScope" + Jsii::Object.register_jsii_fqn("jsii-calc.ParamShadowsScope", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :use_scope => { kind: :method, name: "useScope", is_optional: false }, + } + end + + # @param scope [Scope::JsiiCalcLib::Number] + # @return [Scope::JsiiCalcLib::Number] + def use_scope(scope) + jsii_call_method("useScope", [scope]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/parent_struct982.rb 1`] = ` +require 'jsii' + +# https://github.com/aws/jsii/issues/982. +class JsiiCalc::ParentStruct982 < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.ParentStruct982", self) + + # @param foo [String] + def initialize(foo:) + @foo = foo + end + + # @return [String] + attr_reader :foo + + def self.jsii_properties + { + :foo => "foo", + } + end + + def to_jsii + result = {} + result.merge!({ + "foo" => @foo, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/partially_initialized_this_consumer.rb 1`] = ` +require 'jsii' + +class JsiiCalc::PartiallyInitializedThisConsumer < Jsii::Object + self.jsii_fqn = "jsii-calc.PartiallyInitializedThisConsumer" + Jsii::Object.register_jsii_fqn("jsii-calc.PartiallyInitializedThisConsumer", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :consume_partially_initialized_this => { kind: :method, name: "consumePartiallyInitializedThis", is_optional: false }, + } + end + + # @param obj [JsiiCalc::ConstructorPassesThisOut] + # @param dt [DateTime] + # @param ev [JsiiCalc::AllTypesEnum] + # @return [String] + def consume_partially_initialized_this(obj, dt, ev) + jsii_call_method("consumePartiallyInitializedThis", [obj, dt, ev]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/pascal_case_name/sub_subclass.rb 1`] = ` +require 'jsii' + +class JsiiCalc::PascalCaseName::SubSubclass < ::JsiiCalc::PascalCaseName::Subclass + self.jsii_fqn = "jsii-calc.pascalCaseName.SubSubclass" + Jsii::Object.register_jsii_fqn("jsii-calc.pascalCaseName.SubSubclass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/pascal_case_name/subclass.rb 1`] = ` +require 'jsii' + +class JsiiCalc::PascalCaseName::Subclass < ::JsiiCalc::PascalCaseName::Superclass + self.jsii_fqn = "jsii-calc.pascalCaseName.Subclass" + Jsii::Object.register_jsii_fqn("jsii-calc.pascalCaseName.Subclass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/pascal_case_name/superclass.rb 1`] = ` +require 'jsii' + +# This module ensures that language code is generated in correct topological order. +# +# We deliberately name classes & interfaces so that the ones that must come first in code, +# are last in alphabetical order. +# +# Previously, the generated Python code would miss certain dependencies +# and effectively render classes alphabetically. Which then obviously fails. +class JsiiCalc::PascalCaseName::Superclass < Jsii::Object + self.jsii_fqn = "jsii-calc.pascalCaseName.Superclass" + Jsii::Object.register_jsii_fqn("jsii-calc.pascalCaseName.Superclass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/polymorphism.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Polymorphism < Jsii::Object + self.jsii_fqn = "jsii-calc.Polymorphism" + Jsii::Object.register_jsii_fqn("jsii-calc.Polymorphism", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :say_hello => { kind: :method, name: "sayHello", is_optional: false }, + } + end + + # @param friendly [Scope::JsiiCalcLib::IFriendly] + # @return [String] + def say_hello(friendly) + friendly = Jsii::Utils.coerce_callable(friendly, ::Scope::JsiiCalcLib::IFriendly) + jsii_call_method("sayHello", [friendly]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/power.rb 1`] = ` +require 'jsii' + +# The power operation. +class JsiiCalc::Power < ::JsiiCalc::Composition::CompositeOperation + self.jsii_fqn = "jsii-calc.Power" + Jsii::Object.register_jsii_fqn("jsii-calc.Power", self) + + # Creates a Power operation. + # + # @param base [Scope::JsiiCalcLib::NumericValue] The base of the power. + # @param pow [Scope::JsiiCalcLib::NumericValue] The number of times to multiply. + def initialize(base, pow) + Jsii::Object.instance_method(:initialize).bind(self).call(base, pow) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :expression => { kind: :property, name: "expression", is_optional: false }, + :decoration_postfixes => { kind: :property, name: "decorationPostfixes", is_optional: false }, + :decoration_prefixes => { kind: :property, name: "decorationPrefixes", is_optional: false }, + :string_style => { kind: :property, name: "stringStyle", is_optional: false }, + :base => { kind: :property, name: "base", is_optional: false }, + :pow => { kind: :property, name: "pow", is_optional: false }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + } + end + + # The value. + # + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # The expression that this operation consists of. + # + # Must be implemented by derived classes. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def expression() + jsii_get_property("expression") + end + + # A set of postfixes to include in a decorated .toString(). + # + # @return [Array] + def decoration_postfixes() + jsii_get_property("decorationPostfixes") + end + + def decoration_postfixes=(value) + jsii_set_property("decorationPostfixes", value) + end + + # A set of prefixes to include in a decorated .toString(). + # + # @return [Array] + def decoration_prefixes() + jsii_get_property("decorationPrefixes") + end + + def decoration_prefixes=(value) + jsii_set_property("decorationPrefixes", value) + end + + # The .toString() style. + # + # @return [JsiiCalc::Composition::CompositeOperation::CompositionStringStyle] + def string_style() + jsii_get_property("stringStyle") + end + + def string_style=(value) + jsii_set_property("stringStyle", value) + end + + # The base of the power. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def base() + jsii_get_property("base") + end + + # The number of times to multiply. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def pow() + jsii_get_property("pow") + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # String representation of the value. + # + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/promise_nothing.rb 1`] = ` +require 'jsii' + +class JsiiCalc::PromiseNothing < Jsii::Object + self.jsii_fqn = "jsii-calc.PromiseNothing" + Jsii::Object.register_jsii_fqn("jsii-calc.PromiseNothing", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :instance_promise_it => { kind: :method, name: "instancePromiseIt", is_optional: false }, + } + end + + # @return [void] + def self.promise_it() + Jsii::Kernel.instance.call_static("jsii-calc.PromiseNothing", "promiseIt", []) + end + + # @return [void] + def instance_promise_it() + jsii_async_call_method("instancePromiseIt", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/property_named_property.rb 1`] = ` +require 'jsii' + +# Reproduction for https://github.com/aws/jsii/issues/1113 Where a method or property named "property" would result in impossible to load Python code. +class JsiiCalc::PropertyNamedProperty < Jsii::Object + self.jsii_fqn = "jsii-calc.PropertyNamedProperty" + Jsii::Object.register_jsii_fqn("jsii-calc.PropertyNamedProperty", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :property => { kind: :property, name: "property", is_optional: false }, + :yet_anoter_one => { kind: :property, name: "yetAnoterOne", is_optional: false }, + } + end + + # @return [String] + def property() + jsii_get_property("property") + end + + # @return [Boolean] + def yet_anoter_one() + jsii_get_property("yetAnoterOne") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/public_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::PublicClass < Jsii::Object + self.jsii_fqn = "jsii-calc.PublicClass" + Jsii::Object.register_jsii_fqn("jsii-calc.PublicClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :hello => { kind: :method, name: "hello", is_optional: false }, + } + end + + # @return [void] + def hello() + jsii_call_method("hello", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/python_reserved_words.rb 1`] = ` +require 'jsii' + +class JsiiCalc::PythonReservedWords < Jsii::Object + self.jsii_fqn = "jsii-calc.PythonReservedWords" + Jsii::Object.register_jsii_fqn("jsii-calc.PythonReservedWords", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :_and => { kind: :method, name: "and", is_optional: false }, + :as => { kind: :method, name: "as", is_optional: false }, + :assert => { kind: :method, name: "assert", is_optional: false }, + :async => { kind: :method, name: "async", is_optional: false }, + :await => { kind: :method, name: "await", is_optional: false }, + :_break => { kind: :method, name: "break", is_optional: false }, + :_class => { kind: :method, name: "class", is_optional: false }, + :continue => { kind: :method, name: "continue", is_optional: false }, + :_def => { kind: :method, name: "def", is_optional: false }, + :del => { kind: :method, name: "del", is_optional: false }, + :elif => { kind: :method, name: "elif", is_optional: false }, + :_else => { kind: :method, name: "else", is_optional: false }, + :except => { kind: :method, name: "except", is_optional: false }, + :finally => { kind: :method, name: "finally", is_optional: false }, + :_for => { kind: :method, name: "for", is_optional: false }, + :from => { kind: :method, name: "from", is_optional: false }, + :global => { kind: :method, name: "global", is_optional: false }, + :_if => { kind: :method, name: "if", is_optional: false }, + :import => { kind: :method, name: "import", is_optional: false }, + :_in => { kind: :method, name: "in", is_optional: false }, + :is => { kind: :method, name: "is", is_optional: false }, + :lambda => { kind: :method, name: "lambda", is_optional: false }, + :nonlocal => { kind: :method, name: "nonlocal", is_optional: false }, + :_not => { kind: :method, name: "not", is_optional: false }, + :_or => { kind: :method, name: "or", is_optional: false }, + :pass => { kind: :method, name: "pass", is_optional: false }, + :raise => { kind: :method, name: "raise", is_optional: false }, + :_return => { kind: :method, name: "return", is_optional: false }, + :try => { kind: :method, name: "try", is_optional: false }, + :_while => { kind: :method, name: "while", is_optional: false }, + :with => { kind: :method, name: "with", is_optional: false }, + :_yield => { kind: :method, name: "yield", is_optional: false }, + } + end + + # @return [void] + def _and() + jsii_call_method("and", []) + end + + # @return [void] + def as() + jsii_call_method("as", []) + end + + # @return [void] + def assert() + jsii_call_method("assert", []) + end + + # @return [void] + def async() + jsii_call_method("async", []) + end + + # @return [void] + def await() + jsii_call_method("await", []) + end + + # @return [void] + def _break() + jsii_call_method("break", []) + end + + # @return [void] + def _class() + jsii_call_method("class", []) + end + + # @return [void] + def continue() + jsii_call_method("continue", []) + end + + # @return [void] + def _def() + jsii_call_method("def", []) + end + + # @return [void] + def del() + jsii_call_method("del", []) + end + + # @return [void] + def elif() + jsii_call_method("elif", []) + end + + # @return [void] + def _else() + jsii_call_method("else", []) + end + + # @return [void] + def except() + jsii_call_method("except", []) + end + + # @return [void] + def finally() + jsii_call_method("finally", []) + end + + # @return [void] + def _for() + jsii_call_method("for", []) + end + + # @return [void] + def from() + jsii_call_method("from", []) + end + + # @return [void] + def global() + jsii_call_method("global", []) + end + + # @return [void] + def _if() + jsii_call_method("if", []) + end + + # @return [void] + def import() + jsii_call_method("import", []) + end + + # @return [void] + def _in() + jsii_call_method("in", []) + end + + # @return [void] + def is() + jsii_call_method("is", []) + end + + # @return [void] + def lambda() + jsii_call_method("lambda", []) + end + + # @return [void] + def nonlocal() + jsii_call_method("nonlocal", []) + end + + # @return [void] + def _not() + jsii_call_method("not", []) + end + + # @return [void] + def _or() + jsii_call_method("or", []) + end + + # @return [void] + def pass() + jsii_call_method("pass", []) + end + + # @return [void] + def raise() + jsii_call_method("raise", []) + end + + # @return [void] + def _return() + jsii_call_method("return", []) + end + + # @return [void] + def try() + jsii_call_method("try", []) + end + + # @return [void] + def _while() + jsii_call_method("while", []) + end + + # @return [void] + def with() + jsii_call_method("with", []) + end + + # @return [void] + def _yield() + jsii_call_method("yield", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/python_self/class_with_self.rb 1`] = ` +require 'jsii' + +class JsiiCalc::PythonSelf::ClassWithSelf < Jsii::Object + self.jsii_fqn = "jsii-calc.PythonSelf.ClassWithSelf" + Jsii::Object.register_jsii_fqn("jsii-calc.PythonSelf.ClassWithSelf", self) + + # @param _self [String] + def initialize(_self) + Jsii::Object.instance_method(:initialize).bind(self).call(_self) + end + + def self.jsii_overridable_methods + { + :_self => { kind: :property, name: "self", is_optional: false }, + :method => { kind: :method, name: "method", is_optional: false }, + } + end + + # @return [String] + def _self() + jsii_get_property("self") + end + + # @param _self [Numeric] + # @return [String] + def method(_self) + jsii_call_method("method", [_self]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/python_self/class_with_self_kwarg.rb 1`] = ` +require 'jsii' + +class JsiiCalc::PythonSelf::ClassWithSelfKwarg < Jsii::Object + self.jsii_fqn = "jsii-calc.PythonSelf.ClassWithSelfKwarg" + Jsii::Object.register_jsii_fqn("jsii-calc.PythonSelf.ClassWithSelfKwarg", self) + + # @param props [JsiiCalc::PythonSelf::StructWithSelf] + def initialize(props) + props = props.is_a?(Hash) ? ::JsiiCalc::PythonSelf::StructWithSelf.new(**props.transform_keys(&:to_sym)) : props + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { + :props => { kind: :property, name: "props", is_optional: false }, + } + end + + # @return [JsiiCalc::PythonSelf::StructWithSelf] + def props() + jsii_get_property("props") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/python_self/i_interface_with_self.rb 1`] = ` +require 'jsii' + +module JsiiCalc::PythonSelf::IInterfaceWithSelf + Jsii::Object.register_jsii_fqn("jsii-calc.PythonSelf.IInterfaceWithSelf", self) + + # @param _self [Numeric] + # @return [String] + def method(_self) + jsii_call_method("method", [_self]) + end + + def self.jsii_overridable_methods + { + :method => { kind: :method, name: "method", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/python_self/struct_with_self.rb 1`] = ` +require 'jsii' + +class JsiiCalc::PythonSelf::StructWithSelf < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.PythonSelf.StructWithSelf", self) + + # @param _self [String] + def initialize(_self:) + @_self = _self + end + + # @return [String] + attr_reader :_self + + def self.jsii_properties + { + :_self => "self", + } + end + + def to_jsii + result = {} + result.merge!({ + "self" => @_self, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/reference_enum_from_scoped_package.rb 1`] = ` +require 'jsii' + +# See awslabs/jsii#138. +class JsiiCalc::ReferenceEnumFromScopedPackage < Jsii::Object + self.jsii_fqn = "jsii-calc.ReferenceEnumFromScopedPackage" + Jsii::Object.register_jsii_fqn("jsii-calc.ReferenceEnumFromScopedPackage", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :foo => { kind: :property, name: "foo", is_optional: true }, + :load_foo => { kind: :method, name: "loadFoo", is_optional: false }, + :save_foo => { kind: :method, name: "saveFoo", is_optional: false }, + } + end + + # @return [Scope::JsiiCalcLib::EnumFromScopedModule, nil] + def foo() + jsii_get_property("foo") + end + + def foo=(value) + jsii_set_property("foo", value) + end + + # @return [Scope::JsiiCalcLib::EnumFromScopedModule, nil] + def load_foo() + jsii_call_method("loadFoo", []) + end + + # @param value [Scope::JsiiCalcLib::EnumFromScopedModule] + # @return [void] + def save_foo(value) + jsii_call_method("saveFoo", [value]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/returns_private_implementation_of_interface.rb 1`] = ` +require 'jsii' + +# Helps ensure the JSII kernel & runtime cooperate correctly when an un-exported instance of a class is returned with a declared type that is an exported interface, and the instance inherits from an exported class. +# +# @see https://github.com/aws/jsii/issues/320 +class JsiiCalc::ReturnsPrivateImplementationOfInterface < Jsii::Object + self.jsii_fqn = "jsii-calc.ReturnsPrivateImplementationOfInterface" + Jsii::Object.register_jsii_fqn("jsii-calc.ReturnsPrivateImplementationOfInterface", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :private_implementation => { kind: :property, name: "privateImplementation", is_optional: false }, + } + end + + # @return [JsiiCalc::IPrivatelyImplemented] + def private_implementation() + jsii_get_property("privateImplementation") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/root_struct.rb 1`] = ` +require 'jsii' + +# This is here to check that we can pass a nested struct into a kwargs by specifying it as an in-line dictionary. +# +# This is cheating with the (current) declared types, but this is the "more +# idiomatic" way for Pythonists. +class JsiiCalc::RootStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.RootStruct", self) + + # @param string_prop [String] May not be empty. + # @param nested_struct [JsiiCalc::NestedStruct, nil] + def initialize(string_prop:, nested_struct: nil) + @string_prop = string_prop + @nested_struct = nested_struct.is_a?(Hash) ? ::JsiiCalc::NestedStruct.new(**nested_struct.transform_keys(&:to_sym)) : nested_struct + end + + # May not be empty. + # + # @return [String] + attr_reader :string_prop + # @return [JsiiCalc::NestedStruct, nil] + attr_reader :nested_struct + + def self.jsii_properties + { + :string_prop => "stringProp", + :nested_struct => "nestedStruct", + } + end + + def to_jsii + result = {} + result.merge!({ + "stringProp" => @string_prop, + "nestedStruct" => @nested_struct, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/root_struct_validator.rb 1`] = ` +require 'jsii' + +class JsiiCalc::RootStructValidator < Jsii::Object + self.jsii_fqn = "jsii-calc.RootStructValidator" + Jsii::Object.register_jsii_fqn("jsii-calc.RootStructValidator", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.RootStructValidator does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @param struct [JsiiCalc::RootStruct] + # @return [void] + def self.validate(struct) + struct = struct.is_a?(Hash) ? ::JsiiCalc::RootStruct.new(**struct.transform_keys(&:to_sym)) : struct + Jsii::Kernel.instance.call_static("jsii-calc.RootStructValidator", "validate", [struct]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/runtime_type_checking.rb 1`] = ` +require 'jsii' + +class JsiiCalc::RuntimeTypeChecking < Jsii::Object + self.jsii_fqn = "jsii-calc.RuntimeTypeChecking" + Jsii::Object.register_jsii_fqn("jsii-calc.RuntimeTypeChecking", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :method_with_defaulted_arguments => { kind: :method, name: "methodWithDefaultedArguments", is_optional: false }, + :method_with_optional_any_argument => { kind: :method, name: "methodWithOptionalAnyArgument", is_optional: false }, + :method_with_optional_arguments => { kind: :method, name: "methodWithOptionalArguments", is_optional: false }, + } + end + + # @param arg1 [Numeric, nil] + # @param arg2 [String, nil] + # @param arg3 [DateTime, nil] + # @return [void] + def method_with_defaulted_arguments(arg1 = nil, arg2 = nil, arg3 = nil) + jsii_call_method("methodWithDefaultedArguments", [arg1, arg2, arg3]) + end + + # @param arg [Object, nil] + # @return [void] + def method_with_optional_any_argument(arg = nil) + jsii_call_method("methodWithOptionalAnyArgument", [arg]) + end + + # Used to verify verification of number of method arguments. + # + # @param arg1 [Numeric] + # @param arg2 [String] + # @param arg3 [DateTime, nil] + # @return [void] + def method_with_optional_arguments(arg1, arg2, arg3 = nil) + jsii_call_method("methodWithOptionalArguments", [arg1, arg2, arg3]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/second_level_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::SecondLevelStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.SecondLevelStruct", self) + + # @param deeper_required_prop [String] It's long and required. + # @param deeper_optional_prop [String, nil] It's long, but you'll almost never pass it. + def initialize(deeper_required_prop:, deeper_optional_prop: nil) + @deeper_required_prop = deeper_required_prop + @deeper_optional_prop = deeper_optional_prop + end + + # It's long and required. + # + # @return [String] + attr_reader :deeper_required_prop + # It's long, but you'll almost never pass it. + # + # @return [String, nil] + attr_reader :deeper_optional_prop + + def self.jsii_properties + { + :deeper_required_prop => "deeperRequiredProp", + :deeper_optional_prop => "deeperOptionalProp", + } + end + + def to_jsii + result = {} + result.merge!({ + "deeperRequiredProp" => @deeper_required_prop, + "deeperOptionalProp" => @deeper_optional_prop, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/single_instance_two_types.rb 1`] = ` +require 'jsii' + +# Test that a single instance can be returned under two different FQNs. +# +# JSII clients can instantiate 2 different strongly-typed wrappers for the same +# object. Unfortunately, this will break object equality, but if we didn't do +# this it would break runtime type checks in the JVM or CLR. +class JsiiCalc::SingleInstanceTwoTypes < Jsii::Object + self.jsii_fqn = "jsii-calc.SingleInstanceTwoTypes" + Jsii::Object.register_jsii_fqn("jsii-calc.SingleInstanceTwoTypes", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :interface1 => { kind: :method, name: "interface1", is_optional: false }, + :interface2 => { kind: :method, name: "interface2", is_optional: false }, + } + end + + # @return [JsiiCalc::InbetweenClass] + def interface1() + jsii_call_method("interface1", []) + end + + # @return [JsiiCalc::IPublicInterface] + def interface2() + jsii_call_method("interface2", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/singleton_int.rb 1`] = ` +require 'jsii' + +# Verifies that singleton enums are handled correctly. +# +# https://github.com/aws/jsii/issues/231 +class JsiiCalc::SingletonInt < Jsii::Object + self.jsii_fqn = "jsii-calc.SingletonInt" + Jsii::Object.register_jsii_fqn("jsii-calc.SingletonInt", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.SingletonInt does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + :is_singleton_int => { kind: :method, name: "isSingletonInt", is_optional: false }, + } + end + + # @param value [Numeric] + # @return [Boolean] + def is_singleton_int(value) + jsii_call_method("isSingletonInt", [value]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/singleton_int_enum.rb 1`] = ` +require 'jsii' + +# A singleton integer. +module JsiiCalc::SingletonIntEnum + # Elite! + # + # @note Default: + # @deprecated + SINGLETON_INT = Jsii::Enum.new("jsii-calc.SingletonIntEnum", "SINGLETON_INT") +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/singleton_string.rb 1`] = ` +require 'jsii' + +# Verifies that singleton enums are handled correctly. +# +# https://github.com/aws/jsii/issues/231 +class JsiiCalc::SingletonString < Jsii::Object + self.jsii_fqn = "jsii-calc.SingletonString" + Jsii::Object.register_jsii_fqn("jsii-calc.SingletonString", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.SingletonString does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + :is_singleton_string => { kind: :method, name: "isSingletonString", is_optional: false }, + } + end + + # @param value [String] + # @return [Boolean] + def is_singleton_string(value) + jsii_call_method("isSingletonString", [value]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/singleton_string_enum.rb 1`] = ` +require 'jsii' + +# A singleton string. +module JsiiCalc::SingletonStringEnum + # 1337. + # + # @note Default: + # @deprecated + SINGLETON_STRING = Jsii::Enum.new("jsii-calc.SingletonStringEnum", "SINGLETON_STRING") +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/smelly_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::SmellyStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.SmellyStruct", self) + + # @param property [String] + # @param yet_anoter_one [Boolean] + def initialize(property:, yet_anoter_one:) + @property = property + @yet_anoter_one = yet_anoter_one + end + + # @return [String] + attr_reader :property + # @return [Boolean] + attr_reader :yet_anoter_one + + def self.jsii_properties + { + :property => "property", + :yet_anoter_one => "yetAnoterOne", + } + end + + def to_jsii + result = {} + result.merge!({ + "property" => @property, + "yetAnoterOne" => @yet_anoter_one, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/some_containing_class.rb 1`] = ` +require 'jsii' + +# Check that we can have 2 interfaces in a class namespace inherit from each other. +# +# This gave trouble in Python. +# +# Also purposely have the types in the wrong order in the source code to catch potential ordering mistakes. +class JsiiCalc::SomeContainingClass < Jsii::Object + self.jsii_fqn = "jsii-calc.SomeContainingClass" + Jsii::Object.register_jsii_fqn("jsii-calc.SomeContainingClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :say_hello => { kind: :method, name: "sayHello", is_optional: false }, + } + end + + # @return [String] + def say_hello() + jsii_call_method("sayHello", []) + end + +end + +class JsiiCalc::SomeContainingClass::ParentStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.SomeContainingClass.ParentStruct", self) + + # @param field1 [String] + def initialize(field1:) + @field1 = field1 + end + + # @return [String] + attr_reader :field1 + + def self.jsii_properties + { + :field1 => "field1", + } + end + + def to_jsii + result = {} + result.merge!({ + "field1" => @field1, + }) + result.compact + end +end + +class JsiiCalc::SomeContainingClass::ChildStruct < ::JsiiCalc::SomeContainingClass::ParentStruct + Jsii::Object.register_jsii_fqn("jsii-calc.SomeContainingClass.ChildStruct", self) + + # @param field1 [String] + # @param field2 [String] + def initialize(field1:, field2:) + @field1 = field1 + @field2 = field2 + end + + # @return [String] + attr_reader :field1 + # @return [String] + attr_reader :field2 + + def self.jsii_properties + { + :field1 => "field1", + :field2 => "field2", + } + end + + def to_jsii + result = {} + result.merge!(super) + result.merge!({ + "field1" => @field1, + "field2" => @field2, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/some_type_jsii976.rb 1`] = ` +require 'jsii' + +class JsiiCalc::SomeTypeJsii976 < Jsii::Object + self.jsii_fqn = "jsii-calc.SomeTypeJsii976" + Jsii::Object.register_jsii_fqn("jsii-calc.SomeTypeJsii976", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + + # @return [Object] + def self.return_anonymous() + Jsii::Kernel.instance.call_static("jsii-calc.SomeTypeJsii976", "returnAnonymous", []) + end + + # @return [JsiiCalc::IReturnJsii976] + def self.return_return() + Jsii::Kernel.instance.call_static("jsii-calc.SomeTypeJsii976", "returnReturn", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/stable_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::StableClass < Jsii::Object + self.jsii_fqn = "jsii-calc.StableClass" + Jsii::Object.register_jsii_fqn("jsii-calc.StableClass", self) + + # @param readonly_string [String] + # @param mutable_number [Numeric, nil] + def initialize(readonly_string, mutable_number = nil) + Jsii::Object.instance_method(:initialize).bind(self).call(readonly_string, mutable_number) + end + + def self.jsii_overridable_methods + { + :readonly_property => { kind: :property, name: "readonlyProperty", is_optional: false }, + :mutable_property => { kind: :property, name: "mutableProperty", is_optional: true }, + :method => { kind: :method, name: "method", is_optional: false }, + } + end + + # @return [String] + def readonly_property() + jsii_get_property("readonlyProperty") + end + + # @return [Numeric, nil] + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) + jsii_set_property("mutableProperty", value) + end + + # @return [void] + def method() + jsii_call_method("method", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/stable_enum.rb 1`] = ` +require 'jsii' + +module JsiiCalc::StableEnum + # @note Default: + # @deprecated + OPTION_A = Jsii::Enum.new("jsii-calc.StableEnum", "OPTION_A") + # @note Default: + # @deprecated + OPTION_B = Jsii::Enum.new("jsii-calc.StableEnum", "OPTION_B") +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/stable_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::StableStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.StableStruct", self) + + # @param readonly_property [String] + def initialize(readonly_property:) + @readonly_property = readonly_property + end + + # @return [String] + attr_reader :readonly_property + + def self.jsii_properties + { + :readonly_property => "readonlyProperty", + } + end + + def to_jsii + result = {} + result.merge!({ + "readonlyProperty" => @readonly_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/static_context.rb 1`] = ` +require 'jsii' + +# This is used to validate the ability to use \`this\` from within a static context. +# +# https://github.com/awslabs/aws-cdk/issues/2304 +class JsiiCalc::StaticContext < Jsii::Object + self.jsii_fqn = "jsii-calc.StaticContext" + Jsii::Object.register_jsii_fqn("jsii-calc.StaticContext", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.StaticContext does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @return [Boolean] + def self.can_access_static_context() + Jsii::Kernel.instance.call_static("jsii-calc.StaticContext", "canAccessStaticContext", []) + end + + # @return [Boolean] + def self.static_variable() + Jsii::Kernel.instance.get_static("jsii-calc.StaticContext", "staticVariable") + end + + def self.static_variable=(value) + Jsii::Kernel.instance.set_static("jsii-calc.StaticContext", "staticVariable", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/static_hello_child.rb 1`] = ` +require 'jsii' + +class JsiiCalc::StaticHelloChild < ::JsiiCalc::StaticHelloParent + self.jsii_fqn = "jsii-calc.StaticHelloChild" + Jsii::Object.register_jsii_fqn("jsii-calc.StaticHelloChild", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.StaticHelloChild does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @return [void] + def self.method() + Jsii::Kernel.instance.call_static("jsii-calc.StaticHelloChild", "method", []) + end + + # @return [Numeric] + def self.property() + Jsii::Kernel.instance.get_static("jsii-calc.StaticHelloChild", "property") + end + + # @return [Numeric] + def self.PROPERTY() + Jsii::Kernel.instance.get_static("jsii-calc.StaticHelloChild", "PROPERTY") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/static_hello_parent.rb 1`] = ` +require 'jsii' + +# Static methods that override parent class are technically overrides (the inheritance of statics is part of the ES6 specification), but certain other languages such as Java do not carry statics in the inheritance chain at all, so they cannot be overridden, only hidden. +# +# The difference is fairly minor (for typical use-cases, the end result is the +# same), however this has implications on what the generated code should look +# like. +class JsiiCalc::StaticHelloParent < Jsii::Object + self.jsii_fqn = "jsii-calc.StaticHelloParent" + Jsii::Object.register_jsii_fqn("jsii-calc.StaticHelloParent", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + + # @return [void] + def self.method() + Jsii::Kernel.instance.call_static("jsii-calc.StaticHelloParent", "method", []) + end + + # @return [Numeric] + def self.property() + Jsii::Kernel.instance.get_static("jsii-calc.StaticHelloParent", "property") + end + + # @return [Numeric] + def self.PROPERTY() + Jsii::Kernel.instance.get_static("jsii-calc.StaticHelloParent", "PROPERTY") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/statics.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Statics < Jsii::Object + self.jsii_fqn = "jsii-calc.Statics" + Jsii::Object.register_jsii_fqn("jsii-calc.Statics", self) + + # @param value [String] + def initialize(value) + Jsii::Object.instance_method(:initialize).bind(self).call(value) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :just_method => { kind: :method, name: "justMethod", is_optional: false }, + } + end + + # Jsdocs for static method. + # + # @param name [String] The name of the person to say hello to. + # @return [String] + def self.static_method(name) + Jsii::Kernel.instance.call_static("jsii-calc.Statics", "staticMethod", [name]) + end + + # Constants may also use all-caps. + # + # @return [Numeric] + def self.BAR() + Jsii::Kernel.instance.get_static("jsii-calc.Statics", "BAR") + end + + # @return [JsiiCalc::DoubleTrouble] + def self.CONST_OBJ() + Jsii::Kernel.instance.get_static("jsii-calc.Statics", "ConstObj") + end + + # Jsdocs for static property. + # + # @return [String] + def self.FOO() + Jsii::Kernel.instance.get_static("jsii-calc.Statics", "Foo") + end + + # Constants can also use camelCase. + # + # @return [Hash{String => String}] + def self.ZOO_BAR() + Jsii::Kernel.instance.get_static("jsii-calc.Statics", "zooBar") + end + + # Jsdocs for static getter. + # + # Jsdocs for static setter. + # + # @return [JsiiCalc::Statics] + def self.instance() + Jsii::Kernel.instance.get_static("jsii-calc.Statics", "instance") + end + + def self.instance=(value) + Jsii::Kernel.instance.set_static("jsii-calc.Statics", "instance", value) + end + + # @return [Numeric] + def self.non_const_static() + Jsii::Kernel.instance.get_static("jsii-calc.Statics", "nonConstStatic") + end + + def self.non_const_static=(value) + Jsii::Kernel.instance.set_static("jsii-calc.Statics", "nonConstStatic", value) + end + + # @return [String] + def value() + jsii_get_property("value") + end + + # @return [String] + def just_method() + jsii_call_method("justMethod", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/string_enum.rb 1`] = ` +require 'jsii' + +module JsiiCalc::StringEnum + # @note Default: + # @deprecated + A = Jsii::Enum.new("jsii-calc.StringEnum", "A") + # @note Default: + # @deprecated + B = Jsii::Enum.new("jsii-calc.StringEnum", "B") + # @note Default: + # @deprecated + C = Jsii::Enum.new("jsii-calc.StringEnum", "C") +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/stringable.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Stringable < Jsii::Object + include ::JsiiCalc::IStringable + self.jsii_fqn = "jsii-calc.Stringable" + Jsii::Object.register_jsii_fqn("jsii-calc.Stringable", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :describe => { kind: :method, name: "describe", is_optional: false }, + :native_to_string => { kind: :method, name: "nativeToString", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + } + end + + # @return [JsiiCalc::IStringable] + def self.make_anonymous_stringable() + Jsii::Kernel.instance.call_static("jsii-calc.Stringable", "makeAnonymousStringable", []) + end + + # @return [JsiiCalc::IStringable] + def self.make_private_stringable() + Jsii::Kernel.instance.call_static("jsii-calc.Stringable", "makePrivateStringable", []) + end + + # @return [JsiiCalc::IStringable] + def self.make_public_stringable() + Jsii::Kernel.instance.call_static("jsii-calc.Stringable", "makePublicStringable", []) + end + + # @return [String] + def describe() + jsii_call_method("describe", []) + end + + # @return [String] + def native_to_string() + jsii_call_method("nativeToString", []) + end + + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/strip_internal.rb 1`] = ` +require 'jsii' + +class JsiiCalc::StripInternal < Jsii::Object + self.jsii_fqn = "jsii-calc.StripInternal" + Jsii::Object.register_jsii_fqn("jsii-calc.StripInternal", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :you_see_me => { kind: :property, name: "youSeeMe", is_optional: false }, + } + end + + # @return [String] + def you_see_me() + jsii_get_property("youSeeMe") + end + + def you_see_me=(value) + jsii_set_property("youSeeMe", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_a.rb 1`] = ` +require 'jsii' + +# We can serialize and deserialize structs without silently ignoring optional fields. +class JsiiCalc::StructA < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.StructA", self) + + # @param required_string [String] + # @param optional_number [Numeric, nil] + # @param optional_string [String, nil] + def initialize(required_string:, optional_number: nil, optional_string: nil) + @required_string = required_string + @optional_number = optional_number + @optional_string = optional_string + end + + # @return [String] + attr_reader :required_string + # @return [Numeric, nil] + attr_reader :optional_number + # @return [String, nil] + attr_reader :optional_string + + def self.jsii_properties + { + :required_string => "requiredString", + :optional_number => "optionalNumber", + :optional_string => "optionalString", + } + end + + def to_jsii + result = {} + result.merge!({ + "requiredString" => @required_string, + "optionalNumber" => @optional_number, + "optionalString" => @optional_string, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_b.rb 1`] = ` +require 'jsii' + +# This intentionally overlaps with StructA (where only requiredString is provided) to test htat the kernel properly disambiguates those. +class JsiiCalc::StructB < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.StructB", self) + + # @param required_string [String] + # @param optional_boolean [Boolean, nil] + # @param optional_struct_a [JsiiCalc::StructA, nil] + def initialize(required_string:, optional_boolean: nil, optional_struct_a: nil) + @required_string = required_string + @optional_boolean = optional_boolean + @optional_struct_a = optional_struct_a.is_a?(Hash) ? ::JsiiCalc::StructA.new(**optional_struct_a.transform_keys(&:to_sym)) : optional_struct_a + end + + # @return [String] + attr_reader :required_string + # @return [Boolean, nil] + attr_reader :optional_boolean + # @return [JsiiCalc::StructA, nil] + attr_reader :optional_struct_a + + def self.jsii_properties + { + :required_string => "requiredString", + :optional_boolean => "optionalBoolean", + :optional_struct_a => "optionalStructA", + } + end + + def to_jsii + result = {} + result.merge!({ + "requiredString" => @required_string, + "optionalBoolean" => @optional_boolean, + "optionalStructA" => @optional_struct_a, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_parameter_type.rb 1`] = ` +require 'jsii' + +# Verifies that, in languages that do keyword lifting (e.g: Python), having a struct member with the same name as a positional parameter results in the correct code being emitted. +# +# See: https://github.com/aws/aws-cdk/issues/4302 +class JsiiCalc::StructParameterType < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.StructParameterType", self) + + # @param scope [String] + # @param props [Boolean, nil] + def initialize(scope:, props: nil) + @scope = scope + @props = props + end + + # @return [String] + attr_reader :scope + # @return [Boolean, nil] + attr_reader :props + + def self.jsii_properties + { + :scope => "scope", + :props => "props", + } + end + + def to_jsii + result = {} + result.merge!({ + "scope" => @scope, + "props" => @props, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_passing.rb 1`] = ` +require 'jsii' + +# Just because we can. +class JsiiCalc::StructPassing < Jsii::Object + self.jsii_fqn = "jsii-calc.StructPassing" + Jsii::Object.register_jsii_fqn("jsii-calc.StructPassing", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + + # @param _positional [Numeric] + # @param inputs [Array] + # @return [Numeric] + def self.how_many_var_args_did_i_pass(_positional, *inputs) + inputs.map! { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::TopLevelStruct.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } + Jsii::Kernel.instance.call_static("jsii-calc.StructPassing", "howManyVarArgsDidIPass", [_positional, *inputs]) + end + + # @param _positional [Numeric] + # @param input [JsiiCalc::TopLevelStruct] + # @return [JsiiCalc::TopLevelStruct] + def self.round_trip(_positional, input) + input = input.is_a?(Hash) ? ::JsiiCalc::TopLevelStruct.new(**input.transform_keys(&:to_sym)) : input + Jsii::Kernel.instance.call_static("jsii-calc.StructPassing", "roundTrip", [_positional, input]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_union_consumer.rb 1`] = ` +require 'jsii' + +class JsiiCalc::StructUnionConsumer < Jsii::Object + self.jsii_fqn = "jsii-calc.StructUnionConsumer" + Jsii::Object.register_jsii_fqn("jsii-calc.StructUnionConsumer", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.StructUnionConsumer does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @param struct [JsiiCalc::StructA, JsiiCalc::StructB] + # @return [Boolean] + def self.is_struct_a(struct) + Jsii::Kernel.instance.call_static("jsii-calc.StructUnionConsumer", "isStructA", [struct]) + end + + # @param struct [JsiiCalc::StructA, JsiiCalc::StructB] + # @return [Boolean] + def self.is_struct_b(struct) + Jsii::Kernel.instance.call_static("jsii-calc.StructUnionConsumer", "isStructB", [struct]) + end + + # @param which [String] + # @return [JsiiCalc::StructA, JsiiCalc::StructB] + def self.provide_struct(which) + Jsii::Kernel.instance.call_static("jsii-calc.StructUnionConsumer", "provideStruct", [which]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_with_collection_of_unionts.rb 1`] = ` +require 'jsii' + +class JsiiCalc::StructWithCollectionOfUnionts < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.StructWithCollectionOfUnionts", self) + + # @param union_property [Array JsiiCalc::StructA, JsiiCalc::StructB}>] + def initialize(union_property:) + @union_property = union_property + end + + # @return [Array JsiiCalc::StructA, JsiiCalc::StructB}>] + attr_reader :union_property + + def self.jsii_properties + { + :union_property => "unionProperty", + } + end + + def to_jsii + result = {} + result.merge!({ + "unionProperty" => @union_property, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_with_enum.rb 1`] = ` +require 'jsii' + +class JsiiCalc::StructWithEnum < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.StructWithEnum", self) + + # @param foo [JsiiCalc::StringEnum] An enum value. + # @param bar [JsiiCalc::AllTypesEnum, nil] Optional enum value (of type integer). + def initialize(foo:, bar: nil) + @foo = foo + @bar = bar + end + + # An enum value. + # + # @return [JsiiCalc::StringEnum] + attr_reader :foo + # Optional enum value (of type integer). + # + # @return [JsiiCalc::AllTypesEnum, nil] + # @note Default: AllTypesEnum.YOUR_ENUM_VALUE + attr_reader :bar + + def self.jsii_properties + { + :foo => "foo", + :bar => "bar", + } + end + + def to_jsii + result = {} + result.merge!({ + "foo" => @foo, + "bar" => @bar, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_with_java_reserved_words.rb 1`] = ` +require 'jsii' + +class JsiiCalc::StructWithJavaReservedWords < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.StructWithJavaReservedWords", self) + + # @param default [String] + # @param assert [String, nil] + # @param result [String, nil] + # @param that [String, nil] + def initialize(default:, assert: nil, result: nil, that: nil) + @default = default + @assert = assert + @result = result + @that = that + end + + # @return [String] + attr_reader :default + # @return [String, nil] + attr_reader :assert + # @return [String, nil] + attr_reader :result + # @return [String, nil] + attr_reader :that + + def self.jsii_properties + { + :default => "default", + :assert => "assert", + :result => "result", + :that => "that", + } + end + + def to_jsii + result = {} + result.merge!({ + "default" => @default, + "assert" => @assert, + "result" => @result, + "that" => @that, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/_readme.rb 1`] = ` +# # Read you, read me +# +# This is the readme of the \`jsii-calc.submodule\` module. +module JsiiCalc::Submodule; end + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/back_references/my_class_reference.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Submodule::BackReferences::MyClassReference < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.back_references.MyClassReference", self) + + # @param reference [JsiiCalc::Submodule::MyClass] + def initialize(reference:) + @reference = reference + end + + # @return [JsiiCalc::Submodule::MyClass] + attr_reader :reference + + def self.jsii_properties + { + :reference => "reference", + } + end + + def to_jsii + result = {} + result.merge!({ + "reference" => @reference, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/child/awesomeness.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Submodule::Child::Awesomeness + # It was awesome! + # + # @note Default: + # @deprecated + AWESOME = Jsii::Enum.new("jsii-calc.submodule.child.Awesomeness", "AWESOME") +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/child/goodness.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Submodule::Child::Goodness + # It's pretty good. + # + # @note Default: + # @deprecated + PRETTY_GOOD = Jsii::Enum.new("jsii-calc.submodule.child.Goodness", "PRETTY_GOOD") + # It's really good. + # + # @note Default: + # @deprecated + REALLY_GOOD = Jsii::Enum.new("jsii-calc.submodule.child.Goodness", "REALLY_GOOD") + # It's amazingly good. + # + # @note Default: + # @deprecated + AMAZINGLY_GOOD = Jsii::Enum.new("jsii-calc.submodule.child.Goodness", "AMAZINGLY_GOOD") +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/child/inner_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Submodule::Child::InnerClass < Jsii::Object + self.jsii_fqn = "jsii-calc.submodule.child.InnerClass" + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.child.InnerClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + } + end + + # @return [JsiiCalc::Submodule::Child::SomeStruct] + def self.STATIC_PROP() + Jsii::Kernel.instance.get_static("jsii-calc.submodule.child.InnerClass", "staticProp") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/child/kwargs_props.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Submodule::Child::KwargsProps < ::JsiiCalc::Submodule::Child::SomeStruct + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.child.KwargsProps", self) + + # @param prop [JsiiCalc::Submodule::Child::SomeEnum] + # @param extra [String, nil] + def initialize(prop:, extra: nil) + @prop = prop + @extra = extra + end + + # @return [JsiiCalc::Submodule::Child::SomeEnum] + attr_reader :prop + # @return [String, nil] + attr_reader :extra + + def self.jsii_properties + { + :prop => "prop", + :extra => "extra", + } + end + + def to_jsii + result = {} + result.merge!(super) + result.merge!({ + "prop" => @prop, + "extra" => @extra, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/child/outer_class.rb 1`] = ` +require 'jsii' + +# Checks that classes can self-reference during initialization. +# +# @see https://github.com/aws/jsii/pull/1706 +class JsiiCalc::Submodule::Child::OuterClass < Jsii::Object + self.jsii_fqn = "jsii-calc.submodule.child.OuterClass" + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.child.OuterClass", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :inner_class => { kind: :property, name: "innerClass", is_optional: false }, + } + end + + # @return [JsiiCalc::Submodule::Child::InnerClass] + def inner_class() + jsii_get_property("innerClass") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/child/some_enum.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Submodule::Child::SomeEnum + # @note Default: + # @deprecated + SOME = Jsii::Enum.new("jsii-calc.submodule.child.SomeEnum", "SOME") +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/child/some_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Submodule::Child::SomeStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.child.SomeStruct", self) + + # @param prop [JsiiCalc::Submodule::Child::SomeEnum] + def initialize(prop:) + @prop = prop + end + + # @return [JsiiCalc::Submodule::Child::SomeEnum] + attr_reader :prop + + def self.jsii_properties + { + :prop => "prop", + } + end + + def to_jsii + result = {} + result.merge!({ + "prop" => @prop, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/child/structure.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Submodule::Child::Structure < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.child.Structure", self) + + # @param bool [Boolean] + def initialize(bool:) + @bool = bool + end + + # @return [Boolean] + attr_reader :bool + + def self.jsii_properties + { + :bool => "bool", + } + end + + def to_jsii + result = {} + result.merge!({ + "bool" => @bool, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/default.rb 1`] = ` +require 'jsii' + +# A struct named "Default". +# +# @see https://github.com/aws/jsii/issues/2637 +class JsiiCalc::Submodule::Default < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.Default", self) + + # @param foo [Numeric] + def initialize(foo:) + @foo = foo + end + + # @return [Numeric] + attr_reader :foo + + def self.jsii_properties + { + :foo => "foo", + } + end + + def to_jsii + result = {} + result.merge!({ + "foo" => @foo, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/isolated/_readme.rb 1`] = ` +# # Read you, read me +# +# This is the readme of the \`jsii-calc.submodule.isolated\` module. +module JsiiCalc::Submodule::Isolated; end + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/isolated/kwargs.rb 1`] = ` +require 'jsii' + +# Ensures imports are correctly registered for kwargs lifted properties from super-structs. +class JsiiCalc::Submodule::Isolated::Kwargs < Jsii::Object + self.jsii_fqn = "jsii-calc.submodule.isolated.Kwargs" + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.isolated.Kwargs", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.submodule.isolated.Kwargs does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @param props [JsiiCalc::Submodule::Child::KwargsProps, nil] + # @return [Boolean] + def self.method(props = nil) + props = props.is_a?(Hash) ? ::JsiiCalc::Submodule::Child::KwargsProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Kernel.instance.call_static("jsii-calc.submodule.isolated.Kwargs", "method", [props]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/my_class.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Submodule::MyClass < Jsii::Object + include ::JsiiCalc::Submodule::NestedSubmodule::DeeplyNested::INamespaced + self.jsii_fqn = "jsii-calc.submodule.MyClass" + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.MyClass", self) + + # @param props [JsiiCalc::Submodule::Child::SomeStruct] + def initialize(props) + props = props.is_a?(Hash) ? ::JsiiCalc::Submodule::Child::SomeStruct.new(**props.transform_keys(&:to_sym)) : props + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { + :awesomeness => { kind: :property, name: "awesomeness", is_optional: false }, + :defined_at => { kind: :property, name: "definedAt", is_optional: false }, + :goodness => { kind: :property, name: "goodness", is_optional: false }, + :props => { kind: :property, name: "props", is_optional: false }, + :all_types => { kind: :property, name: "allTypes", is_optional: true }, + :method_with_special_param => { kind: :method, name: "methodWithSpecialParam", is_optional: false }, + } + end + + # @return [JsiiCalc::Submodule::Child::Awesomeness] + def awesomeness() + jsii_get_property("awesomeness") + end + + # @return [String] + def defined_at() + jsii_get_property("definedAt") + end + + # @return [JsiiCalc::Submodule::Child::Goodness] + def goodness() + jsii_get_property("goodness") + end + + # @return [JsiiCalc::Submodule::Child::SomeStruct] + def props() + jsii_get_property("props") + end + + # @return [JsiiCalc::AllTypes, nil] + def all_types() + jsii_get_property("allTypes") + end + + def all_types=(value) + jsii_set_property("allTypes", value) + end + + # @param param [JsiiCalc::Submodule::Param::SpecialParameter] + # @return [String] + def method_with_special_param(param) + param = param.is_a?(Hash) ? ::JsiiCalc::Submodule::Param::SpecialParameter.new(**param.transform_keys(&:to_sym)) : param + jsii_call_method("methodWithSpecialParam", [param]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/nested_submodule/deeply_nested/i_namespaced.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Submodule::NestedSubmodule::DeeplyNested::INamespaced + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.nested_submodule.deeplyNested.INamespaced", self) + + # @return [String] + def defined_at() + jsii_get_property("definedAt") + end + + def self.jsii_overridable_methods + { + :defined_at => { kind: :property, name: "definedAt", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/nested_submodule/namespaced.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Submodule::NestedSubmodule::Namespaced < Jsii::Object + include ::JsiiCalc::Submodule::NestedSubmodule::DeeplyNested::INamespaced + self.jsii_fqn = "jsii-calc.submodule.nested_submodule.Namespaced" + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.nested_submodule.Namespaced", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.submodule.nested_submodule.Namespaced does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + :defined_at => { kind: :property, name: "definedAt", is_optional: false }, + :goodness => { kind: :property, name: "goodness", is_optional: false }, + } + end + + # @return [String] + def defined_at() + jsii_get_property("definedAt") + end + + # @return [JsiiCalc::Submodule::Child::Goodness] + def goodness() + jsii_get_property("goodness") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/param/special_parameter.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Submodule::Param::SpecialParameter < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.param.SpecialParameter", self) + + # @param value [String] + def initialize(value:) + @value = value + end + + # @return [String] + attr_reader :value + + def self.jsii_properties + { + :value => "value", + } + end + + def to_jsii + result = {} + result.merge!({ + "value" => @value, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/returnsparam/returns_special_parameter.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Submodule::Returnsparam::ReturnsSpecialParameter < Jsii::Object + self.jsii_fqn = "jsii-calc.submodule.returnsparam.ReturnsSpecialParameter" + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.returnsparam.ReturnsSpecialParameter", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :returns_special_param => { kind: :method, name: "returnsSpecialParam", is_optional: false }, + } + end + + # @return [JsiiCalc::Submodule::Param::SpecialParameter] + def returns_special_param() + jsii_call_method("returnsSpecialParam", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/sum.rb 1`] = ` +require 'jsii' + +# An operation that sums multiple values. +class JsiiCalc::Sum < ::JsiiCalc::Composition::CompositeOperation + self.jsii_fqn = "jsii-calc.Sum" + Jsii::Object.register_jsii_fqn("jsii-calc.Sum", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :expression => { kind: :property, name: "expression", is_optional: false }, + :decoration_postfixes => { kind: :property, name: "decorationPostfixes", is_optional: false }, + :decoration_prefixes => { kind: :property, name: "decorationPrefixes", is_optional: false }, + :string_style => { kind: :property, name: "stringStyle", is_optional: false }, + :parts => { kind: :property, name: "parts", is_optional: false }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + } + end + + # The value. + # + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # The expression that this operation consists of. + # + # Must be implemented by derived classes. + # + # @return [Scope::JsiiCalcLib::NumericValue] + def expression() + jsii_get_property("expression") + end + + # A set of postfixes to include in a decorated .toString(). + # + # @return [Array] + def decoration_postfixes() + jsii_get_property("decorationPostfixes") + end + + def decoration_postfixes=(value) + jsii_set_property("decorationPostfixes", value) + end + + # A set of prefixes to include in a decorated .toString(). + # + # @return [Array] + def decoration_prefixes() + jsii_get_property("decorationPrefixes") + end + + def decoration_prefixes=(value) + jsii_set_property("decorationPrefixes", value) + end + + # The .toString() style. + # + # @return [JsiiCalc::Composition::CompositeOperation::CompositionStringStyle] + def string_style() + jsii_get_property("stringStyle") + end + + def string_style=(value) + jsii_set_property("stringStyle", value) + end + + # The parts to sum. + # + # @return [Array] + def parts() + jsii_get_property("parts") + end + + def parts=(value) + jsii_set_property("parts", value) + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # String representation of the value. + # + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/supports_nice_java_builder.rb 1`] = ` +require 'jsii' + +class JsiiCalc::SupportsNiceJavaBuilder < ::JsiiCalc::SupportsNiceJavaBuilderWithRequiredProps + self.jsii_fqn = "jsii-calc.SupportsNiceJavaBuilder" + Jsii::Object.register_jsii_fqn("jsii-calc.SupportsNiceJavaBuilder", self) + + # @param id [Numeric] some identifier. + # @param default_bar [Numeric, nil] the default value of \`bar\`. + # @param props [JsiiCalc::SupportsNiceJavaBuilderProps, nil] some props once can provide. + # @param rest [Array] a variadic continuation. + def initialize(id, default_bar = nil, props = nil, *rest) + props = props.is_a?(Hash) ? ::JsiiCalc::SupportsNiceJavaBuilderProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Object.instance_method(:initialize).bind(self).call(id, default_bar, props, *rest) + end + + def self.jsii_overridable_methods + { + :bar => { kind: :property, name: "bar", is_optional: false }, + :id => { kind: :property, name: "id", is_optional: false }, + :prop_id => { kind: :property, name: "propId", is_optional: true }, + :rest => { kind: :property, name: "rest", is_optional: false }, + } + end + + # @return [Numeric] + def bar() + jsii_get_property("bar") + end + + # some identifier. + # + # @return [Numeric] + def id() + jsii_get_property("id") + end + + # @return [String, nil] + def prop_id() + jsii_get_property("propId") + end + + # @return [Array] + def rest() + jsii_get_property("rest") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/supports_nice_java_builder_props.rb 1`] = ` +require 'jsii' + +class JsiiCalc::SupportsNiceJavaBuilderProps < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.SupportsNiceJavaBuilderProps", self) + + # @param bar [Numeric] Some number, like 42. + # @param id [String, nil] An \`id\` field here is terrible API design, because the constructor of \`SupportsNiceJavaBuilder\` already has a parameter named \`id\`. + def initialize(bar:, id: nil) + @bar = bar + @id = id + end + + # Some number, like 42. + # + # @return [Numeric] + attr_reader :bar + # An \`id\` field here is terrible API design, because the constructor of \`SupportsNiceJavaBuilder\` already has a parameter named \`id\`. + # + # But here we are, doing it like we didn't care. + # + # @return [String, nil] + attr_reader :id + + def self.jsii_properties + { + :bar => "bar", + :id => "id", + } + end + + def to_jsii + result = {} + result.merge!({ + "bar" => @bar, + "id" => @id, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/supports_nice_java_builder_with_required_props.rb 1`] = ` +require 'jsii' + +# We can generate fancy builders in Java for classes which take a mix of positional & struct parameters. +class JsiiCalc::SupportsNiceJavaBuilderWithRequiredProps < Jsii::Object + self.jsii_fqn = "jsii-calc.SupportsNiceJavaBuilderWithRequiredProps" + Jsii::Object.register_jsii_fqn("jsii-calc.SupportsNiceJavaBuilderWithRequiredProps", self) + + # @param id [Numeric] some identifier of your choice. + # @param props [JsiiCalc::SupportsNiceJavaBuilderProps] some properties. + def initialize(id, props) + props = props.is_a?(Hash) ? ::JsiiCalc::SupportsNiceJavaBuilderProps.new(**props.transform_keys(&:to_sym)) : props + Jsii::Object.instance_method(:initialize).bind(self).call(id, props) + end + + def self.jsii_overridable_methods + { + :bar => { kind: :property, name: "bar", is_optional: false }, + :id => { kind: :property, name: "id", is_optional: false }, + :prop_id => { kind: :property, name: "propId", is_optional: true }, + } + end + + # @return [Numeric] + def bar() + jsii_get_property("bar") + end + + # some identifier of your choice. + # + # @return [Numeric] + def id() + jsii_get_property("id") + end + + # @return [String, nil] + def prop_id() + jsii_get_property("propId") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/sync_override_extra_args.rb 1`] = ` +require 'jsii' + +# Demonstrates that arguments passed by JS-side callers in excess of a method's declared signature are silently dropped at the language-runtime boundary. +# +# Calling a function with more arguments than declared is legal in JavaScript +# (the extras are simply ignored), and jsii cannot prevent packages from doing +# so. jsii must therefore accept these calls and forward only the declared +# arguments to the language runtime — refusing them would break otherwise-valid +# JS code as soon as the receiver happens to be implemented in another language. +# +# This pattern occurs in the wild when a JS caller (e.g. the CDK +# \`Lazy.any\` resolution path with \`IStableAnyProducer\`) invokes an override +# with more arguments than the interface declares. +# +# @see https://github.com/aws/jsii/pull/5126 +class JsiiCalc::SyncOverrideExtraArgs < Jsii::Object + self.jsii_fqn = "jsii-calc.SyncOverrideExtraArgs" + Jsii::Object.register_jsii_fqn("jsii-calc.SyncOverrideExtraArgs", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :call_produce_with_extra_arg => { kind: :method, name: "callProduceWithExtraArg", is_optional: false }, + :produce => { kind: :method, name: "produce", is_optional: false }, + } + end + + # Calls \`produce()\` with one extra argument that the spec does not declare, and returns whatever the override produced. + # + # The extra argument is expected + # to be silently dropped before it crosses the language boundary. + # + # @return [String] + def call_produce_with_extra_arg() + jsii_call_method("callProduceWithExtraArg", []) + end + + # Override this method. + # + # Declared with no parameters. + # + # @return [String] + def produce() + jsii_call_method("produce", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/sync_virtual_methods.rb 1`] = ` +require 'jsii' + +class JsiiCalc::SyncVirtualMethods < Jsii::Object + self.jsii_fqn = "jsii-calc.SyncVirtualMethods" + Jsii::Object.register_jsii_fqn("jsii-calc.SyncVirtualMethods", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :readonly_property => { kind: :property, name: "readonlyProperty", is_optional: false }, + :a => { kind: :property, name: "a", is_optional: false }, + :caller_is_property => { kind: :property, name: "callerIsProperty", is_optional: false }, + :other_property => { kind: :property, name: "otherProperty", is_optional: false }, + :the_property => { kind: :property, name: "theProperty", is_optional: false }, + :value_of_other_property => { kind: :property, name: "valueOfOtherProperty", is_optional: false }, + :caller_is_async => { kind: :method, name: "callerIsAsync", is_optional: false }, + :caller_is_method => { kind: :method, name: "callerIsMethod", is_optional: false }, + :modify_other_property => { kind: :method, name: "modifyOtherProperty", is_optional: false }, + :modify_value_of_the_property => { kind: :method, name: "modifyValueOfTheProperty", is_optional: false }, + :read_a => { kind: :method, name: "readA", is_optional: false }, + :retrieve_other_property => { kind: :method, name: "retrieveOtherProperty", is_optional: false }, + :retrieve_read_only_property => { kind: :method, name: "retrieveReadOnlyProperty", is_optional: false }, + :retrieve_value_of_the_property => { kind: :method, name: "retrieveValueOfTheProperty", is_optional: false }, + :virtual_method => { kind: :method, name: "virtualMethod", is_optional: false }, + :write_a => { kind: :method, name: "writeA", is_optional: false }, + } + end + + # @return [String] + def readonly_property() + jsii_get_property("readonlyProperty") + end + + # @return [Numeric] + def a() + jsii_get_property("a") + end + + def a=(value) + jsii_set_property("a", value) + end + + # @return [Numeric] + def caller_is_property() + jsii_get_property("callerIsProperty") + end + + def caller_is_property=(value) + jsii_set_property("callerIsProperty", value) + end + + # @return [String] + def other_property() + jsii_get_property("otherProperty") + end + + def other_property=(value) + jsii_set_property("otherProperty", value) + end + + # @return [String] + def the_property() + jsii_get_property("theProperty") + end + + def the_property=(value) + jsii_set_property("theProperty", value) + end + + # @return [String] + def value_of_other_property() + jsii_get_property("valueOfOtherProperty") + end + + def value_of_other_property=(value) + jsii_set_property("valueOfOtherProperty", value) + end + + # @return [Numeric] + def caller_is_async() + jsii_async_call_method("callerIsAsync", []) + end + + # @return [Numeric] + def caller_is_method() + jsii_call_method("callerIsMethod", []) + end + + # @param value [String] + # @return [void] + def modify_other_property(value) + jsii_call_method("modifyOtherProperty", [value]) + end + + # @param value [String] + # @return [void] + def modify_value_of_the_property(value) + jsii_call_method("modifyValueOfTheProperty", [value]) + end + + # @return [Numeric] + def read_a() + jsii_call_method("readA", []) + end + + # @return [String] + def retrieve_other_property() + jsii_call_method("retrieveOtherProperty", []) + end + + # @return [String] + def retrieve_read_only_property() + jsii_call_method("retrieveReadOnlyProperty", []) + end + + # @return [String] + def retrieve_value_of_the_property() + jsii_call_method("retrieveValueOfTheProperty", []) + end + + # @param n [Numeric] + # @return [Numeric] + def virtual_method(n) + jsii_call_method("virtualMethod", [n]) + end + + # @param value [Numeric] + # @return [void] + def write_a(value) + jsii_call_method("writeA", [value]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/test_struct_with_enum.rb 1`] = ` +require 'jsii' + +class JsiiCalc::TestStructWithEnum < Jsii::Object + self.jsii_fqn = "jsii-calc.TestStructWithEnum" + Jsii::Object.register_jsii_fqn("jsii-calc.TestStructWithEnum", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :struct_with_foo => { kind: :property, name: "structWithFoo", is_optional: false }, + :struct_with_foo_bar => { kind: :property, name: "structWithFooBar", is_optional: false }, + :is_string_enum_a => { kind: :method, name: "isStringEnumA", is_optional: false }, + :is_string_enum_b => { kind: :method, name: "isStringEnumB", is_optional: false }, + } + end + + # Returns \`foo: StringEnum.A\`. + # + # @return [JsiiCalc::StructWithEnum] + def struct_with_foo() + jsii_get_property("structWithFoo") + end + + # Returns \`foo: StringEnum.C\` and \`bar: AllTypesEnum.MY_ENUM_VALUE\`. + # + # @return [JsiiCalc::StructWithEnum] + def struct_with_foo_bar() + jsii_get_property("structWithFooBar") + end + + # Returns true if \`foo\` is \`StringEnum.A\`. + # + # @param input [JsiiCalc::StructWithEnum] + # @return [Boolean] + def is_string_enum_a(input) + input = input.is_a?(Hash) ? ::JsiiCalc::StructWithEnum.new(**input.transform_keys(&:to_sym)) : input + jsii_call_method("isStringEnumA", [input]) + end + + # Returns true if \`foo\` is \`StringEnum.B\` and \`bar\` is \`AllTypesEnum.THIS_IS_GREAT\`. + # + # @param input [JsiiCalc::StructWithEnum] + # @return [Boolean] + def is_string_enum_b(input) + input = input.is_a?(Hash) ? ::JsiiCalc::StructWithEnum.new(**input.transform_keys(&:to_sym)) : input + jsii_call_method("isStringEnumB", [input]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/thrower.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Thrower < Jsii::Object + self.jsii_fqn = "jsii-calc.Thrower" + Jsii::Object.register_jsii_fqn("jsii-calc.Thrower", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :throw_error => { kind: :method, name: "throwError", is_optional: false }, + } + end + + # @return [void] + def throw_error() + jsii_call_method("throwError", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/top_level_struct.rb 1`] = ` +require 'jsii' + +class JsiiCalc::TopLevelStruct < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.TopLevelStruct", self) + + # @param required [String] This is a required field. + # @param second_level [Numeric, JsiiCalc::SecondLevelStruct] A union to really stress test our serialization. + # @param optional [String, nil] You don't have to pass this. + def initialize(required:, second_level:, optional: nil) + @required = required + @second_level = second_level.is_a?(Hash) ? ::JsiiCalc::SecondLevelStruct.new(**second_level.transform_keys(&:to_sym)) : second_level + @optional = optional + end + + # This is a required field. + # + # @return [String] + attr_reader :required + # A union to really stress test our serialization. + # + # @return [Numeric, JsiiCalc::SecondLevelStruct] + attr_reader :second_level + # You don't have to pass this. + # + # @return [String, nil] + attr_reader :optional + + def self.jsii_properties + { + :required => "required", + :second_level => "secondLevel", + :optional => "optional", + } + end + + def to_jsii + result = {} + result.merge!({ + "required" => @required, + "secondLevel" => @second_level, + "optional" => @optional, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/two_methods_with_similar_capitalization.rb 1`] = ` +require 'jsii' + +# In TypeScript it is possible to have two methods with the same name but different capitalization. +# +# @see https://github.com/aws/jsii/issues/2508 +class JsiiCalc::TwoMethodsWithSimilarCapitalization < Jsii::Object + self.jsii_fqn = "jsii-calc.TwoMethodsWithSimilarCapitalization" + Jsii::Object.register_jsii_fqn("jsii-calc.TwoMethodsWithSimilarCapitalization", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :foo_bar => { kind: :property, name: "fooBar", is_optional: false }, + :to_iso_string => { kind: :method, name: "toIsoString", is_optional: false }, + :to_is_o_string => { kind: :method, name: "toIsOString", is_optional: false }, + } + end + + # @return [Numeric] + def foo_bar() + jsii_get_property("fooBar") + end + + # @return [String] + def to_iso_string() + jsii_call_method("toIsoString", []) + end + + # @return [String] + # @deprecated python requires that all alternatives are deprecated + def to_is_o_string() + jsii_call_method("toIsOString", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/umask_check.rb 1`] = ` +require 'jsii' + +# Checks the current file permissions are cool (no funky UMASK down-scoping happened). +# +# @see https://github.com/aws/jsii/issues/1765 +class JsiiCalc::UmaskCheck < Jsii::Object + self.jsii_fqn = "jsii-calc.UmaskCheck" + Jsii::Object.register_jsii_fqn("jsii-calc.UmaskCheck", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.UmaskCheck does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # This should return 0o644 (-rw-r--r--). + # + # @return [Numeric] + def self.mode() + Jsii::Kernel.instance.call_static("jsii-calc.UmaskCheck", "mode", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/unary_operation.rb 1`] = ` +require 'jsii' + +# An operation on a single operand. +class JsiiCalc::UnaryOperation < ::Scope::JsiiCalcLib::Operation + self.jsii_fqn = "jsii-calc.UnaryOperation" + Jsii::Object.register_jsii_fqn("jsii-calc.UnaryOperation", self) + + # @param operand [Scope::JsiiCalcLib::NumericValue] + def initialize(operand) + Jsii::Object.instance_method(:initialize).bind(self).call(operand) + end + + def self.jsii_overridable_methods + { + :value => { kind: :property, name: "value", is_optional: false }, + :operand => { kind: :property, name: "operand", is_optional: false }, + :type_name => { kind: :method, name: "typeName", is_optional: false }, + :to_string => { kind: :method, name: "toString", is_optional: false }, + } + end + + # The value. + # + # @return [Numeric] + def value() + jsii_get_property("value") + end + + # @return [Scope::JsiiCalcLib::NumericValue] + def operand() + jsii_get_property("operand") + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() + jsii_call_method("typeName", []) + end + + # String representation of the value. + # + # @return [String] + def to_string() + jsii_call_method("toString", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/union/consumes_union.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Union::ConsumesUnion < Jsii::Object + self.jsii_fqn = "jsii-calc.union.ConsumesUnion" + Jsii::Object.register_jsii_fqn("jsii-calc.union.ConsumesUnion", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.union.ConsumesUnion does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + } + end + + # @param param [Scope::JsiiCalcLib::IFriendly, JsiiCalc::Union::IResolvable, JsiiCalc::Union::Resolvable] + # @return [void] + def self.union_type(param) + Jsii::Kernel.instance.call_static("jsii-calc.union.ConsumesUnion", "unionType", [param]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/union/i_resolvable.rb 1`] = ` +require 'jsii' + +module JsiiCalc::Union::IResolvable + Jsii::Object.register_jsii_fqn("jsii-calc.union.IResolvable", self) + + # @return [Object] + def resolve() + jsii_call_method("resolve", []) + end + + def self.jsii_overridable_methods + { + :resolve => { kind: :method, name: "resolve", is_optional: false }, + } + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/union/resolvable.rb 1`] = ` +require 'jsii' + +class JsiiCalc::Union::Resolvable < Jsii::Object + include ::JsiiCalc::Union::IResolvable + self.jsii_fqn = "jsii-calc.union.Resolvable" + Jsii::Object.register_jsii_fqn("jsii-calc.union.Resolvable", self) + + def initialize(*args) + raise NoMethodError, "jsii-calc.union.Resolvable does not have a visible constructor; use the provided factory methods" + end + + def self.jsii_overridable_methods + { + :resolve => { kind: :method, name: "resolve", is_optional: false }, + } + end + + # @return [Object] + def resolve() + jsii_call_method("resolve", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/union_properties.rb 1`] = ` +require 'jsii' + +class JsiiCalc::UnionProperties < Jsii::Struct + Jsii::Object.register_jsii_fqn("jsii-calc.UnionProperties", self) + + # @param bar [String, Numeric, JsiiCalc::AllTypes] + # @param foo [String, Numeric, nil] + def initialize(bar:, foo: nil) + @bar = bar + @foo = foo + end + + # @return [String, Numeric, JsiiCalc::AllTypes] + attr_reader :bar + # @return [String, Numeric, nil] + attr_reader :foo + + def self.jsii_properties + { + :bar => "bar", + :foo => "foo", + } + end + + def to_jsii + result = {} + result.merge!({ + "bar" => @bar, + "foo" => @foo, + }) + result.compact + end +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/upcasing_reflectable.rb 1`] = ` +require 'jsii' + +# Ensures submodule-imported types from dependencies can be used correctly. +class JsiiCalc::UpcasingReflectable < Jsii::Object + include ::Scope::JsiiCalcLib::Submodule::IReflectable + self.jsii_fqn = "jsii-calc.UpcasingReflectable" + Jsii::Object.register_jsii_fqn("jsii-calc.UpcasingReflectable", self) + + # @param delegate [Hash{String => Object}] + def initialize(delegate) + Jsii::Object.instance_method(:initialize).bind(self).call(delegate) + end + + def self.jsii_overridable_methods + { + :entries => { kind: :property, name: "entries", is_optional: false }, + } + end + + # @return [Scope::JsiiCalcLib::Submodule::Reflector] + def self.REFLECTOR() + Jsii::Kernel.instance.get_static("jsii-calc.UpcasingReflectable", "reflector") + end + + # @return [Array] + def entries() + jsii_get_property("entries") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/use_bundled_dependency.rb 1`] = ` +require 'jsii' + +class JsiiCalc::UseBundledDependency < Jsii::Object + self.jsii_fqn = "jsii-calc.UseBundledDependency" + Jsii::Object.register_jsii_fqn("jsii-calc.UseBundledDependency", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :value => { kind: :method, name: "value", is_optional: false }, + } + end + + # @return [Object] + def value() + jsii_call_method("value", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/use_calc_base.rb 1`] = ` +require 'jsii' + +# Depend on a type from jsii-calc-base as a test for awslabs/jsii#128. +class JsiiCalc::UseCalcBase < Jsii::Object + self.jsii_fqn = "jsii-calc.UseCalcBase" + Jsii::Object.register_jsii_fqn("jsii-calc.UseCalcBase", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :hello => { kind: :method, name: "hello", is_optional: false }, + } + end + + # @return [Scope::JsiiCalcBase::Base] + def hello() + jsii_call_method("hello", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/uses_interface_with_properties.rb 1`] = ` +require 'jsii' + +class JsiiCalc::UsesInterfaceWithProperties < Jsii::Object + self.jsii_fqn = "jsii-calc.UsesInterfaceWithProperties" + Jsii::Object.register_jsii_fqn("jsii-calc.UsesInterfaceWithProperties", self) + + # @param obj [JsiiCalc::IInterfaceWithProperties] + def initialize(obj) + Jsii::Object.instance_method(:initialize).bind(self).call(obj) + end + + def self.jsii_overridable_methods + { + :obj => { kind: :property, name: "obj", is_optional: false }, + :just_read => { kind: :method, name: "justRead", is_optional: false }, + :read_string_and_number => { kind: :method, name: "readStringAndNumber", is_optional: false }, + :write_and_read => { kind: :method, name: "writeAndRead", is_optional: false }, + } + end + + # @return [JsiiCalc::IInterfaceWithProperties] + def obj() + jsii_get_property("obj") + end + + # @return [String] + def just_read() + jsii_call_method("justRead", []) + end + + # @param ext [JsiiCalc::IInterfaceWithPropertiesExtension] + # @return [String] + def read_string_and_number(ext) + jsii_call_method("readStringAndNumber", [ext]) + end + + # @param value [String] + # @return [String] + def write_and_read(value) + jsii_call_method("writeAndRead", [value]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/variadic_invoker.rb 1`] = ` +require 'jsii' + +class JsiiCalc::VariadicInvoker < Jsii::Object + self.jsii_fqn = "jsii-calc.VariadicInvoker" + Jsii::Object.register_jsii_fqn("jsii-calc.VariadicInvoker", self) + + # @param method [JsiiCalc::VariadicMethod] + def initialize(method) + Jsii::Object.instance_method(:initialize).bind(self).call(method) + end + + def self.jsii_overridable_methods + { + :as_array => { kind: :method, name: "asArray", is_optional: false }, + } + end + + # @param values [Array] + # @return [Array] + def as_array(*values) + jsii_call_method("asArray", [*values]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/variadic_method.rb 1`] = ` +require 'jsii' + +class JsiiCalc::VariadicMethod < Jsii::Object + self.jsii_fqn = "jsii-calc.VariadicMethod" + Jsii::Object.register_jsii_fqn("jsii-calc.VariadicMethod", self) + + # @param prefix [Array] a prefix that will be use for all values returned by \`#asArray\`. + def initialize(*prefix) + Jsii::Object.instance_method(:initialize).bind(self).call(*prefix) + end + + def self.jsii_overridable_methods + { + :as_array => { kind: :method, name: "asArray", is_optional: false }, + } + end + + # @param first [Numeric] the first element of the array to be returned (after the \`prefix\` provided at construction time). + # @param others [Array] other elements to be included in the array. + # @return [Array] + def as_array(first, *others) + jsii_call_method("asArray", [first, *others]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/variadic_type_union.rb 1`] = ` +require 'jsii' + +class JsiiCalc::VariadicTypeUnion < Jsii::Object + self.jsii_fqn = "jsii-calc.VariadicTypeUnion" + Jsii::Object.register_jsii_fqn("jsii-calc.VariadicTypeUnion", self) + + # @param union [Array] + def initialize(*union) + Jsii::Object.instance_method(:initialize).bind(self).call(*union) + end + + def self.jsii_overridable_methods + { + :union => { kind: :property, name: "union", is_optional: false }, + } + end + + # @return [Array] + def union() + jsii_get_property("union") + end + + def union=(value) + jsii_set_property("union", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/virtual_method_playground.rb 1`] = ` +require 'jsii' + +class JsiiCalc::VirtualMethodPlayground < Jsii::Object + self.jsii_fqn = "jsii-calc.VirtualMethodPlayground" + Jsii::Object.register_jsii_fqn("jsii-calc.VirtualMethodPlayground", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :override_me_async => { kind: :method, name: "overrideMeAsync", is_optional: false }, + :override_me_sync => { kind: :method, name: "overrideMeSync", is_optional: false }, + :parallel_sum_async => { kind: :method, name: "parallelSumAsync", is_optional: false }, + :serial_sum_async => { kind: :method, name: "serialSumAsync", is_optional: false }, + :sum_sync => { kind: :method, name: "sumSync", is_optional: false }, + } + end + + # @param index [Numeric] + # @return [Numeric] + def override_me_async(index) + jsii_async_call_method("overrideMeAsync", [index]) + end + + # @param index [Numeric] + # @return [Numeric] + def override_me_sync(index) + jsii_call_method("overrideMeSync", [index]) + end + + # @param count [Numeric] + # @return [Numeric] + def parallel_sum_async(count) + jsii_async_call_method("parallelSumAsync", [count]) + end + + # @param count [Numeric] + # @return [Numeric] + def serial_sum_async(count) + jsii_async_call_method("serialSumAsync", [count]) + end + + # @param count [Numeric] + # @return [Numeric] + def sum_sync(count) + jsii_call_method("sumSync", [count]) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/void_callback.rb 1`] = ` +require 'jsii' + +# This test is used to validate the runtimes can return correctly from a void callback. +# +# * Implement \`override_me\` (method does not have to do anything). +# * Invoke \`call_me\` +# * Verify that \`method_was_called\` is \`true\`. +class JsiiCalc::VoidCallback < Jsii::Object + self.jsii_fqn = "jsii-calc.VoidCallback" + Jsii::Object.register_jsii_fqn("jsii-calc.VoidCallback", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :method_was_called => { kind: :property, name: "methodWasCalled", is_optional: false }, + :call_me => { kind: :method, name: "callMe", is_optional: false }, + :override_me => { kind: :method, name: "overrideMe", is_optional: false }, + } + end + + # @return [Boolean] + def method_was_called() + jsii_get_property("methodWasCalled") + end + + # @return [void] + def call_me() + jsii_call_method("callMe", []) + end + + # @return [void] + def override_me() + jsii_call_method("overrideMe", []) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/weird_docs.rb 1`] = ` +require 'jsii' + +# > Don't use this class. +# +# A class that shouldn't be used, with the annotation in a weird place. +class JsiiCalc::WeirdDocs < Jsii::Object + self.jsii_fqn = "jsii-calc.WeirdDocs" + Jsii::Object.register_jsii_fqn("jsii-calc.WeirdDocs", self) + + def initialize + Jsii::Object.instance_method(:initialize).bind(self).call + end + + def self.jsii_overridable_methods + { + :dont_read_me => { kind: :property, name: "dontReadMe", is_optional: true }, + } + end + + # > Don't read this property. + # + # A property that shouldn't be read, with the annotation in a weird place. + # + # @return [String, nil] + def dont_read_me() + jsii_get_property("dontReadMe") + end + + def dont_read_me=(value) + jsii_set_property("dontReadMe", value) + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/with_private_property_in_constructor.rb 1`] = ` +require 'jsii' + +# Verifies that private property declarations in constructor arguments are hidden. +class JsiiCalc::WithPrivatePropertyInConstructor < Jsii::Object + self.jsii_fqn = "jsii-calc.WithPrivatePropertyInConstructor" + Jsii::Object.register_jsii_fqn("jsii-calc.WithPrivatePropertyInConstructor", self) + + # @param private_field [String, nil] + def initialize(private_field = nil) + Jsii::Object.instance_method(:initialize).bind(self).call(private_field) + end + + def self.jsii_overridable_methods + { + :success => { kind: :property, name: "success", is_optional: false }, + } + end + + # @return [Boolean] + def success() + jsii_get_property("success") + end + +end + + +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc@3.20.120.jsii.tgz 1`] = `ruby/lib/jsii-calc@3.20.120.jsii.tgz is a tarball`; + +exports[`Generated code for "jsii-calc": /ruby/sig/jsii-calc.rbs 1`] = ` +module JsiiCalc end +module JsiiCalc::Composition end +module JsiiCalc::DerivedClassHasNoProperties end +module JsiiCalc::InterfaceInNamespaceIncludesClasses end +module JsiiCalc::InterfaceInNamespaceOnlyInterface end +module JsiiCalc::PythonSelf end +module JsiiCalc::Anonymous end +module JsiiCalc::Cdk16625 end +module JsiiCalc::Cdk22369 end +module JsiiCalc::CovariantOverrides end +module JsiiCalc::HomonymousForwardReferences end +module JsiiCalc::Intersection end +module JsiiCalc::Jsii3656 end +module JsiiCalc::Jsii4894 end +module JsiiCalc::Module2530 end +module JsiiCalc::Module2617 end +module JsiiCalc::Module2647 end +module JsiiCalc::Module2689 end +module JsiiCalc::Module2692 end +module JsiiCalc::Module2700 end +module JsiiCalc::Module2702 end +module JsiiCalc::Nodirect end +module JsiiCalc::Onlystatic end +module JsiiCalc::PascalCaseName end +module JsiiCalc::Submodule end +module JsiiCalc::Union end +module JsiiCalc::Cdk16625::Donotimport end +module JsiiCalc::CovariantOverrides::ClassOverrides end +module JsiiCalc::HomonymousForwardReferences::Bar end +module JsiiCalc::HomonymousForwardReferences::Foo end +module JsiiCalc::Module2689::Methods end +module JsiiCalc::Module2689::Props end +module JsiiCalc::Module2689::Retval end +module JsiiCalc::Module2689::Structs end +module JsiiCalc::Module2692::Submodule1 end +module JsiiCalc::Module2692::Submodule2 end +module JsiiCalc::Nodirect::Sub1 end +module JsiiCalc::Nodirect::Sub2 end +module JsiiCalc::Submodule::NestedSubmodule end +module JsiiCalc::Submodule::BackReferences end +module JsiiCalc::Submodule::Child end +module JsiiCalc::Submodule::Isolated end +module JsiiCalc::Submodule::Param end +module JsiiCalc::Submodule::Returnsparam end +module JsiiCalc::Submodule::NestedSubmodule::DeeplyNested end + +class JsiiCalc::AbstractClassBase < ::Jsii::Object + def initialize: () -> void + attr_reader abstract_property: String +end + +module JsiiCalc::IInterfaceImplementedByAbstractClass + attr_reader prop_from_interface: String +end + +class JsiiCalc::AbstractClass < ::JsiiCalc::AbstractClassBase + include ::JsiiCalc::IInterfaceImplementedByAbstractClass + def initialize: () -> void + attr_reader abstract_property: String + attr_reader prop_from_interface: String + def abstract_method: (String name) -> String + def non_abstract_method: () -> Numeric +end + +class JsiiCalc::AbstractClassReturner < ::Jsii::Object + def initialize: () -> void + attr_reader return_abstract_from_property: ::JsiiCalc::AbstractClassBase + def give_me_abstract: () -> ::JsiiCalc::AbstractClass + def give_me_interface: () -> ::JsiiCalc::IInterfaceImplementedByAbstractClass +end + +class JsiiCalc::AbstractSuite < ::Jsii::Object + def initialize: () -> void + attr_reader property: String + attr_writer property: String + def some_method: (String str) -> String + def work_it_all: (String seed) -> String +end + +class JsiiCalc::BinaryOperation < ::Scope::JsiiCalcLib::Operation + include ::Scope::JsiiCalcLib::IFriendly + def initialize: (::Scope::JsiiCalcLib::NumericValue lhs, ::Scope::JsiiCalcLib::NumericValue rhs) -> void + attr_reader value: Numeric + attr_reader lhs: ::Scope::JsiiCalcLib::NumericValue + attr_reader rhs: ::Scope::JsiiCalcLib::NumericValue + def type_name: () -> untyped + def to_string: () -> String + def hello: () -> String +end + +class JsiiCalc::Add < ::JsiiCalc::BinaryOperation + def initialize: (::Scope::JsiiCalcLib::NumericValue lhs, ::Scope::JsiiCalcLib::NumericValue rhs) -> void + attr_reader value: Numeric + attr_reader lhs: ::Scope::JsiiCalcLib::NumericValue + attr_reader rhs: ::Scope::JsiiCalcLib::NumericValue + def type_name: () -> untyped + def to_string: () -> String + def hello: () -> String +end + +class JsiiCalc::AllTypes < ::Jsii::Object + def initialize: () -> void + attr_reader enum_property_value: Numeric + attr_reader any_array_property: Array[untyped] + attr_writer any_array_property: Array[untyped] + attr_reader any_map_property: Hash[String, untyped] + attr_writer any_map_property: Hash[String, untyped] + attr_reader any_property: untyped + attr_writer any_property: untyped + attr_reader array_property: Array[String] + attr_writer array_property: Array[String] + attr_reader boolean_property: bool + attr_writer boolean_property: bool + attr_reader date_property: DateTime + attr_writer date_property: DateTime + attr_reader enum_property: ::JsiiCalc::AllTypesEnum + attr_writer enum_property: ::JsiiCalc::AllTypesEnum + attr_reader json_property: untyped + attr_writer json_property: untyped + attr_reader map_property: Hash[String, ::Scope::JsiiCalcLib::Number] + attr_writer map_property: Hash[String, ::Scope::JsiiCalcLib::Number] + attr_reader number_property: Numeric + attr_writer number_property: Numeric + attr_reader string_property: String + attr_writer string_property: String + attr_reader union_array_property: Array[(Numeric | ::Scope::JsiiCalcLib::NumericValue)] + attr_writer union_array_property: Array[(Numeric | ::Scope::JsiiCalcLib::NumericValue)] + attr_reader union_map_property: Hash[String, (String | Numeric | ::Scope::JsiiCalcLib::Number)] + attr_writer union_map_property: Hash[String, (String | Numeric | ::Scope::JsiiCalcLib::Number)] + attr_reader union_property: (String | Numeric | ::Scope::JsiiCalcLib::Number | ::JsiiCalc::Multiply) + attr_writer union_property: (String | Numeric | ::Scope::JsiiCalcLib::Number | ::JsiiCalc::Multiply) + attr_reader unknown_array_property: Array[untyped] + attr_writer unknown_array_property: Array[untyped] + attr_reader unknown_map_property: Hash[String, untyped] + attr_writer unknown_map_property: Hash[String, untyped] + attr_reader unknown_property: untyped + attr_writer unknown_property: untyped + attr_reader optional_enum_value: ::JsiiCalc::StringEnum? + attr_writer optional_enum_value: ::JsiiCalc::StringEnum? + def any_in: (untyped inp) -> void + def any_out: () -> untyped + def enum_method: (::JsiiCalc::StringEnum value) -> ::JsiiCalc::StringEnum +end + +module JsiiCalc::AllTypesEnum + MY_ENUM_VALUE: ::Jsii::Enum + YOUR_ENUM_VALUE: ::Jsii::Enum + THIS_IS_GREAT: ::Jsii::Enum +end + +class JsiiCalc::AllowedMethodNames < ::Jsii::Object + def initialize: () -> void + def get_bar: (String _p1, Numeric _p2) -> void + def get_foo: (String with_param) -> String + def set_bar: (String _x, Numeric _y, bool _z) -> void + def set_foo: (String _x, Numeric _y) -> void +end + +class JsiiCalc::AmbiguousParameters < ::Jsii::Object + def initialize: (::JsiiCalc::Bell scope, ::JsiiCalc::StructParameterType props) -> void + attr_reader props: ::JsiiCalc::StructParameterType + attr_reader scope: ::JsiiCalc::Bell +end + +module JsiiCalc::IAnonymousImplementationProvider + def provide_as_class: () -> ::JsiiCalc::Implementation + def provide_as_interface: () -> ::JsiiCalc::IAnonymouslyImplementMe +end + +class JsiiCalc::AnonymousImplementationProvider < ::Jsii::Object + include ::JsiiCalc::IAnonymousImplementationProvider + def initialize: () -> void + def provide_as_class: () -> ::JsiiCalc::Implementation + def provide_as_interface: () -> ::JsiiCalc::IAnonymouslyImplementMe +end + +class JsiiCalc::AnyPropertyAccess < ::Jsii::Object + def self.mutate_properties: (untyped obj, String prop_a, String prop_b, String result_prop) -> void +end + +class JsiiCalc::AsyncVirtualMethods < ::Jsii::Object + def initialize: () -> void + def call_me: () -> Numeric + def call_me2: () -> Numeric + def call_me_double_promise: () -> Numeric + def dont_override_me: () -> Numeric + def override_me: (Numeric mult) -> Numeric + def override_me_too: () -> Numeric +end + +class JsiiCalc::AugmentableClass < ::Jsii::Object + def initialize: () -> void + def method_one: () -> void + def method_two: () -> void +end + +class JsiiCalc::BaseClass < ::Jsii::Object + def initialize: () -> void + attr_reader property: String + def method: () -> Numeric +end + +class JsiiCalc::BaseJsii976 < ::Jsii::Object + def initialize: () -> void +end + +module JsiiCalc::IBell + def ring: () -> void +end + +class JsiiCalc::Bell < ::Jsii::Object + include ::JsiiCalc::IBell + def initialize: () -> void + attr_reader rung: bool + attr_writer rung: bool + def ring: () -> void +end + +class JsiiCalc::BurriedAnonymousObject < ::Jsii::Object + def initialize: () -> void + def check: () -> bool + def give_it_back: (untyped value) -> untyped +end + +class JsiiCalc::Composition::CompositeOperation < ::Scope::JsiiCalcLib::Operation + def initialize: () -> void + attr_reader value: Numeric + attr_reader expression: ::Scope::JsiiCalcLib::NumericValue + attr_reader decoration_postfixes: Array[String] + attr_writer decoration_postfixes: Array[String] + attr_reader decoration_prefixes: Array[String] + attr_writer decoration_prefixes: Array[String] + attr_reader string_style: ::JsiiCalc::Composition::CompositeOperation::CompositionStringStyle + attr_writer string_style: ::JsiiCalc::Composition::CompositeOperation::CompositionStringStyle + def type_name: () -> untyped + def to_string: () -> String +end + +class JsiiCalc::Calculator < ::JsiiCalc::Composition::CompositeOperation + def initialize: (?::JsiiCalc::CalculatorProps? props) -> void + attr_reader value: Numeric + attr_reader expression: ::Scope::JsiiCalcLib::NumericValue + attr_reader decoration_postfixes: Array[String] + attr_writer decoration_postfixes: Array[String] + attr_reader decoration_prefixes: Array[String] + attr_writer decoration_prefixes: Array[String] + attr_reader string_style: ::JsiiCalc::Composition::CompositeOperation::CompositionStringStyle + attr_writer string_style: ::JsiiCalc::Composition::CompositeOperation::CompositionStringStyle + attr_reader operations_log: Array[::Scope::JsiiCalcLib::NumericValue] + attr_reader operations_map: Hash[String, Array[::Scope::JsiiCalcLib::NumericValue]] + attr_reader curr: ::Scope::JsiiCalcLib::NumericValue + attr_writer curr: ::Scope::JsiiCalcLib::NumericValue + attr_reader max_value: Numeric? + attr_writer max_value: Numeric? + attr_reader union_property: (::JsiiCalc::Add | ::JsiiCalc::Multiply | ::JsiiCalc::Power)? + attr_writer union_property: (::JsiiCalc::Add | ::JsiiCalc::Multiply | ::JsiiCalc::Power)? + def type_name: () -> untyped + def to_string: () -> String + def add: (Numeric value) -> void + def mul: (Numeric value) -> void + def neg: () -> void + def pow: (Numeric value) -> void + def read_union_value: () -> Numeric +end + +class JsiiCalc::CalculatorProps < ::Jsii::Struct + def initialize: (?initial_value: Numeric?, ?maximum_value: Numeric?) -> void + attr_reader initial_value: Numeric? + attr_reader maximum_value: Numeric? +end + +class JsiiCalc::ParentStruct982 < ::Jsii::Struct + def initialize: (foo: String) -> void + attr_reader foo: String +end + +class JsiiCalc::ChildStruct982 < ::JsiiCalc::ParentStruct982 + def initialize: (foo: String, bar: Numeric) -> void + attr_reader foo: String + attr_reader bar: Numeric +end + +module JsiiCalc::IAnotherPublicInterface + attr_reader a: String + attr_writer a: String +end + +module JsiiCalc::INonInternalInterface + attr_reader a: String + attr_writer a: String + attr_reader b: String + attr_writer b: String + attr_reader c: String + attr_writer c: String +end + +class JsiiCalc::ClassThatImplementsTheInternalInterface < ::Jsii::Object + include ::JsiiCalc::INonInternalInterface + def initialize: () -> void + attr_reader a: String + attr_writer a: String + attr_reader b: String + attr_writer b: String + attr_reader c: String + attr_writer c: String + attr_reader d: String + attr_writer d: String +end + +class JsiiCalc::ClassThatImplementsThePrivateInterface < ::Jsii::Object + include ::JsiiCalc::INonInternalInterface + def initialize: () -> void + attr_reader a: String + attr_writer a: String + attr_reader b: String + attr_writer b: String + attr_reader c: String + attr_writer c: String + attr_reader e: String + attr_writer e: String +end + +class JsiiCalc::ClassWithCollectionOfUnions < ::Jsii::Object + def initialize: (Array[Hash[String, (::JsiiCalc::StructA | ::JsiiCalc::StructB)]] union_property) -> void + attr_reader union_property: Array[Hash[String, (::JsiiCalc::StructA | ::JsiiCalc::StructB)]] + attr_writer union_property: Array[Hash[String, (::JsiiCalc::StructA | ::JsiiCalc::StructB)]] + def self.static_method_with_map_of_unions_param: (Hash[String, (::JsiiCalc::StructA | ::JsiiCalc::StructB)] param) -> void + def method_with_map_of_unions_param: (Hash[String, (::JsiiCalc::StructA | ::JsiiCalc::StructB)] param) -> void +end + +class JsiiCalc::ClassWithCollections < ::Jsii::Object + def initialize: (Hash[String, String] map, Array[String] array) -> void + def self.static_array: () -> Array[String] + def self.static_array=: (Array[String]) -> Array[String] + def self.static_map: () -> Hash[String, String] + def self.static_map=: (Hash[String, String]) -> Hash[String, String] + attr_reader array: Array[String] + attr_writer array: Array[String] + attr_reader map: Hash[String, String] + attr_writer map: Hash[String, String] + def self.create_a_list: () -> Array[String] + def self.create_a_map: () -> Hash[String, String] +end + +class JsiiCalc::ClassWithContainerTypes < ::Jsii::Object + def initialize: (Array[::JsiiCalc::DummyObj] array, Hash[String, ::JsiiCalc::DummyObj] record, Hash[String, ::JsiiCalc::DummyObj] obj, ?::JsiiCalc::ContainerProps? props) -> void + attr_reader array: Array[::JsiiCalc::DummyObj] + attr_reader obj: Hash[String, ::JsiiCalc::DummyObj] + attr_reader record: Hash[String, ::JsiiCalc::DummyObj] + attr_reader props: ::JsiiCalc::ContainerProps? +end + +class JsiiCalc::ClassWithDocs < ::Jsii::Object + def initialize: () -> void +end + +class JsiiCalc::ClassWithJavaReservedWords < ::Jsii::Object + def initialize: (String int) -> void + attr_reader int: String + def import: (String assert) -> String +end + +class JsiiCalc::ClassWithMutableObjectLiteralProperty < ::Jsii::Object + def initialize: () -> void + attr_reader mutable_object: ::JsiiCalc::IMutableObjectLiteral + attr_writer mutable_object: ::JsiiCalc::IMutableObjectLiteral +end + +class JsiiCalc::ClassWithNestedUnion < ::Jsii::Object + def initialize: (Array[(Hash[String, (::JsiiCalc::StructA | ::JsiiCalc::StructB)] | Array[(::JsiiCalc::StructA | ::JsiiCalc::StructB)])] union_property) -> void + attr_reader union_property: Array[(Hash[String, (::JsiiCalc::StructA | ::JsiiCalc::StructB)] | Array[(::JsiiCalc::StructA | ::JsiiCalc::StructB)])] + attr_writer union_property: Array[(Hash[String, (::JsiiCalc::StructA | ::JsiiCalc::StructB)] | Array[(::JsiiCalc::StructA | ::JsiiCalc::StructB)])] +end + +module JsiiCalc::IInterfaceWithProperties + attr_reader read_only_string: String + attr_reader read_write_string: String + attr_writer read_write_string: String +end + +class JsiiCalc::ClassWithPrivateConstructorAndAutomaticProperties < ::Jsii::Object + include ::JsiiCalc::IInterfaceWithProperties + attr_reader read_only_string: String + attr_reader read_write_string: String + attr_writer read_write_string: String + def self.create: (String read_only_string, String read_write_string) -> ::JsiiCalc::ClassWithPrivateConstructorAndAutomaticProperties +end + +class JsiiCalc::ConfusingToJackson < ::Jsii::Object + attr_reader union_property: (::Scope::JsiiCalcLib::IFriendly | Array[(::Scope::JsiiCalcLib::IFriendly | ::JsiiCalc::AbstractClass)])? + attr_writer union_property: (::Scope::JsiiCalcLib::IFriendly | Array[(::Scope::JsiiCalcLib::IFriendly | ::JsiiCalc::AbstractClass)])? + def self.make_instance: () -> ::JsiiCalc::ConfusingToJackson + def self.make_struct_instance: () -> ::JsiiCalc::ConfusingToJacksonStruct +end + +class JsiiCalc::ConfusingToJacksonStruct < ::Jsii::Struct + def initialize: (?union_property: (::Scope::JsiiCalcLib::IFriendly | Array[(::Scope::JsiiCalcLib::IFriendly | ::JsiiCalc::AbstractClass)])?) -> void + attr_reader union_property: (::Scope::JsiiCalcLib::IFriendly | Array[(::Scope::JsiiCalcLib::IFriendly | ::JsiiCalc::AbstractClass)])? +end + +class JsiiCalc::ConstructorPassesThisOut < ::Jsii::Object + def initialize: (::JsiiCalc::PartiallyInitializedThisConsumer consumer) -> void +end + +class JsiiCalc::Constructors < ::Jsii::Object + def initialize: () -> void + def self.hidden_interface: () -> ::JsiiCalc::IPublicInterface + def self.hidden_interfaces: () -> Array[::JsiiCalc::IPublicInterface] + def self.hidden_sub_interfaces: () -> Array[::JsiiCalc::IPublicInterface] + def self.make_class: () -> ::JsiiCalc::PublicClass + def self.make_interface: () -> ::JsiiCalc::IPublicInterface + def self.make_interface2: () -> ::JsiiCalc::IPublicInterface2 + def self.make_interfaces: () -> Array[::JsiiCalc::IPublicInterface] +end + +class JsiiCalc::ConsumePureInterface < ::Jsii::Object + def initialize: (::JsiiCalc::IStructReturningDelegate delegate) -> void + def work_it_baby: () -> ::JsiiCalc::StructB +end + +class JsiiCalc::ConsumerCanRingBell < ::Jsii::Object + def initialize: () -> void + def self.static_implemented_by_object_literal: (::JsiiCalc::IBellRinger ringer) -> bool + def self.static_implemented_by_private_class: (::JsiiCalc::IBellRinger ringer) -> bool + def self.static_implemented_by_public_class: (::JsiiCalc::IBellRinger ringer) -> bool + def self.static_when_typed_as_class: (::JsiiCalc::IConcreteBellRinger ringer) -> bool + def implemented_by_object_literal: (::JsiiCalc::IBellRinger ringer) -> bool + def implemented_by_private_class: (::JsiiCalc::IBellRinger ringer) -> bool + def implemented_by_public_class: (::JsiiCalc::IBellRinger ringer) -> bool + def when_typed_as_class: (::JsiiCalc::IConcreteBellRinger ringer) -> bool +end + +class JsiiCalc::ConsumersOfThisCrazyTypeSystem < ::Jsii::Object + def initialize: () -> void + def consume_another_public_interface: (::JsiiCalc::IAnotherPublicInterface obj) -> String + def consume_non_internal_interface: (::JsiiCalc::INonInternalInterface obj) -> untyped +end + +class JsiiCalc::ContainerProps < ::Jsii::Struct + def initialize: (array_prop: Array[::JsiiCalc::DummyObj], obj_prop: Hash[String, ::JsiiCalc::DummyObj], record_prop: Hash[String, ::JsiiCalc::DummyObj]) -> void + attr_reader array_prop: Array[::JsiiCalc::DummyObj] + attr_reader obj_prop: Hash[String, ::JsiiCalc::DummyObj] + attr_reader record_prop: Hash[String, ::JsiiCalc::DummyObj] +end + +class JsiiCalc::DataRenderer < ::Jsii::Object + def initialize: () -> void + def render: (?::Scope::JsiiCalcLib::MyFirstStruct? data) -> String + def render_arbitrary: (Hash[String, untyped] data) -> String + def render_map: (Hash[String, untyped] map) -> String +end + +class JsiiCalc::Default < ::Jsii::Object + def initialize: () -> void + def please_compile: () -> void +end + +class JsiiCalc::DefaultedConstructorArgument < ::Jsii::Object + def initialize: (?Numeric? arg1, ?String? arg2, ?DateTime? arg3) -> void + attr_reader arg1: Numeric + attr_reader arg3: DateTime + attr_reader arg2: String? +end + +class JsiiCalc::Demonstrate982 < ::Jsii::Object + def initialize: () -> void + def self.take_this: () -> ::JsiiCalc::ChildStruct982 + def self.take_this_too: () -> ::JsiiCalc::ParentStruct982 +end + +class JsiiCalc::DeprecatedClass < ::Jsii::Object + def initialize: (String readonly_string, ?Numeric? mutable_number) -> void + attr_reader readonly_property: String + attr_reader mutable_property: Numeric? + attr_writer mutable_property: Numeric? + def method: () -> void +end + +module JsiiCalc::DeprecatedEnum + OPTION_A: ::Jsii::Enum + OPTION_B: ::Jsii::Enum +end + +class JsiiCalc::DeprecatedStruct < ::Jsii::Struct + def initialize: (readonly_property: String) -> void + attr_reader readonly_property: String +end + +class JsiiCalc::DerivedStruct < ::Scope::JsiiCalcLib::MyFirstStruct + def initialize: (anumber: Numeric, astring: String, ?first_optional: Array[String]?, another_required: DateTime, bool: bool, non_primitive: ::JsiiCalc::DoubleTrouble, ?another_optional: Hash[String, ::Scope::JsiiCalcLib::NumericValue]?, ?optional_any: untyped, ?optional_array: Array[String]?) -> void + attr_reader anumber: Numeric + attr_reader astring: String + attr_reader first_optional: Array[String]? + attr_reader another_required: DateTime + attr_reader bool: bool + attr_reader non_primitive: ::JsiiCalc::DoubleTrouble + attr_reader another_optional: Hash[String, ::Scope::JsiiCalcLib::NumericValue]? + attr_reader optional_any: untyped + attr_reader optional_array: Array[String]? +end + +class JsiiCalc::DiamondBottom < ::Scope::JsiiCalcLib::DiamondLeft + def initialize: (?hoisted_top: String?, ?left: Numeric?, ?right: bool?, ?bottom: DateTime?) -> void + attr_reader hoisted_top: String? + attr_reader left: Numeric? + attr_reader right: bool? + attr_reader bottom: DateTime? +end + +class JsiiCalc::DiamondInheritanceBaseLevelStruct < ::Jsii::Struct + def initialize: (base_level_property: String) -> void + attr_reader base_level_property: String +end + +class JsiiCalc::DiamondInheritanceFirstMidLevelStruct < ::JsiiCalc::DiamondInheritanceBaseLevelStruct + def initialize: (base_level_property: String, first_mid_level_property: String) -> void + attr_reader base_level_property: String + attr_reader first_mid_level_property: String +end + +class JsiiCalc::DiamondInheritanceSecondMidLevelStruct < ::JsiiCalc::DiamondInheritanceBaseLevelStruct + def initialize: (base_level_property: String, second_mid_level_property: String) -> void + attr_reader base_level_property: String + attr_reader second_mid_level_property: String +end + +class JsiiCalc::DiamondInheritanceTopLevelStruct < ::JsiiCalc::DiamondInheritanceFirstMidLevelStruct + def initialize: (base_level_property: String, first_mid_level_property: String, second_mid_level_property: String, top_level_property: String) -> void + attr_reader base_level_property: String + attr_reader first_mid_level_property: String + attr_reader second_mid_level_property: String + attr_reader top_level_property: String +end + +class JsiiCalc::DisappointingCollectionSource < ::Jsii::Object + def self.MAYBE_LIST: () -> Array[String]? + def self.MAYBE_MAP: () -> Hash[String, Numeric]? +end + +class JsiiCalc::DoNotOverridePrivates < ::Jsii::Object + def initialize: () -> void + def change_private_property_value: (String new_value) -> void + def private_method_value: () -> String + def private_property_value: () -> String +end + +class JsiiCalc::DoNotRecognizeAnyAsOptional < ::Jsii::Object + def initialize: () -> void + def method: (untyped _required_any, ?untyped _optional_any, ?String? _optional_string) -> void +end + +class JsiiCalc::DocumentedClass < ::Jsii::Object + def initialize: () -> void + def greet: (?::JsiiCalc::Greetee? greetee) -> Numeric + def hola: () -> void + def moin: () -> void +end + +class JsiiCalc::DontComplainAboutVariadicAfterOptional < ::Jsii::Object + def initialize: () -> void + def optional_and_variadic: (?String? optional, *String things) -> String +end + +class JsiiCalc::DontUseMe < ::Jsii::Struct + def initialize: (?dont_set_me: String?) -> void + attr_reader dont_set_me: String? +end + +module JsiiCalc::IRandomNumberGenerator + def _next: () -> Numeric +end + +module JsiiCalc::IFriendlyRandomGenerator + def _next: () -> Numeric + def hello: () -> String +end + +class JsiiCalc::DoubleTrouble < ::Jsii::Object + include ::JsiiCalc::IFriendlyRandomGenerator + def initialize: () -> void + def hello: () -> String + def _next: () -> Numeric +end + +class JsiiCalc::DummyObj < ::Jsii::Struct + def initialize: (example: String) -> void + attr_reader example: String +end + +class JsiiCalc::DynamicPropertyBearer < ::Jsii::Object + def initialize: (String value_store) -> void + attr_reader dynamic_property: String + attr_writer dynamic_property: String + attr_reader value_store: String + attr_writer value_store: String +end + +class JsiiCalc::DynamicPropertyBearerChild < ::JsiiCalc::DynamicPropertyBearer + def initialize: (String original_value) -> void + attr_reader dynamic_property: String + attr_writer dynamic_property: String + attr_reader value_store: String + attr_writer value_store: String + attr_reader original_value: String + def override_value: (String new_value) -> String +end + +class JsiiCalc::Entropy < ::Jsii::Object + def initialize: (::JsiiCalc::IWallClock clock) -> void + def increase: () -> String + def repeat: (String word) -> String +end + +class JsiiCalc::EnumDispenser < ::Jsii::Object + def self.random_integer_like_enum: () -> ::JsiiCalc::AllTypesEnum + def self.random_string_like_enum: () -> ::JsiiCalc::StringEnum +end + +class JsiiCalc::EraseUndefinedHashValues < ::Jsii::Object + def initialize: () -> void + def self.does_key_exist: (::JsiiCalc::EraseUndefinedHashValuesOptions opts, String key) -> bool + def self.prop1_is_null: () -> Hash[String, untyped] + def self.prop2_is_undefined: () -> Hash[String, untyped] +end + +class JsiiCalc::EraseUndefinedHashValuesOptions < ::Jsii::Struct + def initialize: (?option1: String?, ?option2: String?) -> void + attr_reader option1: String? + attr_reader option2: String? +end + +class JsiiCalc::ExperimentalClass < ::Jsii::Object + def initialize: (String readonly_string, ?Numeric? mutable_number) -> void + attr_reader readonly_property: String + attr_reader mutable_property: Numeric? + attr_writer mutable_property: Numeric? + def method: () -> void +end + +module JsiiCalc::ExperimentalEnum + OPTION_A: ::Jsii::Enum + OPTION_B: ::Jsii::Enum +end + +class JsiiCalc::ExperimentalStruct < ::Jsii::Struct + def initialize: (readonly_property: String) -> void + attr_reader readonly_property: String +end + +class JsiiCalc::ExportedBaseClass < ::Jsii::Object + def initialize: (bool success) -> void + attr_reader success: bool +end + +class JsiiCalc::ExtendsInternalInterface < ::Jsii::Struct + def initialize: (boom: bool, prop: String) -> void + attr_reader boom: bool + attr_reader prop: String +end + +class JsiiCalc::ExternalClass < ::Jsii::Object + def initialize: (String readonly_string, ?Numeric? mutable_number) -> void + attr_reader readonly_property: String + attr_reader mutable_property: Numeric? + attr_writer mutable_property: Numeric? + def method: () -> void +end + +module JsiiCalc::ExternalEnum + OPTION_A: ::Jsii::Enum + OPTION_B: ::Jsii::Enum +end + +class JsiiCalc::ExternalStruct < ::Jsii::Struct + def initialize: (readonly_property: String) -> void + attr_reader readonly_property: String +end + +module JsiiCalc::IIndirectlyImplemented + attr_reader property: String + def method: () -> Numeric +end + +class JsiiCalc::FullCombo < ::JsiiCalc::BaseClass + include ::JsiiCalc::IIndirectlyImplemented + attr_reader property: String + def method: () -> Numeric +end + +class JsiiCalc::GiveMeStructs < ::Jsii::Object + def initialize: () -> void + attr_reader struct_literal: ::Scope::JsiiCalcLib::StructWithOnlyOptionals + def derived_to_first: (::JsiiCalc::DerivedStruct derived) -> ::Scope::JsiiCalcLib::MyFirstStruct + def read_derived_non_primitive: (::JsiiCalc::DerivedStruct derived) -> ::JsiiCalc::DoubleTrouble + def read_first_number: (::Scope::JsiiCalcLib::MyFirstStruct first) -> Numeric +end + +class JsiiCalc::Greetee < ::Jsii::Struct + def initialize: (?name: String?) -> void + attr_reader name: String? +end + +class JsiiCalc::GreetingAugmenter < ::Jsii::Object + def initialize: () -> void + def better_greeting: (::Scope::JsiiCalcLib::IFriendly friendly) -> String +end + +module JsiiCalc::IAnonymouslyImplementMe + attr_reader value: Numeric + def verb: () -> String +end + +module JsiiCalc::IBellRinger + def your_turn: (::JsiiCalc::IBell bell) -> void +end + +module JsiiCalc::IConcreteBellRinger + def your_turn: (::JsiiCalc::Bell bell) -> void +end + +module JsiiCalc::IDeprecatedInterface + attr_reader mutable_property: Numeric? + attr_writer mutable_property: Numeric? + def method: () -> void +end + +module JsiiCalc::IExperimentalInterface + attr_reader mutable_property: Numeric? + attr_writer mutable_property: Numeric? + def method: () -> void +end + +module JsiiCalc::IExtendsPrivateInterface + attr_reader more_things: Array[String] + attr_reader private: String + attr_writer private: String +end + +module JsiiCalc::IExternalInterface + attr_reader mutable_property: Numeric? + attr_writer mutable_property: Numeric? + def method: () -> void +end + +module JsiiCalc::IFriendlier + def hello: () -> String + def farewell: () -> String + def goodbye: () -> String +end + +module JsiiCalc::IInterfaceWithMethods + attr_reader value: String + def do_things: () -> void +end + +module JsiiCalc::IInterfaceThatShouldNotBeADataType + attr_reader value: String + attr_reader other_value: String + def do_things: () -> void +end + +module JsiiCalc::IInterfaceWithInternal + def visible: () -> void +end + +module JsiiCalc::IInterfaceWithOptionalMethodArguments + def hello: (String arg1, ?Numeric? arg2) -> void +end + +module JsiiCalc::IInterfaceWithPropertiesExtension + attr_reader read_only_string: String + attr_reader read_write_string: String + attr_writer read_write_string: String + attr_reader foo: Numeric + attr_writer foo: Numeric +end + +module JsiiCalc::IJSII417PublicBaseOfBase + attr_reader has_root: bool + def foo: () -> void +end + +module JsiiCalc::IJSII417Derived + attr_reader has_root: bool + attr_reader property: String + def foo: () -> void + def bar: () -> void + def baz: () -> void +end + +module JsiiCalc::IJavaReservedWordsInAnInterface + attr_reader _while: String + def abstract: () -> void + def assert: () -> void + def boolean: () -> void + def _break: () -> void + def byte: () -> void + def _case: () -> void + def catch: () -> void + def char: () -> void + def _class: () -> void + def const: () -> void + def continue: () -> void + def default: () -> void + def _do: () -> void + def double: () -> void + def _else: () -> void + def enum: () -> void + def extends: () -> void + def _false: () -> void + def final: () -> void + def finally: () -> void + def float: () -> void + def _for: () -> void + def goto: () -> void + def _if: () -> void + def implements: () -> void + def import: () -> void + def instanceof: () -> void + def int: () -> void + def interface: () -> void + def long: () -> void + def native: () -> void + def null: () -> void + def package: () -> void + def private: () -> void + def protected: () -> void + def public: () -> void + def _return: () -> void + def short: () -> void + def static: () -> void + def strictfp: () -> void + def _super: () -> void + def switch: () -> void + def synchronized: () -> void + def this: () -> void + def throw: () -> void + def throws: () -> void + def transient: () -> void + def _true: () -> void + def try: () -> void + def void: () -> void + def volatile: () -> void +end + +module JsiiCalc::IJsii487External +end + +module JsiiCalc::IJsii487External2 +end + +module JsiiCalc::IJsii496 +end + +module JsiiCalc::IMutableObjectLiteral + attr_reader value: String + attr_writer value: String +end + +module JsiiCalc::IObjectWithProperty + attr_reader property: String + attr_writer property: String + def was_set: () -> bool +end + +module JsiiCalc::IOptionalMethod + def optional: () -> String? +end + +module JsiiCalc::IPrivatelyImplemented + attr_reader success: bool +end + +module JsiiCalc::IPublicInterface + def bye: () -> String +end + +module JsiiCalc::IPublicInterface2 + def ciao: () -> String +end + +module JsiiCalc::IReturnJsii976 + attr_reader foo: Numeric +end + +module JsiiCalc::IReturnsNumber + attr_reader number_prop: ::Scope::JsiiCalcLib::Number + def obtain_number: () -> ::Scope::JsiiCalcLib::IDoublable +end + +module JsiiCalc::IStableInterface + attr_reader mutable_property: Numeric? + attr_writer mutable_property: Numeric? + def method: () -> void +end + +module JsiiCalc::IStringable + def describe: () -> String + def native_to_string: () -> String + def to_string: () -> String +end + +module JsiiCalc::IStructReturningDelegate + def return_struct: () -> ::JsiiCalc::StructB +end + +module JsiiCalc::IWallClock + def iso8601_now: () -> String +end + +class JsiiCalc::ImplementInternalInterface < ::Jsii::Object + def initialize: () -> void + attr_reader prop: String + attr_writer prop: String +end + +class JsiiCalc::Implementation < ::Jsii::Object + def initialize: () -> void + attr_reader value: Numeric +end + +class JsiiCalc::ImplementsInterfaceWithInternal < ::Jsii::Object + include ::JsiiCalc::IInterfaceWithInternal + def initialize: () -> void + def visible: () -> void +end + +class JsiiCalc::ImplementsInterfaceWithInternalSubclass < ::JsiiCalc::ImplementsInterfaceWithInternal + def initialize: () -> void + def visible: () -> void +end + +class JsiiCalc::ImplementsPrivateInterface < ::Jsii::Object + def initialize: () -> void + attr_reader private: String + attr_writer private: String +end + +class JsiiCalc::ImplictBaseOfBase < ::Scope::JsiiCalcBase::BaseProps + def initialize: (foo: ::Scope::JsiiCalcBaseOfBase::Very, bar: String, goo: DateTime) -> void + attr_reader foo: ::Scope::JsiiCalcBaseOfBase::Very + attr_reader bar: String + attr_reader goo: DateTime +end + +class JsiiCalc::PublicClass < ::Jsii::Object + def initialize: () -> void + def hello: () -> void +end + +class JsiiCalc::InbetweenClass < ::JsiiCalc::PublicClass + include ::JsiiCalc::IPublicInterface2 + def initialize: () -> void + def hello: () -> void + def ciao: () -> String +end + +class JsiiCalc::InterfaceCollections < ::Jsii::Object + def self.list_of_interfaces: () -> Array[::JsiiCalc::IBell] + def self.list_of_structs: () -> Array[::JsiiCalc::StructA] + def self.map_of_interfaces: () -> Hash[String, ::JsiiCalc::IBell] + def self.map_of_structs: () -> Hash[String, ::JsiiCalc::StructA] +end + +class JsiiCalc::InterfacesMaker < ::Jsii::Object + def self.make_interfaces: (Numeric count) -> Array[::Scope::JsiiCalcLib::IDoublable] +end + +class JsiiCalc::Isomorphism < ::Jsii::Object + def initialize: () -> void + def myself: () -> ::JsiiCalc::Isomorphism +end + +class JsiiCalc::Issue2638 < ::Jsii::Object + def initialize: () -> void +end + +class JsiiCalc::Issue2638B < ::Jsii::Object + def initialize: () -> void +end + +class JsiiCalc::JSII417PublicBaseOfBase < ::Jsii::Object + def initialize: () -> void + attr_reader has_root: bool + def self.make_instance: () -> ::JsiiCalc::JSII417PublicBaseOfBase + def foo: () -> void +end + +class JsiiCalc::JSII417Derived < ::JsiiCalc::JSII417PublicBaseOfBase + def initialize: (String property) -> void + attr_reader has_root: bool + attr_reader property: String + def self.make_instance: () -> ::JsiiCalc::JSII417PublicBaseOfBase + def foo: () -> void + def bar: () -> void + def baz: () -> void +end + +class JsiiCalc::JSObjectLiteralForInterface < ::Jsii::Object + def initialize: () -> void + def give_me_friendly: () -> ::Scope::JsiiCalcLib::IFriendly + def give_me_friendly_generator: () -> ::JsiiCalc::IFriendlyRandomGenerator +end + +class JsiiCalc::JSObjectLiteralToNative < ::Jsii::Object + def initialize: () -> void + def return_literal: () -> ::JsiiCalc::JSObjectLiteralToNativeClass +end + +class JsiiCalc::JSObjectLiteralToNativeClass < ::Jsii::Object + def initialize: () -> void + attr_reader prop_a: String + attr_writer prop_a: String + attr_reader prop_b: Numeric + attr_writer prop_b: Numeric +end + +class JsiiCalc::JavaReservedWords < ::Jsii::Object + def initialize: () -> void + attr_reader _while: String + attr_writer _while: String + def abstract: () -> void + def assert: () -> void + def boolean: () -> void + def _break: () -> void + def byte: () -> void + def _case: () -> void + def catch: () -> void + def char: () -> void + def _class: () -> void + def const: () -> void + def continue: () -> void + def default: () -> void + def _do: () -> void + def double: () -> void + def _else: () -> void + def enum: () -> void + def extends: () -> void + def _false: () -> void + def final: () -> void + def finally: () -> void + def float: () -> void + def _for: () -> void + def goto: () -> void + def _if: () -> void + def implements: () -> void + def import: () -> void + def instanceof: () -> void + def int: () -> void + def interface: () -> void + def long: () -> void + def native: () -> void + def _new: () -> void + def null: () -> void + def package: () -> void + def private: () -> void + def protected: () -> void + def public: () -> void + def _return: () -> void + def short: () -> void + def static: () -> void + def strictfp: () -> void + def _super: () -> void + def switch: () -> void + def synchronized: () -> void + def this: () -> void + def throw: () -> void + def throws: () -> void + def transient: () -> void + def _true: () -> void + def try: () -> void + def void: () -> void + def volatile: () -> void +end + +class JsiiCalc::Jsii487Derived < ::Jsii::Object + include ::JsiiCalc::IJsii487External2 + include ::JsiiCalc::IJsii487External + def initialize: () -> void +end + +class JsiiCalc::Jsii496Derived < ::Jsii::Object + include ::JsiiCalc::IJsii496 + def initialize: () -> void +end + +class JsiiCalc::JsiiAgent < ::Jsii::Object + def initialize: () -> void + def self.value: () -> String? +end + +class JsiiCalc::JsonFormatter < ::Jsii::Object + def self.any_array: () -> untyped + def self.any_boolean_false: () -> untyped + def self.any_boolean_true: () -> untyped + def self.any_date: () -> untyped + def self.any_empty_string: () -> untyped + def self.any_function: () -> untyped + def self.any_hash: () -> untyped + def self.any_null: () -> untyped + def self.any_number: () -> untyped + def self.any_ref: () -> untyped + def self.any_string: () -> untyped + def self.any_undefined: () -> untyped + def self.any_zero: () -> untyped + def self.stringify: (?untyped value) -> String? +end + +class JsiiCalc::LevelOne < ::Jsii::Object + def initialize: (::JsiiCalc::LevelOneProps props) -> void + attr_reader props: ::JsiiCalc::LevelOneProps +end + +class JsiiCalc::LevelOne::PropBooleanValue < ::Jsii::Struct + def initialize: (value: bool) -> void + attr_reader value: bool +end + +class JsiiCalc::LevelOne::PropProperty < ::Jsii::Struct + def initialize: (prop: ::JsiiCalc::LevelOne::PropBooleanValue) -> void + attr_reader prop: ::JsiiCalc::LevelOne::PropBooleanValue +end + +class JsiiCalc::LevelOneProps < ::Jsii::Struct + def initialize: (prop: ::JsiiCalc::LevelOne::PropProperty) -> void + attr_reader prop: ::JsiiCalc::LevelOne::PropProperty +end + +class JsiiCalc::LoadBalancedFargateServiceProps < ::Jsii::Struct + def initialize: (?container_port: Numeric?, ?cpu: String?, ?memory_mib: String?, ?public_load_balancer: bool?, ?public_tasks: bool?) -> void + attr_reader container_port: Numeric? + attr_reader cpu: String? + attr_reader memory_mib: String? + attr_reader public_load_balancer: bool? + attr_reader public_tasks: bool? +end + +class JsiiCalc::MethodNamedProperty < ::Jsii::Object + def initialize: () -> void + attr_reader elite: Numeric + def property: () -> String +end + +class JsiiCalc::Multiply < ::JsiiCalc::BinaryOperation + include ::JsiiCalc::IFriendlier + include ::JsiiCalc::IRandomNumberGenerator + def initialize: (::Scope::JsiiCalcLib::NumericValue lhs, ::Scope::JsiiCalcLib::NumericValue rhs) -> void + attr_reader value: Numeric + attr_reader lhs: ::Scope::JsiiCalcLib::NumericValue + attr_reader rhs: ::Scope::JsiiCalcLib::NumericValue + def type_name: () -> untyped + def to_string: () -> String + def hello: () -> String + def farewell: () -> String + def goodbye: () -> String + def _next: () -> Numeric +end + +class JsiiCalc::UnaryOperation < ::Scope::JsiiCalcLib::Operation + def initialize: (::Scope::JsiiCalcLib::NumericValue operand) -> void + attr_reader value: Numeric + attr_reader operand: ::Scope::JsiiCalcLib::NumericValue + def type_name: () -> untyped + def to_string: () -> String +end + +class JsiiCalc::Negate < ::JsiiCalc::UnaryOperation + include ::JsiiCalc::IFriendlier + def initialize: (::Scope::JsiiCalcLib::NumericValue operand) -> void + attr_reader value: Numeric + attr_reader operand: ::Scope::JsiiCalcLib::NumericValue + def type_name: () -> untyped + def to_string: () -> String + def farewell: () -> String + def goodbye: () -> String + def hello: () -> String +end + +class JsiiCalc::NestedClassInstance < ::Jsii::Object + def self.make_instance: () -> ::Scope::JsiiCalcLib::Submodule::NestingClass::NestedClass +end + +class JsiiCalc::NestedStruct < ::Jsii::Struct + def initialize: (number_prop: Numeric) -> void + attr_reader number_prop: Numeric +end + +class JsiiCalc::NodeStandardLibrary < ::Jsii::Object + def initialize: () -> void + attr_reader os_platform: String + def crypto_sha256: () -> String + def fs_read_file: () -> String + def fs_read_file_sync: () -> String +end + +class JsiiCalc::NullShouldBeTreatedAsUndefined < ::Jsii::Object + def initialize: (String _param1, ?untyped optional) -> void + attr_reader change_me_to_undefined: String? + attr_writer change_me_to_undefined: String? + def give_me_undefined: (?untyped value) -> void + def give_me_undefined_inside_an_object: (::JsiiCalc::NullShouldBeTreatedAsUndefinedData input) -> void + def verify_property_is_undefined: () -> void +end + +class JsiiCalc::NullShouldBeTreatedAsUndefinedData < ::Jsii::Struct + def initialize: (array_with_three_elements_and_undefined_as_second_argument: Array[untyped], ?this_should_be_undefined: untyped) -> void + attr_reader array_with_three_elements_and_undefined_as_second_argument: Array[untyped] + attr_reader this_should_be_undefined: untyped +end + +class JsiiCalc::NumberGenerator < ::Jsii::Object + def initialize: (::JsiiCalc::IRandomNumberGenerator generator) -> void + attr_reader generator: ::JsiiCalc::IRandomNumberGenerator + attr_writer generator: ::JsiiCalc::IRandomNumberGenerator + def is_same_generator: (::JsiiCalc::IRandomNumberGenerator gen) -> bool + def next_times100: () -> Numeric +end + +class JsiiCalc::ObjectRefsInCollections < ::Jsii::Object + def initialize: () -> void + def sum_from_array: (Array[::Scope::JsiiCalcLib::NumericValue] values) -> Numeric + def sum_from_map: (Hash[String, ::Scope::JsiiCalcLib::NumericValue] values) -> Numeric +end + +class JsiiCalc::ObjectWithPropertyProvider < ::Jsii::Object + def self.provide: () -> ::JsiiCalc::IObjectWithProperty +end + +class JsiiCalc::Old < ::Jsii::Object + def initialize: () -> void + def do_a_thing: () -> void +end + +class JsiiCalc::OptionalArgumentInvoker < ::Jsii::Object + def initialize: (::JsiiCalc::IInterfaceWithOptionalMethodArguments delegate) -> void + def invoke_with_optional: () -> void + def invoke_without_optional: () -> void +end + +class JsiiCalc::OptionalConstructorArgument < ::Jsii::Object + def initialize: (Numeric arg1, String arg2, ?DateTime? arg3) -> void + attr_reader arg1: Numeric + attr_reader arg2: String + attr_reader arg3: DateTime? +end + +class JsiiCalc::OptionalStruct < ::Jsii::Struct + def initialize: (?field: String?) -> void + attr_reader field: String? +end + +class JsiiCalc::OptionalStructConsumer < ::Jsii::Object + def initialize: (?::JsiiCalc::OptionalStruct? optional_struct) -> void + attr_reader parameter_was_undefined: bool + attr_reader field_value: String? +end + +class JsiiCalc::OverridableProtectedMember < ::Jsii::Object + def initialize: () -> void + attr_reader override_read_only: String + attr_reader override_read_write: String + attr_writer override_read_write: String + def override_me: () -> String + def switch_modes: () -> void + def value_from_protected: () -> String +end + +class JsiiCalc::OverrideReturnsObject < ::Jsii::Object + def initialize: () -> void + def test: (::JsiiCalc::IReturnsNumber obj) -> Numeric +end + +class JsiiCalc::ParamShadowsBuiltins < ::Jsii::Object + def initialize: (String builtins, String str, ::JsiiCalc::ParamShadowsBuiltinsProps props) -> void +end + +class JsiiCalc::ParamShadowsBuiltinsProps < ::Jsii::Struct + def initialize: (boolean_property: bool, string_property: String, struct_property: ::JsiiCalc::StructA) -> void + attr_reader boolean_property: bool + attr_reader string_property: String + attr_reader struct_property: ::JsiiCalc::StructA +end + +class JsiiCalc::ParamShadowsScope < ::Jsii::Object + def initialize: () -> void + def use_scope: (::Scope::JsiiCalcLib::Number scope) -> ::Scope::JsiiCalcLib::Number +end + +class JsiiCalc::PartiallyInitializedThisConsumer < ::Jsii::Object + def initialize: () -> void + def consume_partially_initialized_this: (::JsiiCalc::ConstructorPassesThisOut obj, DateTime dt, ::JsiiCalc::AllTypesEnum ev) -> String +end + +class JsiiCalc::Polymorphism < ::Jsii::Object + def initialize: () -> void + def say_hello: (::Scope::JsiiCalcLib::IFriendly friendly) -> String +end + +class JsiiCalc::Power < ::JsiiCalc::Composition::CompositeOperation + def initialize: (::Scope::JsiiCalcLib::NumericValue base, ::Scope::JsiiCalcLib::NumericValue pow) -> void + attr_reader value: Numeric + attr_reader expression: ::Scope::JsiiCalcLib::NumericValue + attr_reader decoration_postfixes: Array[String] + attr_writer decoration_postfixes: Array[String] + attr_reader decoration_prefixes: Array[String] + attr_writer decoration_prefixes: Array[String] + attr_reader string_style: ::JsiiCalc::Composition::CompositeOperation::CompositionStringStyle + attr_writer string_style: ::JsiiCalc::Composition::CompositeOperation::CompositionStringStyle + attr_reader base: ::Scope::JsiiCalcLib::NumericValue + attr_reader pow: ::Scope::JsiiCalcLib::NumericValue + def type_name: () -> untyped + def to_string: () -> String +end + +class JsiiCalc::PromiseNothing < ::Jsii::Object + def initialize: () -> void + def self.promise_it: () -> void + def instance_promise_it: () -> void +end + +class JsiiCalc::PropertyNamedProperty < ::Jsii::Object + def initialize: () -> void + attr_reader property: String + attr_reader yet_anoter_one: bool +end + +class JsiiCalc::PythonReservedWords < ::Jsii::Object + def initialize: () -> void + def _and: () -> void + def as: () -> void + def assert: () -> void + def async: () -> void + def await: () -> void + def _break: () -> void + def _class: () -> void + def continue: () -> void + def _def: () -> void + def del: () -> void + def elif: () -> void + def _else: () -> void + def except: () -> void + def finally: () -> void + def _for: () -> void + def from: () -> void + def global: () -> void + def _if: () -> void + def import: () -> void + def _in: () -> void + def is: () -> void + def lambda: () -> void + def nonlocal: () -> void + def _not: () -> void + def _or: () -> void + def pass: () -> void + def raise: () -> void + def _return: () -> void + def try: () -> void + def _while: () -> void + def with: () -> void + def _yield: () -> void +end + +class JsiiCalc::ReferenceEnumFromScopedPackage < ::Jsii::Object + def initialize: () -> void + attr_reader foo: ::Scope::JsiiCalcLib::EnumFromScopedModule? + attr_writer foo: ::Scope::JsiiCalcLib::EnumFromScopedModule? + def load_foo: () -> ::Scope::JsiiCalcLib::EnumFromScopedModule? + def save_foo: (::Scope::JsiiCalcLib::EnumFromScopedModule value) -> void +end + +class JsiiCalc::ReturnsPrivateImplementationOfInterface < ::Jsii::Object + def initialize: () -> void + attr_reader private_implementation: ::JsiiCalc::IPrivatelyImplemented +end + +class JsiiCalc::RootStruct < ::Jsii::Struct + def initialize: (string_prop: String, ?nested_struct: ::JsiiCalc::NestedStruct?) -> void + attr_reader string_prop: String + attr_reader nested_struct: ::JsiiCalc::NestedStruct? +end + +class JsiiCalc::RootStructValidator < ::Jsii::Object + def self.validate: (::JsiiCalc::RootStruct struct) -> void +end + +class JsiiCalc::RuntimeTypeChecking < ::Jsii::Object + def initialize: () -> void + def method_with_defaulted_arguments: (?Numeric? arg1, ?String? arg2, ?DateTime? arg3) -> void + def method_with_optional_any_argument: (?untyped arg) -> void + def method_with_optional_arguments: (Numeric arg1, String arg2, ?DateTime? arg3) -> void +end + +class JsiiCalc::SecondLevelStruct < ::Jsii::Struct + def initialize: (deeper_required_prop: String, ?deeper_optional_prop: String?) -> void + attr_reader deeper_required_prop: String + attr_reader deeper_optional_prop: String? +end + +class JsiiCalc::SingleInstanceTwoTypes < ::Jsii::Object + def initialize: () -> void + def interface1: () -> ::JsiiCalc::InbetweenClass + def interface2: () -> ::JsiiCalc::IPublicInterface +end + +class JsiiCalc::SingletonInt < ::Jsii::Object + def is_singleton_int: (Numeric value) -> bool +end + +module JsiiCalc::SingletonIntEnum + SINGLETON_INT: ::Jsii::Enum +end + +class JsiiCalc::SingletonString < ::Jsii::Object + def is_singleton_string: (String value) -> bool +end + +module JsiiCalc::SingletonStringEnum + SINGLETON_STRING: ::Jsii::Enum +end + +class JsiiCalc::SmellyStruct < ::Jsii::Struct + def initialize: (property: String, yet_anoter_one: bool) -> void + attr_reader property: String + attr_reader yet_anoter_one: bool +end + +class JsiiCalc::SomeContainingClass < ::Jsii::Object + def initialize: () -> void + def say_hello: () -> String +end + +class JsiiCalc::SomeContainingClass::ParentStruct < ::Jsii::Struct + def initialize: (field1: String) -> void + attr_reader field1: String +end + +class JsiiCalc::SomeContainingClass::ChildStruct < ::JsiiCalc::SomeContainingClass::ParentStruct + def initialize: (field1: String, field2: String) -> void + attr_reader field1: String + attr_reader field2: String +end + +class JsiiCalc::SomeTypeJsii976 < ::Jsii::Object + def initialize: () -> void + def self.return_anonymous: () -> untyped + def self.return_return: () -> ::JsiiCalc::IReturnJsii976 +end + +class JsiiCalc::StableClass < ::Jsii::Object + def initialize: (String readonly_string, ?Numeric? mutable_number) -> void + attr_reader readonly_property: String + attr_reader mutable_property: Numeric? + attr_writer mutable_property: Numeric? + def method: () -> void +end + +module JsiiCalc::StableEnum + OPTION_A: ::Jsii::Enum + OPTION_B: ::Jsii::Enum +end + +class JsiiCalc::StableStruct < ::Jsii::Struct + def initialize: (readonly_property: String) -> void + attr_reader readonly_property: String +end + +class JsiiCalc::StaticContext < ::Jsii::Object + def self.static_variable: () -> bool + def self.static_variable=: (bool) -> bool + def self.can_access_static_context: () -> bool +end + +class JsiiCalc::StaticHelloParent < ::Jsii::Object + def initialize: () -> void + def self.property: () -> Numeric + def self.PROPERTY: () -> Numeric + def self.method: () -> void +end + +class JsiiCalc::StaticHelloChild < ::JsiiCalc::StaticHelloParent + def self.property: () -> Numeric + def self.PROPERTY: () -> Numeric + def self.method: () -> void +end + +class JsiiCalc::Statics < ::Jsii::Object + def initialize: (String value) -> void + def self.BAR: () -> Numeric + def self.CONST_OBJ: () -> ::JsiiCalc::DoubleTrouble + def self.FOO: () -> String + def self.ZOO_BAR: () -> Hash[String, String] + def self.instance: () -> ::JsiiCalc::Statics + def self.instance=: (::JsiiCalc::Statics) -> ::JsiiCalc::Statics + def self.non_const_static: () -> Numeric + def self.non_const_static=: (Numeric) -> Numeric + attr_reader value: String + def self.static_method: (String name) -> String + def just_method: () -> String +end + +module JsiiCalc::StringEnum + A: ::Jsii::Enum + B: ::Jsii::Enum + C: ::Jsii::Enum +end + +class JsiiCalc::Stringable < ::Jsii::Object + include ::JsiiCalc::IStringable + def initialize: () -> void + def self.make_anonymous_stringable: () -> ::JsiiCalc::IStringable + def self.make_private_stringable: () -> ::JsiiCalc::IStringable + def self.make_public_stringable: () -> ::JsiiCalc::IStringable + def describe: () -> String + def native_to_string: () -> String + def to_string: () -> String +end + +class JsiiCalc::StripInternal < ::Jsii::Object + def initialize: () -> void + attr_reader you_see_me: String + attr_writer you_see_me: String +end + +class JsiiCalc::StructA < ::Jsii::Struct + def initialize: (required_string: String, ?optional_number: Numeric?, ?optional_string: String?) -> void + attr_reader required_string: String + attr_reader optional_number: Numeric? + attr_reader optional_string: String? +end + +class JsiiCalc::StructB < ::Jsii::Struct + def initialize: (required_string: String, ?optional_boolean: bool?, ?optional_struct_a: ::JsiiCalc::StructA?) -> void + attr_reader required_string: String + attr_reader optional_boolean: bool? + attr_reader optional_struct_a: ::JsiiCalc::StructA? +end + +class JsiiCalc::StructParameterType < ::Jsii::Struct + def initialize: (scope: String, ?props: bool?) -> void + attr_reader scope: String + attr_reader props: bool? +end + +class JsiiCalc::StructPassing < ::Jsii::Object + def initialize: () -> void + def self.how_many_var_args_did_i_pass: (Numeric _positional, *::JsiiCalc::TopLevelStruct inputs) -> Numeric + def self.round_trip: (Numeric _positional, ::JsiiCalc::TopLevelStruct input) -> ::JsiiCalc::TopLevelStruct +end + +class JsiiCalc::StructUnionConsumer < ::Jsii::Object + def self.is_struct_a: ((::JsiiCalc::StructA | ::JsiiCalc::StructB) struct) -> bool + def self.is_struct_b: ((::JsiiCalc::StructA | ::JsiiCalc::StructB) struct) -> bool + def self.provide_struct: (String which) -> (::JsiiCalc::StructA | ::JsiiCalc::StructB) +end + +class JsiiCalc::StructWithCollectionOfUnionts < ::Jsii::Struct + def initialize: (union_property: Array[Hash[String, (::JsiiCalc::StructA | ::JsiiCalc::StructB)]]) -> void + attr_reader union_property: Array[Hash[String, (::JsiiCalc::StructA | ::JsiiCalc::StructB)]] +end + +class JsiiCalc::StructWithEnum < ::Jsii::Struct + def initialize: (foo: ::JsiiCalc::StringEnum, ?bar: ::JsiiCalc::AllTypesEnum?) -> void + attr_reader foo: ::JsiiCalc::StringEnum + attr_reader bar: ::JsiiCalc::AllTypesEnum? +end + +class JsiiCalc::StructWithJavaReservedWords < ::Jsii::Struct + def initialize: (default: String, ?assert: String?, ?result: String?, ?that: String?) -> void + attr_reader default: String + attr_reader assert: String? + attr_reader result: String? + attr_reader that: String? +end + +class JsiiCalc::Sum < ::JsiiCalc::Composition::CompositeOperation + def initialize: () -> void + attr_reader value: Numeric + attr_reader expression: ::Scope::JsiiCalcLib::NumericValue + attr_reader decoration_postfixes: Array[String] + attr_writer decoration_postfixes: Array[String] + attr_reader decoration_prefixes: Array[String] + attr_writer decoration_prefixes: Array[String] + attr_reader string_style: ::JsiiCalc::Composition::CompositeOperation::CompositionStringStyle + attr_writer string_style: ::JsiiCalc::Composition::CompositeOperation::CompositionStringStyle + attr_reader parts: Array[::Scope::JsiiCalcLib::NumericValue] + attr_writer parts: Array[::Scope::JsiiCalcLib::NumericValue] + def type_name: () -> untyped + def to_string: () -> String +end + +class JsiiCalc::SupportsNiceJavaBuilderWithRequiredProps < ::Jsii::Object + def initialize: (Numeric id, ::JsiiCalc::SupportsNiceJavaBuilderProps props) -> void + attr_reader bar: Numeric + attr_reader id: Numeric + attr_reader prop_id: String? +end + +class JsiiCalc::SupportsNiceJavaBuilder < ::JsiiCalc::SupportsNiceJavaBuilderWithRequiredProps + def initialize: (Numeric id, ?Numeric? default_bar, ?::JsiiCalc::SupportsNiceJavaBuilderProps? props, *String rest) -> void + attr_reader bar: Numeric + attr_reader id: Numeric + attr_reader prop_id: String? + attr_reader rest: Array[String] +end + +class JsiiCalc::SupportsNiceJavaBuilderProps < ::Jsii::Struct + def initialize: (bar: Numeric, ?id: String?) -> void + attr_reader bar: Numeric + attr_reader id: String? +end + +class JsiiCalc::SyncOverrideExtraArgs < ::Jsii::Object + def initialize: () -> void + def call_produce_with_extra_arg: () -> String + def produce: () -> String +end + +class JsiiCalc::SyncVirtualMethods < ::Jsii::Object + def initialize: () -> void + attr_reader readonly_property: String + attr_reader a: Numeric + attr_writer a: Numeric + attr_reader caller_is_property: Numeric + attr_writer caller_is_property: Numeric + attr_reader other_property: String + attr_writer other_property: String + attr_reader the_property: String + attr_writer the_property: String + attr_reader value_of_other_property: String + attr_writer value_of_other_property: String + def caller_is_async: () -> Numeric + def caller_is_method: () -> Numeric + def modify_other_property: (String value) -> void + def modify_value_of_the_property: (String value) -> void + def read_a: () -> Numeric + def retrieve_other_property: () -> String + def retrieve_read_only_property: () -> String + def retrieve_value_of_the_property: () -> String + def virtual_method: (Numeric n) -> Numeric + def write_a: (Numeric value) -> void +end + +class JsiiCalc::TestStructWithEnum < ::Jsii::Object + def initialize: () -> void + attr_reader struct_with_foo: ::JsiiCalc::StructWithEnum + attr_reader struct_with_foo_bar: ::JsiiCalc::StructWithEnum + def is_string_enum_a: (::JsiiCalc::StructWithEnum input) -> bool + def is_string_enum_b: (::JsiiCalc::StructWithEnum input) -> bool +end + +class JsiiCalc::Thrower < ::Jsii::Object + def initialize: () -> void + def throw_error: () -> void +end + +class JsiiCalc::TopLevelStruct < ::Jsii::Struct + def initialize: (required: String, second_level: (Numeric | ::JsiiCalc::SecondLevelStruct), ?optional: String?) -> void + attr_reader required: String + attr_reader second_level: (Numeric | ::JsiiCalc::SecondLevelStruct) + attr_reader optional: String? +end + +class JsiiCalc::TwoMethodsWithSimilarCapitalization < ::Jsii::Object + def initialize: () -> void + attr_reader foo_bar: Numeric + def to_iso_string: () -> String + def to_is_o_string: () -> String +end + +class JsiiCalc::UmaskCheck < ::Jsii::Object + def self.mode: () -> Numeric +end + +class JsiiCalc::UnionProperties < ::Jsii::Struct + def initialize: (bar: (String | Numeric | ::JsiiCalc::AllTypes), ?foo: (String | Numeric)?) -> void + attr_reader bar: (String | Numeric | ::JsiiCalc::AllTypes) + attr_reader foo: (String | Numeric)? +end + +class JsiiCalc::UpcasingReflectable < ::Jsii::Object + include ::Scope::JsiiCalcLib::Submodule::IReflectable + def initialize: (Hash[String, untyped] delegate) -> void + def self.REFLECTOR: () -> ::Scope::JsiiCalcLib::Submodule::Reflector + attr_reader entries: Array[::Scope::JsiiCalcLib::Submodule::ReflectableEntry] +end + +class JsiiCalc::UseBundledDependency < ::Jsii::Object + def initialize: () -> void + def value: () -> untyped +end + +class JsiiCalc::UseCalcBase < ::Jsii::Object + def initialize: () -> void + def hello: () -> ::Scope::JsiiCalcBase::Base +end + +class JsiiCalc::UsesInterfaceWithProperties < ::Jsii::Object + def initialize: (::JsiiCalc::IInterfaceWithProperties obj) -> void + attr_reader obj: ::JsiiCalc::IInterfaceWithProperties + def just_read: () -> String + def read_string_and_number: (::JsiiCalc::IInterfaceWithPropertiesExtension ext) -> String + def write_and_read: (String value) -> String +end + +class JsiiCalc::VariadicInvoker < ::Jsii::Object + def initialize: (::JsiiCalc::VariadicMethod method) -> void + def as_array: (*Numeric values) -> Array[Numeric] +end + +class JsiiCalc::VariadicMethod < ::Jsii::Object + def initialize: (*Numeric prefix) -> void + def as_array: (Numeric first, *Numeric others) -> Array[Numeric] +end + +class JsiiCalc::VariadicTypeUnion < ::Jsii::Object + def initialize: (*(::JsiiCalc::StructA | ::JsiiCalc::StructB) union) -> void + attr_reader union: Array[(::JsiiCalc::StructA | ::JsiiCalc::StructB)] + attr_writer union: Array[(::JsiiCalc::StructA | ::JsiiCalc::StructB)] +end + +class JsiiCalc::VirtualMethodPlayground < ::Jsii::Object + def initialize: () -> void + def override_me_async: (Numeric index) -> Numeric + def override_me_sync: (Numeric index) -> Numeric + def parallel_sum_async: (Numeric count) -> Numeric + def serial_sum_async: (Numeric count) -> Numeric + def sum_sync: (Numeric count) -> Numeric +end + +class JsiiCalc::VoidCallback < ::Jsii::Object + def initialize: () -> void + attr_reader method_was_called: bool + def call_me: () -> void + def override_me: () -> void +end + +class JsiiCalc::WeirdDocs < ::Jsii::Object + def initialize: () -> void + attr_reader dont_read_me: String? + attr_writer dont_read_me: String? +end + +class JsiiCalc::WithPrivatePropertyInConstructor < ::Jsii::Object + def initialize: (?String? private_field) -> void + attr_reader success: bool +end + +class JsiiCalc::DerivedClassHasNoProperties::Base < ::Jsii::Object + def initialize: () -> void + attr_reader prop: String + attr_writer prop: String +end + +class JsiiCalc::DerivedClassHasNoProperties::Derived < ::JsiiCalc::DerivedClassHasNoProperties::Base + def initialize: () -> void + attr_reader prop: String + attr_writer prop: String +end + +class JsiiCalc::InterfaceInNamespaceIncludesClasses::Foo < ::Jsii::Object + def initialize: () -> void + attr_reader bar: String? + attr_writer bar: String? +end + +class JsiiCalc::InterfaceInNamespaceIncludesClasses::Hello < ::Jsii::Struct + def initialize: (foo: Numeric) -> void + attr_reader foo: Numeric +end + +class JsiiCalc::InterfaceInNamespaceOnlyInterface::Hello < ::Jsii::Struct + def initialize: (foo: Numeric) -> void + attr_reader foo: Numeric +end + +class JsiiCalc::PythonSelf::ClassWithSelf < ::Jsii::Object + def initialize: (String _self) -> void + attr_reader _self: String + def method: (Numeric _self) -> String +end + +class JsiiCalc::PythonSelf::ClassWithSelfKwarg < ::Jsii::Object + def initialize: (::JsiiCalc::PythonSelf::StructWithSelf props) -> void + attr_reader props: ::JsiiCalc::PythonSelf::StructWithSelf +end + +module JsiiCalc::PythonSelf::IInterfaceWithSelf + def method: (Numeric _self) -> String +end + +class JsiiCalc::PythonSelf::StructWithSelf < ::Jsii::Struct + def initialize: (_self: String) -> void + attr_reader _self: String +end + +module JsiiCalc::Anonymous::IOptionA + def do_something: () -> String +end + +module JsiiCalc::Anonymous::IOptionB + def do_something_else: () -> String +end + +class JsiiCalc::Anonymous::UseOptions < ::Jsii::Object + def self.consume: ((::JsiiCalc::Anonymous::IOptionA | ::JsiiCalc::Anonymous::IOptionB) option) -> String + def self.privide_as_any: (String which) -> untyped + def self.provide: (String which) -> (::JsiiCalc::Anonymous::IOptionA | ::JsiiCalc::Anonymous::IOptionB) +end + +class JsiiCalc::Cdk16625::Cdk16625 < ::Jsii::Object + def initialize: () -> void + def test: () -> void + def unwrap: (::JsiiCalc::IRandomNumberGenerator gen) -> Numeric +end + +class JsiiCalc::Cdk16625::Donotimport::UnimportedSubmoduleType < ::Jsii::Object + include ::JsiiCalc::IRandomNumberGenerator + def initialize: (Numeric value) -> void + def _next: () -> Numeric +end + +class JsiiCalc::Cdk22369::AcceptsPath < ::Jsii::Object + def initialize: (::JsiiCalc::Cdk22369::AcceptsPathProps props) -> void +end + +class JsiiCalc::Cdk22369::AcceptsPathProps < ::Jsii::Struct + def initialize: (source_path: String) -> void + attr_reader source_path: String +end + +module JsiiCalc::Composition::CompositeOperation::CompositionStringStyle + NORMAL: ::Jsii::Enum + DECORATED: ::Jsii::Enum +end + +module JsiiCalc::CovariantOverrides::ClassOverrides::IBase + attr_reader something: ::JsiiCalc::CovariantOverrides::ClassOverrides::Superclass +end + +class JsiiCalc::CovariantOverrides::ClassOverrides::Base < ::Jsii::Object + include ::JsiiCalc::CovariantOverrides::ClassOverrides::IBase + def initialize: () -> void + attr_reader list: Array[::JsiiCalc::CovariantOverrides::ClassOverrides::Superclass] + attr_reader something: ::JsiiCalc::CovariantOverrides::ClassOverrides::Superclass + def create_something: () -> ::JsiiCalc::CovariantOverrides::ClassOverrides::Superclass +end + +class JsiiCalc::CovariantOverrides::ClassOverrides::Middle < ::JsiiCalc::CovariantOverrides::ClassOverrides::Base + def initialize: () -> void + attr_reader list: Array[::JsiiCalc::CovariantOverrides::ClassOverrides::Superclass] + attr_reader something: ::JsiiCalc::CovariantOverrides::ClassOverrides::Superclass + attr_reader add_unrelated_member: Numeric + attr_writer add_unrelated_member: Numeric + def create_something: () -> ::JsiiCalc::CovariantOverrides::ClassOverrides::Superclass +end + +class JsiiCalc::CovariantOverrides::ClassOverrides::Derived < ::JsiiCalc::CovariantOverrides::ClassOverrides::Middle + def initialize: () -> void + attr_reader list: Array[::JsiiCalc::CovariantOverrides::ClassOverrides::Superclass] + attr_reader something: ::JsiiCalc::CovariantOverrides::ClassOverrides::SubSubclass + attr_reader add_unrelated_member: Numeric + attr_writer add_unrelated_member: Numeric + def create_something: () -> ::JsiiCalc::CovariantOverrides::ClassOverrides::SubSubclass +end + +class JsiiCalc::CovariantOverrides::ClassOverrides::Superclass < ::Jsii::Object + def initialize: () -> void + attr_reader name: String + attr_writer name: String + def say_hello: () -> String +end + +class JsiiCalc::CovariantOverrides::ClassOverrides::Subclass < ::JsiiCalc::CovariantOverrides::ClassOverrides::Superclass + def initialize: () -> void + attr_reader name: String + attr_writer name: String + def say_hello: () -> String +end + +class JsiiCalc::CovariantOverrides::ClassOverrides::SubSubclass < ::JsiiCalc::CovariantOverrides::ClassOverrides::Subclass + def initialize: () -> void + attr_reader name: String + attr_writer name: String + attr_reader unique: String + attr_writer unique: String + def say_hello: () -> String +end + +class JsiiCalc::HomonymousForwardReferences::Bar::Consumer < ::Jsii::Object + def self.consume: (::JsiiCalc::HomonymousForwardReferences::Bar::ConsumerProps props) -> ::JsiiCalc::HomonymousForwardReferences::Bar::Homonymous +end + +class JsiiCalc::HomonymousForwardReferences::Bar::ConsumerProps < ::Jsii::Struct + def initialize: (homonymous: ::JsiiCalc::HomonymousForwardReferences::Bar::Homonymous) -> void + attr_reader homonymous: ::JsiiCalc::HomonymousForwardReferences::Bar::Homonymous +end + +class JsiiCalc::HomonymousForwardReferences::Bar::Homonymous < ::Jsii::Struct + def initialize: (numeric_property: Numeric) -> void + attr_reader numeric_property: Numeric +end + +class JsiiCalc::HomonymousForwardReferences::Foo::Consumer < ::Jsii::Object + def self.consume: (::JsiiCalc::HomonymousForwardReferences::Foo::ConsumerProps props) -> ::JsiiCalc::HomonymousForwardReferences::Foo::Homonymous +end + +class JsiiCalc::HomonymousForwardReferences::Foo::ConsumerProps < ::Jsii::Struct + def initialize: (homonymous: ::JsiiCalc::HomonymousForwardReferences::Foo::Homonymous) -> void + attr_reader homonymous: ::JsiiCalc::HomonymousForwardReferences::Foo::Homonymous +end + +class JsiiCalc::HomonymousForwardReferences::Foo::Homonymous < ::Jsii::Struct + def initialize: (string_property: String) -> void + attr_reader string_property: String +end + +class JsiiCalc::Intersection::ConsumesIntersection < ::Jsii::Object + def initialize: (::JsiiCalc::Intersection::IntersectionProps props) -> void + def self.accepts_intersection: (untyped param) -> void + def self.accepts_prop_with_intersection: (::JsiiCalc::Intersection::IntersectionProps props) -> void +end + +module JsiiCalc::Intersection::ISomething + def something: () -> untyped +end + +class JsiiCalc::Intersection::IntersectionProps < ::Jsii::Struct + def initialize: (param: untyped) -> void + attr_reader param: untyped +end + +class JsiiCalc::Jsii3656::ImplementMeOpts < ::Jsii::Struct + def initialize: (name: String, ?count: Numeric?) -> void + attr_reader name: String + attr_reader count: Numeric? +end + +class JsiiCalc::Jsii3656::OverrideMe < ::Jsii::Object + def initialize: () -> void + def self.call_abstract: (::JsiiCalc::Jsii3656::OverrideMe receiver) -> bool + def implement_me: (::JsiiCalc::Jsii3656::ImplementMeOpts opts) -> bool +end + +class JsiiCalc::Jsii4894::NonPascalCaseTest < ::Jsii::Object + def initialize: (::JsiiCalc::Jsii4894::NonPascalCaseTestProps props) -> void + attr_reader props: ::JsiiCalc::Jsii4894::NonPascalCaseTestProps + attr_reader some_type: ::Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName::SomeType +end + +class JsiiCalc::Jsii4894::NonPascalCaseTestProps < ::Jsii::Struct + def initialize: (some_type: ::Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName::SomeType) -> void + attr_reader some_type: ::Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName::SomeType +end + +class JsiiCalc::Module2530::MyClass < ::Jsii::Object + def initialize: (Numeric _) -> void + def self.bar: (bool _) -> void + def foo: (String _) -> void + def multiple_underscores: (String _, String __, String ___) -> void +end + +class JsiiCalc::Module2617::OnlyStatics < ::Jsii::Object + def self.bar: () -> void + def self.foo: () -> void +end + +class JsiiCalc::Module2647::ExtendAndImplement < ::Scope::JsiiCalcLib::BaseFor2647 + include ::Scope::JsiiCalcLib::IFriendly + def initialize: (::Scope::JsiiCalcBaseOfBase::Very very) -> void + def foo: (::Scope::JsiiCalcBase::IBaseInterface obj) -> void + def hello: () -> String + def local_method: () -> String +end + +class JsiiCalc::Module2689::Methods::MyClass < ::Jsii::Object + def initialize: () -> void + def bar: (Hash[String, ::Scope::JsiiCalcBase::BaseProps] _bar) -> void + def foo: (Array[::Scope::JsiiCalcLib::Number] _values) -> void +end + +class JsiiCalc::Module2689::Props::MyClass < ::Jsii::Object + def initialize: () -> void + attr_reader bar: Hash[String, ::Scope::JsiiCalcBase::BaseProps] + attr_reader foo: Array[::Scope::JsiiCalcLib::Number] +end + +class JsiiCalc::Module2689::Retval::MyClass < ::Jsii::Object + def initialize: () -> void + def bar: () -> Hash[String, ::Scope::JsiiCalcBase::BaseProps] + def foo: () -> Array[::Scope::JsiiCalcLib::Number] +end + +class JsiiCalc::Module2689::Structs::MyStruct < ::Jsii::Struct + def initialize: (base_map: Hash[String, ::Scope::JsiiCalcBase::BaseProps], numbers: Array[::Scope::JsiiCalcLib::Number]) -> void + attr_reader base_map: Hash[String, ::Scope::JsiiCalcBase::BaseProps] + attr_reader numbers: Array[::Scope::JsiiCalcLib::Number] +end + +class JsiiCalc::Module2692::Submodule1::Bar < ::Jsii::Struct + def initialize: (bar1: String) -> void + attr_reader bar1: String +end + +class JsiiCalc::Module2692::Submodule2::Bar < ::Jsii::Struct + def initialize: (bar2: String) -> void + attr_reader bar2: String +end + +class JsiiCalc::Module2692::Submodule2::Foo < ::JsiiCalc::Module2692::Submodule2::Bar + def initialize: (bar2: String, bar1: String, foo2: String) -> void + attr_reader bar2: String + attr_reader bar1: String + attr_reader foo2: String +end + +module JsiiCalc::Module2700::IFoo + attr_reader baz: Numeric + def bar: () -> String +end + +class JsiiCalc::Module2700::Base < ::Jsii::Object + include ::JsiiCalc::Module2700::IFoo + def initialize: () -> void + attr_reader baz: Numeric + def bar: () -> String +end + +class JsiiCalc::Module2700::Derived < ::JsiiCalc::Module2700::Base + include ::JsiiCalc::Module2700::IFoo + def initialize: () -> void + attr_reader baz: Numeric + def bar: () -> String + def zoo: () -> String +end + +class JsiiCalc::Module2702::Class3 < ::Jsii::Object + include ::Scope::JsiiCalcBase::IBaseInterface + def initialize: () -> void + def bar: () -> void + def foo: () -> void + def i_base_interface: () -> void +end + +module JsiiCalc::Module2702::IBaz + def foo: () -> void + def bar: () -> void + def baz_method: () -> void +end + +class JsiiCalc::Module2702::Baz < ::JsiiCalc::Module2702::Class3 + include ::JsiiCalc::Module2702::IBaz + def initialize: () -> void + def bar: () -> void + def foo: () -> void + def i_base_interface: () -> void + def baz_method: () -> void +end + +class JsiiCalc::Module2702::Class1 < ::Scope::JsiiCalcBase::Base + def initialize: () -> void + def type_name: () -> untyped + def base: () -> void +end + +class JsiiCalc::Module2702::Class2 < ::Scope::JsiiCalcBase::Base + def initialize: () -> void + attr_reader base: String + def type_name: () -> untyped +end + +module JsiiCalc::Module2702::IConstruct + def construct_method: () -> void +end + +class JsiiCalc::Module2702::Construct < ::Jsii::Object + include ::JsiiCalc::Module2702::IConstruct + def initialize: () -> void + def construct_method: () -> void +end + +module JsiiCalc::Module2702::IFoo + attr_reader i_base_interface: String + def foo: () -> void + def bar: () -> void +end + +module JsiiCalc::Module2702::IResource + def construct_method: () -> void + def resource_method: () -> void +end + +module JsiiCalc::Module2702::IVpc + def construct_method: () -> void + def resource_method: () -> void + def vpc_method: () -> void +end + +class JsiiCalc::Module2702::Resource < ::JsiiCalc::Module2702::Construct + include ::JsiiCalc::Module2702::IResource + def initialize: () -> void + def construct_method: () -> void + def resource_method: () -> void +end + +class JsiiCalc::Module2702::Vpc < ::JsiiCalc::Module2702::Resource + include ::JsiiCalc::Module2702::IVpc + def initialize: () -> void + def construct_method: () -> void + def resource_method: () -> void + def vpc_method: () -> void +end + +class JsiiCalc::Nodirect::Sub1::TypeFromSub1 < ::Jsii::Object + def initialize: () -> void + def sub1: () -> String +end + +class JsiiCalc::Nodirect::Sub2::TypeFromSub2 < ::Jsii::Object + def initialize: () -> void + def sub2: () -> String +end + +class JsiiCalc::Onlystatic::OnlyStaticMethods < ::Jsii::Object + def self.static_method: () -> String +end + +class JsiiCalc::PascalCaseName::Superclass < ::Jsii::Object + def initialize: () -> void +end + +class JsiiCalc::PascalCaseName::Subclass < ::JsiiCalc::PascalCaseName::Superclass + def initialize: () -> void +end + +class JsiiCalc::PascalCaseName::SubSubclass < ::JsiiCalc::PascalCaseName::Subclass + def initialize: () -> void +end + +class JsiiCalc::Submodule::Default < ::Jsii::Struct + def initialize: (foo: Numeric) -> void + attr_reader foo: Numeric +end + +module JsiiCalc::Submodule::NestedSubmodule::DeeplyNested::INamespaced + attr_reader defined_at: String +end + +class JsiiCalc::Submodule::MyClass < ::Jsii::Object + include ::JsiiCalc::Submodule::NestedSubmodule::DeeplyNested::INamespaced + def initialize: (::JsiiCalc::Submodule::Child::SomeStruct props) -> void + attr_reader awesomeness: ::JsiiCalc::Submodule::Child::Awesomeness + attr_reader defined_at: String + attr_reader goodness: ::JsiiCalc::Submodule::Child::Goodness + attr_reader props: ::JsiiCalc::Submodule::Child::SomeStruct + attr_reader all_types: ::JsiiCalc::AllTypes? + attr_writer all_types: ::JsiiCalc::AllTypes? + def method_with_special_param: (::JsiiCalc::Submodule::Param::SpecialParameter param) -> String +end + +class JsiiCalc::Submodule::BackReferences::MyClassReference < ::Jsii::Struct + def initialize: (reference: ::JsiiCalc::Submodule::MyClass) -> void + attr_reader reference: ::JsiiCalc::Submodule::MyClass +end + +module JsiiCalc::Submodule::Child::Awesomeness + AWESOME: ::Jsii::Enum +end + +module JsiiCalc::Submodule::Child::Goodness + PRETTY_GOOD: ::Jsii::Enum + REALLY_GOOD: ::Jsii::Enum + AMAZINGLY_GOOD: ::Jsii::Enum +end + +class JsiiCalc::Submodule::Child::InnerClass < ::Jsii::Object + def initialize: () -> void + def self.STATIC_PROP: () -> ::JsiiCalc::Submodule::Child::SomeStruct +end + +class JsiiCalc::Submodule::Child::SomeStruct < ::Jsii::Struct + def initialize: (prop: ::JsiiCalc::Submodule::Child::SomeEnum) -> void + attr_reader prop: ::JsiiCalc::Submodule::Child::SomeEnum +end + +class JsiiCalc::Submodule::Child::KwargsProps < ::JsiiCalc::Submodule::Child::SomeStruct + def initialize: (prop: ::JsiiCalc::Submodule::Child::SomeEnum, ?extra: String?) -> void + attr_reader prop: ::JsiiCalc::Submodule::Child::SomeEnum + attr_reader extra: String? +end + +class JsiiCalc::Submodule::Child::OuterClass < ::Jsii::Object + def initialize: () -> void + attr_reader inner_class: ::JsiiCalc::Submodule::Child::InnerClass +end + +module JsiiCalc::Submodule::Child::SomeEnum + SOME: ::Jsii::Enum +end + +class JsiiCalc::Submodule::Child::Structure < ::Jsii::Struct + def initialize: (bool: bool) -> void + attr_reader bool: bool +end + +class JsiiCalc::Submodule::Isolated::Kwargs < ::Jsii::Object + def self.method: (?::JsiiCalc::Submodule::Child::KwargsProps? props) -> bool +end + +class JsiiCalc::Submodule::NestedSubmodule::Namespaced < ::Jsii::Object + include ::JsiiCalc::Submodule::NestedSubmodule::DeeplyNested::INamespaced + attr_reader defined_at: String + attr_reader goodness: ::JsiiCalc::Submodule::Child::Goodness +end + +class JsiiCalc::Submodule::Param::SpecialParameter < ::Jsii::Struct + def initialize: (value: String) -> void + attr_reader value: String +end + +class JsiiCalc::Submodule::Returnsparam::ReturnsSpecialParameter < ::Jsii::Object + def initialize: () -> void + def returns_special_param: () -> ::JsiiCalc::Submodule::Param::SpecialParameter +end + +class JsiiCalc::Union::ConsumesUnion < ::Jsii::Object + def self.union_type: ((::Scope::JsiiCalcLib::IFriendly | ::JsiiCalc::Union::IResolvable | ::JsiiCalc::Union::Resolvable) param) -> void +end + +module JsiiCalc::Union::IResolvable + def resolve: () -> untyped +end + +class JsiiCalc::Union::Resolvable < ::Jsii::Object + include ::JsiiCalc::Union::IResolvable + def resolve: () -> untyped +end + + +`; + +exports[`Generated code for "jsii-calc": / 1`] = ` + + ┗━ 📁 ruby + ┗━ 📁 lib + ┗━ 📁 jsii-calc + ┣━ 📄 abstract_class.rb.diff + ┣━ 📄 abstract_suite.rb.diff + ┣━ 📄 add.rb.diff + ┣━ 📄 all_types.rb.diff + ┣━ 📄 allowed_method_names.rb.diff + ┣━ 📄 ambiguous_parameters.rb.diff + ┣━ 📁 anonymous + ┃ ┗━ 📄 use_options.rb.diff + ┣━ 📄 any_property_access.rb.diff + ┣━ 📄 async_virtual_methods.rb.diff + ┣━ 📄 bell.rb.diff + ┣━ 📄 binary_operation.rb.diff + ┣━ 📄 burried_anonymous_object.rb.diff + ┣━ 📄 calculator_props.rb.diff + ┣━ 📄 calculator.rb.diff + ┣━ 📁 cdk16625 + ┃ ┣━ 📄 cdk16625.rb.diff + ┃ ┗━ 📁 donotimport + ┃ ┗━ 📄 unimported_submodule_type.rb.diff + ┣━ 📁 cdk22369 + ┃ ┣━ 📄 accepts_path_props.rb.diff + ┃ ┗━ 📄 accepts_path.rb.diff + ┣━ 📄 child_struct982.rb.diff + ┣━ 📄 class_that_implements_the_internal_interface.rb.diff + ┣━ 📄 class_that_implements_the_private_interface.rb.diff + ┣━ 📄 class_with_collection_of_unions.rb.diff + ┣━ 📄 class_with_collections.rb.diff + ┣━ 📄 class_with_container_types.rb.diff + ┣━ 📄 class_with_java_reserved_words.rb.diff + ┣━ 📄 class_with_mutable_object_literal_property.rb.diff + ┣━ 📄 class_with_nested_union.rb.diff + ┣━ 📄 class_with_private_constructor_and_automatic_properties.rb.diff + ┣━ 📁 composition + ┃ ┗━ 📄 composite_operation.rb.diff + ┣━ 📄 confusing_to_jackson_struct.rb.diff + ┣━ 📄 confusing_to_jackson.rb.diff + ┣━ 📄 constructor_passes_this_out.rb.diff + ┣━ 📄 consume_pure_interface.rb.diff + ┣━ 📄 consumer_can_ring_bell.rb.diff + ┣━ 📄 consumers_of_this_crazy_type_system.rb.diff + ┣━ 📄 container_props.rb.diff + ┣━ 📁 covariant_overrides + ┃ ┗━ 📁 class_overrides + ┃ ┣━ 📄 derived.rb.diff + ┃ ┣━ 📄 middle.rb.diff + ┃ ┣━ 📄 sub_subclass.rb.diff + ┃ ┣━ 📄 subclass.rb.diff + ┃ ┗━ 📄 superclass.rb.diff + ┣━ 📄 data_renderer.rb.diff + ┣━ 📄 defaulted_constructor_argument.rb.diff + ┣━ 📄 deprecated_class.rb.diff + ┣━ 📄 deprecated_struct.rb.diff + ┣━ 📁 derived_class_has_no_properties + ┃ ┣━ 📄 base.rb.diff + ┃ ┗━ 📄 derived.rb.diff + ┣━ 📄 derived_struct.rb.diff + ┣━ 📄 diamond_bottom.rb.diff + ┣━ 📄 diamond_inheritance_base_level_struct.rb.diff + ┣━ 📄 diamond_inheritance_first_mid_level_struct.rb.diff + ┣━ 📄 diamond_inheritance_second_mid_level_struct.rb.diff + ┣━ 📄 diamond_inheritance_top_level_struct.rb.diff + ┣━ 📄 do_not_override_privates.rb.diff + ┣━ 📄 do_not_recognize_any_as_optional.rb.diff + ┣━ 📄 documented_class.rb.diff + ┣━ 📄 dont_complain_about_variadic_after_optional.rb.diff + ┣━ 📄 dont_use_me.rb.diff + ┣━ 📄 dummy_obj.rb.diff + ┣━ 📄 dynamic_property_bearer_child.rb.diff + ┣━ 📄 dynamic_property_bearer.rb.diff + ┣━ 📄 entropy.rb.diff + ┣━ 📄 erase_undefined_hash_values_options.rb.diff + ┣━ 📄 erase_undefined_hash_values.rb.diff + ┣━ 📄 experimental_class.rb.diff + ┣━ 📄 experimental_struct.rb.diff + ┣━ 📄 exported_base_class.rb.diff + ┣━ 📄 extends_internal_interface.rb.diff + ┣━ 📄 external_class.rb.diff + ┣━ 📄 external_struct.rb.diff + ┣━ 📄 give_me_structs.rb.diff + ┣━ 📄 greetee.rb.diff + ┣━ 📄 greeting_augmenter.rb.diff + ┣━ 📁 homonymous_forward_references + ┃ ┣━ 📁 bar + ┃ ┃ ┣━ 📄 consumer_props.rb.diff + ┃ ┃ ┣━ 📄 consumer.rb.diff + ┃ ┃ ┗━ 📄 homonymous.rb.diff + ┃ ┗━ 📁 foo + ┃ ┣━ 📄 consumer_props.rb.diff + ┃ ┣━ 📄 consumer.rb.diff + ┃ ┗━ 📄 homonymous.rb.diff + ┣━ 📄 i_another_public_interface.rb.diff + ┣━ 📄 i_bell_ringer.rb.diff + ┣━ 📄 i_concrete_bell_ringer.rb.diff + ┣━ 📄 i_deprecated_interface.rb.diff + ┣━ 📄 i_experimental_interface.rb.diff + ┣━ 📄 i_extends_private_interface.rb.diff + ┣━ 📄 i_external_interface.rb.diff + ┣━ 📄 i_interface_with_optional_method_arguments.rb.diff + ┣━ 📄 i_interface_with_properties_extension.rb.diff + ┣━ 📄 i_interface_with_properties.rb.diff + ┣━ 📄 i_mutable_object_literal.rb.diff + ┣━ 📄 i_non_internal_interface.rb.diff + ┣━ 📄 i_object_with_property.rb.diff + ┣━ 📄 i_stable_interface.rb.diff + ┣━ 📄 implement_internal_interface.rb.diff + ┣━ 📄 implements_private_interface.rb.diff + ┣━ 📄 implict_base_of_base.rb.diff + ┣━ 📁 interface_in_namespace_includes_classes + ┃ ┣━ 📄 foo.rb.diff + ┃ ┗━ 📄 hello.rb.diff + ┣━ 📁 interface_in_namespace_only_interface + ┃ ┗━ 📄 hello.rb.diff + ┣━ 📄 interfaces_maker.rb.diff + ┣━ 📁 intersection + ┃ ┣━ 📄 consumes_intersection.rb.diff + ┃ ┗━ 📄 intersection_props.rb.diff + ┣━ 📄 java_reserved_words.rb.diff + ┣━ 📄 js_object_literal_to_native_class.rb.diff + ┣━ 📁 jsii3656 + ┃ ┣━ 📄 implement_me_opts.rb.diff + ┃ ┗━ 📄 override_me.rb.diff + ┣━ 📄 jsii417_derived.rb.diff + ┣━ 📁 jsii4894 + ┃ ┣━ 📄 non_pascal_case_test_props.rb.diff + ┃ ┗━ 📄 non_pascal_case_test.rb.diff + ┣━ 📄 json_formatter.rb.diff + ┣━ 📄 level_one_props.rb.diff + ┣━ 📄 level_one.rb.diff + ┣━ 📄 load_balanced_fargate_service_props.rb.diff + ┣━ 📁 module2530 + ┃ ┗━ 📄 my_class.rb.diff + ┣━ 📁 module2647 + ┃ ┗━ 📄 extend_and_implement.rb.diff + ┣━ 📁 module2689 + ┃ ┣━ 📁 methods + ┃ ┃ ┗━ 📄 my_class.rb.diff + ┃ ┗━ 📁 structs + ┃ ┗━ 📄 my_struct.rb.diff + ┣━ 📁 module2692 + ┃ ┣━ 📁 submodule1 + ┃ ┃ ┗━ 📄 bar.rb.diff + ┃ ┗━ 📁 submodule2 + ┃ ┣━ 📄 bar.rb.diff + ┃ ┗━ 📄 foo.rb.diff + ┣━ 📄 multiply.rb.diff + ┣━ 📄 negate.rb.diff + ┣━ 📄 nested_struct.rb.diff + ┣━ 📄 null_should_be_treated_as_undefined_data.rb.diff + ┣━ 📄 null_should_be_treated_as_undefined.rb.diff + ┣━ 📄 number_generator.rb.diff + ┣━ 📄 object_refs_in_collections.rb.diff + ┣━ 📄 optional_argument_invoker.rb.diff + ┣━ 📄 optional_constructor_argument.rb.diff + ┣━ 📄 optional_struct_consumer.rb.diff + ┣━ 📄 optional_struct.rb.diff + ┣━ 📄 overridable_protected_member.rb.diff + ┣━ 📄 override_returns_object.rb.diff + ┣━ 📄 param_shadows_builtins_props.rb.diff + ┣━ 📄 param_shadows_builtins.rb.diff + ┣━ 📄 param_shadows_scope.rb.diff + ┣━ 📄 parent_struct982.rb.diff + ┣━ 📄 partially_initialized_this_consumer.rb.diff + ┣━ 📄 polymorphism.rb.diff + ┣━ 📄 power.rb.diff + ┣━ 📁 python_self + ┃ ┣━ 📄 class_with_self_kwarg.rb.diff + ┃ ┣━ 📄 class_with_self.rb.diff + ┃ ┣━ 📄 i_interface_with_self.rb.diff + ┃ ┗━ 📄 struct_with_self.rb.diff + ┣━ 📄 reference_enum_from_scoped_package.rb.diff + ┣━ 📄 root_struct_validator.rb.diff + ┣━ 📄 root_struct.rb.diff + ┣━ 📄 runtime_type_checking.rb.diff + ┣━ 📄 second_level_struct.rb.diff + ┣━ 📄 singleton_int.rb.diff + ┣━ 📄 singleton_string.rb.diff + ┣━ 📄 smelly_struct.rb.diff + ┣━ 📄 some_containing_class.rb.diff + ┣━ 📄 stable_class.rb.diff + ┣━ 📄 stable_struct.rb.diff + ┣━ 📄 static_context.rb.diff + ┣━ 📄 statics.rb.diff + ┣━ 📄 strip_internal.rb.diff + ┣━ 📄 struct_a.rb.diff + ┣━ 📄 struct_b.rb.diff + ┣━ 📄 struct_parameter_type.rb.diff + ┣━ 📄 struct_passing.rb.diff + ┣━ 📄 struct_union_consumer.rb.diff + ┣━ 📄 struct_with_collection_of_unionts.rb.diff + ┣━ 📄 struct_with_enum.rb.diff + ┣━ 📄 struct_with_java_reserved_words.rb.diff + ┣━ 📁 submodule + ┃ ┣━ 📁 back_references + ┃ ┃ ┗━ 📄 my_class_reference.rb.diff + ┃ ┣━ 📁 child + ┃ ┃ ┣━ 📄 kwargs_props.rb.diff + ┃ ┃ ┣━ 📄 some_struct.rb.diff + ┃ ┃ ┗━ 📄 structure.rb.diff + ┃ ┣━ 📄 default.rb.diff + ┃ ┣━ 📁 isolated + ┃ ┃ ┗━ 📄 kwargs.rb.diff + ┃ ┣━ 📄 my_class.rb.diff + ┃ ┗━ 📁 param + ┃ ┗━ 📄 special_parameter.rb.diff + ┣━ 📄 sum.rb.diff + ┣━ 📄 supports_nice_java_builder_props.rb.diff + ┣━ 📄 supports_nice_java_builder_with_required_props.rb.diff + ┣━ 📄 supports_nice_java_builder.rb.diff + ┣━ 📄 sync_virtual_methods.rb.diff + ┣━ 📄 test_struct_with_enum.rb.diff + ┣━ 📄 top_level_struct.rb.diff + ┣━ 📄 unary_operation.rb.diff + ┣━ 📁 union + ┃ ┗━ 📄 consumes_union.rb.diff + ┣━ 📄 union_properties.rb.diff + ┣━ 📄 upcasing_reflectable.rb.diff + ┣━ 📄 uses_interface_with_properties.rb.diff + ┣━ 📄 variadic_invoker.rb.diff + ┣━ 📄 variadic_method.rb.diff + ┣━ 📄 variadic_type_union.rb.diff + ┣━ 📄 virtual_method_playground.rb.diff + ┣━ 📄 weird_docs.rb.diff + ┗━ 📄 with_private_property_in_constructor.rb.diff +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/abstract_class.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/abstract_class.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/abstract_class.rb --runtime-type-checking +@@ -29,10 +29,11 @@ + end + + # @param name [String] + # @return [String] + def abstract_method(name) ++ Jsii::Type.check_type(name, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "name") + jsii_call_method("abstractMethod", [name]) + end + + # @return [Numeric] + def non_abstract_method() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/abstract_suite.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/abstract_suite.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/abstract_suite.rb --runtime-type-checking +@@ -21,24 +21,27 @@ + def property() + jsii_get_property("property") + end + + def property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "property") + jsii_set_property("property", value) + end + + # @param str [String] + # @return [String] + def some_method(str) ++ Jsii::Type.check_type(str, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "str") + jsii_call_method("someMethod", [str]) + end + + # Sets \`seed\` to \`this.property\`, then calls \`someMethod\` with \`this.property\` and returns the result. + # + # @param seed [String] a \`string\`. + # @return [String] + def work_it_all(seed) ++ Jsii::Type.check_type(seed, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "seed") + jsii_call_method("workItAll", [seed]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/add.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/add.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/add.rb --runtime-type-checking +@@ -8,10 +8,12 @@ + # Creates a BinaryOperation. + # + # @param lhs [Scope::JsiiCalcLib::NumericValue] Left-hand side operand. + # @param rhs [Scope::JsiiCalcLib::NumericValue] Right-hand side operand. + def initialize(lhs, rhs) ++ Jsii::Type.check_type(lhs, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1lcmljVmFsdWUifQ==")), "lhs") ++ Jsii::Type.check_type(rhs, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1lcmljVmFsdWUifQ==")), "rhs") + Jsii::Object.instance_method(:initialize).bind(self).call(lhs, rhs) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/all_types.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/all_types.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/all_types.rb --runtime-type-checking +@@ -48,169 +48,188 @@ + def any_array_property() + jsii_get_property("anyArrayProperty") + end + + def any_array_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6ImFueSJ9LCJraW5kIjoiYXJyYXkifX0=")), "anyArrayProperty") + jsii_set_property("anyArrayProperty", value) + end + + # @return [Hash{String => Object}] + def any_map_property() + jsii_get_property("anyMapProperty") + end + + def any_map_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6ImFueSJ9LCJraW5kIjoibWFwIn19")), "anyMapProperty") + jsii_set_property("anyMapProperty", value) + end + + # @return [Object] + def any_property() + jsii_get_property("anyProperty") + end + + def any_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "anyProperty") + jsii_set_property("anyProperty", value) + end + + # @return [Array] + def array_property() + jsii_get_property("arrayProperty") + end + + def array_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "arrayProperty") + jsii_set_property("arrayProperty", value) + end + + # @return [Boolean] + def boolean_property() + jsii_get_property("booleanProperty") + end + + def boolean_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "booleanProperty") + jsii_set_property("booleanProperty", value) + end + + # @return [DateTime] + def date_property() + jsii_get_property("dateProperty") + end + + def date_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJkYXRlIn0=")), "dateProperty") + jsii_set_property("dateProperty", value) + end + + # @return [JsiiCalc::AllTypesEnum] + def enum_property() + jsii_get_property("enumProperty") + end + + def enum_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuQWxsVHlwZXNFbnVtIn0=")), "enumProperty") + jsii_set_property("enumProperty", value) + end + + # @return [Hash] + def json_property() + jsii_get_property("jsonProperty") + end + + def json_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJqc29uIn0=")), "jsonProperty") + jsii_set_property("jsonProperty", value) + end + + # @return [Hash{String => Scope::JsiiCalcLib::Number}] + def map_property() + jsii_get_property("mapProperty") + end + + def map_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6IkBzY29wZS9qc2lpLWNhbGMtbGliLk51bWJlciJ9LCJraW5kIjoibWFwIn19")), "mapProperty") + jsii_set_property("mapProperty", value) + end + + # @return [Numeric] + def number_property() + jsii_get_property("numberProperty") + end + + def number_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "numberProperty") + jsii_set_property("numberProperty", value) + end + + # @return [String] + def string_property() + jsii_get_property("stringProperty") + end + + def string_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "stringProperty") + jsii_set_property("stringProperty", value) + end + + # @return [Array] + def union_array_property() + jsii_get_property("unionArrayProperty") + end + + def union_array_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InVuaW9uIjp7InR5cGVzIjpbeyJwcmltaXRpdmUiOiJudW1iZXIifSx7ImZxbiI6IkBzY29wZS9qc2lpLWNhbGMtbGliLk51bWVyaWNWYWx1ZSJ9XX19LCJraW5kIjoiYXJyYXkifX0=")), "unionArrayProperty") + jsii_set_property("unionArrayProperty", value) + end + + # @return [Hash{String => String, Numeric, Scope::JsiiCalcLib::Number}] + def union_map_property() + jsii_get_property("unionMapProperty") + end + + def union_map_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InVuaW9uIjp7InR5cGVzIjpbeyJwcmltaXRpdmUiOiJzdHJpbmcifSx7InByaW1pdGl2ZSI6Im51bWJlciJ9LHsiZnFuIjoiQHNjb3BlL2pzaWktY2FsYy1saWIuTnVtYmVyIn1dfX0sImtpbmQiOiJtYXAifX0=")), "unionMapProperty") + jsii_set_property("unionMapProperty", value) + end + + # @return [String, Numeric, Scope::JsiiCalcLib::Number, JsiiCalc::Multiply] + def union_property() + jsii_get_property("unionProperty") + end + + def union_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJ1bmlvbiI6eyJ0eXBlcyI6W3sicHJpbWl0aXZlIjoic3RyaW5nIn0seyJwcmltaXRpdmUiOiJudW1iZXIifSx7ImZxbiI6IkBzY29wZS9qc2lpLWNhbGMtbGliLk51bWJlciJ9LHsiZnFuIjoianNpaS1jYWxjLk11bHRpcGx5In1dfX0=")), "unionProperty") + jsii_set_property("unionProperty", value) + end + + # @return [Array] + def unknown_array_property() + jsii_get_property("unknownArrayProperty") + end + + def unknown_array_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6ImFueSJ9LCJraW5kIjoiYXJyYXkifX0=")), "unknownArrayProperty") + jsii_set_property("unknownArrayProperty", value) + end + + # @return [Hash{String => Object}] + def unknown_map_property() + jsii_get_property("unknownMapProperty") + end + + def unknown_map_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6ImFueSJ9LCJraW5kIjoibWFwIn19")), "unknownMapProperty") + jsii_set_property("unknownMapProperty", value) + end + + # @return [Object] + def unknown_property() + jsii_get_property("unknownProperty") + end + + def unknown_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "unknownProperty") + jsii_set_property("unknownProperty", value) + end + + # @return [JsiiCalc::StringEnum, nil] + def optional_enum_value() + jsii_get_property("optionalEnumValue") + end + + def optional_enum_value=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuU3RyaW5nRW51bSJ9")), "optionalEnumValue") unless value.nil? + jsii_set_property("optionalEnumValue", value) + end + + # @param inp [Object] + # @return [void] + def any_in(inp) ++ Jsii::Type.check_type(inp, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "inp") + jsii_call_method("anyIn", [inp]) + end + + # @return [Object] + def any_out() +@@ -218,10 +237,11 @@ + end + + # @param value [JsiiCalc::StringEnum] + # @return [JsiiCalc::StringEnum] + def enum_method(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuU3RyaW5nRW51bSJ9")), "value") + jsii_call_method("enumMethod", [value]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/allowed_method_names.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/allowed_method_names.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/allowed_method_names.rb --runtime-type-checking +@@ -19,35 +19,43 @@ + + # @param _p1 [String] + # @param _p2 [Numeric] + # @return [void] + def get_bar(_p1, _p2) ++ Jsii::Type.check_type(_p1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "_p1") ++ Jsii::Type.check_type(_p2, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "_p2") + jsii_call_method("getBar", [_p1, _p2]) + end + + # getXxx() is not allowed (see negatives), but getXxx(a, ...) is okay. + # + # @param with_param [String] + # @return [String] + def get_foo(with_param) ++ Jsii::Type.check_type(with_param, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "withParam") + jsii_call_method("getFoo", [with_param]) + end + + # @param _x [String] + # @param _y [Numeric] + # @param _z [Boolean] + # @return [void] + def set_bar(_x, _y, _z) ++ Jsii::Type.check_type(_x, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "_x") ++ Jsii::Type.check_type(_y, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "_y") ++ Jsii::Type.check_type(_z, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "_z") + jsii_call_method("setBar", [_x, _y, _z]) + end + + # setFoo(x) is not allowed (see negatives), but setXxx(a, b, ...) is okay. + # + # @param _x [String] + # @param _y [Numeric] + # @return [void] + def set_foo(_x, _y) ++ Jsii::Type.check_type(_x, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "_x") ++ Jsii::Type.check_type(_y, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "_y") + jsii_call_method("setFoo", [_x, _y]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/ambiguous_parameters.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/ambiguous_parameters.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/ambiguous_parameters.rb --runtime-type-checking +@@ -6,10 +6,12 @@ + + # @param scope [JsiiCalc::Bell] + # @param props [JsiiCalc::StructParameterType] + def initialize(scope, props) + props = props.is_a?(Hash) ? ::JsiiCalc::StructParameterType.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(scope, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuQmVsbCJ9")), "scope") ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0UGFyYW1ldGVyVHlwZSJ9")), "props") + Jsii::Object.instance_method(:initialize).bind(self).call(scope, props) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/anonymous/use_options.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/anonymous/use_options.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/anonymous/use_options.rb --runtime-type-checking +@@ -14,22 +14,25 @@ + end + + # @param option [JsiiCalc::Anonymous::IOptionA, JsiiCalc::Anonymous::IOptionB] + # @return [String] + def self.consume(option) ++ Jsii::Type.check_type(option, JSON.parse(Base64.strict_decode64("eyJ1bmlvbiI6eyJ0eXBlcyI6W3siZnFuIjoianNpaS1jYWxjLmFub255bW91cy5JT3B0aW9uQSJ9LHsiZnFuIjoianNpaS1jYWxjLmFub255bW91cy5JT3B0aW9uQiJ9XX19")), "option") + Jsii::Kernel.instance.call_static("jsii-calc.anonymous.UseOptions", "consume", [option]) + end + + # @param which [String] + # @return [Object] + def self.privide_as_any(which) ++ Jsii::Type.check_type(which, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "which") + Jsii::Kernel.instance.call_static("jsii-calc.anonymous.UseOptions", "privideAsAny", [which]) + end + + # @param which [String] + # @return [JsiiCalc::Anonymous::IOptionA, JsiiCalc::Anonymous::IOptionB] + def self.provide(which) ++ Jsii::Type.check_type(which, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "which") + Jsii::Kernel.instance.call_static("jsii-calc.anonymous.UseOptions", "provide", [which]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/any_property_access.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/any_property_access.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/any_property_access.rb --runtime-type-checking +@@ -19,10 +19,14 @@ + # @param prop_a [String] the first property to read. + # @param prop_b [String] the second property to read. + # @param result_prop [String] the property to write into. + # @return [void] + def self.mutate_properties(obj, prop_a, prop_b, result_prop) ++ Jsii::Type.check_type(obj, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "obj") ++ Jsii::Type.check_type(prop_a, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "propA") ++ Jsii::Type.check_type(prop_b, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "propB") ++ Jsii::Type.check_type(result_prop, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "resultProp") + Jsii::Kernel.instance.call_static("jsii-calc.AnyPropertyAccess", "mutateProperties", [obj, prop_a, prop_b, result_prop]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/async_virtual_methods.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/async_virtual_methods.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/async_virtual_methods.rb --runtime-type-checking +@@ -48,10 +48,11 @@ + end + + # @param mult [Numeric] + # @return [Numeric] + def override_me(mult) ++ Jsii::Type.check_type(mult, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mult") + jsii_async_call_method("overrideMe", [mult]) + end + + # @return [Numeric] + def override_me_too() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/bell.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/bell.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/bell.rb --runtime-type-checking +@@ -20,10 +20,11 @@ + def rung() + jsii_get_property("rung") + end + + def rung=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "rung") + jsii_set_property("rung", value) + end + + # @return [void] + def ring() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/binary_operation.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/binary_operation.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/binary_operation.rb --runtime-type-checking +@@ -9,10 +9,12 @@ + # Creates a BinaryOperation. + # + # @param lhs [Scope::JsiiCalcLib::NumericValue] Left-hand side operand. + # @param rhs [Scope::JsiiCalcLib::NumericValue] Right-hand side operand. + def initialize(lhs, rhs) ++ Jsii::Type.check_type(lhs, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1lcmljVmFsdWUifQ==")), "lhs") ++ Jsii::Type.check_type(rhs, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1lcmljVmFsdWUifQ==")), "rhs") + Jsii::Object.instance_method(:initialize).bind(self).call(lhs, rhs) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/burried_anonymous_object.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/burried_anonymous_object.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/burried_anonymous_object.rb --runtime-type-checking +@@ -24,10 +24,11 @@ + # Implement this method and have it return it's parameter. + # + # @param value [Object] the value that should be returned. + # @return [Object] \`value\` + def give_it_back(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "value") + jsii_call_method("giveItBack", [value]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/calculator.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/calculator.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/calculator.rb --runtime-type-checking +@@ -25,10 +25,11 @@ + # Creates a Calculator object. + # + # @param props [JsiiCalc::CalculatorProps, nil] Initialization properties. + def initialize(props = nil) + props = props.is_a?(Hash) ? ::JsiiCalc::CalculatorProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuQ2FsY3VsYXRvclByb3BzIn0=")), "props") unless props.nil? + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { +@@ -72,10 +73,11 @@ + def decoration_postfixes() + jsii_get_property("decorationPostfixes") + end + + def decoration_postfixes=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "decorationPostfixes") + jsii_set_property("decorationPostfixes", value) + end + + # A set of prefixes to include in a decorated .toString(). + # +@@ -83,10 +85,11 @@ + def decoration_prefixes() + jsii_get_property("decorationPrefixes") + end + + def decoration_prefixes=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "decorationPrefixes") + jsii_set_property("decorationPrefixes", value) + end + + # The .toString() style. + # +@@ -94,10 +97,11 @@ + def string_style() + jsii_get_property("stringStyle") + end + + def string_style=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuY29tcG9zaXRpb24uQ29tcG9zaXRlT3BlcmF0aW9uLkNvbXBvc2l0aW9uU3RyaW5nU3R5bGUifQ==")), "stringStyle") + jsii_set_property("stringStyle", value) + end + + # A log of all operations. + # +@@ -119,10 +123,11 @@ + def curr() + jsii_get_property("curr") + end + + def curr=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1lcmljVmFsdWUifQ==")), "curr") + jsii_set_property("curr", value) + end + + # The maximum value allows in this calculator. + # +@@ -130,10 +135,11 @@ + def max_value() + jsii_get_property("maxValue") + end + + def max_value=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "maxValue") unless value.nil? + jsii_set_property("maxValue", value) + end + + # Example of a property that accepts a union of types. + # +@@ -141,10 +147,11 @@ + def union_property() + jsii_get_property("unionProperty") + end + + def union_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJ1bmlvbiI6eyJ0eXBlcyI6W3siZnFuIjoianNpaS1jYWxjLkFkZCJ9LHsiZnFuIjoianNpaS1jYWxjLk11bHRpcGx5In0seyJmcW4iOiJqc2lpLWNhbGMuUG93ZXIifV19fQ==")), "unionProperty") unless value.nil? + jsii_set_property("unionProperty", value) + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() +@@ -161,18 +168,20 @@ + # Adds a number to the current value. + # + # @param value [Numeric] + # @return [void] + def add(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "value") + jsii_call_method("add", [value]) + end + + # Multiplies the current value by a number. + # + # @param value [Numeric] + # @return [void] + def mul(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "value") + jsii_call_method("mul", [value]) + end + + # Negates the current value. + # +@@ -184,10 +193,11 @@ + # Raises the current value by a power. + # + # @param value [Numeric] + # @return [void] + def pow(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "value") + jsii_call_method("pow", [value]) + end + + # Returns teh value of the union property (if defined). + # +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/calculator_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/calculator_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/calculator_props.rb --runtime-type-checking +@@ -6,11 +6,13 @@ + + # @param initial_value [Numeric, nil] The initial value of the calculator. + # @param maximum_value [Numeric, nil] The maximum value the calculator can store. + def initialize(initial_value: nil, maximum_value: nil) + @initial_value = initial_value ++ Jsii::Type.check_type(@initial_value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "initialValue") unless @initial_value.nil? + @maximum_value = maximum_value ++ Jsii::Type.check_type(@maximum_value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "maximumValue") unless @maximum_value.nil? + end + + # The initial value of the calculator. + # + # NOTE: Any number works here, it's fine. +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/cdk16625/cdk16625.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/cdk16625/cdk16625.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/cdk16625/cdk16625.rb --runtime-type-checking +@@ -26,10 +26,11 @@ + # + # @param gen [JsiiCalc::IRandomNumberGenerator] a VERY pseudo random number generator. + # @return [Numeric] + def unwrap(gen) + gen = Jsii::Utils.coerce_callable(gen, ::JsiiCalc::IRandomNumberGenerator) ++ Jsii::Type.check_type(gen, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSVJhbmRvbU51bWJlckdlbmVyYXRvciJ9")), "gen") + jsii_call_method("unwrap", [gen]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/cdk16625/donotimport/unimported_submodule_type.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/cdk16625/donotimport/unimported_submodule_type.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/cdk16625/donotimport/unimported_submodule_type.rb --runtime-type-checking +@@ -12,10 +12,11 @@ + self.jsii_fqn = "jsii-calc.cdk16625.donotimport.UnimportedSubmoduleType" + Jsii::Object.register_jsii_fqn("jsii-calc.cdk16625.donotimport.UnimportedSubmoduleType", self) + + # @param value [Numeric] + def initialize(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "value") + Jsii::Object.instance_method(:initialize).bind(self).call(value) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/cdk22369/accepts_path.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/cdk22369/accepts_path.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/cdk22369/accepts_path.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.cdk22369.AcceptsPath", self) + + # @param props [JsiiCalc::Cdk22369::AcceptsPathProps] + def initialize(props) + props = props.is_a?(Hash) ? ::JsiiCalc::Cdk22369::AcceptsPathProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuY2RrMjIzNjkuQWNjZXB0c1BhdGhQcm9wcyJ9")), "props") + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/cdk22369/accepts_path_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/cdk22369/accepts_path_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/cdk22369/accepts_path_props.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.cdk22369.AcceptsPathProps", self) + + # @param source_path [String] A path that doesn't exist. + def initialize(source_path:) + @source_path = source_path ++ Jsii::Type.check_type(@source_path, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "sourcePath") + end + + # A path that doesn't exist. + # + # @return [String] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/child_struct982.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/child_struct982.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/child_struct982.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param foo [String] + # @param bar [Numeric] + def initialize(foo:, bar:) + @foo = foo ++ Jsii::Type.check_type(@foo, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "foo") + @bar = bar ++ Jsii::Type.check_type(@bar, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "bar") + end + + # @return [String] + attr_reader :foo + # @return [Numeric] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_that_implements_the_internal_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/class_that_implements_the_internal_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/class_that_implements_the_internal_interface.rb --runtime-type-checking +@@ -22,37 +22,41 @@ + def a() + jsii_get_property("a") + end + + def a=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "a") + jsii_set_property("a", value) + end + + # @return [String] + def b() + jsii_get_property("b") + end + + def b=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "b") + jsii_set_property("b", value) + end + + # @return [String] + def c() + jsii_get_property("c") + end + + def c=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "c") + jsii_set_property("c", value) + end + + # @return [String] + def d() + jsii_get_property("d") + end + + def d=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "d") + jsii_set_property("d", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_that_implements_the_private_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/class_that_implements_the_private_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/class_that_implements_the_private_interface.rb --runtime-type-checking +@@ -22,37 +22,41 @@ + def a() + jsii_get_property("a") + end + + def a=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "a") + jsii_set_property("a", value) + end + + # @return [String] + def b() + jsii_get_property("b") + end + + def b=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "b") + jsii_set_property("b", value) + end + + # @return [String] + def c() + jsii_get_property("c") + end + + def c=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "c") + jsii_set_property("c", value) + end + + # @return [String] + def e() + jsii_get_property("e") + end + + def e=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "e") + jsii_set_property("e", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_collection_of_unions.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/class_with_collection_of_unions.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/class_with_collection_of_unions.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + self.jsii_fqn = "jsii-calc.ClassWithCollectionOfUnions" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassWithCollectionOfUnions", self) + + # @param union_property [Array JsiiCalc::StructA, JsiiCalc::StructB}>] + def initialize(union_property) ++ Jsii::Type.check_type(union_property, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImNvbGxlY3Rpb24iOnsiZWxlbWVudHR5cGUiOnsidW5pb24iOnsidHlwZXMiOlt7ImZxbiI6ImpzaWktY2FsYy5TdHJ1Y3RBIn0seyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0QiJ9XX19LCJraW5kIjoibWFwIn19LCJraW5kIjoiYXJyYXkifX0=")), "unionProperty") + Jsii::Object.instance_method(:initialize).bind(self).call(union_property) + end + + def self.jsii_overridable_methods + { +@@ -17,25 +18,28 @@ + end + + # @param param [Hash{String => JsiiCalc::StructA, JsiiCalc::StructB}] + # @return [void] + def self.static_method_with_map_of_unions_param(param) ++ Jsii::Type.check_type(param, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InVuaW9uIjp7InR5cGVzIjpbeyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0QSJ9LHsiZnFuIjoianNpaS1jYWxjLlN0cnVjdEIifV19fSwia2luZCI6Im1hcCJ9fQ==")), "param") + Jsii::Kernel.instance.call_static("jsii-calc.ClassWithCollectionOfUnions", "staticMethodWithMapOfUnionsParam", [param]) + end + + # @return [Array JsiiCalc::StructA, JsiiCalc::StructB}>] + def union_property() + jsii_get_property("unionProperty") + end + + def union_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImNvbGxlY3Rpb24iOnsiZWxlbWVudHR5cGUiOnsidW5pb24iOnsidHlwZXMiOlt7ImZxbiI6ImpzaWktY2FsYy5TdHJ1Y3RBIn0seyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0QiJ9XX19LCJraW5kIjoibWFwIn19LCJraW5kIjoiYXJyYXkifX0=")), "unionProperty") + jsii_set_property("unionProperty", value) + end + + # @param param [Hash{String => JsiiCalc::StructA, JsiiCalc::StructB}] + # @return [void] + def method_with_map_of_unions_param(param) ++ Jsii::Type.check_type(param, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InVuaW9uIjp7InR5cGVzIjpbeyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0QSJ9LHsiZnFuIjoianNpaS1jYWxjLlN0cnVjdEIifV19fSwia2luZCI6Im1hcCJ9fQ==")), "param") + jsii_call_method("methodWithMapOfUnionsParam", [param]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_collections.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/class_with_collections.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/class_with_collections.rb --runtime-type-checking +@@ -5,10 +5,12 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.ClassWithCollections", self) + + # @param map [Hash{String => String}] + # @param array [Array] + def initialize(map, array) ++ Jsii::Type.check_type(map, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoibWFwIn19")), "map") ++ Jsii::Type.check_type(array, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "array") + Jsii::Object.instance_method(:initialize).bind(self).call(map, array) + end + + def self.jsii_overridable_methods + { +@@ -31,37 +33,41 @@ + def self.static_array() + Jsii::Kernel.instance.get_static("jsii-calc.ClassWithCollections", "staticArray") + end + + def self.static_array=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "staticArray") + Jsii::Kernel.instance.set_static("jsii-calc.ClassWithCollections", "staticArray", value) + end + + # @return [Hash{String => String}] + def self.static_map() + Jsii::Kernel.instance.get_static("jsii-calc.ClassWithCollections", "staticMap") + end + + def self.static_map=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoibWFwIn19")), "staticMap") + Jsii::Kernel.instance.set_static("jsii-calc.ClassWithCollections", "staticMap", value) + end + + # @return [Array] + def array() + jsii_get_property("array") + end + + def array=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "array") + jsii_set_property("array", value) + end + + # @return [Hash{String => String}] + def map() + jsii_get_property("map") + end + + def map=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoibWFwIn19")), "map") + jsii_set_property("map", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_container_types.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/class_with_container_types.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/class_with_container_types.rb --runtime-type-checking +@@ -11,10 +11,14 @@ + def initialize(array, record, obj, props = nil) + array = array.is_a?(Array) ? array.map { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::DummyObj.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : array + record = record.is_a?(Hash) ? record.transform_values { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::DummyObj.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : record + obj = obj.is_a?(Hash) ? obj.transform_values { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::DummyObj.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : obj + props = props.is_a?(Hash) ? ::JsiiCalc::ContainerProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(array, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6ImpzaWktY2FsYy5EdW1teU9iaiJ9LCJraW5kIjoiYXJyYXkifX0=")), "array") ++ Jsii::Type.check_type(record, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6ImpzaWktY2FsYy5EdW1teU9iaiJ9LCJraW5kIjoibWFwIn19")), "record") ++ Jsii::Type.check_type(obj, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6ImpzaWktY2FsYy5EdW1teU9iaiJ9LCJraW5kIjoibWFwIn19")), "obj") ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuQ29udGFpbmVyUHJvcHMifQ==")), "props") unless props.nil? + Jsii::Object.instance_method(:initialize).bind(self).call(array, record, obj, props) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_java_reserved_words.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/class_with_java_reserved_words.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/class_with_java_reserved_words.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + self.jsii_fqn = "jsii-calc.ClassWithJavaReservedWords" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassWithJavaReservedWords", self) + + # @param int [String] + def initialize(int) ++ Jsii::Type.check_type(int, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "int") + Jsii::Object.instance_method(:initialize).bind(self).call(int) + end + + def self.jsii_overridable_methods + { +@@ -22,10 +23,11 @@ + end + + # @param assert [String] + # @return [String] + def import(assert) ++ Jsii::Type.check_type(assert, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "assert") + jsii_call_method("import", [assert]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_mutable_object_literal_property.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/class_with_mutable_object_literal_property.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/class_with_mutable_object_literal_property.rb --runtime-type-checking +@@ -18,10 +18,11 @@ + def mutable_object() + jsii_get_property("mutableObject") + end + + def mutable_object=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSU11dGFibGVPYmplY3RMaXRlcmFsIn0=")), "mutableObject") + jsii_set_property("mutableObject", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_nested_union.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/class_with_nested_union.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/class_with_nested_union.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + self.jsii_fqn = "jsii-calc.ClassWithNestedUnion" + Jsii::Object.register_jsii_fqn("jsii-calc.ClassWithNestedUnion", self) + + # @param union_property [Array JsiiCalc::StructA, JsiiCalc::StructB}, Array>] + def initialize(union_property) ++ Jsii::Type.check_type(union_property, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InVuaW9uIjp7InR5cGVzIjpbeyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InVuaW9uIjp7InR5cGVzIjpbeyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0QSJ9LHsiZnFuIjoianNpaS1jYWxjLlN0cnVjdEIifV19fSwia2luZCI6Im1hcCJ9fSx7ImNvbGxlY3Rpb24iOnsiZWxlbWVudHR5cGUiOnsidW5pb24iOnsidHlwZXMiOlt7ImZxbiI6ImpzaWktY2FsYy5TdHJ1Y3RBIn0seyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0QiJ9XX19LCJraW5kIjoiYXJyYXkifX1dfX0sImtpbmQiOiJhcnJheSJ9fQ==")), "unionProperty") + Jsii::Object.instance_method(:initialize).bind(self).call(union_property) + end + + def self.jsii_overridable_methods + { +@@ -19,10 +20,11 @@ + def union_property() + jsii_get_property("unionProperty") + end + + def union_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InVuaW9uIjp7InR5cGVzIjpbeyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InVuaW9uIjp7InR5cGVzIjpbeyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0QSJ9LHsiZnFuIjoianNpaS1jYWxjLlN0cnVjdEIifV19fSwia2luZCI6Im1hcCJ9fSx7ImNvbGxlY3Rpb24iOnsiZWxlbWVudHR5cGUiOnsidW5pb24iOnsidHlwZXMiOlt7ImZxbiI6ImpzaWktY2FsYy5TdHJ1Y3RBIn0seyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0QiJ9XX19LCJraW5kIjoiYXJyYXkifX1dfX0sImtpbmQiOiJhcnJheSJ9fQ==")), "unionProperty") + jsii_set_property("unionProperty", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/class_with_private_constructor_and_automatic_properties.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/class_with_private_constructor_and_automatic_properties.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/class_with_private_constructor_and_automatic_properties.rb --runtime-type-checking +@@ -19,10 +19,12 @@ + + # @param read_only_string [String] + # @param read_write_string [String] + # @return [JsiiCalc::ClassWithPrivateConstructorAndAutomaticProperties] + def self.create(read_only_string, read_write_string) ++ Jsii::Type.check_type(read_only_string, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readOnlyString") ++ Jsii::Type.check_type(read_write_string, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readWriteString") + Jsii::Kernel.instance.call_static("jsii-calc.ClassWithPrivateConstructorAndAutomaticProperties", "create", [read_only_string, read_write_string]) + end + + # @return [String] + def read_only_string() +@@ -33,10 +35,11 @@ + def read_write_string() + jsii_get_property("readWriteString") + end + + def read_write_string=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readWriteString") + jsii_set_property("readWriteString", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/composition/composite_operation.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/composition/composite_operation.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/composition/composite_operation.rb --runtime-type-checking +@@ -43,10 +43,11 @@ + def decoration_postfixes() + jsii_get_property("decorationPostfixes") + end + + def decoration_postfixes=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "decorationPostfixes") + jsii_set_property("decorationPostfixes", value) + end + + # A set of prefixes to include in a decorated .toString(). + # +@@ -54,10 +55,11 @@ + def decoration_prefixes() + jsii_get_property("decorationPrefixes") + end + + def decoration_prefixes=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "decorationPrefixes") + jsii_set_property("decorationPrefixes", value) + end + + # The .toString() style. + # +@@ -65,10 +67,11 @@ + def string_style() + jsii_get_property("stringStyle") + end + + def string_style=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuY29tcG9zaXRpb24uQ29tcG9zaXRlT3BlcmF0aW9uLkNvbXBvc2l0aW9uU3RyaW5nU3R5bGUifQ==")), "stringStyle") + jsii_set_property("stringStyle", value) + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/confusing_to_jackson.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/confusing_to_jackson.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/confusing_to_jackson.rb --runtime-type-checking +@@ -31,10 +31,11 @@ + def union_property() + jsii_get_property("unionProperty") + end + + def union_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJ1bmlvbiI6eyJ0eXBlcyI6W3siZnFuIjoiQHNjb3BlL2pzaWktY2FsYy1saWIuSUZyaWVuZGx5In0seyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InVuaW9uIjp7InR5cGVzIjpbeyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5JRnJpZW5kbHkifSx7ImZxbiI6ImpzaWktY2FsYy5BYnN0cmFjdENsYXNzIn1dfX0sImtpbmQiOiJhcnJheSJ9fV19fQ==")), "unionProperty") unless value.nil? + jsii_set_property("unionProperty", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/confusing_to_jackson_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/confusing_to_jackson_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/confusing_to_jackson_struct.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.ConfusingToJacksonStruct", self) + + # @param union_property [Scope::JsiiCalcLib::IFriendly, Array, nil] + def initialize(union_property: nil) + @union_property = union_property ++ Jsii::Type.check_type(@union_property, JSON.parse(Base64.strict_decode64("eyJ1bmlvbiI6eyJ0eXBlcyI6W3siZnFuIjoiQHNjb3BlL2pzaWktY2FsYy1saWIuSUZyaWVuZGx5In0seyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InVuaW9uIjp7InR5cGVzIjpbeyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5JRnJpZW5kbHkifSx7ImZxbiI6ImpzaWktY2FsYy5BYnN0cmFjdENsYXNzIn1dfX0sImtpbmQiOiJhcnJheSJ9fV19fQ==")), "unionProperty") unless @union_property.nil? + end + + # @return [Scope::JsiiCalcLib::IFriendly, Array, nil] + attr_reader :union_property +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/constructor_passes_this_out.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/constructor_passes_this_out.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/constructor_passes_this_out.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + self.jsii_fqn = "jsii-calc.ConstructorPassesThisOut" + Jsii::Object.register_jsii_fqn("jsii-calc.ConstructorPassesThisOut", self) + + # @param consumer [JsiiCalc::PartiallyInitializedThisConsumer] + def initialize(consumer) ++ Jsii::Type.check_type(consumer, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuUGFydGlhbGx5SW5pdGlhbGl6ZWRUaGlzQ29uc3VtZXIifQ==")), "consumer") + Jsii::Object.instance_method(:initialize).bind(self).call(consumer) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/consume_pure_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/consume_pure_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/consume_pure_interface.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.ConsumePureInterface", self) + + # @param delegate [JsiiCalc::IStructReturningDelegate] + def initialize(delegate) + delegate = Jsii::Utils.coerce_callable(delegate, ::JsiiCalc::IStructReturningDelegate) ++ Jsii::Type.check_type(delegate, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSVN0cnVjdFJldHVybmluZ0RlbGVnYXRlIn0=")), "delegate") + Jsii::Object.instance_method(:initialize).bind(self).call(delegate) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/consumer_can_ring_bell.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/consumer_can_ring_bell.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/consumer_can_ring_bell.rb --runtime-type-checking +@@ -27,10 +27,11 @@ + # + # @param ringer [JsiiCalc::IBellRinger] + # @return [Boolean] + def self.static_implemented_by_object_literal(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IBellRinger) ++ Jsii::Type.check_type(ringer, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUJlbGxSaW5nZXIifQ==")), "ringer") + Jsii::Kernel.instance.call_static("jsii-calc.ConsumerCanRingBell", "staticImplementedByObjectLiteral", [ringer]) + end + + # ...if the interface is implemented using a private class. + # +@@ -38,10 +39,11 @@ + # + # @param ringer [JsiiCalc::IBellRinger] + # @return [Boolean] + def self.static_implemented_by_private_class(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IBellRinger) ++ Jsii::Type.check_type(ringer, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUJlbGxSaW5nZXIifQ==")), "ringer") + Jsii::Kernel.instance.call_static("jsii-calc.ConsumerCanRingBell", "staticImplementedByPrivateClass", [ringer]) + end + + # ...if the interface is implemented using a public class. + # +@@ -49,10 +51,11 @@ + # + # @param ringer [JsiiCalc::IBellRinger] + # @return [Boolean] + def self.static_implemented_by_public_class(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IBellRinger) ++ Jsii::Type.check_type(ringer, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUJlbGxSaW5nZXIifQ==")), "ringer") + Jsii::Kernel.instance.call_static("jsii-calc.ConsumerCanRingBell", "staticImplementedByPublicClass", [ringer]) + end + + # If the parameter is a concrete class instead of an interface. + # +@@ -60,10 +63,11 @@ + # + # @param ringer [JsiiCalc::IConcreteBellRinger] + # @return [Boolean] + def self.static_when_typed_as_class(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IConcreteBellRinger) ++ Jsii::Type.check_type(ringer, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUNvbmNyZXRlQmVsbFJpbmdlciJ9")), "ringer") + Jsii::Kernel.instance.call_static("jsii-calc.ConsumerCanRingBell", "staticWhenTypedAsClass", [ringer]) + end + + # ...if the interface is implemented using an object literal. + # +@@ -71,10 +75,11 @@ + # + # @param ringer [JsiiCalc::IBellRinger] + # @return [Boolean] + def implemented_by_object_literal(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IBellRinger) ++ Jsii::Type.check_type(ringer, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUJlbGxSaW5nZXIifQ==")), "ringer") + jsii_call_method("implementedByObjectLiteral", [ringer]) + end + + # ...if the interface is implemented using a private class. + # +@@ -82,10 +87,11 @@ + # + # @param ringer [JsiiCalc::IBellRinger] + # @return [Boolean] + def implemented_by_private_class(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IBellRinger) ++ Jsii::Type.check_type(ringer, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUJlbGxSaW5nZXIifQ==")), "ringer") + jsii_call_method("implementedByPrivateClass", [ringer]) + end + + # ...if the interface is implemented using a public class. + # +@@ -93,10 +99,11 @@ + # + # @param ringer [JsiiCalc::IBellRinger] + # @return [Boolean] + def implemented_by_public_class(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IBellRinger) ++ Jsii::Type.check_type(ringer, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUJlbGxSaW5nZXIifQ==")), "ringer") + jsii_call_method("implementedByPublicClass", [ringer]) + end + + # If the parameter is a concrete class instead of an interface. + # +@@ -104,10 +111,11 @@ + # + # @param ringer [JsiiCalc::IConcreteBellRinger] + # @return [Boolean] + def when_typed_as_class(ringer) + ringer = Jsii::Utils.coerce_callable(ringer, ::JsiiCalc::IConcreteBellRinger) ++ Jsii::Type.check_type(ringer, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUNvbmNyZXRlQmVsbFJpbmdlciJ9")), "ringer") + jsii_call_method("whenTypedAsClass", [ringer]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/consumers_of_this_crazy_type_system.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/consumers_of_this_crazy_type_system.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/consumers_of_this_crazy_type_system.rb --runtime-type-checking +@@ -16,16 +16,18 @@ + end + + # @param obj [JsiiCalc::IAnotherPublicInterface] + # @return [String] + def consume_another_public_interface(obj) ++ Jsii::Type.check_type(obj, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUFub3RoZXJQdWJsaWNJbnRlcmZhY2UifQ==")), "obj") + jsii_call_method("consumeAnotherPublicInterface", [obj]) + end + + # @param obj [JsiiCalc::INonInternalInterface] + # @return [Object] + def consume_non_internal_interface(obj) ++ Jsii::Type.check_type(obj, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSU5vbkludGVybmFsSW50ZXJmYWNlIn0=")), "obj") + jsii_call_method("consumeNonInternalInterface", [obj]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/container_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/container_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/container_props.rb --runtime-type-checking +@@ -6,12 +6,15 @@ + # @param array_prop [Array] + # @param obj_prop [Hash{String => JsiiCalc::DummyObj}] + # @param record_prop [Hash{String => JsiiCalc::DummyObj}] + def initialize(array_prop:, obj_prop:, record_prop:) + @array_prop = array_prop.is_a?(Array) ? array_prop.map { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::DummyObj.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : array_prop ++ Jsii::Type.check_type(@array_prop, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6ImpzaWktY2FsYy5EdW1teU9iaiJ9LCJraW5kIjoiYXJyYXkifX0=")), "arrayProp") + @obj_prop = obj_prop.is_a?(Hash) ? obj_prop.transform_values { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::DummyObj.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : obj_prop ++ Jsii::Type.check_type(@obj_prop, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6ImpzaWktY2FsYy5EdW1teU9iaiJ9LCJraW5kIjoibWFwIn19")), "objProp") + @record_prop = record_prop.is_a?(Hash) ? record_prop.transform_values { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::DummyObj.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : record_prop ++ Jsii::Type.check_type(@record_prop, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6ImpzaWktY2FsYy5EdW1teU9iaiJ9LCJraW5kIjoibWFwIn19")), "recordProp") + end + + # @return [Array] + attr_reader :array_prop + # @return [Hash{String => JsiiCalc::DummyObj}] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/covariant_overrides/class_overrides/derived.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/covariant_overrides/class_overrides/derived.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/covariant_overrides/class_overrides/derived.rb --runtime-type-checking +@@ -35,10 +35,11 @@ + def add_unrelated_member() + jsii_get_property("addUnrelatedMember") + end + + def add_unrelated_member=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "addUnrelatedMember") + jsii_set_property("addUnrelatedMember", value) + end + + # @return [JsiiCalc::CovariantOverrides::ClassOverrides::SubSubclass] + def create_something() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/covariant_overrides/class_overrides/middle.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/covariant_overrides/class_overrides/middle.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/covariant_overrides/class_overrides/middle.rb --runtime-type-checking +@@ -32,10 +32,11 @@ + def add_unrelated_member() + jsii_get_property("addUnrelatedMember") + end + + def add_unrelated_member=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "addUnrelatedMember") + jsii_set_property("addUnrelatedMember", value) + end + + # @return [JsiiCalc::CovariantOverrides::ClassOverrides::Superclass] + def create_something() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/covariant_overrides/class_overrides/sub_subclass.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/covariant_overrides/class_overrides/sub_subclass.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/covariant_overrides/class_overrides/sub_subclass.rb --runtime-type-checking +@@ -21,10 +21,11 @@ + def name() + jsii_get_property("name") + end + + def name=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "name") + jsii_set_property("name", value) + end + + # Ensures this class is different than its parent. + # +@@ -32,10 +33,11 @@ + def unique() + jsii_get_property("unique") + end + + def unique=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "unique") + jsii_set_property("unique", value) + end + + # @return [String] + def say_hello() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/covariant_overrides/class_overrides/subclass.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/covariant_overrides/class_overrides/subclass.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/covariant_overrides/class_overrides/subclass.rb --runtime-type-checking +@@ -20,10 +20,11 @@ + def name() + jsii_get_property("name") + end + + def name=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "name") + jsii_set_property("name", value) + end + + # @return [String] + def say_hello() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/covariant_overrides/class_overrides/superclass.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/covariant_overrides/class_overrides/superclass.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/covariant_overrides/class_overrides/superclass.rb --runtime-type-checking +@@ -20,10 +20,11 @@ + def name() + jsii_get_property("name") + end + + def name=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "name") + jsii_set_property("name", value) + end + + # @return [String] + def say_hello() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/data_renderer.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/data_renderer.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/data_renderer.rb --runtime-type-checking +@@ -19,22 +19,25 @@ + + # @param data [Scope::JsiiCalcLib::MyFirstStruct, nil] + # @return [String] + def render(data = nil) + data = data.is_a?(Hash) ? ::Scope::JsiiCalcLib::MyFirstStruct.new(**data.transform_keys(&:to_sym)) : data ++ Jsii::Type.check_type(data, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5NeUZpcnN0U3RydWN0In0=")), "data") unless data.nil? + jsii_call_method("render", [data]) + end + + # @param data [Hash{String => Object}] + # @return [String] + def render_arbitrary(data) ++ Jsii::Type.check_type(data, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6ImFueSJ9LCJraW5kIjoibWFwIn19")), "data") + jsii_call_method("renderArbitrary", [data]) + end + + # @param map [Hash{String => Object}] + # @return [String] + def render_map(map) ++ Jsii::Type.check_type(map, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6ImFueSJ9LCJraW5kIjoibWFwIn19")), "map") + jsii_call_method("renderMap", [map]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/defaulted_constructor_argument.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/defaulted_constructor_argument.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/defaulted_constructor_argument.rb --runtime-type-checking +@@ -6,10 +6,13 @@ + + # @param arg1 [Numeric, nil] + # @param arg2 [String, nil] + # @param arg3 [DateTime, nil] + def initialize(arg1 = nil, arg2 = nil, arg3 = nil) ++ Jsii::Type.check_type(arg1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "arg1") unless arg1.nil? ++ Jsii::Type.check_type(arg2, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "arg2") unless arg2.nil? ++ Jsii::Type.check_type(arg3, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJkYXRlIn0=")), "arg3") unless arg3.nil? + Jsii::Object.instance_method(:initialize).bind(self).call(arg1, arg2, arg3) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/deprecated_class.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/deprecated_class.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/deprecated_class.rb --runtime-type-checking +@@ -7,10 +7,12 @@ + + # @param readonly_string [String] + # @param mutable_number [Numeric, nil] + # @deprecated this constructor is "just" okay + def initialize(readonly_string, mutable_number = nil) ++ Jsii::Type.check_type(readonly_string, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readonlyString") ++ Jsii::Type.check_type(mutable_number, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mutableNumber") unless mutable_number.nil? + Jsii::Object.instance_method(:initialize).bind(self).call(readonly_string, mutable_number) + end + + def self.jsii_overridable_methods + { +@@ -31,10 +33,11 @@ + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mutableProperty") unless value.nil? + jsii_set_property("mutableProperty", value) + end + + # @return [void] + # @deprecated it was a bad idea +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/deprecated_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/deprecated_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/deprecated_struct.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.DeprecatedStruct", self) + + # @param readonly_property [String] + def initialize(readonly_property:) + @readonly_property = readonly_property ++ Jsii::Type.check_type(@readonly_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readonlyProperty") + end + + # @return [String] + # @deprecated well, yeah + attr_reader :readonly_property +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/derived_class_has_no_properties/base.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/derived_class_has_no_properties/base.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/derived_class_has_no_properties/base.rb --runtime-type-checking +@@ -18,10 +18,11 @@ + def prop() + jsii_get_property("prop") + end + + def prop=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "prop") + jsii_set_property("prop", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/derived_class_has_no_properties/derived.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/derived_class_has_no_properties/derived.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/derived_class_has_no_properties/derived.rb --runtime-type-checking +@@ -18,10 +18,11 @@ + def prop() + jsii_get_property("prop") + end + + def prop=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "prop") + jsii_set_property("prop", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/derived_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/derived_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/derived_struct.rb --runtime-type-checking +@@ -13,18 +13,27 @@ + # @param another_optional [Hash{String => Scope::JsiiCalcLib::NumericValue}, nil] This is optional. + # @param optional_any [Object, nil] + # @param optional_array [Array, nil] + def initialize(anumber:, astring:, first_optional: nil, another_required:, bool:, non_primitive:, another_optional: nil, optional_any: nil, optional_array: nil) + @anumber = anumber ++ Jsii::Type.check_type(@anumber, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "anumber") + @astring = astring ++ Jsii::Type.check_type(@astring, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "astring") + @first_optional = first_optional ++ Jsii::Type.check_type(@first_optional, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "firstOptional") unless @first_optional.nil? + @another_required = another_required ++ Jsii::Type.check_type(@another_required, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJkYXRlIn0=")), "anotherRequired") + @bool = bool ++ Jsii::Type.check_type(@bool, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "bool") + @non_primitive = non_primitive ++ Jsii::Type.check_type(@non_primitive, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuRG91YmxlVHJvdWJsZSJ9")), "nonPrimitive") + @another_optional = another_optional ++ Jsii::Type.check_type(@another_optional, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6IkBzY29wZS9qc2lpLWNhbGMtbGliLk51bWVyaWNWYWx1ZSJ9LCJraW5kIjoibWFwIn19")), "anotherOptional") unless @another_optional.nil? + @optional_any = optional_any ++ Jsii::Type.check_type(@optional_any, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "optionalAny") unless @optional_any.nil? + @optional_array = optional_array ++ Jsii::Type.check_type(@optional_array, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "optionalArray") unless @optional_array.nil? + end + + # An awesome number value. + # + # @return [Numeric] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/diamond_bottom.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/diamond_bottom.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/diamond_bottom.rb --runtime-type-checking +@@ -8,13 +8,17 @@ + # @param left [Numeric, nil] + # @param right [Boolean, nil] + # @param bottom [DateTime, nil] + def initialize(hoisted_top: nil, left: nil, right: nil, bottom: nil) + @hoisted_top = hoisted_top ++ Jsii::Type.check_type(@hoisted_top, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "hoistedTop") unless @hoisted_top.nil? + @left = left ++ Jsii::Type.check_type(@left, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "left") unless @left.nil? + @right = right ++ Jsii::Type.check_type(@right, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "right") unless @right.nil? + @bottom = bottom ++ Jsii::Type.check_type(@bottom, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJkYXRlIn0=")), "bottom") unless @bottom.nil? + end + + # @return [String, nil] + attr_reader :hoisted_top + # @return [Numeric, nil] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/diamond_inheritance_base_level_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/diamond_inheritance_base_level_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/diamond_inheritance_base_level_struct.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.DiamondInheritanceBaseLevelStruct", self) + + # @param base_level_property [String] + def initialize(base_level_property:) + @base_level_property = base_level_property ++ Jsii::Type.check_type(@base_level_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "baseLevelProperty") + end + + # @return [String] + attr_reader :base_level_property +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/diamond_inheritance_first_mid_level_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/diamond_inheritance_first_mid_level_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/diamond_inheritance_first_mid_level_struct.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param base_level_property [String] + # @param first_mid_level_property [String] + def initialize(base_level_property:, first_mid_level_property:) + @base_level_property = base_level_property ++ Jsii::Type.check_type(@base_level_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "baseLevelProperty") + @first_mid_level_property = first_mid_level_property ++ Jsii::Type.check_type(@first_mid_level_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "firstMidLevelProperty") + end + + # @return [String] + attr_reader :base_level_property + # @return [String] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/diamond_inheritance_second_mid_level_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/diamond_inheritance_second_mid_level_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/diamond_inheritance_second_mid_level_struct.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param base_level_property [String] + # @param second_mid_level_property [String] + def initialize(base_level_property:, second_mid_level_property:) + @base_level_property = base_level_property ++ Jsii::Type.check_type(@base_level_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "baseLevelProperty") + @second_mid_level_property = second_mid_level_property ++ Jsii::Type.check_type(@second_mid_level_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "secondMidLevelProperty") + end + + # @return [String] + attr_reader :base_level_property + # @return [String] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/diamond_inheritance_top_level_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/diamond_inheritance_top_level_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/diamond_inheritance_top_level_struct.rb --runtime-type-checking +@@ -8,13 +8,17 @@ + # @param first_mid_level_property [String] + # @param second_mid_level_property [String] + # @param top_level_property [String] + def initialize(base_level_property:, first_mid_level_property:, second_mid_level_property:, top_level_property:) + @base_level_property = base_level_property ++ Jsii::Type.check_type(@base_level_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "baseLevelProperty") + @first_mid_level_property = first_mid_level_property ++ Jsii::Type.check_type(@first_mid_level_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "firstMidLevelProperty") + @second_mid_level_property = second_mid_level_property ++ Jsii::Type.check_type(@second_mid_level_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "secondMidLevelProperty") + @top_level_property = top_level_property ++ Jsii::Type.check_type(@top_level_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "topLevelProperty") + end + + # @return [String] + attr_reader :base_level_property + # @return [String] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/do_not_override_privates.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/do_not_override_privates.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/do_not_override_privates.rb --runtime-type-checking +@@ -17,10 +17,11 @@ + end + + # @param new_value [String] + # @return [void] + def change_private_property_value(new_value) ++ Jsii::Type.check_type(new_value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "newValue") + jsii_call_method("changePrivatePropertyValue", [new_value]) + end + + # @return [String] + def private_method_value() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/do_not_recognize_any_as_optional.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/do_not_recognize_any_as_optional.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/do_not_recognize_any_as_optional.rb --runtime-type-checking +@@ -18,10 +18,13 @@ + # @param _required_any [Object] + # @param _optional_any [Object, nil] + # @param _optional_string [String, nil] + # @return [void] + def method(_required_any, _optional_any = nil, _optional_string = nil) ++ Jsii::Type.check_type(_required_any, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "_requiredAny") ++ Jsii::Type.check_type(_optional_any, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "_optionalAny") unless _optional_any.nil? ++ Jsii::Type.check_type(_optional_string, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "_optionalString") unless _optional_string.nil? + jsii_call_method("method", [_required_any, _optional_any, _optional_string]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/documented_class.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/documented_class.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/documented_class.rb --runtime-type-checking +@@ -36,10 +36,11 @@ + # + # @param greetee [JsiiCalc::Greetee, nil] The person to be greeted. + # @return [Numeric] A number that everyone knows very well and represents the answer to the ultimate question + def greet(greetee = nil) + greetee = greetee.is_a?(Hash) ? ::JsiiCalc::Greetee.new(**greetee.transform_keys(&:to_sym)) : greetee ++ Jsii::Type.check_type(greetee, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuR3JlZXRlZSJ9")), "greetee") unless greetee.nil? + jsii_call_method("greet", [greetee]) + end + + # Say ¡Hola! + # +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/dont_complain_about_variadic_after_optional.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/dont_complain_about_variadic_after_optional.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/dont_complain_about_variadic_after_optional.rb --runtime-type-checking +@@ -16,10 +16,14 @@ + + # @param optional [String, nil] + # @param things [Array] + # @return [String] + def optional_and_variadic(optional = nil, *things) ++ Jsii::Type.check_type(optional, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "optional") unless optional.nil? ++ things.each_with_index do |item, index| ++ Jsii::Type.check_type(item, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "things[#{index}]") ++ end + jsii_call_method("optionalAndVariadic", [optional, *things]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/dont_use_me.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/dont_use_me.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/dont_use_me.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.DontUseMe", self) + + # @param dont_set_me [String, nil] > Don't set this parameter. + def initialize(dont_set_me: nil) + @dont_set_me = dont_set_me ++ Jsii::Type.check_type(@dont_set_me, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "dontSetMe") unless @dont_set_me.nil? + end + + # > Don't set this parameter. + # + # A parameter that shouldn't be set, with the annotation in a weird place. +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/dummy_obj.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/dummy_obj.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/dummy_obj.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.DummyObj", self) + + # @param example [String] + def initialize(example:) + @example = example ++ Jsii::Type.check_type(@example, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "example") + end + + # @return [String] + attr_reader :example +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/dynamic_property_bearer.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/dynamic_property_bearer.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/dynamic_property_bearer.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + self.jsii_fqn = "jsii-calc.DynamicPropertyBearer" + Jsii::Object.register_jsii_fqn("jsii-calc.DynamicPropertyBearer", self) + + # @param value_store [String] + def initialize(value_store) ++ Jsii::Type.check_type(value_store, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "valueStore") + Jsii::Object.instance_method(:initialize).bind(self).call(value_store) + end + + def self.jsii_overridable_methods + { +@@ -21,19 +22,21 @@ + def dynamic_property() + jsii_get_property("dynamicProperty") + end + + def dynamic_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "dynamicProperty") + jsii_set_property("dynamicProperty", value) + end + + # @return [String] + def value_store() + jsii_get_property("valueStore") + end + + def value_store=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "valueStore") + jsii_set_property("valueStore", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/dynamic_property_bearer_child.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/dynamic_property_bearer_child.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/dynamic_property_bearer_child.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + self.jsii_fqn = "jsii-calc.DynamicPropertyBearerChild" + Jsii::Object.register_jsii_fqn("jsii-calc.DynamicPropertyBearerChild", self) + + # @param original_value [String] + def initialize(original_value) ++ Jsii::Type.check_type(original_value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "originalValue") + Jsii::Object.instance_method(:initialize).bind(self).call(original_value) + end + + def self.jsii_overridable_methods + { +@@ -22,19 +23,21 @@ + def dynamic_property() + jsii_get_property("dynamicProperty") + end + + def dynamic_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "dynamicProperty") + jsii_set_property("dynamicProperty", value) + end + + # @return [String] + def value_store() + jsii_get_property("valueStore") + end + + def value_store=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "valueStore") + jsii_set_property("valueStore", value) + end + + # @return [String] + def original_value() +@@ -44,10 +47,11 @@ + # Sets \`this.dynamicProperty\` to the new value, and returns the old value. + # + # @param new_value [String] the new value to be set. + # @return [String] the old value that was set. + def override_value(new_value) ++ Jsii::Type.check_type(new_value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "newValue") + jsii_call_method("overrideValue", [new_value]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/entropy.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/entropy.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/entropy.rb --runtime-type-checking +@@ -8,10 +8,11 @@ + # Creates a new instance of Entropy. + # + # @param clock [JsiiCalc::IWallClock] your implementation of \`WallClock\`. + def initialize(clock) + clock = Jsii::Utils.coerce_callable(clock, ::JsiiCalc::IWallClock) ++ Jsii::Type.check_type(clock, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSVdhbGxDbG9jayJ9")), "clock") + Jsii::Object.instance_method(:initialize).bind(self).call(clock) + end + + def self.jsii_overridable_methods + { +@@ -30,10 +31,11 @@ + # Implement this method such that it returns \`word\`. + # + # @param word [String] the value to return. + # @return [String] \`word\`. + def repeat(word) ++ Jsii::Type.check_type(word, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "word") + jsii_call_method("repeat", [word]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/erase_undefined_hash_values.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/erase_undefined_hash_values.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/erase_undefined_hash_values.rb --runtime-type-checking +@@ -21,10 +21,12 @@ + # @param opts [JsiiCalc::EraseUndefinedHashValuesOptions] + # @param key [String] + # @return [Boolean] + def self.does_key_exist(opts, key) + opts = opts.is_a?(Hash) ? ::JsiiCalc::EraseUndefinedHashValuesOptions.new(**opts.transform_keys(&:to_sym)) : opts ++ Jsii::Type.check_type(opts, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuRXJhc2VVbmRlZmluZWRIYXNoVmFsdWVzT3B0aW9ucyJ9")), "opts") ++ Jsii::Type.check_type(key, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "key") + Jsii::Kernel.instance.call_static("jsii-calc.EraseUndefinedHashValues", "doesKeyExist", [opts, key]) + end + + # We expect "prop1" to be erased. + # +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/erase_undefined_hash_values_options.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/erase_undefined_hash_values_options.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/erase_undefined_hash_values_options.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param option1 [String, nil] + # @param option2 [String, nil] + def initialize(option1: nil, option2: nil) + @option1 = option1 ++ Jsii::Type.check_type(@option1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "option1") unless @option1.nil? + @option2 = option2 ++ Jsii::Type.check_type(@option2, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "option2") unless @option2.nil? + end + + # @return [String, nil] + attr_reader :option1 + # @return [String, nil] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/experimental_class.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/experimental_class.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/experimental_class.rb --runtime-type-checking +@@ -5,10 +5,12 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.ExperimentalClass", self) + + # @param readonly_string [String] + # @param mutable_number [Numeric, nil] + def initialize(readonly_string, mutable_number = nil) ++ Jsii::Type.check_type(readonly_string, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readonlyString") ++ Jsii::Type.check_type(mutable_number, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mutableNumber") unless mutable_number.nil? + Jsii::Object.instance_method(:initialize).bind(self).call(readonly_string, mutable_number) + end + + def self.jsii_overridable_methods + { +@@ -27,10 +29,11 @@ + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mutableProperty") unless value.nil? + jsii_set_property("mutableProperty", value) + end + + # @return [void] + def method() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/experimental_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/experimental_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/experimental_struct.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.ExperimentalStruct", self) + + # @param readonly_property [String] + def initialize(readonly_property:) + @readonly_property = readonly_property ++ Jsii::Type.check_type(@readonly_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readonlyProperty") + end + + # @return [String] + attr_reader :readonly_property +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/exported_base_class.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/exported_base_class.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/exported_base_class.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + self.jsii_fqn = "jsii-calc.ExportedBaseClass" + Jsii::Object.register_jsii_fqn("jsii-calc.ExportedBaseClass", self) + + # @param success [Boolean] + def initialize(success) ++ Jsii::Type.check_type(success, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "success") + Jsii::Object.instance_method(:initialize).bind(self).call(success) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/extends_internal_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/extends_internal_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/extends_internal_interface.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param boom [Boolean] + # @param prop [String] + def initialize(boom:, prop:) + @boom = boom ++ Jsii::Type.check_type(@boom, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "boom") + @prop = prop ++ Jsii::Type.check_type(@prop, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "prop") + end + + # @return [Boolean] + attr_reader :boom + # @return [String] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/external_class.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/external_class.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/external_class.rb --runtime-type-checking +@@ -5,10 +5,12 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.ExternalClass", self) + + # @param readonly_string [String] + # @param mutable_number [Numeric, nil] + def initialize(readonly_string, mutable_number = nil) ++ Jsii::Type.check_type(readonly_string, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readonlyString") ++ Jsii::Type.check_type(mutable_number, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mutableNumber") unless mutable_number.nil? + Jsii::Object.instance_method(:initialize).bind(self).call(readonly_string, mutable_number) + end + + def self.jsii_overridable_methods + { +@@ -27,10 +29,11 @@ + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mutableProperty") unless value.nil? + jsii_set_property("mutableProperty", value) + end + + # @return [void] + def method() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/external_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/external_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/external_struct.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.ExternalStruct", self) + + # @param readonly_property [String] + def initialize(readonly_property:) + @readonly_property = readonly_property ++ Jsii::Type.check_type(@readonly_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readonlyProperty") + end + + # @return [String] + attr_reader :readonly_property +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/give_me_structs.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/give_me_structs.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/give_me_structs.rb --runtime-type-checking +@@ -26,28 +26,31 @@ + # + # @param derived [JsiiCalc::DerivedStruct] + # @return [Scope::JsiiCalcLib::MyFirstStruct] + def derived_to_first(derived) + derived = derived.is_a?(Hash) ? ::JsiiCalc::DerivedStruct.new(**derived.transform_keys(&:to_sym)) : derived ++ Jsii::Type.check_type(derived, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuRGVyaXZlZFN0cnVjdCJ9")), "derived") + jsii_call_method("derivedToFirst", [derived]) + end + + # Returns the boolean from a DerivedStruct struct. + # + # @param derived [JsiiCalc::DerivedStruct] + # @return [JsiiCalc::DoubleTrouble] + def read_derived_non_primitive(derived) + derived = derived.is_a?(Hash) ? ::JsiiCalc::DerivedStruct.new(**derived.transform_keys(&:to_sym)) : derived ++ Jsii::Type.check_type(derived, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuRGVyaXZlZFN0cnVjdCJ9")), "derived") + jsii_call_method("readDerivedNonPrimitive", [derived]) + end + + # Returns the "anumber" from a MyFirstStruct struct; + # + # @param first [Scope::JsiiCalcLib::MyFirstStruct] + # @return [Numeric] + def read_first_number(first) + first = first.is_a?(Hash) ? ::Scope::JsiiCalcLib::MyFirstStruct.new(**first.transform_keys(&:to_sym)) : first ++ Jsii::Type.check_type(first, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5NeUZpcnN0U3RydWN0In0=")), "first") + jsii_call_method("readFirstNumber", [first]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/greetee.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/greetee.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/greetee.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.Greetee", self) + + # @param name [String, nil] The name of the greetee. + def initialize(name: nil) + @name = name ++ Jsii::Type.check_type(@name, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "name") unless @name.nil? + end + + # The name of the greetee. + # + # @return [String, nil] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/greeting_augmenter.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/greeting_augmenter.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/greeting_augmenter.rb --runtime-type-checking +@@ -16,10 +16,11 @@ + + # @param friendly [Scope::JsiiCalcLib::IFriendly] + # @return [String] + def better_greeting(friendly) + friendly = Jsii::Utils.coerce_callable(friendly, ::Scope::JsiiCalcLib::IFriendly) ++ Jsii::Type.check_type(friendly, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5JRnJpZW5kbHkifQ==")), "friendly") + jsii_call_method("betterGreeting", [friendly]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/bar/consumer.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/homonymous_forward_references/bar/consumer.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/homonymous_forward_references/bar/consumer.rb --runtime-type-checking +@@ -15,10 +15,11 @@ + + # @param props [JsiiCalc::HomonymousForwardReferences::Bar::ConsumerProps] + # @return [JsiiCalc::HomonymousForwardReferences::Bar::Homonymous] + def self.consume(props) + props = props.is_a?(Hash) ? ::JsiiCalc::HomonymousForwardReferences::Bar::ConsumerProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuaG9tb255bW91c0ZvcndhcmRSZWZlcmVuY2VzLmJhci5Db25zdW1lclByb3BzIn0=")), "props") + Jsii::Kernel.instance.call_static("jsii-calc.homonymousForwardReferences.bar.Consumer", "consume", [props]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/bar/consumer_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/homonymous_forward_references/bar/consumer_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/homonymous_forward_references/bar/consumer_props.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.homonymousForwardReferences.bar.ConsumerProps", self) + + # @param homonymous [JsiiCalc::HomonymousForwardReferences::Bar::Homonymous] + def initialize(homonymous:) + @homonymous = homonymous.is_a?(Hash) ? ::JsiiCalc::HomonymousForwardReferences::Bar::Homonymous.new(**homonymous.transform_keys(&:to_sym)) : homonymous ++ Jsii::Type.check_type(@homonymous, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuaG9tb255bW91c0ZvcndhcmRSZWZlcmVuY2VzLmJhci5Ib21vbnltb3VzIn0=")), "homonymous") + end + + # @return [JsiiCalc::HomonymousForwardReferences::Bar::Homonymous] + attr_reader :homonymous +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/bar/homonymous.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/homonymous_forward_references/bar/homonymous.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/homonymous_forward_references/bar/homonymous.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.homonymousForwardReferences.bar.Homonymous", self) + + # @param numeric_property [Numeric] + def initialize(numeric_property:) + @numeric_property = numeric_property ++ Jsii::Type.check_type(@numeric_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "numericProperty") + end + + # @return [Numeric] + attr_reader :numeric_property +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/foo/consumer.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/homonymous_forward_references/foo/consumer.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/homonymous_forward_references/foo/consumer.rb --runtime-type-checking +@@ -15,10 +15,11 @@ + + # @param props [JsiiCalc::HomonymousForwardReferences::Foo::ConsumerProps] + # @return [JsiiCalc::HomonymousForwardReferences::Foo::Homonymous] + def self.consume(props) + props = props.is_a?(Hash) ? ::JsiiCalc::HomonymousForwardReferences::Foo::ConsumerProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuaG9tb255bW91c0ZvcndhcmRSZWZlcmVuY2VzLmZvby5Db25zdW1lclByb3BzIn0=")), "props") + Jsii::Kernel.instance.call_static("jsii-calc.homonymousForwardReferences.foo.Consumer", "consume", [props]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/foo/consumer_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/homonymous_forward_references/foo/consumer_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/homonymous_forward_references/foo/consumer_props.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.homonymousForwardReferences.foo.ConsumerProps", self) + + # @param homonymous [JsiiCalc::HomonymousForwardReferences::Foo::Homonymous] + def initialize(homonymous:) + @homonymous = homonymous.is_a?(Hash) ? ::JsiiCalc::HomonymousForwardReferences::Foo::Homonymous.new(**homonymous.transform_keys(&:to_sym)) : homonymous ++ Jsii::Type.check_type(@homonymous, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuaG9tb255bW91c0ZvcndhcmRSZWZlcmVuY2VzLmZvby5Ib21vbnltb3VzIn0=")), "homonymous") + end + + # @return [JsiiCalc::HomonymousForwardReferences::Foo::Homonymous] + attr_reader :homonymous +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/homonymous_forward_references/foo/homonymous.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/homonymous_forward_references/foo/homonymous.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/homonymous_forward_references/foo/homonymous.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.homonymousForwardReferences.foo.Homonymous", self) + + # @param string_property [String] + def initialize(string_property:) + @string_property = string_property ++ Jsii::Type.check_type(@string_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "stringProperty") + end + + # @return [String] + attr_reader :string_property +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_another_public_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_another_public_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_another_public_interface.rb --runtime-type-checking +@@ -7,10 +7,11 @@ + def a() + jsii_get_property("a") + end + + def a=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "a") + jsii_set_property("a", value) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_bell_ringer.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_bell_ringer.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_bell_ringer.rb --runtime-type-checking +@@ -6,10 +6,11 @@ + + # @param bell [JsiiCalc::IBell] + # @return [void] + def your_turn(bell) + bell = Jsii::Utils.coerce_callable(bell, ::JsiiCalc::IBell) ++ Jsii::Type.check_type(bell, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUJlbGwifQ==")), "bell") + jsii_call_method("yourTurn", [bell]) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_concrete_bell_ringer.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_concrete_bell_ringer.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_concrete_bell_ringer.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.IConcreteBellRinger", self) + + # @param bell [JsiiCalc::Bell] + # @return [void] + def your_turn(bell) ++ Jsii::Type.check_type(bell, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuQmVsbCJ9")), "bell") + jsii_call_method("yourTurn", [bell]) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_deprecated_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_deprecated_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_deprecated_interface.rb --runtime-type-checking +@@ -9,10 +9,11 @@ + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mutableProperty") unless value.nil? + jsii_set_property("mutableProperty", value) + end + + # @return [void] + # @deprecated services no purpose +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_experimental_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_experimental_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_experimental_interface.rb --runtime-type-checking +@@ -7,10 +7,11 @@ + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mutableProperty") unless value.nil? + jsii_set_property("mutableProperty", value) + end + + # @return [void] + def method() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_extends_private_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_extends_private_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_extends_private_interface.rb --runtime-type-checking +@@ -12,10 +12,11 @@ + def private() + jsii_get_property("private") + end + + def private=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "private") + jsii_set_property("private", value) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_external_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_external_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_external_interface.rb --runtime-type-checking +@@ -7,10 +7,11 @@ + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mutableProperty") unless value.nil? + jsii_set_property("mutableProperty", value) + end + + # @return [void] + def method() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_interface_with_optional_method_arguments.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_interface_with_optional_method_arguments.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_interface_with_optional_method_arguments.rb --runtime-type-checking +@@ -6,10 +6,12 @@ + + # @param arg1 [String] + # @param arg2 [Numeric, nil] + # @return [void] + def hello(arg1, arg2 = nil) ++ Jsii::Type.check_type(arg1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "arg1") ++ Jsii::Type.check_type(arg2, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "arg2") unless arg2.nil? + jsii_call_method("hello", [arg1, arg2]) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_interface_with_properties.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_interface_with_properties.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_interface_with_properties.rb --runtime-type-checking +@@ -12,10 +12,11 @@ + def read_write_string() + jsii_get_property("readWriteString") + end + + def read_write_string=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readWriteString") + jsii_set_property("readWriteString", value) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_interface_with_properties_extension.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_interface_with_properties_extension.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_interface_with_properties_extension.rb --runtime-type-checking +@@ -13,19 +13,21 @@ + def read_write_string() + jsii_get_property("readWriteString") + end + + def read_write_string=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readWriteString") + jsii_set_property("readWriteString", value) + end + + # @return [Numeric] + def foo() + jsii_get_property("foo") + end + + def foo=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "foo") + jsii_set_property("foo", value) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_mutable_object_literal.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_mutable_object_literal.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_mutable_object_literal.rb --runtime-type-checking +@@ -7,10 +7,11 @@ + def value() + jsii_get_property("value") + end + + def value=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "value") + jsii_set_property("value", value) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_non_internal_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_non_internal_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_non_internal_interface.rb --runtime-type-checking +@@ -8,28 +8,31 @@ + def a() + jsii_get_property("a") + end + + def a=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "a") + jsii_set_property("a", value) + end + + # @return [String] + def b() + jsii_get_property("b") + end + + def b=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "b") + jsii_set_property("b", value) + end + + # @return [String] + def c() + jsii_get_property("c") + end + + def c=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "c") + jsii_set_property("c", value) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_object_with_property.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_object_with_property.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_object_with_property.rb --runtime-type-checking +@@ -8,10 +8,11 @@ + def property() + jsii_get_property("property") + end + + def property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "property") + jsii_set_property("property", value) + end + + # @return [Boolean] + def was_set() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/i_stable_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/i_stable_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/i_stable_interface.rb --runtime-type-checking +@@ -7,10 +7,11 @@ + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mutableProperty") unless value.nil? + jsii_set_property("mutableProperty", value) + end + + # @return [void] + def method() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/implement_internal_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/implement_internal_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/implement_internal_interface.rb --runtime-type-checking +@@ -18,10 +18,11 @@ + def prop() + jsii_get_property("prop") + end + + def prop=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "prop") + jsii_set_property("prop", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/implements_private_interface.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/implements_private_interface.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/implements_private_interface.rb --runtime-type-checking +@@ -18,10 +18,11 @@ + def private() + jsii_get_property("private") + end + + def private=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "private") + jsii_set_property("private", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/implict_base_of_base.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/implict_base_of_base.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/implict_base_of_base.rb --runtime-type-checking +@@ -6,12 +6,15 @@ + # @param foo [Scope::JsiiCalcBaseOfBase::Very] + # @param bar [String] + # @param goo [DateTime] + def initialize(foo:, bar:, goo:) + @foo = foo ++ Jsii::Type.check_type(@foo, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWJhc2Utb2YtYmFzZS5WZXJ5In0=")), "foo") + @bar = bar ++ Jsii::Type.check_type(@bar, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "bar") + @goo = goo ++ Jsii::Type.check_type(@goo, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJkYXRlIn0=")), "goo") + end + + # @return [Scope::JsiiCalcBaseOfBase::Very] + # @note Default: + # @deprecated +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/interface_in_namespace_includes_classes/foo.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/interface_in_namespace_includes_classes/foo.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/interface_in_namespace_includes_classes/foo.rb --runtime-type-checking +@@ -18,10 +18,11 @@ + def bar() + jsii_get_property("bar") + end + + def bar=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "bar") unless value.nil? + jsii_set_property("bar", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/interface_in_namespace_includes_classes/hello.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/interface_in_namespace_includes_classes/hello.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/interface_in_namespace_includes_classes/hello.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.InterfaceInNamespaceIncludesClasses.Hello", self) + + # @param foo [Numeric] + def initialize(foo:) + @foo = foo ++ Jsii::Type.check_type(@foo, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "foo") + end + + # @return [Numeric] + attr_reader :foo +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/interface_in_namespace_only_interface/hello.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/interface_in_namespace_only_interface/hello.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/interface_in_namespace_only_interface/hello.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.InterfaceInNamespaceOnlyInterface.Hello", self) + + # @param foo [Numeric] + def initialize(foo:) + @foo = foo ++ Jsii::Type.check_type(@foo, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "foo") + end + + # @return [Numeric] + attr_reader :foo +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/interfaces_maker.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/interfaces_maker.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/interfaces_maker.rb --runtime-type-checking +@@ -15,10 +15,11 @@ + end + + # @param count [Numeric] + # @return [Array] + def self.make_interfaces(count) ++ Jsii::Type.check_type(count, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "count") + Jsii::Kernel.instance.call_static("jsii-calc.InterfacesMaker", "makeInterfaces", [count]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/intersection/consumes_intersection.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/intersection/consumes_intersection.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/intersection/consumes_intersection.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.intersection.ConsumesIntersection", self) + + # @param props [JsiiCalc::Intersection::IntersectionProps] + def initialize(props) + props = props.is_a?(Hash) ? ::JsiiCalc::Intersection::IntersectionProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuaW50ZXJzZWN0aW9uLkludGVyc2VjdGlvblByb3BzIn0=")), "props") + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { +@@ -16,17 +17,19 @@ + end + + # @param param [Object] + # @return [void] + def self.accepts_intersection(param) ++ Jsii::Type.check_type(param, JSON.parse(Base64.strict_decode64("eyJpbnRlcnNlY3Rpb24iOnsidHlwZXMiOlt7ImZxbiI6ImpzaWktY2FsYy5pbnRlcnNlY3Rpb24uSVNvbWV0aGluZyJ9LHsiZnFuIjoiQHNjb3BlL2pzaWktY2FsYy1saWIuSUZyaWVuZGx5In1dfX0=")), "param") + Jsii::Kernel.instance.call_static("jsii-calc.intersection.ConsumesIntersection", "acceptsIntersection", [param]) + end + + # @param props [JsiiCalc::Intersection::IntersectionProps] + # @return [void] + def self.accepts_prop_with_intersection(props) + props = props.is_a?(Hash) ? ::JsiiCalc::Intersection::IntersectionProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuaW50ZXJzZWN0aW9uLkludGVyc2VjdGlvblByb3BzIn0=")), "props") + Jsii::Kernel.instance.call_static("jsii-calc.intersection.ConsumesIntersection", "acceptsPropWithIntersection", [props]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/intersection/intersection_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/intersection/intersection_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/intersection/intersection_props.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.intersection.IntersectionProps", self) + + # @param param [Object] + def initialize(param:) + @param = param ++ Jsii::Type.check_type(@param, JSON.parse(Base64.strict_decode64("eyJpbnRlcnNlY3Rpb24iOnsidHlwZXMiOlt7ImZxbiI6ImpzaWktY2FsYy5pbnRlcnNlY3Rpb24uSVNvbWV0aGluZyJ9LHsiZnFuIjoiQHNjb3BlL2pzaWktY2FsYy1saWIuSUZyaWVuZGx5In1dfX0=")), "param") + end + + # @return [Object] + attr_reader :param +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/java_reserved_words.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/java_reserved_words.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/java_reserved_words.rb --runtime-type-checking +@@ -70,10 +70,11 @@ + def _while() + jsii_get_property("while") + end + + def _while=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "while") + jsii_set_property("while", value) + end + + # @return [void] + def abstract() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/js_object_literal_to_native_class.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/js_object_literal_to_native_class.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/js_object_literal_to_native_class.rb --runtime-type-checking +@@ -19,19 +19,21 @@ + def prop_a() + jsii_get_property("propA") + end + + def prop_a=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "propA") + jsii_set_property("propA", value) + end + + # @return [Numeric] + def prop_b() + jsii_get_property("propB") + end + + def prop_b=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "propB") + jsii_set_property("propB", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii417_derived.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/jsii417_derived.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/jsii417_derived.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + self.jsii_fqn = "jsii-calc.JSII417Derived" + Jsii::Object.register_jsii_fqn("jsii-calc.JSII417Derived", self) + + # @param property [String] + def initialize(property) ++ Jsii::Type.check_type(property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "property") + Jsii::Object.instance_method(:initialize).bind(self).call(property) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii3656/implement_me_opts.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/jsii3656/implement_me_opts.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/jsii3656/implement_me_opts.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param name [String] + # @param count [Numeric, nil] + def initialize(name:, count: nil) + @name = name ++ Jsii::Type.check_type(@name, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "name") + @count = count ++ Jsii::Type.check_type(@count, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "count") unless @count.nil? + end + + # @return [String] + attr_reader :name + # @return [Numeric, nil] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii3656/override_me.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/jsii3656/override_me.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/jsii3656/override_me.rb --runtime-type-checking +@@ -15,17 +15,19 @@ + end + + # @param receiver [JsiiCalc::Jsii3656::OverrideMe] + # @return [Boolean] + def self.call_abstract(receiver) ++ Jsii::Type.check_type(receiver, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuanNpaTM2NTYuT3ZlcnJpZGVNZSJ9")), "receiver") + Jsii::Kernel.instance.call_static("jsii-calc.jsii3656.OverrideMe", "callAbstract", [receiver]) + end + + # @param opts [JsiiCalc::Jsii3656::ImplementMeOpts] + # @return [Boolean] + def implement_me(opts) + opts = opts.is_a?(Hash) ? ::JsiiCalc::Jsii3656::ImplementMeOpts.new(**opts.transform_keys(&:to_sym)) : opts ++ Jsii::Type.check_type(opts, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuanNpaTM2NTYuSW1wbGVtZW50TWVPcHRzIn0=")), "opts") + jsii_call_method("implementMe", [opts]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii4894/non_pascal_case_test.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/jsii4894/non_pascal_case_test.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/jsii4894/non_pascal_case_test.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.jsii4894.NonPascalCaseTest", self) + + # @param props [JsiiCalc::Jsii4894::NonPascalCaseTestProps] + def initialize(props) + props = props.is_a?(Hash) ? ::JsiiCalc::Jsii4894::NonPascalCaseTestProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuanNpaTQ4OTQuTm9uUGFzY2FsQ2FzZVRlc3RQcm9wcyJ9")), "props") + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/jsii4894/non_pascal_case_test_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/jsii4894/non_pascal_case_test_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/jsii4894/non_pascal_case_test_props.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.jsii4894.NonPascalCaseTestProps", self) + + # @param some_type [Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName::SomeType] + def initialize(some_type:) + @some_type = some_type.is_a?(Hash) ? ::Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName::SomeType.new(**some_type.transform_keys(&:to_sym)) : some_type ++ Jsii::Type.check_type(@some_type, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5zdWJtb2R1bGUuQ2xhc3NXaXRoTk9OUEFTQ0FMQ0FTRUROYW1lLlNvbWVUeXBlIn0=")), "someType") + end + + # @return [Scope::JsiiCalcLib::Submodule::ClassWithNONPASCALCASEDName::SomeType] + attr_reader :some_type +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/json_formatter.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/json_formatter.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/json_formatter.rb --runtime-type-checking +@@ -82,10 +82,11 @@ + end + + # @param value [Object, nil] + # @return [String, nil] + def self.stringify(value = nil) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "value") unless value.nil? + Jsii::Kernel.instance.call_static("jsii-calc.JsonFormatter", "stringify", [value]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/level_one.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/level_one.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/level_one.rb --runtime-type-checking +@@ -6,10 +6,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.LevelOne", self) + + # @param props [JsiiCalc::LevelOneProps] + def initialize(props) + props = props.is_a?(Hash) ? ::JsiiCalc::LevelOneProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuTGV2ZWxPbmVQcm9wcyJ9")), "props") + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { +@@ -28,10 +29,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.LevelOne.PropBooleanValue", self) + + # @param value [Boolean] + def initialize(value:) + @value = value ++ Jsii::Type.check_type(@value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "value") + end + + # @return [Boolean] + attr_reader :value + +@@ -54,10 +56,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.LevelOne.PropProperty", self) + + # @param prop [JsiiCalc::LevelOne::PropBooleanValue] + def initialize(prop:) + @prop = prop.is_a?(Hash) ? ::JsiiCalc::LevelOne::PropBooleanValue.new(**prop.transform_keys(&:to_sym)) : prop ++ Jsii::Type.check_type(@prop, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuTGV2ZWxPbmUuUHJvcEJvb2xlYW5WYWx1ZSJ9")), "prop") + end + + # @return [JsiiCalc::LevelOne::PropBooleanValue] + attr_reader :prop +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/level_one_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/level_one_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/level_one_props.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.LevelOneProps", self) + + # @param prop [JsiiCalc::LevelOne::PropProperty] + def initialize(prop:) + @prop = prop.is_a?(Hash) ? ::JsiiCalc::LevelOne::PropProperty.new(**prop.transform_keys(&:to_sym)) : prop ++ Jsii::Type.check_type(@prop, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuTGV2ZWxPbmUuUHJvcFByb3BlcnR5In0=")), "prop") + end + + # @return [JsiiCalc::LevelOne::PropProperty] + attr_reader :prop +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/load_balanced_fargate_service_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/load_balanced_fargate_service_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/load_balanced_fargate_service_props.rb --runtime-type-checking +@@ -9,14 +9,19 @@ + # @param memory_mib [String, nil] The amount (in MiB) of memory used by the task. + # @param public_load_balancer [Boolean, nil] Determines whether the Application Load Balancer will be internet-facing. + # @param public_tasks [Boolean, nil] Determines whether your Fargate Service will be assigned a public IP address. + def initialize(container_port: nil, cpu: nil, memory_mib: nil, public_load_balancer: nil, public_tasks: nil) + @container_port = container_port ++ Jsii::Type.check_type(@container_port, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "containerPort") unless @container_port.nil? + @cpu = cpu ++ Jsii::Type.check_type(@cpu, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "cpu") unless @cpu.nil? + @memory_mib = memory_mib ++ Jsii::Type.check_type(@memory_mib, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "memoryMiB") unless @memory_mib.nil? + @public_load_balancer = public_load_balancer ++ Jsii::Type.check_type(@public_load_balancer, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "publicLoadBalancer") unless @public_load_balancer.nil? + @public_tasks = public_tasks ++ Jsii::Type.check_type(@public_tasks, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "publicTasks") unless @public_tasks.nil? + end + + # The container port of the application load balancer attached to your Fargate service. + # + # Corresponds to container port mapping. +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2530/my_class.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/module2530/my_class.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/module2530/my_class.rb --runtime-type-checking +@@ -7,10 +7,11 @@ + self.jsii_fqn = "jsii-calc.module2530.MyClass" + Jsii::Object.register_jsii_fqn("jsii-calc.module2530.MyClass", self) + + # @param _ [Numeric] + def initialize(_) ++ Jsii::Type.check_type(_, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "_") + Jsii::Object.instance_method(:initialize).bind(self).call(_) + end + + def self.jsii_overridable_methods + { +@@ -20,24 +21,29 @@ + end + + # @param _ [Boolean] + # @return [void] + def self.bar(_) ++ Jsii::Type.check_type(_, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "_") + Jsii::Kernel.instance.call_static("jsii-calc.module2530.MyClass", "bar", [_]) + end + + # @param _ [String] + # @return [void] + def foo(_) ++ Jsii::Type.check_type(_, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "_") + jsii_call_method("foo", [_]) + end + + # @param _ [String] + # @param __ [String] + # @param ___ [String] + # @return [void] + def multiple_underscores(_, __, ___) ++ Jsii::Type.check_type(_, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "_") ++ Jsii::Type.check_type(__, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "__") ++ Jsii::Type.check_type(___, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "___") + jsii_call_method("multipleUnderscores", [_, __, ___]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2647/extend_and_implement.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/module2647/extend_and_implement.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/module2647/extend_and_implement.rb --runtime-type-checking +@@ -8,10 +8,11 @@ + self.jsii_fqn = "jsii-calc.module2647.ExtendAndImplement" + Jsii::Object.register_jsii_fqn("jsii-calc.module2647.ExtendAndImplement", self) + + # @param very [Scope::JsiiCalcBaseOfBase::Very] + def initialize(very) ++ Jsii::Type.check_type(very, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWJhc2Utb2YtYmFzZS5WZXJ5In0=")), "very") + Jsii::Object.instance_method(:initialize).bind(self).call(very) + end + + def self.jsii_overridable_methods + { +@@ -22,10 +23,11 @@ + end + + # @param obj [Scope::JsiiCalcBase::IBaseInterface] + # @return [void] + def foo(obj) ++ Jsii::Type.check_type(obj, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWJhc2UuSUJhc2VJbnRlcmZhY2UifQ==")), "obj") + jsii_call_method("foo", [obj]) + end + + # Say hello! + # +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2689/methods/my_class.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/module2689/methods/my_class.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/module2689/methods/my_class.rb --runtime-type-checking +@@ -17,16 +17,18 @@ + + # @param _bar [Hash{String => Scope::JsiiCalcBase::BaseProps}] + # @return [void] + def bar(_bar) + _bar = _bar.is_a?(Hash) ? _bar.transform_values { |jsii_v0| jsii_v0.is_a?(Hash) ? ::Scope::JsiiCalcBase::BaseProps.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : _bar ++ Jsii::Type.check_type(_bar, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6IkBzY29wZS9qc2lpLWNhbGMtYmFzZS5CYXNlUHJvcHMifSwia2luZCI6Im1hcCJ9fQ==")), "_bar") + jsii_call_method("bar", [_bar]) + end + + # @param _values [Array] + # @return [void] + def foo(_values) ++ Jsii::Type.check_type(_values, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6IkBzY29wZS9qc2lpLWNhbGMtbGliLk51bWJlciJ9LCJraW5kIjoiYXJyYXkifX0=")), "_values") + jsii_call_method("foo", [_values]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2689/structs/my_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/module2689/structs/my_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/module2689/structs/my_struct.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param base_map [Hash{String => Scope::JsiiCalcBase::BaseProps}] + # @param numbers [Array] + def initialize(base_map:, numbers:) + @base_map = base_map.is_a?(Hash) ? base_map.transform_values { |jsii_v0| jsii_v0.is_a?(Hash) ? ::Scope::JsiiCalcBase::BaseProps.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } : base_map ++ Jsii::Type.check_type(@base_map, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6IkBzY29wZS9qc2lpLWNhbGMtYmFzZS5CYXNlUHJvcHMifSwia2luZCI6Im1hcCJ9fQ==")), "baseMap") + @numbers = numbers ++ Jsii::Type.check_type(@numbers, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6IkBzY29wZS9qc2lpLWNhbGMtbGliLk51bWJlciJ9LCJraW5kIjoiYXJyYXkifX0=")), "numbers") + end + + # @return [Hash{String => Scope::JsiiCalcBase::BaseProps}] + attr_reader :base_map + # @return [Array] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2692/submodule1/bar.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/module2692/submodule1/bar.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/module2692/submodule1/bar.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.module2692.submodule1.Bar", self) + + # @param bar1 [String] + def initialize(bar1:) + @bar1 = bar1 ++ Jsii::Type.check_type(@bar1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "bar1") + end + + # @return [String] + attr_reader :bar1 +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2692/submodule2/bar.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/module2692/submodule2/bar.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/module2692/submodule2/bar.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.module2692.submodule2.Bar", self) + + # @param bar2 [String] + def initialize(bar2:) + @bar2 = bar2 ++ Jsii::Type.check_type(@bar2, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "bar2") + end + + # @return [String] + attr_reader :bar2 +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/module2692/submodule2/foo.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/module2692/submodule2/foo.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/module2692/submodule2/foo.rb --runtime-type-checking +@@ -7,12 +7,15 @@ + # @param bar2 [String] + # @param bar1 [String] + # @param foo2 [String] + def initialize(bar2:, bar1:, foo2:) + @bar2 = bar2 ++ Jsii::Type.check_type(@bar2, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "bar2") + @bar1 = bar1 ++ Jsii::Type.check_type(@bar1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "bar1") + @foo2 = foo2 ++ Jsii::Type.check_type(@foo2, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "foo2") + end + + # @return [String] + attr_reader :bar2 + # @return [String] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/multiply.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/multiply.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/multiply.rb --runtime-type-checking +@@ -10,10 +10,12 @@ + # Creates a BinaryOperation. + # + # @param lhs [Scope::JsiiCalcLib::NumericValue] Left-hand side operand. + # @param rhs [Scope::JsiiCalcLib::NumericValue] Right-hand side operand. + def initialize(lhs, rhs) ++ Jsii::Type.check_type(lhs, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1lcmljVmFsdWUifQ==")), "lhs") ++ Jsii::Type.check_type(rhs, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1lcmljVmFsdWUifQ==")), "rhs") + Jsii::Object.instance_method(:initialize).bind(self).call(lhs, rhs) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/negate.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/negate.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/negate.rb --runtime-type-checking +@@ -6,10 +6,11 @@ + self.jsii_fqn = "jsii-calc.Negate" + Jsii::Object.register_jsii_fqn("jsii-calc.Negate", self) + + # @param operand [Scope::JsiiCalcLib::NumericValue] + def initialize(operand) ++ Jsii::Type.check_type(operand, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1lcmljVmFsdWUifQ==")), "operand") + Jsii::Object.instance_method(:initialize).bind(self).call(operand) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/nested_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/nested_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/nested_struct.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.NestedStruct", self) + + # @param number_prop [Numeric] When provided, must be > 0. + def initialize(number_prop:) + @number_prop = number_prop ++ Jsii::Type.check_type(@number_prop, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "numberProp") + end + + # When provided, must be > 0. + # + # @return [Numeric] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/null_should_be_treated_as_undefined.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/null_should_be_treated_as_undefined.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/null_should_be_treated_as_undefined.rb --runtime-type-checking +@@ -6,10 +6,12 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.NullShouldBeTreatedAsUndefined", self) + + # @param _param1 [String] + # @param optional [Object, nil] + def initialize(_param1, optional = nil) ++ Jsii::Type.check_type(_param1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "_param1") ++ Jsii::Type.check_type(optional, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "optional") unless optional.nil? + Jsii::Object.instance_method(:initialize).bind(self).call(_param1, optional) + end + + def self.jsii_overridable_methods + { +@@ -24,23 +26,26 @@ + def change_me_to_undefined() + jsii_get_property("changeMeToUndefined") + end + + def change_me_to_undefined=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "changeMeToUndefined") unless value.nil? + jsii_set_property("changeMeToUndefined", value) + end + + # @param value [Object, nil] + # @return [void] + def give_me_undefined(value = nil) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "value") unless value.nil? + jsii_call_method("giveMeUndefined", [value]) + end + + # @param input [JsiiCalc::NullShouldBeTreatedAsUndefinedData] + # @return [void] + def give_me_undefined_inside_an_object(input) + input = input.is_a?(Hash) ? ::JsiiCalc::NullShouldBeTreatedAsUndefinedData.new(**input.transform_keys(&:to_sym)) : input ++ Jsii::Type.check_type(input, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuTnVsbFNob3VsZEJlVHJlYXRlZEFzVW5kZWZpbmVkRGF0YSJ9")), "input") + jsii_call_method("giveMeUndefinedInsideAnObject", [input]) + end + + # @return [void] + def verify_property_is_undefined() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/null_should_be_treated_as_undefined_data.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/null_should_be_treated_as_undefined_data.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/null_should_be_treated_as_undefined_data.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param array_with_three_elements_and_undefined_as_second_argument [Array] + # @param this_should_be_undefined [Object, nil] + def initialize(array_with_three_elements_and_undefined_as_second_argument:, this_should_be_undefined: nil) + @array_with_three_elements_and_undefined_as_second_argument = array_with_three_elements_and_undefined_as_second_argument ++ Jsii::Type.check_type(@array_with_three_elements_and_undefined_as_second_argument, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6ImFueSJ9LCJraW5kIjoiYXJyYXkifX0=")), "arrayWithThreeElementsAndUndefinedAsSecondArgument") + @this_should_be_undefined = this_should_be_undefined ++ Jsii::Type.check_type(@this_should_be_undefined, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "thisShouldBeUndefined") unless @this_should_be_undefined.nil? + end + + # @return [Array] + attr_reader :array_with_three_elements_and_undefined_as_second_argument + # @return [Object, nil] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/number_generator.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/number_generator.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/number_generator.rb --runtime-type-checking +@@ -6,10 +6,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.NumberGenerator", self) + + # @param generator [JsiiCalc::IRandomNumberGenerator] + def initialize(generator) + generator = Jsii::Utils.coerce_callable(generator, ::JsiiCalc::IRandomNumberGenerator) ++ Jsii::Type.check_type(generator, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSVJhbmRvbU51bWJlckdlbmVyYXRvciJ9")), "generator") + Jsii::Object.instance_method(:initialize).bind(self).call(generator) + end + + def self.jsii_overridable_methods + { +@@ -24,17 +25,19 @@ + jsii_get_property("generator") + end + + def generator=(value) + value = Jsii::Utils.coerce_callable(value, ::JsiiCalc::IRandomNumberGenerator) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSVJhbmRvbU51bWJlckdlbmVyYXRvciJ9")), "generator") + jsii_set_property("generator", value) + end + + # @param gen [JsiiCalc::IRandomNumberGenerator] + # @return [Boolean] + def is_same_generator(gen) + gen = Jsii::Utils.coerce_callable(gen, ::JsiiCalc::IRandomNumberGenerator) ++ Jsii::Type.check_type(gen, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSVJhbmRvbU51bWJlckdlbmVyYXRvciJ9")), "gen") + jsii_call_method("isSameGenerator", [gen]) + end + + # @return [Numeric] + def next_times100() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/object_refs_in_collections.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/object_refs_in_collections.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/object_refs_in_collections.rb --runtime-type-checking +@@ -19,18 +19,20 @@ + # Returns the sum of all values. + # + # @param values [Array] + # @return [Numeric] + def sum_from_array(values) ++ Jsii::Type.check_type(values, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6IkBzY29wZS9qc2lpLWNhbGMtbGliLk51bWVyaWNWYWx1ZSJ9LCJraW5kIjoiYXJyYXkifX0=")), "values") + jsii_call_method("sumFromArray", [values]) + end + + # Returns the sum of all values in a map. + # + # @param values [Hash{String => Scope::JsiiCalcLib::NumericValue}] + # @return [Numeric] + def sum_from_map(values) ++ Jsii::Type.check_type(values, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6IkBzY29wZS9qc2lpLWNhbGMtbGliLk51bWVyaWNWYWx1ZSJ9LCJraW5kIjoibWFwIn19")), "values") + jsii_call_method("sumFromMap", [values]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/optional_argument_invoker.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/optional_argument_invoker.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/optional_argument_invoker.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.OptionalArgumentInvoker", self) + + # @param delegate [JsiiCalc::IInterfaceWithOptionalMethodArguments] + def initialize(delegate) + delegate = Jsii::Utils.coerce_callable(delegate, ::JsiiCalc::IInterfaceWithOptionalMethodArguments) ++ Jsii::Type.check_type(delegate, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUludGVyZmFjZVdpdGhPcHRpb25hbE1ldGhvZEFyZ3VtZW50cyJ9")), "delegate") + Jsii::Object.instance_method(:initialize).bind(self).call(delegate) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/optional_constructor_argument.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/optional_constructor_argument.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/optional_constructor_argument.rb --runtime-type-checking +@@ -6,10 +6,13 @@ + + # @param arg1 [Numeric] + # @param arg2 [String] + # @param arg3 [DateTime, nil] + def initialize(arg1, arg2, arg3 = nil) ++ Jsii::Type.check_type(arg1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "arg1") ++ Jsii::Type.check_type(arg2, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "arg2") ++ Jsii::Type.check_type(arg3, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJkYXRlIn0=")), "arg3") unless arg3.nil? + Jsii::Object.instance_method(:initialize).bind(self).call(arg1, arg2, arg3) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/optional_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/optional_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/optional_struct.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.OptionalStruct", self) + + # @param field [String, nil] + def initialize(field: nil) + @field = field ++ Jsii::Type.check_type(@field, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "field") unless @field.nil? + end + + # @return [String, nil] + attr_reader :field +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/optional_struct_consumer.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/optional_struct_consumer.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/optional_struct_consumer.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.OptionalStructConsumer", self) + + # @param optional_struct [JsiiCalc::OptionalStruct, nil] + def initialize(optional_struct = nil) + optional_struct = optional_struct.is_a?(Hash) ? ::JsiiCalc::OptionalStruct.new(**optional_struct.transform_keys(&:to_sym)) : optional_struct ++ Jsii::Type.check_type(optional_struct, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuT3B0aW9uYWxTdHJ1Y3QifQ==")), "optionalStruct") unless optional_struct.nil? + Jsii::Object.instance_method(:initialize).bind(self).call(optional_struct) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/overridable_protected_member.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/overridable_protected_member.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/overridable_protected_member.rb --runtime-type-checking +@@ -28,10 +28,11 @@ + def override_read_write() + jsii_get_property("overrideReadWrite") + end + + def override_read_write=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "overrideReadWrite") + jsii_set_property("overrideReadWrite", value) + end + + # @return [String] + def override_me() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/override_returns_object.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/override_returns_object.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/override_returns_object.rb --runtime-type-checking +@@ -15,10 +15,11 @@ + end + + # @param obj [JsiiCalc::IReturnsNumber] + # @return [Numeric] + def test(obj) ++ Jsii::Type.check_type(obj, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSVJldHVybnNOdW1iZXIifQ==")), "obj") + jsii_call_method("test", [obj]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/param_shadows_builtins.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/param_shadows_builtins.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/param_shadows_builtins.rb --runtime-type-checking +@@ -8,10 +8,13 @@ + # @param builtins [String] should be set to something that is NOT a valid expression in Python (e.g: "\${NOPE}""). + # @param str [String] should be set to something that is NOT a valid expression in Python (e.g: "\${NOPE}""). + # @param props [JsiiCalc::ParamShadowsBuiltinsProps] should be set to valid values. + def initialize(builtins, str, props) + props = props.is_a?(Hash) ? ::JsiiCalc::ParamShadowsBuiltinsProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(builtins, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "builtins") ++ Jsii::Type.check_type(str, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "str") ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuUGFyYW1TaGFkb3dzQnVpbHRpbnNQcm9wcyJ9")), "props") + Jsii::Object.instance_method(:initialize).bind(self).call(builtins, str, props) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/param_shadows_builtins_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/param_shadows_builtins_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/param_shadows_builtins_props.rb --runtime-type-checking +@@ -6,12 +6,15 @@ + # @param boolean_property [Boolean] + # @param string_property [String] + # @param struct_property [JsiiCalc::StructA] + def initialize(boolean_property:, string_property:, struct_property:) + @boolean_property = boolean_property ++ Jsii::Type.check_type(@boolean_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "booleanProperty") + @string_property = string_property ++ Jsii::Type.check_type(@string_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "stringProperty") + @struct_property = struct_property.is_a?(Hash) ? ::JsiiCalc::StructA.new(**struct_property.transform_keys(&:to_sym)) : struct_property ++ Jsii::Type.check_type(@struct_property, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0QSJ9")), "structProperty") + end + + # @return [Boolean] + attr_reader :boolean_property + # @return [String] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/param_shadows_scope.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/param_shadows_scope.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/param_shadows_scope.rb --runtime-type-checking +@@ -18,10 +18,11 @@ + end + + # @param scope [Scope::JsiiCalcLib::Number] + # @return [Scope::JsiiCalcLib::Number] + def use_scope(scope) ++ Jsii::Type.check_type(scope, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1iZXIifQ==")), "scope") + jsii_call_method("useScope", [scope]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/parent_struct982.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/parent_struct982.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/parent_struct982.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.ParentStruct982", self) + + # @param foo [String] + def initialize(foo:) + @foo = foo ++ Jsii::Type.check_type(@foo, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "foo") + end + + # @return [String] + attr_reader :foo +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/partially_initialized_this_consumer.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/partially_initialized_this_consumer.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/partially_initialized_this_consumer.rb --runtime-type-checking +@@ -17,10 +17,13 @@ + # @param obj [JsiiCalc::ConstructorPassesThisOut] + # @param dt [DateTime] + # @param ev [JsiiCalc::AllTypesEnum] + # @return [String] + def consume_partially_initialized_this(obj, dt, ev) ++ Jsii::Type.check_type(obj, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuQ29uc3RydWN0b3JQYXNzZXNUaGlzT3V0In0=")), "obj") ++ Jsii::Type.check_type(dt, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJkYXRlIn0=")), "dt") ++ Jsii::Type.check_type(ev, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuQWxsVHlwZXNFbnVtIn0=")), "ev") + jsii_call_method("consumePartiallyInitializedThis", [obj, dt, ev]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/polymorphism.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/polymorphism.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/polymorphism.rb --runtime-type-checking +@@ -16,10 +16,11 @@ + + # @param friendly [Scope::JsiiCalcLib::IFriendly] + # @return [String] + def say_hello(friendly) + friendly = Jsii::Utils.coerce_callable(friendly, ::Scope::JsiiCalcLib::IFriendly) ++ Jsii::Type.check_type(friendly, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5JRnJpZW5kbHkifQ==")), "friendly") + jsii_call_method("sayHello", [friendly]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/power.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/power.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/power.rb --runtime-type-checking +@@ -8,10 +8,12 @@ + # Creates a Power operation. + # + # @param base [Scope::JsiiCalcLib::NumericValue] The base of the power. + # @param pow [Scope::JsiiCalcLib::NumericValue] The number of times to multiply. + def initialize(base, pow) ++ Jsii::Type.check_type(base, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1lcmljVmFsdWUifQ==")), "base") ++ Jsii::Type.check_type(pow, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1lcmljVmFsdWUifQ==")), "pow") + Jsii::Object.instance_method(:initialize).bind(self).call(base, pow) + end + + def self.jsii_overridable_methods + { +@@ -49,10 +51,11 @@ + def decoration_postfixes() + jsii_get_property("decorationPostfixes") + end + + def decoration_postfixes=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "decorationPostfixes") + jsii_set_property("decorationPostfixes", value) + end + + # A set of prefixes to include in a decorated .toString(). + # +@@ -60,10 +63,11 @@ + def decoration_prefixes() + jsii_get_property("decorationPrefixes") + end + + def decoration_prefixes=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "decorationPrefixes") + jsii_set_property("decorationPrefixes", value) + end + + # The .toString() style. + # +@@ -71,10 +75,11 @@ + def string_style() + jsii_get_property("stringStyle") + end + + def string_style=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuY29tcG9zaXRpb24uQ29tcG9zaXRlT3BlcmF0aW9uLkNvbXBvc2l0aW9uU3RyaW5nU3R5bGUifQ==")), "stringStyle") + jsii_set_property("stringStyle", value) + end + + # The base of the power. + # +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/python_self/class_with_self.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/python_self/class_with_self.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/python_self/class_with_self.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + self.jsii_fqn = "jsii-calc.PythonSelf.ClassWithSelf" + Jsii::Object.register_jsii_fqn("jsii-calc.PythonSelf.ClassWithSelf", self) + + # @param _self [String] + def initialize(_self) ++ Jsii::Type.check_type(_self, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "self") + Jsii::Object.instance_method(:initialize).bind(self).call(_self) + end + + def self.jsii_overridable_methods + { +@@ -22,10 +23,11 @@ + end + + # @param _self [Numeric] + # @return [String] + def method(_self) ++ Jsii::Type.check_type(_self, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "self") + jsii_call_method("method", [_self]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/python_self/class_with_self_kwarg.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/python_self/class_with_self_kwarg.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/python_self/class_with_self_kwarg.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.PythonSelf.ClassWithSelfKwarg", self) + + # @param props [JsiiCalc::PythonSelf::StructWithSelf] + def initialize(props) + props = props.is_a?(Hash) ? ::JsiiCalc::PythonSelf::StructWithSelf.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuUHl0aG9uU2VsZi5TdHJ1Y3RXaXRoU2VsZiJ9")), "props") + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/python_self/i_interface_with_self.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/python_self/i_interface_with_self.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/python_self/i_interface_with_self.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.PythonSelf.IInterfaceWithSelf", self) + + # @param _self [Numeric] + # @return [String] + def method(_self) ++ Jsii::Type.check_type(_self, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "self") + jsii_call_method("method", [_self]) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/python_self/struct_with_self.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/python_self/struct_with_self.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/python_self/struct_with_self.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.PythonSelf.StructWithSelf", self) + + # @param _self [String] + def initialize(_self:) + @_self = _self ++ Jsii::Type.check_type(@_self, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "self") + end + + # @return [String] + attr_reader :_self +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/reference_enum_from_scoped_package.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/reference_enum_from_scoped_package.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/reference_enum_from_scoped_package.rb --runtime-type-checking +@@ -21,10 +21,11 @@ + def foo() + jsii_get_property("foo") + end + + def foo=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5FbnVtRnJvbVNjb3BlZE1vZHVsZSJ9")), "foo") unless value.nil? + jsii_set_property("foo", value) + end + + # @return [Scope::JsiiCalcLib::EnumFromScopedModule, nil] + def load_foo() +@@ -32,10 +33,11 @@ + end + + # @param value [Scope::JsiiCalcLib::EnumFromScopedModule] + # @return [void] + def save_foo(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5FbnVtRnJvbVNjb3BlZE1vZHVsZSJ9")), "value") + jsii_call_method("saveFoo", [value]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/root_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/root_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/root_struct.rb --runtime-type-checking +@@ -9,11 +9,13 @@ + + # @param string_prop [String] May not be empty. + # @param nested_struct [JsiiCalc::NestedStruct, nil] + def initialize(string_prop:, nested_struct: nil) + @string_prop = string_prop ++ Jsii::Type.check_type(@string_prop, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "stringProp") + @nested_struct = nested_struct.is_a?(Hash) ? ::JsiiCalc::NestedStruct.new(**nested_struct.transform_keys(&:to_sym)) : nested_struct ++ Jsii::Type.check_type(@nested_struct, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuTmVzdGVkU3RydWN0In0=")), "nestedStruct") unless @nested_struct.nil? + end + + # May not be empty. + # + # @return [String] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/root_struct_validator.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/root_struct_validator.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/root_struct_validator.rb --runtime-type-checking +@@ -15,10 +15,11 @@ + + # @param struct [JsiiCalc::RootStruct] + # @return [void] + def self.validate(struct) + struct = struct.is_a?(Hash) ? ::JsiiCalc::RootStruct.new(**struct.transform_keys(&:to_sym)) : struct ++ Jsii::Type.check_type(struct, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuUm9vdFN0cnVjdCJ9")), "struct") + Jsii::Kernel.instance.call_static("jsii-calc.RootStructValidator", "validate", [struct]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/runtime_type_checking.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/runtime_type_checking.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/runtime_type_checking.rb --runtime-type-checking +@@ -19,26 +19,33 @@ + # @param arg1 [Numeric, nil] + # @param arg2 [String, nil] + # @param arg3 [DateTime, nil] + # @return [void] + def method_with_defaulted_arguments(arg1 = nil, arg2 = nil, arg3 = nil) ++ Jsii::Type.check_type(arg1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "arg1") unless arg1.nil? ++ Jsii::Type.check_type(arg2, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "arg2") unless arg2.nil? ++ Jsii::Type.check_type(arg3, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJkYXRlIn0=")), "arg3") unless arg3.nil? + jsii_call_method("methodWithDefaultedArguments", [arg1, arg2, arg3]) + end + + # @param arg [Object, nil] + # @return [void] + def method_with_optional_any_argument(arg = nil) ++ Jsii::Type.check_type(arg, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJhbnkifQ==")), "arg") unless arg.nil? + jsii_call_method("methodWithOptionalAnyArgument", [arg]) + end + + # Used to verify verification of number of method arguments. + # + # @param arg1 [Numeric] + # @param arg2 [String] + # @param arg3 [DateTime, nil] + # @return [void] + def method_with_optional_arguments(arg1, arg2, arg3 = nil) ++ Jsii::Type.check_type(arg1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "arg1") ++ Jsii::Type.check_type(arg2, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "arg2") ++ Jsii::Type.check_type(arg3, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJkYXRlIn0=")), "arg3") unless arg3.nil? + jsii_call_method("methodWithOptionalArguments", [arg1, arg2, arg3]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/second_level_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/second_level_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/second_level_struct.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param deeper_required_prop [String] It's long and required. + # @param deeper_optional_prop [String, nil] It's long, but you'll almost never pass it. + def initialize(deeper_required_prop:, deeper_optional_prop: nil) + @deeper_required_prop = deeper_required_prop ++ Jsii::Type.check_type(@deeper_required_prop, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "deeperRequiredProp") + @deeper_optional_prop = deeper_optional_prop ++ Jsii::Type.check_type(@deeper_optional_prop, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "deeperOptionalProp") unless @deeper_optional_prop.nil? + end + + # It's long and required. + # + # @return [String] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/singleton_int.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/singleton_int.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/singleton_int.rb --runtime-type-checking +@@ -18,10 +18,11 @@ + end + + # @param value [Numeric] + # @return [Boolean] + def is_singleton_int(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "value") + jsii_call_method("isSingletonInt", [value]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/singleton_string.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/singleton_string.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/singleton_string.rb --runtime-type-checking +@@ -18,10 +18,11 @@ + end + + # @param value [String] + # @return [Boolean] + def is_singleton_string(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "value") + jsii_call_method("isSingletonString", [value]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/smelly_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/smelly_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/smelly_struct.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param property [String] + # @param yet_anoter_one [Boolean] + def initialize(property:, yet_anoter_one:) + @property = property ++ Jsii::Type.check_type(@property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "property") + @yet_anoter_one = yet_anoter_one ++ Jsii::Type.check_type(@yet_anoter_one, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "yetAnoterOne") + end + + # @return [String] + attr_reader :property + # @return [Boolean] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/some_containing_class.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/some_containing_class.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/some_containing_class.rb --runtime-type-checking +@@ -30,10 +30,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.SomeContainingClass.ParentStruct", self) + + # @param field1 [String] + def initialize(field1:) + @field1 = field1 ++ Jsii::Type.check_type(@field1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "field1") + end + + # @return [String] + attr_reader :field1 + +@@ -57,11 +58,13 @@ + + # @param field1 [String] + # @param field2 [String] + def initialize(field1:, field2:) + @field1 = field1 ++ Jsii::Type.check_type(@field1, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "field1") + @field2 = field2 ++ Jsii::Type.check_type(@field2, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "field2") + end + + # @return [String] + attr_reader :field1 + # @return [String] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/stable_class.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/stable_class.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/stable_class.rb --runtime-type-checking +@@ -5,10 +5,12 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.StableClass", self) + + # @param readonly_string [String] + # @param mutable_number [Numeric, nil] + def initialize(readonly_string, mutable_number = nil) ++ Jsii::Type.check_type(readonly_string, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readonlyString") ++ Jsii::Type.check_type(mutable_number, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mutableNumber") unless mutable_number.nil? + Jsii::Object.instance_method(:initialize).bind(self).call(readonly_string, mutable_number) + end + + def self.jsii_overridable_methods + { +@@ -27,10 +29,11 @@ + def mutable_property() + jsii_get_property("mutableProperty") + end + + def mutable_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "mutableProperty") unless value.nil? + jsii_set_property("mutableProperty", value) + end + + # @return [void] + def method() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/stable_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/stable_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/stable_struct.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.StableStruct", self) + + # @param readonly_property [String] + def initialize(readonly_property:) + @readonly_property = readonly_property ++ Jsii::Type.check_type(@readonly_property, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "readonlyProperty") + end + + # @return [String] + attr_reader :readonly_property +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/static_context.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/static_context.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/static_context.rb --runtime-type-checking +@@ -25,10 +25,11 @@ + def self.static_variable() + Jsii::Kernel.instance.get_static("jsii-calc.StaticContext", "staticVariable") + end + + def self.static_variable=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "staticVariable") + Jsii::Kernel.instance.set_static("jsii-calc.StaticContext", "staticVariable", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/statics.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/statics.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/statics.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + self.jsii_fqn = "jsii-calc.Statics" + Jsii::Object.register_jsii_fqn("jsii-calc.Statics", self) + + # @param value [String] + def initialize(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "value") + Jsii::Object.instance_method(:initialize).bind(self).call(value) + end + + def self.jsii_overridable_methods + { +@@ -19,10 +20,11 @@ + # Jsdocs for static method. + # + # @param name [String] The name of the person to say hello to. + # @return [String] + def self.static_method(name) ++ Jsii::Type.check_type(name, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "name") + Jsii::Kernel.instance.call_static("jsii-calc.Statics", "staticMethod", [name]) + end + + # Constants may also use all-caps. + # +@@ -58,19 +60,21 @@ + def self.instance() + Jsii::Kernel.instance.get_static("jsii-calc.Statics", "instance") + end + + def self.instance=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuU3RhdGljcyJ9")), "instance") + Jsii::Kernel.instance.set_static("jsii-calc.Statics", "instance", value) + end + + # @return [Numeric] + def self.non_const_static() + Jsii::Kernel.instance.get_static("jsii-calc.Statics", "nonConstStatic") + end + + def self.non_const_static=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "nonConstStatic") + Jsii::Kernel.instance.set_static("jsii-calc.Statics", "nonConstStatic", value) + end + + # @return [String] + def value() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/strip_internal.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/strip_internal.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/strip_internal.rb --runtime-type-checking +@@ -18,10 +18,11 @@ + def you_see_me() + jsii_get_property("youSeeMe") + end + + def you_see_me=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "youSeeMe") + jsii_set_property("youSeeMe", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_a.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/struct_a.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/struct_a.rb --runtime-type-checking +@@ -7,12 +7,15 @@ + # @param required_string [String] + # @param optional_number [Numeric, nil] + # @param optional_string [String, nil] + def initialize(required_string:, optional_number: nil, optional_string: nil) + @required_string = required_string ++ Jsii::Type.check_type(@required_string, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "requiredString") + @optional_number = optional_number ++ Jsii::Type.check_type(@optional_number, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "optionalNumber") unless @optional_number.nil? + @optional_string = optional_string ++ Jsii::Type.check_type(@optional_string, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "optionalString") unless @optional_string.nil? + end + + # @return [String] + attr_reader :required_string + # @return [Numeric, nil] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_b.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/struct_b.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/struct_b.rb --runtime-type-checking +@@ -7,12 +7,15 @@ + # @param required_string [String] + # @param optional_boolean [Boolean, nil] + # @param optional_struct_a [JsiiCalc::StructA, nil] + def initialize(required_string:, optional_boolean: nil, optional_struct_a: nil) + @required_string = required_string ++ Jsii::Type.check_type(@required_string, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "requiredString") + @optional_boolean = optional_boolean ++ Jsii::Type.check_type(@optional_boolean, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "optionalBoolean") unless @optional_boolean.nil? + @optional_struct_a = optional_struct_a.is_a?(Hash) ? ::JsiiCalc::StructA.new(**optional_struct_a.transform_keys(&:to_sym)) : optional_struct_a ++ Jsii::Type.check_type(@optional_struct_a, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0QSJ9")), "optionalStructA") unless @optional_struct_a.nil? + end + + # @return [String] + attr_reader :required_string + # @return [Boolean, nil] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_parameter_type.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/struct_parameter_type.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/struct_parameter_type.rb --runtime-type-checking +@@ -8,11 +8,13 @@ + + # @param scope [String] + # @param props [Boolean, nil] + def initialize(scope:, props: nil) + @scope = scope ++ Jsii::Type.check_type(@scope, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "scope") + @props = props ++ Jsii::Type.check_type(@props, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "props") unless @props.nil? + end + + # @return [String] + attr_reader :scope + # @return [Boolean, nil] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_passing.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/struct_passing.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/struct_passing.rb --runtime-type-checking +@@ -16,19 +16,25 @@ + + # @param _positional [Numeric] + # @param inputs [Array] + # @return [Numeric] + def self.how_many_var_args_did_i_pass(_positional, *inputs) ++ Jsii::Type.check_type(_positional, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "_positional") + inputs.map! { |jsii_v0| jsii_v0.is_a?(Hash) ? ::JsiiCalc::TopLevelStruct.new(**jsii_v0.transform_keys(&:to_sym)) : jsii_v0 } ++ inputs.each_with_index do |item, index| ++ Jsii::Type.check_type(item, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuVG9wTGV2ZWxTdHJ1Y3QifQ==")), "inputs[#{index}]") ++ end + Jsii::Kernel.instance.call_static("jsii-calc.StructPassing", "howManyVarArgsDidIPass", [_positional, *inputs]) + end + + # @param _positional [Numeric] + # @param input [JsiiCalc::TopLevelStruct] + # @return [JsiiCalc::TopLevelStruct] + def self.round_trip(_positional, input) ++ Jsii::Type.check_type(_positional, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "_positional") + input = input.is_a?(Hash) ? ::JsiiCalc::TopLevelStruct.new(**input.transform_keys(&:to_sym)) : input ++ Jsii::Type.check_type(input, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuVG9wTGV2ZWxTdHJ1Y3QifQ==")), "input") + Jsii::Kernel.instance.call_static("jsii-calc.StructPassing", "roundTrip", [_positional, input]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_union_consumer.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/struct_union_consumer.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/struct_union_consumer.rb --runtime-type-checking +@@ -14,22 +14,25 @@ + end + + # @param struct [JsiiCalc::StructA, JsiiCalc::StructB] + # @return [Boolean] + def self.is_struct_a(struct) ++ Jsii::Type.check_type(struct, JSON.parse(Base64.strict_decode64("eyJ1bmlvbiI6eyJ0eXBlcyI6W3siZnFuIjoianNpaS1jYWxjLlN0cnVjdEEifSx7ImZxbiI6ImpzaWktY2FsYy5TdHJ1Y3RCIn1dfX0=")), "struct") + Jsii::Kernel.instance.call_static("jsii-calc.StructUnionConsumer", "isStructA", [struct]) + end + + # @param struct [JsiiCalc::StructA, JsiiCalc::StructB] + # @return [Boolean] + def self.is_struct_b(struct) ++ Jsii::Type.check_type(struct, JSON.parse(Base64.strict_decode64("eyJ1bmlvbiI6eyJ0eXBlcyI6W3siZnFuIjoianNpaS1jYWxjLlN0cnVjdEEifSx7ImZxbiI6ImpzaWktY2FsYy5TdHJ1Y3RCIn1dfX0=")), "struct") + Jsii::Kernel.instance.call_static("jsii-calc.StructUnionConsumer", "isStructB", [struct]) + end + + # @param which [String] + # @return [JsiiCalc::StructA, JsiiCalc::StructB] + def self.provide_struct(which) ++ Jsii::Type.check_type(which, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "which") + Jsii::Kernel.instance.call_static("jsii-calc.StructUnionConsumer", "provideStruct", [which]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_with_collection_of_unionts.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/struct_with_collection_of_unionts.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/struct_with_collection_of_unionts.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.StructWithCollectionOfUnionts", self) + + # @param union_property [Array JsiiCalc::StructA, JsiiCalc::StructB}>] + def initialize(union_property:) + @union_property = union_property ++ Jsii::Type.check_type(@union_property, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImNvbGxlY3Rpb24iOnsiZWxlbWVudHR5cGUiOnsidW5pb24iOnsidHlwZXMiOlt7ImZxbiI6ImpzaWktY2FsYy5TdHJ1Y3RBIn0seyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0QiJ9XX19LCJraW5kIjoibWFwIn19LCJraW5kIjoiYXJyYXkifX0=")), "unionProperty") + end + + # @return [Array JsiiCalc::StructA, JsiiCalc::StructB}>] + attr_reader :union_property +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_with_enum.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/struct_with_enum.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/struct_with_enum.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param foo [JsiiCalc::StringEnum] An enum value. + # @param bar [JsiiCalc::AllTypesEnum, nil] Optional enum value (of type integer). + def initialize(foo:, bar: nil) + @foo = foo ++ Jsii::Type.check_type(@foo, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuU3RyaW5nRW51bSJ9")), "foo") + @bar = bar ++ Jsii::Type.check_type(@bar, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuQWxsVHlwZXNFbnVtIn0=")), "bar") unless @bar.nil? + end + + # An enum value. + # + # @return [JsiiCalc::StringEnum] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/struct_with_java_reserved_words.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/struct_with_java_reserved_words.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/struct_with_java_reserved_words.rb --runtime-type-checking +@@ -7,13 +7,17 @@ + # @param assert [String, nil] + # @param result [String, nil] + # @param that [String, nil] + def initialize(default:, assert: nil, result: nil, that: nil) + @default = default ++ Jsii::Type.check_type(@default, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "default") + @assert = assert ++ Jsii::Type.check_type(@assert, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "assert") unless @assert.nil? + @result = result ++ Jsii::Type.check_type(@result, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "result") unless @result.nil? + @that = that ++ Jsii::Type.check_type(@that, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "that") unless @that.nil? + end + + # @return [String] + attr_reader :default + # @return [String, nil] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/back_references/my_class_reference.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/submodule/back_references/my_class_reference.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/submodule/back_references/my_class_reference.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.back_references.MyClassReference", self) + + # @param reference [JsiiCalc::Submodule::MyClass] + def initialize(reference:) + @reference = reference ++ Jsii::Type.check_type(@reference, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuc3VibW9kdWxlLk15Q2xhc3MifQ==")), "reference") + end + + # @return [JsiiCalc::Submodule::MyClass] + attr_reader :reference +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/child/kwargs_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/submodule/child/kwargs_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/submodule/child/kwargs_props.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param prop [JsiiCalc::Submodule::Child::SomeEnum] + # @param extra [String, nil] + def initialize(prop:, extra: nil) + @prop = prop ++ Jsii::Type.check_type(@prop, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuc3VibW9kdWxlLmNoaWxkLlNvbWVFbnVtIn0=")), "prop") + @extra = extra ++ Jsii::Type.check_type(@extra, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "extra") unless @extra.nil? + end + + # @return [JsiiCalc::Submodule::Child::SomeEnum] + attr_reader :prop + # @return [String, nil] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/child/some_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/submodule/child/some_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/submodule/child/some_struct.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.child.SomeStruct", self) + + # @param prop [JsiiCalc::Submodule::Child::SomeEnum] + def initialize(prop:) + @prop = prop ++ Jsii::Type.check_type(@prop, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuc3VibW9kdWxlLmNoaWxkLlNvbWVFbnVtIn0=")), "prop") + end + + # @return [JsiiCalc::Submodule::Child::SomeEnum] + attr_reader :prop +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/child/structure.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/submodule/child/structure.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/submodule/child/structure.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.child.Structure", self) + + # @param bool [Boolean] + def initialize(bool:) + @bool = bool ++ Jsii::Type.check_type(@bool, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJib29sZWFuIn0=")), "bool") + end + + # @return [Boolean] + attr_reader :bool +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/default.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/submodule/default.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/submodule/default.rb --runtime-type-checking +@@ -7,10 +7,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.Default", self) + + # @param foo [Numeric] + def initialize(foo:) + @foo = foo ++ Jsii::Type.check_type(@foo, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "foo") + end + + # @return [Numeric] + attr_reader :foo +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/isolated/kwargs.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/submodule/isolated/kwargs.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/submodule/isolated/kwargs.rb --runtime-type-checking +@@ -16,10 +16,11 @@ + + # @param props [JsiiCalc::Submodule::Child::KwargsProps, nil] + # @return [Boolean] + def self.method(props = nil) + props = props.is_a?(Hash) ? ::JsiiCalc::Submodule::Child::KwargsProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuc3VibW9kdWxlLmNoaWxkLkt3YXJnc1Byb3BzIn0=")), "props") unless props.nil? + Jsii::Kernel.instance.call_static("jsii-calc.submodule.isolated.Kwargs", "method", [props]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/my_class.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/submodule/my_class.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/submodule/my_class.rb --runtime-type-checking +@@ -6,10 +6,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.MyClass", self) + + # @param props [JsiiCalc::Submodule::Child::SomeStruct] + def initialize(props) + props = props.is_a?(Hash) ? ::JsiiCalc::Submodule::Child::SomeStruct.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuc3VibW9kdWxlLmNoaWxkLlNvbWVTdHJ1Y3QifQ==")), "props") + Jsii::Object.instance_method(:initialize).bind(self).call(props) + end + + def self.jsii_overridable_methods + { +@@ -46,17 +47,19 @@ + def all_types() + jsii_get_property("allTypes") + end + + def all_types=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuQWxsVHlwZXMifQ==")), "allTypes") unless value.nil? + jsii_set_property("allTypes", value) + end + + # @param param [JsiiCalc::Submodule::Param::SpecialParameter] + # @return [String] + def method_with_special_param(param) + param = param.is_a?(Hash) ? ::JsiiCalc::Submodule::Param::SpecialParameter.new(**param.transform_keys(&:to_sym)) : param ++ Jsii::Type.check_type(param, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuc3VibW9kdWxlLnBhcmFtLlNwZWNpYWxQYXJhbWV0ZXIifQ==")), "param") + jsii_call_method("methodWithSpecialParam", [param]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/submodule/param/special_parameter.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/submodule/param/special_parameter.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/submodule/param/special_parameter.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + Jsii::Object.register_jsii_fqn("jsii-calc.submodule.param.SpecialParameter", self) + + # @param value [String] + def initialize(value:) + @value = value ++ Jsii::Type.check_type(@value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "value") + end + + # @return [String] + attr_reader :value +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/sum.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/sum.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/sum.rb --runtime-type-checking +@@ -44,10 +44,11 @@ + def decoration_postfixes() + jsii_get_property("decorationPostfixes") + end + + def decoration_postfixes=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "decorationPostfixes") + jsii_set_property("decorationPostfixes", value) + end + + # A set of prefixes to include in a decorated .toString(). + # +@@ -55,10 +56,11 @@ + def decoration_prefixes() + jsii_get_property("decorationPrefixes") + end + + def decoration_prefixes=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6InN0cmluZyJ9LCJraW5kIjoiYXJyYXkifX0=")), "decorationPrefixes") + jsii_set_property("decorationPrefixes", value) + end + + # The .toString() style. + # +@@ -66,10 +68,11 @@ + def string_style() + jsii_get_property("stringStyle") + end + + def string_style=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuY29tcG9zaXRpb24uQ29tcG9zaXRlT3BlcmF0aW9uLkNvbXBvc2l0aW9uU3RyaW5nU3R5bGUifQ==")), "stringStyle") + jsii_set_property("stringStyle", value) + end + + # The parts to sum. + # +@@ -77,10 +80,11 @@ + def parts() + jsii_get_property("parts") + end + + def parts=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7ImZxbiI6IkBzY29wZS9qc2lpLWNhbGMtbGliLk51bWVyaWNWYWx1ZSJ9LCJraW5kIjoiYXJyYXkifX0=")), "parts") + jsii_set_property("parts", value) + end + + # @return [Object] the name of the class (to verify native type names are created for derived classes). + def type_name() +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/supports_nice_java_builder.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/supports_nice_java_builder.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/supports_nice_java_builder.rb --runtime-type-checking +@@ -8,10 +8,16 @@ + # @param default_bar [Numeric, nil] the default value of \`bar\`. + # @param props [JsiiCalc::SupportsNiceJavaBuilderProps, nil] some props once can provide. + # @param rest [Array] a variadic continuation. + def initialize(id, default_bar = nil, props = nil, *rest) + props = props.is_a?(Hash) ? ::JsiiCalc::SupportsNiceJavaBuilderProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(id, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "id") ++ Jsii::Type.check_type(default_bar, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "defaultBar") unless default_bar.nil? ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuU3VwcG9ydHNOaWNlSmF2YUJ1aWxkZXJQcm9wcyJ9")), "props") unless props.nil? ++ rest.each_with_index do |item, index| ++ Jsii::Type.check_type(item, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "rest[#{index}]") ++ end + Jsii::Object.instance_method(:initialize).bind(self).call(id, default_bar, props, *rest) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/supports_nice_java_builder_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/supports_nice_java_builder_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/supports_nice_java_builder_props.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param bar [Numeric] Some number, like 42. + # @param id [String, nil] An \`id\` field here is terrible API design, because the constructor of \`SupportsNiceJavaBuilder\` already has a parameter named \`id\`. + def initialize(bar:, id: nil) + @bar = bar ++ Jsii::Type.check_type(@bar, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "bar") + @id = id ++ Jsii::Type.check_type(@id, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "id") unless @id.nil? + end + + # Some number, like 42. + # + # @return [Numeric] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/supports_nice_java_builder_with_required_props.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/supports_nice_java_builder_with_required_props.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/supports_nice_java_builder_with_required_props.rb --runtime-type-checking +@@ -7,10 +7,12 @@ + + # @param id [Numeric] some identifier of your choice. + # @param props [JsiiCalc::SupportsNiceJavaBuilderProps] some properties. + def initialize(id, props) + props = props.is_a?(Hash) ? ::JsiiCalc::SupportsNiceJavaBuilderProps.new(**props.transform_keys(&:to_sym)) : props ++ Jsii::Type.check_type(id, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "id") ++ Jsii::Type.check_type(props, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuU3VwcG9ydHNOaWNlSmF2YUJ1aWxkZXJQcm9wcyJ9")), "props") + Jsii::Object.instance_method(:initialize).bind(self).call(id, props) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/sync_virtual_methods.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/sync_virtual_methods.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/sync_virtual_methods.rb --runtime-type-checking +@@ -38,46 +38,51 @@ + def a() + jsii_get_property("a") + end + + def a=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "a") + jsii_set_property("a", value) + end + + # @return [Numeric] + def caller_is_property() + jsii_get_property("callerIsProperty") + end + + def caller_is_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "callerIsProperty") + jsii_set_property("callerIsProperty", value) + end + + # @return [String] + def other_property() + jsii_get_property("otherProperty") + end + + def other_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "otherProperty") + jsii_set_property("otherProperty", value) + end + + # @return [String] + def the_property() + jsii_get_property("theProperty") + end + + def the_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "theProperty") + jsii_set_property("theProperty", value) + end + + # @return [String] + def value_of_other_property() + jsii_get_property("valueOfOtherProperty") + end + + def value_of_other_property=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "valueOfOtherProperty") + jsii_set_property("valueOfOtherProperty", value) + end + + # @return [Numeric] + def caller_is_async() +@@ -90,16 +95,18 @@ + end + + # @param value [String] + # @return [void] + def modify_other_property(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "value") + jsii_call_method("modifyOtherProperty", [value]) + end + + # @param value [String] + # @return [void] + def modify_value_of_the_property(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "value") + jsii_call_method("modifyValueOfTheProperty", [value]) + end + + # @return [Numeric] + def read_a() +@@ -122,16 +129,18 @@ + end + + # @param n [Numeric] + # @return [Numeric] + def virtual_method(n) ++ Jsii::Type.check_type(n, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "n") + jsii_call_method("virtualMethod", [n]) + end + + # @param value [Numeric] + # @return [void] + def write_a(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "value") + jsii_call_method("writeA", [value]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/test_struct_with_enum.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/test_struct_with_enum.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/test_struct_with_enum.rb --runtime-type-checking +@@ -35,19 +35,21 @@ + # + # @param input [JsiiCalc::StructWithEnum] + # @return [Boolean] + def is_string_enum_a(input) + input = input.is_a?(Hash) ? ::JsiiCalc::StructWithEnum.new(**input.transform_keys(&:to_sym)) : input ++ Jsii::Type.check_type(input, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0V2l0aEVudW0ifQ==")), "input") + jsii_call_method("isStringEnumA", [input]) + end + + # Returns true if \`foo\` is \`StringEnum.B\` and \`bar\` is \`AllTypesEnum.THIS_IS_GREAT\`. + # + # @param input [JsiiCalc::StructWithEnum] + # @return [Boolean] + def is_string_enum_b(input) + input = input.is_a?(Hash) ? ::JsiiCalc::StructWithEnum.new(**input.transform_keys(&:to_sym)) : input ++ Jsii::Type.check_type(input, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0V2l0aEVudW0ifQ==")), "input") + jsii_call_method("isStringEnumB", [input]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/top_level_struct.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/top_level_struct.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/top_level_struct.rb --runtime-type-checking +@@ -6,12 +6,15 @@ + # @param required [String] This is a required field. + # @param second_level [Numeric, JsiiCalc::SecondLevelStruct] A union to really stress test our serialization. + # @param optional [String, nil] You don't have to pass this. + def initialize(required:, second_level:, optional: nil) + @required = required ++ Jsii::Type.check_type(@required, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "required") + @second_level = second_level.is_a?(Hash) ? ::JsiiCalc::SecondLevelStruct.new(**second_level.transform_keys(&:to_sym)) : second_level ++ Jsii::Type.check_type(@second_level, JSON.parse(Base64.strict_decode64("eyJ1bmlvbiI6eyJ0eXBlcyI6W3sicHJpbWl0aXZlIjoibnVtYmVyIn0seyJmcW4iOiJqc2lpLWNhbGMuU2Vjb25kTGV2ZWxTdHJ1Y3QifV19fQ==")), "secondLevel") + @optional = optional ++ Jsii::Type.check_type(@optional, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "optional") unless @optional.nil? + end + + # This is a required field. + # + # @return [String] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/unary_operation.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/unary_operation.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/unary_operation.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + self.jsii_fqn = "jsii-calc.UnaryOperation" + Jsii::Object.register_jsii_fqn("jsii-calc.UnaryOperation", self) + + # @param operand [Scope::JsiiCalcLib::NumericValue] + def initialize(operand) ++ Jsii::Type.check_type(operand, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJAc2NvcGUvanNpaS1jYWxjLWxpYi5OdW1lcmljVmFsdWUifQ==")), "operand") + Jsii::Object.instance_method(:initialize).bind(self).call(operand) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/union/consumes_union.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/union/consumes_union.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/union/consumes_union.rb --runtime-type-checking +@@ -14,10 +14,11 @@ + end + + # @param param [Scope::JsiiCalcLib::IFriendly, JsiiCalc::Union::IResolvable, JsiiCalc::Union::Resolvable] + # @return [void] + def self.union_type(param) ++ Jsii::Type.check_type(param, JSON.parse(Base64.strict_decode64("eyJ1bmlvbiI6eyJ0eXBlcyI6W3siZnFuIjoiQHNjb3BlL2pzaWktY2FsYy1saWIuSUZyaWVuZGx5In0seyJmcW4iOiJqc2lpLWNhbGMudW5pb24uSVJlc29sdmFibGUifSx7ImZxbiI6ImpzaWktY2FsYy51bmlvbi5SZXNvbHZhYmxlIn1dfX0=")), "param") + Jsii::Kernel.instance.call_static("jsii-calc.union.ConsumesUnion", "unionType", [param]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/union_properties.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/union_properties.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/union_properties.rb --runtime-type-checking +@@ -5,11 +5,13 @@ + + # @param bar [String, Numeric, JsiiCalc::AllTypes] + # @param foo [String, Numeric, nil] + def initialize(bar:, foo: nil) + @bar = bar ++ Jsii::Type.check_type(@bar, JSON.parse(Base64.strict_decode64("eyJ1bmlvbiI6eyJ0eXBlcyI6W3sicHJpbWl0aXZlIjoic3RyaW5nIn0seyJwcmltaXRpdmUiOiJudW1iZXIifSx7ImZxbiI6ImpzaWktY2FsYy5BbGxUeXBlcyJ9XX19")), "bar") + @foo = foo ++ Jsii::Type.check_type(@foo, JSON.parse(Base64.strict_decode64("eyJ1bmlvbiI6eyJ0eXBlcyI6W3sicHJpbWl0aXZlIjoic3RyaW5nIn0seyJwcmltaXRpdmUiOiJudW1iZXIifV19fQ==")), "foo") unless @foo.nil? + end + + # @return [String, Numeric, JsiiCalc::AllTypes] + attr_reader :bar + # @return [String, Numeric, nil] +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/upcasing_reflectable.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/upcasing_reflectable.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/upcasing_reflectable.rb --runtime-type-checking +@@ -6,10 +6,11 @@ + self.jsii_fqn = "jsii-calc.UpcasingReflectable" + Jsii::Object.register_jsii_fqn("jsii-calc.UpcasingReflectable", self) + + # @param delegate [Hash{String => Object}] + def initialize(delegate) ++ Jsii::Type.check_type(delegate, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InByaW1pdGl2ZSI6ImFueSJ9LCJraW5kIjoibWFwIn19")), "delegate") + Jsii::Object.instance_method(:initialize).bind(self).call(delegate) + end + + def self.jsii_overridable_methods + { +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/uses_interface_with_properties.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/uses_interface_with_properties.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/uses_interface_with_properties.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + self.jsii_fqn = "jsii-calc.UsesInterfaceWithProperties" + Jsii::Object.register_jsii_fqn("jsii-calc.UsesInterfaceWithProperties", self) + + # @param obj [JsiiCalc::IInterfaceWithProperties] + def initialize(obj) ++ Jsii::Type.check_type(obj, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUludGVyZmFjZVdpdGhQcm9wZXJ0aWVzIn0=")), "obj") + Jsii::Object.instance_method(:initialize).bind(self).call(obj) + end + + def self.jsii_overridable_methods + { +@@ -29,16 +30,18 @@ + end + + # @param ext [JsiiCalc::IInterfaceWithPropertiesExtension] + # @return [String] + def read_string_and_number(ext) ++ Jsii::Type.check_type(ext, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuSUludGVyZmFjZVdpdGhQcm9wZXJ0aWVzRXh0ZW5zaW9uIn0=")), "ext") + jsii_call_method("readStringAndNumber", [ext]) + end + + # @param value [String] + # @return [String] + def write_and_read(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "value") + jsii_call_method("writeAndRead", [value]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/variadic_invoker.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/variadic_invoker.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/variadic_invoker.rb --runtime-type-checking +@@ -4,10 +4,11 @@ + self.jsii_fqn = "jsii-calc.VariadicInvoker" + Jsii::Object.register_jsii_fqn("jsii-calc.VariadicInvoker", self) + + # @param method [JsiiCalc::VariadicMethod] + def initialize(method) ++ Jsii::Type.check_type(method, JSON.parse(Base64.strict_decode64("eyJmcW4iOiJqc2lpLWNhbGMuVmFyaWFkaWNNZXRob2QifQ==")), "method") + Jsii::Object.instance_method(:initialize).bind(self).call(method) + end + + def self.jsii_overridable_methods + { +@@ -16,10 +17,13 @@ + end + + # @param values [Array] + # @return [Array] + def as_array(*values) ++ values.each_with_index do |item, index| ++ Jsii::Type.check_type(item, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "values[#{index}]") ++ end + jsii_call_method("asArray", [*values]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/variadic_method.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/variadic_method.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/variadic_method.rb --runtime-type-checking +@@ -4,10 +4,13 @@ + self.jsii_fqn = "jsii-calc.VariadicMethod" + Jsii::Object.register_jsii_fqn("jsii-calc.VariadicMethod", self) + + # @param prefix [Array] a prefix that will be use for all values returned by \`#asArray\`. + def initialize(*prefix) ++ prefix.each_with_index do |item, index| ++ Jsii::Type.check_type(item, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "prefix[#{index}]") ++ end + Jsii::Object.instance_method(:initialize).bind(self).call(*prefix) + end + + def self.jsii_overridable_methods + { +@@ -17,10 +20,14 @@ + + # @param first [Numeric] the first element of the array to be returned (after the \`prefix\` provided at construction time). + # @param others [Array] other elements to be included in the array. + # @return [Array] + def as_array(first, *others) ++ Jsii::Type.check_type(first, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "first") ++ others.each_with_index do |item, index| ++ Jsii::Type.check_type(item, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "others[#{index}]") ++ end + jsii_call_method("asArray", [first, *others]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/variadic_type_union.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/variadic_type_union.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/variadic_type_union.rb --runtime-type-checking +@@ -4,10 +4,13 @@ + self.jsii_fqn = "jsii-calc.VariadicTypeUnion" + Jsii::Object.register_jsii_fqn("jsii-calc.VariadicTypeUnion", self) + + # @param union [Array] + def initialize(*union) ++ union.each_with_index do |item, index| ++ Jsii::Type.check_type(item, JSON.parse(Base64.strict_decode64("eyJ1bmlvbiI6eyJ0eXBlcyI6W3siZnFuIjoianNpaS1jYWxjLlN0cnVjdEEifSx7ImZxbiI6ImpzaWktY2FsYy5TdHJ1Y3RCIn1dfX0=")), "union[#{index}]") ++ end + Jsii::Object.instance_method(:initialize).bind(self).call(*union) + end + + def self.jsii_overridable_methods + { +@@ -19,10 +22,11 @@ + def union() + jsii_get_property("union") + end + + def union=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJjb2xsZWN0aW9uIjp7ImVsZW1lbnR0eXBlIjp7InVuaW9uIjp7InR5cGVzIjpbeyJmcW4iOiJqc2lpLWNhbGMuU3RydWN0QSJ9LHsiZnFuIjoianNpaS1jYWxjLlN0cnVjdEIifV19fSwia2luZCI6ImFycmF5In19")), "union") + jsii_set_property("union", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/virtual_method_playground.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/virtual_method_playground.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/virtual_method_playground.rb --runtime-type-checking +@@ -19,34 +19,39 @@ + end + + # @param index [Numeric] + # @return [Numeric] + def override_me_async(index) ++ Jsii::Type.check_type(index, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "index") + jsii_async_call_method("overrideMeAsync", [index]) + end + + # @param index [Numeric] + # @return [Numeric] + def override_me_sync(index) ++ Jsii::Type.check_type(index, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "index") + jsii_call_method("overrideMeSync", [index]) + end + + # @param count [Numeric] + # @return [Numeric] + def parallel_sum_async(count) ++ Jsii::Type.check_type(count, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "count") + jsii_async_call_method("parallelSumAsync", [count]) + end + + # @param count [Numeric] + # @return [Numeric] + def serial_sum_async(count) ++ Jsii::Type.check_type(count, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "count") + jsii_async_call_method("serialSumAsync", [count]) + end + + # @param count [Numeric] + # @return [Numeric] + def sum_sync(count) ++ Jsii::Type.check_type(count, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJudW1iZXIifQ==")), "count") + jsii_call_method("sumSync", [count]) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/weird_docs.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/weird_docs.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/weird_docs.rb --runtime-type-checking +@@ -25,10 +25,11 @@ + def dont_read_me() + jsii_get_property("dontReadMe") + end + + def dont_read_me=(value) ++ Jsii::Type.check_type(value, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "dontReadMe") unless value.nil? + jsii_set_property("dontReadMe", value) + end + + end +`; + +exports[`Generated code for "jsii-calc": /ruby/lib/jsii-calc/with_private_property_in_constructor.rb.diff 1`] = ` +--- ruby/lib/jsii-calc/with_private_property_in_constructor.rb --no-runtime-type-checking ++++ ruby/lib/jsii-calc/with_private_property_in_constructor.rb --runtime-type-checking +@@ -5,10 +5,11 @@ + self.jsii_fqn = "jsii-calc.WithPrivatePropertyInConstructor" + Jsii::Object.register_jsii_fqn("jsii-calc.WithPrivatePropertyInConstructor", self) + + # @param private_field [String, nil] + def initialize(private_field = nil) ++ Jsii::Type.check_type(private_field, JSON.parse(Base64.strict_decode64("eyJwcmltaXRpdmUiOiJzdHJpbmcifQ==")), "privateField") unless private_field.nil? + Jsii::Object.instance_method(:initialize).bind(self).call(private_field) + end + + def self.jsii_overridable_methods + { +`; diff --git a/packages/jsii-pacmak/test/generated-code/target-ruby.test.ts b/packages/jsii-pacmak/test/generated-code/target-ruby.test.ts new file mode 100644 index 0000000000..03550543ac --- /dev/null +++ b/packages/jsii-pacmak/test/generated-code/target-ruby.test.ts @@ -0,0 +1,4 @@ +import { verifyGeneratedCodeFor } from './harness'; +import { TargetName } from '../../lib/targets'; + +verifyGeneratedCodeFor(TargetName.RUBY, 300_000); diff --git a/packages/jsii-pacmak/test/targets/ruby/ruby-names.test.ts b/packages/jsii-pacmak/test/targets/ruby/ruby-names.test.ts new file mode 100644 index 0000000000..84c2468ae0 --- /dev/null +++ b/packages/jsii-pacmak/test/targets/ruby/ruby-names.test.ts @@ -0,0 +1,276 @@ +import { TypeSystem } from 'jsii-reflect'; + +import { RubyGenerator } from '../../../lib/targets/ruby'; + +// A representative subset of the CDK acronym list — only those exercised by +// the assertions below. Includes the cases that matter beyond a simple match: +// the IP/IPv4 overlap and the 2-letter `CE` surviving among its neighbours. +const CDK_ACRONYMS = [ + 'AWS', + 'VPC', + 'ECS', + 'API', + 'DB', + 'CIDR', + 'IP', + 'IPv4', + 'CE', +]; + +describe('Ruby naming behavior', () => { + let typeSystem: TypeSystem; + let rubyTarget: any; // Use any to access private methods for testing + + beforeAll(async () => { + typeSystem = new TypeSystem(); + const assembly = await typeSystem.load( + require.resolve('../fixtures/base.jsii.json'), + ); + + // Mock targets to include the acronyms array + (assembly as any).spec.targets = { + ruby: { + acronyms: CDK_ACRONYMS, + module: 'BaseModule', + }, + }; + + rubyTarget = new RubyGenerator({} as any, { + targetName: 'ruby', + packageDir: '.', + assembly, + runtimeTypeChecking: true, + arguments: {}, + rosetta: {} as any, // not used for this test + }); + await rubyTarget.load('.', assembly); + }); + + describe('rubyModuleName', () => { + it('capitalizes acronyms correctly', () => { + expect(rubyTarget.rubyModuleName('CfnVpc')).toBe('CfnVPC'); + expect(rubyTarget.rubyModuleName('CfnVPCConnection')).toBe( + 'CfnVPCConnection', + ); + expect(rubyTarget.rubyModuleName('dbTable')).toBe('DBTable'); + expect(rubyTarget.rubyModuleName('IpAddress')).toBe('IPAddress'); + expect(rubyTarget.rubyModuleName('awsIpv4Cidr')).toBe('AWSIPv4CIDR'); + expect(rubyTarget.rubyModuleName('apiGateway')).toBe('APIGateway'); // API is an acronym + expect(rubyTarget.rubyModuleName('EcsCluster')).toBe('ECSCluster'); + }); + + it('produces valid constants for digit- and underscore-leading names', () => { + // npm allows package names like `3d-tools`; Ruby constants must start + // with an uppercase letter. V_ prefix mirrors rubyConstName. + expect(rubyTarget.rubyModuleName('3d-tools')).toBe('V_3dTools'); + expect(rubyTarget.rubyModuleName('3DSecure')).toBe('V_3DSecure'); + expect(rubyTarget.rubyModuleName('@scope/3d')).toBe('Scope::V_3d'); + expect(rubyTarget.rubyModuleName('_internal')).toBe('V__internal'); + // Ordinary names are untouched. + expect(rubyTarget.rubyModuleName('jsii-calc')).toBe('JsiiCalc'); + }); + + it('treats acronyms as literal text, not regex patterns', () => { + // A config-supplied acronym containing regex metacharacters must not + // break generation (previously: "Nothing to repeat" SyntaxError) or + // inject match behavior. + expect(() => + rubyTarget.rubyModuleName('CppHelper', ['C++']), + ).not.toThrow(); + expect(rubyTarget.rubyModuleName('CppHelper', ['C++'])).toBe('CppHelper'); + expect(rubyTarget.rubyModuleName('fooBar', ['.*'])).toBe('FooBar'); + }); + + it('scopes acronyms to the supplied list (per-assembly, not pooled)', () => { + // Explicit empty list: nothing rewritten even though the test + // assembly configures VPC as an acronym. + expect(rubyTarget.rubyModuleName('CfnVpc', [])).toBe('CfnVpc'); + expect(rubyTarget.rubyModuleName('CfnVpc', ['VPC'])).toBe('CfnVPC'); + // Default (no list passed) uses the generated assembly's own config. + expect(rubyTarget.rubyModuleName('CfnVpc')).toBe('CfnVPC'); + }); + + it('ignores blank acronym entries', () => { + // An empty-string acronym would match everywhere; assemblyAcronyms + // filters it out before it reaches the regex. + expect( + rubyTarget.assemblyAcronyms({ + targets: { ruby: { acronyms: ['', 'VPC', 42] } }, + }), + ).toEqual(['VPC']); + }); + + it('does not over-capitalize acronyms embedded inside words', () => { + // "Special" contains "pec", "ial" etc. "AWS" is an acronym. + // "AWSpecial" has "AWS" but it is not followed by an uppercase letter or end of string. + // With word boundaries, it should remain AWSpecial or Awspecial depending on toPascalCase! + // In JSII, "AWSpecial" starts with 'A' (uppercase). + // Our fix ensures it does not get replaced incorrectly. + expect(rubyTarget.rubyModuleName('AWSpecial')).toBe('AWSpecial'); + expect(rubyTarget.rubyModuleName('VpcEndpoint')).toBe('VPCEndpoint'); + expect(rubyTarget.rubyModuleName('awsCertificatemanager')).toBe( + 'AWSCertificatemanager', + ); + expect(rubyTarget.rubyModuleName('awsCeService')).toBe('AWSCEService'); + }); + }); + + describe('rubyName', () => { + it('passes through ordinary member names', () => { + expect(rubyTarget.rubyName('fooBar')).toBe('foo_bar'); + expect(rubyTarget.rubyName('hello')).toBe('hello'); + }); + + it('prefixes Ruby keywords', () => { + expect(rubyTarget.rubyName('break')).toBe('_break'); + expect(rubyTarget.rubyName('class')).toBe('_class'); + expect(rubyTarget.rubyName('while')).toBe('_while'); + }); + + it('prefixes constructor/allocation hooks so members cannot clobber them', () => { + // `def initialize` would silently replace the generated constructor; + // `new`/`allocate` are the class methods used to instantiate proxies. + expect(rubyTarget.rubyName('initialize')).toBe('_initialize'); + expect(rubyTarget.rubyName('new')).toBe('_new'); + expect(rubyTarget.rubyName('allocate')).toBe('_allocate'); + }); + + it('prefixes runtime serialization/dispatch hooks', () => { + expect(rubyTarget.rubyName('toJsii')).toBe('_to_jsii'); + expect(rubyTarget.rubyName('rubyClass')).toBe('_ruby_class'); + expect(rubyTarget.rubyName('send')).toBe('_send'); + }); + + it('prefixes anything landing in the reserved jsii_ namespace', () => { + expect(rubyTarget.rubyName('jsiiRef')).toBe('_jsii_ref'); + expect(rubyTarget.rubyName('jsiiSerialize')).toBe('_jsii_serialize'); + expect(rubyTarget.rubyName('jsiiSomeFutureApi')).toBe( + '_jsii_some_future_api', + ); + }); + + it('prefixes names that start with a digit', () => { + expect(rubyTarget.rubyName('2fa')).toBe('_2fa'); + }); + }); + + describe('dedupCrossCategory', () => { + const byRubyName = (m: any) => rubyTarget.rubyName(m.name); + const dedup = (props: any[], methods: any[]) => + rubyTarget.dedupCrossCategory( + props, + methods, + byRubyName, + byRubyName, + 'test.Type', + ); + + it('passes through non-colliding members', () => { + const props = [{ name: 'fooBar' }]; + const methods = [{ name: 'doThing' }]; + expect(dedup(props, methods)).toEqual({ props, methods }); + }); + + it('does not treat a static and an instance member as colliding', () => { + const props = [{ name: 'value', static: true }]; + const methods = [{ name: 'value' }]; + expect(dedup(props, methods)).toEqual({ props, methods }); + }); + + it('drops the deprecated side of a property/method collision', () => { + const prop = { name: 'fooBar', docs: { deprecated: 'use foo_bar()' } }; + const method = { name: 'foo_bar' }; + expect(dedup([prop], [method])).toEqual({ + props: [], + methods: [method], + }); + }); + + it('throws when a property and a method collide and neither is deprecated', () => { + expect(() => dedup([{ name: 'fooBar' }], [{ name: 'foo_bar' }])).toThrow( + /property 'fooBar', method 'foo_bar'/, + ); + }); + + it('throws when every colliding member is deprecated', () => { + expect(() => + dedup( + [{ name: 'fooBar', docs: { deprecated: 'x' } }], + [{ name: 'foo_bar', docs: { deprecated: 'y' } }], + ), + ).toThrow(/cannot pick a winner/); + }); + }); + + describe('rubyFullTypeName with submodules', () => { + it('respects explicit submodule targets', () => { + // Mock an assembly with submodules explicitly configured + const mockConfig = { + name: 'aws-cdk-lib', + targets: { ruby: { module: 'AWSCDK' } }, + submodules: { + 'aws-cdk-lib.aws_dynamodb': { + targets: { ruby: { module: 'AWSCDK::DynamoDB' } }, + }, + 'aws-cdk-lib.aws_dynamodb.nested': { + targets: { ruby: { module: 'AWSCDK::DynamoDB::Nested' } }, + }, + }, + }; + + // Monkey patch this.assembly for the test + const originalAssembly = rubyTarget.assembly; + Object.defineProperty(rubyTarget, 'assembly', { + value: mockConfig, + configurable: true, + }); + + expect( + rubyTarget.rubyFullTypeName('aws-cdk-lib.aws_dynamodb.Table'), + ).toBe('AWSCDK::DynamoDB::Table'); + + expect( + rubyTarget.rubyFullTypeName('aws-cdk-lib.aws_dynamodb.nested.Type'), + ).toBe('AWSCDK::DynamoDB::Nested::Type'); + + // Fallback for unconfigured submodule + expect(rubyTarget.rubyFullTypeName('aws-cdk-lib.aws_s3.Bucket')).toBe( + 'AWSCDK::AwsS3::Bucket', + ); // Assuming 'AwsS3' via fallback logic + + Object.defineProperty(rubyTarget, 'assembly', { + value: originalAssembly, + configurable: true, + }); + }); + + it('rejects submodule modules that do not extend the assembly module', () => { + const mockConfig = { + name: 'aws-cdk-lib', + targets: { ruby: { module: 'AWSCDK' } }, + submodules: { + 'aws-cdk-lib.rogue': { + // Replaces the root instead of extending it — relative-namespace + // slicing would emit types into the wrong module. + targets: { ruby: { module: 'Flat' } }, + }, + }, + }; + + const originalAssembly = rubyTarget.assembly; + Object.defineProperty(rubyTarget, 'assembly', { + value: mockConfig, + configurable: true, + }); + + expect(() => + rubyTarget.relativeRubyNamespace('aws-cdk-lib.rogue.Type'), + ).toThrow(/does not live under its assembly's module 'AWSCDK'/); + + Object.defineProperty(rubyTarget, 'assembly', { + value: originalAssembly, + configurable: true, + }); + }); + }); +}); diff --git a/packages/jsii-pacmak/test/targets/version-utils.test.ts b/packages/jsii-pacmak/test/targets/version-utils.test.ts index 129ec494f0..fe4321de62 100644 --- a/packages/jsii-pacmak/test/targets/version-utils.test.ts +++ b/packages/jsii-pacmak/test/targets/version-utils.test.ts @@ -3,28 +3,32 @@ import { toMavenVersionRange, toNuGetVersionRange, toPythonVersionRange, + toRubyVersionRange, toReleaseVersion, } from '../../lib/targets/version-utils'; const examples: Record< string, - { maven: string; nuget: string; python: string } + { maven: string; nuget: string; python: string; ruby?: string } > = { // Regular versions, "classic" ranges '1.2.3': { maven: '[1.2.3]', nuget: '[1.2.3]', python: '==1.2.3', + ruby: "'= 1.2.3'", }, '~1.2.3': { maven: '[1.2.3,1.3.0)', nuget: '[1.2.3,1.3.0)', python: '>=1.2.3, <1.3.0', + ruby: "'>= 1.2.3', '< 1.3.0'", }, '^1.2.3': { maven: '[1.2.3,2.0.0)', nuget: '[1.2.3,2.0.0)', python: '>=1.2.3, <2.0.0', + ruby: "'>= 1.2.3', '< 2.0.0'", }, // Pre-1.0 versions, "classic" ranges @@ -32,16 +36,19 @@ const examples: Record< maven: '[0.1.2]', nuget: '[0.1.2]', python: '==0.1.2', + ruby: "'= 0.1.2'", }, '~0.1.2': { maven: '[0.1.2,0.2.0)', nuget: '[0.1.2,0.2.0)', python: '>=0.1.2, <0.2.0', + ruby: "'>= 0.1.2', '< 0.2.0'", }, '^0.1.2': { maven: '[0.1.2,0.2.0)', nuget: '[0.1.2,0.2.0)', python: '>=0.1.2, <0.2.0', + ruby: "'>= 0.1.2', '< 0.2.0'", }, // Less usual ranges @@ -49,21 +56,25 @@ const examples: Record< maven: '(0.1.2,)', nuget: '(0.1.2,)', python: '>0.1.2', + ruby: "'> 0.1.2'", }, '>=0.1.2': { maven: '[0.1.2,)', nuget: '[0.1.2,)', python: '>=0.1.2', + ruby: "'>= 0.1.2'", }, '<0.1.2': { maven: '(,0.1.2)', nuget: '(,0.1.2)', python: '<0.1.2', + ruby: "'< 0.1.2'", }, '<=0.1.2': { maven: '(,0.1.2]', nuget: '(,0.1.2]', python: '<=0.1.2', + ruby: "'<= 0.1.2'", }, // Somewhat unusual ranges @@ -71,16 +82,19 @@ const examples: Record< maven: '[0.0.0,)', nuget: '[0.0.0,)', python: '>=0.0.0', + ruby: "'>= 0.0.0'", }, '1.2.*': { maven: '[1.2.0,1.3.0)', nuget: '[1.2.0,1.3.0)', python: '>=1.2.0, <1.3.0', + ruby: "'>= 1.2.0', '< 1.3.0'", }, '1.*': { maven: '[1.0.0,2.0.0)', nuget: '[1.0.0,2.0.0)', python: '>=1.0.0, <2.0.0', + ruby: "'>= 1.0.0', '< 2.0.0'", }, }; @@ -109,10 +123,26 @@ describe(toPythonVersionRange, () => { } }); +describe(toRubyVersionRange, () => { + for (const [semver, { ruby }] of Object.entries(examples)) { + if (ruby) { + test(`${semver} translates to ${ruby}`, () => + expect(toRubyVersionRange(semver)).toEqual(ruby)); + } + } + + test('handles OR conditions (multiple sets)', () => { + expect(() => + toRubyVersionRange('>=1.0.0 <2.0.0 || >=3.0.0 <4.0.0'), + ).toThrow(/RubyGems does not support OR \(\|\|\) requirements natively/); + }); +}); + describe(toReleaseVersion, () => { type Expectations = { readonly [K in TargetName]: string | RegExp }; const examples: Record = { '1.2.3': { + ruby: '1.2.3', dotnet: '1.2.3', go: '1.2.3', java: '1.2.3', @@ -120,6 +150,7 @@ describe(toReleaseVersion, () => { python: '1.2.3', }, '1.2.3-pre': { + ruby: /Unable to map prerelease identifier \(in: 1\.2\.3-pre\) components to ruby: \[ 'pre' \]/, dotnet: '1.2.3-pre', go: '1.2.3-pre', java: '1.2.3-pre', @@ -128,6 +159,7 @@ describe(toReleaseVersion, () => { /Unable to map prerelease identifier \(in: 1\.2\.3-pre\) components to python: \[ 'pre' \]/, }, '1.2.3-dev.123.0+abc123.foo.bar': { + ruby: '1.2.3.dev.123', dotnet: '1.2.3-dev.123.0+abc123.foo.bar', go: '1.2.3-dev.123.0+abc123.foo.bar', java: '1.2.3-dev.123.0+abc123.foo.bar', @@ -135,6 +167,7 @@ describe(toReleaseVersion, () => { python: '1.2.3.dev123+abc123.foo.bar', }, '1.2.3-alpha.1337': { + ruby: '1.2.3.alpha.1337', dotnet: '1.2.3-alpha.1337', go: '1.2.3-alpha.1337', java: '1.2.3-alpha.1337', @@ -142,6 +175,7 @@ describe(toReleaseVersion, () => { python: '1.2.3.a1337', }, '1.2.3-beta.42': { + ruby: '1.2.3.beta.42', dotnet: '1.2.3-beta.42', go: '1.2.3-beta.42', java: '1.2.3-beta.42', @@ -149,6 +183,7 @@ describe(toReleaseVersion, () => { python: '1.2.3.b42', }, '1.2.3-rc.9': { + ruby: '1.2.3.rc.9', dotnet: '1.2.3-rc.9', go: '1.2.3-rc.9', java: '1.2.3-rc.9', @@ -156,6 +191,7 @@ describe(toReleaseVersion, () => { python: '1.2.3.rc9', }, '1.2.3-rc.123.post.456.dev.789': { + ruby: '1.2.3.rc.123.post.456.dev.789', dotnet: '1.2.3-rc.123.post.456.dev.789', go: '1.2.3-rc.123.post.456.dev.789', java: '1.2.3-rc.123.post.456.dev.789', @@ -163,6 +199,7 @@ describe(toReleaseVersion, () => { python: '1.2.3.rc123.post456.dev789', }, '1.2.3-rc.alpha': { + ruby: /Unable to map prerelease identifier \(in: 1.2.3-rc.alpha\) components to ruby: \[ 'rc', 'alpha' \]/, dotnet: '1.2.3-rc.alpha', go: '1.2.3-rc.alpha', java: '1.2.3-rc.alpha', @@ -170,6 +207,14 @@ describe(toReleaseVersion, () => { python: /Unable to map prerelease identifier \(in: 1.2.3-rc.alpha\) components to python: \[ 'rc', 'alpha' \]/, }, + '1.2.3-rc.0': { + ruby: /Label rc must be followed by a positive integer/, + dotnet: '1.2.3-rc.0', + go: '1.2.3-rc.0', + java: '1.2.3-rc.0', + js: '1.2.3-rc.0', + python: '1.2.3.rc0', + }, }; for (const [version, targets] of Object.entries(examples)) { @@ -187,4 +232,13 @@ describe(toReleaseVersion, () => { } }); } + + test('ruby rejects multiple prerelease labels of the same or different categories', () => { + expect(() => + toReleaseVersion('1.2.3-alpha.1.rc.2', TargetName.RUBY), + ).toThrow(/Contains multiple or unmappable prerelease labels/); + expect(() => + toReleaseVersion('1.2.3-alpha.1.alpha.2', TargetName.RUBY), + ).toThrow(/Contains multiple or unmappable prerelease labels/); + }); }); diff --git a/tools/jsii-build-tools/bin/package-ruby.bin b/tools/jsii-build-tools/bin/package-ruby.bin index a217193a45..31a685cd5b 100755 --- a/tools/jsii-build-tools/bin/package-ruby.bin +++ b/tools/jsii-build-tools/bin/package-ruby.bin @@ -3,5 +3,5 @@ set -euo pipefail mkdir -p dist/ruby -gem build project/*.gemspec +gem build *.gemspec mv *.gem dist/ruby diff --git a/tools/jsii-compliance/report.ts b/tools/jsii-compliance/report.ts index 6128ee6fd0..bff85eb78b 100755 --- a/tools/jsii-compliance/report.ts +++ b/tools/jsii-compliance/report.ts @@ -149,7 +149,15 @@ for (const [i, testCase] of suite.testCases.entries()) { for (const language of Object.keys(suite.bindings)) { const report = reports[language]; - const testResult = report?.[normalizeTestName(testCase.name)]; + + // No report file for this binding means we have no data at all — render + // 'n/a' rather than implying every test is missing (or scoring 0.00%). + if (!report) { + row[language] = 'n/a'; + continue; + } + + const testResult = report[normalizeTestName(testCase.name)]; const status = determineTestStatus(testResult); row[language] = testResult?.url ? `[${status}](${testResult.url})` : status; @@ -166,7 +174,13 @@ for (const [i, testCase] of suite.testCases.entries()) { const columns = ['number', 'test']; -for (const language of Object.keys(reports)) { +for (const language of Object.keys(suite.bindings)) { + // A binding without a report file has no percentage to claim. + if (!(language in reports)) { + columns.push(`${language} (n/a)`); + continue; + } + const coverage = ( (successes[language] / suite.testCases.length) * 100 diff --git a/tools/jsii-compliance/suite.ts b/tools/jsii-compliance/suite.ts index 4a482e0df1..3abde9f23c 100644 --- a/tools/jsii-compliance/suite.ts +++ b/tools/jsii-compliance/suite.ts @@ -17,6 +17,9 @@ export const suite: schema.Suite = { python: { report: 'packages/@jsii/python-runtime-test/compliance-report.json', }, + ruby: { + report: 'packages/@jsii/ruby-runtime-test/compliance-report.json', + }, }, testCases: [ { diff --git a/tsconfig-base.json b/tsconfig-base.json index bac6fe82d7..1333443045 100644 --- a/tsconfig-base.json +++ b/tsconfig-base.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "ignoreDeprecations": "6.0", "target": "ES2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ "module": "Node16", /* Specify module code generation. */ "moduleResolution": "Node16", /* Specify module resolution strategy. */ diff --git a/yarn.lock b/yarn.lock index fb2c5c150d..6c555154c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1908,6 +1908,31 @@ __metadata: languageName: unknown linkType: soft +"@jsii/ruby-runtime-test@workspace:packages/@jsii/ruby-runtime-test": + version: 0.0.0-use.local + resolution: "@jsii/ruby-runtime-test@workspace:packages/@jsii/ruby-runtime-test" + dependencies: + "@jsii/ruby-runtime": "npm:^0.0.0" + "@scope/jsii-calc-base": "npm:^0.0.0" + "@scope/jsii-calc-base-of-base": "npm:^2.1.1" + "@scope/jsii-calc-lib": "npm:^0.0.0" + jsii-calc: "npm:^3.20.120" + jsii-pacmak: "npm:^0.0.0" + languageName: unknown + linkType: soft + +"@jsii/ruby-runtime@npm:^0.0.0, @jsii/ruby-runtime@workspace:packages/@jsii/ruby-runtime": + version: 0.0.0-use.local + resolution: "@jsii/ruby-runtime@workspace:packages/@jsii/ruby-runtime" + dependencies: + "@jsii/runtime": "npm:^0.0.0" + fs-extra: "npm:^10.1.0" + jsii-build-tools: "npm:^0.0.0" + jsii-calc: "npm:^3.20.120" + jsii-pacmak: "npm:^0.0.0" + languageName: unknown + linkType: soft + "@jsii/runtime@npm:^0.0.0, @jsii/runtime@workspace:packages/@jsii/runtime": version: 0.0.0-use.local resolution: "@jsii/runtime@workspace:packages/@jsii/runtime" @@ -2529,7 +2554,7 @@ __metadata: languageName: node linkType: hard -"@scope/jsii-calc-base-of-base@npm:2.1.1, @scope/jsii-calc-base-of-base@workspace:packages/@scope/jsii-calc-base-of-base": +"@scope/jsii-calc-base-of-base@npm:2.1.1, @scope/jsii-calc-base-of-base@npm:^2.1.1, @scope/jsii-calc-base-of-base@workspace:packages/@scope/jsii-calc-base-of-base": version: 0.0.0-use.local resolution: "@scope/jsii-calc-base-of-base@workspace:packages/@scope/jsii-calc-base-of-base" dependencies: