diff --git a/packages/nitrogen/src/syntax/swift/SwiftStruct.ts b/packages/nitrogen/src/syntax/swift/SwiftStruct.ts index f61ccf0e4f..fbd21aac75 100644 --- a/packages/nitrogen/src/syntax/swift/SwiftStruct.ts +++ b/packages/nitrogen/src/syntax/swift/SwiftStruct.ts @@ -9,8 +9,6 @@ import type { SourceFile } from '../SourceFile.js' import type { SwiftStructType } from './types/SwiftStructType.js' import { getImportsCode } from '../getImportCode.js' import { getProtocolConformanceImports, getSwiftImports } from './getSwiftImports.js' -import type { CppHelper } from '../c++/CppHelper.js' -import type { SwiftNamedType } from './types/SwiftNamedType.js' export function createSwiftStructBridge(swiftType: SwiftStructType): SourceFile[] { const structType = swiftType.type @@ -22,38 +20,16 @@ export function createSwiftStructBridge(swiftType: SwiftStructType): SourceFile[ .map((p) => `${p.escapedName}: ${p.getCode('swift', { context: 'property' })}`) .join(', ') const swiftPropertyInitializers = structType.properties.map((p) => `self.${p.escapedName} = ${p.escapedName}`) - const swiftBridgeProperties = swiftType.properties.map((p) => { - let propertyType: string - let propertyValue: string - if (p.requiresOpaqueCxxBridge) { - propertyType = getStructPropertyWrapperName({ type: swiftType, property: p, language: 'swift' }) - propertyValue = p.toSwift(`${p.escapedName}.value`) - } else { - propertyType = p.getCode('swift', { context: 'property' }) - propertyValue = p.toSwift(p.escapedName) - } - return { name: p.escapedName, type: propertyType, value: propertyValue } - }) - const swiftBridgeInitializerParameters = swiftBridgeProperties.map((p) => `_ ${p.name}: ${p.type}`).join(', ') - const swiftBridgeInitializerArguments = swiftBridgeProperties.map((p) => `${p.name}: ${p.value}`).join(', ') + const swiftBridgeInitializerParameters = swiftType.properties + .map((p) => `_ ${p.escapedName}: ${p.getCode('swift', { context: 'property' })}`) + .join(', ') + const swiftBridgeInitializerArguments = swiftType.properties.map((p) => `${p.escapedName}: ${p.toSwift(p.escapedName)}`).join(', ') const swiftBridgeGetters = swiftType.properties.map((p) => { - const swiftToCppValue = p.fromSwift(`self.${p.escapedName}`) - let swiftGetterReturnType: string - let swiftGetterValue: string - if (p.requiresOpaqueCxxBridge) { - swiftGetterReturnType = getStructPropertyWrapperName({ type: swiftType, property: p, language: 'swift' }) - swiftGetterValue = `${swiftGetterReturnType}(${swiftToCppValue})` - } else { - swiftGetterReturnType = p.getCode('swift', { context: 'return' }) - swiftGetterValue = swiftToCppValue - } - const swiftGetterBody = ` -return ${indent(swiftGetterValue, '')} -`.trim() + const swiftGetterBody = `return ${p.fromSwift(`self.${p.escapedName}`)}` return ` @_spi(NitroCxx) -public borrowing func get${capitalizeName(p.escapedName)}_cxx() -> ${swiftGetterReturnType} { - ${indent(swiftGetterBody, ' ')} +public borrowing func get${capitalizeName(p.escapedName)}_cxx() -> ${p.getCode('swift', { context: 'return' })} { + ${swiftGetterBody} } `.trim() }) @@ -92,19 +68,13 @@ public struct ${structType.structName}${conformancePrefix}${protocolNames.join(' } const cppStructType = swiftType.getCode('c++', { context: 'value' }) - const cppInitializerArguments = swiftType.properties.map((p) => { - const cppPropertyType = p.getCode('c++', { context: 'type-argument' }) - const jsToSwiftPropertyCode = ` -JSIConverter<${cppPropertyType}>::fromJSI(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "${p.name}"))) -`.trim() - return wrapCppStructProperty({ type: swiftType, property: p, value: jsToSwiftPropertyCode }) - }) + const cppInitializerArguments = swiftType.properties.map( + (p) => + `JSIConverter<${p.getCode('c++', { context: 'type-argument' })}>::fromJSI(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "${p.name}")))` + ) const cppPropertyConversions = swiftType.properties.map((p) => { - const cppGetter = getCppStructProperty(p) - const cppPropertyType = p.getCode('c++', { context: 'type-argument' }) - return ` -object.setProperty(runtime, PropNameIDCache::get(runtime, "${p.name}"), JSIConverter<${cppPropertyType}>::toJSI(runtime, ${indent(cppGetter, '')})); -`.trim() + const swiftGetterName = `get${capitalizeName(p.escapedName)}_cxx` + return `object.setProperty(runtime, PropNameIDCache::get(runtime, "${p.name}"), JSIConverter<${p.getCode('c++', { context: 'type-argument' })}>::toJSI(runtime, value.${swiftGetterName}()));` }) const cppPropertyChecks = swiftType.properties.map( (p) => @@ -162,17 +132,12 @@ export function createSwiftStructCppConverter({ type, cppType }: SwiftStructCppC const nativeStructType = structType.getCode('c++', { context: 'value', fullyQualified: true }) const cppInitializerValues = properties.map(({ native, swift }) => { const converter = getSwiftConverter({ cppType: native, swiftType: swift }) - const cppGetter = getCppStructProperty(swift) - return ` -${converter}::fromSwift(${indent(cppGetter, '')}) -`.trim() + const getterName = `get${capitalizeName(swift.escapedName)}_cxx` + return `${converter}::fromSwift(value.${getterName}())` }) const swiftInitializerValues = properties.map(({ native, swift }) => { const converter = getSwiftConverter({ cppType: native, swiftType: swift }) - const cppToSwiftPropertyCode = ` -${converter}::toSwift(value.${native.escapedName}) -`.trim() - return wrapCppStructProperty({ type: type, property: swift, value: cppToSwiftPropertyCode }) + return `${converter}::toSwift(value.${native.escapedName})` }) const swiftToCppConverterCode = ` return ${nativeStructType}(${cppInitializerValues.join(', ')}); @@ -192,71 +157,3 @@ return SwiftType::init_cxx(${swiftInitializerValues.join(', ')}); dependencies: dependencies, }) } - -interface StructPropertyWrapperOptions { - type: SwiftStructType - property: SwiftNamedType - language: 'swift' | 'c++' -} - -function getStructPropertyWrapperName({ type, property, language }: StructPropertyWrapperOptions): string { - const namespace = type.config.getSwiftBridgeNamespace(language) - const name = `${type.name}_${property.escapedName}_cxx` - switch (language) { - case 'swift': - return `${namespace}.${name}` - case 'c++': - return `${namespace}::${name}` - } -} - -interface WrapCppStructPropertyOptions { - type: SwiftStructType - property: SwiftNamedType - value: string -} - -function wrapCppStructProperty({ type, property, value }: WrapCppStructPropertyOptions): string { - if (property.requiresOpaqueCxxBridge) { - const wrapper = getStructPropertyWrapperName({ type: type, property: property, language: 'c++' }) - return ` -${wrapper}(${indent(value, '')}) -`.trim() - } - return value -} - -function getCppStructProperty(property: SwiftNamedType): string { - const getterName = capitalizeName(property.escapedName) - const cppGetter = `value.get${getterName}_cxx()` - if (property.requiresOpaqueCxxBridge) { - return `${cppGetter}.value` - } - return cppGetter -} - -export function createSwiftStructPropertyHelpers(type: SwiftStructType): CppHelper[] { - if (type.config.isExternalConfig) return [] - const properties = type.properties.filter((property) => property.requiresOpaqueCxxBridge) - return properties.map((property) => { - const name = `${type.name}_${property.escapedName}_cxx` - const cppType = property.getCode('c++', { context: 'value' }) - // TODO: Remove these module-owned wrappers once our minimum Xcode includes - // https://github.com/swiftlang/swift/pull/93321, fixing https://github.com/swiftlang/swift/issues/93318. - const cppWrapperCode = ` -struct ${name} final { - ${cppType} value; - explicit ${name}(${cppType} value) : value(std::move(value)) {} -}; -`.trim() - return { - header: { - code: cppWrapperCode, - requiredImports: [ - ...property.getRequiredImports('c++', 'declaration'), - { language: 'c++', declaration: { header: 'utility', space: 'system' } }, - ], - }, - } - }) -} diff --git a/packages/nitrogen/src/syntax/swift/types/SwiftStructType.ts b/packages/nitrogen/src/syntax/swift/types/SwiftStructType.ts index 4f9b9a62ef..dc7bc69708 100644 --- a/packages/nitrogen/src/syntax/swift/types/SwiftStructType.ts +++ b/packages/nitrogen/src/syntax/swift/types/SwiftStructType.ts @@ -2,7 +2,7 @@ import type { Type, GetCodeOptions, TypeContext } from '../../types/Type.js' import type { CppHelper } from '../../c++/CppHelper.js' import type { SourceFile } from '../../SourceFile.js' import { StructType } from '../../types/StructType.js' -import { createSwiftStructBridge, createSwiftStructCppConverter, createSwiftStructPropertyHelpers } from '../SwiftStruct.js' +import { createSwiftStructBridge, createSwiftStructCppConverter } from '../SwiftStruct.js' import { wrapSwiftType } from '../wrapSwiftType.js' import { NitroConfig } from '../../../config/NitroConfig.js' import type { Language } from '../../../getPlatformSpecs.js' @@ -102,7 +102,7 @@ export class SwiftStructType extends StructType implements SwiftType { } get requiredCppHelpers(): CppHelper[] { - return [...this.properties.flatMap((p) => p.requiredCppHelpers), ...createSwiftStructPropertyHelpers(this)] + return this.properties.flatMap((p) => p.requiredCppHelpers) } override getRequiredImports(language: Language, context: 'declaration' | 'implementation' = 'implementation'): SourceImport[] { diff --git a/tests/standalone/nitro-test/nitrogen/generated/apple/NitroTestAppleCxx/include/NitroTestAppleCxx/NitroTestAppleCxx.h b/tests/standalone/nitro-test/nitrogen/generated/apple/NitroTestAppleCxx/include/NitroTestAppleCxx/NitroTestAppleCxx.h index caf71cc964..87c691d3a4 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/apple/NitroTestAppleCxx/include/NitroTestAppleCxx/NitroTestAppleCxx.h +++ b/tests/standalone/nitro-test/nitrogen/generated/apple/NitroTestAppleCxx/include/NitroTestAppleCxx/NitroTestAppleCxx.h @@ -151,7 +151,6 @@ namespace margelo::nitro::test::external { class HybridSomeExternalObjectSpecSwi namespace margelo::nitro::test { class HybridSomeExternalObjectChildSpecSwift; } // Forward declaration of `HybridTestObjectSwiftKotlinSpecSwift` to properly resolve imports. namespace margelo::nitro::test { class HybridTestObjectSwiftKotlinSpecSwift; } -#include #include // Forward declaration of `HybridSharedSpecializationsSpecSwift` to properly resolve imports. namespace margelo::nitro::test::external { class HybridSharedSpecializationsSpecSwift; } @@ -263,10 +262,6 @@ namespace margelo::nitro::test::swift_bridge { using Callback_uint64_t_uint64_t = Callback; Result callSync_Callback_uint64_t_uint64_t(const Callback_uint64_t_uint64_t& callback, uint64_t param0) noexcept; Callback_uint64_t_uint64_t create_Callback_uint64_t_uint64_t(std::function(uint64_t param0)> closure); - struct JsStyleStruct_onChanged_cxx final { - Callback value; - explicit JsStyleStruct_onChanged_cxx(Callback value) : value(std::move(value)) {} - }; using Result_double = Result; using Callback_double = Callback; Result callSync_Callback_double(const Callback_double& callback) noexcept; diff --git a/tests/standalone/nitro-test/nitrogen/generated/apple/c++/JsStyleStruct-Swift.cpp b/tests/standalone/nitro-test/nitrogen/generated/apple/c++/JsStyleStruct-Swift.cpp index 58059b42c5..8cd1bbee06 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/apple/c++/JsStyleStruct-Swift.cpp +++ b/tests/standalone/nitro-test/nitrogen/generated/apple/c++/JsStyleStruct-Swift.cpp @@ -13,13 +13,13 @@ namespace margelo::nitro { ::NitroTest::JsStyleStruct JSIConverter<::NitroTest::JsStyleStruct>::fromJSI(jsi::Runtime& runtime, const jsi::Value& value) { auto object = value.asObject(runtime); - return ::NitroTest::JsStyleStruct::init_cxx(JSIConverter::fromJSI(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "value"))), margelo::nitro::test::swift_bridge::JsStyleStruct_onChanged_cxx(JSIConverter>::fromJSI(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "onChanged"))))); + return ::NitroTest::JsStyleStruct::init_cxx(JSIConverter::fromJSI(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "value"))), JSIConverter>::fromJSI(runtime, object.getProperty(runtime, PropNameIDCache::get(runtime, "onChanged")))); } jsi::Value JSIConverter<::NitroTest::JsStyleStruct>::toJSI(jsi::Runtime& runtime, const ::NitroTest::JsStyleStruct& value) { jsi::Object object(runtime); object.setProperty(runtime, PropNameIDCache::get(runtime, "value"), JSIConverter::toJSI(runtime, value.getValue_cxx())); - object.setProperty(runtime, PropNameIDCache::get(runtime, "onChanged"), JSIConverter>::toJSI(runtime, value.getOnChanged_cxx().value)); + object.setProperty(runtime, PropNameIDCache::get(runtime, "onChanged"), JSIConverter>::toJSI(runtime, value.getOnChanged_cxx())); return object; } diff --git a/tests/standalone/nitro-test/nitrogen/generated/apple/swift/JsStyleStruct.swift b/tests/standalone/nitro-test/nitrogen/generated/apple/swift/JsStyleStruct.swift index 16a7b8fe8e..2467139a33 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/apple/swift/JsStyleStruct.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/apple/swift/JsStyleStruct.swift @@ -20,8 +20,8 @@ public struct JsStyleStruct: Sendable { } @_spi(NitroCxx) - public static func init_cxx(_ value: Double, _ onChanged: margelo.nitro.test.swift_bridge.JsStyleStruct_onChanged_cxx) -> Self { - return Self(value: value, onChanged: onChanged.value) + public static func init_cxx(_ value: Double, _ onChanged: margelo.nitro.test.swift_bridge.Callback_void_double) -> Self { + return Self(value: value, onChanged: onChanged) } @_spi(NitroCxx) @@ -30,7 +30,7 @@ public struct JsStyleStruct: Sendable { } @_spi(NitroCxx) - public borrowing func getOnChanged_cxx() -> margelo.nitro.test.swift_bridge.JsStyleStruct_onChanged_cxx { - return margelo.nitro.test.swift_bridge.JsStyleStruct_onChanged_cxx(self.onChanged.toCpp()) + public borrowing func getOnChanged_cxx() -> margelo.nitro.test.swift_bridge.Callback_void_double { + return self.onChanged.toCpp() } }