17c804472Sopenharmony_ci/* 27c804472Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 37c804472Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 47c804472Sopenharmony_ci * you may not use this file except in compliance with the License. 57c804472Sopenharmony_ci * You may obtain a copy of the License at 67c804472Sopenharmony_ci * 77c804472Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 87c804472Sopenharmony_ci * 97c804472Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 107c804472Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 117c804472Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 127c804472Sopenharmony_ci * See the License for the specific language governing permissions and 137c804472Sopenharmony_ci * limitations under the License. 147c804472Sopenharmony_ci */ 157c804472Sopenharmony_ci 167c804472Sopenharmony_ciimport type { SourceFile } from 'typescript'; 177c804472Sopenharmony_ciimport { SyntaxKind } from 'typescript'; 187c804472Sopenharmony_ciimport type { MethodEntity } from '../declaration-node/methodDeclaration'; 197c804472Sopenharmony_ciimport type { FunctionEntity } from '../declaration-node/functionDeclaration'; 207c804472Sopenharmony_ciimport type { MethodSignatureEntity } from '../declaration-node/methodSignatureDeclaration'; 217c804472Sopenharmony_ciimport { 227c804472Sopenharmony_ci generateSymbolIterator, 237c804472Sopenharmony_ci getCallbackStatement, 247c804472Sopenharmony_ci getReturnStatement, 257c804472Sopenharmony_ci getWarnConsole, 267c804472Sopenharmony_ci getReturnData, 277c804472Sopenharmony_ci getOverloadedFunctionCallbackStatement, 287c804472Sopenharmony_ci overloadedFunctionArr 297c804472Sopenharmony_ci} from './generateCommonUtil'; 307c804472Sopenharmony_ci 317c804472Sopenharmony_ciinterface MethodArrayProps { 327c804472Sopenharmony_ci methodArray: Array<MethodEntity>; 337c804472Sopenharmony_ci methodEntity: MethodEntity; 347c804472Sopenharmony_ci sourceFile: SourceFile; 357c804472Sopenharmony_ci mockApi: string; 367c804472Sopenharmony_ci methodBody: string; 377c804472Sopenharmony_ci} 387c804472Sopenharmony_ci 397c804472Sopenharmony_ciinterface MethodArrayItemForEachProps { 407c804472Sopenharmony_ci returnSet: Set<string>; 417c804472Sopenharmony_ci value: MethodEntity | FunctionEntity | MethodSignatureEntity; 427c804472Sopenharmony_ci argSet: Set<string>; 437c804472Sopenharmony_ci isCallBack: boolean; 447c804472Sopenharmony_ci argParamsSet: string; 457c804472Sopenharmony_ci needOverloaded: boolean; 467c804472Sopenharmony_ci} 477c804472Sopenharmony_ci 487c804472Sopenharmony_ciinterface MethodArrayBack { 497c804472Sopenharmony_ci returnSet: Set<string>; 507c804472Sopenharmony_ci methodBody: string; 517c804472Sopenharmony_ci isCallBack: boolean; 527c804472Sopenharmony_ci} 537c804472Sopenharmony_ci 547c804472Sopenharmony_ci/** 557c804472Sopenharmony_ci * generate class method 567c804472Sopenharmony_ci * @param rootName 577c804472Sopenharmony_ci * @param methodArray 587c804472Sopenharmony_ci * @param sourceFile 597c804472Sopenharmony_ci * @returns 607c804472Sopenharmony_ci */ 617c804472Sopenharmony_ciexport function generateCommonMethod( 627c804472Sopenharmony_ci rootName: string, 637c804472Sopenharmony_ci methodArray: Array<MethodEntity>, 647c804472Sopenharmony_ci sourceFile: SourceFile, 657c804472Sopenharmony_ci mockApi: string 667c804472Sopenharmony_ci): string { 677c804472Sopenharmony_ci let methodBody = ''; 687c804472Sopenharmony_ci const methodEntity = methodArray[0]; 697c804472Sopenharmony_ci if (methodEntity.functionName.name === 'Symbol.iterator') { 707c804472Sopenharmony_ci methodBody += `this[${methodEntity.functionName.name}] = function(...args) {`; 717c804472Sopenharmony_ci methodBody += getWarnConsole(rootName, methodEntity.functionName.name); 727c804472Sopenharmony_ci methodBody += generateSymbolIterator(methodEntity); 737c804472Sopenharmony_ci methodBody += '};\n'; 747c804472Sopenharmony_ci return methodBody; 757c804472Sopenharmony_ci } else { 767c804472Sopenharmony_ci methodBody += `this.${methodEntity.functionName.name} = function(...args) {`; 777c804472Sopenharmony_ci methodBody += getWarnConsole(rootName, methodEntity.functionName.name); 787c804472Sopenharmony_ci } 797c804472Sopenharmony_ci 807c804472Sopenharmony_ci if (methodArray.length === 1) { 817c804472Sopenharmony_ci const args = methodEntity.args; 827c804472Sopenharmony_ci const len = args.length; 837c804472Sopenharmony_ci if (len && args[len - 1].paramName.toLowerCase().includes('callback')) { 847c804472Sopenharmony_ci methodBody += getCallbackStatement(mockApi, args[len - 1]?.paramTypeString); 857c804472Sopenharmony_ci } 867c804472Sopenharmony_ci if (methodEntity.returnType.returnKind !== SyntaxKind.VoidKeyword) { 877c804472Sopenharmony_ci if (methodEntity.functionName.name === 'getApplicationContext') { 887c804472Sopenharmony_ci methodBody += getApplicationContextValue(methodEntity.functionName.name); 897c804472Sopenharmony_ci } else { 907c804472Sopenharmony_ci methodBody += getReturnStatement(methodEntity.returnType, sourceFile); 917c804472Sopenharmony_ci } 927c804472Sopenharmony_ci } 937c804472Sopenharmony_ci } else { 947c804472Sopenharmony_ci const methodArrayBack = methodArrayForEach({ methodArray, methodEntity, sourceFile, mockApi, methodBody }); 957c804472Sopenharmony_ci methodBody = returnSetForEach(methodArrayBack, methodArray, sourceFile, mockApi); 967c804472Sopenharmony_ci } 977c804472Sopenharmony_ci methodBody += '};\n'; 987c804472Sopenharmony_ci return methodBody; 997c804472Sopenharmony_ci} 1007c804472Sopenharmony_ci 1017c804472Sopenharmony_cifunction getApplicationContextValue(name: string): string { 1027c804472Sopenharmony_ci return ` 1037c804472Sopenharmony_ciconst mockData = { 1047c804472Sopenharmony_ci on: function (...args) { 1057c804472Sopenharmony_ci console.warn( 1067c804472Sopenharmony_ci 'The ${name}.on interface in the Previewer is a mocked implementation and may behave differently than on a real device.' 1077c804472Sopenharmony_ci ); 1087c804472Sopenharmony_ci if (args && ['environment'].includes(args[0])) { 1097c804472Sopenharmony_ci if (args && typeof args[args.length - 1] === 'function') { 1107c804472Sopenharmony_ci const EnvironmentCallback = mockEnvironmentCallback(); 1117c804472Sopenharmony_ci args[args.length - 1].call(this, new EnvironmentCallback()); 1127c804472Sopenharmony_ci } 1137c804472Sopenharmony_ci } 1147c804472Sopenharmony_ci return 0; 1157c804472Sopenharmony_ci }, 1167c804472Sopenharmony_ci off: function (...args) { 1177c804472Sopenharmony_ci console.warn( 1187c804472Sopenharmony_ci 'The ${name}.off interface in the Previewer is a mocked implementation and may behave differently than on a real device.' 1197c804472Sopenharmony_ci ); 1207c804472Sopenharmony_ci if (args && ['environment'].includes(args[0])) { 1217c804472Sopenharmony_ci if (args && typeof args[args.length - 1] === 'function') { 1227c804472Sopenharmony_ci args[args.length - 1].call( 1237c804472Sopenharmony_ci this, 1247c804472Sopenharmony_ci { 'code': '', 'data': '', 'name': '', 'message': '', 'stack': '' }, 1257c804472Sopenharmony_ci '[PC Preview] unknown type' 1267c804472Sopenharmony_ci ); 1277c804472Sopenharmony_ci } 1287c804472Sopenharmony_ci } 1297c804472Sopenharmony_ci return new Promise((resolve, reject) => { 1307c804472Sopenharmony_ci resolve('[PC Preview] unknown type'); 1317c804472Sopenharmony_ci }); 1327c804472Sopenharmony_ci } 1337c804472Sopenharmony_ci}; 1347c804472Sopenharmony_cireturn mockData; 1357c804472Sopenharmony_ci `; 1367c804472Sopenharmony_ci} 1377c804472Sopenharmony_ci 1387c804472Sopenharmony_ci/** 1397c804472Sopenharmony_ci * method Array ForEach 1407c804472Sopenharmony_ci * @param props 1417c804472Sopenharmony_ci * @returns 1427c804472Sopenharmony_ci */ 1437c804472Sopenharmony_cifunction methodArrayForEach(props: MethodArrayProps): MethodArrayBack { 1447c804472Sopenharmony_ci let argSet: Set<string> = new Set<string>(); 1457c804472Sopenharmony_ci let argParamsSet: string = ''; 1467c804472Sopenharmony_ci let returnSet: Set<string> = new Set<string>(); 1477c804472Sopenharmony_ci let isCallBack = false; 1487c804472Sopenharmony_ci let needOverloaded = false; 1497c804472Sopenharmony_ci props.methodArray.forEach(value => { 1507c804472Sopenharmony_ci ({ returnSet, argSet, isCallBack, argParamsSet, needOverloaded} = 1517c804472Sopenharmony_ci methodArrayItemForEach({returnSet, value, argSet, isCallBack, argParamsSet, needOverloaded})); 1527c804472Sopenharmony_ci }); 1537c804472Sopenharmony_ci if (isCallBack) { 1547c804472Sopenharmony_ci if (overloadedFunctionArr.includes(props.methodEntity.functionName.name) && needOverloaded) { 1557c804472Sopenharmony_ci props.methodBody += getOverloadedFunctionCallbackStatement(props.methodArray, props.sourceFile, props.mockApi); 1567c804472Sopenharmony_ci } else { 1577c804472Sopenharmony_ci props.methodBody += getCallbackStatement(props.mockApi, argParamsSet); 1587c804472Sopenharmony_ci } 1597c804472Sopenharmony_ci } 1607c804472Sopenharmony_ci return { 1617c804472Sopenharmony_ci returnSet, 1627c804472Sopenharmony_ci methodBody: props.methodBody, 1637c804472Sopenharmony_ci isCallBack 1647c804472Sopenharmony_ci }; 1657c804472Sopenharmony_ci} 1667c804472Sopenharmony_ci 1677c804472Sopenharmony_ci/** 1687c804472Sopenharmony_ci * method ArrayItem ForEach 1697c804472Sopenharmony_ci * @param props 1707c804472Sopenharmony_ci * @returns 1717c804472Sopenharmony_ci */ 1727c804472Sopenharmony_ciexport function methodArrayItemForEach(props: MethodArrayItemForEachProps): MethodArrayItemForEachProps { 1737c804472Sopenharmony_ci props.returnSet.add(props.value.returnType.returnKindName); 1747c804472Sopenharmony_ci props.value.args.forEach(arg => { 1757c804472Sopenharmony_ci props.argSet.add(arg.paramName); 1767c804472Sopenharmony_ci if (arg.paramName.toLowerCase().includes('callback')) { 1777c804472Sopenharmony_ci props.isCallBack = true; 1787c804472Sopenharmony_ci if (arg.paramTypeString) { 1797c804472Sopenharmony_ci props.argParamsSet = arg.paramTypeString; 1807c804472Sopenharmony_ci } 1817c804472Sopenharmony_ci } 1827c804472Sopenharmony_ci if ( 1837c804472Sopenharmony_ci arg.paramTypeString.startsWith("'") && arg.paramTypeString.endsWith("'") || 1847c804472Sopenharmony_ci arg.paramTypeString.startsWith('"') && arg.paramTypeString.endsWith('"') 1857c804472Sopenharmony_ci ) { 1867c804472Sopenharmony_ci props.needOverloaded = true; 1877c804472Sopenharmony_ci } 1887c804472Sopenharmony_ci }); 1897c804472Sopenharmony_ci return props; 1907c804472Sopenharmony_ci} 1917c804472Sopenharmony_ci 1927c804472Sopenharmony_ci/** 1937c804472Sopenharmony_ci * returnSet ForEach 1947c804472Sopenharmony_ci * @param props 1957c804472Sopenharmony_ci * @param methodArray 1967c804472Sopenharmony_ci * @param sourceFile 1977c804472Sopenharmony_ci * @param mockApi 1987c804472Sopenharmony_ci * @returns 1997c804472Sopenharmony_ci */ 2007c804472Sopenharmony_cifunction returnSetForEach( 2017c804472Sopenharmony_ci props: MethodArrayBack, 2027c804472Sopenharmony_ci methodArray: Array<MethodEntity>, 2037c804472Sopenharmony_ci sourceFile: SourceFile, 2047c804472Sopenharmony_ci mockApi: string 2057c804472Sopenharmony_ci): string { 2067c804472Sopenharmony_ci let isReturnPromise = false; 2077c804472Sopenharmony_ci let promiseReturnValue = ''; 2087c804472Sopenharmony_ci let methodOtherReturnValue = ''; 2097c804472Sopenharmony_ci props.returnSet.forEach(value => { 2107c804472Sopenharmony_ci if (value.includes('Promise<')) { 2117c804472Sopenharmony_ci isReturnPromise = true; 2127c804472Sopenharmony_ci promiseReturnValue = value; 2137c804472Sopenharmony_ci } else { 2147c804472Sopenharmony_ci if (!methodOtherReturnValue) { 2157c804472Sopenharmony_ci methodOtherReturnValue = value; 2167c804472Sopenharmony_ci } 2177c804472Sopenharmony_ci } 2187c804472Sopenharmony_ci }); 2197c804472Sopenharmony_ci if (isReturnPromise) { 2207c804472Sopenharmony_ci if (promiseReturnValue) { 2217c804472Sopenharmony_ci let returnType = null; 2227c804472Sopenharmony_ci methodArray.forEach(value => { 2237c804472Sopenharmony_ci if (value.returnType.returnKindName === promiseReturnValue) { 2247c804472Sopenharmony_ci returnType = value.returnType; 2257c804472Sopenharmony_ci } 2267c804472Sopenharmony_ci }); 2277c804472Sopenharmony_ci props.methodBody += getReturnData(props.isCallBack, isReturnPromise, returnType, sourceFile, mockApi); 2287c804472Sopenharmony_ci } else { 2297c804472Sopenharmony_ci props.methodBody += ` 2307c804472Sopenharmony_ci return new Promise((resolve, reject) => { 2317c804472Sopenharmony_ci resolve('[PC Preview] unknow boolean'); 2327c804472Sopenharmony_ci }) 2337c804472Sopenharmony_ci `; 2347c804472Sopenharmony_ci } 2357c804472Sopenharmony_ci } else if (methodOtherReturnValue) { 2367c804472Sopenharmony_ci let returnType = null; 2377c804472Sopenharmony_ci methodArray.forEach(value => { 2387c804472Sopenharmony_ci if (value.returnType.returnKindName === methodOtherReturnValue) { 2397c804472Sopenharmony_ci returnType = value.returnType; 2407c804472Sopenharmony_ci } 2417c804472Sopenharmony_ci }); 2427c804472Sopenharmony_ci props.methodBody += getReturnData(props.isCallBack, isReturnPromise, returnType, sourceFile, mockApi); 2437c804472Sopenharmony_ci } 2447c804472Sopenharmony_ci return props.methodBody; 2457c804472Sopenharmony_ci} 246