• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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