nitrogen 0.30.0 → 0.30.1

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/lib/init.js CHANGED
@@ -41,7 +41,7 @@ async function isGitInstalled() {
41
41
  execSync('git --version');
42
42
  return true;
43
43
  }
44
- catch (error) {
44
+ catch {
45
45
  return false;
46
46
  }
47
47
  }
@@ -32,10 +32,6 @@ export class KotlinCxxBridgedType {
32
32
  case 'function':
33
33
  // Function needs to be converted from JFunc_... to Lambda
34
34
  return true;
35
- case 'struct':
36
- // Structs don't need special handling - they have direct mappings
37
- // Returning false prevents secondary constructor generation that causes duplicates
38
- return false;
39
35
  case 'optional':
40
36
  // Optionals need special handling if the wrapped type needs special handling
41
37
  const optional = getTypeAs(this.type, OptionalType);
@@ -44,16 +40,6 @@ export class KotlinCxxBridgedType {
44
40
  default:
45
41
  break;
46
42
  }
47
- // check if any types this type references (e.g. underlying optional, array element, ...)
48
- // needs special handling. if yes, we need it as well
49
- const referencedTypes = getReferencedTypes(this.type)
50
- .filter((t) => t !== this.type)
51
- .map((t) => new KotlinCxxBridgedType(t));
52
- for (const type of referencedTypes) {
53
- if (type.needsSpecialHandling) {
54
- return true;
55
- }
56
- }
57
43
  // no special handling needed
58
44
  return false;
59
45
  }
@@ -81,7 +81,7 @@ abstract class ${name.HybridTSpec}: ${kotlinBase}() {
81
81
  private external fun initHybrid(): HybridData
82
82
 
83
83
  companion object {
84
- private const val TAG = "${name.HybridTSpec}"
84
+ protected const val TAG = "${name.HybridTSpec}"
85
85
  }
86
86
  }
87
87
  `.trim();
@@ -6,44 +6,25 @@ import { createFileMetadataString, isNotDuplicate } from '../helpers.js';
6
6
  import { KotlinCxxBridgedType } from './KotlinCxxBridgedType.js';
7
7
  export function createKotlinStruct(structType) {
8
8
  const packageName = NitroConfig.current.getAndroidPackage('java/kotlin');
9
- const values = structType.properties.map((p) => {
10
- const bridged = new KotlinCxxBridgedType(p);
11
- return `
9
+ const parameters = structType.properties
10
+ .map((p) => `
12
11
  @DoNotStrip
13
12
  @Keep
14
- val ${p.escapedName}: ${bridged.getTypeCode('kotlin', false)}
15
- `.trim();
16
- });
17
- let secondaryConstructor;
18
- const needsSpecialHandling = structType.properties.some((p) => {
13
+ val ${p.escapedName}: ${p.getCode('kotlin')}
14
+ `.trim())
15
+ .join(',\n');
16
+ const cxxCreateFunctionParameters = structType.properties
17
+ .map((p) => {
19
18
  const bridged = new KotlinCxxBridgedType(p);
20
- const parseCode = bridged.parseFromKotlinToCpp(p.escapedName, 'kotlin', false);
21
- return parseCode !== p.escapedName;
22
- });
23
- if (needsSpecialHandling) {
24
- // If we need special handling for any of our properties, we need to add a convenience initializer.
25
- const params = structType.properties.map((p) => `${p.escapedName}: ${p.getCode('kotlin')}`);
26
- const paramsForward = structType.properties.map((p) => {
27
- const bridged = new KotlinCxxBridgedType(p);
28
- if (bridged.needsSpecialHandling) {
29
- // We need special parsing for this type
30
- return bridged.parseFromKotlinToCpp(p.escapedName, 'kotlin', false);
31
- }
32
- else {
33
- return p.escapedName;
34
- }
35
- });
36
- secondaryConstructor = `
37
- /**
38
- * Initialize a new instance of \`${structType.structName}\` from Kotlin.
39
- */
40
- constructor(${indent(params.join(', '), 12)})
41
- : this(${indent(paramsForward.join(', '), 12)})
42
- `.trim();
43
- }
44
- else {
45
- secondaryConstructor = `/* main constructor */`;
46
- }
19
+ return `${p.escapedName}: ${bridged.getTypeCode('kotlin', false)}`;
20
+ })
21
+ .join(', ');
22
+ const cxxCreateFunctionForward = structType.properties
23
+ .map((p) => {
24
+ const bridged = new KotlinCxxBridgedType(p);
25
+ return bridged.parseFromCppToKotlin(p.escapedName, 'kotlin', false);
26
+ })
27
+ .join(', ');
47
28
  const extraImports = structType.properties
48
29
  .flatMap((t) => t.getRequiredImports('kotlin'))
49
30
  .map((i) => `import ${i.name}`);
@@ -62,13 +43,21 @@ ${extraImports.join('\n')}
62
43
  */
63
44
  @DoNotStrip
64
45
  @Keep
65
- data class ${structType.structName}
66
- @DoNotStrip
67
- @Keep
68
- constructor(
69
- ${indent(values.join(',\n'), ' ')}
70
- ) {
71
- ${indent(secondaryConstructor, ' ')}
46
+ data class ${structType.structName}(
47
+ ${indent(parameters, ' ')}
48
+ ) {
49
+ private companion object {
50
+ /**
51
+ * Constructor called from C++
52
+ */
53
+ @DoNotStrip
54
+ @Keep
55
+ @Suppress("unused")
56
+ @JvmStatic
57
+ private fun fromCpp(${cxxCreateFunctionParameters}): ${structType.structName} {
58
+ return ${structType.structName}(${cxxCreateFunctionForward})
59
+ }
60
+ }
72
61
  }
73
62
  `.trim();
74
63
  const cxxNamespace = NitroConfig.current.getCxxNamespace('c++');
@@ -163,14 +152,26 @@ function createJNIStructInitializer(structType) {
163
152
  return lines.join('\n');
164
153
  }
165
154
  function createCppStructInitializer(cppValueName, structType) {
166
- const lines = [];
167
- lines.push(`return newInstance(`);
168
- const names = structType.properties.map((p) => {
155
+ const jniTypes = structType.properties
156
+ .map((p) => {
157
+ const bridge = new KotlinCxxBridgedType(p);
158
+ return bridge.asJniReferenceType('alias');
159
+ })
160
+ .join(', ');
161
+ const params = structType.properties
162
+ .map((p) => {
169
163
  const name = `${cppValueName}.${p.escapedName}`;
170
164
  const bridge = new KotlinCxxBridgedType(p);
171
165
  return bridge.parse(name, 'c++', 'kotlin', 'c++');
172
- });
173
- lines.push(` ${indent(names.join(',\n'), ' ')}`);
174
- lines.push(');');
175
- return lines.join('\n');
166
+ })
167
+ .join(',\n');
168
+ return `
169
+ using JSignature = J${structType.structName}(${jniTypes});
170
+ static const auto clazz = javaClassStatic();
171
+ static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
172
+ return create(
173
+ clazz,
174
+ ${indent(params, ' ')}
175
+ );
176
+ `.trim();
176
177
  }
@@ -2,17 +2,19 @@ import { NitroConfig } from '../../config/NitroConfig.js';
2
2
  import { capitalizeName, indent } from '../../utils.js';
3
3
  import { includeHeader } from '../c++/includeNitroHeader.js';
4
4
  import { createFileMetadataString, isNotDuplicate, toReferenceType, } from '../helpers.js';
5
+ import { OptionalType } from '../types/OptionalType.js';
5
6
  import {} from '../types/VariantType.js';
6
7
  import { KotlinCxxBridgedType } from './KotlinCxxBridgedType.js';
7
8
  export function createKotlinVariant(variant) {
8
- const jsName = variant.variants.map((v) => v.getCode('kotlin')).join('|');
9
+ const jsName = variant.variants.map((v) => v.getCode('kotlin')).join(' | ');
9
10
  const kotlinName = variant.getAliasName('kotlin');
10
11
  const namespace = `J${kotlinName}_impl`;
11
12
  const innerClasses = variant.cases.map(([label, v]) => {
12
13
  const innerName = capitalizeName(label);
14
+ const bridge = new KotlinCxxBridgedType(v);
13
15
  return `
14
16
  @DoNotStrip
15
- data class ${innerName}(@DoNotStrip val value: ${v.getCode('kotlin')}): ${kotlinName}()
17
+ data class ${innerName}(@DoNotStrip val value: ${bridge.getTypeCode('kotlin')}): ${kotlinName}()
16
18
  `.trim();
17
19
  });
18
20
  const packageName = NitroConfig.current.getAndroidPackage('java/kotlin');
@@ -25,15 +27,37 @@ data class ${innerName}(@DoNotStrip val value: ${v.getCode('kotlin')}): ${kotlin
25
27
  return `
26
28
  val is${innerName}: Boolean
27
29
  get() = this is ${innerName}
30
+ `.trim();
31
+ });
32
+ const asFunctions = variant.cases.map(([label, v]) => {
33
+ const innerName = capitalizeName(label);
34
+ const bridge = new KotlinCxxBridgedType(v);
35
+ const optional = new OptionalType(v);
36
+ return `
37
+ fun as${innerName}OrNull(): ${optional.getCode('kotlin')} {
38
+ val value = (this as? ${innerName})?.value ?: return null
39
+ return ${bridge.parseFromCppToKotlin('value', 'kotlin')}
40
+ }
41
+ `.trim();
42
+ });
43
+ const matchParameters = variant.cases.map(([label, v]) => {
44
+ return `${label}: (${v.getCode('kotlin')}) -> R`;
45
+ });
46
+ const matchCases = variant.cases.map(([label, v]) => {
47
+ const innerName = capitalizeName(label);
48
+ const bridge = new KotlinCxxBridgedType(v);
49
+ return `
50
+ is ${innerName} -> ${label}(${bridge.parseFromCppToKotlin('value', 'kotlin')})
28
51
  `.trim();
29
52
  });
30
53
  const createFunctions = variant.cases.map(([label, v]) => {
54
+ const bridge = new KotlinCxxBridgedType(v);
31
55
  const innerName = capitalizeName(label);
32
56
  return `
33
57
  @JvmStatic
34
58
  @DoNotStrip
35
- fun create(value: ${v.getCode('kotlin')}): ${kotlinName} = ${innerName}(value)
36
- `.trim();
59
+ fun create(value: ${bridge.getTypeCode('kotlin')}): ${kotlinName} = ${innerName}(${bridge.parseFromCppToKotlin('value', 'kotlin')})
60
+ `.trim();
37
61
  });
38
62
  const extraImports = variant.variants
39
63
  .flatMap((t) => t.getRequiredImports('kotlin'))
@@ -54,12 +78,21 @@ ${extraImports.join('\n')}
54
78
  sealed class ${kotlinName} {
55
79
  ${indent(innerClasses.join('\n'), ' ')}
56
80
 
81
+ @Deprecated("getAs() is not type-safe. Use fold/asFirstOrNull/asSecondOrNull instead.", level = DeprecationLevel.ERROR)
57
82
  inline fun <reified T> getAs(): T? = when (this) {
58
83
  ${indent(getterCases.join('\n'), ' ')}
59
84
  }
60
85
 
61
86
  ${indent(isFunctions.join('\n'), ' ')}
62
87
 
88
+ ${indent(asFunctions.join('\n'), ' ')}
89
+
90
+ inline fun <R> match(${matchParameters.join(', ')}): R {
91
+ return when (this) {
92
+ ${indent(matchCases.join('\n'), ' ')}
93
+ }
94
+ }
95
+
63
96
  companion object {
64
97
  ${indent(createFunctions.join('\n'), ' ')}
65
98
  }
@@ -409,7 +409,9 @@ export class SwiftCxxBridgedType {
409
409
  return `${cppParameterName}.has_value() ? ${cppParameterName}.pointee : nil`;
410
410
  }
411
411
  }
412
- if (!wrapping.needsSpecialHandling) {
412
+ // TODO: Remove this check for booleans once https://github.com/swiftlang/swift/issues/84848 is fixed.
413
+ const swiftBug84848Workaround = optional.wrappingType.kind === 'boolean';
414
+ if (!wrapping.needsSpecialHandling && !swiftBug84848Workaround) {
413
415
  return `${cppParameterName}.value`;
414
416
  }
415
417
  return `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nitrogen",
3
- "version": "0.30.0",
3
+ "version": "0.30.1",
4
4
  "description": "The code-generator for react-native-nitro-modules.",
5
5
  "main": "lib/index",
6
6
  "types": "lib/index.d.ts",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "chalk": "^5.3.0",
39
- "react-native-nitro-modules": "^0.30.0",
39
+ "react-native-nitro-modules": "^0.30.1",
40
40
  "ts-morph": "^27.0.0",
41
41
  "yargs": "^18.0.0",
42
42
  "zod": "^4.0.5"
package/src/init.ts CHANGED
@@ -70,7 +70,7 @@ async function isGitInstalled(): Promise<boolean> {
70
70
  try {
71
71
  execSync('git --version')
72
72
  return true
73
- } catch (error) {
73
+ } catch {
74
74
  return false
75
75
  }
76
76
  }
@@ -41,10 +41,6 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
41
41
  case 'function':
42
42
  // Function needs to be converted from JFunc_... to Lambda
43
43
  return true
44
- case 'struct':
45
- // Structs don't need special handling - they have direct mappings
46
- // Returning false prevents secondary constructor generation that causes duplicates
47
- return false
48
44
  case 'optional':
49
45
  // Optionals need special handling if the wrapped type needs special handling
50
46
  const optional = getTypeAs(this.type, OptionalType)
@@ -53,16 +49,6 @@ export class KotlinCxxBridgedType implements BridgedType<'kotlin', 'c++'> {
53
49
  default:
54
50
  break
55
51
  }
56
- // check if any types this type references (e.g. underlying optional, array element, ...)
57
- // needs special handling. if yes, we need it as well
58
- const referencedTypes = getReferencedTypes(this.type)
59
- .filter((t) => t !== this.type)
60
- .map((t) => new KotlinCxxBridgedType(t))
61
- for (const type of referencedTypes) {
62
- if (type.needsSpecialHandling) {
63
- return true
64
- }
65
- }
66
52
  // no special handling needed
67
53
  return false
68
54
  }
@@ -95,7 +95,7 @@ abstract class ${name.HybridTSpec}: ${kotlinBase}() {
95
95
  private external fun initHybrid(): HybridData
96
96
 
97
97
  companion object {
98
- private const val TAG = "${name.HybridTSpec}"
98
+ protected const val TAG = "${name.HybridTSpec}"
99
99
  }
100
100
  }
101
101
  `.trim()
@@ -9,50 +9,28 @@ import { KotlinCxxBridgedType } from './KotlinCxxBridgedType.js'
9
9
 
10
10
  export function createKotlinStruct(structType: StructType): SourceFile[] {
11
11
  const packageName = NitroConfig.current.getAndroidPackage('java/kotlin')
12
- const values = structType.properties.map((p) => {
13
- const bridged = new KotlinCxxBridgedType(p)
14
- return `
12
+ const parameters = structType.properties
13
+ .map((p) =>
14
+ `
15
15
  @DoNotStrip
16
16
  @Keep
17
- val ${p.escapedName}: ${bridged.getTypeCode('kotlin', false)}
17
+ val ${p.escapedName}: ${p.getCode('kotlin')}
18
18
  `.trim()
19
- })
20
- let secondaryConstructor: string
21
-
22
- const needsSpecialHandling = structType.properties.some((p) => {
23
- const bridged = new KotlinCxxBridgedType(p)
24
- const parseCode = bridged.parseFromKotlinToCpp(
25
- p.escapedName,
26
- 'kotlin',
27
- false
28
19
  )
29
- return parseCode !== p.escapedName
30
- })
20
+ .join(',\n')
31
21
 
32
- if (needsSpecialHandling) {
33
- // If we need special handling for any of our properties, we need to add a convenience initializer.
34
- const params = structType.properties.map(
35
- (p) => `${p.escapedName}: ${p.getCode('kotlin')}`
36
- )
37
- const paramsForward = structType.properties.map((p) => {
22
+ const cxxCreateFunctionParameters = structType.properties
23
+ .map((p) => {
38
24
  const bridged = new KotlinCxxBridgedType(p)
39
- if (bridged.needsSpecialHandling) {
40
- // We need special parsing for this type
41
- return bridged.parseFromKotlinToCpp(p.escapedName, 'kotlin', false)
42
- } else {
43
- return p.escapedName
44
- }
25
+ return `${p.escapedName}: ${bridged.getTypeCode('kotlin', false)}`
45
26
  })
46
- secondaryConstructor = `
47
- /**
48
- * Initialize a new instance of \`${structType.structName}\` from Kotlin.
49
- */
50
- constructor(${indent(params.join(', '), 12)})
51
- : this(${indent(paramsForward.join(', '), 12)})
52
- `.trim()
53
- } else {
54
- secondaryConstructor = `/* main constructor */`
55
- }
27
+ .join(', ')
28
+ const cxxCreateFunctionForward = structType.properties
29
+ .map((p) => {
30
+ const bridged = new KotlinCxxBridgedType(p)
31
+ return bridged.parseFromCppToKotlin(p.escapedName, 'kotlin', false)
32
+ })
33
+ .join(', ')
56
34
 
57
35
  const extraImports = structType.properties
58
36
  .flatMap((t) => t.getRequiredImports('kotlin'))
@@ -73,13 +51,21 @@ ${extraImports.join('\n')}
73
51
  */
74
52
  @DoNotStrip
75
53
  @Keep
76
- data class ${structType.structName}
77
- @DoNotStrip
78
- @Keep
79
- constructor(
80
- ${indent(values.join(',\n'), ' ')}
81
- ) {
82
- ${indent(secondaryConstructor, ' ')}
54
+ data class ${structType.structName}(
55
+ ${indent(parameters, ' ')}
56
+ ) {
57
+ private companion object {
58
+ /**
59
+ * Constructor called from C++
60
+ */
61
+ @DoNotStrip
62
+ @Keep
63
+ @Suppress("unused")
64
+ @JvmStatic
65
+ private fun fromCpp(${cxxCreateFunctionParameters}): ${structType.structName} {
66
+ return ${structType.structName}(${cxxCreateFunctionForward})
67
+ }
68
+ }
83
69
  }
84
70
  `.trim()
85
71
 
@@ -193,14 +179,27 @@ function createCppStructInitializer(
193
179
  cppValueName: string,
194
180
  structType: StructType
195
181
  ): string {
196
- const lines: string[] = []
197
- lines.push(`return newInstance(`)
198
- const names = structType.properties.map((p) => {
199
- const name = `${cppValueName}.${p.escapedName}`
200
- const bridge = new KotlinCxxBridgedType(p)
201
- return bridge.parse(name, 'c++', 'kotlin', 'c++')
202
- })
203
- lines.push(` ${indent(names.join(',\n'), ' ')}`)
204
- lines.push(');')
205
- return lines.join('\n')
182
+ const jniTypes = structType.properties
183
+ .map((p) => {
184
+ const bridge = new KotlinCxxBridgedType(p)
185
+ return bridge.asJniReferenceType('alias')
186
+ })
187
+ .join(', ')
188
+ const params = structType.properties
189
+ .map((p) => {
190
+ const name = `${cppValueName}.${p.escapedName}`
191
+ const bridge = new KotlinCxxBridgedType(p)
192
+ return bridge.parse(name, 'c++', 'kotlin', 'c++')
193
+ })
194
+ .join(',\n')
195
+
196
+ return `
197
+ using JSignature = J${structType.structName}(${jniTypes});
198
+ static const auto clazz = javaClassStatic();
199
+ static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
200
+ return create(
201
+ clazz,
202
+ ${indent(params, ' ')}
203
+ );
204
+ `.trim()
206
205
  }
@@ -7,19 +7,21 @@ import {
7
7
  toReferenceType,
8
8
  } from '../helpers.js'
9
9
  import type { SourceFile } from '../SourceFile.js'
10
+ import { OptionalType } from '../types/OptionalType.js'
10
11
  import { type VariantType } from '../types/VariantType.js'
11
12
  import { KotlinCxxBridgedType } from './KotlinCxxBridgedType.js'
12
13
 
13
14
  export function createKotlinVariant(variant: VariantType): SourceFile[] {
14
- const jsName = variant.variants.map((v) => v.getCode('kotlin')).join('|')
15
+ const jsName = variant.variants.map((v) => v.getCode('kotlin')).join(' | ')
15
16
  const kotlinName = variant.getAliasName('kotlin')
16
17
  const namespace = `J${kotlinName}_impl`
17
18
 
18
19
  const innerClasses = variant.cases.map(([label, v]) => {
19
20
  const innerName = capitalizeName(label)
21
+ const bridge = new KotlinCxxBridgedType(v)
20
22
  return `
21
23
  @DoNotStrip
22
- data class ${innerName}(@DoNotStrip val value: ${v.getCode('kotlin')}): ${kotlinName}()
24
+ data class ${innerName}(@DoNotStrip val value: ${bridge.getTypeCode('kotlin')}): ${kotlinName}()
23
25
  `.trim()
24
26
  })
25
27
 
@@ -35,14 +37,36 @@ val is${innerName}: Boolean
35
37
  get() = this is ${innerName}
36
38
  `.trim()
37
39
  })
40
+ const asFunctions = variant.cases.map(([label, v]) => {
41
+ const innerName = capitalizeName(label)
42
+ const bridge = new KotlinCxxBridgedType(v)
43
+ const optional = new OptionalType(v)
44
+ return `
45
+ fun as${innerName}OrNull(): ${optional.getCode('kotlin')} {
46
+ val value = (this as? ${innerName})?.value ?: return null
47
+ return ${bridge.parseFromCppToKotlin('value', 'kotlin')}
48
+ }
49
+ `.trim()
50
+ })
51
+ const matchParameters = variant.cases.map(([label, v]) => {
52
+ return `${label}: (${v.getCode('kotlin')}) -> R`
53
+ })
54
+ const matchCases = variant.cases.map(([label, v]) => {
55
+ const innerName = capitalizeName(label)
56
+ const bridge = new KotlinCxxBridgedType(v)
57
+ return `
58
+ is ${innerName} -> ${label}(${bridge.parseFromCppToKotlin('value', 'kotlin')})
59
+ `.trim()
60
+ })
38
61
 
39
62
  const createFunctions = variant.cases.map(([label, v]) => {
63
+ const bridge = new KotlinCxxBridgedType(v)
40
64
  const innerName = capitalizeName(label)
41
65
  return `
42
66
  @JvmStatic
43
67
  @DoNotStrip
44
- fun create(value: ${v.getCode('kotlin')}): ${kotlinName} = ${innerName}(value)
45
- `.trim()
68
+ fun create(value: ${bridge.getTypeCode('kotlin')}): ${kotlinName} = ${innerName}(${bridge.parseFromCppToKotlin('value', 'kotlin')})
69
+ `.trim()
46
70
  })
47
71
 
48
72
  const extraImports = variant.variants
@@ -65,12 +89,21 @@ ${extraImports.join('\n')}
65
89
  sealed class ${kotlinName} {
66
90
  ${indent(innerClasses.join('\n'), ' ')}
67
91
 
92
+ @Deprecated("getAs() is not type-safe. Use fold/asFirstOrNull/asSecondOrNull instead.", level = DeprecationLevel.ERROR)
68
93
  inline fun <reified T> getAs(): T? = when (this) {
69
94
  ${indent(getterCases.join('\n'), ' ')}
70
95
  }
71
96
 
72
97
  ${indent(isFunctions.join('\n'), ' ')}
73
98
 
99
+ ${indent(asFunctions.join('\n'), ' ')}
100
+
101
+ inline fun <R> match(${matchParameters.join(', ')}): R {
102
+ return when (this) {
103
+ ${indent(matchCases.join('\n'), ' ')}
104
+ }
105
+ }
106
+
74
107
  companion object {
75
108
  ${indent(createFunctions.join('\n'), ' ')}
76
109
  }
@@ -449,7 +449,10 @@ export class SwiftCxxBridgedType implements BridgedType<'swift', 'c++'> {
449
449
  return `${cppParameterName}.has_value() ? ${cppParameterName}.pointee : nil`
450
450
  }
451
451
  }
452
- if (!wrapping.needsSpecialHandling) {
452
+ // TODO: Remove this check for booleans once https://github.com/swiftlang/swift/issues/84848 is fixed.
453
+ const swiftBug84848Workaround =
454
+ optional.wrappingType.kind === 'boolean'
455
+ if (!wrapping.needsSpecialHandling && !swiftBug84848Workaround) {
453
456
  return `${cppParameterName}.value`
454
457
  }
455
458
  return `