diff --git a/mock-generate/src/declaration-node/sourceFileElementsAssemply.ts b/mock-generate/src/declaration-node/sourceFileElementsAssemply.ts index 30568e5bfc28d63ee0a3bfae80a08a00657a43c9..c2e733d09ac292a2ba5331d14b12180c1a7d9401 100644 --- a/mock-generate/src/declaration-node/sourceFileElementsAssemply.ts +++ b/mock-generate/src/declaration-node/sourceFileElementsAssemply.ts @@ -53,7 +53,7 @@ export function getSourceFileAssembly(sourceFile: SourceFile, fileName: string): let exportAssignment: Array = []; const staticMethods: Array> = []; const exportDeclarations: Array = []; - const functionDeclarations: Array = []; + const functionDeclarations: Map> = new Map>(); sourceFile.forEachChild(node => { if (isImportDeclaration(node)) { @@ -86,10 +86,16 @@ export function getSourceFileAssembly(sourceFile: SourceFile, fileName: string): enumDeclarations.push(getEnumDeclaration(node, sourceFile)); } else if (isExportDeclaration(node)) { exportDeclarations.push(sourceFile.text.substring(node.pos, node.end).trimStart().trimEnd()); - } else if (isFunctionDeclaration(node)){ - functionDeclarations.push(getFunctionDeclaration(node, sourceFile)); - } - else { + } else if (isFunctionDeclaration(node)) { + const functionEntity = getFunctionDeclaration(node, sourceFile); + if (functionDeclarations.get(functionEntity.functionName) !== undefined) { + functionDeclarations.get(functionEntity.functionName)?.push(functionEntity); + } else { + const functionArray: Array = []; + functionArray.push(functionEntity); + functionDeclarations.set(functionEntity.functionName, functionArray); + } + } else { if (node.kind !== SyntaxKind.EndOfFileToken && !isFunctionDeclaration(node) && !isVariableStatement(node)) { console.log('--------------------------- uncaught sourceFile type start -----------------------'); console.log('fileName: ' + fileName); @@ -175,5 +181,5 @@ export interface SourceFileEntity { exportAssignment: Array, staticMethods: Array>, exportDeclarations: Array, - functionDeclarations: Array + functionDeclarations: Map> } diff --git a/mock-generate/src/generate/generateCommonFunction.ts b/mock-generate/src/generate/generateCommonFunction.ts index 3f7f485b7e96fc79843dde08f516db1887b60028..b55f23f0516c96007c0ffef8aab650d3e4bf31d8 100644 --- a/mock-generate/src/generate/generateCommonFunction.ts +++ b/mock-generate/src/generate/generateCommonFunction.ts @@ -16,26 +16,39 @@ import type { SourceFile } from 'typescript'; import { SyntaxKind } from 'typescript'; import type { FunctionEntity } from '../declaration-node/functionDeclaration'; -import { getCallbackStatement, getReturnStatement, getWarnConsole, getReturnData } from './generateCommonUtil'; +import { + getCallbackStatement, + getReturnStatement, + getWarnConsole, + getReturnData, + getOverloadedFunctionCallbackStatement, + overloadedFunctionArr +} from './generateCommonUtil'; /** * generate function * @param rootName * @param functionArray * @param sourceFile + * @param mockApi + * @param isRoot * @returns */ -export function generateCommonFunction(rootName: string, functionArray: Array, sourceFile: SourceFile, mockApi: string): string { +export function generateCommonFunction( + rootName: string, + functionArray: Array, + sourceFile: SourceFile, + mockApi: string, + isRoot: boolean +): string { let functionBody = ''; const functionEntity = functionArray[0]; - functionBody = `${functionEntity.functionName}: function(...args) {`; - functionBody += getWarnConsole(rootName, functionEntity.functionName); - - // The callback function cannot be executed immediately, otherwise an error will be reported - if (sourceFile.fileName.includes('@ohos.events.emitter.d.ts')) { - functionBody += '},'; - return functionBody; + if (isRoot) { + functionBody = `const ${functionEntity.functionName} = function(...args) {`; + } else { + functionBody = `${functionEntity.functionName}: function(...args) {`; } + functionBody += getWarnConsole(rootName, functionEntity.functionName); if (functionArray.length === 1) { const args = functionEntity.args; @@ -57,6 +70,7 @@ export function generateCommonFunction(rootName: string, functionArray: Array = new Set(); let isCallBack = false; + let needOverloaded = false; functionArray.forEach(value => { returnSet.add(value.returnType.returnKindName); value.args.forEach(arg => { @@ -67,10 +81,20 @@ export function generateCommonFunction(rootName: string, functionArray: Array { - resolve('[PC Preview] unknow boolean'); - }) - }`; - } else { - functionBody += ` - return new Promise((resolve, reject) => { - resolve('[PC Preview] unknow boolean'); - }) - `; - } + functionBody += ` + return new Promise((resolve, reject) => { + resolve('[PC Preview] unknow boolean'); + }) + `; } } else if (otherReturnValue) { let returnType = null; @@ -119,6 +135,13 @@ export function generateCommonFunction(rootName: string, functionArray: Array, sourceFile: SourceFile, mockApi: string): string { +export function generateCommonMethod( + rootName: string, + methodArray: Array, + sourceFile: SourceFile, + mockApi: string +): string { let methodBody = ''; const methodEntity = methodArray[0]; if (methodEntity.functionName.name === 'Symbol.iterator') { @@ -60,6 +70,7 @@ export function generateCommonMethod(rootName: string, methodArray: Array = new Set(); let isCallBack = false; + let needOverloaded = false; methodArray.forEach(value => { returnSet.add(value.returnType.returnKindName); value.args.forEach(arg => { @@ -70,10 +81,20 @@ export function generateCommonMethod(rootName: string, methodArray: Array { - resolve('[PC Preview] unknow boolean'); - }) - }`; - } else { - methodBody += ` - return new Promise((resolve, reject) => { - resolve('[PC Preview] unknow boolean'); - }) - `; - } + methodBody += ` + return new Promise((resolve, reject) => { + resolve('[PC Preview] unknow boolean'); + }) + `; } } else if (otherReturnValue) { let returnType = null; diff --git a/mock-generate/src/generate/generateCommonMethodSignature.ts b/mock-generate/src/generate/generateCommonMethodSignature.ts index 115116c00d3619e171569d9c25d930f1e8ae7b3a..829a97ea96977a02d80c33bdbd48e51fd7fe481b 100644 --- a/mock-generate/src/generate/generateCommonMethodSignature.ts +++ b/mock-generate/src/generate/generateCommonMethodSignature.ts @@ -16,7 +16,14 @@ import type { SourceFile } from 'typescript'; import { SyntaxKind } from 'typescript'; import type { MethodSignatureEntity } from '../declaration-node/methodSignatureDeclaration'; -import { getCallbackStatement, getReturnStatement, getWarnConsole, getReturnData } from './generateCommonUtil'; +import { + getCallbackStatement, + getReturnStatement, + getWarnConsole, + getReturnData, + getOverloadedFunctionCallbackStatement, + overloadedFunctionArr +} from './generateCommonUtil'; /** * generate interface signature method @@ -25,7 +32,13 @@ import { getCallbackStatement, getReturnStatement, getWarnConsole, getReturnData * @param sourceFile * @returns */ -export function generateCommonMethodSignature(rootName: string, methodSignatureArray: Array, sourceFile: SourceFile, mockApi: string): string { +export function generateCommonMethodSignature( + rootName: string, + methodSignatureArray: + Array, + sourceFile: SourceFile, + mockApi: string +): string { let methodSignatureBody = ''; const methodEntity = methodSignatureArray[0]; methodSignatureBody += `${methodEntity.functionName}: function(...args) {`; @@ -48,6 +61,7 @@ export function generateCommonMethodSignature(rootName: string, methodSignatureA let argParamsSet: string = ''; const returnSet: Set = new Set(); let isCallBack = false; + let needOverloaded = false; methodSignatureArray.forEach(value => { returnSet.add(value.returnType.returnKindName); value.args.forEach(arg => { @@ -58,10 +72,20 @@ export function generateCommonMethodSignature(rootName: string, methodSignatureA argParamsSet = arg.paramTypeString; } } + if ( + arg.paramTypeString.startsWith("'") && arg.paramTypeString.endsWith("'") || + arg.paramTypeString.startsWith('"') && arg.paramTypeString.endsWith('"') + ) { + needOverloaded = true; + } }); }); if (isCallBack) { - methodSignatureBody += getCallbackStatement(mockApi, argParamsSet); + if (overloadedFunctionArr.includes(methodEntity.functionName) && needOverloaded) { + methodSignatureBody += getOverloadedFunctionCallbackStatement(methodSignatureArray, sourceFile, mockApi); + } else { + methodSignatureBody += getCallbackStatement(mockApi, argParamsSet); + } } let isReturnPromise = false; let promiseReturnValue = ''; @@ -86,19 +110,11 @@ export function generateCommonMethodSignature(rootName: string, methodSignatureA }); methodSignatureBody += getReturnData(isCallBack, isReturnPromise, returnType, sourceFile, mockApi); } else { - if (isCallBack) { - methodSignatureBody += `else { - return new Promise((resolve, reject) => { - resolve('[PC Preview] unknow boolean'); - }) - }`; - } else { - methodSignatureBody += ` - return new Promise((resolve, reject) => { - resolve('[PC Preview] unknow boolean'); - }) - `; - } + methodSignatureBody += ` + return new Promise((resolve, reject) => { + resolve('[PC Preview] unknow boolean'); + }) + `; } } else if (otherReturnValue) { let returnType = null; diff --git a/mock-generate/src/generate/generateCommonUtil.ts b/mock-generate/src/generate/generateCommonUtil.ts index 6630838167ea5a2b5d9ea1cab0435954726548d8..37aabee68522980445814c8fb0cd5a8b621e0f80 100644 --- a/mock-generate/src/generate/generateCommonUtil.ts +++ b/mock-generate/src/generate/generateCommonUtil.ts @@ -20,6 +20,8 @@ import type { ReturnTypeEntity } from '../common/commonUtils'; import { getImportDeclarationArray } from '../declaration-node/importAndExportDeclaration'; import type { ImportElementEntity } from '../declaration-node/importAndExportDeclaration'; import type { MethodEntity } from '../declaration-node/methodDeclaration'; +import type { FunctionEntity } from '../declaration-node/functionDeclaration'; +import type { MethodSignatureEntity } from '../declaration-node/methodSignatureDeclaration'; /** * get warn console template @@ -31,6 +33,22 @@ export function getWarnConsole(interfaceNameOrClassName: string, functionNameOrP return `console.warn('The ${interfaceNameOrClassName}.${functionNameOrPropertyName} interface in the Previewer is a mocked implementation and may behave differently than on a real device.');\n`; } +function handlePromiseParams(returnType: ReturnTypeEntity): string { + const returnKindName = returnType.returnKindName.slice(0, returnType.returnKindName.length - 1).slice(8).trim(); + let returnName = `return new Promise((resolve, reject) => { + resolve('[PC Preview] unknown type'); + })`; + Object.keys(paramsTypeStart).forEach(key => { + if (returnKindName.startsWith(key)) { + const data = paramsTypeStart[key] === '[PC Preview] unknown type' ? `'${paramsTypeStart[key]}'` : `${paramsTypeStart[key]}`; + returnName = `return new Promise((resolve, reject) => { + resolve(${data}); + })`; + } + }); + return returnName; +} + /** * generate return statement; * @param returnType @@ -40,13 +58,19 @@ export function getWarnConsole(interfaceNameOrClassName: string, functionNameOrP export function getReturnStatement(returnType: ReturnTypeEntity, sourceFile: SourceFile): string { if (returnType.returnKind === SyntaxKind.TypeReference) { if (returnType.returnKindName.startsWith('Promise')) { - return `return new Promise((resolve, reject) => { - resolve('[PC Preview] unknown type'); - })`; + return handlePromiseParams(returnType); } else if (returnType.returnKindName === 'T') { return 'return \'[PC Preview] unknown type\''; - } else if (returnType.returnKindName === 'String') { + } else if (returnType.returnKindName === 'object' || returnType.returnKindName === 'Object') { + return 'return {}'; + } else if (returnType.returnKindName === 'Function') { + return 'return \'[PC Preview] unknown type\''; + } else if (returnType.returnKindName === 'String' || returnType.returnKindName === 'string') { return `return ${returnType.returnKindName}(...args)`; + } else if (returnType.returnKindName === 'number' || returnType.returnKindName === 'Number') { + return 'return 0'; + } else if (returnType.returnKindName === 'boolean' || returnType.returnKindName === 'Boolean') { + return 'return false'; } else if (returnType.returnKindName === 'ArrayBuffer') { return `return new ${returnType.returnKindName}(0)`; } else if (returnType.returnKindName.startsWith('Array')) { @@ -147,7 +171,23 @@ export function getReturnStatement(returnType: ReturnTypeEntity, sourceFile: Sou return `return ${getBaseReturnValue(returnName.trimStart().trimEnd())}`; } } else { - return 'return \'[PC Preview] unknown type\''; + let returnName = returnType.returnKindName.trim(); + let temp = true; + if (returnName.endsWith(']')) { + returnName = '[]'; + temp = false; + } else { + Object.keys(paramsTypeStart).forEach(key => { + if (returnType.returnKindName.startsWith(key)) { + returnName = paramsTypeStart[key]; + temp = false; + } + }); + } + if (temp) { + return 'return \'[PC Preview] unknown type\''; + } + return `return ${returnName};`; } return 'return \'[PC Preview] unknown type\''; } @@ -300,10 +340,14 @@ const paramsTypeStart = { 'void': '[PC Preview] unknown type', 'Array': '[]', 'Object': '{}', + 'object': '{}', '{': '{}', 'string': '""', + 'String': '""', 'number': 0, + 'Number': 0, 'boolean': false, + 'Boolean': false, 'ArrayBuffer': 'new ArrayBuffer(0)', 'Uint8Array': 'new Uint8Array()', 'unknown': '[PC Preview] unknown type' @@ -434,6 +478,70 @@ export function getCallbackStatement(mockApi: string, paramTypeString?: string): return outPut; } +/** + * get callback statement + * @returns callback statement + */ +export function getOverloadedFunctionCallbackStatement( + entityArray: Array | Array | Array, + sourceFile: SourceFile, + mockApi: string +): string { + let overloadedCallbackBody = ''; + entityArray.forEach(functionBody => { + let content = ''; + let firstParamContent = ''; + let callbackParamContent = ''; + functionBody.args.forEach(arg => { + if ( + arg.paramTypeString.startsWith("'") && arg.paramTypeString.endsWith("'") || + arg.paramTypeString.startsWith('"') && arg.paramTypeString.endsWith('"') + ) { + const paramTypeStringArr = arg.paramTypeString.split('|'); + firstParamContent += `if (args && [${paramTypeStringArr}].includes(args[0])) {\n`; + } + if (['callback', 'observercallback', 'listener', 'synccallback'].includes(arg.paramName.toLowerCase())) { + callbackParamContent += getCallbackBody(mockApi, arg.paramTypeString); + } + }); + if (firstParamContent) { + content = `${firstParamContent}${callbackParamContent}\n}` + content; + } else { + content += callbackParamContent; + } + overloadedCallbackBody += content; + }); + overloadedCallbackBody += '\n'; + return overloadedCallbackBody; +} + +/** + * get callback statement + * @returns callback statement + */ +function getCallbackBody(mockApi: string, paramString: string): string { + let bodyInfo = `if (args && typeof args[args.length - 1] === 'function') { + args[args.length - 1].call(this,`; + const callbackError = "{'code': '','data': '','name': '','message': '','stack': ''}"; + if (paramString === 'ErrorCallback') { + bodyInfo += callbackError + ');\n}'; + return bodyInfo; + } + let callbackDataParams = { + type: '', + data: '[PC Preview] unknown type' + }; + if (paramString) { + callbackDataParams = setCallbackData(mockApi, paramString); + } + if (callbackDataParams?.type === 'AsyncCallback') { + bodyInfo += ` ${callbackError},`; + } + bodyInfo += callbackDataParams.data === '[PC Preview] unknown type' ? ` '${callbackDataParams.data}');\n` : ` ${callbackDataParams.data});\n`; + bodyInfo += '}'; + return bodyInfo; +} + /** * get iterator template string * @param methodEntity @@ -614,19 +722,11 @@ export function getReturnData(isCallBack: boolean, isReturnPromise: boolean, ret } const data = typeof returnData === 'string' && returnData.startsWith('[PC Preview] unknown') ? `'${returnData}'` : `${returnData}`; if (isReturnPromise) { - if (isCallBack) { - return `else { - return new Promise((resolve, reject) => { - resolve(${data}); - }) - }`; - } else { - return ` + return ` return new Promise((resolve, reject) => { resolve(${data}); }) `; - } } else { return `return ${data}`; } @@ -674,3 +774,7 @@ function getSeparatorParam(returnPromiseParams: string): string { } return otherValue; } + +export const overloadedFunctionArr = ['on', 'off']; + +export const needToAddBrace = ['ViewData', 'AutoFillType']; diff --git a/mock-generate/src/generate/generateExportFunction.ts b/mock-generate/src/generate/generateExportFunction.ts index d45972fb4c5f120a33b7ecd2a61474080c8c1ae8..3925221a5ccebadb794d5a09a87a935b062d207d 100644 --- a/mock-generate/src/generate/generateExportFunction.ts +++ b/mock-generate/src/generate/generateExportFunction.ts @@ -27,11 +27,11 @@ import { getCallbackStatement, getReturnStatement } from './generateCommonUtil'; * @returns */ export function generateExportFunction(functionEntity: FunctionEntity, sourceFile: SourceFile, mockApi: string): string { - if (functionEntity.functionName !== 'getContext') { + let functionBody = ''; + functionBody = `const ${functionEntity.functionName} = function (...args) {`; + if (mockApi.includes(functionBody)) { return ''; } - let functionBody = ''; - functionBody = `global.${functionEntity.functionName} = function (...args) {`; functionBody += `console.warn('The ${functionEntity.functionName} interface in the Previewer is a mocked implementation and may behave differently than on a real device.');\n`; const args = functionEntity.args; @@ -43,5 +43,11 @@ export function generateExportFunction(functionEntity: FunctionEntity, sourceFil functionBody += getReturnStatement(functionEntity.returnType, sourceFile); } functionBody += '}'; + functionBody += ` + if (!global.${functionEntity.functionName}) { + global.${functionEntity.functionName} = ${functionEntity.functionName} + } + `; return functionBody; } + diff --git a/mock-generate/src/generate/generateIndex.ts b/mock-generate/src/generate/generateIndex.ts index 1df5b3a8c70bff6a43c7dda83b11ac4009c8a838..0d88820ed13b891d604565884f6d16540483152b 100644 --- a/mock-generate/src/generate/generateIndex.ts +++ b/mock-generate/src/generate/generateIndex.ts @@ -35,6 +35,7 @@ export function getIndexArray(): Array { export function generateIndex(): string { let indexBody = 'import * as common from \'./@internal/component/ets/common\';\n'; let caseBody = ''; + indexBody += 'import * as etsglobal from \'./@internal/ets/global\';\n'; const filterSet: Set = new Set(); indexArray.forEach(value => { diff --git a/mock-generate/src/generate/generateMockJsFile.ts b/mock-generate/src/generate/generateMockJsFile.ts index 7df4e79e9c4122cfd87d565fb73ba22ae4ff4832..ecc04f43bda971ddbbf1d39f9834fb9c0533a6b8 100644 --- a/mock-generate/src/generate/generateMockJsFile.ts +++ b/mock-generate/src/generate/generateMockJsFile.ts @@ -29,7 +29,8 @@ import { generateModuleDeclaration } from './generateModuleDeclaration'; import { generateStaticFunction } from './generateStaticFunction'; import { addToSystemIndexArray } from './generateSystemIndex'; import { generateTypeAliasDeclaration } from './generateTypeAlias'; -import { generateExportFunction } from './generateExportFunction'; +import { generateCommonFunction } from './generateCommonFunction'; +import { needToAddBrace } from './generateCommonUtil'; /** * generate mock file string @@ -40,7 +41,7 @@ import { generateExportFunction } from './generateExportFunction'; * @returns */ export function generateSourceFileElements(rootName: string, sourceFileEntity: SourceFileEntity, sourceFile: SourceFile, fileName: string): string { - + let mockApi = ''; const mockFunctionElements: Array = []; const dependsSourceFileList = collectReferenceFiles(sourceFile); @@ -55,7 +56,7 @@ export function generateSourceFileElements(rootName: string, sourceFileEntity: S if (sourceFileEntity.moduleDeclarations.length > 0) { sourceFileEntity.moduleDeclarations.forEach(value => { - mockApi += generateModuleDeclaration('', value, sourceFile, fileName, mockApi, extraImport) + '\n'; + mockApi += generateModuleDeclaration('', value, sourceFile, fileName, mockApi, extraImport, sourceFileEntity.importDeclarations) + '\n'; }); } @@ -85,14 +86,14 @@ export function generateSourceFileElements(rootName: string, sourceFileEntity: S if (sourceFileEntity.typeAliasDeclarations.length > 0) { sourceFileEntity.typeAliasDeclarations.forEach(value => { - mockApi += generateTypeAliasDeclaration(value, false, sourceFile, extraImport) + '\n'; + mockApi += generateTypeAliasDeclaration(value, false, sourceFile, extraImport, mockApi) + '\n'; mockFunctionElements.push({ elementName: value.typeAliasName, type: 'typeAlias' }); }); } - if (sourceFileEntity.functionDeclarations.length > 0) { - sourceFileEntity.functionDeclarations.forEach(value => { - mockApi += generateExportFunction(value, sourceFile, mockApi) + '\n'; + if (sourceFileEntity.functionDeclarations.size > 0) { + Array.from(sourceFileEntity.functionDeclarations.keys()).forEach(key => { + mockApi += generateCommonFunction(key, sourceFileEntity.functionDeclarations.get(key), sourceFile, mockApi, true) + '\n'; }); } @@ -207,6 +208,9 @@ export function generateImportDeclaration( sourceFileName === 'Context' && tmpImportPath === './ApplicationContext') { return ''; } + if (!importElements.includes('{') && !importElements.includes('}') && needToAddBrace.includes(importElements)) { + importElements = `{ ${importElements} }`; + } collectAllLegalImports(importElements); return `import ${importElements} from ${importPath}\n`; } @@ -327,7 +331,11 @@ function generateImportElements(importEntity: ImportElementEntity, heritageClaus let importElements = importEntity.importElements; if (!importElements.includes('{') && !importElements.includes('* as') && !heritageClausesArray.includes(importElements) && importEntity.importPath.includes('@ohos')) { const tmpArr = importEntity.importPath.split('.'); - importElements = `{ mock${firstCharacterToUppercase(tmpArr[tmpArr.length - 1].replace('"', '').replace('\'', ''))} }`; + const mockModuleName = firstCharacterToUppercase(tmpArr[tmpArr.length - 1].replace('"', '').replace('\'', '')); + if (importElements === 'observer' && importEntity.importPath.includes('@ohos.arkui.observer')) { + return `{ mockUIObserver as ${importElements}}`; + } + importElements = `{ mock${mockModuleName} }`; } else { // adapt no rules .d.ts if (importElements.trimRight().trimEnd() === 'AccessibilityExtensionContext, { AccessibilityElement }') { diff --git a/mock-generate/src/generate/generateModuleDeclaration.ts b/mock-generate/src/generate/generateModuleDeclaration.ts index 4967044bd072904e52edbd1417ec10eddab5f104..6f75a349d54cccc9bd2e25514afdf1269c4ba5d0 100644 --- a/mock-generate/src/generate/generateModuleDeclaration.ts +++ b/mock-generate/src/generate/generateModuleDeclaration.ts @@ -32,6 +32,7 @@ import { generateStaticFunction } from './generateStaticFunction'; import { addToSystemIndexArray } from './generateSystemIndex'; import { generateTypeAliasDeclaration } from './generateTypeAlias'; import { generateVariableStatementDelcatation } from './generateVariableStatementDeclaration'; +import type { ImportElementEntity } from '../declaration-node/importAndExportDeclaration'; /** * generate declare @@ -43,9 +44,11 @@ import { generateVariableStatementDelcatation } from './generateVariableStatemen * @returns */ export function generateModuleDeclaration(rootName: string, moduleEntity: ModuleBlockEntity, sourceFile: SourceFile, - filename: string, mockApi: string, extraImport: string[]): string { - let moduleName = moduleEntity.moduleName.replace(/["']/g, ''); + filename: string, mockApi: string, extraImport: string[], importDeclarations: ImportElementEntity[]): string { + let innerModuleBody = ''; + const moduleName = moduleEntity.moduleName.replace(/["']/g, ''); let moduleBody = `export function mock${firstCharacterToUppercase(moduleName)}() {\n`; + let enumBody = ''; if (!(moduleEntity.exportModifiers.includes(SyntaxKind.DeclareKeyword) && (moduleEntity.moduleName.startsWith('"') || moduleEntity.moduleName.startsWith('\''))) && path.basename(sourceFile.fileName).startsWith('@ohos') @@ -84,7 +87,7 @@ export function generateModuleDeclaration(rootName: string, moduleEntity: Module if (moduleEntity.typeAliasDeclarations.length > 0) { moduleEntity.typeAliasDeclarations.forEach(value => { - outBody += generateTypeAliasDeclaration(value, true, sourceFile, extraImport) + '\n'; + outBody += generateTypeAliasDeclaration(value, true, sourceFile, extraImport, mockApi) + '\n'; }); } @@ -107,9 +110,9 @@ export function generateModuleDeclaration(rootName: string, moduleEntity: Module if (moduleEntity.interfaceDeclarations.length > 0) { moduleEntity.interfaceDeclarations.forEach(value => { if (value.exportModifiers.length > 0) { - outBody += generateInterfaceDeclaration(moduleName, value, sourceFile, false, mockApi, moduleEntity.interfaceDeclarations) + ';\n'; + outBody += generateInterfaceDeclaration(moduleName, value, sourceFile, false, mockApi, moduleEntity.interfaceDeclarations, importDeclarations, extraImport) + ';\n'; } else { - moduleBody += '\t' + generateInterfaceDeclaration(moduleName, value, sourceFile, false, mockApi, moduleEntity.interfaceDeclarations) + ';\n'; + moduleBody += '\t' + generateInterfaceDeclaration(moduleName, value, sourceFile, false, mockApi, moduleEntity.interfaceDeclarations, importDeclarations, extraImport) + ';\n'; } }); } @@ -119,7 +122,7 @@ export function generateModuleDeclaration(rootName: string, moduleEntity: Module if (value.exportModifiers.length > 0) { outBody += generateEnumDeclaration(moduleName, value) + '\n'; } else { - moduleBody += '\t' + generateEnumDeclaration(moduleName, value) + '\n'; + enumBody += generateEnumDeclaration(moduleName, value); } }); } @@ -127,10 +130,21 @@ export function generateModuleDeclaration(rootName: string, moduleEntity: Module let functionBody = ''; if (moduleEntity.functionDeclarations.size > 0) { moduleEntity.functionDeclarations.forEach(value => { - functionBody += '\t' + generateCommonFunction(moduleName, value, sourceFile, mockApi) + '\n'; + functionBody += '\t' + generateCommonFunction(moduleName, value, sourceFile, mockApi, false) + '\n'; }); } + if (moduleEntity.moduleDeclarations.length > 0) { + moduleEntity.moduleDeclarations.forEach(value => { + if (!value.moduleName.startsWith("'") && !value.moduleName.startsWith('"')) { + innerModuleBody += generateInnerModuleDeclaration(value, sourceFile, filename, mockApi, extraImport, importDeclarations); + } + }); + } + if (innerModuleBody) { + moduleBody += innerModuleBody + '\n'; + } + moduleBody += '\t' + `const ${moduleName} = {`; if (moduleEntity.variableStatements.length > 0) { moduleEntity.variableStatements.forEach(value => { @@ -144,7 +158,7 @@ export function generateModuleDeclaration(rootName: string, moduleEntity: Module let sourceFileFunctionBody = ''; if (sourceFileFunctions.size > 0) { sourceFileFunctions.forEach(value => { - sourceFileFunctionBody += generateCommonFunction(moduleName, value, sourceFile, mockApi); + sourceFileFunctionBody += '\n' + generateCommonFunction(moduleName, value, sourceFile, mockApi, false); }); } @@ -153,7 +167,7 @@ export function generateModuleDeclaration(rootName: string, moduleEntity: Module if (sourceFileVariableStatements.length > 0) { sourceFileVariableStatements.forEach(value => { value.forEach(val => { - sourceFileStatementBody += generateVariableStatementDelcatation(val, false); + sourceFileStatementBody += '\n' + generateVariableStatementDelcatation(val, false); }); }); } @@ -165,7 +179,11 @@ export function generateModuleDeclaration(rootName: string, moduleEntity: Module const exports = getModuleExportElements(moduleEntity); let exportString = ''; exports.forEach(value => { - exportString += `${value.name}: ${value.name},\n`; + if (value.type === 'module' && !value.name.startsWith("'") && !value.name.startsWith('"')) { + exportString += `${value.name}: mock${value.name}(),\n`; + } else { + exportString += `${value.name}: ${value.name},\n`; + } }); if (exportString !== '') { moduleBody += '\t' + exportString; @@ -174,6 +192,104 @@ export function generateModuleDeclaration(rootName: string, moduleEntity: Module moduleBody += '\t};'; moduleBody += `\n\treturn ${moduleName};}\n`; moduleBody += outBody; + moduleBody = enumBody + moduleBody; + return moduleBody; +} + +function generateInnerModuleDeclaration(moduleEntity: ModuleBlockEntity, sourceFile: SourceFile, + filename: string, mockApi: string, extraImport: string[], importDeclarations: ImportElementEntity[]): string { + let innerModuleBody = ''; + const innerModuleName = moduleEntity.moduleName.replace(/["']/g, ''); + let moduleBody = `function mock${innerModuleName}() {\n`; + let innerOutBody = ''; + let innerFunctionBody = ''; + + if (moduleEntity.typeAliasDeclarations.length) { + moduleEntity.typeAliasDeclarations.forEach(value => { + innerOutBody += generateTypeAliasDeclaration(value, true, sourceFile, extraImport, mockApi) + '\n'; + }); + } + + if (moduleEntity.moduleImportEquaqls.length) { + moduleEntity.moduleImportEquaqls.forEach(value => { + innerOutBody += generateImportEqual(value) + '\n'; + }); + } + + if (moduleEntity.classDeclarations.length) { + moduleEntity.classDeclarations.forEach(value => { + if (value.exportModifiers.length && value.exportModifiers.includes(SyntaxKind.ExportKeyword)) { + innerOutBody += generateClassDeclaration(innerModuleName, value, false, '', '', sourceFile, false, mockApi) + '\n'; + } else { + moduleBody += '\t' + generateClassDeclaration(innerModuleName, value, false, '', '', sourceFile, true, mockApi) + '\n'; + } + }); + } + + if (moduleEntity.interfaceDeclarations.length) { + moduleEntity.interfaceDeclarations.forEach(value => { + if (value.exportModifiers.length) { + innerOutBody += generateInterfaceDeclaration(innerModuleName, value, sourceFile, false, mockApi, moduleEntity.interfaceDeclarations, importDeclarations, extraImport) + ';\n'; + } else { + moduleBody += '\t' + generateInterfaceDeclaration(innerModuleName, value, sourceFile, false, mockApi, moduleEntity.interfaceDeclarations, importDeclarations, extraImport) + ';\n'; + } + }); + } + + if (moduleEntity.enumDeclarations.length) { + moduleEntity.enumDeclarations.forEach(value => { + if (value.exportModifiers.length) { + innerOutBody += generateEnumDeclaration(innerModuleName, value) + '\n'; + } else { + moduleBody += generateEnumDeclaration(innerModuleName, value); + } + }); + } + + if (moduleEntity.functionDeclarations.size) { + moduleEntity.functionDeclarations.forEach(value => { + innerFunctionBody += '\n' + generateCommonFunction(innerModuleName, value, sourceFile, mockApi, false) + '\n'; + }); + } + + if (moduleEntity.moduleDeclarations.length) { + moduleEntity.moduleDeclarations.forEach(value => { + if (!value.moduleName.startsWith("'") && !value.moduleName.startsWith('"')) { + innerModuleBody += generateInnerModuleDeclaration(value, sourceFile, filename, mockApi, extraImport, importDeclarations); + } + }); + } + if (innerModuleBody) { + moduleBody += innerModuleBody + '\n'; + } + + moduleBody += `const ${innerModuleName} = {\n`; + if (moduleEntity.variableStatements.length) { + moduleEntity.variableStatements.forEach(value => { + value.forEach(val => { + moduleBody += generateVariableStatementDelcatation(val, false) + '\n'; + }); + }); + } + + moduleBody += innerFunctionBody + '\n'; + + const exportArr = getModuleExportElements(moduleEntity); + let innerExportString = ''; + exportArr.forEach(value => { + if (value.type === 'module' && !value.name.startsWith("'") && !value.name.startsWith('"')) { + innerExportString += `${value.name}: mock${value.name}(),\n`; + } else { + innerExportString += `${value.name}: ${value.name},\n`; + } + }); + if (innerExportString !== '') { + moduleBody += '\t' + innerExportString; + } + + moduleBody += '\t};'; + moduleBody += `\n\treturn ${innerModuleName};}\n`; + moduleBody += innerOutBody; return moduleBody; } @@ -200,7 +316,7 @@ function generateInnerDeclareModule(moduleEntity: ModuleBlockEntity): string { * @param extraImport * @returns */ -function generateInnerModule(moduleEntity: ModuleBlockEntity, sourceFile: SourceFile, extraImport: string[]): string { +function generateInnerModule(moduleEntity: ModuleBlockEntity, sourceFile: SourceFile, extraImport: string[], mockApi: string): string { const moduleName = moduleEntity.moduleName; let innerModuleBody = `const ${moduleName} = (()=> {`; @@ -212,7 +328,7 @@ function generateInnerModule(moduleEntity: ModuleBlockEntity, sourceFile: Source if (moduleEntity.typeAliasDeclarations.length > 0) { moduleEntity.typeAliasDeclarations.forEach(value => { - innerModuleBody += generateTypeAliasDeclaration(value, true, sourceFile, extraImport) + '\n'; + innerModuleBody += generateTypeAliasDeclaration(value, true, sourceFile, extraImport, mockApi) + '\n'; }); } @@ -231,7 +347,7 @@ function generateInnerModule(moduleEntity: ModuleBlockEntity, sourceFile: Source let functionBody = 'return {'; if (moduleEntity.functionDeclarations.size > 0) { moduleEntity.functionDeclarations.forEach(value => { - functionBody += generateCommonFunction(moduleName, value, sourceFile, '') + '\n'; + functionBody += generateCommonFunction(moduleName, value, sourceFile, '', false) + '\n'; }); } diff --git a/mock-generate/src/generate/generatePropertySignatureDeclaration.ts b/mock-generate/src/generate/generatePropertySignatureDeclaration.ts index 335e61812665b641d37b7c78dd3cd99e1e139bb9..6dddcd65088470ee7a904e97d4123c7842b38920 100644 --- a/mock-generate/src/generate/generatePropertySignatureDeclaration.ts +++ b/mock-generate/src/generate/generatePropertySignatureDeclaration.ts @@ -36,7 +36,13 @@ export function generatePropertySignatureDeclaration(rootName: string, propertyS propertySignatureBody += getCallbackStatement(mockApi); propertySignatureBody += '},\n'; } else { - if (propertySignature.propertyTypeName.startsWith('{')) { + if ( + (propertySignature.propertyTypeName.startsWith('{') || + propertySignature.propertyTypeName.startsWith('Record<') || + propertySignature.propertyTypeName.startsWith('Object') || + propertySignature.propertyTypeName.startsWith('object')) && + !propertySignature.propertyTypeName.endsWith(']') + ) { propertySignatureBody = `${propertySignature.propertyName}: {},`; } else if (propertySignature.kind === SyntaxKind.TypeReference) { if (propertySignature.propertyTypeName.startsWith('Array')) { diff --git a/mock-generate/src/generate/generateSystemIndex.ts b/mock-generate/src/generate/generateSystemIndex.ts index 386f00f48540e3dc3dd59c2b9891bba398572ea2..1c7c488f7e31479771fd0db6d77ef17c4ed533c8 100644 --- a/mock-generate/src/generate/generateSystemIndex.ts +++ b/mock-generate/src/generate/generateSystemIndex.ts @@ -17,7 +17,7 @@ const systemIndexArray: Array = []; const systemNoMockArray = ['system.app', 'system.configuration', 'system.device', 'system.mediaquery', 'system.prompt', 'system.router']; -export function addToSystemIndexArray(systemIndexEntity: SystemIndexEntity) { +export function addToSystemIndexArray(systemIndexEntity: SystemIndexEntity): void { systemIndexArray.push(systemIndexEntity); } diff --git a/mock-generate/src/generate/generateTypeAlias.ts b/mock-generate/src/generate/generateTypeAlias.ts index 5836ebe8c7158e8435b6c67240044dc629a252d4..156be4bd07c6b1d07d1c08badcf0619369b0c98f 100644 --- a/mock-generate/src/generate/generateTypeAlias.ts +++ b/mock-generate/src/generate/generateTypeAlias.ts @@ -30,7 +30,7 @@ const interceptIndex = 2; * @returns */ export function generateTypeAliasDeclaration( - typeAliasEntity: TypeAliasEntity, isInner: boolean, sourceFile: SourceFile, extraImport: string[] + typeAliasEntity: TypeAliasEntity, isInner: boolean, sourceFile: SourceFile, extraImport: string[], mockApi: string ): string { let typeAliasName = ''; if (!isInner) {