Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/server/editorServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1304,7 +1304,7 @@ namespace ts.server {
// Closing file should trigger re-reading the file content from disk. This is
// because the user may chose to discard the buffer content before saving
// to the disk, and the server's version of the file can be out of sync.
const fileExists = this.host.fileExists(info.fileName);
const fileExists = info.isDynamic ? false : this.host.fileExists(info.fileName);
info.close(fileExists);
this.stopWatchingConfigFilesForClosedScriptInfo(info);

Expand Down
3 changes: 2 additions & 1 deletion src/server/scriptInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ namespace ts.server {

/*@internal*/
export function isDynamicFileName(fileName: NormalizedPath) {
return fileName[0] === "^";
return fileName[0] === "^" ||
(stringContains(fileName, ":^") && !stringContains(fileName, directorySeparator));
}

/*@internal*/
Expand Down
1 change: 1 addition & 0 deletions src/testRunner/unittests/tsserver/externalProjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ namespace ts.projectSystem {

checkNumberOfExternalProjects(projectService, 1);
checkNumberOfInferredProjects(projectService, 0);
verifyDynamic(projectService, "/^scriptdocument1 file1.ts");

externalFiles[0].content = "let x =1;";
projectService.applyChangesInOpenFiles(arrayIterator(externalFiles));
Expand Down
3 changes: 3 additions & 0 deletions src/testRunner/unittests/tsserver/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,7 @@ namespace ts.projectSystem {
const project = projectService.inferredProjects[0];
checkProjectRootFiles(project, [file.path]);
checkProjectActualFiles(project, [file.path, libFile.path]);
verifyDynamic(projectService, `/${file.path}`);

assert.strictEqual(projectService.ensureDefaultProjectForFile(server.toNormalizedPath(file.path)), project);
const indexOfX = file.content.indexOf("x");
Expand Down Expand Up @@ -1124,6 +1125,7 @@ var x = 10;`
const host = createServerHost([libFile]);
const projectService = createProjectService(host);
projectService.openClientFile(file.path, file.content);
verifyDynamic(projectService, projectService.toPath(file.path));

projectService.checkNumberOfProjects({ inferredProjects: 1 });
const project = projectService.inferredProjects[0];
Expand Down Expand Up @@ -1152,6 +1154,7 @@ var x = 10;`
const projectService = session.getProjectService();
checkNumberOfProjects(projectService, { inferredProjects: 1 });
checkProjectActualFiles(projectService.inferredProjects[0], [file.path, libFile.path]);
verifyDynamic(projectService, `${tscWatch.projectRoot}/${file.path}`);

session.executeCommandSeq<protocol.OutliningSpansRequest>({
command: protocol.CommandTypes.GetOutliningSpans,
Expand Down
44 changes: 41 additions & 3 deletions src/testRunner/unittests/tsserver/untitledFiles.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
namespace ts.projectSystem {
export function verifyDynamic(service: server.ProjectService, path: string) {
const info = Debug.assertDefined(service.filenameToScriptInfo.get(path), `Expected ${path} in :: ${JSON.stringify(arrayFrom(service.filenameToScriptInfo.entries(), ([key, f]) => ({ key, fileName: f.fileName, path: f.path })))}`);
assert.isTrue(info.isDynamic);
}

describe("unittests:: tsserver:: Untitled files", () => {
const untitledFile = "untitled:^Untitled-1";
it("Can convert positions to locations", () => {
const aTs: File = { path: "/proj/a.ts", content: "" };
const tsconfig: File = { path: "/proj/tsconfig.json", content: "{}" };
const session = createSession(createServerHost([aTs, tsconfig]));
const session = createSession(createServerHost([aTs, tsconfig]), { useInferredProjectPerProjectRoot: true });

openFilesForSession([aTs], session);

const untitledFile = "untitled:^Untitled-1";
executeSessionRequestNoResponse<protocol.OpenRequest>(session, protocol.CommandTypes.Open, {
file: untitledFile,
fileContent: `/// <reference path="../../../../../../typings/@epic/Core.d.ts" />\nlet foo = 1;\nfooo/**/`,
scriptKindName: "TS",
projectRootPath: "/proj",
});

verifyDynamic(session.getProjectService(), `/proj/untitled:^untitled-1`);
const response = executeSessionRequest<protocol.CodeFixRequest, protocol.CodeFixResponse>(session, protocol.CommandTypes.GetCodeFixes, {
file: untitledFile,
startLine: 3,
Expand All @@ -41,5 +46,38 @@ namespace ts.projectSystem {
},
]);
});

it("opening untitled files", () => {
const config: File = {
path: `${tscWatch.projectRoot}/tsconfig.json`,
content: "{}"
};
const host = createServerHost([config, libFile], { useCaseSensitiveFileNames: true, currentDirectory: tscWatch.projectRoot });
const service = createProjectService(host);
service.openClientFile(untitledFile, "const x = 10;", /*scriptKind*/ undefined, tscWatch.projectRoot);
checkNumberOfProjects(service, { inferredProjects: 1 });
checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]);
verifyDynamic(service, `${tscWatch.projectRoot}/${untitledFile}`);

const untitled: File = {
path: `${tscWatch.projectRoot}/Untitled-1.ts`,
content: "const x = 10;"
};
host.writeFile(untitled.path, untitled.content);
host.checkTimeoutQueueLength(0);
service.openClientFile(untitled.path, untitled.content, /*scriptKind*/ undefined, tscWatch.projectRoot);
checkNumberOfProjects(service, { configuredProjects: 1, inferredProjects: 1 });
checkProjectActualFiles(service.configuredProjects.get(config.path)!, [untitled.path, libFile.path, config.path]);
checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]);

service.closeClientFile(untitledFile);
checkProjectActualFiles(service.configuredProjects.get(config.path)!, [untitled.path, libFile.path, config.path]);
checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]);

service.openClientFile(untitledFile, "const x = 10;", /*scriptKind*/ undefined, tscWatch.projectRoot);
verifyDynamic(service, `${tscWatch.projectRoot}/${untitledFile}`);
checkProjectActualFiles(service.configuredProjects.get(config.path)!, [untitled.path, libFile.path, config.path]);
checkProjectActualFiles(service.inferredProjects[0], [untitledFile, libFile.path]);
});
});
}