1/* 2 * Copyright (c) 2023 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 type { SourceFile } from 'typescript'; 17import { SyntaxKind } from 'typescript'; 18import { firstCharacterToUppercase, getClassNameSet } from '../common/commonUtils'; 19import type { ReturnTypeEntity } from '../common/commonUtils'; 20import { getImportDeclarationArray } from '../declaration-node/importAndExportDeclaration'; 21import type { ImportElementEntity } from '../declaration-node/importAndExportDeclaration'; 22import type { MethodEntity } from '../declaration-node/methodDeclaration'; 23import type { FunctionEntity } from '../declaration-node/functionDeclaration'; 24import type { MethodSignatureEntity } from '../declaration-node/methodSignatureDeclaration'; 25 26/** 27 * get warn console template 28 * @param interfaceNameOrClassName 29 * @param functionNameOrPropertyName 30 * @returns 31 */ 32export function getWarnConsole(interfaceNameOrClassName: string, functionNameOrPropertyName: string): string { 33 return `console.warn('The ${interfaceNameOrClassName}.${functionNameOrPropertyName} interface in the Previewer is a mocked implementation and may behave differently than on a real device.');\n`; 34} 35 36function handlePromiseParams(returnType: ReturnTypeEntity): string { 37 const returnKindName = returnType.returnKindName.slice(0, returnType.returnKindName.length - 1).slice(8).trim(); 38 let returnName = `return new Promise((resolve, reject) => { 39 resolve('[PC Preview] unknown type'); 40 })`; 41 Object.keys(paramsTypeStart).forEach(key => { 42 if (returnKindName.startsWith(key)) { 43 const data = paramsTypeStart[key] === '[PC Preview] unknown type' ? `'${paramsTypeStart[key]}'` : `${paramsTypeStart[key]}`; 44 returnName = `return new Promise((resolve, reject) => { 45 resolve(${data}); 46 })`; 47 } 48 }); 49 return returnName; 50} 51 52/** 53 * generate return statement; 54 * @param returnType 55 * @param sourceFile 56 * @returns 57 */ 58export function getReturnStatement(returnType: ReturnTypeEntity, sourceFile: SourceFile): string { 59 if (returnType.returnKind === SyntaxKind.TypeReference) { 60 if (returnType.returnKindName.startsWith('Promise')) { 61 return handlePromiseParams(returnType); 62 } else if (returnType.returnKindName === 'T') { 63 return 'return \'[PC Preview] unknown type\''; 64 } else if (returnType.returnKindName === 'object' || returnType.returnKindName === 'Object') { 65 return 'return {}'; 66 } else if (returnType.returnKindName === 'Function') { 67 return 'return \'[PC Preview] unknown type\''; 68 } else if (returnType.returnKindName === 'String' || returnType.returnKindName === 'string') { 69 return `return ${returnType.returnKindName}(...args)`; 70 } else if (returnType.returnKindName === 'number' || returnType.returnKindName === 'Number') { 71 return 'return 0'; 72 } else if (returnType.returnKindName === 'boolean' || returnType.returnKindName === 'Boolean') { 73 return 'return false'; 74 } else if (returnType.returnKindName === 'ArrayBuffer') { 75 return `return new ${returnType.returnKindName}(0)`; 76 } else if (returnType.returnKindName.startsWith('Array')) { 77 if (returnType.returnKindName.includes('<') && returnType.returnKindName.includes('>')) { 78 return `return [${generateGenericTypeToMockValue(returnType.returnKindName)}]`; 79 } else { 80 return `return new ${returnType.returnKindName}()`; 81 } 82 } else if (returnType.returnKindName.startsWith('Readonly')) { 83 return `return ${returnType.returnKindName.split('<')[1].split('>')[0]}`; 84 } else if (checkIsGenericSymbol(returnType.returnKindName)) { 85 return `return '[PC Preview] unknown iterableiterator_${returnType.returnKindName}'`; 86 } else if (returnType.returnKindName.startsWith('Uint8Array')) { 87 return `return new ${returnType.returnKindName}()`; 88 } else if (returnType.returnKindName.startsWith('IterableIterator')) { 89 if (returnType.returnKindName.includes(',')) { 90 return `let index = 0; 91 const IteratorEntriesMock = { 92 *[Symbol.iterator]() { 93 yield ['[PC Preview] unknown paramIterMock_K', '[PC Preview] unknown paramIterMock_V']; 94 }, 95 next: () => { 96 if (index < 1) { 97 const returnValue = ['[PC Previwe] unknown paramIterMock_K', '[PC Previwe] unknown paramIterMock_V']; 98 index++; 99 return { 100 value: returnValue, 101 done: false 102 }; 103 } else { 104 return { 105 done: true 106 }; 107 } 108 } 109 }; 110 return IteratorEntriesMock;`; 111 } else { 112 return `let index = 0; 113 const IteratorStringMock = { 114 *[Symbol.iterator]() { 115 yield '[PC Preview] unknown string'; 116 }, 117 next: () => { 118 if (index < 1) { 119 const returnValue = '[PC Previwe] unknown string'; 120 index++; 121 return { 122 value: returnValue, 123 done: false 124 }; 125 } else { 126 return { 127 done: true 128 }; 129 } 130 } 131 }; 132 return IteratorStringMock;`; 133 } 134 } else if (returnType.returnKindName.includes('<T>')) { 135 const tmpReturn = returnType.returnKindName.split('<')[0]; 136 if (tmpReturn.startsWith('Array')) { 137 return 'return []'; 138 } else { 139 `return new ${tmpReturn}()`; 140 } 141 } else if (returnType.returnKindName.includes('<')) { 142 return `return new ${returnType.returnKindName.split('<')[0]}()`; 143 } else { 144 if (getClassNameSet().has(returnType.returnKindName)) { 145 if (returnType.returnKindName === 'Want') { 146 return 'return mockWant().Want'; 147 } else { 148 return `return new ${returnType.returnKindName}()`; 149 } 150 } else if (propertyTypeWhiteList(returnType.returnKindName) === returnType.returnKindName) { 151 return `return ${getTheRealReferenceFromImport(sourceFile, returnType.returnKindName)}`; 152 } else { 153 return `return ${propertyTypeWhiteList(returnType.returnKindName)}`; 154 } 155 } 156 } else if (returnType.returnKind === SyntaxKind.UnionType) { 157 const returnNames = returnType.returnKindName.split('|'); 158 let returnName = returnNames[0]; 159 for (let i = 0; i < returnNames.length; i++) { 160 if (!returnNames[i].includes('[]') && !returnNames[i].includes('<')) { 161 returnName = returnNames[i]; 162 break; 163 } 164 } 165 if (returnName.trimStart().trimEnd() === 'void') { 166 return ''; 167 } 168 if (getClassNameSet().has(returnName)) { 169 return `return new ${returnName}()`; 170 } else { 171 return `return ${getBaseReturnValue(returnName.trimStart().trimEnd())}`; 172 } 173 } else { 174 let returnName = returnType.returnKindName.trim(); 175 let temp = true; 176 if (returnName.endsWith(']')) { 177 returnName = '[]'; 178 temp = false; 179 } else { 180 Object.keys(paramsTypeStart).forEach(key => { 181 if (returnType.returnKindName.startsWith(key)) { 182 returnName = paramsTypeStart[key]; 183 temp = false; 184 } 185 }); 186 } 187 if (temp) { 188 return 'return \'[PC Preview] unknown type\''; 189 } 190 return `return ${returnName};`; 191 } 192 return 'return \'[PC Preview] unknown type\''; 193} 194 195/** 196 * special property whitelist 197 * @param propertyTypeName 198 * @returns 199 */ 200export function propertyTypeWhiteList(propertyTypeName: string): boolean | number | string { 201 const whiteList = ['GLboolean', 'GLuint', 'GLenum', 'GLint', 'NotificationFlags']; 202 if (whiteList.includes(propertyTypeName)) { 203 if (propertyTypeName === 'NotificationFlags' || propertyTypeName === 'GLenum') { 204 return `'[PC Preview] unknown ${propertyTypeName}'`; 205 } else if (propertyTypeName === 'GLboolean') { 206 return true; 207 } else { 208 return 0; 209 } 210 } else { 211 return propertyTypeName; 212 } 213} 214 215/** 216 * get basic return value 217 * @param value 218 * @returns 219 */ 220export function getBaseReturnValue(value: string): string | number | boolean { 221 if (value === 'string') { 222 return '\'\''; 223 } else if (value === 'number') { 224 return 0; 225 } else if (value === 'boolean') { 226 return true; 227 } else if (value === 'Object' || value === 'object') { 228 return '{}'; 229 } else if (checkIsGenericSymbol(value)) { 230 return '\'[PC Preview] unknown type\''; 231 } else if (value === 'WebGLActiveInfo') { 232 return '{size: \'[PC Preview] unknown GLint\', type: 0, name: \'[PC Preview] unknown name\'}'; 233 } else { 234 return value; 235 } 236} 237 238/** 239 * get current sourceFile import data 240 * @param sourceFile 241 * @param typeName 242 * @returns 243 */ 244export function getTheRealReferenceFromImport(sourceFile: SourceFile, typeName: string): string { 245 const importArray = getImportDeclarationArray(sourceFile); 246 let returnName = ''; 247 let isFromImport = false; 248 let isOhos = false; 249 let mockMockName = ''; 250 importArray.forEach(value => { 251 if (typeName.includes('.') && typeName.split('.')[0] === value.importElements) { 252 isFromImport = true; 253 if (value.importPath.includes('@ohos')) { 254 isOhos = true; 255 } 256 if (value.importElements.trimStart().trimEnd() === typeName.split('.')[0]) { 257 const tmpArr = value.importPath.split('.'); 258 mockMockName = tmpArr[tmpArr.length - 1].replace(/'/g, '').replace(/"/g, ''); 259 } 260 } 261 }); 262 if (isFromImport) { 263 const splitReturnKindName = typeName.split('.'); 264 let left = ''; 265 for (let i = 1; i < splitReturnKindName.length; i++) { 266 left += `.${splitReturnKindName[i]}`; 267 } 268 if (isOhos) { 269 returnName = `mock${firstCharacterToUppercase(mockMockName)}()${left}`; 270 } 271 } else { 272 returnName = getImportTypeAliasNameFromImportElements(importArray, typeName); 273 } 274 return returnName.split('<')[0]; 275} 276 277/** 278 * get return type alias, for example: {Context as _Context} return _Context 279 * @param importElementEntity 280 * @param typeName 281 * @returns 282 */ 283function getImportTypeAliasNameFromImportElements(importElementEntity: ImportElementEntity[], typeName: string): string { 284 for (let i = 0; i < importElementEntity.length; i++) { 285 if (importElementEntity[i].importElements.includes('_')) { 286 const importElements = importElementEntity[i].importElements.replace('{', '').replace('}', '').split(','); 287 for (let j = 0; j < importElements.length; j++) { 288 const element = importElements[j].trimStart().trimEnd(); 289 if (!element) { 290 continue; 291 } 292 if (`_${typeName}` === element.trim()) { 293 return `_${typeName}`; 294 } 295 if (element.includes(' as ') && `_${typeName}` === element.split('as')[1].trim()) { 296 return `_${typeName}`; 297 } 298 } 299 } 300 } 301 if (typeName === 'Want') { 302 typeName = 'mockWant().Want'; 303 } else if (typeName === 'InputMethodExtensionContext') { 304 typeName = 'mockInputMethodExtensionContext().InputMethodExtensionContext'; 305 } 306 return typeName; 307} 308 309/** 310 * check is generic symbol 311 * @param type 312 * @returns 313 */ 314export function checkIsGenericSymbol(type: string): boolean { 315 const words = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; 316 return words.includes(type); 317} 318 319/** 320 * generate basic type default value 321 * @param kindName 322 * @returns 323 */ 324export function generateGenericTypeToMockValue(kindName: string): string | number | boolean { 325 const genericTypeName = kindName.split('<')[1].split('>')[0]; 326 if (genericTypeName === 'string') { 327 return '\'\''; 328 } else if (genericTypeName === 'number') { 329 return 0; 330 } else if (genericTypeName === 'boolean') { 331 return true; 332 } else if (genericTypeName === 'Object' || genericTypeName === 'object') { 333 return '{}'; 334 } else { 335 return ''; 336 } 337} 338 339const paramsTypeStart = { 340 'void': '[PC Preview] unknown type', 341 'Array': '[]', 342 'Object': '{}', 343 'object': '{}', 344 '{': '{}', 345 'string': '""', 346 'String': '""', 347 'number': 0, 348 'Number': 0, 349 'boolean': false, 350 'Boolean': false, 351 'ArrayBuffer': 'new ArrayBuffer(0)', 352 'Uint8Array': 'new Uint8Array()', 353 'unknown': '[PC Preview] unknown type' 354}; 355 356const removeCallback = (str: string) => { 357 const callbackParams = { 358 type: 'Callback', 359 value: '' 360 }; 361 if (str.startsWith('Callback')) { 362 callbackParams.value = str.slice(0, str.length - 1).slice(9).trim(); 363 callbackParams.type = 'Callback'; 364 } else if (str.startsWith('AsyncCallback')) { 365 callbackParams.value = str.slice(0, str.length - 1).slice(14).trim(); 366 callbackParams.type = 'AsyncCallback'; 367 } 368 if (callbackParams.value.includes(',')) { 369 callbackParams.value = callbackParams.value.split(',')[0].trim(); 370 } 371 return callbackParams; 372}; 373 374const isInImportType = (mockApi: string, value: string) => { 375 let hasDotFirstWorld = ''; 376 if (value.includes('.')) { 377 hasDotFirstWorld = value.split('.')[0].trim(); 378 } 379 if (hasDotFirstWorld && mockApi.includes(`import { mock${firstLetterWord(hasDotFirstWorld)} `)) { 380 return 'isHasDotImportMock'; 381 } 382 if (hasDotFirstWorld && mockApi.includes(`import { ${firstLetterWord(hasDotFirstWorld)} `)) { 383 return 'isNoHasDotImportMock'; 384 } 385 if (mockApi.includes(`import { mock${firstLetterWord(value)} `)) { 386 return 'isImportMock'; 387 } 388 if (mockApi.includes(`import { ${value} `)) { 389 return 'isImport'; 390 } 391 return 'noImport'; 392}; 393 394const firstLetterWord = (word: string) => { 395 return word.slice(0, 1).toUpperCase() + word.slice(1); 396}; 397 398const hasDotFirstWord = (str: string) => { 399 return str.includes('.') ? str.split('.')[0] : str; 400}; 401 402/** 403 * get callback parameters data 404 * @returns data: parameters data: type: AsyncCallback or Callback 405 */ 406const setCallbackData = (mockApi: string, paramTypeString: string): {data: string, type: string} => { 407 const callbackParams = removeCallback(paramTypeString); 408 let callbackData = ''; 409 let importType = ''; 410 if (callbackParams.value) { 411 importType = isInImportType(mockApi, callbackParams.value); 412 } 413 if (importType === 'isHasDotImportMock') { 414 const upperWord = firstLetterWord(callbackParams.value); // Image.PixelMap 415 const firstWord = hasDotFirstWord(upperWord); // Image 416 callbackData = `mock${firstWord}()${upperWord.slice(firstWord.length)}`; 417 } else if (importType === 'isNoHasDotImportMock') { 418 callbackData = callbackParams.value; 419 } else if (importType === 'isImportMock') { 420 callbackData = `mock${firstLetterWord(callbackParams.value)}()`; 421 } else if (importType === 'isImport') { 422 callbackData = callbackParams.value; 423 } else if (importType === 'noImport') { 424 let paramsTypeNoHas = true; 425 if (callbackParams.value.endsWith(']')) { 426 callbackData = '[]'; 427 } else { 428 Object.keys(paramsTypeStart).forEach(item => { 429 if (callbackParams.value.startsWith(item)) { 430 callbackData = paramsTypeStart[item]; 431 paramsTypeNoHas = false; 432 } 433 }); 434 if (paramsTypeNoHas) { 435 callbackData = callbackParams.value; 436 if (callbackParams.value.includes('<')) { 437 callbackData = `${callbackParams.value.split('<')[0]}`; 438 } 439 } 440 if (callbackParams.value === 'Date') { 441 callbackData = 'new Date()'; 442 } 443 if (callbackParams.value === 'Uint8Array') { 444 callbackData = 'new Uint8Array()'; 445 } 446 if (callbackParams.value === 'T') { 447 callbackData = '[PC Preview] unknown type'; 448 } 449 } 450 } else { 451 callbackData = '[PC Preview] unknown type'; 452 } 453 return { 454 data: callbackData, 455 type: callbackParams.type 456 }; 457}; 458 459/** 460 * get callback statement 461 * @returns callback statement 462 */ 463export function getCallbackStatement(mockApi: string, paramTypeString?: string): string { 464 let outPut = `if (args && typeof args[args.length - 1] === 'function') { 465 args[args.length - 1].call(this,`; 466 const callbackError = "{'code': '','data': '','name': '','message': '','stack': ''}"; 467 let callbackDataParams = { 468 type: '', 469 data: '[PC Preview] unknown type' 470 }; 471 if (paramTypeString) { 472 callbackDataParams = setCallbackData(mockApi, paramTypeString); 473 } 474 if (callbackDataParams?.type === 'AsyncCallback') { 475 outPut += ` ${callbackError},`; 476 } 477 outPut += callbackDataParams.data === '[PC Preview] unknown type' ? ` '${callbackDataParams.data}');\n}` : ` ${callbackDataParams.data});\n}`; 478 return outPut; 479} 480 481/** 482 * get callback statement 483 * @returns callback statement 484 */ 485export function getOverloadedFunctionCallbackStatement( 486 entityArray: Array<FunctionEntity> | Array<MethodEntity> | Array<MethodSignatureEntity>, 487 sourceFile: SourceFile, 488 mockApi: string 489): string { 490 let overloadedCallbackBody = ''; 491 entityArray.forEach(functionBody => { 492 let content = ''; 493 let firstParamContent = ''; 494 let callbackParamContent = ''; 495 functionBody.args.forEach(arg => { 496 if ( 497 arg.paramTypeString.startsWith("'") && arg.paramTypeString.endsWith("'") || 498 arg.paramTypeString.startsWith('"') && arg.paramTypeString.endsWith('"') 499 ) { 500 const paramTypeStringArr = arg.paramTypeString.split('|'); 501 firstParamContent += `if (args && [${paramTypeStringArr}].includes(args[0])) {\n`; 502 } 503 if (['callback', 'observercallback', 'listener', 'synccallback'].includes(arg.paramName.toLowerCase())) { 504 callbackParamContent += getCallbackBody(mockApi, arg.paramTypeString); 505 } 506 }); 507 if (firstParamContent) { 508 content = `${firstParamContent}${callbackParamContent}\n}` + content; 509 } else { 510 content += callbackParamContent; 511 } 512 overloadedCallbackBody += content; 513 }); 514 overloadedCallbackBody += '\n'; 515 return overloadedCallbackBody; 516} 517 518/** 519 * get callback statement 520 * @returns callback statement 521 */ 522function getCallbackBody(mockApi: string, paramString: string): string { 523 let bodyInfo = `if (args && typeof args[args.length - 1] === 'function') { 524 args[args.length - 1].call(this,`; 525 const callbackError = "{'code': '','data': '','name': '','message': '','stack': ''}"; 526 if (paramString === 'ErrorCallback') { 527 bodyInfo += callbackError + ');\n}'; 528 return bodyInfo; 529 } 530 let callbackDataParams = { 531 type: '', 532 data: '[PC Preview] unknown type' 533 }; 534 if (paramString) { 535 callbackDataParams = setCallbackData(mockApi, paramString); 536 } 537 if (callbackDataParams?.type === 'AsyncCallback') { 538 bodyInfo += ` ${callbackError},`; 539 } 540 bodyInfo += callbackDataParams.data === '[PC Preview] unknown type' ? ` '${callbackDataParams.data}');\n` : ` ${callbackDataParams.data});\n`; 541 bodyInfo += '}'; 542 return bodyInfo; 543} 544 545/** 546 * get iterator template string 547 * @param methodEntity 548 * @returns 549 */ 550export function generateSymbolIterator(methodEntity: MethodEntity): string { 551 let iteratorMethod = ''; 552 if (methodEntity.returnType.returnKindName.includes('<[')) { 553 iteratorMethod += `let index = 0; 554 const IteratorMock = { 555 next: () => { 556 if (index < 1) { 557 const returnValue = ['[PC Previwe] unknown iterableiterator_k', '[PC Previwe] unknown iterableiterator_v']; 558 index++; 559 return { 560 value: returnValue, 561 done: false 562 }; 563 } else { 564 return { 565 done: true 566 }; 567 } 568 } 569 }; 570 return IteratorMock;`; 571 } else { 572 iteratorMethod += `let index = 0; 573 const IteratorMock = { 574 next: () => { 575 if (index < 1) { 576 index++; 577 return { 578 value: '[PC Preview] unknown any', 579 done: false 580 }; 581 } else { 582 return { 583 done: true 584 }; 585 } 586 } 587 }; 588 return IteratorMock;`; 589 } 590 591 return iteratorMethod; 592} 593 594/** 595 * generate more function name return statement; 596 * @param isReturnPromise 597 * @param returnType 598 * @param sourceFile 599 * @param mockApi 600 * @returns 601 */ 602export function getReturnData(isCallBack: boolean, isReturnPromise: boolean, returnType: ReturnTypeEntity, sourceFile: SourceFile, mockApi: string): string { 603 // If the return value is an iterator IterableIterator, then IteratorEntriesMock is directly returned 604 if (returnType.returnKindName.startsWith('IterableIterator')) { 605 if (returnType.returnKindName.includes(',')) { 606 return `let index = 0; 607 const IteratorEntriesMock = { 608 *[Symbol.iterator]() { 609 yield ['[PC Preview] unknown paramIterMock_K', '[PC Preview] unknown paramIterMock_V']; 610 }, 611 next: () => { 612 if (index < 1) { 613 const returnValue = ['[PC Previwe] unknown paramIterMock_K', '[PC Previwe] unknown paramIterMock_V']; 614 index++; 615 return { 616 value: returnValue, 617 done: false 618 }; 619 } else { 620 return { 621 done: true 622 }; 623 } 624 } 625 }; 626 return IteratorEntriesMock;`; 627 } else { 628 return `let index = 0; 629 const IteratorStringMock = { 630 *[Symbol.iterator]() { 631 yield '[PC Preview] unknown string'; 632 }, 633 next: () => { 634 if (index < 1) { 635 const returnValue = '[PC Previwe] unknown string'; 636 index++; 637 return { 638 value: returnValue, 639 done: false 640 }; 641 } else { 642 return { 643 done: true 644 }; 645 } 646 } 647 }; 648 return IteratorStringMock;`; 649 } 650 } 651 // If it is a promise, intercept the content of x in promise<x>, which may have the following formats: 652 // fun(): y | Promise<y>、 fun(): Promise<x | y | z>、 fun(): Promise<x>、 fun(): Promise<x.y> 653 // If it is not a promise, the returned type may be x, x | y | z, x.y 654 let returnPromiseParams = returnType.returnKindName; 655 if (isReturnPromise) { 656 if (returnType.returnKind === SyntaxKind.UnionType) { 657 // fun(): y | Promise<y> 658 const returnNames = returnPromiseParams.split('|'); 659 for (let i = 0; i < returnNames.length; i++) { 660 if (returnNames[i].trim().startsWith('Promise<')) { 661 // Promise<y> 662 returnPromiseParams = returnNames[i].trim(); 663 break; 664 } 665 } 666 } 667 // At this point, obtain the values in these formats: Promise<x | y | z>, Promise<y>, Promise<x.y>, Promise<x> 668 const kindName = returnPromiseParams; 669 returnPromiseParams = kindName.slice(0, kindName.length - 1).slice(8).trim(); 670 } 671 // At this point, the value type of param in promise<param>may be x, x | y | z, x.y 672 if (returnPromiseParams.includes('|')) { 673 returnPromiseParams = getSeparatorParam(returnPromiseParams); 674 } 675 676 // At this point, the possible types of promiseParam are x, x.y x [] Array<x> 677 // Check if it was imported 678 let returnData = '"[PC Preview] unknown type"'; 679 const importType = isInImportType(mockApi, returnPromiseParams); 680 if (importType === 'isHasDotImportMock') { 681 const upperWord = firstLetterWord(returnPromiseParams); // Image.PixelMap 682 const firstWord = hasDotFirstWord(upperWord); // Image 683 returnData = `mock${firstWord}()${upperWord.slice(firstWord.length)}`; 684 } else if (importType === 'isNoHasDotImportMock') { 685 returnData = returnPromiseParams; 686 } else if (importType === 'isImportMock') { 687 returnData = `mock${firstLetterWord(returnPromiseParams)}()`; 688 } else if (importType === 'isImport') { 689 returnData = returnPromiseParams; 690 } else if (importType === 'noImport') { 691 if (returnPromiseParams.endsWith(']')) { 692 returnData = '[]'; 693 } else { 694 let paramsTypeNoHas = true; 695 Object.keys(paramsTypeStart).forEach(item => { 696 if (returnPromiseParams.startsWith(item)) { 697 returnData = paramsTypeStart[item]; 698 paramsTypeNoHas = false; 699 } 700 }); 701 if (paramsTypeNoHas) { 702 returnData = returnPromiseParams; 703 if (returnPromiseParams.includes('<')) { 704 returnData = `${returnPromiseParams.split('<')[0]}`; 705 } 706 } 707 if (returnPromiseParams === 'Date') { 708 returnData = 'new Date()'; 709 } 710 if (returnPromiseParams === 'T') { 711 returnData = '"[PC Preview] unknown type"'; 712 } 713 if (returnType.returnKindName.startsWith('Readonly')) { 714 returnData = `${returnType.returnKindName.split('<')[1].split('>')[0]}`; 715 } 716 if (checkIsGenericSymbol(returnType.returnKindName)) { 717 returnData = `'[PC Preview] unknown iterableiterator_${returnType.returnKindName}'`; 718 } 719 } 720 } else { 721 returnData = '"[PC Preview] unknown type"'; 722 } 723 const data = typeof returnData === 'string' && returnData.startsWith('[PC Preview] unknown') ? `'${returnData}'` : `${returnData}`; 724 if (isReturnPromise) { 725 return ` 726 return new Promise((resolve, reject) => { 727 resolve(${data}); 728 }) 729 `; 730 } else { 731 return `return ${data}`; 732 } 733} 734 735/** 736 * 737 * @param returnPromiseParams 738 * @returns 739 */ 740function getSeparatorParam(returnPromiseParams: string): string { 741 let hasObj = ''; 742 let hasArr = ''; 743 let hasUint8Array = ''; 744 let hasArrayBuffer = ''; 745 let otherValue = ''; 746 const paramsArr = returnPromiseParams.split('|'); 747 for (let i = 0; i < paramsArr.length; i++) { 748 const param = paramsArr[i].trim(); 749 if (param.startsWith('{') || param.startsWith('Object')) { 750 hasObj = '{}'; 751 } else if (param.endsWith(']') || param.startsWith('[') || param.startsWith('Array<')) { 752 hasArr = '[]'; 753 } else if (param.startsWith('Uint8Array')) { 754 hasUint8Array = 'Uint8Array'; 755 } else if (param.startsWith('ArrayBuffer')) { 756 hasArrayBuffer = 'ArrayBuffer'; 757 } else { 758 if (param !== null) { 759 otherValue = param; 760 } 761 } 762 } 763 if (hasObj) { 764 return hasObj; 765 } 766 if (hasArr) { 767 return hasArr; 768 } 769 if (hasUint8Array) { 770 return hasUint8Array; 771 } 772 if (hasArrayBuffer) { 773 return hasArrayBuffer; 774 } 775 return otherValue; 776} 777 778export const overloadedFunctionArr = ['on', 'off']; 779