• 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 type { FunctionEntity } from '../declaration-node/functionDeclaration';
19import {
20  getCallbackStatement,
21  getReturnStatement,
22  getWarnConsole,
23  getReturnData,
24  getOverloadedFunctionCallbackStatement,
25  overloadedFunctionArr
26} from './generateCommonUtil';
27import { methodArrayItemForEach } from './generateCommonMethod';
28
29interface AssemblyFunctionProps {
30  functionArray: Array<FunctionEntity>,
31  functionEntity: FunctionEntity,
32  functionBody: string,
33  sourceFile: SourceFile,
34  mockApi: string
35}
36
37interface AssemblyFunctionBack {
38  isReturnPromise: boolean,
39  promiseReturnValue: string,
40  functionOtherReturnValue: string,
41  isCallBack: boolean,
42  functionBody: string
43}
44
45/**
46 * generate function
47 * @param rootName
48 * @param functionArray
49 * @param sourceFile
50 * @param mockApi
51 * @param isRoot
52 * @returns
53 */
54export function generateCommonFunction(
55  rootName: string,
56  functionArray: Array<FunctionEntity>,
57  sourceFile: SourceFile,
58  mockApi: string,
59  isRoot: boolean
60): string {
61  let functionBody = '';
62  const functionEntity = functionArray[0];
63  if (isRoot) {
64    functionBody = `${functionEntity.isExport ? 'export ' : ''}const ${functionEntity.functionName} = function(...args) {`;
65  } else {
66    functionBody = `${functionEntity.functionName}: function(...args) {`;
67  }
68  functionBody += getWarnConsole(rootName, functionEntity.functionName);
69
70  if (functionArray.length === 1) {
71    const args = functionEntity.args;
72    const len = args.length;
73    if (args.length > 0 && args[len - 1].paramName.toLowerCase().includes('callback')) {
74      functionBody += getCallbackStatement(mockApi, args[len - 1]?.paramTypeString);
75    }
76    if (functionEntity.returnType.returnKind !== SyntaxKind.VoidKeyword) {
77      if (rootName === 'featureAbility' && functionEntity.returnType.returnKindName === 'Context') {
78        functionBody += 'return _Context;';
79      } else if (rootName === 'inputMethod' && functionEntity.returnType.returnKindName === 'InputMethodSubtype') {
80        functionBody += 'return mockInputMethodSubtype().InputMethodSubtype;';
81      } else {
82        functionBody += getReturnStatement(functionEntity.returnType, sourceFile);
83      }
84    }
85  } else {
86    const assemblyBack = assemblyFunctionBody({ functionArray, functionEntity, functionBody, mockApi, sourceFile });
87    functionBody = assemblyFuntion(assemblyBack, functionArray, sourceFile, mockApi);
88    functionBody = assemblyBack.functionBody;
89  }
90  functionBody += isRoot ? '};' : '},';
91  if (isRoot) {
92    functionBody += `
93      if (!global.${functionEntity.functionName}) {
94        global.${functionEntity.functionName} = ${functionEntity.functionName};
95      }
96    `;
97  }
98  return functionBody;
99}
100
101/**
102 * generate assembly function
103 * @param props
104 * @returns
105 */
106function assemblyFunctionBody(props: AssemblyFunctionProps): AssemblyFunctionBack {
107  let argSet: Set<string> = new Set<string>();
108  let argParamsSet: string = '';
109  let returnSet: Set<string> = new Set<string>();
110  let isCallBack = false;
111  let needOverloaded = false;
112  props.functionArray.forEach(value => {
113    ({ returnSet, argSet, isCallBack, argParamsSet, needOverloaded} =
114      methodArrayItemForEach({returnSet, value, argSet, isCallBack, argParamsSet, needOverloaded}));
115  });
116  props.functionBody = forEachFuntionArray(isCallBack, props, needOverloaded, argParamsSet);
117  let isReturnPromise = false;
118  let promiseReturnValue = '';
119  let functionOtherReturnValue = '';
120  returnSet.forEach(value => {
121    if (value.includes('Promise<')) {
122      isReturnPromise = true;
123      promiseReturnValue = value;
124    } else {
125      if (!functionOtherReturnValue) {
126        functionOtherReturnValue = value;
127      }
128    }
129  });
130  return {
131    isReturnPromise,
132    promiseReturnValue,
133    functionOtherReturnValue,
134    isCallBack,
135    functionBody: props.functionBody
136  };
137}
138
139/**
140 * forEach functionArray
141 * @param isCallBack
142 * @param props
143 * @param needOverloaded
144 * @param argParamsSet
145 * @returns
146 */
147function forEachFuntionArray(
148  isCallBack: boolean,
149  props: AssemblyFunctionProps,
150  needOverloaded: boolean,
151  argParamsSet:string
152): string {
153  if (isCallBack) {
154    if (overloadedFunctionArr.includes(props.functionEntity.functionName) && needOverloaded) {
155      const stateEment = getOverloadedFunctionCallbackStatement(props.functionArray, props.sourceFile, props.mockApi);
156      props.functionBody += stateEment;
157    } else {
158      props.functionBody += getCallbackStatement(props.mockApi, argParamsSet);
159    }
160  }
161  return props.functionBody;
162}
163
164/**
165 * assembly Function
166 * @param porps
167 * @param functionArray
168 * @param sourceFile
169 * @param mockApi
170 * @returns
171 */
172function assemblyFuntion(
173  porps: AssemblyFunctionBack,
174  functionArray: Array<FunctionEntity>,
175  sourceFile: SourceFile,
176  mockApi: string
177): string {
178  if (porps.isReturnPromise) {
179    if (porps.promiseReturnValue) {
180      let returnType = null;
181      functionArray.forEach(value => {
182        if (value.returnType.returnKindName === porps.promiseReturnValue) {
183          returnType = value.returnType;
184        }
185      });
186      porps.functionBody += getReturnData(porps.isCallBack, porps.isReturnPromise, returnType, sourceFile, mockApi);
187    } else {
188      porps.functionBody += `
189          return new Promise((resolve, reject) => {
190            resolve('[PC Preview] unknow boolean');
191          })
192        `;
193    }
194  } else if (porps.functionOtherReturnValue) {
195    let returnType = null;
196    functionArray.forEach(value => {
197      if (value.returnType.returnKindName === porps.functionOtherReturnValue) {
198        returnType = value.returnType;
199      }
200    });
201    porps.functionBody += getReturnData(porps.isCallBack, porps.isReturnPromise, returnType, sourceFile, mockApi);
202  }
203  return porps.functionBody;
204}
205
206