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