• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15import { global } from './static/global';
16import { KInt, KNativePointer, KNativePointer as KPtr, nullptr } from '@koalaui/interop';
17import {
18    Es2pandaContextState,
19    Es2pandaMethodDefinitionKind,
20    Es2pandaModifierFlags,
21    Es2pandaScriptFunctionFlags,
22    Es2pandaTokenType,
23    Es2pandaVariableDeclarationKind,
24    Es2pandaVariableDeclaratorFlag,
25} from '../generated/Es2pandaEnums';
26import {
27    allFlags,
28    arrayOfNullptr,
29    assertValidPeer,
30    nodeType,
31    passNode,
32    passNodeArray,
33    passString,
34    unpackNode,
35    unpackNodeArray,
36    unpackNonNullableNode,
37    unpackString,
38    updatePeerByNode,
39} from './utilities/private';
40import { proceedToState } from './utilities/public';
41import { Es2pandaAstNodeType } from '../Es2pandaEnums';
42import { AstNode } from './peers/AstNode';
43import { ArktsObject } from './peers/ArktsObject';
44import { Config } from './peers/Config';
45import { Context } from './peers/Context';
46import * as path from 'node:path';
47import { nodeByType } from './class-by-peer';
48import { MemberExpression } from './to-be-generated/MemberExpression';
49import {
50    AnnotationUsage,
51    ArrayExpression,
52    BlockStatement,
53    ClassDefinition,
54    ETSTypeReference,
55    ETSTypeReferencePart,
56    Expression,
57    FunctionSignature,
58    Identifier,
59    ImportSpecifier,
60    Literal,
61    ObjectExpression,
62    ScriptFunction,
63    StringLiteral,
64    TSTypeParameterDeclaration,
65    TSTypeParameterInstantiation,
66    TypeNode,
67} from '../generated';
68
69export class EtsScript extends AstNode {
70    constructor(peer: KPtr) {
71        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_ETS_MODULE);
72        super(peer);
73    }
74
75    static fromContext(): EtsScript {
76        console.log('[TS WRAPPER] GET AST FROM CONTEXT');
77        return new EtsScript(
78            global.es2panda._ProgramAst(global.context, global.es2panda._ContextProgram(global.context))
79        );
80    }
81
82    /**
83     * @deprecated
84     */
85    static createFromSource(
86        source: string,
87        state: Es2pandaContextState = Es2pandaContextState.ES2PANDA_STATE_PARSED
88    ): EtsScript {
89        if (!global.configIsInitialized()) {
90            global.config = Config.createDefault().peer;
91        }
92        global.compilerContext = Context.createFromString(source);
93        proceedToState(state);
94        return new EtsScript(
95            global.es2panda._ProgramAst(global.context, global.es2panda._ContextProgram(global.context))
96        );
97    }
98
99    /**
100     * @deprecated
101     */
102    static updateByStatements(node: EtsScript, statements: readonly AstNode[]): EtsScript {
103        global.generatedEs2panda._BlockStatementSetStatements(
104            global.context,
105            node.peer,
106            passNodeArray(statements),
107            statements.length
108        );
109        return node;
110    }
111
112    get statements(): readonly AstNode[] {
113        return unpackNodeArray(global.generatedEs2panda._BlockStatementStatements(global.context, this.peer));
114    }
115
116    set statements(nodes: readonly AstNode[]) {
117        global.generatedEs2panda._BlockStatementSetStatements(
118            global.context,
119            this.peer,
120            passNodeArray(nodes),
121            nodes.length
122        );
123    }
124}
125
126export class ExpressionStatement extends AstNode {
127    constructor(peer: KPtr) {
128        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_EXPRESSION_STATEMENT);
129        super(peer);
130    }
131
132    static create(expression: AstNode): ExpressionStatement {
133        return new ExpressionStatement(
134            global.generatedEs2panda._CreateExpressionStatement(global.context, expression.peer)
135        );
136    }
137
138    static update(node: ExpressionStatement, expression: AstNode): ExpressionStatement {
139        return new ExpressionStatement(
140            global.generatedEs2panda._UpdateExpressionStatement(global.context, node.peer, expression.peer)
141        );
142    }
143
144    get expression(): AstNode {
145        return unpackNonNullableNode(
146            global.generatedEs2panda._ExpressionStatementGetExpressionConst(global.context, this.peer)
147        );
148    }
149    /** @deprecated */
150    setExpression(expr?: Expression): this {
151        global.generatedEs2panda._ExpressionStatementSetExpression(global.context, this.peer, passNode(expr));
152        return this;
153    }
154}
155
156// TODO:
157//  the CallExpression idl Create signature doesn't include the trailing block at all.
158//  Need to clarify with the compiler people if they will provide create signature with a trailing block argument.
159export class CallExpression extends Expression {
160    constructor(peer: KPtr) {
161        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_CALL_EXPRESSION);
162        super(peer);
163        this.expression = unpackNonNullableNode(
164            global.generatedEs2panda._CallExpressionCallee(global.context, this.peer)
165        );
166        this.typeParams = unpackNode(global.generatedEs2panda._CallExpressionTypeParams(global.context, this.peer));
167        this.typeArguments = this.typeParams
168            ? unpackNodeArray(
169                  global.generatedEs2panda._TSTypeParameterInstantiationParamsConst(
170                      global.context,
171                      this.typeParams.peer
172                  )
173              )
174            : undefined;
175        this.arguments = unpackNodeArray(global.generatedEs2panda._CallExpressionArguments(global.context, this.peer));
176    }
177
178    static create(
179        expression: AstNode,
180        typeArguments: readonly TypeNode[] | undefined,
181        args: readonly AstNode[] | undefined,
182        isOptional: boolean = false,
183        trailingComma: boolean = false
184    ): CallExpression {
185        const peer = global.generatedEs2panda._CreateCallExpression(
186            global.context,
187            passNode(expression),
188            passNodeArray(args),
189            args?.length ?? 0,
190            typeArguments
191                ? passNode(TSTypeParameterInstantiation.createTSTypeParameterInstantiation(typeArguments))
192                : nullptr,
193            isOptional,
194            trailingComma
195        );
196        return new CallExpression(peer);
197    }
198
199    static update(
200        node: CallExpression,
201        expression: AstNode,
202        typeArguments: readonly TypeNode[] | undefined,
203        args: readonly AstNode[] | undefined,
204        isOptional: boolean = false,
205        trailingComma: boolean = false
206    ): CallExpression {
207        const peer = global.es2panda._UpdateCallExpression(
208            global.context,
209            node.peer,
210            passNode(expression),
211            passNodeArray(args),
212            args?.length ?? 0,
213            typeArguments
214                ? passNode(TSTypeParameterInstantiation.createTSTypeParameterInstantiation(typeArguments))
215                : nullptr,
216            isOptional,
217            trailingComma
218        );
219        return new CallExpression(peer);
220    }
221
222    get trailingBlock(): BlockStatement | undefined {
223        return unpackNode(global.generatedEs2panda._CallExpressionTrailingBlockConst(global.context, this.peer));
224    }
225
226    setTralingBlock(trailingBlock: BlockStatement | undefined): this {
227        if (!trailingBlock) return this;
228        global.generatedEs2panda._CallExpressionSetTrailingBlock(global.context, this.peer, trailingBlock.peer);
229        return this;
230    }
231
232    /** @deprecated */
233    setCallee(callee?: Expression): this {
234        global.generatedEs2panda._CallExpressionSetCallee(global.context, this.peer, passNode(callee));
235        return this;
236    }
237
238    /** @deprecated */
239    setTypeParams(typeParams?: TSTypeParameterInstantiation): this {
240        global.generatedEs2panda._CallExpressionSetTypeParams(global.context, this.peer, passNode(typeParams));
241        return this;
242    }
243
244    readonly expression: AstNode; // Expression
245    readonly typeArguments: readonly TypeNode[] | undefined;
246    readonly arguments: readonly Expression[];
247    readonly typeParams: TSTypeParameterInstantiation | undefined;
248}
249
250export class AssignmentExpression extends AstNode {
251    constructor(peer: KPtr) {
252        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_ASSIGNMENT_EXPRESSION);
253        super(peer);
254    }
255
256    static create(left: AstNode, assignmentOperator: Es2pandaTokenType, right: AstNode): AssignmentExpression {
257        return new AssignmentExpression(
258            global.generatedEs2panda._CreateAssignmentExpression(
259                global.context,
260                passNode(left),
261                passNode(right),
262                assignmentOperator
263            )
264        );
265    }
266
267    static update(
268        node: AssignmentExpression,
269        left: AstNode,
270        assignmentOperator: Es2pandaTokenType,
271        right: AstNode
272    ): AssignmentExpression {
273        return new AssignmentExpression(
274            global.generatedEs2panda._UpdateAssignmentExpression(
275                global.context,
276                node.peer,
277                passNode(left),
278                passNode(right),
279                assignmentOperator
280            )
281        );
282    }
283
284    get left(): Expression | undefined {
285        return unpackNode(global.generatedEs2panda._AssignmentExpressionLeftConst(global.context, this.peer));
286    }
287    get right(): Expression | undefined {
288        return unpackNode(global.generatedEs2panda._AssignmentExpressionRightConst(global.context, this.peer));
289    }
290    get operatorType(): Es2pandaTokenType {
291        return global.generatedEs2panda._AssignmentExpressionOperatorTypeConst(global.context, this.peer);
292    }
293    /** @deprecated */
294    setRight(expr?: Expression): this {
295        global.generatedEs2panda._AssignmentExpressionSetRight(global.context, this.peer, passNode(expr));
296        return this;
297    }
298    /** @deprecated */
299    setLeft(expr?: Expression): this {
300        global.generatedEs2panda._AssignmentExpressionSetLeft(global.context, this.peer, passNode(expr));
301        return this;
302    }
303    setOperatorType(operatorType: Es2pandaTokenType): this {
304        global.generatedEs2panda._AssignmentExpressionSetOperatorType(global.context, this.peer, operatorType);
305        return this;
306    }
307}
308
309export class TSUnionType extends AstNode {
310    constructor(peer: KPtr) {
311        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_TS_UNION_TYPE);
312        super(peer);
313        this.types = unpackNodeArray(global.generatedEs2panda._TSUnionTypeTypesConst(global.context, this.peer));
314    }
315
316    static create(node: undefined | TSUnionType, types: AstNode[]): TSUnionType {
317        return new TSUnionType(
318            updatePeerByNode(
319                global.generatedEs2panda._CreateTSUnionType(global.context, passNodeArray(types), types.length),
320                node
321            )
322        );
323    }
324
325    readonly types: readonly AstNode[];
326}
327
328export class NumberLiteral extends Literal {
329    constructor(peer: KPtr) {
330        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_NUMBER_LITERAL);
331        super(peer);
332        this.value = 0.0;
333    }
334
335    static create(value: number): NumberLiteral {
336        return new NumberLiteral(global.es2panda._CreateNumberLiteral(global.context, value));
337    }
338
339    protected override dumpMessage(): string {
340        return ` <value: ${this.value}>`;
341    }
342
343    readonly value: number = 0.0;
344}
345
346export class ArrowFunctionExpression extends Expression {
347    constructor(peer: KPtr) {
348        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_ARROW_FUNCTION_EXPRESSION);
349        super(peer);
350        this.scriptFunction = unpackNonNullableNode(
351            global.generatedEs2panda._ArrowFunctionExpressionFunction(global.context, this.peer)
352        );
353    }
354
355    static create(func: ScriptFunction): ArrowFunctionExpression {
356        return new ArrowFunctionExpression(
357            global.generatedEs2panda._CreateArrowFunctionExpression(global.context, passNode(func))
358        );
359    }
360
361    static update(node: ArrowFunctionExpression, func: ScriptFunction): ArrowFunctionExpression {
362        return new ArrowFunctionExpression(
363            global.generatedEs2panda._UpdateArrowFunctionExpression(global.context, node.peer, passNode(func))
364        );
365    }
366
367    get annotations(): AnnotationUsage[] {
368        return unpackNodeArray(global.generatedEs2panda._ArrowFunctionExpressionAnnotations(global.context, this.peer));
369    }
370
371    setAnnotations(annotations: AnnotationUsage[]): this {
372        global.generatedEs2panda._ArrowFunctionExpressionSetAnnotations(
373            global.context,
374            this.peer,
375            passNodeArray(annotations),
376            annotations.length
377        );
378
379        return this;
380    }
381
382    readonly scriptFunction: ScriptFunction;
383}
384
385export class FunctionDeclaration extends AstNode {
386    constructor(peer: KPtr) {
387        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_FUNCTION_DECLARATION);
388        super(peer);
389        this.scriptFunction = unpackNonNullableNode(
390            global.generatedEs2panda._FunctionDeclarationFunction(global.context, this.peer)
391        );
392        this.parameters = unpackNodeArray(
393            global.generatedEs2panda._ScriptFunctionParams(global.context, this.scriptFunction.peer)
394        );
395        this.name = unpackNode(global.generatedEs2panda._ScriptFunctionId(global.context, this.scriptFunction.peer));
396        this.body = unpackNode(global.generatedEs2panda._ScriptFunctionBody(global.context, this.scriptFunction.peer));
397        this.typeParamsDecl = unpackNode(
398            global.generatedEs2panda._ScriptFunctionTypeParams(global.context, this.scriptFunction.peer)
399        );
400        this.returnType = unpackNode(
401            global.generatedEs2panda._ScriptFunctionReturnTypeAnnotation(global.context, this.scriptFunction.peer)
402        );
403        this.isAnon = global.generatedEs2panda._FunctionDeclarationIsAnonymousConst(global.context, this.peer);
404    }
405
406    static create(
407        scriptFunction: ScriptFunction,
408        isAnon: boolean,
409        annotations?: AnnotationUsage[]
410    ): FunctionDeclaration {
411        const res = new FunctionDeclaration(
412            global.es2panda._CreateFunctionDeclaration(
413                global.context,
414                scriptFunction.peer,
415                // TODO: support annotations
416                arrayOfNullptr,
417                0,
418                isAnon
419            )
420        );
421        // TODO: maybe wrong
422        res.modifiers = scriptFunction.modifiers;
423        if (annotations) {
424            res.annotations = annotations;
425        }
426        return res;
427    }
428
429    static update(
430        node: FunctionDeclaration,
431        scriptFunction: ScriptFunction,
432        isAnon: boolean,
433        annotations?: AnnotationUsage[]
434    ): FunctionDeclaration {
435        const res = new FunctionDeclaration(
436            global.generatedEs2panda._UpdateFunctionDeclaration(
437                global.context,
438                node.peer,
439                scriptFunction.peer,
440                // TODO: support annotations
441                passNodeArray(annotations),
442                0,
443                isAnon
444            )
445        );
446        if (annotations) {
447            res.annotations = annotations;
448        }
449        return res;
450    }
451
452    get annotations(): AnnotationUsage[] {
453        return unpackNodeArray(
454            global.generatedEs2panda._FunctionDeclarationAnnotationsConst(global.context, this.peer)
455        );
456    }
457
458    set annotations(newAnnotations: AnnotationUsage[]) {
459        global.generatedEs2panda._FunctionDeclarationSetAnnotations(
460            global.context,
461            this.peer,
462            passNodeArray(newAnnotations),
463            newAnnotations.length
464        );
465    }
466
467    readonly scriptFunction: ScriptFunction;
468    readonly parameters: readonly AstNode[];
469    readonly name?: Identifier;
470    readonly body?: BlockStatement;
471    readonly typeParamsDecl?: TSTypeParameterDeclaration;
472    readonly returnType?: AstNode;
473    readonly isAnon: boolean;
474}
475
476export class FunctionExpression extends AstNode {
477    constructor(peer: KPtr) {
478        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_FUNCTION_EXPRESSION);
479        super(peer);
480        this.scriptFunction = unpackNonNullableNode(
481            global.generatedEs2panda._FunctionExpressionFunction(global.context, this.peer)
482        );
483    }
484
485    static create(expression: ScriptFunction): FunctionExpression {
486        return new FunctionExpression(
487            global.generatedEs2panda._CreateFunctionExpression(global.context, passNode(expression))
488        );
489    }
490
491    static update(node: FunctionExpression, expression: ScriptFunction): FunctionExpression {
492        return new FunctionExpression(
493            global.generatedEs2panda._UpdateFunctionExpression(global.context, node.peer, passNode(expression))
494        );
495    }
496
497    readonly scriptFunction: ScriptFunction;
498}
499
500export class ETSParameterExpression extends Expression {
501    constructor(peer: KPtr) {
502        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_ETS_PARAMETER_EXPRESSION);
503        super(peer);
504    }
505
506    static create(identifier: Identifier, initializer: AstNode | undefined): ETSParameterExpression {
507        if (initializer !== undefined) {
508            return new ETSParameterExpression(
509                global.generatedEs2panda._CreateETSParameterExpression1(
510                    global.context,
511                    passNode(identifier),
512                    passNode(initializer)
513                )
514            );
515        }
516        return new ETSParameterExpression(
517            global.generatedEs2panda._CreateETSParameterExpression(global.context, passNode(identifier), false)
518        );
519    }
520
521    static update(
522        node: ETSParameterExpression,
523        identifier: Identifier,
524        initializer: AstNode | undefined
525    ): ETSParameterExpression {
526        if (initializer !== undefined) {
527            return new ETSParameterExpression(
528                global.generatedEs2panda._UpdateETSParameterExpression1(
529                    global.context,
530                    node.peer,
531                    passNode(identifier),
532                    passNode(initializer)
533                )
534            );
535        }
536        return new ETSParameterExpression(
537            global.generatedEs2panda._UpdateETSParameterExpression(
538                global.context,
539                node.peer,
540                passNode(identifier),
541                false
542            )
543        );
544    }
545
546    get annotations(): AnnotationUsage[] {
547        return unpackNodeArray(global.es2panda._ETSParameterExpressionAnnotations(global.context, this.peer, nullptr));
548    }
549
550    set annotations(newAnnotations: AnnotationUsage[]) {
551        global.es2panda._ETSParameterExpressionSetAnnotations(
552            global.context,
553            this.peer,
554            passNodeArray(newAnnotations),
555            newAnnotations.length
556        );
557    }
558
559    get type(): AstNode | undefined {
560        return unpackNode(global.generatedEs2panda._ETSParameterExpressionTypeAnnotation(global.context, this.peer));
561    }
562
563    set type(t: AstNode | undefined) {
564        if (t === undefined) return;
565        global.generatedEs2panda._ETSParameterExpressionSetTypeAnnotation(global.context, this.peer, t.peer);
566    }
567
568    get optional(): Boolean {
569        return global.generatedEs2panda._ETSParameterExpressionIsOptionalConst(global.context, this.peer);
570    }
571
572    get initializer(): Expression | undefined {
573        return unpackNode(global.generatedEs2panda._ETSParameterExpressionInitializerConst(global.context, this.peer));
574    }
575
576    /** @deprecated */
577    setInitializer(initExpr?: Expression): this {
578        global.generatedEs2panda._ETSParameterExpressionSetInitializer(global.context, this.peer, passNode(initExpr));
579        return this;
580    }
581
582    setOptional(value: boolean): this {
583        global.generatedEs2panda._ETSParameterExpressionSetOptional(global.context, this.peer, value);
584        return this;
585    }
586
587    get identifier(): Identifier {
588        return unpackNonNullableNode(
589            global.generatedEs2panda._ETSParameterExpressionIdentConst(global.context, this.peer)
590        );
591    }
592
593    /** @deprecated */
594    setIdent(ident?: Identifier): this {
595        global.generatedEs2panda._ETSParameterExpressionSetIdent(global.context, this.peer, passNode(ident));
596        return this;
597    }
598}
599
600export class IfStatement extends AstNode {
601    constructor(peer: KPtr) {
602        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_IF_STATEMENT);
603        super(peer);
604        this.test = unpackNonNullableNode(global.generatedEs2panda._IfStatementTest(global.context, this.peer));
605        this.consequent = unpackNonNullableNode(
606            global.generatedEs2panda._IfStatementConsequent(global.context, this.peer)
607        );
608        this.alternate = unpackNode(global.generatedEs2panda._IfStatementAlternate(global.context, this.peer));
609    }
610
611    static create(test: AstNode, consequent: AstNode, alternate?: AstNode): IfStatement {
612        return new IfStatement(
613            global.generatedEs2panda._CreateIfStatement(
614                global.context,
615                passNode(test),
616                passNode(consequent),
617                passNode(alternate)
618            )
619        );
620    }
621
622    static update(node: IfStatement, test: AstNode, consequent: AstNode, alternate?: AstNode): IfStatement {
623        return new IfStatement(
624            global.generatedEs2panda._UpdateIfStatement(
625                global.context,
626                node.peer,
627                passNode(test),
628                passNode(consequent),
629                passNode(alternate)
630            )
631        );
632    }
633
634    test: AstNode;
635    consequent: AstNode;
636    alternate: AstNode | undefined;
637}
638
639export class StructDeclaration extends AstNode {
640    constructor(peer: KPtr) {
641        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_STRUCT_DECLARATION);
642        super(peer);
643        // TODO: is struct definition the same as struct definition?
644        this.definition = unpackNonNullableNode(
645            global.generatedEs2panda._ClassDeclarationDefinition(global.context, this.peer)
646        );
647    }
648
649    static create(definition: ClassDefinition): StructDeclaration {
650        return new StructDeclaration(
651            global.generatedEs2panda._CreateETSStructDeclaration(global.context, passNode(definition))
652        );
653    }
654
655    static update(node: StructDeclaration, definition: ClassDefinition): StructDeclaration {
656        return new StructDeclaration(
657            global.generatedEs2panda._UpdateETSStructDeclaration(global.context, node.peer, passNode(definition))
658        );
659    }
660
661    readonly definition: ClassDefinition;
662}
663
664export class MethodDefinition extends AstNode {
665    constructor(peer: KPtr, key?: KPtr) {
666        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_METHOD_DEFINITION);
667        super(peer);
668        this.kind = global.generatedEs2panda._MethodDefinitionKindConst(global.context, this.peer);
669        this.funcExpr = unpackNonNullableNode(global.generatedEs2panda._ClassElementValue(global.context, this.peer));
670        this.scriptFunction = this.funcExpr.scriptFunction;
671        assertValidPeer(this.scriptFunction.peer, Es2pandaAstNodeType.AST_NODE_TYPE_SCRIPT_FUNCTION);
672
673        // Somehow the scriptFunction cannot attach method's key to its ident after checker
674        if (key) {
675            assertValidPeer(key, Es2pandaAstNodeType.AST_NODE_TYPE_IDENTIFIER);
676            const _name = unpackNonNullableNode(key);
677            this.scriptFunction = this.scriptFunction.setIdent(_name as Identifier);
678        }
679
680        this.name = unpackNonNullableNode(
681            global.generatedEs2panda._ScriptFunctionId(global.context, this.scriptFunction.peer)
682        );
683        this.kind = global.generatedEs2panda._MethodDefinitionKindConst(global.context, this.peer);
684    }
685
686    static create(
687        kind: Es2pandaMethodDefinitionKind,
688        key: AstNode,
689        value: ScriptFunction,
690        modifiers: KInt,
691        isComputed: boolean
692    ): MethodDefinition {
693        return new MethodDefinition(
694            global.generatedEs2panda._CreateMethodDefinition(
695                global.context,
696                kind,
697                passNode(key),
698                passNode(FunctionExpression.create(value)),
699                modifiers,
700                isComputed
701            ),
702            key.peer
703        );
704    }
705
706    static update(
707        node: MethodDefinition,
708        kind: Es2pandaMethodDefinitionKind,
709        key: AstNode,
710        value: ScriptFunction,
711        modifiers: KInt,
712        isComputed: boolean
713    ): MethodDefinition {
714        return new MethodDefinition(
715            global.generatedEs2panda._UpdateMethodDefinition(
716                global.context,
717                node.peer,
718                kind,
719                passNode(key),
720                passNode(FunctionExpression.update(node.funcExpr, value)),
721                modifiers,
722                isComputed
723            ),
724            key.peer
725        );
726    }
727
728    // TODO: does not work
729    isConstructor(): boolean {
730        return global.generatedEs2panda._MethodDefinitionIsConstructorConst(global.context, this.peer);
731    }
732
733    get overloads(): readonly MethodDefinition[] {
734        return unpackNodeArray(global.generatedEs2panda._MethodDefinitionOverloadsConst(global.context, this.peer));
735    }
736
737    setOverloads(overloads: readonly MethodDefinition[]): this {
738        global.generatedEs2panda._MethodDefinitionSetOverloads(
739            global.context,
740            this.peer,
741            passNodeArray(overloads),
742            overloads.length
743        );
744        return this;
745    }
746
747    readonly kind: Es2pandaMethodDefinitionKind;
748    readonly scriptFunction: ScriptFunction;
749    readonly name: Identifier;
750    readonly funcExpr: FunctionExpression;
751}
752
753export class VariableDeclaration extends AstNode {
754    constructor(peer: KPtr) {
755        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_VARIABLE_DECLARATION);
756        super(peer);
757        this.declarationKind = global.generatedEs2panda._VariableDeclarationKindConst(global.context, this.peer);
758        this.declarators = unpackNodeArray(
759            global.generatedEs2panda._VariableDeclarationDeclaratorsConst(global.context, this.peer)
760        );
761    }
762
763    static create(
764        modifiers: KInt,
765        kind: Es2pandaVariableDeclarationKind,
766        declarators: readonly VariableDeclarator[]
767    ): VariableDeclaration {
768        const peer = global.generatedEs2panda._CreateVariableDeclaration(
769            global.context,
770            kind,
771            passNodeArray(declarators),
772            declarators.length
773        );
774        global.generatedEs2panda._AstNodeClearModifier(global.context, peer, allFlags);
775        global.generatedEs2panda._AstNodeAddModifier(global.context, peer, modifiers);
776        return new VariableDeclaration(peer);
777    }
778
779    static update(
780        node: VariableDeclaration,
781        modifiers: KInt,
782        kind: Es2pandaVariableDeclarationKind,
783        declarators: readonly VariableDeclarator[]
784    ): VariableDeclaration {
785        const peer = global.generatedEs2panda._UpdateVariableDeclaration(
786            global.context,
787            node.peer,
788            kind,
789            passNodeArray(declarators),
790            declarators.length
791        );
792        global.generatedEs2panda._AstNodeClearModifier(global.context, peer, allFlags);
793        global.generatedEs2panda._AstNodeAddModifier(global.context, peer, modifiers);
794        return new VariableDeclaration(peer);
795    }
796
797    get annotations(): readonly AnnotationUsage[] {
798        return unpackNodeArray(
799            global.generatedEs2panda._VariableDeclarationAnnotationsConst(global.context, this.peer)
800        );
801    }
802    /** @deprecated */
803    setAnnotations(annotations: readonly AnnotationUsage[]): this {
804        global.generatedEs2panda._VariableDeclarationSetAnnotations(
805            global.context,
806            this.peer,
807            passNodeArray(annotations),
808            annotations.length
809        );
810        return this;
811    }
812
813    readonly declarationKind: Es2pandaVariableDeclarationKind;
814    readonly declarators: readonly VariableDeclarator[];
815}
816
817export class VariableDeclarator extends AstNode {
818    constructor(peer: KPtr) {
819        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_VARIABLE_DECLARATOR);
820        super(peer);
821        this.name = unpackNonNullableNode(global.generatedEs2panda._VariableDeclaratorId(global.context, this.peer));
822    }
823
824    static create(
825        flag: Es2pandaVariableDeclaratorFlag,
826        name: Identifier,
827        initializer: AstNode | undefined
828    ): VariableDeclarator {
829        const peer = global.generatedEs2panda._CreateVariableDeclarator(global.context, flag, passNode(name));
830        if (initializer !== undefined) {
831            global.generatedEs2panda._VariableDeclaratorSetInit(global.context, peer, initializer.peer);
832        }
833        return new VariableDeclarator(peer);
834    }
835
836    static update(
837        node: VariableDeclarator,
838        flag: Es2pandaVariableDeclaratorFlag,
839        name: Identifier,
840        initializer: AstNode | undefined
841    ): VariableDeclarator {
842        const peer = global.generatedEs2panda._UpdateVariableDeclarator(
843            global.context,
844            node.peer,
845            flag,
846            passNode(name)
847        );
848        if (initializer !== undefined) {
849            global.generatedEs2panda._VariableDeclaratorSetInit(global.context, peer, initializer.peer);
850        }
851        return new VariableDeclarator(peer);
852    }
853
854    get initializer(): AstNode | undefined {
855        return unpackNode(global.generatedEs2panda._VariableDeclaratorInit(global.context, this.peer));
856    }
857
858    /** @deprecated */
859    setInit(init?: Expression): this {
860        global.generatedEs2panda._VariableDeclaratorSetInit(global.context, this.peer, passNode(init));
861        return this;
862    }
863
864    get flag(): Es2pandaVariableDeclaratorFlag {
865        return global.generatedEs2panda._VariableDeclaratorFlag(global.context, this.peer);
866    }
867
868    readonly name: Identifier;
869}
870
871export class SuperExpression extends AstNode {
872    constructor(peer: KPtr) {
873        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_SUPER_EXPRESSION);
874        super(peer);
875        this.id = unpackNode(global.generatedEs2panda._TSInterfaceDeclarationId(global.context, this.peer));
876    }
877
878    static create(): SuperExpression {
879        return new SuperExpression(global.generatedEs2panda._CreateSuperExpression(global.context));
880    }
881
882    readonly id?: Identifier;
883}
884
885export class ETSStringLiteralType extends TypeNode {
886    constructor(peer: KPtr) {
887        assertValidPeer(peer, Es2pandaAstNodeType.AST_NODE_TYPE_ETS_STRING_LITERAL_TYPE);
888        super(peer);
889    }
890
891    static create(str: string): ETSStringLiteralType {
892        return new ETSStringLiteralType(global.es2panda._CreateETSStringLiteralType(global.context, passString(str)));
893    }
894}
895
896const pairs: [Es2pandaAstNodeType, { new (peer: KNativePointer): AstNode }][] = [
897    [Es2pandaAstNodeType.AST_NODE_TYPE_ETS_MODULE, EtsScript],
898    [Es2pandaAstNodeType.AST_NODE_TYPE_IDENTIFIER, Identifier],
899    [Es2pandaAstNodeType.AST_NODE_TYPE_NUMBER_LITERAL, NumberLiteral],
900    [Es2pandaAstNodeType.AST_NODE_TYPE_EXPRESSION_STATEMENT, ExpressionStatement],
901    [Es2pandaAstNodeType.AST_NODE_TYPE_FUNCTION_DECLARATION, FunctionDeclaration],
902    [Es2pandaAstNodeType.AST_NODE_TYPE_SCRIPT_FUNCTION, ScriptFunction],
903    [Es2pandaAstNodeType.AST_NODE_TYPE_BLOCK_STATEMENT, BlockStatement],
904    [Es2pandaAstNodeType.AST_NODE_TYPE_ETS_PARAMETER_EXPRESSION, ETSParameterExpression],
905    [Es2pandaAstNodeType.AST_NODE_TYPE_TS_TYPE_PARAMETER_DECLARATION, TSTypeParameterDeclaration],
906    [Es2pandaAstNodeType.AST_NODE_TYPE_CALL_EXPRESSION, CallExpression],
907    [Es2pandaAstNodeType.AST_NODE_TYPE_MEMBER_EXPRESSION, MemberExpression],
908    [Es2pandaAstNodeType.AST_NODE_TYPE_IF_STATEMENT, IfStatement],
909    [Es2pandaAstNodeType.AST_NODE_TYPE_ARROW_FUNCTION_EXPRESSION, ArrowFunctionExpression],
910    [Es2pandaAstNodeType.AST_NODE_TYPE_STRUCT_DECLARATION, StructDeclaration],
911    [Es2pandaAstNodeType.AST_NODE_TYPE_METHOD_DEFINITION, MethodDefinition],
912    [Es2pandaAstNodeType.AST_NODE_TYPE_ASSIGNMENT_EXPRESSION, AssignmentExpression],
913    [Es2pandaAstNodeType.AST_NODE_TYPE_VARIABLE_DECLARATION, VariableDeclaration],
914    [Es2pandaAstNodeType.AST_NODE_TYPE_VARIABLE_DECLARATOR, VariableDeclarator],
915    [Es2pandaAstNodeType.AST_NODE_TYPE_FUNCTION_EXPRESSION, FunctionExpression],
916    [Es2pandaAstNodeType.AST_NODE_TYPE_ETS_TYPE_REFERENCE, ETSTypeReference],
917    [Es2pandaAstNodeType.AST_NODE_TYPE_ETS_TYPE_REFERENCE_PART, ETSTypeReferencePart],
918    [Es2pandaAstNodeType.AST_NODE_TYPE_OBJECT_EXPRESSION, ObjectExpression],
919    [Es2pandaAstNodeType.AST_NODE_TYPE_ARRAY_EXPRESSION, ArrayExpression],
920];
921pairs.forEach(([nodeType, astNode]) => nodeByType.set(nodeType, astNode));
922