Skip to content

Commit

Permalink
fix: race condition in workspace scanner (#212)
Browse files Browse the repository at this point in the history
This time without the infinite loop for workspaces with circular
references.
  • Loading branch information
wkillerud authored Aug 24, 2024
1 parent e0b0af6 commit 099a54b
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 20 deletions.
37 changes: 22 additions & 15 deletions packages/language-server/src/workspace-scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,22 @@ export default class WorkspaceScanner {
uri = URI.parse(file.toString().replace("/static/extensions/fs", ""));
}

const alreadyParsed = this.#ls.hasCached(uri);
if (alreadyParsed) {
// The same file may be referenced by multiple other files,
// so skip doing the parsing work if it's already been done.
// Changes to the file are handled by the `update` method.
return;
}

try {
// TODO: figure out what caused the loop
const content = await this.#fs.readFile(uri);
let document: TextDocument | null | undefined =
this.#ls.getCachedTextDocument(uri);

const document = getSCSSRegionsDocument(
TextDocument.create(uri.toString(), "scss", 1, content),
);
if (!document) return;
if (!document) {
const content = await this.#fs.readFile(uri);

document = getSCSSRegionsDocument(
TextDocument.create(uri.toString(), "scss", 1, content),
);
if (!document) return;
}

this.#ls.parseStylesheet(document);
const links = await this.#ls.findDocumentLinks(document);

for (const link of links) {
if (
!link.target ||
Expand All @@ -81,8 +79,17 @@ export default class WorkspaceScanner {
continue;
}

let uri = URI.parse(link.target);
let visited: TextDocument | null | undefined =
this.#ls.getCachedTextDocument(uri);

if (visited) {
// avoid infinite loop if circular references
continue;
}

try {
await this.parse(URI.parse(link.target), depth + 1);
await this.parse(uri, depth + 1);
} catch {
// do nothing
}
Expand Down
2 changes: 1 addition & 1 deletion packages/language-services/src/language-services-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export interface LanguageService {
range: Range,
context?: CodeActionContext,
): Promise<CodeAction[]>;
hasCached(uri: URI): boolean;
getCachedTextDocument(uri: URI): TextDocument | undefined;
/**
* Utility function to reparse an updated document.
* Like {@link LanguageService.parseStylesheet}, but returns nothing.
Expand Down
4 changes: 2 additions & 2 deletions packages/language-services/src/language-services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ class LanguageServiceImpl implements LanguageService {
return this.#findSymbols.findWorkspaceSymbols(query);
}

hasCached(uri: URI): boolean {
return this.#cache.has(uri.toString());
getCachedTextDocument(uri: URI): TextDocument | undefined {
return this.#cache.getDocument(uri.toString());
}

getColorPresentations(document: TextDocument, color: Color, range: Range) {
Expand Down
4 changes: 2 additions & 2 deletions vscode-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
"build": "webpack --mode development",
"start:web": "vscode-test-web --browserType=chromium --extensionDevelopmentPath=.",
"lint": "eslint \"**/*.ts\" --cache",
"test:e2e": "node ./test/e2e/runTest.js",
"test:e2e": "node ./test/e2e/runTest.js && node ./test/new-e2e/runTest.js",
"pretest:web": "webpack --config ./webpack.test-web.config.js ",
"test:web": "node ./test/web/runTest.js"
},
Expand All @@ -141,4 +141,4 @@
"publisherId": "02638283-c13a-4acf-9f26-24bdcfdfce24",
"isPreReleaseVersion": false
}
}
}

0 comments on commit 099a54b

Please sign in to comment.