nitrogen 0.2.24 → 0.29.5

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.
Files changed (241) hide show
  1. package/README.md +18 -108
  2. package/lib/Logger.js +56 -0
  3. package/lib/autolinking/Autolinking.js +1 -0
  4. package/lib/autolinking/android/createCMakeExtension.js +109 -0
  5. package/lib/autolinking/android/createGradleExtension.js +36 -0
  6. package/lib/autolinking/android/createHybridObjectInitializer.js +159 -0
  7. package/lib/autolinking/createAndroidAutolinking.js +13 -0
  8. package/lib/autolinking/createIOSAutolinking.js +19 -0
  9. package/lib/autolinking/ios/createHybridObjectInitializer.js +97 -0
  10. package/lib/autolinking/ios/createPodspecRubyExtension.js +69 -0
  11. package/lib/autolinking/ios/createSwiftCxxBridge.js +117 -0
  12. package/lib/autolinking/ios/createSwiftUmbrellaHeader.js +74 -0
  13. package/lib/config/NitroConfig.js +112 -0
  14. package/lib/config/NitroUserConfig.js +88 -0
  15. package/lib/config/getConfig.js +84 -0
  16. package/lib/createGitAttributes.js +11 -0
  17. package/lib/createPlatformSpec.js +127 -0
  18. package/lib/getFiles.js +28 -0
  19. package/lib/getPlatformSpecs.js +153 -0
  20. package/lib/index.js +113 -10
  21. package/lib/init.js +123 -0
  22. package/lib/nitrogen.js +165 -0
  23. package/lib/prettifyDirectory.js +27 -0
  24. package/lib/syntax/BridgedType.js +1 -0
  25. package/lib/syntax/CodeNode.js +1 -0
  26. package/lib/syntax/HybridObjectSpec.js +1 -0
  27. package/lib/syntax/Method.js +108 -0
  28. package/lib/syntax/Parameter.js +65 -0
  29. package/lib/syntax/Property.js +147 -0
  30. package/lib/syntax/SourceFile.js +7 -0
  31. package/lib/syntax/c++/CppEnum.js +110 -0
  32. package/lib/syntax/c++/CppHybridObject.js +146 -0
  33. package/lib/syntax/c++/CppHybridObjectRegistration.js +18 -0
  34. package/lib/syntax/c++/CppStruct.js +108 -0
  35. package/lib/syntax/c++/CppUnion.js +88 -0
  36. package/lib/syntax/c++/getForwardDeclaration.js +14 -0
  37. package/lib/syntax/c++/includeNitroHeader.js +34 -0
  38. package/lib/syntax/createType.js +303 -0
  39. package/lib/syntax/getAllTypes.js +11 -0
  40. package/lib/syntax/getCustomTypeConfig.js +53 -0
  41. package/lib/syntax/getHybridObjectName.d.ts +36 -0
  42. package/lib/syntax/getHybridObjectName.js +10 -0
  43. package/lib/syntax/getInterfaceProperties.js +9 -0
  44. package/lib/syntax/getReferencedTypes.js +47 -0
  45. package/lib/syntax/helpers.js +53 -0
  46. package/lib/syntax/isCoreType.js +47 -0
  47. package/lib/syntax/kotlin/FbjniHybridObject.js +261 -0
  48. package/lib/syntax/kotlin/JNINativeRegistrations.js +7 -0
  49. package/lib/syntax/kotlin/KotlinBoxedPrimitive.js +17 -0
  50. package/lib/syntax/kotlin/KotlinCxxBridgedType.js +893 -0
  51. package/lib/syntax/kotlin/KotlinEnum.js +113 -0
  52. package/lib/syntax/kotlin/KotlinFunction.js +256 -0
  53. package/lib/syntax/kotlin/KotlinHybridObject.js +177 -0
  54. package/lib/syntax/kotlin/KotlinHybridObjectRegistration.js +26 -0
  55. package/lib/syntax/kotlin/KotlinStruct.js +172 -0
  56. package/lib/syntax/kotlin/KotlinVariant.js +191 -0
  57. package/lib/syntax/swift/SwiftCxxBridgedType.js +819 -0
  58. package/lib/syntax/swift/SwiftCxxTypeHelper.js +613 -0
  59. package/lib/syntax/swift/SwiftEnum.js +52 -0
  60. package/lib/syntax/swift/SwiftFunction.js +83 -0
  61. package/lib/syntax/swift/SwiftHybridObject.js +103 -0
  62. package/lib/syntax/swift/SwiftHybridObjectBridge.js +451 -0
  63. package/lib/syntax/swift/SwiftHybridObjectRegistration.js +42 -0
  64. package/lib/syntax/swift/SwiftStruct.js +75 -0
  65. package/lib/syntax/swift/SwiftVariant.js +58 -0
  66. package/lib/syntax/types/ArrayBufferType.js +37 -0
  67. package/lib/syntax/types/ArrayType.d.ts +12 -0
  68. package/lib/syntax/types/ArrayType.js +52 -0
  69. package/lib/syntax/types/BigIntType.js +27 -0
  70. package/lib/syntax/types/BooleanType.js +27 -0
  71. package/lib/syntax/types/CustomType.d.ts +14 -0
  72. package/lib/syntax/types/CustomType.js +36 -0
  73. package/lib/syntax/types/DateType.js +35 -0
  74. package/lib/syntax/types/EnumType.js +101 -0
  75. package/lib/syntax/types/ErrorType.js +37 -0
  76. package/lib/syntax/types/FunctionType.js +147 -0
  77. package/lib/syntax/types/HybridObjectBaseType.js +38 -0
  78. package/lib/syntax/types/HybridObjectType.js +131 -0
  79. package/lib/syntax/types/MapType.js +37 -0
  80. package/lib/syntax/types/NamedWrappingType.js +27 -0
  81. package/lib/syntax/types/NullType.js +23 -0
  82. package/lib/syntax/types/NumberType.js +27 -0
  83. package/lib/syntax/types/OptionalType.js +59 -0
  84. package/lib/syntax/types/PromiseType.js +62 -0
  85. package/lib/syntax/types/RecordType.js +47 -0
  86. package/lib/syntax/types/ResultWrappingType.js +44 -0
  87. package/lib/syntax/types/StringType.js +35 -0
  88. package/lib/syntax/types/StructType.js +61 -0
  89. package/lib/syntax/types/TupleType.js +39 -0
  90. package/lib/syntax/types/Type.js +1 -0
  91. package/lib/syntax/types/VariantType.js +75 -0
  92. package/lib/syntax/types/VoidType.js +27 -0
  93. package/lib/syntax/types/getTypeAs.js +12 -0
  94. package/lib/utils.js +126 -0
  95. package/lib/views/CppHybridViewComponent.js +256 -0
  96. package/lib/views/createHostComponentJs.js +27 -0
  97. package/lib/views/kotlin/KotlinHybridViewManager.js +229 -0
  98. package/lib/views/swift/SwiftHybridViewManager.js +131 -0
  99. package/lib/writeFile.js +19 -0
  100. package/package.json +58 -29
  101. package/src/Logger.ts +63 -0
  102. package/src/autolinking/Autolinking.ts +9 -0
  103. package/src/autolinking/android/createCMakeExtension.ts +126 -0
  104. package/src/autolinking/android/createGradleExtension.ts +43 -0
  105. package/src/autolinking/android/createHybridObjectInitializer.ts +174 -0
  106. package/src/autolinking/createAndroidAutolinking.ts +28 -0
  107. package/src/autolinking/createIOSAutolinking.ts +24 -0
  108. package/src/autolinking/ios/createHybridObjectInitializer.ts +112 -0
  109. package/src/autolinking/ios/createPodspecRubyExtension.ts +76 -0
  110. package/src/autolinking/ios/createSwiftCxxBridge.ts +137 -0
  111. package/src/autolinking/ios/createSwiftUmbrellaHeader.ts +90 -0
  112. package/src/config/NitroConfig.ts +139 -0
  113. package/src/config/NitroUserConfig.ts +105 -0
  114. package/src/config/getConfig.ts +91 -0
  115. package/src/createGitAttributes.ts +15 -0
  116. package/src/createPlatformSpec.ts +176 -0
  117. package/src/getFiles.ts +31 -0
  118. package/src/getPlatformSpecs.ts +202 -0
  119. package/src/index.ts +146 -0
  120. package/src/init.ts +186 -0
  121. package/src/nitrogen.ts +246 -0
  122. package/src/prettifyDirectory.ts +32 -0
  123. package/src/syntax/BridgedType.ts +59 -0
  124. package/src/syntax/CodeNode.ts +24 -0
  125. package/src/syntax/HybridObjectSpec.ts +14 -0
  126. package/src/syntax/Method.ts +154 -0
  127. package/src/syntax/Parameter.ts +81 -0
  128. package/src/syntax/Property.ts +203 -0
  129. package/src/syntax/SourceFile.ts +80 -0
  130. package/src/syntax/c++/CppEnum.ts +128 -0
  131. package/src/syntax/c++/CppHybridObject.ts +165 -0
  132. package/src/syntax/c++/CppHybridObjectRegistration.ts +39 -0
  133. package/src/syntax/c++/CppStruct.ts +129 -0
  134. package/src/syntax/c++/CppUnion.ts +105 -0
  135. package/src/syntax/c++/getForwardDeclaration.ts +19 -0
  136. package/src/syntax/c++/includeNitroHeader.ts +40 -0
  137. package/src/syntax/createType.ts +365 -0
  138. package/src/syntax/getAllTypes.ts +18 -0
  139. package/src/syntax/getCustomTypeConfig.ts +71 -0
  140. package/src/syntax/getHybridObjectName.ts +48 -0
  141. package/src/syntax/getInterfaceProperties.ts +21 -0
  142. package/src/syntax/getReferencedTypes.ts +57 -0
  143. package/src/syntax/helpers.ts +79 -0
  144. package/src/syntax/isCoreType.ts +60 -0
  145. package/src/syntax/kotlin/FbjniHybridObject.ts +313 -0
  146. package/src/syntax/kotlin/JNINativeRegistrations.ts +19 -0
  147. package/src/syntax/kotlin/KotlinBoxedPrimitive.ts +19 -0
  148. package/src/syntax/kotlin/KotlinCxxBridgedType.ts +942 -0
  149. package/src/syntax/kotlin/KotlinEnum.ts +130 -0
  150. package/src/syntax/kotlin/KotlinFunction.ts +277 -0
  151. package/src/syntax/kotlin/KotlinHybridObject.ts +205 -0
  152. package/src/syntax/kotlin/KotlinHybridObjectRegistration.ts +51 -0
  153. package/src/syntax/kotlin/KotlinStruct.ts +198 -0
  154. package/src/syntax/kotlin/KotlinVariant.ts +212 -0
  155. package/src/syntax/swift/SwiftCxxBridgedType.ts +874 -0
  156. package/src/syntax/swift/SwiftCxxTypeHelper.ts +674 -0
  157. package/src/syntax/swift/SwiftEnum.ts +65 -0
  158. package/src/syntax/swift/SwiftFunction.ts +91 -0
  159. package/src/syntax/swift/SwiftHybridObject.ts +121 -0
  160. package/src/syntax/swift/SwiftHybridObjectBridge.ts +522 -0
  161. package/src/syntax/swift/SwiftHybridObjectRegistration.ts +75 -0
  162. package/src/syntax/swift/SwiftStruct.ts +85 -0
  163. package/src/syntax/swift/SwiftVariant.ts +67 -0
  164. package/src/syntax/types/ArrayBufferType.ts +49 -0
  165. package/src/syntax/types/ArrayType.ts +62 -0
  166. package/src/syntax/types/BigIntType.ts +35 -0
  167. package/src/syntax/types/BooleanType.ts +35 -0
  168. package/src/syntax/types/CustomType.ts +47 -0
  169. package/src/syntax/types/DateType.ts +43 -0
  170. package/src/syntax/types/EnumType.ts +130 -0
  171. package/src/syntax/types/ErrorType.ts +44 -0
  172. package/src/syntax/types/FunctionType.ts +167 -0
  173. package/src/syntax/types/HybridObjectBaseType.ts +54 -0
  174. package/src/syntax/types/HybridObjectType.ts +198 -0
  175. package/src/syntax/types/MapType.ts +49 -0
  176. package/src/syntax/types/NamedWrappingType.ts +33 -0
  177. package/src/syntax/types/NullType.ts +30 -0
  178. package/src/syntax/types/NumberType.ts +34 -0
  179. package/src/syntax/types/OptionalType.ts +66 -0
  180. package/src/syntax/types/PromiseType.ts +72 -0
  181. package/src/syntax/types/RecordType.ts +56 -0
  182. package/src/syntax/types/ResultWrappingType.ts +53 -0
  183. package/src/syntax/types/StringType.ts +44 -0
  184. package/src/syntax/types/StructType.ts +83 -0
  185. package/src/syntax/types/TupleType.ts +53 -0
  186. package/src/syntax/types/Type.ts +82 -0
  187. package/src/syntax/types/VariantType.ts +92 -0
  188. package/src/syntax/types/VoidType.ts +34 -0
  189. package/src/syntax/types/getTypeAs.ts +15 -0
  190. package/src/utils.ts +162 -0
  191. package/src/views/CppHybridViewComponent.ts +304 -0
  192. package/src/views/createHostComponentJs.ts +34 -0
  193. package/src/views/kotlin/KotlinHybridViewManager.ts +258 -0
  194. package/src/views/swift/SwiftHybridViewManager.ts +153 -0
  195. package/src/writeFile.ts +27 -0
  196. package/.jshintignore +0 -6
  197. package/.jshintrc +0 -3
  198. package/.npmignore +0 -3
  199. package/.travis.yml +0 -13
  200. package/LICENSE +0 -13
  201. package/browser/nitrogen-min.js +0 -3
  202. package/browser/nitrogen.js +0 -6369
  203. package/lib/apiKey.js +0 -67
  204. package/lib/blob.js +0 -57
  205. package/lib/commandManager.js +0 -350
  206. package/lib/device.js +0 -19
  207. package/lib/memoryStore.js +0 -24
  208. package/lib/message.js +0 -298
  209. package/lib/permission.js +0 -121
  210. package/lib/principal.js +0 -330
  211. package/lib/service.js +0 -347
  212. package/lib/session.js +0 -494
  213. package/lib/user.js +0 -20
  214. package/publish +0 -2
  215. package/scripts/build-documentation +0 -4
  216. package/scripts/build-module +0 -27
  217. package/scripts/module.js +0 -12
  218. package/scripts/postamble.js +0 -1
  219. package/scripts/preamble.js +0 -2
  220. package/scripts/run-test-server +0 -9
  221. package/test/config.js +0 -12
  222. package/test/fixtures/images/image.jpg +0 -0
  223. package/test/fixtures/images/motion0.jpg +0 -0
  224. package/test/fixtures/images/motion1.jpg +0 -0
  225. package/test/fixtures/images/motion2.jpg +0 -0
  226. package/test/fixtures/index.js +0 -76
  227. package/test/main.js +0 -5
  228. package/test/memoryStore.js +0 -22
  229. package/test/mocha.opts +0 -3
  230. package/test/units/apiKey.js +0 -46
  231. package/test/units/blob.js +0 -35
  232. package/test/units/commandManager.js +0 -67
  233. package/test/units/device.js +0 -26
  234. package/test/units/heartbeat.js +0 -28
  235. package/test/units/message.js +0 -79
  236. package/test/units/permissions.js +0 -43
  237. package/test/units/principal.js +0 -116
  238. package/test/units/service.js +0 -92
  239. package/test/units/session.js +0 -97
  240. package/test/units/user.js +0 -48
  241. package/yuidoc.json +0 -8
@@ -0,0 +1,172 @@
1
+ import { NitroConfig } from '../../config/NitroConfig.js';
2
+ import { capitalizeName, indent } from '../../utils.js';
3
+ import { includeHeader } from '../c++/includeNitroHeader.js';
4
+ import { getReferencedTypes } from '../getReferencedTypes.js';
5
+ import { createFileMetadataString, isNotDuplicate } from '../helpers.js';
6
+ import { KotlinCxxBridgedType } from './KotlinCxxBridgedType.js';
7
+ export function createKotlinStruct(structType) {
8
+ const packageName = NitroConfig.current.getAndroidPackage('java/kotlin');
9
+ const values = structType.properties.map((p) => {
10
+ const bridged = new KotlinCxxBridgedType(p);
11
+ return `
12
+ @DoNotStrip
13
+ @Keep
14
+ val ${p.escapedName}: ${bridged.getTypeCode('kotlin', false)}
15
+ `.trim();
16
+ });
17
+ let secondaryConstructor;
18
+ const needsSpecialHandling = structType.properties.some((p) => new KotlinCxxBridgedType(p).needsSpecialHandling);
19
+ if (needsSpecialHandling) {
20
+ // If we need special handling for any of our properties, we need to add a convenience initializer.
21
+ const params = structType.properties.map((p) => `${p.escapedName}: ${p.getCode('kotlin')}`);
22
+ const paramsForward = structType.properties.map((p) => {
23
+ const bridged = new KotlinCxxBridgedType(p);
24
+ if (bridged.needsSpecialHandling) {
25
+ // We need special parsing for this type
26
+ return bridged.parseFromKotlinToCpp(p.escapedName, 'kotlin', false);
27
+ }
28
+ else {
29
+ return p.escapedName;
30
+ }
31
+ });
32
+ secondaryConstructor = `
33
+ /**
34
+ * Initialize a new instance of \`${structType.structName}\` from Kotlin.
35
+ */
36
+ constructor(${indent(params.join(', '), 12)})
37
+ : this(${indent(paramsForward.join(', '), 12)})
38
+ `.trim();
39
+ }
40
+ else {
41
+ secondaryConstructor = `/* main constructor */`;
42
+ }
43
+ const extraImports = structType.properties
44
+ .flatMap((t) => t.getRequiredImports('kotlin'))
45
+ .map((i) => `import ${i.name}`);
46
+ const code = `
47
+ ${createFileMetadataString(`${structType.structName}.kt`)}
48
+
49
+ package ${packageName}
50
+
51
+ import androidx.annotation.Keep
52
+ import com.facebook.proguard.annotations.DoNotStrip
53
+ import com.margelo.nitro.core.*
54
+ ${extraImports.join('\n')}
55
+
56
+ /**
57
+ * Represents the JavaScript object/struct "${structType.structName}".
58
+ */
59
+ @DoNotStrip
60
+ @Keep
61
+ data class ${structType.structName}
62
+ @DoNotStrip
63
+ @Keep
64
+ constructor(
65
+ ${indent(values.join(',\n'), ' ')}
66
+ ) {
67
+ ${indent(secondaryConstructor, ' ')}
68
+ }
69
+ `.trim();
70
+ const cxxNamespace = NitroConfig.current.getCxxNamespace('c++');
71
+ const jniClassDescriptor = NitroConfig.current.getAndroidPackage('c++/jni', structType.structName);
72
+ const jniStructInitializerBody = createJNIStructInitializer(structType);
73
+ const cppStructInitializerBody = createCppStructInitializer('value', structType);
74
+ const imports = structType.properties
75
+ .flatMap((p) => getReferencedTypes(p))
76
+ .map((t) => new KotlinCxxBridgedType(t))
77
+ .flatMap((t) => t.getRequiredImports('c++'));
78
+ const includes = imports
79
+ .map((i) => includeHeader(i))
80
+ .filter(isNotDuplicate)
81
+ .sort();
82
+ const fbjniCode = `
83
+ ${createFileMetadataString(`J${structType.structName}.hpp`)}
84
+
85
+ #pragma once
86
+
87
+ #include <fbjni/fbjni.h>
88
+ #include "${structType.declarationFile.name}"
89
+
90
+ ${includes.join('\n')}
91
+
92
+ namespace ${cxxNamespace} {
93
+
94
+ using namespace facebook;
95
+
96
+ /**
97
+ * The C++ JNI bridge between the C++ struct "${structType.structName}" and the the Kotlin data class "${structType.structName}".
98
+ */
99
+ struct J${structType.structName} final: public jni::JavaClass<J${structType.structName}> {
100
+ public:
101
+ static auto constexpr kJavaDescriptor = "L${jniClassDescriptor};";
102
+
103
+ public:
104
+ /**
105
+ * Convert this Java/Kotlin-based struct to the C++ struct ${structType.structName} by copying all values to C++.
106
+ */
107
+ [[maybe_unused]]
108
+ [[nodiscard]]
109
+ ${structType.structName} toCpp() const {
110
+ ${indent(jniStructInitializerBody, ' ')}
111
+ }
112
+
113
+ public:
114
+ /**
115
+ * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
116
+ */
117
+ [[maybe_unused]]
118
+ static jni::local_ref<J${structType.structName}::javaobject> fromCpp(const ${structType.structName}& value) {
119
+ ${indent(cppStructInitializerBody, ' ')}
120
+ }
121
+ };
122
+
123
+ } // namespace ${cxxNamespace}
124
+ `.trim();
125
+ const files = [];
126
+ files.push({
127
+ content: code,
128
+ language: 'kotlin',
129
+ name: `${structType.structName}.kt`,
130
+ subdirectory: NitroConfig.current.getAndroidPackageDirectory(),
131
+ platform: 'android',
132
+ });
133
+ files.push({
134
+ content: fbjniCode,
135
+ language: 'c++',
136
+ name: `J${structType.structName}.hpp`,
137
+ subdirectory: [],
138
+ platform: 'android',
139
+ });
140
+ return files;
141
+ }
142
+ function createJNIStructInitializer(structType) {
143
+ const lines = ['static const auto clazz = javaClassStatic();'];
144
+ for (const prop of structType.properties) {
145
+ const fieldName = `field${capitalizeName(prop.escapedName)}`;
146
+ const jniType = new KotlinCxxBridgedType(prop);
147
+ const signatureType = jniType.getTypeCode('c++');
148
+ const valueType = jniType.asJniReferenceType('local');
149
+ lines.push(`static const auto ${fieldName} = clazz->getField<${signatureType}>("${prop.escapedName}");`);
150
+ lines.push(`${valueType} ${prop.escapedName} = this->getFieldValue(${fieldName});`);
151
+ }
152
+ const propsForward = structType.properties.map((p) => {
153
+ const bridged = new KotlinCxxBridgedType(p);
154
+ return bridged.parse(p.escapedName, 'kotlin', 'c++', 'c++');
155
+ });
156
+ lines.push(`return ${structType.structName}(`);
157
+ lines.push(` ${indent(propsForward.join(',\n'), ' ')}`);
158
+ lines.push(`);`);
159
+ return lines.join('\n');
160
+ }
161
+ function createCppStructInitializer(cppValueName, structType) {
162
+ const lines = [];
163
+ lines.push(`return newInstance(`);
164
+ const names = structType.properties.map((p) => {
165
+ const name = `${cppValueName}.${p.escapedName}`;
166
+ const bridge = new KotlinCxxBridgedType(p);
167
+ return bridge.parse(name, 'c++', 'kotlin', 'c++');
168
+ });
169
+ lines.push(` ${indent(names.join(',\n'), ' ')}`);
170
+ lines.push(');');
171
+ return lines.join('\n');
172
+ }
@@ -0,0 +1,191 @@
1
+ import { NitroConfig } from '../../config/NitroConfig.js';
2
+ import { capitalizeName, indent } from '../../utils.js';
3
+ import { includeHeader } from '../c++/includeNitroHeader.js';
4
+ import { createFileMetadataString, isNotDuplicate, toReferenceType, } from '../helpers.js';
5
+ import {} from '../types/VariantType.js';
6
+ import { KotlinCxxBridgedType } from './KotlinCxxBridgedType.js';
7
+ export function createKotlinVariant(variant) {
8
+ const jsName = variant.variants.map((v) => v.getCode('kotlin')).join('|');
9
+ const kotlinName = variant.getAliasName('kotlin');
10
+ const namespace = `J${kotlinName}_impl`;
11
+ const innerClasses = variant.cases.map(([label, v]) => {
12
+ const innerName = capitalizeName(label);
13
+ return `
14
+ @DoNotStrip
15
+ data class ${innerName}(@DoNotStrip val value: ${v.getCode('kotlin')}): ${kotlinName}()
16
+ `.trim();
17
+ });
18
+ const packageName = NitroConfig.current.getAndroidPackage('java/kotlin');
19
+ const getterCases = variant.cases.map(([label]) => {
20
+ const innerName = capitalizeName(label);
21
+ return `is ${innerName} -> value as? T`;
22
+ });
23
+ const isFunctions = variant.cases.map(([label]) => {
24
+ const innerName = capitalizeName(label);
25
+ return `
26
+ val is${innerName}: Boolean
27
+ get() = this is ${innerName}
28
+ `.trim();
29
+ });
30
+ const createFunctions = variant.cases.map(([label, v]) => {
31
+ const innerName = capitalizeName(label);
32
+ return `
33
+ @JvmStatic
34
+ @DoNotStrip
35
+ fun create(value: ${v.getCode('kotlin')}): ${kotlinName} = ${innerName}(value)
36
+ `.trim();
37
+ });
38
+ const extraImports = variant.variants
39
+ .flatMap((t) => t.getRequiredImports('kotlin'))
40
+ .map((i) => `import ${i.name}`);
41
+ const code = `
42
+ ${createFileMetadataString(`${kotlinName}.kt`)}
43
+
44
+ package ${packageName}
45
+
46
+ import com.facebook.proguard.annotations.DoNotStrip
47
+ ${extraImports.join('\n')}
48
+
49
+ /**
50
+ * Represents the TypeScript variant "${jsName}".
51
+ */
52
+ @Suppress("ClassName")
53
+ @DoNotStrip
54
+ sealed class ${kotlinName} {
55
+ ${indent(innerClasses.join('\n'), ' ')}
56
+
57
+ inline fun <reified T> getAs(): T? = when (this) {
58
+ ${indent(getterCases.join('\n'), ' ')}
59
+ }
60
+
61
+ ${indent(isFunctions.join('\n'), ' ')}
62
+
63
+ companion object {
64
+ ${indent(createFunctions.join('\n'), ' ')}
65
+ }
66
+ }
67
+ `.trim();
68
+ const cxxNamespace = NitroConfig.current.getCxxNamespace('c++');
69
+ const jniClassDescriptor = NitroConfig.current.getAndroidPackage('c++/jni', kotlinName);
70
+ const cppCreateFuncs = variant.variants.map((v, i) => {
71
+ const bridge = new KotlinCxxBridgedType(v);
72
+ return `
73
+ static jni::local_ref<J${kotlinName}> create_${i}(${bridge.asJniReferenceType('alias')} value) {
74
+ static const auto method = javaClassStatic()->getStaticMethod<J${kotlinName}(${bridge.asJniReferenceType('alias')})>("create");
75
+ return method(javaClassStatic(), value);
76
+ }
77
+ `.trim();
78
+ });
79
+ const variantCases = variant.variants.map((v, i) => {
80
+ const bridge = new KotlinCxxBridgedType(v);
81
+ return `case ${i}: return create_${i}(${bridge.parseFromCppToKotlin(`std::get<${i}>(variant)`, 'c++')});`;
82
+ });
83
+ const cppGetIfs = variant.cases.map(([label, v]) => {
84
+ const innerName = capitalizeName(label);
85
+ const bridge = new KotlinCxxBridgedType(v);
86
+ return `
87
+ if (isInstanceOf(${namespace}::${innerName}::javaClassStatic())) {
88
+ // It's a \`${v.getCode('c++')}\`
89
+ auto jniValue = static_cast<const ${namespace}::${innerName}*>(this)->getValue();
90
+ return ${bridge.parseFromKotlinToCpp('jniValue', 'c++')};
91
+ }
92
+ `.trim();
93
+ });
94
+ const cppInnerClasses = variant.cases.map(([label, v]) => {
95
+ const bridge = new KotlinCxxBridgedType(v);
96
+ const innerName = capitalizeName(label);
97
+ const descriptor = NitroConfig.current.getAndroidPackage('c++/jni', `${kotlinName}$${innerName}`);
98
+ return `
99
+ class ${innerName}: public jni::JavaClass<${innerName}, J${kotlinName}> {
100
+ public:
101
+ static auto constexpr kJavaDescriptor = "L${descriptor};";
102
+
103
+ [[nodiscard]] ${bridge.asJniReferenceType('local')} getValue() const {
104
+ static const auto field = javaClassStatic()->getField<${bridge.getTypeCode('c++')}>("value");
105
+ return getFieldValue(field);
106
+ }
107
+ };
108
+ `.trim();
109
+ });
110
+ const includes = new KotlinCxxBridgedType(variant)
111
+ .getRequiredImports('c++')
112
+ .filter((i) => i.name !== `J${kotlinName}.hpp`)
113
+ .map((i) => includeHeader(i, true))
114
+ .filter(isNotDuplicate);
115
+ const fbjniHeaderCode = `
116
+ ${createFileMetadataString(`J${kotlinName}.hpp`)}
117
+
118
+ #pragma once
119
+
120
+ #include <fbjni/fbjni.h>
121
+ #include <variant>
122
+
123
+ ${includes.join('\n')}
124
+
125
+ namespace ${cxxNamespace} {
126
+
127
+ using namespace facebook;
128
+
129
+ /**
130
+ * The C++ JNI bridge between the C++ std::variant and the Java class "${kotlinName}".
131
+ */
132
+ class J${kotlinName}: public jni::JavaClass<J${kotlinName}> {
133
+ public:
134
+ static auto constexpr kJavaDescriptor = "L${jniClassDescriptor};";
135
+
136
+ ${indent(cppCreateFuncs.join('\n'), ' ')}
137
+
138
+ static jni::local_ref<J${kotlinName}> fromCpp(${toReferenceType(variant.getCode('c++'))} variant) {
139
+ switch (variant.index()) {
140
+ ${indent(variantCases.join('\n'), ' ')}
141
+ default: throw std::invalid_argument("Variant holds unknown index! (" + std::to_string(variant.index()) + ")");
142
+ }
143
+ }
144
+
145
+ [[nodiscard]] ${variant.getCode('c++')} toCpp() const;
146
+ };
147
+
148
+ namespace ${namespace} {
149
+ ${indent(cppInnerClasses.join('\n\n'), ' ')}
150
+ } // namespace ${namespace}
151
+ } // namespace ${cxxNamespace}
152
+ `.trim();
153
+ const fbjniImplementationCode = `
154
+ ${createFileMetadataString(`J${kotlinName}.cpp`)}
155
+
156
+ #include "J${kotlinName}.hpp"
157
+
158
+ namespace ${cxxNamespace} {
159
+ /**
160
+ * Converts J${kotlinName} to ${variant.getCode('c++')}
161
+ */
162
+ ${variant.getCode('c++')} J${kotlinName}::toCpp() const {
163
+ ${indent(cppGetIfs.join(' else '), ' ')}
164
+ throw std::invalid_argument("Variant is unknown Kotlin instance!");
165
+ }
166
+ } // namespace ${cxxNamespace}
167
+ `.trim();
168
+ const files = [];
169
+ files.push({
170
+ content: code,
171
+ language: 'kotlin',
172
+ name: `${kotlinName}.kt`,
173
+ subdirectory: NitroConfig.current.getAndroidPackageDirectory(),
174
+ platform: 'android',
175
+ });
176
+ files.push({
177
+ content: fbjniHeaderCode,
178
+ language: 'c++',
179
+ name: `J${kotlinName}.hpp`,
180
+ subdirectory: [],
181
+ platform: 'android',
182
+ });
183
+ files.push({
184
+ content: fbjniImplementationCode,
185
+ language: 'c++',
186
+ name: `J${kotlinName}.cpp`,
187
+ subdirectory: [],
188
+ platform: 'android',
189
+ });
190
+ return files;
191
+ }