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