nitro-codegen
Version:
The code-generator for react-native-nitro-modules.
94 lines (93 loc) • 3.8 kB
JavaScript
import { EnumDeclaration } from 'ts-morph';
import { Type as TSMorphType } from 'ts-morph';
import { getForwardDeclaration } from '../c++/getForwardDeclaration.js';
import {} from '../SourceFile.js';
import { createCppEnum } from '../c++/CppEnum.js';
import { escapeCppName } from '../helpers.js';
import { createCppUnion } from '../c++/CppUnion.js';
import { NitroConfig } from '../../config/NitroConfig.js';
export class EnumType {
enumName;
enumMembers;
jsType;
declarationFile;
constructor(enumName, declaration) {
this.enumName = enumName;
if (declaration instanceof EnumDeclaration) {
// It's a JS enum { ... }
this.jsType = 'enum';
this.enumMembers = declaration.getMembers().map((m) => {
const name = m.getSymbolOrThrow().getEscapedName();
const value = m.getValue();
if (typeof value !== 'number') {
throw new Error(`Enum member ${enumName}.${name} is ${value} (${typeof value}), which cannot be represented in C++ enums.\n` +
`Each enum member must be a number! If you want to use strings, use TypeScript unions ("a" | "b") instead!`);
}
return {
name: escapeCppName(name).toUpperCase(),
value: value,
stringValue: name,
};
});
this.declarationFile = createCppEnum(enumName, this.enumMembers);
}
else {
// It's a TS union '..' | '..'
this.jsType = 'union';
this.enumMembers = declaration
.getNonNullableType()
.getUnionTypes()
.map((t, i) => {
if (t.isStringLiteral()) {
const literalValue = t.getLiteralValueOrThrow();
if (typeof literalValue !== 'string')
throw new Error(`${enumName}: Value "${literalValue}" is not a string - it is ${typeof literalValue}!`);
return {
name: escapeCppName(literalValue).toUpperCase(),
value: i,
stringValue: literalValue,
};
}
else {
throw new Error(`${enumName}: Value "${t.getText()}" is not a string literal - it cannot be represented in a C++ enum!`);
}
});
this.declarationFile = createCppUnion(enumName, this.enumMembers);
}
if (this.enumName.startsWith('__')) {
throw new Error(`Enum name cannot start with two underscores (__) as this is reserved syntax for Nitrogen! (In ${this.enumName}: ${this.enumMembers.map((m) => m.name).join(' | ')})`);
}
}
get canBePassedByReference() {
// It's a primitive.
return false;
}
get kind() {
return 'enum';
}
getCode(language) {
switch (language) {
case 'c++':
return this.enumName;
case 'swift':
return this.enumName;
case 'kotlin':
return this.enumName;
default:
throw new Error(`Language ${language} is not yet supported for NumberType!`);
}
}
getExtraFiles() {
return [this.declarationFile];
}
getRequiredImports() {
const cxxNamespace = NitroConfig.getCxxNamespace('c++');
const extraImport = {
name: this.declarationFile.name,
language: this.declarationFile.language,
forwardDeclaration: getForwardDeclaration('enum class', this.enumName, cxxNamespace),
space: 'user',
};
return [extraImport];
}
}