nitrogen 0.2.24 → 0.29.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -109
- package/lib/Logger.d.ts +10 -0
- package/lib/Logger.js +56 -0
- package/lib/autolinking/Autolinking.d.ts +8 -0
- package/lib/autolinking/Autolinking.js +1 -0
- package/lib/autolinking/android/createCMakeExtension.d.ts +6 -0
- package/lib/autolinking/android/createCMakeExtension.js +106 -0
- package/lib/autolinking/android/createGradleExtension.d.ts +5 -0
- package/lib/autolinking/android/createGradleExtension.js +36 -0
- package/lib/autolinking/android/createHybridObjectInitializer.d.ts +2 -0
- package/lib/autolinking/android/createHybridObjectInitializer.js +159 -0
- package/lib/autolinking/createAndroidAutolinking.d.ts +11 -0
- package/lib/autolinking/createAndroidAutolinking.js +13 -0
- package/lib/autolinking/createIOSAutolinking.d.ts +5 -0
- package/lib/autolinking/createIOSAutolinking.js +19 -0
- package/lib/autolinking/ios/createHybridObjectInitializer.d.ts +9 -0
- package/lib/autolinking/ios/createHybridObjectInitializer.js +97 -0
- package/lib/autolinking/ios/createPodspecRubyExtension.d.ts +5 -0
- package/lib/autolinking/ios/createPodspecRubyExtension.js +69 -0
- package/lib/autolinking/ios/createSwiftCxxBridge.d.ts +2 -0
- package/lib/autolinking/ios/createSwiftCxxBridge.js +117 -0
- package/lib/autolinking/ios/createSwiftUmbrellaHeader.d.ts +3 -0
- package/lib/autolinking/ios/createSwiftUmbrellaHeader.js +74 -0
- package/lib/config/NitroConfig.d.ts +52 -0
- package/lib/config/NitroConfig.js +112 -0
- package/lib/config/NitroUserConfig.d.ts +22 -0
- package/lib/config/NitroUserConfig.js +88 -0
- package/lib/config/getConfig.d.ts +2 -0
- package/lib/config/getConfig.js +84 -0
- package/lib/createGitAttributes.d.ts +1 -0
- package/lib/createGitAttributes.js +11 -0
- package/lib/createPlatformSpec.d.ts +4 -0
- package/lib/createPlatformSpec.js +127 -0
- package/lib/getFiles.d.ts +1 -0
- package/lib/getFiles.js +28 -0
- package/lib/getPlatformSpecs.d.ts +17 -0
- package/lib/getPlatformSpecs.js +153 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +113 -10
- package/lib/init.d.ts +1 -0
- package/lib/init.js +123 -0
- package/lib/nitrogen.d.ts +11 -0
- package/lib/nitrogen.js +165 -0
- package/lib/prettifyDirectory.d.ts +1 -0
- package/lib/prettifyDirectory.js +27 -0
- package/lib/syntax/BridgedType.d.ts +41 -0
- package/lib/syntax/BridgedType.js +1 -0
- package/lib/syntax/CodeNode.d.ts +23 -0
- package/lib/syntax/CodeNode.js +1 -0
- package/lib/syntax/HybridObjectSpec.d.ts +13 -0
- package/lib/syntax/HybridObjectSpec.js +1 -0
- package/lib/syntax/Method.d.ts +41 -0
- package/lib/syntax/Method.js +108 -0
- package/lib/syntax/Parameter.d.ts +15 -0
- package/lib/syntax/Parameter.js +65 -0
- package/lib/syntax/Property.d.ts +50 -0
- package/lib/syntax/Property.js +147 -0
- package/lib/syntax/SourceFile.d.ts +70 -0
- package/lib/syntax/SourceFile.js +7 -0
- package/lib/syntax/c++/CppEnum.d.ts +6 -0
- package/lib/syntax/c++/CppEnum.js +110 -0
- package/lib/syntax/c++/CppHybridObject.d.ts +3 -0
- package/lib/syntax/c++/CppHybridObject.js +146 -0
- package/lib/syntax/c++/CppHybridObjectRegistration.d.ts +17 -0
- package/lib/syntax/c++/CppHybridObjectRegistration.js +18 -0
- package/lib/syntax/c++/CppStruct.d.ts +3 -0
- package/lib/syntax/c++/CppStruct.js +108 -0
- package/lib/syntax/c++/CppUnion.d.ts +6 -0
- package/lib/syntax/c++/CppUnion.js +88 -0
- package/lib/syntax/c++/getForwardDeclaration.d.ts +3 -0
- package/lib/syntax/c++/getForwardDeclaration.js +14 -0
- package/lib/syntax/c++/includeNitroHeader.d.ts +7 -0
- package/lib/syntax/c++/includeNitroHeader.js +34 -0
- package/lib/syntax/createType.d.ts +15 -0
- package/lib/syntax/createType.js +303 -0
- package/lib/syntax/getAllTypes.d.ts +3 -0
- package/lib/syntax/getAllTypes.js +11 -0
- package/lib/syntax/getCustomTypeConfig.d.ts +8 -0
- package/lib/syntax/getCustomTypeConfig.js +53 -0
- package/lib/syntax/getHybridObjectName.d.ts +36 -0
- package/lib/syntax/getHybridObjectName.js +10 -0
- package/lib/syntax/getInterfaceProperties.d.ts +4 -0
- package/lib/syntax/getInterfaceProperties.js +9 -0
- package/lib/syntax/getReferencedTypes.d.ts +2 -0
- package/lib/syntax/getReferencedTypes.js +47 -0
- package/lib/syntax/helpers.d.ts +13 -0
- package/lib/syntax/helpers.js +53 -0
- package/lib/syntax/isCoreType.d.ts +9 -0
- package/lib/syntax/isCoreType.js +47 -0
- package/lib/syntax/kotlin/FbjniHybridObject.d.ts +3 -0
- package/lib/syntax/kotlin/FbjniHybridObject.js +261 -0
- package/lib/syntax/kotlin/JNINativeRegistrations.d.ts +8 -0
- package/lib/syntax/kotlin/JNINativeRegistrations.js +7 -0
- package/lib/syntax/kotlin/KotlinBoxedPrimitive.d.ts +7 -0
- package/lib/syntax/kotlin/KotlinBoxedPrimitive.js +17 -0
- package/lib/syntax/kotlin/KotlinCxxBridgedType.d.ts +19 -0
- package/lib/syntax/kotlin/KotlinCxxBridgedType.js +893 -0
- package/lib/syntax/kotlin/KotlinEnum.d.ts +3 -0
- package/lib/syntax/kotlin/KotlinEnum.js +113 -0
- package/lib/syntax/kotlin/KotlinFunction.d.ts +3 -0
- package/lib/syntax/kotlin/KotlinFunction.js +256 -0
- package/lib/syntax/kotlin/KotlinHybridObject.d.ts +3 -0
- package/lib/syntax/kotlin/KotlinHybridObject.js +177 -0
- package/lib/syntax/kotlin/KotlinHybridObjectRegistration.d.ts +17 -0
- package/lib/syntax/kotlin/KotlinHybridObjectRegistration.js +26 -0
- package/lib/syntax/kotlin/KotlinStruct.d.ts +3 -0
- package/lib/syntax/kotlin/KotlinStruct.js +172 -0
- package/lib/syntax/kotlin/KotlinVariant.d.ts +3 -0
- package/lib/syntax/kotlin/KotlinVariant.js +191 -0
- package/lib/syntax/swift/SwiftCxxBridgedType.d.ts +21 -0
- package/lib/syntax/swift/SwiftCxxBridgedType.js +819 -0
- package/lib/syntax/swift/SwiftCxxTypeHelper.d.ts +17 -0
- package/lib/syntax/swift/SwiftCxxTypeHelper.js +613 -0
- package/lib/syntax/swift/SwiftEnum.d.ts +3 -0
- package/lib/syntax/swift/SwiftEnum.js +52 -0
- package/lib/syntax/swift/SwiftFunction.d.ts +3 -0
- package/lib/syntax/swift/SwiftFunction.js +83 -0
- package/lib/syntax/swift/SwiftHybridObject.d.ts +3 -0
- package/lib/syntax/swift/SwiftHybridObject.js +103 -0
- package/lib/syntax/swift/SwiftHybridObjectBridge.d.ts +11 -0
- package/lib/syntax/swift/SwiftHybridObjectBridge.js +451 -0
- package/lib/syntax/swift/SwiftHybridObjectRegistration.d.ts +19 -0
- package/lib/syntax/swift/SwiftHybridObjectRegistration.js +42 -0
- package/lib/syntax/swift/SwiftStruct.d.ts +3 -0
- package/lib/syntax/swift/SwiftStruct.js +75 -0
- package/lib/syntax/swift/SwiftVariant.d.ts +3 -0
- package/lib/syntax/swift/SwiftVariant.js +58 -0
- package/lib/syntax/types/ArrayBufferType.d.ts +10 -0
- package/lib/syntax/types/ArrayBufferType.js +37 -0
- package/lib/syntax/types/ArrayType.d.ts +12 -0
- package/lib/syntax/types/ArrayType.js +52 -0
- package/lib/syntax/types/BigIntType.d.ts +10 -0
- package/lib/syntax/types/BigIntType.js +27 -0
- package/lib/syntax/types/BooleanType.d.ts +10 -0
- package/lib/syntax/types/BooleanType.js +27 -0
- package/lib/syntax/types/CustomType.d.ts +14 -0
- package/lib/syntax/types/CustomType.js +36 -0
- package/lib/syntax/types/DateType.d.ts +10 -0
- package/lib/syntax/types/DateType.js +35 -0
- package/lib/syntax/types/EnumType.d.ts +23 -0
- package/lib/syntax/types/EnumType.js +101 -0
- package/lib/syntax/types/ErrorType.d.ts +11 -0
- package/lib/syntax/types/ErrorType.js +37 -0
- package/lib/syntax/types/FunctionType.d.ts +29 -0
- package/lib/syntax/types/FunctionType.js +147 -0
- package/lib/syntax/types/HybridObjectBaseType.d.ts +11 -0
- package/lib/syntax/types/HybridObjectBaseType.js +38 -0
- package/lib/syntax/types/HybridObjectType.d.ts +23 -0
- package/lib/syntax/types/HybridObjectType.js +131 -0
- package/lib/syntax/types/MapType.d.ts +10 -0
- package/lib/syntax/types/MapType.js +37 -0
- package/lib/syntax/types/NamedWrappingType.d.ts +14 -0
- package/lib/syntax/types/NamedWrappingType.js +27 -0
- package/lib/syntax/types/NullType.d.ts +10 -0
- package/lib/syntax/types/NullType.js +23 -0
- package/lib/syntax/types/NumberType.d.ts +10 -0
- package/lib/syntax/types/NumberType.js +27 -0
- package/lib/syntax/types/OptionalType.d.ts +13 -0
- package/lib/syntax/types/OptionalType.js +59 -0
- package/lib/syntax/types/PromiseType.d.ts +16 -0
- package/lib/syntax/types/PromiseType.js +62 -0
- package/lib/syntax/types/RecordType.d.ts +13 -0
- package/lib/syntax/types/RecordType.js +47 -0
- package/lib/syntax/types/ResultWrappingType.d.ts +13 -0
- package/lib/syntax/types/ResultWrappingType.js +44 -0
- package/lib/syntax/types/StringType.d.ts +10 -0
- package/lib/syntax/types/StringType.js +35 -0
- package/lib/syntax/types/StructType.d.ts +14 -0
- package/lib/syntax/types/StructType.js +61 -0
- package/lib/syntax/types/TupleType.d.ts +12 -0
- package/lib/syntax/types/TupleType.js +39 -0
- package/lib/syntax/types/Type.d.ts +55 -0
- package/lib/syntax/types/Type.js +1 -0
- package/lib/syntax/types/VariantType.d.ts +19 -0
- package/lib/syntax/types/VariantType.js +75 -0
- package/lib/syntax/types/VoidType.d.ts +10 -0
- package/lib/syntax/types/VoidType.js +27 -0
- package/lib/syntax/types/getTypeAs.d.ts +2 -0
- package/lib/syntax/types/getTypeAs.js +12 -0
- package/lib/utils.d.ts +22 -0
- package/lib/utils.js +126 -0
- package/lib/views/CppHybridViewComponent.d.ts +14 -0
- package/lib/views/CppHybridViewComponent.js +254 -0
- package/lib/views/createHostComponentJs.d.ts +3 -0
- package/lib/views/createHostComponentJs.js +27 -0
- package/lib/views/kotlin/KotlinHybridViewManager.d.ts +3 -0
- package/lib/views/kotlin/KotlinHybridViewManager.js +229 -0
- package/lib/views/swift/SwiftHybridViewManager.d.ts +3 -0
- package/lib/views/swift/SwiftHybridViewManager.js +131 -0
- package/lib/writeFile.d.ts +5 -0
- package/lib/writeFile.js +19 -0
- package/package.json +58 -29
- package/src/Logger.ts +63 -0
- package/src/autolinking/Autolinking.ts +9 -0
- package/src/autolinking/android/createCMakeExtension.ts +123 -0
- package/src/autolinking/android/createGradleExtension.ts +43 -0
- package/src/autolinking/android/createHybridObjectInitializer.ts +174 -0
- package/src/autolinking/createAndroidAutolinking.ts +28 -0
- package/src/autolinking/createIOSAutolinking.ts +24 -0
- package/src/autolinking/ios/createHybridObjectInitializer.ts +112 -0
- package/src/autolinking/ios/createPodspecRubyExtension.ts +76 -0
- package/src/autolinking/ios/createSwiftCxxBridge.ts +137 -0
- package/src/autolinking/ios/createSwiftUmbrellaHeader.ts +90 -0
- package/src/config/NitroConfig.ts +139 -0
- package/src/config/NitroUserConfig.ts +105 -0
- package/src/config/getConfig.ts +91 -0
- package/src/createGitAttributes.ts +15 -0
- package/src/createPlatformSpec.ts +176 -0
- package/src/getFiles.ts +31 -0
- package/src/getPlatformSpecs.ts +202 -0
- package/src/index.ts +146 -0
- package/src/init.ts +186 -0
- package/src/nitrogen.ts +246 -0
- package/src/prettifyDirectory.ts +32 -0
- package/src/syntax/BridgedType.ts +59 -0
- package/src/syntax/CodeNode.ts +24 -0
- package/src/syntax/HybridObjectSpec.ts +14 -0
- package/src/syntax/Method.ts +154 -0
- package/src/syntax/Parameter.ts +81 -0
- package/src/syntax/Property.ts +203 -0
- package/src/syntax/SourceFile.ts +80 -0
- package/src/syntax/c++/CppEnum.ts +128 -0
- package/src/syntax/c++/CppHybridObject.ts +165 -0
- package/src/syntax/c++/CppHybridObjectRegistration.ts +39 -0
- package/src/syntax/c++/CppStruct.ts +129 -0
- package/src/syntax/c++/CppUnion.ts +105 -0
- package/src/syntax/c++/getForwardDeclaration.ts +19 -0
- package/src/syntax/c++/includeNitroHeader.ts +40 -0
- package/src/syntax/createType.ts +365 -0
- package/src/syntax/getAllTypes.ts +18 -0
- package/src/syntax/getCustomTypeConfig.ts +71 -0
- package/src/syntax/getHybridObjectName.ts +48 -0
- package/src/syntax/getInterfaceProperties.ts +21 -0
- package/src/syntax/getReferencedTypes.ts +57 -0
- package/src/syntax/helpers.ts +79 -0
- package/src/syntax/isCoreType.ts +60 -0
- package/src/syntax/kotlin/FbjniHybridObject.ts +313 -0
- package/src/syntax/kotlin/JNINativeRegistrations.ts +19 -0
- package/src/syntax/kotlin/KotlinBoxedPrimitive.ts +19 -0
- package/src/syntax/kotlin/KotlinCxxBridgedType.ts +942 -0
- package/src/syntax/kotlin/KotlinEnum.ts +130 -0
- package/src/syntax/kotlin/KotlinFunction.ts +277 -0
- package/src/syntax/kotlin/KotlinHybridObject.ts +205 -0
- package/src/syntax/kotlin/KotlinHybridObjectRegistration.ts +51 -0
- package/src/syntax/kotlin/KotlinStruct.ts +198 -0
- package/src/syntax/kotlin/KotlinVariant.ts +212 -0
- package/src/syntax/swift/SwiftCxxBridgedType.ts +874 -0
- package/src/syntax/swift/SwiftCxxTypeHelper.ts +674 -0
- package/src/syntax/swift/SwiftEnum.ts +65 -0
- package/src/syntax/swift/SwiftFunction.ts +91 -0
- package/src/syntax/swift/SwiftHybridObject.ts +121 -0
- package/src/syntax/swift/SwiftHybridObjectBridge.ts +522 -0
- package/src/syntax/swift/SwiftHybridObjectRegistration.ts +75 -0
- package/src/syntax/swift/SwiftStruct.ts +85 -0
- package/src/syntax/swift/SwiftVariant.ts +67 -0
- package/src/syntax/types/ArrayBufferType.ts +49 -0
- package/src/syntax/types/ArrayType.ts +62 -0
- package/src/syntax/types/BigIntType.ts +35 -0
- package/src/syntax/types/BooleanType.ts +35 -0
- package/src/syntax/types/CustomType.ts +47 -0
- package/src/syntax/types/DateType.ts +43 -0
- package/src/syntax/types/EnumType.ts +130 -0
- package/src/syntax/types/ErrorType.ts +44 -0
- package/src/syntax/types/FunctionType.ts +167 -0
- package/src/syntax/types/HybridObjectBaseType.ts +54 -0
- package/src/syntax/types/HybridObjectType.ts +198 -0
- package/src/syntax/types/MapType.ts +49 -0
- package/src/syntax/types/NamedWrappingType.ts +33 -0
- package/src/syntax/types/NullType.ts +30 -0
- package/src/syntax/types/NumberType.ts +34 -0
- package/src/syntax/types/OptionalType.ts +66 -0
- package/src/syntax/types/PromiseType.ts +72 -0
- package/src/syntax/types/RecordType.ts +56 -0
- package/src/syntax/types/ResultWrappingType.ts +53 -0
- package/src/syntax/types/StringType.ts +44 -0
- package/src/syntax/types/StructType.ts +83 -0
- package/src/syntax/types/TupleType.ts +53 -0
- package/src/syntax/types/Type.ts +82 -0
- package/src/syntax/types/VariantType.ts +92 -0
- package/src/syntax/types/VoidType.ts +34 -0
- package/src/syntax/types/getTypeAs.ts +15 -0
- package/src/utils.ts +162 -0
- package/src/views/CppHybridViewComponent.ts +301 -0
- package/src/views/createHostComponentJs.ts +34 -0
- package/src/views/kotlin/KotlinHybridViewManager.ts +258 -0
- package/src/views/swift/SwiftHybridViewManager.ts +153 -0
- package/src/writeFile.ts +27 -0
- package/.jshintignore +0 -6
- package/.jshintrc +0 -3
- package/.npmignore +0 -3
- package/.travis.yml +0 -13
- package/LICENSE +0 -13
- package/browser/nitrogen-min.js +0 -3
- package/browser/nitrogen.js +0 -6369
- package/lib/apiKey.js +0 -67
- package/lib/blob.js +0 -57
- package/lib/commandManager.js +0 -350
- package/lib/device.js +0 -19
- package/lib/memoryStore.js +0 -24
- package/lib/message.js +0 -298
- package/lib/permission.js +0 -121
- package/lib/principal.js +0 -330
- package/lib/service.js +0 -347
- package/lib/session.js +0 -494
- package/lib/user.js +0 -20
- package/publish +0 -2
- package/scripts/build-documentation +0 -4
- package/scripts/build-module +0 -27
- package/scripts/module.js +0 -12
- package/scripts/postamble.js +0 -1
- package/scripts/preamble.js +0 -2
- package/scripts/run-test-server +0 -9
- package/test/config.js +0 -12
- package/test/fixtures/images/image.jpg +0 -0
- package/test/fixtures/images/motion0.jpg +0 -0
- package/test/fixtures/images/motion1.jpg +0 -0
- package/test/fixtures/images/motion2.jpg +0 -0
- package/test/fixtures/index.js +0 -76
- package/test/main.js +0 -5
- package/test/memoryStore.js +0 -22
- package/test/mocha.opts +0 -3
- package/test/units/apiKey.js +0 -46
- package/test/units/blob.js +0 -35
- package/test/units/commandManager.js +0 -67
- package/test/units/device.js +0 -26
- package/test/units/heartbeat.js +0 -28
- package/test/units/message.js +0 -79
- package/test/units/permissions.js +0 -43
- package/test/units/principal.js +0 -116
- package/test/units/service.js +0 -92
- package/test/units/session.js +0 -97
- package/test/units/user.js +0 -48
- package/yuidoc.json +0 -8
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { indent } from '../../utils.js';
|
|
2
|
+
import { createFileMetadataString, isNotDuplicate } from '../helpers.js';
|
|
3
|
+
import { includeHeader, includeNitroHeader } from './includeNitroHeader.js';
|
|
4
|
+
import { NitroConfig } from '../../config/NitroConfig.js';
|
|
5
|
+
export function createCppStruct(typename, properties) {
|
|
6
|
+
// Namespace typename
|
|
7
|
+
const fullyQualifiedTypename = NitroConfig.current.getCxxNamespace('c++', typename);
|
|
8
|
+
// Get C++ code for all struct members
|
|
9
|
+
const cppStructProps = properties
|
|
10
|
+
.map((p) => `${p.getCode('c++')} ${p.escapedName} SWIFT_PRIVATE;`)
|
|
11
|
+
.join('\n');
|
|
12
|
+
const cppConstructorParams = properties
|
|
13
|
+
.map((p) => `${p.getCode('c++')} ${p.escapedName}`)
|
|
14
|
+
.join(', ');
|
|
15
|
+
const cppInitializerParams = properties
|
|
16
|
+
.map((p) => `${p.escapedName}(${p.escapedName})`)
|
|
17
|
+
.join(', ');
|
|
18
|
+
// Get C++ code for converting each member from a jsi::Value
|
|
19
|
+
const codeOptions = {
|
|
20
|
+
fullyQualified: true,
|
|
21
|
+
includeNameInfo: false,
|
|
22
|
+
};
|
|
23
|
+
const cppFromJsiParams = properties
|
|
24
|
+
.map((p) => `JSIConverter<${p.getCode('c++', codeOptions)}>::fromJSI(runtime, obj.getProperty(runtime, "${p.name}"))`)
|
|
25
|
+
.join(',\n');
|
|
26
|
+
// Get C++ code for converting each member to a jsi::Value
|
|
27
|
+
const cppToJsiCalls = properties
|
|
28
|
+
.map((p) => `obj.setProperty(runtime, "${p.name}", JSIConverter<${p.getCode('c++', codeOptions)}>::toJSI(runtime, arg.${p.escapedName}));`)
|
|
29
|
+
.join('\n');
|
|
30
|
+
// Get C++ code for verifying if jsi::Value can be converted to type
|
|
31
|
+
const cppCanConvertCalls = properties
|
|
32
|
+
.map((p) => `if (!JSIConverter<${p.getCode('c++', codeOptions)}>::canConvert(runtime, obj.getProperty(runtime, "${p.name}"))) return false;`)
|
|
33
|
+
.join('\n');
|
|
34
|
+
// Get C++ includes for each extra-file we need to include
|
|
35
|
+
const includedTypes = properties.flatMap((r) => r.getRequiredImports('c++'));
|
|
36
|
+
const cppForwardDeclarations = includedTypes
|
|
37
|
+
.map((i) => i.forwardDeclaration)
|
|
38
|
+
.filter((v) => v != null)
|
|
39
|
+
.filter(isNotDuplicate);
|
|
40
|
+
const cppExtraIncludes = includedTypes
|
|
41
|
+
.map((i) => includeHeader(i))
|
|
42
|
+
.filter(isNotDuplicate);
|
|
43
|
+
const cxxNamespace = NitroConfig.current.getCxxNamespace('c++');
|
|
44
|
+
const cppCode = `
|
|
45
|
+
${createFileMetadataString(`${typename}.hpp`)}
|
|
46
|
+
|
|
47
|
+
#pragma once
|
|
48
|
+
|
|
49
|
+
${includeNitroHeader('JSIConverter.hpp')}
|
|
50
|
+
${includeNitroHeader('NitroDefines.hpp')}
|
|
51
|
+
|
|
52
|
+
${cppForwardDeclarations.join('\n')}
|
|
53
|
+
|
|
54
|
+
${cppExtraIncludes.join('\n')}
|
|
55
|
+
|
|
56
|
+
namespace ${cxxNamespace} {
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A struct which can be represented as a JavaScript object (${typename}).
|
|
60
|
+
*/
|
|
61
|
+
struct ${typename} {
|
|
62
|
+
public:
|
|
63
|
+
${indent(cppStructProps, ' ')}
|
|
64
|
+
|
|
65
|
+
public:
|
|
66
|
+
${typename}() = default;
|
|
67
|
+
explicit ${typename}(${cppConstructorParams}): ${cppInitializerParams} {}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
} // namespace ${cxxNamespace}
|
|
71
|
+
|
|
72
|
+
namespace margelo::nitro {
|
|
73
|
+
|
|
74
|
+
// C++ ${typename} <> JS ${typename} (object)
|
|
75
|
+
template <>
|
|
76
|
+
struct JSIConverter<${fullyQualifiedTypename}> final {
|
|
77
|
+
static inline ${fullyQualifiedTypename} fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
78
|
+
jsi::Object obj = arg.asObject(runtime);
|
|
79
|
+
return ${fullyQualifiedTypename}(
|
|
80
|
+
${indent(cppFromJsiParams, ' ')}
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, const ${fullyQualifiedTypename}& arg) {
|
|
84
|
+
jsi::Object obj(runtime);
|
|
85
|
+
${indent(cppToJsiCalls, ' ')}
|
|
86
|
+
return obj;
|
|
87
|
+
}
|
|
88
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
89
|
+
if (!value.isObject()) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
jsi::Object obj = value.getObject(runtime);
|
|
93
|
+
${indent(cppCanConvertCalls, ' ')}
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
} // namespace margelo::nitro
|
|
99
|
+
`;
|
|
100
|
+
return {
|
|
101
|
+
content: cppCode,
|
|
102
|
+
name: `${typename}.hpp`,
|
|
103
|
+
subdirectory: [],
|
|
104
|
+
language: 'c++',
|
|
105
|
+
referencedTypes: properties,
|
|
106
|
+
platform: 'shared',
|
|
107
|
+
};
|
|
108
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SourceFile } from '../SourceFile.js';
|
|
2
|
+
import type { EnumMember } from '../types/EnumType.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a C++ enum that converts to a TypeScript union (aka just strings).
|
|
5
|
+
*/
|
|
6
|
+
export declare function createCppUnion(typename: string, enumMembers: EnumMember[]): SourceFile;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { createFileMetadataString } from './../helpers.js';
|
|
2
|
+
import { indent, toLowerCamelCase } from '../../utils.js';
|
|
3
|
+
import { includeNitroHeader } from './includeNitroHeader.js';
|
|
4
|
+
import { NitroConfig } from '../../config/NitroConfig.js';
|
|
5
|
+
/**
|
|
6
|
+
* Creates a C++ enum that converts to a TypeScript union (aka just strings).
|
|
7
|
+
*/
|
|
8
|
+
export function createCppUnion(typename, enumMembers) {
|
|
9
|
+
// Namespace typename
|
|
10
|
+
const fullyQualifiedTypename = NitroConfig.current.getCxxNamespace('c++', typename);
|
|
11
|
+
const cppEnumMembers = enumMembers
|
|
12
|
+
.map((m, i) => `${m.name} SWIFT_NAME(${toLowerCamelCase(m.name)}) = ${i},`)
|
|
13
|
+
.join('\n');
|
|
14
|
+
const cppFromJsiHashCases = enumMembers
|
|
15
|
+
.map((v) => `case hashString("${v.stringValue}"): return ${fullyQualifiedTypename}::${v.name};`.trim())
|
|
16
|
+
.join('\n');
|
|
17
|
+
const cppToJsiCases = enumMembers
|
|
18
|
+
.map((v) => `case ${fullyQualifiedTypename}::${v.name}: return JSIConverter<std::string>::toJSI(runtime, "${v.stringValue}");`)
|
|
19
|
+
.join('\n');
|
|
20
|
+
const cppCanConvertCases = enumMembers
|
|
21
|
+
.map((m) => `case hashString("${m.stringValue}"):`)
|
|
22
|
+
.join('\n');
|
|
23
|
+
const cxxNamespace = NitroConfig.current.getCxxNamespace('c++');
|
|
24
|
+
const cppCode = `
|
|
25
|
+
${createFileMetadataString(`${typename}.hpp`)}
|
|
26
|
+
|
|
27
|
+
#pragma once
|
|
28
|
+
|
|
29
|
+
${includeNitroHeader('NitroHash.hpp')}
|
|
30
|
+
${includeNitroHeader('JSIConverter.hpp')}
|
|
31
|
+
${includeNitroHeader('NitroDefines.hpp')}
|
|
32
|
+
|
|
33
|
+
namespace ${cxxNamespace} {
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* An enum which can be represented as a JavaScript union (${typename}).
|
|
37
|
+
*/
|
|
38
|
+
enum class ${typename} {
|
|
39
|
+
${indent(cppEnumMembers, ' ')}
|
|
40
|
+
} CLOSED_ENUM;
|
|
41
|
+
|
|
42
|
+
} // namespace ${cxxNamespace}
|
|
43
|
+
|
|
44
|
+
namespace margelo::nitro {
|
|
45
|
+
|
|
46
|
+
// C++ ${typename} <> JS ${typename} (union)
|
|
47
|
+
template <>
|
|
48
|
+
struct JSIConverter<${fullyQualifiedTypename}> final {
|
|
49
|
+
static inline ${fullyQualifiedTypename} fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
50
|
+
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);
|
|
51
|
+
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
52
|
+
${indent(cppFromJsiHashCases, ' ')}
|
|
53
|
+
default: [[unlikely]]
|
|
54
|
+
throw std::invalid_argument("Cannot convert \\"" + unionValue + "\\" to enum ${typename} - invalid value!");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, ${fullyQualifiedTypename} arg) {
|
|
58
|
+
switch (arg) {
|
|
59
|
+
${indent(cppToJsiCases, ' ')}
|
|
60
|
+
default: [[unlikely]]
|
|
61
|
+
throw std::invalid_argument("Cannot convert ${typename} to JS - invalid value: "
|
|
62
|
+
+ std::to_string(static_cast<int>(arg)) + "!");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
66
|
+
if (!value.isString()) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);
|
|
70
|
+
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
71
|
+
${indent(cppCanConvertCases, ' ')}
|
|
72
|
+
return true;
|
|
73
|
+
default:
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
} // namespace margelo::nitro
|
|
80
|
+
`;
|
|
81
|
+
return {
|
|
82
|
+
content: cppCode,
|
|
83
|
+
name: `${typename}.hpp`,
|
|
84
|
+
subdirectory: [],
|
|
85
|
+
language: 'c++',
|
|
86
|
+
platform: 'shared',
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function getForwardDeclaration(kind, className, namespace) {
|
|
2
|
+
if (namespace != null) {
|
|
3
|
+
return `
|
|
4
|
+
// Forward declaration of \`${className}\` to properly resolve imports.
|
|
5
|
+
namespace ${namespace} { ${kind} ${className}; }
|
|
6
|
+
`.trim();
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
return `
|
|
10
|
+
// Forward declaration of \`${className}\` to properly resolve imports.
|
|
11
|
+
${kind} ${className};
|
|
12
|
+
`.trim();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SourceImport } from '../SourceFile.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates C++ code for including a `NitroModules` header.
|
|
4
|
+
* @example `Hash.hpp` -> `#include <NitroModules/Hash.hpp>`
|
|
5
|
+
*/
|
|
6
|
+
export declare function includeNitroHeader(headerName: string): string;
|
|
7
|
+
export declare function includeHeader(sourceImport: SourceImport, force?: boolean): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates C++ code for including a `NitroModules` header.
|
|
3
|
+
* @example `Hash.hpp` -> `#include <NitroModules/Hash.hpp>`
|
|
4
|
+
*/
|
|
5
|
+
export function includeNitroHeader(headerName) {
|
|
6
|
+
return `
|
|
7
|
+
#if __has_include(<NitroModules/${headerName}>)
|
|
8
|
+
#include <NitroModules/${headerName}>
|
|
9
|
+
#else
|
|
10
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
11
|
+
#endif
|
|
12
|
+
`.trim();
|
|
13
|
+
}
|
|
14
|
+
export function includeHeader(sourceImport, force = true) {
|
|
15
|
+
const header = getHeader(sourceImport.name, sourceImport.space);
|
|
16
|
+
if (force) {
|
|
17
|
+
return `#include ${header}`;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
return `
|
|
21
|
+
#if __has_include(${header})
|
|
22
|
+
#include ${header}
|
|
23
|
+
#endif
|
|
24
|
+
`.trim();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function getHeader(name, space) {
|
|
28
|
+
switch (space) {
|
|
29
|
+
case 'user':
|
|
30
|
+
return `"${name}"`;
|
|
31
|
+
case 'system':
|
|
32
|
+
return `<${name}>`;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Type as TSMorphType } from 'ts-morph';
|
|
2
|
+
import type { Type } from './types/Type.js';
|
|
3
|
+
import { NamedWrappingType } from './types/NamedWrappingType.js';
|
|
4
|
+
import { type Language } from '../getPlatformSpecs.js';
|
|
5
|
+
export declare function createNamedType(language: Language, name: string, type: TSMorphType, isOptional: boolean): NamedWrappingType<Type>;
|
|
6
|
+
export declare function createVoidType(): Type;
|
|
7
|
+
/**
|
|
8
|
+
* Get a list of all currently known complex types.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getAllKnownTypes(language?: Language): Type[];
|
|
11
|
+
export declare function addKnownType(key: string, type: Type, language: Language): void;
|
|
12
|
+
/**
|
|
13
|
+
* Create a new type (or return it from cache if it is already known)
|
|
14
|
+
*/
|
|
15
|
+
export declare function createType(language: Language, type: TSMorphType, isOptional: boolean): Type;
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { ts, Type as TSMorphType } from 'ts-morph';
|
|
2
|
+
import { NullType } from './types/NullType.js';
|
|
3
|
+
import { BooleanType } from './types/BooleanType.js';
|
|
4
|
+
import { NumberType } from './types/NumberType.js';
|
|
5
|
+
import { StringType } from './types/StringType.js';
|
|
6
|
+
import { BigIntType } from './types/BigIntType.js';
|
|
7
|
+
import { VoidType } from './types/VoidType.js';
|
|
8
|
+
import { ArrayType } from './types/ArrayType.js';
|
|
9
|
+
import { FunctionType } from './types/FunctionType.js';
|
|
10
|
+
import { PromiseType } from './types/PromiseType.js';
|
|
11
|
+
import { RecordType } from './types/RecordType.js';
|
|
12
|
+
import { ArrayBufferType } from './types/ArrayBufferType.js';
|
|
13
|
+
import { EnumType } from './types/EnumType.js';
|
|
14
|
+
import { HybridObjectType } from './types/HybridObjectType.js';
|
|
15
|
+
import { StructType } from './types/StructType.js';
|
|
16
|
+
import { OptionalType } from './types/OptionalType.js';
|
|
17
|
+
import { NamedWrappingType } from './types/NamedWrappingType.js';
|
|
18
|
+
import { getInterfaceProperties } from './getInterfaceProperties.js';
|
|
19
|
+
import { VariantType } from './types/VariantType.js';
|
|
20
|
+
import { MapType } from './types/MapType.js';
|
|
21
|
+
import { TupleType } from './types/TupleType.js';
|
|
22
|
+
import { isAnyHybridSubclass, isDirectlyHybridObject, isHybridView, } from '../getPlatformSpecs.js';
|
|
23
|
+
import { HybridObjectBaseType } from './types/HybridObjectBaseType.js';
|
|
24
|
+
import { ErrorType } from './types/ErrorType.js';
|
|
25
|
+
import { getBaseTypes, getHybridObjectNitroModuleConfig } from '../utils.js';
|
|
26
|
+
import { DateType } from './types/DateType.js';
|
|
27
|
+
import { NitroConfig } from '../config/NitroConfig.js';
|
|
28
|
+
import { CustomType } from './types/CustomType.js';
|
|
29
|
+
import { isSyncFunction, isArrayBuffer, isCustomType, isDate, isError, isMap, isPromise, isRecord, } from './isCoreType.js';
|
|
30
|
+
import { getCustomTypeConfig } from './getCustomTypeConfig.js';
|
|
31
|
+
function getHybridObjectName(type) {
|
|
32
|
+
const symbol = isHybridView(type) ? type.getAliasSymbol() : type.getSymbol();
|
|
33
|
+
if (symbol == null) {
|
|
34
|
+
throw new Error(`Cannot get name of \`${type.getText()}\` - symbol not found!`);
|
|
35
|
+
}
|
|
36
|
+
return symbol.getEscapedName();
|
|
37
|
+
}
|
|
38
|
+
function getFunctionCallSignature(func) {
|
|
39
|
+
const callSignatures = func.getCallSignatures();
|
|
40
|
+
const callSignature = callSignatures[0];
|
|
41
|
+
if (callSignatures.length !== 1 || callSignature == null) {
|
|
42
|
+
throw new Error(`Function overloads are not supported in Nitrogen! (in ${func.getText()})`);
|
|
43
|
+
}
|
|
44
|
+
return callSignature;
|
|
45
|
+
}
|
|
46
|
+
function removeDuplicates(types) {
|
|
47
|
+
return types.filter((t1, index, array) => {
|
|
48
|
+
const firstIndexOfType = array.findIndex((t2) => t1.getCode('c++') === t2.getCode('c++'));
|
|
49
|
+
return firstIndexOfType === index;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function getArguments(type, typename, count) {
|
|
53
|
+
const typeArguments = type.getTypeArguments();
|
|
54
|
+
if (typeArguments.length === count) {
|
|
55
|
+
return typeArguments;
|
|
56
|
+
}
|
|
57
|
+
const aliasTypeArguments = type.getAliasTypeArguments();
|
|
58
|
+
if (aliasTypeArguments.length === count) {
|
|
59
|
+
return aliasTypeArguments;
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`Type ${type.getText()} looks like a ${typename}, but has ${typeArguments.length} or ${aliasTypeArguments.length} type arguments instead of ${count}!`);
|
|
62
|
+
}
|
|
63
|
+
export function createNamedType(language, name, type, isOptional) {
|
|
64
|
+
if (name.startsWith('__')) {
|
|
65
|
+
throw new Error(`Name cannot start with two underscores (__) as this is reserved syntax for Nitrogen! (In ${type.getText()})`);
|
|
66
|
+
}
|
|
67
|
+
return new NamedWrappingType(name, createType(language, type, isOptional));
|
|
68
|
+
}
|
|
69
|
+
export function createVoidType() {
|
|
70
|
+
return new VoidType();
|
|
71
|
+
}
|
|
72
|
+
const knownTypes = {
|
|
73
|
+
'c++': new Map(),
|
|
74
|
+
'swift': new Map(),
|
|
75
|
+
'kotlin': new Map(),
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Get a list of all currently known complex types.
|
|
79
|
+
*/
|
|
80
|
+
export function getAllKnownTypes(language) {
|
|
81
|
+
if (language != null) {
|
|
82
|
+
// Get types for the given language
|
|
83
|
+
return Array.from(knownTypes[language].values());
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Get types for all languages alltogether
|
|
87
|
+
const allMaps = Object.values(knownTypes);
|
|
88
|
+
return allMaps.flatMap((m) => Array.from(m.values()));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function getTypeId(type, isOptional) {
|
|
92
|
+
const symbol = type.getSymbol();
|
|
93
|
+
let key = type.getText();
|
|
94
|
+
if (symbol != null) {
|
|
95
|
+
key += '_' + symbol.getFullyQualifiedName();
|
|
96
|
+
}
|
|
97
|
+
if (isOptional)
|
|
98
|
+
key += '?';
|
|
99
|
+
return key;
|
|
100
|
+
}
|
|
101
|
+
export function addKnownType(key, type, language) {
|
|
102
|
+
if (knownTypes[language].has(key)) {
|
|
103
|
+
// type is already known
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
knownTypes[language].set(key, type);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Create a new type (or return it from cache if it is already known)
|
|
110
|
+
*/
|
|
111
|
+
export function createType(language, type, isOptional) {
|
|
112
|
+
const key = getTypeId(type, isOptional);
|
|
113
|
+
if (key != null && knownTypes[language].has(key)) {
|
|
114
|
+
const known = knownTypes[language].get(key);
|
|
115
|
+
if (isOptional === known instanceof OptionalType) {
|
|
116
|
+
return known;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const get = () => {
|
|
120
|
+
if (isOptional) {
|
|
121
|
+
const wrapping = createType(language, type, false);
|
|
122
|
+
return new OptionalType(wrapping);
|
|
123
|
+
}
|
|
124
|
+
if (type.isNull() || type.isUndefined()) {
|
|
125
|
+
return new NullType();
|
|
126
|
+
}
|
|
127
|
+
else if (type.isBoolean() || type.isBooleanLiteral()) {
|
|
128
|
+
return new BooleanType();
|
|
129
|
+
}
|
|
130
|
+
else if (type.isNumber() || type.isNumberLiteral()) {
|
|
131
|
+
if (type.isEnumLiteral()) {
|
|
132
|
+
// enum literals are technically just numbers - but we treat them differently in C++.
|
|
133
|
+
return createType(language, type.getBaseTypeOfLiteralType(), isOptional);
|
|
134
|
+
}
|
|
135
|
+
return new NumberType();
|
|
136
|
+
}
|
|
137
|
+
else if (type.isString()) {
|
|
138
|
+
return new StringType();
|
|
139
|
+
}
|
|
140
|
+
else if (type.isBigInt() || type.isBigIntLiteral()) {
|
|
141
|
+
return new BigIntType();
|
|
142
|
+
}
|
|
143
|
+
else if (type.isVoid()) {
|
|
144
|
+
return new VoidType();
|
|
145
|
+
}
|
|
146
|
+
else if (type.isArray()) {
|
|
147
|
+
const arrayElementType = type.getArrayElementTypeOrThrow();
|
|
148
|
+
const elementType = createType(language, arrayElementType, false);
|
|
149
|
+
return new ArrayType(elementType);
|
|
150
|
+
}
|
|
151
|
+
else if (type.isTuple()) {
|
|
152
|
+
const itemTypes = type
|
|
153
|
+
.getTupleElements()
|
|
154
|
+
.map((t) => createType(language, t, t.isNullable()));
|
|
155
|
+
return new TupleType(itemTypes);
|
|
156
|
+
}
|
|
157
|
+
else if (type.getCallSignatures().length > 0) {
|
|
158
|
+
// It's a function!
|
|
159
|
+
const callSignature = getFunctionCallSignature(type);
|
|
160
|
+
const funcReturnType = callSignature.getReturnType();
|
|
161
|
+
const returnType = createType(language, funcReturnType, funcReturnType.isNullable());
|
|
162
|
+
const parameters = callSignature.getParameters().map((p) => {
|
|
163
|
+
const declaration = p.getValueDeclarationOrThrow();
|
|
164
|
+
const parameterType = p.getTypeAtLocation(declaration);
|
|
165
|
+
const isNullable = parameterType.isNullable() || p.isOptional();
|
|
166
|
+
return createNamedType(language, p.getName(), parameterType, isNullable);
|
|
167
|
+
});
|
|
168
|
+
const isSync = isSyncFunction(type);
|
|
169
|
+
return new FunctionType(returnType, parameters, isSync);
|
|
170
|
+
}
|
|
171
|
+
else if (isPromise(type)) {
|
|
172
|
+
// It's a Promise!
|
|
173
|
+
const [promiseResolvingType] = getArguments(type, 'Promise', 1);
|
|
174
|
+
const resolvingType = createType(language, promiseResolvingType, promiseResolvingType.isNullable());
|
|
175
|
+
return new PromiseType(resolvingType);
|
|
176
|
+
}
|
|
177
|
+
else if (isRecord(type)) {
|
|
178
|
+
// Record<K, V> -> unordered_map<K, V>
|
|
179
|
+
const [keyTypeT, valueTypeT] = getArguments(type, 'Record', 2);
|
|
180
|
+
const keyType = createType(language, keyTypeT, false);
|
|
181
|
+
const valueType = createType(language, valueTypeT, false);
|
|
182
|
+
return new RecordType(keyType, valueType);
|
|
183
|
+
}
|
|
184
|
+
else if (isArrayBuffer(type)) {
|
|
185
|
+
// ArrayBuffer
|
|
186
|
+
return new ArrayBufferType();
|
|
187
|
+
}
|
|
188
|
+
else if (isMap(type)) {
|
|
189
|
+
// Map
|
|
190
|
+
return new MapType();
|
|
191
|
+
}
|
|
192
|
+
else if (isDate(type)) {
|
|
193
|
+
// Date
|
|
194
|
+
return new DateType();
|
|
195
|
+
}
|
|
196
|
+
else if (isError(type)) {
|
|
197
|
+
// Error
|
|
198
|
+
return new ErrorType();
|
|
199
|
+
}
|
|
200
|
+
else if (isCustomType(type)) {
|
|
201
|
+
// Custom C++ type (manually written)
|
|
202
|
+
const { name, config } = getCustomTypeConfig(type);
|
|
203
|
+
return new CustomType(name, config);
|
|
204
|
+
}
|
|
205
|
+
else if (type.isEnum()) {
|
|
206
|
+
// It is an enum. We need to generate a C++ declaration for the enum
|
|
207
|
+
const typename = type.getSymbolOrThrow().getEscapedName();
|
|
208
|
+
const declaration = type.getSymbolOrThrow().getValueDeclarationOrThrow();
|
|
209
|
+
const enumDeclaration = declaration.asKindOrThrow(ts.SyntaxKind.EnumDeclaration);
|
|
210
|
+
return new EnumType(typename, enumDeclaration);
|
|
211
|
+
}
|
|
212
|
+
else if (type.isUnion()) {
|
|
213
|
+
// It is some kind of union;
|
|
214
|
+
// - of string literals (then it's an enum)
|
|
215
|
+
// - of type `T | undefined` (then it's just optional `T`)
|
|
216
|
+
// - of different types (then it's a variant `A | B | C`)
|
|
217
|
+
const types = type.getUnionTypes();
|
|
218
|
+
const nonNullTypes = types.filter((t) => !t.isNull() && !t.isUndefined() && !t.isVoid());
|
|
219
|
+
const isEnumUnion = nonNullTypes.every((t) => t.isStringLiteral());
|
|
220
|
+
if (isEnumUnion) {
|
|
221
|
+
// It consists only of string literaly - that means it's describing an enum!
|
|
222
|
+
const symbol = type.getNonNullableType().getAliasSymbol();
|
|
223
|
+
if (symbol == null) {
|
|
224
|
+
// If there is no alias, it is an inline union instead of a separate type declaration!
|
|
225
|
+
throw new Error(`Inline union types ("${type.getText()}") are not supported by Nitrogen!\n` +
|
|
226
|
+
`Extract the union to a separate type, and re-run nitrogen!`);
|
|
227
|
+
}
|
|
228
|
+
const typename = symbol.getEscapedName();
|
|
229
|
+
return new EnumType(typename, type);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
// It consists of different types - that means it's a variant!
|
|
233
|
+
let variants = type
|
|
234
|
+
.getUnionTypes()
|
|
235
|
+
// Filter out any nulls or undefineds, as those are already treated as `isOptional`.
|
|
236
|
+
.filter((t) => !t.isNull() && !t.isUndefined() && !t.isVoid())
|
|
237
|
+
.map((t) => createType(language, t, false));
|
|
238
|
+
variants = removeDuplicates(variants);
|
|
239
|
+
if (variants.length === 1) {
|
|
240
|
+
// It's just one type with undefined/null variant(s) - so we treat it like a simple optional.
|
|
241
|
+
return variants[0];
|
|
242
|
+
}
|
|
243
|
+
const name = type.getAliasSymbol()?.getName();
|
|
244
|
+
return new VariantType(variants, name);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else if (isAnyHybridSubclass(type)) {
|
|
248
|
+
// It is another HybridObject being referenced!
|
|
249
|
+
const typename = getHybridObjectName(type);
|
|
250
|
+
const baseTypes = getBaseTypes(type)
|
|
251
|
+
.filter((t) => isAnyHybridSubclass(t))
|
|
252
|
+
.map((b) => createType(language, b, false));
|
|
253
|
+
const baseHybrids = baseTypes.filter((b) => b instanceof HybridObjectType);
|
|
254
|
+
const sourceConfig = getHybridObjectNitroModuleConfig(type) ?? NitroConfig.current;
|
|
255
|
+
return new HybridObjectType(typename, language, baseHybrids, sourceConfig);
|
|
256
|
+
}
|
|
257
|
+
else if (isDirectlyHybridObject(type)) {
|
|
258
|
+
// It is a HybridObject directly/literally. Base type
|
|
259
|
+
return new HybridObjectBaseType();
|
|
260
|
+
}
|
|
261
|
+
else if (type.isInterface()) {
|
|
262
|
+
// It is an `interface T { ... }`, which is a `struct`
|
|
263
|
+
const typename = type.getSymbolOrThrow().getName();
|
|
264
|
+
const properties = getInterfaceProperties(language, type);
|
|
265
|
+
return new StructType(typename, properties);
|
|
266
|
+
}
|
|
267
|
+
else if (type.isObject()) {
|
|
268
|
+
// It is an object. If it has a symbol/name, it is a `type T = ...` declaration, so a `struct`.
|
|
269
|
+
// Otherwise, it is an anonymous/inline object, which cannot be represented in native.
|
|
270
|
+
const symbol = type.getAliasSymbol();
|
|
271
|
+
if (symbol != null) {
|
|
272
|
+
// it has a `type T = ...` declaration
|
|
273
|
+
const typename = symbol.getName();
|
|
274
|
+
const properties = getInterfaceProperties(language, type);
|
|
275
|
+
return new StructType(typename, properties);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
// It's an anonymous object (`{ ... }`)
|
|
279
|
+
throw new Error(`Anonymous objects cannot be represented in C++! Extract "${type.getText()}" to a separate interface/type declaration.`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else if (type.isStringLiteral()) {
|
|
283
|
+
throw new Error(`String literal ${type.getText()} cannot be represented in C++ because it is ambiguous between a string and a discriminating union enum.`);
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
if (type.getSymbol() == null) {
|
|
287
|
+
// There is no declaration for it!
|
|
288
|
+
// Could be an invalid import, e.g. an alias
|
|
289
|
+
throw new Error(`The TypeScript type "${type.getText()}" cannot be resolved - is it imported properly? ` +
|
|
290
|
+
`Make sure to import it properly using fully specified relative or absolute imports, no aliases.`);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
// A different error
|
|
294
|
+
throw new Error(`The TypeScript type "${type.getText()}" cannot be represented in C++!`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
const result = get();
|
|
299
|
+
if (key != null) {
|
|
300
|
+
knownTypes[language].set(key, result);
|
|
301
|
+
}
|
|
302
|
+
return result;
|
|
303
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// TODO: Structs or other HybridObjects may reference other types recursively - we need to add a `referencedTypes` prop to each `Type` to be able to resolve that.
|
|
2
|
+
export function getAllTypes(spec) {
|
|
3
|
+
const types = [];
|
|
4
|
+
// 1. Properties
|
|
5
|
+
types.push(...spec.properties.map((p) => p.type));
|
|
6
|
+
// 2. Method return types
|
|
7
|
+
types.push(...spec.methods.map((m) => m.returnType));
|
|
8
|
+
// 3. Method parameters
|
|
9
|
+
types.push(...spec.methods.flatMap((m) => m.parameters.map((p) => p.type)));
|
|
10
|
+
return types;
|
|
11
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CustomTypeConfig } from 'react-native-nitro-modules';
|
|
2
|
+
import type { Type as TSMorphType } from 'ts-morph';
|
|
3
|
+
interface Result {
|
|
4
|
+
name: string;
|
|
5
|
+
config: CustomTypeConfig;
|
|
6
|
+
}
|
|
7
|
+
export declare function getCustomTypeConfig(type: TSMorphType): Result;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export function getCustomTypeConfig(type) {
|
|
2
|
+
const parts = type.getIntersectionTypes();
|
|
3
|
+
for (const part of parts) {
|
|
4
|
+
const typeNameProperty = part.getProperty('__customTypeName');
|
|
5
|
+
if (typeNameProperty == null)
|
|
6
|
+
continue;
|
|
7
|
+
const typeConfigProperty = part.getProperty('__customTypeConfig');
|
|
8
|
+
if (typeConfigProperty == null)
|
|
9
|
+
continue;
|
|
10
|
+
const declaration = type.getAliasSymbolOrThrow().getDeclarations()[0];
|
|
11
|
+
if (declaration == null)
|
|
12
|
+
throw new Error(`Type has no declaration! ${type.getText()}`);
|
|
13
|
+
const typeNameTypeOrUndefined = typeNameProperty.getTypeAtLocation(declaration);
|
|
14
|
+
const typeConfigTypeOrUndefined = typeConfigProperty.getTypeAtLocation(declaration);
|
|
15
|
+
const typeNameType = typeNameTypeOrUndefined
|
|
16
|
+
.getUnionTypes()
|
|
17
|
+
.find((t) => t.isLiteral());
|
|
18
|
+
if (typeNameType == null)
|
|
19
|
+
continue;
|
|
20
|
+
const typeConfigType = typeConfigTypeOrUndefined
|
|
21
|
+
.getUnionTypes()
|
|
22
|
+
.find((t) => t.isObject());
|
|
23
|
+
if (typeConfigType == null)
|
|
24
|
+
continue;
|
|
25
|
+
const typeName = typeNameType.getLiteralValue();
|
|
26
|
+
if (typeof typeName !== 'string') {
|
|
27
|
+
throw new Error(`CustomType's second argument (TypeName) needs to be a string! Instead, it is a ${typeof typeName} (${typeName})`);
|
|
28
|
+
}
|
|
29
|
+
const includeType = typeConfigType
|
|
30
|
+
.getPropertyOrThrow('include')
|
|
31
|
+
.getTypeAtLocation(declaration);
|
|
32
|
+
const include = includeType.getLiteralValue();
|
|
33
|
+
if (typeof include !== 'string')
|
|
34
|
+
throw new Error(`CustomType's third argument (Config) needs to contain { include }, which should be a string! (It is ${includeType.getText()} instead)`);
|
|
35
|
+
const canBePassedByReferenceType = typeConfigType
|
|
36
|
+
.getProperty('canBePassedByReference')
|
|
37
|
+
?.getTypeAtLocation(declaration)
|
|
38
|
+
.getUnionTypes()
|
|
39
|
+
.find((u) => u.isBooleanLiteral())
|
|
40
|
+
?.getLiteralValue();
|
|
41
|
+
const canBePassedByReference = typeof canBePassedByReferenceType === 'boolean'
|
|
42
|
+
? canBePassedByReferenceType
|
|
43
|
+
: false;
|
|
44
|
+
return {
|
|
45
|
+
name: typeName,
|
|
46
|
+
config: {
|
|
47
|
+
include: include,
|
|
48
|
+
canBePassedByReference: canBePassedByReference,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
throw new Error(`Type looks like a CustomType<...>, but doesn't have generic arguments! ${type.getText()}`);
|
|
53
|
+
}
|