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