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 { SyntaxKind } from 'typescript';
17import type { SourceFile } from 'typescript';
18import { getClassNameSet, specialClassName } from '../common/commonUtils';
19import type { PropertyEntity } from '../declaration-node/propertyDeclaration';
20import { getTheRealReferenceFromImport, getWarnConsole } from './generateCommonUtil';
21import { ImportElementEntity } from '../declaration-node/importAndExportDeclaration';
22import { addExtraImport } from './generateInterfaceDeclaration';
23
24/**
25 * generate class property
26 * @param rootName
27 * @param propertyDeclaration
28 * @param sourceFile
29 * @returns
30 */
31export function generatePropertyDeclaration(
32  rootName: string,
33  propertyDeclaration: PropertyEntity,
34  sourceFile: SourceFile,
35  extraImport: string[],
36  importDeclarations?: ImportElementEntity[]
37): string {
38  let propertyBody = '';
39  if (propertyDeclaration.isInitializer) {
40    propertyBody = `this.${propertyDeclaration.propertyName} = ${propertyDeclaration.initializer};`;
41  } else {
42    propertyBody = `this.${propertyDeclaration.propertyName} = `;
43    if (propertyDeclaration.kinds === SyntaxKind.GetAccessor) {
44      const warnCon = getWarnConsole(rootName, propertyDeclaration.propertyName);
45      propertyBody += `(function () {\n ${warnCon} \n return `;
46    }
47    if (propertyDeclaration.propertyTypeName.startsWith('{')) {
48      propertyBody += '{};';
49    } else if (propertyDeclaration.kind === SyntaxKind.LiteralType) {
50      propertyBody += `${propertyDeclaration.propertyTypeName};`;
51    } else if (propertyDeclaration.kind === SyntaxKind.NumberKeyword) {
52      propertyBody += '0;';
53    } else if (propertyDeclaration.kind === SyntaxKind.StringKeyword) {
54      propertyBody += '\'\'';
55    } else if (propertyDeclaration.kind === SyntaxKind.BooleanKeyword) {
56      propertyBody += 'true';
57    } else if (propertyDeclaration.propertyTypeName.startsWith('Array')) {
58      propertyBody += '[];';
59    } else if (propertyDeclaration.propertyTypeName.startsWith('Map')) {
60      propertyBody += '{key: {}};';
61    } else if (propertyDeclaration.kind === SyntaxKind.TypeReference) {
62      propertyBody = generateTypeReference(propertyDeclaration, sourceFile, propertyBody);
63    } else if (
64      propertyDeclaration.kind === SyntaxKind.NumericLiteral ||
65      propertyDeclaration.kind === SyntaxKind.StringLiteral
66    ) {
67      propertyBody += ` ${propertyDeclaration.propertyTypeName};`;
68    } else {
69      propertyBody += `'[PC Previwe] unknown ${propertyDeclaration.propertyName}';`;
70    }
71    if (propertyDeclaration.kinds === SyntaxKind.GetAccessor) {
72      addExtraImport(extraImport, importDeclarations, sourceFile, propertyDeclaration);
73      propertyBody += '\n })();';
74    }
75  }
76  return propertyBody;
77}
78
79/**
80 * generate type reference
81 * @param propertyDeclaration
82 * @param sourceFile
83 * @param propertyBody
84 * @returns
85 */
86function generateTypeReference(
87  propertyDeclaration: PropertyEntity,
88  sourceFile: SourceFile,
89  propertyBody: string
90): string {
91  if (getClassNameSet().has(propertyDeclaration.propertyTypeName)) {
92    if (!specialClassName.includes(propertyDeclaration.propertyTypeName)) {
93      propertyBody += `new ${getTheRealReferenceFromImport(sourceFile, propertyDeclaration.propertyTypeName)}();`;
94    } else {
95      propertyBody += `${getTheRealReferenceFromImport(sourceFile, propertyDeclaration.propertyTypeName)};`;
96    }
97  } else {
98    propertyBody += `${getTheRealReferenceFromImport(sourceFile, propertyDeclaration.propertyTypeName)};`;
99  }
100  return propertyBody;
101}
102