diff --git a/compiler/src/compile_info.ts b/compiler/src/compile_info.ts index 681f5f6..bbdab83 100644 --- a/compiler/src/compile_info.ts +++ b/compiler/src/compile_info.ts @@ -71,6 +71,7 @@ interface Info { export interface CacheFileName { mtimeMs: number, children: string[], + parent: string[], error: boolean } @@ -78,7 +79,8 @@ interface NeedUpdateFlag { flag: boolean; } -export let cache: Cache; +export let cache: Cache = {}; +export const shouldResolvedFiles: Set = new Set() type Cache = Record; export class ResultStates { @@ -223,6 +225,18 @@ export class ResultStates { } }); + compiler.hooks.watchRun.tap('WatchRun', (comp) => { + comp.modifiedFiles = comp.modifiedFiles || []; + comp.removedFiles = comp.removedFiles || []; + const changedFiles: string[] = [...comp.modifiedFiles, ...comp.removedFiles]; + if (changedFiles.length) { + shouldResolvedFiles.clear(); + } + changedFiles.forEach((file) => { + this.judgeFileShouldResolved(file, shouldResolvedFiles) + }) + }) + compiler.hooks.done.tap('Result States', (stats: Stats) => { if (projectConfig.isPreview && projectConfig.aceSoPath && useOSFiles && useOSFiles.size > 0) { @@ -241,6 +255,25 @@ export class ResultStates { }); } + private judgeFileShouldResolved(file: string, shouldResolvedFiles: Set): void { + if (shouldResolvedFiles.has(file)) { + return; + } + shouldResolvedFiles.add(file); + if (cache && cache[file] && cache[file].parent) { + cache[file].parent.forEach((item)=>{ + this.judgeFileShouldResolved(item, shouldResolvedFiles); + }) + cache[file].parent = []; + } + if (cache && cache[file] && cache[file].children) { + cache[file].children.forEach((item)=>{ + this.judgeFileShouldResolved(item, shouldResolvedFiles); + }) + cache[file].children = []; + } + } + private printDiagnostic(diagnostic: ts.Diagnostic): void { const message: string = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); if (this.validateError(message)) { diff --git a/compiler/src/ets_checker.ts b/compiler/src/ets_checker.ts index 6dab74f..b1c2cc5 100644 --- a/compiler/src/ets_checker.ts +++ b/compiler/src/ets_checker.ts @@ -42,7 +42,8 @@ import { props } from './compile_info'; import { resolveSourceFile } from './resolve_ohm_url'; import { CacheFileName, - cache + cache, + shouldResolvedFiles } from './compile_info'; import { hasDecorator } from './utils'; import { isExtendFunction, isOriginalExtend } from './process_ui_syntax'; @@ -136,68 +137,74 @@ function getOhmUrlFile(moduleName: string): {modulePath: string, suffix: string} return {modulePath, suffix}; } +const resolvedModulesCache: Map = new Map(); + 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 (/^@bundle:/.test(moduleName.trim())) { - const module: {modulePath: string, suffix: string} = getOhmUrlFile(moduleName.trim()); - if (ts.sys.fileExists(module.modulePath)) { - resolvedModules.push(getResolveModule(module.modulePath, module.suffix)); + if (![...shouldResolvedFiles].length || shouldResolvedFiles.has(path.resolve(containingFile))) { + 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 (/^@bundle:/.test(moduleName.trim())) { + const module: {modulePath: string, suffix: string} = getOhmUrlFile(moduleName.trim()); + if (ts.sys.fileExists(module.modulePath)) { + resolvedModules.push(getResolveModule(module.modulePath, module.suffix)); + } else { + resolvedModules.push(null); + } + } else if (/^@(system|ohos)\./i.test(moduleName.trim())) { + const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts'); + if (systemModules.includes(moduleName + '.d.ts') && 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 { - resolvedModules.push(null); - } - } else if (/^@(system|ohos)\./i.test(moduleName.trim())) { - const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts'); - if (systemModules.includes(moduleName + '.d.ts') && 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'); - const suffix: string = /\.js$/.test(moduleName) ? '' : '.js'; - const jsModulePath: string = path.resolve(__dirname, '../node_modules', moduleName + suffix); - const fileModulePath: string = - path.resolve(__dirname, '../node_modules', moduleName + '/index.js'); - if (ts.sys.fileExists(modulePath)) { - resolvedModules.push(getResolveModule(modulePath, '.d.ts')); - } else if (ts.sys.fileExists(jsModulePath)) { - resolvedModules.push(getResolveModule(jsModulePath, '.js')); - } else if (ts.sys.fileExists(fileModulePath)) { - resolvedModules.push(getResolveModule(fileModulePath, '.js')); - } else { - resolvedModules.push(null); + const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts'); + const suffix: string = /\.js$/.test(moduleName) ? '' : '.js'; + const jsModulePath: string = path.resolve(__dirname, '../node_modules', moduleName + suffix); + const fileModulePath: string = + path.resolve(__dirname, '../node_modules', moduleName + '/index.js'); + if (ts.sys.fileExists(modulePath)) { + resolvedModules.push(getResolveModule(modulePath, '.d.ts')); + } else if (ts.sys.fileExists(jsModulePath)) { + resolvedModules.push(getResolveModule(jsModulePath, '.js')); + } else if (ts.sys.fileExists(fileModulePath)) { + resolvedModules.push(getResolveModule(fileModulePath, '.js')); + } else { + resolvedModules.push(null); + } } } + if (!projectConfig.xtsMode) { + createOrUpdateCache(resolvedModules, containingFile); + } + resolvedModulesCache[path.resolve(containingFile)] = resolvedModules + return resolvedModules; } - if (process.env.watchMode !== 'true' && !projectConfig.xtsMode) { - createOrUpdateCache(resolvedModules, containingFile); - } - return resolvedModules; + return resolvedModulesCache[path.resolve(containingFile)]; } function createOrUpdateCache(resolvedModules: ts.ResolvedModuleFull[], containingFile: string): void { @@ -212,12 +219,16 @@ function createOrUpdateCache(resolvedModules: ts.ResolvedModuleFull[], containin if (value) { value.mtimeMs = mtimeMs; value.error = error; + value.parent.push(path.resolve(containingFile)); + value.parent = [...new Set(value.parent)]; } else { - cache[file] = { mtimeMs, children: [], error }; + cache[file] = { mtimeMs, children: [], parent: [containingFile], error }; } } }); - cache[path.resolve(containingFile)] = { mtimeMs: fs.statSync(containingFile).mtimeMs, children, error }; + cache[path.resolve(containingFile)] = { mtimeMs: fs.statSync(containingFile).mtimeMs, children, + parent: cache[path.resolve(containingFile)] && cache[path.resolve(containingFile)].parent ? + cache[path.resolve(containingFile)].parent : [], error }; } export function createWatchCompilerHost(rootFileNames: string[],