1/* 2 * Copyright (c) 2021-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 16const path = require('path'); 17const fs = require('fs'); 18const ts = require('typescript'); 19const ExcelJS = require('exceljs'); 20const applicationModules = []; 21 22const typeCollection = true; 23const isNotMerge = false; 24function collectArkUiApis() { 25 const apis = []; 26 const arkUiApiDir = path.resolve(__dirname, '../sdk/build-tools/ets-loader/declarations'); 27 try { 28 readFile(arkUiApiDir, apis); 29 } catch (error) { 30 return; 31 } 32 return apis; 33} 34 35function parseFiles(files) { 36 files = files.concat(collectArkUiApis()); 37 const fileContentList = []; 38 files.forEach(file => { 39 let fileContent = fs.readFileSync(file, 'utf-8'); 40 fileContentList.push({ 41 fileName: path.basename(file).replace(/.d.ts$/g, '.ts'), 42 fileContent: fileContent, 43 fileRoot: file, 44 }); 45 }); 46 47 const api = []; 48 const exportApi = []; 49 const returnDeclarationArr = new Set([]); 50 const hash = new Set([]); 51 52 fileContentList.forEach(item => { 53 const fileName = item.fileName.replace(/\.d.ts$/g, '.ts'); 54 let packageName = item.fileRoot.indexOf('build-tools\\ets-loader\\declarations') >= 0 || 55 item.fileRoot.indexOf('build-tools/ets-loader/declarations') >= 0 ? 56 'ArkUI' : fileName.replace(/\@|.ts$/g, ''); 57 ts.transpileModule(item.fileContent, { 58 compilerOptions: { 59 'target': ts.ScriptTarget.ES2017, 60 }, 61 fileName: fileName, 62 transformers: { before: [getReturnDeclarationArr(packageName, exportApi, returnDeclarationArr, fileName)] }, 63 }); 64 }); 65 66 fileContentList.forEach(item => { 67 const fileName = item.fileName.replace(/\.d.ts$/g, '.ts'); 68 let packageName = item.fileRoot.indexOf('build-tools\\ets-loader\\declarations') >= 0 || 69 item.fileRoot.indexOf('build-tools/ets-loader/declarations') >= 0 ? 'ArkUI' : 70 fileName.replace(/\@|.ts$/g, ''); 71 ts.transpileModule(item.fileContent, { 72 compilerOptions: { 73 'target': ts.ScriptTarget.ES2017, 74 }, 75 fileName: fileName, 76 transformers: { before: [processDeclarationSourceFile(packageName, api, exportApi, returnDeclarationArr, hash)] }, 77 }); 78 }); 79 return api; 80} 81exports.parseFiles = parseFiles; 82 83 84function visitAllNode(node, returnDeclarationArr, packageName) { 85 if ((ts.isMethodDeclaration(node) || ts.isFunctionDeclaration(node)) && node && node.type && 86 ts.isTypeReferenceNode(node.type)) { 87 returnDeclarationArr.add(node.type.typeName.getText()); 88 } 89 90 if (ts.isModuleDeclaration(node) && ts.isModuleBlock(node.body) && node.body && node.body.statements) { 91 node.body.statements.forEach(statement => { 92 if (statement.name) { 93 applicationModules.push({ 94 packageName: packageName, 95 className: node.name.escapedText, 96 methodName: statement.name.escapedText, 97 }); 98 } 99 }); 100 } 101 node.getChildren().forEach(item => visitAllNode(item, returnDeclarationArr, packageName)); 102} 103 104function getExportApi(node, packageName, exportApi) { 105 node.statements.forEach(stat => { 106 if (ts.isModuleDeclaration(stat)) { 107 if (stat.getText().indexOf('namespace') > 0) { 108 let apiInfo = { 109 isSystemApi: '公开API', 110 version: '', 111 deprecated: '', 112 permission: 'N/A', 113 sysCap: 'N/A', 114 model: '', 115 }; 116 exportApi.push({ 117 packageName: packageName, 118 className: stat.name.escapedText.toString(), 119 methodName: '', 120 apiInfo: getApiInfo(stat, apiInfo), 121 }); 122 } 123 } 124 }); 125} 126 127const getReturnDeclarationArr = (packageName, exportApi, returnDeclarationArr, fileName) => { 128 return (context) => { 129 return (node) => { 130 visitAllNode(node, returnDeclarationArr, packageName); 131 getExportApi(node, packageName, exportApi); 132 return node; 133 }; 134 }; 135}; 136exports.applicationModules = applicationModules; 137 138function processDeclarationSourceFile(packageName, api, exportApi, returnDeclarationArr, hash) { 139 return (context) => { 140 return (node) => { 141 const statements = node.statements; 142 const currentClassFunSet = new Set([]); 143 const currentTypeList = new Array(); 144 statements.forEach(stat => { 145 if (ts.isTypeAliasDeclaration(stat)) { 146 if (stat.type.types) { 147 let typeObj = { 148 name: stat.name.escapedText, 149 value: [], 150 }; 151 stat.type.types.forEach(type => { 152 if (type.literal && type.literal.text) { 153 typeObj.value.push(type.literal.text); 154 } 155 }); 156 if (typeObj.value.length > 0) { 157 currentTypeList.push(typeObj); 158 } 159 } 160 } 161 }); 162 163 statements.forEach(stat => { 164 let apiInfo = { 165 isSystemApi: '公开API', 166 version: '', 167 deprecated: '', 168 permission: 'N/A', 169 sysCap: 'N/A', 170 model: '', 171 }; 172 if (ts.isInterfaceDeclaration(stat)) { 173 collectInterfaceDeclaration(stat, packageName, api, exportApi, returnDeclarationArr, hash, apiInfo, currentTypeList); 174 } else if (ts.isModuleDeclaration(stat)) { 175 collectModuleDeclaration(stat, packageName, api, exportApi, returnDeclarationArr, hash, apiInfo, currentTypeList); 176 } else if (ts.isClassDeclaration(stat)) { 177 collectClassDeclaration(stat, packageName, api, exportApi, returnDeclarationArr, hash, apiInfo, currentTypeList); 178 } else if (ts.isEnumDeclaration(stat)) { 179 collectEnumDeclaration(stat, packageName, api, exportApi, returnDeclarationArr, hash, apiInfo, currentTypeList); 180 } else if (ts.isTypeAliasDeclaration(stat)) { 181 182 } else { 183 if (ts.isMethodDeclaration(stat) || ts.isMethodSignature(stat) || ts.isFunctionDeclaration(stat)) { 184 var methodName = stat.name.escapedText ? stat.name.escapedText.toString() : stat.name.text.toString(); 185 let className = ''; 186 exportApi.forEach(item => { 187 if (item.methodName === methodName && item.packageName === packageName) { 188 className = item.className; 189 if (item.apiInfo) { 190 apiInfo = item.apiInfo; 191 } 192 } 193 }); 194 addFunctionOnOffApi(packageName, className, methodName, getApiInfo(stat, apiInfo), 'Method', api, 195 hash, currentClassFunSet, stat); 196 } 197 } 198 }); 199 return node; 200 }; 201 }; 202} 203 204function collectInterfaceDeclaration(stat, packageName, api, exportApi, returnDeclarationArr, hash, apiInfo, currentTypeList) { 205 const className = stat.name.escapedText.toString(); 206 const interfaceChildren = stat.members; 207 collectEachChildNode(interfaceChildren, packageName, className, 'Field', api, exportApi, returnDeclarationArr, hash, 208 getApiInfo(stat, apiInfo), currentTypeList); 209} 210 211function collectClassDeclaration(stat, packageName, api, exportApi, returnDeclarationArr, hash, apiInfo, currentTypeList) { 212 const className = stat.name.escapedText.toString(); 213 const classChildren = stat.members; 214 collectEachChildNode(classChildren, packageName, className, 'Field', api, exportApi, returnDeclarationArr, hash, 215 getApiInfo(stat, apiInfo), currentTypeList); 216} 217 218function collectEnumDeclaration(stat, packageName, api, exportApi, returnDeclarationArr, hash, apiInfo, currentTypeList) { 219 const className = stat.name.escapedText.toString(); 220 const enumChildren = stat.members; 221 collectEachChildNode(enumChildren, packageName, className, 'Enum', api, exportApi, returnDeclarationArr, hash, 222 getApiInfo(stat, apiInfo), currentTypeList); 223} 224 225function collectModuleDeclaration(stat, packageName, api, exportApi, returnDeclarationArr, hash, apiInfo, currentTypeList) { 226 const className = stat.name.escapedText ? stat.name.escapedText.toString() : stat.name.text.toString(); 227 const moduleChildren = stat.body.statements; 228 collectEachChildNode(moduleChildren, packageName, className, 'Field', api, exportApi, returnDeclarationArr, hash, 229 getApiInfo(stat, apiInfo), currentTypeList); 230} 231 232function collectEachChildNode(children, packageName, className, faterApiType, api, exportApi, returnDeclarationArr, 233 hash, apiInfo, currentTypeList) { 234 const currentClassFunSet = new Set([]); 235 children.forEach(child => { 236 if (ts.isTypeAliasDeclaration(child)) { 237 if (child.type) { 238 let typeObj = collectTypeApi(child, packageName, className, faterApiType, api, exportApi, returnDeclarationArr, 239 hash, apiInfo); 240 if (typeObj.value.length > 0) { 241 currentTypeList.push(typeObj); 242 } 243 } 244 } 245 }); 246 247 children.forEach(child => { 248 let faterApiInfo = JSON.parse(JSON.stringify(apiInfo)); 249 let apiType = new String(faterApiType); 250 251 if (/export.*\{.*\}/g.test(child.getText())) { 252 exportApi.push({ 253 packageName: packageName, 254 className: className, 255 methodName: child.getText().replace('export', '').replace('{', '').replace('}', '').replace(';', '').trim(), 256 apiInfo: faterApiInfo, 257 }); 258 return; 259 } 260 261 if (ts.isInterfaceDeclaration(child)) { 262 collectInterfaceDeclaration(child, packageName, api, exportApi, returnDeclarationArr, hash, faterApiInfo); 263 } else if (ts.isModuleDeclaration(child)) { 264 collectModuleDeclaration(child, packageName, api, exportApi, returnDeclarationArr, hash, faterApiInfo); 265 } else if (ts.isClassDeclaration(child)) { 266 collectClassDeclaration(child, packageName, api, exportApi, returnDeclarationArr, hash, faterApiInfo); 267 } else if (ts.isEnumDeclaration(child)) { 268 collectEnumDeclaration(child, packageName, api, exportApi, returnDeclarationArr, hash, faterApiInfo); 269 } else { 270 if ((ts.isMethodDeclaration(child) || ts.isMethodSignature(child) || ts.isFunctionDeclaration(child)) && 271 (child.name.escapedText === 'on' || child.name.escapedText === 'off') && child.parameters && child.parameters.length > 0) { 272 apiType = 'Method'; 273 collectSpecialApis(child, apiType, packageName, className, faterApiInfo, api, exportApi, currentTypeList, 274 hash, apiInfo, currentClassFunSet); 275 } else { 276 collectMethodOrFieldApis(child, packageName, className, faterApiInfo, apiType, api, 277 hash, currentClassFunSet, child, returnDeclarationArr); 278 } 279 } 280 }); 281} 282 283function collectMethodOrFieldApis(child, packageName, className, faterApiInfo, apiType, api, 284 hash, currentClassFunSet, child, returnDeclarationArr) { 285 let methodName = ''; 286 if (ts.isMethodDeclaration(child) || ts.isMethodSignature(child) || ts.isFunctionDeclaration(child) || 287 ts.isCallSignatureDeclaration(child) || ts.isConstructSignatureDeclaration(child) || 288 ts.isIndexSignatureDeclaration(child)) { 289 if (child.name) { 290 methodName = child.name.getText(); 291 } else { 292 methodName = className; 293 } 294 apiType = 'Method'; 295 } else if (ts.isPropertyDeclaration(child) || ts.isPropertySignature(child)) { 296 if (child.type && child.type.parameters) { 297 methodName = child.name.escapedText; 298 apiType = 'Method'; 299 } else { 300 methodName = child.name.escapedText; 301 apiType = 'Field'; 302 } 303 } else { 304 if (child.name) { 305 methodName = child.name.getText(); 306 } 307 } 308 309 if (methodName !== '') { 310 addFunctionOnOffApi(packageName, className, methodName, faterApiInfo, apiType, api, 311 hash, currentClassFunSet, child); 312 } else { 313 if (child.getText().indexOf('constructor') === 0) { 314 methodName = 'constructor'; 315 apiType = 'Method'; 316 } else if (child.getText().indexOf('const') === 0) { 317 const dataObj = collectFiledOrConstant(apiType, methodName, child, returnDeclarationArr); 318 methodName = dataObj.name; 319 apiType = dataObj.apiType; 320 } else if (/\w+:\s*\w+/g.test(child.getText())) { 321 apiType = 'Field'; 322 methodName = child.getText().split(':')[0].trim(); 323 } 324 325 if (methodName !== '') { 326 addApi(packageName, className, methodName, child.getText(), 327 getApiInfo(child, faterApiInfo), apiType, api, hash); 328 } 329 } 330} 331 332function collectFiledOrConstant(apiType, methodName, child, returnDeclarationArr) { 333 if (child.getText().replace('const', '').indexOf(':') > 0) { 334 if (returnDeclarationArr.has(child.getText().replace('const', '').split(':')[1].trim())) { 335 apiType = 'Field'; 336 } else { 337 apiType = 'Constant'; 338 } 339 methodName = child.getText().replace('const', '').split(':')[0].trim(); 340 } else if (child.getText().replace('const', '').indexOf('=') > 0) { 341 if (returnDeclarationArr.has(child.getText().replace('const', '').split('=')[1].trim())) { 342 apiType = 'Field'; 343 } else { 344 apiType = 'Constant'; 345 } 346 methodName = child.getText().replace('const', '').split('=')[0].trim(); 347 } 348 return { apiType, methodName }; 349} 350 351function collectSpecialApis(child, apiType, packageName, className, faterApiInfo, api, exportApi, currentTypeList, 352 hash, apiInfo, currentClassFunSet) { 353 for (let i = 0; i < child.parameters.length; i++) { 354 const param = child.parameters[i]; 355 if (param.name.escapedText === 'type' || param.name.escapedText === 'event' || 356 param.name.escapedText === 'eventType') { 357 collectCommonTypesOfApi(packageName, className, faterApiInfo, apiType, api, hash, currentClassFunSet, 358 child, currentTypeList, param); 359 break; 360 } else { 361 let methodName = child.name.escapedText; 362 addFunctionOnOffApi(packageName, className, methodName, faterApiInfo, apiType, api, 363 hash, currentClassFunSet, child); 364 } 365 } 366} 367 368function collectCommonTypesOfApi(packageName, className, faterApiInfo, apiType, api, hash, currentClassFunSet, 369 child, currentTypeList, param) { 370 if (param.type && param.type.literal && param.type.literal.text) { 371 const typeTextArr = param.getText().replace(/\s*/g, '').split(':'); 372 if (typeTextArr[0] === 'type' || typeTextArr[0] === 'event') { 373 let methodName = child.name.escapedText + '_' + param.type.literal.text; 374 addFunctionOnOffApi(packageName, className, methodName, faterApiInfo, apiType, api, 375 hash, currentClassFunSet, child); 376 } 377 } else if (param.type && param.type.types && param.type.types.length > 0) { 378 param.type.types.forEach(type => { 379 if (type.literal && type.literal.text) { 380 let methodName = child.name.escapedText + '_' + type.literal.text; 381 addFunctionOnOffApi(packageName, className, methodName, faterApiInfo, apiType, api, 382 hash, currentClassFunSet, child); 383 } 384 }); 385 } else if (param.type && param.type.typeName && param.type.typeName.escapedText) { 386 collectInCurrentTypeListApi(packageName, className, faterApiInfo, apiType, api, 387 hash, currentClassFunSet, child, currentTypeList, param); 388 } else { 389 let methodName = child.name.escapedText; 390 addFunctionOnOffApi(packageName, className, methodName, faterApiInfo, apiType, api, 391 hash, currentClassFunSet, child); 392 } 393} 394 395function collectInCurrentTypeListApi(packageName, className, faterApiInfo, apiType, api, 396 hash, currentClassFunSet, child, currentTypeList, param) { 397 if (currentTypeList && currentTypeList.length > 0) { 398 currentTypeList.forEach(type => { 399 if (type.name === param.type.typeName.escapedText) { 400 type.value.forEach(typeString => { 401 let methodName = child.name.escapedText + '_' + typeString; 402 addFunctionOnOffApi(packageName, className, methodName, faterApiInfo, apiType, api, 403 hash, currentClassFunSet, child); 404 }); 405 } 406 }); 407 } else if (param.type.typeName.escapedText === 'InnerEvent') { 408 let methodName = child.name.escapedText + '_' + param.type.typeName.escapedText; 409 addFunctionOnOffApi(packageName, className, methodName, faterApiInfo, apiType, api, 410 hash, currentClassFunSet, child); 411 } else { 412 let methodName = child.name.escapedText; 413 addFunctionOnOffApi(packageName, className, methodName, faterApiInfo, apiType, api, 414 hash, currentClassFunSet, child); 415 } 416} 417 418function collectTypeApi(child, packageName, className, faterApiType, api, exportApi, returnDeclarationArr, 419 hash, apiInfo) { 420 let typeObj = { 421 name: child.name.escapedText, 422 value: [], 423 }; 424 425 if (child.type.types) { 426 child.type.types.forEach(type => { 427 if (type.literal && type.literal.text) { 428 typeObj.value.push(type.literal.text); 429 if (typeCollection) { 430 let faterApiInfo = JSON.parse(JSON.stringify(apiInfo)); 431 addApi(packageName, child.name.escapedText, type.literal.text, child.getText(), 432 getApiInfo(child, faterApiInfo), 'Type', api, hash); 433 } 434 } else { 435 if (type.getText() !== '') { 436 typeObj.value.push(type.getText()); 437 if (typeCollection) { 438 let faterApiInfo = JSON.parse(JSON.stringify(apiInfo)); 439 addApi(packageName, child.name.escapedText, type.getText(), child.getText(), 440 getApiInfo(child, faterApiInfo), 'Type', api, hash); 441 } 442 } 443 } 444 }); 445 } else if (child.type.members) { 446 child.type.members.forEach(member => { 447 member.type.types.forEach(type => { 448 collectMembersApi(type, packageName, child, api, hash, typeObj, apiInfo, className); 449 }); 450 }); 451 } 452 return typeObj; 453} 454 455function collectMembersApi(type, packageName, child, api, hash, typeObj, apiInfo, className) { 456 if (type.literal && type.literal.text) { 457 typeObj.value.push(type.literal.text); 458 if (typeCollection) { 459 let faterApiInfo = JSON.parse(JSON.stringify(apiInfo)); 460 addApi(packageName, child.name.escapedText, type.literal.text, child.getText(), 461 getApiInfo(child, faterApiInfo), 'Type', api, hash); 462 } 463 } else { 464 if (type.getText() !== '') { 465 typeObj.value.push(type.getText()); 466 if (typeCollection) { 467 let faterApiInfo = JSON.parse(JSON.stringify(apiInfo)); 468 addApi(packageName, className, child.name.escapedText, child.getText(), 469 getApiInfo(child, faterApiInfo), 'Type', api, hash); 470 } 471 } 472 } 473} 474 475function addFunctionOnOffApi(packageName, className, methodName, apiInfo, apiType, api, 476 hash, currentClassFunSet, childNode) { 477 if (currentClassFunSet.has(methodName) && !isNotMerge) { 478 for (let i = 0; i < api.length; i++) { 479 const curApi = api[i]; 480 if (curApi.packageName === packageName && curApi.className === className && 481 curApi.methodName === methodName) { 482 if (curApi.methodText.indexOf(`${childNode.getText().replace('declare', '').trim()}`) < 0) { 483 curApi.methodText += `<br>${childNode.getText().replace('declare', '').trim()}`; 484 break; 485 } 486 } 487 } 488 } else { 489 if (!currentClassFunSet.has(methodName)) { 490 currentClassFunSet.add(methodName); 491 addApi(packageName, className, methodName, childNode.getText().replace('declare', '').trim(), 492 getApiInfo(childNode, apiInfo), apiType, api, hash); 493 } else { 494 if (childNode.getFullText().indexOf('\/**') >= 0) { 495 addApi(packageName, className, methodName, childNode.getText().replace('declare', '').trim(), 496 getApiInfo(childNode, apiInfo), apiType, api, hash); 497 } else { 498 let firstApiInfo = {}; 499 for (let i = 0; i < api.length; i++) { 500 const curApi = api[i]; 501 if (curApi.packageName === packageName && curApi.className === className && 502 curApi.methodName === methodName) { 503 firstApiInfo.isSystemApi = curApi.isSystemApi; 504 firstApiInfo.version = curApi.version; 505 firstApiInfo.sysCap = curApi.sysCap; 506 firstApiInfo.permission = curApi.permission; 507 firstApiInfo.model = curApi.model; 508 } 509 510 } 511 addApi(packageName, className, methodName, childNode.getText().replace('declare', '').trim(), 512 firstApiInfo, apiType, api, hash); 513 } 514 } 515 } 516} 517 518function getApiInfo(node, apiInfo) { 519 const notesStr = node.getFullText().replace(node.getText(), ''); 520 521 if (notesStr !== '') { 522 if (/\@[S|s][Y|y][S|s][T|t][E|e][M|m][A|a][P|p][I|i]/g.test(notesStr)) { 523 apiInfo.isSystemApi = '系统API'; 524 } 525 if (/\@[S|s][I|i][N|n][C|c][E|e]\s*(\d+)/g.test(notesStr)) { 526 notesStr.replace(/\@[S|s][I|i][N|n][C|c][E|e]\s*(\d+)/g, (versionInfo) => { 527 apiInfo.version = versionInfo.replace(/\@[S|s][I|i][N|n][C|c][E|e]/g, '').trim(); 528 }); 529 } 530 if (/\@[D|d][E|e][P|p][R|r][E|e][C|c][A|a][T|t][E|e][D|d].*[S|s][I|i][N|n][C|c][E|e]\s*(\d+)/g.test(notesStr)) { 531 notesStr.replace(/\@[D|d][E|e][P|p][R|r][E|e][C|c][A|a][T|t][E|e][D|d].*[S|s][I|i][N|n][C|c][E|e]\s*(\d+)/g, 532 versionInfo => { 533 apiInfo.deprecated = versionInfo.replace( 534 /\@[D|d][E|e][P|p][R|r][E|e][C|c][A|a][T|t][E|e][D|d].*[S|s][I|i][N|n][C|c][E|e]\s*/g, '').trim(); 535 }); 536 } 537 if (/\@[F|f][A|a][M|m][O|o][D|d][E|e][L|l][O|o][N|n][L|l][Y|y]/g.test(notesStr)) { 538 notesStr.replace(/\@[F|f][A|a][M|m][O|o][D|d][E|e][L|l][O|o][N|n][L|l][Y|y]/g, modelInfo => { 539 apiInfo.model = modelInfo; 540 }); 541 } else if (/\@[S|s][T|t][A|a][G|g][E|e][M|m][O|o][D|d][E|e][L|l][O|o][N|n][L|l][Y|y]/g.test(notesStr)) { 542 notesStr.replace(/\@[S|s][T|t][A|a][G|g][E|e][M|m][O|o][D|d][E|e][L|l][O|o][N|n][L|l][Y|y]/g, modelInfo => { 543 apiInfo.model = modelInfo; 544 }); 545 } 546 if (/\@[S|s][Y|y][S|s][C|c][A|a][P|p]\s*((\w|\.|\/|\{|\@|\}|\s)+)/g.test(notesStr)) { 547 notesStr.replace(/\@[S|s][Y|y][S|s][C|c][A|a][P|p]\s*((\w|\.|\/|\{|\@|\}|\s)+)/g, sysCapInfo => { 548 apiInfo.sysCap = sysCapInfo.replace(/\@[S|s][Y|y][S|s][C|c][A|a][P|p]/g, '').trim(); 549 }); 550 } 551 if (/\@[P|p][E|e][R|r][M|m][I|i][S|s][S|s][I|i][O|o][N|n]\s*((\w|\.|\/|\{|\@|\}|\s)+)/g.test(notesStr)) { 552 notesStr.replace(/\@[P|p][E|e][R|r][M|m][I|i][S|s][S|s][I|i][O|o][N|n]\s*((\w|\.|\/|\{|\@|\}|\s)+)/g, 553 permissionInfo => { 554 apiInfo.permission = permissionInfo. 555 replace(/\@[P|p][E|e][R|r][M|m][I|i][S|s][S|s][I|i][O|o][N|n]/g, '').trim(); 556 }); 557 } 558 } 559 return apiInfo; 560} 561 562function addApi(packageName, className, methodName, methodText, apiInfo, apiType, api, hash) { 563 let recard = isNotMerge ? `${packageName}.${className}/${methodName}/${methodText}` : 564 `${packageName}.${className}/${methodName}`; 565 566 if (!hash.has(recard)) { 567 hash.add(recard); 568 api.push({ 569 packageName: packageName, 570 className: className, 571 methodName: methodName, 572 methodText: methodText.replace(/export\s/g, ''), 573 isSystemApi: apiInfo.isSystemApi, 574 version: apiInfo.version, 575 deprecated: apiInfo.deprecated, 576 apiType: apiType, 577 sysCap: apiInfo.sysCap, 578 permission: apiInfo.permission, 579 model: apiInfo.model, 580 applicationFile: '', 581 pos: '', 582 functionType: '', 583 optionalArg: 0, 584 arguments: 0, 585 }); 586 } 587} 588 589async function getExcelBuffer(api) { 590 const workbook = new ExcelJS.Workbook(); 591 const sheet = workbook.addWorksheet('Js Api', { views: [{ xSplit: 1 }] }); 592 sheet.getRow(1).values = ['模块名', '类名', '方法名', '函数', '文件位置', '类型', 'SysCap', 593 '权限', '支持起始版本', '访问级别']; 594 for (let i = 1; i <= api.length; i++) { 595 const apiData = api[i - 1]; 596 sheet.getRow(i + 1).values = [apiData.packageName, apiData.className, apiData.methodName, 597 apiData.methodText, apiData.pos, apiData.apiType, apiData.sysCap, apiData.permission, 598 apiData.version, apiData.isSystemApi]; 599 } 600 const buffer = await workbook.xlsx.writeBuffer(); 601 return buffer; 602} 603 604exports.getExcelBuffer = getExcelBuffer; 605 606function readFile(dir, utFiles) { 607 try { 608 const files = fs.readdirSync(dir); 609 files.forEach((element) => { 610 const filePath = path.join(dir, element); 611 const status = fs.statSync(filePath); 612 if (status.isDirectory()) { 613 readFile(filePath, utFiles); 614 } else { 615 if (/\.d\.ts/.test(filePath)) { 616 utFiles.push(filePath); 617 } 618 } 619 }); 620 } catch (e) { 621 console.error('ETS ERROR: ' + e); 622 } 623} 624 625exports.readFile = readFile; 626 627async function excel(api) { 628 let buffer = await getExcelBuffer(api); 629 fs.writeFile('../Js_Api.xlsx', buffer, function (err) { 630 if (err) { 631 console.error('WEITE FAILED: ', err); 632 return; 633 } else { 634 console.log('WRITE SUCCEED!'); 635 } 636 }); 637} 638 639exports.excel = excel;