diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts
index 457ece7e13271..c4c70553940bc 100644
--- a/src/harness/fourslash.ts
+++ b/src/harness/fourslash.ts
@@ -373,17 +373,17 @@ namespace FourSlash {
}
// Opens a file given its 0-based index or fileName
- public openFile(index: number): void;
- public openFile(name: string): void;
- public openFile(indexOrName: any) {
- let fileToOpen: FourSlashFile = this.findFile(indexOrName);
+ public openFile(index: number, content?: string): void;
+ public openFile(name: string, content?: string): void;
+ public openFile(indexOrName: any, content?: string) {
+ const fileToOpen: FourSlashFile = this.findFile(indexOrName);
fileToOpen.fileName = ts.normalizeSlashes(fileToOpen.fileName);
this.activeFile = fileToOpen;
- let fileName = fileToOpen.fileName.replace(Harness.IO.directoryName(fileToOpen.fileName), "").substr(1);
+ const fileName = fileToOpen.fileName.replace(Harness.IO.directoryName(fileToOpen.fileName), "").substr(1);
this.scenarioActions.push(``);
// Let the host know that this file is now open
- this.languageServiceAdapterHost.openFile(fileToOpen.fileName);
+ this.languageServiceAdapterHost.openFile(fileToOpen.fileName, content);
}
public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, negative: boolean) {
diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts
index df5efccdcb5ea..0f427944eaca2 100644
--- a/src/harness/harnessLanguageService.ts
+++ b/src/harness/harnessLanguageService.ts
@@ -153,7 +153,7 @@ namespace Harness.LanguageService {
throw new Error("No script with name '" + fileName + "'");
}
- public openFile(fileName: string): void {
+ public openFile(fileName: string, content?: string): void {
}
/**
@@ -493,9 +493,9 @@ namespace Harness.LanguageService {
this.client = client;
}
- openFile(fileName: string): void {
- super.openFile(fileName);
- this.client.openFile(fileName);
+ openFile(fileName: string, content?: string): void {
+ super.openFile(fileName, content);
+ this.client.openFile(fileName, content);
}
editScript(fileName: string, start: number, end: number, newText: string) {
diff --git a/src/server/client.ts b/src/server/client.ts
index ae234750d88da..08939b2b44aca 100644
--- a/src/server/client.ts
+++ b/src/server/client.ts
@@ -120,8 +120,8 @@ namespace ts.server {
return response;
}
- openFile(fileName: string): void {
- var args: protocol.FileRequestArgs = { file: fileName };
+ openFile(fileName: string, content?: string): void {
+ var args: protocol.OpenRequestArgs = { file: fileName, fileContent: content };
this.processRequest(CommandNames.Open, args);
}
diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts
index 304be55804eb8..31ba66fb31a1d 100644
--- a/src/server/editorServices.ts
+++ b/src/server/editorServices.ts
@@ -992,14 +992,15 @@ namespace ts.server {
/**
* @param filename is absolute pathname
+ * @param fileContent is a known version of the file content that is more up to date than the one on disk
*/
- openFile(fileName: string, openedByClient: boolean) {
+ openFile(fileName: string, openedByClient: boolean, fileContent?: string) {
fileName = ts.normalizePath(fileName);
- var info = ts.lookUp(this.filenameToScriptInfo, fileName);
+ let info = ts.lookUp(this.filenameToScriptInfo, fileName);
if (!info) {
- var content: string;
+ let content: string;
if (this.host.fileExists(fileName)) {
- content = this.host.readFile(fileName);
+ content = fileContent || this.host.readFile(fileName);
}
if (!content) {
if (openedByClient) {
@@ -1017,6 +1018,9 @@ namespace ts.server {
}
}
if (info) {
+ if (fileContent) {
+ info.svc.reload(fileContent);
+ }
if (openedByClient) {
info.isOpen = true;
}
@@ -1047,10 +1051,11 @@ namespace ts.server {
/**
* Open file whose contents is managed by the client
* @param filename is absolute pathname
+ * @param fileContent is a known version of the file content that is more up to date than the one on disk
*/
- openClientFile(fileName: string) {
+ openClientFile(fileName: string, fileContent?: string) {
this.openOrUpdateConfiguredProjectForFile(fileName);
- var info = this.openFile(fileName, true);
+ const info = this.openFile(fileName, true, fileContent);
this.addOpenFile(info);
this.printProjects();
return info;
diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts
index ce918abda3c7e..77df56c05bdc4 100644
--- a/src/server/protocol.d.ts
+++ b/src/server/protocol.d.ts
@@ -513,6 +513,11 @@ declare namespace ts.server.protocol {
* Information found in an "open" request.
*/
export interface OpenRequestArgs extends FileRequestArgs {
+ /**
+ * Used when a version of the file content is known to be more up to date than the one on disk.
+ * Then the known content will be used upon opening instead of the disk copy
+ */
+ fileContent?: string;
}
/**
diff --git a/src/server/session.ts b/src/server/session.ts
index 550b551e51a5b..5a937bf1a1730 100644
--- a/src/server/session.ts
+++ b/src/server/session.ts
@@ -4,7 +4,7 @@
///
namespace ts.server {
- var spaceCache:string[] = [];
+ const spaceCache: string[] = [];
interface StackTraceError extends Error {
stack?: string;
@@ -531,9 +531,13 @@ namespace ts.server {
};
}
- private openClientFile(fileName: string) {
- var file = ts.normalizePath(fileName);
- this.projectService.openClientFile(file);
+ /**
+ * @param fileName is the name of the file to be opened
+ * @param fileContent is a version of the file content that is known to be more up to date than the one on disk
+ */
+ private openClientFile(fileName: string, fileContent?: string) {
+ const file = ts.normalizePath(fileName);
+ this.projectService.openClientFile(file, fileContent);
}
private getQuickInfo(line: number, offset: number, fileName: string): protocol.QuickInfoResponseBody {
@@ -966,7 +970,7 @@ namespace ts.server {
},
[CommandNames.Open]: (request: protocol.Request) => {
var openArgs = request.arguments;
- this.openClientFile(openArgs.file);
+ this.openClientFile(openArgs.file, openArgs.fileContent);
return {responseRequired: false}
},
[CommandNames.Quickinfo]: (request: protocol.Request) => {
diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts
index 41e8d9005f762..f6451e1f1c4cc 100644
--- a/tests/cases/fourslash/fourslash.ts
+++ b/tests/cases/fourslash/fourslash.ts
@@ -169,10 +169,10 @@ module FourSlashInterface {
// Opens a file, given either its index as it
// appears in the test source, or its filename
// as specified in the test metadata
- public file(index: number);
- public file(name: string);
- public file(indexOrName: any) {
- FourSlash.currentTestState.openFile(indexOrName);
+ public file(index: number, content?: string);
+ public file(name: string, content?: string);
+ public file(indexOrName: any, content?: string) {
+ FourSlash.currentTestState.openFile(indexOrName, content);
}
}
diff --git a/tests/cases/fourslash/server/openFile.ts b/tests/cases/fourslash/server/openFile.ts
new file mode 100644
index 0000000000000..320e52c9f5e1a
--- /dev/null
+++ b/tests/cases/fourslash/server/openFile.ts
@@ -0,0 +1,16 @@
+///
+
+// @Filename: test1.ts
+////t.
+
+// @Filename: test.ts
+////var t = '10';
+
+// @Filename: tsconfig.json
+////{ "files": ["test.ts", "test1.ts"] }
+
+var overridingContent = "var t = 10; t.";
+goTo.file("test.ts", overridingContent);
+goTo.file("test1.ts");
+goTo.eof();
+verify.completionListContains("toExponential");