• 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 { SyntaxKind } from 'typescript';
17import type { SourceFile } from 'typescript';
18import type { PropertySignatureEntity } from '../declaration-node/propertySignatureDeclaration';
19import {
20  checkIsGenericSymbol, getCallbackStatement, getTheRealReferenceFromImport,
21  getWarnConsole, propertyTypeWhiteList, paramsTypeStart
22} from './generateCommonUtil';
23
24/**
25 * generate interface signature property
26 * @param rootName
27 * @param propertySignature
28 * @param sourceFile
29 * @returns
30 */
31export function generatePropertySignatureDeclaration(
32  rootName: string,
33  propertySignature: PropertySignatureEntity,
34  sourceFile: SourceFile,
35  mockApi: string
36): string {
37  let propertySignatureBody = '';
38  if (propertySignature.kind === SyntaxKind.FunctionType) {
39    propertySignatureBody += `${propertySignature.propertyName}: function(...args) {`;
40    propertySignatureBody += getWarnConsole(rootName, propertySignature.propertyName);
41    propertySignatureBody += getCallbackStatement(mockApi);
42    propertySignatureBody += '},\n';
43  } else {
44    if (
45      (propertySignature.propertyTypeName.startsWith('{') ||
46      propertySignature.propertyTypeName.startsWith('Record<') ||
47      propertySignature.propertyTypeName.startsWith('Object') ||
48      propertySignature.propertyTypeName.startsWith('object')) &&
49      !propertySignature.propertyTypeName.endsWith(']')
50    ) {
51      propertySignatureBody = `${propertySignature.propertyName}: {},`;
52    } else if (propertySignature.kind === SyntaxKind.TypeReference) {
53      propertySignatureBody = generatePropertySignatureForTypeReference(propertySignature, sourceFile);
54    } else if (propertySignature.kind === SyntaxKind.NumberKeyword) {
55      propertySignatureBody = `${propertySignature.propertyName}: 0,`;
56    } else if (propertySignature.kind === SyntaxKind.StringKeyword) {
57      propertySignatureBody = `${propertySignature.propertyName}: '[PC Preview] unknown ${propertySignature.propertyName}',`;
58    } else if (propertySignature.kind === SyntaxKind.BooleanKeyword) {
59      propertySignatureBody = `${propertySignature.propertyName}: true,`;
60    } else if (propertySignature.kind === SyntaxKind.UnionType) {
61      propertySignatureBody = generatePropertySignatureForUnionType(propertySignature, sourceFile);
62    } else if (propertySignature.kind === SyntaxKind.ArrayType) {
63      propertySignatureBody = `${propertySignature.propertyName}: [],`;
64    } else {
65      propertySignatureBody = `${propertySignature.propertyName}: '[PC Preview] unknown ${propertySignature.propertyName}',`;
66    }
67  }
68  return propertySignatureBody;
69}
70
71/**
72 * generate interface signature property for TypeReference
73 * @param propertySignature
74 * @param sourceFile
75 * @returns
76 */
77function generatePropertySignatureForTypeReference(propertySignature: PropertySignatureEntity, sourceFile: SourceFile): string {
78  let propertySignatureBody = '';
79  if (propertySignature.propertyTypeName.startsWith('Array')) {
80    propertySignatureBody = `${propertySignature.propertyName}: [],`;
81  } else if (propertySignature.propertyTypeName.startsWith('Map')) {
82    propertySignatureBody = `${propertySignature.propertyName}: {key: {}},`;
83  } else if (
84    propertySignature.propertyTypeName === 'string' ||
85    checkIsGenericSymbol(propertySignature.propertyTypeName) ||
86    propertySignature.propertyTypeName === 'bool' ||
87    propertySignature.propertyTypeName === 'Data'
88  ) {
89    propertySignatureBody = `${propertySignature.propertyName}: '[PC Preview] unknown ${propertySignature.propertyName}',`;
90  } else if (propertySignature.propertyTypeName === 'IlluminateType') {
91    propertySignatureBody = `${propertySignature.propertyName}: '',`;
92  } else {
93    if (propertySignature.propertyTypeName.includes('<')) {
94      propertySignatureBody = handlepropertyTypeNameBody(propertySignature, sourceFile);
95    } else {
96      if (propertyTypeWhiteList(propertySignature.propertyTypeName) === propertySignature.propertyTypeName) {
97        propertySignatureBody = `${propertySignature.propertyName}: ${getTheRealReferenceFromImport(sourceFile, propertySignature.propertyTypeName)},`;
98      } else {
99        propertySignatureBody = `${propertySignature.propertyName}: ${propertyTypeWhiteList(propertySignature.propertyTypeName)},`;
100      }
101    }
102  }
103  return propertySignatureBody;
104}
105
106/**
107 * generate interface signature property for UnionType
108 * @param propertySignature
109 * @param sourceFile
110 * @returns
111 */
112function generatePropertySignatureForUnionType(propertySignature: PropertySignatureEntity, sourceFile: SourceFile): string {
113  let propertySignatureBody = '';
114  let unionFirstElement = propertySignature.propertyTypeName.split('|')[0].trim();
115  if (unionFirstElement.includes('[]') || unionFirstElement.startsWith('[') || unionFirstElement.endsWith(']')) {
116    unionFirstElement = '[]';
117  }
118  if (unionFirstElement.startsWith('"') || unionFirstElement.startsWith("'")) {
119    propertySignatureBody = `${propertySignature.propertyName}: ${unionFirstElement},`;
120  } else if (unionFirstElement === 'string') {
121    propertySignatureBody = `${propertySignature.propertyName}: '[PC Preview] unknown ${propertySignature.propertyName}',`;
122  } else if (unionFirstElement === 'number') {
123    propertySignatureBody = `${propertySignature.propertyName}: 0,`;
124  } else if (unionFirstElement === 'boolean') {
125    propertySignatureBody = `${propertySignature.propertyName}: true,`;
126  } else if (unionFirstElement === 'Uint8Array') {
127    propertySignatureBody = `${propertySignature.propertyName}: new ${unionFirstElement}(),`;
128  } else {
129    let element = unionFirstElement;
130    if (element === 'HTMLCanvasElement') {
131      element = `'[PC Preview] unknown ${propertySignature.propertyName}'`;
132    } else if (element === 'WebGLActiveInfo') {
133      element = '{size: \'[PC Preview] unknown GLint\', type: 0, name: \'[PC Preview] unknown name\'}';
134    } else if (element.startsWith('Array')) {
135      element = '[]';
136    } else if (propertyTypeWhiteList(unionFirstElement) === unionFirstElement) {
137      element = getTheRealReferenceFromImport(sourceFile, unionFirstElement);
138    }
139    propertySignatureBody = `${propertySignature.propertyName}: ${element},`;
140  }
141  return propertySignatureBody;
142}
143
144/**
145 * generate interface signature property for TypeReference
146 * @param propertySignature
147 * @param sourceFile
148 * @returns
149 */
150function handlepropertyTypeNameBody(propertySignature: PropertySignatureEntity, sourceFile: SourceFile): string {
151  let propertySignatureBody = '';
152  if (propertySignature.propertyTypeName.startsWith('AsyncCallback') || propertySignature.propertyTypeName.startsWith('Callback')) {
153    propertySignatureBody = `${propertySignature.propertyName}: ()=>{},`;
154  } else {
155    const preSplit = propertySignature.propertyTypeName.split('<');
156    const genericArg = preSplit[preSplit.length - 1].split('>')[0];
157    if (genericArg.includes(',')) {
158      return `${propertySignature.propertyName}: {},`;
159    }
160    let sourceFileContent = sourceFile.text;
161    const removeNoteRegx = /\/\*[\s\S]*?\*\//g;
162    sourceFileContent = sourceFileContent.replace(removeNoteRegx, '');
163    const regex = new RegExp(`\\s${genericArg}\\s({|=|extends)`);
164    const results = sourceFileContent.match(regex);
165    if (results) {
166      propertySignatureBody = `${propertySignature.propertyName}: ${genericArg},`;
167    } else {
168      let getPropertyTypeName = null;
169      Object.keys(paramsTypeStart).forEach(key => {
170        if (genericArg.startsWith(key)) {
171          getPropertyTypeName = paramsTypeStart[key] === '[PC Preview] unknown type' ? `'${paramsTypeStart[key]}'` : `${paramsTypeStart[key]}`;
172        }
173      });
174      propertySignatureBody = `${propertySignature.propertyName}: ${getPropertyTypeName ?? '\'[PC Preview] unknown type\''},`;
175    }
176  }
177  return propertySignatureBody;
178}
179