* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as idl from "../../idl"
import { Language } from "../../Language"
import { IdlNameConvertor } from "../../LanguageWriters"
import { capitalize } from "../../util"
export function generateSyntheticIdlNodeName(type: idl.IDLType): string {
if (idl.isPrimitiveType(type)) return capitalize(type.name)
if (idl.isContainerType(type)) {
const typeArgs = type.elementType.map(it => generateSyntheticIdlNodeName(it)).join("_").replaceAll(".", "_")
switch (type.containerKind) {
case "sequence": return "Array_" + typeArgs
case "record": return "Map_" + typeArgs
case "Promise": return "Promise_" + typeArgs
default: throw new Error(`Unknown container type ${idl.DebugUtils.debugPrintType(type)}`)
}
}
if (idl.isNamedNode(type))
return type.name.split('.').map(capitalize).join('_')
if (idl.isOptionalType(type))
return `Opt_${generateSyntheticIdlNodeName(type.type)}`
throw `Can not compute type name of ${idl.IDLKind[type.kind]}`
}
export function qualifiedName(decl: idl.IDLNode, languageOrDelimiter: Language|string, pattern: idl.QNPattern): string {
if (!idl.isNamedNode(decl))
throw new Error("internal error, name required for no-named node")
const delimiter = typeof languageOrDelimiter === "string"
? languageOrDelimiter
: ([Language.CPP, Language.CJ, Language.KOTLIN].includes(languageOrDelimiter) ? '_' : '.')
if (!idl.isEntry(decl))
throw new Error(`Expected to have an IDLEntry, got ${idl.IDLKind[decl.kind]}`)
return idl.getQualifiedName(decl, pattern).split(".").join(delimiter)
}
export function collapseTypes(types: idl.IDLType[], name?: string): idl.IDLType {
const seenNames = new Set<string>()
const uniqueTypes = types.filter(it => {
const typeName = idl.printType(it)
if (seenNames.has(typeName)) return false
seenNames.add(typeName)
return true
})
return uniqueTypes.length === 1 ? uniqueTypes[0] : idl.createUnionType(uniqueTypes, name)
}
export function generifiedTypeName(refType: idl.IDLReferenceType, nameConvertor: IdlNameConvertor, refName?: string): string {
const typeArgs = refType.typeArguments?.map(it => nameConvertor.convert(it)).join(",")
return `${refName ? refName : refType.name}${typeArgs ? `<${typeArgs}>` : ``}`
}
export function sanitizeGenerics(genericDeclarationString:string): string {
const eqIdx = genericDeclarationString.indexOf('=')
if (eqIdx !== -1) {
genericDeclarationString = genericDeclarationString.substring(0, eqIdx)
}
const extendsIdx = genericDeclarationString.indexOf('extends')
if (extendsIdx !== -1) {
genericDeclarationString = genericDeclarationString.substring(0, extendsIdx)
}
return genericDeclarationString.trim()
}
export function generateSyntheticUnionName(types: idl.IDLType[]) {
return `Union_${types.map(it => generateSyntheticIdlNodeName(it)).join("_").replaceAll(".", "_")}`
}
export function generateSyntheticFunctionParameterName(parameter:idl.IDLParameter): string {
if (parameter.isOptional) {
return generateSyntheticIdlNodeName(idl.createOptionalType(parameter.type))
}
return generateSyntheticIdlNodeName(parameter.type)
}
export function generateSyntheticFunctionName(parameters: idl.IDLParameter[], returnType: idl.IDLType, options?: { isAsync?: boolean, nameConvertor?: IdlNameConvertor }): string {
let prefix = options?.isAsync ? "AsyncCallback" : "Callback"
const names = options?.nameConvertor !== undefined
? parameters.map(it => options.nameConvertor!.convert(it.type)).concat(options.nameConvertor!.convert(returnType))
: parameters.map(generateSyntheticFunctionParameterName).concat(generateSyntheticIdlNodeName(returnType))
return `${prefix}_${names.join("_").replaceAll(".", "_")}`
}
export function isImportAttr(decl: idl.IDLNode): boolean {
return idl.hasExtAttribute(decl, idl.IDLExtendedAttributes.Import)
}