107ac75b1Sopenharmony_ci/*
207ac75b1Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
307ac75b1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
407ac75b1Sopenharmony_ci * you may not use this file except in compliance with the License.
507ac75b1Sopenharmony_ci * You may obtain a copy of the License at
607ac75b1Sopenharmony_ci *
707ac75b1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
807ac75b1Sopenharmony_ci *
907ac75b1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1007ac75b1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1107ac75b1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1207ac75b1Sopenharmony_ci * See the License for the specific language governing permissions and
1307ac75b1Sopenharmony_ci * limitations under the License.
1407ac75b1Sopenharmony_ci */
1507ac75b1Sopenharmony_ci
1607ac75b1Sopenharmony_ciimport * as ts from 'typescript';
1707ac75b1Sopenharmony_ciimport Stats from 'webpack/lib/Stats';
1807ac75b1Sopenharmony_ciimport Compiler from 'webpack/lib/Compiler';
1907ac75b1Sopenharmony_ciimport Compilation from 'webpack/lib/Compilation';
2007ac75b1Sopenharmony_ciimport JavascriptModulesPlugin from 'webpack/lib/javascript/JavascriptModulesPlugin';
2107ac75b1Sopenharmony_ciimport {
2207ac75b1Sopenharmony_ci  configure,
2307ac75b1Sopenharmony_ci  getLogger
2407ac75b1Sopenharmony_ci} from 'log4js';
2507ac75b1Sopenharmony_ciimport path from 'path';
2607ac75b1Sopenharmony_ciimport fs from 'fs';
2707ac75b1Sopenharmony_ciimport CachedSource from 'webpack-sources/lib/CachedSource';
2807ac75b1Sopenharmony_ciimport ConcatSource from 'webpack-sources/lib/ConcatSource';
2907ac75b1Sopenharmony_ci
3007ac75b1Sopenharmony_ciimport { transformLog } from './process_ui_syntax';
3107ac75b1Sopenharmony_ciimport {
3207ac75b1Sopenharmony_ci  useOSFiles,
3307ac75b1Sopenharmony_ci  sourcemapNamesCollection
3407ac75b1Sopenharmony_ci} from './validate_ui_syntax';
3507ac75b1Sopenharmony_ciimport {
3607ac75b1Sopenharmony_ci  circularFile,
3707ac75b1Sopenharmony_ci  writeUseOSFiles,
3807ac75b1Sopenharmony_ci  writeFileSync,
3907ac75b1Sopenharmony_ci  parseErrorMessage,
4007ac75b1Sopenharmony_ci  genTemporaryPath,
4107ac75b1Sopenharmony_ci  shouldWriteChangedList,
4207ac75b1Sopenharmony_ci  getHotReloadFiles,
4307ac75b1Sopenharmony_ci  setChecker,
4407ac75b1Sopenharmony_ci} from './utils';
4507ac75b1Sopenharmony_ciimport {
4607ac75b1Sopenharmony_ci  MODULE_ETS_PATH,
4707ac75b1Sopenharmony_ci  MODULE_SHARE_PATH,
4807ac75b1Sopenharmony_ci  BUILD_SHARE_PATH,
4907ac75b1Sopenharmony_ci  EXTNAME_JS,
5007ac75b1Sopenharmony_ci  EXTNAME_JS_MAP
5107ac75b1Sopenharmony_ci} from './pre_define';
5207ac75b1Sopenharmony_ciimport {
5307ac75b1Sopenharmony_ci  serviceChecker,
5407ac75b1Sopenharmony_ci  createWatchCompilerHost,
5507ac75b1Sopenharmony_ci  hotReloadSupportFiles,
5607ac75b1Sopenharmony_ci  printDiagnostic,
5707ac75b1Sopenharmony_ci  checkerResult,
5807ac75b1Sopenharmony_ci  incrementWatchFile,
5907ac75b1Sopenharmony_ci  warnCheckerResult
6007ac75b1Sopenharmony_ci} from './ets_checker';
6107ac75b1Sopenharmony_ciimport {
6207ac75b1Sopenharmony_ci  globalProgram,
6307ac75b1Sopenharmony_ci  projectConfig
6407ac75b1Sopenharmony_ci} from '../main';
6507ac75b1Sopenharmony_ciimport cluster from 'cluster';
6607ac75b1Sopenharmony_ci
6707ac75b1Sopenharmony_ciconfigure({
6807ac75b1Sopenharmony_ci  appenders: { 'ETS': {type: 'stderr', layout: {type: 'messagePassThrough'}}},
6907ac75b1Sopenharmony_ci  categories: {'default': {appenders: ['ETS'], level: 'info'}}
7007ac75b1Sopenharmony_ci});
7107ac75b1Sopenharmony_ciexport const logger = getLogger('ETS');
7207ac75b1Sopenharmony_ci
7307ac75b1Sopenharmony_ciconst checkErrorMessage: Set<string | Info> = new Set([]);
7407ac75b1Sopenharmony_ci
7507ac75b1Sopenharmony_ciinterface Info {
7607ac75b1Sopenharmony_ci  message?: string;
7707ac75b1Sopenharmony_ci  issue?: {
7807ac75b1Sopenharmony_ci    message: string,
7907ac75b1Sopenharmony_ci    file: string,
8007ac75b1Sopenharmony_ci    location: { start?: { line: number, column: number } }
8107ac75b1Sopenharmony_ci  };
8207ac75b1Sopenharmony_ci}
8307ac75b1Sopenharmony_ci
8407ac75b1Sopenharmony_ciexport interface CacheFileName {
8507ac75b1Sopenharmony_ci  mtimeMs: number,
8607ac75b1Sopenharmony_ci  children: string[],
8707ac75b1Sopenharmony_ci  parent: string[],
8807ac75b1Sopenharmony_ci  error: boolean
8907ac75b1Sopenharmony_ci}
9007ac75b1Sopenharmony_ci
9107ac75b1Sopenharmony_ciinterface hotReloadIncrementalTime {
9207ac75b1Sopenharmony_ci  hotReloadIncrementalStartTime: string;
9307ac75b1Sopenharmony_ci  hotReloadIncrementalEndTime: string;
9407ac75b1Sopenharmony_ci}
9507ac75b1Sopenharmony_ci
9607ac75b1Sopenharmony_ciexport class ResultStates {
9707ac75b1Sopenharmony_ci  private mStats: Stats;
9807ac75b1Sopenharmony_ci  private mErrorCount: number = 0;
9907ac75b1Sopenharmony_ci  private mPreErrorCount: number = 0;
10007ac75b1Sopenharmony_ci  private mWarningCount: number = 0;
10107ac75b1Sopenharmony_ci  private warningCount: number = 0;
10207ac75b1Sopenharmony_ci  private noteCount: number = 0;
10307ac75b1Sopenharmony_ci  private red: string = '\u001b[31m';
10407ac75b1Sopenharmony_ci  private yellow: string = '\u001b[33m';
10507ac75b1Sopenharmony_ci  private blue: string = '\u001b[34m';
10607ac75b1Sopenharmony_ci  private reset: string = '\u001b[39m';
10707ac75b1Sopenharmony_ci  private moduleSharePaths: Set<string> = new Set([]);
10807ac75b1Sopenharmony_ci  private removedFiles: string[] = [];
10907ac75b1Sopenharmony_ci  private hotReloadIncrementalTime: hotReloadIncrementalTime = {
11007ac75b1Sopenharmony_ci    hotReloadIncrementalStartTime: '',
11107ac75b1Sopenharmony_ci    hotReloadIncrementalEndTime: ''
11207ac75b1Sopenharmony_ci  };
11307ac75b1Sopenharmony_ci  private incrementalFileInHar: Map<string, string> = new Map();
11407ac75b1Sopenharmony_ci
11507ac75b1Sopenharmony_ci  public apply(compiler: Compiler): void {
11607ac75b1Sopenharmony_ci    compiler.hooks.compilation.tap('SourcemapFixer', compilation => {
11707ac75b1Sopenharmony_ci      compilation.hooks.processAssets.tap('RemoveHar', (assets) => {
11807ac75b1Sopenharmony_ci        if (!projectConfig.compileHar) {
11907ac75b1Sopenharmony_ci          return;
12007ac75b1Sopenharmony_ci        }
12107ac75b1Sopenharmony_ci        Object.keys(compilation.assets).forEach(key => {
12207ac75b1Sopenharmony_ci          if (path.extname(key) === EXTNAME_JS || path.extname(key) === EXTNAME_JS_MAP) {
12307ac75b1Sopenharmony_ci            delete assets[key];
12407ac75b1Sopenharmony_ci          }
12507ac75b1Sopenharmony_ci        });
12607ac75b1Sopenharmony_ci      });
12707ac75b1Sopenharmony_ci
12807ac75b1Sopenharmony_ci      compilation.hooks.afterProcessAssets.tap('SourcemapFixer', assets => {
12907ac75b1Sopenharmony_ci        Reflect.ownKeys(assets).forEach(key => {
13007ac75b1Sopenharmony_ci          if (/\.map$/.test(key.toString()) && assets[key]._value) {
13107ac75b1Sopenharmony_ci            assets[key]._value = assets[key]._value.toString().replace('.ets?entry', '.ets');
13207ac75b1Sopenharmony_ci            assets[key]._value = assets[key]._value.toString().replace('.ts?entry', '.ts');
13307ac75b1Sopenharmony_ci            let absPath: string = path.resolve(projectConfig.projectPath, key.toString().replace('.js.map', '.js'));
13407ac75b1Sopenharmony_ci            if (sourcemapNamesCollection && absPath) {
13507ac75b1Sopenharmony_ci              let map: Map<string, string> = sourcemapNamesCollection.get(absPath);
13607ac75b1Sopenharmony_ci              if (map && map.size !== 0) {
13707ac75b1Sopenharmony_ci                let names: Array<string> = Array.from(map).flat();
13807ac75b1Sopenharmony_ci                let sourcemapObj: any = JSON.parse(assets[key]._value);
13907ac75b1Sopenharmony_ci                sourcemapObj.nameMap = names;
14007ac75b1Sopenharmony_ci                assets[key]._value = JSON.stringify(sourcemapObj);
14107ac75b1Sopenharmony_ci              }
14207ac75b1Sopenharmony_ci            }
14307ac75b1Sopenharmony_ci          }
14407ac75b1Sopenharmony_ci        });
14507ac75b1Sopenharmony_ci      }
14607ac75b1Sopenharmony_ci      );
14707ac75b1Sopenharmony_ci
14807ac75b1Sopenharmony_ci      compilation.hooks.succeedModule.tap('findModule', (module) => {
14907ac75b1Sopenharmony_ci        if (module && module.error) {
15007ac75b1Sopenharmony_ci          const errorLog: string = module.error.toString();
15107ac75b1Sopenharmony_ci          if (module.resourceResolveData && module.resourceResolveData.path &&
15207ac75b1Sopenharmony_ci            /Module parse failed/.test(errorLog) && /Invalid regular expression:/.test(errorLog)) {
15307ac75b1Sopenharmony_ci            this.mErrorCount++;
15407ac75b1Sopenharmony_ci            const errorInfos: string[] = errorLog.split('\n>')[1].split(';');
15507ac75b1Sopenharmony_ci            if (errorInfos && errorInfos.length > 0 && errorInfos[0]) {
15607ac75b1Sopenharmony_ci              const errorInformation: string = `ERROR in ${module.resourceResolveData.path}\n The following syntax is incorrect.\n > ${errorInfos[0]}`;
15707ac75b1Sopenharmony_ci              this.printErrorMessage(parseErrorMessage(errorInformation), false, module.error);
15807ac75b1Sopenharmony_ci            }
15907ac75b1Sopenharmony_ci          }
16007ac75b1Sopenharmony_ci        }
16107ac75b1Sopenharmony_ci      });
16207ac75b1Sopenharmony_ci
16307ac75b1Sopenharmony_ci      compilation.hooks.buildModule.tap('findModule', (module) => {
16407ac75b1Sopenharmony_ci        if (module.context) {
16507ac75b1Sopenharmony_ci          if (module.context.indexOf(projectConfig.projectPath) >= 0) {
16607ac75b1Sopenharmony_ci            return;
16707ac75b1Sopenharmony_ci          }
16807ac75b1Sopenharmony_ci          const modulePath: string = path.join(module.context);
16907ac75b1Sopenharmony_ci          const srcIndex: number = modulePath.lastIndexOf(MODULE_ETS_PATH);
17007ac75b1Sopenharmony_ci          if (srcIndex < 0) {
17107ac75b1Sopenharmony_ci            return;
17207ac75b1Sopenharmony_ci          }
17307ac75b1Sopenharmony_ci          const moduleSharePath: string = path.resolve(modulePath.substring(0, srcIndex), MODULE_SHARE_PATH);
17407ac75b1Sopenharmony_ci          if (fs.existsSync(moduleSharePath)) {
17507ac75b1Sopenharmony_ci            this.moduleSharePaths.add(moduleSharePath);
17607ac75b1Sopenharmony_ci          }
17707ac75b1Sopenharmony_ci        }
17807ac75b1Sopenharmony_ci      });
17907ac75b1Sopenharmony_ci
18007ac75b1Sopenharmony_ci      compilation.hooks.finishModules.tap('finishModules', handleFinishModules.bind(this));
18107ac75b1Sopenharmony_ci    });
18207ac75b1Sopenharmony_ci
18307ac75b1Sopenharmony_ci    compiler.hooks.afterCompile.tap('copyFindModule', () => {
18407ac75b1Sopenharmony_ci      this.moduleSharePaths.forEach(modulePath => {
18507ac75b1Sopenharmony_ci        circularFile(modulePath, path.resolve(projectConfig.buildPath, BUILD_SHARE_PATH));
18607ac75b1Sopenharmony_ci      });
18707ac75b1Sopenharmony_ci    });
18807ac75b1Sopenharmony_ci
18907ac75b1Sopenharmony_ci    compiler.hooks.compilation.tap('CommonAsset', compilation => {
19007ac75b1Sopenharmony_ci      compilation.hooks.processAssets.tap(
19107ac75b1Sopenharmony_ci        {
19207ac75b1Sopenharmony_ci          name: 'GLOBAL_COMMON_MODULE_CACHE',
19307ac75b1Sopenharmony_ci          stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS
19407ac75b1Sopenharmony_ci        },
19507ac75b1Sopenharmony_ci        (assets) => {
19607ac75b1Sopenharmony_ci          const GLOBAL_COMMON_MODULE_CACHE = `
19707ac75b1Sopenharmony_ci          globalThis["__common_module_cache__${projectConfig.hashProjectPath}"] =` +
19807ac75b1Sopenharmony_ci          ` globalThis["__common_module_cache__${projectConfig.hashProjectPath}"] || {};`;
19907ac75b1Sopenharmony_ci          if (assets['commons.js']) {
20007ac75b1Sopenharmony_ci            assets['commons.js'] = new CachedSource(
20107ac75b1Sopenharmony_ci              new ConcatSource(assets['commons.js'], GLOBAL_COMMON_MODULE_CACHE));
20207ac75b1Sopenharmony_ci          } else if (assets['vendors.js']) {
20307ac75b1Sopenharmony_ci            assets['vendors.js'] = new CachedSource(
20407ac75b1Sopenharmony_ci              new ConcatSource(assets['vendors.js'], GLOBAL_COMMON_MODULE_CACHE));
20507ac75b1Sopenharmony_ci          }
20607ac75b1Sopenharmony_ci        });
20707ac75b1Sopenharmony_ci    });
20807ac75b1Sopenharmony_ci
20907ac75b1Sopenharmony_ci    compiler.hooks.compilation.tap('Require', compilation => {
21007ac75b1Sopenharmony_ci      JavascriptModulesPlugin.getCompilationHooks(compilation).renderRequire.tap('renderRequire',
21107ac75b1Sopenharmony_ci        (source) => {
21207ac75b1Sopenharmony_ci          return `var commonCachedModule = globalThis` +
21307ac75b1Sopenharmony_ci          `["__common_module_cache__${projectConfig.hashProjectPath}"] ? ` +
21407ac75b1Sopenharmony_ci            `globalThis["__common_module_cache__${projectConfig.hashProjectPath}"]` +
21507ac75b1Sopenharmony_ci            `[moduleId]: null;\n` +
21607ac75b1Sopenharmony_ci            `if (commonCachedModule) { return commonCachedModule.exports; }\n` +
21707ac75b1Sopenharmony_ci            source.replace('// Execute the module function',
21807ac75b1Sopenharmony_ci              `function isCommonModue(moduleId) {
21907ac75b1Sopenharmony_ci                if (globalThis["webpackChunk${projectConfig.hashProjectPath}"]) {
22007ac75b1Sopenharmony_ci                  const length = globalThis["webpackChunk${projectConfig.hashProjectPath}"].length;
22107ac75b1Sopenharmony_ci                  switch (length) {
22207ac75b1Sopenharmony_ci                    case 1:
22307ac75b1Sopenharmony_ci                      return globalThis["webpackChunk${projectConfig.hashProjectPath}"][0][1][moduleId];
22407ac75b1Sopenharmony_ci                    case 2:
22507ac75b1Sopenharmony_ci                      return globalThis["webpackChunk${projectConfig.hashProjectPath}"][0][1][moduleId] ||
22607ac75b1Sopenharmony_ci                      globalThis["webpackChunk${projectConfig.hashProjectPath}"][1][1][moduleId];
22707ac75b1Sopenharmony_ci                  }
22807ac75b1Sopenharmony_ci                }
22907ac75b1Sopenharmony_ci                return undefined;
23007ac75b1Sopenharmony_ci              }\n` +
23107ac75b1Sopenharmony_ci              `if (globalThis["__common_module_cache__${projectConfig.hashProjectPath}"]` +
23207ac75b1Sopenharmony_ci              ` && String(moduleId).indexOf("?name=") < 0 && isCommonModue(moduleId)) {\n` +
23307ac75b1Sopenharmony_ci              `  globalThis["__common_module_cache__${projectConfig.hashProjectPath}"]` +
23407ac75b1Sopenharmony_ci              `[moduleId] = module;\n}`);
23507ac75b1Sopenharmony_ci        });
23607ac75b1Sopenharmony_ci    });
23707ac75b1Sopenharmony_ci
23807ac75b1Sopenharmony_ci    compiler.hooks.entryOption.tap('beforeRun', () => {
23907ac75b1Sopenharmony_ci      const rootFileNames: string[] = [];
24007ac75b1Sopenharmony_ci      Object.values(projectConfig.entryObj).forEach((fileName: string) => {
24107ac75b1Sopenharmony_ci        rootFileNames.push(fileName.replace('?entry', ''));
24207ac75b1Sopenharmony_ci      });
24307ac75b1Sopenharmony_ci      if (process.env.watchMode === 'true') {
24407ac75b1Sopenharmony_ci        globalProgram.watchProgram = ts.createWatchProgram(
24507ac75b1Sopenharmony_ci          createWatchCompilerHost(rootFileNames, printDiagnostic,
24607ac75b1Sopenharmony_ci            this.delayPrintLogCount.bind(this), this.resetTsErrorCount));
24707ac75b1Sopenharmony_ci      } else {
24807ac75b1Sopenharmony_ci        serviceChecker(rootFileNames);
24907ac75b1Sopenharmony_ci      }
25007ac75b1Sopenharmony_ci      setChecker();
25107ac75b1Sopenharmony_ci    });
25207ac75b1Sopenharmony_ci
25307ac75b1Sopenharmony_ci    compiler.hooks.watchRun.tap('WatchRun', (comp) => {
25407ac75b1Sopenharmony_ci      process.env.watchEts = 'start';
25507ac75b1Sopenharmony_ci      checkErrorMessage.clear();
25607ac75b1Sopenharmony_ci      this.clearCount();
25707ac75b1Sopenharmony_ci      comp.modifiedFiles = comp.modifiedFiles || [];
25807ac75b1Sopenharmony_ci      comp.removedFiles = comp.removedFiles || [];
25907ac75b1Sopenharmony_ci      const watchModifiedFiles: string[] = [...comp.modifiedFiles];
26007ac75b1Sopenharmony_ci      let watchRemovedFiles: string[] = [...comp.removedFiles];
26107ac75b1Sopenharmony_ci      if (watchRemovedFiles.length) {
26207ac75b1Sopenharmony_ci        this.removedFiles = watchRemovedFiles;
26307ac75b1Sopenharmony_ci      }
26407ac75b1Sopenharmony_ci      if (watchModifiedFiles.length) {
26507ac75b1Sopenharmony_ci        watchModifiedFiles.some((item: string) => {
26607ac75b1Sopenharmony_ci          if (fs.statSync(item).isFile() && !/.(ts|ets)$/.test(item)) {
26707ac75b1Sopenharmony_ci            process.env.watchTs = 'end';
26807ac75b1Sopenharmony_ci            return true;
26907ac75b1Sopenharmony_ci          }
27007ac75b1Sopenharmony_ci          return false;
27107ac75b1Sopenharmony_ci        });
27207ac75b1Sopenharmony_ci      }
27307ac75b1Sopenharmony_ci      if (shouldWriteChangedList(watchModifiedFiles, watchRemovedFiles)) {
27407ac75b1Sopenharmony_ci        writeFileSync(projectConfig.changedFileList, JSON.stringify(
27507ac75b1Sopenharmony_ci          getHotReloadFiles(watchModifiedFiles, watchRemovedFiles, hotReloadSupportFiles)));
27607ac75b1Sopenharmony_ci      }
27707ac75b1Sopenharmony_ci      incrementWatchFile(watchModifiedFiles, watchRemovedFiles);
27807ac75b1Sopenharmony_ci    });
27907ac75b1Sopenharmony_ci
28007ac75b1Sopenharmony_ci    compiler.hooks.done.tap('Result States', (stats: Stats) => {
28107ac75b1Sopenharmony_ci      if (projectConfig.isPreview && projectConfig.aceSoPath &&
28207ac75b1Sopenharmony_ci        useOSFiles && useOSFiles.size > 0) {
28307ac75b1Sopenharmony_ci        writeUseOSFiles(useOSFiles);
28407ac75b1Sopenharmony_ci      }
28507ac75b1Sopenharmony_ci      if (projectConfig.compileHar) {
28607ac75b1Sopenharmony_ci        this.incrementalFileInHar.forEach((jsBuildFilePath, jsCacheFilePath) => {
28707ac75b1Sopenharmony_ci          const sourceCode: string = fs.readFileSync(jsCacheFilePath, 'utf-8');
28807ac75b1Sopenharmony_ci          writeFileSync(jsBuildFilePath, sourceCode);
28907ac75b1Sopenharmony_ci        });
29007ac75b1Sopenharmony_ci      }
29107ac75b1Sopenharmony_ci      this.mStats = stats;
29207ac75b1Sopenharmony_ci      this.warningCount = 0;
29307ac75b1Sopenharmony_ci      this.noteCount = 0;
29407ac75b1Sopenharmony_ci      if (this.mStats.compilation.warnings) {
29507ac75b1Sopenharmony_ci        this.mWarningCount = this.mStats.compilation.warnings.length;
29607ac75b1Sopenharmony_ci      }
29707ac75b1Sopenharmony_ci      this.printResult();
29807ac75b1Sopenharmony_ci    });
29907ac75b1Sopenharmony_ci  }
30007ac75b1Sopenharmony_ci
30107ac75b1Sopenharmony_ci  private resetTsErrorCount(): void {
30207ac75b1Sopenharmony_ci    checkerResult.count = 0;
30307ac75b1Sopenharmony_ci    warnCheckerResult.count = 0;
30407ac75b1Sopenharmony_ci  }
30507ac75b1Sopenharmony_ci
30607ac75b1Sopenharmony_ci  private printResult(): void {
30707ac75b1Sopenharmony_ci    this.printWarning();
30807ac75b1Sopenharmony_ci    this.printError();
30907ac75b1Sopenharmony_ci    if (process.env.watchMode === 'true') {
31007ac75b1Sopenharmony_ci      process.env.watchEts = 'end';
31107ac75b1Sopenharmony_ci      this.delayPrintLogCount(true);
31207ac75b1Sopenharmony_ci    } else {
31307ac75b1Sopenharmony_ci      this.printLogCount();
31407ac75b1Sopenharmony_ci    }
31507ac75b1Sopenharmony_ci  }
31607ac75b1Sopenharmony_ci
31707ac75b1Sopenharmony_ci  private delayPrintLogCount(isCompile: boolean = false) {
31807ac75b1Sopenharmony_ci    if (process.env.watchEts === 'end' && process.env.watchTs === 'end') {
31907ac75b1Sopenharmony_ci      this.printLogCount();
32007ac75b1Sopenharmony_ci      process.env.watchTs = 'start';
32107ac75b1Sopenharmony_ci      this.removedFiles = [];
32207ac75b1Sopenharmony_ci    } else if (isCompile && this.removedFiles.length && this.mErrorCount === 0 && this.mPreErrorCount > 0) {
32307ac75b1Sopenharmony_ci      this.printLogCount();
32407ac75b1Sopenharmony_ci    }
32507ac75b1Sopenharmony_ci    this.mPreErrorCount = this.mErrorCount;
32607ac75b1Sopenharmony_ci  }
32707ac75b1Sopenharmony_ci
32807ac75b1Sopenharmony_ci  private printLogCount(): void {
32907ac75b1Sopenharmony_ci    let errorCount: number = this.mErrorCount + checkerResult.count;
33007ac75b1Sopenharmony_ci    const warnCount: number = this.warningCount + warnCheckerResult.count;
33107ac75b1Sopenharmony_ci    if (errorCount + warnCount + this.noteCount > 0 || process.env.abcCompileSuccess === 'false') {
33207ac75b1Sopenharmony_ci      let result: string;
33307ac75b1Sopenharmony_ci      let resultInfo: string = '';
33407ac75b1Sopenharmony_ci      if (errorCount > 0) {
33507ac75b1Sopenharmony_ci        resultInfo += `ERROR:${errorCount}`;
33607ac75b1Sopenharmony_ci        result = 'FAIL ';
33707ac75b1Sopenharmony_ci        process.exitCode = 1;
33807ac75b1Sopenharmony_ci      } else {
33907ac75b1Sopenharmony_ci        result = 'SUCCESS ';
34007ac75b1Sopenharmony_ci      }
34107ac75b1Sopenharmony_ci      if (process.env.abcCompileSuccess === 'false') {
34207ac75b1Sopenharmony_ci        result = 'FAIL ';
34307ac75b1Sopenharmony_ci      }
34407ac75b1Sopenharmony_ci      if (warnCount > 0) {
34507ac75b1Sopenharmony_ci        resultInfo += ` WARN:${warnCount}`;
34607ac75b1Sopenharmony_ci      }
34707ac75b1Sopenharmony_ci      if (this.noteCount > 0) {
34807ac75b1Sopenharmony_ci        resultInfo += ` NOTE:${this.noteCount}`;
34907ac75b1Sopenharmony_ci      }
35007ac75b1Sopenharmony_ci      if (result === 'SUCCESS ' && process.env.watchMode === 'true') {
35107ac75b1Sopenharmony_ci        this.printPreviewResult(resultInfo);
35207ac75b1Sopenharmony_ci      } else {
35307ac75b1Sopenharmony_ci        logger.info(this.blue, 'COMPILE RESULT:' + result + `{${resultInfo}}`, this.reset);
35407ac75b1Sopenharmony_ci      }
35507ac75b1Sopenharmony_ci    } else {
35607ac75b1Sopenharmony_ci      if (process.env.watchMode === 'true') {
35707ac75b1Sopenharmony_ci        this.printPreviewResult();
35807ac75b1Sopenharmony_ci      } else {
35907ac75b1Sopenharmony_ci        console.info(this.blue, 'COMPILE RESULT:SUCCESS ', this.reset);
36007ac75b1Sopenharmony_ci      }
36107ac75b1Sopenharmony_ci    }
36207ac75b1Sopenharmony_ci  }
36307ac75b1Sopenharmony_ci
36407ac75b1Sopenharmony_ci  private clearCount(): void {
36507ac75b1Sopenharmony_ci    this.mErrorCount = 0;
36607ac75b1Sopenharmony_ci    this.warningCount = 0;
36707ac75b1Sopenharmony_ci    this.noteCount = 0;
36807ac75b1Sopenharmony_ci    process.env.abcCompileSuccess = 'true';
36907ac75b1Sopenharmony_ci  }
37007ac75b1Sopenharmony_ci
37107ac75b1Sopenharmony_ci  private printPreviewResult(resultInfo: string = ''): void {
37207ac75b1Sopenharmony_ci    const workerNum: number = Object.keys(cluster.workers).length;
37307ac75b1Sopenharmony_ci    const blue: string = this.blue;
37407ac75b1Sopenharmony_ci    const reset: string = this.reset;
37507ac75b1Sopenharmony_ci    if (workerNum === 0) {
37607ac75b1Sopenharmony_ci      this.printSuccessInfo(blue, reset, resultInfo);
37707ac75b1Sopenharmony_ci    }
37807ac75b1Sopenharmony_ci  }
37907ac75b1Sopenharmony_ci
38007ac75b1Sopenharmony_ci  private printSuccessInfo(blue: string, reset: string, resultInfo: string): void {
38107ac75b1Sopenharmony_ci    if (projectConfig.hotReload) {
38207ac75b1Sopenharmony_ci      this.hotReloadIncrementalTime.hotReloadIncrementalEndTime = new Date().getTime().toString();
38307ac75b1Sopenharmony_ci      console.info(blue, 'Incremental build start: ' + this.hotReloadIncrementalTime.hotReloadIncrementalStartTime +
38407ac75b1Sopenharmony_ci        '\n' + 'Incremental build end: ' + this.hotReloadIncrementalTime.hotReloadIncrementalEndTime, reset);
38507ac75b1Sopenharmony_ci    }
38607ac75b1Sopenharmony_ci    if (resultInfo.length === 0) {
38707ac75b1Sopenharmony_ci      console.info(blue, 'COMPILE RESULT:SUCCESS ', reset);
38807ac75b1Sopenharmony_ci    } else {
38907ac75b1Sopenharmony_ci      console.info(blue, 'COMPILE RESULT:SUCCESS ' + `{${resultInfo}}`, reset);
39007ac75b1Sopenharmony_ci    }
39107ac75b1Sopenharmony_ci  }
39207ac75b1Sopenharmony_ci
39307ac75b1Sopenharmony_ci  private printWarning(): void {
39407ac75b1Sopenharmony_ci    if (this.mWarningCount > 0) {
39507ac75b1Sopenharmony_ci      const warnings: Info[] = this.mStats.compilation.warnings;
39607ac75b1Sopenharmony_ci      const length: number = warnings.length;
39707ac75b1Sopenharmony_ci      for (let index = 0; index < length; index++) {
39807ac75b1Sopenharmony_ci        const message: string = warnings[index].message.replace(/^Module Warning\s*.*:\n/, '')
39907ac75b1Sopenharmony_ci          .replace(/\(Emitted value instead of an instance of Error\) BUILD/, '');
40007ac75b1Sopenharmony_ci        if (/^NOTE/.test(message)) {
40107ac75b1Sopenharmony_ci          if (!checkErrorMessage.has(message)) {
40207ac75b1Sopenharmony_ci            this.noteCount++;
40307ac75b1Sopenharmony_ci            logger.info(this.blue, message.replace(/^NOTE/, 'ArkTS:NOTE'), this.reset, '\n');
40407ac75b1Sopenharmony_ci            checkErrorMessage.add(message);
40507ac75b1Sopenharmony_ci          }
40607ac75b1Sopenharmony_ci        } else {
40707ac75b1Sopenharmony_ci          if (!checkErrorMessage.has(message)) {
40807ac75b1Sopenharmony_ci            this.warningCount++;
40907ac75b1Sopenharmony_ci            logger.warn(this.yellow, message.replace(/^WARN/, 'ArkTS:WARN'), this.reset, '\n');
41007ac75b1Sopenharmony_ci            checkErrorMessage.add(message);
41107ac75b1Sopenharmony_ci          }
41207ac75b1Sopenharmony_ci        }
41307ac75b1Sopenharmony_ci      }
41407ac75b1Sopenharmony_ci      if (this.mWarningCount > length) {
41507ac75b1Sopenharmony_ci        this.warningCount = this.warningCount + this.mWarningCount - length;
41607ac75b1Sopenharmony_ci      }
41707ac75b1Sopenharmony_ci    }
41807ac75b1Sopenharmony_ci  }
41907ac75b1Sopenharmony_ci
42007ac75b1Sopenharmony_ci  private printError(): void {
42107ac75b1Sopenharmony_ci    if (this.mStats.compilation.errors.length > 0) {
42207ac75b1Sopenharmony_ci      const errors: Info[] = [...this.mStats.compilation.errors];
42307ac75b1Sopenharmony_ci      for (let index = 0; index < errors.length; index++) {
42407ac75b1Sopenharmony_ci        if (errors[index].issue) {
42507ac75b1Sopenharmony_ci          if (!checkErrorMessage.has(errors[index].issue)) {
42607ac75b1Sopenharmony_ci            this.mErrorCount++;
42707ac75b1Sopenharmony_ci            const position: string = errors[index].issue.location
42807ac75b1Sopenharmony_ci              ? `:${errors[index].issue.location.start.line}:${errors[index].issue.location.start.column}`
42907ac75b1Sopenharmony_ci              : '';
43007ac75b1Sopenharmony_ci            const location: string = errors[index].issue.file.replace(/\\/g, '/') + position;
43107ac75b1Sopenharmony_ci            const detail: string = errors[index].issue.message;
43207ac75b1Sopenharmony_ci            logger.error(this.red, 'ArkTS:ERROR File: ' + location, this.reset);
43307ac75b1Sopenharmony_ci            logger.error(this.red, detail, this.reset, '\n');
43407ac75b1Sopenharmony_ci            checkErrorMessage.add(errors[index].issue);
43507ac75b1Sopenharmony_ci          }
43607ac75b1Sopenharmony_ci        } else if (/BUILDERROR/.test(errors[index].message)) {
43707ac75b1Sopenharmony_ci          if (!checkErrorMessage.has(errors[index].message)) {
43807ac75b1Sopenharmony_ci            this.mErrorCount++;
43907ac75b1Sopenharmony_ci            const errorMessage: string = errors[index].message.replace(/^Module Error\s*.*:\n/, '')
44007ac75b1Sopenharmony_ci              .replace(/\(Emitted value instead of an instance of Error\) BUILD/, '')
44107ac75b1Sopenharmony_ci              .replace(/^ERROR/, 'ArkTS:ERROR');
44207ac75b1Sopenharmony_ci            this.printErrorMessage(errorMessage, true, errors[index]);
44307ac75b1Sopenharmony_ci            checkErrorMessage.add(errors[index].message);
44407ac75b1Sopenharmony_ci          }
44507ac75b1Sopenharmony_ci        } else if (!/TS[0-9]+:/.test(errors[index].message.toString()) &&
44607ac75b1Sopenharmony_ci          !/Module parse failed/.test(errors[index].message.toString())) {
44707ac75b1Sopenharmony_ci          this.mErrorCount++;
44807ac75b1Sopenharmony_ci          let errorMessage: string = `${errors[index].message.replace(/\[tsl\]\s*/, '')
44907ac75b1Sopenharmony_ci            .replace(/\u001b\[.*?m/g, '').replace(/\.ets\.ts/g, '.ets').trim()}\n`;
45007ac75b1Sopenharmony_ci          errorMessage = this.filterModuleError(errorMessage)
45107ac75b1Sopenharmony_ci            .replace(/^ERROR in /, 'ArkTS:ERROR File: ').replace(/\s{6}TS/g, ' TS')
45207ac75b1Sopenharmony_ci            .replace(/\(([0-9]+),([0-9]+)\)/, ':$1:$2');
45307ac75b1Sopenharmony_ci          this.printErrorMessage(parseErrorMessage(errorMessage), false, errors[index]);
45407ac75b1Sopenharmony_ci        }
45507ac75b1Sopenharmony_ci      }
45607ac75b1Sopenharmony_ci    }
45707ac75b1Sopenharmony_ci  }
45807ac75b1Sopenharmony_ci  private printErrorMessage(errorMessage: string, lineFeed: boolean, errorInfo: Info): void {
45907ac75b1Sopenharmony_ci    const formatErrMsg = errorMessage.replace(/\\/g, '/');
46007ac75b1Sopenharmony_ci    if (lineFeed) {
46107ac75b1Sopenharmony_ci      logger.error(this.red, formatErrMsg + '\n', this.reset);
46207ac75b1Sopenharmony_ci    } else {
46307ac75b1Sopenharmony_ci      logger.error(this.red, formatErrMsg, this.reset);
46407ac75b1Sopenharmony_ci    }
46507ac75b1Sopenharmony_ci  }
46607ac75b1Sopenharmony_ci  private filterModuleError(message: string): string {
46707ac75b1Sopenharmony_ci    if (/You may need an additional loader/.test(message) && transformLog && transformLog.sourceFile) {
46807ac75b1Sopenharmony_ci      const fileName: string = transformLog.sourceFile.fileName;
46907ac75b1Sopenharmony_ci      const errorInfos: string[] = message.split('You may need an additional loader to handle the result of these loaders.');
47007ac75b1Sopenharmony_ci      if (errorInfos && errorInfos.length > 1 && errorInfos[1]) {
47107ac75b1Sopenharmony_ci        message = `ERROR in ${fileName}\n The following syntax is incorrect.${errorInfos[1]}`;
47207ac75b1Sopenharmony_ci      }
47307ac75b1Sopenharmony_ci    }
47407ac75b1Sopenharmony_ci    return message;
47507ac75b1Sopenharmony_ci  }
47607ac75b1Sopenharmony_ci}
47707ac75b1Sopenharmony_ci
47807ac75b1Sopenharmony_cifunction handleFinishModules(modules, callback) {
47907ac75b1Sopenharmony_ci  if (projectConfig.compileHar) {
48007ac75b1Sopenharmony_ci    modules.forEach(module => {
48107ac75b1Sopenharmony_ci      if (module !== undefined && module.resourceResolveData !== undefined) {
48207ac75b1Sopenharmony_ci        const filePath: string = module.resourceResolveData.path;
48307ac75b1Sopenharmony_ci        if (!filePath.match(/node_modules/)) {
48407ac75b1Sopenharmony_ci          const jsCacheFilePath: string = genTemporaryPath(filePath, projectConfig.moduleRootPath, process.env.cachePath,
48507ac75b1Sopenharmony_ci            projectConfig, undefined);
48607ac75b1Sopenharmony_ci          const jsBuildFilePath: string = genTemporaryPath(filePath, projectConfig.moduleRootPath,
48707ac75b1Sopenharmony_ci            projectConfig.buildPath, projectConfig, undefined, true);
48807ac75b1Sopenharmony_ci          if (filePath.match(/\.e?ts$/)) {
48907ac75b1Sopenharmony_ci            this.incrementalFileInHar.set(jsCacheFilePath.replace(/\.ets$/, '.d.ets').replace(/\.ts$/, '.d.ts'),
49007ac75b1Sopenharmony_ci              jsBuildFilePath.replace(/\.ets$/, '.d.ets').replace(/\.ts$/, '.d.ts'));
49107ac75b1Sopenharmony_ci            this.incrementalFileInHar.set(jsCacheFilePath.replace(/\.e?ts$/, '.js'), jsBuildFilePath.replace(/\.e?ts$/, '.js'));
49207ac75b1Sopenharmony_ci          } else {
49307ac75b1Sopenharmony_ci            this.incrementalFileInHar.set(jsCacheFilePath, jsBuildFilePath);
49407ac75b1Sopenharmony_ci          }
49507ac75b1Sopenharmony_ci        }
49607ac75b1Sopenharmony_ci      }
49707ac75b1Sopenharmony_ci    });
49807ac75b1Sopenharmony_ci  }
49907ac75b1Sopenharmony_ci}
500