1/* 2 * Copyright (c) 2024 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 ts, { SyntaxKind } from 'typescript'; 17import { HeritageKeyValue, KeyValue, Members, MockBuffer } from '../types'; 18import { 19 BASE_KINDS, 20 ClosedSourceFileMapping, 21 COMPONENT_DECORATORS, 22 D_ETS, 23 DECLARES, 24 KeyValueTypes, 25 specialTSTypes 26} from './constants'; 27import { associateTypeParameters, generateKeyValue, getAbsolutePath, isArktsOne } from './commonUtils'; 28import path from 'path'; 29 30/** 31 * 处理import导入节点 32 * @param node typescript node节点 33 * @param mockBuffer mock信息 34 * @param members 当前节点应该归属的member 35 * @param parent 父级节点 36 * @param type KeyValue节点类型 37 */ 38export function handleImportDeclaration( 39 node: ts.ImportDeclaration, 40 mockBuffer: MockBuffer, 41 members: Members, 42 parent: KeyValue, 43 type: KeyValueTypes 44): void { 45 const moduleSpecifier = handleExpression(node.moduleSpecifier, mockBuffer, {}, parent, type, []); 46 const importFilePath = getAbsolutePath(mockBuffer, moduleSpecifier.key); 47 const importClauseNode = node.importClause; 48 if (importClauseNode) { 49 handleImportClauseNode(importClauseNode, members, parent, KeyValueTypes.IMPORT, importFilePath); 50 } 51} 52 53/** 54 * 处理module节点 55 * @param node typescript node节点 56 * @param mockBuffer mock信息 57 * @param members 当前节点应该归属的member 58 * @param parent 父级节点 59 * @param type KeyValue节点类型 60 * @returns 61 */ 62export function handleModuleDeclaration( 63 sourceFile: ts.SourceFile, 64 node: ts.ModuleDeclaration, 65 mockBuffer: MockBuffer, 66 members: Members, 67 parent: KeyValue, 68 type: KeyValueTypes 69): void { 70 const moduleName = handleModuleName(node.name, members, parent, type); 71 moduleName.isNeedMock = true; 72 if (!moduleName) { 73 return; 74 } 75 handleDefaultOrExport(mockBuffer, moduleName, node.modifiers); 76 77 handleModuleBody(sourceFile, mockBuffer, moduleName.members, moduleName, node.body); 78} 79 80/** 81 * 处理type节点 82 * @param node typescript node节点 83 * @param mockBuffer mock信息 84 * @param members 当前节点应该归属的member 85 * @param parent 父级节点 86 * @param type KeyValue节点类型 87 * @returns 88 */ 89export function handleTypeAliasDeclaration( 90 node: ts.TypeAliasDeclaration, 91 mockBuffer: MockBuffer, 92 members: Members, 93 parent: KeyValue, 94 type: KeyValueTypes 95): KeyValue { 96 const name = handleIdentifier(node.name, members, parent, type); 97 node.typeParameters?.forEach(typeParam => { 98 handleTypeParameterDeclaration(typeParam, mockBuffer, name.typeParameters, name, KeyValueTypes.REFERENCE); 99 }); 100 handleTypeNode(mockBuffer, name.members, name, KeyValueTypes.REFERENCE, node.type); 101 handleDefaultOrExport(mockBuffer, name, node.modifiers); 102 return name; 103} 104 105/** 106 * 处理class节点 107 * @param node typescript node节点 108 * @param mockBuffer mock信息 109 * @param members 当前节点应该归属的member 110 * @param parent 父级节点 111 * @param type KeyValue节点类型 112 * @returns 113 */ 114export function handleClassDeclaration( 115 sourceFile: ts.SourceFile, 116 node: ts.ClassDeclaration, 117 mockBuffer: MockBuffer, 118 members: Members, 119 parent: KeyValue, 120 type: KeyValueTypes 121): KeyValue { 122 const isComponent: boolean = isComponentNode(node, mockBuffer); 123 const className = handleIdentifier(node.name, members, parent, type); 124 className.isNeedMock = true; 125 handleDefaultOrExport(mockBuffer, className, node.modifiers); 126 if (isComponent) { 127 return className; 128 } 129 130 node.typeParameters?.forEach(typeParameterNode => { 131 handleTypeParameterDeclaration(typeParameterNode, mockBuffer, className.typeParameters, className, KeyValueTypes.REFERENCE); 132 }); 133 134 if (!className.key) { 135 throw new Error('ClassDeclaration 没有名字'); 136 } 137 node.heritageClauses?.forEach(heritageClause => { 138 className.heritage = handleHeritageClause(heritageClause, mockBuffer, {}, className, KeyValueTypes.REFERENCE); 139 }); 140 141 node.members.forEach(member => { 142 if (!isArktsOne(member, sourceFile)) { 143 return; 144 } 145 handleClassElement(member, mockBuffer, className.members, className, KeyValueTypes.PROPERTY); 146 }); 147 return className; 148} 149 150/** 151 * 处理interface节点 152 * @param node typescript node节点 153 * @param mockBuffer mock信息 154 * @param members 当前节点应该归属的member 155 * @param parent 父级节点 156 * @param type KeyValue节点类型 157 * @returns 158 */ 159export function handleInterfaceDeclaration( 160 sourceFile: ts.SourceFile, 161 node: ts.InterfaceDeclaration, 162 mockBuffer: MockBuffer, 163 members: Members, 164 parent: KeyValue, 165 type: KeyValueTypes 166): KeyValue { 167 const interfaceName = handleIdentifier(node.name, members, parent, type); 168 handleDefaultOrExport(mockBuffer, interfaceName, node.modifiers); 169 node.typeParameters?.forEach(typeParameter => { 170 handleTypeParameterDeclaration(typeParameter, mockBuffer, interfaceName.typeParameters, interfaceName, KeyValueTypes.REFERENCE); 171 }); 172 node.heritageClauses?.forEach(heritageClause => { 173 interfaceName.heritage = handleHeritageClause(heritageClause, mockBuffer, {}, interfaceName, KeyValueTypes.REFERENCE); 174 }); 175 node.members.forEach(member => { 176 if (!isArktsOne(member, sourceFile)) { 177 return; 178 } 179 handleTypeElement(member, mockBuffer, interfaceName.members, interfaceName, KeyValueTypes.PROPERTY); 180 }); 181 return interfaceName; 182} 183 184/** 185 * 处理enum节点 186 * @param node typescript node节点 187 * @param mockBuffer mock信息 188 * @param members 当前节点应该归属的member 189 * @param parent 父级节点 190 * @param type KeyValue节点类型 191 * @returns 192 */ 193export function handleEnumDeclaration( 194 sourceFile: ts.SourceFile, 195 node: ts.EnumDeclaration, 196 mockBuffer: MockBuffer, 197 members: Members, 198 parent: KeyValue, 199 type: KeyValueTypes 200): KeyValue { 201 const enumName = handleEnumName(node, members, parent, type); 202 enumName.isNeedMock = true; 203 handleDefaultOrExport(mockBuffer, enumName, node.modifiers); 204 node.members.forEach(member => { 205 if (!isArktsOne(member, sourceFile)) { 206 return; 207 } 208 handleEnumMember(member, mockBuffer, enumName.members, enumName, KeyValueTypes.PROPERTY); 209 }); 210 return enumName; 211} 212 213/** 214 * 处理function节点 215 * @param node typescript node节点 216 * @param mockBuffer mock信息 217 * @param members 当前节点应该归属的member 218 * @param parent 父级节点 219 * @param type KeyValue节点类型 220 * @returns 221 */ 222export function handleFunctionDeclaration( 223 node: ts.FunctionDeclaration, 224 mockBuffer: MockBuffer, 225 members: Members, 226 parent: KeyValue, 227 type: KeyValueTypes 228): KeyValue { 229 const functionName = handleIdentifier(node.name, members, parent, type); 230 functionName.isNeedMock = true; 231 handleDefaultOrExport(mockBuffer, functionName, node.modifiers); 232 for (let i = 0; i < node.parameters.length; i++) { 233 handleParameterDeclaration(node.parameters[i], mockBuffer, functionName.methodParams, functionName, KeyValueTypes.REFERENCE); 234 } 235 node.typeParameters?.forEach( 236 typeParameter => handleTypeParameterDeclaration(typeParameter, mockBuffer, functionName.typeParameters, functionName, KeyValueTypes.VALUE) 237 ); 238 handleTypeNode(mockBuffer, functionName.members, functionName, KeyValueTypes.REFERENCE, node.type); 239 return functionName; 240} 241 242/** 243 * 处理export节点 244 * @param node typescript node节点 245 * @param mockBuffer mock信息 246 * @param members 当前节点应该归属的member 247 * @param parent 父级节点 248 * @param type KeyValue节点类型 249 * @returns 250 */ 251export function handleExportDeclaration( 252 node: ts.ExportDeclaration, 253 mockBuffer: MockBuffer, 254 members: Members, 255 parent: KeyValue, 256 type: KeyValueTypes 257): void { 258 let moduleSpecifier: KeyValue; 259 let importedModulePath: string | undefined; 260 if (node.moduleSpecifier) { 261 moduleSpecifier = handleExpression(node.moduleSpecifier, mockBuffer, {}, parent, KeyValueTypes.EXPORT, []); 262 importedModulePath = getAbsolutePath(mockBuffer, moduleSpecifier.key); 263 moduleSpecifier.key = importedModulePath; 264 } 265 266 if (node.exportClause) { 267 handleNamedExportBindings(node.exportClause, mockBuffer, parent, type, importedModulePath); 268 } else { 269 if (moduleSpecifier) { 270 members[moduleSpecifier.key] = moduleSpecifier; 271 } else { 272 throw new Error('当导出*时,未指定模块路径'); 273 } 274 } 275} 276 277/** 278 * 处理const节点 279 * @param node typescript node节点 280 * @param mockBuffer mock信息 281 * @param members 当前节点应该归属的member 282 * @param parent 父级节点 283 * @param type KeyValue节点类型 284 * @returns 285 */ 286export function handleVariableStatement( 287 node: ts.VariableStatement, 288 mockBuffer: MockBuffer, 289 members: Members, 290 parent: KeyValue, 291 type: KeyValueTypes 292): void { 293 node.declarationList.declarations.forEach(declaration => { 294 const declarationName = handleBindingName(declaration.name, members, parent, type); 295 declarationName.isNeedMock = true; 296 declarationName.operateElements = []; 297 handleDefaultOrExport(mockBuffer, declarationName, node.modifiers); 298 if (declaration.initializer) { 299 handleExpression( 300 declaration.initializer, 301 mockBuffer, 302 declarationName.members, 303 declarationName, KeyValueTypes.REFERENCE, 304 declarationName.operateElements 305 ); 306 return; 307 } 308 declaration.initializer && handleExpression( 309 declaration.initializer, 310 mockBuffer, 311 declarationName.members, 312 declarationName, KeyValueTypes.REFERENCE, 313 declarationName.operateElements 314 ); 315 declaration.type && handleTypeNode( 316 mockBuffer, 317 declarationName.members, 318 declarationName, 319 KeyValueTypes.REFERENCE, 320 declaration.type 321 ); 322 }); 323} 324 325/** 326 * 处理export节点 327 * @param node typescript node节点 328 * @param mockBuffer mock信息 329 * @param members 当前节点应该归属的member 330 * @param parent 父级节点 331 * @param type KeyValue节点类型 332 * @returns 333 */ 334export function handleExportAssignment( 335 node: ts.ExportAssignment, 336 mockBuffer: MockBuffer, 337 members: Members, 338 parent: KeyValue, 339 type: KeyValueTypes 340): void { 341 const exportDefault = handleExpression(node.expression, mockBuffer, {}, parent, type, []); 342 if (members[exportDefault.key]) { 343 members[exportDefault.key].isDefault = true; 344 mockBuffer.contents.members.default = members[exportDefault.key]; 345 } 346} 347 348function handleNamedExportBindings( 349 node: ts.NamedExportBindings, 350 mockBuffer: MockBuffer, 351 parent: KeyValue, 352 type: KeyValueTypes, 353 importedModulePath: string | undefined 354): void { 355 if (!node) { 356 throw new Error('NamedExportBindings类型node为undefined'); 357 } 358 switch (node.kind) { 359 case SyntaxKind.NamedExports: { 360 handleNamedExports(node, mockBuffer, parent, type, importedModulePath); 361 break; 362 } 363 case SyntaxKind.NamespaceExport: { 364 break; 365 } 366 default: { 367 throw new Error('未知的NamedExportBindings类型'); 368 } 369 } 370} 371 372function handleNamedExports( 373 node: ts.NamedExports, 374 mockBuffer: MockBuffer, 375 parent: KeyValue, 376 type: KeyValueTypes, 377 importedModulePath: string | undefined 378): void { 379 const whereParent = mockBuffer.contents.members[parent.key] ?? mockBuffer.contents; 380 node.elements.forEach(element => { 381 if (importedModulePath) { 382 const exportName = handleIdentifier(element.name, whereParent.members, whereParent, type); 383 exportName.importedModulePath = importedModulePath; 384 } 385 handleIdentifier(element.name, whereParent.members, whereParent, KeyValueTypes.REFERENCE); 386 }); 387} 388 389function handleParameterDeclaration( 390 node: ts.ParameterDeclaration, 391 mockBuffer: MockBuffer, 392 members: Members, 393 parent: KeyValue, 394 type: KeyValueTypes 395): KeyValue { 396 const name = handleBindingName(node.name, members, parent, type); 397 if (name.key === 'arguments') { 398 delete members.arguments; 399 name.key = name.key.replace('arguments', 'args'); 400 members.args = name; 401 } 402 handleTypeNode(mockBuffer, name.members, name, KeyValueTypes.REFERENCE, node.type); 403 return name; 404} 405 406function handleBindingName( 407 node: ts.BindingName, 408 members: Members, 409 parent: KeyValue, 410 type: KeyValueTypes 411): KeyValue { 412 let text: string; 413 switch (node.kind) { 414 case SyntaxKind.Identifier: { 415 text = node.escapedText.toString(); 416 break; 417 } 418 case SyntaxKind.ObjectBindingPattern: { 419 return handleObjectBindingPattern(); 420 } 421 default: { 422 throw new Error('未知的Statement类型'); 423 } 424 } 425 members[text] = generateKeyValue(text, type, parent); 426 return members[text]; 427} 428 429function handleObjectBindingPattern(): KeyValue { 430 return generateKeyValue('', KeyValueTypes.VALUE); 431} 432 433function handleEnumName( 434 node: ts.EnumDeclaration, 435 members: Members, 436 parent: KeyValue, 437 type: KeyValueTypes 438): KeyValue { 439 const enumName = node.name.escapedText.toString(); 440 members[enumName] = generateKeyValue(enumName, type, parent); 441 return members[enumName]; 442} 443 444function handleEnumMember( 445 node: ts.EnumMember, 446 mockBuffer: MockBuffer, 447 members: Members, 448 parent: KeyValue, 449 type: KeyValueTypes 450): KeyValue { 451 const memberName = handlePropertyNameNode(node.name, mockBuffer, members, parent, type); 452 if (node.initializer) { 453 handleEnumMemberInitializer(node.initializer, mockBuffer, memberName.members, memberName, KeyValueTypes.REFERENCE); 454 } else { 455 memberName.value = '0'; 456 } 457 return memberName; 458} 459 460function handleEnumMemberInitializer( 461 node: ts.Expression, 462 mockBuffer: MockBuffer, 463 members: Members, 464 parent: KeyValue, 465 type: KeyValueTypes 466): void { 467 switch (node.kind) { 468 case SyntaxKind.NumericLiteral: { 469 const numericLiteral = node as ts.NumericLiteral; 470 members[numericLiteral.text] = generateKeyValue(numericLiteral.text, KeyValueTypes.VALUE, parent); 471 break; 472 } 473 case SyntaxKind.BigIntLiteral: { 474 handleBigIntLiteral(node as ts.BigIntLiteral, members, parent, KeyValueTypes.VALUE); 475 break; 476 } 477 case SyntaxKind.StringLiteral: { 478 handleStringLiteral(node as ts.StringLiteral, members, parent); 479 break; 480 } 481 case SyntaxKind.BinaryExpression: { 482 handleBinaryExpression(node as ts.BinaryExpression, mockBuffer, members, parent); 483 break; 484 } 485 case SyntaxKind.PrefixUnaryExpression: { 486 handlePrefixUnaryExpression(node as ts.PrefixUnaryExpression, members, parent); 487 break; 488 } 489 case SyntaxKind.Identifier: { 490 handleIdentifier(node as ts.Identifier, members, parent, type); 491 break; 492 } 493 case SyntaxKind.PropertyAccessExpression: { 494 const expression = generateKeyValue('expression', KeyValueTypes.EXPRESSION, parent); 495 expression.operateElements = []; 496 members.expression = expression; 497 handlePropertyAccessExpression( 498 node as ts.PropertyAccessExpression, 499 mockBuffer, expression.members, 500 expression.parent, 501 type, 502 expression.operateElements 503 ); 504 break; 505 } 506 case SyntaxKind.EmptyStatement: 507 case SyntaxKind.Block: 508 case SyntaxKind.SemicolonClassElement: 509 case SyntaxKind.ExpressionStatement: { 510 break; 511 } 512 default: { 513 throw new Error('未知的EnumMemberInitializer类型'); 514 } 515 } 516} 517 518function handleTypeElement( 519 node: ts.TypeElement, 520 mockBuffer: MockBuffer, 521 members: Members, 522 parent: KeyValue, 523 type: KeyValueTypes 524): void { 525 switch (node.kind) { 526 case SyntaxKind.PropertySignature: { 527 handlePropertySignature(node as ts.PropertySignature, mockBuffer, members, parent, type); 528 break; 529 } 530 case SyntaxKind.MethodSignature: { 531 handleMethodSignature(node as ts.MethodSignature, mockBuffer, members, parent, KeyValueTypes.FUNCTION); 532 break; 533 } 534 case SyntaxKind.IndexSignature: { 535 handleIndexSignature(); 536 break; 537 } 538 case SyntaxKind.CallSignature: { 539 handleCallSignatureDeclaration(node as ts.CallSignatureDeclaration, mockBuffer, members, parent, type); 540 break; 541 } 542 case SyntaxKind.ConstructSignature: { 543 generateKeyValue('', type, parent); 544 break; 545 } 546 case SyntaxKind.EmptyStatement: 547 case SyntaxKind.Block: 548 case SyntaxKind.SemicolonClassElement: 549 case SyntaxKind.ExpressionStatement: { 550 break; 551 } 552 default: { 553 throw new Error('未知的TypeElement类型'); 554 } 555 } 556} 557 558function handleCallSignatureDeclaration( 559 node: ts.CallSignatureDeclaration, 560 mockBuffer: MockBuffer, 561 members: Members, 562 parent: KeyValue, 563 type: KeyValueTypes 564): void { 565 if (node.questionToken) { 566 return; 567 } 568 handleMethodSignature(node, mockBuffer, members, parent, type); 569} 570 571function handleIndexSignature(): KeyValue { 572 return generateKeyValue('', KeyValueTypes.VALUE); 573} 574 575function handleMethodSignature( 576 node: ts.CallSignatureDeclaration | ts.MethodSignature, 577 mockBuffer: MockBuffer, 578 members: Members, 579 parent: KeyValue, 580 type: KeyValueTypes 581): void { 582 if (node.questionToken) { 583 return; 584 } 585 if (!node.name) { 586 return; 587 } 588 const methodName = handlePropertyNameNode(node.name, mockBuffer, members, parent, type); 589 for (let i = 0; i < node.parameters.length; i++) { 590 node.parameters.forEach(_ => handleParameterDeclaration( 591 node.parameters[i], 592 mockBuffer, 593 methodName.methodParams, 594 methodName, 595 KeyValueTypes.REFERENCE 596 )); 597 } 598 node.typeParameters?.forEach(parameter => { 599 handleTypeParameterDeclaration(parameter, mockBuffer, methodName.typeParameters, methodName, KeyValueTypes.VALUE); 600 }); 601 handleTypeNode(mockBuffer, methodName.members, methodName, KeyValueTypes.REFERENCE, node.type); 602} 603 604function handlePropertySignature( 605 node: ts.PropertySignature, 606 mockBuffer: MockBuffer, 607 members: Members, 608 parent: KeyValue, 609 type: KeyValueTypes 610): void { 611 if (node.questionToken) { 612 return; 613 } 614 const propertyName = handlePropertyNameNode(node.name, mockBuffer, members, parent, type); 615 handleTypeNode(mockBuffer, propertyName.members, propertyName, KeyValueTypes.REFERENCE, node.type); 616} 617 618function handleClassElement( 619 node: ts.ClassElement, 620 mockBuffer: MockBuffer, 621 members: Members, 622 parent: KeyValue, 623 type: KeyValueTypes 624): void { 625 switch (node.kind) { 626 case SyntaxKind.PropertyDeclaration: { 627 handlePropertyDeclaration(node as ts.PropertyDeclaration, mockBuffer, members, parent, type); 628 return; 629 } 630 case SyntaxKind.MethodDeclaration: { 631 handleMethodDeclaration(node as ts.MethodDeclaration, mockBuffer, members, parent, KeyValueTypes.FUNCTION); 632 return; 633 } 634 case SyntaxKind.EmptyStatement: 635 case SyntaxKind.Block: 636 case SyntaxKind.SemicolonClassElement: 637 case SyntaxKind.ExpressionStatement: 638 case SyntaxKind.IndexSignature: 639 case SyntaxKind.Constructor: { 640 return; 641 } 642 case SyntaxKind.GetAccessor: { 643 handleGetAccessorDeclaration(node as ts.GetAccessorDeclaration, mockBuffer, members, parent, KeyValueTypes.FUNCTION); 644 return; 645 } 646 case SyntaxKind.SetAccessor: { 647 handleSetAccessorDeclaration(node as ts.SetAccessorDeclaration, mockBuffer, members, parent, KeyValueTypes.FUNCTION); 648 return; 649 } 650 default: { 651 throw new Error('未知的ClassElement类型'); 652 } 653 } 654} 655 656function handleMethodDeclaration( 657 node: ts.MethodDeclaration, 658 mockBuffer: MockBuffer, 659 members: Members, 660 parent: KeyValue, 661 type: KeyValueTypes 662): void { 663 if (node.questionToken) { 664 return; 665 } 666 const methodName = handlePropertyNameNode(node.name, mockBuffer, members, parent, type); 667 methodName.isStatic = node.modifiers?.some(modify => modify.kind === SyntaxKind.StaticKeyword); 668 node.typeParameters?.forEach(typeParameter => { 669 handleTypeParameterDeclaration(typeParameter, mockBuffer, methodName.typeParameters, methodName, KeyValueTypes.REFERENCE); 670 }); 671 for (let i = 0; i < node.parameters.length; i++) { 672 handleParameterDeclaration(node.parameters[i], mockBuffer, methodName.methodParams, methodName, KeyValueTypes.REFERENCE); 673 } 674 handleTypeNode(mockBuffer, methodName.members, methodName, KeyValueTypes.REFERENCE, node.type); 675} 676 677function handleHeritageClause( 678 node: ts.HeritageClause, 679 mockBuffer: MockBuffer, 680 members: Members, 681 parent: KeyValue, 682 type: KeyValueTypes 683): HeritageKeyValue { 684 if (node.token === SyntaxKind.ImplementsKeyword) { 685 return undefined as HeritageKeyValue; 686 } 687 return handleExpressionWithTypeArguments(node.types[node.types.length - 1], mockBuffer, members, parent, type, []) as HeritageKeyValue; 688} 689 690function handleExpressionWithTypeArguments( 691 node: ts.ExpressionWithTypeArguments, 692 mockBuffer: MockBuffer, 693 members: Members, 694 parent: KeyValue, 695 type: KeyValueTypes, 696 operateElements: KeyValue[] 697): KeyValue { 698 const expression = handleLeftHandSideExpression(node.expression, mockBuffer, members, parent, type, operateElements); 699 node.typeArguments?.forEach(typeNode => { 700 handleTypeNode(mockBuffer, expression.typeParameters, expression, KeyValueTypes.REFERENCE, typeNode); 701 }); 702 return expression; 703} 704 705function handleLeftHandSideExpression( 706 node: ts.LeftHandSideExpression, 707 mockBuffer: MockBuffer, 708 members: Members, 709 parent: KeyValue, 710 type: KeyValueTypes, 711 operateElements: KeyValue[] 712): KeyValue { 713 switch (node.kind) { 714 case SyntaxKind.Identifier: { 715 const keyValue = handleIdentifier(node as ts.Identifier, members, parent, KeyValueTypes.REFERENCE); 716 operateElements.push(keyValue); 717 return keyValue; 718 } 719 case SyntaxKind.PropertyAccessExpression: { 720 return handlePropertyAccessExpression(node as ts.PropertyAccessExpression, mockBuffer, members, parent, type, operateElements); 721 } 722 default: { 723 throw new Error('未知的LeftHandSideExpression类型'); 724 } 725 } 726} 727 728function isComponentNode(node: ts.ClassDeclaration, mockBuffer: MockBuffer): boolean { 729 if (!mockBuffer.rawFilePath.endsWith(D_ETS)) { 730 return false; 731 } 732 if (!node.decorators) { 733 return false; 734 } 735 return !!node.decorators.find(decorator => { 736 return COMPONENT_DECORATORS.includes( 737 handleExpression(decorator.expression, mockBuffer, {}, {} as KeyValue, KeyValueTypes.REFERENCE, []).key 738 ); 739 }); 740} 741 742function handleImportClauseNode( 743 node: ts.ImportClause, 744 members: Members, 745 parent: KeyValue, 746 type: KeyValueTypes, 747 importFilePath: string 748): void { 749 const namedImportBindings = node.namedBindings; 750 if (namedImportBindings) { 751 handleNamedBindings(namedImportBindings, members, parent, type, importFilePath); 752 } 753 754 if (node.name) { 755 const defaultExportName = handleIdentifier(node.name, members, parent, KeyValueTypes.IMPORT); 756 defaultExportName.isImportDefault = true; 757 defaultExportName.importedModulePath = importFilePath; 758 } 759} 760 761function handlePropertyNameNode( 762 node: ts.PropertyName, 763 mockBuffer: MockBuffer, 764 members: Members, 765 parent: KeyValue, 766 type: KeyValueTypes 767): KeyValue { 768 if (!node) { 769 members[''] = generateKeyValue('', type, parent); 770 return members['']; 771 } 772 switch (node.kind) { 773 case SyntaxKind.Identifier: { 774 return handleIdentifier(node, members, parent, type); 775 } 776 case SyntaxKind.ComputedPropertyName: { 777 return handleComputedPropertyName(node, mockBuffer, members, parent, type); 778 } 779 default: { 780 throw new Error('位置的PropertyNameNode类型'); 781 } 782 } 783} 784 785function handleComputedPropertyName( 786 node: ts.ComputedPropertyName, 787 mockBuffer: MockBuffer, 788 members: Members, 789 parent: KeyValue, 790 type: KeyValueTypes 791): KeyValue { 792 const expression = generateKeyValue('expression', KeyValueTypes.EXPRESSION, parent); 793 expression.operateElements = []; 794 let randomName = `expression_${Math.random()}`; 795 while (members[randomName]) { 796 randomName = `expression_${Math.random()}`; 797 } 798 members[randomName] = expression; 799 800 handleExpression(node.expression, mockBuffer, {}, expression, type, expression.operateElements); 801 return expression; 802} 803 804function handleNamedBindings( 805 node: ts.NamedImportBindings, 806 members: Members, 807 parent: KeyValue, 808 type: KeyValueTypes, 809 importFilePath: string 810): void { 811 switch (node.kind) { 812 case SyntaxKind.NamespaceImport: { 813 handleNamespaceImport(node, members, parent, type, importFilePath); 814 break; 815 } 816 case SyntaxKind.NamedImports: { 817 node.elements.forEach(element => { 818 handleNamedImports(element, members, parent, type, importFilePath); 819 }); 820 break; 821 } 822 } 823} 824 825function handleNamespaceImport( 826 node: ts.NamespaceImport, 827 members: Members, 828 parent: KeyValue, 829 type: KeyValueTypes, 830 importFilePath: string 831): KeyValue { 832 const namespaceName = handleIdentifier(node.name, members, parent, type); 833 namespaceName.isNamespaceImport = true; 834 namespaceName.importedModulePath = importFilePath; 835 return namespaceName; 836} 837 838function handleNamedImports( 839 node: ts.ImportSpecifier, 840 members: Members, 841 parent: KeyValue, 842 type: KeyValueTypes, 843 importFilePath: string 844): KeyValue { 845 const name = handleIdentifier(node.name, members, parent, type); 846 if (node.propertyName) { 847 name.rawName = handleIdentifier(node.propertyName, {}, parent, type).key; 848 } 849 850 name.importedModulePath = importFilePath; 851 return name; 852} 853 854function handleDefaultOrExport( 855 mockBuffer: MockBuffer, 856 keyValue: KeyValue, 857 modifiers?: ts.ModifiersArray 858): void { 859 if (!modifiers) { 860 return; 861 } 862 if (modifiers.findIndex(modifier => modifier.kind === SyntaxKind.DefaultKeyword) >= 0) { 863 mockBuffer.contents.members.default = keyValue; 864 keyValue.isDefault = true; 865 } 866 867 if (modifiers.findIndex(modifier => modifier.kind === SyntaxKind.DeclareKeyword) >= 0) { 868 if (!DECLARES[keyValue.key]) { 869 DECLARES[keyValue.key] = { keyValue, from: mockBuffer.mockedFilePath }; 870 } else { 871 DECLARES[keyValue.key].keyValue.sameDeclares.push({keyValue, from: mockBuffer.mockedFilePath}); 872 } 873 keyValue.isGlobalDeclare = true; 874 } 875} 876 877function handleModuleName( 878 node: ts.ModuleName, 879 members: Members, 880 parent: KeyValue, 881 type: KeyValueTypes 882): KeyValue { 883 switch (node.kind) { 884 case SyntaxKind.Identifier: { 885 return handleIdentifier(node, members, parent, type); 886 } 887 case SyntaxKind.StringLiteral: { 888 members[''] = generateKeyValue('', type, parent); 889 return members['']; 890 } 891 default: { 892 throw new Error('未知的ModuleName类型'); 893 } 894 } 895} 896 897function handleModuleBody( 898 sourceFile: ts.SourceFile, 899 mockBuffer: MockBuffer, 900 members: Members, 901 parent: KeyValue, 902 node?: ts.ModuleBody | ts.JSDocNamespaceDeclaration 903): void { 904 switch (node.kind) { 905 case SyntaxKind.ModuleBlock: { 906 node.statements.forEach(statement => { 907 if (!isArktsOne(statement, sourceFile)) { 908 return; 909 } 910 handleStatement(sourceFile, statement, mockBuffer, members, parent); 911 }); 912 return; 913 } 914 default: { 915 throw new Error('未知的ModuleBody类型'); 916 } 917 } 918} 919 920function handleStatement( 921 sourceFile: ts.SourceFile, 922 node: ts.Statement, 923 mockBuffer: MockBuffer, 924 members: Members, 925 parent: KeyValue 926): void { 927 switch (node.kind) { 928 case SyntaxKind.EnumDeclaration: { 929 handleEnumDeclaration(sourceFile, node as ts.EnumDeclaration, mockBuffer, members, parent, KeyValueTypes.ENUM); 930 break; 931 } 932 case SyntaxKind.InterfaceDeclaration: { 933 handleInterfaceDeclaration(sourceFile, node as ts.InterfaceDeclaration, mockBuffer, members, parent, KeyValueTypes.INTERFACE); 934 break; 935 } 936 case SyntaxKind.VariableStatement: { 937 handleVariableStatement(node as ts.VariableStatement, mockBuffer, members, parent, KeyValueTypes.VARIABLE); 938 break; 939 } 940 case SyntaxKind.FunctionDeclaration: { 941 handleFunctionDeclaration(node as ts.FunctionDeclaration, mockBuffer, members, parent, KeyValueTypes.FUNCTION); 942 break; 943 } 944 case SyntaxKind.ClassDeclaration: { 945 handleClassDeclaration(sourceFile, node as ts.ClassDeclaration, mockBuffer, members, parent, KeyValueTypes.CLASS); 946 break; 947 } 948 case SyntaxKind.TypeAliasDeclaration: { 949 handleTypeAliasDeclaration(node as ts.TypeAliasDeclaration, mockBuffer, members, parent, KeyValueTypes.VARIABLE); 950 break; 951 } 952 case SyntaxKind.ExportDeclaration: { 953 handleExportDeclaration(node as ts.ExportDeclaration, mockBuffer, members, parent, KeyValueTypes.IMPORT); 954 break; 955 } 956 case SyntaxKind.ModuleDeclaration: { 957 handleModuleDeclaration(sourceFile, node as ts.ModuleDeclaration, mockBuffer, members, parent, KeyValueTypes.MODULE); 958 break; 959 } 960 case SyntaxKind.ImportEqualsDeclaration: { 961 handleImportEqualsDeclaration(node as ts.ImportEqualsDeclaration, mockBuffer, members, parent, KeyValueTypes.VARIABLE); 962 break; 963 } 964 case SyntaxKind.EmptyStatement: 965 case SyntaxKind.Block: 966 case SyntaxKind.SemicolonClassElement: 967 case SyntaxKind.ExpressionStatement: 968 case SyntaxKind.IndexSignature: 969 case SyntaxKind.Constructor: { 970 break; 971 } 972 default: { 973 throw new Error('未知的Statement类型'); 974 } 975 } 976} 977 978function handleImportEqualsDeclaration( 979 node: ts.ImportEqualsDeclaration, 980 mockBuffer: MockBuffer, 981 members: Members, 982 parent: KeyValue, 983 type: KeyValueTypes 984): KeyValue { 985 const name = handleIdentifier(node.name, members, parent, type); 986 handleModuleReference(node.moduleReference, mockBuffer, name.members, name, type); 987 return name; 988} 989 990function handleModuleReference( 991 node: ts.ModuleReference, 992 mockBuffer: MockBuffer, 993 members: Members, 994 parent: KeyValue, 995 type: KeyValueTypes 996): KeyValue { 997 switch (node.kind) { 998 case SyntaxKind.QualifiedName: { 999 return handleQualifiedName(node as ts.QualifiedName, mockBuffer, members, parent, type); 1000 } 1001 default: { 1002 throw new Error('未知的ModuleReference类型'); 1003 } 1004 } 1005} 1006 1007function handleGetAccessorDeclaration( 1008 node: ts.GetAccessorDeclaration, 1009 mockBuffer: MockBuffer, 1010 members: Members, 1011 parent: KeyValue, 1012 type: KeyValueTypes 1013): KeyValue { 1014 const methodName = handlePropertyNameNode(node.name, mockBuffer, {}, parent, type); 1015 members[`get ${methodName.key}`] = methodName; 1016 handleAccessorDeclaration(node, mockBuffer, methodName); 1017 return methodName; 1018} 1019 1020function handleSetAccessorDeclaration( 1021 node: ts.SetAccessorDeclaration, 1022 mockBuffer: MockBuffer, 1023 members: Members, 1024 parent: KeyValue, 1025 type: KeyValueTypes 1026): KeyValue { 1027 const methodName = handlePropertyNameNode(node.name, mockBuffer, {}, parent, type); 1028 members[`set ${methodName.key}`] = methodName; 1029 handleAccessorDeclaration(node, mockBuffer, methodName); 1030 return methodName; 1031} 1032 1033function handleAccessorDeclaration( 1034 node: ts.GetAccessorDeclaration | ts.SetAccessorDeclaration, 1035 mockBuffer: MockBuffer, 1036 method: KeyValue 1037): KeyValue { 1038 for (let i = 0; i < node.parameters.length; i++) { 1039 handleParameterDeclaration(node.parameters[i], mockBuffer, method.methodParams, method, KeyValueTypes.REFERENCE); 1040 } 1041 handleTypeNode(mockBuffer, method.members, method, KeyValueTypes.REFERENCE, node.type); 1042 return method; 1043} 1044 1045function handleTypeParameterDeclaration( 1046 node: ts.TypeParameterDeclaration, 1047 mockBuffer: MockBuffer, 1048 members: Members, 1049 parent: KeyValue, 1050 type: KeyValueTypes 1051): KeyValue { 1052 const typeParameterName = handleIdentifier(node.name, members, parent, type); 1053 typeParameterName.value = '{name: "unknown type"}'; 1054 handleTypeNode(mockBuffer, typeParameterName.constraint, typeParameterName, KeyValueTypes.REFERENCE, node.constraint); 1055 return typeParameterName; 1056} 1057 1058function handleTypeNode( 1059 mockBuffer: MockBuffer, 1060 members: Members, 1061 parent: KeyValue, 1062 type: KeyValueTypes, 1063 node?: ts.TypeNode 1064): KeyValue { 1065 let typeText: string; 1066 if (!node) { 1067 const keyValue = generateKeyValue('\'any type\'', KeyValueTypes.VALUE, parent); 1068 members['\'any type\''] = keyValue; 1069 return keyValue; 1070 } 1071 switch (node.kind) { 1072 case SyntaxKind.NumberKeyword: { 1073 typeText = '0'; 1074 break; 1075 } 1076 case SyntaxKind.StringKeyword: { 1077 typeText = '\'\''; 1078 break; 1079 } 1080 case SyntaxKind.ArrayType: { 1081 typeText = '[]'; 1082 break; 1083 } 1084 case SyntaxKind.BooleanKeyword: { 1085 typeText = 'false'; 1086 break; 1087 } 1088 case SyntaxKind.TypeReference: { 1089 return handleTypeReferenceNode(node as ts.TypeReferenceNode, mockBuffer, members, parent, type); 1090 } 1091 case SyntaxKind.VoidKeyword: { 1092 const keyValue = generateKeyValue('\'undefined\'', KeyValueTypes.VALUE, parent); 1093 members[keyValue.key] = keyValue; 1094 keyValue.value = 'undefined'; 1095 return keyValue; 1096 } 1097 case SyntaxKind.UnionType: { 1098 return handleUnionTypeNode(node as ts.UnionTypeNode, mockBuffer, members, parent, type); 1099 } 1100 case SyntaxKind.LiteralType: { 1101 return handleLiteralTypeNode(node as ts.LiteralTypeNode, members, parent, KeyValueTypes.VALUE); 1102 } 1103 case SyntaxKind.TupleType: { 1104 return handleTupleTypeNode(node as ts.TupleTypeNode, members, mockBuffer, parent, type); 1105 } 1106 case SyntaxKind.FunctionType: { 1107 return handleFunctionTypeNode(node as ts.FunctionTypeNode, mockBuffer, members, parent, KeyValueTypes.FUNCTION); 1108 } 1109 case SyntaxKind.AnyKeyword: 1110 case SyntaxKind.ObjectKeyword: 1111 case SyntaxKind.TypeLiteral: 1112 case SyntaxKind.UnknownKeyword: { 1113 typeText = '{}'; 1114 break; 1115 } 1116 case SyntaxKind.BigIntKeyword: { 1117 typeText = '100000000000'; 1118 break; 1119 } 1120 case SyntaxKind.KeyOfKeyword: { 1121 typeText = 'keyof'; 1122 break; 1123 } 1124 default: { 1125 const keyValue = handleOthersTypeNode(mockBuffer, members, parent, type, node); 1126 if (keyValue) { 1127 return keyValue; 1128 } 1129 } 1130 } 1131 members[typeText] = generateKeyValue(typeText, KeyValueTypes.VALUE, parent); 1132 return members[typeText]; 1133} 1134 1135function handleOthersTypeNode( 1136 mockBuffer: MockBuffer, 1137 members: Members, 1138 parent: KeyValue, 1139 type: KeyValueTypes, 1140 node: ts.TypeNode 1141): KeyValue | undefined { 1142 switch (node.kind) { 1143 case SyntaxKind.MappedType: { 1144 return handleMappedTypeNode(node as ts.MappedTypeNode, mockBuffer, members, parent, type); 1145 } 1146 case SyntaxKind.TypeOperator: { 1147 return handleTypeOperatorNode(node as ts.TypeOperatorNode, mockBuffer, members, parent, type); 1148 } 1149 case SyntaxKind.IndexedAccessType: { 1150 return handleIndexedAccessTypeNode(node as ts.IndexedAccessTypeNode, mockBuffer, members, parent, type); 1151 } 1152 case SyntaxKind.ImportType: { 1153 return handleImportTypeNode(node as ts.ImportTypeNode, mockBuffer, members, parent, type); 1154 } 1155 case SyntaxKind.ParenthesizedType: { 1156 return handleParenthesizedTypeNode(node as ts.ParenthesizedTypeNode, mockBuffer, members, parent, type); 1157 } 1158 case SyntaxKind.TemplateLiteralType: { 1159 return handleTemplateLiteralTypeNode(node as ts.TemplateLiteralTypeNode, mockBuffer, members, parent, type); 1160 } 1161 case SyntaxKind.UndefinedKeyword: { 1162 return handleUndefinedKeywordNode(members, parent); 1163 } 1164 case SyntaxKind.IntersectionType: { 1165 return handleIntersectionTypeNode(node as ts.IntersectionTypeNode, mockBuffer, members, parent, KeyValueTypes.INTERSECTION); 1166 } 1167 case SyntaxKind.TypeQuery: { 1168 return handleTypeQueryNode(node as ts.TypeQueryNode, mockBuffer, members, parent, type); 1169 } 1170 case SyntaxKind.EmptyStatement: 1171 case SyntaxKind.Block: 1172 case SyntaxKind.SemicolonClassElement: 1173 case SyntaxKind.ExpressionStatement: { 1174 return undefined; 1175 } 1176 default: { 1177 throw new Error('未知的TypeNode类型'); 1178 } 1179 } 1180} 1181 1182function handleTypeQueryNode( 1183 node: ts.TypeQueryNode, 1184 mockBuffer: MockBuffer, 1185 members: Members, 1186 parent: KeyValue, 1187 type: KeyValueTypes 1188): KeyValue { 1189 return handleEntityName(node.exprName, mockBuffer, members, parent, type); 1190} 1191 1192function handleEntityName( 1193 node: ts.EntityName, 1194 mockBuffer: MockBuffer, 1195 members: Members, 1196 parent: KeyValue, 1197 type: KeyValueTypes 1198): KeyValue { 1199 if (!node) { 1200 return generateKeyValue('', KeyValueTypes.VALUE, parent); 1201 } 1202 switch (node.kind) { 1203 case SyntaxKind.Identifier: { 1204 return handleIdentifier(node, members, parent, KeyValueTypes.REFERENCE); 1205 } 1206 case SyntaxKind.QualifiedName: { 1207 return handleQualifiedName(node as ts.QualifiedName, mockBuffer, members, parent, type); 1208 } 1209 default: { 1210 throw new Error('未知的EntityName类型'); 1211 } 1212 } 1213} 1214 1215function handleQualifiedName( 1216 node: ts.QualifiedName, 1217 mockBuffer: MockBuffer, 1218 members: Members, 1219 parent: KeyValue, 1220 type: KeyValueTypes 1221): KeyValue { 1222 const left = handleEntityName(node.left, mockBuffer, members, parent, type); 1223 const right = node.right.escapedText.toString(); 1224 left.property = generateKeyValue(right, KeyValueTypes.REFERENCE, left); 1225 return left; 1226} 1227 1228function handlePropertyDeclaration( 1229 node: ts.PropertyDeclaration, 1230 mockBuffer: MockBuffer, 1231 members: Members, 1232 parent: KeyValue, 1233 type: KeyValueTypes 1234): void { 1235 if (node.questionToken) { 1236 return; 1237 } 1238 const propertyName = handlePropertyNameNode(node.name, mockBuffer, members, parent, type); 1239 propertyName.isStatic = node.modifiers?.some(modify => modify.kind === SyntaxKind.StaticKeyword); 1240 if (node.initializer) { 1241 const expressionKeyValue = generateKeyValue('expression', KeyValueTypes.EXPRESSION, propertyName); 1242 propertyName.members.expression = expressionKeyValue; 1243 expressionKeyValue.operateElements = []; 1244 handleExpression(node.initializer, mockBuffer, {}, expressionKeyValue, KeyValueTypes.VALUE, expressionKeyValue.operateElements); 1245 return; 1246 } 1247 handleTypeNode(mockBuffer, propertyName.members, propertyName, KeyValueTypes.REFERENCE, node.type); 1248} 1249 1250function handleIntersectionTypeNode( 1251 node: ts.IntersectionTypeNode, 1252 mockBuffer: MockBuffer, 1253 members: Members, 1254 parent: KeyValue, 1255 type: KeyValueTypes 1256): KeyValue { 1257 const intersectKeyValue = generateKeyValue('Object.assign', type, parent); 1258 members[intersectKeyValue.key] = intersectKeyValue; 1259 node.types.forEach(typeNode => handleTypeNode(mockBuffer, intersectKeyValue.methodParams, intersectKeyValue, KeyValueTypes.REFERENCE, typeNode)); 1260 return intersectKeyValue; 1261} 1262 1263function handleUndefinedKeywordNode( 1264 members: Members, 1265 parent: KeyValue 1266): KeyValue { 1267 members.undefined = generateKeyValue('undefined', KeyValueTypes.VALUE, parent); 1268 return members.undefined; 1269} 1270 1271function handleTemplateLiteralTypeNode( 1272 node: ts.TemplateLiteralTypeNode, 1273 mockBuffer: MockBuffer, 1274 members: Members, 1275 parent: KeyValue, 1276 type: KeyValueTypes 1277): KeyValue { 1278 const expression = generateKeyValue('expression', KeyValueTypes.EXPRESSION, parent); 1279 members[expression.key] = expression; 1280 expression.operateElements = []; 1281 1282 handleTemplateHead(node.head, expression.operateElements, expression, type); 1283 1284 node.templateSpans.forEach(templateSpan => handleTemplateLiteralTypeSpan(templateSpan, expression.operateElements, expression, mockBuffer)); 1285 return expression; 1286} 1287 1288function handleTemplateLiteralTypeSpan( 1289 node: ts.TemplateLiteralTypeSpan, 1290 operateElements: KeyValue[], 1291 parent: KeyValue, 1292 mockBuffer: MockBuffer 1293): void { 1294 const addKeyValue = generateKeyValue('+', KeyValueTypes.VALUE, parent); 1295 addKeyValue.value = '+'; 1296 1297 operateElements.push(addKeyValue); 1298 operateElements.push(handleTypeNode(mockBuffer, {}, parent, KeyValueTypes.REFERENCE, node.type)); 1299 operateElements.push(addKeyValue); 1300 1301 switch (node.literal.kind) { 1302 case SyntaxKind.TemplateTail: { 1303 return handleTemplateTail(node.literal, operateElements, parent, KeyValueTypes.VALUE); 1304 } 1305 case SyntaxKind.TemplateMiddle: { 1306 return handleTemplateMiddle(node.literal, operateElements, parent, KeyValueTypes.VALUE); 1307 } 1308 default: { 1309 throw new Error('未知的templateSpan类型'); 1310 } 1311 } 1312} 1313 1314function handleTemplateTail( 1315 node: ts.TemplateTail, 1316 operateElements: KeyValue[], 1317 parent: KeyValue, 1318 type: KeyValueTypes 1319): void { 1320 const keyValue = generateKeyValue(node.text, type, parent); 1321 keyValue.value = `'${node.text}'`; 1322 operateElements.push(keyValue); 1323} 1324 1325function handleTemplateMiddle( 1326 node: ts.TemplateMiddle, 1327 operateElements: KeyValue[], 1328 parent: KeyValue, 1329 type: KeyValueTypes 1330): void { 1331 const keyValue = generateKeyValue(node.text, type, parent); 1332 keyValue.value = `'${node.text}'`; 1333 operateElements.push(keyValue); 1334} 1335 1336function handleTemplateHead( 1337 node: ts.TemplateHead, 1338 operateElements: KeyValue[], 1339 parent: KeyValue, 1340 type: KeyValueTypes 1341): void { 1342 const keyValue = generateKeyValue(node.text, type, parent); 1343 keyValue.value = `'${node.text}'`; 1344 operateElements.push(keyValue); 1345} 1346 1347function handleParenthesizedTypeNode( 1348 node: ts.ParenthesizedTypeNode, 1349 mockBuffer: MockBuffer, 1350 members: Members, 1351 parent: KeyValue, 1352 type: KeyValueTypes 1353): KeyValue { 1354 return handleTypeNode(mockBuffer, members, parent, type, node.type as ts.TypeNode); 1355} 1356 1357function handleImportTypeNode( 1358 node: ts.ImportTypeNode, 1359 mockBuffer: MockBuffer, 1360 members: Members, 1361 parent: KeyValue, 1362 type: KeyValueTypes 1363): KeyValue { 1364 const argument = handleTypeNode(mockBuffer, {}, parent, type, node.argument); 1365 argument.type = KeyValueTypes.IMPORT; 1366 1367 const typeArguments = {} as Members; 1368 node.typeArguments?.forEach(typeArgument => handleTypeNode(mockBuffer, typeArguments, parent, KeyValueTypes.REFERENCE, typeArgument)); 1369 const specifier = argument.key; 1370 const defaultName = `imported_by_${path.basename(specifier).replace(/\./g, '_').replace(/[@'"]/g, '')}`; 1371 const importFilePath = getAbsolutePath(mockBuffer, specifier.replace(/['"]/g, '')); 1372 1373 if (!importFilePath) { 1374 throw new Error(`不能到达文件 ${importFilePath}`); 1375 } 1376 const qualifier = handleEntityName(node.qualifier, mockBuffer, {}, parent, type); 1377 associateTypeParameters(qualifier, typeArguments); 1378 1379 const moduleSpecifier = generateKeyValue(defaultName, KeyValueTypes.IMPORT, mockBuffer.contents); 1380 moduleSpecifier.importedModulePath = importFilePath; 1381 mockBuffer.contents.members[defaultName] = moduleSpecifier; 1382 if (qualifier.key === 'default') { 1383 moduleSpecifier.isImportDefault = true; 1384 qualifier.key = defaultName; 1385 members[defaultName] = qualifier; 1386 return qualifier; 1387 } else { 1388 moduleSpecifier.isNamespaceImport = true; 1389 const namespace = generateKeyValue(defaultName, KeyValueTypes.REFERENCE, parent); 1390 namespace.property = qualifier; 1391 qualifier.parent = namespace; 1392 members[defaultName] = namespace; 1393 return namespace; 1394 } 1395} 1396 1397function handleIndexedAccessTypeNode( 1398 node: ts.IndexedAccessTypeNode, 1399 mockBuffer: MockBuffer, 1400 members: Members, 1401 parent: KeyValue, 1402 type: KeyValueTypes 1403): KeyValue { 1404 return handleTypeNode(mockBuffer, members, parent, type, node.objectType); 1405} 1406 1407function handleTypeOperatorNode( 1408 node: ts.TypeOperatorNode, 1409 mockBuffer: MockBuffer, 1410 members: Members, 1411 parent: KeyValue, 1412 type: KeyValueTypes 1413): KeyValue { 1414 return handleTypeNode(mockBuffer, members, parent, type, node.type); 1415} 1416 1417function handleMappedTypeNode( 1418 node: ts.MappedTypeNode, 1419 mockBuffer: MockBuffer, 1420 members: Members, 1421 parent: KeyValue, 1422 type: KeyValueTypes 1423): KeyValue { 1424 return handleTypeNode(mockBuffer, members, parent, type, node.type); 1425} 1426 1427function handleFunctionTypeNode( 1428 node: ts.FunctionTypeNode, 1429 mockBuffer: MockBuffer, 1430 members: Members, 1431 parent: KeyValue, 1432 type: KeyValueTypes 1433): KeyValue { 1434 let functionName: KeyValue; 1435 if (node.name) { 1436 functionName = handlePropertyNameNode(node.name, mockBuffer, members, parent, type); 1437 } else { 1438 functionName = parent; 1439 parent.type = KeyValueTypes.FUNCTION; 1440 } 1441 functionName.isArrowFunction = new Set<KeyValueTypes>([ 1442 KeyValueTypes.INTERSECTION, 1443 KeyValueTypes.VARIABLE, 1444 KeyValueTypes.PROPERTY, 1445 KeyValueTypes.FUNCTION 1446 ]).has(parent.type); 1447 for (let i = 0; i < node.parameters.length; i++) { 1448 handleParameterDeclaration(node.parameters[i], mockBuffer, functionName.methodParams, functionName, KeyValueTypes.REFERENCE); 1449 } 1450 handleTypeNode(mockBuffer, functionName.members, functionName, KeyValueTypes.REFERENCE, node.type); 1451 return functionName; 1452} 1453 1454function handleTupleTypeNode( 1455 node: ts.TupleTypeNode, 1456 members: Members, 1457 mockBuffer: MockBuffer, 1458 parent: KeyValue, 1459 type: KeyValueTypes 1460): KeyValue { 1461 const keyValue = generateKeyValue('Array', KeyValueTypes.REFERENCE, parent); 1462 members.Array = keyValue; 1463 let index: number = 0; 1464 node.elements.forEach(element => { 1465 let elementKeyValue: KeyValue; 1466 switch (element.kind) { 1467 case SyntaxKind.NumberKeyword: { 1468 elementKeyValue = generateKeyValue('0', KeyValueTypes.VALUE, keyValue); 1469 break; 1470 } 1471 case SyntaxKind.StringKeyword: { 1472 elementKeyValue = generateKeyValue('\'\'', KeyValueTypes.VALUE, keyValue); 1473 break; 1474 } 1475 case SyntaxKind.NamedTupleMember: { 1476 elementKeyValue = handleNamedTupleMember(element as ts.NamedTupleMember, mockBuffer, {}, keyValue, type); 1477 break; 1478 } 1479 case SyntaxKind.ParenthesizedType: { 1480 elementKeyValue = handleParenthesizedTypeNode(element as ts.ParenthesizedTypeNode, mockBuffer, {}, keyValue, type); 1481 break; 1482 } 1483 case SyntaxKind.TypeReference: { 1484 elementKeyValue = handleTypeReferenceNode(element as ts.TypeReferenceNode, mockBuffer, {}, keyValue, type); 1485 break; 1486 } 1487 case SyntaxKind.OptionalType: { 1488 elementKeyValue = handleOptionTypeNode(element as ts.OptionalTypeNode, mockBuffer, {}, keyValue, type); 1489 break; 1490 } 1491 default: { 1492 throw new Error('未知的TupleType类型'); 1493 } 1494 } 1495 keyValue.methodParams[index++] = elementKeyValue; 1496 }); 1497 return keyValue; 1498} 1499 1500function handleOptionTypeNode( 1501 node: ts.OptionalTypeNode, 1502 mockBuffer: MockBuffer, 1503 members: Members, 1504 parent: KeyValue, 1505 type: KeyValueTypes 1506): KeyValue { 1507 return handleTypeNode(mockBuffer, members, parent, type, node.type); 1508} 1509 1510function handleNamedTupleMember( 1511 node: ts.NamedTupleMember, 1512 mockBuffer: MockBuffer, 1513 members: Members, 1514 parent: KeyValue, 1515 type: KeyValueTypes 1516): KeyValue { 1517 return handleTypeNode(mockBuffer, members, parent, type, node.type); 1518} 1519 1520function handleUnionTypeNode( 1521 node: ts.UnionTypeNode, 1522 mockBuffer: MockBuffer, 1523 members: Members, 1524 parent: KeyValue, 1525 type: KeyValueTypes 1526): KeyValue { 1527 if (!node.types.length) { 1528 const undefinedKeyValue = generateKeyValue('undefined', KeyValueTypes.VALUE, parent); 1529 undefinedKeyValue.value = 'undefined'; 1530 return undefinedKeyValue; 1531 } 1532 const typeIndex = node.types.findIndex(typeNode => { 1533 return BASE_KINDS.includes(typeNode.kind); 1534 }); 1535 1536 return handleTypeNode(mockBuffer, members, parent, type, node.types[Math.max(typeIndex, 0)]); 1537} 1538 1539function handleLiteralTypeNode( 1540 node: ts.LiteralTypeNode, 1541 members: Members, 1542 parent: KeyValue, 1543 type: KeyValueTypes 1544): KeyValue { 1545 switch (node.literal.kind) { 1546 case SyntaxKind.StringLiteral: { 1547 return handleStringLiteral(node.literal as ts.StringLiteral, members, parent); 1548 } 1549 case SyntaxKind.TrueKeyword: { 1550 return handleTrueKeyword(members, parent); 1551 } 1552 case SyntaxKind.FalseKeyword: { 1553 return handleFalseKeyword(members, parent); 1554 } 1555 case SyntaxKind.PrefixUnaryExpression: { 1556 return handlePrefixUnaryExpression(node.literal as ts.PrefixUnaryExpression, members, parent); 1557 } 1558 case SyntaxKind.NumericLiteral: { 1559 return handleNumericLiteral(node.literal as ts.NumericLiteral, members, parent); 1560 } 1561 case SyntaxKind.NullKeyword: { 1562 return handleNullLiteral(members, parent, type); 1563 } 1564 case SyntaxKind.BigIntLiteral: { 1565 return handleBigIntLiteral(node.literal as ts.BigIntLiteral, members, parent, type); 1566 } 1567 default: { 1568 throw new Error('未知的literal类型'); 1569 } 1570 } 1571} 1572 1573function handleBigIntLiteral( 1574 node: ts.BigIntLiteral, 1575 members: Members, 1576 parent: KeyValue, 1577 type: KeyValueTypes 1578): KeyValue { 1579 const literal = node.text.replace('n', ''); 1580 members[literal] = generateKeyValue(literal, type, parent); 1581 return members[literal]; 1582} 1583 1584function handleNullLiteral( 1585 members: Members, 1586 parent: KeyValue, 1587 type: KeyValueTypes 1588): KeyValue { 1589 members.null = generateKeyValue('null', type, parent); 1590 return members.null; 1591} 1592 1593function handlePrefixUnaryExpression( 1594 node: ts.PrefixUnaryExpression, 1595 members: Members, 1596 parent: KeyValue 1597): KeyValue { 1598 const expression = generateKeyValue('expression', KeyValueTypes.EXPRESSION, parent); 1599 members.expression = expression; 1600 expression.operateElements = []; 1601 1602 const operator = handlePrefixUnaryOperator(node.operator, {}, expression, KeyValueTypes.VALUE); 1603 expression.operateElements.push(operator); 1604 expression.operateElements.push(handleUnaryExpression(node.operand, {}, operator)); 1605 return expression; 1606} 1607 1608function handlePrefixUnaryOperator( 1609 node: ts.PrefixUnaryOperator, 1610 members: Members, 1611 parent: KeyValue, 1612 type: KeyValueTypes 1613): KeyValue { 1614 let operator: string; 1615 switch (node) { 1616 case SyntaxKind.MinusToken: 1617 operator = '-'; 1618 break; 1619 default: { 1620 throw new Error('未知类型的PrefixUnaryOperator'); 1621 } 1622 } 1623 members[operator] = generateKeyValue(operator, type, parent); 1624 return members[operator]; 1625} 1626 1627function handleUnaryExpression( 1628 node: ts.UnaryExpression, 1629 members: Members, 1630 parent: KeyValue 1631): KeyValue { 1632 switch (node.kind) { 1633 case SyntaxKind.NumericLiteral: { 1634 return handleNumericLiteral(node as ts.NumericLiteral, members, parent); 1635 } 1636 case SyntaxKind.BigIntLiteral: { 1637 return handleBigIntLiteral(node as ts.BigIntLiteral, members, parent, KeyValueTypes.VALUE); 1638 } 1639 default: { 1640 throw new Error('位置类型的UnaryExpression'); 1641 } 1642 } 1643} 1644 1645function handleTypeReferenceNode( 1646 node: ts.TypeReferenceNode, 1647 mockBuffer: MockBuffer, 1648 members: Members, 1649 parent: KeyValue, 1650 type: KeyValueTypes 1651): KeyValue { 1652 const typeName = handleEntityName(node.typeName, mockBuffer, members, parent, type); 1653 if (specialTSTypes.includes(typeName.key)) { 1654 return typeName; 1655 } 1656 node.typeArguments?.forEach( 1657 typeArgument => handleTypeNode(mockBuffer, typeName.typeParameters, typeName, KeyValueTypes.REFERENCE, typeArgument) 1658 ); 1659 return typeName; 1660} 1661 1662function handleExpression( 1663 node: ts.Expression, 1664 mockBuffer: MockBuffer, 1665 members: Members, 1666 parent: KeyValue, 1667 type: KeyValueTypes, 1668 operateElements: KeyValue[] 1669): KeyValue { 1670 if (!node) { 1671 members[''] = generateKeyValue('', KeyValueTypes.VALUE, parent); 1672 return members['']; 1673 } 1674 let keyValue: KeyValue; 1675 switch (node.kind) { 1676 case SyntaxKind.Identifier: { 1677 keyValue = handleIdentifier(node as ts.Identifier, members, parent, KeyValueTypes.REFERENCE); 1678 operateElements.push(keyValue); 1679 break; 1680 } 1681 case SyntaxKind.NumericLiteral: { 1682 keyValue = handleNumericLiteral(node as ts.NumericLiteral, members, parent); 1683 operateElements.push(keyValue); 1684 break; 1685 } 1686 case SyntaxKind.BigIntLiteral: { 1687 keyValue = handleBigIntLiteral(node as ts.BigIntLiteral, members, parent, KeyValueTypes.VALUE); 1688 operateElements.push(keyValue); 1689 break; 1690 } 1691 case SyntaxKind.PropertyAccessExpression: { 1692 keyValue = handlePropertyAccessExpression(node as ts.PropertyAccessExpression, mockBuffer, members, parent, type, operateElements); 1693 break; 1694 } 1695 case SyntaxKind.StringLiteral: { 1696 keyValue = handleStringLiteral(node as ts.StringLiteral, members, parent); 1697 operateElements.push(keyValue); 1698 break; 1699 } 1700 case SyntaxKind.ParenthesizedExpression: { 1701 keyValue = handleParenthesizedExpression(node as ts.ParenthesizedExpression, mockBuffer, members, parent, type, operateElements); 1702 break; 1703 } 1704 case SyntaxKind.BinaryExpression: { 1705 keyValue = handleBinaryExpression(node as ts.BinaryExpression, mockBuffer, members, parent); 1706 operateElements.push(keyValue); 1707 break; 1708 } 1709 case SyntaxKind.TrueKeyword: { 1710 keyValue = handleTrueKeyword(members, parent); 1711 operateElements.push(keyValue); 1712 break; 1713 } 1714 case SyntaxKind.FalseKeyword: { 1715 keyValue = handleFalseKeyword(members, parent); 1716 operateElements.push(keyValue); 1717 break; 1718 } 1719 case SyntaxKind.EmptyStatement: 1720 case SyntaxKind.Block: 1721 case SyntaxKind.SemicolonClassElement: 1722 case SyntaxKind.ExpressionStatement: { 1723 break; 1724 } 1725 default: { 1726 throw new Error('未知类型的Expression'); 1727 } 1728 } 1729 return keyValue; 1730} 1731 1732function handleIdentifier( 1733 node: ts.Identifier | ts.PrivateIdentifier, 1734 members: Members, 1735 parent: KeyValue, 1736 type: KeyValueTypes = KeyValueTypes.VALUE 1737): KeyValue { 1738 const text = node?.escapedText.toString() ?? ''; 1739 const keyValue = generateKeyValue(text, type, parent); 1740 if (members[text] && members[text].sameName) { 1741 if (parent.key === 'fileIo' && text === 'OpenMode') { 1742 members[text] = keyValue; 1743 } else { 1744 members[text].sameName.push(keyValue); 1745 } 1746 return keyValue; 1747 } 1748 members[text] = keyValue; 1749 return keyValue; 1750} 1751 1752function handleNumericLiteral( 1753 node: ts.NumericLiteral, 1754 members: Members, 1755 parent: KeyValue 1756): KeyValue { 1757 const text = node.text; 1758 members[text] = generateKeyValue(text, KeyValueTypes.VALUE, parent); 1759 return members[text]; 1760} 1761 1762function handlePropertyAccessExpression( 1763 node: ts.PropertyAccessExpression, 1764 mockBuffer: MockBuffer, 1765 members: Members, 1766 parent: KeyValue, 1767 type: KeyValueTypes, 1768 operateElements: KeyValue[] 1769): KeyValue { 1770 const expression = handleExpression(node.expression, mockBuffer, members, parent, KeyValueTypes.REFERENCE, operateElements); 1771 1772 switch (node.name.kind) { 1773 case SyntaxKind.Identifier: { 1774 expression.property = handleIdentifier(node.name as ts.Identifier, {}, expression, type); 1775 break; 1776 } 1777 case SyntaxKind.PrivateIdentifier: { 1778 expression.property = handlePrivateIdentifier(node.name as ts.PrivateIdentifier, {}, expression, type); 1779 break; 1780 } 1781 default: { 1782 throw new Error('未知类型的PropertyAccessExpression'); 1783 } 1784 } 1785 return expression; 1786} 1787 1788function handlePrivateIdentifier( 1789 node: ts.PrivateIdentifier, 1790 members: Members, 1791 parent: KeyValue, 1792 type: KeyValueTypes 1793): KeyValue { 1794 return handleIdentifier(node, members, parent, type); 1795} 1796 1797function handleStringLiteral( 1798 node: ts.StringLiteral, 1799 members: Members, 1800 parent: KeyValue 1801): KeyValue { 1802 let text = node.text; 1803 if (ClosedSourceFileMapping[text]) { 1804 text = ClosedSourceFileMapping[text]; 1805 } 1806 members[text] = generateKeyValue(`'${text}'`, KeyValueTypes.VALUE, parent); 1807 return members[text]; 1808} 1809 1810function handleParenthesizedExpression( 1811 node: ts.ParenthesizedExpression, 1812 mockBuffer: MockBuffer, 1813 members: Members, 1814 parent: KeyValue, 1815 type: KeyValueTypes, 1816 operateElements: KeyValue[] 1817): KeyValue { 1818 operateElements.push(generateKeyValue('(', KeyValueTypes.VALUE, parent)); 1819 const expression = handleExpression(node.expression, mockBuffer, members, parent, type, operateElements); 1820 operateElements.push(generateKeyValue(')', KeyValueTypes.VALUE, parent)); 1821 return expression; 1822} 1823 1824function handleBinaryExpression( 1825 node: ts.BinaryExpression, 1826 mockBuffer: MockBuffer, 1827 members: Members, 1828 parent: KeyValue 1829): KeyValue { 1830 const expression = generateKeyValue('expression', KeyValueTypes.EXPRESSION, parent); 1831 members.expression = expression; 1832 expression.operateElements = []; 1833 1834 handleExpression(node.left, mockBuffer, {}, parent, KeyValueTypes.VALUE, expression.operateElements); 1835 handleBinaryOperatorToken(node.operatorToken, parent, KeyValueTypes.VALUE, expression.operateElements); 1836 handleExpression(node.right, mockBuffer, {}, parent, KeyValueTypes.VALUE, expression.operateElements); 1837 return expression; 1838} 1839 1840function handleBinaryOperatorToken( 1841 node: ts.BinaryOperatorToken, 1842 parent: KeyValue, 1843 type: KeyValueTypes, 1844 operateElements: KeyValue[] 1845): KeyValue { 1846 let operator: string; 1847 switch (node.kind) { 1848 case SyntaxKind.PlusToken: { 1849 operator = '+'; 1850 break; 1851 } 1852 case SyntaxKind.LessThanLessThanToken: { 1853 operator = '<<'; 1854 break; 1855 } 1856 case SyntaxKind.GreaterThanGreaterThanToken: { 1857 operator = '>>'; 1858 break; 1859 } 1860 case SyntaxKind.BarToken: { 1861 operator = '|'; 1862 break; 1863 } 1864 default: { 1865 throw new Error('位置类型的BinaryOperatorToken'); 1866 } 1867 } 1868 const keyValue = generateKeyValue(operator, type, parent); 1869 operateElements.push(keyValue); 1870 return keyValue; 1871} 1872 1873function handleTrueKeyword( 1874 members: Members, 1875 parent: KeyValue 1876): KeyValue { 1877 const keyValue = generateKeyValue('true', KeyValueTypes.VALUE, parent); 1878 members['\'true\''] = keyValue; 1879 return keyValue; 1880} 1881 1882function handleFalseKeyword( 1883 members: Members, 1884 parent: KeyValue 1885): KeyValue { 1886 const keyValue = generateKeyValue('false', KeyValueTypes.VALUE, parent); 1887 members['\'false\''] = keyValue; 1888 return keyValue; 1889} 1890