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