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