107ac75b1Sopenharmony_ci/*
207ac75b1Sopenharmony_ci * Copyright (c) 2022 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 fs from 'fs';
1707ac75b1Sopenharmony_ciimport path from 'path';
1807ac75b1Sopenharmony_ciimport * as ts from 'typescript';
1907ac75b1Sopenharmony_ciimport * as crypto from 'crypto';
2007ac75b1Sopenharmony_ciconst fse = require('fs-extra');
2107ac75b1Sopenharmony_ci
2207ac75b1Sopenharmony_ciimport {
2307ac75b1Sopenharmony_ci  projectConfig,
2407ac75b1Sopenharmony_ci  systemModules,
2507ac75b1Sopenharmony_ci  globalProgram,
2607ac75b1Sopenharmony_ci  sdkConfigs,
2707ac75b1Sopenharmony_ci  sdkConfigPrefix,
2807ac75b1Sopenharmony_ci  partialUpdateConfig,
2907ac75b1Sopenharmony_ci  resetProjectConfig,
3007ac75b1Sopenharmony_ci  resetGlobalProgram
3107ac75b1Sopenharmony_ci} from '../main';
3207ac75b1Sopenharmony_ciimport {
3307ac75b1Sopenharmony_ci  preprocessExtend,
3407ac75b1Sopenharmony_ci  preprocessNewExtend
3507ac75b1Sopenharmony_ci} from './validate_ui_syntax';
3607ac75b1Sopenharmony_ciimport {
3707ac75b1Sopenharmony_ci  INNER_COMPONENT_MEMBER_DECORATORS,
3807ac75b1Sopenharmony_ci  COMPONENT_DECORATORS_PARAMS,
3907ac75b1Sopenharmony_ci  COMPONENT_BUILD_FUNCTION,
4007ac75b1Sopenharmony_ci  STYLE_ADD_DOUBLE_DOLLAR,
4107ac75b1Sopenharmony_ci  $$,
4207ac75b1Sopenharmony_ci  PROPERTIES_ADD_DOUBLE_DOLLAR,
4307ac75b1Sopenharmony_ci  DOLLAR_BLOCK_INTERFACE,
4407ac75b1Sopenharmony_ci  COMPONENT_EXTEND_DECORATOR,
4507ac75b1Sopenharmony_ci  COMPONENT_BUILDER_DECORATOR,
4607ac75b1Sopenharmony_ci  ESMODULE,
4707ac75b1Sopenharmony_ci  EXTNAME_D_ETS,
4807ac75b1Sopenharmony_ci  EXTNAME_JS,
4907ac75b1Sopenharmony_ci  FOREACH_LAZYFOREACH,
5007ac75b1Sopenharmony_ci  COMPONENT_IF,
5107ac75b1Sopenharmony_ci  TS_WATCH_END_MSG,
5207ac75b1Sopenharmony_ci  TS_BUILD_INFO_SUFFIX,
5307ac75b1Sopenharmony_ci  HOT_RELOAD_BUILD_INFO_SUFFIX,
5407ac75b1Sopenharmony_ci  WATCH_COMPILER_BUILD_INFO_SUFFIX,
5507ac75b1Sopenharmony_ci  COMPONENT_STYLES_DECORATOR
5607ac75b1Sopenharmony_ci} from './pre_define';
5707ac75b1Sopenharmony_ciimport {
5807ac75b1Sopenharmony_ci  INNER_COMPONENT_NAMES,
5907ac75b1Sopenharmony_ci  JS_BIND_COMPONENTS,
6007ac75b1Sopenharmony_ci  BUILDIN_STYLE_NAMES
6107ac75b1Sopenharmony_ci} from './component_map';
6207ac75b1Sopenharmony_ciimport { logger } from './compile_info';
6307ac75b1Sopenharmony_ciimport {
6407ac75b1Sopenharmony_ci  hasDecorator,
6507ac75b1Sopenharmony_ci  isString,
6607ac75b1Sopenharmony_ci  generateSourceFilesInHar,
6707ac75b1Sopenharmony_ci  startTimeStatisticsLocation,
6807ac75b1Sopenharmony_ci  stopTimeStatisticsLocation,
6907ac75b1Sopenharmony_ci  resolveModuleNamesTime,
7007ac75b1Sopenharmony_ci  CompilationTimeStatistics,
7107ac75b1Sopenharmony_ci  storedFileInfo,
7207ac75b1Sopenharmony_ci  toUnixPath,
7307ac75b1Sopenharmony_ci  isWindows,
7407ac75b1Sopenharmony_ci  isMac,
7507ac75b1Sopenharmony_ci  tryToLowerCasePath,
7607ac75b1Sopenharmony_ci  getRollupCache,
7707ac75b1Sopenharmony_ci  setRollupCache
7807ac75b1Sopenharmony_ci} from './utils';
7907ac75b1Sopenharmony_ciimport {
8007ac75b1Sopenharmony_ci  isExtendFunction,
8107ac75b1Sopenharmony_ci  isOriginalExtend
8207ac75b1Sopenharmony_ci} from './process_ui_syntax';
8307ac75b1Sopenharmony_ciimport { visualTransform } from './process_visual';
8407ac75b1Sopenharmony_ciimport { tsWatchEmitter } from './fast_build/ets_ui/rollup-plugin-ets-checker';
8507ac75b1Sopenharmony_ciimport {
8607ac75b1Sopenharmony_ci  doArkTSLinter,
8707ac75b1Sopenharmony_ci  ArkTSLinterMode,
8807ac75b1Sopenharmony_ci  ArkTSVersion,
8907ac75b1Sopenharmony_ci} from './do_arkTS_linter';
9007ac75b1Sopenharmony_ciimport {
9107ac75b1Sopenharmony_ci  getJsDocNodeCheckConfig,
9207ac75b1Sopenharmony_ci  isCardFile,
9307ac75b1Sopenharmony_ci  getRealModulePath,
9407ac75b1Sopenharmony_ci  getJsDocNodeConditionCheckResult
9507ac75b1Sopenharmony_ci} from './fast_build/system_api/api_check_utils';
9607ac75b1Sopenharmony_ciimport { sourceFileDependencies } from './fast_build/ark_compiler/common/ob_config_resolver';
9707ac75b1Sopenharmony_ci
9807ac75b1Sopenharmony_ciexport interface LanguageServiceCache {
9907ac75b1Sopenharmony_ci  service?: ts.LanguageService;
10007ac75b1Sopenharmony_ci  pkgJsonFileHash?: string;
10107ac75b1Sopenharmony_ci  targetESVersion?: ts.ScriptTarget;
10207ac75b1Sopenharmony_ci  preTsImportSendable?: boolean;
10307ac75b1Sopenharmony_ci}
10407ac75b1Sopenharmony_ci
10507ac75b1Sopenharmony_ciexport const SOURCE_FILES: Map<string, ts.SourceFile> = new Map();
10607ac75b1Sopenharmony_ciexport let localPackageSet: Set<string> = new Set();
10707ac75b1Sopenharmony_ci
10807ac75b1Sopenharmony_ciexport function readDeaclareFiles(): string[] {
10907ac75b1Sopenharmony_ci  const declarationsFileNames: string[] = [];
11007ac75b1Sopenharmony_ci  fs.readdirSync(path.resolve(__dirname, '../declarations'))
11107ac75b1Sopenharmony_ci    .forEach((fileName: string) => {
11207ac75b1Sopenharmony_ci      if (/\.d\.ts$/.test(fileName)) {
11307ac75b1Sopenharmony_ci        declarationsFileNames.push(path.resolve(__dirname, '../declarations', fileName));
11407ac75b1Sopenharmony_ci      }
11507ac75b1Sopenharmony_ci    });
11607ac75b1Sopenharmony_ci  return declarationsFileNames;
11707ac75b1Sopenharmony_ci}
11807ac75b1Sopenharmony_ci
11907ac75b1Sopenharmony_ciconst buildInfoWriteFile: ts.WriteFileCallback = (fileName: string, data: string) => {
12007ac75b1Sopenharmony_ci  if (fileName.includes(TS_BUILD_INFO_SUFFIX)) {
12107ac75b1Sopenharmony_ci    const fd: number = fs.openSync(fileName, 'w');
12207ac75b1Sopenharmony_ci    fs.writeSync(fd, data, undefined, 'utf8');
12307ac75b1Sopenharmony_ci    fs.closeSync(fd);
12407ac75b1Sopenharmony_ci  }
12507ac75b1Sopenharmony_ci};
12607ac75b1Sopenharmony_ci// The collection records the file name and the corresponding version, where the version is the hash value of the text in last compilation.
12707ac75b1Sopenharmony_ciconst filesBuildInfo: Map<string, string> = new Map();
12807ac75b1Sopenharmony_ci
12907ac75b1Sopenharmony_ciexport const compilerOptions: ts.CompilerOptions = ts.readConfigFile(
13007ac75b1Sopenharmony_ci  path.resolve(__dirname, '../tsconfig.json'), ts.sys.readFile).config.compilerOptions;
13107ac75b1Sopenharmony_cifunction setCompilerOptions(resolveModulePaths: string[]): void {
13207ac75b1Sopenharmony_ci  const allPath: Array<string> = ['*'];
13307ac75b1Sopenharmony_ci  const basePath: string = path.resolve(projectConfig.projectPath);
13407ac75b1Sopenharmony_ci  if (process.env.compileTool === 'rollup' && resolveModulePaths && resolveModulePaths.length) {
13507ac75b1Sopenharmony_ci    resolveModulePaths.forEach((item: string) => {
13607ac75b1Sopenharmony_ci      if (!(/oh_modules$/.test(item) || /node_modules$/.test(item))) {
13707ac75b1Sopenharmony_ci        allPath.push(path.join(path.relative(basePath, item), '*'));
13807ac75b1Sopenharmony_ci      }
13907ac75b1Sopenharmony_ci    });
14007ac75b1Sopenharmony_ci  } else {
14107ac75b1Sopenharmony_ci    if (!projectConfig.aceModuleJsonPath) {
14207ac75b1Sopenharmony_ci      allPath.push('../../../../../*');
14307ac75b1Sopenharmony_ci      allPath.push('../../*');
14407ac75b1Sopenharmony_ci    } else {
14507ac75b1Sopenharmony_ci      allPath.push('../../../../*');
14607ac75b1Sopenharmony_ci      allPath.push('../*');
14707ac75b1Sopenharmony_ci    }
14807ac75b1Sopenharmony_ci  }
14907ac75b1Sopenharmony_ci  const suffix: string = projectConfig.hotReload ? HOT_RELOAD_BUILD_INFO_SUFFIX : TS_BUILD_INFO_SUFFIX;
15007ac75b1Sopenharmony_ci  const buildInfoPath: string = path.resolve(projectConfig.cachePath, '..', suffix);
15107ac75b1Sopenharmony_ci  checkArkTSVersion();
15207ac75b1Sopenharmony_ci  Object.assign(compilerOptions, {
15307ac75b1Sopenharmony_ci    'allowJs': getArkTSLinterMode() !== ArkTSLinterMode.NOT_USE ? true : false,
15407ac75b1Sopenharmony_ci    'checkJs': getArkTSLinterMode() !== ArkTSLinterMode.NOT_USE ? false : undefined,
15507ac75b1Sopenharmony_ci    'emitNodeModulesFiles': true,
15607ac75b1Sopenharmony_ci    'importsNotUsedAsValues': ts.ImportsNotUsedAsValues.Preserve,
15707ac75b1Sopenharmony_ci    'module': ts.ModuleKind.CommonJS,
15807ac75b1Sopenharmony_ci    'moduleResolution': ts.ModuleResolutionKind.NodeJs,
15907ac75b1Sopenharmony_ci    'noEmit': true,
16007ac75b1Sopenharmony_ci    'target': convertConfigTarget(getTargetESVersion()),
16107ac75b1Sopenharmony_ci    'baseUrl': basePath,
16207ac75b1Sopenharmony_ci    'paths': {
16307ac75b1Sopenharmony_ci      '*': allPath
16407ac75b1Sopenharmony_ci    },
16507ac75b1Sopenharmony_ci    'lib': convertConfigLib(getTargetESVersionLib()),
16607ac75b1Sopenharmony_ci    'types': projectConfig.compilerTypes,
16707ac75b1Sopenharmony_ci    'etsLoaderPath': projectConfig.etsLoaderPath,
16807ac75b1Sopenharmony_ci    'needDoArkTsLinter': getArkTSLinterMode() !== ArkTSLinterMode.NOT_USE,
16907ac75b1Sopenharmony_ci    'isCompatibleVersion': getArkTSLinterMode() === ArkTSLinterMode.COMPATIBLE_MODE,
17007ac75b1Sopenharmony_ci    'skipTscOhModuleCheck': partialUpdateConfig.skipTscOhModuleCheck,
17107ac75b1Sopenharmony_ci    'skipArkTSStaticBlocksCheck': partialUpdateConfig.skipArkTSStaticBlocksCheck,
17207ac75b1Sopenharmony_ci    // options incremental && tsBuildInfoFile are required for applying incremental ability of typescript
17307ac75b1Sopenharmony_ci    'incremental': true,
17407ac75b1Sopenharmony_ci    'tsBuildInfoFile': buildInfoPath,
17507ac75b1Sopenharmony_ci    'tsImportSendableEnable': tsImportSendable,
17607ac75b1Sopenharmony_ci    'skipPathsInKeyForCompilationSettings': reuseLanguageServiceForDepChange,
17707ac75b1Sopenharmony_ci    'compatibleSdkVersionStage': projectConfig.compatibleSdkVersionStage,
17807ac75b1Sopenharmony_ci    'compatibleSdkVersion': projectConfig.compatibleSdkVersion
17907ac75b1Sopenharmony_ci  });
18007ac75b1Sopenharmony_ci  if (projectConfig.compileMode === ESMODULE) {
18107ac75b1Sopenharmony_ci    Object.assign(compilerOptions, {
18207ac75b1Sopenharmony_ci      'importsNotUsedAsValues': ts.ImportsNotUsedAsValues.Remove,
18307ac75b1Sopenharmony_ci      'module': ts.ModuleKind.ES2020
18407ac75b1Sopenharmony_ci    });
18507ac75b1Sopenharmony_ci  }
18607ac75b1Sopenharmony_ci  if (projectConfig.packageDir === 'oh_modules') {
18707ac75b1Sopenharmony_ci    Object.assign(compilerOptions, {'packageManagerType': 'ohpm'});
18807ac75b1Sopenharmony_ci  }
18907ac75b1Sopenharmony_ci  readTsBuildInfoFileInCrementalMode(buildInfoPath, projectConfig);
19007ac75b1Sopenharmony_ci}
19107ac75b1Sopenharmony_ci
19207ac75b1Sopenharmony_cifunction checkArkTSVersion(): void {
19307ac75b1Sopenharmony_ci  const etsCheckerLogger = fastBuildLogger || logger;
19407ac75b1Sopenharmony_ci  if (getArkTSVersion() === ArkTSVersion.ArkTS_1_0 && tsImportSendable) {
19507ac75b1Sopenharmony_ci    const logMessage: string = 'ArkTS: ArkTSVersion1.0 does not support tsImportSendable in any condition';
19607ac75b1Sopenharmony_ci    etsCheckerLogger.error('\u001b[31m' + logMessage);
19707ac75b1Sopenharmony_ci    tsImportSendable = false;
19807ac75b1Sopenharmony_ci  }
19907ac75b1Sopenharmony_ci}
20007ac75b1Sopenharmony_ci
20107ac75b1Sopenharmony_ci// Change target to enum's value,e.g: "es2021" => ts.ScriptTarget.ES2021
20207ac75b1Sopenharmony_cifunction convertConfigTarget(target: number | string): number | string {
20307ac75b1Sopenharmony_ci  if ((typeof target === 'number') && (target in ts.ScriptTarget)) {
20407ac75b1Sopenharmony_ci    return target;
20507ac75b1Sopenharmony_ci  }
20607ac75b1Sopenharmony_ci  return ts.convertCompilerOptionsFromJson({ 'target': target }, '').options.target;
20707ac75b1Sopenharmony_ci}
20807ac75b1Sopenharmony_ci
20907ac75b1Sopenharmony_ci// Change lib to libMap's value,e.g: "es2021" => "lib.es2021.d.ts"
21007ac75b1Sopenharmony_cifunction convertConfigLib(libs: string[]): string[] {
21107ac75b1Sopenharmony_ci  let converted: boolean = true;
21207ac75b1Sopenharmony_ci  let libMapValues: string[] = Array.from(ts.libMap.values());
21307ac75b1Sopenharmony_ci  for (let i = 0; i < libs.length; i++) {
21407ac75b1Sopenharmony_ci    if (!libMapValues.includes(libs[i])) {
21507ac75b1Sopenharmony_ci      converted = false;
21607ac75b1Sopenharmony_ci      break;
21707ac75b1Sopenharmony_ci    }
21807ac75b1Sopenharmony_ci  }
21907ac75b1Sopenharmony_ci  if (converted) {
22007ac75b1Sopenharmony_ci    return libs;
22107ac75b1Sopenharmony_ci  }
22207ac75b1Sopenharmony_ci  return ts.convertCompilerOptionsFromJson({ 'lib': libs }, '').options.lib;
22307ac75b1Sopenharmony_ci}
22407ac75b1Sopenharmony_ci
22507ac75b1Sopenharmony_ci/**
22607ac75b1Sopenharmony_ci * Read the source code information in the project of the last compilation process, and then use it
22707ac75b1Sopenharmony_ci * to determine whether the file has been modified during this compilation process.
22807ac75b1Sopenharmony_ci */
22907ac75b1Sopenharmony_cifunction readTsBuildInfoFileInCrementalMode(buildInfoPath: string, projectConfig: Object): void {
23007ac75b1Sopenharmony_ci  if (!fs.existsSync(buildInfoPath) || !(projectConfig.compileHar || projectConfig.compileShared)) {
23107ac75b1Sopenharmony_ci    return;
23207ac75b1Sopenharmony_ci  }
23307ac75b1Sopenharmony_ci
23407ac75b1Sopenharmony_ci  type FileInfoType = {
23507ac75b1Sopenharmony_ci    version: string;
23607ac75b1Sopenharmony_ci    affectsGlobalScope: boolean;
23707ac75b1Sopenharmony_ci  };
23807ac75b1Sopenharmony_ci  type ProgramType = {
23907ac75b1Sopenharmony_ci    fileNames: string[];
24007ac75b1Sopenharmony_ci    fileInfos: (FileInfoType | string)[];
24107ac75b1Sopenharmony_ci  };
24207ac75b1Sopenharmony_ci  let buildInfoProgram: ProgramType;
24307ac75b1Sopenharmony_ci  try {
24407ac75b1Sopenharmony_ci    const content: {program: ProgramType} = JSON.parse(fs.readFileSync(buildInfoPath, 'utf-8'));
24507ac75b1Sopenharmony_ci    buildInfoProgram = content.program;
24607ac75b1Sopenharmony_ci    if (!buildInfoProgram || !buildInfoProgram.fileNames || !buildInfoProgram.fileInfos) {
24707ac75b1Sopenharmony_ci      throw new Error('.tsbuildinfo content is invalid');
24807ac75b1Sopenharmony_ci    }
24907ac75b1Sopenharmony_ci  } catch (err) {
25007ac75b1Sopenharmony_ci    fastBuildLogger.warn('\u001b[33m' + 'ArkTS: Failed to parse .tsbuildinfo file. Error message: ' + err.message.toString());
25107ac75b1Sopenharmony_ci    return;
25207ac75b1Sopenharmony_ci  }
25307ac75b1Sopenharmony_ci  const buildInfoDirectory: string = path.dirname(buildInfoPath);
25407ac75b1Sopenharmony_ci  /**
25507ac75b1Sopenharmony_ci   * For the windos and mac platform, the file path in tsbuildinfo is in lowercase, while buildInfoDirectory is the original path (including uppercase).
25607ac75b1Sopenharmony_ci   * Therefore, the path needs to be converted to lowercase, and then perform path comparison.
25707ac75b1Sopenharmony_ci   */
25807ac75b1Sopenharmony_ci  const isMacOrWin = isWindows() || isMac();
25907ac75b1Sopenharmony_ci  const fileNames: string[] = buildInfoProgram.fileNames;
26007ac75b1Sopenharmony_ci  const fileInfos: (FileInfoType | string)[] = buildInfoProgram.fileInfos;
26107ac75b1Sopenharmony_ci  fileInfos.forEach((fileInfo, index) => {
26207ac75b1Sopenharmony_ci    const version: string = typeof fileInfo === 'string' ? fileInfo : fileInfo.version;
26307ac75b1Sopenharmony_ci    const absPath: string = path.resolve(buildInfoDirectory, fileNames[index]);
26407ac75b1Sopenharmony_ci    filesBuildInfo.set(isMacOrWin ? tryToLowerCasePath(absPath) : absPath, version);
26507ac75b1Sopenharmony_ci  });
26607ac75b1Sopenharmony_ci}
26707ac75b1Sopenharmony_ci
26807ac75b1Sopenharmony_ciinterface extendInfo {
26907ac75b1Sopenharmony_ci  start: number,
27007ac75b1Sopenharmony_ci  end: number,
27107ac75b1Sopenharmony_ci  compName: string
27207ac75b1Sopenharmony_ci}
27307ac75b1Sopenharmony_ci
27407ac75b1Sopenharmony_cifunction createHash(str: string): string {
27507ac75b1Sopenharmony_ci  const hash = crypto.createHash('sha256');
27607ac75b1Sopenharmony_ci  hash.update(str);
27707ac75b1Sopenharmony_ci  return hash.digest('hex');
27807ac75b1Sopenharmony_ci}
27907ac75b1Sopenharmony_ci
28007ac75b1Sopenharmony_ciexport const fileHashScriptVersion: (fileName: string) => string = (fileName: string) => {
28107ac75b1Sopenharmony_ci  if (!fs.existsSync(fileName)) {
28207ac75b1Sopenharmony_ci    return '0';
28307ac75b1Sopenharmony_ci  }
28407ac75b1Sopenharmony_ci
28507ac75b1Sopenharmony_ci  let fileContent: string = fs.readFileSync(fileName).toString();
28607ac75b1Sopenharmony_ci  let cacheInfo: CacheFileName = cache[path.resolve(fileName)];
28707ac75b1Sopenharmony_ci
28807ac75b1Sopenharmony_ci  // Error code corresponding to message `Cannot find module xx or its corresponding type declarations`
28907ac75b1Sopenharmony_ci  const errorCodeRequireRecheck: number = 2307;
29007ac75b1Sopenharmony_ci
29107ac75b1Sopenharmony_ci  if (cacheInfo && cacheInfo.error === true && cacheInfo.errorCodes && cacheInfo.errorCodes.includes(errorCodeRequireRecheck)) {
29207ac75b1Sopenharmony_ci    // If this file had errors that require recheck in the last compilation,
29307ac75b1Sopenharmony_ci    // mark the file as modified by modifying its hash value, thereby triggering tsc to recheck.
29407ac75b1Sopenharmony_ci    fileContent += Date.now().toString();
29507ac75b1Sopenharmony_ci  }
29607ac75b1Sopenharmony_ci  return createHash(fileContent);
29707ac75b1Sopenharmony_ci};
29807ac75b1Sopenharmony_ci
29907ac75b1Sopenharmony_ci// Reuse the last language service when dependency in oh-package.json5 changes to enhance performance in incremental building.
30007ac75b1Sopenharmony_ci// Setting this to false will create a new language service on dependency changes, like a full rebuild.
30107ac75b1Sopenharmony_ciconst reuseLanguageServiceForDepChange: boolean = true;
30207ac75b1Sopenharmony_ci// When dependency changes and reusing the last language service, enable this flag to recheck code dependent on those dependencies.
30307ac75b1Sopenharmony_ciexport let needReCheckForChangedDepUsers: boolean = false;
30407ac75b1Sopenharmony_ci
30507ac75b1Sopenharmony_ciexport function createLanguageService(rootFileNames: string[], resolveModulePaths: string[],
30607ac75b1Sopenharmony_ci  compilationTime: CompilationTimeStatistics = null, rollupShareObject?: any): ts.LanguageService {
30707ac75b1Sopenharmony_ci  setCompilerOptions(resolveModulePaths);
30807ac75b1Sopenharmony_ci  const servicesHost: ts.LanguageServiceHost = {
30907ac75b1Sopenharmony_ci    getScriptFileNames: () => [...rootFileNames, ...readDeaclareFiles()],
31007ac75b1Sopenharmony_ci    getScriptVersion: fileHashScriptVersion,
31107ac75b1Sopenharmony_ci    getScriptSnapshot: function(fileName) {
31207ac75b1Sopenharmony_ci      if (!fs.existsSync(fileName)) {
31307ac75b1Sopenharmony_ci        return undefined;
31407ac75b1Sopenharmony_ci      }
31507ac75b1Sopenharmony_ci      if (/(?<!\.d)\.(ets|ts)$/.test(fileName)) {
31607ac75b1Sopenharmony_ci        startTimeStatisticsLocation(compilationTime ? compilationTime.scriptSnapshotTime : undefined);
31707ac75b1Sopenharmony_ci        appComponentCollection.set(path.join(fileName), new Set());
31807ac75b1Sopenharmony_ci        let content: string = processContent(fs.readFileSync(fileName).toString(), fileName);
31907ac75b1Sopenharmony_ci        const extendFunctionInfo: extendInfo[] = [];
32007ac75b1Sopenharmony_ci        content = instanceInsteadThis(content, fileName, extendFunctionInfo, this.uiProps);
32107ac75b1Sopenharmony_ci        stopTimeStatisticsLocation(compilationTime ? compilationTime.scriptSnapshotTime : undefined);
32207ac75b1Sopenharmony_ci        return ts.ScriptSnapshot.fromString(content);
32307ac75b1Sopenharmony_ci      }
32407ac75b1Sopenharmony_ci      return ts.ScriptSnapshot.fromString(fs.readFileSync(fileName).toString());
32507ac75b1Sopenharmony_ci    },
32607ac75b1Sopenharmony_ci    getCurrentDirectory: () => process.cwd(),
32707ac75b1Sopenharmony_ci    getCompilationSettings: () => compilerOptions,
32807ac75b1Sopenharmony_ci    getDefaultLibFileName: options => ts.getDefaultLibFilePath(options),
32907ac75b1Sopenharmony_ci    fileExists: ts.sys.fileExists,
33007ac75b1Sopenharmony_ci    readFile: ts.sys.readFile,
33107ac75b1Sopenharmony_ci    readDirectory: ts.sys.readDirectory,
33207ac75b1Sopenharmony_ci    resolveModuleNames: resolveModuleNames,
33307ac75b1Sopenharmony_ci    resolveTypeReferenceDirectives: resolveTypeReferenceDirectives,
33407ac75b1Sopenharmony_ci    directoryExists: ts.sys.directoryExists,
33507ac75b1Sopenharmony_ci    getDirectories: ts.sys.getDirectories,
33607ac75b1Sopenharmony_ci    getJsDocNodeCheckedConfig: (fileCheckedInfo: ts.FileCheckModuleInfo, sourceFileName: string) => {
33707ac75b1Sopenharmony_ci      return getJsDocNodeCheckConfig(fileCheckedInfo.currentFileName, sourceFileName);
33807ac75b1Sopenharmony_ci    },
33907ac75b1Sopenharmony_ci    getFileCheckedModuleInfo: (containFilePath: string) => {
34007ac75b1Sopenharmony_ci      return {
34107ac75b1Sopenharmony_ci        fileNeedCheck: true,
34207ac75b1Sopenharmony_ci        checkPayload: undefined,
34307ac75b1Sopenharmony_ci        currentFileName: containFilePath
34407ac75b1Sopenharmony_ci      };
34507ac75b1Sopenharmony_ci    },
34607ac75b1Sopenharmony_ci    getJsDocNodeConditionCheckedResult: (jsDocFileCheckedInfo: ts.FileCheckModuleInfo, jsDocs: ts.JsDocTagInfo[]) => {
34707ac75b1Sopenharmony_ci      return getJsDocNodeConditionCheckResult(jsDocFileCheckedInfo, jsDocs);
34807ac75b1Sopenharmony_ci    },
34907ac75b1Sopenharmony_ci    uiProps: [],
35007ac75b1Sopenharmony_ci    clearProps: function() {
35107ac75b1Sopenharmony_ci      dollarCollection.clear();
35207ac75b1Sopenharmony_ci      extendCollection.clear();
35307ac75b1Sopenharmony_ci      this.uiProps.length = 0;
35407ac75b1Sopenharmony_ci    },
35507ac75b1Sopenharmony_ci    // TSC will re-do resolution if this callback return true.
35607ac75b1Sopenharmony_ci    hasInvalidatedResolutions: (filePath: string): boolean => {
35707ac75b1Sopenharmony_ci      return reuseLanguageServiceForDepChange && needReCheckForChangedDepUsers;
35807ac75b1Sopenharmony_ci    }
35907ac75b1Sopenharmony_ci  };
36007ac75b1Sopenharmony_ci
36107ac75b1Sopenharmony_ci  if (process.env.watchMode === 'true') {
36207ac75b1Sopenharmony_ci    return ts.createLanguageService(servicesHost, ts.createDocumentRegistry());
36307ac75b1Sopenharmony_ci  }
36407ac75b1Sopenharmony_ci
36507ac75b1Sopenharmony_ci  return getOrCreateLanguageService(servicesHost, rootFileNames, rollupShareObject);
36607ac75b1Sopenharmony_ci}
36707ac75b1Sopenharmony_ci
36807ac75b1Sopenharmony_ciexport let targetESVersionChanged: boolean = false;
36907ac75b1Sopenharmony_ci
37007ac75b1Sopenharmony_cifunction getOrCreateLanguageService(servicesHost: ts.LanguageServiceHost, rootFileNames: string[],
37107ac75b1Sopenharmony_ci  rollupShareObject?: any): ts.LanguageService {
37207ac75b1Sopenharmony_ci  let cacheKey: string = 'service';
37307ac75b1Sopenharmony_ci  let cache: LanguageServiceCache | undefined = getRollupCache(rollupShareObject, projectConfig, cacheKey);
37407ac75b1Sopenharmony_ci
37507ac75b1Sopenharmony_ci  let service: ts.LanguageService | undefined = cache?.service;
37607ac75b1Sopenharmony_ci  const currentHash: string | undefined = rollupShareObject?.projectConfig?.pkgJsonFileHash;
37707ac75b1Sopenharmony_ci  const currentTargetESVersion: ts.ScriptTarget = compilerOptions.target;
37807ac75b1Sopenharmony_ci  const lastHash: string | undefined = cache?.pkgJsonFileHash;
37907ac75b1Sopenharmony_ci  const lastTargetESVersion: ts.ScriptTarget | undefined = cache?.targetESVersion;
38007ac75b1Sopenharmony_ci  const hashDiffers: boolean | undefined = currentHash && lastHash && currentHash !== lastHash;
38107ac75b1Sopenharmony_ci  const shouldRebuildForDepDiffers: boolean | undefined = reuseLanguageServiceForDepChange ?
38207ac75b1Sopenharmony_ci    (hashDiffers && !rollupShareObject?.depInfo?.enableIncre) : hashDiffers;
38307ac75b1Sopenharmony_ci  const targetESVersionDiffers: boolean | undefined = lastTargetESVersion && currentTargetESVersion && lastTargetESVersion !== currentTargetESVersion;
38407ac75b1Sopenharmony_ci  const tsImportSendableDiff: boolean = (cache?.preTsImportSendable === undefined && !tsImportSendable) ?
38507ac75b1Sopenharmony_ci    false :
38607ac75b1Sopenharmony_ci    cache?.preTsImportSendable !== tsImportSendable;
38707ac75b1Sopenharmony_ci  const shouldRebuild: boolean | undefined = shouldRebuildForDepDiffers || targetESVersionDiffers || tsImportSendableDiff;
38807ac75b1Sopenharmony_ci  if (reuseLanguageServiceForDepChange && hashDiffers && rollupShareObject?.depInfo?.enableIncre) {
38907ac75b1Sopenharmony_ci    needReCheckForChangedDepUsers = true;
39007ac75b1Sopenharmony_ci  }
39107ac75b1Sopenharmony_ci
39207ac75b1Sopenharmony_ci  if (!service || shouldRebuild) {
39307ac75b1Sopenharmony_ci    rebuiuldProgram(targetESVersionDiffers, tsImportSendableDiff);
39407ac75b1Sopenharmony_ci    service = ts.createLanguageService(servicesHost, ts.createDocumentRegistry());
39507ac75b1Sopenharmony_ci  } else {
39607ac75b1Sopenharmony_ci    // Found language service from cache, update root files
39707ac75b1Sopenharmony_ci    const updateRootFileNames = [...rootFileNames, ...readDeaclareFiles()];
39807ac75b1Sopenharmony_ci    service.updateRootFiles(updateRootFileNames);
39907ac75b1Sopenharmony_ci  }
40007ac75b1Sopenharmony_ci
40107ac75b1Sopenharmony_ci  const newCache: LanguageServiceCache = {
40207ac75b1Sopenharmony_ci    service: service,
40307ac75b1Sopenharmony_ci    pkgJsonFileHash: currentHash,
40407ac75b1Sopenharmony_ci    targetESVersion: currentTargetESVersion,
40507ac75b1Sopenharmony_ci    preTsImportSendable: tsImportSendable
40607ac75b1Sopenharmony_ci  };
40707ac75b1Sopenharmony_ci  setRollupCache(rollupShareObject, projectConfig, cacheKey, newCache);
40807ac75b1Sopenharmony_ci  return service;
40907ac75b1Sopenharmony_ci}
41007ac75b1Sopenharmony_ci
41107ac75b1Sopenharmony_cifunction rebuiuldProgram(targetESVersionDiffers: boolean | undefined, tsImportSendableDiff: boolean): void {
41207ac75b1Sopenharmony_ci  if (targetESVersionDiffers) {
41307ac75b1Sopenharmony_ci    // If the targetESVersion is changed, we need to delete the build info cahce files
41407ac75b1Sopenharmony_ci    deleteBuildInfoCache(compilerOptions.tsBuildInfoFile);
41507ac75b1Sopenharmony_ci    targetESVersionChanged = true;
41607ac75b1Sopenharmony_ci  } else if (tsImportSendableDiff) {
41707ac75b1Sopenharmony_ci    // When tsImportSendable is changed, we need to delete the build info cahce files
41807ac75b1Sopenharmony_ci    deleteBuildInfoCache(compilerOptions.tsBuildInfoFile);
41907ac75b1Sopenharmony_ci  }
42007ac75b1Sopenharmony_ci}
42107ac75b1Sopenharmony_ci
42207ac75b1Sopenharmony_cifunction deleteBuildInfoCache(tsBuildInfoFilePath: string): void {
42307ac75b1Sopenharmony_ci  // The file name of tsBuildInfoLinterFile is '.tsbuildinfo.linter', so we need to add '.linter' after tsBuildInfoFilePath
42407ac75b1Sopenharmony_ci  const tsBuildInfoLinterFilePath: string = tsBuildInfoFilePath + '.linter';
42507ac75b1Sopenharmony_ci  deleteFile(tsBuildInfoFilePath);
42607ac75b1Sopenharmony_ci  deleteFile(tsBuildInfoLinterFilePath);
42707ac75b1Sopenharmony_ci}
42807ac75b1Sopenharmony_ci
42907ac75b1Sopenharmony_cifunction deleteFile(filePath: string): void {
43007ac75b1Sopenharmony_ci  if (fs.existsSync(filePath)) {
43107ac75b1Sopenharmony_ci      fs.unlinkSync(filePath);
43207ac75b1Sopenharmony_ci  }
43307ac75b1Sopenharmony_ci}
43407ac75b1Sopenharmony_ci
43507ac75b1Sopenharmony_ciinterface CacheFileName {
43607ac75b1Sopenharmony_ci  mtimeMs: number,
43707ac75b1Sopenharmony_ci  children: string[],
43807ac75b1Sopenharmony_ci  parent: string[],
43907ac75b1Sopenharmony_ci  error: boolean,
44007ac75b1Sopenharmony_ci  errorCodes?: number[]
44107ac75b1Sopenharmony_ci}
44207ac75b1Sopenharmony_ciinterface NeedUpdateFlag {
44307ac75b1Sopenharmony_ci  flag: boolean;
44407ac75b1Sopenharmony_ci}
44507ac75b1Sopenharmony_ciinterface CheckerResult {
44607ac75b1Sopenharmony_ci  count: number
44707ac75b1Sopenharmony_ci}
44807ac75b1Sopenharmony_ci
44907ac75b1Sopenharmony_ciinterface WarnCheckerResult {
45007ac75b1Sopenharmony_ci  count: number
45107ac75b1Sopenharmony_ci}
45207ac75b1Sopenharmony_ci
45307ac75b1Sopenharmony_ciinterface WholeCache {
45407ac75b1Sopenharmony_ci  runtimeOS: string,
45507ac75b1Sopenharmony_ci  sdkInfo: string,
45607ac75b1Sopenharmony_ci  fileList: Cache
45707ac75b1Sopenharmony_ci}
45807ac75b1Sopenharmony_citype Cache = Record<string, CacheFileName>;
45907ac75b1Sopenharmony_ciexport let cache: Cache = {};
46007ac75b1Sopenharmony_ciexport const hotReloadSupportFiles: Set<string> = new Set();
46107ac75b1Sopenharmony_ciexport const shouldResolvedFiles: Set<string> = new Set();
46207ac75b1Sopenharmony_ciexport const appComponentCollection: Map<string, Set<string>> = new Map();
46307ac75b1Sopenharmony_ciconst allResolvedModules: Set<string> = new Set();
46407ac75b1Sopenharmony_ci// all files of tsc and rollup for obfuscation scanning.
46507ac75b1Sopenharmony_ciexport const allSourceFilePaths: Set<string> = new Set();
46607ac75b1Sopenharmony_ci// Used to collect file paths that have not been converted toUnixPath.
46707ac75b1Sopenharmony_ciexport const allModuleIds: Set<string> = new Set();
46807ac75b1Sopenharmony_ciexport let props: string[] = [];
46907ac75b1Sopenharmony_ci
47007ac75b1Sopenharmony_ciexport let fastBuildLogger = null;
47107ac75b1Sopenharmony_ci
47207ac75b1Sopenharmony_ciexport const checkerResult: CheckerResult = { count: 0 };
47307ac75b1Sopenharmony_ciexport const warnCheckerResult: WarnCheckerResult = { count: 0 };
47407ac75b1Sopenharmony_ciexport let languageService: ts.LanguageService = null;
47507ac75b1Sopenharmony_cilet tsImportSendable: boolean = false;
47607ac75b1Sopenharmony_ciexport function serviceChecker(rootFileNames: string[], newLogger: Object = null, resolveModulePaths: string[] = null,
47707ac75b1Sopenharmony_ci  compilationTime: CompilationTimeStatistics = null, rollupShareObject?: Object): void {
47807ac75b1Sopenharmony_ci  fastBuildLogger = newLogger;
47907ac75b1Sopenharmony_ci  let cacheFile: string = null;
48007ac75b1Sopenharmony_ci  tsImportSendable = rollupShareObject?.projectConfig.tsImportSendable;
48107ac75b1Sopenharmony_ci  if (projectConfig.xtsMode || process.env.watchMode === 'true') {
48207ac75b1Sopenharmony_ci    if (projectConfig.hotReload) {
48307ac75b1Sopenharmony_ci      rootFileNames.forEach(fileName => {
48407ac75b1Sopenharmony_ci        hotReloadSupportFiles.add(fileName);
48507ac75b1Sopenharmony_ci      });
48607ac75b1Sopenharmony_ci    }
48707ac75b1Sopenharmony_ci    languageService = createLanguageService(rootFileNames, resolveModulePaths, compilationTime);
48807ac75b1Sopenharmony_ci    props = languageService.getProps();
48907ac75b1Sopenharmony_ci  } else {
49007ac75b1Sopenharmony_ci    cacheFile = path.resolve(projectConfig.cachePath, '../.ts_checker_cache');
49107ac75b1Sopenharmony_ci    const [isJsonObject, cacheJsonObject]: [boolean, WholeCache | undefined] = isJsonString(cacheFile);
49207ac75b1Sopenharmony_ci    const wholeCache: WholeCache = isJsonObject ? cacheJsonObject : { 'runtimeOS': projectConfig.runtimeOS, 'sdkInfo': projectConfig.sdkInfo, 'fileList': {} };
49307ac75b1Sopenharmony_ci    if (wholeCache.runtimeOS === projectConfig.runtimeOS && wholeCache.sdkInfo === projectConfig.sdkInfo) {
49407ac75b1Sopenharmony_ci      cache = wholeCache.fileList;
49507ac75b1Sopenharmony_ci    } else {
49607ac75b1Sopenharmony_ci      cache = {};
49707ac75b1Sopenharmony_ci    }
49807ac75b1Sopenharmony_ci    languageService = createLanguageService(rootFileNames, resolveModulePaths, compilationTime, rollupShareObject);
49907ac75b1Sopenharmony_ci  }
50007ac75b1Sopenharmony_ci
50107ac75b1Sopenharmony_ci  const timePrinterInstance = ts.ArkTSLinterTimePrinter.getInstance();
50207ac75b1Sopenharmony_ci  timePrinterInstance.setArkTSTimePrintSwitch(false);
50307ac75b1Sopenharmony_ci  timePrinterInstance.appendTime(ts.TimePhase.START);
50407ac75b1Sopenharmony_ci  startTimeStatisticsLocation(compilationTime ? compilationTime.createProgramTime : undefined);
50507ac75b1Sopenharmony_ci
50607ac75b1Sopenharmony_ci  globalProgram.builderProgram = languageService.getBuilderProgram(/*withLinterProgram*/ true);
50707ac75b1Sopenharmony_ci  globalProgram.program = globalProgram.builderProgram.getProgram();
50807ac75b1Sopenharmony_ci  props = languageService.getProps();
50907ac75b1Sopenharmony_ci  timePrinterInstance.appendTime(ts.TimePhase.GET_PROGRAM);
51007ac75b1Sopenharmony_ci  stopTimeStatisticsLocation(compilationTime ? compilationTime.createProgramTime : undefined);
51107ac75b1Sopenharmony_ci
51207ac75b1Sopenharmony_ci  collectAllFiles(globalProgram.program, undefined, undefined, rollupShareObject);
51307ac75b1Sopenharmony_ci  collectFileToIgnoreDiagnostics(rootFileNames);
51407ac75b1Sopenharmony_ci  startTimeStatisticsLocation(compilationTime ? compilationTime.runArkTSLinterTime : undefined);
51507ac75b1Sopenharmony_ci  runArkTSLinter();
51607ac75b1Sopenharmony_ci  stopTimeStatisticsLocation(compilationTime ? compilationTime.runArkTSLinterTime : undefined);
51707ac75b1Sopenharmony_ci
51807ac75b1Sopenharmony_ci  if (process.env.watchMode !== 'true') {
51907ac75b1Sopenharmony_ci    processBuildHap(cacheFile, rootFileNames, compilationTime, rollupShareObject);
52007ac75b1Sopenharmony_ci  }
52107ac75b1Sopenharmony_ci}
52207ac75b1Sopenharmony_ci
52307ac75b1Sopenharmony_cifunction isJsonString(cacheFile: string): [boolean, WholeCache | undefined] {
52407ac75b1Sopenharmony_ci  if (fs.existsSync(cacheFile)) {
52507ac75b1Sopenharmony_ci    try {
52607ac75b1Sopenharmony_ci      return [true, JSON.parse(fs.readFileSync(cacheFile).toString())];
52707ac75b1Sopenharmony_ci    } catch (e) {
52807ac75b1Sopenharmony_ci      return [false, undefined];
52907ac75b1Sopenharmony_ci    }
53007ac75b1Sopenharmony_ci  } else {
53107ac75b1Sopenharmony_ci    return [false, undefined];
53207ac75b1Sopenharmony_ci  }
53307ac75b1Sopenharmony_ci}
53407ac75b1Sopenharmony_ci
53507ac75b1Sopenharmony_ci// collect the compiled files of tsc and rollup for obfuscation scanning.
53607ac75b1Sopenharmony_ciexport function collectAllFiles(program?: ts.Program, rollupFileList?: IterableIterator<string>,
53707ac75b1Sopenharmony_ci  rollupObject?: Object, rollupShareObject: Object = null): void {
53807ac75b1Sopenharmony_ci  if (program) {
53907ac75b1Sopenharmony_ci    collectTscFiles(program, rollupShareObject);
54007ac75b1Sopenharmony_ci    return;
54107ac75b1Sopenharmony_ci  }
54207ac75b1Sopenharmony_ci  mergeRollUpFiles(rollupFileList, rollupObject);
54307ac75b1Sopenharmony_ci}
54407ac75b1Sopenharmony_ci
54507ac75b1Sopenharmony_ciexport function collectTscFiles(program: ts.Program, rollupShareObject: Object = null): void {
54607ac75b1Sopenharmony_ci  const programAllFiles: readonly ts.SourceFile[] = program.getSourceFiles();
54707ac75b1Sopenharmony_ci  let projectRootPath: string = projectConfig.projectRootPath;
54807ac75b1Sopenharmony_ci  if (!projectRootPath) {
54907ac75b1Sopenharmony_ci    return;
55007ac75b1Sopenharmony_ci  }
55107ac75b1Sopenharmony_ci  projectRootPath = toUnixPath(projectRootPath);
55207ac75b1Sopenharmony_ci  const isMacOrWin = isWindows() || isMac();
55307ac75b1Sopenharmony_ci  programAllFiles.forEach(sourceFile => {
55407ac75b1Sopenharmony_ci    const fileName = toUnixPath(sourceFile.fileName);
55507ac75b1Sopenharmony_ci    // @ts-ignore
55607ac75b1Sopenharmony_ci    sourceFileDependencies.set(fileName, sourceFile.resolvedModules);
55707ac75b1Sopenharmony_ci    if (!(fileName.startsWith(projectRootPath + '/') || isOtherProjectResolvedModulesFilePaths(rollupShareObject, fileName))) {
55807ac75b1Sopenharmony_ci      return;
55907ac75b1Sopenharmony_ci    }
56007ac75b1Sopenharmony_ci    allSourceFilePaths.add(fileName);
56107ac75b1Sopenharmony_ci    allModuleIds.add(sourceFile.fileName);
56207ac75b1Sopenharmony_ci    // For the windos and mac platform, the file path in filesBuildInfo is in lowercase,
56307ac75b1Sopenharmony_ci    // while fileName of sourceFile is the original path (including uppercase).
56407ac75b1Sopenharmony_ci    if (filesBuildInfo.size > 0 &&
56507ac75b1Sopenharmony_ci      Reflect.get(sourceFile, 'version') !== filesBuildInfo.get(isMacOrWin ? tryToLowerCasePath(fileName) : fileName)) {
56607ac75b1Sopenharmony_ci      allResolvedModules.add(fileName);
56707ac75b1Sopenharmony_ci    }
56807ac75b1Sopenharmony_ci  });
56907ac75b1Sopenharmony_ci}
57007ac75b1Sopenharmony_ci
57107ac75b1Sopenharmony_cifunction isOtherProjectResolvedModulesFilePaths(rollupShareObject: Object, fileName: string): boolean {
57207ac75b1Sopenharmony_ci  if (!!rollupShareObject && rollupShareObject.projectConfig && !!rollupShareObject.projectConfig.rootPathSet) {
57307ac75b1Sopenharmony_ci    const rootPathSet: string[] | Set<string> = rollupShareObject.projectConfig.rootPathSet;
57407ac75b1Sopenharmony_ci    if (Array.isArray(rootPathSet)) {
57507ac75b1Sopenharmony_ci      for (let i = 0; i < rootPathSet.length; i++) {
57607ac75b1Sopenharmony_ci        const pathNormalization: string = toUnixPath(rootPathSet[i]) + '/';
57707ac75b1Sopenharmony_ci        if (fileName.startsWith(pathNormalization)) {
57807ac75b1Sopenharmony_ci          return true;
57907ac75b1Sopenharmony_ci        }
58007ac75b1Sopenharmony_ci      }
58107ac75b1Sopenharmony_ci    } else {
58207ac75b1Sopenharmony_ci      return false;
58307ac75b1Sopenharmony_ci    }
58407ac75b1Sopenharmony_ci  }
58507ac75b1Sopenharmony_ci  return false;
58607ac75b1Sopenharmony_ci}
58707ac75b1Sopenharmony_ci
58807ac75b1Sopenharmony_ciexport function mergeRollUpFiles(rollupFileList: IterableIterator<string>, rollupObject: Object) {
58907ac75b1Sopenharmony_ci  for (const moduleId of rollupFileList) {
59007ac75b1Sopenharmony_ci    if (fs.existsSync(moduleId)) {
59107ac75b1Sopenharmony_ci      allSourceFilePaths.add(toUnixPath(moduleId));
59207ac75b1Sopenharmony_ci      allModuleIds.add(moduleId);
59307ac75b1Sopenharmony_ci      addLocalPackageSet(moduleId, rollupObject);
59407ac75b1Sopenharmony_ci    }
59507ac75b1Sopenharmony_ci  }
59607ac75b1Sopenharmony_ci}
59707ac75b1Sopenharmony_ci
59807ac75b1Sopenharmony_ci// collect the modulename or pkgname of all local modules.
59907ac75b1Sopenharmony_ciexport function addLocalPackageSet(moduleId: string, rollupObject: Object): void {
60007ac75b1Sopenharmony_ci  const moduleInfo: Object = rollupObject.getModuleInfo(moduleId);
60107ac75b1Sopenharmony_ci  const metaInfo: Object = moduleInfo.meta;
60207ac75b1Sopenharmony_ci  if (metaInfo.isLocalDependency) {
60307ac75b1Sopenharmony_ci    if (projectConfig.useNormalizedOHMUrl && metaInfo.pkgName) {
60407ac75b1Sopenharmony_ci      localPackageSet.add(metaInfo.pkgName);
60507ac75b1Sopenharmony_ci    }
60607ac75b1Sopenharmony_ci    if (!projectConfig.useNormalizedOHMUrl && metaInfo.moduleName) {
60707ac75b1Sopenharmony_ci      localPackageSet.add(metaInfo.moduleName);
60807ac75b1Sopenharmony_ci    }
60907ac75b1Sopenharmony_ci  }
61007ac75b1Sopenharmony_ci}
61107ac75b1Sopenharmony_ci
61207ac75b1Sopenharmony_ciexport function emitBuildInfo(): void {
61307ac75b1Sopenharmony_ci  globalProgram.builderProgram.emitBuildInfo(buildInfoWriteFile);
61407ac75b1Sopenharmony_ci}
61507ac75b1Sopenharmony_ci
61607ac75b1Sopenharmony_cifunction processBuildHap(cacheFile: string, rootFileNames: string[], compilationTime: CompilationTimeStatistics,
61707ac75b1Sopenharmony_ci  rollupShareObject: Object): void {
61807ac75b1Sopenharmony_ci  startTimeStatisticsLocation(compilationTime ? compilationTime.diagnosticTime : undefined);
61907ac75b1Sopenharmony_ci  const allDiagnostics: ts.Diagnostic[] = globalProgram.builderProgram
62007ac75b1Sopenharmony_ci    .getSyntacticDiagnostics()
62107ac75b1Sopenharmony_ci    .concat(globalProgram.builderProgram.getSemanticDiagnostics());
62207ac75b1Sopenharmony_ci  stopTimeStatisticsLocation(compilationTime ? compilationTime.diagnosticTime : undefined);
62307ac75b1Sopenharmony_ci  emitBuildInfo();
62407ac75b1Sopenharmony_ci  allDiagnostics.forEach((diagnostic: ts.Diagnostic) => {
62507ac75b1Sopenharmony_ci    printDiagnostic(diagnostic);
62607ac75b1Sopenharmony_ci  });
62707ac75b1Sopenharmony_ci  if (!projectConfig.xtsMode) {
62807ac75b1Sopenharmony_ci    fse.ensureDirSync(projectConfig.cachePath);
62907ac75b1Sopenharmony_ci    fs.writeFileSync(cacheFile, JSON.stringify({
63007ac75b1Sopenharmony_ci      'runtimeOS': projectConfig.runtimeOS,
63107ac75b1Sopenharmony_ci      'sdkInfo': projectConfig.sdkInfo,
63207ac75b1Sopenharmony_ci      'fileList': cache
63307ac75b1Sopenharmony_ci    }, null, 2));
63407ac75b1Sopenharmony_ci  }
63507ac75b1Sopenharmony_ci  if (projectConfig.compileHar || projectConfig.compileShared) {
63607ac75b1Sopenharmony_ci    let emit: string | undefined = undefined;
63707ac75b1Sopenharmony_ci    let writeFile = (fileName: string, text: string, writeByteOrderMark: boolean): void => {
63807ac75b1Sopenharmony_ci      emit = text;
63907ac75b1Sopenharmony_ci    };
64007ac75b1Sopenharmony_ci    [...allResolvedModules, ...rootFileNames].forEach(moduleFile => {
64107ac75b1Sopenharmony_ci      if (!(moduleFile.match(new RegExp(projectConfig.packageDir)) && projectConfig.compileHar)) {
64207ac75b1Sopenharmony_ci        try {
64307ac75b1Sopenharmony_ci          if ((/\.d\.e?ts$/).test(moduleFile)) {
64407ac75b1Sopenharmony_ci            generateSourceFilesInHar(moduleFile, fs.readFileSync(moduleFile, 'utf-8'), path.extname(moduleFile),
64507ac75b1Sopenharmony_ci              projectConfig, projectConfig.modulePathMap);
64607ac75b1Sopenharmony_ci          } else if ((/\.e?ts$/).test(moduleFile)) {
64707ac75b1Sopenharmony_ci            emit = undefined;
64807ac75b1Sopenharmony_ci            let sourcefile = globalProgram.program.getSourceFile(moduleFile);
64907ac75b1Sopenharmony_ci            if (sourcefile) {
65007ac75b1Sopenharmony_ci              globalProgram.program.emit(sourcefile, writeFile, undefined, true, undefined, true);
65107ac75b1Sopenharmony_ci            }
65207ac75b1Sopenharmony_ci            if (emit) {
65307ac75b1Sopenharmony_ci              generateSourceFilesInHar(moduleFile, emit, '.d' + path.extname(moduleFile), projectConfig, projectConfig.modulePathMap);
65407ac75b1Sopenharmony_ci            }
65507ac75b1Sopenharmony_ci          }
65607ac75b1Sopenharmony_ci        } catch (err) { }
65707ac75b1Sopenharmony_ci      }
65807ac75b1Sopenharmony_ci    });
65907ac75b1Sopenharmony_ci    printDeclarationDiagnostics();
66007ac75b1Sopenharmony_ci  }
66107ac75b1Sopenharmony_ci}
66207ac75b1Sopenharmony_ci
66307ac75b1Sopenharmony_cifunction printDeclarationDiagnostics(): void {
66407ac75b1Sopenharmony_ci  globalProgram.builderProgram.getDeclarationDiagnostics().forEach((diagnostic: ts.Diagnostic) => {
66507ac75b1Sopenharmony_ci    printDiagnostic(diagnostic);
66607ac75b1Sopenharmony_ci  });
66707ac75b1Sopenharmony_ci}
66807ac75b1Sopenharmony_ci
66907ac75b1Sopenharmony_cifunction containFormError(message: string): boolean {
67007ac75b1Sopenharmony_ci  if (/can't support form application./.test(message)) {
67107ac75b1Sopenharmony_ci    return true;
67207ac75b1Sopenharmony_ci  }
67307ac75b1Sopenharmony_ci  return false;
67407ac75b1Sopenharmony_ci}
67507ac75b1Sopenharmony_ci
67607ac75b1Sopenharmony_cilet fileToIgnoreDiagnostics: Set<string> | undefined = undefined;
67707ac75b1Sopenharmony_ci
67807ac75b1Sopenharmony_cifunction collectFileToThrowDiagnostics(file: string, fileToThrowDiagnostics: Set<string>): void {
67907ac75b1Sopenharmony_ci  const normalizedFilePath: string = path.resolve(file);
68007ac75b1Sopenharmony_ci  const unixFilePath: string = toUnixPath(file);
68107ac75b1Sopenharmony_ci  if (fileToThrowDiagnostics.has(unixFilePath)) {
68207ac75b1Sopenharmony_ci    return;
68307ac75b1Sopenharmony_ci  }
68407ac75b1Sopenharmony_ci
68507ac75b1Sopenharmony_ci  fileToThrowDiagnostics.add(unixFilePath);
68607ac75b1Sopenharmony_ci  // Although the cache object filters JavaScript files when collecting dependency relationships, we still include the
68707ac75b1Sopenharmony_ci  // filtering of JavaScript files here to avoid potential omissions.
68807ac75b1Sopenharmony_ci  if ((/\.(c|m)?js$/).test(file) ||
68907ac75b1Sopenharmony_ci    !cache[normalizedFilePath] || cache[normalizedFilePath].children.length === 0) {
69007ac75b1Sopenharmony_ci    return;
69107ac75b1Sopenharmony_ci  }
69207ac75b1Sopenharmony_ci  cache[normalizedFilePath].children.forEach(file => {
69307ac75b1Sopenharmony_ci    collectFileToThrowDiagnostics(file, fileToThrowDiagnostics);
69407ac75b1Sopenharmony_ci  });
69507ac75b1Sopenharmony_ci}
69607ac75b1Sopenharmony_ci
69707ac75b1Sopenharmony_ciexport function collectFileToIgnoreDiagnostics(rootFileNames: string[]): void {
69807ac75b1Sopenharmony_ci  if (getArkTSLinterMode() === ArkTSLinterMode.NOT_USE) {
69907ac75b1Sopenharmony_ci    return;
70007ac75b1Sopenharmony_ci  }
70107ac75b1Sopenharmony_ci
70207ac75b1Sopenharmony_ci  // In watch mode, the `beforeBuild` phase will clear the parent and children fields in the cache. For files that have
70307ac75b1Sopenharmony_ci  // not been modified, the information needs to be restored using the `resolvedModuleNames` variable.
70407ac75b1Sopenharmony_ci  if (process.env.watchMode === 'true') {
70507ac75b1Sopenharmony_ci    for (let [file, resolvedModules] of resolvedModulesCache) {
70607ac75b1Sopenharmony_ci      createOrUpdateCache(resolvedModules, file);
70707ac75b1Sopenharmony_ci    }
70807ac75b1Sopenharmony_ci  }
70907ac75b1Sopenharmony_ci
71007ac75b1Sopenharmony_ci  // With arkts linter enabled, `allowJs` option is set to true, resulting JavaScript files themselves and
71107ac75b1Sopenharmony_ci  // JavaScript-referenced files are included in the tsc program and checking process,
71207ac75b1Sopenharmony_ci  // potentially introducing new errors. For instance, in scenarios where an ets file imports js file imports ts file,
71307ac75b1Sopenharmony_ci  // it’s necessary to filter out errors from ts files.
71407ac75b1Sopenharmony_ci  let fileToThrowDiagnostics: Set<string> = new Set<string>();
71507ac75b1Sopenharmony_ci  rootFileNames.forEach(file => {
71607ac75b1Sopenharmony_ci    if (!(/\.(c|m)?js$/).test(file)) {
71707ac75b1Sopenharmony_ci      collectFileToThrowDiagnostics(file, fileToThrowDiagnostics);
71807ac75b1Sopenharmony_ci    }
71907ac75b1Sopenharmony_ci  });
72007ac75b1Sopenharmony_ci
72107ac75b1Sopenharmony_ci  let resolvedTypeReferenceDirectivesFiles: Set<string> = new Set<string>();
72207ac75b1Sopenharmony_ci  globalProgram.program.getResolvedTypeReferenceDirectives().forEach(
72307ac75b1Sopenharmony_ci    (elem: ts.ResolvedTypeReferenceDirective | undefined) => {
72407ac75b1Sopenharmony_ci      elem && elem.resolvedFileName && resolvedTypeReferenceDirectivesFiles.add(elem.resolvedFileName);
72507ac75b1Sopenharmony_ci  });
72607ac75b1Sopenharmony_ci
72707ac75b1Sopenharmony_ci  fileToIgnoreDiagnostics = new Set<string>();
72807ac75b1Sopenharmony_ci  globalProgram.program.getSourceFiles().forEach(sourceFile => {
72907ac75b1Sopenharmony_ci    // Previous projects had js libraries that were available through SDK, so need to filter js-file in SDK,
73007ac75b1Sopenharmony_ci    // like: hypium library
73107ac75b1Sopenharmony_ci    sourceFile.fileName &&
73207ac75b1Sopenharmony_ci    (!isInSDK(sourceFile.fileName) || (/\.(c|m)?js$/).test(sourceFile.fileName)) &&
73307ac75b1Sopenharmony_ci    !resolvedTypeReferenceDirectivesFiles.has(sourceFile.fileName) &&
73407ac75b1Sopenharmony_ci    fileToIgnoreDiagnostics.add(toUnixPath(sourceFile.fileName));
73507ac75b1Sopenharmony_ci  });
73607ac75b1Sopenharmony_ci
73707ac75b1Sopenharmony_ci  fileToThrowDiagnostics.forEach(file => {
73807ac75b1Sopenharmony_ci    fileToIgnoreDiagnostics.delete(file);
73907ac75b1Sopenharmony_ci  });
74007ac75b1Sopenharmony_ci}
74107ac75b1Sopenharmony_ci
74207ac75b1Sopenharmony_ciexport function printDiagnostic(diagnostic: ts.Diagnostic): void {
74307ac75b1Sopenharmony_ci  if (projectConfig.ignoreWarning) {
74407ac75b1Sopenharmony_ci    return;
74507ac75b1Sopenharmony_ci  }
74607ac75b1Sopenharmony_ci
74707ac75b1Sopenharmony_ci  if (fileToIgnoreDiagnostics && diagnostic.file && diagnostic.file.fileName &&
74807ac75b1Sopenharmony_ci    fileToIgnoreDiagnostics.has(toUnixPath(diagnostic.file.fileName))) {
74907ac75b1Sopenharmony_ci    return;
75007ac75b1Sopenharmony_ci  }
75107ac75b1Sopenharmony_ci
75207ac75b1Sopenharmony_ci  const message: string = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
75307ac75b1Sopenharmony_ci  if (validateError(message)) {
75407ac75b1Sopenharmony_ci    if (process.env.watchMode !== 'true' && !projectConfig.xtsMode) {
75507ac75b1Sopenharmony_ci      updateErrorFileCache(diagnostic);
75607ac75b1Sopenharmony_ci    }
75707ac75b1Sopenharmony_ci
75807ac75b1Sopenharmony_ci    if (containFormError(message) && !isCardFile(diagnostic.file.fileName)) {
75907ac75b1Sopenharmony_ci      return;
76007ac75b1Sopenharmony_ci    }
76107ac75b1Sopenharmony_ci
76207ac75b1Sopenharmony_ci    const logPrefix: string = diagnostic.category === ts.DiagnosticCategory.Error ? 'ERROR' : 'WARN';
76307ac75b1Sopenharmony_ci    const etsCheckerLogger = fastBuildLogger || logger;
76407ac75b1Sopenharmony_ci    let logMessage: string;
76507ac75b1Sopenharmony_ci    if (logPrefix === 'ERROR') {
76607ac75b1Sopenharmony_ci      checkerResult.count += 1;
76707ac75b1Sopenharmony_ci    } else {
76807ac75b1Sopenharmony_ci      warnCheckerResult.count += 1;
76907ac75b1Sopenharmony_ci    }
77007ac75b1Sopenharmony_ci    if (diagnostic.file) {
77107ac75b1Sopenharmony_ci      const { line, character }: ts.LineAndCharacter =
77207ac75b1Sopenharmony_ci        diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
77307ac75b1Sopenharmony_ci      logMessage = `ArkTS:${logPrefix} File: ${diagnostic.file.fileName}:${line + 1}:${character + 1}\n ${message}\n`;
77407ac75b1Sopenharmony_ci    } else {
77507ac75b1Sopenharmony_ci      logMessage = `ArkTS:${logPrefix}: ${message}`;
77607ac75b1Sopenharmony_ci    }
77707ac75b1Sopenharmony_ci
77807ac75b1Sopenharmony_ci    if (diagnostic.category === ts.DiagnosticCategory.Error) {
77907ac75b1Sopenharmony_ci      etsCheckerLogger.error('\u001b[31m' + logMessage);
78007ac75b1Sopenharmony_ci    } else {
78107ac75b1Sopenharmony_ci      etsCheckerLogger.warn('\u001b[33m' + logMessage);
78207ac75b1Sopenharmony_ci    }
78307ac75b1Sopenharmony_ci  }
78407ac75b1Sopenharmony_ci}
78507ac75b1Sopenharmony_ci
78607ac75b1Sopenharmony_cifunction validateError(message: string): boolean {
78707ac75b1Sopenharmony_ci  const propInfoReg: RegExp = /Cannot find name\s*'(\$?\$?[_a-zA-Z0-9]+)'/;
78807ac75b1Sopenharmony_ci  const stateInfoReg: RegExp = /Property\s*'(\$?[_a-zA-Z0-9]+)' does not exist on type/;
78907ac75b1Sopenharmony_ci  if (matchMessage(message, props, propInfoReg) ||
79007ac75b1Sopenharmony_ci    matchMessage(message, props, stateInfoReg)) {
79107ac75b1Sopenharmony_ci    return false;
79207ac75b1Sopenharmony_ci  }
79307ac75b1Sopenharmony_ci  return true;
79407ac75b1Sopenharmony_ci}
79507ac75b1Sopenharmony_cifunction matchMessage(message: string, nameArr: any, reg: RegExp): boolean {
79607ac75b1Sopenharmony_ci  if (reg.test(message)) {
79707ac75b1Sopenharmony_ci    const match: string[] = message.match(reg);
79807ac75b1Sopenharmony_ci    if (match[1] && nameArr.includes(match[1])) {
79907ac75b1Sopenharmony_ci      return true;
80007ac75b1Sopenharmony_ci    }
80107ac75b1Sopenharmony_ci  }
80207ac75b1Sopenharmony_ci  return false;
80307ac75b1Sopenharmony_ci}
80407ac75b1Sopenharmony_ci
80507ac75b1Sopenharmony_cifunction updateErrorFileCache(diagnostic: ts.Diagnostic): void {
80607ac75b1Sopenharmony_ci  if (!diagnostic.file) {
80707ac75b1Sopenharmony_ci    return;
80807ac75b1Sopenharmony_ci  }
80907ac75b1Sopenharmony_ci
81007ac75b1Sopenharmony_ci  let cacheInfo: CacheFileName = cache[path.resolve(diagnostic.file.fileName)];
81107ac75b1Sopenharmony_ci  if (cacheInfo) {
81207ac75b1Sopenharmony_ci    cacheInfo.error = true;
81307ac75b1Sopenharmony_ci    if (!cacheInfo.errorCodes) {
81407ac75b1Sopenharmony_ci      cacheInfo.errorCodes = [];
81507ac75b1Sopenharmony_ci    }
81607ac75b1Sopenharmony_ci    cacheInfo.errorCodes.includes(diagnostic.code) || cacheInfo.errorCodes.push(diagnostic.code);
81707ac75b1Sopenharmony_ci  }
81807ac75b1Sopenharmony_ci}
81907ac75b1Sopenharmony_ci
82007ac75b1Sopenharmony_cifunction filterInput(rootFileNames: string[]): string[] {
82107ac75b1Sopenharmony_ci  return rootFileNames.filter((file: string) => {
82207ac75b1Sopenharmony_ci    const needUpdate: NeedUpdateFlag = { flag: false };
82307ac75b1Sopenharmony_ci    const alreadyCheckedFiles: Set<string> = new Set();
82407ac75b1Sopenharmony_ci    checkNeedUpdateFiles(path.resolve(file), needUpdate, alreadyCheckedFiles);
82507ac75b1Sopenharmony_ci    if (!needUpdate.flag) {
82607ac75b1Sopenharmony_ci      storedFileInfo.changeFiles.push(path.resolve(file));
82707ac75b1Sopenharmony_ci    }
82807ac75b1Sopenharmony_ci    return needUpdate.flag;
82907ac75b1Sopenharmony_ci  });
83007ac75b1Sopenharmony_ci}
83107ac75b1Sopenharmony_ci
83207ac75b1Sopenharmony_cifunction checkNeedUpdateFiles(file: string, needUpdate: NeedUpdateFlag, alreadyCheckedFiles: Set<string>): void {
83307ac75b1Sopenharmony_ci  if (alreadyCheckedFiles.has(file)) {
83407ac75b1Sopenharmony_ci    return;
83507ac75b1Sopenharmony_ci  } else {
83607ac75b1Sopenharmony_ci    alreadyCheckedFiles.add(file);
83707ac75b1Sopenharmony_ci  }
83807ac75b1Sopenharmony_ci
83907ac75b1Sopenharmony_ci  if (needUpdate.flag) {
84007ac75b1Sopenharmony_ci    return;
84107ac75b1Sopenharmony_ci  }
84207ac75b1Sopenharmony_ci
84307ac75b1Sopenharmony_ci  const value: CacheFileName = cache[file];
84407ac75b1Sopenharmony_ci  const mtimeMs: number = fs.statSync(file).mtimeMs;
84507ac75b1Sopenharmony_ci  if (value) {
84607ac75b1Sopenharmony_ci    if (value.error || value.mtimeMs !== mtimeMs) {
84707ac75b1Sopenharmony_ci      needUpdate.flag = true;
84807ac75b1Sopenharmony_ci      return;
84907ac75b1Sopenharmony_ci    }
85007ac75b1Sopenharmony_ci    for (let i = 0; i < value.children.length; ++i) {
85107ac75b1Sopenharmony_ci      if (fs.existsSync(value.children[i])) {
85207ac75b1Sopenharmony_ci        checkNeedUpdateFiles(value.children[i], needUpdate, alreadyCheckedFiles);
85307ac75b1Sopenharmony_ci      } else {
85407ac75b1Sopenharmony_ci        needUpdate.flag = true;
85507ac75b1Sopenharmony_ci      }
85607ac75b1Sopenharmony_ci    }
85707ac75b1Sopenharmony_ci  } else {
85807ac75b1Sopenharmony_ci    cache[file] = { mtimeMs, children: [], parent: [], error: false };
85907ac75b1Sopenharmony_ci    needUpdate.flag = true;
86007ac75b1Sopenharmony_ci  }
86107ac75b1Sopenharmony_ci}
86207ac75b1Sopenharmony_ci
86307ac75b1Sopenharmony_ciconst fileExistsCache: Map<string, boolean> = new Map<string, boolean>();
86407ac75b1Sopenharmony_ciconst dirExistsCache: Map<string, boolean> = new Map<string, boolean>();
86507ac75b1Sopenharmony_ciconst moduleResolutionHost: ts.ModuleResolutionHost = {
86607ac75b1Sopenharmony_ci  fileExists: (fileName: string): boolean => {
86707ac75b1Sopenharmony_ci    let exists = fileExistsCache.get(fileName);
86807ac75b1Sopenharmony_ci    if (exists === undefined) {
86907ac75b1Sopenharmony_ci      exists = ts.sys.fileExists(fileName);
87007ac75b1Sopenharmony_ci      fileExistsCache.set(fileName, exists);
87107ac75b1Sopenharmony_ci    }
87207ac75b1Sopenharmony_ci    return exists;
87307ac75b1Sopenharmony_ci  },
87407ac75b1Sopenharmony_ci  directoryExists: (directoryName: string): boolean => {
87507ac75b1Sopenharmony_ci    let exists = dirExistsCache.get(directoryName);
87607ac75b1Sopenharmony_ci    if (exists === undefined) {
87707ac75b1Sopenharmony_ci      exists = ts.sys.directoryExists(directoryName);
87807ac75b1Sopenharmony_ci      dirExistsCache.set(directoryName, exists);
87907ac75b1Sopenharmony_ci    }
88007ac75b1Sopenharmony_ci    return exists;
88107ac75b1Sopenharmony_ci  },
88207ac75b1Sopenharmony_ci  readFile(fileName: string): string | undefined {
88307ac75b1Sopenharmony_ci    return ts.sys.readFile(fileName);
88407ac75b1Sopenharmony_ci  },
88507ac75b1Sopenharmony_ci  realpath(path: string): string {
88607ac75b1Sopenharmony_ci    return ts.sys.realpath(path);
88707ac75b1Sopenharmony_ci  },
88807ac75b1Sopenharmony_ci  trace(s: string): void {
88907ac75b1Sopenharmony_ci    console.info(s);
89007ac75b1Sopenharmony_ci  }
89107ac75b1Sopenharmony_ci};
89207ac75b1Sopenharmony_ci
89307ac75b1Sopenharmony_ci//This is only for test
89407ac75b1Sopenharmony_ciexport const moduleResolutionHostTest = moduleResolutionHost;
89507ac75b1Sopenharmony_ci
89607ac75b1Sopenharmony_ciexport function resolveTypeReferenceDirectives(typeDirectiveNames: string[] | ts.FileReference[]): ts.ResolvedTypeReferenceDirective[] {
89707ac75b1Sopenharmony_ci  if (typeDirectiveNames.length === 0) {
89807ac75b1Sopenharmony_ci    return [];
89907ac75b1Sopenharmony_ci  }
90007ac75b1Sopenharmony_ci
90107ac75b1Sopenharmony_ci  const resolvedTypeReferenceCache: ts.ResolvedTypeReferenceDirective[] = [];
90207ac75b1Sopenharmony_ci  const cache: Map<string, ts.ResolvedTypeReferenceDirective> = new Map<string, ts.ResolvedTypeReferenceDirective>();
90307ac75b1Sopenharmony_ci  const containingFile: string = path.join(projectConfig.modulePath, 'build-profile.json5');
90407ac75b1Sopenharmony_ci
90507ac75b1Sopenharmony_ci  for (const entry of typeDirectiveNames) {
90607ac75b1Sopenharmony_ci    const typeName = isString(entry) ? entry : entry.fileName.toLowerCase();
90707ac75b1Sopenharmony_ci    if (!cache.has(typeName)) {
90807ac75b1Sopenharmony_ci      const resolvedFile = ts.resolveTypeReferenceDirective(typeName, containingFile, compilerOptions, moduleResolutionHost);
90907ac75b1Sopenharmony_ci      if (!resolvedFile || !resolvedFile.resolvedTypeReferenceDirective) {
91007ac75b1Sopenharmony_ci        logger.error('\u001b[31m', `ArkTS:Cannot find type definition file for: ${typeName}\n`);
91107ac75b1Sopenharmony_ci      }
91207ac75b1Sopenharmony_ci      const result: ts.ResolvedTypeReferenceDirective = resolvedFile.resolvedTypeReferenceDirective;
91307ac75b1Sopenharmony_ci      cache.set(typeName, result);
91407ac75b1Sopenharmony_ci      resolvedTypeReferenceCache.push(result);
91507ac75b1Sopenharmony_ci    }
91607ac75b1Sopenharmony_ci  }
91707ac75b1Sopenharmony_ci  return resolvedTypeReferenceCache;
91807ac75b1Sopenharmony_ci}
91907ac75b1Sopenharmony_ci
92007ac75b1Sopenharmony_ci// resolvedModulesCache records the files and their dependencies of program.
92107ac75b1Sopenharmony_ciexport const resolvedModulesCache: Map<string, ts.ResolvedModuleFull[]> = new Map();
92207ac75b1Sopenharmony_ci
92307ac75b1Sopenharmony_ciexport function resolveModuleNames(moduleNames: string[], containingFile: string): ts.ResolvedModuleFull[] {
92407ac75b1Sopenharmony_ci  startTimeStatisticsLocation(resolveModuleNamesTime);
92507ac75b1Sopenharmony_ci  const resolvedModules: ts.ResolvedModuleFull[] = [];
92607ac75b1Sopenharmony_ci  const cacheFileContent: ts.ResolvedModuleFull[] = resolvedModulesCache.get(path.resolve(containingFile));
92707ac75b1Sopenharmony_ci  if (![...shouldResolvedFiles].length || shouldResolvedFiles.has(path.resolve(containingFile)) ||
92807ac75b1Sopenharmony_ci    !(cacheFileContent && cacheFileContent.length === moduleNames.length)) {
92907ac75b1Sopenharmony_ci    for (const moduleName of moduleNames) {
93007ac75b1Sopenharmony_ci      const result = ts.resolveModuleName(moduleName, containingFile, compilerOptions, moduleResolutionHost);
93107ac75b1Sopenharmony_ci      if (result.resolvedModule) {
93207ac75b1Sopenharmony_ci        if (result.resolvedModule.resolvedFileName &&
93307ac75b1Sopenharmony_ci          path.extname(result.resolvedModule.resolvedFileName) === EXTNAME_JS) {
93407ac75b1Sopenharmony_ci          const resultDETSPath: string =
93507ac75b1Sopenharmony_ci            result.resolvedModule.resolvedFileName.replace(EXTNAME_JS, EXTNAME_D_ETS);
93607ac75b1Sopenharmony_ci          if (ts.sys.fileExists(resultDETSPath)) {
93707ac75b1Sopenharmony_ci            resolvedModules.push(getResolveModule(resultDETSPath, EXTNAME_D_ETS));
93807ac75b1Sopenharmony_ci          } else {
93907ac75b1Sopenharmony_ci            resolvedModules.push(result.resolvedModule);
94007ac75b1Sopenharmony_ci          }
94107ac75b1Sopenharmony_ci        } else {
94207ac75b1Sopenharmony_ci          resolvedModules.push(result.resolvedModule);
94307ac75b1Sopenharmony_ci        }
94407ac75b1Sopenharmony_ci      } else if (new RegExp(`^@(${sdkConfigPrefix})\\.`, 'i').test(moduleName.trim())) {
94507ac75b1Sopenharmony_ci        let apiFileExist: boolean = false;
94607ac75b1Sopenharmony_ci        for (let i = 0; i < sdkConfigs.length; i++) {
94707ac75b1Sopenharmony_ci          const sdkConfig = sdkConfigs[i];
94807ac75b1Sopenharmony_ci          const resolveModuleInfo: ResolveModuleInfo = getRealModulePath(sdkConfig.apiPath, moduleName, ['.d.ts', '.d.ets']);
94907ac75b1Sopenharmony_ci          const modulePath: string = resolveModuleInfo.modulePath;
95007ac75b1Sopenharmony_ci          const isDETS: boolean = resolveModuleInfo.isEts;
95107ac75b1Sopenharmony_ci          if (systemModules.includes(moduleName + (isDETS ? '.d.ets' : '.d.ts')) && ts.sys.fileExists(modulePath)) {
95207ac75b1Sopenharmony_ci            resolvedModules.push(getResolveModule(modulePath, isDETS ? '.d.ets' : '.d.ts'));
95307ac75b1Sopenharmony_ci            apiFileExist = true;
95407ac75b1Sopenharmony_ci            break;
95507ac75b1Sopenharmony_ci          }
95607ac75b1Sopenharmony_ci        }
95707ac75b1Sopenharmony_ci        if (!apiFileExist) {
95807ac75b1Sopenharmony_ci          resolvedModules.push(null);
95907ac75b1Sopenharmony_ci        }
96007ac75b1Sopenharmony_ci      } else if (/\.ets$/.test(moduleName) && !/\.d\.ets$/.test(moduleName)) {
96107ac75b1Sopenharmony_ci        const modulePath: string = path.resolve(path.dirname(containingFile), moduleName);
96207ac75b1Sopenharmony_ci        if (ts.sys.fileExists(modulePath)) {
96307ac75b1Sopenharmony_ci          resolvedModules.push(getResolveModule(modulePath, '.ets'));
96407ac75b1Sopenharmony_ci        } else {
96507ac75b1Sopenharmony_ci          resolvedModules.push(null);
96607ac75b1Sopenharmony_ci        }
96707ac75b1Sopenharmony_ci      } else if (/\.ts$/.test(moduleName)) {
96807ac75b1Sopenharmony_ci        const modulePath: string = path.resolve(path.dirname(containingFile), moduleName);
96907ac75b1Sopenharmony_ci        if (ts.sys.fileExists(modulePath)) {
97007ac75b1Sopenharmony_ci          resolvedModules.push(getResolveModule(modulePath, '.ts'));
97107ac75b1Sopenharmony_ci        } else {
97207ac75b1Sopenharmony_ci          resolvedModules.push(null);
97307ac75b1Sopenharmony_ci        }
97407ac75b1Sopenharmony_ci      } else {
97507ac75b1Sopenharmony_ci        const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts');
97607ac75b1Sopenharmony_ci        const systemDETSModulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ets');
97707ac75b1Sopenharmony_ci        const kitModulePath: string = path.resolve(__dirname, '../../../kits', moduleName + '.d.ts');
97807ac75b1Sopenharmony_ci        const kitSystemDETSModulePath: string = path.resolve(__dirname, '../../../kits', moduleName + '.d.ets');
97907ac75b1Sopenharmony_ci        const suffix: string = /\.js$/.test(moduleName) ? '' : '.js';
98007ac75b1Sopenharmony_ci        const jsModulePath: string = path.resolve(__dirname, '../node_modules', moduleName + suffix);
98107ac75b1Sopenharmony_ci        const fileModulePath: string =
98207ac75b1Sopenharmony_ci          path.resolve(__dirname, '../node_modules', moduleName + '/index.js');
98307ac75b1Sopenharmony_ci        const DETSModulePath: string = path.resolve(path.dirname(containingFile),
98407ac75b1Sopenharmony_ci          /\.d\.ets$/.test(moduleName) ? moduleName : moduleName + EXTNAME_D_ETS);
98507ac75b1Sopenharmony_ci        if (ts.sys.fileExists(modulePath)) {
98607ac75b1Sopenharmony_ci          resolvedModules.push(getResolveModule(modulePath, '.d.ts'));
98707ac75b1Sopenharmony_ci        } else if (ts.sys.fileExists(systemDETSModulePath)) {
98807ac75b1Sopenharmony_ci          resolvedModules.push(getResolveModule(systemDETSModulePath, '.d.ets'));
98907ac75b1Sopenharmony_ci        } else if (ts.sys.fileExists(kitModulePath)) {
99007ac75b1Sopenharmony_ci          resolvedModules.push(getResolveModule(kitModulePath, '.d.ts'));
99107ac75b1Sopenharmony_ci        } else if (ts.sys.fileExists(kitSystemDETSModulePath)) {
99207ac75b1Sopenharmony_ci          resolvedModules.push(getResolveModule(kitSystemDETSModulePath, '.d.ets'));
99307ac75b1Sopenharmony_ci        } else if (ts.sys.fileExists(jsModulePath)) {
99407ac75b1Sopenharmony_ci          resolvedModules.push(getResolveModule(jsModulePath, '.js'));
99507ac75b1Sopenharmony_ci        } else if (ts.sys.fileExists(fileModulePath)) {
99607ac75b1Sopenharmony_ci          resolvedModules.push(getResolveModule(fileModulePath, '.js'));
99707ac75b1Sopenharmony_ci        } else if (ts.sys.fileExists(DETSModulePath)) {
99807ac75b1Sopenharmony_ci          resolvedModules.push(getResolveModule(DETSModulePath, '.d.ets'));
99907ac75b1Sopenharmony_ci        } else {
100007ac75b1Sopenharmony_ci          const srcIndex: number = projectConfig.projectPath.indexOf('src' + path.sep + 'main');
100107ac75b1Sopenharmony_ci          let DETSModulePathFromModule: string;
100207ac75b1Sopenharmony_ci          if (srcIndex > 0) {
100307ac75b1Sopenharmony_ci            DETSModulePathFromModule = path.resolve(
100407ac75b1Sopenharmony_ci              projectConfig.projectPath.substring(0, srcIndex), moduleName + path.sep + 'index' + EXTNAME_D_ETS);
100507ac75b1Sopenharmony_ci            if (DETSModulePathFromModule && ts.sys.fileExists(DETSModulePathFromModule)) {
100607ac75b1Sopenharmony_ci              resolvedModules.push(getResolveModule(DETSModulePathFromModule, '.d.ets'));
100707ac75b1Sopenharmony_ci            } else {
100807ac75b1Sopenharmony_ci              resolvedModules.push(null);
100907ac75b1Sopenharmony_ci            }
101007ac75b1Sopenharmony_ci          } else {
101107ac75b1Sopenharmony_ci            resolvedModules.push(null);
101207ac75b1Sopenharmony_ci          }
101307ac75b1Sopenharmony_ci        }
101407ac75b1Sopenharmony_ci      }
101507ac75b1Sopenharmony_ci      if (projectConfig.hotReload && resolvedModules.length &&
101607ac75b1Sopenharmony_ci        resolvedModules[resolvedModules.length - 1]) {
101707ac75b1Sopenharmony_ci        hotReloadSupportFiles.add(path.resolve(resolvedModules[resolvedModules.length - 1].resolvedFileName));
101807ac75b1Sopenharmony_ci      }
101907ac75b1Sopenharmony_ci      if (collectShouldPackedFiles(resolvedModules)) {
102007ac75b1Sopenharmony_ci        allResolvedModules.add(resolvedModules[resolvedModules.length - 1].resolvedFileName);
102107ac75b1Sopenharmony_ci      }
102207ac75b1Sopenharmony_ci    }
102307ac75b1Sopenharmony_ci    if (!projectConfig.xtsMode) {
102407ac75b1Sopenharmony_ci      createOrUpdateCache(resolvedModules, path.resolve(containingFile));
102507ac75b1Sopenharmony_ci    }
102607ac75b1Sopenharmony_ci    resolvedModulesCache.set(path.resolve(containingFile), resolvedModules);
102707ac75b1Sopenharmony_ci    stopTimeStatisticsLocation(resolveModuleNamesTime);
102807ac75b1Sopenharmony_ci    return resolvedModules;
102907ac75b1Sopenharmony_ci  }
103007ac75b1Sopenharmony_ci  stopTimeStatisticsLocation(resolveModuleNamesTime);
103107ac75b1Sopenharmony_ci  return resolvedModulesCache.get(path.resolve(containingFile));
103207ac75b1Sopenharmony_ci}
103307ac75b1Sopenharmony_ci
103407ac75b1Sopenharmony_ciexport interface ResolveModuleInfo {
103507ac75b1Sopenharmony_ci  modulePath: string;
103607ac75b1Sopenharmony_ci  isEts: boolean;
103707ac75b1Sopenharmony_ci}
103807ac75b1Sopenharmony_ci
103907ac75b1Sopenharmony_cifunction collectShouldPackedFiles(resolvedModules: ts.ResolvedModuleFull[]): boolean | RegExpMatchArray {
104007ac75b1Sopenharmony_ci  return (projectConfig.compileHar || projectConfig.compileShared) && resolvedModules[resolvedModules.length - 1] &&
104107ac75b1Sopenharmony_ci    resolvedModules[resolvedModules.length - 1].resolvedFileName &&
104207ac75b1Sopenharmony_ci    (path.resolve(resolvedModules[resolvedModules.length - 1].resolvedFileName).match(/(\.[^d]|[^\.]d|[^\.][^d])\.e?ts$/) ||
104307ac75b1Sopenharmony_ci      path.resolve(resolvedModules[resolvedModules.length - 1].resolvedFileName).match(/\.d\.e?ts$/) &&
104407ac75b1Sopenharmony_ci      path.resolve(resolvedModules[resolvedModules.length - 1].resolvedFileName).match(
104507ac75b1Sopenharmony_ci        new RegExp('\\' + path.sep + 'src' + '\\' + path.sep + 'main' + '\\' + path.sep)));
104607ac75b1Sopenharmony_ci}
104707ac75b1Sopenharmony_ci
104807ac75b1Sopenharmony_cifunction createOrUpdateCache(resolvedModules: ts.ResolvedModuleFull[], containingFile: string): void {
104907ac75b1Sopenharmony_ci  const children: string[] = [];
105007ac75b1Sopenharmony_ci  const error: boolean = false;
105107ac75b1Sopenharmony_ci  resolvedModules.forEach(moduleObj => {
105207ac75b1Sopenharmony_ci    if (moduleObj && moduleObj.resolvedFileName && /\.(ets|ts)$/.test(moduleObj.resolvedFileName)) {
105307ac75b1Sopenharmony_ci      const file: string = path.resolve(moduleObj.resolvedFileName);
105407ac75b1Sopenharmony_ci      const mtimeMs: number = fs.statSync(file).mtimeMs;
105507ac75b1Sopenharmony_ci      children.push(file);
105607ac75b1Sopenharmony_ci      const value: CacheFileName = cache[file];
105707ac75b1Sopenharmony_ci      if (value) {
105807ac75b1Sopenharmony_ci        value.mtimeMs = mtimeMs;
105907ac75b1Sopenharmony_ci        value.error = error;
106007ac75b1Sopenharmony_ci        value.parent = value.parent || [];
106107ac75b1Sopenharmony_ci        value.parent.push(path.resolve(containingFile));
106207ac75b1Sopenharmony_ci        value.parent = [...new Set(value.parent)];
106307ac75b1Sopenharmony_ci      } else {
106407ac75b1Sopenharmony_ci        cache[file] = { mtimeMs, children: [], parent: [containingFile], error };
106507ac75b1Sopenharmony_ci      }
106607ac75b1Sopenharmony_ci    }
106707ac75b1Sopenharmony_ci  });
106807ac75b1Sopenharmony_ci  cache[path.resolve(containingFile)] = {
106907ac75b1Sopenharmony_ci    mtimeMs: fs.statSync(containingFile).mtimeMs, children,
107007ac75b1Sopenharmony_ci    parent: cache[path.resolve(containingFile)] && cache[path.resolve(containingFile)].parent ?
107107ac75b1Sopenharmony_ci      cache[path.resolve(containingFile)].parent : [], error
107207ac75b1Sopenharmony_ci  };
107307ac75b1Sopenharmony_ci}
107407ac75b1Sopenharmony_ci
107507ac75b1Sopenharmony_ciexport function createWatchCompilerHost(rootFileNames: string[],
107607ac75b1Sopenharmony_ci  reportDiagnostic: ts.DiagnosticReporter, delayPrintLogCount: Function, resetErrorCount: Function,
107707ac75b1Sopenharmony_ci  isPipe: boolean = false, resolveModulePaths: string[] = null): ts.WatchCompilerHostOfFilesAndCompilerOptions<ts.BuilderProgram> {
107807ac75b1Sopenharmony_ci  if (projectConfig.hotReload) {
107907ac75b1Sopenharmony_ci    rootFileNames.forEach(fileName => {
108007ac75b1Sopenharmony_ci      hotReloadSupportFiles.add(fileName);
108107ac75b1Sopenharmony_ci    });
108207ac75b1Sopenharmony_ci  }
108307ac75b1Sopenharmony_ci  if (!(isPipe && process.env.compileTool === 'rollup')) {
108407ac75b1Sopenharmony_ci    setCompilerOptions(resolveModulePaths);
108507ac75b1Sopenharmony_ci  }
108607ac75b1Sopenharmony_ci  // Change the buildInfo file path, or it will cover the buildInfo file created before.
108707ac75b1Sopenharmony_ci  const buildInfoPath: string = path.resolve(projectConfig.cachePath, '..', WATCH_COMPILER_BUILD_INFO_SUFFIX);
108807ac75b1Sopenharmony_ci  const watchCompilerOptions = {...compilerOptions, tsBuildInfoFile: buildInfoPath};
108907ac75b1Sopenharmony_ci  const createProgram = ts.createSemanticDiagnosticsBuilderProgram;
109007ac75b1Sopenharmony_ci  const host = ts.createWatchCompilerHost(
109107ac75b1Sopenharmony_ci    [...rootFileNames, ...readDeaclareFiles()], watchCompilerOptions,
109207ac75b1Sopenharmony_ci    ts.sys, createProgram, reportDiagnostic,
109307ac75b1Sopenharmony_ci    (diagnostic: ts.Diagnostic) => {
109407ac75b1Sopenharmony_ci      if ([6031, 6032].includes(diagnostic.code)) {
109507ac75b1Sopenharmony_ci        if (!isPipe) {
109607ac75b1Sopenharmony_ci          process.env.watchTs = 'start';
109707ac75b1Sopenharmony_ci          resetErrorCount();
109807ac75b1Sopenharmony_ci        }
109907ac75b1Sopenharmony_ci      }
110007ac75b1Sopenharmony_ci      // End of compilation in watch mode flag.
110107ac75b1Sopenharmony_ci      if ([6193, 6194].includes(diagnostic.code)) {
110207ac75b1Sopenharmony_ci        if (!isPipe) {
110307ac75b1Sopenharmony_ci          process.env.watchTs = 'end';
110407ac75b1Sopenharmony_ci          if (fastBuildLogger) {
110507ac75b1Sopenharmony_ci            fastBuildLogger.debug(TS_WATCH_END_MSG);
110607ac75b1Sopenharmony_ci            tsWatchEmitter.emit(TS_WATCH_END_MSG);
110707ac75b1Sopenharmony_ci          }
110807ac75b1Sopenharmony_ci        }
110907ac75b1Sopenharmony_ci        delayPrintLogCount();
111007ac75b1Sopenharmony_ci      }
111107ac75b1Sopenharmony_ci    });
111207ac75b1Sopenharmony_ci  host.readFile = (fileName: string) => {
111307ac75b1Sopenharmony_ci    if (!fs.existsSync(fileName)) {
111407ac75b1Sopenharmony_ci      return undefined;
111507ac75b1Sopenharmony_ci    }
111607ac75b1Sopenharmony_ci    if (/(?<!\.d)\.(ets|ts)$/.test(fileName)) {
111707ac75b1Sopenharmony_ci      let content: string = processContent(fs.readFileSync(fileName).toString(), fileName);
111807ac75b1Sopenharmony_ci      const extendFunctionInfo: extendInfo[] = [];
111907ac75b1Sopenharmony_ci      content = instanceInsteadThis(content, fileName, extendFunctionInfo, props);
112007ac75b1Sopenharmony_ci      return content;
112107ac75b1Sopenharmony_ci    }
112207ac75b1Sopenharmony_ci    return fs.readFileSync(fileName).toString();
112307ac75b1Sopenharmony_ci  };
112407ac75b1Sopenharmony_ci  host.resolveModuleNames = resolveModuleNames;
112507ac75b1Sopenharmony_ci  host.resolveTypeReferenceDirectives = resolveTypeReferenceDirectives;
112607ac75b1Sopenharmony_ci  return host;
112707ac75b1Sopenharmony_ci}
112807ac75b1Sopenharmony_ci
112907ac75b1Sopenharmony_ciexport function watchChecker(rootFileNames: string[], newLogger: any = null, resolveModulePaths: string[] = null): void {
113007ac75b1Sopenharmony_ci  fastBuildLogger = newLogger;
113107ac75b1Sopenharmony_ci  globalProgram.watchProgram = ts.createWatchProgram(
113207ac75b1Sopenharmony_ci    createWatchCompilerHost(rootFileNames, printDiagnostic, () => { }, () => { }, false, resolveModulePaths));
113307ac75b1Sopenharmony_ci}
113407ac75b1Sopenharmony_ci
113507ac75b1Sopenharmony_ciexport function instanceInsteadThis(content: string, fileName: string, extendFunctionInfo: extendInfo[],
113607ac75b1Sopenharmony_ci  props: string[]): string {
113707ac75b1Sopenharmony_ci  checkUISyntax(content, fileName, extendFunctionInfo, props);
113807ac75b1Sopenharmony_ci  extendFunctionInfo.reverse().forEach((item) => {
113907ac75b1Sopenharmony_ci    const subStr: string = content.substring(item.start, item.end);
114007ac75b1Sopenharmony_ci    const insert: string = subStr.replace(/(\s)\$(\.)/g, (origin, item1, item2) => {
114107ac75b1Sopenharmony_ci      return item1 + item.compName + 'Instance' + item2;
114207ac75b1Sopenharmony_ci    });
114307ac75b1Sopenharmony_ci    content = content.slice(0, item.start) + insert + content.slice(item.end);
114407ac75b1Sopenharmony_ci  });
114507ac75b1Sopenharmony_ci  return content;
114607ac75b1Sopenharmony_ci}
114707ac75b1Sopenharmony_ci
114807ac75b1Sopenharmony_cifunction getResolveModule(modulePath: string, type): ts.ResolvedModuleFull {
114907ac75b1Sopenharmony_ci  return {
115007ac75b1Sopenharmony_ci    resolvedFileName: modulePath,
115107ac75b1Sopenharmony_ci    isExternalLibraryImport: false,
115207ac75b1Sopenharmony_ci    extension: type
115307ac75b1Sopenharmony_ci  };
115407ac75b1Sopenharmony_ci}
115507ac75b1Sopenharmony_ci
115607ac75b1Sopenharmony_ciexport const dollarCollection: Set<string> = new Set();
115707ac75b1Sopenharmony_ciexport const extendCollection: Set<string> = new Set();
115807ac75b1Sopenharmony_ciexport const importModuleCollection: Set<string> = new Set();
115907ac75b1Sopenharmony_ci
116007ac75b1Sopenharmony_cifunction checkUISyntax(source: string, fileName: string, extendFunctionInfo: extendInfo[], props: string[]): void {
116107ac75b1Sopenharmony_ci  if (/\.ets$/.test(fileName)) {
116207ac75b1Sopenharmony_ci    if (process.env.compileMode === 'moduleJson' ||
116307ac75b1Sopenharmony_ci      path.resolve(fileName) !== path.resolve(projectConfig.projectPath, 'app.ets')) {
116407ac75b1Sopenharmony_ci      const sourceFile: ts.SourceFile = ts.createSourceFile(fileName, source,
116507ac75b1Sopenharmony_ci        ts.ScriptTarget.Latest, true, ts.ScriptKind.ETS, compilerOptions);
116607ac75b1Sopenharmony_ci      collectComponents(sourceFile);
116707ac75b1Sopenharmony_ci      collectionCustomizeStyles(sourceFile);
116807ac75b1Sopenharmony_ci      parseAllNode(sourceFile, sourceFile, extendFunctionInfo);
116907ac75b1Sopenharmony_ci      props.push(...dollarCollection, ...extendCollection);
117007ac75b1Sopenharmony_ci    }
117107ac75b1Sopenharmony_ci  }
117207ac75b1Sopenharmony_ci}
117307ac75b1Sopenharmony_ci
117407ac75b1Sopenharmony_cifunction collectionCustomizeStyles(node: ts.Node): void {
117507ac75b1Sopenharmony_ci  if ((ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) &&
117607ac75b1Sopenharmony_ci    (isUIDecorator(node, COMPONENT_STYLES_DECORATOR) || isUIDecorator(node, COMPONENT_EXTEND_DECORATOR)) &&
117707ac75b1Sopenharmony_ci    node.name && ts.isIdentifier(node.name)) {
117807ac75b1Sopenharmony_ci    BUILDIN_STYLE_NAMES.add(node.name.escapedText.toString());
117907ac75b1Sopenharmony_ci  }
118007ac75b1Sopenharmony_ci  if (ts.isSourceFile(node)) {
118107ac75b1Sopenharmony_ci    node.statements.forEach((item: ts.Node) => {
118207ac75b1Sopenharmony_ci      return collectionCustomizeStyles(item);
118307ac75b1Sopenharmony_ci    });
118407ac75b1Sopenharmony_ci  } else if (ts.isStructDeclaration(node)) {
118507ac75b1Sopenharmony_ci    node.members.forEach((item: ts.Node) => {
118607ac75b1Sopenharmony_ci      return collectionCustomizeStyles(item);
118707ac75b1Sopenharmony_ci    });
118807ac75b1Sopenharmony_ci  }
118907ac75b1Sopenharmony_ci}
119007ac75b1Sopenharmony_ci
119107ac75b1Sopenharmony_cifunction isUIDecorator(node: ts.MethodDeclaration | ts.FunctionDeclaration |
119207ac75b1Sopenharmony_ci  ts.StructDeclaration | ts.ClassDeclaration, decortorName: string): boolean {
119307ac75b1Sopenharmony_ci  const decorators: readonly ts.Decorator[] = ts.getAllDecorators(node);
119407ac75b1Sopenharmony_ci  if (decorators && decorators.length) {
119507ac75b1Sopenharmony_ci    for (let i = 0; i < decorators.length; i++) {
119607ac75b1Sopenharmony_ci      const originalDecortor: string = decorators[i].getText().replace(/\(.*\)$/, '').trim();
119707ac75b1Sopenharmony_ci      if (originalDecortor === decortorName) {
119807ac75b1Sopenharmony_ci        return true;
119907ac75b1Sopenharmony_ci      } else {
120007ac75b1Sopenharmony_ci        return false;
120107ac75b1Sopenharmony_ci      }
120207ac75b1Sopenharmony_ci    }
120307ac75b1Sopenharmony_ci  }
120407ac75b1Sopenharmony_ci  return false;
120507ac75b1Sopenharmony_ci}
120607ac75b1Sopenharmony_cifunction collectComponents(node: ts.SourceFile): void {
120707ac75b1Sopenharmony_ci  // @ts-ignore
120807ac75b1Sopenharmony_ci  if (process.env.watchMode !== 'true' && node.identifiers && node.identifiers.size) {
120907ac75b1Sopenharmony_ci    // @ts-ignore
121007ac75b1Sopenharmony_ci    for (const key of node.identifiers.keys()) {
121107ac75b1Sopenharmony_ci      if (JS_BIND_COMPONENTS.has(key)) {
121207ac75b1Sopenharmony_ci        appComponentCollection.get(path.join(node.fileName)).add(key);
121307ac75b1Sopenharmony_ci      }
121407ac75b1Sopenharmony_ci    }
121507ac75b1Sopenharmony_ci  }
121607ac75b1Sopenharmony_ci}
121707ac75b1Sopenharmony_ci
121807ac75b1Sopenharmony_cifunction parseAllNode(node: ts.Node, sourceFileNode: ts.SourceFile, extendFunctionInfo: extendInfo[]): void {
121907ac75b1Sopenharmony_ci  if (ts.isStructDeclaration(node)) {
122007ac75b1Sopenharmony_ci    if (node.members) {
122107ac75b1Sopenharmony_ci      node.members.forEach(item => {
122207ac75b1Sopenharmony_ci        if (ts.isPropertyDeclaration(item) && ts.isIdentifier(item.name)) {
122307ac75b1Sopenharmony_ci          const propertyName: string = item.name.getText();
122407ac75b1Sopenharmony_ci          const decorators: readonly ts.Decorator[] = ts.getAllDecorators(item);
122507ac75b1Sopenharmony_ci          if (decorators && decorators.length) {
122607ac75b1Sopenharmony_ci            for (let i = 0; i < decorators.length; i++) {
122707ac75b1Sopenharmony_ci              const decoratorName: string = decorators[i].getText().replace(/\(.*\)$/, '').trim();
122807ac75b1Sopenharmony_ci              if (INNER_COMPONENT_MEMBER_DECORATORS.has(decoratorName)) {
122907ac75b1Sopenharmony_ci                dollarCollection.add('$' + propertyName);
123007ac75b1Sopenharmony_ci              }
123107ac75b1Sopenharmony_ci            }
123207ac75b1Sopenharmony_ci          }
123307ac75b1Sopenharmony_ci        }
123407ac75b1Sopenharmony_ci      });
123507ac75b1Sopenharmony_ci    }
123607ac75b1Sopenharmony_ci  }
123707ac75b1Sopenharmony_ci  if (process.env.watchMode !== 'true' && ts.isIfStatement(node)) {
123807ac75b1Sopenharmony_ci    appComponentCollection.get(path.join(sourceFileNode.fileName)).add(COMPONENT_IF);
123907ac75b1Sopenharmony_ci  }
124007ac75b1Sopenharmony_ci  if (ts.isMethodDeclaration(node) && node.name.getText() === COMPONENT_BUILD_FUNCTION ||
124107ac75b1Sopenharmony_ci    (ts.isMethodDeclaration(node) || ts.isFunctionDeclaration(node)) &&
124207ac75b1Sopenharmony_ci    hasDecorator(node, COMPONENT_BUILDER_DECORATOR)) {
124307ac75b1Sopenharmony_ci    if (node.body && node.body.statements && node.body.statements.length) {
124407ac75b1Sopenharmony_ci      const checkProp: ts.NodeArray<ts.Statement> = node.body.statements;
124507ac75b1Sopenharmony_ci      checkProp.forEach((item, index) => {
124607ac75b1Sopenharmony_ci        traverseBuild(item, index);
124707ac75b1Sopenharmony_ci      });
124807ac75b1Sopenharmony_ci    }
124907ac75b1Sopenharmony_ci  }
125007ac75b1Sopenharmony_ci  if (ts.isFunctionDeclaration(node) && hasDecorator(node, COMPONENT_EXTEND_DECORATOR)) {
125107ac75b1Sopenharmony_ci    if (node.body && node.body.statements && node.body.statements.length &&
125207ac75b1Sopenharmony_ci      !isOriginalExtend(node.body)) {
125307ac75b1Sopenharmony_ci      extendFunctionInfo.push({
125407ac75b1Sopenharmony_ci        start: node.pos,
125507ac75b1Sopenharmony_ci        end: node.end,
125607ac75b1Sopenharmony_ci        compName: isExtendFunction(node, { decoratorName: '', componentName: '' })
125707ac75b1Sopenharmony_ci      });
125807ac75b1Sopenharmony_ci    }
125907ac75b1Sopenharmony_ci  }
126007ac75b1Sopenharmony_ci  node.getChildren().forEach((item: ts.Node) => parseAllNode(item, sourceFileNode, extendFunctionInfo));
126107ac75b1Sopenharmony_ci}
126207ac75b1Sopenharmony_ci
126307ac75b1Sopenharmony_cifunction isForeachAndLzayForEach(node: ts.Node): boolean {
126407ac75b1Sopenharmony_ci  return ts.isCallExpression(node) && node.expression && ts.isIdentifier(node.expression) &&
126507ac75b1Sopenharmony_ci    FOREACH_LAZYFOREACH.has(node.expression.escapedText.toString()) && node.arguments && node.arguments[1] &&
126607ac75b1Sopenharmony_ci    ts.isArrowFunction(node.arguments[1]) && node.arguments[1].body && ts.isBlock(node.arguments[1].body);
126707ac75b1Sopenharmony_ci}
126807ac75b1Sopenharmony_ci
126907ac75b1Sopenharmony_cifunction getComponentName(node: ts.Node): string {
127007ac75b1Sopenharmony_ci  let temp = node.expression;
127107ac75b1Sopenharmony_ci  let name: string;
127207ac75b1Sopenharmony_ci  while (temp) {
127307ac75b1Sopenharmony_ci    if (ts.isIdentifier(temp) && temp.parent && (ts.isCallExpression(temp.parent) ||
127407ac75b1Sopenharmony_ci      ts.isEtsComponentExpression(temp.parent))) {
127507ac75b1Sopenharmony_ci      name = temp.escapedText.toString();
127607ac75b1Sopenharmony_ci      break;
127707ac75b1Sopenharmony_ci    }
127807ac75b1Sopenharmony_ci    temp = temp.expression;
127907ac75b1Sopenharmony_ci  }
128007ac75b1Sopenharmony_ci  return name;
128107ac75b1Sopenharmony_ci}
128207ac75b1Sopenharmony_ci
128307ac75b1Sopenharmony_cifunction traverseBuild(node: ts.Node, index: number): void {
128407ac75b1Sopenharmony_ci  if (ts.isExpressionStatement(node)) {
128507ac75b1Sopenharmony_ci    const parentComponentName: string = getComponentName(node);
128607ac75b1Sopenharmony_ci    node = node.expression;
128707ac75b1Sopenharmony_ci    while (node) {
128807ac75b1Sopenharmony_ci      if (ts.isEtsComponentExpression(node) && node.body && ts.isBlock(node.body) &&
128907ac75b1Sopenharmony_ci        ts.isIdentifier(node.expression) && !DOLLAR_BLOCK_INTERFACE.has(node.expression.escapedText.toString())) {
129007ac75b1Sopenharmony_ci        node.body.statements.forEach((item: ts.Statement, indexBlock: number) => {
129107ac75b1Sopenharmony_ci          traverseBuild(item, indexBlock);
129207ac75b1Sopenharmony_ci        });
129307ac75b1Sopenharmony_ci        break;
129407ac75b1Sopenharmony_ci      } else if (isForeachAndLzayForEach(node)) {
129507ac75b1Sopenharmony_ci        node.arguments[1].body.statements.forEach((item: ts.Statement, indexBlock: number) => {
129607ac75b1Sopenharmony_ci          traverseBuild(item, indexBlock);
129707ac75b1Sopenharmony_ci        });
129807ac75b1Sopenharmony_ci        break;
129907ac75b1Sopenharmony_ci      } else {
130007ac75b1Sopenharmony_ci        loopNodeFindDoubleDollar(node, parentComponentName);
130107ac75b1Sopenharmony_ci        if (ts.isEtsComponentExpression(node) && node.body && ts.isBlock(node.body) &&
130207ac75b1Sopenharmony_ci          ts.isIdentifier(node.expression)) {
130307ac75b1Sopenharmony_ci          node.body.statements.forEach((item: ts.Statement, indexBlock: number) => {
130407ac75b1Sopenharmony_ci            traverseBuild(item, indexBlock);
130507ac75b1Sopenharmony_ci          });
130607ac75b1Sopenharmony_ci          break;
130707ac75b1Sopenharmony_ci        }
130807ac75b1Sopenharmony_ci      }
130907ac75b1Sopenharmony_ci      node = node.expression;
131007ac75b1Sopenharmony_ci    }
131107ac75b1Sopenharmony_ci  } else if (ts.isIfStatement(node)) {
131207ac75b1Sopenharmony_ci    ifInnerDollarAttribute(node);
131307ac75b1Sopenharmony_ci  }
131407ac75b1Sopenharmony_ci}
131507ac75b1Sopenharmony_ci
131607ac75b1Sopenharmony_cifunction ifInnerDollarAttribute(node: ts.IfStatement): void {
131707ac75b1Sopenharmony_ci  if (node.thenStatement && ts.isBlock(node.thenStatement) && node.thenStatement.statements) {
131807ac75b1Sopenharmony_ci    node.thenStatement.statements.forEach((item, indexIfBlock) => {
131907ac75b1Sopenharmony_ci      traverseBuild(item, indexIfBlock);
132007ac75b1Sopenharmony_ci    });
132107ac75b1Sopenharmony_ci  }
132207ac75b1Sopenharmony_ci  if (node.elseStatement) {
132307ac75b1Sopenharmony_ci    elseInnerDollarAttribute(node);
132407ac75b1Sopenharmony_ci  }
132507ac75b1Sopenharmony_ci}
132607ac75b1Sopenharmony_ci
132707ac75b1Sopenharmony_cifunction elseInnerDollarAttribute(node: ts.IfStatement): void {
132807ac75b1Sopenharmony_ci  if (ts.isIfStatement(node.elseStatement) && node.elseStatement.thenStatement && ts.isBlock(node.elseStatement.thenStatement)) {
132907ac75b1Sopenharmony_ci    traverseBuild(node.elseStatement, 0);
133007ac75b1Sopenharmony_ci  } else if (ts.isBlock(node.elseStatement) && node.elseStatement.statements) {
133107ac75b1Sopenharmony_ci    node.elseStatement.statements.forEach((item, indexElseBlock) => {
133207ac75b1Sopenharmony_ci      traverseBuild(item, indexElseBlock);
133307ac75b1Sopenharmony_ci    });
133407ac75b1Sopenharmony_ci  }
133507ac75b1Sopenharmony_ci}
133607ac75b1Sopenharmony_ci
133707ac75b1Sopenharmony_cifunction isPropertiesAddDoubleDollar(node: ts.Node): boolean {
133807ac75b1Sopenharmony_ci  if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.arguments && node.arguments.length) {
133907ac75b1Sopenharmony_ci    return true;
134007ac75b1Sopenharmony_ci  } else if (ts.isEtsComponentExpression(node) && ts.isIdentifier(node.expression) &&
134107ac75b1Sopenharmony_ci    DOLLAR_BLOCK_INTERFACE.has(node.expression.escapedText.toString())) {
134207ac75b1Sopenharmony_ci    return true;
134307ac75b1Sopenharmony_ci  } else {
134407ac75b1Sopenharmony_ci    return false;
134507ac75b1Sopenharmony_ci  }
134607ac75b1Sopenharmony_ci}
134707ac75b1Sopenharmony_cifunction loopNodeFindDoubleDollar(node: ts.Node, parentComponentName: string): void {
134807ac75b1Sopenharmony_ci  if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
134907ac75b1Sopenharmony_ci    const argument: ts.NodeArray<ts.Node> = node.arguments;
135007ac75b1Sopenharmony_ci    const propertyName: ts.Identifier | ts.PrivateIdentifier = node.expression.name;
135107ac75b1Sopenharmony_ci    if (isCanAddDoubleDollar(propertyName.getText(), parentComponentName)) {
135207ac75b1Sopenharmony_ci      argument.forEach((item: ts.Node) => {
135307ac75b1Sopenharmony_ci        doubleDollarCollection(item);
135407ac75b1Sopenharmony_ci      });
135507ac75b1Sopenharmony_ci    }
135607ac75b1Sopenharmony_ci  } else if (isPropertiesAddDoubleDollar(node)) {
135707ac75b1Sopenharmony_ci    node.arguments.forEach((item: ts.Node) => {
135807ac75b1Sopenharmony_ci      if (ts.isObjectLiteralExpression(item) && item.properties && item.properties.length) {
135907ac75b1Sopenharmony_ci        item.properties.forEach((param: ts.Node) => {
136007ac75b1Sopenharmony_ci          if (isObjectPram(param, parentComponentName)) {
136107ac75b1Sopenharmony_ci            doubleDollarCollection(param.initializer);
136207ac75b1Sopenharmony_ci          }
136307ac75b1Sopenharmony_ci        });
136407ac75b1Sopenharmony_ci      } else if (ts.isPropertyAccessExpression(item) && (handleComponentDollarBlock(node as ts.CallExpression, parentComponentName) ||
136507ac75b1Sopenharmony_ci        STYLE_ADD_DOUBLE_DOLLAR.has(node.expression.getText()))) {
136607ac75b1Sopenharmony_ci        doubleDollarCollection(item);
136707ac75b1Sopenharmony_ci      }
136807ac75b1Sopenharmony_ci    });
136907ac75b1Sopenharmony_ci  }
137007ac75b1Sopenharmony_ci}
137107ac75b1Sopenharmony_ci
137207ac75b1Sopenharmony_cifunction handleComponentDollarBlock(node: ts.CallExpression, parentComponentName: string): boolean {
137307ac75b1Sopenharmony_ci  return ts.isCallExpression(node) && ts.isIdentifier(node.expression) &&
137407ac75b1Sopenharmony_ci    DOLLAR_BLOCK_INTERFACE.has(parentComponentName) && PROPERTIES_ADD_DOUBLE_DOLLAR.has(parentComponentName) &&
137507ac75b1Sopenharmony_ci    PROPERTIES_ADD_DOUBLE_DOLLAR.get(parentComponentName).has(node.expression.escapedText.toString());
137607ac75b1Sopenharmony_ci}
137707ac75b1Sopenharmony_ci
137807ac75b1Sopenharmony_cifunction doubleDollarCollection(item: ts.Node): void {
137907ac75b1Sopenharmony_ci  if (item.getText().startsWith($$)) {
138007ac75b1Sopenharmony_ci    while (item.expression) {
138107ac75b1Sopenharmony_ci      item = item.expression;
138207ac75b1Sopenharmony_ci    }
138307ac75b1Sopenharmony_ci    dollarCollection.add(item.getText());
138407ac75b1Sopenharmony_ci  }
138507ac75b1Sopenharmony_ci}
138607ac75b1Sopenharmony_ci
138707ac75b1Sopenharmony_cifunction isObjectPram(param: ts.Node, parentComponentName: string): boolean {
138807ac75b1Sopenharmony_ci  return ts.isPropertyAssignment(param) && param.name && ts.isIdentifier(param.name) &&
138907ac75b1Sopenharmony_ci    param.initializer && PROPERTIES_ADD_DOUBLE_DOLLAR.has(parentComponentName) &&
139007ac75b1Sopenharmony_ci    PROPERTIES_ADD_DOUBLE_DOLLAR.get(parentComponentName).has(param.name.getText());
139107ac75b1Sopenharmony_ci}
139207ac75b1Sopenharmony_ci
139307ac75b1Sopenharmony_cifunction isCanAddDoubleDollar(propertyName: string, parentComponentName: string): boolean {
139407ac75b1Sopenharmony_ci  return PROPERTIES_ADD_DOUBLE_DOLLAR.has(parentComponentName) &&
139507ac75b1Sopenharmony_ci    PROPERTIES_ADD_DOUBLE_DOLLAR.get(parentComponentName).has(propertyName) ||
139607ac75b1Sopenharmony_ci    STYLE_ADD_DOUBLE_DOLLAR.has(propertyName);
139707ac75b1Sopenharmony_ci}
139807ac75b1Sopenharmony_ci
139907ac75b1Sopenharmony_cifunction processContent(source: string, id: string): string {
140007ac75b1Sopenharmony_ci  if (fastBuildLogger) {
140107ac75b1Sopenharmony_ci    source = visualTransform(source, id, fastBuildLogger);
140207ac75b1Sopenharmony_ci  }
140307ac75b1Sopenharmony_ci  source = preprocessExtend(source, extendCollection);
140407ac75b1Sopenharmony_ci  source = preprocessNewExtend(source, extendCollection);
140507ac75b1Sopenharmony_ci  return source;
140607ac75b1Sopenharmony_ci}
140707ac75b1Sopenharmony_ci
140807ac75b1Sopenharmony_cifunction judgeFileShouldResolved(file: string, shouldResolvedFiles: Set<string>): void {
140907ac75b1Sopenharmony_ci  if (shouldResolvedFiles.has(file)) {
141007ac75b1Sopenharmony_ci    return;
141107ac75b1Sopenharmony_ci  }
141207ac75b1Sopenharmony_ci  shouldResolvedFiles.add(file);
141307ac75b1Sopenharmony_ci  if (cache && cache[file] && cache[file].parent) {
141407ac75b1Sopenharmony_ci    cache[file].parent.forEach((item) => {
141507ac75b1Sopenharmony_ci      judgeFileShouldResolved(item, shouldResolvedFiles);
141607ac75b1Sopenharmony_ci    });
141707ac75b1Sopenharmony_ci    cache[file].parent = [];
141807ac75b1Sopenharmony_ci  }
141907ac75b1Sopenharmony_ci  if (cache && cache[file] && cache[file].children) {
142007ac75b1Sopenharmony_ci    cache[file].children.forEach((item) => {
142107ac75b1Sopenharmony_ci      judgeFileShouldResolved(item, shouldResolvedFiles);
142207ac75b1Sopenharmony_ci    });
142307ac75b1Sopenharmony_ci    cache[file].children = [];
142407ac75b1Sopenharmony_ci  }
142507ac75b1Sopenharmony_ci}
142607ac75b1Sopenharmony_ci
142707ac75b1Sopenharmony_ciexport function incrementWatchFile(watchModifiedFiles: string[],
142807ac75b1Sopenharmony_ci  watchRemovedFiles: string[]): void {
142907ac75b1Sopenharmony_ci  const changedFiles: string[] = [...watchModifiedFiles, ...watchRemovedFiles];
143007ac75b1Sopenharmony_ci  if (changedFiles.length) {
143107ac75b1Sopenharmony_ci    shouldResolvedFiles.clear();
143207ac75b1Sopenharmony_ci  }
143307ac75b1Sopenharmony_ci  changedFiles.forEach((file) => {
143407ac75b1Sopenharmony_ci    judgeFileShouldResolved(file, shouldResolvedFiles);
143507ac75b1Sopenharmony_ci  });
143607ac75b1Sopenharmony_ci}
143707ac75b1Sopenharmony_ci
143807ac75b1Sopenharmony_ciexport function runArkTSLinter(): void {
143907ac75b1Sopenharmony_ci  const originProgram: ts.BuilderProgram = globalProgram.builderProgram;
144007ac75b1Sopenharmony_ci
144107ac75b1Sopenharmony_ci  const timePrinterInstance = ts.ArkTSLinterTimePrinter.getInstance();
144207ac75b1Sopenharmony_ci
144307ac75b1Sopenharmony_ci  const arkTSLinterDiagnostics = doArkTSLinter(getArkTSVersion(),
144407ac75b1Sopenharmony_ci    getArkTSLinterMode(),
144507ac75b1Sopenharmony_ci    originProgram,
144607ac75b1Sopenharmony_ci    printArkTSLinterDiagnostic,
144707ac75b1Sopenharmony_ci    !projectConfig.xtsMode,
144807ac75b1Sopenharmony_ci    buildInfoWriteFile);
144907ac75b1Sopenharmony_ci
145007ac75b1Sopenharmony_ci  if (process.env.watchMode !== 'true' && !projectConfig.xtsMode) {
145107ac75b1Sopenharmony_ci    arkTSLinterDiagnostics.forEach((diagnostic: ts.Diagnostic) => {
145207ac75b1Sopenharmony_ci      updateErrorFileCache(diagnostic);
145307ac75b1Sopenharmony_ci    });
145407ac75b1Sopenharmony_ci    timePrinterInstance.appendTime(ts.TimePhase.UPDATE_ERROR_FILE);
145507ac75b1Sopenharmony_ci  }
145607ac75b1Sopenharmony_ci  timePrinterInstance.printTimes();
145707ac75b1Sopenharmony_ci  ts.ArkTSLinterTimePrinter.destroyInstance();
145807ac75b1Sopenharmony_ci}
145907ac75b1Sopenharmony_ci
146007ac75b1Sopenharmony_cifunction printArkTSLinterDiagnostic(diagnostic: ts.Diagnostic): void {
146107ac75b1Sopenharmony_ci  if (diagnostic.category === ts.DiagnosticCategory.Error && (isInOhModuleFile(diagnostic) || isEtsDeclFileInSdk(diagnostic))) {
146207ac75b1Sopenharmony_ci    const originalCategory = diagnostic.category;
146307ac75b1Sopenharmony_ci    diagnostic.category = ts.DiagnosticCategory.Warning;
146407ac75b1Sopenharmony_ci    printDiagnostic(diagnostic);
146507ac75b1Sopenharmony_ci    diagnostic.category = originalCategory;
146607ac75b1Sopenharmony_ci    return;
146707ac75b1Sopenharmony_ci  }
146807ac75b1Sopenharmony_ci  printDiagnostic(diagnostic);
146907ac75b1Sopenharmony_ci}
147007ac75b1Sopenharmony_ci
147107ac75b1Sopenharmony_cifunction isEtsDeclFileInSdk(diagnostics: ts.Diagnostic): boolean {
147207ac75b1Sopenharmony_ci  if (diagnostics.file?.fileName === undefined) {
147307ac75b1Sopenharmony_ci    return false;
147407ac75b1Sopenharmony_ci  }
147507ac75b1Sopenharmony_ci  return isInSDK(diagnostics.file.fileName) && diagnostics.file.fileName.endsWith('.ets');
147607ac75b1Sopenharmony_ci}
147707ac75b1Sopenharmony_ci
147807ac75b1Sopenharmony_cifunction isInOhModuleFile(diagnostics: ts.Diagnostic): boolean {
147907ac75b1Sopenharmony_ci  return (diagnostics.file !== undefined) &&
148007ac75b1Sopenharmony_ci    ((diagnostics.file.fileName.indexOf('/oh_modules/') !== -1) || diagnostics.file.fileName.indexOf('\\oh_modules\\') !== -1);
148107ac75b1Sopenharmony_ci}
148207ac75b1Sopenharmony_ci
148307ac75b1Sopenharmony_cifunction isInSDK(fileName: string | undefined): boolean {
148407ac75b1Sopenharmony_ci  if (projectConfig.etsLoaderPath === undefined || fileName === undefined) {
148507ac75b1Sopenharmony_ci    return false;
148607ac75b1Sopenharmony_ci  }
148707ac75b1Sopenharmony_ci  const sdkPath = path.resolve(projectConfig.etsLoaderPath, '../../../');
148807ac75b1Sopenharmony_ci  return path.resolve(fileName).startsWith(sdkPath);
148907ac75b1Sopenharmony_ci}
149007ac75b1Sopenharmony_ci
149107ac75b1Sopenharmony_ciexport function getArkTSLinterMode(): ArkTSLinterMode {
149207ac75b1Sopenharmony_ci  if (!partialUpdateConfig.executeArkTSLinter) {
149307ac75b1Sopenharmony_ci    return ArkTSLinterMode.NOT_USE;
149407ac75b1Sopenharmony_ci  }
149507ac75b1Sopenharmony_ci
149607ac75b1Sopenharmony_ci  if (!partialUpdateConfig.standardArkTSLinter) {
149707ac75b1Sopenharmony_ci    return ArkTSLinterMode.COMPATIBLE_MODE;
149807ac75b1Sopenharmony_ci  }
149907ac75b1Sopenharmony_ci
150007ac75b1Sopenharmony_ci  if (isStandardMode()) {
150107ac75b1Sopenharmony_ci    return ArkTSLinterMode.STANDARD_MODE;
150207ac75b1Sopenharmony_ci  }
150307ac75b1Sopenharmony_ci  return ArkTSLinterMode.COMPATIBLE_MODE;
150407ac75b1Sopenharmony_ci}
150507ac75b1Sopenharmony_ci
150607ac75b1Sopenharmony_ciexport function isStandardMode(): boolean {
150707ac75b1Sopenharmony_ci  const STANDARD_MODE_COMPATIBLE_SDK_VERSION = 10;
150807ac75b1Sopenharmony_ci  if (projectConfig &&
150907ac75b1Sopenharmony_ci    projectConfig.compatibleSdkVersion &&
151007ac75b1Sopenharmony_ci    projectConfig.compatibleSdkVersion >= STANDARD_MODE_COMPATIBLE_SDK_VERSION) {
151107ac75b1Sopenharmony_ci    return true;
151207ac75b1Sopenharmony_ci  }
151307ac75b1Sopenharmony_ci  return false;
151407ac75b1Sopenharmony_ci}
151507ac75b1Sopenharmony_ci
151607ac75b1Sopenharmony_cifunction getArkTSVersion(): ArkTSVersion {
151707ac75b1Sopenharmony_ci  if (projectConfig.arkTSVersion === '1.0') {
151807ac75b1Sopenharmony_ci    return ArkTSVersion.ArkTS_1_0;
151907ac75b1Sopenharmony_ci  } else if (projectConfig.arkTSVersion === '1.1') {
152007ac75b1Sopenharmony_ci    return ArkTSVersion.ArkTS_1_1;
152107ac75b1Sopenharmony_ci  } else if (projectConfig.arkTSVersion !== undefined) {
152207ac75b1Sopenharmony_ci    const arkTSVersionLogger = fastBuildLogger || logger;
152307ac75b1Sopenharmony_ci    arkTSVersionLogger.warn('\u001b[33m' + 'ArkTS: Invalid ArkTS version\n');
152407ac75b1Sopenharmony_ci  }
152507ac75b1Sopenharmony_ci
152607ac75b1Sopenharmony_ci  if (partialUpdateConfig.arkTSVersion === '1.0') {
152707ac75b1Sopenharmony_ci    return ArkTSVersion.ArkTS_1_0;
152807ac75b1Sopenharmony_ci  } else if (partialUpdateConfig.arkTSVersion === '1.1') {
152907ac75b1Sopenharmony_ci    return ArkTSVersion.ArkTS_1_1;
153007ac75b1Sopenharmony_ci  } else if (partialUpdateConfig.arkTSVersion !== undefined) {
153107ac75b1Sopenharmony_ci    const arkTSVersionLogger = fastBuildLogger || logger;
153207ac75b1Sopenharmony_ci    arkTSVersionLogger.warn('\u001b[33m' + 'ArkTS: Invalid ArkTS version in metadata\n');
153307ac75b1Sopenharmony_ci  }
153407ac75b1Sopenharmony_ci
153507ac75b1Sopenharmony_ci  return ArkTSVersion.ArkTS_1_1;
153607ac75b1Sopenharmony_ci}
153707ac75b1Sopenharmony_ci
153807ac75b1Sopenharmony_cienum TargetESVersion {
153907ac75b1Sopenharmony_ci  ES2017 = 'ES2017',
154007ac75b1Sopenharmony_ci  ES2021 = 'ES2021',
154107ac75b1Sopenharmony_ci}
154207ac75b1Sopenharmony_ci
154307ac75b1Sopenharmony_cifunction getTargetESVersion(): TargetESVersion {
154407ac75b1Sopenharmony_ci  const targetESVersion = projectConfig?.projectArkOption?.tscConfig?.targetESVersion;
154507ac75b1Sopenharmony_ci  if (targetESVersion === 'ES2017') {
154607ac75b1Sopenharmony_ci    return TargetESVersion.ES2017;
154707ac75b1Sopenharmony_ci  } else if (targetESVersion === 'ES2021') {
154807ac75b1Sopenharmony_ci    return TargetESVersion.ES2021;
154907ac75b1Sopenharmony_ci  } else if (targetESVersion !== undefined) {
155007ac75b1Sopenharmony_ci    const targetESVersionLogger = fastBuildLogger || logger;
155107ac75b1Sopenharmony_ci    targetESVersionLogger.warn('\u001b[33m' + 'ArkTS: Invalid Target ES version\n');
155207ac75b1Sopenharmony_ci  }
155307ac75b1Sopenharmony_ci  return TargetESVersion.ES2021;
155407ac75b1Sopenharmony_ci}
155507ac75b1Sopenharmony_ci
155607ac75b1Sopenharmony_ciinterface TargetESVersionLib {
155707ac75b1Sopenharmony_ci  ES2017: string[],
155807ac75b1Sopenharmony_ci  ES2021: string[],
155907ac75b1Sopenharmony_ci}
156007ac75b1Sopenharmony_ci
156107ac75b1Sopenharmony_ciconst targetESVersionLib: TargetESVersionLib = {
156207ac75b1Sopenharmony_ci  // When target is es2017, the lib is es2020.
156307ac75b1Sopenharmony_ci  ES2017: ['ES2020'],
156407ac75b1Sopenharmony_ci  ES2021: ['ES2021'],
156507ac75b1Sopenharmony_ci};
156607ac75b1Sopenharmony_ci
156707ac75b1Sopenharmony_cifunction getTargetESVersionLib(): string[] {
156807ac75b1Sopenharmony_ci  const targetESVersion = projectConfig?.projectArkOption?.tscConfig?.targetESVersion;
156907ac75b1Sopenharmony_ci  if (targetESVersion === 'ES2017') {
157007ac75b1Sopenharmony_ci    return targetESVersionLib.ES2017;
157107ac75b1Sopenharmony_ci  } else if (targetESVersion === 'ES2021') {
157207ac75b1Sopenharmony_ci    return targetESVersionLib.ES2021;
157307ac75b1Sopenharmony_ci  } else if (targetESVersion !== undefined) {
157407ac75b1Sopenharmony_ci    const targetESVersionLogger = fastBuildLogger || logger;
157507ac75b1Sopenharmony_ci    targetESVersionLogger.warn('\u001b[33m' + 'ArkTS: Invalid Target ES version\n');
157607ac75b1Sopenharmony_ci  }
157707ac75b1Sopenharmony_ci  return targetESVersionLib.ES2021;
157807ac75b1Sopenharmony_ci}
157907ac75b1Sopenharmony_ci
158007ac75b1Sopenharmony_cifunction initEtsStandaloneCheckerConfig(logger, config): void {
158107ac75b1Sopenharmony_ci  fastBuildLogger = logger;
158207ac75b1Sopenharmony_ci  if (config.packageManagerType === 'ohpm') {
158307ac75b1Sopenharmony_ci    config.packageDir = 'oh_modules';
158407ac75b1Sopenharmony_ci    config.packageJson = 'oh-package.json5';
158507ac75b1Sopenharmony_ci  } else {
158607ac75b1Sopenharmony_ci    config.packageDir = 'node_modules';
158707ac75b1Sopenharmony_ci    config.packageJson = 'package.json';
158807ac75b1Sopenharmony_ci  }
158907ac75b1Sopenharmony_ci  if (config.aceModuleJsonPath && fs.existsSync(config.aceModuleJsonPath)) {
159007ac75b1Sopenharmony_ci    process.env.compileMode = 'moduleJson';
159107ac75b1Sopenharmony_ci  }
159207ac75b1Sopenharmony_ci  Object.assign(projectConfig, config);
159307ac75b1Sopenharmony_ci}
159407ac75b1Sopenharmony_ci
159507ac75b1Sopenharmony_cifunction resetEtsStandaloneCheckerConfig(beforeInitFastBuildLogger, beforeInitCompileMode: string): void {
159607ac75b1Sopenharmony_ci  resetProjectConfig();
159707ac75b1Sopenharmony_ci  resetEtsCheck();
159807ac75b1Sopenharmony_ci  fastBuildLogger = beforeInitFastBuildLogger;
159907ac75b1Sopenharmony_ci  process.env.compileMode = beforeInitCompileMode;
160007ac75b1Sopenharmony_ci}
160107ac75b1Sopenharmony_ci
160207ac75b1Sopenharmony_ciexport function etsStandaloneChecker(entryObj, logger, projectConfig): void {
160307ac75b1Sopenharmony_ci  const beforeInitFastBuildLogger = fastBuildLogger;
160407ac75b1Sopenharmony_ci  const beforeInitCompileMode = process.env.compileMode;
160507ac75b1Sopenharmony_ci  initEtsStandaloneCheckerConfig(logger, projectConfig);
160607ac75b1Sopenharmony_ci  const rootFileNames: string[] = [];
160707ac75b1Sopenharmony_ci  const resolveModulePaths: string[] = [];
160807ac75b1Sopenharmony_ci  Object.values(entryObj).forEach((fileName: string) => {
160907ac75b1Sopenharmony_ci    rootFileNames.push(path.resolve(fileName));
161007ac75b1Sopenharmony_ci  });
161107ac75b1Sopenharmony_ci  if (projectConfig.resolveModulePaths && Array.isArray(projectConfig.resolveModulePaths)) {
161207ac75b1Sopenharmony_ci    resolveModulePaths.push(...projectConfig.resolveModulePaths);
161307ac75b1Sopenharmony_ci  }
161407ac75b1Sopenharmony_ci  const filterFiles: string[] = filterInput(rootFileNames);
161507ac75b1Sopenharmony_ci  languageService = createLanguageService(filterFiles, resolveModulePaths);
161607ac75b1Sopenharmony_ci  const timePrinterInstance = ts.ArkTSLinterTimePrinter.getInstance();
161707ac75b1Sopenharmony_ci  timePrinterInstance.setArkTSTimePrintSwitch(false);
161807ac75b1Sopenharmony_ci  timePrinterInstance.appendTime(ts.TimePhase.START);
161907ac75b1Sopenharmony_ci  globalProgram.builderProgram = languageService.getBuilderProgram(/*withLinterProgram*/ true);
162007ac75b1Sopenharmony_ci  globalProgram.program = globalProgram.builderProgram.getProgram();
162107ac75b1Sopenharmony_ci  props = languageService.getProps();
162207ac75b1Sopenharmony_ci  timePrinterInstance.appendTime(ts.TimePhase.GET_PROGRAM);
162307ac75b1Sopenharmony_ci  collectFileToIgnoreDiagnostics(filterFiles);
162407ac75b1Sopenharmony_ci  runArkTSLinter();
162507ac75b1Sopenharmony_ci  const allDiagnostics: ts.Diagnostic[] = globalProgram.builderProgram
162607ac75b1Sopenharmony_ci    .getSyntacticDiagnostics()
162707ac75b1Sopenharmony_ci    .concat(globalProgram.builderProgram.getSemanticDiagnostics());
162807ac75b1Sopenharmony_ci  globalProgram.builderProgram.emitBuildInfo(buildInfoWriteFile);
162907ac75b1Sopenharmony_ci
163007ac75b1Sopenharmony_ci  allDiagnostics.forEach((diagnostic: ts.Diagnostic) => {
163107ac75b1Sopenharmony_ci    printDiagnostic(diagnostic);
163207ac75b1Sopenharmony_ci  });
163307ac75b1Sopenharmony_ci  resetEtsStandaloneCheckerConfig(beforeInitFastBuildLogger, beforeInitCompileMode);
163407ac75b1Sopenharmony_ci}
163507ac75b1Sopenharmony_ci
163607ac75b1Sopenharmony_ciexport function resetEtsCheckTypeScript(): void {
163707ac75b1Sopenharmony_ci  if (globalProgram.program) {
163807ac75b1Sopenharmony_ci    globalProgram.program.releaseTypeChecker();
163907ac75b1Sopenharmony_ci  } else if (languageService) {
164007ac75b1Sopenharmony_ci    languageService.getProgram().releaseTypeChecker();
164107ac75b1Sopenharmony_ci  }
164207ac75b1Sopenharmony_ci  resetGlobalProgram();
164307ac75b1Sopenharmony_ci  languageService = null;
164407ac75b1Sopenharmony_ci}
164507ac75b1Sopenharmony_ci
164607ac75b1Sopenharmony_ciexport function resetEtsCheck(): void {
164707ac75b1Sopenharmony_ci  cache = {};
164807ac75b1Sopenharmony_ci  props = [];
164907ac75b1Sopenharmony_ci  needReCheckForChangedDepUsers = false;
165007ac75b1Sopenharmony_ci  resetEtsCheckTypeScript();
165107ac75b1Sopenharmony_ci  allResolvedModules.clear();
165207ac75b1Sopenharmony_ci  checkerResult.count = 0;
165307ac75b1Sopenharmony_ci  warnCheckerResult.count = 0;
165407ac75b1Sopenharmony_ci  resolvedModulesCache.clear();
165507ac75b1Sopenharmony_ci  dollarCollection.clear();
165607ac75b1Sopenharmony_ci  extendCollection.clear();
165707ac75b1Sopenharmony_ci  allSourceFilePaths.clear();
165807ac75b1Sopenharmony_ci  allModuleIds.clear();
165907ac75b1Sopenharmony_ci  filesBuildInfo.clear();
166007ac75b1Sopenharmony_ci  fileExistsCache.clear();
166107ac75b1Sopenharmony_ci  dirExistsCache.clear();
166207ac75b1Sopenharmony_ci  targetESVersionChanged = false;
166307ac75b1Sopenharmony_ci  fileToIgnoreDiagnostics = undefined;
166407ac75b1Sopenharmony_ci}
1665