From cc03d6530e080b6aea21e516301638f28117f220 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Wed, 21 Oct 2026 01:35:23 +0200 Subject: [PATCH 1/2] feat(nitrogen): require static and initializer implementation contracts --- docs/docs/concepts/nitrogen.md | 11 +++++-- packages/nitrogen/src/syntax/StaticMethod.ts | 7 +++-- .../nitrogen/src/syntax/StaticProperty.ts | 14 ++++++++- .../src/syntax/kotlin/KotlinHybridObject.ts | 29 ++++++++++++++++++- .../src/syntax/swift/SwiftHybridObject.ts | 21 ++++++++++++++ .../nitro/test/external/HybridTestViewSpec.kt | 4 ++- .../ios/swift/HybridTestViewSpec.swift | 2 ++ .../ios/HybridBenchmarkObjectSwift.swift | 4 +++ .../HybridBenchmarkObjectSwiftKotlinSpec.kt | 4 ++- .../test/HybridRecyclableTestViewSpec.kt | 4 ++- .../margelo/nitro/test/HybridTestViewSpec.kt | 4 ++- ...HybridBenchmarkObjectSwiftKotlinSpec.swift | 2 ++ .../swift/HybridRecyclableTestViewSpec.swift | 2 ++ .../ios/swift/HybridTestViewSpec.swift | 2 ++ .../nitro-test-external/ios/HybridBase.swift | 4 +++ .../ios/HybridSomeExternalObject.swift | 4 +++ .../nitro/test/external/HybridBaseSpec.kt | 4 ++- .../external/HybridSomeExternalObjectSpec.kt | 4 ++- .../generated/ios/swift/HybridBaseSpec.swift | 2 ++ .../swift/HybridSomeExternalObjectSpec.swift | 2 ++ .../java/com/margelo/nitro/test/HybridBase.kt | 6 ++-- .../nitro/test/HybridTestObjectKotlin.kt | 6 ++-- .../nitro-test/ios/HybridBase.swift | 4 +++ .../nitro-test/ios/HybridChild.swift | 13 +++++++++ .../nitro-test/ios/HybridGrandchild.swift | 13 +++++++++ .../nitro-test/ios/HybridPlatformObject.swift | 4 +++ .../ios/HybridSomeInternalObject.swift | 4 +++ .../ios/HybridTestObjectSwift.swift | 4 +++ .../com/margelo/nitro/test/HybridBaseSpec.kt | 10 ++++++- .../com/margelo/nitro/test/HybridChildSpec.kt | 4 ++- .../nitro/test/HybridGrandchildSpec.kt | 4 ++- .../nitro/test/HybridPlatformObjectSpec.kt | 4 ++- .../test/HybridTestObjectSwiftKotlinSpec.kt | 10 ++++++- .../generated/ios/swift/HybridBaseSpec.swift | 4 +++ .../generated/ios/swift/HybridChildSpec.swift | 2 ++ .../ios/swift/HybridGrandchildSpec.swift | 2 ++ .../ios/swift/HybridPlatformObjectSpec.swift | 2 ++ .../HybridTestObjectSwiftKotlinSpec.swift | 4 +++ 38 files changed, 206 insertions(+), 24 deletions(-) diff --git a/docs/docs/concepts/nitrogen.md b/docs/docs/concepts/nitrogen.md index a845075541..3b24b30d83 100644 --- a/docs/docs/concepts/nitrogen.md +++ b/docs/docs/concepts/nitrogen.md @@ -320,8 +320,8 @@ To implement `Math` now, you just need to implement the spec: ```kotlin title="HybridMath.kt" class HybridMath : HybridMathSpec() { - companion object { - fun add(a: Double, b: Double): Double { + companion object : HybridMathSpec.Companion { + override fun add(a: Double, b: Double): Double { return a + b } } @@ -358,6 +358,13 @@ To implement `Math` now, you just need to implement the spec: +The Swift protocol requires the declared constructors, static methods, and static properties. A non-final Swift implementation must mark +required initializers with `required`; when overriding the generated base initializer, use `required override init(...)`. + +For Kotlin specs with static members, the implementation's companion must implement `HybridMathSpec.Companion`. Missing companion +conformance or missing members fails compilation. Constructors are checked separately by the generated Kotlin factories, which call the +configured implementation directly. JNI calls generated `@JvmStatic` entry points on the spec. + ### 5. Use the Hybrid Objects Static methods are directly callable on the `Math` type: diff --git a/packages/nitrogen/src/syntax/StaticMethod.ts b/packages/nitrogen/src/syntax/StaticMethod.ts index d29a67face..a7040ea785 100644 --- a/packages/nitrogen/src/syntax/StaticMethod.ts +++ b/packages/nitrogen/src/syntax/StaticMethod.ts @@ -2,6 +2,8 @@ import type { Language } from '../getPlatformSpecs.js' import { Method, type MethodOptions, type MethodSignatureOptions } from './Method.js' export interface StaticMethodOptions extends MethodOptions { + /** Swift only: declare a static protocol requirement rather than a class method. */ + readonly protocolRequirement?: boolean /** Swift only: overrides the superclass's `class func` with the same signature. */ readonly override?: boolean readonly virtual?: never @@ -29,9 +31,8 @@ export class StaticMethod extends Method { case 'swift': { let throws = '' if (options.throwing !== false) throws = ' throws' - // Swift only declares static methods on classes, where a subclass can - // override a `class func` with the same signature. - let signature = `class func ${this.name}(${parameters.join(', ')})${throws} -> ${returnType}` + const keyword = options.protocolRequirement ? 'static' : 'class' + let signature = `${keyword} func ${this.name}(${parameters.join(', ')})${throws} -> ${returnType}` if (options.override) signature = `override ${signature}` if (options.access != null) signature = `${options.access} ${signature}` if (options.inline) { diff --git a/packages/nitrogen/src/syntax/StaticProperty.ts b/packages/nitrogen/src/syntax/StaticProperty.ts index e0fd05412a..ad29bc40e2 100644 --- a/packages/nitrogen/src/syntax/StaticProperty.ts +++ b/packages/nitrogen/src/syntax/StaticProperty.ts @@ -1,8 +1,20 @@ -import { Property } from './Property.js' +import type { Language } from '../getPlatformSpecs.js' +import { Property, type PropertyBody, type PropertyModifiers } from './Property.js' import { StaticMethod } from './StaticMethod.js' /** A class property exposed through native static getter and setter functions. */ export class StaticProperty extends Property { + override getCode(language: Language, modifiers?: PropertyModifiers, body?: PropertyBody): string { + const declaration = super.getCode(language, modifiers, body) + switch (language) { + case 'swift': + return `static ${declaration}` + case 'c++': + case 'kotlin': + return declaration + } + } + getStaticMethods(): [getter: StaticMethod] | [getter: StaticMethod, setter: StaticMethod] { const methods = this.getCppMethods().map( (method) => diff --git a/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts b/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts index 7da5c95783..28cdc3480d 100644 --- a/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts +++ b/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts @@ -33,6 +33,7 @@ export function createKotlinHybridObject(publicSpec: HybridObjectSpec<'kotlin'>) const properties = spec.properties.map(getKotlinPropertyCode).join('\n\n') const methods = spec.methods.map(getKotlinMethodCode).join('\n\n') const companion = getKotlinCompanion(spec) + const companionContract = getKotlinCompanionInterface(spec) const extraImports: SourceImport[] = [ ...spec.properties.flatMap((p) => p.getRequiredImports('kotlin')), @@ -125,7 +126,9 @@ abstract class ${name.HybridTSpec}: ${supertypes} { return CxxPart(this) } - companion object { + ${indent(companionContract, ' ')} + + companion object Bridge { ${indent(companion.code, ' ')} } } @@ -193,6 +196,15 @@ protected const val TAG = "${name.HybridTSpec}" }) } const sections = [tagCode] + if (spec.staticMethods.length > 0 || spec.staticProperties.length > 0) { + const implementation = getKotlinImplementation(spec) + // Check the configured companion's contract; forwarders still call it directly. + const companionRequirement = ` +private val implementationCompanion: Companion + get() = ${implementation.className} +`.trim() + sections.push(companionRequirement) + } for (const group of groups) { const forwarders = group.callables .flatMap((callable) => callable.createBridge().kotlinMethods) @@ -244,3 +256,18 @@ function getImplementedInterfaceImport(implementedInterface: KotlinImplementedIn language: 'kotlin', } } + +function getKotlinCompanionInterface(spec: HybridObjectSpec<'kotlin'>): string { + const declarations = spec.staticProperties.map((property) => property.getCode('kotlin')) + const methods = spec.staticMethods.map((method) => { + const requirement = new InstanceMethod(method.name, method.returnType, method.parameters) + return requirement.getDeclaration('kotlin') + }) + declarations.push(...methods) + if (declarations.length === 0) return '' + return ` +interface Companion { + ${indent(declarations.join('\n'), ' ')} +} +`.trim() +} diff --git a/packages/nitrogen/src/syntax/swift/SwiftHybridObject.ts b/packages/nitrogen/src/syntax/swift/SwiftHybridObject.ts index 54e3ea6dd6..a9a7949dc2 100644 --- a/packages/nitrogen/src/syntax/swift/SwiftHybridObject.ts +++ b/packages/nitrogen/src/syntax/swift/SwiftHybridObject.ts @@ -6,6 +6,7 @@ import { createFileMetadataString } from '../helpers.js' import type { HybridObjectSpec } from '../HybridObjectSpec.js' import type { SourceFile } from '../SourceFile.js' import { HybridObjectType } from '../types/HybridObjectType.js' +import { StaticMethod } from '../StaticMethod.js' import { createSwiftHybridObjectCxxBridge } from './SwiftHybridObjectBridge.js' import { getImportsCode } from '../getImportCode.js' import { getAllTypes } from '../getAllTypes.js' @@ -20,6 +21,7 @@ export function createSwiftHybridObject(spec: HybridObjectSpec<'swift'>): Source const protocolName = name.HybridTSpec const properties = spec.properties.map((p) => p.getCode('swift')).join('\n') const methods = spec.methods.map((method) => method.getDeclaration('swift')).join('\n') + const classMembers = getSwiftClassRequirements(spec) const extraImports = [ ...spec.properties.flatMap((p) => p.getRequiredImports('swift')), ...spec.staticProperties.flatMap((p) => p.getRequiredImports('swift')), @@ -86,6 +88,8 @@ ${imports} /// See \`\`${protocolName}\`\` public protocol ${protocolName}_protocol: ${protocolBaseClasses.join(', ')} { + ${indent(classMembers, ' ')} + // Properties ${indent(properties, ' ')} @@ -137,3 +141,20 @@ public typealias ${protocolName} = ${protocolName}_protocol & ${protocolName}_ba return files } + +function getSwiftClassRequirements(spec: HybridObjectSpec<'swift'>): string { + const declarations: string[] = [] + if (spec.constructor != null) { + declarations.push(spec.constructor.getDeclaration('swift')) + } + declarations.push(...spec.staticProperties.map((property) => property.getCode('swift'))) + const staticMethods = spec.staticMethods.map((method) => { + const requirement = new StaticMethod(method.name, method.returnType, method.parameters, { + ...method.options, + protocolRequirement: true, + }) + return requirement.getDeclaration('swift') + }) + declarations.push(...staticMethods) + return declarations.join('\n') +} diff --git a/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridTestViewSpec.kt b/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridTestViewSpec.kt index 9f06ed0867..0f6cb897b2 100644 --- a/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridTestViewSpec.kt +++ b/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridTestViewSpec.kt @@ -73,7 +73,9 @@ abstract class HybridTestViewSpec: HybridView() { return CxxPart(this) } - companion object { + + + companion object Bridge { protected const val TAG = "HybridTestViewSpec" } } diff --git a/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/ios/swift/HybridTestViewSpec.swift b/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/ios/swift/HybridTestViewSpec.swift index 129ec3220e..ae8dc3cf2f 100644 --- a/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/ios/swift/HybridTestViewSpec.swift +++ b/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/ios/swift/HybridTestViewSpec.swift @@ -9,6 +9,8 @@ public import NitroModules /// See ``HybridTestViewSpec`` public protocol HybridTestViewSpec_protocol: HybridObject, HybridView { + + // Properties var isBlue: Bool { get set } var someCallback: any Callback<(), Void> { get set } diff --git a/tests/react-native/packages/react-native-nitro-test/ios/HybridBenchmarkObjectSwift.swift b/tests/react-native/packages/react-native-nitro-test/ios/HybridBenchmarkObjectSwift.swift index 04f2a844ed..d0b8b3fb2b 100644 --- a/tests/react-native/packages/react-native-nitro-test/ios/HybridBenchmarkObjectSwift.swift +++ b/tests/react-native/packages/react-native-nitro-test/ios/HybridBenchmarkObjectSwift.swift @@ -6,6 +6,10 @@ import NitroModules #endif class HybridBenchmarkObjectSwift: HybridBenchmarkObjectSwiftKotlinSpec { + required override init() { + super.init() + } + private var pendingPromise: (any Promise)? var numberValue: Double = 0.0 diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBenchmarkObjectSwiftKotlinSpec.kt b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBenchmarkObjectSwiftKotlinSpec.kt index 5a06c9b9b9..58326bb101 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBenchmarkObjectSwiftKotlinSpec.kt +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBenchmarkObjectSwiftKotlinSpec.kt @@ -122,7 +122,9 @@ abstract class HybridBenchmarkObjectSwiftKotlinSpec: HybridObject() { return CxxPart(this) } - companion object { + + + companion object Bridge { protected const val TAG = "HybridBenchmarkObjectSwiftKotlinSpec" // Constructor diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridRecyclableTestViewSpec.kt b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridRecyclableTestViewSpec.kt index c8dc53cb42..568f9ad787 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridRecyclableTestViewSpec.kt +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridRecyclableTestViewSpec.kt @@ -73,7 +73,9 @@ abstract class HybridRecyclableTestViewSpec: HybridView() { return CxxPart(this) } - companion object { + + + companion object Bridge { protected const val TAG = "HybridRecyclableTestViewSpec" } } diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestViewSpec.kt b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestViewSpec.kt index 90973cfaef..c614727a3b 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestViewSpec.kt +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestViewSpec.kt @@ -109,7 +109,9 @@ abstract class HybridTestViewSpec: HybridView() { return CxxPart(this) } - companion object { + + + companion object Bridge { protected const val TAG = "HybridTestViewSpec" } } diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridBenchmarkObjectSwiftKotlinSpec.swift b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridBenchmarkObjectSwiftKotlinSpec.swift index 2fa87ddf73..4aac21a9c3 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridBenchmarkObjectSwiftKotlinSpec.swift +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridBenchmarkObjectSwiftKotlinSpec.swift @@ -9,6 +9,8 @@ public import NitroModules /// See ``HybridBenchmarkObjectSwiftKotlinSpec`` public protocol HybridBenchmarkObjectSwiftKotlinSpec_protocol: HybridObject { + init() throws + // Properties var numberValue: Double { get set } var thisObject: (any HybridBenchmarkObjectSwiftKotlinSpec) { get } diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridRecyclableTestViewSpec.swift b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridRecyclableTestViewSpec.swift index 91745804c1..4a257caa99 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridRecyclableTestViewSpec.swift +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridRecyclableTestViewSpec.swift @@ -9,6 +9,8 @@ public import NitroModules /// See ``HybridRecyclableTestViewSpec`` public protocol HybridRecyclableTestViewSpec_protocol: HybridObject, HybridView { + + // Properties var isBlue: Bool { get set } var nativeDefaultValue: Double? { get set } diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestViewSpec.swift b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestViewSpec.swift index ab121ced9a..2f03299763 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestViewSpec.swift +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestViewSpec.swift @@ -9,6 +9,8 @@ public import NitroModules /// See ``HybridTestViewSpec`` public protocol HybridTestViewSpec_protocol: HybridObject, HybridView { + + // Properties var isBlue: Bool { get set } var hasBeenCalled: Bool { get set } diff --git a/tests/standalone/nitro-test-external/ios/HybridBase.swift b/tests/standalone/nitro-test-external/ios/HybridBase.swift index 69b7b8ea09..99fac9f0ee 100644 --- a/tests/standalone/nitro-test-external/ios/HybridBase.swift +++ b/tests/standalone/nitro-test-external/ios/HybridBase.swift @@ -1,6 +1,10 @@ import NitroModules class HybridBase: HybridBaseSpec { + required override init() { + super.init() + } + var baseValue: Double { return 20 } diff --git a/tests/standalone/nitro-test-external/ios/HybridSomeExternalObject.swift b/tests/standalone/nitro-test-external/ios/HybridSomeExternalObject.swift index 3dd849e6df..cf20bc3316 100644 --- a/tests/standalone/nitro-test-external/ios/HybridSomeExternalObject.swift +++ b/tests/standalone/nitro-test-external/ios/HybridSomeExternalObject.swift @@ -8,6 +8,10 @@ import NitroModules class HybridSomeExternalObject: HybridSomeExternalObjectSpec { + required override init() { + super.init() + } + func getValue() throws -> String { return "Hello world!" } diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridBaseSpec.kt b/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridBaseSpec.kt index ed1c9d6edb..8bff16a5f9 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridBaseSpec.kt +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridBaseSpec.kt @@ -67,7 +67,9 @@ abstract class HybridBaseSpec: HybridObject() { return CxxPart(this) } - companion object { + + + companion object Bridge { protected const val TAG = "HybridBaseSpec" // Constructor diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridSomeExternalObjectSpec.kt b/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridSomeExternalObjectSpec.kt index 169b702408..25e1223424 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridSomeExternalObjectSpec.kt +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridSomeExternalObjectSpec.kt @@ -60,7 +60,9 @@ abstract class HybridSomeExternalObjectSpec: HybridObject() { return CxxPart(this) } - companion object { + + + companion object Bridge { protected const val TAG = "HybridSomeExternalObjectSpec" // Constructor diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridBaseSpec.swift b/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridBaseSpec.swift index 32f5f96073..2cdc9038ae 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridBaseSpec.swift +++ b/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridBaseSpec.swift @@ -9,6 +9,8 @@ public import NitroModules /// See ``HybridBaseSpec`` public protocol HybridBaseSpec_protocol: HybridObject { + init() throws + // Properties var baseValue: Double { get } diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridSomeExternalObjectSpec.swift b/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridSomeExternalObjectSpec.swift index 1e2358e3a3..f1c6451450 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridSomeExternalObjectSpec.swift +++ b/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridSomeExternalObjectSpec.swift @@ -9,6 +9,8 @@ public import NitroModules /// See ``HybridSomeExternalObjectSpec`` public protocol HybridSomeExternalObjectSpec_protocol: HybridObject { + init() throws + // Properties diff --git a/tests/standalone/nitro-test/android/src/main/java/com/margelo/nitro/test/HybridBase.kt b/tests/standalone/nitro-test/android/src/main/java/com/margelo/nitro/test/HybridBase.kt index eee92c5a88..2652ab1c66 100644 --- a/tests/standalone/nitro-test/android/src/main/java/com/margelo/nitro/test/HybridBase.kt +++ b/tests/standalone/nitro-test/android/src/main/java/com/margelo/nitro/test/HybridBase.kt @@ -9,12 +9,12 @@ import com.margelo.nitro.test.external.HybridSomeExternalObjectSpec @Keep @DoNotStrip open class HybridBase : HybridBaseSpec() { - companion object { + companion object : HybridBaseSpec.Companion { @JvmStatic - fun createAlternativeBase(): HybridBaseSpec = HybridAlternativeBase() + override fun createAlternativeBase(): HybridBaseSpec = HybridAlternativeBase() @JvmStatic - fun createInternalExternalObject(): HybridSomeExternalObjectSpec = HybridSomeInternalObject() + override fun createInternalExternalObject(): HybridSomeExternalObjectSpec = HybridSomeInternalObject() } override val baseValue: Double diff --git a/tests/standalone/nitro-test/android/src/main/java/com/margelo/nitro/test/HybridTestObjectKotlin.kt b/tests/standalone/nitro-test/android/src/main/java/com/margelo/nitro/test/HybridTestObjectKotlin.kt index 2d8ba9014c..f1f74a0c18 100644 --- a/tests/standalone/nitro-test/android/src/main/java/com/margelo/nitro/test/HybridTestObjectKotlin.kt +++ b/tests/standalone/nitro-test/android/src/main/java/com/margelo/nitro/test/HybridTestObjectKotlin.kt @@ -23,10 +23,10 @@ import java.math.BigDecimal class HybridTestObjectKotlin : HybridTestObjectSwiftKotlinSpec() { private var pendingPromise: Promise? = null - companion object { - val readonlyNumber: Double = 42.0 + companion object : HybridTestObjectSwiftKotlinSpec.Companion { + override val readonlyNumber: Double = 42.0 - @Volatile var sharedNumber: Double = 0.0 + @Volatile override var sharedNumber: Double = 0.0 private val promiseScope = CoroutineScope(Dispatchers.Default) } diff --git a/tests/standalone/nitro-test/ios/HybridBase.swift b/tests/standalone/nitro-test/ios/HybridBase.swift index 4ea2dc995c..1a9d27b43f 100644 --- a/tests/standalone/nitro-test/ios/HybridBase.swift +++ b/tests/standalone/nitro-test/ios/HybridBase.swift @@ -9,6 +9,10 @@ import NitroModules import NitroTestExternal class HybridBase: HybridBaseSpec { + required override init() { + super.init() + } + static func createAlternativeBase() -> any HybridBaseSpec { return HybridAlternativeBase() } diff --git a/tests/standalone/nitro-test/ios/HybridChild.swift b/tests/standalone/nitro-test/ios/HybridChild.swift index ff44702203..5554b3dbd2 100644 --- a/tests/standalone/nitro-test/ios/HybridChild.swift +++ b/tests/standalone/nitro-test/ios/HybridChild.swift @@ -6,8 +6,21 @@ // import NitroModules +import NitroTestExternal class HybridChild: HybridChildSpec { + required override init() { + super.init() + } + + static func createAlternativeBase() -> any HybridBaseSpec { + return HybridBase.createAlternativeBase() + } + + static func createInternalExternalObject() -> any HybridSomeExternalObjectSpec { + return HybridBase.createInternalExternalObject() + } + var baseValue: Double { return 20 } diff --git a/tests/standalone/nitro-test/ios/HybridGrandchild.swift b/tests/standalone/nitro-test/ios/HybridGrandchild.swift index c5b7403457..d2cf03d521 100644 --- a/tests/standalone/nitro-test/ios/HybridGrandchild.swift +++ b/tests/standalone/nitro-test/ios/HybridGrandchild.swift @@ -1,6 +1,19 @@ import NitroModules +import NitroTestExternal class HybridGrandchild: HybridGrandchildSpec { + required override init() { + super.init() + } + + static func createAlternativeBase() -> any HybridBaseSpec { + return HybridBase.createAlternativeBase() + } + + static func createInternalExternalObject() -> any HybridSomeExternalObjectSpec { + return HybridBase.createInternalExternalObject() + } + var baseValue: Double { return 20 } diff --git a/tests/standalone/nitro-test/ios/HybridPlatformObject.swift b/tests/standalone/nitro-test/ios/HybridPlatformObject.swift index 913c30686d..d6603a2c24 100644 --- a/tests/standalone/nitro-test/ios/HybridPlatformObject.swift +++ b/tests/standalone/nitro-test/ios/HybridPlatformObject.swift @@ -9,6 +9,10 @@ import NitroModules import Foundation class HybridPlatformObject: HybridPlatformObjectSpec { + required override init() { + super.init() + } + func getOSVersion() -> String { let version = ProcessInfo.processInfo.operatingSystemVersion let baseVersion = "\(version.majorVersion).\(version.minorVersion)" diff --git a/tests/standalone/nitro-test/ios/HybridSomeInternalObject.swift b/tests/standalone/nitro-test/ios/HybridSomeInternalObject.swift index 73bb22c8bc..686e2ce8d3 100644 --- a/tests/standalone/nitro-test/ios/HybridSomeInternalObject.swift +++ b/tests/standalone/nitro-test/ios/HybridSomeInternalObject.swift @@ -9,6 +9,10 @@ import NitroModules import NitroTestExternal class HybridSomeInternalObject: HybridSomeExternalObjectSpec { + required override init() { + super.init() + } + func getValue() throws -> String { return "This is overridden!" } diff --git a/tests/standalone/nitro-test/ios/HybridTestObjectSwift.swift b/tests/standalone/nitro-test/ios/HybridTestObjectSwift.swift index f593e6ec85..6d1774b183 100644 --- a/tests/standalone/nitro-test/ios/HybridTestObjectSwift.swift +++ b/tests/standalone/nitro-test/ios/HybridTestObjectSwift.swift @@ -13,6 +13,10 @@ import NitroTestExternal import os class HybridTestObjectSwift: HybridTestObjectSwiftKotlinSpec { + required override init() { + super.init() + } + static let readonlyNumber: Double = 42.0 private static let sharedNumberStorage = OSAllocatedUnfairLock(initialState: 0.0) static var sharedNumber: Double { diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBaseSpec.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBaseSpec.kt index 30b617ce61..5be7d1b34f 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBaseSpec.kt +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBaseSpec.kt @@ -68,9 +68,17 @@ abstract class HybridBaseSpec: HybridObject() { return CxxPart(this) } - companion object { + interface Companion { + fun createAlternativeBase(): HybridBaseSpec + fun createInternalExternalObject(): com.margelo.nitro.test.external.HybridSomeExternalObjectSpec + } + + companion object Bridge { protected const val TAG = "HybridBaseSpec" + private val implementationCompanion: Companion + get() = HybridBase + // Constructor @JvmStatic @DoNotStrip diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridChildSpec.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridChildSpec.kt index b2d735f63e..bf9f015119 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridChildSpec.kt +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridChildSpec.kt @@ -53,7 +53,9 @@ abstract class HybridChildSpec: HybridBaseSpec() { return CxxPart(this) } - companion object { + + + companion object Bridge { protected const val TAG = "HybridChildSpec" // Constructor diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridGrandchildSpec.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridGrandchildSpec.kt index 736a3d304c..d54e24d04b 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridGrandchildSpec.kt +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridGrandchildSpec.kt @@ -51,7 +51,9 @@ abstract class HybridGrandchildSpec: HybridChildSpec() { return CxxPart(this) } - companion object { + + + companion object Bridge { protected const val TAG = "HybridGrandchildSpec" // Constructor diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridPlatformObjectSpec.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridPlatformObjectSpec.kt index 2f442ebf5b..2519923b04 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridPlatformObjectSpec.kt +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridPlatformObjectSpec.kt @@ -51,7 +51,9 @@ abstract class HybridPlatformObjectSpec: HybridObject() { return CxxPart(this) } - companion object { + + + companion object Bridge { protected const val TAG = "HybridPlatformObjectSpec" // Constructor diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt index d89825d61c..b9eea58ce2 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt @@ -804,9 +804,17 @@ abstract class HybridTestObjectSwiftKotlinSpec: HybridObject() { return CxxPart(this) } - companion object { + interface Companion { + val readonlyNumber: Double + var sharedNumber: Double + } + + companion object Bridge { protected const val TAG = "HybridTestObjectSwiftKotlinSpec" + private val implementationCompanion: Companion + get() = HybridTestObjectKotlin + // Constructor @JvmStatic @DoNotStrip diff --git a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridBaseSpec.swift b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridBaseSpec.swift index 321c310202..bc8006f911 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridBaseSpec.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridBaseSpec.swift @@ -10,6 +10,10 @@ public import NitroTestExternal /// See ``HybridBaseSpec`` public protocol HybridBaseSpec_protocol: HybridObject { + init() throws + static func createAlternativeBase() throws -> (any HybridBaseSpec) + static func createInternalExternalObject() throws -> (any HybridSomeExternalObjectSpec) + // Properties var baseValue: Double { get } diff --git a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridChildSpec.swift b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridChildSpec.swift index 571ef00886..f2b8b09437 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridChildSpec.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridChildSpec.swift @@ -9,6 +9,8 @@ public import NitroModules /// See ``HybridChildSpec`` public protocol HybridChildSpec_protocol: HybridObject, HybridBaseSpec_protocol { + init() throws + // Properties var childValue: Double { get } diff --git a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridGrandchildSpec.swift b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridGrandchildSpec.swift index 2a8916aba8..3a8280639c 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridGrandchildSpec.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridGrandchildSpec.swift @@ -9,6 +9,8 @@ public import NitroModules /// See ``HybridGrandchildSpec`` public protocol HybridGrandchildSpec_protocol: HybridObject, HybridChildSpec_protocol { + init() throws + // Properties var grandchildValue: Double { get } diff --git a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridPlatformObjectSpec.swift b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridPlatformObjectSpec.swift index 46116dee78..d9473eed75 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridPlatformObjectSpec.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridPlatformObjectSpec.swift @@ -9,6 +9,8 @@ public import NitroModules /// See ``HybridPlatformObjectSpec`` public protocol HybridPlatformObjectSpec_protocol: HybridObject { + init() throws + // Properties diff --git a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift index ad5537685e..630efa80bd 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift @@ -10,6 +10,10 @@ public import NitroTestExternal /// See ``HybridTestObjectSwiftKotlinSpec`` public protocol HybridTestObjectSwiftKotlinSpec_protocol: HybridObject { + init() throws + static var readonlyNumber: Double { get } + static var sharedNumber: Double { get set } + // Properties var numberValue: Double { get set } var boolValue: Bool { get set } From 50fc3464cf0584d9092a0a3b2b5dce04c7e9740c Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Wed, 21 Oct 2026 12:25:59 +0200 Subject: [PATCH 2/2] refactor(nitrogen): organize static implementation contracts --- docs/docs/concepts/nitrogen.md | 7 ---- .../src/syntax/kotlin/KotlinHybridObject.ts | 40 +++++++++---------- .../src/syntax/swift/SwiftHybridObject.ts | 38 +++++++++--------- .../nitro/test/external/HybridTestViewSpec.kt | 8 +++- .../ios/swift/HybridTestViewSpec.swift | 7 ++++ .../HybridBenchmarkObjectSwiftKotlinSpec.kt | 8 +++- .../test/HybridRecyclableTestViewSpec.kt | 8 +++- .../margelo/nitro/test/HybridTestViewSpec.kt | 8 +++- ...HybridBenchmarkObjectSwiftKotlinSpec.swift | 7 ++++ .../swift/HybridRecyclableTestViewSpec.swift | 7 ++++ .../ios/swift/HybridTestViewSpec.swift | 7 ++++ .../nitro/test/external/HybridBaseSpec.kt | 8 +++- .../external/HybridSomeExternalObjectSpec.kt | 8 +++- .../generated/ios/swift/HybridBaseSpec.swift | 7 ++++ .../swift/HybridSomeExternalObjectSpec.swift | 7 ++++ .../com/margelo/nitro/test/HybridBaseSpec.kt | 7 +++- .../com/margelo/nitro/test/HybridChildSpec.kt | 8 +++- .../nitro/test/HybridGrandchildSpec.kt | 8 +++- .../nitro/test/HybridPlatformObjectSpec.kt | 8 +++- .../test/HybridTestObjectSwiftKotlinSpec.kt | 7 +++- .../generated/ios/swift/HybridBaseSpec.swift | 10 ++++- .../generated/ios/swift/HybridChildSpec.swift | 7 ++++ .../ios/swift/HybridGrandchildSpec.swift | 7 ++++ .../ios/swift/HybridPlatformObjectSpec.swift | 7 ++++ .../HybridTestObjectSwiftKotlinSpec.swift | 10 ++++- 25 files changed, 192 insertions(+), 62 deletions(-) diff --git a/docs/docs/concepts/nitrogen.md b/docs/docs/concepts/nitrogen.md index 3b24b30d83..7f98b6f9dc 100644 --- a/docs/docs/concepts/nitrogen.md +++ b/docs/docs/concepts/nitrogen.md @@ -358,13 +358,6 @@ To implement `Math` now, you just need to implement the spec: -The Swift protocol requires the declared constructors, static methods, and static properties. A non-final Swift implementation must mark -required initializers with `required`; when overriding the generated base initializer, use `required override init(...)`. - -For Kotlin specs with static members, the implementation's companion must implement `HybridMathSpec.Companion`. Missing companion -conformance or missing members fails compilation. Constructors are checked separately by the generated Kotlin factories, which call the -configured implementation directly. JNI calls generated `@JvmStatic` entry points on the spec. - ### 5. Use the Hybrid Objects Static methods are directly callable on the `Math` type: diff --git a/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts b/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts index 28cdc3480d..a2d339b150 100644 --- a/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts +++ b/packages/nitrogen/src/syntax/kotlin/KotlinHybridObject.ts @@ -32,8 +32,14 @@ export function createKotlinHybridObject(publicSpec: HybridObjectSpec<'kotlin'>) const name = getHybridObjectName(spec.name) const properties = spec.properties.map(getKotlinPropertyCode).join('\n\n') const methods = spec.methods.map(getKotlinMethodCode).join('\n\n') - const companion = getKotlinCompanion(spec) - const companionContract = getKotlinCompanionInterface(spec) + const companionProperties = spec.staticProperties.map((property) => property.getCode('kotlin')).join('\n\n') + const companionMethods = spec.staticMethods + .map((method) => { + const requirement = new InstanceMethod(method.name, method.returnType, method.parameters) + return requirement.getDeclaration('kotlin') + }) + .join('\n\n') + const bridgeCompanion = getKotlinCompanion(spec) const extraImports: SourceImport[] = [ ...spec.properties.flatMap((p) => p.getRequiredImports('kotlin')), @@ -41,7 +47,7 @@ export function createKotlinHybridObject(publicSpec: HybridObjectSpec<'kotlin'>) ...spec.methods.flatMap((m) => m.getRequiredImports('kotlin')), ...spec.staticMethods.flatMap((m) => m.getRequiredImports('kotlin')), ...(spec.constructor?.getRequiredImports('kotlin') ?? []), - ...companion.imports, + ...bridgeCompanion.imports, ...spec.baseTypes.flatMap((b) => new HybridObjectType(b).getRequiredImports('kotlin')), { name: 'com.margelo.nitro.core.HybridObject', @@ -126,10 +132,16 @@ abstract class ${name.HybridTSpec}: ${supertypes} { return CxxPart(this) } - ${indent(companionContract, ' ')} + interface Companion { + // Static Properties + ${indent(companionProperties, ' ')} + + // Static Methods + ${indent(companionMethods, ' ')} + } - companion object Bridge { - ${indent(companion.code, ' ')} + protected companion object Bridge { + ${indent(bridgeCompanion.code, ' ')} } } `.trim() @@ -196,6 +208,7 @@ protected const val TAG = "${name.HybridTSpec}" }) } const sections = [tagCode] + // Only static members require a companion; instance-only specs may have no configured implementation. if (spec.staticMethods.length > 0 || spec.staticProperties.length > 0) { const implementation = getKotlinImplementation(spec) // Check the configured companion's contract; forwarders still call it directly. @@ -256,18 +269,3 @@ function getImplementedInterfaceImport(implementedInterface: KotlinImplementedIn language: 'kotlin', } } - -function getKotlinCompanionInterface(spec: HybridObjectSpec<'kotlin'>): string { - const declarations = spec.staticProperties.map((property) => property.getCode('kotlin')) - const methods = spec.staticMethods.map((method) => { - const requirement = new InstanceMethod(method.name, method.returnType, method.parameters) - return requirement.getDeclaration('kotlin') - }) - declarations.push(...methods) - if (declarations.length === 0) return '' - return ` -interface Companion { - ${indent(declarations.join('\n'), ' ')} -} -`.trim() -} diff --git a/packages/nitrogen/src/syntax/swift/SwiftHybridObject.ts b/packages/nitrogen/src/syntax/swift/SwiftHybridObject.ts index a9a7949dc2..651c489b26 100644 --- a/packages/nitrogen/src/syntax/swift/SwiftHybridObject.ts +++ b/packages/nitrogen/src/syntax/swift/SwiftHybridObject.ts @@ -19,9 +19,19 @@ export function createSwiftHybridObject(spec: HybridObjectSpec<'swift'>): Source const conformances = swiftType.getProtocolConformances() const name = getHybridObjectName(spec.name) const protocolName = name.HybridTSpec + const constructor = spec.constructor?.getDeclaration('swift') ?? '' const properties = spec.properties.map((p) => p.getCode('swift')).join('\n') const methods = spec.methods.map((method) => method.getDeclaration('swift')).join('\n') - const classMembers = getSwiftClassRequirements(spec) + const staticProperties = spec.staticProperties.map((property) => property.getCode('swift')).join('\n') + const staticMethods = spec.staticMethods + .map((method) => { + const requirement = new StaticMethod(method.name, method.returnType, method.parameters, { + ...method.options, + protocolRequirement: true, + }) + return requirement.getDeclaration('swift') + }) + .join('\n') const extraImports = [ ...spec.properties.flatMap((p) => p.getRequiredImports('swift')), ...spec.staticProperties.flatMap((p) => p.getRequiredImports('swift')), @@ -88,13 +98,20 @@ ${imports} /// See \`\`${protocolName}\`\` public protocol ${protocolName}_protocol: ${protocolBaseClasses.join(', ')} { - ${indent(classMembers, ' ')} + // Constructor + ${indent(constructor, ' ')} // Properties ${indent(properties, ' ')} // Methods ${indent(methods, ' ')} + + // Static Properties + ${indent(staticProperties, ' ')} + + // Static Methods + ${indent(staticMethods, ' ')} } public extension ${protocolName}_protocol { @@ -141,20 +158,3 @@ public typealias ${protocolName} = ${protocolName}_protocol & ${protocolName}_ba return files } - -function getSwiftClassRequirements(spec: HybridObjectSpec<'swift'>): string { - const declarations: string[] = [] - if (spec.constructor != null) { - declarations.push(spec.constructor.getDeclaration('swift')) - } - declarations.push(...spec.staticProperties.map((property) => property.getCode('swift'))) - const staticMethods = spec.staticMethods.map((method) => { - const requirement = new StaticMethod(method.name, method.returnType, method.parameters, { - ...method.options, - protocolRequirement: true, - }) - return requirement.getDeclaration('swift') - }) - declarations.push(...staticMethods) - return declarations.join('\n') -} diff --git a/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridTestViewSpec.kt b/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridTestViewSpec.kt index 0f6cb897b2..b8089511fb 100644 --- a/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridTestViewSpec.kt +++ b/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridTestViewSpec.kt @@ -73,9 +73,15 @@ abstract class HybridTestViewSpec: HybridView() { return CxxPart(this) } + interface Companion { + // Static Properties - companion object Bridge { + // Static Methods + + } + + protected companion object Bridge { protected const val TAG = "HybridTestViewSpec" } } diff --git a/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/ios/swift/HybridTestViewSpec.swift b/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/ios/swift/HybridTestViewSpec.swift index ae8dc3cf2f..266a60a068 100644 --- a/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/ios/swift/HybridTestViewSpec.swift +++ b/tests/react-native/packages/react-native-nitro-test-external/nitrogen/generated/ios/swift/HybridTestViewSpec.swift @@ -9,6 +9,7 @@ public import NitroModules /// See ``HybridTestViewSpec`` public protocol HybridTestViewSpec_protocol: HybridObject, HybridView { + // Constructor // Properties @@ -18,6 +19,12 @@ public protocol HybridTestViewSpec_protocol: HybridObject, HybridView { // Methods func someMethod() throws -> Void func getModuleName() throws -> String + + // Static Properties + + + // Static Methods + } public extension HybridTestViewSpec_protocol { diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBenchmarkObjectSwiftKotlinSpec.kt b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBenchmarkObjectSwiftKotlinSpec.kt index 58326bb101..7f6515505f 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBenchmarkObjectSwiftKotlinSpec.kt +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBenchmarkObjectSwiftKotlinSpec.kt @@ -122,9 +122,15 @@ abstract class HybridBenchmarkObjectSwiftKotlinSpec: HybridObject() { return CxxPart(this) } + interface Companion { + // Static Properties - companion object Bridge { + // Static Methods + + } + + protected companion object Bridge { protected const val TAG = "HybridBenchmarkObjectSwiftKotlinSpec" // Constructor diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridRecyclableTestViewSpec.kt b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridRecyclableTestViewSpec.kt index 568f9ad787..e932e149c3 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridRecyclableTestViewSpec.kt +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridRecyclableTestViewSpec.kt @@ -73,9 +73,15 @@ abstract class HybridRecyclableTestViewSpec: HybridView() { return CxxPart(this) } + interface Companion { + // Static Properties - companion object Bridge { + // Static Methods + + } + + protected companion object Bridge { protected const val TAG = "HybridRecyclableTestViewSpec" } } diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestViewSpec.kt b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestViewSpec.kt index c614727a3b..da74b49caa 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestViewSpec.kt +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestViewSpec.kt @@ -109,9 +109,15 @@ abstract class HybridTestViewSpec: HybridView() { return CxxPart(this) } + interface Companion { + // Static Properties - companion object Bridge { + // Static Methods + + } + + protected companion object Bridge { protected const val TAG = "HybridTestViewSpec" } } diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridBenchmarkObjectSwiftKotlinSpec.swift b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridBenchmarkObjectSwiftKotlinSpec.swift index 4aac21a9c3..279570d3f9 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridBenchmarkObjectSwiftKotlinSpec.swift +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridBenchmarkObjectSwiftKotlinSpec.swift @@ -9,6 +9,7 @@ public import NitroModules /// See ``HybridBenchmarkObjectSwiftKotlinSpec`` public protocol HybridBenchmarkObjectSwiftKotlinSpec_protocol: HybridObject { + // Constructor init() throws // Properties @@ -31,6 +32,12 @@ public protocol HybridBenchmarkObjectSwiftKotlinSpec_protocol: HybridObject { func createPendingPromise() throws -> any Promise func resolvePendingPromiseOnWorker() throws -> Void func newBenchmarkObject() throws -> (any HybridBenchmarkObjectSwiftKotlinSpec) + + // Static Properties + + + // Static Methods + } public extension HybridBenchmarkObjectSwiftKotlinSpec_protocol { diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridRecyclableTestViewSpec.swift b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridRecyclableTestViewSpec.swift index 4a257caa99..5b90e4696d 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridRecyclableTestViewSpec.swift +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridRecyclableTestViewSpec.swift @@ -9,6 +9,7 @@ public import NitroModules /// See ``HybridRecyclableTestViewSpec`` public protocol HybridRecyclableTestViewSpec_protocol: HybridObject, HybridView { + // Constructor // Properties @@ -20,6 +21,12 @@ public protocol HybridRecyclableTestViewSpec_protocol: HybridObject, HybridView func getOnDropViewCount() throws -> Double func getPrepareForRecycleCount() throws -> Double func getNativeDefaultValueSetterCallCount() throws -> Double + + // Static Properties + + + // Static Methods + } public extension HybridRecyclableTestViewSpec_protocol { diff --git a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestViewSpec.swift b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestViewSpec.swift index 2f03299763..e3c6539709 100644 --- a/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestViewSpec.swift +++ b/tests/react-native/packages/react-native-nitro-test/nitrogen/generated/ios/swift/HybridTestViewSpec.swift @@ -9,6 +9,7 @@ public import NitroModules /// See ``HybridTestViewSpec`` public protocol HybridTestViewSpec_protocol: HybridObject, HybridView { + // Constructor // Properties @@ -25,6 +26,12 @@ public protocol HybridTestViewSpec_protocol: HybridObject, HybridView { func getIsBlueSetterCallCount() throws -> Double func getNativeDefaultValueSetterCallCount() throws -> Double func someMethod() throws -> Void + + // Static Properties + + + // Static Methods + } public extension HybridTestViewSpec_protocol { diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridBaseSpec.kt b/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridBaseSpec.kt index 8bff16a5f9..eef7ed12c2 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridBaseSpec.kt +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridBaseSpec.kt @@ -67,9 +67,15 @@ abstract class HybridBaseSpec: HybridObject() { return CxxPart(this) } + interface Companion { + // Static Properties - companion object Bridge { + // Static Methods + + } + + protected companion object Bridge { protected const val TAG = "HybridBaseSpec" // Constructor diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridSomeExternalObjectSpec.kt b/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridSomeExternalObjectSpec.kt index 25e1223424..529b075e30 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridSomeExternalObjectSpec.kt +++ b/tests/standalone/nitro-test-external/nitrogen/generated/android/kotlin/com/margelo/nitro/test/external/HybridSomeExternalObjectSpec.kt @@ -60,9 +60,15 @@ abstract class HybridSomeExternalObjectSpec: HybridObject() { return CxxPart(this) } + interface Companion { + // Static Properties - companion object Bridge { + // Static Methods + + } + + protected companion object Bridge { protected const val TAG = "HybridSomeExternalObjectSpec" // Constructor diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridBaseSpec.swift b/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridBaseSpec.swift index 2cdc9038ae..48d798668a 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridBaseSpec.swift +++ b/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridBaseSpec.swift @@ -9,6 +9,7 @@ public import NitroModules /// See ``HybridBaseSpec`` public protocol HybridBaseSpec_protocol: HybridObject { + // Constructor init() throws // Properties @@ -18,6 +19,12 @@ public protocol HybridBaseSpec_protocol: HybridObject { func bounceSize(size: Size) throws -> Size func bounceSizeUnit(unit: SizeUnit) throws -> SizeUnit func mapSize(size: Size, callback: any Callback<(/* size */ Size), Size>) throws -> any Promise + + // Static Properties + + + // Static Methods + } public extension HybridBaseSpec_protocol { diff --git a/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridSomeExternalObjectSpec.swift b/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridSomeExternalObjectSpec.swift index f1c6451450..687cce4df6 100644 --- a/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridSomeExternalObjectSpec.swift +++ b/tests/standalone/nitro-test-external/nitrogen/generated/ios/swift/HybridSomeExternalObjectSpec.swift @@ -9,6 +9,7 @@ public import NitroModules /// See ``HybridSomeExternalObjectSpec`` public protocol HybridSomeExternalObjectSpec_protocol: HybridObject { + // Constructor init() throws // Properties @@ -17,6 +18,12 @@ public protocol HybridSomeExternalObjectSpec_protocol: HybridObject { // Methods func getValue() throws -> String func createOptionalPrimitivesHolder(optionalNumber: Double?, optionalBoolean: Bool?, optionalUInt64: UInt64?, optionalInt64: Int64?) throws -> OptionalPrimitivesHolder + + // Static Properties + + + // Static Methods + } public extension HybridSomeExternalObjectSpec_protocol { diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBaseSpec.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBaseSpec.kt index 5be7d1b34f..2c010e1b79 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBaseSpec.kt +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridBaseSpec.kt @@ -69,11 +69,16 @@ abstract class HybridBaseSpec: HybridObject() { } interface Companion { + // Static Properties + + + // Static Methods fun createAlternativeBase(): HybridBaseSpec + fun createInternalExternalObject(): com.margelo.nitro.test.external.HybridSomeExternalObjectSpec } - companion object Bridge { + protected companion object Bridge { protected const val TAG = "HybridBaseSpec" private val implementationCompanion: Companion diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridChildSpec.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridChildSpec.kt index bf9f015119..8a4494d1ba 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridChildSpec.kt +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridChildSpec.kt @@ -53,9 +53,15 @@ abstract class HybridChildSpec: HybridBaseSpec() { return CxxPart(this) } + interface Companion { + // Static Properties - companion object Bridge { + // Static Methods + + } + + protected companion object Bridge { protected const val TAG = "HybridChildSpec" // Constructor diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridGrandchildSpec.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridGrandchildSpec.kt index d54e24d04b..47716c077d 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridGrandchildSpec.kt +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridGrandchildSpec.kt @@ -51,9 +51,15 @@ abstract class HybridGrandchildSpec: HybridChildSpec() { return CxxPart(this) } + interface Companion { + // Static Properties - companion object Bridge { + // Static Methods + + } + + protected companion object Bridge { protected const val TAG = "HybridGrandchildSpec" // Constructor diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridPlatformObjectSpec.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridPlatformObjectSpec.kt index 2519923b04..5c71bcadbd 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridPlatformObjectSpec.kt +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridPlatformObjectSpec.kt @@ -51,9 +51,15 @@ abstract class HybridPlatformObjectSpec: HybridObject() { return CxxPart(this) } + interface Companion { + // Static Properties - companion object Bridge { + // Static Methods + + } + + protected companion object Bridge { protected const val TAG = "HybridPlatformObjectSpec" // Constructor diff --git a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt index b9eea58ce2..383569354b 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt +++ b/tests/standalone/nitro-test/nitrogen/generated/android/kotlin/com/margelo/nitro/test/HybridTestObjectSwiftKotlinSpec.kt @@ -805,11 +805,16 @@ abstract class HybridTestObjectSwiftKotlinSpec: HybridObject() { } interface Companion { + // Static Properties val readonlyNumber: Double + var sharedNumber: Double + + // Static Methods + } - companion object Bridge { + protected companion object Bridge { protected const val TAG = "HybridTestObjectSwiftKotlinSpec" private val implementationCompanion: Companion diff --git a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridBaseSpec.swift b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridBaseSpec.swift index bc8006f911..9eed5a3cbc 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridBaseSpec.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridBaseSpec.swift @@ -10,9 +10,8 @@ public import NitroTestExternal /// See ``HybridBaseSpec`` public protocol HybridBaseSpec_protocol: HybridObject { + // Constructor init() throws - static func createAlternativeBase() throws -> (any HybridBaseSpec) - static func createInternalExternalObject() throws -> (any HybridSomeExternalObjectSpec) // Properties var baseValue: Double { get } @@ -21,6 +20,13 @@ public protocol HybridBaseSpec_protocol: HybridObject { func bounceSize(size: Size) throws -> Size func bounceSizeUnit(unit: SizeUnit) throws -> SizeUnit func mapSize(size: Size, callback: any Callback<(/* size */ Size), Size>) throws -> any Promise + + // Static Properties + + + // Static Methods + static func createAlternativeBase() throws -> (any HybridBaseSpec) + static func createInternalExternalObject() throws -> (any HybridSomeExternalObjectSpec) } public extension HybridBaseSpec_protocol { diff --git a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridChildSpec.swift b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridChildSpec.swift index f2b8b09437..fb95dca8f6 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridChildSpec.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridChildSpec.swift @@ -9,6 +9,7 @@ public import NitroModules /// See ``HybridChildSpec`` public protocol HybridChildSpec_protocol: HybridObject, HybridBaseSpec_protocol { + // Constructor init() throws // Properties @@ -16,6 +17,12 @@ public protocol HybridChildSpec_protocol: HybridObject, HybridBaseSpec_protocol // Methods func bounceVariant(variant: NamedVariant) throws -> NamedVariant + + // Static Properties + + + // Static Methods + } public extension HybridChildSpec_protocol { diff --git a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridGrandchildSpec.swift b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridGrandchildSpec.swift index 3a8280639c..f1d977d350 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridGrandchildSpec.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridGrandchildSpec.swift @@ -9,6 +9,7 @@ public import NitroModules /// See ``HybridGrandchildSpec`` public protocol HybridGrandchildSpec_protocol: HybridObject, HybridChildSpec_protocol { + // Constructor init() throws // Properties @@ -16,6 +17,12 @@ public protocol HybridGrandchildSpec_protocol: HybridObject, HybridChildSpec_pro // Methods + + // Static Properties + + + // Static Methods + } public extension HybridGrandchildSpec_protocol { diff --git a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridPlatformObjectSpec.swift b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridPlatformObjectSpec.swift index d9473eed75..ab9cf2a362 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridPlatformObjectSpec.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridPlatformObjectSpec.swift @@ -9,6 +9,7 @@ public import NitroModules /// See ``HybridPlatformObjectSpec`` public protocol HybridPlatformObjectSpec_protocol: HybridObject { + // Constructor init() throws // Properties @@ -16,6 +17,12 @@ public protocol HybridPlatformObjectSpec_protocol: HybridObject { // Methods func getOSVersion() throws -> String + + // Static Properties + + + // Static Methods + } public extension HybridPlatformObjectSpec_protocol { diff --git a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift index 630efa80bd..1e318b1818 100644 --- a/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift +++ b/tests/standalone/nitro-test/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift @@ -10,9 +10,8 @@ public import NitroTestExternal /// See ``HybridTestObjectSwiftKotlinSpec`` public protocol HybridTestObjectSwiftKotlinSpec_protocol: HybridObject { + // Constructor init() throws - static var readonlyNumber: Double { get } - static var sharedNumber: Double { get set } // Properties var numberValue: Double { get set } @@ -162,6 +161,13 @@ public protocol HybridTestObjectSwiftKotlinSpec_protocol: HybridObject { func newTestObject() throws -> (any HybridTestObjectSwiftKotlinSpec) func newTestObjectAsync() throws -> any Promise<(any HybridTestObjectSwiftKotlinSpec)> func getVariantHybrid(variant: Variant__any_HybridTestObjectSwiftKotlinSpec__Person) throws -> Variant__any_HybridTestObjectSwiftKotlinSpec__Person + + // Static Properties + static var readonlyNumber: Double { get } + static var sharedNumber: Double { get set } + + // Static Methods + } public extension HybridTestObjectSwiftKotlinSpec_protocol {