19
IDLContainerType, IDLEntry, IDLEnum, IDLFunction, IDLInterface, IDLKind, IDLProperty, IDLType, IDLTypedef,
21
IDLVariable, hasExtAttribute, isTypeParameterType, printType
23
import { TypeChecker, TypeKind } from "./typecheck";
24
import { capitalize, stringOrNone, toSet } from "./util";
32
const typeMapper = new Map<string, string>(
34
["undefined", "void"],
36
["number", "ArkUI_Float32"],
37
["string", "ArkUI_CharPtr"],
38
["boolean", "ArkUI_Bool"],
39
["LabelStyle", "ArkUILabelStyle"],
40
["ButtonType", "ArkUIButtonType"],
41
["ButtonStyleMode", "ArkUIButtonStyleMode"]
45
function mapInterfaceName(type: string, isReference: boolean = false): string {
47
case "any": return "void*";
48
case "undefined": return "void";
50
return `ArkUI${type}${isReference ? "*" : ""}`
53
let currentInterface: IDLInterface|undefined = undefined
55
function mapType(typechecker: TypeChecker, type: IDLType|undefined): string {
56
if (!type) return "/* undefined type */ void"
57
const rawType = type.name
58
if (typeMapper.get(rawType)) {
59
return typeMapper.get(rawType)!
61
if (isTypeParameterType(type) && currentInterface) {
62
return mapInterfaceName(currentInterface.name!, true)
64
let declarations = typechecker.find(type.name)
65
if (declarations.length > 0) {
66
console.log(`Type for ${type.name} is ${TypeKind[declarations[0].kind]}`)
71
case IDLKind.UnionType: return `ArkUI_${(type as IDLUnionType).types.map(it => capitalize(it.name)).join("Or")}`
72
case IDLKind.ContainerType: return mapType(typechecker, (type as IDLContainerType).elementType[0]) + "*"
73
case IDLKind.ReferenceType: return mapInterfaceName(rawType, true)
74
case IDLKind.PrimitiveType: return rawType
76
throw new Error(`Unhandled ${type}: ${declarations}`)
78
function printProperty(typechecker: TypeChecker, iface: IDLInterface, idl: IDLProperty): stringOrNone[] {
79
let isCommon = hasExtAttribute(idl, "CommonMethod")
80
let arg = isCommon ? "ArkUINodeHandle node" : `${mapInterfaceName(iface.name, true)} instance`
82
`\t${mapType(typechecker, idl.type)} (*get${capitalize(idl.name!)})(${arg});`,
83
idl.isReadonly ? undefined : `\tvoid (*set${capitalize(idl.name!)})(${arg}, ${mapType(typechecker, idl.type)} value);`,
87
function printParameters(typechecker: TypeChecker, parameters: IDLVariable[] | undefined): string {
88
if (!parameters) return ""
89
return parameters?.map(param => `${mapType(typechecker, param.type)} ${param.name}`)?.join(", ")
92
function printConstructor(typechecker: TypeChecker, iface: IDLInterface, idl: IDLConstructor, index: number): string {
93
return `\t${mapInterfaceName(iface.name)}* (*construct${index == 0 ? "" : index.toString()})(${printParameters(typechecker, idl.parameters)});`
96
function printDestructor(idl: IDLInterface): string {
97
let isCommon = hasExtAttribute(idl, "CommonMethod")
98
let arg = isCommon ? "ArkUINodeHandle node" : `${mapInterfaceName(idl.name, true)} instance`
99
return `\tvoid (*destruct)(${arg});`
102
function printFunction(typechecker: TypeChecker, iface: IDLInterface, idl: IDLFunction): string {
103
let isCommon = hasExtAttribute(idl, "CommonMethod")
104
let maybeComma = idl.parameters.length > 0 ? ", " : ""
105
let arg = isCommon ? "ArkUINodeHandle node" : `${mapInterfaceName(iface.name, true)} instance`
106
return `\t${mapType(typechecker, idl.returnType)} (*${idl.name})(${arg}${maybeComma}${printParameters(typechecker, idl.parameters)});`
109
function printCallable(typechecker: TypeChecker, idl: IDLFunction, index: number): string {
110
return `\t${mapType(typechecker, idl.returnType)} (*invoke${index == 0 ? "" : index.toString()})(${printParameters(typechecker, idl.parameters)});`
113
function printCallback(idl: IDLCallback): stringOrNone {
117
function printInterface(typechecker: TypeChecker, idl: IDLInterface, bodyOnly: boolean): stringOrNone[] {
118
currentInterface = idl
120
bodyOnly ? undefined : structName(idl),
121
bodyOnly ? undefined : "{",
122
... idl.constructors?.map((it, index) => printConstructor(typechecker, idl, it, index)) ?? [],
123
idl.constructors.length > 0 ? printDestructor(idl) : undefined,
124
... idl.properties?.flatMap(it => printProperty(typechecker, idl, it)) ?? [],
125
... idl.methods?.map(it => printFunction(typechecker, idl, it)) ?? [],
126
... idl.callables?.map((it, index) => printCallable(typechecker, it, index)) ?? [],
127
bodyOnly ? undefined : "};"
129
currentInterface = undefined
133
function structName(idl: IDLInterface): stringOrNone {
134
let name = `struct ${mapInterfaceName(idl.name!)}`
135
if (idl.inheritance.length > 0) {
136
name += " : " + idl.inheritance.map(it => mapInterfaceName(it.name)).join(", ")
141
function printEnum(typechecker: TypeChecker, idl: IDLEnum): stringOrNone[] {
143
`enum ${mapInterfaceName(idl.name)} {`,
144
... idl.elements.map(it => `\t${it.name}${it.initializer ? " = " + it.initializer : "" },`),
149
function printTypedef(typechecker: TypeChecker, idl: IDLTypedef): stringOrNone[] {
151
`typedef ${mapType(typechecker, idl.type)} ${idl.name};`
155
export function printHeader(typechecker: TypeChecker, idls: IDLEntry[], interfacesToGenerate: Set<string>): stringOrNone[] {
156
let result: stringOrNone[] = []
157
idls.forEach((idl) => {
158
if (idl.kind == IDLKind.Class || idl.kind == IDLKind.Interface || idl.kind == IDLKind.AnonymousInterface) {
159
let iface = idl as IDLInterface
160
if (interfacesToGenerate.size == 0 || interfacesToGenerate.has(iface.name))
161
result.push(... printInterface(typechecker, idl as IDLInterface, false))
162
} else if (idl.kind == IDLKind.Enum) {
163
if (interfacesToGenerate.size == 0)
164
result.push(... printEnum(typechecker, idl as IDLEnum))
165
} else if (idl.kind == IDLKind.Typedef) {
166
if (interfacesToGenerate.size == 0)
167
result.push(... printTypedef(typechecker, idl as IDLTypedef))
168
} else if (idl.kind == IDLKind.Callback) {
169
result.push(printCallback(idl as IDLCallback))
171
result.push("unexpected kind: " + idl.kind)
178
* Copyright (c) 2024 Huawei Device Co., Ltd.
179
* Licensed under the Apache License, Version 2.0 (the "License");
180
* you may not use this file except in compliance with the License.
181
* You may obtain a copy of the License at
183
* http://www.apache.org/licenses/LICENSE-2.0
185
* Unless required by applicable law or agreed to in writing, software
186
* distributed under the License is distributed on an "AS IS" BASIS,
187
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
188
* See the License for the specific language governing permissions and
189
* limitations under the License.
191
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_INTERFACES_ARKOALA_API_H
192
#define FOUNDATION_ACE_FRAMEWORKS_CORE_INTERFACES_ARKOALA_API_H
198
#define ARKUI_FULL_API_VERSION 67
200
typedef int ArkUI_Bool;
201
typedef int ArkUI_Int32;
202
typedef unsigned int ArkUI_Uint32;
203
typedef long long ArkUI_Int64;
204
typedef float ArkUI_Float32;
205
typedef double ArkUI_Float64;
206
typedef const char* ArkUI_CharPtr;
215
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_INTERFACES_ARKOALA_API_H
219
export function wrapWithPrologueAndEpilogue(body: string): string {
220
return prologue + body + epilogue
223
export function toHeaderString(typechecker: TypeChecker, allEntries: Array<IDLEntry[]>, interfacesToGenerate: string|undefined): string {
224
const generatedHeader =
227
.flatMap(it => printHeader(typechecker, it, toSet(interfacesToGenerate)))
228
.filter(element => (element?.length ?? 0) > 0)
231
return generatedHeader