1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import path from 'path'; 17import { EventEmitter } from 'events'; 18import * as ts from 'typescript'; 19 20import { 21 projectConfig, 22 globalProgram 23} from '../../../main'; 24import { 25 serviceChecker, 26 languageService, 27 printDiagnostic, 28 fastBuildLogger, 29 emitBuildInfo 30} from '../../ets_checker'; 31import { TS_WATCH_END_MSG } from '../../pre_define'; 32import { 33 setChecker, 34 startTimeStatisticsLocation, 35 stopTimeStatisticsLocation, 36 CompilationTimeStatistics 37} from '../../utils'; 38import { configureSyscapInfo } from "../system_api/api_check_utils"; 39 40export let tsWatchEmitter: EventEmitter | undefined = undefined; 41export let tsWatchEndPromise: Promise<void>; 42 43export function etsChecker() { 44 let executedOnce: boolean = false; 45 return { 46 name: 'etsChecker', 47 buildStart() { 48 if (projectConfig.useArkoala) { 49 return; 50 } 51 const compilationTime: CompilationTimeStatistics = new CompilationTimeStatistics(this.share, 'etsChecker', 'buildStart'); 52 if (process.env.watchMode === 'true' && process.env.triggerTsWatch === 'true') { 53 tsWatchEmitter = new EventEmitter(); 54 tsWatchEndPromise = new Promise<void>(resolve => { 55 tsWatchEmitter.on(TS_WATCH_END_MSG, () => { 56 resolve(); 57 }); 58 }); 59 } 60 if (this.share.projectConfig.deviceTypes) { 61 configureSyscapInfo(this.share.projectConfig); 62 } 63 Object.assign(projectConfig, this.share.projectConfig); 64 Object.assign(this.share.projectConfig, { 65 compileHar: projectConfig.compileHar, 66 compileShared: projectConfig.compileShared, 67 moduleRootPath: projectConfig.moduleRootPath, 68 buildPath: projectConfig.buildPath, 69 isCrossplatform: projectConfig.isCrossplatform, 70 syscapIntersectionSet: projectConfig.syscapIntersectionSet, 71 syscapUnionSet: projectConfig.syscapUnionSet, 72 deviceTypesMessage: projectConfig.deviceTypesMessage, 73 }); 74 const logger = this.share.getLogger('etsChecker'); 75 const rootFileNames: string[] = []; 76 const resolveModulePaths: string[] = []; 77 Object.values(projectConfig.entryObj).forEach((fileName: string) => { 78 rootFileNames.push(path.resolve(fileName)); 79 }); 80 if (this.share && this.share.projectConfig && this.share.projectConfig.resolveModulePaths && 81 Array.isArray(this.share.projectConfig.resolveModulePaths)) { 82 resolveModulePaths.push(...this.share.projectConfig.resolveModulePaths); 83 } 84 if (process.env.watchMode === 'true') { 85 !executedOnce && serviceChecker(rootFileNames, logger, resolveModulePaths, compilationTime); 86 startTimeStatisticsLocation(compilationTime ? compilationTime.diagnosticTime : undefined); 87 if (executedOnce) { 88 globalProgram.builderProgram = languageService.getBuilderProgram(); 89 globalProgram.program = globalProgram.builderProgram.getProgram(); 90 } 91 executedOnce = true; 92 const allDiagnostics: ts.Diagnostic[] = globalProgram.builderProgram 93 .getSyntacticDiagnostics() 94 .concat(globalProgram.builderProgram.getSemanticDiagnostics()); 95 stopTimeStatisticsLocation(compilationTime ? compilationTime.diagnosticTime : undefined); 96 emitBuildInfo(); 97 allDiagnostics.forEach((diagnostic: ts.Diagnostic) => { 98 printDiagnostic(diagnostic); 99 }); 100 fastBuildLogger.debug(TS_WATCH_END_MSG); 101 tsWatchEmitter.emit(TS_WATCH_END_MSG); 102 } else { 103 serviceChecker(rootFileNames, logger, resolveModulePaths, compilationTime, this.share); 104 } 105 setChecker(); 106 } 107 }; 108} 109