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