• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2024-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 */
15
16import * as ts from 'ohos-typescript';
17import { Local } from '../base/Local';
18import { FullPosition } from '../base/Position';
19import { ArkAliasTypeDefineStmt, ArkAssignStmt, ArkIfStmt, ArkInvokeStmt, Stmt } from '../base/Stmt';
20import {
21    AbstractBinopExpr,
22    ArkAwaitExpr,
23    ArkCastExpr,
24    ArkConditionExpr,
25    ArkDeleteExpr,
26    ArkInstanceInvokeExpr,
27    ArkInstanceOfExpr,
28    ArkNewArrayExpr,
29    ArkNewExpr,
30    ArkNormalBinopExpr,
31    ArkPtrInvokeExpr,
32    ArkStaticInvokeExpr,
33    ArkTypeOfExpr,
34    ArkUnopExpr,
35    ArkYieldExpr,
36    BinaryOperator,
37    NormalBinaryOperator,
38    RelationalBinaryOperator,
39} from '../base/Expr';
40import { ArkClass } from '../model/ArkClass';
41import { buildNormalArkClassFromArkFile, buildNormalArkClassFromArkNamespace } from '../model/builder/ArkClassBuilder';
42import {
43    AliasType,
44    AnyType,
45    ArrayType,
46    BigIntType,
47    BooleanType,
48    ClassType,
49    FunctionType,
50    IntersectionType,
51    LiteralType,
52    NeverType,
53    NullType,
54    NumberType,
55    StringType,
56    TupleType,
57    Type,
58    UnclearReferenceType,
59    UndefinedType,
60    UnionType,
61    UnknownType,
62    VoidType,
63} from '../base/Type';
64import { ArkSignatureBuilder } from '../model/builder/ArkSignatureBuilder';
65import { CONSTRUCTOR_NAME, THIS_NAME } from './TSConst';
66import { ClassSignature, FieldSignature, MethodSignature } from '../model/ArkSignature';
67import { Value } from '../base/Value';
68import {
69    COMPONENT_CREATE_FUNCTION,
70    COMPONENT_CUSTOMVIEW,
71    COMPONENT_FOR_EACH,
72    COMPONENT_LAZY_FOR_EACH,
73    COMPONENT_POP_FUNCTION,
74    isEtsSystemComponent,
75} from './EtsConst';
76import { ValueUtil } from './ValueUtil';
77import { IRUtils } from './IRUtils';
78import { AbstractFieldRef, ArkArrayRef, ArkInstanceFieldRef, ArkStaticFieldRef, GlobalRef } from '../base/Ref';
79import { ModelUtils } from './ModelUtils';
80import { ArkMethod } from '../model/ArkMethod';
81import { buildArkMethodFromArkClass } from '../model/builder/ArkMethodBuilder';
82import { Builtin } from './Builtin';
83import { Constant } from '../base/Constant';
84import { TEMP_LOCAL_PREFIX } from './Const';
85import { ArkIRTransformer, DummyStmt, ValueAndStmts } from './ArkIRTransformer';
86import Logger, { LOG_MODULE_TYPE } from '../../utils/logger';
87import { TypeInference } from './TypeInference';
88import { KeyofTypeExpr, TypeQueryExpr } from '../base/TypeExpr';
89
90const logger = Logger.getLogger(LOG_MODULE_TYPE.ARKANALYZER, 'ArkValueTransformer');
91
92export class ArkValueTransformer {
93    private conditionalOperatorNo: number = 0;
94    private tempLocalNo: number = 0;
95    private sourceFile: ts.SourceFile;
96    private locals: Map<string, Local> = new Map();
97    private globals?: Map<string, GlobalRef>;
98    private thisLocal: Local;
99    private declaringMethod: ArkMethod;
100    private arkIRTransformer: ArkIRTransformer;
101    private aliasTypeMap: Map<string, [AliasType, ArkAliasTypeDefineStmt]> = new Map();
102    private builderMethodContextFlag = false;
103
104    constructor(arkIRTransformer: ArkIRTransformer, sourceFile: ts.SourceFile, declaringMethod: ArkMethod) {
105        this.arkIRTransformer = arkIRTransformer;
106        this.sourceFile = sourceFile;
107        this.thisLocal = new Local(THIS_NAME, declaringMethod.getDeclaringArkClass().getSignature().getType());
108        this.locals.set(this.thisLocal.getName(), this.thisLocal);
109        this.declaringMethod = declaringMethod;
110    }
111
112    public getLocals(): Set<Local> {
113        return new Set<Local>(this.locals.values());
114    }
115
116    public getThisLocal(): Local {
117        return this.thisLocal;
118    }
119
120    public getAliasTypeMap(): Map<string, [AliasType, ArkAliasTypeDefineStmt]> {
121        return this.aliasTypeMap;
122    }
123
124    public addNewLocal(localName: string, localType: Type = UnknownType.getInstance()): Local {
125        let local = new Local(localName, localType);
126        this.locals.set(localName, local);
127        return local;
128    }
129
130    public getGlobals(): Map<string, GlobalRef> | null {
131        return this.globals ?? null;
132    }
133
134    private addNewGlobal(name: string, ref?: Value): GlobalRef {
135        let globalRef = new GlobalRef(name, ref);
136        this.globals = this.globals ?? new Map();
137        this.globals.set(name, globalRef);
138        return globalRef;
139    }
140
141    public tsNodeToValueAndStmts(node: ts.Node): ValueAndStmts {
142        if (ts.isBinaryExpression(node)) {
143            return this.binaryExpressionToValueAndStmts(node);
144        } else if (ts.isCallExpression(node)) {
145            return this.callExpressionToValueAndStmts(node);
146        } else if (ts.isVariableDeclarationList(node)) {
147            return this.variableDeclarationListToValueAndStmts(node);
148        } else if (ts.isIdentifier(node)) {
149            return this.identifierToValueAndStmts(node);
150        } else if (ts.isPropertyAccessExpression(node)) {
151            return this.propertyAccessExpressionToValue(node);
152        } else if (ts.isPrefixUnaryExpression(node)) {
153            return this.prefixUnaryExpressionToValueAndStmts(node);
154        } else if (ts.isPostfixUnaryExpression(node)) {
155            return this.postfixUnaryExpressionToValueAndStmts(node);
156        } else if (ts.isTemplateExpression(node)) {
157            return this.templateExpressionToValueAndStmts(node);
158        } else if (ts.isTaggedTemplateExpression(node)) {
159            return this.taggedTemplateExpressionToValueAndStmts(node);
160        } else if (ts.isAwaitExpression(node)) {
161            return this.awaitExpressionToValueAndStmts(node);
162        } else if (ts.isYieldExpression(node)) {
163            return this.yieldExpressionToValueAndStmts(node);
164        } else if (ts.isDeleteExpression(node)) {
165            return this.deleteExpressionToValueAndStmts(node);
166        } else if (ts.isVoidExpression(node)) {
167            return this.voidExpressionToValueAndStmts(node);
168        } else if (ts.isElementAccessExpression(node)) {
169            return this.elementAccessExpressionToValueAndStmts(node);
170        } else if (ts.isNewExpression(node)) {
171            return this.newExpressionToValueAndStmts(node);
172        } else if (ts.isParenthesizedExpression(node)) {
173            return this.parenthesizedExpressionToValueAndStmts(node);
174        } else if (ts.isAsExpression(node)) {
175            return this.asExpressionToValueAndStmts(node);
176        } else if (ts.isNonNullExpression(node)) {
177            return this.nonNullExpressionToValueAndStmts(node);
178        } else if (ts.isTypeAssertionExpression(node)) {
179            return this.typeAssertionToValueAndStmts(node);
180        } else if (ts.isTypeOfExpression(node)) {
181            return this.typeOfExpressionToValueAndStmts(node);
182        } else if (ts.isArrayLiteralExpression(node)) {
183            return this.arrayLiteralExpressionToValueAndStmts(node);
184        } else if (this.isLiteralNode(node)) {
185            return this.literalNodeToValueAndStmts(node) as ValueAndStmts;
186        } else if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
187            return this.callableNodeToValueAndStmts(node);
188        } else if (ts.isClassExpression(node)) {
189            return this.classExpressionToValueAndStmts(node);
190        } else if (ts.isEtsComponentExpression(node)) {
191            return this.etsComponentExpressionToValueAndStmts(node);
192        } else if (ts.isObjectLiteralExpression(node)) {
193            return this.objectLiteralExpresionToValueAndStmts(node);
194        } else if (node.kind === ts.SyntaxKind.ThisKeyword) {
195            return this.thisExpressionToValueAndStmts(node as ts.ThisExpression);
196        } else if (ts.isConditionalExpression(node)) {
197            return this.conditionalExpressionToValueAndStmts(node);
198        }
199
200        return {
201            value: new Local(node.getText(this.sourceFile)),
202            valueOriginalPositions: [FullPosition.buildFromNode(node, this.sourceFile)],
203            stmts: [],
204        };
205    }
206
207    private tsNodeToSingleAddressValueAndStmts(node: ts.Node): ValueAndStmts {
208        const allStmts: Stmt[] = [];
209        let { value, valueOriginalPositions, stmts } = this.tsNodeToValueAndStmts(node);
210        stmts.forEach(stmt => allStmts.push(stmt));
211        if (IRUtils.moreThanOneAddress(value)) {
212            ({ value, valueOriginalPositions, stmts } = this.arkIRTransformer.generateAssignStmtForValue(value, valueOriginalPositions));
213            stmts.forEach(stmt => allStmts.push(stmt));
214        }
215        return { value, valueOriginalPositions, stmts: allStmts };
216    }
217
218    private thisExpressionToValueAndStmts(thisExpression: ts.ThisExpression): ValueAndStmts {
219        return {
220            value: this.getThisLocal(),
221            valueOriginalPositions: [FullPosition.buildFromNode(thisExpression, this.sourceFile)],
222            stmts: [],
223        };
224    }
225
226    private conditionalExpressionToValueAndStmts(conditionalExpression: ts.ConditionalExpression): ValueAndStmts {
227        const stmts: Stmt[] = [];
228        const currConditionalOperatorIndex = this.conditionalOperatorNo++;
229        const {
230            value: conditionValue,
231            valueOriginalPositions: conditionPositions,
232            stmts: conditionStmts,
233        } = this.conditionToValueAndStmts(conditionalExpression.condition);
234        conditionStmts.forEach(stmt => stmts.push(stmt));
235        const ifStmt = new ArkIfStmt(conditionValue as ArkConditionExpr);
236        ifStmt.setOperandOriginalPositions(conditionPositions);
237        stmts.push(ifStmt);
238
239        stmts.push(new DummyStmt(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_TRUE_STMT + currConditionalOperatorIndex));
240        const {
241            value: whenTrueValue,
242            valueOriginalPositions: whenTruePositions,
243            stmts: whenTrueStmts,
244        } = this.tsNodeToValueAndStmts(conditionalExpression.whenTrue);
245        whenTrueStmts.forEach(stmt => stmts.push(stmt));
246        const resultLocal = this.generateTempLocal();
247        const assignStmtWhenTrue = new ArkAssignStmt(resultLocal, whenTrueValue);
248        const resultLocalPosition: FullPosition[] = [whenTruePositions[0]];
249        assignStmtWhenTrue.setOperandOriginalPositions([...resultLocalPosition, ...whenTruePositions]);
250        stmts.push(assignStmtWhenTrue);
251
252        stmts.push(new DummyStmt(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_IF_FALSE_STMT + currConditionalOperatorIndex));
253        const {
254            value: whenFalseValue,
255            valueOriginalPositions: whenFalsePositions,
256            stmts: whenFalseStmts,
257        } = this.tsNodeToValueAndStmts(conditionalExpression.whenFalse);
258        whenFalseStmts.forEach(stmt => stmts.push(stmt));
259        const assignStmt = new ArkAssignStmt(resultLocal, whenFalseValue);
260        assignStmt.setOperandOriginalPositions([...resultLocalPosition, ...whenFalsePositions]);
261        stmts.push(assignStmt);
262        stmts.push(new DummyStmt(ArkIRTransformer.DUMMY_CONDITIONAL_OPERATOR_END_STMT + currConditionalOperatorIndex));
263        return {
264            value: resultLocal,
265            valueOriginalPositions: resultLocalPosition,
266            stmts: stmts,
267        };
268    }
269
270    private objectLiteralExpresionToValueAndStmts(objectLiteralExpression: ts.ObjectLiteralExpression): ValueAndStmts {
271        const declaringArkClass = this.declaringMethod.getDeclaringArkClass();
272        const declaringArkNamespace = declaringArkClass.getDeclaringArkNamespace();
273        const anonymousClass = new ArkClass();
274        if (declaringArkNamespace) {
275            buildNormalArkClassFromArkNamespace(objectLiteralExpression, declaringArkNamespace, anonymousClass, this.sourceFile, this.declaringMethod);
276            declaringArkNamespace.addArkClass(anonymousClass);
277        } else {
278            const declaringArkFile = declaringArkClass.getDeclaringArkFile();
279            buildNormalArkClassFromArkFile(objectLiteralExpression, declaringArkFile, anonymousClass, this.sourceFile, this.declaringMethod);
280            declaringArkFile.addArkClass(anonymousClass);
281        }
282
283        const objectLiteralExpressionPosition = FullPosition.buildFromNode(objectLiteralExpression, this.sourceFile);
284        const stmts: Stmt[] = [];
285        const anonymousClassSignature = anonymousClass.getSignature();
286        const anonymousClassType = new ClassType(anonymousClassSignature);
287        const newExpr = new ArkNewExpr(anonymousClassType);
288        const {
289            value: newExprLocal,
290            valueOriginalPositions: newExprLocalPositions,
291            stmts: newExprStmts,
292        } = this.arkIRTransformer.generateAssignStmtForValue(newExpr, [objectLiteralExpressionPosition]);
293        newExprStmts.forEach(stmt => stmts.push(stmt));
294
295        const constructorMethodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(CONSTRUCTOR_NAME);
296        const constructorMethodSignature = new MethodSignature(anonymousClassSignature, constructorMethodSubSignature);
297        const constructorInvokeExpr = new ArkInstanceInvokeExpr(newExprLocal as Local, constructorMethodSignature, []);
298        const constructorInvokeExprPositions = [objectLiteralExpressionPosition, ...newExprLocalPositions];
299        const constructorInvokeStmt = new ArkInvokeStmt(constructorInvokeExpr);
300        constructorInvokeStmt.setOperandOriginalPositions(constructorInvokeExprPositions);
301        stmts.push(constructorInvokeStmt);
302
303        return {
304            value: newExprLocal,
305            valueOriginalPositions: newExprLocalPositions,
306            stmts: stmts,
307        };
308    }
309
310    private generateSystemComponentStmt(
311        componentName: string,
312        args: Value[],
313        argPositionsAllFlat: FullPosition[],
314        componentExpression: ts.EtsComponentExpression | ts.CallExpression,
315        currStmts: Stmt[]
316    ): ValueAndStmts {
317        const stmts: Stmt[] = [...currStmts];
318        const componentExpressionPosition = FullPosition.buildFromNode(componentExpression, this.sourceFile);
319        const {
320            value: componentValue,
321            valueOriginalPositions: componentPositions,
322            stmts: componentStmts,
323        } = this.generateComponentCreationStmts(componentName, args, componentExpressionPosition, argPositionsAllFlat);
324        componentStmts.forEach(stmt => stmts.push(stmt));
325
326        if (ts.isEtsComponentExpression(componentExpression) && componentExpression.body) {
327            for (const statement of componentExpression.body.statements) {
328                this.arkIRTransformer.tsNodeToStmts(statement).forEach(stmt => stmts.push(stmt));
329            }
330        }
331        stmts.push(this.generateComponentPopStmts(componentName, componentExpressionPosition));
332        return {
333            value: componentValue,
334            valueOriginalPositions: componentPositions,
335            stmts: stmts,
336        };
337    }
338
339    private generateCustomViewStmt(
340        componentName: string,
341        args: Value[],
342        argPositionsAllFlat: FullPosition[],
343        componentExpression: ts.EtsComponentExpression | ts.CallExpression,
344        currStmts: Stmt[]
345    ): ValueAndStmts {
346        const stmts: Stmt[] = [...currStmts];
347        const componentExpressionPosition = FullPosition.buildFromNode(componentExpression, this.sourceFile);
348        const classSignature = ArkSignatureBuilder.buildClassSignatureFromClassName(componentName);
349        const classType = new ClassType(classSignature);
350        const newExpr = new ArkNewExpr(classType);
351        const {
352            value: newExprLocal,
353            valueOriginalPositions: newExprPositions,
354            stmts: newExprStmts,
355        } = this.arkIRTransformer.generateAssignStmtForValue(newExpr, [componentExpressionPosition]);
356        newExprStmts.forEach(stmt => stmts.push(stmt));
357        const constructorMethodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(CONSTRUCTOR_NAME);
358        const constructorMethodSignature = new MethodSignature(classSignature, constructorMethodSubSignature);
359        const instanceInvokeExpr = new ArkInstanceInvokeExpr(newExprLocal as Local, constructorMethodSignature, args);
360        const instanceInvokeExprPositions = [componentExpressionPosition, ...newExprPositions, ...argPositionsAllFlat];
361        const instanceInvokeStmt = new ArkInvokeStmt(instanceInvokeExpr);
362        instanceInvokeStmt.setOperandOriginalPositions(instanceInvokeExprPositions);
363        stmts.push(instanceInvokeStmt);
364        const createViewArgs = [newExprLocal];
365        const createViewArgPositionsAll = [newExprPositions];
366        if (ts.isEtsComponentExpression(componentExpression) && componentExpression.body) {
367            const anonymous = ts.factory.createArrowFunction([], [], [], undefined, undefined, componentExpression.body);
368            // @ts-expect-error: add pos info for the created ArrowFunction
369            anonymous.pos = componentExpression.body.pos;
370            // @ts-expect-error: add end info for the created ArrowFunction
371            anonymous.end = componentExpression.body.end;
372            const { value: builderMethod, valueOriginalPositions: builderMethodPositions } = this.callableNodeToValueAndStmts(anonymous);
373            createViewArgs.push(builderMethod);
374            createViewArgPositionsAll.push(builderMethodPositions);
375        }
376        const {
377            value: componentValue,
378            valueOriginalPositions: componentPositions,
379            stmts: componentStmts,
380        } = this.generateComponentCreationStmts(COMPONENT_CUSTOMVIEW, createViewArgs, componentExpressionPosition, createViewArgPositionsAll.flat());
381        componentStmts.forEach(stmt => stmts.push(stmt));
382        stmts.push(this.generateComponentPopStmts(COMPONENT_CUSTOMVIEW, componentExpressionPosition));
383        return {
384            value: componentValue,
385            valueOriginalPositions: componentPositions,
386            stmts: stmts,
387        };
388    }
389
390    private generateComponentCreationStmts(
391        componentName: string,
392        createArgs: Value[],
393        componentExpressionPosition: FullPosition,
394        createArgsPositionsAllFlat: FullPosition[]
395    ): ValueAndStmts {
396        const createMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(componentName, COMPONENT_CREATE_FUNCTION);
397        const createInvokeExpr = new ArkStaticInvokeExpr(createMethodSignature, createArgs);
398        const createInvokeExprPositions = [componentExpressionPosition, ...createArgsPositionsAllFlat];
399        const {
400            value: componentValue,
401            valueOriginalPositions: componentPositions,
402            stmts: componentStmts,
403        } = this.arkIRTransformer.generateAssignStmtForValue(createInvokeExpr, createInvokeExprPositions);
404        return {
405            value: componentValue,
406            valueOriginalPositions: componentPositions,
407            stmts: componentStmts,
408        };
409    }
410
411    private generateComponentPopStmts(componentName: string, componentExpressionPosition: FullPosition): Stmt {
412        const popMethodSignature = ArkSignatureBuilder.buildMethodSignatureFromClassNameAndMethodName(componentName, COMPONENT_POP_FUNCTION);
413        const popInvokeExpr = new ArkStaticInvokeExpr(popMethodSignature, []);
414        const popInvokeExprPositions = [componentExpressionPosition];
415        const popInvokeStmt = new ArkInvokeStmt(popInvokeExpr);
416        popInvokeStmt.setOperandOriginalPositions(popInvokeExprPositions);
417        return popInvokeStmt;
418    }
419
420    private etsComponentExpressionToValueAndStmts(etsComponentExpression: ts.EtsComponentExpression): ValueAndStmts {
421        const stmts: Stmt[] = [];
422        const componentName = (etsComponentExpression.expression as ts.Identifier).text;
423        const { args: args, argPositions: argPositions } = this.parseArguments(stmts, etsComponentExpression.arguments);
424        if (isEtsSystemComponent(componentName)) {
425            return this.generateSystemComponentStmt(componentName, args, argPositions, etsComponentExpression, stmts);
426        }
427        return this.generateCustomViewStmt(componentName, args, argPositions, etsComponentExpression, stmts);
428    }
429
430    private classExpressionToValueAndStmts(classExpression: ts.ClassExpression): ValueAndStmts {
431        const declaringArkClass = this.declaringMethod.getDeclaringArkClass();
432        const declaringArkNamespace = declaringArkClass.getDeclaringArkNamespace();
433        const newClass = new ArkClass();
434        if (declaringArkNamespace) {
435            buildNormalArkClassFromArkNamespace(classExpression, declaringArkNamespace, newClass, this.sourceFile, this.declaringMethod);
436            declaringArkNamespace.addArkClass(newClass);
437        } else {
438            const declaringArkFile = declaringArkClass.getDeclaringArkFile();
439            buildNormalArkClassFromArkFile(classExpression, declaringArkFile, newClass, this.sourceFile, this.declaringMethod);
440            declaringArkFile.addArkClass(newClass);
441        }
442        const classValue = this.addNewLocal(newClass.getName(), new ClassType(newClass.getSignature()));
443        return {
444            value: classValue,
445            valueOriginalPositions: [FullPosition.buildFromNode(classExpression, this.sourceFile)],
446            stmts: [],
447        };
448    }
449
450    private templateExpressionToValueAndStmts(templateExpression: ts.TemplateExpression): ValueAndStmts {
451        const { stmts, stringTextValues, placeholderValues, stringTextPositions, placeholderPositions } = this.collectTemplateValues(templateExpression);
452
453        const { placeholderStringLocals, placeholderStringLocalPositions, newStmts } = this.processTemplatePlaceholders(
454            placeholderValues,
455            placeholderPositions,
456            stmts
457        );
458
459        return this.combineTemplateParts(stringTextValues, stringTextPositions, placeholderStringLocals, placeholderStringLocalPositions, newStmts);
460    }
461
462    private processTemplatePlaceholders(
463        placeholderValues: Value[],
464        placeholderPositions: FullPosition[],
465        currStmts: Stmt[]
466    ): {
467        placeholderStringLocals: Local[];
468        placeholderStringLocalPositions: FullPosition[];
469        newStmts: Stmt[];
470    } {
471        const placeholderStringLocals: Local[] = [];
472        const placeholderStringLocalPositions: FullPosition[] = [];
473        const newStmts: Stmt[] = [...currStmts];
474
475        for (let i = 0; i < placeholderValues.length; i++) {
476            let placeholderValue = placeholderValues[i];
477            let placeholderPosition: FullPosition[] = [placeholderPositions[i]];
478            let placeholderStmts: Stmt[] = [];
479
480            if (!(placeholderValue instanceof Local)) {
481                ({
482                    value: placeholderValue,
483                    valueOriginalPositions: placeholderPosition,
484                    stmts: placeholderStmts,
485                } = this.arkIRTransformer.generateAssignStmtForValue(placeholderValue, placeholderPosition));
486            }
487
488            placeholderStmts.forEach(stmt => newStmts.push(stmt));
489            const toStringExpr = new ArkInstanceInvokeExpr(placeholderValue as Local, Builtin.TO_STRING_METHOD_SIGNATURE, []);
490            const toStringExprPosition: FullPosition[] = [placeholderPosition[0], placeholderPosition[0]];
491            const {
492                value: placeholderStringLocal,
493                valueOriginalPositions: placeholderStringPositions,
494                stmts: toStringStmts,
495            } = this.arkIRTransformer.generateAssignStmtForValue(toStringExpr, toStringExprPosition);
496            placeholderStringLocals.push(placeholderStringLocal as Local);
497            placeholderStringLocalPositions.push(placeholderStringPositions[0]);
498            toStringStmts.forEach(stmt => newStmts.push(stmt));
499        }
500
501        return {
502            placeholderStringLocals,
503            placeholderStringLocalPositions,
504            newStmts,
505        };
506    }
507
508    private combineTemplateParts(
509        stringTextValues: Value[],
510        stringTextPositions: FullPosition[],
511        placeholderStringLocals: Local[],
512        placeholderStringLocalPositions: FullPosition[],
513        currStmts: Stmt[]
514    ): ValueAndStmts {
515        const templateParts: Value[] = [];
516        const templatePartPositions: FullPosition[] = [];
517
518        for (let i = 0; i < placeholderStringLocals.length; i++) {
519            if (stringTextValues[i] !== ValueUtil.EMPTY_STRING_CONSTANT) {
520                templateParts.push(stringTextValues[i]);
521                templatePartPositions.push(stringTextPositions[i]);
522            }
523            templateParts.push(placeholderStringLocals[i]);
524            templatePartPositions.push(placeholderStringLocalPositions[i]);
525        }
526
527        if (stringTextValues[stringTextValues.length - 1] !== ValueUtil.EMPTY_STRING_CONSTANT) {
528            templateParts.push(stringTextValues[stringTextValues.length - 1]);
529            templatePartPositions.push(stringTextPositions[stringTextPositions.length - 1]);
530        }
531
532        let currTemplateResult: Value = templateParts[0];
533        let currTemplateResultPosition: FullPosition = templatePartPositions[0];
534        const finalStmts: Stmt[] = [...currStmts];
535
536        for (let i = 1; i < templateParts.length; i++) {
537            const nextTemplatePartPosition = templatePartPositions[i];
538            const normalBinopExpr = new ArkNormalBinopExpr(currTemplateResult, templateParts[i], NormalBinaryOperator.Addition);
539            const normalBinopExprPositions = [
540                FullPosition.merge(currTemplateResultPosition, nextTemplatePartPosition),
541                currTemplateResultPosition,
542                nextTemplatePartPosition,
543            ];
544            const {
545                value: combinationValue,
546                valueOriginalPositions: combinationValuePositions,
547                stmts: combinationStmts,
548            } = this.arkIRTransformer.generateAssignStmtForValue(normalBinopExpr, normalBinopExprPositions);
549            combinationStmts.forEach(stmt => finalStmts.push(stmt));
550            currTemplateResult = combinationValue;
551            currTemplateResultPosition = combinationValuePositions[0];
552        }
553
554        return {
555            value: currTemplateResult,
556            valueOriginalPositions: [currTemplateResultPosition],
557            stmts: finalStmts,
558        };
559    }
560
561    private taggedTemplateExpressionToValueAndStmts(taggedTemplateExpression: ts.TaggedTemplateExpression): ValueAndStmts {
562        const { stmts, stringTextValues, placeholderValues, stringTextPositions, placeholderPositions } = this.collectTemplateValues(
563            taggedTemplateExpression.template
564        );
565        const stringTextBaseType = StringType.getInstance();
566        const stringTextArrayLen = stringTextValues.length;
567        const stringTextArrayLenValue = ValueUtil.getOrCreateNumberConst(stringTextArrayLen);
568        const stringTextArrayLenPosition = FullPosition.DEFAULT;
569        const {
570            value: templateObjectLocal,
571            valueOriginalPositions: templateObjectLocalPositions,
572            stmts: templateObjectStmts,
573        } = this.generateArrayExprAndStmts(
574            stringTextBaseType,
575            stringTextArrayLenValue,
576            stringTextArrayLenPosition,
577            stringTextArrayLen,
578            stringTextValues,
579            stringTextPositions,
580            stmts,
581            FullPosition.DEFAULT,
582            true
583        );
584
585        const placeholderBaseType = AnyType.getInstance();
586        const placeholdersArrayLen = placeholderValues.length;
587        const placeholdersArrayLenValue = ValueUtil.getOrCreateNumberConst(placeholdersArrayLen);
588        const placeholdersArrayLenPosition = FullPosition.DEFAULT;
589        const {
590            value: placeholdersLocal,
591            valueOriginalPositions: placeholdersLocalPositions,
592            stmts: placeholdersStmts,
593        } = this.generateArrayExprAndStmts(
594            placeholderBaseType,
595            placeholdersArrayLenValue,
596            placeholdersArrayLenPosition,
597            placeholdersArrayLen,
598            placeholderValues,
599            placeholderPositions,
600            templateObjectStmts,
601            FullPosition.DEFAULT,
602            true
603        );
604
605        const taggedFuncArgus = {
606            realGenericTypes: undefined,
607            args: [templateObjectLocal, placeholdersLocal],
608            argPositions: [templateObjectLocalPositions[0], placeholdersLocalPositions[0]],
609        };
610        return this.generateInvokeValueAndStmts(taggedTemplateExpression.tag, taggedFuncArgus, placeholdersStmts, taggedTemplateExpression);
611    }
612
613    private collectTemplateValues(templateLiteral: ts.TemplateLiteral): {
614        stmts: Stmt[];
615        stringTextValues: Value[];
616        placeholderValues: Value[];
617        stringTextPositions: FullPosition[];
618        placeholderPositions: FullPosition[];
619    } {
620        const stmts: Stmt[] = [];
621        if (ts.isNoSubstitutionTemplateLiteral(templateLiteral)) {
622            const templateLiteralString = templateLiteral.getText(this.sourceFile);
623            return {
624                stmts: [],
625                stringTextValues: [ValueUtil.createStringConst(templateLiteralString)],
626                placeholderValues: [],
627                stringTextPositions: [FullPosition.buildFromNode(templateLiteral, this.sourceFile)],
628                placeholderPositions: [],
629            };
630        }
631        const head = templateLiteral.head;
632        const stringTextValues: Value[] = [ValueUtil.createStringConst(head.rawText || '')];
633        const placeholderValues: Value[] = [];
634        const stringTextPositions: FullPosition[] = [FullPosition.buildFromNode(head, this.sourceFile)];
635        const placeholderPositions: FullPosition[] = [];
636        for (const templateSpan of templateLiteral.templateSpans) {
637            let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(templateSpan.expression);
638            exprStmts.forEach(stmt => stmts.push(stmt));
639            if (IRUtils.moreThanOneAddress(exprValue)) {
640                ({
641                    value: exprValue,
642                    valueOriginalPositions: exprPositions,
643                    stmts: exprStmts,
644                } = this.arkIRTransformer.generateAssignStmtForValue(exprValue, exprPositions));
645                exprStmts.forEach(stmt => stmts.push(stmt));
646            }
647            placeholderValues.push(exprValue);
648            placeholderPositions.push(exprPositions[0]);
649            stringTextPositions.push(FullPosition.buildFromNode(templateSpan.literal, this.sourceFile));
650            stringTextValues.push(ValueUtil.createStringConst(templateSpan.literal.rawText || ''));
651        }
652        return {
653            stmts,
654            stringTextValues,
655            placeholderValues,
656            stringTextPositions,
657            placeholderPositions,
658        };
659    }
660
661    private identifierToValueAndStmts(identifier: ts.Identifier, variableDefFlag: boolean = false): ValueAndStmts {
662        let identifierValue: Value;
663        let identifierPositions = [FullPosition.buildFromNode(identifier, this.sourceFile)];
664        if (identifier.text === UndefinedType.getInstance().getName()) {
665            identifierValue = ValueUtil.getUndefinedConst();
666        } else {
667            if (variableDefFlag) {
668                identifierValue = this.addNewLocal(identifier.text);
669            } else {
670                identifierValue = this.getOrCreateLocal(identifier.text);
671            }
672        }
673        return {
674            value: identifierValue,
675            valueOriginalPositions: identifierPositions,
676            stmts: [],
677        };
678    }
679
680    private propertyAccessExpressionToValue(propertyAccessExpression: ts.PropertyAccessExpression): ValueAndStmts {
681        const stmts: Stmt[] = [];
682        let { value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts } = this.tsNodeToValueAndStmts(propertyAccessExpression.expression);
683        baseStmts.forEach(stmt => stmts.push(stmt));
684        if (IRUtils.moreThanOneAddress(baseValue)) {
685            ({
686                value: baseValue,
687                valueOriginalPositions: basePositions,
688                stmts: baseStmts,
689            } = this.arkIRTransformer.generateAssignStmtForValue(baseValue, basePositions));
690            baseStmts.forEach(stmt => stmts.push(stmt));
691        }
692        if (!(baseValue instanceof Local)) {
693            ({
694                value: baseValue,
695                valueOriginalPositions: basePositions,
696                stmts: baseStmts,
697            } = this.arkIRTransformer.generateAssignStmtForValue(baseValue, basePositions));
698            baseStmts.forEach(stmt => stmts.push(stmt));
699        }
700
701        const fieldRefPositions = [FullPosition.buildFromNode(propertyAccessExpression, this.sourceFile), ...basePositions];
702
703        // this if for the case: const obj: Object = Object.create(Object.prototype);
704        if (baseValue instanceof Local && baseValue.getName() === Builtin.OBJECT) {
705            this.locals.delete(baseValue.getName());
706            const fieldSignature = new FieldSignature(
707                propertyAccessExpression.name.getText(this.sourceFile),
708                Builtin.OBJECT_CLASS_SIGNATURE,
709                UnknownType.getInstance(),
710                true
711            );
712            const fieldRef = new ArkStaticFieldRef(fieldSignature);
713            return {
714                value: fieldRef,
715                valueOriginalPositions: fieldRefPositions,
716                stmts: stmts,
717            };
718        }
719
720        let fieldSignature: FieldSignature;
721        if (baseValue instanceof Local && baseValue.getType() instanceof ClassType) {
722            fieldSignature = new FieldSignature(
723                propertyAccessExpression.name.getText(this.sourceFile),
724                (baseValue.getType() as ClassType).getClassSignature(),
725                UnknownType.getInstance()
726            );
727        } else {
728            fieldSignature = ArkSignatureBuilder.buildFieldSignatureFromFieldName(propertyAccessExpression.name.getText(this.sourceFile));
729        }
730        const fieldRef = new ArkInstanceFieldRef(baseValue as Local, fieldSignature);
731
732        return {
733            value: fieldRef,
734            valueOriginalPositions: fieldRefPositions,
735            stmts: stmts,
736        };
737    }
738
739    private elementAccessExpressionToValueAndStmts(elementAccessExpression: ts.ElementAccessExpression): ValueAndStmts {
740        const stmts: Stmt[] = [];
741        let { value: baseValue, valueOriginalPositions: basePositions, stmts: baseStmts } = this.tsNodeToValueAndStmts(elementAccessExpression.expression);
742        baseStmts.forEach(stmt => stmts.push(stmt));
743        if (!(baseValue instanceof Local)) {
744            ({
745                value: baseValue,
746                valueOriginalPositions: basePositions,
747                stmts: baseStmts,
748            } = this.arkIRTransformer.generateAssignStmtForValue(baseValue, basePositions));
749            baseStmts.forEach(stmt => stmts.push(stmt));
750        }
751        let {
752            value: argumentValue,
753            valueOriginalPositions: arguPositions,
754            stmts: argumentStmts,
755        } = this.tsNodeToValueAndStmts(elementAccessExpression.argumentExpression);
756        argumentStmts.forEach(stmt => stmts.push(stmt));
757        if (IRUtils.moreThanOneAddress(argumentValue)) {
758            ({
759                value: argumentValue,
760                valueOriginalPositions: arguPositions,
761                stmts: argumentStmts,
762            } = this.arkIRTransformer.generateAssignStmtForValue(argumentValue, arguPositions));
763            argumentStmts.forEach(stmt => stmts.push(stmt));
764        }
765
766        let elementAccessExpr: Value;
767        if (baseValue.getType() instanceof ArrayType) {
768            elementAccessExpr = new ArkArrayRef(baseValue as Local, argumentValue);
769        } else {
770            // TODO: deal with ArkStaticFieldRef
771            const fieldSignature = ArkSignatureBuilder.buildFieldSignatureFromFieldName(argumentValue.toString());
772            elementAccessExpr = new ArkInstanceFieldRef(baseValue as Local, fieldSignature);
773        }
774        // reserve positions for field name
775        const exprPositions = [FullPosition.buildFromNode(elementAccessExpression, this.sourceFile), ...basePositions, ...arguPositions];
776        return {
777            value: elementAccessExpr,
778            valueOriginalPositions: exprPositions,
779            stmts: stmts,
780        };
781    }
782
783    private callExpressionToValueAndStmts(callExpression: ts.CallExpression): ValueAndStmts {
784        const stmts: Stmt[] = [];
785        const argus = this.parseArgumentsOfCallExpression(stmts, callExpression);
786        return this.generateInvokeValueAndStmts(callExpression.expression, argus, stmts, callExpression);
787    }
788
789    private generateInvokeValueAndStmts(
790        functionNameNode: ts.LeftHandSideExpression,
791        argus: {
792            realGenericTypes: Type[] | undefined;
793            args: Value[];
794            argPositions: FullPosition[];
795        },
796        currStmts: Stmt[],
797        callExpression: ts.CallExpression | ts.TaggedTemplateExpression
798    ): ValueAndStmts {
799        const stmts: Stmt[] = [...currStmts];
800        let { value: callerValue, valueOriginalPositions: callerPositions, stmts: callerStmts } = this.tsNodeToValueAndStmts(functionNameNode);
801        callerStmts.forEach(stmt => stmts.push(stmt));
802
803        let invokeValue: Value;
804        let invokeValuePositions: FullPosition[] = [FullPosition.buildFromNode(callExpression, this.sourceFile)];
805        const { args, argPositions, realGenericTypes } = argus;
806        if (callerValue instanceof AbstractFieldRef) {
807            let methodSignature: MethodSignature;
808            const declareSignature = callerValue.getFieldSignature().getDeclaringSignature();
809            if (declareSignature instanceof ClassSignature) {
810                methodSignature = new MethodSignature(declareSignature, ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(callerValue.getFieldName()));
811            } else {
812                methodSignature = ArkSignatureBuilder.buildMethodSignatureFromMethodName(callerValue.getFieldName());
813            }
814            if (callerValue instanceof ArkInstanceFieldRef) {
815                invokeValue = new ArkInstanceInvokeExpr(callerValue.getBase(), methodSignature, args, realGenericTypes);
816                invokeValuePositions.push(...callerPositions.slice(1));
817            } else {
818                invokeValue = new ArkStaticInvokeExpr(methodSignature, args, realGenericTypes);
819            }
820        } else if (callerValue instanceof Local) {
821            const callerName = callerValue.getName();
822            let classSignature = ArkSignatureBuilder.buildClassSignatureFromClassName(callerName);
823            let cls = ModelUtils.getClass(this.declaringMethod, classSignature);
824            if (cls?.hasComponentDecorator() && ts.isCallExpression(callExpression)) {
825                return this.generateCustomViewStmt(callerName, args, argPositions, callExpression, stmts);
826            } else if ((callerName === COMPONENT_FOR_EACH || callerName === COMPONENT_LAZY_FOR_EACH) && ts.isCallExpression(callExpression)) {
827                // foreach/lazyforeach will be parsed as ts.callExpression
828                return this.generateSystemComponentStmt(callerName, args, argPositions, callExpression, stmts);
829            }
830            const methodSignature = ArkSignatureBuilder.buildMethodSignatureFromMethodName(callerName);
831            if (callerValue.getType() instanceof FunctionType) {
832                invokeValue = new ArkPtrInvokeExpr(methodSignature, callerValue, args, realGenericTypes);
833            } else {
834                invokeValue = new ArkStaticInvokeExpr(methodSignature, args, realGenericTypes);
835            }
836        } else if (callerValue instanceof ArkArrayRef && ts.isElementAccessExpression(functionNameNode)) {
837            const methodSignature = ArkSignatureBuilder.buildMethodSignatureFromMethodName(functionNameNode.argumentExpression.getText());
838            invokeValue = new ArkInstanceInvokeExpr(callerValue.getBase(), methodSignature, args, realGenericTypes);
839            invokeValuePositions.push(...callerPositions.slice(1));
840            stmts.pop();
841        } else {
842            ({
843                value: callerValue,
844                valueOriginalPositions: callerPositions,
845                stmts: callerStmts,
846            } = this.arkIRTransformer.generateAssignStmtForValue(callerValue, callerPositions));
847            callerStmts.forEach(stmt => stmts.push(stmt));
848            const methodSignature = ArkSignatureBuilder.buildMethodSignatureFromMethodName((callerValue as Local).getName());
849            invokeValue = new ArkStaticInvokeExpr(methodSignature, args, realGenericTypes);
850        }
851        invokeValuePositions.push(...argPositions);
852        return {
853            value: invokeValue,
854            valueOriginalPositions: invokeValuePositions,
855            stmts: stmts,
856        };
857    }
858
859    private parseArgumentsOfCallExpression(
860        currStmts: Stmt[],
861        callExpression: ts.CallExpression
862    ): {
863        realGenericTypes: Type[] | undefined;
864        args: Value[];
865        argPositions: FullPosition[];
866    } {
867        let realGenericTypes: Type[] | undefined;
868        if (callExpression.typeArguments) {
869            realGenericTypes = [];
870            callExpression.typeArguments.forEach(typeArgument => {
871                realGenericTypes!.push(this.resolveTypeNode(typeArgument));
872            });
873        }
874
875        let builderMethodIndexes: Set<number> | undefined;
876        if (ts.isIdentifier(callExpression.expression)) {
877            const callerName = callExpression.expression.text;
878            if (callerName === COMPONENT_FOR_EACH || callerName === COMPONENT_LAZY_FOR_EACH) {
879                builderMethodIndexes = new Set<number>([1]);
880            }
881        }
882        const { args: args, argPositions: argPositions } = this.parseArguments(currStmts, callExpression.arguments, builderMethodIndexes);
883        return {
884            realGenericTypes: realGenericTypes,
885            args: args,
886            argPositions: argPositions,
887        };
888    }
889
890    private parseArguments(
891        currStmts: Stmt[],
892        argumentNodes?: ts.NodeArray<ts.Expression>,
893        builderMethodIndexes?: Set<number>
894    ): {
895        args: Value[];
896        argPositions: FullPosition[];
897    } {
898        const args: Value[] = [];
899        const argPositions: FullPosition[] = [];
900        if (argumentNodes) {
901            for (let i = 0; i < argumentNodes.length; i++) {
902                const argument = argumentNodes[i];
903                const prevBuilderMethodContextFlag = this.builderMethodContextFlag;
904                if (builderMethodIndexes?.has(i)) {
905                    this.builderMethodContextFlag = true;
906                    this.arkIRTransformer.setBuilderMethodContextFlag(true);
907                }
908                let { value: argValue, valueOriginalPositions: argPositionsSingle, stmts: argStmts } = this.tsNodeToValueAndStmts(argument);
909                this.builderMethodContextFlag = prevBuilderMethodContextFlag;
910                this.arkIRTransformer.setBuilderMethodContextFlag(prevBuilderMethodContextFlag);
911                argStmts.forEach(s => currStmts.push(s));
912                if (IRUtils.moreThanOneAddress(argValue)) {
913                    ({
914                        value: argValue,
915                        valueOriginalPositions: argPositionsSingle,
916                        stmts: argStmts,
917                    } = this.arkIRTransformer.generateAssignStmtForValue(argValue, argPositionsSingle));
918                    argStmts.forEach(s => currStmts.push(s));
919                }
920                args.push(argValue);
921                argPositions.push(argPositionsSingle[0]);
922            }
923        }
924        return { args: args, argPositions: argPositions };
925    }
926
927    private callableNodeToValueAndStmts(callableNode: ts.ArrowFunction | ts.FunctionExpression): ValueAndStmts {
928        const declaringClass = this.declaringMethod.getDeclaringArkClass();
929        const arrowArkMethod = new ArkMethod();
930        if (this.builderMethodContextFlag) {
931            ModelUtils.implicitArkUIBuilderMethods.add(arrowArkMethod);
932        }
933        buildArkMethodFromArkClass(callableNode, declaringClass, arrowArkMethod, this.sourceFile, this.declaringMethod);
934
935        const callableType = new FunctionType(arrowArkMethod.getSignature());
936        const callableValue = this.addNewLocal(arrowArkMethod.getName(), callableType);
937        return {
938            value: callableValue,
939            valueOriginalPositions: [FullPosition.buildFromNode(callableNode, this.sourceFile)],
940            stmts: [],
941        };
942    }
943
944    private newExpressionToValueAndStmts(newExpression: ts.NewExpression): ValueAndStmts {
945        let className = '';
946        if (ts.isClassExpression(newExpression.expression) && newExpression.expression.name) {
947            className = newExpression.expression.name.text;
948        } else {
949            className = newExpression.expression.getText(this.sourceFile);
950        }
951        if (className === Builtin.ARRAY) {
952            return this.newArrayExpressionToValueAndStmts(newExpression);
953        }
954
955        const stmts: Stmt[] = [];
956        let realGenericTypes: Type[] | undefined;
957        if (newExpression.typeArguments) {
958            realGenericTypes = [];
959            newExpression.typeArguments.forEach(typeArgument => {
960                realGenericTypes!.push(this.resolveTypeNode(typeArgument));
961            });
962        }
963
964        let classSignature = ArkSignatureBuilder.buildClassSignatureFromClassName(className);
965        let classType = new ClassType(classSignature, realGenericTypes);
966        if (className === Builtin.OBJECT) {
967            classSignature = Builtin.OBJECT_CLASS_SIGNATURE;
968            classType = Builtin.OBJECT_CLASS_TYPE;
969        }
970
971        const newExpr = new ArkNewExpr(classType);
972        const {
973            value: newLocal,
974            valueOriginalPositions: newLocalPositions,
975            stmts: newExprStmts,
976        } = this.arkIRTransformer.generateAssignStmtForValue(newExpr, [FullPosition.buildFromNode(newExpression, this.sourceFile)]);
977        newExprStmts.forEach(stmt => stmts.push(stmt));
978
979        const constructorMethodSubSignature = ArkSignatureBuilder.buildMethodSubSignatureFromMethodName(CONSTRUCTOR_NAME);
980        const constructorMethodSignature = new MethodSignature(classSignature, constructorMethodSubSignature);
981
982        const { args: argValues, argPositions: argPositions } = this.parseArguments(stmts, newExpression.arguments);
983        const instanceInvokeExpr = new ArkInstanceInvokeExpr(newLocal as Local, constructorMethodSignature, argValues);
984        const instanceInvokeExprPositions = [newLocalPositions[0], ...newLocalPositions, ...argPositions];
985        const invokeStmt = new ArkInvokeStmt(instanceInvokeExpr);
986        invokeStmt.setOperandOriginalPositions(instanceInvokeExprPositions);
987        stmts.push(invokeStmt);
988        return {
989            value: newLocal,
990            valueOriginalPositions: newLocalPositions,
991            stmts: stmts,
992        };
993    }
994
995    private newArrayExpressionToValueAndStmts(newArrayExpression: ts.NewExpression): ValueAndStmts {
996        let baseType: Type = UnknownType.getInstance();
997        if (newArrayExpression.typeArguments && newArrayExpression.typeArguments.length > 0) {
998            const argumentType = this.resolveTypeNode(newArrayExpression.typeArguments[0]);
999            if (!(argumentType instanceof AnyType || argumentType instanceof UnknownType)) {
1000                baseType = argumentType;
1001            }
1002        }
1003        const stmts: Stmt[] = [];
1004        const { args: argumentValues, argPositions: argPositions } = this.parseArguments(stmts, newArrayExpression.arguments);
1005        let argumentsLength = newArrayExpression.arguments ? newArrayExpression.arguments.length : 0;
1006        let arrayLengthValue: Value;
1007        let arrayLength = -1;
1008        let arrayLengthPosition = FullPosition.DEFAULT;
1009        if (argumentsLength === 1 && (argumentValues[0].getType() instanceof NumberType || argumentValues[0].getType() instanceof UnknownType)) {
1010            arrayLengthValue = argumentValues[0];
1011            arrayLengthPosition = argPositions[0];
1012        } else {
1013            arrayLengthValue = ValueUtil.getOrCreateNumberConst(argumentsLength);
1014            arrayLength = argumentsLength;
1015        }
1016        if (baseType instanceof UnknownType) {
1017            if (argumentsLength > 1 && !(argumentValues[0].getType() instanceof UnknownType)) {
1018                baseType = argumentValues[0].getType();
1019            } else {
1020                baseType = AnyType.getInstance();
1021            }
1022        }
1023        const newArrayExprPosition = FullPosition.buildFromNode(newArrayExpression, this.sourceFile);
1024        return this.generateArrayExprAndStmts(
1025            baseType,
1026            arrayLengthValue,
1027            arrayLengthPosition,
1028            arrayLength,
1029            argumentValues,
1030            argPositions,
1031            stmts,
1032            newArrayExprPosition,
1033            false
1034        );
1035    }
1036
1037    private arrayLiteralExpressionToValueAndStmts(arrayLiteralExpression: ts.ArrayLiteralExpression): ValueAndStmts {
1038        const stmts: Stmt[] = [];
1039        const elementTypes: Set<Type> = new Set();
1040        const elementValues: Value[] = [];
1041        const elementPositions: FullPosition[] = [];
1042        const arrayLength = arrayLiteralExpression.elements.length;
1043        for (const element of arrayLiteralExpression.elements) {
1044            let { value: elementValue, valueOriginalPositions: elementPosition, stmts: elementStmts } = this.tsNodeToValueAndStmts(element);
1045            elementStmts.forEach(stmt => stmts.push(stmt));
1046            if (IRUtils.moreThanOneAddress(elementValue)) {
1047                ({
1048                    value: elementValue,
1049                    valueOriginalPositions: elementPosition,
1050                    stmts: elementStmts,
1051                } = this.arkIRTransformer.generateAssignStmtForValue(elementValue, elementPosition));
1052                elementStmts.forEach(stmt => stmts.push(stmt));
1053            }
1054            elementValues.push(elementValue);
1055            elementTypes.add(elementValue.getType());
1056            elementPositions.push(elementPosition[0]);
1057        }
1058
1059        let baseType: Type = AnyType.getInstance();
1060        if (elementTypes.size === 1) {
1061            baseType = elementTypes.keys().next().value as Type;
1062        } else if (elementTypes.size > 1) {
1063            baseType = new UnionType(Array.from(elementTypes));
1064        }
1065        const newArrayExprPosition = FullPosition.buildFromNode(arrayLiteralExpression, this.sourceFile);
1066        return this.generateArrayExprAndStmts(
1067            baseType,
1068            ValueUtil.getOrCreateNumberConst(arrayLength),
1069            FullPosition.DEFAULT,
1070            arrayLength,
1071            elementValues,
1072            elementPositions,
1073            stmts,
1074            newArrayExprPosition,
1075            true
1076        );
1077    }
1078
1079    private generateArrayExprAndStmts(
1080        baseType: Type,
1081        arrayLengthValue: Value,
1082        arrayLengthPosition: FullPosition,
1083        arrayLength: number,
1084        initializerValues: Value[],
1085        initializerPositions: FullPosition[],
1086        currStmts: Stmt[],
1087        newArrayExprPosition: FullPosition,
1088        fromLiteral: boolean
1089    ): ValueAndStmts {
1090        const stmts: Stmt[] = [...currStmts];
1091        const newArrayExpr = new ArkNewArrayExpr(baseType, arrayLengthValue, fromLiteral);
1092        const newArrayExprPositions = [newArrayExprPosition, arrayLengthPosition];
1093        const {
1094            value: arrayLocal,
1095            valueOriginalPositions: arrayLocalPositions,
1096            stmts: arrayStmts,
1097        } = this.arkIRTransformer.generateAssignStmtForValue(newArrayExpr, newArrayExprPositions);
1098        arrayStmts.forEach(stmt => stmts.push(stmt));
1099        for (let i = 0; i < arrayLength; i++) {
1100            const indexValue = ValueUtil.getOrCreateNumberConst(i);
1101            const arrayRef = new ArkArrayRef(arrayLocal as Local, indexValue);
1102            const arrayRefPositions = [arrayLocalPositions[0], ...arrayLocalPositions, FullPosition.DEFAULT];
1103            const assignStmt = new ArkAssignStmt(arrayRef, initializerValues[i]);
1104            assignStmt.setOperandOriginalPositions([...arrayRefPositions, initializerPositions[i]]);
1105            stmts.push(assignStmt);
1106        }
1107        return {
1108            value: arrayLocal,
1109            valueOriginalPositions: arrayLocalPositions,
1110            stmts: stmts,
1111        };
1112    }
1113
1114    private prefixUnaryExpressionToValueAndStmts(prefixUnaryExpression: ts.PrefixUnaryExpression): ValueAndStmts {
1115        const stmts: Stmt[] = [];
1116        let {
1117            value: originOperandValue,
1118            valueOriginalPositions: originOperandPositions,
1119            stmts: operandStmts,
1120        } = this.tsNodeToValueAndStmts(prefixUnaryExpression.operand);
1121        operandStmts.forEach(stmt => stmts.push(stmt));
1122        let operandValue: Value;
1123        let operandPositions: FullPosition[];
1124        if (IRUtils.moreThanOneAddress(originOperandValue)) {
1125            ({
1126                value: operandValue,
1127                valueOriginalPositions: operandPositions,
1128                stmts: operandStmts,
1129            } = this.arkIRTransformer.generateAssignStmtForValue(originOperandValue, originOperandPositions));
1130            operandStmts.forEach(stmt => stmts.push(stmt));
1131        } else {
1132            operandValue = originOperandValue;
1133            operandPositions = originOperandPositions;
1134        }
1135
1136        const operatorToken = prefixUnaryExpression.operator;
1137        let exprPositions = [FullPosition.buildFromNode(prefixUnaryExpression, this.sourceFile)];
1138        if (operatorToken === ts.SyntaxKind.PlusPlusToken || operatorToken === ts.SyntaxKind.MinusMinusToken) {
1139            const binaryOperator = operatorToken === ts.SyntaxKind.PlusPlusToken ? NormalBinaryOperator.Addition : NormalBinaryOperator.Subtraction;
1140            const binopExpr = new ArkNormalBinopExpr(operandValue, ValueUtil.getOrCreateNumberConst(1), binaryOperator);
1141            exprPositions.push(...operandPositions, FullPosition.DEFAULT);
1142            const assignStmt = new ArkAssignStmt(operandValue, binopExpr);
1143            assignStmt.setOperandOriginalPositions([...operandPositions, ...exprPositions]);
1144            stmts.push(assignStmt);
1145            if (operandValue !== originOperandValue) {
1146                const lastAssignStmt = new ArkAssignStmt(originOperandValue, operandValue);
1147                lastAssignStmt.setOperandOriginalPositions([...originOperandPositions, ...operandPositions]);
1148                stmts.push(lastAssignStmt);
1149            }
1150            return { value: originOperandValue, valueOriginalPositions: originOperandPositions, stmts: stmts };
1151        } else if (operatorToken === ts.SyntaxKind.PlusToken) {
1152            return { value: operandValue, valueOriginalPositions: operandPositions, stmts: stmts };
1153        } else {
1154            let unopExpr: Value;
1155            const operator = ArkIRTransformer.tokenToUnaryOperator(operatorToken);
1156            if (operator) {
1157                unopExpr = new ArkUnopExpr(operandValue, operator);
1158                exprPositions.push(...operandPositions);
1159            } else {
1160                unopExpr = ValueUtil.getUndefinedConst();
1161                exprPositions = [FullPosition.DEFAULT];
1162            }
1163            return { value: unopExpr, valueOriginalPositions: exprPositions, stmts: stmts };
1164        }
1165    }
1166
1167    private postfixUnaryExpressionToValueAndStmts(postfixUnaryExpression: ts.PostfixUnaryExpression): ValueAndStmts {
1168        const stmts: Stmt[] = [];
1169        let {
1170            value: originOperandValue,
1171            valueOriginalPositions: originOperandPositions,
1172            stmts: exprStmts,
1173        } = this.tsNodeToValueAndStmts(postfixUnaryExpression.operand);
1174        exprStmts.forEach(stmt => stmts.push(stmt));
1175        let operandValue: Value;
1176        let operandPositions: FullPosition[];
1177        if (IRUtils.moreThanOneAddress(originOperandValue)) {
1178            ({
1179                value: operandValue,
1180                valueOriginalPositions: operandPositions,
1181                stmts: exprStmts,
1182            } = this.arkIRTransformer.generateAssignStmtForValue(originOperandValue, originOperandPositions));
1183            exprStmts.forEach(stmt => stmts.push(stmt));
1184        } else {
1185            operandValue = originOperandValue;
1186            operandPositions = originOperandPositions;
1187        }
1188
1189        let exprPositions = [FullPosition.buildFromNode(postfixUnaryExpression, this.sourceFile)];
1190        const operatorToken = postfixUnaryExpression.operator;
1191        if (operatorToken === ts.SyntaxKind.PlusPlusToken || operatorToken === ts.SyntaxKind.MinusMinusToken) {
1192            const binaryOperator = operatorToken === ts.SyntaxKind.PlusPlusToken ? NormalBinaryOperator.Addition : NormalBinaryOperator.Subtraction;
1193            const binopExpr = new ArkNormalBinopExpr(operandValue, ValueUtil.getOrCreateNumberConst(1), binaryOperator);
1194            exprPositions.push(...operandPositions, FullPosition.DEFAULT);
1195            const assignStmt = new ArkAssignStmt(operandValue, binopExpr);
1196            assignStmt.setOperandOriginalPositions([...operandPositions, ...exprPositions]);
1197            stmts.push(assignStmt);
1198            if (operandValue !== originOperandValue) {
1199                const lastAssignStmt = new ArkAssignStmt(originOperandValue, operandValue);
1200                lastAssignStmt.setOperandOriginalPositions([...originOperandPositions, ...operandPositions]);
1201                stmts.push(lastAssignStmt);
1202            }
1203            return {
1204                value: originOperandValue,
1205                valueOriginalPositions: originOperandPositions,
1206                stmts: stmts,
1207            };
1208        }
1209
1210        return {
1211            value: ValueUtil.getUndefinedConst(),
1212            valueOriginalPositions: [FullPosition.DEFAULT],
1213            stmts: stmts,
1214        };
1215    }
1216
1217    private awaitExpressionToValueAndStmts(awaitExpression: ts.AwaitExpression): ValueAndStmts {
1218        const stmts: Stmt[] = [];
1219        let { value: promiseValue, valueOriginalPositions: promisePositions, stmts: promiseStmts } = this.tsNodeToValueAndStmts(awaitExpression.expression);
1220        promiseStmts.forEach(stmt => stmts.push(stmt));
1221        if (IRUtils.moreThanOneAddress(promiseValue)) {
1222            ({
1223                value: promiseValue,
1224                valueOriginalPositions: promisePositions,
1225                stmts: promiseStmts,
1226            } = this.arkIRTransformer.generateAssignStmtForValue(promiseValue, promisePositions));
1227            promiseStmts.forEach(stmt => stmts.push(stmt));
1228        }
1229        const awaitExpr = new ArkAwaitExpr(promiseValue);
1230        const awaitExprPositions = [FullPosition.buildFromNode(awaitExpression, this.sourceFile), ...promisePositions];
1231        return {
1232            value: awaitExpr,
1233            valueOriginalPositions: awaitExprPositions,
1234            stmts: stmts,
1235        };
1236    }
1237
1238    private yieldExpressionToValueAndStmts(yieldExpression: ts.YieldExpression): ValueAndStmts {
1239        let yieldValue: Value = ValueUtil.getUndefinedConst();
1240        let yieldPositions = [FullPosition.DEFAULT];
1241        let stmts: Stmt[] = [];
1242        if (yieldExpression.expression) {
1243            ({ value: yieldValue, valueOriginalPositions: yieldPositions, stmts: stmts } = this.tsNodeToValueAndStmts(yieldExpression.expression));
1244        }
1245
1246        const yieldExpr = new ArkYieldExpr(yieldValue);
1247        const yieldExprPositions = [FullPosition.buildFromNode(yieldExpression, this.sourceFile), ...yieldPositions];
1248        return {
1249            value: yieldExpr,
1250            valueOriginalPositions: yieldExprPositions,
1251            stmts: stmts,
1252        };
1253    }
1254
1255    private deleteExpressionToValueAndStmts(deleteExpression: ts.DeleteExpression): ValueAndStmts {
1256        const { value: exprValue, valueOriginalPositions: exprPositions, stmts: stmts } = this.tsNodeToValueAndStmts(deleteExpression.expression);
1257        const deleteExpr = new ArkDeleteExpr(exprValue as AbstractFieldRef);
1258        const deleteExprPositions = [FullPosition.buildFromNode(deleteExpression, this.sourceFile), ...exprPositions];
1259        return {
1260            value: deleteExpr,
1261            valueOriginalPositions: deleteExprPositions,
1262            stmts: stmts,
1263        };
1264    }
1265
1266    private voidExpressionToValueAndStmts(voidExpression: ts.VoidExpression): ValueAndStmts {
1267        const { value: exprValue, valueOriginalPositions: exprPositions, stmts: stmts } = this.tsNodeToValueAndStmts(voidExpression.expression);
1268        const { stmts: exprStmts } = this.arkIRTransformer.generateAssignStmtForValue(exprValue, exprPositions);
1269        exprStmts.forEach(stmt => stmts.push(stmt));
1270        return {
1271            value: ValueUtil.getUndefinedConst(),
1272            valueOriginalPositions: [FullPosition.DEFAULT],
1273            stmts: stmts,
1274        };
1275    }
1276
1277    private nonNullExpressionToValueAndStmts(nonNullExpression: ts.NonNullExpression): ValueAndStmts {
1278        return this.tsNodeToValueAndStmts(nonNullExpression.expression);
1279    }
1280
1281    private parenthesizedExpressionToValueAndStmts(parenthesizedExpression: ts.ParenthesizedExpression): ValueAndStmts {
1282        return this.tsNodeToValueAndStmts(parenthesizedExpression.expression);
1283    }
1284
1285    private typeOfExpressionToValueAndStmts(typeOfExpression: ts.TypeOfExpression): ValueAndStmts {
1286        const { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(typeOfExpression.expression);
1287        const typeOfExpr = new ArkTypeOfExpr(exprValue);
1288        const typeOfExprPositions = [FullPosition.buildFromNode(typeOfExpression, this.sourceFile), ...exprPositions];
1289        return {
1290            value: typeOfExpr,
1291            valueOriginalPositions: typeOfExprPositions,
1292            stmts: exprStmts,
1293        };
1294    }
1295
1296    private asExpressionToValueAndStmts(asExpression: ts.AsExpression): ValueAndStmts {
1297        const stmts: Stmt[] = [];
1298        let { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(asExpression.expression);
1299        exprStmts.forEach(stmt => stmts.push(stmt));
1300        if (IRUtils.moreThanOneAddress(exprValue)) {
1301            ({
1302                value: exprValue,
1303                valueOriginalPositions: exprPositions,
1304                stmts: exprStmts,
1305            } = this.arkIRTransformer.generateAssignStmtForValue(exprValue, exprPositions));
1306            exprStmts.forEach(stmt => stmts.push(stmt));
1307        }
1308        const castExpr = new ArkCastExpr(exprValue, this.resolveTypeNode(asExpression.type));
1309        const castExprPositions = [FullPosition.buildFromNode(asExpression, this.sourceFile), ...exprPositions];
1310        return {
1311            value: castExpr,
1312            valueOriginalPositions: castExprPositions,
1313            stmts: stmts,
1314        };
1315    }
1316
1317    private typeAssertionToValueAndStmts(typeAssertion: ts.TypeAssertion): ValueAndStmts {
1318        const { value: exprValue, valueOriginalPositions: exprPositions, stmts: exprStmts } = this.tsNodeToValueAndStmts(typeAssertion.expression);
1319        const castExpr = new ArkCastExpr(exprValue, this.resolveTypeNode(typeAssertion.type));
1320        const castExprPositions = [FullPosition.buildFromNode(typeAssertion, this.sourceFile), ...exprPositions];
1321        return {
1322            value: castExpr,
1323            valueOriginalPositions: castExprPositions,
1324            stmts: exprStmts,
1325        };
1326    }
1327
1328    public variableDeclarationListToValueAndStmts(variableDeclarationList: ts.VariableDeclarationList): ValueAndStmts {
1329        const stmts: Stmt[] = [];
1330        const isConst = (variableDeclarationList.flags & ts.NodeFlags.Const) !== 0;
1331        for (const declaration of variableDeclarationList.declarations) {
1332            const { stmts: declaredStmts } = this.variableDeclarationToValueAndStmts(declaration, isConst);
1333            declaredStmts.forEach(s => stmts.push(s));
1334        }
1335        return {
1336            value: ValueUtil.getUndefinedConst(),
1337            valueOriginalPositions: [FullPosition.DEFAULT],
1338            stmts: stmts,
1339        };
1340    }
1341
1342    public variableDeclarationToValueAndStmts(variableDeclaration: ts.VariableDeclaration, isConst: boolean, needRightOp: boolean = true): ValueAndStmts {
1343        const leftOpNode = variableDeclaration.name;
1344        const rightOpNode = variableDeclaration.initializer;
1345        const declarationType = variableDeclaration.type ? this.resolveTypeNode(variableDeclaration.type) : UnknownType.getInstance();
1346        return this.assignmentToValueAndStmts(leftOpNode, rightOpNode, true, isConst, declarationType, needRightOp);
1347    }
1348
1349    private assignmentToValueAndStmts(
1350        leftOpNode: ts.Node,
1351        rightOpNode: ts.Node | undefined,
1352        variableDefFlag: boolean,
1353        isConst: boolean,
1354        declarationType: Type,
1355        needRightOp: boolean = true
1356    ): ValueAndStmts {
1357        let leftValueAndStmts: ValueAndStmts;
1358        if (ts.isIdentifier(leftOpNode)) {
1359            leftValueAndStmts = this.identifierToValueAndStmts(leftOpNode, variableDefFlag);
1360        } else if (ts.isArrayBindingPattern(leftOpNode) || ts.isArrayLiteralExpression(leftOpNode)) {
1361            leftValueAndStmts = this.arrayDestructuringToValueAndStmts(leftOpNode, isConst);
1362        } else if (ts.isObjectBindingPattern(leftOpNode) || ts.isObjectLiteralExpression(leftOpNode)) {
1363            leftValueAndStmts = this.objectDestructuringToValueAndStmts(leftOpNode, isConst);
1364        } else {
1365            leftValueAndStmts = this.tsNodeToValueAndStmts(leftOpNode);
1366        }
1367        const { value: leftValue, valueOriginalPositions: leftPositions, stmts: leftStmts } = leftValueAndStmts;
1368
1369        let stmts: Stmt[] = [];
1370        if (needRightOp) {
1371            const {
1372                value: rightValue,
1373                valueOriginalPositions: rightPositions,
1374                stmts: rightStmts,
1375            } = this.assignmentRightOpToValueAndStmts(rightOpNode, leftValue);
1376            if (leftValue instanceof Local) {
1377                if (variableDefFlag) {
1378                    leftValue.setConstFlag(isConst);
1379                    leftValue.setType(declarationType);
1380                }
1381                if (
1382                    leftValue.getType() instanceof UnknownType &&
1383                    !(rightValue.getType() instanceof UnknownType) &&
1384                    !(rightValue.getType() instanceof UndefinedType)
1385                ) {
1386                    leftValue.setType(rightValue.getType());
1387                }
1388            }
1389            const assignStmt = new ArkAssignStmt(leftValue, rightValue);
1390            assignStmt.setOperandOriginalPositions([...leftPositions, ...rightPositions]);
1391            if (
1392                ts.isArrayBindingPattern(leftOpNode) ||
1393                ts.isArrayLiteralExpression(leftOpNode) ||
1394                ts.isObjectBindingPattern(leftOpNode) ||
1395                ts.isObjectLiteralExpression(leftOpNode)
1396            ) {
1397                rightStmts.forEach(stmt => stmts.push(stmt));
1398                stmts.push(assignStmt);
1399                leftStmts.forEach(stmt => stmts.push(stmt));
1400            } else {
1401                rightStmts.forEach(stmt => stmts.push(stmt));
1402                leftStmts.forEach(stmt => stmts.push(stmt));
1403                stmts.push(assignStmt);
1404            }
1405        } else {
1406            stmts = leftStmts;
1407        }
1408        return {
1409            value: leftValue,
1410            valueOriginalPositions: leftPositions,
1411            stmts: stmts,
1412        };
1413    }
1414
1415    private assignmentRightOpToValueAndStmts(rightOpNode: ts.Node | undefined, leftValue: Value): ValueAndStmts {
1416        let rightValue: Value;
1417        let rightPositions: FullPosition[];
1418        let tempRightStmts: Stmt[] = [];
1419        const rightStmts: Stmt[] = [];
1420        if (rightOpNode) {
1421            ({ value: rightValue, valueOriginalPositions: rightPositions, stmts: tempRightStmts } = this.tsNodeToValueAndStmts(rightOpNode));
1422            tempRightStmts.forEach(stmt => rightStmts.push(stmt));
1423        } else {
1424            rightValue = ValueUtil.getUndefinedConst();
1425            rightPositions = [FullPosition.DEFAULT];
1426        }
1427        if (IRUtils.moreThanOneAddress(leftValue) && IRUtils.moreThanOneAddress(rightValue)) {
1428            ({
1429                value: rightValue,
1430                valueOriginalPositions: rightPositions,
1431                stmts: tempRightStmts,
1432            } = this.arkIRTransformer.generateAssignStmtForValue(rightValue, rightPositions));
1433            tempRightStmts.forEach(stmt => rightStmts.push(stmt));
1434        }
1435        return {
1436            value: rightValue,
1437            valueOriginalPositions: rightPositions,
1438            stmts: rightStmts,
1439        };
1440    }
1441
1442    // In assignment patterns, the left operand will be an array literal expression
1443    private arrayDestructuringToValueAndStmts(arrayDestructuring: ts.ArrayBindingPattern | ts.ArrayLiteralExpression, isConst: boolean = false): ValueAndStmts {
1444        const stmts: Stmt[] = [];
1445        const arrayTempLocal = this.generateTempLocal();
1446        const leftOriginalPosition = FullPosition.buildFromNode(arrayDestructuring, this.sourceFile);
1447        const elements = arrayDestructuring.elements;
1448        const isArrayBindingPattern = ts.isArrayBindingPattern(arrayDestructuring);
1449        let index = 0;
1450        for (const element of elements) {
1451            const arrayRef = new ArkArrayRef(arrayTempLocal, ValueUtil.getOrCreateNumberConst(index));
1452            const arrayRefPositions = [leftOriginalPosition, leftOriginalPosition, FullPosition.DEFAULT];
1453            const itemName = element.getText(this.sourceFile);
1454            const targetLocal = isArrayBindingPattern ? this.addNewLocal(itemName) : this.getOrCreateLocal(itemName);
1455            const targetLocalPosition = FullPosition.buildFromNode(element, this.sourceFile);
1456            isArrayBindingPattern && targetLocal.setConstFlag(isConst);
1457            const assignStmt = new ArkAssignStmt(targetLocal, arrayRef);
1458            assignStmt.setOperandOriginalPositions([targetLocalPosition, ...arrayRefPositions]);
1459            stmts.push(assignStmt);
1460            index++;
1461        }
1462        return {
1463            value: arrayTempLocal,
1464            valueOriginalPositions: [leftOriginalPosition],
1465            stmts: stmts,
1466        };
1467    }
1468
1469    // In assignment patterns, the left operand will be an object literal expression
1470    private objectDestructuringToValueAndStmts(
1471        objectDestructuring: ts.ObjectBindingPattern | ts.ObjectLiteralExpression,
1472        isConst: boolean = false
1473    ): ValueAndStmts {
1474        const stmts: Stmt[] = [];
1475        const objectTempLocal = this.generateTempLocal();
1476        const leftOriginalPosition = FullPosition.buildFromNode(objectDestructuring, this.sourceFile);
1477        const isObjectBindingPattern = ts.isObjectBindingPattern(objectDestructuring);
1478        const elements = isObjectBindingPattern ? objectDestructuring.elements : objectDestructuring.properties;
1479        for (const element of elements) {
1480            let fieldName = '';
1481            let targetName = '';
1482            if (ts.isBindingElement(element)) {
1483                fieldName = element.propertyName ? element.propertyName.getText(this.sourceFile) : element.name.getText(this.sourceFile);
1484                targetName = element.name.getText(this.sourceFile);
1485            } else if (ts.isPropertyAssignment(element)) {
1486                fieldName = element.name.getText(this.sourceFile);
1487                targetName = element.initializer.getText(this.sourceFile);
1488            } else if (ts.isShorthandPropertyAssignment(element)) {
1489                fieldName = element.name.getText(this.sourceFile);
1490                targetName = fieldName;
1491            } else {
1492                continue;
1493            }
1494
1495            const fieldSignature = ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName);
1496            const fieldRef = new ArkInstanceFieldRef(objectTempLocal, fieldSignature);
1497            const fieldRefPositions = [leftOriginalPosition, leftOriginalPosition];
1498            const targetLocal = isObjectBindingPattern ? this.addNewLocal(targetName) : this.getOrCreateLocal(targetName);
1499            isObjectBindingPattern && targetLocal.setConstFlag(isConst);
1500            const targetLocalPosition = FullPosition.buildFromNode(element, this.sourceFile);
1501            const assignStmt = new ArkAssignStmt(targetLocal, fieldRef);
1502            assignStmt.setOperandOriginalPositions([targetLocalPosition, ...fieldRefPositions]);
1503            stmts.push(assignStmt);
1504        }
1505        return {
1506            value: objectTempLocal,
1507            valueOriginalPositions: [leftOriginalPosition],
1508            stmts: stmts,
1509        };
1510    }
1511
1512    private binaryExpressionToValueAndStmts(binaryExpression: ts.BinaryExpression): ValueAndStmts {
1513        const operatorToken = binaryExpression.operatorToken;
1514        if (operatorToken.kind === ts.SyntaxKind.FirstAssignment) {
1515            const leftOpNode = binaryExpression.left;
1516            const rightOpNode = binaryExpression.right;
1517            const declarationType = UnknownType.getInstance();
1518            return this.assignmentToValueAndStmts(leftOpNode, rightOpNode, false, false, declarationType, true);
1519        } else if (ArkValueTransformer.isCompoundAssignmentOperator(operatorToken.kind)) {
1520            return this.compoundAssignmentToValueAndStmts(binaryExpression);
1521        }
1522        const stmts: Stmt[] = [];
1523        const binaryExpressionPosition = FullPosition.buildFromNode(binaryExpression, this.sourceFile);
1524        const { value: opValue1, valueOriginalPositions: opPositions1, stmts: opStmts1 } = this.tsNodeToSingleAddressValueAndStmts(binaryExpression.left);
1525        opStmts1.forEach(stmt => stmts.push(stmt));
1526
1527        if (operatorToken.kind === ts.SyntaxKind.InstanceOfKeyword) {
1528            const instanceOfExpr = new ArkInstanceOfExpr(opValue1, new UnclearReferenceType(binaryExpression.right.getText(this.sourceFile)));
1529            const instanceOfExprPositions = [binaryExpressionPosition, ...opPositions1];
1530            const {
1531                value: instanceofRes,
1532                valueOriginalPositions: instanceofPos,
1533                stmts: instanceofStmt,
1534            } = this.arkIRTransformer.generateAssignStmtForValue(instanceOfExpr, instanceOfExprPositions);
1535            instanceofStmt.forEach(stmt => stmts.push(stmt));
1536            return {
1537                value: instanceofRes,
1538                valueOriginalPositions: instanceofPos,
1539                stmts: stmts,
1540            };
1541        }
1542
1543        const { value: opValue2, valueOriginalPositions: opPositions2, stmts: opStmts2 } = this.tsNodeToSingleAddressValueAndStmts(binaryExpression.right);
1544        opStmts2.forEach(stmt => stmts.push(stmt));
1545        let exprValue: Value;
1546        let exprValuePositions = [binaryExpressionPosition];
1547        if (operatorToken.kind === ts.SyntaxKind.CommaToken) {
1548            exprValue = opValue2;
1549        } else {
1550            const operator = ArkIRTransformer.tokenToBinaryOperator(operatorToken.kind);
1551            if (operator) {
1552                if (this.isRelationalOperator(operator)) {
1553                    exprValue = new ArkConditionExpr(opValue1, opValue2, operator as RelationalBinaryOperator);
1554                } else {
1555                    exprValue = new ArkNormalBinopExpr(opValue1, opValue2, operator as NormalBinaryOperator);
1556                }
1557                exprValuePositions.push(...opPositions1, ...opPositions2);
1558            } else {
1559                exprValue = ValueUtil.getUndefinedConst();
1560                exprValuePositions.push(binaryExpressionPosition);
1561            }
1562        }
1563        return {
1564            value: exprValue,
1565            valueOriginalPositions: exprValuePositions,
1566            stmts: stmts,
1567        };
1568    }
1569
1570    private compoundAssignmentToValueAndStmts(binaryExpression: ts.BinaryExpression): ValueAndStmts {
1571        const stmts: Stmt[] = [];
1572        let { value: leftValue, valueOriginalPositions: leftPositions, stmts: leftStmts } = this.tsNodeToValueAndStmts(binaryExpression.left);
1573        leftStmts.forEach(stmt => stmts.push(stmt));
1574        let { value: rightValue, valueOriginalPositions: rightPositions, stmts: rightStmts } = this.tsNodeToValueAndStmts(binaryExpression.right);
1575        rightStmts.forEach(stmt => stmts.push(stmt));
1576        if (IRUtils.moreThanOneAddress(leftValue) && IRUtils.moreThanOneAddress(rightValue)) {
1577            const {
1578                value: newRightValue,
1579                valueOriginalPositions: newRightPositions,
1580                stmts: rightStmts,
1581            } = this.arkIRTransformer.generateAssignStmtForValue(rightValue, rightPositions);
1582            rightValue = newRightValue;
1583            rightPositions = newRightPositions;
1584            rightStmts.forEach(stmt => stmts.push(stmt));
1585        }
1586
1587        let leftOpValue: Value;
1588        let leftOpPositions: FullPosition[];
1589        const operator = this.compoundAssignmentTokenToBinaryOperator(binaryExpression.operatorToken.kind);
1590        if (operator) {
1591            const exprValue = new ArkNormalBinopExpr(leftValue, rightValue, operator);
1592            const exprValuePosition = FullPosition.buildFromNode(binaryExpression, this.sourceFile);
1593            const assignStmt = new ArkAssignStmt(leftValue, exprValue);
1594            assignStmt.setOperandOriginalPositions([...leftPositions, exprValuePosition, ...leftPositions, ...rightPositions]);
1595            stmts.push(assignStmt);
1596            leftOpValue = leftValue;
1597            leftOpPositions = leftPositions;
1598        } else {
1599            leftOpValue = ValueUtil.getUndefinedConst();
1600            leftOpPositions = [leftPositions[0]];
1601        }
1602        return {
1603            value: leftOpValue,
1604            valueOriginalPositions: leftOpPositions,
1605            stmts: stmts,
1606        };
1607    }
1608
1609    private compoundAssignmentTokenToBinaryOperator(token: ts.SyntaxKind): NormalBinaryOperator | null {
1610        switch (token) {
1611            case ts.SyntaxKind.QuestionQuestionEqualsToken:
1612                return NormalBinaryOperator.NullishCoalescing;
1613            case ts.SyntaxKind.AsteriskAsteriskEqualsToken:
1614                return NormalBinaryOperator.Exponentiation;
1615            case ts.SyntaxKind.SlashEqualsToken:
1616                return NormalBinaryOperator.Division;
1617            case ts.SyntaxKind.PlusEqualsToken:
1618                return NormalBinaryOperator.Addition;
1619            case ts.SyntaxKind.MinusEqualsToken:
1620                return NormalBinaryOperator.Subtraction;
1621            case ts.SyntaxKind.AsteriskEqualsToken:
1622                return NormalBinaryOperator.Multiplication;
1623            case ts.SyntaxKind.PercentEqualsToken:
1624                return NormalBinaryOperator.Remainder;
1625            case ts.SyntaxKind.LessThanLessThanEqualsToken:
1626                return NormalBinaryOperator.LeftShift;
1627            case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken:
1628                return NormalBinaryOperator.RightShift;
1629            case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:
1630                return NormalBinaryOperator.UnsignedRightShift;
1631            case ts.SyntaxKind.AmpersandEqualsToken:
1632                return NormalBinaryOperator.BitwiseAnd;
1633            case ts.SyntaxKind.BarEqualsToken:
1634                return NormalBinaryOperator.BitwiseOr;
1635            case ts.SyntaxKind.CaretEqualsToken:
1636                return NormalBinaryOperator.BitwiseXor;
1637            case ts.SyntaxKind.AmpersandAmpersandEqualsToken:
1638                return NormalBinaryOperator.LogicalAnd;
1639            case ts.SyntaxKind.BarBarEqualsToken:
1640                return NormalBinaryOperator.LogicalOr;
1641            default:
1642        }
1643        return null;
1644    }
1645
1646    public conditionToValueAndStmts(condition: ts.Expression): ValueAndStmts {
1647        const stmts: Stmt[] = [];
1648        let { value: conditionValue, valueOriginalPositions: conditionPositions, stmts: conditionStmts } = this.tsNodeToValueAndStmts(condition);
1649        conditionStmts.forEach(stmt => stmts.push(stmt));
1650        let conditionExpr: ArkConditionExpr;
1651        if (conditionValue instanceof AbstractBinopExpr && this.isRelationalOperator(conditionValue.getOperator())) {
1652            const operator = conditionValue.getOperator() as RelationalBinaryOperator;
1653            conditionExpr = new ArkConditionExpr(conditionValue.getOp1(), conditionValue.getOp2(), operator);
1654        } else {
1655            if (IRUtils.moreThanOneAddress(conditionValue)) {
1656                ({
1657                    value: conditionValue,
1658                    valueOriginalPositions: conditionPositions,
1659                    stmts: conditionStmts,
1660                } = this.arkIRTransformer.generateAssignStmtForValue(conditionValue, conditionPositions));
1661                conditionStmts.forEach(stmt => stmts.push(stmt));
1662            }
1663            conditionExpr = new ArkConditionExpr(conditionValue, ValueUtil.getOrCreateNumberConst(0), RelationalBinaryOperator.InEquality);
1664            conditionPositions = [conditionPositions[0], ...conditionPositions, FullPosition.DEFAULT];
1665        }
1666        return {
1667            value: conditionExpr,
1668            valueOriginalPositions: conditionPositions,
1669            stmts: stmts,
1670        };
1671    }
1672
1673    private literalNodeToValueAndStmts(literalNode: ts.Node): ValueAndStmts | null {
1674        const syntaxKind = literalNode.kind;
1675        let constant: Constant | null = null;
1676        switch (syntaxKind) {
1677            case ts.SyntaxKind.NumericLiteral:
1678                constant = ValueUtil.getOrCreateNumberConst(parseFloat((literalNode as ts.NumericLiteral).text));
1679                break;
1680            case ts.SyntaxKind.BigIntLiteral:
1681                constant = ValueUtil.createBigIntConst(BigInt((literalNode as ts.BigIntLiteral).text.slice(0, -1)));
1682                break;
1683            case ts.SyntaxKind.StringLiteral:
1684                constant = ValueUtil.createStringConst((literalNode as ts.StringLiteral).text);
1685                break;
1686            case ts.SyntaxKind.RegularExpressionLiteral:
1687                constant = new Constant((literalNode as ts.RegularExpressionLiteral).text, Builtin.REGEXP_CLASS_TYPE);
1688                break;
1689            case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
1690                constant = ValueUtil.createStringConst((literalNode as ts.NoSubstitutionTemplateLiteral).text);
1691                break;
1692            case ts.SyntaxKind.NullKeyword:
1693                constant = ValueUtil.getNullConstant();
1694                break;
1695            case ts.SyntaxKind.UndefinedKeyword:
1696                constant = ValueUtil.getUndefinedConst();
1697                break;
1698            case ts.SyntaxKind.TrueKeyword:
1699                constant = ValueUtil.getBooleanConstant(true);
1700                break;
1701            case ts.SyntaxKind.FalseKeyword:
1702                constant = ValueUtil.getBooleanConstant(false);
1703                break;
1704            default:
1705                logger.warn(`ast node's syntaxKind is ${ts.SyntaxKind[literalNode.kind]}, not literalNode`);
1706        }
1707
1708        if (constant === null) {
1709            return null;
1710        }
1711        return {
1712            value: constant,
1713            valueOriginalPositions: [FullPosition.buildFromNode(literalNode, this.sourceFile)],
1714            stmts: [],
1715        };
1716    }
1717
1718    private getOrCreateLocal(localName: string, localType: Type = UnknownType.getInstance()): Local {
1719        let local = this.locals.get(localName);
1720        if (local !== undefined) {
1721            return local;
1722        }
1723        local = this.addNewLocal(localName, localType);
1724        this.addNewGlobal(localName);
1725        return local;
1726    }
1727
1728    public generateTempLocal(localType: Type = UnknownType.getInstance()): Local {
1729        const tempLocalName = TEMP_LOCAL_PREFIX + this.tempLocalNo;
1730        this.tempLocalNo++;
1731        const tempLocal: Local = new Local(tempLocalName, localType);
1732        this.locals.set(tempLocalName, tempLocal);
1733        return tempLocal;
1734    }
1735
1736    private isRelationalOperator(operator: BinaryOperator): boolean {
1737        return (
1738            operator === RelationalBinaryOperator.LessThan ||
1739            operator === RelationalBinaryOperator.LessThanOrEqual ||
1740            operator === RelationalBinaryOperator.GreaterThan ||
1741            operator === RelationalBinaryOperator.GreaterThanOrEqual ||
1742            operator === RelationalBinaryOperator.Equality ||
1743            operator === RelationalBinaryOperator.InEquality ||
1744            operator === RelationalBinaryOperator.StrictEquality ||
1745            operator === RelationalBinaryOperator.StrictInequality
1746        );
1747    }
1748
1749    private isLiteralNode(node: ts.Node): boolean {
1750        if (
1751            ts.isStringLiteral(node) ||
1752            ts.isNumericLiteral(node) ||
1753            ts.isBigIntLiteral(node) ||
1754            ts.isRegularExpressionLiteral(node) ||
1755            ts.isNoSubstitutionTemplateLiteral(node) ||
1756            node.kind === ts.SyntaxKind.NullKeyword ||
1757            node.kind === ts.SyntaxKind.TrueKeyword ||
1758            node.kind === ts.SyntaxKind.FalseKeyword ||
1759            node.kind === ts.SyntaxKind.UndefinedKeyword
1760        ) {
1761            return true;
1762        }
1763        return false;
1764    }
1765
1766    public resolveTypeNode(type: ts.TypeNode): Type {
1767        const kind = type.kind;
1768        switch (kind) {
1769            case ts.SyntaxKind.BooleanKeyword:
1770                return BooleanType.getInstance();
1771            case ts.SyntaxKind.NumberKeyword:
1772                return NumberType.getInstance();
1773            case ts.SyntaxKind.StringKeyword:
1774                return StringType.getInstance();
1775            case ts.SyntaxKind.UndefinedKeyword:
1776                return UndefinedType.getInstance();
1777            case ts.SyntaxKind.AnyKeyword:
1778                return AnyType.getInstance();
1779            case ts.SyntaxKind.VoidKeyword:
1780                return VoidType.getInstance();
1781            case ts.SyntaxKind.NeverKeyword:
1782                return NeverType.getInstance();
1783            case ts.SyntaxKind.BigIntKeyword:
1784                return BigIntType.getInstance();
1785            case ts.SyntaxKind.TypeReference:
1786                return this.resolveTypeReferenceNode(type as ts.TypeReferenceNode);
1787            case ts.SyntaxKind.ArrayType:
1788                return new ArrayType(this.resolveTypeNode((type as ts.ArrayTypeNode).elementType), 1);
1789            case ts.SyntaxKind.UnionType: {
1790                const mayTypes: Type[] = [];
1791                (type as ts.UnionTypeNode).types.forEach(t => mayTypes.push(this.resolveTypeNode(t)));
1792                return new UnionType(mayTypes);
1793            }
1794            case ts.SyntaxKind.IntersectionType: {
1795                const intersectionTypes: Type[] = [];
1796                (type as ts.IntersectionTypeNode).types.forEach(t => intersectionTypes.push(this.resolveTypeNode(t)));
1797                return new IntersectionType(intersectionTypes);
1798            }
1799            case ts.SyntaxKind.TupleType: {
1800                const types: Type[] = [];
1801                (type as ts.TupleTypeNode).elements.forEach(element => {
1802                    types.push(this.resolveTypeNode(element));
1803                });
1804                return new TupleType(types);
1805            }
1806            case ts.SyntaxKind.NamedTupleMember:
1807                return this.resolveTypeNode((type as ts.NamedTupleMember).type);
1808            case ts.SyntaxKind.LiteralType:
1809                return ArkValueTransformer.resolveLiteralTypeNode(type as ts.LiteralTypeNode, this.sourceFile);
1810            case ts.SyntaxKind.TemplateLiteralType:
1811                return this.resolveTemplateLiteralTypeNode(type as ts.TemplateLiteralTypeNode);
1812            case ts.SyntaxKind.TypeLiteral:
1813                return this.resolveTypeLiteralNode(type as ts.TypeLiteralNode);
1814            case ts.SyntaxKind.FunctionType:
1815                return this.resolveFunctionTypeNode(type as ts.FunctionTypeNode);
1816            case ts.SyntaxKind.ImportType:
1817                return UnknownType.getInstance();
1818            case ts.SyntaxKind.TypeQuery:
1819                return this.resolveTypeQueryNode(type as ts.TypeQueryNode);
1820            case ts.SyntaxKind.ParenthesizedType:
1821                return this.resolveTypeNode((type as ts.ParenthesizedTypeNode).type);
1822            case ts.SyntaxKind.TypeOperator:
1823                return this.resolveTypeOperatorNode(type as ts.TypeOperatorNode);
1824            default:
1825                return UnknownType.getInstance();
1826        }
1827    }
1828
1829    private resolveTypeQueryNode(typeQueryNode: ts.TypeQueryNode): Type {
1830        const genericTypes: Type[] = [];
1831        if (typeQueryNode.typeArguments) {
1832            for (const typeArgument of typeQueryNode.typeArguments) {
1833                genericTypes.push(this.resolveTypeNode(typeArgument));
1834            }
1835        }
1836
1837        const exprNameNode = typeQueryNode.exprName;
1838        let opValue: Value;
1839        if (ts.isQualifiedName(exprNameNode)) {
1840            if (exprNameNode.left.getText(this.sourceFile) === THIS_NAME) {
1841                const fieldName = exprNameNode.right.getText(this.sourceFile);
1842                const fieldSignature =
1843                    this.declaringMethod.getDeclaringArkClass().getFieldWithName(fieldName)?.getSignature() ??
1844                    ArkSignatureBuilder.buildFieldSignatureFromFieldName(fieldName);
1845                const baseLocal =
1846                    this.locals.get(THIS_NAME) ?? new Local(THIS_NAME, new ClassType(this.declaringMethod.getDeclaringArkClass().getSignature(), genericTypes));
1847                opValue = new ArkInstanceFieldRef(baseLocal, fieldSignature);
1848            } else {
1849                const exprName = exprNameNode.getText(this.sourceFile);
1850                opValue = new Local(exprName, UnknownType.getInstance());
1851            }
1852        } else {
1853            const exprName = exprNameNode.escapedText.toString();
1854            opValue = this.locals.get(exprName) ?? this.globals?.get(exprName) ?? new Local(exprName, UnknownType.getInstance());
1855        }
1856
1857        return new TypeQueryExpr(opValue, genericTypes);
1858    }
1859
1860    private resolveTypeOperatorNode(typeOperatorNode: ts.TypeOperatorNode): Type {
1861        let type = this.resolveTypeNode(typeOperatorNode.type);
1862
1863        switch (typeOperatorNode.operator) {
1864            case ts.SyntaxKind.ReadonlyKeyword: {
1865                if (type instanceof ArrayType || type instanceof TupleType) {
1866                    type.setReadonlyFlag(true);
1867                }
1868                return type;
1869            }
1870            case ts.SyntaxKind.KeyOfKeyword: {
1871                return new KeyofTypeExpr(type);
1872            }
1873            case ts.SyntaxKind.UniqueKeyword: {
1874                return UnknownType.getInstance();
1875            }
1876            default:
1877                return UnknownType.getInstance();
1878        }
1879    }
1880
1881    public static resolveLiteralTypeNode(literalTypeNode: ts.LiteralTypeNode, sourceFile: ts.SourceFile): Type {
1882        const literal = literalTypeNode.literal;
1883        const kind = literal.kind;
1884        switch (kind) {
1885            case ts.SyntaxKind.NullKeyword:
1886                return NullType.getInstance();
1887            case ts.SyntaxKind.TrueKeyword:
1888                return LiteralType.TRUE;
1889            case ts.SyntaxKind.FalseKeyword:
1890                return LiteralType.FALSE;
1891            case ts.SyntaxKind.NumericLiteral:
1892                return new LiteralType(parseFloat((literal as ts.NumericLiteral).text));
1893            case ts.SyntaxKind.PrefixUnaryExpression:
1894                return new LiteralType(parseFloat(literal.getText(sourceFile)));
1895            default:
1896        }
1897        return new LiteralType(literal.getText(sourceFile));
1898    }
1899
1900    private resolveTemplateLiteralTypeNode(templateLiteralTypeNode: ts.TemplateLiteralTypeNode): Type {
1901        let stringLiterals: string[] = [''];
1902        const headString = templateLiteralTypeNode.head.rawText || '';
1903        let newStringLiterals: string[] = [];
1904        for (const stringLiteral of stringLiterals) {
1905            newStringLiterals.push(stringLiteral + headString);
1906        }
1907        stringLiterals = newStringLiterals;
1908        newStringLiterals = [];
1909
1910        for (const templateSpan of templateLiteralTypeNode.templateSpans) {
1911            const templateType = this.resolveTypeNode(templateSpan.type);
1912            const unfoldTemplateTypes: Type[] = [];
1913            if (templateType instanceof UnionType) {
1914                unfoldTemplateTypes.push(...templateType.getTypes());
1915            } else {
1916                unfoldTemplateTypes.push(templateType);
1917            }
1918            const unfoldTemplateTypeStrs: string[] = [];
1919            for (const unfoldTemplateType of unfoldTemplateTypes) {
1920                unfoldTemplateTypeStrs.push(
1921                    unfoldTemplateType instanceof AliasType ? unfoldTemplateType.getOriginalType().toString() : unfoldTemplateType.toString()
1922                );
1923            }
1924
1925            const templateSpanString = templateSpan.literal.rawText || '';
1926            for (const stringLiteral of stringLiterals) {
1927                for (const unfoldTemplateTypeStr of unfoldTemplateTypeStrs) {
1928                    newStringLiterals.push(stringLiteral + unfoldTemplateTypeStr + templateSpanString);
1929                }
1930            }
1931            stringLiterals = newStringLiterals;
1932            newStringLiterals = [];
1933        }
1934
1935        const templateTypes: Type[] = [];
1936        for (const stringLiteral of stringLiterals) {
1937            templateTypes.push(new LiteralType(stringLiteral));
1938        }
1939        if (templateTypes.length > 0) {
1940            return new UnionType(templateTypes);
1941        }
1942        return templateTypes[0];
1943    }
1944
1945    private resolveTypeReferenceNode(typeReferenceNode: ts.TypeReferenceNode): Type {
1946        const typeReferenceFullName = ts.isIdentifier(typeReferenceNode.typeName) ? typeReferenceNode.typeName.text :
1947            typeReferenceNode.typeName.getText(this.sourceFile);
1948        if (typeReferenceFullName === Builtin.OBJECT) {
1949            return Builtin.OBJECT_CLASS_TYPE;
1950        }
1951        const aliasTypeAndStmt = this.aliasTypeMap.get(typeReferenceFullName);
1952
1953        const genericTypes: Type[] = [];
1954        if (typeReferenceNode.typeArguments) {
1955            for (const typeArgument of typeReferenceNode.typeArguments) {
1956                genericTypes.push(this.resolveTypeNode(typeArgument));
1957            }
1958        }
1959
1960        if (!aliasTypeAndStmt) {
1961            const local = this.locals.get(typeReferenceFullName);
1962            if (local !== undefined) {
1963                return local.getType();
1964            }
1965            return new UnclearReferenceType(typeReferenceFullName, genericTypes);
1966        } else {
1967            if (genericTypes.length > 0) {
1968                const oldAlias = aliasTypeAndStmt[0];
1969                let alias = new AliasType(
1970                    oldAlias.getName(),
1971                    TypeInference.replaceTypeWithReal(oldAlias.getOriginalType(), genericTypes),
1972                    oldAlias.getSignature(),
1973                    oldAlias.getGenericTypes()
1974                );
1975                alias.setRealGenericTypes(genericTypes);
1976                return alias;
1977            }
1978            return aliasTypeAndStmt[0];
1979        }
1980    }
1981
1982    private resolveTypeLiteralNode(typeLiteralNode: ts.TypeLiteralNode): Type {
1983        const anonymousClass = new ArkClass();
1984        const declaringClass = this.declaringMethod.getDeclaringArkClass();
1985        const declaringNamespace = declaringClass.getDeclaringArkNamespace();
1986        if (declaringNamespace) {
1987            buildNormalArkClassFromArkNamespace(typeLiteralNode, declaringNamespace, anonymousClass, this.sourceFile);
1988        } else {
1989            buildNormalArkClassFromArkFile(typeLiteralNode, declaringClass.getDeclaringArkFile(), anonymousClass, this.sourceFile);
1990        }
1991        return new ClassType(anonymousClass.getSignature());
1992    }
1993
1994    private resolveFunctionTypeNode(functionTypeNode: ts.FunctionTypeNode): Type {
1995        const anonymousMethod = new ArkMethod();
1996        const declaringClass = this.declaringMethod.getDeclaringArkClass();
1997        buildArkMethodFromArkClass(functionTypeNode, declaringClass, anonymousMethod, this.sourceFile);
1998        return new FunctionType(anonymousMethod.getSignature());
1999    }
2000
2001    public static isCompoundAssignmentOperator(operator: ts.SyntaxKind): boolean {
2002        const compoundAssignmentOperators = [
2003            ts.SyntaxKind.PlusEqualsToken,
2004            ts.SyntaxKind.MinusEqualsToken,
2005            ts.SyntaxKind.AsteriskAsteriskEqualsToken,
2006            ts.SyntaxKind.AsteriskEqualsToken,
2007            ts.SyntaxKind.SlashEqualsToken,
2008            ts.SyntaxKind.PercentEqualsToken,
2009            ts.SyntaxKind.AmpersandEqualsToken,
2010            ts.SyntaxKind.BarEqualsToken,
2011            ts.SyntaxKind.CaretEqualsToken,
2012            ts.SyntaxKind.LessThanLessThanEqualsToken,
2013            ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken,
2014            ts.SyntaxKind.GreaterThanGreaterThanEqualsToken,
2015            ts.SyntaxKind.BarBarEqualsToken,
2016            ts.SyntaxKind.AmpersandAmpersandEqualsToken,
2017            ts.SyntaxKind.QuestionQuestionEqualsToken,
2018        ];
2019        return compoundAssignmentOperators.includes(operator);
2020    }
2021}
2022