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 { ClassDeclaration, SourceFile } from 'typescript'; 17import { 18 isConstructorDeclaration, 19 isGetAccessor, 20 isMethodDeclaration, 21 isPropertyDeclaration, 22 isTypeParameterDeclaration, 23 SyntaxKind 24} from 'typescript'; 25import { getExportKeyword } from '../common/commonUtils'; 26import { getConstructorDeclaration } from './constructorDeclaration'; 27import type { ConstructorEntity } from './constructorDeclaration'; 28import { getHeritageClauseDeclaration } from './heritageClauseDeclaration'; 29import type { HeritageClauseEntity } from './heritageClauseDeclaration'; 30import { getMethodDeclaration } from './methodDeclaration'; 31import type { MethodEntity, StaticMethodEntity } from './methodDeclaration'; 32import { getGetDeclaration, getPropertyDeclaration } from './propertyDeclaration'; 33import type { PropertyEntity } from './propertyDeclaration'; 34import { getTypeParameterDeclaration } from './typeParameterDeclaration'; 35import type { TypeParameterEntity } from './typeParameterDeclaration'; 36 37interface SubstepClassEntity { 38 className: string, 39 typeParameters: Array<TypeParameterEntity>, 40 classConstructor: Array<Array<ConstructorEntity>>, 41 classMethod: Map<string, Array<MethodEntity>>, 42 classProperty: Array<PropertyEntity>, 43 staticMethods: Array<StaticMethodEntity> 44} 45 46export interface ClassEntity { 47 className: string, 48 typeParameters: Array<TypeParameterEntity>, 49 heritageClauses: Array<HeritageClauseEntity>, 50 classConstructor: Array<Array<ConstructorEntity>>, 51 classMethod: Map<string, Array<MethodEntity>>, 52 classProperty: Array<PropertyEntity>, 53 exportModifiers: Array<number>, 54 staticMethods: Array<StaticMethodEntity> 55} 56 57/** 58 * get class info 59 * @param classNode 60 * @param sourceFile 61 * @returns 62 */ 63export function getClassDeclaration(classNode: ClassDeclaration, sourceFile: SourceFile): ClassEntity { 64 let exportModifiers: Array<number> = []; 65 if (classNode.modifiers !== undefined) { 66 exportModifiers = getExportKeyword(classNode.modifiers); 67 } 68 69 const heritageClauses: Array<HeritageClauseEntity> = []; 70 71 if (classNode.heritageClauses !== undefined) { 72 classNode.heritageClauses.forEach(value => { 73 heritageClauses.push(getHeritageClauseDeclaration(value, sourceFile)); 74 }); 75 } 76 77 const substepClassEntitys: SubstepClassEntity = substepGetClass(classNode, sourceFile); 78 return { 79 ...substepClassEntitys, 80 exportModifiers, 81 heritageClauses 82 }; 83} 84 85/** 86 *get some class info 87 * @param classNode 88 * @param sourceFile 89 * @returns 90 */ 91function substepGetClass(classNode: ClassDeclaration, sourceFile: SourceFile): SubstepClassEntity { 92 const className = classNode.name === undefined ? '' : classNode.name.escapedText.toString(); 93 const classConstructor: Array<Array<ConstructorEntity>> = []; 94 const classMethod: Map<string, Array<MethodEntity>> = new Map<string, Array<MethodEntity>>(); 95 const classProperty: Array<PropertyEntity> = []; 96 const typeParameters: Array<TypeParameterEntity> = []; 97 const staticMethods: Array<StaticMethodEntity> = []; 98 classNode.members.forEach(value => { 99 if (isMethodDeclaration(value)) { 100 const methodEntity = getMethodDeclaration(value, sourceFile); 101 if (methodEntity.modifiers.includes(SyntaxKind.StaticKeyword)) { 102 staticMethods.push({ className: className, methodEntity: methodEntity }); 103 } else { 104 if (classMethod.get(methodEntity.functionName.name) !== undefined) { 105 classMethod.get(methodEntity.functionName.name)?.push(methodEntity); 106 } else { 107 const methodArray: Array<MethodEntity> = []; 108 methodArray.push(methodEntity); 109 classMethod.set(methodEntity.functionName.name, methodArray); 110 } 111 } 112 } else if (isPropertyDeclaration(value)) { 113 classProperty.push(getPropertyDeclaration(value, sourceFile)); 114 } else if (isConstructorDeclaration(value)) { 115 classConstructor.push(getConstructorDeclaration(value, sourceFile)); 116 } else if (isTypeParameterDeclaration(value)) { 117 typeParameters.push(getTypeParameterDeclaration(value, sourceFile)); 118 } else if (isGetAccessor(value)) { 119 classProperty.push(getGetDeclaration(value, sourceFile)); 120 } else { 121 console.log('--------------------------- uncaught class type start -----------------------'); 122 console.log('className: ' + className); 123 console.log(value); 124 console.log('--------------------------- uncaught class type end -----------------------'); 125 } 126 }); 127 return { 128 className, 129 typeParameters, 130 classConstructor, 131 classMethod, 132 classProperty, 133 staticMethods 134 }; 135} 136