nitrogen 0.31.10 → 0.32.0

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 (104) hide show
  1. package/lib/autolinking/ios/createPodspecRubyExtension.js +1 -1
  2. package/lib/index.js +1 -1
  3. package/lib/syntax/c++/CppStruct.js +20 -4
  4. package/lib/syntax/createType.js +1 -1
  5. package/lib/syntax/getHybridObjectName.d.ts +1 -1
  6. package/lib/syntax/kotlin/KotlinCxxBridgedType.js +19 -13
  7. package/lib/syntax/kotlin/KotlinEnum.js +3 -6
  8. package/lib/syntax/kotlin/KotlinStruct.js +1 -1
  9. package/lib/syntax/kotlin/KotlinVariant.js +1 -1
  10. package/lib/syntax/swift/SwiftCxxTypeHelper.js +1 -1
  11. package/lib/syntax/swift/SwiftStruct.js +2 -8
  12. package/lib/syntax/types/AnyHybridObjectType.d.ts +1 -0
  13. package/lib/syntax/types/AnyHybridObjectType.js +3 -0
  14. package/lib/syntax/types/ArrayBufferType.d.ts +1 -0
  15. package/lib/syntax/types/ArrayBufferType.js +3 -0
  16. package/lib/syntax/types/ArrayType.d.ts +1 -0
  17. package/lib/syntax/types/ArrayType.js +3 -0
  18. package/lib/syntax/types/BigIntType.d.ts +1 -0
  19. package/lib/syntax/types/BigIntType.js +3 -0
  20. package/lib/syntax/types/BooleanType.d.ts +1 -0
  21. package/lib/syntax/types/BooleanType.js +3 -0
  22. package/lib/syntax/types/CustomType.d.ts +1 -0
  23. package/lib/syntax/types/CustomType.js +3 -0
  24. package/lib/syntax/types/DateType.d.ts +1 -0
  25. package/lib/syntax/types/DateType.js +3 -0
  26. package/lib/syntax/types/EnumType.d.ts +1 -0
  27. package/lib/syntax/types/EnumType.js +3 -0
  28. package/lib/syntax/types/ErrorType.d.ts +1 -0
  29. package/lib/syntax/types/ErrorType.js +4 -1
  30. package/lib/syntax/types/FunctionType.d.ts +1 -0
  31. package/lib/syntax/types/FunctionType.js +3 -0
  32. package/lib/syntax/types/HybridObjectType.d.ts +1 -0
  33. package/lib/syntax/types/HybridObjectType.js +3 -0
  34. package/lib/syntax/types/MapType.d.ts +1 -0
  35. package/lib/syntax/types/MapType.js +3 -0
  36. package/lib/syntax/types/NamedWrappingType.d.ts +1 -0
  37. package/lib/syntax/types/NamedWrappingType.js +3 -0
  38. package/lib/syntax/types/NullType.d.ts +1 -0
  39. package/lib/syntax/types/NullType.js +3 -0
  40. package/lib/syntax/types/NumberType.d.ts +1 -0
  41. package/lib/syntax/types/NumberType.js +3 -0
  42. package/lib/syntax/types/OptionalType.d.ts +1 -0
  43. package/lib/syntax/types/OptionalType.js +3 -0
  44. package/lib/syntax/types/PromiseType.d.ts +1 -0
  45. package/lib/syntax/types/PromiseType.js +3 -0
  46. package/lib/syntax/types/RecordType.d.ts +1 -0
  47. package/lib/syntax/types/RecordType.js +3 -0
  48. package/lib/syntax/types/ResultWrappingType.d.ts +1 -0
  49. package/lib/syntax/types/ResultWrappingType.js +3 -0
  50. package/lib/syntax/types/StringType.d.ts +1 -0
  51. package/lib/syntax/types/StringType.js +3 -0
  52. package/lib/syntax/types/StructType.d.ts +1 -0
  53. package/lib/syntax/types/StructType.js +3 -0
  54. package/lib/syntax/types/TupleType.d.ts +1 -0
  55. package/lib/syntax/types/TupleType.js +3 -0
  56. package/lib/syntax/types/Type.d.ts +4 -0
  57. package/lib/syntax/types/VariantType.d.ts +1 -0
  58. package/lib/syntax/types/VariantType.js +3 -0
  59. package/lib/syntax/types/VoidType.d.ts +1 -0
  60. package/lib/syntax/types/VoidType.js +3 -0
  61. package/lib/views/CppHybridViewComponent.js +2 -1
  62. package/lib/writeFile.d.ts +1 -1
  63. package/lib/writeFile.js +1 -1
  64. package/package.json +2 -3
  65. package/src/autolinking/ios/createPodspecRubyExtension.ts +1 -1
  66. package/src/index.ts +1 -1
  67. package/src/syntax/c++/CppStruct.ts +20 -4
  68. package/src/syntax/createType.ts +1 -1
  69. package/src/syntax/getHybridObjectName.ts +1 -1
  70. package/src/syntax/kotlin/KotlinCxxBridgedType.ts +29 -13
  71. package/src/syntax/kotlin/KotlinEnum.ts +3 -7
  72. package/src/syntax/kotlin/KotlinStruct.ts +1 -1
  73. package/src/syntax/kotlin/KotlinVariant.ts +1 -1
  74. package/src/syntax/swift/SwiftCxxTypeHelper.ts +1 -1
  75. package/src/syntax/swift/SwiftStruct.ts +2 -8
  76. package/src/syntax/types/AnyHybridObjectType.ts +3 -0
  77. package/src/syntax/types/ArrayBufferType.ts +3 -0
  78. package/src/syntax/types/ArrayType.ts +3 -0
  79. package/src/syntax/types/BigIntType.ts +3 -0
  80. package/src/syntax/types/BooleanType.ts +3 -0
  81. package/src/syntax/types/CustomType.ts +3 -0
  82. package/src/syntax/types/DateType.ts +3 -0
  83. package/src/syntax/types/EnumType.ts +3 -0
  84. package/src/syntax/types/ErrorType.ts +4 -1
  85. package/src/syntax/types/FunctionType.ts +3 -0
  86. package/src/syntax/types/HybridObjectType.ts +3 -0
  87. package/src/syntax/types/MapType.ts +3 -0
  88. package/src/syntax/types/NamedWrappingType.ts +3 -0
  89. package/src/syntax/types/NullType.ts +3 -0
  90. package/src/syntax/types/NumberType.ts +3 -0
  91. package/src/syntax/types/OptionalType.ts +3 -0
  92. package/src/syntax/types/PromiseType.ts +3 -0
  93. package/src/syntax/types/RecordType.ts +3 -0
  94. package/src/syntax/types/ResultWrappingType.ts +3 -0
  95. package/src/syntax/types/StringType.ts +3 -0
  96. package/src/syntax/types/StructType.ts +3 -0
  97. package/src/syntax/types/TupleType.ts +3 -0
  98. package/src/syntax/types/Type.ts +4 -0
  99. package/src/syntax/types/VariantType.ts +3 -0
  100. package/src/syntax/types/VoidType.ts +3 -0
  101. package/src/views/CppHybridViewComponent.ts +2 -1
  102. package/src/writeFile.ts +1 -1
  103. package/lib/syntax/types/UndefinedType.d.ts +0 -10
  104. package/lib/syntax/types/UndefinedType.js +0 -23
@@ -4,6 +4,7 @@ import type { Type, TypeKind } from './Type.js';
4
4
  export declare class StringType implements Type {
5
5
  get canBePassedByReference(): boolean;
6
6
  get kind(): TypeKind;
7
+ get isEquatable(): boolean;
7
8
  getCode(language: Language): string;
8
9
  getExtraFiles(): SourceFile[];
9
10
  getRequiredImports(language: Language): SourceImport[];
@@ -6,6 +6,9 @@ export class StringType {
6
6
  get kind() {
7
7
  return 'string';
8
8
  }
9
+ get isEquatable() {
10
+ return true;
11
+ }
9
12
  getCode(language) {
10
13
  switch (language) {
11
14
  case 'c++':
@@ -8,6 +8,7 @@ export declare class StructType implements Type {
8
8
  constructor(structName: string, properties: NamedType[]);
9
9
  get canBePassedByReference(): boolean;
10
10
  get kind(): TypeKind;
11
+ get isEquatable(): boolean;
11
12
  getCode(language: Language, { fullyQualified }?: GetCodeOptions): string;
12
13
  getExtraFiles(): SourceFile[];
13
14
  getRequiredImports(language: Language): SourceImport[];
@@ -24,6 +24,9 @@ export class StructType {
24
24
  get kind() {
25
25
  return 'struct';
26
26
  }
27
+ get isEquatable() {
28
+ return this.properties.every((p) => p.isEquatable);
29
+ }
27
30
  getCode(language, { fullyQualified } = {}) {
28
31
  switch (language) {
29
32
  case 'c++':
@@ -6,6 +6,7 @@ export declare class TupleType implements Type {
6
6
  constructor(itemTypes: Type[]);
7
7
  get canBePassedByReference(): boolean;
8
8
  get kind(): TypeKind;
9
+ get isEquatable(): boolean;
9
10
  getCode(language: Language, options?: GetCodeOptions): string;
10
11
  getExtraFiles(): SourceFile[];
11
12
  getRequiredImports(language: Language): SourceImport[];
@@ -11,6 +11,9 @@ export class TupleType {
11
11
  get kind() {
12
12
  return 'tuple';
13
13
  }
14
+ get isEquatable() {
15
+ return this.itemTypes.every((t) => t.isEquatable);
16
+ }
14
17
  getCode(language, options) {
15
18
  const types = this.itemTypes.map((t) => t.getCode(language, options));
16
19
  switch (language) {
@@ -20,6 +20,10 @@ export interface Type {
20
20
  * Get the kind of the type.
21
21
  */
22
22
  readonly kind: TypeKind;
23
+ /**
24
+ * `true` if the type is equatable.
25
+ */
26
+ readonly isEquatable: boolean;
23
27
  /**
24
28
  * Get the native code required to represent this type for the given language (C++, Swift, Kotlin).
25
29
  *
@@ -9,6 +9,7 @@ export declare class VariantType implements Type {
9
9
  constructor(variants: Type[], aliasName?: string);
10
10
  get canBePassedByReference(): boolean;
11
11
  get kind(): TypeKind;
12
+ get isEquatable(): boolean;
12
13
  get jsType(): string;
13
14
  get cases(): [VariantLabel, Type][];
14
15
  getAliasName(language: Language, options?: GetCodeOptions): string;
@@ -26,6 +26,9 @@ export class VariantType {
26
26
  get kind() {
27
27
  return 'variant';
28
28
  }
29
+ get isEquatable() {
30
+ return this.variants.every((v) => v.isEquatable);
31
+ }
29
32
  get jsType() {
30
33
  return this.variants.map((v) => v.kind).join(' | ');
31
34
  }
@@ -4,6 +4,7 @@ import type { Type, TypeKind } from './Type.js';
4
4
  export declare class VoidType implements Type {
5
5
  get canBePassedByReference(): boolean;
6
6
  get kind(): TypeKind;
7
+ get isEquatable(): boolean;
7
8
  getCode(language: Language): string;
8
9
  getExtraFiles(): SourceFile[];
9
10
  getRequiredImports(): SourceImport[];
@@ -6,6 +6,9 @@ export class VoidType {
6
6
  get kind() {
7
7
  return 'void';
8
8
  }
9
+ get isEquatable() {
10
+ return true;
11
+ }
9
12
  getCode(language) {
10
13
  switch (language) {
11
14
  case 'c++':
@@ -156,7 +156,7 @@ namespace ${namespace} {
156
156
  // Due to a React limitation, functions cannot be passed to native directly,
157
157
  // because RN converts them to booleans (`true`). Nitro knows this and just
158
158
  // wraps functions as objects - the original function is stored in `f`.
159
- valueConversion = `value.asObject(*runtime).getProperty(*runtime, "f")`;
159
+ valueConversion = `value.asObject(*runtime).getProperty(*runtime, PropNameIDCache::get(*runtime, "f"))`;
160
160
  }
161
161
  propInitializers.push(`
162
162
  ${name}([&]() -> CachedProp<${type}> {
@@ -183,6 +183,7 @@ ${createFileMetadataString(`${component}.cpp`)}
183
183
  #include <utility>
184
184
  #include <NitroModules/NitroDefines.hpp>
185
185
  #include <NitroModules/JSIConverter.hpp>
186
+ #include <NitroModules/PropNameIDCache.hpp>
186
187
  #include <react/renderer/core/RawValue.h>
187
188
  #include <react/renderer/core/ShadowNode.h>
188
189
  #include <react/renderer/core/ComponentDescriptor.h>
@@ -1,5 +1,5 @@
1
1
  import type { SourceFile } from './syntax/SourceFile.js';
2
2
  /**
3
- * Writes the given file to disk and returns it's actual path.
3
+ * Writes the given file to disk and returns its actual path.
4
4
  */
5
5
  export declare function writeFile(basePath: string, file: SourceFile): Promise<string>;
package/lib/writeFile.js CHANGED
@@ -4,7 +4,7 @@ import { capitalizeName } from './utils.js';
4
4
  import chalk from 'chalk';
5
5
  import { Logger } from './Logger.js';
6
6
  /**
7
- * Writes the given file to disk and returns it's actual path.
7
+ * Writes the given file to disk and returns its actual path.
8
8
  */
9
9
  export async function writeFile(basePath, file) {
10
10
  const filepath = path.join(basePath, ...file.subdirectory, file.name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nitrogen",
3
- "version": "0.31.10",
3
+ "version": "0.32.0",
4
4
  "description": "The code-generator for react-native-nitro-modules.",
5
5
  "main": "lib/index",
6
6
  "types": "lib/index.d.ts",
@@ -26,7 +26,6 @@
26
26
  "registry": "https://registry.npmjs.org/"
27
27
  },
28
28
  "scripts": {
29
- "postinstall": "bun build || exit 0;",
30
29
  "build": "bun tsc",
31
30
  "start": "tsc && node lib/index.js",
32
31
  "typecheck": "tsc --noEmit",
@@ -36,7 +35,7 @@
36
35
  },
37
36
  "dependencies": {
38
37
  "chalk": "^5.3.0",
39
- "react-native-nitro-modules": "^0.31.10",
38
+ "react-native-nitro-modules": "^0.32.0",
40
39
  "ts-morph": "^27.0.0",
41
40
  "yargs": "^18.0.0",
42
41
  "zod": "^4.0.5"
@@ -59,7 +59,7 @@ def add_nitrogen_files(spec)
59
59
  spec.pod_target_xcconfig = current_pod_target_xcconfig.merge({
60
60
  # Use C++ 20
61
61
  "CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
62
- # Enables C++ <-> Swift interop (by default it's only C)
62
+ # Enables C++ <-> Swift interop (by default it's only ObjC)
63
63
  "SWIFT_OBJC_INTEROP_MODE" => "objcxx",
64
64
  # Enables stricter modular headers
65
65
  "DEFINES_MODULE" => "YES",
package/src/index.ts CHANGED
@@ -85,7 +85,7 @@ await yargs(hideBin(process.argv))
85
85
  `Usage: ${chalk.bold('$0 [options]')}\n` +
86
86
  `$0 is a code-generater for Nitro Modules (${chalk.underline('https://github.com/mrousavy/nitro')})\n` +
87
87
  `It converts all TypeScript specs found in ${chalk.underline('**/*.nitro.ts')} to C++, Swift or Kotlin specs.\n` +
88
- `Each library/module must have a ${chalk.underline('nitro.json')} configuration file in it's root directory.\n` +
88
+ `Each library/module must have a ${chalk.underline('nitro.json')} configuration file in its root directory.\n` +
89
89
  `$Nitrogen Version: ${chalk.bold(NITROGEN_VERSION)}`
90
90
  )
91
91
  .help()
@@ -33,24 +33,36 @@ export function createCppStruct(
33
33
  const cppFromJsiParams = properties
34
34
  .map(
35
35
  (p) =>
36
- `JSIConverter<${p.getCode('c++', codeOptions)}>::fromJSI(runtime, obj.getProperty(runtime, "${p.name}"))`
36
+ `JSIConverter<${p.getCode('c++', codeOptions)}>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "${p.name}")))`
37
37
  )
38
38
  .join(',\n')
39
39
  // Get C++ code for converting each member to a jsi::Value
40
40
  const cppToJsiCalls = properties
41
41
  .map(
42
42
  (p) =>
43
- `obj.setProperty(runtime, "${p.name}", JSIConverter<${p.getCode('c++', codeOptions)}>::toJSI(runtime, arg.${p.escapedName}));`
43
+ `obj.setProperty(runtime, PropNameIDCache::get(runtime, "${p.name}"), JSIConverter<${p.getCode('c++', codeOptions)}>::toJSI(runtime, arg.${p.escapedName}));`
44
44
  )
45
45
  .join('\n')
46
46
  // Get C++ code for verifying if jsi::Value can be converted to type
47
47
  const cppCanConvertCalls = properties
48
48
  .map(
49
49
  (p) =>
50
- `if (!JSIConverter<${p.getCode('c++', codeOptions)}>::canConvert(runtime, obj.getProperty(runtime, "${p.name}"))) return false;`
50
+ `if (!JSIConverter<${p.getCode('c++', codeOptions)}>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "${p.name}")))) return false;`
51
51
  )
52
52
  .join('\n')
53
53
 
54
+ // Only equatable types have an operator== overload
55
+ let equatableFunc: string
56
+ const isEquatable = properties.every((p) => p.isEquatable)
57
+ if (isEquatable) {
58
+ equatableFunc = `friend bool operator==(const ${typename}& lhs, const ${typename}& rhs) = default;`
59
+ } else {
60
+ const nonEquatableTypes = properties
61
+ .filter((p) => !p.isEquatable)
62
+ .map((p) => p.name)
63
+ equatableFunc = `// ${typename} is not equatable because these properties are not equatable: ${nonEquatableTypes.join(', ')}`
64
+ }
65
+
54
66
  // Get C++ includes for each extra-file we need to include
55
67
  const includedTypes = properties.flatMap((r) => r.getRequiredImports('c++'))
56
68
  const cppForwardDeclarations = includedTypes
@@ -70,6 +82,7 @@ ${createFileMetadataString(`${typename}.hpp`)}
70
82
  ${includeNitroHeader('JSIConverter.hpp')}
71
83
  ${includeNitroHeader('NitroDefines.hpp')}
72
84
  ${includeNitroHeader('JSIHelpers.hpp')}
85
+ ${includeNitroHeader('PropNameIDCache.hpp')}
73
86
 
74
87
  ${cppForwardDeclarations.join('\n')}
75
88
 
@@ -80,13 +93,16 @@ namespace ${cxxNamespace} {
80
93
  /**
81
94
  * A struct which can be represented as a JavaScript object (${typename}).
82
95
  */
83
- struct ${typename} {
96
+ struct ${typename} final {
84
97
  public:
85
98
  ${indent(cppStructProps, ' ')}
86
99
 
87
100
  public:
88
101
  ${typename}() = default;
89
102
  explicit ${typename}(${cppConstructorParams}): ${cppInitializerParams} {}
103
+
104
+ public:
105
+ ${indent(equatableFunc, ' ')}
90
106
  };
91
107
 
92
108
  } // namespace ${cxxNamespace}
@@ -359,7 +359,7 @@ export function createType(
359
359
  } else if (type.isUndefined()) {
360
360
  throw new Error(
361
361
  `The TypeScript type "undefined" cannot be represented in Nitro.\n` +
362
- `- If you want to make a type optional, add \`?\` to it's name, or make it an union with \`undefined\`.\n` +
362
+ `- If you want to make a type optional, add \`?\` to its name, or make it an union with \`undefined\`.\n` +
363
363
  `- If you want a method that returns nothing, use \`void\` instead.\n` +
364
364
  `- If you want to represent an explicit absence of a value, use \`null\` instead.`
365
365
  )
@@ -11,7 +11,7 @@ export interface HybridObjectName {
11
11
  HybridT: string
12
12
  /**
13
13
  * The name of the C++ class, Kotlin interface or Swift protocol that represents the
14
- * specification (all of it's virtual properties and methods) of the Hybrid Object.
14
+ * specification (all of its virtual properties and methods) of the Hybrid Object.
15
15
  * @example "HybridImageSpec"
16
16
  */
17
17
  HybridTSpec: string
@@ -111,11 +111,6 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
111
111
  name: 'NitroModules/JArrayBuffer.hpp',
112
112
  space: 'system',
113
113
  })
114
- imports.push({
115
- language: 'c++',
116
- name: 'NitroModules/JUnit.hpp',
117
- space: 'system',
118
- })
119
114
  break
120
115
  case 'promise':
121
116
  imports.push({
@@ -123,6 +118,15 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
123
118
  name: 'NitroModules/JPromise.hpp',
124
119
  space: 'system',
125
120
  })
121
+ const promiseType = getTypeAs(this.type, PromiseType)
122
+ if (promiseType.resultingType.kind === 'void') {
123
+ // Promise<void> uses JUnit
124
+ imports.push({
125
+ language: 'c++',
126
+ name: 'NitroModules/JUnit.hpp',
127
+ space: 'system',
128
+ })
129
+ }
126
130
  break
127
131
  case 'date':
128
132
  imports.push({
@@ -293,10 +297,10 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
293
297
  const recordType = getTypeAs(this.type, RecordType)
294
298
  const keyType = new KotlinCxxBridgedType(
295
299
  recordType.keyType
296
- ).getTypeCode(language)
300
+ ).getTypeCode(language, true)
297
301
  const valueType = new KotlinCxxBridgedType(
298
302
  recordType.valueType
299
- ).getTypeCode(language)
303
+ ).getTypeCode(language, true)
300
304
  return `jni::JMap<${keyType}, ${valueType}>`
301
305
  default:
302
306
  return this.type.getCode(language)
@@ -583,13 +587,20 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
583
587
  const record = getTypeAs(this.type, RecordType)
584
588
  const key = new KotlinCxxBridgedType(record.keyType)
585
589
  const value = new KotlinCxxBridgedType(record.valueType)
586
- const parseKey = key.parseFromCppToKotlin('__entry.first', 'c++')
590
+ const parseKey = key.parseFromCppToKotlin(
591
+ '__entry.first',
592
+ 'c++',
593
+ true
594
+ )
587
595
  const parseValue = value.parseFromCppToKotlin(
588
596
  '__entry.second',
589
- 'c++'
597
+ 'c++',
598
+ true
590
599
  )
591
- const javaMapType = `jni::JMap<${key.getTypeCode('c++')}, ${value.getTypeCode('c++')}>`
592
- const javaHashMapType = `jni::JHashMap<${key.getTypeCode('c++')}, ${value.getTypeCode('c++')}>`
600
+ const keyType = key.getTypeCode('c++', true)
601
+ const valueType = value.getTypeCode('c++', true)
602
+ const javaMapType = `jni::JMap<${keyType}, ${valueType}>`
603
+ const javaHashMapType = `jni::JHashMap<${keyType}, ${valueType}>`
593
604
  return `
594
605
  [&]() -> jni::local_ref<${javaMapType}> {
595
606
  auto __map = ${javaHashMapType}::create(${parameterName}.size());
@@ -862,10 +873,15 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
862
873
  const record = getTypeAs(this.type, RecordType)
863
874
  const key = new KotlinCxxBridgedType(record.keyType)
864
875
  const value = new KotlinCxxBridgedType(record.valueType)
865
- const parseKey = key.parseFromKotlinToCpp('__entry.first', 'c++')
876
+ const parseKey = key.parseFromKotlinToCpp(
877
+ '__entry.first',
878
+ 'c++',
879
+ true
880
+ )
866
881
  const parseValue = value.parseFromKotlinToCpp(
867
882
  '__entry.second',
868
- 'c++'
883
+ 'c++',
884
+ true
869
885
  )
870
886
  const cxxType = this.type.getCode('c++')
871
887
  return `
@@ -24,6 +24,8 @@ import com.facebook.proguard.annotations.DoNotStrip
24
24
  @Keep
25
25
  enum class ${enumType.enumName}(@DoNotStrip @Keep val value: Int) {
26
26
  ${indent(members.join(',\n'), ' ')};
27
+
28
+ companion object
27
29
  }
28
30
  `.trim()
29
31
 
@@ -103,23 +105,17 @@ function getCppToJniConverterCode(
103
105
  ): string {
104
106
  const jniEnumName = `J${enumType.enumName}`
105
107
 
106
- const fields = enumType.enumMembers.map((m) => {
107
- const fieldName = `field${capitalizeName(m.name)}`
108
- return `static const auto ${fieldName} = clazz->getStaticField<${jniEnumName}>("${m.name}");`
109
- })
110
-
111
108
  const cases = enumType.enumMembers.map((m) => {
112
109
  const fieldName = `field${capitalizeName(m.name)}`
113
110
  return `
114
111
  case ${enumType.enumName}::${m.name}:
112
+ static const auto ${fieldName} = clazz->getStaticField<${jniEnumName}>("${m.name}");
115
113
  return clazz->getStaticFieldValue(${fieldName});
116
114
  `.trim()
117
115
  })
118
116
 
119
117
  return `
120
118
  static const auto clazz = javaClassStatic();
121
- ${fields.join('\n')}
122
-
123
119
  switch (${cppValueName}) {
124
120
  ${indent(cases.join('\n'), ' ')}
125
121
  default:
@@ -64,7 +64,7 @@ data class ${structType.structName}(
64
64
  ) {
65
65
  ${indent(secondaryConstructor, ' ')}
66
66
 
67
- private companion object {
67
+ companion object {
68
68
  /**
69
69
  * Constructor called from C++
70
70
  */
@@ -152,7 +152,7 @@ if (isInstanceOf(${namespace}::${innerName}::javaClassStatic())) {
152
152
  `${kotlinName}$${innerName}`
153
153
  )
154
154
  return `
155
- class ${innerName}: public jni::JavaClass<${innerName}, J${kotlinName}> {
155
+ class ${innerName} final: public jni::JavaClass<${innerName}, J${kotlinName}> {
156
156
  public:
157
157
  static auto constexpr kJavaDescriptor = "L${descriptor};";
158
158
 
@@ -509,7 +509,7 @@ inline ${t.getCode('c++')} get_${i}() const noexcept {
509
509
  * std::variant cannot be used in Swift because of a Swift bug.
510
510
  * Not even specializing it works. So we create a wrapper struct.
511
511
  */
512
- struct ${name} {
512
+ struct ${name} final {
513
513
  ${actualType} variant;
514
514
  ${name}(${actualType} variant): variant(variant) { }
515
515
  operator ${actualType}() const noexcept {
@@ -20,15 +20,9 @@ export function createSwiftStructBridge(
20
20
  const bridge = new SwiftCxxBridgedType(p, true)
21
21
  const cppName = `self.__${p.escapedName}`
22
22
  return `
23
+ @inline(__always)
23
24
  var ${p.escapedName}: ${p.getCode('swift')} {
24
- @inline(__always)
25
- get {
26
- return ${indent(bridge.parseFromCppToSwift(cppName, 'swift'), ' ')}
27
- }
28
- @inline(__always)
29
- set {
30
- ${cppName} = ${indent(bridge.parseFromSwiftToCpp('newValue', 'swift'), ' ')}
31
- }
25
+ return ${indent(bridge.parseFromCppToSwift(cppName, 'swift'), ' ')}
32
26
  }
33
27
  `.trim()
34
28
  })
@@ -14,6 +14,9 @@ export class AnyHybridObjectType implements Type {
14
14
  get kind(): TypeKind {
15
15
  return 'hybrid-object-base'
16
16
  }
17
+ get isEquatable(): boolean {
18
+ return true
19
+ }
17
20
 
18
21
  getCode(language: Language): string {
19
22
  switch (language) {
@@ -11,6 +11,9 @@ export class ArrayBufferType implements Type {
11
11
  get kind(): TypeKind {
12
12
  return 'array-buffer'
13
13
  }
14
+ get isEquatable(): boolean {
15
+ return true
16
+ }
14
17
 
15
18
  getCode(language: Language): string {
16
19
  switch (language) {
@@ -17,6 +17,9 @@ export class ArrayType implements Type {
17
17
  get kind(): TypeKind {
18
18
  return 'array'
19
19
  }
20
+ get isEquatable(): boolean {
21
+ return this.itemType.isEquatable
22
+ }
20
23
 
21
24
  getCode(language: Language, options?: GetCodeOptions): string {
22
25
  const itemCode = this.itemType.getCode(language, options)
@@ -11,6 +11,9 @@ export class BigIntType implements Type {
11
11
  get kind(): TypeKind {
12
12
  return 'bigint'
13
13
  }
14
+ get isEquatable(): boolean {
15
+ return true
16
+ }
14
17
 
15
18
  getCode(language: Language): string {
16
19
  switch (language) {
@@ -11,6 +11,9 @@ export class BooleanType implements Type {
11
11
  get kind(): TypeKind {
12
12
  return 'boolean'
13
13
  }
14
+ get isEquatable(): boolean {
15
+ return true
16
+ }
14
17
 
15
18
  getCode(language: Language): string {
16
19
  switch (language) {
@@ -19,6 +19,9 @@ export class CustomType implements Type {
19
19
  get kind(): TypeKind {
20
20
  return 'custom-type'
21
21
  }
22
+ get isEquatable(): boolean {
23
+ return false
24
+ }
22
25
 
23
26
  getCode(language: Language): string {
24
27
  switch (language) {
@@ -11,6 +11,9 @@ export class DateType implements Type {
11
11
  get kind(): TypeKind {
12
12
  return 'date'
13
13
  }
14
+ get isEquatable(): boolean {
15
+ return true
16
+ }
14
17
 
15
18
  getCode(language: Language): string {
16
19
  switch (language) {
@@ -88,6 +88,9 @@ export class EnumType implements Type {
88
88
  get kind(): TypeKind {
89
89
  return 'enum'
90
90
  }
91
+ get isEquatable(): boolean {
92
+ return true
93
+ }
91
94
 
92
95
  getCode(language: Language, { fullyQualified }: GetCodeOptions = {}): string {
93
96
  switch (language) {
@@ -6,12 +6,15 @@ export class ErrorType implements Type {
6
6
  constructor() {}
7
7
 
8
8
  get canBePassedByReference(): boolean {
9
- // It's a exception<..>, pass by reference.
9
+ // It's an exception<..>, pass by reference.
10
10
  return true
11
11
  }
12
12
  get kind(): TypeKind {
13
13
  return 'error'
14
14
  }
15
+ get isEquatable(): boolean {
16
+ return true
17
+ }
15
18
 
16
19
  getCode(language: Language): string {
17
20
  switch (language) {
@@ -56,6 +56,9 @@ export class FunctionType implements Type {
56
56
  get kind(): TypeKind {
57
57
  return 'function'
58
58
  }
59
+ get isEquatable(): boolean {
60
+ return false
61
+ }
59
62
 
60
63
  /**
61
64
  * For a function, get the forward recreation of it:
@@ -69,6 +69,9 @@ export class HybridObjectType implements Type {
69
69
  get kind(): TypeKind {
70
70
  return 'hybrid-object'
71
71
  }
72
+ get isEquatable(): boolean {
73
+ return true
74
+ }
72
75
 
73
76
  getCode(
74
77
  language: Language,
@@ -11,6 +11,9 @@ export class MapType implements Type {
11
11
  get kind(): TypeKind {
12
12
  return 'map'
13
13
  }
14
+ get isEquatable(): boolean {
15
+ return true
16
+ }
14
17
 
15
18
  getCode(language: Language): string {
16
19
  switch (language) {
@@ -18,6 +18,9 @@ export class NamedWrappingType<T extends Type> implements NamedType {
18
18
  get kind(): TypeKind {
19
19
  return this.type.kind
20
20
  }
21
+ get isEquatable(): boolean {
22
+ return this.type.isEquatable
23
+ }
21
24
  get canBePassedByReference(): boolean {
22
25
  return this.type.canBePassedByReference
23
26
  }
@@ -10,6 +10,9 @@ export class NullType implements Type {
10
10
  get kind(): TypeKind {
11
11
  return 'null'
12
12
  }
13
+ get isEquatable(): boolean {
14
+ return true
15
+ }
13
16
 
14
17
  getCode(language: Language): string {
15
18
  switch (language) {
@@ -10,6 +10,9 @@ export class NumberType implements Type {
10
10
  get kind(): TypeKind {
11
11
  return 'number'
12
12
  }
13
+ get isEquatable(): boolean {
14
+ return true
15
+ }
13
16
 
14
17
  getCode(language: Language): string {
15
18
  switch (language) {
@@ -16,6 +16,9 @@ export class OptionalType implements Type {
16
16
  get kind(): TypeKind {
17
17
  return 'optional'
18
18
  }
19
+ get isEquatable(): boolean {
20
+ return this.wrappingType.isEquatable
21
+ }
19
22
  get needsBraces(): boolean {
20
23
  switch (this.wrappingType.kind) {
21
24
  case 'function':
@@ -22,6 +22,9 @@ export class PromiseType implements Type {
22
22
  get kind(): TypeKind {
23
23
  return 'promise'
24
24
  }
25
+ get isEquatable(): boolean {
26
+ return false
27
+ }
25
28
 
26
29
  get resolverFunction(): FunctionType {
27
30
  if (this.resultingType.kind === 'void') {