diff --git a/js_framework_build.sh b/js_framework_build.sh index fef25a10..cb2ffd11 100755 --- a/js_framework_build.sh +++ b/js_framework_build.sh @@ -57,14 +57,14 @@ if [ -d "$prebuilts_path" ]; then cp -r $2 $9 cd $9 if [ "${11}" == 'true' ];then - ./node-v12.18.4-darwin-x64/bin/node ./mock-generate/build.js && + ./node-v12.18.4-darwin-x64/bin/node ./mock-generate/build.js ./node-v12.18.4-darwin-x64/bin/node build_jsmock_system_plugin.js || exit 1 & ./node-v12.18.4-darwin-x64/bin/node build_strip_native_min.js || exit 1 & # run unit test ./node-v12.18.4-darwin-x64/bin/node node_modules/.bin/mocha -r ts-node/register test/lib.ts test/ut/**/*.ts test/ut/*.ts || exit 1 & wait else - ./node-v12.18.4-linux-x64/bin/node ./mock-generate/build.js && + ./node-v12.18.4-linux-x64/bin/node ./mock-generate/build.js ./node-v12.18.4-linux-x64/bin/node build_jsmock_system_plugin.js || exit 1 & ./node-v12.18.4-linux-x64/bin/node build_strip_native_min.js || exit 1 & # run unit test diff --git a/mock-generate/src/common/commonUtils.ts b/mock-generate/src/common/commonUtils.ts index 0801ba41..b764a273 100644 --- a/mock-generate/src/common/commonUtils.ts +++ b/mock-generate/src/common/commonUtils.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import path from 'path'; import { CallSignatureDeclaration, ComputedPropertyName, FunctionDeclaration, Identifier, isClassDeclaration, diff --git a/mock-generate/src/declaration-node/callSignatureDeclaration.ts b/mock-generate/src/declaration-node/callSignatureDeclaration.ts index c68a9b5c..885032f2 100644 --- a/mock-generate/src/declaration-node/callSignatureDeclaration.ts +++ b/mock-generate/src/declaration-node/callSignatureDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { CallSignatureDeclaration, Node, SourceFile } from 'typescript'; import { getFunctionAndMethodReturnInfo, getParameter, getPropertyName, diff --git a/mock-generate/src/declaration-node/classDeclaration.ts b/mock-generate/src/declaration-node/classDeclaration.ts index 61956779..8f1592bc 100644 --- a/mock-generate/src/declaration-node/classDeclaration.ts +++ b/mock-generate/src/declaration-node/classDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { ClassDeclaration, isConstructorDeclaration, isMethodDeclaration, isPropertyDeclaration, diff --git a/mock-generate/src/declaration-node/constructorDeclaration.ts b/mock-generate/src/declaration-node/constructorDeclaration.ts index 82e8fe1b..ee544768 100644 --- a/mock-generate/src/declaration-node/constructorDeclaration.ts +++ b/mock-generate/src/declaration-node/constructorDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { ConstructorDeclaration, isIdentifier, Node, SourceFile } from 'typescript'; /** diff --git a/mock-generate/src/declaration-node/enumDeclaration.ts b/mock-generate/src/declaration-node/enumDeclaration.ts index 1cc509b6..abac4762 100644 --- a/mock-generate/src/declaration-node/enumDeclaration.ts +++ b/mock-generate/src/declaration-node/enumDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { EnumDeclaration, SourceFile } from 'typescript'; import { getExportKeyword, getPropertyName } from '../common/commonUtils'; diff --git a/mock-generate/src/declaration-node/functionDeclaration.ts b/mock-generate/src/declaration-node/functionDeclaration.ts index 7ed2f5f4..990fbb7e 100644 --- a/mock-generate/src/declaration-node/functionDeclaration.ts +++ b/mock-generate/src/declaration-node/functionDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { FunctionDeclaration, Node, SourceFile } from 'typescript'; import { getFunctionAndMethodReturnInfo, getParameter, ParameterEntity, ReturnTypeEntity } from '../common/commonUtils'; diff --git a/mock-generate/src/declaration-node/heritageClauseDeclaration.ts b/mock-generate/src/declaration-node/heritageClauseDeclaration.ts index b736877c..39b6f2da 100644 --- a/mock-generate/src/declaration-node/heritageClauseDeclaration.ts +++ b/mock-generate/src/declaration-node/heritageClauseDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { HeritageClause, Node, SourceFile, SyntaxKind } from 'typescript'; /** diff --git a/mock-generate/src/declaration-node/importAndExportDeclaration.ts b/mock-generate/src/declaration-node/importAndExportDeclaration.ts index b1373930..514a5b35 100644 --- a/mock-generate/src/declaration-node/importAndExportDeclaration.ts +++ b/mock-generate/src/declaration-node/importAndExportDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { ExportAssignment, ExportDeclaration, ImportDeclaration, ImportEqualsDeclaration, isImportDeclaration, Node, SourceFile } from 'typescript'; diff --git a/mock-generate/src/declaration-node/indexSignatureDeclaration.ts b/mock-generate/src/declaration-node/indexSignatureDeclaration.ts index 9aaac595..461d2ae1 100644 --- a/mock-generate/src/declaration-node/indexSignatureDeclaration.ts +++ b/mock-generate/src/declaration-node/indexSignatureDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { IndexSignatureDeclaration, SourceFile } from 'typescript'; /** diff --git a/mock-generate/src/declaration-node/interfaceDeclaration.ts b/mock-generate/src/declaration-node/interfaceDeclaration.ts index d498adfb..31477b52 100644 --- a/mock-generate/src/declaration-node/interfaceDeclaration.ts +++ b/mock-generate/src/declaration-node/interfaceDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { InterfaceDeclaration, isCallSignatureDeclaration, isConstructSignatureDeclaration, isHeritageClause, isIndexSignatureDeclaration, isMethodSignature, isPropertySignature, @@ -33,6 +48,12 @@ export function getInterfaceDeclaration(interfaceNode: InterfaceDeclaration, sou const typeParameters: Array = []; const indexSignature: Array = []; + if (interfaceNode.heritageClauses !== undefined) { + interfaceNode.heritageClauses.forEach(value => { + heritageClauses.push(getHeritageClauseDeclaration(value, sourceFile)); + }); + } + interfaceNode.members.forEach(value => { if (isPropertySignature(value)) { interfacePropertySignatures.push(getPropertySignatureDeclaration(value, sourceFile)); diff --git a/mock-generate/src/declaration-node/methodDeclaration.ts b/mock-generate/src/declaration-node/methodDeclaration.ts index 3bbedcac..dec63959 100644 --- a/mock-generate/src/declaration-node/methodDeclaration.ts +++ b/mock-generate/src/declaration-node/methodDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { isComputedPropertyName, MethodDeclaration, Node, SourceFile } from 'typescript'; import { getFunctionAndMethodReturnInfo, getModifiers, getParameter, diff --git a/mock-generate/src/declaration-node/methodSignatureDeclaration.ts b/mock-generate/src/declaration-node/methodSignatureDeclaration.ts index 74ef04d0..15f7d14c 100644 --- a/mock-generate/src/declaration-node/methodSignatureDeclaration.ts +++ b/mock-generate/src/declaration-node/methodSignatureDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { MethodSignature, Node, SourceFile } from 'typescript'; import { getFunctionAndMethodReturnInfo, getParameter, getPropertyName, diff --git a/mock-generate/src/declaration-node/moduleDeclaration.ts b/mock-generate/src/declaration-node/moduleDeclaration.ts index b38caf80..27b9673a 100644 --- a/mock-generate/src/declaration-node/moduleDeclaration.ts +++ b/mock-generate/src/declaration-node/moduleDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { isClassDeclaration, isEnumDeclaration, isExportDeclaration, isFunctionDeclaration, isIdentifier, isImportEqualsDeclaration, isInterfaceDeclaration, isModuleBlock, isModuleDeclaration, isTypeAliasDeclaration, diff --git a/mock-generate/src/declaration-node/propertyDeclaration.ts b/mock-generate/src/declaration-node/propertyDeclaration.ts index 488c0575..c22f8a66 100644 --- a/mock-generate/src/declaration-node/propertyDeclaration.ts +++ b/mock-generate/src/declaration-node/propertyDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { PropertyDeclaration, SourceFile } from 'typescript'; import { getPropertyName } from '../common/commonUtils'; diff --git a/mock-generate/src/declaration-node/propertySignatureDeclaration.ts b/mock-generate/src/declaration-node/propertySignatureDeclaration.ts index 1c46f166..f137d478 100644 --- a/mock-generate/src/declaration-node/propertySignatureDeclaration.ts +++ b/mock-generate/src/declaration-node/propertySignatureDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { PropertySignature, SourceFile } from 'typescript'; import { getPropertyName } from '../common/commonUtils'; diff --git a/mock-generate/src/declaration-node/sourceFileElementsAssemply.ts b/mock-generate/src/declaration-node/sourceFileElementsAssemply.ts index ba4d0cff..d889f954 100644 --- a/mock-generate/src/declaration-node/sourceFileElementsAssemply.ts +++ b/mock-generate/src/declaration-node/sourceFileElementsAssemply.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { isClassDeclaration, isEnumDeclaration, isExportAssignment, isExportDeclaration, isFunctionDeclaration, isImportDeclaration, isInterfaceDeclaration, isModuleDeclaration, isTypeAliasDeclaration, isVariableStatement, diff --git a/mock-generate/src/declaration-node/typeAliasDeclaration.ts b/mock-generate/src/declaration-node/typeAliasDeclaration.ts index 712d6b12..2a5acc81 100644 --- a/mock-generate/src/declaration-node/typeAliasDeclaration.ts +++ b/mock-generate/src/declaration-node/typeAliasDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { isTypeLiteralNode, isTypeReferenceNode, isUnionTypeNode, Node, SourceFile, TypeAliasDeclaration diff --git a/mock-generate/src/declaration-node/typeParameterDeclaration.ts b/mock-generate/src/declaration-node/typeParameterDeclaration.ts index b1b7a4be..f4a1d7fb 100644 --- a/mock-generate/src/declaration-node/typeParameterDeclaration.ts +++ b/mock-generate/src/declaration-node/typeParameterDeclaration.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { Node, SourceFile, TypeParameterDeclaration } from 'typescript'; /** diff --git a/mock-generate/src/declaration-node/variableStatementResolve.ts b/mock-generate/src/declaration-node/variableStatementResolve.ts index 57363ccd..b16d84a4 100644 --- a/mock-generate/src/declaration-node/variableStatementResolve.ts +++ b/mock-generate/src/declaration-node/variableStatementResolve.ts @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import { isIdentifier, SourceFile, VariableStatement } from 'typescript'; /** diff --git a/mock-generate/src/generate/generateClassDeclaration.ts b/mock-generate/src/generate/generateClassDeclaration.ts new file mode 100644 index 00000000..7f0bdb3b --- /dev/null +++ b/mock-generate/src/generate/generateClassDeclaration.ts @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SourceFile, SyntaxKind } from 'typescript'; +import { firstCharacterToUppercase } from '../common/commonUtils'; +import { ClassEntity } from '../declaration-node/classDeclaration'; +import { generateCommonMethod } from './generateCommonMethod'; +import { getWarnConsole } from './generateCommonUtil'; +import { generatePropertyDeclaration } from './generatePropertyDeclaration'; +import { generateStaticFunction } from './generateStaticFunction'; + +/** + * generate class + * @param rootName + * @param classEntity + * @param isSystem + * @param globalName + * @param filename + * @param sourceFile + * @param isInnerMockFunction + * @returns + */ +export function generateClassDeclaration(rootName: string, classEntity: ClassEntity, isSystem: boolean, globalName: string, + filename: string, sourceFile: SourceFile, isInnerMockFunction: boolean): string { + if (isSystem) { + return ''; + } + + const className = firstCharacterToUppercase(classEntity.className); + let classBody = ''; + if (classEntity.exportModifiers.includes(SyntaxKind.ExportKeyword) && !isInnerMockFunction) { + classBody += `export const ${className} = class ${className} `; + } else { + classBody += `const ${className} = class ${className} `; + } + + let isExtend = false; + + if (classEntity.heritageClauses.length > 0) { + classEntity.heritageClauses.forEach(value => { + if (value.clauseToken === 'extends') { + isExtend = true; + classBody += `${value.clauseToken} `; + value.types.forEach((val, index) => { + if (index !== value.types.length - 1) { + classBody += `${val},`; + } else { + classBody += `${val}`; + } + }); + } + }); + } + + if (!isSystem) { + classBody += '{'; + if (classEntity.classConstructor.length > 1) { + classBody += `constructor(...arg) { `; + } else { + classBody += `constructor() { `; + } + if (isExtend) { + classBody += `super();`; + } + classBody += getWarnConsole(className, 'constructor'); + } + if (classEntity.classProperty.length > 0) { + classEntity.classProperty.forEach(value => { + classBody += generatePropertyDeclaration(className, value, sourceFile) + '\n'; + }); + } + + if (classEntity.classMethod.size > 0) { + classEntity.classMethod.forEach(value => { + classBody += generateCommonMethod(className, value, sourceFile); + }); + } + + classBody += '}\n};'; + if (!filename.startsWith('system_')) { + if (classEntity.staticMethods.length > 0) { + let staticMethodBody = ''; + classEntity.staticMethods.forEach(value => { + staticMethodBody += generateStaticFunction(value, false, sourceFile) + '\n'; + }); + classBody += staticMethodBody; + } + } + return classBody; +} diff --git a/mock-generate/src/generate/generateCommonFunction.ts b/mock-generate/src/generate/generateCommonFunction.ts new file mode 100644 index 00000000..528311af --- /dev/null +++ b/mock-generate/src/generate/generateCommonFunction.ts @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SourceFile, SyntaxKind } from 'typescript'; +import { FunctionEntity } from '../declaration-node/functionDeclaration'; +import { getCallbackStatement, getReturnStatement, getWarnConsole } from './generateCommonUtil'; + +/** + * generate function + * @param rootName + * @param functionArray + * @param sourceFile + * @returns + */ +export function generateCommonFunction(rootName: string, functionArray: Array, sourceFile: SourceFile): string { + let functionBody = ''; + const functionEntity = functionArray[0]; + functionBody = `${functionEntity.functionName}: function(...args) {`; + functionBody += getWarnConsole(rootName, functionEntity.functionName); + + if (functionArray.length === 1) { + const args = functionEntity.args; + const len = args.length; + if (args.length > 0 && args[len - 1].paramName.toLowerCase().includes('callback')) { + functionBody += getCallbackStatement(); + } + if (functionEntity.returnType.returnKind !== SyntaxKind.VoidKeyword) { + functionBody += getReturnStatement(functionEntity.returnType, sourceFile); + } + } else { + const argSet: Set = new Set(); + const returnSet: Set = new Set(); + let isCallBack = false; + functionArray.forEach(value => { + returnSet.add(value.returnType.returnKindName); + value.args.forEach(arg => { + argSet.add(arg.paramName); + if (arg.paramName.toLowerCase().includes('callback')) { + isCallBack = true; + } + }); + }); + if (isCallBack) { + functionBody += getCallbackStatement(); + } + let isReturnPromise = false; + returnSet.forEach(value => { + if (value.startsWith('Promise')) { + isReturnPromise = true; + } + }); + + if (isReturnPromise && isCallBack) { + functionBody += `else { + return new Promise((resolve, reject) => { + resolve('[PC Preview] unknow boolean'); + }) + }`; + } + } + functionBody += '},'; + return functionBody; +} diff --git a/mock-generate/src/generate/generateCommonMethod.ts b/mock-generate/src/generate/generateCommonMethod.ts new file mode 100644 index 00000000..d733fa32 --- /dev/null +++ b/mock-generate/src/generate/generateCommonMethod.ts @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SourceFile, SyntaxKind } from 'typescript'; +import { MethodEntity } from '../declaration-node/methodDeclaration'; +import { + generateSymbolIterator, getCallbackStatement, + getReturnStatement, getWarnConsole +} from './generateCommonUtil'; + +/** + * generate class method + * @param rootName + * @param methodArray + * @param sourceFile + * @returns + */ +export function generateCommonMethod(rootName: string, methodArray: Array, sourceFile: SourceFile): string { + let methodBody = ''; + const methodEntity = methodArray[0]; + if (methodEntity.functionName.name === 'Symbol.iterator') { + methodBody += `this[${methodEntity.functionName.name}] = function(...args) {`; + methodBody += getWarnConsole(rootName, methodEntity.functionName.name); + methodBody += generateSymbolIterator(methodEntity); + methodBody += '};\n'; + return methodBody; + } else { + methodBody += `this.${methodEntity.functionName.name} = function(...args) {`; + methodBody += getWarnConsole(rootName, methodEntity.functionName.name); + } + + if (methodArray.length === 1) { + const args = methodEntity.args; + const len = args.length; + if (args.length > 0 && args[len - 1].paramName.toLowerCase().includes('callback')) { + methodBody += getCallbackStatement(); + } + if (methodEntity.returnType.returnKind !== SyntaxKind.VoidKeyword) { + if (methodEntity.functionName.name === 'getApplicationContext') { + methodBody += 'return new Context();'; + } else { + methodBody += getReturnStatement(methodEntity.returnType, sourceFile); + } + } + } else { + const argSet: Set = new Set(); + const returnSet: Set = new Set(); + let isCallBack = false; + methodArray.forEach(value => { + returnSet.add(value.returnType.returnKindName); + value.args.forEach(arg => { + argSet.add(arg.paramName); + if (arg.paramName.toLowerCase().includes('callback')) { + isCallBack = true; + } + }); + }); + if (isCallBack) { + methodBody += getCallbackStatement(); + } + let isReturnPromise = false; + returnSet.forEach(value => { + if (value.startsWith('Promise')) { + isReturnPromise = true; + } + }); + + if (isReturnPromise && isCallBack) { + methodBody += `else { + return new Promise((resolve, reject) => { + resolve('[PC Preview] unknow boolean'); + }) + }`; + } else { + methodBody += `return new Promise((resolve, reject) => { + resolve('[PC preview] unknown type'); + });`; + } + } + methodBody += '};\n'; + return methodBody; +} diff --git a/mock-generate/src/generate/generateCommonMethodSignature.ts b/mock-generate/src/generate/generateCommonMethodSignature.ts new file mode 100644 index 00000000..9de61ae3 --- /dev/null +++ b/mock-generate/src/generate/generateCommonMethodSignature.ts @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SourceFile, SyntaxKind } from 'typescript'; +import { MethodSignatureEntity } from '../declaration-node/methodSignatureDeclaration'; +import { getCallbackStatement, getReturnStatement, getWarnConsole } from './generateCommonUtil'; + +/** + * generate interface signature method + * @param rootName + * @param methodSignatureArray + * @param sourceFile + * @returns + */ +export function generateCommonMethodSignature(rootName: string, methodSignatureArray: Array, sourceFile: SourceFile): string { + let methodSignatureBody = ''; + const methodEntity = methodSignatureArray[0]; + methodSignatureBody += `${methodEntity.functionName}: function(...args) {`; + methodSignatureBody += getWarnConsole(rootName, methodEntity.functionName); + if (methodSignatureArray.length === 1) { + const args = methodEntity.args; + const len = args.length; + if (args.length > 0 && args[len - 1].paramName.toLowerCase().includes('callback')) { + methodSignatureBody += getCallbackStatement(); + } + if (methodEntity.returnType.returnKind !== SyntaxKind.VoidKeyword) { + methodSignatureBody += getReturnStatement(methodEntity.returnType, sourceFile); + } + } else { + const argSet: Set = new Set(); + const returnSet: Set = new Set(); + let isCallBack = false; + methodSignatureArray.forEach(value => { + returnSet.add(value.returnType.returnKindName); + value.args.forEach(arg => { + argSet.add(arg.paramName); + if (arg.paramName.toLowerCase().includes('callback')) { + isCallBack = true; + } + }); + }); + if (isCallBack) { + methodSignatureBody += getCallbackStatement(); + } + let isReturnPromise = false; + returnSet.forEach(value => { + if (value.startsWith('Promise')) { + isReturnPromise = true; + } + }); + if (isReturnPromise) { + methodSignatureBody += `else { + return new Promise((resolve, reject) => { + resolve('[PC Preview] unknow boolean'); + }) + }`; + } + } + methodSignatureBody += '},\n'; + return methodSignatureBody; +} diff --git a/mock-generate/src/generate/generateCommonUtil.ts b/mock-generate/src/generate/generateCommonUtil.ts new file mode 100644 index 00000000..2ba72095 --- /dev/null +++ b/mock-generate/src/generate/generateCommonUtil.ts @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SourceFile, SyntaxKind } from 'typescript'; +import { firstCharacterToUppercase, getClassNameSet, ReturnTypeEntity } from '../common/commonUtils'; +import { getImportDeclarationArray, ImportElementEntity } from '../declaration-node/importAndExportDeclaration'; +import { MethodEntity } from '../declaration-node/methodDeclaration'; + +/** + * get warn console template + * @param interfaceNameOrClassName + * @param functionNameOrPropertyName + * @returns + */ +export function getWarnConsole(interfaceNameOrClassName: string, functionNameOrPropertyName: string): string { + return `console.warn('${interfaceNameOrClassName}.${functionNameOrPropertyName} interface mocked in the Previewer. How this interface works on the Previewer may be different from that on a real device.');\n`; +} + +/** + * generate return statement; + * @param returnType + * @param sourceFile + * @returns + */ +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] unkonwn type'); + })`; + } else if (returnType.returnKindName === 'T') { + return `return '[PC Preview] unkonwn type'`; + } else if (returnType.returnKindName === 'String') { + return `return ${returnType.returnKindName}(...args)`; + } else if (returnType.returnKindName.startsWith('Array')) { + return `return [${generateGenericTypeToMockValue(returnType.returnKindName)}]`; + } else if (returnType.returnKindName.startsWith('Readonly')) { + return `return ${returnType.returnKindName.split('<')[1].split('>')[0]}`; + } else if (checkIsGenericSymbol(returnType.returnKindName)) { + return `return '[PC Preview] unkonwn iterableiterator_${returnType.returnKindName}'`; + } else if (returnType.returnKindName.startsWith('Uint8Array')) { + return `return new ${returnType.returnKindName}()`; + } else if (returnType.returnKindName.startsWith('IterableIterator')) { + if (returnType.returnKindName.includes(',')) { + return `const IteratorEntriesMock = { + *[Symbol.iterator]() { + yield ['[PC Preview] unkonwn paramIterMock_K', '[PC Preview] unkonwn paramIterMock_V']; + } + }; + return IteratorEntriesMock;`; + } else { + return `const IteratorStringMock = { + *[Symbol.iterator]() { + yield '[PC Preview] unkonwn string'; + } + }; + return IteratorStringMock;`; + } + } else if (returnType.returnKindName.includes('')) { + const tmpReturn = returnType.returnKindName.split('<')[0]; + if (tmpReturn.startsWith('Array')) { + return `return []`; + } else { + `return new ${tmpReturn}()`; + } + } else if (returnType.returnKindName.includes('<')) { + return `return new ${returnType.returnKindName.split('<')[0]}()`; + } else { + if (getClassNameSet().has(returnType.returnKindName)) { + if (returnType.returnKindName === 'Want') { + return `return mockWant().Want`; + } else { + return `return new ${returnType.returnKindName}()`; + } + } else if (propertyTypeWhiteList(returnType.returnKindName) === returnType.returnKindName) { + return `return ${getTheRealReferenceFromImport(sourceFile, returnType.returnKindName)}`; + } else { + return `return ${propertyTypeWhiteList(returnType.returnKindName)}`; + } + } + } else if (returnType.returnKind === SyntaxKind.UnionType) { + const returnNames = returnType.returnKindName.split('|'); + let returnName = returnNames[0]; + for (let i = 0; i < returnNames.length; i++) { + if (!returnNames[i].includes('[]') && !returnNames[i].includes('<')) { + returnName = returnNames[i]; + break; + } + } + if (getClassNameSet().has(returnName)) { + return `return new ${returnName}()`; + } else { + return `return ${getBaseReturnValue(returnName.trimStart().trimEnd())}`; + } + } else { + return `return '[PC Preview] unkonwn type'`; + } + return `return '[PC Preview] unkonwn type'`; +} + +/** + * special property whitelist + * @param propertyTypeName + * @returns + */ +export function propertyTypeWhiteList(propertyTypeName: string): any { + const whiteList = ['GLboolean', 'GLuint', 'GLenum', 'GLint', 'NotificationFlags']; + if (whiteList.includes(propertyTypeName)) { + if (propertyTypeName === 'NotificationFlags' || propertyTypeName === 'GLenum') { + return `'[PC Preview] unkonwn ${propertyTypeName}'`; + } else if (propertyTypeName === 'GLboolean') { + return true; + } else { + return 0; + } + } else { + return propertyTypeName; + } +} + +/** + * get basic return value + * @param value + * @returns + */ +export function getBaseReturnValue(value: string): string | number | boolean { + if (value === 'string') { + return `''`; + } else if (value === 'number') { + return 0; + } else if (value === 'boolean') { + return true; + } else if (value === 'Object' || value === 'object') { + return `{}`; + } else if (checkIsGenericSymbol(value)) { + return `'[PC Preview] unkonwn type'`; + } else if (value === 'WebGLActiveInfo') { + return `{size: '[PC Preview] unkonwn GLint', type: 0, name: '[PC Preview] unkonwn name'}`; + } else { + return value; + } +} + +/** + * get current sourceFile import data + * @param sourceFile + * @param typeName + * @returns + */ +export function getTheRealReferenceFromImport(sourceFile: SourceFile, typeName: string): string { + const importArray = getImportDeclarationArray(sourceFile); + let returnName = ''; + let isFromImport = false; + let isOhos = false; + let mockMockName = ''; + importArray.forEach(value => { + if (typeName.includes('.') && typeName.split('.')[0] === value.importElements) { + isFromImport = true; + if (value.importPath.includes('@ohos')) { + isOhos = true; + } + if (value.importElements.trimStart().trimEnd() === typeName.split('.')[0]) { + const tmpArr = value.importPath.split('.'); + mockMockName = tmpArr[tmpArr.length - 1].replace(/'/g, '').replace(/"/g, ''); + } + } + }); + if (isFromImport) { + const splitReturnKindName = typeName.split('.'); + let left = ''; + for (let i = 1; i < splitReturnKindName.length; i++) { + left += `.${splitReturnKindName[i]}`; + } + if (isOhos) { + returnName = `mock${firstCharacterToUppercase(mockMockName)}()${left}`; + } + } else { + returnName = getImportTypeAliasNameFromImportElements(importArray, typeName); + } + return returnName; +} + +/** + * get return type alias, for example: {Context as _Context} return _Context + * @param importElementEntity + * @param typeName + * @returns + */ + function getImportTypeAliasNameFromImportElements(importElementEntity: ImportElementEntity[], typeName: string): string { + for (let i = 0; i < importElementEntity.length; i++) { + if (importElementEntity[i].importElements.includes('_')) { + const importElements = importElementEntity[i].importElements.replace('{', '').replace('}', '').split(','); + for (let j = 0; j < importElements.length; j++) { + const element = importElements[j].trimStart().trimEnd(); + if (`_${typeName}` === element.split('as')[1].trimStart().trimEnd()) { + return `_${typeName}`; + } + } + } + } + if (typeName === 'Want') { + typeName = `mockWant().Want`; + } else if (typeName === 'InputMethodExtensionContext') { + typeName = `mockInputmethodextensioncontext().InputMethodExtensionContext`; + } + return typeName; +} + +/** + * check is generic symbol + * @param type + * @returns + */ +export function checkIsGenericSymbol(type: string): boolean { + 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']; + return words.includes(type); +} + +/** + * generate basic type default value + * @param kindName + * @returns + */ +export function generateGenericTypeToMockValue(kindName: string): any { + const genericTypeName = kindName.split('<')[1].split('>')[0]; + if (genericTypeName === 'string') { + return `''`; + } else if (genericTypeName === 'number') { + return 0; + } else if (genericTypeName === 'boolean') { + return true; + } else if (genericTypeName === 'Object' || genericTypeName === 'object') { + return '{}'; + } else { + return ``; + } +} + +/** + * get callback statement + * @returns + */ +export function getCallbackStatement(): string { + return `const len = args.length; + if (typeof args[len - 1] === 'function') { + args[len - 1].call(this, null, '[PC Preview] unkonwn type') + }`; +} + +/** + * get iterator template string + * @param methodEntity + * @returns + */ +export function generateSymbolIterator(methodEntity: MethodEntity): string { + let iteratorMethod = ''; + if (methodEntity.returnType.returnKindName.includes('<[')) { + iteratorMethod += `let index = 0; + const IteratorMock = { + next: () => { + if (index < 1) { + const returnValue = ['[PC Previwe] unkonwn iterableiterator_k', '[PC Previwe] unkonwn iterableiterator_v']; + index++; + return { + value: returnValue, + done: false + }; + } else { + return { + done: true + }; + } + } + }; + return IteratorMock;`; + } else { + iteratorMethod += `let index = 0; + const IteratorMock = { + next: () => { + if (index < 1) { + index++; + return { + value: '[PC Preview] unkonwn any', + done: false + }; + } else { + return { + done: true + }; + } + } + }; + return IteratorMock;`; + } + + return iteratorMethod; +} diff --git a/mock-generate/src/generate/generateEntry.ts b/mock-generate/src/generate/generateEntry.ts new file mode 100644 index 00000000..e91aa650 --- /dev/null +++ b/mock-generate/src/generate/generateEntry.ts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * generate entry + * @returns + */ +export function generateEntry(): string { + return `import { mockSystemPlugin } from './index'; + + mockSystemPlugin()`; +} diff --git a/mock-generate/src/generate/generateEnumDeclaration.ts b/mock-generate/src/generate/generateEnumDeclaration.ts new file mode 100644 index 00000000..e97ad98c --- /dev/null +++ b/mock-generate/src/generate/generateEnumDeclaration.ts @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SyntaxKind } from 'typescript'; +import { EnumEntity } from '../declaration-node/enumDeclaration'; + +/** + * generate enum + * @param rootName + * @param enumDeclaration + * @returns + */ +export function generateEnumDeclaration(rootName: string, enumDeclaration: EnumEntity): string { + let enumBody = ''; + if (enumDeclaration.exportModifiers.length !== 0) { + enumBody += `export const ${enumDeclaration.enumName} = {\n`; + } else { + enumBody += `const ${enumDeclaration.enumName} = {\n`; + } + + let defaultValue = 0; + enumDeclaration.enumMembers.forEach(member => { + if (member.enumKind === SyntaxKind.TypeReference) { + enumBody += `${member.enumValueName}: new ${member.enumValue},\n`; + } else if (member.enumKind === SyntaxKind.NumericLiteral) { + enumBody += `${member.enumValueName}: ${member.enumValue.replace(/"/g, '')},\n`; + } else if (member.enumKind === SyntaxKind.StringLiteral) { + enumBody += `${member.enumValueName}: ${member.enumValue},\n`; + } else { + if (member.enumValue === '' || member.enumValue === null || member.enumValue === undefined) { + enumBody += `${member.enumValueName}: ${defaultValue},\n`; + defaultValue++; + } else { + enumBody += `${member.enumValueName}: ${member.enumValue},\n`; + } + } + }); + enumBody += '}\n'; + return enumBody; +} diff --git a/mock-generate/src/generate/generateImportEqual.ts b/mock-generate/src/generate/generateImportEqual.ts new file mode 100644 index 00000000..b47cc100 --- /dev/null +++ b/mock-generate/src/generate/generateImportEqual.ts @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ImportEuqalEntity } from '../declaration-node/importAndExportDeclaration'; + +/** + * generate import equal node info + * @param importEqualEntity + * @returns + */ +export function generateImportEqual(importEqualEntity: ImportEuqalEntity): string { + if (importEqualEntity.importEqualTypeName === 'connection.NetAddress') { + return `const ${importEqualEntity.importEqualName} = mockConnection().NetAddress`; + } else { + return `const ${importEqualEntity.importEqualName} = ${importEqualEntity.importEqualTypeName}`; + } +} diff --git a/mock-generate/src/generate/generateIndex.ts b/mock-generate/src/generate/generateIndex.ts new file mode 100644 index 00000000..5985b7f4 --- /dev/null +++ b/mock-generate/src/generate/generateIndex.ts @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * save all mock function + */ +const indexArray: Array = []; + +export function addToIndexArray(indexEntity: IndexEntity) { + indexArray.push(indexEntity); +} + +export function getIndexArray(): Array { + return indexArray; +} + +/** + * generate index + * @returns + */ +export function generateIndex(): string { + let indexBody = ''; + let caseBody = ''; + const filterSet: Set = new Set(); + + indexArray.forEach(value => { + let functionName = value.mockFunctionName; + let isHasSameValue = false; + if (filterSet.has(value.mockFunctionName)) { + isHasSameValue = true; + functionName = `_${value.mockFunctionName}`; + } + filterSet.add(functionName); + if (isHasSameValue) { + indexBody += `import { ${value.mockFunctionName} as ${functionName} } from './${value.fileName}';\n`; + } else { + indexBody += `import { ${functionName} } from './${value.fileName}';\n`; + } + + if (value.fileName.startsWith('ohos_')) { + caseBody += `case '${value.fileName.split('ohos_')[1].replace('_', '.')}':\n\treturn ${functionName}();\n`; + } else { + caseBody += `case '${value.fileName}':\n\treturn ${functionName}();\n`; + } + }); + + indexBody += `export function mockRequireNapiFun() { + global.requireNapi = function (...args) { + const globalNapi = global.requireNapiPreview(...args); + if (globalNapi !== undefined) { + return globalNapi; + } + switch (args[0]) {`; + indexBody += caseBody; + const endBody = `} + } + }`; + indexBody += endBody; + return indexBody; +} + +interface IndexEntity { + fileName: string, + mockFunctionName: string +} diff --git a/mock-generate/src/generate/generateIndexSignature.ts b/mock-generate/src/generate/generateIndexSignature.ts new file mode 100644 index 00000000..6582e265 --- /dev/null +++ b/mock-generate/src/generate/generateIndexSignature.ts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SyntaxKind } from 'typescript'; +import { IndexSignatureEntity } from '../declaration-node/indexSignatureDeclaration'; + +/** + * generate index signature + * @param signatureEntity + * @returns + */ +export function generateIndexSignature(signatureEntity: IndexSignatureEntity): string { + const signatureKey = signatureEntity.indexSignatureKey; + let signatureTypeName = ''; + if (signatureEntity.indexSignatureKind === SyntaxKind.TypeReference) { + signatureTypeName = signatureEntity.indexSignatureTypeName; + } else { + signatureTypeName = `'[PC Preview] unkonwn type',\n`; + } + return `${signatureKey}: ${signatureTypeName}`; +} diff --git a/mock-generate/src/generate/generateInterfaceDeclaration.ts b/mock-generate/src/generate/generateInterfaceDeclaration.ts new file mode 100644 index 00000000..05c1cbc8 --- /dev/null +++ b/mock-generate/src/generate/generateInterfaceDeclaration.ts @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SourceFile } from 'typescript'; +import { InterfaceEntity } from '../declaration-node/interfaceDeclaration'; +import { generateCommonMethodSignature } from './generateCommonMethodSignature'; +import { generateIndexSignature } from './generateIndexSignature'; +import { generatePropertySignatureDeclaration } from './generatePropertySignatureDeclaration'; + +/** + * generate interface + * @param rootName + * @param interfaceEntity + * @param sourceFile + * @param isSourceFile + * @returns + */ +export function generateInterfaceDeclaration(rootName: string, interfaceEntity: InterfaceEntity, sourceFile: SourceFile, isSourceFile: boolean, + currentSourceInterfaceArray: InterfaceEntity[]): string { + const interfaceName = interfaceEntity.interfaceName; + let interfaceBody = ''; + const interfaceElementSet = new Set(); + if (interfaceEntity.exportModifiers.length > 0 || isSourceFile) { + interfaceBody += `export const ${interfaceName} = { \n`; + } else { + interfaceBody += `const ${interfaceName} = { \n`; + } + + if (interfaceEntity.interfacePropertySignatures.length > 0) { + interfaceEntity.interfacePropertySignatures.forEach(value => { + interfaceBody += generatePropertySignatureDeclaration(interfaceName, value, sourceFile) + '\n'; + interfaceElementSet.add(value.propertyName); + }); + } + + if (interfaceEntity.interfaceMethodSignature.size > 0) { + interfaceEntity.interfaceMethodSignature.forEach(value => { + interfaceBody += generateCommonMethodSignature(interfaceName, value, sourceFile) + '\n'; + interfaceElementSet.add(value[0].functionName); + }); + } + + if (interfaceEntity.indexSignature.length > 0) { + interfaceEntity.indexSignature.forEach(value => { + interfaceBody += generateIndexSignature(value) + '\n'; + interfaceElementSet.add(value.indexSignatureKey); + }); + } + + if (interfaceEntity.heritageClauses.length > 0) { + interfaceEntity.heritageClauses.forEach(value => { + currentSourceInterfaceArray.forEach(currentInterface => { + if (value.types.includes(currentInterface.interfaceName)) { + interfaceBody += generateHeritageInterface(currentInterface, sourceFile, interfaceElementSet); + } + }); + }); + } + + interfaceBody += '}'; + return interfaceBody; +} + +function generateHeritageInterface(interfaceEntity: InterfaceEntity, sourceFile: SourceFile, elements: Set): string { + const interfaceName = interfaceEntity.interfaceName; + let interfaceBody = ''; + if (interfaceEntity.interfacePropertySignatures.length > 0) { + interfaceEntity.interfacePropertySignatures.forEach(value => { + if (!elements.has(value.propertyName)) { + interfaceBody += generatePropertySignatureDeclaration(interfaceName, value, sourceFile) + '\n'; + } + }); + } + + if (interfaceEntity.interfaceMethodSignature.size > 0) { + interfaceEntity.interfaceMethodSignature.forEach(value => { + if (!elements.has(value[0].functionName)) { + interfaceBody += generateCommonMethodSignature(interfaceName, value, sourceFile) + '\n'; + } + }); + } + + if (interfaceEntity.indexSignature.length > 0) { + interfaceEntity.indexSignature.forEach(value => { + if (elements.has(value.indexSignatureKey)) { + interfaceBody += generateIndexSignature(value) + '\n'; + } + }); + } + return interfaceBody; +} diff --git a/mock-generate/src/generate/generateMockJsFile.ts b/mock-generate/src/generate/generateMockJsFile.ts new file mode 100644 index 00000000..f3775f59 --- /dev/null +++ b/mock-generate/src/generate/generateMockJsFile.ts @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SourceFile, SyntaxKind } from 'typescript'; +import { collectAllLegalImports, firstCharacterToUppercase, getAllFileNameList } from '../common/commonUtils'; +import { ImportElementEntity } from '../declaration-node/importAndExportDeclaration'; +import { getDefaultExportClassDeclaration, getSourceFileFunctions, getSourceFileVariableStatements, SourceFileEntity } from '../declaration-node/sourceFileElementsAssemply'; +import { generateClassDeclaration } from './generateClassDeclaration'; +import { generateCommonFunction } from './generateCommonFunction'; +import { generateEnumDeclaration } from './generateEnumDeclaration'; +import { addToIndexArray } from './generateIndex'; +import { generateInterfaceDeclaration } from './generateInterfaceDeclaration'; +import { generateModuleDeclaration } from './generateModuleDeclaration'; +import { generateStaticFunction } from './generateStaticFunction'; +import { addToSystemIndexArray } from './generateSystemIndex'; +import { generateTypeAliasDeclaration } from './generateTypeAlias'; +import { generateVariableStatementDelcatation } from './generateVariableStatementDeclaration'; + +/** + * generate mock file string + * @param rootName + * @param sourceFileEntity + * @param sourceFile + * @param fileName + * @returns + */ +export function generateSourceFileElements(rootName: string, sourceFileEntity: SourceFileEntity, sourceFile: SourceFile, fileName: string): string { + let mockApi = ''; + const mockFunctionElements: Array = []; + const heritageClausesArray = getCurrentApiHeritageArray(sourceFileEntity, sourceFile); + if (sourceFileEntity.importDeclarations.length > 0) { + sourceFileEntity.importDeclarations.forEach(value => { + mockApi += generateImportDeclaration(value, fileName, heritageClausesArray); + }); + } + + if (sourceFileEntity.moduleDeclarations.length > 0) { + sourceFileEntity.moduleDeclarations.forEach(value => { + mockApi += generateModuleDeclaration('', value, sourceFile, fileName) + '\n'; + }); + } + + if (sourceFileEntity.classDeclarations.length > 0) { + sourceFileEntity.classDeclarations.forEach(value => { + if (!fileName.startsWith('system_') && !value.exportModifiers.includes(SyntaxKind.DefaultKeyword)) { + mockApi += generateClassDeclaration('', value, false, '', fileName, sourceFile, false) + '\n'; + mockFunctionElements.push({ elementName: value.className, type: 'class' }); + } + }); + } + + if (sourceFileEntity.interfaceDeclarations.length > 0) { + sourceFileEntity.interfaceDeclarations.forEach(value => { + mockApi += generateInterfaceDeclaration('', value, sourceFile, true, sourceFileEntity.interfaceDeclarations) + '\n'; + mockFunctionElements.push({ elementName: value.interfaceName, type: 'interface' }); + }); + } + + if (sourceFileEntity.enumDeclarations.length > 0) { + sourceFileEntity.enumDeclarations.forEach(value => { + mockApi += generateEnumDeclaration('', value) + '\n'; + mockFunctionElements.push({ elementName: value.enumName, type: 'enum' }); + }); + } + + if (sourceFileEntity.typeAliasDeclarations.length > 0) { + sourceFileEntity.typeAliasDeclarations.forEach(value => { + mockApi += generateTypeAliasDeclaration(value, false) + '\n'; + mockFunctionElements.push({ elementName: value.typeAliasName, type: 'typeAlias' }); + }); + } + + if (sourceFileEntity.moduleDeclarations.length === 0 && (fileName.startsWith('ohos_') || fileName.startsWith('system_') || fileName.startsWith('webgl'))) { + const mockNameArr = fileName.split('_'); + const mockName = mockNameArr[mockNameArr.length - 1]; + const defaultExportClass = getDefaultExportClassDeclaration(sourceFile); + if (defaultExportClass.length > 0) { + defaultExportClass.forEach(value => { + mockApi += generateClassDeclaration(rootName, value, false, mockName, '', sourceFile, false) + '\n'; + mockFunctionElements.push({ elementName: value.className, type: 'class' }); + }); + } + mockApi += `export function mock${firstCharacterToUppercase(mockName)}() {\n`; + if (fileName.startsWith('system_')) { + addToSystemIndexArray({ + filename: fileName, + mockFunctionName: `mock${firstCharacterToUppercase(mockName)}` + }); + mockApi += `global.systemplugin.${mockName} = {`; + const defaultClass = getDefaultExportClassDeclaration(sourceFile); + let staticMethodBody = ''; + if (defaultClass.length > 0) { + defaultClass.forEach(value => { + value.staticMethods.forEach(val => { + staticMethodBody += generateStaticFunction(val, true, sourceFile); + }); + }); + } + mockApi += staticMethodBody; + mockApi += '}'; + } else { + if (!fileName.startsWith('webgl')) { + addToIndexArray({ fileName: fileName, mockFunctionName: `mock${firstCharacterToUppercase(mockName)}` }); + } + } + mockApi += `\nconst mockModule${firstCharacterToUppercase(mockName)} = {`; + mockFunctionElements.forEach(val => { + mockApi += `${val.elementName}: ${val.elementName},`; + }); + mockApi += '}\n'; + mockApi += `return mockModule${firstCharacterToUppercase(mockName)}\n`; + mockApi += '}'; + } else { + const defaultExportClass = getDefaultExportClassDeclaration(sourceFile); + if (defaultExportClass.length > 0) { + const mockNameArr = fileName.split('_'); + const mockName = mockNameArr[mockNameArr.length - 1]; + defaultExportClass.forEach(value => { + mockApi += generateClassDeclaration(rootName, value, false, mockName, '', sourceFile, false) + '\n'; + }); + } + } + if (sourceFileEntity.exportDeclarations.length > 0) { + sourceFileEntity.exportDeclarations.forEach(value => { + if (!value.includes('export {')) { + mockApi += `${value}\n`; + } + }); + } + return mockApi; +} + +/** + * generate import definition + * @param importEntity + * @param sourceFileName + * @returns + */ +export function generateImportDeclaration(importEntity: ImportElementEntity, sourceFileName: string, heritageClausesArray: string[]): string { + let importPathName = ''; + const importPathSplit = importEntity.importPath.split('/'); + let fileName = importPathSplit[importPathSplit.length - 1]; + if (fileName.endsWith('.d.ts')) { + fileName = fileName.split('.d.')[0]; + } + if (fileName.includes('@')) { + importPathName = fileName.replace('@', '').replace(/\./g, '_'); + } else { + importPathName = fileName.replace(/\./g, '_'); + } + let importPath = ''; + for (let i = 0; i < importPathSplit.length - 1; i++) { + importPath += importPathSplit[i] + '/'; + } + importPath += importPathName; + let importElements = importEntity.importElements; + if (!importElements.includes('{') && !importElements.includes('* as') && !heritageClausesArray.includes(importElements)) { + if (importEntity.importPath.includes('@ohos')) { + const tmpArr = importEntity.importPath.split('.'); + importElements = `{ mock${firstCharacterToUppercase(tmpArr[tmpArr.length - 1].replace('"', '').replace('\'', ''))} }`; + } else { + importElements = `{ ${importElements} }`; + } + } + if (checIsDefaultExportClass(importEntity.importElements)) { + importElements = `{ ${importEntity.importElements} }`; + } + const testPath = importPath.replace(/"/g, '').replace(/'/g, '').split('/'); + if (getAllFileNameList().has(testPath[testPath.length - 1]) || testPath[testPath.length - 1] === 'ohos_application_want') { + const tmpImportPath = importPath.replace(/'/g, '').replace(/"/g, ''); + if (!tmpImportPath.startsWith('./') && !tmpImportPath.startsWith('../')) { + importPath = `'./${tmpImportPath}'`; + } + if (sourceFileName === 'tagSession' && importPath === `'./basic'` || sourceFileName === 'notificationContent' && importPath === `'./ohos_multimedia_image'`) { + importPath = `'.${importPath.replace(/'/g, '')}'`; + } + + // adapt no rules .d.ts + if (importElements.trimRight().trimEnd() === 'AccessibilityExtensionContext, { AccessibilityElement }') { + importElements = '{ AccessibilityExtensionContext, AccessibilityElement }'; + } + if (importElements.trimRight().trimEnd() === '{ image }') { + importElements = '{ mockImage as image }'; + } + if (sourceFileName === 'AbilityContext' && importPath === `'../ohos_application_Ability'` || + sourceFileName === 'Context' && importPath === `"./ApplicationContext"`) { + return ''; + } + collectAllLegalImports(importElements); + return `import ${importElements} from ${importPath}\n`; + } else { + return ''; + } +} + +/** + * adapter default export + * @param importName + * @returns + */ + function checIsDefaultExportClass(importName: string): boolean { + const defaultExportClass = ['Context', 'BaseContext', 'ExtensionContext', 'ApplicationContext']; + return defaultExportClass.includes(importName); +} + +/** + * get heritage elements + * @param sourceFileEntity + * @param sourceFile + * @returns + */ +function getCurrentApiHeritageArray(sourceFileEntity: SourceFileEntity, sourceFile: SourceFile): string[] { + const heritageClausesArray = []; + const defaultClassArray = getDefaultExportClassDeclaration(sourceFile); + sourceFileEntity.classDeclarations.forEach(value => { + value.heritageClauses.forEach(val => { + val.types.forEach(v => { + heritageClausesArray.push(v); + }); + }); + }); + defaultClassArray.forEach(value => { + value.heritageClauses.forEach(val => { + val.types.forEach(v => { + heritageClausesArray.push(v); + }); + }); + }); + return heritageClausesArray; +} + +interface MockFunctionElementEntity { + elementName: string, + type: string +} diff --git a/mock-generate/src/generate/generateModuleDeclaration.ts b/mock-generate/src/generate/generateModuleDeclaration.ts new file mode 100644 index 00000000..8c5f9289 --- /dev/null +++ b/mock-generate/src/generate/generateModuleDeclaration.ts @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SourceFile, SyntaxKind } from 'typescript'; +import { firstCharacterToUppercase } from '../common/commonUtils'; +import { ModuleBlockEntity } from '../declaration-node/moduleDeclaration'; +import { + getDefaultExportClassDeclaration, getSourceFileFunctions, + getSourceFileVariableStatements +} from '../declaration-node/sourceFileElementsAssemply'; +import { generateClassDeclaration } from './generateClassDeclaration'; +import { generateCommonFunction } from './generateCommonFunction'; +import { generateEnumDeclaration } from './generateEnumDeclaration'; +import { generateImportEqual } from './generateImportEqual'; +import { addToIndexArray } from './generateIndex'; +import { generateInterfaceDeclaration } from './generateInterfaceDeclaration'; +import { generateStaticFunction } from './generateStaticFunction'; +import { addToSystemIndexArray } from './generateSystemIndex'; +import { generateTypeAliasDeclaration } from './generateTypeAlias'; +import { generateVariableStatementDelcatation } from './generateVariableStatementDeclaration'; + +/** + * generate declare + * @param rootName + * @param moduleEntity + * @param sourceFile + * @param filename + * @returns + */ +export function generateModuleDeclaration(rootName: string, moduleEntity: ModuleBlockEntity, sourceFile: SourceFile, filename: string): string { + const moduleName = moduleEntity.moduleName; + const mockNameArr = filename.split('_'); + const mockName = mockNameArr[mockNameArr.length - 1]; + let moduleBody = `export function mock${firstCharacterToUppercase(mockName)}() {\n`; + addToIndexArray({ fileName: filename, mockFunctionName: `mock${firstCharacterToUppercase(mockName)}` }); + let outBody = ''; + const defaultExportClass = getDefaultExportClassDeclaration(sourceFile); + + if (defaultExportClass.length > 0) { + defaultExportClass.forEach(value => { + if (value.exportModifiers.includes(SyntaxKind.DefaultKeyword) && value.exportModifiers.includes(SyntaxKind.ExportKeyword)) { + if (filename.startsWith('system_')) { + const mockNameArr = filename.split('_'); + const mockName = mockNameArr[mockNameArr.length - 1]; + addToSystemIndexArray({ + filename: filename, + mockFunctionName: `mock${firstCharacterToUppercase(mockName)}` + }); + + moduleBody += `global.systemplugin.${mockName} = {`; + if (value.staticMethods.length > 0) { + let staticMethodBody = ''; + value.staticMethods.forEach(val => { + staticMethodBody += generateStaticFunction(val, true, sourceFile) + '\n'; + }); + moduleBody += staticMethodBody; + } + moduleBody += '}'; + } else { + outBody += generateClassDeclaration('', value, false, '', filename, sourceFile, false); + } + } + }); + } + + if (moduleEntity.typeAliasDeclarations.length > 0) { + moduleEntity.typeAliasDeclarations.forEach(value => { + outBody += generateTypeAliasDeclaration(value, true) + '\n'; + }); + } + + if (moduleEntity.moduleImportEquaqls.length > 0) { + moduleEntity.moduleImportEquaqls.forEach(value => { + outBody += generateImportEqual(value) + '\n'; + }); + } + + if (moduleEntity.classDeclarations.length > 0) { + moduleEntity.classDeclarations.forEach(value => { + if (value.exportModifiers.length > 0 && value.exportModifiers.includes(SyntaxKind.ExportKeyword)) { + outBody += generateClassDeclaration(moduleName, value, false, '', '', sourceFile, false) + '\n'; + } else { + moduleBody += '\t' + generateClassDeclaration(moduleName, value, false, '', '', sourceFile, true) + '\n'; + } + }); + } + + if (moduleEntity.interfaceDeclarations.length > 0) { + moduleEntity.interfaceDeclarations.forEach(value => { + if (value.exportModifiers.length > 0) { + outBody += generateInterfaceDeclaration(moduleName, value, sourceFile, false, moduleEntity.interfaceDeclarations) + ';\n'; + } else { + moduleBody += '\t' + generateInterfaceDeclaration(moduleName, value, sourceFile, false, moduleEntity.interfaceDeclarations) + ';\n'; + } + }); + } + + if (moduleEntity.enumDeclarations.length > 0) { + moduleEntity.enumDeclarations.forEach(value => { + if (value.exportModifiers.length > 0) { + outBody += generateEnumDeclaration(moduleName, value) + '\n'; + } else { + moduleBody += '\t' + generateEnumDeclaration(moduleName, value) + '\n'; + } + }); + } + + if (moduleEntity.moduleDeclarations.length > 0) { + moduleEntity.moduleDeclarations.forEach(value => { + moduleBody += generateInnerModule(value, sourceFile) + '\n'; + }); + } + + let functionBody = ''; + if (moduleEntity.functionDeclarations.size > 0) { + moduleEntity.functionDeclarations.forEach(value => { + functionBody += '\t' + generateCommonFunction(moduleName, value, sourceFile) + '\n'; + }); + } + + moduleBody += '\t' + `const ${moduleName} = {`; + if (moduleEntity.variableStatements.length > 0) { + moduleEntity.variableStatements.forEach(value => { + value.forEach(val => { + moduleBody += generateVariableStatementDelcatation(val) + '\n'; + }); + }); + } + + const sourceFileFunctions = getSourceFileFunctions(sourceFile); + let sourceFileFunctionBody = ''; + if (sourceFileFunctions.size > 0) { + sourceFileFunctions.forEach(value => { + sourceFileFunctionBody += generateCommonFunction(moduleName, value, sourceFile); + }); + } + + const sourceFileVariableStatements = getSourceFileVariableStatements(sourceFile); + let sourceFileStatementBody = ''; + if (sourceFileVariableStatements.length > 0) { + sourceFileVariableStatements.forEach(value => { + value.forEach(val => { + sourceFileStatementBody += generateVariableStatementDelcatation(val); + }); + }); + } + + moduleBody += sourceFileFunctionBody + '\n'; + moduleBody += sourceFileStatementBody + '\n'; + moduleBody += functionBody + '\n'; + + const exports = getModuleExportElements(moduleEntity); + let exportString = ''; + exports.forEach(value => { + exportString += `${value.name}: ${value.name},\n`; + }); + if (exportString !== '') { + moduleBody += '\t' + exportString; + } + + moduleBody += '\t};'; + moduleBody += `\n\treturn ${moduleName};}\n`; + moduleBody += outBody; + return moduleBody; +} + +/** + * generate inner module + * @param moduleEntity + * @param sourceFile + * @returns + */ +function generateInnerModule(moduleEntity: ModuleBlockEntity, sourceFile: SourceFile): string { + const moduleName = moduleEntity.moduleName; + let innerModuleBody = `const ${moduleName} = {`; + + if (moduleEntity.typeAliasDeclarations.length > 0) { + moduleEntity.typeAliasDeclarations.forEach(value => { + innerModuleBody += generateTypeAliasDeclaration(value, true) + '\n'; + }); + } + + if (moduleEntity.moduleImportEquaqls.length > 0) { + moduleEntity.moduleImportEquaqls.forEach(value => { + innerModuleBody += generateImportEqual(value) + '\n'; + }); + } + + if (moduleEntity.interfaceDeclarations.length > 0) { + moduleEntity.interfaceDeclarations.forEach(value => { + innerModuleBody += generateInterfaceDeclaration(moduleName, value, sourceFile, false, moduleEntity.interfaceDeclarations) + '\n'; + }); + } + + if (moduleEntity.enumDeclarations.length > 0) { + moduleEntity.enumDeclarations.forEach(value => { + innerModuleBody += generateEnumDeclaration(moduleName, value) + '\n'; + }); + } + + let functionBody = ''; + if (moduleEntity.functionDeclarations.size > 0) { + moduleEntity.functionDeclarations.forEach(value => { + functionBody += generateCommonFunction(moduleName, value, sourceFile) + '\n'; + }); + } + + if (moduleEntity.variableStatements.length > 0) { + moduleEntity.variableStatements.forEach(value => { + value.forEach(val => { + innerModuleBody += generateVariableStatementDelcatation(val) + '\n'; + }); + }); + } + innerModuleBody += functionBody + '\n'; + + const exports = getModuleExportElements(moduleEntity); + let exportString = ''; + exports.forEach(value => { + exportString += `${value.name}: ${value.name},\n`; + }); + if (exportString !== '') { + innerModuleBody += '\t' + exportString; + } + innerModuleBody += '\t};'; + return innerModuleBody; +} + +/** + * get all export elements + * @param moduleEntity + * @returns + */ +function getModuleExportElements(moduleEntity: ModuleBlockEntity): Array { + const exportElements: Array = []; + if (moduleEntity.classDeclarations.length > 0) { + moduleEntity.classDeclarations.forEach(value => { + exportElements.push({ name: firstCharacterToUppercase(value.className), type: 'class' }); + }); + } + + if (moduleEntity.interfaceDeclarations.length > 0) { + moduleEntity.interfaceDeclarations.forEach(value => { + exportElements.push({ name: value.interfaceName, type: 'interface' }); + }); + } + + if (moduleEntity.enumDeclarations.length > 0) { + moduleEntity.enumDeclarations.forEach(value => { + exportElements.push({ name: value.enumName, type: 'enum' }); + }); + } + + if (moduleEntity.moduleDeclarations.length > 0) { + moduleEntity.moduleDeclarations.forEach(value => { + exportElements.push({ name: value.moduleName, type: 'module' }); + }); + } + + if (moduleEntity.typeAliasDeclarations.length > 0) { + moduleEntity.typeAliasDeclarations.forEach(value => { + exportElements.push({ name: value.typeAliasName, type: 'type' }); + }); + } + return exportElements; +} + +interface ModuleExportEntity { + type: string, + name: string +} diff --git a/mock-generate/src/generate/generatePropertyDeclaration.ts b/mock-generate/src/generate/generatePropertyDeclaration.ts new file mode 100644 index 00000000..12e56923 --- /dev/null +++ b/mock-generate/src/generate/generatePropertyDeclaration.ts @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SourceFile, SyntaxKind } from 'typescript'; +import { getClassNameSet } from '../common/commonUtils'; +import { PropertyEntity } from '../declaration-node/propertyDeclaration'; +import { getTheRealReferenceFromImport } from './generateCommonUtil'; + +/** + * generate class property + * @param rootName + * @param propertyDeclaration + * @param sourceFile + * @returns + */ +export function generatePropertyDeclaration(rootName: string, propertyDeclaration: PropertyEntity, sourceFile: SourceFile): string { + let propertyBody = ''; + if (propertyDeclaration.isInitializer) { + propertyBody = `this.${propertyDeclaration.propertyName} = ${propertyDeclaration.initializer};`; + } else { + if (propertyDeclaration.propertyTypeName.startsWith('{')) { + propertyBody = `this.${propertyDeclaration.propertyName} = {};`; + } else if (propertyDeclaration.kind === SyntaxKind.LiteralType) { + propertyBody = `this.${propertyDeclaration.propertyName} = ${propertyDeclaration.propertyTypeName};`; + } else if (propertyDeclaration.kind === SyntaxKind.NumberKeyword) { + propertyBody = `this.${propertyDeclaration.propertyName} = 0;`; + } else if (propertyDeclaration.kind === SyntaxKind.StringKeyword) { + propertyBody = `this.${propertyDeclaration.propertyName} = ''`; + } else if (propertyDeclaration.kind === SyntaxKind.BooleanKeyword) { + propertyBody = `this.${propertyDeclaration.propertyName} = true`; + } else if (propertyDeclaration.propertyTypeName.startsWith('Array')) { + propertyBody = `this.${propertyDeclaration.propertyName} = [];`; + } else if (propertyDeclaration.propertyTypeName.startsWith('Map')) { + propertyBody = `this.${propertyDeclaration.propertyName} = {key: {}};`; + } else if (propertyDeclaration.kind === SyntaxKind.TypeReference) { + propertyBody = `this.${propertyDeclaration.propertyName} = `; + if (getClassNameSet().has(propertyDeclaration.propertyTypeName)) { + if (propertyDeclaration.propertyTypeName !== 'Want' && propertyDeclaration.propertyTypeName !== 'InputMethodExtensionContext') { + propertyBody += `new ${getTheRealReferenceFromImport(sourceFile, propertyDeclaration.propertyTypeName)}();`; + } else { + propertyBody += `${getTheRealReferenceFromImport(sourceFile, propertyDeclaration.propertyTypeName)};`; + } + } else { + propertyBody += `${getTheRealReferenceFromImport(sourceFile, propertyDeclaration.propertyTypeName)};`; + } + } else if (propertyDeclaration.kind === SyntaxKind.NumericLiteral || propertyDeclaration.kind === SyntaxKind.StringLiteral) { + propertyBody = `this.${propertyDeclaration.propertyName} = ${propertyDeclaration.propertyTypeName};`; + } else { + propertyBody = `this.${propertyDeclaration.propertyName} = '[PC Previwe] unkonwn ${propertyDeclaration.propertyName}';`; + } + } + return propertyBody; +} diff --git a/mock-generate/src/generate/generatePropertySignatureDeclaration.ts b/mock-generate/src/generate/generatePropertySignatureDeclaration.ts new file mode 100644 index 00000000..c69fefba --- /dev/null +++ b/mock-generate/src/generate/generatePropertySignatureDeclaration.ts @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SourceFile, SyntaxKind } from 'typescript'; +import { PropertySignatureEntity } from '../declaration-node/propertySignatureDeclaration'; +import { + checkIsGenericSymbol, getCallbackStatement, getTheRealReferenceFromImport, + getWarnConsole, propertyTypeWhiteList +} from './generateCommonUtil'; + +/** + * generate interface signature property + * @param rootName + * @param propertySignature + * @param sourceFile + * @returns + */ +export function generatePropertySignatureDeclaration(rootName: string, propertySignature: PropertySignatureEntity, sourceFile: SourceFile): string { + let propertySignatureBody = ''; + if (propertySignature.kind === SyntaxKind.FunctionType) { + propertySignatureBody += `${propertySignature.propertyName}: function(...args) {`; + propertySignatureBody += getWarnConsole(rootName, propertySignature.propertyName); + propertySignatureBody += getCallbackStatement(); + propertySignatureBody += '},\n'; + } else { + if (propertySignature.propertyTypeName.startsWith('{')) { + propertySignatureBody = `${propertySignature.propertyName}: {},`; + } else if (propertySignature.kind === SyntaxKind.TypeReference) { + if (propertySignature.propertyTypeName.startsWith('Array')) { + propertySignatureBody = `${propertySignature.propertyName}: [],`; + } else if (propertySignature.propertyTypeName.startsWith('Map')) { + propertySignatureBody = `${propertySignature.propertyName}: {key: {}},`; + } else if (propertySignature.propertyTypeName === 'string' || checkIsGenericSymbol(propertySignature.propertyTypeName) || + propertySignature.propertyTypeName === 'bool' || propertySignature.propertyTypeName === 'Data') { + propertySignatureBody = `${propertySignature.propertyName}: '[PC Preview] unkonwn ${propertySignature.propertyName}',`; + } else { + if (propertySignature.propertyTypeName.includes('<')) { + const preSplit = propertySignature.propertyTypeName.split('<'); + const genericArg = preSplit[preSplit.length - 1].split('>')[0]; + propertySignatureBody = `${propertySignature.propertyName}: ${genericArg},`; + } else { + if (propertyTypeWhiteList(propertySignature.propertyTypeName) === propertySignature.propertyTypeName) { + propertySignatureBody = `${propertySignature.propertyName}: ${getTheRealReferenceFromImport(sourceFile, propertySignature.propertyTypeName)},`; + } else { + propertySignatureBody = `${propertySignature.propertyName}: ${propertyTypeWhiteList(propertySignature.propertyTypeName)},`; + } + } + } + } else if (propertySignature.kind === SyntaxKind.NumberKeyword) { + propertySignatureBody = `${propertySignature.propertyName}: 0,`; + } else if (propertySignature.kind === SyntaxKind.StringKeyword) { + propertySignatureBody = `${propertySignature.propertyName}: '[PC Preview] unkonwn ${propertySignature.propertyName}',`; + } else if (propertySignature.kind === SyntaxKind.BooleanKeyword) { + propertySignatureBody = `${propertySignature.propertyName}: true,`; + } else if (propertySignature.kind === SyntaxKind.UnionType) { + const unionFirstElement = propertySignature.propertyTypeName.split('|')[0].trimStart().trimEnd(); + if (unionFirstElement.startsWith('"')) { + propertySignatureBody = `${propertySignature.propertyName}: ${unionFirstElement},`; + } else if (unionFirstElement === 'string') { + propertySignatureBody = `${propertySignature.propertyName}: '[PC Preview] unkonwn ${propertySignature.propertyName}',`; + } else if (unionFirstElement === 'number') { + propertySignatureBody = `${propertySignature.propertyName}: 0,`; + } else if (unionFirstElement === 'boolean') { + propertySignatureBody = `${propertySignature.propertyName}: true,`; + } else if (unionFirstElement === 'Uint8Array') { + propertySignatureBody = `${propertySignature.propertyName}: new ${unionFirstElement}(),`; + } else { + let element = unionFirstElement; + if (element === 'HTMLCanvasElement') { + element = `'[PC Preview] unkonwn ${propertySignature.propertyName}'`; + } else if (element === 'WebGLActiveInfo') { + element = `{size: '[PC Preview] unkonwn GLint', type: 0, name: '[PC Preview] unkonwn name'}`; + } else if (element === 'accessibility.EventType') { + element = `mockAccessibility().EventType`; + } + propertySignatureBody = `${propertySignature.propertyName}: ${element},`; + } + } else if (propertySignature.kind === SyntaxKind.ArrayType) { + propertySignatureBody = `${propertySignature.propertyName}: [],`; + } else { + propertySignatureBody = `${propertySignature.propertyName}: '[PC Preview] unkonwn ${propertySignature.propertyName}',`; + } + } + return propertySignatureBody; +} diff --git a/mock-generate/src/generate/generateStaticFunction.ts b/mock-generate/src/generate/generateStaticFunction.ts new file mode 100644 index 00000000..fda79e06 --- /dev/null +++ b/mock-generate/src/generate/generateStaticFunction.ts @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SourceFile, SyntaxKind } from 'typescript'; +import { firstCharacterToUppercase } from '../common/commonUtils'; +import { StaticMethodEntity } from '../declaration-node/methodDeclaration'; +import { generateSymbolIterator, getCallbackStatement, getReturnStatement, getWarnConsole } from './generateCommonUtil'; + +/** + * generate static method + * @param staticMethod + * @param isSystem + * @param sourceFile + * @returns + */ +export function generateStaticFunction(staticMethod: StaticMethodEntity, isSystem: boolean, sourceFile: SourceFile): string { + let methodBody = ''; + const rootName = staticMethod.className; + const methodEntity = staticMethod.methodEntity; + if (isSystem) { + methodBody += `${methodEntity.functionName.name}: function(...args) {`; + } else { + methodBody += `${firstCharacterToUppercase(staticMethod.className)}.${methodEntity.functionName.name} = function(...args) {`; + } + + methodBody += getWarnConsole(rootName, methodEntity.functionName.name); + if (methodEntity.functionName.name === 'Symbol.iterator') { + methodBody += generateSymbolIterator(methodEntity); + methodBody += '}'; + return methodBody; + } + + const args = methodEntity.args; + const len = args.length; + if (args.length > 0 && args[len - 1].paramName === 'callback') { + methodBody += getCallbackStatement(); + } + + if (methodEntity.returnType.returnKind !== SyntaxKind.VoidKeyword) { + methodBody += getReturnStatement(methodEntity.returnType, sourceFile); + } + methodBody += '}'; + + if (isSystem) { + methodBody += ','; + } else { + methodBody += ';'; + } + return methodBody; +} diff --git a/mock-generate/src/generate/generateSystemIndex.ts b/mock-generate/src/generate/generateSystemIndex.ts new file mode 100644 index 00000000..5cef408a --- /dev/null +++ b/mock-generate/src/generate/generateSystemIndex.ts @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const systemIndexArray: Array = []; + +export function addToSystemIndexArray(systemIndexEntity: SystemIndexEntity) { + systemIndexArray.push(systemIndexEntity); +} + +export function getSystemIndexArray(): Array { + return systemIndexArray; +} + +/** + * generate startswith 'system_' + * @returns + */ +export function generateSystemIndex(): string { + let systemIndex = `import regeneratorRuntime from 'babel-runtime/regenerator'\n`; + let exportFunction = ''; + systemIndexArray.forEach(value => { + systemIndex += `import { ${value.mockFunctionName} } from './${value.filename}'\n`; + exportFunction += `${value.mockFunctionName}();\n`; + }); + systemIndex += `import {mockRequireNapiFun} from './napi';`; + systemIndex += `export function mockSystemPlugin() { + global.regeneratorRuntime = regeneratorRuntime + global.systemplugin = {} + global.ohosplugin = {}\n`; + systemIndex += exportFunction; + systemIndex += `mockRequireNapiFun();\n`; + systemIndex += '}'; + return systemIndex; +} + +export interface SystemIndexEntity { + filename: string, + mockFunctionName: string +} diff --git a/mock-generate/src/generate/generateTypeAlias.ts b/mock-generate/src/generate/generateTypeAlias.ts new file mode 100644 index 00000000..96c987c7 --- /dev/null +++ b/mock-generate/src/generate/generateTypeAlias.ts @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TypeAliasEntity } from '../declaration-node/typeAliasDeclaration'; + +/** + * generate type alias + * @param typeAliasEntity + * @param isInner + * @returns + */ +export function generateTypeAliasDeclaration(typeAliasEntity: TypeAliasEntity, isInner: boolean): string { + let typeAliasName = ''; + if (!isInner) { + typeAliasName += `export const ${typeAliasEntity.typeAliasName} = `; + } else { + typeAliasName += `const ${typeAliasEntity.typeAliasName} = `; + } + let typeAliasValue = ''; + typeAliasValue += `'[PC Preview] unkonwn ${typeAliasEntity.typeAliasName}'`; + return typeAliasName + typeAliasValue + ';'; +} diff --git a/mock-generate/src/generate/generateVariableStatementDeclaration.ts b/mock-generate/src/generate/generateVariableStatementDeclaration.ts new file mode 100644 index 00000000..9c0db497 --- /dev/null +++ b/mock-generate/src/generate/generateVariableStatementDeclaration.ts @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SyntaxKind } from 'typescript'; +import { getClassNameSet } from '../common/commonUtils'; +import { StatementEntity } from '../declaration-node/variableStatementResolve'; + +/** + * generate const variable statement + * @param statementEntity + * @returns + */ +export function generateVariableStatementDelcatation(statementEntity: StatementEntity): string { + let statementBody = `${statementEntity.statementName}: `; + let statementValue; + if (statementEntity.typeKind === SyntaxKind.StringKeyword) { + statementValue = `''`; + } else if (statementEntity.typeKind === SyntaxKind.LiteralType || statementEntity.typeKind === SyntaxKind.StringLiteral || + statementEntity.typeKind === SyntaxKind.NumericLiteral) { + if (statementEntity.initializer === '') { + if (statementEntity.typeName.endsWith('n')) { + statementValue = statementEntity.typeName.replace('n', ''); + } else { + statementValue = statementEntity.typeName; + } + } else { + statementValue = statementEntity.initializer; + } + } else if (statementEntity.typeKind === SyntaxKind.NumberKeyword) { + statementValue = 0; + } else if (statementEntity.typeKind === SyntaxKind.UnionType) { + statementValue = statementEntity.typeName.split('|')[0]; + } else if (statementEntity.typeKind === SyntaxKind.TypeReference) { + if (statementEntity.typeName.includes('<')) { + const tmpTypeName = statementEntity.typeName.split('<')[0]; + if (getClassNameSet().has(tmpTypeName)) { + statementValue = `new ${tmpTypeName}()`; + } else { + statementValue = `${tmpTypeName}`; + } + } else { + statementValue = statementEntity.typeName; + } + } else if (statementEntity.typeKind === SyntaxKind.BooleanKeyword) { + statementValue = 'true'; + } else if (statementEntity.initializer !== '') { + statementValue = statementEntity.initializer.endsWith('n'); + } else { + statementValue = `'[PC Preivew] unknown ${statementEntity.statementName}'`; + } + statementBody += statementValue; + statementBody += ','; + return statementBody; +} diff --git a/mock-generate/src/main.ts b/mock-generate/src/main.ts new file mode 100644 index 00000000..25d5bcfa --- /dev/null +++ b/mock-generate/src/main.ts @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import fs from 'fs'; +import path from 'path'; +import os from 'os'; +import { createSourceFile, ScriptTarget } from 'typescript'; +import { collectAllFileName, getAllClassDeclaration } from './common/commonUtils'; +import { getSourceFileAssembly } from './declaration-node/sourceFileElementsAssemply'; +import { generateEntry } from './generate/generateEntry'; +import { generateIndex } from './generate/generateIndex'; +import { generateSourceFileElements } from './generate/generateMockJsFile'; +import { generateSystemIndex } from './generate/generateSystemIndex'; + +const dtsFileList: Array = []; + +/** + * get all api .d.ts file path + * @param dir + * @returns + */ +function getAllDtsFile(dir: string): Array { + const arr = fs.readdirSync(dir); + if (!dir.toString().includes('node_modules') && !dir.toString().includes('component')) { + arr.forEach(value => { + const fullPath = path.join(dir, value); + const stats = fs.statSync(fullPath); + if (stats.isDirectory()) { + getAllDtsFile(fullPath); + } else { + dtsFileList.push(fullPath); + } + }); + } + return dtsFileList; +} + +/** + * delete the old mock file befor generate new mock file + * @param outDir + */ + function deleteOldMockJsFile(outDir: string) { + const arr = fs.readdirSync(outDir); + arr.forEach(value => { + const currPath = path.join(outDir, value); + const stas = fs.statSync(currPath); + if (stas.isDirectory()) { + deleteOldMockJsFile(currPath); + } else { + fs.unlink(currPath, function(err) { + if (err) { + console.log(err); + } + }); + } + }); +} + +/** + * mkdir + * @param dirname + * @returns + */ +function mkdirsSync(dirname) { + if (fs.existsSync(dirname)) { + return true; + } else { + if (mkdirsSync(path.dirname(dirname))) { + fs.mkdirSync(dirname); + return true; + } + } +} + +function main() { + let interfaceRootDir = ''; + if (os.platform() === 'linux' || os.platform() === 'darwin') { + interfaceRootDir = __dirname.split('/out')[0]; + } else { + interfaceRootDir = __dirname.split('\\out')[0]; + } + const dtsDir = path.join(interfaceRootDir, './interface/sdk-js/api'); + const outMockJsFileDir = path.join(__dirname, '../../runtime/main/extend/systemplugin'); + deleteOldMockJsFile(outMockJsFileDir); + getAllDtsFile(dtsDir); + + dtsFileList.forEach(value => { + collectAllFileName(value); + if (value.endsWith('.d.ts')) { + const code = fs.readFileSync(value); + const sourceFile = createSourceFile('', code.toString(), ScriptTarget.Latest); + getAllClassDeclaration(sourceFile); + } + }); + + dtsFileList.forEach(value => { + if (value.endsWith('.d.ts')) { + const code = fs.readFileSync(value); + const sourceFile = createSourceFile('', code.toString(), ScriptTarget.Latest); + const fileName = path.basename(value).split('.d.ts')[0]; + let outputFileName = ''; + if (fileName.includes('@')) { + outputFileName = fileName.split('@')[1].replace(/\./g, '_'); + } else { + outputFileName = fileName; + } + + let tmpOutputMockJsFileDir = outMockJsFileDir; + if (!outputFileName.startsWith('system_')) { + tmpOutputMockJsFileDir = path.join(outMockJsFileDir, 'napi'); + } + let dirName = ''; + if (os.platform() === 'linux' || os.platform() === 'darwin') { + dirName = path.join(tmpOutputMockJsFileDir, path.dirname(value).split('/api')[1]); + } else { + dirName = path.join(tmpOutputMockJsFileDir, path.dirname(value).split('\\api')[1]); + } + if (!fs.existsSync(dirName)) { + mkdirsSync(dirName); + } + const sourceFileEntity = getSourceFileAssembly(sourceFile, fileName); + const filePath = path.join(dirName, outputFileName + '.js'); + fs.writeFileSync(filePath, ''); + fs.appendFileSync(path.join(filePath), generateSourceFileElements('', sourceFileEntity, sourceFile, outputFileName)); + } + }); + fs.writeFileSync(path.join(outMockJsFileDir, 'napi', 'index.js'), generateIndex()); + fs.writeFileSync(path.join(outMockJsFileDir, 'index.js'), generateSystemIndex()); + fs.writeFileSync(path.join(outMockJsFileDir, 'entry.js'), generateEntry()); +} + +main(); diff --git a/package.json b/package.json index b978e480..2192d1f0 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "scripts": { "test:lint": "eslint -c .eslintrc --fix test/**/*.ts", "test:unit": "mocha --timeout 5000 -r ts-node/register test/lib.ts test/ut/**/*.ts test/ut/*.ts", + "build:mock": "cd ./mock-generate && npm run build && cd ..", "build": "node build_jsmock_system_plugin.js && node build_strip_native_min.js" }, "keywords": [