• 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 { 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  const heritageClausesData = handleClassEntityHeritageClauses(rootName, classEntity);
53  const isExtend = heritageClausesData.isExtend;
54  classBody += heritageClausesData.classBody;
55
56  if (!isSystem) {
57    classBody += '{';
58    if (classEntity.classConstructor.length > 1) {
59      classBody += 'constructor(...arg) { ';
60    } else {
61      classBody += 'constructor() { ';
62    }
63    if (isExtend) {
64      classBody += 'super();\n';
65    }
66    classBody += sourceFile.fileName.endsWith('PermissionRequestResult.d.ts') ? '' : getWarnConsole(className, 'constructor');
67  }
68  if (classEntity.classProperty.length > 0) {
69    classEntity.classProperty.forEach(value => {
70      classBody += generatePropertyDeclaration(className, value, sourceFile) + '\n';
71    });
72  }
73
74  if (classEntity.classMethod.size > 0) {
75    classEntity.classMethod.forEach(value => {
76      classBody += generateCommonMethod(className, value, sourceFile, mockApi);
77    });
78  }
79
80  classBody += '}\n};';
81  if (
82    (classEntity.exportModifiers.includes(SyntaxKind.ExportKeyword) ||
83    classEntity.exportModifiers.includes(SyntaxKind.DeclareKeyword)) &&
84    !isInnerMockFunction
85  ) {
86    classBody += `
87      if (!global.${className}) {
88        global.${className} = ${className};\n
89      }
90    `;
91  }
92  if (!filename.startsWith('system_')) {
93    if (classEntity.staticMethods.length > 0) {
94      let staticMethodBody = '';
95      classEntity.staticMethods.forEach(value => {
96        staticMethodBody += generateStaticFunction(value, false, sourceFile, mockApi) + '\n';
97      });
98      classBody += staticMethodBody;
99    }
100  }
101  if (classEntity.exportModifiers.includes(SyntaxKind.DefaultKeyword)) {
102    classBody += `\nexport default ${className};`;
103  }
104  return classBody;
105}
106
107/**
108 * generate class
109 * @param rootName
110 * @param classEntity
111 * @returns
112 */
113function handleClassEntityHeritageClauses(rootName: string, classEntity: ClassEntity): { isExtend: boolean, classBody: string } {
114  let isExtend = false;
115  let classBody = '';
116  if (classEntity.heritageClauses.length > 0) {
117    classEntity.heritageClauses.forEach(value => {
118      if (value.clauseToken === 'extends') {
119        isExtend = true;
120        classBody += `${value.clauseToken} `;
121        value.types.forEach((val, index) => {
122          const extendClassName = val.split('<')[0];
123          const moduleName = firstCharacterToUppercase(rootName);
124          if (val.startsWith('Array<')) {
125            val = 'Array';
126          } else {
127            if (classEntity.exportModifiers.includes(SyntaxKind.ExportKeyword) && rootName !== '') {
128              val = `mock${moduleName}().${val}`;
129            }
130          }
131          if (index !== value.types.length - 1) {
132            classBody += `${extendClassName},`;
133          } else {
134            classBody += val === 'uri.URI' ? 'mockUri().URI' : `${extendClassName}`;
135          }
136        });
137      }
138    });
139  }
140  return {
141    isExtend,
142    classBody
143  };
144}
145