• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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