nitro-codegen
Version:
The code-generator for react-native-nitro-modules.
82 lines (74 loc) • 2.76 kB
text/typescript
import type { ParameterDeclaration } from 'ts-morph'
import type { CodeNode } from './CodeNode.js'
import { escapeCppName, toReferenceType } from './helpers.js'
import type { Language } from '../getPlatformSpecs.js'
import { type SourceFile, type SourceImport } from './SourceFile.js'
import type { NamedType, Type } from './types/Type.js'
import { NamedWrappingType } from './types/NamedWrappingType.js'
import { createNamedType } from './createType.js'
export class Parameter implements CodeNode {
readonly type: NamedType
constructor(name: string, type: Type)
constructor(parameter: ParameterDeclaration, language: Language)
constructor(...args: [string, Type] | [ParameterDeclaration, Language]) {
if (typeof args[0] === 'string' && typeof args[1] === 'object') {
// constructor(...) #1
if (args.length !== 2)
throw new Error(`Missing arguments for new Parameter(...) overload #1!`)
const [name, type] = args
this.type = new NamedWrappingType(name, type)
} else if (typeof args[0] === 'object' && typeof args[1] === 'string') {
// constructor(...) #2
const [param, language] = args
const name = param.getSymbolOrThrow().getEscapedName()
const type = param.getType()
const isOptional =
param.hasQuestionToken() || param.isOptional() || type.isNullable()
this.type = createNamedType(language, name, type, isOptional)
} else {
// constructor(...)???
throw new Error(`Invalid constructor! Arguments: ${args}`)
}
if (this.type.name.startsWith('__')) {
throw new Error(
`Parameter names are not allowed to start with two underscores (__)! (In ${this.jsSignature})`
)
}
}
get jsSignature(): string {
return `${this.type.name}: ${this.type.kind}`
}
get name(): string {
return this.type.name
}
getCode(language: Language): string {
const name = escapeCppName(this.name)
switch (language) {
case 'c++':
let cppType = this.type.getCode('c++')
if (this.type.canBePassedByReference) {
// T -> const T&
cppType = toReferenceType(cppType)
}
return `${cppType} ${name}`
case 'swift':
let flags = ''
if (this.type.kind === 'function') {
flags = '@escaping '
}
return `${name}: ${flags + this.type.getCode('swift')}`
case 'kotlin':
return `${name}: ${this.type.getCode('kotlin')}`
default:
throw new Error(
`Language ${language} is not yet supported for parameters!`
)
}
}
getExtraFiles(): SourceFile[] {
return this.type.getExtraFiles()
}
getRequiredImports(): SourceImport[] {
return this.type.getRequiredImports()
}
}