diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 603a78b5f75..9c61c3b1e27 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -282,6 +282,8 @@ module FourSlash { return new Harness.LanguageService.NativeLanugageServiceAdapter(cancellationToken, compilationOptions); case FourSlashTestType.Shims: return new Harness.LanguageService.ShimLanugageServiceAdapter(cancellationToken, compilationOptions); + case FourSlashTestType.Server: + return new Harness.LanguageService.ServerLanugageServiceAdapter(cancellationToken, compilationOptions); default: throw new Error("Unknown FourSlash test type: "); } diff --git a/src/harness/fourslashRunner.ts b/src/harness/fourslashRunner.ts index fe3b6c7a91f..1ab6e31cdbb 100644 --- a/src/harness/fourslashRunner.ts +++ b/src/harness/fourslashRunner.ts @@ -4,7 +4,8 @@ const enum FourSlashTestType { Native, - Shims + Shims, + Server } class FourSlashRunner extends RunnerBase { @@ -22,6 +23,10 @@ class FourSlashRunner extends RunnerBase { this.basePath = 'tests/cases/fourslash/shims'; this.testSuiteName = 'fourslash-shims'; break; + case FourSlashTestType.Server: + this.basePath = 'tests/cases/fourslash/server'; + this.testSuiteName = 'fourslash-server'; + break; } } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 534bf85d119..cbc4064119a 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -16,14 +16,15 @@ /// /// +/// +/// +/// /// /// /// /// -declare var require: any; -declare var process: any; -var Buffer = require('buffer').Buffer; +var Buffer: BufferConstructor = require('buffer').Buffer; // this will work in the browser via browserify var _chai: typeof chai = require('chai'); diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 2f95f5072d0..eb0daf74dcf 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -1,5 +1,6 @@ /// /// +/// /// module Harness.LanguageService { @@ -23,18 +24,18 @@ module Harness.LanguageService { this.version++; } - public editContent(minChar: number, limChar: number, newText: string): void { + public editContent(start: number, end: number, newText: string): void { // Apply edits - var prefix = this.content.substring(0, minChar); + var prefix = this.content.substring(0, start); var middle = newText; - var suffix = this.content.substring(limChar); + var suffix = this.content.substring(end); this.setContent(prefix + middle + suffix); // Store edit range + new length of script this.editRanges.push({ length: this.content.length, textChangeRange: ts.createTextChangeRange( - ts.createTextSpanFromBounds(minChar, limChar), newText.length) + ts.createTextSpanFromBounds(start, end), newText.length) }); // Update version # @@ -127,9 +128,7 @@ module Harness.LanguageService { protected settings = ts.getDefaultCompilerOptions()) { } - public getNewLine(): string { - return "\r\n"; - } + public getNewLine(): string { return "\r\n"; } public getFilenames(): string[] { var fileNames: string[] = []; @@ -145,20 +144,10 @@ module Harness.LanguageService { this.fileNameToScript[fileName] = new ScriptInfo(fileName, content); } - public updateScript(fileName: string, content: string) { + public editScript(fileName: string, start: number, end: number, newText: string) { var script = this.getScriptInfo(fileName); if (script !== null) { - script.updateContent(content); - return; - } - - this.addScript(fileName, content); - } - - public editScript(fileName: string, minChar: number, limChar: number, newText: string) { - var script = this.getScriptInfo(fileName); - if (script !== null) { - script.editContent(minChar, limChar, newText); + script.editContent(start, end, newText); return; } @@ -236,8 +225,7 @@ module Harness.LanguageService { getFilenames(): string[] { return this.nativeHost.getFilenames(); } getScriptInfo(fileName: string): ScriptInfo { return this.nativeHost.getScriptInfo(fileName); } addScript(fileName: string, content: string): void { this.nativeHost.addScript(fileName, content); } - updateScript(fileName: string, content: string): void { return this.nativeHost.updateScript(fileName, content); } - editScript(fileName: string, minChar: number, limChar: number, newText: string): void { this.nativeHost.editScript(fileName, minChar, limChar, newText); } + editScript(fileName: string, start: number, end: number, newText: string): void { this.nativeHost.editScript(fileName, start, end, newText); } lineColToPosition(fileName: string, line: number, col: number): number { return this.nativeHost.lineColToPosition(fileName, line, col); } positionToZeroBasedLineCol(fileName: string, position: number): ts.LineAndCharacter { return this.nativeHost.positionToZeroBasedLineCol(fileName, position); } @@ -442,5 +430,43 @@ module Harness.LanguageService { return convertResult; } } + + // Server adapter + class ServerLanguageServiceHost extends NativeLanguageServiceHost { + private client: ts.server.SessionClient; + constructor(cancellationToken: ts.CancellationToken, settings: ts.CompilerOptions) { + super(cancellationToken, settings); + } + + setClient(client: ts.server.SessionClient) { + this.client = client; + } + + addScript(fileName: string, content: string): void { + super.addScript(fileName, content); + this.client.openFile(fileName); + } + + editScript(fileName: string, start: number, end: number, newText: string) { + super.editScript(fileName, start, end, newText); + this.client.changeFile(fileName, start, end, newText); + } + } + + export class ServerLanugageServiceAdapter implements LanguageServiceAdapter { + private host: ServerLanguageServiceHost; + private client: ts.server.SessionClient; + constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { + debugger; + + this.host = new ServerLanguageServiceHost(cancellationToken, options); + this.client = new ts.server.SessionClient(this.host); + this.host.setClient(this.client); + } + getHost() { return this.host; } + getLanguageService(): ts.LanguageService { return this.client; } + getClassifier(): ts.Classifier { throw new Error("getClassifier is not available using the server interface."); } + getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { throw new Error("getPreProcessedFileInfo is not available using the server interface."); } + } } \ No newline at end of file diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 942ae56bf6f..e1e5429b007 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -66,6 +66,9 @@ if (testConfigFile !== '') { case 'fourslash-shims': runners.push(new FourSlashRunner(FourSlashTestType.Shims)); break; + case 'fourslash-server': + runners.push(new FourSlashRunner(FourSlashTestType.Server)); + break; case 'fourslash-generated': runners.push(new GeneratedFourslashRunner(FourSlashTestType.Native)); break; @@ -95,6 +98,7 @@ if (runners.length === 0) { // language services runners.push(new FourSlashRunner(FourSlashTestType.Native)); runners.push(new FourSlashRunner(FourSlashTestType.Shims)); + runners.push(new FourSlashRunner(FourSlashTestType.Server)); //runners.push(new GeneratedFourslashRunner()); }