!562 fix watch mode syntax check.

Merge pull request !562 from lihong/watch
This commit is contained in:
openharmony_ci
2022-04-14 02:26:29 +00:00
committed by Gitee
5 changed files with 144 additions and 79 deletions
+4 -1
View File
@@ -322,7 +322,10 @@ function hashProjectPath(projectPath) {
return process.env.hashProjectPath;
}
const globalProgram = { program: null };
const globalProgram = {
program: null,
watchProgram: null
};
exports.globalProgram = globalProgram;
exports.projectConfig = projectConfig;
+49 -27
View File
@@ -41,11 +41,9 @@ import {
import { MODULE_SHARE_PATH, BUILD_SHARE_PATH } from './pre_define';
import {
createLanguageService,
dollarCollection,
appComponentCollection,
decoratorParamsCollection,
extendCollection,
importModuleCollection
importModuleCollection,
createWatchCompilerHost
} from './ets_checker';
import { globalProgram } from '../main';
@@ -156,29 +154,21 @@ export class ResultStates {
Object.values(projectConfig.entryObj).forEach((fileName: string) => {
rootFileNames.push(fileName.replace('?entry', ''));
});
const languageService: ts.LanguageService = createLanguageService(rootFileNames);
globalProgram.program = languageService.getProgram();
const rootProgram: ts.Program = globalProgram.program;
props.push(...dollarCollection, ...decoratorParamsCollection, ...extendCollection);
let allDiagnostics: ts.Diagnostic[] = rootProgram
.getSyntacticDiagnostics()
.concat(rootProgram.getSemanticDiagnostics())
.concat(rootProgram.getDeclarationDiagnostics());
allDiagnostics = allDiagnostics.filter((item) => {
return this.validateError(ts.flattenDiagnosticMessageText(item.messageText, '\n'));
});
this.mErrorCount += allDiagnostics.length;
allDiagnostics.forEach((diagnostic: ts.Diagnostic) => {
const message: string = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
if (diagnostic.file) {
const { line, character }: ts.LineAndCharacter =
diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
logger.error(this.red,
`ETS:ERROR File: ${diagnostic.file.fileName}:${line + 1}:${character + 1}\n ${message}\n`);
} else {
logger.error(this.red, `ETS:ERROR: ${message}`);
}
});
if (process.env.watchMode === 'true') {
globalProgram.watchProgram = ts.createWatchProgram(
createWatchCompilerHost(rootFileNames, this.printDiagnostic.bind(this),
this.delayPrintLogCount.bind(this)));
} else {
const languageService: ts.LanguageService = createLanguageService(rootFileNames);
globalProgram.program = languageService.getProgram();
const allDiagnostics: ts.Diagnostic[] = globalProgram.program
.getSyntacticDiagnostics()
.concat(globalProgram.program.getSemanticDiagnostics())
.concat(globalProgram.program.getDeclarationDiagnostics());
allDiagnostics.forEach((diagnostic: ts.Diagnostic) => {
this.printDiagnostic(diagnostic);
});
}
});
compiler.hooks.done.tap('Result States', (stats: Stats) => {
@@ -214,6 +204,21 @@ export class ResultStates {
}
}
private printDiagnostic(diagnostic: ts.Diagnostic): void {
const message: string = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
if (this.validateError(message)) {
this.mErrorCount += 1;
if (diagnostic.file) {
const { line, character }: ts.LineAndCharacter =
diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!);
logger.error(this.red,
`ETS:ERROR File: ${diagnostic.file.fileName}:${line + 1}:${character + 1}\n ${message}\n`);
} else {
logger.error(this.red, `ETS:ERROR: ${message}`);
}
}
}
private writeUseOSFiles(): void {
let info: string = '';
if (!fs.existsSync(projectConfig.aceSoPath)) {
@@ -230,6 +235,23 @@ export class ResultStates {
private printResult(): void {
this.printWarning();
this.printError();
if (process.env.watchMode === 'true') {
process.env.watchEts = 'end';
this.delayPrintLogCount();
} else {
this.printLogCount();
}
}
private delayPrintLogCount() {
if (process.env.watchEts === 'end' && process.env.watchTs === 'end') {
this.printLogCount();
process.env.watchEts = 'start';
process.env.watchTs = 'start';
}
}
private printLogCount(): void {
if (this.mErrorCount + this.warningCount + this.noteCount > 0) {
let result: string;
let resultInfo: string = '';
+87 -49
View File
@@ -35,6 +35,7 @@ import {
import { JS_BIND_COMPONENTS } from './component_map';
import { getName } from './process_component_build';
import { INNER_COMPONENT_NAMES } from './component_map';
import { props } from './compile_info';
function readDeaclareFiles(): string[] {
const declarationsFileNames: string[] = [];
@@ -47,14 +48,15 @@ function readDeaclareFiles(): string[] {
return declarationsFileNames;
}
export function createLanguageService(rootFileNames: string[]): ts.LanguageService {
const compilerOptions: ts.CompilerOptions = ts.readConfigFile(
path.resolve(__dirname, '../tsconfig.json'), ts.sys.readFile).config.compilerOptions;
const compilerOptions: ts.CompilerOptions = ts.readConfigFile(
path.resolve(__dirname, '../tsconfig.json'), ts.sys.readFile).config.compilerOptions;
function setCompilerOptions() {
Object.assign(compilerOptions, {
'allowJs': false,
'importsNotUsedAsValues': ts.ImportsNotUsedAsValues.Preserve,
'module': ts.ModuleKind.CommonJS,
'moduleResolution': ts.ModuleResolutionKind.NodeJs,
'noEmit': true,
'target': ts.ScriptTarget.ES2017,
'baseUrl': path.resolve(projectConfig.projectPath),
'paths': {
@@ -67,6 +69,10 @@ export function createLanguageService(rootFileNames: string[]): ts.LanguageServi
'lib.es2020.d.ts'
]
});
}
export function createLanguageService(rootFileNames: string[]): ts.LanguageService {
setCompilerOptions();
const files: ts.MapLike<{ version: number }> = {};
const servicesHost: ts.LanguageServiceHost = {
getScriptFileNames: () => [...rootFileNames, ...readDeaclareFiles()],
@@ -88,57 +94,88 @@ export function createLanguageService(rootFileNames: string[]): ts.LanguageServi
fileExists: ts.sys.fileExists,
readFile: ts.sys.readFile,
readDirectory: ts.sys.readDirectory,
resolveModuleNames(moduleNames: string[], containingFile: string): ts.ResolvedModuleFull[] {
const resolvedModules: ts.ResolvedModuleFull[] = [];
for (const moduleName of moduleNames) {
const result = ts.resolveModuleName(moduleName, containingFile, compilerOptions, {
fileExists(fileName: string): boolean {
return ts.sys.fileExists(fileName);
},
readFile(fileName: string): string | undefined {
return ts.sys.readFile(fileName);
}
});
if (result.resolvedModule) {
resolvedModules.push(result.resolvedModule);
} else if (/^@(system|ohos)/.test(moduleName.trim())) {
const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts');
if (ts.sys.fileExists(modulePath)) {
resolvedModules.push(getResolveModule(modulePath, '.d.ts'));
} else {
resolvedModules.push(null);
}
} else if (/\.ets$/.test(moduleName)) {
const modulePath: string = path.resolve(path.dirname(containingFile), moduleName);
if (ts.sys.fileExists(modulePath)) {
resolvedModules.push(getResolveModule(modulePath, '.ets'));
} else {
resolvedModules.push(null);
}
} else if (/\.ts$/.test(moduleName)) {
const modulePath: string = path.resolve(path.dirname(containingFile), moduleName);
if (ts.sys.fileExists(modulePath)) {
resolvedModules.push(getResolveModule(modulePath, '.ts'));
} else {
resolvedModules.push(null);
}
} else {
const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts');
if (ts.sys.fileExists(modulePath)) {
resolvedModules.push(getResolveModule(modulePath, '.d.ts'));
} else {
resolvedModules.push(null);
}
}
}
return resolvedModules;
},
resolveModuleNames: resolveModuleNames,
directoryExists: ts.sys.directoryExists,
getDirectories: ts.sys.getDirectories
};
return ts.createLanguageService(servicesHost, ts.createDocumentRegistry());
}
function resolveModuleNames(moduleNames: string[], containingFile: string): ts.ResolvedModuleFull[] {
const resolvedModules: ts.ResolvedModuleFull[] = [];
for (const moduleName of moduleNames) {
const result = ts.resolveModuleName(moduleName, containingFile, compilerOptions, {
fileExists(fileName: string): boolean {
return ts.sys.fileExists(fileName);
},
readFile(fileName: string): string | undefined {
return ts.sys.readFile(fileName);
}
});
if (result.resolvedModule) {
resolvedModules.push(result.resolvedModule);
} else if (/^@(system|ohos)/.test(moduleName.trim())) {
const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts');
if (ts.sys.fileExists(modulePath)) {
resolvedModules.push(getResolveModule(modulePath, '.d.ts'));
} else {
resolvedModules.push(null);
}
} else if (/\.ets$/.test(moduleName)) {
const modulePath: string = path.resolve(path.dirname(containingFile), moduleName);
if (ts.sys.fileExists(modulePath)) {
resolvedModules.push(getResolveModule(modulePath, '.ets'));
} else {
resolvedModules.push(null);
}
} else if (/\.ts$/.test(moduleName)) {
const modulePath: string = path.resolve(path.dirname(containingFile), moduleName);
if (ts.sys.fileExists(modulePath)) {
resolvedModules.push(getResolveModule(modulePath, '.ts'));
} else {
resolvedModules.push(null);
}
} else {
const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts');
if (ts.sys.fileExists(modulePath)) {
resolvedModules.push(getResolveModule(modulePath, '.d.ts'));
} else {
resolvedModules.push(null);
}
}
}
return resolvedModules;
}
export function createWatchCompilerHost(rootFileNames: string[],
reportDiagnostic: ts.DiagnosticReporter, delayPrintLogCount: Function
): ts.WatchCompilerHostOfFilesAndCompilerOptions<ts.BuilderProgram> {
setCompilerOptions();
const createProgram = ts.createSemanticDiagnosticsBuilderProgram;
const host = ts.createWatchCompilerHost(
[...rootFileNames, ...readDeaclareFiles()], compilerOptions,
ts.sys, createProgram, reportDiagnostic,
(diagnostic: ts.Diagnostic) => {
// End of compilation in watch mode flag.
if ([6193, 6194].includes(diagnostic.code)) {
process.env.watchTs = 'end';
delayPrintLogCount();
}
});
host.readFile = (fileName: string) => {
if (!fs.existsSync(fileName)) {
return undefined;
}
if (/(?<!\.d)\.(ets|ts)$/.test(fileName)) {
checkUISyntax(fs.readFileSync(fileName).toString(), fileName);
return processContent(fs.readFileSync(fileName).toString());
}
return fs.readFileSync(fileName).toString();
};
host.resolveModuleNames = resolveModuleNames;
return host;
}
function getResolveModule(modulePath: string, type): ts.ResolvedModuleFull {
return {
resolvedFileName: modulePath,
@@ -160,13 +197,14 @@ function checkUISyntax(source: string, fileName: string): void {
ts.ScriptTarget.Latest, true, ts.ScriptKind.ETS);
collectComponents(sourceFile);
parseAllNode(sourceFile, sourceFile);
props.push(...dollarCollection, ...decoratorParamsCollection, ...extendCollection);
}
}
}
function collectComponents(node: ts.SourceFile): void {
// @ts-ignore
if (node.identifiers && node.identifiers.size) {
if (process.env.watchMode !== 'true' && node.identifiers && node.identifiers.size) {
// @ts-ignore
for (const key of node.identifiers.keys()) {
if (JS_BIND_COMPONENTS.has(key)) {
+2
View File
@@ -689,6 +689,8 @@ export function isSimpleType(typeNode: ts.TypeNode, program: ts.Program): boolea
let checker: ts.TypeChecker;
if (globalProgram.program) {
checker = globalProgram.program.getTypeChecker();
} else if (globalProgram.watchProgram) {
checker = globalProgram.watchProgram.getCurrentProgram().getProgram().getTypeChecker();
} else if (program) {
checker = program.getTypeChecker();
}
+2 -2
View File
@@ -33,13 +33,13 @@ const { processUISyntax } = require('./lib/process_ui_syntax');
const { IGNORE_ERROR_CODE } = require('./lib/utils');
const { BUILD_SHARE_PATH } = require('./lib/pre_define');
const watchMode = (process.env.watchMode && process.env.watchMode === 'true') || false;
process.env.watchMode = (process.env.watchMode && process.env.watchMode === 'true') || 'false';
function initConfig(config) {
const projectPath = path.resolve(projectConfig.projectPath);
Object.assign(config, {
entry: projectConfig.entryObj,
watch: watchMode,
watch: process.env.watchMode === 'true',
watchOptions: {
aggregateTimeout: 10,
poll: false,