1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import type { SourceFile } from 'typescript'; 17import { SyntaxKind } from 'typescript'; 18import { firstCharacterToUppercase } from '../common/commonUtils'; 19import type { ClassEntity } from '../declaration-node/classDeclaration'; 20import { generateCommonMethod } from './generateCommonMethod'; 21import { getWarnConsole } from './generateCommonUtil'; 22import { generatePropertyDeclaration } from './generatePropertyDeclaration'; 23import { generateStaticFunction } from './generateStaticFunction'; 24 25/** 26 * generate class 27 * @param rootName 28 * @param classEntity 29 * @param isSystem 30 * @param globalName 31 * @param filename 32 * @param sourceFile 33 * @param isInnerMockFunction 34 * @returns 35 */ 36export function generateClassDeclaration(rootName: string, classEntity: ClassEntity, isSystem: boolean, globalName: string, 37 filename: string, sourceFile: SourceFile, isInnerMockFunction: boolean, mockApi: string): string { 38 if (isSystem) { 39 return ''; 40 } 41 42 const className = firstCharacterToUppercase(classEntity.className); 43 let classBody = ''; 44 if ((classEntity.exportModifiers.includes(SyntaxKind.ExportKeyword) || 45 classEntity.exportModifiers.includes(SyntaxKind.DeclareKeyword)) && 46 !isInnerMockFunction) { 47 classBody += `export const ${className} = class ${className} `; 48 } else { 49 classBody += `const ${className} = class ${className} `; 50 } 51 52 let isExtend = false; 53 54 if (classEntity.heritageClauses.length > 0) { 55 classEntity.heritageClauses.forEach(value => { 56 if (value.clauseToken === 'extends') { 57 isExtend = true; 58 classBody += `${value.clauseToken} `; 59 value.types.forEach((val, index) => { 60 const extendClassName = val.split('<')[0]; 61 const moduleName = firstCharacterToUppercase(rootName); 62 if (val.startsWith('Array<')) { 63 val = 'Array'; 64 } else { 65 if (classEntity.exportModifiers.includes(SyntaxKind.ExportKeyword) && rootName !== '') { 66 val = `mock${moduleName}().${val}`; 67 } 68 } 69 if (index !== value.types.length - 1) { 70 classBody += `${extendClassName},`; 71 } else { 72 classBody += `${extendClassName}`; 73 } 74 }); 75 } 76 }); 77 } 78 79 if (!isSystem) { 80 classBody += '{'; 81 if (classEntity.classConstructor.length > 1) { 82 classBody += 'constructor(...arg) { '; 83 } else { 84 classBody += 'constructor() { '; 85 } 86 if (isExtend) { 87 classBody += 'super();\n'; 88 } 89 classBody += getWarnConsole(className, 'constructor'); 90 } 91 if (classEntity.classProperty.length > 0) { 92 classEntity.classProperty.forEach(value => { 93 classBody += generatePropertyDeclaration(className, value, sourceFile) + '\n'; 94 }); 95 } 96 97 if (classEntity.classMethod.size > 0) { 98 classEntity.classMethod.forEach(value => { 99 classBody += generateCommonMethod(className, value, sourceFile, mockApi); 100 }); 101 } 102 103 classBody += '}\n};'; 104 if ((classEntity.exportModifiers.includes(SyntaxKind.ExportKeyword) || 105 classEntity.exportModifiers.includes(SyntaxKind.DeclareKeyword)) && 106 !isInnerMockFunction) { 107 classBody += ` 108 if (!global.${className}) { 109 global.${className} = ${className};\n 110 } 111 `; 112 } 113 if (!filename.startsWith('system_')) { 114 if (classEntity.staticMethods.length > 0) { 115 let staticMethodBody = ''; 116 classEntity.staticMethods.forEach(value => { 117 staticMethodBody += generateStaticFunction(value, false, sourceFile, mockApi) + '\n'; 118 }); 119 classBody += staticMethodBody; 120 } 121 } 122 if (classEntity.exportModifiers.includes(SyntaxKind.DefaultKeyword)) { 123 classBody += `\nexport default ${className};`; 124 } 125 return classBody; 126} 127