Skip to content

Commit 20da159

Browse files
Merge pull request microsoft#18127 from RyanCavanaugh/port18120_release25
Don't crash when a JS file appears in an inferred context
2 parents 6ffe829 + 6425ea2 commit 20da159

File tree

3 files changed

+35
-15
lines changed

3 files changed

+35
-15
lines changed

src/harness/unittests/tsserverProjectSystem.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,6 +1760,28 @@ namespace ts.projectSystem {
17601760
checkProjectActualFiles(projectService.externalProjects[0], [file1.path, file2.path, file3.path]);
17611761
});
17621762

1763+
it("regression test for crash in acquireOrUpdateDocument", () => {
1764+
const tsFile = {
1765+
fileName: "/a/b/file1.ts",
1766+
path: "/a/b/file1.ts",
1767+
content: ""
1768+
};
1769+
const jsFile = {
1770+
path: "/a/b/file1.js",
1771+
content: "var x = 10;",
1772+
fileName: "/a/b/file1.js",
1773+
scriptKind: "JS" as "JS"
1774+
};
1775+
1776+
const host = createServerHost([]);
1777+
const projectService = createProjectService(host);
1778+
projectService.applyChangesInOpenFiles([tsFile], [], []);
1779+
const projs = projectService.synchronizeProjectList([]);
1780+
projectService.findProject(projs[0].info.projectName).getLanguageService().getNavigationBarItems(tsFile.fileName);
1781+
projectService.synchronizeProjectList([projs[0].info]);
1782+
projectService.applyChangesInOpenFiles([jsFile], [], []);
1783+
});
1784+
17631785
it("config file is deleted", () => {
17641786
const file1 = {
17651787
path: "/a/b/f1.ts",
@@ -1860,7 +1882,7 @@ namespace ts.projectSystem {
18601882

18611883
// Open HTML file
18621884
projectService.applyChangesInOpenFiles(
1863-
/*openFiles*/ [{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }],
1885+
/*openFiles*/[{ fileName: file2.path, hasMixedContent: true, scriptKind: ScriptKind.JS, content: `var hello = "hello";` }],
18641886
/*changedFiles*/ undefined,
18651887
/*closedFiles*/ undefined);
18661888

@@ -1877,7 +1899,7 @@ namespace ts.projectSystem {
18771899
projectService.applyChangesInOpenFiles(
18781900
/*openFiles*/ undefined,
18791901
/*changedFiles*/ undefined,
1880-
/*closedFiles*/ [file2.path]);
1902+
/*closedFiles*/[file2.path]);
18811903

18821904
// HTML file is still included in project
18831905
checkNumberOfProjects(projectService, { configuredProjects: 1 });
@@ -3308,7 +3330,7 @@ namespace ts.projectSystem {
33083330
const error1Result = <protocol.Diagnostic[]>session.executeCommand(dTsFile1GetErrRequest).response;
33093331
assert.isTrue(error1Result.length === 0);
33103332

3311-
const dTsFile2GetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
3333+
const dTsFile2GetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
33123334
CommandNames.SemanticDiagnosticsSync,
33133335
{ file: dTsFile2.path }
33143336
);

src/server/editorServices.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1609,7 +1609,7 @@ namespace ts.server {
16091609
if (openFiles) {
16101610
for (const file of openFiles) {
16111611
const scriptInfo = this.getScriptInfo(file.fileName);
1612-
Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen());
1612+
Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already");
16131613
const normalizedPath = scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName);
16141614
this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent);
16151615
}

src/services/documentRegistry.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,12 @@ namespace ts {
173173
const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true);
174174
let entry = bucket.get(path);
175175
if (!entry) {
176-
Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?");
177-
178176
// Have never seen this file with these settings. Create a new source file for it.
179177
const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false, scriptKind);
180178

181179
entry = {
182180
sourceFile,
183-
languageServiceRefCount: 0,
181+
languageServiceRefCount: 1,
184182
owners: []
185183
};
186184
bucket.set(path, entry);
@@ -193,15 +191,15 @@ namespace ts {
193191
entry.sourceFile = updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version,
194192
scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot));
195193
}
196-
}
197194

198-
// If we're acquiring, then this is the first time this LS is asking for this document.
199-
// Increase our ref count so we know there's another LS using the document. If we're
200-
// not acquiring, then that means the LS is 'updating' the file instead, and that means
201-
// it has already acquired the document previously. As such, we do not need to increase
202-
// the ref count.
203-
if (acquiring) {
204-
entry.languageServiceRefCount++;
195+
// If we're acquiring, then this is the first time this LS is asking for this document.
196+
// Increase our ref count so we know there's another LS using the document. If we're
197+
// not acquiring, then that means the LS is 'updating' the file instead, and that means
198+
// it has already acquired the document previously. As such, we do not need to increase
199+
// the ref count.
200+
if (acquiring) {
201+
entry.languageServiceRefCount++;
202+
}
205203
}
206204

207205
return entry.sourceFile;

0 commit comments

Comments
 (0)