161847f8eSopenharmony_ci/* 261847f8eSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 361847f8eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 461847f8eSopenharmony_ci * you may not use this file except in compliance with the License. 561847f8eSopenharmony_ci * You may obtain a copy of the License at 661847f8eSopenharmony_ci * 761847f8eSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 861847f8eSopenharmony_ci * 961847f8eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1061847f8eSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1161847f8eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1261847f8eSopenharmony_ci * See the License for the specific language governing permissions and 1361847f8eSopenharmony_ci * limitations under the License. 1461847f8eSopenharmony_ci */ 1561847f8eSopenharmony_ciconst path = require('path'); 1661847f8eSopenharmony_ciconst fs = require('fs'); 1761847f8eSopenharmony_ciconst ts = require('typescript'); 1861847f8eSopenharmony_ci 1961847f8eSopenharmony_cilet sourceFile = null; 2061847f8eSopenharmony_cilet lastNoteStr = ''; 2161847f8eSopenharmony_cilet lastNodeName = ''; 2261847f8eSopenharmony_ciconst referencesMap = new Map(); 2361847f8eSopenharmony_ciconst referencesModuleMap = new Map(); 2461847f8eSopenharmony_ciconst kitFileNeedDeleteMap = new Map(); 2561847f8eSopenharmony_ci/** 2661847f8eSopenharmony_ci * @enum {string} references地址的切换类型 2761847f8eSopenharmony_ci */ 2861847f8eSopenharmony_ciconst REFERENCE_TYPE = { 2961847f8eSopenharmony_ci TOLOCAL: 'toLocal', 3061847f8eSopenharmony_ci TORIGHTSDK: 'toRightSDK', 3161847f8eSopenharmony_ci TOSDK: 'toSDK', 3261847f8eSopenharmony_ci}; 3361847f8eSopenharmony_ciconst PATT = { 3461847f8eSopenharmony_ci GET_REFERENCE: /\/\/\/\s*<reference.*>/g, 3561847f8eSopenharmony_ci GET_REFERENCEURL: /\/\/\/\s*<reference\s*path=("|')(.*)("|')\s*\/>/g, 3661847f8eSopenharmony_ci REFERENCEURL_LOCAL: /(.\/)?(\S*)@internal\/component\/ets\/(\S*)/g, 3761847f8eSopenharmony_ci REFERENCEURL_RIGHTSDK: /(..\/)(\S*)build-tools\/ets-loader\/declarations\/(\S*)/g, 3861847f8eSopenharmony_ci REFERENCEURL_SDK: /(..\/)(\S*)component\/(\S*)/g, 3961847f8eSopenharmony_ci}; 4061847f8eSopenharmony_cifunction collectDeclaration(url) { 4161847f8eSopenharmony_ci // 入口 4261847f8eSopenharmony_ci try { 4361847f8eSopenharmony_ci const utPath = path.resolve(__dirname, url); 4461847f8eSopenharmony_ci const arktsPath = path.resolve(utPath, '../arkts'); 4561847f8eSopenharmony_ci const kitPath = path.resolve(utPath, '../kits'); 4661847f8eSopenharmony_ci const utFiles = []; 4761847f8eSopenharmony_ci readFile(utPath, utFiles); // 读取文件 4861847f8eSopenharmony_ci readFile(arktsPath, utFiles); // 读取文件 4961847f8eSopenharmony_ci tsTransform(utFiles, deleteSystemApi); 5061847f8eSopenharmony_ci tsTransformKitFile(kitPath); 5161847f8eSopenharmony_ci } catch (error) { 5261847f8eSopenharmony_ci console.error('DELETE_SYSTEM_PLUGIN ERROR: ', error); 5361847f8eSopenharmony_ci } 5461847f8eSopenharmony_ci} 5561847f8eSopenharmony_ci 5661847f8eSopenharmony_ci/** 5761847f8eSopenharmony_ci * 解析url目录下方的kit文件,删除对应systemapi 5861847f8eSopenharmony_ci * @param { string } kitPath kit文件路径 5961847f8eSopenharmony_ci */ 6061847f8eSopenharmony_cifunction tsTransformKitFile(kitPath) { 6161847f8eSopenharmony_ci kitFileNeedDeleteMap.delete(''); 6261847f8eSopenharmony_ci if (kitFileNeedDeleteMap.length === 0) { 6361847f8eSopenharmony_ci return; 6461847f8eSopenharmony_ci } 6561847f8eSopenharmony_ci const kitFiles = []; 6661847f8eSopenharmony_ci readFile(kitPath, kitFiles); // 读取文件 6761847f8eSopenharmony_ci kitFiles.forEach((kitFile) => { 6861847f8eSopenharmony_ci const kitName = processFileNameWithoutExt(kitFile).replace('@kit.', ''); 6961847f8eSopenharmony_ci const content = fs.readFileSync(kitFile, 'utf-8'); 7061847f8eSopenharmony_ci const fileName = processFileName(kitFile); 7161847f8eSopenharmony_ci let sourceFile = ts.createSourceFile(fileName, content, ts.ScriptTarget.ES2017, true); 7261847f8eSopenharmony_ci const sourceInfo = getKitNewSourceFile(sourceFile, kitName); 7361847f8eSopenharmony_ci if (isEmptyFile(sourceInfo.sourceFile)) { 7461847f8eSopenharmony_ci return; 7561847f8eSopenharmony_ci } 7661847f8eSopenharmony_ci const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); 7761847f8eSopenharmony_ci let result = printer.printNode(ts.EmitHint.Unspecified, sourceInfo.sourceFile, sourceFile); 7861847f8eSopenharmony_ci if (sourceInfo.copyrightMessage !== '') { 7961847f8eSopenharmony_ci result = sourceInfo.copyrightMessage + result; 8061847f8eSopenharmony_ci } 8161847f8eSopenharmony_ci writeFile(kitFile, result); 8261847f8eSopenharmony_ci }); 8361847f8eSopenharmony_ci} 8461847f8eSopenharmony_ci 8561847f8eSopenharmony_ci/** 8661847f8eSopenharmony_ci * 处理kit中需要删除的节点,在其他文件被systemapi修饰的api 8761847f8eSopenharmony_ci * @param { ts.SourceFile } sourceFile 8861847f8eSopenharmony_ci * @param { string } kitName 8961847f8eSopenharmony_ci * @returns 删除完的节点,全部删除为空字符串 9061847f8eSopenharmony_ci */ 9161847f8eSopenharmony_cifunction getKitNewSourceFile(sourceFile, kitName) { 9261847f8eSopenharmony_ci const newStatements = []; 9361847f8eSopenharmony_ci const needDeleteExportName = new Set(); 9461847f8eSopenharmony_ci const needDeleteMap = kitFileNeedDeleteMap.get(kitName); 9561847f8eSopenharmony_ci let copyrightMessage = ''; 9661847f8eSopenharmony_ci // 初始化ts工厂 9761847f8eSopenharmony_ci const factory = ts.factory; 9861847f8eSopenharmony_ci sourceFile.statements.forEach((statement, index) => { 9961847f8eSopenharmony_ci if (ts.isImportDeclaration(statement)) { 10061847f8eSopenharmony_ci const newStatement = processKitImportDeclaration(statement, needDeleteMap, needDeleteExportName); 10161847f8eSopenharmony_ci if (newStatement) { 10261847f8eSopenharmony_ci newStatements.push(newStatement); 10361847f8eSopenharmony_ci } else if (index === 0) { 10461847f8eSopenharmony_ci copyrightMessage = sourceFile.getFullText().replace(sourceFile.getText(), ''); 10561847f8eSopenharmony_ci } 10661847f8eSopenharmony_ci } else if (ts.isExportDeclaration(statement)) { 10761847f8eSopenharmony_ci const exportSpecifiers = statement.exportClause.elements.filter((item) => { 10861847f8eSopenharmony_ci return !needDeleteExportName.has(item.name.escapedText.toString()); 10961847f8eSopenharmony_ci }); 11061847f8eSopenharmony_ci if (exportSpecifiers.length !== 0) { 11161847f8eSopenharmony_ci statement.exportClause = factory.updateNamedExports(statement.exportClause, exportSpecifiers); 11261847f8eSopenharmony_ci newStatements.push(statement); 11361847f8eSopenharmony_ci } 11461847f8eSopenharmony_ci } 11561847f8eSopenharmony_ci }); 11661847f8eSopenharmony_ci sourceFile = factory.updateSourceFile(sourceFile, newStatements); 11761847f8eSopenharmony_ci return { sourceFile, copyrightMessage }; 11861847f8eSopenharmony_ci} 11961847f8eSopenharmony_ci 12061847f8eSopenharmony_ci/** 12161847f8eSopenharmony_ci * 根据节点和需要删除的节点数据生成新节点 12261847f8eSopenharmony_ci * @param { ts.ImportDeclaration } statement 需要处理的import节点 12361847f8eSopenharmony_ci * @param { Map} needDeleteMap 需要删除的节点数据 12461847f8eSopenharmony_ci * @param { Map} needDeleteExportName 需要删除的导出节点 12561847f8eSopenharmony_ci * @returns { ts.ImportDeclaration | undefined } 返回新的import节点,全部删除为undefined 12661847f8eSopenharmony_ci */ 12761847f8eSopenharmony_cifunction processKitImportDeclaration(statement, needDeleteMap, needDeleteExportName) { 12861847f8eSopenharmony_ci // 初始化ts工厂 12961847f8eSopenharmony_ci const factory = ts.factory; 13061847f8eSopenharmony_ci const importClause = statement.importClause; 13161847f8eSopenharmony_ci if (!ts.isImportClause(importClause)) { 13261847f8eSopenharmony_ci return statement; 13361847f8eSopenharmony_ci } 13461847f8eSopenharmony_ci const importPath = statement.moduleSpecifier.text.replace('../', ''); 13561847f8eSopenharmony_ci if (needDeleteMap === undefined || !needDeleteMap.has(importPath)) { 13661847f8eSopenharmony_ci const hasFilePath = hasFileByImportPath(importPath); 13761847f8eSopenharmony_ci return hasFilePath ? statement : undefined; 13861847f8eSopenharmony_ci } 13961847f8eSopenharmony_ci const currImportInfo = needDeleteMap.get(importPath); 14061847f8eSopenharmony_ci let defaultName = ''; 14161847f8eSopenharmony_ci let importNodeNamedBindings = []; 14261847f8eSopenharmony_ci if (importClause.name) { 14361847f8eSopenharmony_ci if (currImportInfo.default === importClause.name.escapedText.toString()) { 14461847f8eSopenharmony_ci //import buffer from "../@ohos.buffer"; 14561847f8eSopenharmony_ci needDeleteExportName.add(currImportInfo.default); 14661847f8eSopenharmony_ci } else { 14761847f8eSopenharmony_ci defaultName = importClause.name.escapedText.toString(); 14861847f8eSopenharmony_ci } 14961847f8eSopenharmony_ci } 15061847f8eSopenharmony_ci const namedBindings = importClause.namedBindings; 15161847f8eSopenharmony_ci if (namedBindings !== undefined && ts.isNamedImports(namedBindings)) { 15261847f8eSopenharmony_ci const elements = namedBindings.elements; 15361847f8eSopenharmony_ci elements.forEach((element) => { 15461847f8eSopenharmony_ci const exportName = element.propertyName ? 15561847f8eSopenharmony_ci element.propertyName.escapedText.toString() : 15661847f8eSopenharmony_ci element.name.escapedText.toString(); 15761847f8eSopenharmony_ci if (!currImportInfo.exportName.has(exportName)) { 15861847f8eSopenharmony_ci importNodeNamedBindings.push(factory.createImportSpecifier(element.propertyName, element.name)); 15961847f8eSopenharmony_ci } else { 16061847f8eSopenharmony_ci needDeleteExportName.add(element.name.escapedText.toString()); 16161847f8eSopenharmony_ci } 16261847f8eSopenharmony_ci }); 16361847f8eSopenharmony_ci } 16461847f8eSopenharmony_ci if (defaultName !== '' || importNodeNamedBindings.length !== 0) { 16561847f8eSopenharmony_ci const newImportNode = factory.createImportDeclaration( 16661847f8eSopenharmony_ci undefined, 16761847f8eSopenharmony_ci undefined, 16861847f8eSopenharmony_ci factory.createImportClause( 16961847f8eSopenharmony_ci false, 17061847f8eSopenharmony_ci defaultName === '' ? undefined : factory.createIdentifier(defaultName), 17161847f8eSopenharmony_ci importNodeNamedBindings.length === 0 ? undefined : factory.createNamedImports(importNodeNamedBindings) 17261847f8eSopenharmony_ci ), 17361847f8eSopenharmony_ci statement.moduleSpecifier 17461847f8eSopenharmony_ci ); 17561847f8eSopenharmony_ci return newImportNode; 17661847f8eSopenharmony_ci } 17761847f8eSopenharmony_ci return undefined; 17861847f8eSopenharmony_ci} 17961847f8eSopenharmony_ci 18061847f8eSopenharmony_ci/** 18161847f8eSopenharmony_ci * 判断文件路径对应的文件是否存在 18261847f8eSopenharmony_ci * @param {string} importPath kit文件import 18361847f8eSopenharmony_ci * @returns {boolean} importPath是否存在 18461847f8eSopenharmony_ci */ 18561847f8eSopenharmony_cifunction hasFileByImportPath(importPath) { 18661847f8eSopenharmony_ci let fileDir = path.resolve(apiSourcePath); 18761847f8eSopenharmony_ci if (importPath.startsWith('@arkts')) { 18861847f8eSopenharmony_ci fileDir = path.resolve(apiSourcePath, '../arkts'); 18961847f8eSopenharmony_ci } 19061847f8eSopenharmony_ci const flag = ['.d.ts', '.d.ets'].some(ext => { 19161847f8eSopenharmony_ci const filePath = path.resolve(fileDir, `${importPath}${ext}`); 19261847f8eSopenharmony_ci return fs.existsSync(filePath); 19361847f8eSopenharmony_ci }); 19461847f8eSopenharmony_ci return flag; 19561847f8eSopenharmony_ci} 19661847f8eSopenharmony_ci 19761847f8eSopenharmony_ci/** 19861847f8eSopenharmony_ci * 统一处理文件名称,修改后缀等 19961847f8eSopenharmony_ci * @param {string} filePath 文件路径 20061847f8eSopenharmony_ci * @returns {string} filename 文件名称 20161847f8eSopenharmony_ci */ 20261847f8eSopenharmony_cifunction processFileName(filePath) { 20361847f8eSopenharmony_ci return path 20461847f8eSopenharmony_ci .basename(filePath) 20561847f8eSopenharmony_ci .replace(/\.d\.ts$/g, '.ts') 20661847f8eSopenharmony_ci .replace(/\.d\.ets$/g, '.ets'); 20761847f8eSopenharmony_ci} 20861847f8eSopenharmony_ci 20961847f8eSopenharmony_cifunction processFileNameWithoutExt(filePath) { 21061847f8eSopenharmony_ci return path 21161847f8eSopenharmony_ci .basename(filePath) 21261847f8eSopenharmony_ci .replace(/\.d\.ts$/g, '') 21361847f8eSopenharmony_ci .replace(/\.d\.ets$/g, '') 21461847f8eSopenharmony_ci .replace(/\.ts$/g, '') 21561847f8eSopenharmony_ci .replace(/\.ets$/g, ''); 21661847f8eSopenharmony_ci} 21761847f8eSopenharmony_ci 21861847f8eSopenharmony_ci/** 21961847f8eSopenharmony_ci * 遍历所有文件进行处理 22061847f8eSopenharmony_ci * @param {Array} utFiles 所有文件 22161847f8eSopenharmony_ci * @param {deleteSystemApi} callback 回调函数 22261847f8eSopenharmony_ci */ 22361847f8eSopenharmony_cifunction tsTransform(utFiles, callback) { 22461847f8eSopenharmony_ci utFiles.forEach((url) => { 22561847f8eSopenharmony_ci const apiBaseName = path.basename(url); 22661847f8eSopenharmony_ci if (/\.json/.test(url) || apiBaseName === 'index-full.d.ts') { 22761847f8eSopenharmony_ci // 特殊类型文件处理 22861847f8eSopenharmony_ci const content = fs.readFileSync(url, 'utf-8'); 22961847f8eSopenharmony_ci writeFile(url, content); 23061847f8eSopenharmony_ci } else if (/\.d\.ts/.test(apiBaseName) || /\.d\.ets/.test(apiBaseName)) { 23161847f8eSopenharmony_ci // dts文件处理 23261847f8eSopenharmony_ci let content = fs.readFileSync(url, 'utf-8'); // 文件内容 23361847f8eSopenharmony_ci const fileName = processFileName(url); 23461847f8eSopenharmony_ci let references = content.match(PATT.GET_REFERENCE); 23561847f8eSopenharmony_ci if (references) { 23661847f8eSopenharmony_ci referencesMap.set(url, { references: references }); 23761847f8eSopenharmony_ci for (let index = 0; index < references.length; index++) { 23861847f8eSopenharmony_ci const item = references[index]; 23961847f8eSopenharmony_ci content = content.replace(item, ''); 24061847f8eSopenharmony_ci } 24161847f8eSopenharmony_ci } 24261847f8eSopenharmony_ci ts.transpileModule(content, { 24361847f8eSopenharmony_ci compilerOptions: { 24461847f8eSopenharmony_ci target: ts.ScriptTarget.ES2017, 24561847f8eSopenharmony_ci }, 24661847f8eSopenharmony_ci fileName: fileName, 24761847f8eSopenharmony_ci transformers: { before: [callback(url)] }, 24861847f8eSopenharmony_ci }); 24961847f8eSopenharmony_ci } 25061847f8eSopenharmony_ci }); 25161847f8eSopenharmony_ci} 25261847f8eSopenharmony_ci/** 25361847f8eSopenharmony_ci * 切换references或者references中path的格式 25461847f8eSopenharmony_ci * @param {string} references references或者references中的path 25561847f8eSopenharmony_ci * @param {REFERENCE_TYPE} reverse 切换类型 25661847f8eSopenharmony_ci * @returns {string} 25761847f8eSopenharmony_ci */ 25861847f8eSopenharmony_cifunction referencesToOthers(references, type) { 25961847f8eSopenharmony_ci let referencesurl; 26061847f8eSopenharmony_ci let hasFullpatt = references.match(PATT.GET_REFERENCEURL); 26161847f8eSopenharmony_ci let isFullReferenceurl = hasFullpatt && hasFullpatt.length > 0; 26261847f8eSopenharmony_ci if (isFullReferenceurl) { 26361847f8eSopenharmony_ci referencesurl = RegExp.$2; 26461847f8eSopenharmony_ci } else { 26561847f8eSopenharmony_ci referencesurl = references; 26661847f8eSopenharmony_ci } 26761847f8eSopenharmony_ci let currentType = ''; 26861847f8eSopenharmony_ci if (referencesurl.match(PATT.REFERENCEURL_LOCAL)) { 26961847f8eSopenharmony_ci currentType = REFERENCE_TYPE.TOLOCAL; 27061847f8eSopenharmony_ci } else if (referencesurl.match(PATT.REFERENCEURL_RIGHTSDK)) { 27161847f8eSopenharmony_ci currentType = REFERENCE_TYPE.TORIGHTSDK; 27261847f8eSopenharmony_ci } else if (referencesurl.match(PATT.REFERENCEURL_SDK)) { 27361847f8eSopenharmony_ci currentType = REFERENCE_TYPE.TOSDK; 27461847f8eSopenharmony_ci } 27561847f8eSopenharmony_ci if (currentType === '' || currentType === type) { 27661847f8eSopenharmony_ci return references; 27761847f8eSopenharmony_ci } 27861847f8eSopenharmony_ci let starturl = ''; 27961847f8eSopenharmony_ci let fileName = ''; 28061847f8eSopenharmony_ci switch (currentType) { 28161847f8eSopenharmony_ci case REFERENCE_TYPE.TOLOCAL: 28261847f8eSopenharmony_ci starturl = RegExp.$2; 28361847f8eSopenharmony_ci fileName = RegExp.$3; 28461847f8eSopenharmony_ci break; 28561847f8eSopenharmony_ci case REFERENCE_TYPE.TORIGHTSDK: 28661847f8eSopenharmony_ci starturl = RegExp.$2; 28761847f8eSopenharmony_ci fileName = RegExp.$3; 28861847f8eSopenharmony_ci break; 28961847f8eSopenharmony_ci case REFERENCE_TYPE.TOSDK: 29061847f8eSopenharmony_ci starturl = RegExp.$2; 29161847f8eSopenharmony_ci fileName = RegExp.$3; 29261847f8eSopenharmony_ci break; 29361847f8eSopenharmony_ci default: 29461847f8eSopenharmony_ci break; 29561847f8eSopenharmony_ci } 29661847f8eSopenharmony_ci let finallyurl; 29761847f8eSopenharmony_ci switch (type) { 29861847f8eSopenharmony_ci case REFERENCE_TYPE.TOLOCAL: 29961847f8eSopenharmony_ci finallyurl = `${starturl === '' ? './' : ''}${starturl}@internal/component/ets/${fileName}`; 30061847f8eSopenharmony_ci break; 30161847f8eSopenharmony_ci case REFERENCE_TYPE.TORIGHTSDK: 30261847f8eSopenharmony_ci finallyurl = `../${starturl}build-tools/ets-loader/declarations/${fileName}`; 30361847f8eSopenharmony_ci break; 30461847f8eSopenharmony_ci case REFERENCE_TYPE.TOSDK: 30561847f8eSopenharmony_ci finallyurl = `../${starturl}component/${fileName}`; 30661847f8eSopenharmony_ci break; 30761847f8eSopenharmony_ci default: 30861847f8eSopenharmony_ci break; 30961847f8eSopenharmony_ci } 31061847f8eSopenharmony_ci if (isFullReferenceurl) { 31161847f8eSopenharmony_ci finallyurl = `/// <reference path="${finallyurl}"/>`; 31261847f8eSopenharmony_ci } 31361847f8eSopenharmony_ci return finallyurl; 31461847f8eSopenharmony_ci} 31561847f8eSopenharmony_ci 31661847f8eSopenharmony_ci/** 31761847f8eSopenharmony_ci * 读取目录下所有文件 31861847f8eSopenharmony_ci * @param {string} dir 文件目录 31961847f8eSopenharmony_ci * @param {Array} utFiles 所有文件 32061847f8eSopenharmony_ci */ 32161847f8eSopenharmony_cifunction readFile(dir, utFiles) { 32261847f8eSopenharmony_ci try { 32361847f8eSopenharmony_ci const files = fs.readdirSync(dir); 32461847f8eSopenharmony_ci files.forEach((element) => { 32561847f8eSopenharmony_ci const filePath = path.join(dir, element); 32661847f8eSopenharmony_ci const status = fs.statSync(filePath); 32761847f8eSopenharmony_ci if (status.isDirectory()) { 32861847f8eSopenharmony_ci readFile(filePath, utFiles); 32961847f8eSopenharmony_ci } else { 33061847f8eSopenharmony_ci utFiles.push(filePath); 33161847f8eSopenharmony_ci } 33261847f8eSopenharmony_ci }); 33361847f8eSopenharmony_ci } catch (e) { 33461847f8eSopenharmony_ci console.log('ETS ERROR: ' + e); 33561847f8eSopenharmony_ci } 33661847f8eSopenharmony_ci} 33761847f8eSopenharmony_ci 33861847f8eSopenharmony_cifunction writeFile(url, data, option) { 33961847f8eSopenharmony_ci if (fs.existsSync(outputPath)) { 34061847f8eSopenharmony_ci fs.rmdirSync(outputPath, { recursive: true }); 34161847f8eSopenharmony_ci } 34261847f8eSopenharmony_ci const newFilePath = path.resolve(outputPath, path.relative(__dirname, url)); 34361847f8eSopenharmony_ci fs.mkdir(path.dirname(newFilePath), { recursive: true }, (err) => { 34461847f8eSopenharmony_ci if (err) { 34561847f8eSopenharmony_ci console.log(`ERROR FOR CREATE PATH ${err}`); 34661847f8eSopenharmony_ci } else { 34761847f8eSopenharmony_ci if (data === '') { 34861847f8eSopenharmony_ci fs.rmSync(newFilePath); 34961847f8eSopenharmony_ci return; 35061847f8eSopenharmony_ci } 35161847f8eSopenharmony_ci fs.writeFileSync(newFilePath, data, option, (err) => { 35261847f8eSopenharmony_ci if (err) { 35361847f8eSopenharmony_ci console.log(`ERROR FOR CREATE FILE ${err}`); 35461847f8eSopenharmony_ci } 35561847f8eSopenharmony_ci }); 35661847f8eSopenharmony_ci } 35761847f8eSopenharmony_ci }); 35861847f8eSopenharmony_ci} 35961847f8eSopenharmony_ci 36061847f8eSopenharmony_ciconst globalModules = new Map(); 36161847f8eSopenharmony_ci 36261847f8eSopenharmony_ci/** 36361847f8eSopenharmony_ci * 每个文件处理前回调函数第二个 36461847f8eSopenharmony_ci * @param {string} url 文件路径 36561847f8eSopenharmony_ci * @returns {Function} 36661847f8eSopenharmony_ci */ 36761847f8eSopenharmony_cifunction formatImportDeclaration(url, copyrightMessage = '', isCopyrightDeleted = false) { 36861847f8eSopenharmony_ci return (context) => { 36961847f8eSopenharmony_ci const allIdentifierSet = new Set([]); 37061847f8eSopenharmony_ci return (node) => { 37161847f8eSopenharmony_ci sourceFile = node; 37261847f8eSopenharmony_ci collectAllIdentifier(node); // 获取所有标识符 37361847f8eSopenharmony_ci formatValue = formatAllNodes(url, node, allIdentifierSet); // 获取所有节点 37461847f8eSopenharmony_ci node = formatValue.node; 37561847f8eSopenharmony_ci const referencesMessage = formatValue.referencesMessage; 37661847f8eSopenharmony_ci if (formatValue.isCopyrightDeleted) { 37761847f8eSopenharmony_ci copyrightMessage = formatValue.copyrightMessage; 37861847f8eSopenharmony_ci isCopyrightDeleted = formatValue.isCopyrightDeleted; 37961847f8eSopenharmony_ci } 38061847f8eSopenharmony_ci if (!isEmptyFile(node)) { 38161847f8eSopenharmony_ci const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); 38261847f8eSopenharmony_ci let result = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile); 38361847f8eSopenharmony_ci if (isCopyrightDeleted) { 38461847f8eSopenharmony_ci // 当第一个节点被删除时会同步删除整个文件jsdoc 38561847f8eSopenharmony_ci result = copyrightMessage + '\n' + result; 38661847f8eSopenharmony_ci } 38761847f8eSopenharmony_ci copyrightMessage = node.getFullText().replace(node.getText(), ''); 38861847f8eSopenharmony_ci if (referencesMessage) { 38961847f8eSopenharmony_ci // 将references写入文件 39061847f8eSopenharmony_ci result = 39161847f8eSopenharmony_ci result.substring(0, copyrightMessage.length) + 39261847f8eSopenharmony_ci '\n' + 39361847f8eSopenharmony_ci referencesMessage + 39461847f8eSopenharmony_ci result.substring(copyrightMessage.length); 39561847f8eSopenharmony_ci } 39661847f8eSopenharmony_ci writeFile(url, result); 39761847f8eSopenharmony_ci } 39861847f8eSopenharmony_ci return node; 39961847f8eSopenharmony_ci }; 40061847f8eSopenharmony_ci function collectAllIdentifier(node) { 40161847f8eSopenharmony_ci if (ts.isSourceFile(node) && node.statements) { 40261847f8eSopenharmony_ci node.statements.forEach((stat) => { 40361847f8eSopenharmony_ci if (!ts.isImportDeclaration(stat)) { 40461847f8eSopenharmony_ci ts.visitEachChild(stat, collectAllNodes, context); 40561847f8eSopenharmony_ci } 40661847f8eSopenharmony_ci }); 40761847f8eSopenharmony_ci } 40861847f8eSopenharmony_ci } 40961847f8eSopenharmony_ci function collectAllNodes(node) { 41061847f8eSopenharmony_ci if (ts.isIdentifier(node)) { 41161847f8eSopenharmony_ci allIdentifierSet.add(node.escapedText.toString()); 41261847f8eSopenharmony_ci } 41361847f8eSopenharmony_ci return ts.visitEachChild(node, collectAllNodes, context); 41461847f8eSopenharmony_ci } 41561847f8eSopenharmony_ci }; 41661847f8eSopenharmony_ci} 41761847f8eSopenharmony_ci 41861847f8eSopenharmony_cifunction formatAllNodes(url, node, allIdentifierSet, copyrightMessage = '', isCopyrightDeleted = false) { 41961847f8eSopenharmony_ci let referencesMessage = ''; 42061847f8eSopenharmony_ci let currReferencesModule = formatAllNodesReferences(url); 42161847f8eSopenharmony_ci if (ts.isSourceFile(node) && node.statements) { 42261847f8eSopenharmony_ci const newStatements = []; 42361847f8eSopenharmony_ci node.statements.forEach((statement) => { 42461847f8eSopenharmony_ci if (ts.isImportDeclaration(statement)) { 42561847f8eSopenharmony_ci const importInfo = formatAllNodesImportDeclaration( 42661847f8eSopenharmony_ci node, 42761847f8eSopenharmony_ci statement, 42861847f8eSopenharmony_ci url, 42961847f8eSopenharmony_ci currReferencesModule, 43061847f8eSopenharmony_ci allIdentifierSet 43161847f8eSopenharmony_ci ); 43261847f8eSopenharmony_ci if (importInfo.statement) { 43361847f8eSopenharmony_ci newStatements.push(statement); 43461847f8eSopenharmony_ci } else if (importInfo.isCopyrightDeleted) { 43561847f8eSopenharmony_ci copyrightMessage = importInfo.copyrightMessage; 43661847f8eSopenharmony_ci isCopyrightDeleted = importInfo.isCopyrightDeleted; 43761847f8eSopenharmony_ci } 43861847f8eSopenharmony_ci } else if (ts.isStructDeclaration(statement)) { 43961847f8eSopenharmony_ci statement = ts.factory.updateStructDeclaration( 44061847f8eSopenharmony_ci statement, 44161847f8eSopenharmony_ci statement.decorators, 44261847f8eSopenharmony_ci statement.modifiers, 44361847f8eSopenharmony_ci statement.name, 44461847f8eSopenharmony_ci statement.typeParameters, 44561847f8eSopenharmony_ci statement.heritageClauses, 44661847f8eSopenharmony_ci statement.members.slice(1) 44761847f8eSopenharmony_ci ); 44861847f8eSopenharmony_ci newStatements.push(statement); 44961847f8eSopenharmony_ci } else { 45061847f8eSopenharmony_ci newStatements.push(statement); 45161847f8eSopenharmony_ci } 45261847f8eSopenharmony_ci }); 45361847f8eSopenharmony_ci currReferencesModule.forEach((item) => { 45461847f8eSopenharmony_ci if (item.isUsed) { 45561847f8eSopenharmony_ci referencesMessage += item.reference + '\n'; 45661847f8eSopenharmony_ci } 45761847f8eSopenharmony_ci }); 45861847f8eSopenharmony_ci node = ts.factory.updateSourceFile(node, newStatements); 45961847f8eSopenharmony_ci } 46061847f8eSopenharmony_ci return { node, referencesMessage, copyrightMessage, isCopyrightDeleted }; 46161847f8eSopenharmony_ci} 46261847f8eSopenharmony_ci 46361847f8eSopenharmony_cifunction hasCopyright(node) { 46461847f8eSopenharmony_ci return /http\:\/\/www\.apache\.org\/licenses\/LICENSE\-2\.0/g.test(node.getFullText().replace(node.getText(), '')); 46561847f8eSopenharmony_ci} 46661847f8eSopenharmony_ci 46761847f8eSopenharmony_ci/** 46861847f8eSopenharmony_ci * 处理References节点 46961847f8eSopenharmony_ci * @param {ts.node} node 当前节点 47061847f8eSopenharmony_ci * @param {string} url 文件路径 47161847f8eSopenharmony_ci * @returns {Array} currReferencesModule 返回该文件的references数据 47261847f8eSopenharmony_ci */ 47361847f8eSopenharmony_cifunction formatAllNodesReferences(url) { 47461847f8eSopenharmony_ci globalModules.clear(); 47561847f8eSopenharmony_ci let currReferences = []; 47661847f8eSopenharmony_ci let currReferencesModule = []; 47761847f8eSopenharmony_ci if (referencesMap.has(url)) { 47861847f8eSopenharmony_ci currReferences = referencesMap.get(url); 47961847f8eSopenharmony_ci currReferencesModule = currReferences.references.map((element, index) => { 48061847f8eSopenharmony_ci element.match(PATT.GET_REFERENCEURL); 48161847f8eSopenharmony_ci let referencePath = RegExp.$2; 48261847f8eSopenharmony_ci referencePath = referencesToOthers(referencePath, REFERENCE_TYPE.TOLOCAL); 48361847f8eSopenharmony_ci let fullReferencePath = path.resolve(path.dirname(url), referencePath); 48461847f8eSopenharmony_ci let module = referencesModuleMap.get(fullReferencePath); 48561847f8eSopenharmony_ci for (const key in module) { 48661847f8eSopenharmony_ci if (Object.hasOwnProperty.call(module, key)) { 48761847f8eSopenharmony_ci globalModules.set(key, index); 48861847f8eSopenharmony_ci } 48961847f8eSopenharmony_ci } 49061847f8eSopenharmony_ci return { modules: module, fullReferencePath: fullReferencePath, reference: element, isUsed: false }; 49161847f8eSopenharmony_ci }); 49261847f8eSopenharmony_ci } 49361847f8eSopenharmony_ci return currReferencesModule; 49461847f8eSopenharmony_ci} 49561847f8eSopenharmony_ci 49661847f8eSopenharmony_ci/** 49761847f8eSopenharmony_ci * 处理Import节点 去除未使用、不存在、References中没有对应模块的导入 49861847f8eSopenharmony_ci * @param {ts.node} node 当前节点 49961847f8eSopenharmony_ci * @param {ts.ImportDeclaration} statement 导入节点 50061847f8eSopenharmony_ci * @param {string} url 文件路径 50161847f8eSopenharmony_ci * @param {string} url 文件路径 50261847f8eSopenharmony_ci * @param {Set} allIdentifierSet 该文件的所有Identifier关键字 50361847f8eSopenharmony_ci * @returns {{statement:ts.ImportDeclaration,copyrightMessage:string,isCopyrightDeleted:boolean}} statement 处理完成的导入节点、copyrightMessage 50461847f8eSopenharmony_ci */ 50561847f8eSopenharmony_cifunction formatAllNodesImportDeclaration(node, statement, url, currReferencesModule, allIdentifierSet) { 50661847f8eSopenharmony_ci // 是import节点 import { AsyncCallback } from './@ohos.base'; 50761847f8eSopenharmony_ci const clauseSet = new Set([]); 50861847f8eSopenharmony_ci if (statement.importClause && ts.isImportClause(statement.importClause)) { 50961847f8eSopenharmony_ci // 标识符 51061847f8eSopenharmony_ci const clauseNode = statement.importClause; 51161847f8eSopenharmony_ci if (!clauseNode.namedBindings && clauseNode.name && ts.isIdentifier(clauseNode.name)) { 51261847f8eSopenharmony_ci // 没有大括号的标识符 51361847f8eSopenharmony_ci clauseSet.add(clauseNode.name.escapedText.toString()); 51461847f8eSopenharmony_ci } else if ( 51561847f8eSopenharmony_ci clauseNode.namedBindings && 51661847f8eSopenharmony_ci clauseNode.namedBindings.name && 51761847f8eSopenharmony_ci ts.isIdentifier(clauseNode.namedBindings.name) 51861847f8eSopenharmony_ci ) { 51961847f8eSopenharmony_ci // 没有标识符 *号 52061847f8eSopenharmony_ci clauseSet.add(clauseNode.namedBindings.name.escapedText.toString()); 52161847f8eSopenharmony_ci } else if (clauseNode.namedBindings && clauseNode.namedBindings.elements) { 52261847f8eSopenharmony_ci // 有花括号的标识符 52361847f8eSopenharmony_ci clauseNode.namedBindings.elements.forEach((ele) => { 52461847f8eSopenharmony_ci if (ele.name && ts.isIdentifier(ele.name)) { 52561847f8eSopenharmony_ci clauseSet.add(ele.name.escapedText.toString()); 52661847f8eSopenharmony_ci } 52761847f8eSopenharmony_ci }); 52861847f8eSopenharmony_ci } 52961847f8eSopenharmony_ci } 53061847f8eSopenharmony_ci const importSpecifier = statement.moduleSpecifier.getText().replace(/[\'\"]/g, ''); 53161847f8eSopenharmony_ci const dtsImportSpecifierPath = path.resolve(url, `../${importSpecifier}.d.ts`); // import 文件路径判断 53261847f8eSopenharmony_ci const detsImportSpecifierPath = path.resolve(url, `../${importSpecifier}.d.ets`); // import 文件路径判断 53361847f8eSopenharmony_ci let hasImportSpecifierFile = fs.existsSync(dtsImportSpecifierPath) || fs.existsSync(detsImportSpecifierPath); 53461847f8eSopenharmony_ci let hasImportSpecifierInModules = globalModules.has(importSpecifier); 53561847f8eSopenharmony_ci if ((hasImportSpecifierFile || hasImportSpecifierInModules) && clauseSet.size > 0) { 53661847f8eSopenharmony_ci let currModule = []; 53761847f8eSopenharmony_ci if (hasImportSpecifierInModules) { 53861847f8eSopenharmony_ci let index = globalModules.get(importSpecifier); 53961847f8eSopenharmony_ci currModule = currReferencesModule[index].modules[importSpecifier]; 54061847f8eSopenharmony_ci } 54161847f8eSopenharmony_ci const clasueCheckList = []; 54261847f8eSopenharmony_ci let exsitClauseSet = new Set([]); 54361847f8eSopenharmony_ci for (const clause of clauseSet) { 54461847f8eSopenharmony_ci let flag = allIdentifierSet.has(clause); 54561847f8eSopenharmony_ci if (hasImportSpecifierInModules) { 54661847f8eSopenharmony_ci flag = allIdentifierSet.has(clause) && currModule.includes(clause); 54761847f8eSopenharmony_ci } 54861847f8eSopenharmony_ci if (flag) { 54961847f8eSopenharmony_ci // 标识符使用到了当前import中的引用 55061847f8eSopenharmony_ci exsitClauseSet.add(clause); 55161847f8eSopenharmony_ci clasueCheckList.push('exist'); 55261847f8eSopenharmony_ci } else { 55361847f8eSopenharmony_ci clasueCheckList.push('non-exist'); 55461847f8eSopenharmony_ci } 55561847f8eSopenharmony_ci } 55661847f8eSopenharmony_ci let hasExsitStatus = false; 55761847f8eSopenharmony_ci let hasNonExsitStatus = false; 55861847f8eSopenharmony_ci clasueCheckList.forEach((ele) => { 55961847f8eSopenharmony_ci if (ele === 'exist') { 56061847f8eSopenharmony_ci hasExsitStatus = true; 56161847f8eSopenharmony_ci } else { 56261847f8eSopenharmony_ci hasNonExsitStatus = true; 56361847f8eSopenharmony_ci } 56461847f8eSopenharmony_ci }); 56561847f8eSopenharmony_ci if (hasExsitStatus) { 56661847f8eSopenharmony_ci // 有使用到的标识符 56761847f8eSopenharmony_ci if (hasNonExsitStatus) { 56861847f8eSopenharmony_ci // 有没有使用到的标识符 56961847f8eSopenharmony_ci const newSpecifiers = []; 57061847f8eSopenharmony_ci statement.importClause.namedBindings.elements.forEach((element) => { 57161847f8eSopenharmony_ci if (exsitClauseSet.has(element.name.escapedText.toString())) { 57261847f8eSopenharmony_ci newSpecifiers.push(element); 57361847f8eSopenharmony_ci } 57461847f8eSopenharmony_ci }); 57561847f8eSopenharmony_ci statement.importClause.namedBindings = ts.factory.updateNamedImports( 57661847f8eSopenharmony_ci statement.importClause.namedBindings, 57761847f8eSopenharmony_ci newSpecifiers 57861847f8eSopenharmony_ci ); 57961847f8eSopenharmony_ci } 58061847f8eSopenharmony_ci if (hasImportSpecifierInModules) { 58161847f8eSopenharmony_ci let index = globalModules.get(importSpecifier); 58261847f8eSopenharmony_ci currReferencesModule[index].isUsed = true; 58361847f8eSopenharmony_ci } 58461847f8eSopenharmony_ci return { statement }; 58561847f8eSopenharmony_ci } else if (hasCopyright(statement)) { 58661847f8eSopenharmony_ci return { copyrightMessage: node.getFullText().replace(node.getText(), ''), isCopyrightDeleted: true }; 58761847f8eSopenharmony_ci } 58861847f8eSopenharmony_ci } else if (hasCopyright(statement)) { 58961847f8eSopenharmony_ci return { copyrightMessage: node.getFullText().replace(node.getText(), ''), isCopyrightDeleted: true }; 59061847f8eSopenharmony_ci } 59161847f8eSopenharmony_ci return { statement: undefined, copyrightMessage: '', isCopyrightDeleted: false }; 59261847f8eSopenharmony_ci} 59361847f8eSopenharmony_ci 59461847f8eSopenharmony_ci/** 59561847f8eSopenharmony_ci * 59661847f8eSopenharmony_ci * 防止@file和@kit段注释丢失 59761847f8eSopenharmony_ci * @param {string} fileFullText 59861847f8eSopenharmony_ci * @returns {string} 59961847f8eSopenharmony_ci * 60061847f8eSopenharmony_ci */ 60161847f8eSopenharmony_cifunction getFileAndKitComment(fileFullText) { 60261847f8eSopenharmony_ci let fileAndKitComment = ''; 60361847f8eSopenharmony_ci let pattern = /\/\*\*\s*\*\s*@file[\s\S]*?@kit[\s\S]*?\*\//; 60461847f8eSopenharmony_ci let comment = fileFullText.match(pattern); 60561847f8eSopenharmony_ci if (comment) { 60661847f8eSopenharmony_ci fileAndKitComment = comment[0]; 60761847f8eSopenharmony_ci } 60861847f8eSopenharmony_ci return fileAndKitComment; 60961847f8eSopenharmony_ci} 61061847f8eSopenharmony_ci 61161847f8eSopenharmony_ci 61261847f8eSopenharmony_ci/** 61361847f8eSopenharmony_ci * 每个文件处理前回调函数第一个 61461847f8eSopenharmony_ci * @callback deleteSystemApi 61561847f8eSopenharmony_ci * @param {string} url 文件路径 61661847f8eSopenharmony_ci * @returns {Function} 61761847f8eSopenharmony_ci */ 61861847f8eSopenharmony_cifunction deleteSystemApi(url) { 61961847f8eSopenharmony_ci return (context) => { 62061847f8eSopenharmony_ci return (node) => { 62161847f8eSopenharmony_ci const fullText = String(node.getFullText()); 62261847f8eSopenharmony_ci //获取文件头部的注释信息--这里可能会涉及到@file和@kit段注释丢失 62361847f8eSopenharmony_ci let fileAndKitComment = getFileAndKitComment(fullText); 62461847f8eSopenharmony_ci const copyrightMessage = fullText.replace(node.getText(), '').split(/\/\*\*/)[0] + fileAndKitComment + '\n'; 62561847f8eSopenharmony_ci let kitName = ''; 62661847f8eSopenharmony_ci if (fullText.match(/\@kit (.*)\r?\n/g)) { 62761847f8eSopenharmony_ci kitName = RegExp.$1.replace(/\s/g, ''); 62861847f8eSopenharmony_ci } 62961847f8eSopenharmony_ci sourceFile = node; 63061847f8eSopenharmony_ci const deleteNode = processSourceFile(node, kitName); // 处理最外层节点 63161847f8eSopenharmony_ci node = processVisitEachChild(context, deleteNode.node); 63261847f8eSopenharmony_ci if (!isEmptyFile(node)) { 63361847f8eSopenharmony_ci const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); 63461847f8eSopenharmony_ci const result = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile); 63561847f8eSopenharmony_ci if (referencesMap.has(url)) { 63661847f8eSopenharmony_ci resolveReferences(url); 63761847f8eSopenharmony_ci } 63861847f8eSopenharmony_ci const fileName = processFileName(url); 63961847f8eSopenharmony_ci ts.transpileModule(result, { 64061847f8eSopenharmony_ci compilerOptions: { 64161847f8eSopenharmony_ci target: ts.ScriptTarget.ES2017, 64261847f8eSopenharmony_ci }, 64361847f8eSopenharmony_ci fileName: fileName, 64461847f8eSopenharmony_ci transformers: { before: [formatImportDeclaration(url, copyrightMessage, deleteNode.isCopyrightDeleted)] }, 64561847f8eSopenharmony_ci }); 64661847f8eSopenharmony_ci } 64761847f8eSopenharmony_ci return node; 64861847f8eSopenharmony_ci }; 64961847f8eSopenharmony_ci }; 65061847f8eSopenharmony_ci} 65161847f8eSopenharmony_ci 65261847f8eSopenharmony_ciexports.deleteSystemApi = deleteSystemApi; 65361847f8eSopenharmony_ci 65461847f8eSopenharmony_ci/** 65561847f8eSopenharmony_ci * 遍历每个文件下的所有节点,然后删除节点 65661847f8eSopenharmony_ci * @param node 65761847f8eSopenharmony_ci * @returns 65861847f8eSopenharmony_ci */ 65961847f8eSopenharmony_ci 66061847f8eSopenharmony_ci/** 66161847f8eSopenharmony_ci * 处理最外层的节点看是否删除 66261847f8eSopenharmony_ci * @param node 解析过后的节点 66361847f8eSopenharmony_ci * @param kitName 当前文件kitName 66461847f8eSopenharmony_ci * @returns 66561847f8eSopenharmony_ci */ 66661847f8eSopenharmony_cifunction processSourceFile(node, kitName) { 66761847f8eSopenharmony_ci let isCopyrightDeleted = false; 66861847f8eSopenharmony_ci const newStatements = []; 66961847f8eSopenharmony_ci const newStatementsWithoutExport = []; 67061847f8eSopenharmony_ci const deleteSystemApiSet = new Set(); 67161847f8eSopenharmony_ci let needDeleteExport = { 67261847f8eSopenharmony_ci fileName: '', 67361847f8eSopenharmony_ci default: '', 67461847f8eSopenharmony_ci exportName: new Set(), 67561847f8eSopenharmony_ci }; 67661847f8eSopenharmony_ci isCopyrightDeleted = addNewStatements(node, newStatements, deleteSystemApiSet, needDeleteExport); 67761847f8eSopenharmony_ci newStatements.forEach((statement) => { 67861847f8eSopenharmony_ci const names = getExportIdentifierName(statement); 67961847f8eSopenharmony_ci if (names.length === 0) { 68061847f8eSopenharmony_ci newStatementsWithoutExport.push(statement); 68161847f8eSopenharmony_ci return; 68261847f8eSopenharmony_ci } 68361847f8eSopenharmony_ci if (names.length === 1 && !deleteSystemApiSet.has(names[0])) { 68461847f8eSopenharmony_ci //exports.name = test; 68561847f8eSopenharmony_ci //export default test1 68661847f8eSopenharmony_ci //export {test1} 68761847f8eSopenharmony_ci newStatementsWithoutExport.push(statement); 68861847f8eSopenharmony_ci return; 68961847f8eSopenharmony_ci } 69061847f8eSopenharmony_ci processExportNode(statement, node, needDeleteExport, names, deleteSystemApiSet, newStatementsWithoutExport); 69161847f8eSopenharmony_ci }); 69261847f8eSopenharmony_ci if (needDeleteExport.fileName !== '') { 69361847f8eSopenharmony_ci let kitMap = kitFileNeedDeleteMap.get(kitName); 69461847f8eSopenharmony_ci if (kitMap === undefined) { 69561847f8eSopenharmony_ci kitMap = new Map([[needDeleteExport.fileName, needDeleteExport]]); 69661847f8eSopenharmony_ci } else { 69761847f8eSopenharmony_ci kitMap.set(needDeleteExport.fileName, needDeleteExport); 69861847f8eSopenharmony_ci } 69961847f8eSopenharmony_ci kitFileNeedDeleteMap.set(kitName, kitMap); 70061847f8eSopenharmony_ci } 70161847f8eSopenharmony_ci return { 70261847f8eSopenharmony_ci node: ts.factory.updateSourceFile(node, newStatementsWithoutExport, node.isDeclarationFile, node.referencedFiles), 70361847f8eSopenharmony_ci isCopyrightDeleted, 70461847f8eSopenharmony_ci }; 70561847f8eSopenharmony_ci} 70661847f8eSopenharmony_ci 70761847f8eSopenharmony_cifunction processExportNode(statement, node, needDeleteExport, names, deleteSystemApiSet, newStatementsWithoutExport) { 70861847f8eSopenharmony_ci //删除export节点信息 70961847f8eSopenharmony_ci if (ts.isExportAssignment(statement)) { 71061847f8eSopenharmony_ci //export default abilityAccessCtrl; 71161847f8eSopenharmony_ci needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); 71261847f8eSopenharmony_ci needDeleteExport.default = statement.expression.escapedText.toString(); 71361847f8eSopenharmony_ci } else if (ts.isExportDeclaration(statement)) { 71461847f8eSopenharmony_ci //export {test1 as test,testa as test2} 71561847f8eSopenharmony_ci let needExport = false; 71661847f8eSopenharmony_ci const newSpecifiers = []; 71761847f8eSopenharmony_ci names.forEach((name, index) => { 71861847f8eSopenharmony_ci if (!deleteSystemApiSet.has(name)) { 71961847f8eSopenharmony_ci //未被删除的节点 72061847f8eSopenharmony_ci newSpecifiers.push(statement.exportClause.elements[index]); 72161847f8eSopenharmony_ci needExport = true; 72261847f8eSopenharmony_ci } else { 72361847f8eSopenharmony_ci //被删除的节点 72461847f8eSopenharmony_ci needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); 72561847f8eSopenharmony_ci needDeleteExport.exportName.add(statement.name.escapedText.toString()); 72661847f8eSopenharmony_ci } 72761847f8eSopenharmony_ci }); 72861847f8eSopenharmony_ci if (needExport) { 72961847f8eSopenharmony_ci statement.exportClause = ts.factory.updateNamedExports(statement.exportClause, newSpecifiers); 73061847f8eSopenharmony_ci newStatementsWithoutExport.push(statement); 73161847f8eSopenharmony_ci } 73261847f8eSopenharmony_ci } 73361847f8eSopenharmony_ci} 73461847f8eSopenharmony_ci 73561847f8eSopenharmony_cifunction addNewStatements(node, newStatements, deleteSystemApiSet, needDeleteExport) { 73661847f8eSopenharmony_ci let isCopyrightDeleted = false; 73761847f8eSopenharmony_ci node.statements.forEach((statement, index) => { 73861847f8eSopenharmony_ci if (!isSystemapi(statement)) { 73961847f8eSopenharmony_ci newStatements.push(statement); 74061847f8eSopenharmony_ci return; 74161847f8eSopenharmony_ci } 74261847f8eSopenharmony_ci if (index === 0) { 74361847f8eSopenharmony_ci isCopyrightDeleted = true; 74461847f8eSopenharmony_ci } 74561847f8eSopenharmony_ci if (ts.isVariableStatement(statement)) { 74661847f8eSopenharmony_ci deleteSystemApiSet.add(variableStatementGetEscapedText(statement)); 74761847f8eSopenharmony_ci } else if ( 74861847f8eSopenharmony_ci ts.isModuleDeclaration(statement) || 74961847f8eSopenharmony_ci ts.isInterfaceDeclaration(statement) || 75061847f8eSopenharmony_ci ts.isClassDeclaration(statement) || 75161847f8eSopenharmony_ci ts.isEnumDeclaration(statement) || 75261847f8eSopenharmony_ci ts.isStructDeclaration(statement) || 75361847f8eSopenharmony_ci ts.isTypeAliasDeclaration(statement) 75461847f8eSopenharmony_ci ) { 75561847f8eSopenharmony_ci if (statement && statement.name && statement.name.escapedText) { 75661847f8eSopenharmony_ci deleteSystemApiSet.add(statement.name.escapedText.toString()); 75761847f8eSopenharmony_ci } 75861847f8eSopenharmony_ci setDeleteExport(statement, node, needDeleteExport, deleteSystemApiSet); 75961847f8eSopenharmony_ci } else if (ts.isExportAssignment(statement) || ts.isExportDeclaration(statement)) { 76061847f8eSopenharmony_ci setDeleteExport(statement, node, needDeleteExport, deleteSystemApiSet); 76161847f8eSopenharmony_ci } 76261847f8eSopenharmony_ci }); 76361847f8eSopenharmony_ci 76461847f8eSopenharmony_ci return isCopyrightDeleted; 76561847f8eSopenharmony_ci} 76661847f8eSopenharmony_ci 76761847f8eSopenharmony_cifunction setDeleteExport(statement, node, needDeleteExport, deleteSystemApiSet) { 76861847f8eSopenharmony_ci if (ts.isExportAssignment(statement) && deleteSystemApiSet.has(statement.expression.escapedText.toString())) { 76961847f8eSopenharmony_ci needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); 77061847f8eSopenharmony_ci needDeleteExport.default = statement.expression.escapedText.toString(); 77161847f8eSopenharmony_ci } else if (ts.isExportDeclaration(statement)) { 77261847f8eSopenharmony_ci needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); 77361847f8eSopenharmony_ci statement.exportClause.elements.forEach((element) => { 77461847f8eSopenharmony_ci const exportName = element.propertyName ? 77561847f8eSopenharmony_ci element.propertyName.escapedText.toString() : 77661847f8eSopenharmony_ci element.name.escapedText.toString(); 77761847f8eSopenharmony_ci if (deleteSystemApiSet.has(exportName)) { 77861847f8eSopenharmony_ci needDeleteExport.exportName.add(element.name.escapedText.toString()); 77961847f8eSopenharmony_ci } 78061847f8eSopenharmony_ci }); 78161847f8eSopenharmony_ci } 78261847f8eSopenharmony_ci //export namespace test {} 78361847f8eSopenharmony_ci const modifiers = statement.modifiers; 78461847f8eSopenharmony_ci if (modifiers === undefined) { 78561847f8eSopenharmony_ci return; 78661847f8eSopenharmony_ci } 78761847f8eSopenharmony_ci const exportFlag = modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword); 78861847f8eSopenharmony_ci const defaultFlag = modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword); 78961847f8eSopenharmony_ci if (exportFlag && defaultFlag) { 79061847f8eSopenharmony_ci needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); 79161847f8eSopenharmony_ci needDeleteExport.default = statement.name.escapedText.toString(); 79261847f8eSopenharmony_ci } else if (exportFlag) { 79361847f8eSopenharmony_ci needDeleteExport.fileName = processFileNameWithoutExt(node.fileName); 79461847f8eSopenharmony_ci needDeleteExport.exportName.add(statement.name.escapedText.toString()); 79561847f8eSopenharmony_ci } 79661847f8eSopenharmony_ci} 79761847f8eSopenharmony_ci 79861847f8eSopenharmony_ci/** 79961847f8eSopenharmony_ci * 获取export节点的名字,只获取第一个关键词 80061847f8eSopenharmony_ci * @param {ts.node} statement 80161847f8eSopenharmony_ci * @returns {Array<string>} 80261847f8eSopenharmony_ci */ 80361847f8eSopenharmony_cifunction getExportIdentifierName(statement) { 80461847f8eSopenharmony_ci const names = []; 80561847f8eSopenharmony_ci if (ts.isExpressionStatement(statement)) { 80661847f8eSopenharmony_ci //exports.name = test; 80761847f8eSopenharmony_ci if (ts.isBinaryExpression(statement.expression)) { 80861847f8eSopenharmony_ci names.push(statement.expression.right.escapedText.toString()); 80961847f8eSopenharmony_ci } 81061847f8eSopenharmony_ci } else if (ts.isExportAssignment(statement)) { 81161847f8eSopenharmony_ci //export default test1 81261847f8eSopenharmony_ci names.push(statement.expression.escapedText.toString()); 81361847f8eSopenharmony_ci } else if (ts.isExportDeclaration(statement)) { 81461847f8eSopenharmony_ci //export {test1} 、export {test1 as test} 、export * from './featureability' 81561847f8eSopenharmony_ci const exportClause = statement.exportClause; 81661847f8eSopenharmony_ci if (exportClause) { 81761847f8eSopenharmony_ci const specifiers = exportClause.elements; 81861847f8eSopenharmony_ci specifiers.forEach((specifier) => { 81961847f8eSopenharmony_ci if (ts.isExportSpecifier(specifier)) { 82061847f8eSopenharmony_ci const name = specifier.propertyName ? specifier.propertyName : specifier.name; 82161847f8eSopenharmony_ci names.push(name.escapedText.toString()); 82261847f8eSopenharmony_ci } 82361847f8eSopenharmony_ci }); 82461847f8eSopenharmony_ci } 82561847f8eSopenharmony_ci } 82661847f8eSopenharmony_ci return names; 82761847f8eSopenharmony_ci} 82861847f8eSopenharmony_ci 82961847f8eSopenharmony_ci/** 83061847f8eSopenharmony_ci * 遍历处理tsnode节点 83161847f8eSopenharmony_ci * @param context 解析过后的内容 83261847f8eSopenharmony_ci * @param node 解析过后的节点 83361847f8eSopenharmony_ci * @returns ts.node 83461847f8eSopenharmony_ci */ 83561847f8eSopenharmony_cifunction processVisitEachChild(context, node) { 83661847f8eSopenharmony_ci return ts.visitEachChild(node, processAllNodes, context); // 遍历所有子节点 83761847f8eSopenharmony_ci function processAllNodes(node) { 83861847f8eSopenharmony_ci if (ts.isInterfaceDeclaration(node)) { 83961847f8eSopenharmony_ci const newMembers = []; 84061847f8eSopenharmony_ci node.members.forEach((member) => { 84161847f8eSopenharmony_ci if (!isSystemapi(member)) { 84261847f8eSopenharmony_ci newMembers.push(member); 84361847f8eSopenharmony_ci } 84461847f8eSopenharmony_ci }); 84561847f8eSopenharmony_ci node = ts.factory.updateInterfaceDeclaration( 84661847f8eSopenharmony_ci node, 84761847f8eSopenharmony_ci node.decorators, 84861847f8eSopenharmony_ci node.modifiers, 84961847f8eSopenharmony_ci node.name, 85061847f8eSopenharmony_ci node.typeParameters, 85161847f8eSopenharmony_ci node.heritageClauses, 85261847f8eSopenharmony_ci newMembers 85361847f8eSopenharmony_ci ); 85461847f8eSopenharmony_ci } else if (ts.isClassDeclaration(node)) { 85561847f8eSopenharmony_ci const newMembers = []; 85661847f8eSopenharmony_ci node.members.forEach((member) => { 85761847f8eSopenharmony_ci if (!isSystemapi(member)) { 85861847f8eSopenharmony_ci newMembers.push(member); 85961847f8eSopenharmony_ci } 86061847f8eSopenharmony_ci }); 86161847f8eSopenharmony_ci node = ts.factory.updateClassDeclaration( 86261847f8eSopenharmony_ci node, 86361847f8eSopenharmony_ci node.decorators, 86461847f8eSopenharmony_ci node.modifiers, 86561847f8eSopenharmony_ci node.name, 86661847f8eSopenharmony_ci node.typeParameters, 86761847f8eSopenharmony_ci node.heritageClauses, 86861847f8eSopenharmony_ci newMembers 86961847f8eSopenharmony_ci ); 87061847f8eSopenharmony_ci } else if (ts.isModuleDeclaration(node) && node.body && ts.isModuleBlock(node.body)) { 87161847f8eSopenharmony_ci const newStatements = []; 87261847f8eSopenharmony_ci node.body.statements.forEach((statement) => { 87361847f8eSopenharmony_ci if (!isSystemapi(statement)) { 87461847f8eSopenharmony_ci newStatements.push(statement); 87561847f8eSopenharmony_ci } 87661847f8eSopenharmony_ci }); 87761847f8eSopenharmony_ci const newModuleBody = ts.factory.updateModuleBlock(node.body, newStatements); 87861847f8eSopenharmony_ci node = ts.factory.updateModuleDeclaration(node, node.decorators, node.modifiers, node.name, newModuleBody); 87961847f8eSopenharmony_ci } else if (ts.isEnumDeclaration(node)) { 88061847f8eSopenharmony_ci const newMembers = []; 88161847f8eSopenharmony_ci node.members.forEach((member) => { 88261847f8eSopenharmony_ci if (!isSystemapi(member)) { 88361847f8eSopenharmony_ci newMembers.push(member); 88461847f8eSopenharmony_ci } 88561847f8eSopenharmony_ci }); 88661847f8eSopenharmony_ci node = ts.factory.updateEnumDeclaration(node, node.decorators, node.modifiers, node.name, newMembers); 88761847f8eSopenharmony_ci } else if (ts.isStructDeclaration(node)) { 88861847f8eSopenharmony_ci const newMembers = []; 88961847f8eSopenharmony_ci node.members.forEach((member, index) => { 89061847f8eSopenharmony_ci if (index >= 1 && !isSystemapi(member)) { 89161847f8eSopenharmony_ci newMembers.push(member); 89261847f8eSopenharmony_ci } 89361847f8eSopenharmony_ci }); 89461847f8eSopenharmony_ci node = ts.factory.updateStructDeclaration( 89561847f8eSopenharmony_ci node, 89661847f8eSopenharmony_ci node.decorators, 89761847f8eSopenharmony_ci node.modifiers, 89861847f8eSopenharmony_ci node.name, 89961847f8eSopenharmony_ci node.typeParameters, 90061847f8eSopenharmony_ci node.heritageClauses, 90161847f8eSopenharmony_ci newMembers 90261847f8eSopenharmony_ci ); 90361847f8eSopenharmony_ci } 90461847f8eSopenharmony_ci return ts.visitEachChild(node, processAllNodes, context); 90561847f8eSopenharmony_ci } 90661847f8eSopenharmony_ci} 90761847f8eSopenharmony_ci 90861847f8eSopenharmony_ci/** 90961847f8eSopenharmony_ci * 解析reference 91061847f8eSopenharmony_ci * @param {string} url reference文件地址 91161847f8eSopenharmony_ci */ 91261847f8eSopenharmony_cifunction resolveReferences(url) { 91361847f8eSopenharmony_ci const obj = referencesMap.get(url); 91461847f8eSopenharmony_ci let references = obj.references; 91561847f8eSopenharmony_ci if (!references || references.length === 0) { 91661847f8eSopenharmony_ci return; 91761847f8eSopenharmony_ci } 91861847f8eSopenharmony_ci for (let index = 0; index < references.length; index++) { 91961847f8eSopenharmony_ci const element = references[index]; 92061847f8eSopenharmony_ci element.match(PATT.GET_REFERENCEURL); 92161847f8eSopenharmony_ci let referencePath = RegExp.$2; 92261847f8eSopenharmony_ci referencePath = referencesToOthers(referencePath, REFERENCE_TYPE.TOLOCAL); 92361847f8eSopenharmony_ci let fullReferencePath = path.resolve(path.dirname(url), referencePath); 92461847f8eSopenharmony_ci if (fs.existsSync(fullReferencePath) && !referencesModuleMap.has(fullReferencePath)) { 92561847f8eSopenharmony_ci const content = fs.readFileSync(fullReferencePath, 'utf-8'); //文件内容 92661847f8eSopenharmony_ci const fileName = processFileName(fullReferencePath); 92761847f8eSopenharmony_ci ts.transpileModule(content, { 92861847f8eSopenharmony_ci compilerOptions: { 92961847f8eSopenharmony_ci target: ts.ScriptTarget.ES2017, 93061847f8eSopenharmony_ci }, 93161847f8eSopenharmony_ci fileName: fileName, 93261847f8eSopenharmony_ci transformers: { before: [resolveCallback(fullReferencePath)] }, 93361847f8eSopenharmony_ci }); 93461847f8eSopenharmony_ci } 93561847f8eSopenharmony_ci } 93661847f8eSopenharmony_ci} 93761847f8eSopenharmony_cifunction resolveCallback(url) { 93861847f8eSopenharmony_ci return (context) => { 93961847f8eSopenharmony_ci const allReferencesIdentifierSet = new Set([]); 94061847f8eSopenharmony_ci let allModule = {}; 94161847f8eSopenharmony_ci return (node) => { 94261847f8eSopenharmony_ci const referenceSourceFile = node; 94361847f8eSopenharmony_ci node.statements.forEach((statement) => { 94461847f8eSopenharmony_ci if ( 94561847f8eSopenharmony_ci ts.isModuleDeclaration(statement) && 94661847f8eSopenharmony_ci statement.name && 94761847f8eSopenharmony_ci ts.isStringLiteral(statement.name) && 94861847f8eSopenharmony_ci statement.body && 94961847f8eSopenharmony_ci ts.isModuleBlock(statement.body) && 95061847f8eSopenharmony_ci !isSystemapi(statement) 95161847f8eSopenharmony_ci ) { 95261847f8eSopenharmony_ci ts.visitEachChild(statement, collectAllIdentifier, context); 95361847f8eSopenharmony_ci dealExternalStatements(referenceSourceFile); 95461847f8eSopenharmony_ci allModule[statement.name.text.toString()] = [...allReferencesIdentifierSet]; 95561847f8eSopenharmony_ci allReferencesIdentifierSet.clear(); 95661847f8eSopenharmony_ci } 95761847f8eSopenharmony_ci }); 95861847f8eSopenharmony_ci referencesModuleMap.set(url, allModule); 95961847f8eSopenharmony_ci allModule = {}; 96061847f8eSopenharmony_ci return node; 96161847f8eSopenharmony_ci }; 96261847f8eSopenharmony_ci function dealExternalStatements(node) { 96361847f8eSopenharmony_ci node.statements.forEach((statement) => { 96461847f8eSopenharmony_ci let name = ''; 96561847f8eSopenharmony_ci if (isSystemapi(statement)) { 96661847f8eSopenharmony_ci if (ts.isVariableStatement(statement)) { 96761847f8eSopenharmony_ci name = variableStatementGetEscapedText(statement); 96861847f8eSopenharmony_ci } else if ( 96961847f8eSopenharmony_ci ts.isInterfaceDeclaration(statement) || 97061847f8eSopenharmony_ci ts.isClassDeclaration(statement) || 97161847f8eSopenharmony_ci ts.isEnumDeclaration(statement) 97261847f8eSopenharmony_ci ) { 97361847f8eSopenharmony_ci if (statement && statement.name && statement.name.escapedText) { 97461847f8eSopenharmony_ci name = statement.name.escapedText.toString(); 97561847f8eSopenharmony_ci } 97661847f8eSopenharmony_ci } 97761847f8eSopenharmony_ci allReferencesIdentifierSet.delete(name); 97861847f8eSopenharmony_ci } 97961847f8eSopenharmony_ci }); 98061847f8eSopenharmony_ci } 98161847f8eSopenharmony_ci function collectAllIdentifier(node) { 98261847f8eSopenharmony_ci if (isSystemapi(node)) { 98361847f8eSopenharmony_ci return node; 98461847f8eSopenharmony_ci } 98561847f8eSopenharmony_ci if (ts.isIdentifier(node)) { 98661847f8eSopenharmony_ci allReferencesIdentifierSet.add(node.escapedText.toString()); 98761847f8eSopenharmony_ci } 98861847f8eSopenharmony_ci return ts.visitEachChild(node, collectAllIdentifier, context); 98961847f8eSopenharmony_ci } 99061847f8eSopenharmony_ci }; 99161847f8eSopenharmony_ci} 99261847f8eSopenharmony_ci 99361847f8eSopenharmony_cifunction variableStatementGetEscapedText(statement) { 99461847f8eSopenharmony_ci let name = ''; 99561847f8eSopenharmony_ci if ( 99661847f8eSopenharmony_ci statement && 99761847f8eSopenharmony_ci statement.declarationList && 99861847f8eSopenharmony_ci statement.declarationList.declarations && 99961847f8eSopenharmony_ci statement.declarationList.declarations.length > 0 && 100061847f8eSopenharmony_ci statement.declarationList.declarations[0].name && 100161847f8eSopenharmony_ci statement.declarationList.declarations[0].name.escapedText 100261847f8eSopenharmony_ci ) { 100361847f8eSopenharmony_ci name = statement.declarationList.declarations[0].name.escapedText.toString(); 100461847f8eSopenharmony_ci } 100561847f8eSopenharmony_ci return name; 100661847f8eSopenharmony_ci} 100761847f8eSopenharmony_ci 100861847f8eSopenharmony_cifunction isSystemapi(node) { 100961847f8eSopenharmony_ci const notesContent = node.getFullText().replace(node.getText(), '').replace(/[\s]/g, ''); 101061847f8eSopenharmony_ci const notesArr = notesContent.split(/\/\*\*/); 101161847f8eSopenharmony_ci const notesStr = notesArr[notesArr.length - 1]; 101261847f8eSopenharmony_ci if (notesStr.length !== 0) { 101361847f8eSopenharmony_ci return /@systemapi/g.test(notesStr); 101461847f8eSopenharmony_ci } 101561847f8eSopenharmony_ci return false; 101661847f8eSopenharmony_ci} 101761847f8eSopenharmony_ci 101861847f8eSopenharmony_cifunction isEmptyFile(node) { 101961847f8eSopenharmony_ci let isEmpty = true; 102061847f8eSopenharmony_ci if (ts.isSourceFile(node) && node.statements) { 102161847f8eSopenharmony_ci for (let i = 0; i < node.statements.length; i++) { 102261847f8eSopenharmony_ci const statement = node.statements[i]; 102361847f8eSopenharmony_ci if (ts.isImportDeclaration(statement)) { 102461847f8eSopenharmony_ci continue; 102561847f8eSopenharmony_ci } 102661847f8eSopenharmony_ci isEmpty = false; 102761847f8eSopenharmony_ci break; 102861847f8eSopenharmony_ci } 102961847f8eSopenharmony_ci } 103061847f8eSopenharmony_ci return isEmpty; 103161847f8eSopenharmony_ci} 103261847f8eSopenharmony_ci 103361847f8eSopenharmony_ciconst apiSourcePath = '../api'; 103461847f8eSopenharmony_ciconst outputPath = path.resolve(__dirname, 'output'); 103561847f8eSopenharmony_cicollectDeclaration(apiSourcePath); //入口 1036