1/* 2 * Copyright (c) 2022 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 path from 'path'; 17import { 18 CallSignatureDeclaration, ComputedPropertyName, FunctionDeclaration, Identifier, isClassDeclaration, 19 isComputedPropertyName, isIdentifier, isModuleBlock, isModuleDeclaration, isPrivateIdentifier, MethodDeclaration, 20 MethodSignature, ModifiersArray, ModuleDeclaration, NodeArray, ParameterDeclaration, PropertyName, SourceFile 21} from 'typescript'; 22 23const allLegalImports = new Set<string>(); 24const fileNameList = new Set<string>(); 25const allClassSet = new Set<string>(); 26 27/** 28 * get all legal imports 29 * @returns 30 */ 31export function getAllLegalImports(): Set<string> { 32 return allLegalImports; 33} 34 35/** 36 * get all legal imports 37 * @param element 38 */ 39export function collectAllLegalImports(element: string) { 40 allLegalImports.add(element); 41} 42 43/** 44 * collect all mock js file path 45 * @returns 46 */ 47export function getAllFileNameList(): Set<string> { 48 return fileNameList; 49} 50 51/** 52 * collect all file name 53 */ 54export function collectAllFileName(filePath: string) { 55 const fileName = path.basename(filePath).split('.d.ts')[0]; 56 let outputFileName = ''; 57 if (fileName.includes('@')) { 58 outputFileName = fileName.split('@')[1].replace(/\./g, '_'); 59 } else { 60 outputFileName = fileName; 61 } 62 fileNameList.add(outputFileName); 63} 64 65/** 66 * get all class name set 67 * @returns 68 */ 69export function getClassNameSet(): Set<string> { 70 return allClassSet; 71} 72 73/** 74 * get all class declaration 75 * @param sourceFile 76 * @returns 77 */ 78export function getAllClassDeclaration(sourceFile: SourceFile): Set<string> { 79 sourceFile.forEachChild(node => { 80 if (isClassDeclaration(node)) { 81 if (node.name !== undefined) { 82 allClassSet.add(node.name.escapedText.toString()); 83 } 84 } else if (isModuleDeclaration(node)) { 85 const moduleDeclaration = node as ModuleDeclaration; 86 const moduleBody = moduleDeclaration.body; 87 if (moduleBody !== undefined && isModuleBlock(moduleBody)) { 88 moduleBody.statements.forEach(value => { 89 if (isClassDeclaration(value)) { 90 if (value.name !== undefined) { 91 allClassSet.add(firstCharacterToUppercase(value.name?.escapedText.toString())); 92 } 93 } 94 }); 95 } 96 } 97 }); 98 return allClassSet; 99} 100 101/** 102 * get keywords 103 * @param modifiers 104 * @returns 105 */ 106export function getModifiers(modifiers: ModifiersArray): Array<number> { 107 const modifiersArray: Array<number> = []; 108 modifiers.forEach(value => modifiersArray.push(value.kind)); 109 return modifiersArray; 110} 111 112/** 113 * get property name 114 * @param node property node 115 * @param sourceFile 116 * @returns 117 */ 118export function getPropertyName(node: PropertyName, sourceFile: SourceFile): string { 119 let propertyName = ''; 120 if (isIdentifier(node) || isPrivateIdentifier(node)) { 121 const newNameNode = node as Identifier; 122 propertyName = newNameNode.escapedText.toString(); 123 } else if (isComputedPropertyName(node)) { 124 const newNameNode = node as ComputedPropertyName; 125 propertyName = sourceFile.text.substring(newNameNode.expression.pos, newNameNode.expression.end).trimStart().trimEnd(); 126 } else { 127 propertyName = sourceFile.text.substring(node.pos, node.end).trimStart().trimEnd(); 128 } 129 return propertyName; 130} 131 132/** 133 * get parameter declaration 134 * @param parameter 135 * @param sourceFile 136 * @returns 137 */ 138export function getParameter(parameter: ParameterDeclaration, sourceFile: SourceFile): ParameterEntity { 139 let paramName = ''; 140 let paramTypeString = ''; 141 const paramTypeKind = parameter.type?.kind === undefined ? -1 : parameter.type.kind; 142 if (isIdentifier(parameter.name)) { 143 paramName = parameter.name.escapedText === undefined ? '' : parameter.name.escapedText.toString(); 144 } else { 145 const start = parameter.name.pos === undefined ? 0 : parameter.name.pos; 146 const end = parameter.name.end === undefined ? 0 : parameter.name.end; 147 paramName = sourceFile.text.substring(start, end).trimStart().trimEnd(); 148 } 149 150 const start = parameter.type?.pos === undefined ? 0 : parameter.type.pos; 151 const end = parameter.type?.end === undefined ? 0 : parameter.type.end; 152 paramTypeString = sourceFile.text.substring(start, end).trimStart().trimEnd(); 153 return { 154 paramName: paramName, 155 paramTypeString: paramTypeString, 156 paramTypeKind: paramTypeKind 157 }; 158} 159 160/** 161 * get method or function return info 162 * @param node 163 * @param sourceFile 164 * @returns 165 */ 166export function getFunctionAndMethodReturnInfo(node: FunctionDeclaration | MethodDeclaration | 167 MethodSignature | CallSignatureDeclaration, sourceFile: SourceFile): ReturnTypeEntity { 168 const returnInfo = { returnKindName: '', returnKind: -1 }; 169 if (node.type !== undefined) { 170 const start = node.type.pos === undefined ? 0 : node.type.pos; 171 const end = node.type.end === undefined ? 0 : node.type.end; 172 returnInfo.returnKindName = sourceFile.text.substring(start, end).trimStart().trimEnd(); 173 returnInfo.returnKind = node.type.kind; 174 } 175 return returnInfo; 176} 177 178/** 179 * get export modifiers 180 * @param modifiers 181 * @returns 182 */ 183export function getExportKeyword(modifiers: ModifiersArray): Array<number> { 184 const modifiersArray: Array<number> = []; 185 modifiers.forEach(value => { 186 modifiersArray.push(value.kind); 187 }); 188 return modifiersArray; 189} 190 191/** 192 * 193 * @param str first letter capitalization 194 * @returns 195 */ 196export function firstCharacterToUppercase(str: string): string { 197 return str.slice(0, 1).toUpperCase() + str.slice(1); 198} 199 200/** 201 * parameters entity 202 */ 203export interface ParameterEntity { 204 paramName: string, 205 paramTypeString: string, 206 paramTypeKind: number 207} 208 209/** 210 * return type entity 211 */ 212export interface ReturnTypeEntity { 213 returnKindName: string, 214 returnKind: number 215} 216