nitrogen 0.31.3 → 0.31.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/init.js +1 -1
- package/lib/syntax/createType.js +7 -1
- package/lib/syntax/getInterfaceProperties.js +14 -2
- package/package.json +2 -2
- package/src/init.ts +1 -1
- package/src/syntax/createType.ts +8 -1
- package/src/syntax/getInterfaceProperties.ts +17 -2
- package/lib/syntax/isOverridingFromBase.d.ts +0 -11
- package/lib/syntax/isOverridingFromBase.js +0 -64
- package/lib/syntax/kotlin/isBaseObjectMethodName.d.ts +0 -7
- package/lib/syntax/kotlin/isBaseObjectMethodName.js +0 -9
- package/lib/syntax/swift/isPrimitivelyCopyable.d.ts +0 -7
- package/lib/syntax/swift/isPrimitivelyCopyable.js +0 -18
- package/lib/syntax/types/HybridObjectBaseType.d.ts +0 -11
- package/lib/syntax/types/HybridObjectBaseType.js +0 -47
package/lib/init.js
CHANGED
|
@@ -54,7 +54,7 @@ async function downloadGitHubFolder(owner, repo, branch, folder, outputPath) {
|
|
|
54
54
|
Logger.info(`⏳ Cloning ${chalk.underline(repoUrl)}...`);
|
|
55
55
|
const tempPath = randomUUID();
|
|
56
56
|
const tempDir = path.join(outputPath, tempPath);
|
|
57
|
-
execSync(`git clone --depth 1 --filter=blob:none -b ${branch} --quiet --sparse ${repoUrl} ${tempDir}`);
|
|
57
|
+
execSync(`git clone --depth 1 --filter=blob:none -b ${branch} --quiet --sparse ${repoUrl} "${tempDir}"`);
|
|
58
58
|
const prettyOutputPath = prettifyDirectory(outputPath);
|
|
59
59
|
const initialDir = process.cwd();
|
|
60
60
|
try {
|
package/lib/syntax/createType.js
CHANGED
|
@@ -269,7 +269,10 @@ export function createType(language, type, isOptional) {
|
|
|
269
269
|
}
|
|
270
270
|
else if (type.isInterface()) {
|
|
271
271
|
// It is an `interface T { ... }`, which is a `struct`
|
|
272
|
-
const
|
|
272
|
+
const symbol = type.getAliasSymbol() ?? type.getSymbol();
|
|
273
|
+
if (symbol == null)
|
|
274
|
+
throw new Error(`Interface "${type.getText()}" does not have a Symbol!`);
|
|
275
|
+
const typename = symbol.getName();
|
|
273
276
|
const properties = getInterfaceProperties(language, type);
|
|
274
277
|
return new StructType(typename, properties);
|
|
275
278
|
}
|
|
@@ -291,6 +294,9 @@ export function createType(language, type, isOptional) {
|
|
|
291
294
|
else if (type.isStringLiteral()) {
|
|
292
295
|
throw new Error(`String literal ${type.getText()} cannot be represented in C++ because it is ambiguous between a string and a discriminating union enum.`);
|
|
293
296
|
}
|
|
297
|
+
else if (type.isAny()) {
|
|
298
|
+
throw new Error(`The TypeScript type "${type.getText()}" resolved to any - any is not supported in Nitro.`);
|
|
299
|
+
}
|
|
294
300
|
else {
|
|
295
301
|
if (type.getSymbol() == null) {
|
|
296
302
|
// There is no declaration for it!
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import { createNamedType } from './createType.js';
|
|
2
2
|
export function getInterfaceProperties(language, interfaceType) {
|
|
3
|
+
const symbol = interfaceType.getAliasSymbol() ?? interfaceType.getSymbol();
|
|
4
|
+
if (symbol == null)
|
|
5
|
+
throw new Error(`Interface "${interfaceType.getText()}" does not have a Symbol!`);
|
|
3
6
|
return interfaceType.getProperties().map((prop) => {
|
|
4
|
-
|
|
5
|
-
|
|
7
|
+
let propType = prop.getDeclaredType();
|
|
8
|
+
if (propType.isAny() || propType.isUnknown()) {
|
|
9
|
+
// the interface is aliased/merged - we need to look into the actual declaration
|
|
10
|
+
for (const declaration of symbol.getDeclarations()) {
|
|
11
|
+
const declared = prop.getTypeAtLocation(declaration);
|
|
12
|
+
if (!declared.isAny() && !declared.isUnknown()) {
|
|
13
|
+
propType = declared;
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
6
18
|
const refType = createNamedType(language, prop.getName(), propType, prop.isOptional() || propType.isNullable());
|
|
7
19
|
return refType;
|
|
8
20
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitrogen",
|
|
3
|
-
"version": "0.31.
|
|
3
|
+
"version": "0.31.5",
|
|
4
4
|
"description": "The code-generator for react-native-nitro-modules.",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"chalk": "^5.3.0",
|
|
39
|
-
"react-native-nitro-modules": "^0.31.
|
|
39
|
+
"react-native-nitro-modules": "^0.31.5",
|
|
40
40
|
"ts-morph": "^27.0.0",
|
|
41
41
|
"yargs": "^18.0.0",
|
|
42
42
|
"zod": "^4.0.5"
|
package/src/init.ts
CHANGED
|
@@ -94,7 +94,7 @@ async function downloadGitHubFolder(
|
|
|
94
94
|
const tempPath = randomUUID()
|
|
95
95
|
const tempDir = path.join(outputPath, tempPath)
|
|
96
96
|
execSync(
|
|
97
|
-
`git clone --depth 1 --filter=blob:none -b ${branch} --quiet --sparse ${repoUrl} ${tempDir}`
|
|
97
|
+
`git clone --depth 1 --filter=blob:none -b ${branch} --quiet --sparse ${repoUrl} "${tempDir}"`
|
|
98
98
|
)
|
|
99
99
|
const prettyOutputPath = prettifyDirectory(outputPath)
|
|
100
100
|
|
package/src/syntax/createType.ts
CHANGED
|
@@ -329,7 +329,10 @@ export function createType(
|
|
|
329
329
|
return new HybridObjectType(typename, language, baseHybrids, sourceConfig)
|
|
330
330
|
} else if (type.isInterface()) {
|
|
331
331
|
// It is an `interface T { ... }`, which is a `struct`
|
|
332
|
-
const
|
|
332
|
+
const symbol = type.getAliasSymbol() ?? type.getSymbol()
|
|
333
|
+
if (symbol == null)
|
|
334
|
+
throw new Error(`Interface "${type.getText()}" does not have a Symbol!`)
|
|
335
|
+
const typename = symbol.getName()
|
|
333
336
|
const properties = getInterfaceProperties(language, type)
|
|
334
337
|
return new StructType(typename, properties)
|
|
335
338
|
} else if (type.isObject()) {
|
|
@@ -351,6 +354,10 @@ export function createType(
|
|
|
351
354
|
throw new Error(
|
|
352
355
|
`String literal ${type.getText()} cannot be represented in C++ because it is ambiguous between a string and a discriminating union enum.`
|
|
353
356
|
)
|
|
357
|
+
} else if (type.isAny()) {
|
|
358
|
+
throw new Error(
|
|
359
|
+
`The TypeScript type "${type.getText()}" resolved to any - any is not supported in Nitro.`
|
|
360
|
+
)
|
|
354
361
|
} else {
|
|
355
362
|
if (type.getSymbol() == null) {
|
|
356
363
|
// There is no declaration for it!
|
|
@@ -7,9 +7,24 @@ export function getInterfaceProperties(
|
|
|
7
7
|
language: Language,
|
|
8
8
|
interfaceType: Type<ts.ObjectType>
|
|
9
9
|
): NamedType[] {
|
|
10
|
+
const symbol = interfaceType.getAliasSymbol() ?? interfaceType.getSymbol()
|
|
11
|
+
if (symbol == null)
|
|
12
|
+
throw new Error(
|
|
13
|
+
`Interface "${interfaceType.getText()}" does not have a Symbol!`
|
|
14
|
+
)
|
|
10
15
|
return interfaceType.getProperties().map((prop) => {
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
let propType = prop.getDeclaredType()
|
|
17
|
+
if (propType.isAny() || propType.isUnknown()) {
|
|
18
|
+
// the interface is aliased/merged - we need to look into the actual declaration
|
|
19
|
+
for (const declaration of symbol.getDeclarations()) {
|
|
20
|
+
const declared = prop.getTypeAtLocation(declaration)
|
|
21
|
+
if (!declared.isAny() && !declared.isUnknown()) {
|
|
22
|
+
propType = declared
|
|
23
|
+
break
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
13
28
|
const refType = createNamedType(
|
|
14
29
|
language,
|
|
15
30
|
prop.getName(),
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Language } from '../getPlatformSpecs.js';
|
|
2
|
-
import type { HybridObjectSpec } from './HybridObjectSpec.js';
|
|
3
|
-
/**
|
|
4
|
-
* Returns true when the given {@linkcode memberName} is overriding a
|
|
5
|
-
* property or method from any base class inside the given
|
|
6
|
-
* {@linkcode hybridObject}'s prototype chain (all the way up).
|
|
7
|
-
*
|
|
8
|
-
* For example, `"toString"` would return `true` since it overrides from base HybridObject.
|
|
9
|
-
* On Kotlin, `"hashCode"` would return `true` since it overrides from base `kotlin.Any`.
|
|
10
|
-
*/
|
|
11
|
-
export declare function isMemberOverridingFromBase(memberName: string, hybridObject: HybridObjectSpec, language: Language): boolean;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
function getMemberNamesOfBaseType(language) {
|
|
2
|
-
switch (language) {
|
|
3
|
-
case 'c++':
|
|
4
|
-
// C++ classes don't have any base type.
|
|
5
|
-
return [];
|
|
6
|
-
case 'swift':
|
|
7
|
-
// Swift classes conform to `AnyObject`, but that doesn't have any properties
|
|
8
|
-
return [];
|
|
9
|
-
case 'kotlin':
|
|
10
|
-
// Kotlin/JVM classes always extends `Any`, which has 3 methods
|
|
11
|
-
return ['toString', 'equals', 'hashCode'];
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
function getMemberNamesOfHybridObject() {
|
|
15
|
-
const allKeys = {
|
|
16
|
-
__type: true,
|
|
17
|
-
dispose: true,
|
|
18
|
-
equals: true,
|
|
19
|
-
name: true,
|
|
20
|
-
toString: true,
|
|
21
|
-
};
|
|
22
|
-
return Object.keys(allKeys);
|
|
23
|
-
}
|
|
24
|
-
function flatBaseTypes(type) {
|
|
25
|
-
return type.baseTypes.flatMap((b) => [b, ...flatBaseTypes(b)]);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Returns true when the given {@linkcode memberName} is overriding a
|
|
29
|
-
* property or method from any base class inside the given
|
|
30
|
-
* {@linkcode hybridObject}'s prototype chain (all the way up).
|
|
31
|
-
*
|
|
32
|
-
* For example, `"toString"` would return `true` since it overrides from base HybridObject.
|
|
33
|
-
* On Kotlin, `"hashCode"` would return `true` since it overrides from base `kotlin.Any`.
|
|
34
|
-
*/
|
|
35
|
-
export function isMemberOverridingFromBase(memberName, hybridObject, language) {
|
|
36
|
-
// 1. Check if the HybridObject inherits from other HybridObjects,
|
|
37
|
-
// if yes, check if those have properties of that given name.
|
|
38
|
-
const allBases = flatBaseTypes(hybridObject);
|
|
39
|
-
const anyBaseOverrides = allBases.some((h) => {
|
|
40
|
-
if (h.properties.some((p) => p.name === memberName)) {
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
if (h.methods.some((m) => m.name === memberName)) {
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
return false;
|
|
47
|
-
});
|
|
48
|
-
if (anyBaseOverrides) {
|
|
49
|
-
// A HybridObject base type has the same property name - we need to override it.
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
// 2. Check if the base `HybridObject` type contains a property of the given name
|
|
53
|
-
const baseHybridObjectProps = getMemberNamesOfHybridObject();
|
|
54
|
-
if (baseHybridObjectProps.includes(memberName)) {
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
// 3. Check if the base type in our language contains a property of the given name
|
|
58
|
-
const baseTypeProps = getMemberNamesOfBaseType(language);
|
|
59
|
-
if (baseTypeProps.includes(memberName)) {
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
// 4. Apparently no base type has a property of that name - we are safe!
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Method } from '../Method.js';
|
|
2
|
-
/**
|
|
3
|
-
* Returns `true` if the given {@linkcode method} is a
|
|
4
|
-
* method that exists in the base `Object` type in Java.
|
|
5
|
-
* If this is true, it needs an `override` modifier.
|
|
6
|
-
*/
|
|
7
|
-
export declare function isBaseObjectMethodName(method: Method): boolean;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
const kotlinAnyMethodNames = ['equals', 'hashCode', 'toString'];
|
|
2
|
-
/**
|
|
3
|
-
* Returns `true` if the given {@linkcode method} is a
|
|
4
|
-
* method that exists in the base `Object` type in Java.
|
|
5
|
-
* If this is true, it needs an `override` modifier.
|
|
6
|
-
*/
|
|
7
|
-
export function isBaseObjectMethodName(method) {
|
|
8
|
-
return kotlinAnyMethodNames.includes(method.name);
|
|
9
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Type } from '../types/Type.js';
|
|
2
|
-
/**
|
|
3
|
-
* Returns `true` if the given {@linkcode type} is a datatype that
|
|
4
|
-
* can be copied without running a copy constructor or special logic
|
|
5
|
-
* to copy the data over. In other words; it's _primitively copyable_.
|
|
6
|
-
*/
|
|
7
|
-
export declare function isPrimitivelyCopyable(type: Type): boolean;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns `true` if the given {@linkcode type} is a datatype that
|
|
3
|
-
* can be copied without running a copy constructor or special logic
|
|
4
|
-
* to copy the data over. In other words; it's _primitively copyable_.
|
|
5
|
-
*/
|
|
6
|
-
export function isPrimitivelyCopyable(type) {
|
|
7
|
-
switch (type.kind) {
|
|
8
|
-
case 'number':
|
|
9
|
-
case 'boolean':
|
|
10
|
-
case 'bigint':
|
|
11
|
-
case 'enum':
|
|
12
|
-
case 'null':
|
|
13
|
-
case 'void':
|
|
14
|
-
return true;
|
|
15
|
-
default:
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Language } from '../../getPlatformSpecs.js';
|
|
2
|
-
import type { SourceFile, SourceImport } from '../SourceFile.js';
|
|
3
|
-
import type { Type, TypeKind } from './Type.js';
|
|
4
|
-
export declare class HybridObjectBaseType implements Type {
|
|
5
|
-
constructor();
|
|
6
|
-
get canBePassedByReference(): boolean;
|
|
7
|
-
get kind(): TypeKind;
|
|
8
|
-
getCode(language: Language): string;
|
|
9
|
-
getExtraFiles(): SourceFile[];
|
|
10
|
-
getRequiredImports(language: Language): SourceImport[];
|
|
11
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { getForwardDeclaration } from '../c++/getForwardDeclaration.js';
|
|
2
|
-
export class HybridObjectBaseType {
|
|
3
|
-
constructor() { }
|
|
4
|
-
get canBePassedByReference() {
|
|
5
|
-
// It's a shared_ptr<..>, no copy.
|
|
6
|
-
return true;
|
|
7
|
-
}
|
|
8
|
-
get kind() {
|
|
9
|
-
return 'hybrid-object-base';
|
|
10
|
-
}
|
|
11
|
-
getCode(language) {
|
|
12
|
-
switch (language) {
|
|
13
|
-
case 'c++':
|
|
14
|
-
return `std::shared_ptr<HybridObject>`;
|
|
15
|
-
default:
|
|
16
|
-
throw new Error(`The base type \`HybridObject\` cannot be used directly in ${language} yet. Use a specific derived class of \`HybridObject\` instead!`);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
getExtraFiles() {
|
|
20
|
-
return [];
|
|
21
|
-
}
|
|
22
|
-
getRequiredImports(language) {
|
|
23
|
-
const imports = [];
|
|
24
|
-
switch (language) {
|
|
25
|
-
case 'c++':
|
|
26
|
-
imports.push({
|
|
27
|
-
language: 'c++',
|
|
28
|
-
name: 'memory',
|
|
29
|
-
space: 'system',
|
|
30
|
-
}, {
|
|
31
|
-
name: `NitroModules/HybridObject.hpp`,
|
|
32
|
-
forwardDeclaration: getForwardDeclaration('class', 'HybridObject', 'margelo::nitro'),
|
|
33
|
-
language: 'c++',
|
|
34
|
-
space: 'system',
|
|
35
|
-
});
|
|
36
|
-
break;
|
|
37
|
-
case 'kotlin':
|
|
38
|
-
imports.push({
|
|
39
|
-
name: 'com.margelo.nitro.core.HybridObject',
|
|
40
|
-
space: 'system',
|
|
41
|
-
language: 'kotlin',
|
|
42
|
-
});
|
|
43
|
-
break;
|
|
44
|
-
}
|
|
45
|
-
return imports;
|
|
46
|
-
}
|
|
47
|
-
}
|