nitrogen 0.31.1 → 0.31.3
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/config/nitrogenVersion.d.ts +1 -0
- package/lib/config/nitrogenVersion.js +2 -0
- package/lib/createPlatformSpec.js +8 -0
- package/lib/getPlatformSpecs.d.ts +3 -2
- package/lib/getPlatformSpecs.js +12 -10
- package/lib/index.js +2 -1
- package/lib/nitrogen.js +6 -15
- package/lib/syntax/Method.js +4 -0
- package/lib/syntax/c++/CppHybridObject.js +4 -2
- package/lib/syntax/createType.js +6 -6
- package/lib/syntax/isMemberOverridingFromBase.d.ts +11 -0
- package/lib/syntax/isMemberOverridingFromBase.js +64 -0
- package/lib/syntax/isOverridingFromBase.d.ts +11 -0
- package/lib/syntax/isOverridingFromBase.js +64 -0
- package/lib/syntax/kotlin/FbjniHybridObject.js +7 -0
- package/lib/syntax/kotlin/KotlinHybridObject.js +12 -2
- package/lib/syntax/kotlin/KotlinStruct.js +49 -14
- package/lib/syntax/kotlin/isBaseObjectMethodName.d.ts +7 -0
- package/lib/syntax/kotlin/isBaseObjectMethodName.js +9 -0
- package/lib/syntax/swift/SwiftCxxBridgedType.js +5 -29
- package/lib/syntax/swift/SwiftCxxTypeHelper.js +2 -28
- package/lib/syntax/swift/SwiftHybridObject.js +8 -1
- package/lib/syntax/swift/SwiftHybridObjectBridge.js +12 -1
- package/lib/syntax/types/AnyHybridObjectType.d.ts +11 -0
- package/lib/syntax/types/AnyHybridObjectType.js +40 -0
- package/lib/utils.d.ts +0 -1
- package/lib/utils.js +0 -1
- package/package.json +2 -2
- package/src/config/nitrogenVersion.ts +3 -0
- package/src/createPlatformSpec.ts +16 -0
- package/src/getPlatformSpecs.ts +24 -15
- package/src/index.ts +2 -1
- package/src/nitrogen.ts +6 -17
- package/src/syntax/Method.ts +6 -0
- package/src/syntax/c++/CppHybridObject.ts +7 -2
- package/src/syntax/createType.ts +5 -5
- package/src/syntax/isMemberOverridingFromBase.ts +79 -0
- package/src/syntax/kotlin/FbjniHybridObject.ts +7 -0
- package/src/syntax/kotlin/KotlinHybridObject.ts +12 -2
- package/src/syntax/kotlin/KotlinStruct.ts +61 -15
- package/src/syntax/swift/SwiftCxxBridgedType.ts +5 -27
- package/src/syntax/swift/SwiftCxxTypeHelper.ts +2 -27
- package/src/syntax/swift/SwiftHybridObject.ts +8 -1
- package/src/syntax/swift/SwiftHybridObjectBridge.ts +12 -1
- package/src/syntax/types/{HybridObjectBaseType.ts → AnyHybridObjectType.ts} +2 -9
- package/src/utils.ts +0 -2
- package/src/syntax/swift/isPrimitivelyCopyable.ts +0 -20
|
@@ -7,29 +7,44 @@ import type { SourceFile } from '../SourceFile.js'
|
|
|
7
7
|
import type { StructType } from '../types/StructType.js'
|
|
8
8
|
import { KotlinCxxBridgedType } from './KotlinCxxBridgedType.js'
|
|
9
9
|
|
|
10
|
+
interface BridgedProperty {
|
|
11
|
+
name: string
|
|
12
|
+
type: KotlinCxxBridgedType
|
|
13
|
+
}
|
|
14
|
+
|
|
10
15
|
export function createKotlinStruct(structType: StructType): SourceFile[] {
|
|
11
16
|
const packageName = NitroConfig.current.getAndroidPackage('java/kotlin')
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
|
|
18
|
+
const bridgedProperties = structType.properties.map<BridgedProperty>((p) => ({
|
|
19
|
+
name: p.escapedName,
|
|
20
|
+
type: new KotlinCxxBridgedType(p),
|
|
21
|
+
}))
|
|
22
|
+
// const parameters = structType.properties
|
|
23
|
+
// .map((p) =>
|
|
24
|
+
// `
|
|
25
|
+
// @DoNotStrip
|
|
26
|
+
// @Keep
|
|
27
|
+
// val ${p.escapedName}: ${p.getCode('kotlin')}
|
|
28
|
+
// `.trim()
|
|
29
|
+
// )
|
|
30
|
+
// .join(',\n')
|
|
31
|
+
const properties = bridgedProperties
|
|
32
|
+
.map(({ name, type }) => {
|
|
33
|
+
return `
|
|
15
34
|
@DoNotStrip
|
|
16
35
|
@Keep
|
|
17
|
-
val ${
|
|
36
|
+
val ${name}: ${type.getTypeCode('kotlin', false)}
|
|
18
37
|
`.trim()
|
|
19
|
-
)
|
|
38
|
+
})
|
|
20
39
|
.join(',\n')
|
|
21
40
|
|
|
22
|
-
const cxxCreateFunctionParameters =
|
|
23
|
-
.map((
|
|
24
|
-
|
|
25
|
-
return `${p.escapedName}: ${bridged.getTypeCode('kotlin', false)}`
|
|
41
|
+
const cxxCreateFunctionParameters = bridgedProperties
|
|
42
|
+
.map(({ name, type }) => {
|
|
43
|
+
return `${name}: ${type.getTypeCode('kotlin', false)}`
|
|
26
44
|
})
|
|
27
45
|
.join(', ')
|
|
28
|
-
const cxxCreateFunctionForward =
|
|
29
|
-
.map((p) =>
|
|
30
|
-
const bridged = new KotlinCxxBridgedType(p)
|
|
31
|
-
return bridged.parseFromCppToKotlin(p.escapedName, 'kotlin', false)
|
|
32
|
-
})
|
|
46
|
+
const cxxCreateFunctionForward = bridgedProperties
|
|
47
|
+
.map((p) => p.name)
|
|
33
48
|
.join(', ')
|
|
34
49
|
|
|
35
50
|
const extraImports = structType.properties
|
|
@@ -37,6 +52,8 @@ val ${p.escapedName}: ${p.getCode('kotlin')}
|
|
|
37
52
|
.map((i) => `import ${i.name}`)
|
|
38
53
|
.filter(isNotDuplicate)
|
|
39
54
|
|
|
55
|
+
const secondaryConstructor = createKotlinConstructor(structType)
|
|
56
|
+
|
|
40
57
|
const code = `
|
|
41
58
|
${createFileMetadataString(`${structType.structName}.kt`)}
|
|
42
59
|
|
|
@@ -52,8 +69,10 @@ ${extraImports.join('\n')}
|
|
|
52
69
|
@DoNotStrip
|
|
53
70
|
@Keep
|
|
54
71
|
data class ${structType.structName}(
|
|
55
|
-
${indent(
|
|
72
|
+
${indent(properties, ' ')}
|
|
56
73
|
) {
|
|
74
|
+
${indent(secondaryConstructor, ' ')}
|
|
75
|
+
|
|
57
76
|
private companion object {
|
|
58
77
|
/**
|
|
59
78
|
* Constructor called from C++
|
|
@@ -150,6 +169,33 @@ namespace ${cxxNamespace} {
|
|
|
150
169
|
return files
|
|
151
170
|
}
|
|
152
171
|
|
|
172
|
+
function createKotlinConstructor(structType: StructType): string {
|
|
173
|
+
const bridgedProperties = structType.properties.map<BridgedProperty>((p) => ({
|
|
174
|
+
name: p.escapedName,
|
|
175
|
+
type: new KotlinCxxBridgedType(p),
|
|
176
|
+
}))
|
|
177
|
+
const needsSpecialHandling = bridgedProperties.some(
|
|
178
|
+
({ type }) => type.needsSpecialHandling
|
|
179
|
+
)
|
|
180
|
+
if (needsSpecialHandling) {
|
|
181
|
+
const kotlinParams = structType.properties.map(
|
|
182
|
+
(p) => `${p.escapedName}: ${p.getCode('kotlin')}`
|
|
183
|
+
)
|
|
184
|
+
const paramsForward = bridgedProperties.map(({ name, type }) =>
|
|
185
|
+
type.parseFromKotlinToCpp(name, 'kotlin')
|
|
186
|
+
)
|
|
187
|
+
return `
|
|
188
|
+
/**
|
|
189
|
+
* Create a new instance of ${structType.structName} from Kotlin
|
|
190
|
+
*/
|
|
191
|
+
constructor(${kotlinParams.join(', ')}):
|
|
192
|
+
this(${paramsForward.join(', ')})
|
|
193
|
+
`.trim()
|
|
194
|
+
} else {
|
|
195
|
+
return `/* primary constructor */`
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
153
199
|
function createJNIStructInitializer(structType: StructType): string {
|
|
154
200
|
const lines: string[] = ['static const auto clazz = javaClassStatic();']
|
|
155
201
|
for (const prop of structType.properties) {
|
|
@@ -32,7 +32,6 @@ import { NamedWrappingType } from '../types/NamedWrappingType.js'
|
|
|
32
32
|
import { ErrorType } from '../types/ErrorType.js'
|
|
33
33
|
import { createSwiftFunctionBridge } from './SwiftFunction.js'
|
|
34
34
|
import type { Language } from '../../getPlatformSpecs.js'
|
|
35
|
-
import { isPrimitivelyCopyable } from './isPrimitivelyCopyable.js'
|
|
36
35
|
|
|
37
36
|
// TODO: Remove enum bridge once Swift fixes bidirectional enums crashing the `-Swift.h` header.
|
|
38
37
|
|
|
@@ -490,20 +489,8 @@ export class SwiftCxxBridgedType implements BridgedType<'swift', 'c++'> {
|
|
|
490
489
|
const wrapping = new SwiftCxxBridgedType(array.itemType, true)
|
|
491
490
|
switch (language) {
|
|
492
491
|
case 'swift':
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
const bridge = this.getBridgeOrThrow()
|
|
496
|
-
const getDataFunc = `bridge.get_data_${bridge.specializationName}`
|
|
497
|
-
return `
|
|
498
|
-
{ () -> ${array.getCode('swift')} in
|
|
499
|
-
let __data = ${getDataFunc}(${cppParameterName})
|
|
500
|
-
let __size = ${cppParameterName}.size()
|
|
501
|
-
return Array(UnsafeBufferPointer(start: __data, count: __size))
|
|
502
|
-
}()`.trim()
|
|
503
|
-
} else {
|
|
504
|
-
// We have to iterate the element one by one to create a resulting Array (mapped)
|
|
505
|
-
return `${cppParameterName}.map({ __item in ${wrapping.parseFromCppToSwift('__item', 'swift')} })`.trim()
|
|
506
|
-
}
|
|
492
|
+
// We have to iterate the element one by one to create a resulting Array (mapped)
|
|
493
|
+
return `${cppParameterName}.map({ __item in ${wrapping.parseFromCppToSwift('__item', 'swift')} })`.trim()
|
|
507
494
|
default:
|
|
508
495
|
return cppParameterName
|
|
509
496
|
}
|
|
@@ -764,17 +751,9 @@ case ${i}:
|
|
|
764
751
|
const wrapping = new SwiftCxxBridgedType(array.itemType, true)
|
|
765
752
|
switch (language) {
|
|
766
753
|
case 'swift':
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
return `
|
|
771
|
-
${swiftParameterName}.withUnsafeBufferPointer { __pointer -> bridge.${bridge.specializationName} in
|
|
772
|
-
return ${copyFunc}(__pointer.baseAddress!, ${swiftParameterName}.count)
|
|
773
|
-
}`.trim()
|
|
774
|
-
} else {
|
|
775
|
-
// array has to be iterated and converted one-by-one
|
|
776
|
-
const makeFunc = `bridge.${bridge.funcName}`
|
|
777
|
-
return `
|
|
754
|
+
// array has to be iterated and converted one-by-one
|
|
755
|
+
const makeFunc = `bridge.${bridge.funcName}`
|
|
756
|
+
return `
|
|
778
757
|
{ () -> bridge.${bridge.specializationName} in
|
|
779
758
|
var __vector = ${makeFunc}(${swiftParameterName}.count)
|
|
780
759
|
for __item in ${swiftParameterName} {
|
|
@@ -782,7 +761,6 @@ ${swiftParameterName}.withUnsafeBufferPointer { __pointer -> bridge.${bridge.spe
|
|
|
782
761
|
}
|
|
783
762
|
return __vector
|
|
784
763
|
}()`.trim()
|
|
785
|
-
}
|
|
786
764
|
default:
|
|
787
765
|
return swiftParameterName
|
|
788
766
|
}
|
|
@@ -19,7 +19,6 @@ import { VoidType } from '../types/VoidType.js'
|
|
|
19
19
|
import { NamedWrappingType } from '../types/NamedWrappingType.js'
|
|
20
20
|
import { ErrorType } from '../types/ErrorType.js'
|
|
21
21
|
import { ResultWrappingType } from '../types/ResultWrappingType.js'
|
|
22
|
-
import { isPrimitivelyCopyable } from './isPrimitivelyCopyable.js'
|
|
23
22
|
|
|
24
23
|
export interface SwiftCxxHelper {
|
|
25
24
|
cxxHeader: {
|
|
@@ -268,26 +267,8 @@ function createCxxVectorSwiftHelper(type: ArrayType): SwiftCxxHelper {
|
|
|
268
267
|
const actualType = type.getCode('c++')
|
|
269
268
|
const bridgedType = new SwiftCxxBridgedType(type)
|
|
270
269
|
const name = escapeCppName(actualType)
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
if (isPrimitivelyCopyable(type.itemType)) {
|
|
274
|
-
const itemType = type.itemType.getCode('c++')
|
|
275
|
-
funcName = `copy_${name}`
|
|
276
|
-
code = `
|
|
277
|
-
/**
|
|
278
|
-
* Specialized version of \`${escapeComments(actualType)}\`.
|
|
279
|
-
*/
|
|
280
|
-
using ${name} = ${actualType};
|
|
281
|
-
inline ${actualType} copy_${name}(const ${itemType}* CONTIGUOUS_MEMORY NON_NULL data, size_t size) noexcept {
|
|
282
|
-
return margelo::nitro::FastVectorCopy<${itemType}>(data, size);
|
|
283
|
-
}
|
|
284
|
-
inline const ${itemType}* CONTIGUOUS_MEMORY NON_NULL get_data_${name}(const ${actualType}& vector) noexcept {
|
|
285
|
-
return vector.data();
|
|
286
|
-
}
|
|
287
|
-
`.trim()
|
|
288
|
-
} else {
|
|
289
|
-
funcName = `create_${name}`
|
|
290
|
-
code = `
|
|
270
|
+
const funcName = `create_${name}`
|
|
271
|
+
const code = `
|
|
291
272
|
/**
|
|
292
273
|
* Specialized version of \`${escapeComments(actualType)}\`.
|
|
293
274
|
*/
|
|
@@ -297,7 +278,6 @@ inline ${actualType} create_${name}(size_t size) noexcept {
|
|
|
297
278
|
vector.reserve(size);
|
|
298
279
|
return vector;
|
|
299
280
|
}`.trim()
|
|
300
|
-
}
|
|
301
281
|
|
|
302
282
|
return {
|
|
303
283
|
cxxType: actualType,
|
|
@@ -311,11 +291,6 @@ inline ${actualType} create_${name}(size_t size) noexcept {
|
|
|
311
291
|
space: 'system',
|
|
312
292
|
language: 'c++',
|
|
313
293
|
},
|
|
314
|
-
{
|
|
315
|
-
name: 'NitroModules/FastVectorCopy.hpp',
|
|
316
|
-
space: 'system',
|
|
317
|
-
language: 'c++',
|
|
318
|
-
},
|
|
319
294
|
...bridgedType.getRequiredImports('c++'),
|
|
320
295
|
],
|
|
321
296
|
},
|
|
@@ -11,7 +11,7 @@ export function createSwiftHybridObject(spec: HybridObjectSpec): SourceFile[] {
|
|
|
11
11
|
const name = getHybridObjectName(spec.name)
|
|
12
12
|
const protocolName = name.HybridTSpec
|
|
13
13
|
const properties = spec.properties.map((p) => p.getCode('swift')).join('\n')
|
|
14
|
-
const methods = spec.methods.map((
|
|
14
|
+
const methods = spec.methods.map((m) => m.getCode('swift')).join('\n')
|
|
15
15
|
const extraImports = [
|
|
16
16
|
...spec.properties.flatMap((p) => p.getRequiredImports('swift')),
|
|
17
17
|
...spec.methods.flatMap((m) => m.getRequiredImports('swift')),
|
|
@@ -83,6 +83,13 @@ public protocol ${protocolName}_protocol: ${protocolBaseClasses.join(', ')} {
|
|
|
83
83
|
${indent(methods, ' ')}
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
public extension ${protocolName}_protocol {
|
|
87
|
+
/// Default implementation of \`\`HybridObject.toString\`\`
|
|
88
|
+
func toString() -> String {
|
|
89
|
+
return "[HybridObject ${name.T}]"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
86
93
|
/// See \`\`${protocolName}\`\`
|
|
87
94
|
open class ${protocolName}_base${classBaseClasses.length > 0 ? `: ${classBaseClasses.join(',')}` : ''} {
|
|
88
95
|
${indent(baseMembers.join('\n'), ' ')}
|
|
@@ -191,7 +191,7 @@ ${hasBase ? `open class ${name.HybridTSpecCxx} : ${baseClasses.join(', ')}` : `o
|
|
|
191
191
|
*/
|
|
192
192
|
public func getCxxPart() -> bridge.${bridge.specializationName} {
|
|
193
193
|
let cachedCxxPart = self.__cxxPart.lock()
|
|
194
|
-
if cachedCxxPart
|
|
194
|
+
if Bool(fromCxx: cachedCxxPart) {
|
|
195
195
|
return cachedCxxPart
|
|
196
196
|
} else {
|
|
197
197
|
let newCxxPart = bridge.${bridge.funcName}(self.toUnsafe())
|
|
@@ -220,6 +220,14 @@ ${hasBase ? `open class ${name.HybridTSpecCxx} : ${baseClasses.join(', ')}` : `o
|
|
|
220
220
|
self.__implementation.dispose()
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Call toString() on the Swift class.
|
|
225
|
+
*/
|
|
226
|
+
@inline(__always)
|
|
227
|
+
public ${hasBase ? 'override func' : 'func'} toString() -> String {
|
|
228
|
+
return self.__implementation.toString()
|
|
229
|
+
}
|
|
230
|
+
|
|
223
231
|
// Properties
|
|
224
232
|
${indent(propertiesBridge.join('\n\n'), ' ')}
|
|
225
233
|
|
|
@@ -390,6 +398,9 @@ namespace ${cxxNamespace} {
|
|
|
390
398
|
void dispose() noexcept override {
|
|
391
399
|
_swiftPart.dispose();
|
|
392
400
|
}
|
|
401
|
+
std::string toString() override {
|
|
402
|
+
return _swiftPart.toString();
|
|
403
|
+
}
|
|
393
404
|
|
|
394
405
|
public:
|
|
395
406
|
// Properties
|
|
@@ -3,7 +3,7 @@ import { getForwardDeclaration } from '../c++/getForwardDeclaration.js'
|
|
|
3
3
|
import type { SourceFile, SourceImport } from '../SourceFile.js'
|
|
4
4
|
import type { Type, TypeKind } from './Type.js'
|
|
5
5
|
|
|
6
|
-
export class
|
|
6
|
+
export class AnyHybridObjectType implements Type {
|
|
7
7
|
constructor() {}
|
|
8
8
|
|
|
9
9
|
get canBePassedByReference(): boolean {
|
|
@@ -21,7 +21,7 @@ export class HybridObjectBaseType implements Type {
|
|
|
21
21
|
return `std::shared_ptr<HybridObject>`
|
|
22
22
|
default:
|
|
23
23
|
throw new Error(
|
|
24
|
-
|
|
24
|
+
`\`AnyHybridObject\` cannot be used directly in ${language} yet. Use a specific derived class of \`HybridObject\` instead!`
|
|
25
25
|
)
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -50,13 +50,6 @@ export class HybridObjectBaseType implements Type {
|
|
|
50
50
|
}
|
|
51
51
|
)
|
|
52
52
|
break
|
|
53
|
-
case 'kotlin':
|
|
54
|
-
imports.push({
|
|
55
|
-
name: 'com.margelo.nitro.core.HybridObject',
|
|
56
|
-
space: 'system',
|
|
57
|
-
language: 'kotlin',
|
|
58
|
-
})
|
|
59
|
-
break
|
|
60
53
|
}
|
|
61
54
|
return imports
|
|
62
55
|
}
|
package/src/utils.ts
CHANGED
|
@@ -7,8 +7,6 @@ import { isNotDuplicate } from './syntax/helpers.js'
|
|
|
7
7
|
import { readUserConfig } from './config/getConfig.js'
|
|
8
8
|
import { NitroConfig } from './config/NitroConfig.js'
|
|
9
9
|
|
|
10
|
-
export const NITROGEN_VERSION = process.env.npm_package_version ?? '?.?.?'
|
|
11
|
-
|
|
12
10
|
export function capitalizeName(name: string): string {
|
|
13
11
|
if (name.length === 0) return name
|
|
14
12
|
return name.charAt(0).toUpperCase() + name.slice(1)
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { Type } from '../types/Type.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Returns `true` if the given {@linkcode type} is a datatype that
|
|
5
|
-
* can be copied without running a copy constructor or special logic
|
|
6
|
-
* to copy the data over. In other words; it's _primitively copyable_.
|
|
7
|
-
*/
|
|
8
|
-
export function isPrimitivelyCopyable(type: Type): boolean {
|
|
9
|
-
switch (type.kind) {
|
|
10
|
-
case 'number':
|
|
11
|
-
case 'boolean':
|
|
12
|
-
case 'bigint':
|
|
13
|
-
case 'enum':
|
|
14
|
-
case 'null':
|
|
15
|
-
case 'void':
|
|
16
|
-
return true
|
|
17
|
-
default:
|
|
18
|
-
return false
|
|
19
|
-
}
|
|
20
|
-
}
|