UNPKG

nitro-codegen

Version:

The code-generator for react-native-nitro-modules.

94 lines (93 loc) 3.8 kB
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]; } }