Skip to content

Commit 313e400

Browse files
committed
wip: add Project#addFile/Project#updateFile/Project#deleteFile/
1 parent 7b8fa93 commit 313e400

File tree

1 file changed

+79
-25
lines changed

1 file changed

+79
-25
lines changed

packages/codegen/src/project.ts

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,20 @@ interface ProjectArgs {
2121

2222
interface Project {
2323
config: CMKConfig;
24-
// TODO: Implement these methods later for watch mode
25-
// /** Whether the file matches the wildcard patterns in `include` / `exclude` options */
26-
// isWildcardMatchedFile(fileName: string): boolean;
27-
// /**
28-
// * Add a file to the project.
29-
// * @throws {ReadCSSModuleFileError}
30-
// */
31-
// addFile(fileName: string): void;
32-
// /**
33-
// * Update a file in the project.
34-
// * @throws {ReadCSSModuleFileError}
35-
// */
36-
// updateFile(fileName: string): void;
37-
// /** Remove a file from the project. */
38-
// removeFile(fileName: string): void;
24+
/** Whether the file matches the wildcard patterns in `include` / `exclude` options */
25+
isWildcardMatchedFile(fileName: string): boolean;
26+
/**
27+
* Add a file to the project.
28+
* @throws {ReadCSSModuleFileError}
29+
*/
30+
addFile(fileName: string): void;
31+
/**
32+
* Update a file in the project.
33+
* @throws {ReadCSSModuleFileError}
34+
*/
35+
updateFile(fileName: string): void;
36+
/** Remove a file from the project. */
37+
removeFile(fileName: string): void;
3938
/**
4039
* Get all diagnostics.
4140
* Including three types of diagnostics: project diagnostics, syntactic diagnostics, and semantic diagnostics.
@@ -72,16 +71,64 @@ export function createProject(args: ProjectArgs): Project {
7271
const resolver = createResolver(config.compilerOptions, moduleResolutionCache);
7372
const matchesPattern = createMatchesPattern(config);
7473

75-
const parseStageCache = new Map<string, CSSModule>();
76-
const checkStageCache = new Map<string, Diagnostic[]>();
77-
const getCSSModule = (path: string) => parseStageCache.get(path);
74+
const cssModuleMap = new Map<string, CSSModule>();
75+
const semanticDiagnosticsMap = new Map<string, Diagnostic[]>();
76+
// Tracks whether .d.ts has been emitted after the last change
77+
const emittedSet = new Set<string>();
78+
const getCSSModule = (path: string) => cssModuleMap.get(path);
7879
const exportBuilder = createExportBuilder({ getCSSModule, matchesPattern, resolver });
7980

8081
for (const fileName of getFileNamesByPattern(config)) {
8182
// NOTE: Files may be deleted between executing `getFileNamesByPattern` and `tryParseCSSModule`.
8283
// Therefore, `tryParseCSSModule` may return `undefined`.
8384
const cssModule = tryParseCSSModule(fileName);
84-
if (cssModule) parseStageCache.set(fileName, cssModule);
85+
if (cssModule) cssModuleMap.set(fileName, cssModule);
86+
}
87+
88+
/**
89+
* @throws {ReadCSSModuleFileError}
90+
*/
91+
function addFile(fileName: string) {
92+
if (cssModuleMap.has(fileName)) return;
93+
94+
const cssModule = tryParseCSSModule(fileName);
95+
if (!cssModule) return;
96+
cssModuleMap.set(fileName, cssModule);
97+
98+
// TODO: Delete only the minimum amount of check stage cache
99+
moduleResolutionCache.clear();
100+
exportBuilder.clearCache();
101+
semanticDiagnosticsMap.clear();
102+
}
103+
104+
/**
105+
* @throws {ReadCSSModuleFileError}
106+
*/
107+
function updateFile(fileName: string) {
108+
if (!cssModuleMap.has(fileName)) return;
109+
110+
const cssModule = tryParseCSSModule(fileName);
111+
if (!cssModule) return;
112+
cssModuleMap.set(fileName, cssModule);
113+
114+
// TODO: Delete only the minimum amount of check stage cache
115+
exportBuilder.clearCache();
116+
semanticDiagnosticsMap.clear();
117+
118+
emittedSet.delete(fileName);
119+
}
120+
121+
function removeFile(fileName: string) {
122+
if (!cssModuleMap.has(fileName)) return;
123+
124+
cssModuleMap.delete(fileName);
125+
126+
// TODO: Delete only the minimum amount of check stage cache
127+
moduleResolutionCache.clear();
128+
exportBuilder.clearCache();
129+
semanticDiagnosticsMap.delete(fileName);
130+
131+
emittedSet.delete(fileName);
85132
}
86133

87134
/**
@@ -119,7 +166,7 @@ export function createProject(args: ProjectArgs): Project {
119166
function getProjectDiagnostics() {
120167
const diagnostics: Diagnostic[] = [];
121168
diagnostics.push(...config.diagnostics);
122-
if (parseStageCache.size === 0) {
169+
if (cssModuleMap.size === 0) {
123170
diagnostics.push({
124171
category: 'error',
125172
text: `The file specified in tsconfig.json not found.`,
@@ -129,16 +176,16 @@ export function createProject(args: ProjectArgs): Project {
129176
}
130177

131178
function getSyntacticDiagnostics() {
132-
return Array.from(parseStageCache.values()).flatMap(({ diagnostics }) => diagnostics);
179+
return Array.from(cssModuleMap.values()).flatMap(({ diagnostics }) => diagnostics);
133180
}
134181

135182
function getSemanticDiagnostics() {
136183
const allDiagnostics: Diagnostic[] = [];
137-
for (const cssModule of parseStageCache.values()) {
138-
let diagnostics = checkStageCache.get(cssModule.fileName);
184+
for (const cssModule of cssModuleMap.values()) {
185+
let diagnostics = semanticDiagnosticsMap.get(cssModule.fileName);
139186
if (!diagnostics) {
140187
diagnostics = checkCSSModule(cssModule, config, exportBuilder, matchesPattern, resolver, getCSSModule);
141-
checkStageCache.set(cssModule.fileName, diagnostics);
188+
semanticDiagnosticsMap.set(cssModule.fileName, diagnostics);
142189
}
143190
allDiagnostics.push(...diagnostics);
144191
}
@@ -150,13 +197,16 @@ export function createProject(args: ProjectArgs): Project {
150197
*/
151198
async function emitDtsFiles(): Promise<void> {
152199
const promises: Promise<void>[] = [];
153-
for (const cssModule of parseStageCache.values()) {
200+
for (const cssModule of cssModuleMap.values()) {
201+
if (emittedSet.has(cssModule.fileName)) continue;
154202
const dts = generateDts(cssModule, { resolver, matchesPattern }, { ...config, forTsPlugin: false });
155203
promises.push(
156204
writeDtsFile(dts.text, cssModule.fileName, {
157205
outDir: config.dtsOutDir,
158206
basePath: config.basePath,
159207
arbitraryExtensions: config.arbitraryExtensions,
208+
}).then(() => {
209+
emittedSet.add(cssModule.fileName);
160210
}),
161211
);
162212
}
@@ -165,6 +215,10 @@ export function createProject(args: ProjectArgs): Project {
165215

166216
return {
167217
config,
218+
isWildcardMatchedFile: (fileName) => matchesPattern(fileName),
219+
addFile,
220+
updateFile,
221+
removeFile,
168222
getDiagnostics,
169223
emitDtsFiles,
170224
};

0 commit comments

Comments
 (0)