From d8fb8a967f2d8fab7f46bc379947c67446ff2a4b Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 2 Feb 2015 20:06:33 -0800 Subject: [PATCH 01/14] Remove unused NonCachingDocumentRegistry --- src/harness/harnessLanguageService.ts | 28 --------------------------- 1 file changed, 28 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 1d442822866..47fe720f094 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -94,34 +94,6 @@ module Harness.LanguageService { } } - export class NonCachingDocumentRegistry implements ts.DocumentRegistry { - public static Instance: ts.DocumentRegistry = new NonCachingDocumentRegistry(); - - public acquireDocument( - fileName: string, - compilationSettings: ts.CompilerOptions, - scriptSnapshot: ts.IScriptSnapshot, - version: string): ts.SourceFile { - var sourceFile = ts.createSourceFile(fileName, scriptSnapshot.getText(0, scriptSnapshot.getLength()), compilationSettings.target); - sourceFile.version = version; - return sourceFile; - } - - public updateDocument( - document: ts.SourceFile, - fileName: string, - compilationSettings: ts.CompilerOptions, - scriptSnapshot: ts.IScriptSnapshot, - version: string, - textChangeRange: ts.TextChangeRange - ): ts.SourceFile { - return ts.updateLanguageServiceSourceFile(document, scriptSnapshot, version, textChangeRange); - } - - public releaseDocument(fileName: string, compilationSettings: ts.CompilerOptions): void { - // no op since this class doesn't cache anything - } - } export class TypeScriptLS implements ts.LanguageServiceShimHost { private ls: ts.LanguageServiceShim = null; From f56e7ea743277f7ae6588c98fc44cd0297d136a8 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 2 Feb 2015 20:23:54 -0800 Subject: [PATCH 02/14] Add a new scriptSnapshot and use the shim as a wrapper --- src/harness/harnessLanguageService.ts | 37 +++++++++++++++++++-------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 47fe720f094..6eab17957e9 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -1,5 +1,6 @@ /// /// +/// module Harness.LanguageService { export class ScriptInfo { @@ -54,15 +55,10 @@ module Harness.LanguageService { } } - class ScriptSnapshotShim implements ts.ScriptSnapshotShim { - private lineMap: number[] = null; - private textSnapshot: string; - private version: number; - - constructor(private scriptInfo: ScriptInfo) { - this.textSnapshot = scriptInfo.content; - this.version = scriptInfo.version; - } + class ScriptSnapshot implements ts.IScriptSnapshot { + public textSnapshot: string; public version: number; + constructor(public scriptInfo: ScriptInfo) { + this.textSnapshot = scriptInfo.content; this.version = scriptInfo.version; } public getText(start: number, end: number): string { return this.textSnapshot.substring(start, end); @@ -72,9 +68,28 @@ module Harness.LanguageService { return this.textSnapshot.length; } + public getChangeRange(oldScript: ts.IScriptSnapshot): ts.TextChangeRange { + var oldShim = oldScript; + return this.scriptInfo.getTextChangeRangeBetweenVersions(oldShim.version, this.version); + } + } + + class ScriptSnapshotShim implements ts.ScriptSnapshotShim { + constructor(public scriptSnapshot: ScriptSnapshot) { + } + + public getText(start: number, end: number): string { + return this.scriptSnapshot.getText(start, end); + } + + public getLength(): number { + return this.scriptSnapshot.getLength(); + } + public getChangeRange(oldScript: ts.ScriptSnapshotShim): string { var oldShim = oldScript; - var range = this.scriptInfo.getTextChangeRangeBetweenVersions(oldShim.version, this.version); + + var range = this.scriptSnapshot.getChangeRange(oldShim.scriptSnapshot); if (range === null) { return null; } @@ -194,7 +209,7 @@ module Harness.LanguageService { public getScriptSnapshot(fileName: string): ts.ScriptSnapshotShim { if (this.contains(fileName)) { - return new ScriptSnapshotShim(this.getScriptInfo(fileName)); + return new ScriptSnapshotShim(new ScriptSnapshot(this.getScriptInfo(fileName))); } return undefined; } From c3bf36e78300e46424fdee5697b1485a108f4ad9 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 3 Feb 2015 12:40:37 -0800 Subject: [PATCH 03/14] Add missing definition to shims --- src/services/shims.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/services/shims.ts b/src/services/shims.ts index c9f33914e09..e917323efe7 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -89,6 +89,7 @@ module ts { getCompilerOptionsDiagnostics(): string; getSyntacticClassifications(fileName: string, start: number, length: number): string; + getSemanticClassifications(fileName: string, start: number, length: number): string; getCompletionsAtPosition(fileName: string, position: number): string; getCompletionEntryDetails(fileName: string, position: number, entryName: string): string; From 7a4a8107dd5d934acd743ef7b75494bf40ebf229 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 3 Feb 2015 12:41:12 -0800 Subject: [PATCH 04/14] Add reference to base runner --- src/harness/harness.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 79defabadeb..52884744535 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -19,6 +19,7 @@ /// /// /// +/// declare var require: any; declare var process: any; From 4c06838d608c831921c274632db2112a2bec74a6 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 3 Feb 2015 17:28:16 -0800 Subject: [PATCH 05/14] Add new Adaptor layer on top of Harness Language Service --- src/harness/harnessLanguageService.ts | 335 +++++++++++++++++++++++++- 1 file changed, 329 insertions(+), 6 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 6eab17957e9..9316ef813c6 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -75,7 +75,7 @@ module Harness.LanguageService { } class ScriptSnapshotShim implements ts.ScriptSnapshotShim { - constructor(public scriptSnapshot: ScriptSnapshot) { + constructor(public scriptSnapshot: ts.IScriptSnapshot) { } public getText(start: number, end: number): string { @@ -109,6 +109,334 @@ module Harness.LanguageService { } } + export interface LanugageServiceAdaptor { + getHost(): LanguageServiceAdaptorHost; + getLanguageService(): ts.LanguageService; + getClassifier(): ts.Classifier; + getPreProcessedFileInfo(filename: string, fileContents: string): ts.PreProcessedFileInfo; + } + + class LanguageServiceHostBase { + protected fileNameToScript: ts.Map = {}; + + constructor(protected cancellationToken: ts.CancellationToken = CancellationToken.None, + protected settings = ts.getDefaultCompilerOptions()) { + + } + + public getFilenames(): string[] { + var fileNames: string[] = []; + ts.forEachKey(this.fileNameToScript,(fileName) => { fileNames.push(fileName); }); + return fileNames; + } + + public getScriptInfo(fileName: string): ScriptInfo { + return ts.lookUp(this.fileNameToScript, fileName); + } + + public addScript(fileName: string, content: string): void { + this.fileNameToScript[fileName] = new ScriptInfo(fileName, content); + } + + public updateScript(fileName: string, content: 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); + return; + } + + throw new Error("No script with name '" + fileName + "'"); + } + + /** + * @param line 1 based index + * @param col 1 based index + */ + public lineColToPosition(fileName: string, line: number, col: number): number { + var script: ScriptInfo = this.fileNameToScript[fileName]; + assert.isNotNull(script); + assert.isTrue(line >= 1); + assert.isTrue(col >= 1); + + return ts.getPositionFromLineAndCharacter(script.lineMap, line, col); + } + + /** + * @param line 0 based index + * @param col 0 based index + */ + public positionToZeroBasedLineCol(fileName: string, position: number): ts.LineAndCharacter { + var script: ScriptInfo = this.fileNameToScript[fileName]; + assert.isNotNull(script); + + var result = ts.getLineAndCharacterOfPosition(script.lineMap, position); + + assert.isTrue(result.line >= 1); + assert.isTrue(result.character >= 1); + return { line: result.line - 1, character: result.character - 1 }; + } + } + + export interface LanguageServiceAdaptorHost extends LanguageServiceHostBase { + } + + /// Native adabtor + class NativeLanguageServiceHost extends LanguageServiceHostBase implements ts.LanguageServiceHost { + getCompilationSettings(): ts.CompilerOptions { return this.settings; } + getCancellationToken(): ts.CancellationToken { return this.cancellationToken; } + getCurrentDirectory(): string { return ""; } + getDefaultLibFilename(): string { return ""; } + getScriptFileNames(): string[] { return this.getFilenames(); } + getScriptSnapshot(filename: string): ts.IScriptSnapshot { + var script = this.getScriptInfo(filename); + return script ? new ScriptSnapshot(script) : undefined; + } + getScriptVersion(filename: string): string { + var script = this.getScriptInfo(filename); + return script ? script.version.toString() : undefined; + } + log(s: string): void { } + trace(s: string): void { } + error(s: string): void { } + } + + export class NativeLanugageServiceAdaptor implements LanugageServiceAdaptor { + private host: NativeLanguageServiceHost; + constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { + this.host = new NativeLanguageServiceHost(cancellationToken, options); + } + getHost() { return this.host; } + getLanguageService(): ts.LanguageService { return ts.createLanguageService(this.host); } + getClassifier(): ts.Classifier { return ts.createClassifier(); } + getPreProcessedFileInfo(filename: string, fileContents: string): ts.PreProcessedFileInfo { return ts.preProcessFile(fileContents); } + } + + /// Shim adabtor + class ShimLanguageServiceHost extends LanguageServiceHostBase implements ts.LanguageServiceShimHost { + private nativeHost: NativeLanguageServiceHost; + constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { + super(cancellationToken, options); + this.nativeHost = new NativeLanguageServiceHost(cancellationToken, options); + } + + 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); } + 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); } + + getCompilationSettings(): string { return JSON.stringify(this.nativeHost.getCompilationSettings()); } + getCancellationToken(): ts.CancellationToken { return this.nativeHost.getCancellationToken(); } + getCurrentDirectory(): string { return this.nativeHost.getCurrentDirectory(); } + getDefaultLibFilename(): string { return this.nativeHost.getDefaultLibFilename(); } + getScriptFileNames(): string { return JSON.stringify(this.nativeHost.getScriptFileNames()); } + getScriptSnapshot(filename: string): ts.ScriptSnapshotShim { + var nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(filename); + return nativeScriptSnapshot && new ScriptSnapshotShim(nativeScriptSnapshot); + } + getScriptVersion(filename: string): string { return this.nativeHost.getScriptVersion(filename); } + getLocalizedDiagnosticMessages(): string { return JSON.stringify({}); } + log(s: string): void { this.nativeHost.log(s); } + trace(s: string): void { this.nativeHost.trace(s); } + error(s: string): void { this.nativeHost.error(s); } + } + + class ClassifierShimProxy implements ts.Classifier { + constructor(private shim: ts.ClassifierShim) { } + getClassificationsForLine(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.ClassificationResult { + var result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split('\n'); + var entries: ts.ClassificationInfo[] = []; + var i = 0; + var position = 0; + + for (; i < result.length - 1; i += 2) { + var t = entries[i / 2] = { + length: parseInt(result[i]), + classification: parseInt(result[i + 1]) + }; + + assert.isTrue(t.length > 0, "Result length should be greater than 0, got :" + t.length); + position += t.length; + } + var finalLexState = parseInt(result[result.length - 1]); + + assert.equal(position, text.length, "Expected cumulative length of all entries to match the length of the source. expected: " + text.length + ", but got: " + position); + + return { + finalLexState, + entries + }; + } + } + + function unwrappJSONCallResult(result: string): any { + var parsedResult = JSON.parse(result); + if (parsedResult.error) { + throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error)); + } + else if (parsedResult.canceled) { + throw new ts.OperationCanceledException(); + } + return parsedResult.result; + } + + class LanguageServiceShimProxy implements ts.LanguageService { + constructor(private shim: ts.LanguageServiceShim) { } + private unwrappJSONCallResult(result: string): any { + var parsedResult = JSON.parse(result); + if (parsedResult.error) { + throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error)); + } + return parsedResult.result; + } + cleanupSemanticCache(): void { + this.shim.cleanupSemanticCache(); + } + getSyntacticDiagnostics(fileName: string): ts.Diagnostic[] { + return unwrappJSONCallResult(this.shim.getSyntacticDiagnostics(fileName)); + } + getSemanticDiagnostics(fileName: string): ts.Diagnostic[] { + return unwrappJSONCallResult(this.shim.getSemanticDiagnostics(fileName)); + } + getCompilerOptionsDiagnostics(): ts.Diagnostic[] { + return unwrappJSONCallResult(this.shim.getCompilerOptionsDiagnostics()); + } + getSyntacticClassifications(fileName: string, span: ts.TextSpan): ts.ClassifiedSpan[] { + return unwrappJSONCallResult(this.shim.getSyntacticClassifications(fileName, span.start, span.length)); + } + getSemanticClassifications(fileName: string, span: ts.TextSpan): ts.ClassifiedSpan[] { + return unwrappJSONCallResult(this.shim.getSemanticClassifications(fileName, span.start, span.length)); + } + getCompletionsAtPosition(fileName: string, position: number): ts.CompletionInfo { + return unwrappJSONCallResult(this.shim.getCompletionsAtPosition(fileName, position)); + } + getCompletionEntryDetails(fileName: string, position: number, entryName: string): ts.CompletionEntryDetails { + return unwrappJSONCallResult(this.shim.getCompletionEntryDetails(fileName, position, entryName)); + } + getQuickInfoAtPosition(fileName: string, position: number): ts.QuickInfo { + return unwrappJSONCallResult(this.shim.getQuickInfoAtPosition(fileName, position)); + } + getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): ts.TextSpan { + return unwrappJSONCallResult(this.shim.getNameOrDottedNameSpan(fileName, startPos, endPos)); + } + getBreakpointStatementAtPosition(fileName: string, position: number): ts.TextSpan { + return unwrappJSONCallResult(this.shim.getBreakpointStatementAtPosition(fileName, position)); + } + getSignatureHelpItems(fileName: string, position: number): ts.SignatureHelpItems { + return unwrappJSONCallResult(this.shim.getSignatureHelpItems(fileName, position)); + } + getRenameInfo(fileName: string, position: number): ts.RenameInfo { + return unwrappJSONCallResult(this.shim.getRenameInfo(fileName, position)); + } + findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): ts.RenameLocation[] { + return unwrappJSONCallResult(this.shim.findRenameLocations(fileName, position, findInStrings, findInComments)); + } + getDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] { + return unwrappJSONCallResult(this.shim.getDefinitionAtPosition(fileName, position)); + } + getReferencesAtPosition(fileName: string, position: number): ts.ReferenceEntry[] { + return unwrappJSONCallResult(this.shim.getReferencesAtPosition(fileName, position)); + } + getOccurrencesAtPosition(fileName: string, position: number): ts.ReferenceEntry[] { + return unwrappJSONCallResult(this.shim.getOccurrencesAtPosition(fileName, position)); + } + getNavigateToItems(searchValue: string): ts.NavigateToItem[] { + return unwrappJSONCallResult(this.shim.getNavigateToItems(searchValue)); + } + getNavigationBarItems(fileName: string): ts.NavigationBarItem[] { + return unwrappJSONCallResult(this.shim.getNavigationBarItems(fileName)); + } + getOutliningSpans(fileName: string): ts.OutliningSpan[] { + return unwrappJSONCallResult(this.shim.getOutliningSpans(fileName)); + } + getTodoComments(fileName: string, descriptors: ts.TodoCommentDescriptor[]): ts.TodoComment[] { + return unwrappJSONCallResult(this.shim.getTodoComments(fileName, JSON.stringify(descriptors))); + } + getBraceMatchingAtPosition(fileName: string, position: number): ts.TextSpan[] { + return unwrappJSONCallResult(this.shim.getBraceMatchingAtPosition(fileName, position)); + } + getIndentationAtPosition(fileName: string, position: number, options: ts.EditorOptions): number { + return unwrappJSONCallResult(this.shim.getIndentationAtPosition(fileName, position, JSON.stringify(options))); + } + getFormattingEditsForRange(fileName: string, start: number, end: number, options: ts.FormatCodeOptions): ts.TextChange[] { + return unwrappJSONCallResult(this.shim.getFormattingEditsForRange(fileName, start, end, JSON.stringify(options))); + } + getFormattingEditsForDocument(fileName: string, options: ts.FormatCodeOptions): ts.TextChange[] { + return unwrappJSONCallResult(this.shim.getFormattingEditsForDocument(fileName, JSON.stringify(options))); + } + getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: ts.FormatCodeOptions): ts.TextChange[] { + return unwrappJSONCallResult(this.shim.getFormattingEditsAfterKeystroke(fileName, position, key, JSON.stringify(options))); + } + getEmitOutput(fileName: string): ts.EmitOutput { + return unwrappJSONCallResult(this.shim.getEmitOutput(fileName)); + } + getProgram(): ts.Program { + throw new Error("Program can not be marshalled accross the shim layer."); + } + getSourceFile(filename: string): ts.SourceFile { + throw new Error("SourceFile can not be marshalled accross the shim layer."); + } + dispose(): void { this.shim.dispose({}); } + } + + export class ShimLanugageServiceAdaptor implements LanugageServiceAdaptor { + private host: ShimLanguageServiceHost; + private factory: ts.TypeScriptServicesFactory; + constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { + this.host = new ShimLanguageServiceHost(cancellationToken, options); + this.factory = new TypeScript.Services.TypeScriptServicesFactory(); + } + getHost() { return this.host; } + getLanguageService(): ts.LanguageService { return new LanguageServiceShimProxy(this.factory.createLanguageServiceShim(this.host)); } + getClassifier(): ts.Classifier { return new ClassifierShimProxy(this.factory.createClassifierShim(this.host)); } + getPreProcessedFileInfo(filename: string, fileContents: string): ts.PreProcessedFileInfo { + var shimResult: { + referencedFiles: ts.IFileReference[]; + importedFiles: ts.IFileReference[]; + isLibFile: boolean; + }; + + var coreServicesShim = this.factory.createCoreServicesShim(this.host); + shimResult = unwrappJSONCallResult(coreServicesShim.getPreProcessedFileInfo(filename, ts.ScriptSnapshot.fromString(fileContents))); + + var convertResult: ts.PreProcessedFileInfo = { + referencedFiles: [], + importedFiles: [], + isLibFile: shimResult.isLibFile + }; + + ts.forEach(shimResult.referencedFiles, refFile => { + convertResult.referencedFiles.push({ + filename: refFile.path, + pos: refFile.position, + end: refFile.position + refFile.length + }); + }); + + ts.forEach(shimResult.importedFiles, importedFile => { + convertResult.importedFiles.push({ + filename: importedFile.path, + pos: importedFile.position, + end: importedFile.position + importedFile.length + }); + }); + + return convertResult; + } + } + export class TypeScriptLS implements ts.LanguageServiceShimHost { private ls: ts.LanguageServiceShim = null; @@ -129,11 +457,6 @@ module Harness.LanguageService { return "TypeScriptLS"; } - public addFile(fileName: string) { - var code = Harness.IO.readFile(fileName); - this.addScript(fileName, code); - } - private getScriptInfo(fileName: string): ScriptInfo { return ts.lookUp(this.fileNameToScript, fileName); } From 5aca35e35f978e3387e9724492029d52272b7f31 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 3 Feb 2015 17:28:33 -0800 Subject: [PATCH 06/14] Move unit tests to use the new adaptors --- .../cases/unittests/services/colorization.ts | 91 ++++++------------- 1 file changed, 26 insertions(+), 65 deletions(-) diff --git a/tests/cases/unittests/services/colorization.ts b/tests/cases/unittests/services/colorization.ts index 20038800a3e..b744b65608b 100644 --- a/tests/cases/unittests/services/colorization.ts +++ b/tests/cases/unittests/services/colorization.ts @@ -1,84 +1,47 @@ /// /// -interface Classification { - position: number; - length: number; - class: ts.TokenClass; -} - -interface ClassiferResult { - tuples: Classification[]; - finalEndOfLineState: ts.EndOfLineState; -} - interface ClassificationEntry { value: any; - class: ts.TokenClass; + classification: ts.TokenClass; } describe('Colorization', function () { - var mytypescriptLS = new Harness.LanguageService.TypeScriptLS(); - var myclassifier = mytypescriptLS.getClassifier(); + // Use the shim adaptor to ensure test coverage of the shim layer for the classifier + var languageServiceAdabtor = new Harness.LanguageService.ShimLanugageServiceAdaptor(); + var classifier = languageServiceAdabtor.getClassifier(); - function getLexicalClassifications(code: string, initialEndOfLineState: ts.EndOfLineState = ts.EndOfLineState.Start): ClassiferResult { - var classResult = myclassifier.getClassificationsForLine(code, initialEndOfLineState).split('\n'); - var tuples: Classification[] = []; - var i = 0; - var position = 0; - - for (; i < classResult.length - 1; i += 2) { - var t = tuples[i / 2] = { - position: position, - length: parseInt(classResult[i]), - class: parseInt(classResult[i + 1]) - }; - - assert.isTrue(t.length > 0, "Result length should be greater than 0, got :" + t.length); - position += t.length; - } - var finalEndOfLineState = classResult[classResult.length - 1]; - - assert.equal(position, code.length, "Expected cumulative length of all entries to match the length of the source. expected: " + code.length + ", but got: " + position); - - return { - tuples: tuples, - finalEndOfLineState: parseInt(finalEndOfLineState) - }; - } - - function verifyClassification(classification: Classification, expectedLength: number, expectedClass: number) { - assert.isNotNull(classification); - assert.equal(classification.length, expectedLength, "Classification length does not match expected. Expected: " + expectedLength + ", Actual: " + classification.length); - assert.equal(classification.class, expectedClass, "Classification class does not match expected. Expected: " + ts.TokenClass[expectedClass] + ", Actual: " + ts.TokenClass[classification.class]); - } - - function getEntryAtPosistion(result: ClassiferResult, position: number) { - for (var i = 0, n = result.tuples.length; i < n; i++) { - if (result.tuples[i].position === position) return result.tuples[i]; + function getEntryAtPosistion(result: ts.ClassificationResult, position: number) { + var entryPosition = 0; + for (var i = 0, n = result.entries.length; i < n; i++) { + var entry = result.entries[i]; + if (entryPosition === position) { + return entry; + } + entryPosition += entry.length; } return undefined; } - function punctuation(text: string) { return { value: text, class: ts.TokenClass.Punctuation }; } - function keyword(text: string) { return { value: text, class: ts.TokenClass.Keyword }; } - function operator(text: string) { return { value: text, class: ts.TokenClass.Operator }; } - function comment(text: string) { return { value: text, class: ts.TokenClass.Comment }; } - function whitespace(text: string) { return { value: text, class: ts.TokenClass.Whitespace }; } - function identifier(text: string) { return { value: text, class: ts.TokenClass.Identifier }; } - function numberLiteral(text: string) { return { value: text, class: ts.TokenClass.NumberLiteral }; } - function stringLiteral(text: string) { return { value: text, class: ts.TokenClass.StringLiteral }; } - function regExpLiteral(text: string) { return { value: text, class: ts.TokenClass.RegExpLiteral }; } - function finalEndOfLineState(value: number) { return { value: value, class: undefined }; } + function punctuation(text: string): ClassificationEntry { return { value: text, classification: ts.TokenClass.Punctuation }; } + function keyword(text: string): ClassificationEntry { return { value: text, classification: ts.TokenClass.Keyword }; } + function operator(text: string): ClassificationEntry { return { value: text, classification: ts.TokenClass.Operator }; } + function comment(text: string): ClassificationEntry { return { value: text, classification: ts.TokenClass.Comment }; } + function whitespace(text: string): ClassificationEntry { return { value: text, classification: ts.TokenClass.Whitespace }; } + function identifier(text: string): ClassificationEntry { return { value: text, classification: ts.TokenClass.Identifier }; } + function numberLiteral(text: string): ClassificationEntry { return { value: text, classification: ts.TokenClass.NumberLiteral }; } + function stringLiteral(text: string): ClassificationEntry { return { value: text, classification: ts.TokenClass.StringLiteral }; } + function regExpLiteral(text: string): ClassificationEntry { return { value: text, classification: ts.TokenClass.RegExpLiteral }; } + function finalEndOfLineState(value: number): ClassificationEntry { return { value: value, classification: undefined }; } function testLexicalClassification(text: string, initialEndOfLineState: ts.EndOfLineState, ...expectedEntries: ClassificationEntry[]): void { - var result = getLexicalClassifications(text, initialEndOfLineState); + var result = classifier.getClassificationsForLine(text, initialEndOfLineState); for (var i = 0, n = expectedEntries.length; i < n; i++) { var expectedEntry = expectedEntries[i]; - if (expectedEntry.class === undefined) { - assert.equal(result.finalEndOfLineState, expectedEntry.value, "final endOfLineState does not match expected."); + if (expectedEntry.classification === undefined) { + assert.equal(result.finalLexState, expectedEntry.value, "final endOfLineState does not match expected."); } else { var actualEntryPosition = text.indexOf(expectedEntry.value); @@ -87,7 +50,7 @@ describe('Colorization', function () { var actualEntry = getEntryAtPosistion(result, actualEntryPosition); assert(actualEntry, "Could not find classification entry for '" + expectedEntry.value + "' at position: " + actualEntryPosition); - assert.equal(actualEntry.class, expectedEntry.class, "Classification class does not match expected. Expected: " + ts.TokenClass[expectedEntry.class] + ", Actual: " + ts.TokenClass[actualEntry.class]); + assert.equal(actualEntry.classification, expectedEntry.classification, "Classification class does not match expected. Expected: " + ts.TokenClass[expectedEntry.classification] + ", Actual: " + ts.TokenClass[actualEntry.classification]); assert.equal(actualEntry.length, expectedEntry.value.length, "Classification length does not match expected. Expected: " + ts.TokenClass[expectedEntry.value.length] + ", Actual: " + ts.TokenClass[actualEntry.length]); } } @@ -320,8 +283,6 @@ describe('Colorization', function () { }); it("LexicallyClassifiesConflictTokens", () => { - debugger; - // Test conflict markers. testLexicalClassification( "class C {\r\n\ From 65e8c00d9af5fa9fd57160a2de6bcd986d06184e Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 3 Feb 2015 17:29:12 -0800 Subject: [PATCH 07/14] Update fourslash tests to use the new adaptors --- src/harness/fourslash.ts | 131 +++++++++++++---------------- tests/cases/fourslash/fourslash.ts | 4 +- 2 files changed, 62 insertions(+), 73 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index e0b74318e26..b4fba9a4501 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -245,11 +245,9 @@ module FourSlash { export class TestState { // Language service instance - public languageServiceShimHost: Harness.LanguageService.TypeScriptLS; + private languageServiceAdaptorHost: Harness.LanguageService.LanguageServiceAdaptorHost; private languageService: ts.LanguageService; - - // A reference to the language service's compiler state's compiler instance - private compiler: () => { getSyntaxTree(fileName: string): ts.SourceFile }; + private cancellationToken: TestCancellationToken; // The current caret position in the active file public currentCaretPosition = 0; @@ -263,8 +261,6 @@ module FourSlash { public formatCodeOptions: ts.FormatCodeOptions; - public cancellationToken: TestCancellationToken; - private scenarioActions: string[] = []; private taoInvalidReason: string = null; @@ -275,19 +271,20 @@ module FourSlash { private addMatchedInputFile(referenceFilePath: string) { var inputFile = this.inputFiles[referenceFilePath]; if (inputFile && !Harness.isLibraryFile(referenceFilePath)) { - this.languageServiceShimHost.addScript(referenceFilePath, inputFile); + this.languageServiceAdaptorHost.addScript(referenceFilePath, inputFile); } } constructor(public testData: FourSlashData) { - // Initialize the language service with all the scripts + // Create a new Services Adaptor this.cancellationToken = new TestCancellationToken(); - this.languageServiceShimHost = new Harness.LanguageService.TypeScriptLS(this.cancellationToken); + var compilationOptions = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions); + var languageServiceAdaptor = new Harness.LanguageService.ShimLanugageServiceAdaptor(this.cancellationToken, compilationOptions); + this.languageServiceAdaptorHost = languageServiceAdaptor.getHost(); + this.languageService = languageServiceAdaptor.getLanguageService(); - var compilationSettings = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions); - this.languageServiceShimHost.setCompilationSettings(compilationSettings); - - var startResolveFileRef: FourSlashFile = undefined; + // Initialize the language service with all the scripts + var startResolveFileRef: FourSlashFile; ts.forEach(testData.files, file => { // Create map between fileName and its content for easily looking up when resolveReference flag is specified @@ -302,18 +299,16 @@ module FourSlash { if (startResolveFileRef) { // Add the entry-point file itself into the languageServiceShimHost - this.languageServiceShimHost.addScript(startResolveFileRef.fileName, startResolveFileRef.content); + this.languageServiceAdaptorHost.addScript(startResolveFileRef.fileName, startResolveFileRef.content); - var jsonResolvedResult = JSON.parse(this.languageServiceShimHost.getCoreService().getPreProcessedFileInfo(startResolveFileRef.fileName, - createScriptSnapShot(startResolveFileRef.content))); - var resolvedResult = jsonResolvedResult.result; - var referencedFiles: ts.IFileReference[] = resolvedResult.referencedFiles; - var importedFiles: ts.IFileReference[] = resolvedResult.importedFiles; + var resolvedResult = languageServiceAdaptor.getPreProcessedFileInfo(startResolveFileRef.fileName, startResolveFileRef.content); + var referencedFiles: ts.FileReference[] = resolvedResult.referencedFiles; + var importedFiles: ts.FileReference[] = resolvedResult.importedFiles; // Add triple reference files into language-service host ts.forEach(referencedFiles, referenceFile => { // Fourslash insert tests/cases/fourslash into inputFile.unitName so we will properly append the same base directory to refFile path - var referenceFilePath = "tests/cases/fourslash/" + referenceFile.path; + var referenceFilePath = "tests/cases/fourslash/" + referenceFile.filename; this.addMatchedInputFile(referenceFilePath); }); @@ -321,29 +316,24 @@ module FourSlash { ts.forEach(importedFiles, importedFile => { // Fourslash insert tests/cases/fourslash into inputFile.unitName and import statement doesn't require ".ts" // so convert them before making appropriate comparison - var importedFilePath = "tests/cases/fourslash/" + importedFile.path + ".ts"; + var importedFilePath = "tests/cases/fourslash/" + importedFile.filename + ".ts"; this.addMatchedInputFile(importedFilePath); }); // Check if no-default-lib flag is false and if so add default library if (!resolvedResult.isLibFile) { - this.languageServiceShimHost.addDefaultLibrary(); + this.languageServiceAdaptorHost.addScript(Harness.Compiler.defaultLibFileName, Harness.Compiler.defaultLibSourceFile.text); } } else { // resolveReference file-option is not specified then do not resolve any files and include all inputFiles ts.forEachKey(this.inputFiles, fileName => { if (!Harness.isLibraryFile(fileName)) { - this.languageServiceShimHost.addScript(fileName, this.inputFiles[fileName]); + this.languageServiceAdaptorHost.addScript(fileName, this.inputFiles[fileName]); } }); - this.languageServiceShimHost.addDefaultLibrary(); + this.languageServiceAdaptorHost.addScript(Harness.Compiler.defaultLibFileName, Harness.Compiler.defaultLibSourceFile.text); } - // Sneak into the language service and get its compiler so we can examine the syntax trees - this.languageService = this.languageServiceShimHost.getLanguageService().languageService; - var compilerState = (this.languageService).compiler; - this.compiler = () => compilerState.compiler; - this.formatCodeOptions = { IndentSize: 4, TabSize: 4, @@ -369,6 +359,11 @@ module FourSlash { this.openFile(0); } + private getFileContent(filename: string): string { + var script = this.languageServiceAdaptorHost.getScriptInfo(this.activeFile.fileName); + return script.content; + } + // Entry points from fourslash.ts public goToMarker(name = '') { var marker = this.getMarkerByName(name); @@ -376,8 +371,8 @@ module FourSlash { this.openFile(marker.fileName); } - var scriptSnapshot = this.languageServiceShimHost.getScriptSnapshot(marker.fileName); - if (marker.position === -1 || marker.position > scriptSnapshot.getLength()) { + var content = this.getFileContent(marker.fileName); + if (marker.position === -1 || marker.position > content.length) { throw new Error('Marker "' + name + '" has been invalidated by unrecoverable edits to the file.'); } this.lastKnownMarker = name; @@ -387,14 +382,14 @@ module FourSlash { public goToPosition(pos: number) { this.currentCaretPosition = pos; - var lineStarts = ts.computeLineStarts(this.getCurrentFileContent()); + var lineStarts = ts.computeLineStarts(this.getFileContent(this.activeFile.fileName)); var lineCharPos = ts.getLineAndCharacterOfPosition(lineStarts, pos); this.scenarioActions.push(''); } public moveCaretRight(count = 1) { this.currentCaretPosition += count; - this.currentCaretPosition = Math.min(this.currentCaretPosition, this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getLength()); + this.currentCaretPosition = Math.min(this.currentCaretPosition, this.getFileContent(this.activeFile.fileName).length); if (count > 0) { this.scenarioActions.push(''); } else { @@ -453,7 +448,7 @@ module FourSlash { private getAllDiagnostics(): ts.Diagnostic[] { var diagnostics: ts.Diagnostic[] = []; - var fileNames = JSON.parse(this.languageServiceShimHost.getScriptFileNames()); + var fileNames = this.languageServiceAdaptorHost.getFilenames(); for (var i = 0, n = fileNames.length; i < n; i++) { diagnostics.push.apply(this.getDiagnostics(fileNames[i])); } @@ -794,7 +789,6 @@ module FourSlash { } } - public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: { start: number; length: number; }, displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[]) { @@ -1189,8 +1183,7 @@ module FourSlash { var file = this.testData.files[i]; var active = (this.activeFile === file); Harness.IO.log('=== Script (' + file.fileName + ') ' + (active ? '(active, cursor at |)' : '') + ' ==='); - var snapshot = this.languageServiceShimHost.getScriptSnapshot(file.fileName); - var content = snapshot.getText(0, snapshot.getLength()); + var content = this.getFileContent(file.fileName); if (active) { content = content.substr(0, this.currentCaretPosition) + (makeCaretVisible ? '|' : "") + content.substr(this.currentCaretPosition); } @@ -1224,8 +1217,7 @@ module FourSlash { } public printContext() { - var fileNames: string[] = JSON.parse(this.languageServiceShimHost.getScriptFileNames()); - ts.forEach(fileNames, Harness.IO.log); + ts.forEach(this.languageServiceAdaptorHost.getFilenames(), Harness.IO.log); } public deleteChar(count = 1) { @@ -1238,7 +1230,7 @@ module FourSlash { for (var i = 0; i < count; i++) { // Make the edit - this.languageServiceShimHost.editScript(this.activeFile.fileName, offset, offset + 1, ch); + this.languageServiceAdaptorHost.editScript(this.activeFile.fileName, offset, offset + 1, ch); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset + 1, ch); if (i % checkCadence === 0) { @@ -1265,7 +1257,7 @@ module FourSlash { public replace(start: number, length: number, text: string) { this.taoInvalidReason = 'replace NYI'; - this.languageServiceShimHost.editScript(this.activeFile.fileName, start, start + length, text); + this.languageServiceAdaptorHost.editScript(this.activeFile.fileName, start, start + length, text); this.updateMarkersForEdit(this.activeFile.fileName, start, start + length, text); this.checkPostEditInvariants(); } @@ -1280,7 +1272,7 @@ module FourSlash { for (var i = 0; i < count; i++) { offset--; // Make the edit - this.languageServiceShimHost.editScript(this.activeFile.fileName, offset, offset + 1, ch); + this.languageServiceAdaptorHost.editScript(this.activeFile.fileName, offset, offset + 1, ch); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset + 1, ch); if (i % checkCadence === 0) { @@ -1325,7 +1317,7 @@ module FourSlash { for (var i = 0; i < text.length; i++) { // Make the edit var ch = text.charAt(i); - this.languageServiceShimHost.editScript(this.activeFile.fileName, offset, offset, ch); + this.languageServiceAdaptorHost.editScript(this.activeFile.fileName, offset, offset, ch); this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, offset); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, ch); @@ -1368,7 +1360,7 @@ module FourSlash { var start = this.currentCaretPosition; var offset = this.currentCaretPosition; - this.languageServiceShimHost.editScript(this.activeFile.fileName, offset, offset, text); + this.languageServiceAdaptorHost.editScript(this.activeFile.fileName, offset, offset, text); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, text); this.checkPostEditInvariants(); offset += text.length; @@ -1396,8 +1388,7 @@ module FourSlash { var incrementalSyntaxDiagnostics = incrementalSourceFile.getSyntacticDiagnostics(); // Check syntactic structure - var snapshot = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName); - var content = snapshot.getText(0, snapshot.getLength()); + var content = this.getFileContent(this.activeFile.fileName); var referenceSourceFile = ts.createLanguageServiceSourceFile( this.activeFile.fileName, createScriptSnapShot(content), ts.ScriptTarget.Latest, /*version:*/ "0", /*setNodeParents:*/ false); @@ -1411,7 +1402,7 @@ module FourSlash { // The caret can potentially end up between the \r and \n, which is confusing. If // that happens, move it back one character if (this.currentCaretPosition > 0) { - var ch = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getText(this.currentCaretPosition - 1, this.currentCaretPosition); + var ch = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition - 1, this.currentCaretPosition); if (ch === '\r') { this.currentCaretPosition--; } @@ -1424,10 +1415,9 @@ module FourSlash { var runningOffset = 0; edits = edits.sort((a, b) => a.span.start - b.span.start); // Get a snapshot of the content of the file so we can make sure any formatting edits didn't destroy non-whitespace characters - var snapshot = this.languageServiceShimHost.getScriptSnapshot(fileName); - var oldContent = snapshot.getText(0, snapshot.getLength()); + var oldContent = this.getFileContent(this.activeFile.fileName); for (var j = 0; j < edits.length; j++) { - this.languageServiceShimHost.editScript(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText); + this.languageServiceAdaptorHost.editScript(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText); this.updateMarkersForEdit(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText); var change = (edits[j].span.start - ts.textSpanEnd(edits[j].span)) + edits[j].newText.length; runningOffset += change; @@ -1436,8 +1426,7 @@ module FourSlash { } if (isFormattingEdit) { - snapshot = this.languageServiceShimHost.getScriptSnapshot(fileName); - var newContent = snapshot.getText(0, snapshot.getLength()); + var newContent = this.getFileContent(fileName); if (newContent.replace(/\s/g, '') !== oldContent.replace(/\s/g, '')) { this.raiseError('Formatting operation destroyed non-whitespace content'); @@ -1484,7 +1473,7 @@ module FourSlash { } public goToEOF() { - var len = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getLength(); + var len = this.getFileContent(this.activeFile.fileName).length; this.goToPosition(len); } @@ -1605,7 +1594,7 @@ module FourSlash { public verifyCurrentFileContent(text: string) { this.taoInvalidReason = 'verifyCurrentFileContent NYI'; - var actual = this.getCurrentFileContent(); + var actual = this.getFileContent(this.activeFile.fileName); var replaceNewlines = (str: string) => str.replace(/\r\n/g, "\n"); if (replaceNewlines(actual) !== replaceNewlines(text)) { throw new Error('verifyCurrentFileContent\n' + @@ -1617,7 +1606,7 @@ module FourSlash { public verifyTextAtCaretIs(text: string) { this.taoInvalidReason = 'verifyCurrentFileContent NYI'; - var actual = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getText(this.currentCaretPosition, this.currentCaretPosition + text.length); + var actual = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition, this.currentCaretPosition + text.length); if (actual !== text) { throw new Error('verifyTextAtCaretIs\n' + '\tExpected: "' + text + '"\n' + @@ -1635,7 +1624,7 @@ module FourSlash { '\t Actual: undefined'); } - var actual = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName).getText(span.start, ts.textSpanEnd(span)); + var actual = this.getFileContent(this.activeFile.fileName).substring(span.start, ts.textSpanEnd(span)); if (actual !== text) { this.raiseError('verifyCurrentNameOrDottedNameSpanText\n' + '\tExpected: "' + text + '"\n' + @@ -1722,7 +1711,7 @@ module FourSlash { } public verifySyntacticClassifications(expected: { classificationType: string; text: string }[]) { - var actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName, + var actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length)); this.verifyClassifications(expected, actual); @@ -1812,8 +1801,7 @@ module FourSlash { for (var i = 0; i < this.testData.files.length; i++) { var file = this.testData.files[i]; - var snapshot = this.languageServiceShimHost.getScriptSnapshot(file.fileName); - var content = snapshot.getText(0, snapshot.getLength()); + var content = this.getFileContent(file.fileName); referenceLanguageServiceShimHost.addScript(this.testData.files[i].fileName, content); } @@ -1847,8 +1835,7 @@ module FourSlash { var failure = anyFailed || (refName !== pullName); if (failure) { - snapshot = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName); - content = snapshot.getText(0, snapshot.getLength()); + content = this.getFileContent(this.activeFile.fileName); var textAtPosition = content.substr(positions[i], 10); var positionDescription = 'Position ' + positions[i] + ' ("' + textAtPosition + '"...)'; @@ -2047,12 +2034,11 @@ module FourSlash { // The current caret position (in line/col terms) var line = this.getCurrentCaretFilePosition().line; // The line/col of the start of this line - var pos = this.languageServiceShimHost.lineColToPosition(this.activeFile.fileName, line, 1); + var pos = this.languageServiceAdaptorHost.lineColToPosition(this.activeFile.fileName, line, 1); // The index of the current file // The text from the start of the line to the end of the file - var snapshot = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName); - var text = snapshot.getText(pos, snapshot.getLength()); + var text = this.getFileContent(this.activeFile.fileName).substring(pos); // Truncate to the first newline var newlinePos = text.indexOf('\n'); @@ -2067,13 +2053,8 @@ module FourSlash { } } - private getCurrentFileContent() { - var snapshot = this.languageServiceShimHost.getScriptSnapshot(this.activeFile.fileName); - return snapshot.getText(0, snapshot.getLength()); - } - private getCurrentCaretFilePosition() { - var result = this.languageServiceShimHost.positionToZeroBasedLineCol(this.activeFile.fileName, this.currentCaretPosition); + var result = this.languageServiceAdaptorHost.positionToZeroBasedLineCol(this.activeFile.fileName, this.currentCaretPosition); if (result.line >= 0) { result.line++; } @@ -2158,7 +2139,7 @@ module FourSlash { } private getLineColStringAtPosition(position: number) { - var pos = this.languageServiceShimHost.positionToZeroBasedLineCol(this.activeFile.fileName, position); + var pos = this.languageServiceAdaptorHost.positionToZeroBasedLineCol(this.activeFile.fileName, position); return 'line ' + (pos.line + 1) + ', col ' + pos.character; } @@ -2184,6 +2165,14 @@ module FourSlash { originalName: '' }; } + + public setCancelled(numberOfCalls: number): void { + this.cancellationToken.setCancelled(numberOfCalls) + } + + public resetCancelled(): void { + this.cancellationToken.resetCancelled(); + } } // TOOD: should these just use the Harness's stdout/stderr? diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 5b88b15f9fa..77b5add7a11 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -561,11 +561,11 @@ module FourSlashInterface { export class cancellation { public resetCancelled() { - FourSlash.currentTestState.cancellationToken.resetCancelled(); + FourSlash.currentTestState.resetCancelled(); } public setCancelled(numberOfCalls: number = 0) { - FourSlash.currentTestState.cancellationToken.setCancelled(numberOfCalls); + FourSlash.currentTestState.setCancelled(numberOfCalls); } } From 42457636b6c01b27bc7851bb478e014bff241a79 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 4 Feb 2015 11:07:55 -0800 Subject: [PATCH 08/14] Remove the implementation of TypeScriptLS --- src/harness/fourslash.ts | 63 +--- src/harness/harnessLanguageService.ts | 278 ------------------ .../cases/fourslash/addMethodToInterface1.ts | 1 - .../cases/fourslash/arrayConcatTypeCheck0.ts | 1 - .../cases/fourslash/arrayConcatTypeCheck1.ts | 1 - .../arrayTypeMismatchIncrementalTypeCheck.ts | 31 -- .../cases/fourslash/emptyTypeArgumentList.ts | 7 - tests/cases/fourslash/fourslash.ts | 12 - .../cases/fourslash/getTypeAtModuleExtends.ts | 12 - tests/cases/fourslash/numberAssignement0.ts | 8 - .../pullFullDiffTypeParameterExtends0.ts | 29 -- .../restParametersTypeValidation1.ts | 12 - .../typeCheckAfterAddingGenericParameter.ts | 2 - tests/cases/fourslash/typeCheckExpression0.ts | 27 -- .../typeCheckGenericTypeLiteralArgument.ts | 12 - .../fourslash/typeCheckIndexSignature.ts | 11 - .../fourslash/typeCheckIndexerAccess1.ts | 40 --- 17 files changed, 1 insertion(+), 546 deletions(-) delete mode 100644 tests/cases/fourslash/arrayTypeMismatchIncrementalTypeCheck.ts delete mode 100644 tests/cases/fourslash/emptyTypeArgumentList.ts delete mode 100644 tests/cases/fourslash/getTypeAtModuleExtends.ts delete mode 100644 tests/cases/fourslash/numberAssignement0.ts delete mode 100644 tests/cases/fourslash/pullFullDiffTypeParameterExtends0.ts delete mode 100644 tests/cases/fourslash/restParametersTypeValidation1.ts delete mode 100644 tests/cases/fourslash/typeCheckExpression0.ts delete mode 100644 tests/cases/fourslash/typeCheckGenericTypeLiteralArgument.ts delete mode 100644 tests/cases/fourslash/typeCheckIndexSignature.ts delete mode 100644 tests/cases/fourslash/typeCheckIndexerAccess1.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index b4fba9a4501..5b46ec32a1c 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -279,7 +279,7 @@ module FourSlash { // Create a new Services Adaptor this.cancellationToken = new TestCancellationToken(); var compilationOptions = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions); - var languageServiceAdaptor = new Harness.LanguageService.ShimLanugageServiceAdaptor(this.cancellationToken, compilationOptions); + var languageServiceAdaptor = new Harness.LanguageService.NativeLanugageServiceAdaptor(this.cancellationToken, compilationOptions); this.languageServiceAdaptorHost = languageServiceAdaptor.getHost(); this.languageService = languageServiceAdaptor.getLanguageService(); @@ -1787,67 +1787,6 @@ module FourSlash { } } - public verifyTypesAgainstFullCheckAtPositions(positions: number[]) { - this.taoInvalidReason = 'verifyTypesAgainstFullCheckAtPositions impossible'; - - // Create a from-scratch LS to check against - var referenceLanguageServiceShimHost = new Harness.LanguageService.TypeScriptLS(); - var referenceLanguageServiceShim = referenceLanguageServiceShimHost.getLanguageService(); - var referenceLanguageService = referenceLanguageServiceShim.languageService; - - // Add lib.d.ts to the reference language service - referenceLanguageServiceShimHost.addDefaultLibrary(); - - for (var i = 0; i < this.testData.files.length; i++) { - var file = this.testData.files[i]; - - var content = this.getFileContent(file.fileName); - referenceLanguageServiceShimHost.addScript(this.testData.files[i].fileName, content); - } - - for (i = 0; i < positions.length; i++) { - var nameOf = (type: ts.QuickInfo) => type ? ts.displayPartsToString(type.displayParts) : '(none)'; - - var pullName: string, refName: string; - var anyFailed = false; - - var errMsg = ''; - - try { - var pullType = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, positions[i]); - pullName = nameOf(pullType); - } catch (err1) { - errMsg = 'Failed to get pull type check. Exception: ' + err1 + '\r\n'; - if (err1.stack) errMsg = errMsg + err1.stack; - pullName = '(failed)'; - anyFailed = true; - } - - try { - var referenceType = referenceLanguageService.getQuickInfoAtPosition(this.activeFile.fileName, positions[i]); - refName = nameOf(referenceType); - } catch (err2) { - errMsg = 'Failed to get full type check. Exception: ' + err2 + '\r\n'; - if (err2.stack) errMsg = errMsg + err2.stack; - refName = '(failed)'; - anyFailed = true; - } - - var failure = anyFailed || (refName !== pullName); - if (failure) { - content = this.getFileContent(this.activeFile.fileName); - var textAtPosition = content.substr(positions[i], 10); - var positionDescription = 'Position ' + positions[i] + ' ("' + textAtPosition + '"...)'; - - if (anyFailed) { - throw new Error('Exception thrown in language service for ' + positionDescription + '\r\n' + errMsg); - } else if (refName !== pullName) { - throw new Error('Pull/Full disagreement failed at ' + positionDescription + ' - expected full typecheck type "' + refName + '" to equal pull type "' + pullName + '".'); - } - } - } - } - /* Check number of navigationItems which match both searchValue and matchKind. Report an error if expected value and actual value do not match. diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 9316ef813c6..dcf211d3306 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -436,283 +436,5 @@ module Harness.LanguageService { return convertResult; } } - - export class TypeScriptLS implements ts.LanguageServiceShimHost { - private ls: ts.LanguageServiceShim = null; - - private fileNameToScript: ts.Map = {}; - private settings: ts.CompilerOptions = {}; - - constructor(private cancellationToken: ts.CancellationToken = CancellationToken.None) { - } - - public trace(s: string) { - } - - public addDefaultLibrary() { - this.addScript(Harness.Compiler.defaultLibFileName, Harness.Compiler.defaultLibSourceFile.text); - } - - public getHostIdentifier(): string { - return "TypeScriptLS"; - } - - private getScriptInfo(fileName: string): ScriptInfo { - return ts.lookUp(this.fileNameToScript, fileName); - } - - public addScript(fileName: string, content: string) { - this.fileNameToScript[fileName] = new ScriptInfo(fileName, content); - } - - private contains(fileName: string): boolean { - return ts.hasProperty(this.fileNameToScript, fileName); - } - - public updateScript(fileName: string, content: 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); - return; - } - - throw new Error("No script with name '" + fileName + "'"); - } - - ////////////////////////////////////////////////////////////////////// - // ILogger implementation - // - public information(): boolean { return false; } - public debug(): boolean { return true; } - public warning(): boolean { return true; } - public error(): boolean { return true; } - public fatal(): boolean { return true; } - - public log(s: string): void { - // For debugging... - //TypeScript.Environment.standardOut.WriteLine("TypeScriptLS:" + s); - } - - ////////////////////////////////////////////////////////////////////// - // LanguageServiceShimHost implementation - // - - /// Returns json for Tools.CompilationSettings - public getCompilationSettings(): string { - return JSON.stringify(this.settings); - } - - public getCancellationToken(): ts.CancellationToken { - return this.cancellationToken; - } - - public getCurrentDirectory(): string { - return ""; - } - - public getDefaultLibFilename(): string { - return ""; - } - - public getScriptFileNames(): string { - var fileNames: string[] = []; - ts.forEachKey(this.fileNameToScript,(fileName) => { fileNames.push(fileName); }); - return JSON.stringify(fileNames); - } - - public getScriptSnapshot(fileName: string): ts.ScriptSnapshotShim { - if (this.contains(fileName)) { - return new ScriptSnapshotShim(new ScriptSnapshot(this.getScriptInfo(fileName))); - } - return undefined; - } - - public getScriptVersion(fileName: string): string { - if (this.contains(fileName)) { - return this.getScriptInfo(fileName).version.toString(); - } - return undefined; - } - - public getLocalizedDiagnosticMessages(): string { - return JSON.stringify({}); - } - - /** Return a new instance of the language service shim, up-to-date wrt to typecheck. - * To access the non-shim (i.e. actual) language service, use the "ls.languageService" property. - */ - public getLanguageService(): ts.LanguageServiceShim { - this.ls = new TypeScript.Services.TypeScriptServicesFactory().createLanguageServiceShim(this); - return this.ls; - } - - public setCompilationSettings(settings: ts.CompilerOptions) { - for (var key in settings) { - if (settings.hasOwnProperty(key)) { - this.settings[key] = settings[key]; - } - } - } - - /** Return a new instance of the classifier service shim */ - public getClassifier(): ts.ClassifierShim { - return new TypeScript.Services.TypeScriptServicesFactory().createClassifierShim(this); - } - - public getCoreService(): ts.CoreServicesShim { - return new TypeScript.Services.TypeScriptServicesFactory().createCoreServicesShim(this); - } - - /** Parse file given its source text */ - public parseSourceText(fileName: string, sourceText: ts.IScriptSnapshot): ts.SourceFile { - var result = ts.createSourceFile(fileName, sourceText.getText(0, sourceText.getLength()), ts.ScriptTarget.Latest); - result.version = "1"; - return result; - } - - /** Parse a file on disk given its fileName */ - public parseFile(fileName: string) { - var sourceText = ts.ScriptSnapshot.fromString(Harness.IO.readFile(fileName)); - return this.parseSourceText(fileName, sourceText); - } - - /** - * @param line 1 based index - * @param col 1 based index - */ - public lineColToPosition(fileName: string, line: number, col: number): number { - var script: ScriptInfo = this.fileNameToScript[fileName]; - assert.isNotNull(script); - assert.isTrue(line >= 1); - assert.isTrue(col >= 1); - - return ts.getPositionFromLineAndCharacter(script.lineMap, line, col); - } - - /** - * @param line 0 based index - * @param col 0 based index - */ - public positionToZeroBasedLineCol(fileName: string, position: number): ts.LineAndCharacter { - var script: ScriptInfo = this.fileNameToScript[fileName]; - assert.isNotNull(script); - - var result = ts.getLineAndCharacterOfPosition(script.lineMap, position); - - assert.isTrue(result.line >= 1); - assert.isTrue(result.character >= 1); - return { line: result.line - 1, character: result.character - 1 }; - } - - /** Verify that applying edits to sourceFileName result in the content of the file baselineFileName */ - public checkEdits(sourceFileName: string, baselineFileName: string, edits: ts.TextChange[]) { - var script = Harness.IO.readFile(sourceFileName); - var formattedScript = this.applyEdits(script, edits); - var baseline = Harness.IO.readFile(baselineFileName); - - function noDiff(text1: string, text2: string) { - text1 = text1.replace(/^\s+|\s+$/g, "").replace(/\r\n?/g, "\n"); - text2 = text2.replace(/^\s+|\s+$/g, "").replace(/\r\n?/g, "\n"); - - if (text1 !== text2) { - var errorString = ""; - var text1Lines = text1.split(/\n/); - var text2Lines = text2.split(/\n/); - for (var i = 0; i < text1Lines.length; i++) { - if (text1Lines[i] !== text2Lines[i]) { - errorString += "Difference at line " + (i + 1) + ":\n"; - errorString += " Left File: " + text1Lines[i] + "\n"; - errorString += " Right File: " + text2Lines[i] + "\n\n"; - } - } - throw (new Error(errorString)); - } - } - assert.isTrue(noDiff(formattedScript, baseline)); - assert.equal(formattedScript, baseline); - } - - - /** Apply an array of text edits to a string, and return the resulting string. */ - public applyEdits(content: string, edits: ts.TextChange[]): string { - var result = content; - edits = this.normalizeEdits(edits); - - for (var i = edits.length - 1; i >= 0; i--) { - var edit = edits[i]; - var prefix = result.substring(0, edit.span.start); - var middle = edit.newText; - var suffix = result.substring(ts.textSpanEnd(edit.span)); - result = prefix + middle + suffix; - } - return result; - } - - /** Normalize an array of edits by removing overlapping entries and sorting entries on the minChar position. */ - private normalizeEdits(edits: ts.TextChange[]): ts.TextChange[] { - var result: ts.TextChange[] = []; - - function mapEdits(edits: ts.TextChange[]): { edit: ts.TextChange; index: number; }[] { - var result: { edit: ts.TextChange; index: number; }[] = []; - for (var i = 0; i < edits.length; i++) { - result.push({ edit: edits[i], index: i }); - } - return result; - } - - var temp = mapEdits(edits).sort(function (a, b) { - var result = a.edit.span.start - b.edit.span.start; - if (result === 0) - result = a.index - b.index; - return result; - }); - - var current = 0; - var next = 1; - while (current < temp.length) { - var currentEdit = temp[current].edit; - - // Last edit - if (next >= temp.length) { - result.push(currentEdit); - current++; - continue; - } - var nextEdit = temp[next].edit; - - var gap = nextEdit.span.start - ts.textSpanEnd(currentEdit.span); - - // non-overlapping edits - if (gap >= 0) { - result.push(currentEdit); - current = next; - next++; - continue; - } - - // overlapping edits: for now, we only support ignoring an next edit - // entirely contained in the current edit. - if (ts.textSpanEnd(currentEdit.span) >= ts.textSpanEnd(nextEdit.span)) { - next++; - continue; - } - else { - throw new Error("Trying to apply overlapping edits"); - } - } - - return result; - } - } } \ No newline at end of file diff --git a/tests/cases/fourslash/addMethodToInterface1.ts b/tests/cases/fourslash/addMethodToInterface1.ts index 749f5601173..07cd4700583 100644 --- a/tests/cases/fourslash/addMethodToInterface1.ts +++ b/tests/cases/fourslash/addMethodToInterface1.ts @@ -12,4 +12,3 @@ edit.disableFormatting(); goTo.marker('1'); edit.insert(" compareTo(): number;\n"); -diagnostics.validateTypesAtPositions(168,84,53,118,22); diff --git a/tests/cases/fourslash/arrayConcatTypeCheck0.ts b/tests/cases/fourslash/arrayConcatTypeCheck0.ts index ac5404266a6..9250eb5b6fd 100644 --- a/tests/cases/fourslash/arrayConcatTypeCheck0.ts +++ b/tests/cases/fourslash/arrayConcatTypeCheck0.ts @@ -14,4 +14,3 @@ edit.disableFormatting(); goTo.marker('1'); edit.insert(", 'world'"); -diagnostics.validateTypesAtPositions(78); diff --git a/tests/cases/fourslash/arrayConcatTypeCheck1.ts b/tests/cases/fourslash/arrayConcatTypeCheck1.ts index 42d9cdb8a1c..c62bd5b7f14 100644 --- a/tests/cases/fourslash/arrayConcatTypeCheck1.ts +++ b/tests/cases/fourslash/arrayConcatTypeCheck1.ts @@ -23,5 +23,4 @@ goTo.marker('2'); edit.deleteAtCaret(7); goTo.marker('4'); -diagnostics.validateTypesAtPositions(43); diff --git a/tests/cases/fourslash/arrayTypeMismatchIncrementalTypeCheck.ts b/tests/cases/fourslash/arrayTypeMismatchIncrementalTypeCheck.ts deleted file mode 100644 index 778f20db219..00000000000 --- a/tests/cases/fourslash/arrayTypeMismatchIncrementalTypeCheck.ts +++ /dev/null @@ -1,31 +0,0 @@ -/// - -//// interface Iterator { -//// (value: T, index: any): U; -//// } -//// -//// interface WrappedArray { -//// map(iterator: Iterator): U[]; -//// } -//// -//// interface Underscore { -//// (list: T[]): WrappedArray; -//// map(list: T[], iterator: Iterator, context?: any): U[]; -//// } -//// -//// declare var _: Underscore; -//// -//// var a: string[]; -//// var b = _.map(a, x => x.length); // Type any[], should be number[] -//// var c = _(a).map(); -//// var d = a.map(x => x.length); -//// var bb = _.map(aa, x => x.length); -//// var cc = _(aa).map(x => x.length); // Error, could not select overload -//// var dd = aa.map(x => x.length); // Error, could not select overload -//// -//// -//// -//// - -edit.disableFormatting(); -diagnostics.validateTypesAtPositions(364); diff --git a/tests/cases/fourslash/emptyTypeArgumentList.ts b/tests/cases/fourslash/emptyTypeArgumentList.ts deleted file mode 100644 index d8f7947559b..00000000000 --- a/tests/cases/fourslash/emptyTypeArgumentList.ts +++ /dev/null @@ -1,7 +0,0 @@ -/// - -//// function foo2(test); -//// function foo2() { } -//// /**/foo2<>(""); -goTo.marker(); -diagnostics.validateTypeAtCurrentPosition(); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 77b5add7a11..717962fd39f 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -80,16 +80,6 @@ module FourSlashInterface { } } - export class diagnostics { - public validateTypeAtCurrentPosition() { - return this.validateTypesAtPositions(FourSlash.currentTestState.currentCaretPosition); - } - - public validateTypesAtPositions(...positions: number[]) { - return FourSlash.currentTestState.verifyTypesAgainstFullCheckAtPositions(positions); - } - } - export class goTo { // Moves the caret to the specified marker, // or the anonymous marker ('/**/') if no name @@ -647,7 +637,6 @@ module fs { export var edit = new FourSlashInterface.edit(); export var debug = new FourSlashInterface.debug(); export var format = new FourSlashInterface.format(); - export var diagnostics = new FourSlashInterface.diagnostics(); export var cancellation = new FourSlashInterface.cancellation(); } module ts { @@ -666,6 +655,5 @@ var verify = new FourSlashInterface.verify(); var edit = new FourSlashInterface.edit(); var debug = new FourSlashInterface.debug(); var format = new FourSlashInterface.format(); -var diagnostics = new FourSlashInterface.diagnostics(); var cancellation = new FourSlashInterface.cancellation(); var classification = FourSlashInterface.classification; diff --git a/tests/cases/fourslash/getTypeAtModuleExtends.ts b/tests/cases/fourslash/getTypeAtModuleExtends.ts deleted file mode 100644 index 8114ee94c1b..00000000000 --- a/tests/cases/fourslash/getTypeAtModuleExtends.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// - -////declare module A.B { -//// export class C { } -////} -//// -////import ab = A.B; -//// -////class D extends ab.C/**/{ } - -goTo.marker(); -diagnostics.validateTypesAtPositions(FourSlash.currentTestState.currentCaretPosition); diff --git a/tests/cases/fourslash/numberAssignement0.ts b/tests/cases/fourslash/numberAssignement0.ts deleted file mode 100644 index 540a8d91f3d..00000000000 --- a/tests/cases/fourslash/numberAssignement0.ts +++ /dev/null @@ -1,8 +0,0 @@ -/// - -//// var x: Number; -//// var y: Number; -//// var z = x ; - -edit.disableFormatting(); -diagnostics.validateTypesAtPositions(28); diff --git a/tests/cases/fourslash/pullFullDiffTypeParameterExtends0.ts b/tests/cases/fourslash/pullFullDiffTypeParameterExtends0.ts deleted file mode 100644 index 990d65404d3..00000000000 --- a/tests/cases/fourslash/pullFullDiffTypeParameterExtends0.ts +++ /dev/null @@ -1,29 +0,0 @@ -/// - -//// class A { } -//// class B { -//// data: A; -//// } -//// -//// // Below 2 should compile without error -//// var x: A< { }, { b: number }>; -//// var y: B< { a: string }, { }>; -//// -//// -//// // Below should be in error -//// var x1: A<{ a: string;}>; -//// var x2: A<{ a: number }>; -//// var x3: B<{ a: string;}, { b: string }>; -//// var x4: B<{ a: string;}>; -//// var x5: A<{ a: string; b: number }, { a: string }>; -//// var x6: B<>; -//// -//// interface I1 { -//// a: string; -//// } -//// var x8: B; -//// - -edit.disableFormatting(); -diagnostics.validateTypesAtPositions(34); - diff --git a/tests/cases/fourslash/restParametersTypeValidation1.ts b/tests/cases/fourslash/restParametersTypeValidation1.ts deleted file mode 100644 index b598ae7fc84..00000000000 --- a/tests/cases/fourslash/restParametersTypeValidation1.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// - -//// function f18(a?:string, ...b){} -//// -//// function f19(a?:string, b?){} -//// -//// function f20(a:string, b?:string, ...c:number[]){} -//// -//// function f21(a:string, b?:string, ...d:number[]){} - -edit.disableFormatting(); -diagnostics.validateTypesAtPositions(133); diff --git a/tests/cases/fourslash/typeCheckAfterAddingGenericParameter.ts b/tests/cases/fourslash/typeCheckAfterAddingGenericParameter.ts index e2e978dd7ea..fa312f3c711 100644 --- a/tests/cases/fourslash/typeCheckAfterAddingGenericParameter.ts +++ b/tests/cases/fourslash/typeCheckAfterAddingGenericParameter.ts @@ -20,5 +20,3 @@ edit.insert(", X"); goTo.marker('addTypeParam'); edit.insert(", X"); - -diagnostics.validateTypesAtPositions(91, 163); diff --git a/tests/cases/fourslash/typeCheckExpression0.ts b/tests/cases/fourslash/typeCheckExpression0.ts deleted file mode 100644 index 51c6ae75655..00000000000 --- a/tests/cases/fourslash/typeCheckExpression0.ts +++ /dev/null @@ -1,27 +0,0 @@ -/// - -//// class Point { -//// -//// constructor(public x: number) { -//// -//// } -//// getDist() { -//// } -//// static origin = new Point(0); -//// } -//// -//// class Point3D { -//// -//// constructor(x: number, y: number, private z) { -//// super(x, y); -//// } -//// -//// getDist() { -//// return Math.sqrt(this.x*this.x + this.z*this.m); -//// } -//// } -//// -//// - -edit.disableFormatting(); -diagnostics.validateTypesAtPositions(258); diff --git a/tests/cases/fourslash/typeCheckGenericTypeLiteralArgument.ts b/tests/cases/fourslash/typeCheckGenericTypeLiteralArgument.ts deleted file mode 100644 index 107c7a3b525..00000000000 --- a/tests/cases/fourslash/typeCheckGenericTypeLiteralArgument.ts +++ /dev/null @@ -1,12 +0,0 @@ -/// - -//// interface Sequence { -//// each(iterator: (value: T) => void): void; -//// filter(): Sequence; -//// groupBy(keySelector: () => K): Sequence<{ items: T/**/[]; }>; -//// } - -goTo.file(0); - -// Marker in above file is placed at position 154 -diagnostics.validateTypesAtPositions(154); diff --git a/tests/cases/fourslash/typeCheckIndexSignature.ts b/tests/cases/fourslash/typeCheckIndexSignature.ts deleted file mode 100644 index a0c7d049b93..00000000000 --- a/tests/cases/fourslash/typeCheckIndexSignature.ts +++ /dev/null @@ -1,11 +0,0 @@ -/// - -//// function method() { -//// var dictionary = <{ [index: string]: string; }>{}; -//// } -//// - -edit.disableFormatting(); // Disregard, just here to keep Fourslash happy - -diagnostics.validateTypesAtPositions(44); - diff --git a/tests/cases/fourslash/typeCheckIndexerAccess1.ts b/tests/cases/fourslash/typeCheckIndexerAccess1.ts deleted file mode 100644 index 384f6d003e2..00000000000 --- a/tests/cases/fourslash/typeCheckIndexerAccess1.ts +++ /dev/null @@ -1,40 +0,0 @@ -/// - -//// // @sourcemap: true -//// module Foo.Bar { -//// "use strict"; -//// -//// class Greeter { -//// constructor(public greeting: string) { -//// } -//// -//// greet() { -//// } -//// } -//// -//// -//// function foo(greeting: string): Foo.Bar.Greeter { -//// return new Greeter(greeting); -//// } -//// -//// var greeter = new Greeter("Hello, world!"); -//// var str = greeter.greet(); -//// -//// function foo2(greeting: string, ...restGreetings) { -//// var greeters: Greeter[] = []; -//// new Greeter(greeting); -//// for (var i = 0; restGreetings.length; i++) { -//// greeters.push(new Greeter(restGreetings[i])); -//// } -//// -//// return greeters; -//// } -//// -//// var b = foo2("Hello", "World"); -//// for (var j = 0; j < b.length; j++) { -//// b[j].greet(); -//// } -//// } - -edit.disableFormatting(); -diagnostics.validateTypesAtPositions(705); \ No newline at end of file From c2bca0e84db94c894dac83ec5a69fdd88acbdf65 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 4 Feb 2015 12:16:47 -0800 Subject: [PATCH 09/14] Fix typo in type name --- src/harness/harnessLanguageService.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index dcf211d3306..4b188cf96f6 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -109,7 +109,7 @@ module Harness.LanguageService { } } - export interface LanugageServiceAdaptor { + export interface LanguageServiceAdaptor { getHost(): LanguageServiceAdaptorHost; getLanguageService(): ts.LanguageService; getClassifier(): ts.Classifier; @@ -210,7 +210,7 @@ module Harness.LanguageService { error(s: string): void { } } - export class NativeLanugageServiceAdaptor implements LanugageServiceAdaptor { + export class NativeLanugageServiceAdaptor implements LanguageServiceAdaptor { private host: NativeLanguageServiceHost; constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { this.host = new NativeLanguageServiceHost(cancellationToken, options); @@ -391,7 +391,7 @@ module Harness.LanguageService { dispose(): void { this.shim.dispose({}); } } - export class ShimLanugageServiceAdaptor implements LanugageServiceAdaptor { + export class ShimLanugageServiceAdaptor implements LanguageServiceAdaptor { private host: ShimLanguageServiceHost; private factory: ts.TypeScriptServicesFactory; constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { From c5006ca8acb21ad88f5dedc47370322b2c652b63 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 4 Feb 2015 12:17:04 -0800 Subject: [PATCH 10/14] remove new line --- src/harness/harness.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 52884744535..9bf1932b971 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -690,8 +690,6 @@ module Harness { } } - - module Harness { var tcServicesFilename = "typescriptServices.js"; From bfef4a03658d6d5ac2519aac38b4fcbae4223437 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 4 Feb 2015 15:36:13 -0800 Subject: [PATCH 11/14] Add new tests for shims --- src/harness/fourslash.ts | 45 +++++-- src/harness/fourslashRunner.ts | 36 ++++-- src/harness/harnessLanguageService.ts | 8 +- src/harness/runner.ts | 10 +- .../getBreakpointStatementAtPosition.baseline | 71 +++++++++++ .../reference/getEmitOutput.baseline | 30 +++++ tests/cases/fourslash/indentation.ts | 2 +- ...cellationWhenfindingAllRefsOnDefinition.ts | 38 ++++++ .../shims/getBraceMatchingAtPosition.ts | 43 +++++++ .../shims/getBreakpointStatementAtPosition.ts | 17 +++ .../shims/getCompletionsAtPosition.ts | 20 ++++ .../shims/getDefinitionAtPosition.ts | 29 +++++ tests/cases/fourslash/shims/getEmitOutput.ts | 22 ++++ .../shims/getIndentationAtPosition.ts | 21 ++++ .../fourslash/shims/getNavigateToItems.ts | 27 +++++ .../fourslash/shims/getNavigationBarItems.ts | 13 ++ .../shims/getOccurrencesAtPosition.ts | 18 +++ .../fourslash/shims/getOutliningSpans.ts | 113 ++++++++++++++++++ .../fourslash/shims/getPreProcessedFile.ts | 32 +++++ .../fourslash/shims/getQuickInfoAtPosition.ts | 16 +++ .../shims/getReferencesAtPosition.ts | 29 +++++ tests/cases/fourslash/shims/getRenameInfo.ts | 11 ++ .../shims/getSemanticClassifications.ts | 15 +++ .../fourslash/shims/getSemanticDiagnostics.ts | 11 ++ .../fourslash/shims/getSignatureHelpItems.ts | 13 ++ .../shims/getSyntacticClassifications.ts | 35 ++++++ .../cases/fourslash/shims/getTodoComments.ts | 3 + .../shims/quickInfoDisplayPartsVar.ts | 76 ++++++++++++ 28 files changed, 776 insertions(+), 28 deletions(-) create mode 100644 tests/baselines/reference/getBreakpointStatementAtPosition.baseline create mode 100644 tests/baselines/reference/getEmitOutput.baseline create mode 100644 tests/cases/fourslash/shims/cancellationWhenfindingAllRefsOnDefinition.ts create mode 100644 tests/cases/fourslash/shims/getBraceMatchingAtPosition.ts create mode 100644 tests/cases/fourslash/shims/getBreakpointStatementAtPosition.ts create mode 100644 tests/cases/fourslash/shims/getCompletionsAtPosition.ts create mode 100644 tests/cases/fourslash/shims/getDefinitionAtPosition.ts create mode 100644 tests/cases/fourslash/shims/getEmitOutput.ts create mode 100644 tests/cases/fourslash/shims/getIndentationAtPosition.ts create mode 100644 tests/cases/fourslash/shims/getNavigateToItems.ts create mode 100644 tests/cases/fourslash/shims/getNavigationBarItems.ts create mode 100644 tests/cases/fourslash/shims/getOccurrencesAtPosition.ts create mode 100644 tests/cases/fourslash/shims/getOutliningSpans.ts create mode 100644 tests/cases/fourslash/shims/getPreProcessedFile.ts create mode 100644 tests/cases/fourslash/shims/getQuickInfoAtPosition.ts create mode 100644 tests/cases/fourslash/shims/getReferencesAtPosition.ts create mode 100644 tests/cases/fourslash/shims/getRenameInfo.ts create mode 100644 tests/cases/fourslash/shims/getSemanticClassifications.ts create mode 100644 tests/cases/fourslash/shims/getSemanticDiagnostics.ts create mode 100644 tests/cases/fourslash/shims/getSignatureHelpItems.ts create mode 100644 tests/cases/fourslash/shims/getSyntacticClassifications.ts create mode 100644 tests/cases/fourslash/shims/getTodoComments.ts create mode 100644 tests/cases/fourslash/shims/quickInfoDisplayPartsVar.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 5b46ec32a1c..cccbc448213 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -275,11 +275,26 @@ module FourSlash { } } - constructor(public testData: FourSlashData) { + private getLanguageServiceAdaptor(testType: FourSlashTestType): + { new (cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions): Harness.LanguageService.LanguageServiceAdaptor } { + switch (testType) { + case FourSlashTestType.Native: + return Harness.LanguageService.NativeLanugageServiceAdaptor; + break; + case FourSlashTestType.Shims: + return Harness.LanguageService.ShimLanugageServiceAdaptor; + break; + default: + throw new Error("Unknown FourSlash test type: "); + } + } + + constructor(private basePath: string, private testType: FourSlashTestType, public testData: FourSlashData) { // Create a new Services Adaptor this.cancellationToken = new TestCancellationToken(); var compilationOptions = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions); - var languageServiceAdaptor = new Harness.LanguageService.NativeLanugageServiceAdaptor(this.cancellationToken, compilationOptions); + var languageserviceAdaptorFactory = this.getLanguageServiceAdaptor(testType); + var languageServiceAdaptor = new languageserviceAdaptorFactory(this.cancellationToken, compilationOptions); this.languageServiceAdaptorHost = languageServiceAdaptor.getHost(); this.languageService = languageServiceAdaptor.getLanguageService(); @@ -308,7 +323,7 @@ module FourSlash { // Add triple reference files into language-service host ts.forEach(referencedFiles, referenceFile => { // Fourslash insert tests/cases/fourslash into inputFile.unitName so we will properly append the same base directory to refFile path - var referenceFilePath = "tests/cases/fourslash/" + referenceFile.filename; + var referenceFilePath = this.basePath+ '/' + referenceFile.filename; this.addMatchedInputFile(referenceFilePath); }); @@ -316,7 +331,7 @@ module FourSlash { ts.forEach(importedFiles, importedFile => { // Fourslash insert tests/cases/fourslash into inputFile.unitName and import statement doesn't require ".ts" // so convert them before making appropriate comparison - var importedFilePath = "tests/cases/fourslash/" + importedFile.filename + ".ts"; + var importedFilePath = this.basePath + '/' + importedFile.filename + ".ts"; this.addMatchedInputFile(importedFilePath); }); @@ -1382,6 +1397,12 @@ module FourSlash { } private checkPostEditInvariants() { + if (this.testType !== FourSlashTestType.Native) { + // getSourcefile() results can not be serialized. Only perform these verifications + // if running against a native LS object. + return; + } + var incrementalSourceFile = this.languageService.getSourceFile(this.activeFile.fileName); Utils.assertInvariants(incrementalSourceFile, /*parent:*/ undefined); @@ -2052,7 +2073,7 @@ module FourSlash { } else if (typeof indexOrName === 'string') { var name = indexOrName; // names are stored in the compiler with this relative path, this allows people to use goTo.file on just the filename - name = name.indexOf('/') === -1 ? 'tests/cases/fourslash/' + name : name; + name = name.indexOf('/') === -1 ? (this.basePath + '/' + name) : name; var availableNames: string[] = []; var foundIt = false; for (var i = 0; i < this.testData.files.length; i++) { @@ -2118,17 +2139,17 @@ module FourSlash { var fsOutput = new Harness.Compiler.WriterAggregator(); var fsErrors = new Harness.Compiler.WriterAggregator(); export var xmlData: TestXmlData[] = []; - export function runFourSlashTest(fileName: string) { + export function runFourSlashTest(basePath: string, testType: FourSlashTestType, fileName: string) { var content = Harness.IO.readFile(fileName); - var xml = runFourSlashTestContent(content, fileName); + var xml = runFourSlashTestContent(basePath, testType, content, fileName); xmlData.push(xml); } - export function runFourSlashTestContent(content: string, fileName: string): TestXmlData { + export function runFourSlashTestContent(basePath: string, testType: FourSlashTestType, content: string, fileName: string): TestXmlData { // Parse out the files and their metadata - var testData = parseTestData(content, fileName); + var testData = parseTestData(basePath, content, fileName); - currentTestState = new TestState(testData); + currentTestState = new TestState(basePath, testType, testData); var result = ''; var host = Harness.Compiler.createCompilerHost([{ unitName: Harness.Compiler.fourslashFilename, content: undefined }, @@ -2171,7 +2192,7 @@ module FourSlash { return lines.map(s => s.substr(1)).join('\n'); } - function parseTestData(contents: string, fileName: string): FourSlashData { + function parseTestData(basePath: string, contents: string, fileName: string): FourSlashData { // Regex for parsing options in the format "@Alpha: Value of any sort" var optionRegex = /^\s*@(\w+): (.*)\s*/; @@ -2239,7 +2260,7 @@ module FourSlash { currentFileName = fileName; } - currentFileName = 'tests/cases/fourslash/' + match[2]; + currentFileName = basePath + '/' + match[2]; currentFileOptions[match[1]] = match[2]; } else { // Add other fileMetadata flag diff --git a/src/harness/fourslashRunner.ts b/src/harness/fourslashRunner.ts index 1ecb02df292..fe3b6c7a91f 100644 --- a/src/harness/fourslashRunner.ts +++ b/src/harness/fourslashRunner.ts @@ -2,19 +2,35 @@ /// /// -class FourslashRunner extends RunnerBase { - public basePath = 'tests/cases/fourslash'; +const enum FourSlashTestType { + Native, + Shims +} - constructor() { +class FourSlashRunner extends RunnerBase { + protected basePath: string; + protected testSuiteName: string; + + constructor(private testType: FourSlashTestType) { super(); + switch (testType) { + case FourSlashTestType.Native: + this.basePath = 'tests/cases/fourslash'; + this.testSuiteName = 'fourslash'; + break; + case FourSlashTestType.Shims: + this.basePath = 'tests/cases/fourslash/shims'; + this.testSuiteName = 'fourslash-shims'; + break; + } } public initializeTests() { if (this.tests.length === 0) { - this.tests = this.enumerateFiles(this.basePath, /\.ts/i); + this.tests = this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false }); } - describe("fourslash tests", () => { + describe(this.testSuiteName, () => { this.tests.forEach((fn: string) => { fn = ts.normalizeSlashes(fn); var justName = fn.replace(/^.*[\\\/]/, ''); @@ -24,8 +40,8 @@ class FourslashRunner extends RunnerBase { if (testIndex >= 0) fn = fn.substr(testIndex); if (justName && !justName.match(/fourslash\.ts$/i) && !justName.match(/\.d\.ts$/i)) { - it('FourSlash test ' + justName + ' runs correctly', function () { - FourSlash.runFourSlashTest(fn); + it(this.testSuiteName + ' test ' + justName + ' runs correctly',() => { + FourSlash.runFourSlashTest(this.basePath, this.testType, fn); }); } }); @@ -82,9 +98,9 @@ class FourslashRunner extends RunnerBase { } } -class GeneratedFourslashRunner extends FourslashRunner { - constructor() { - super(); +class GeneratedFourslashRunner extends FourSlashRunner { + constructor(testType: FourSlashTestType) { + super(testType); this.basePath += '/generated/'; } } \ No newline at end of file diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 4b188cf96f6..2fce141bbf3 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -56,9 +56,13 @@ module Harness.LanguageService { } class ScriptSnapshot implements ts.IScriptSnapshot { - public textSnapshot: string; public version: number; + public textSnapshot: string; + public version: number; + constructor(public scriptInfo: ScriptInfo) { - this.textSnapshot = scriptInfo.content; this.version = scriptInfo.version; } + this.textSnapshot = scriptInfo.content; + this.version = scriptInfo.version; + } public getText(start: number, end: number): string { return this.textSnapshot.substring(start, end); diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 24349ada3fd..942ae56bf6f 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -61,10 +61,13 @@ if (testConfigFile !== '') { runners.push(new ProjectRunner()); break; case 'fourslash': - runners.push(new FourslashRunner()); + runners.push(new FourSlashRunner(FourSlashTestType.Native)); + break; + case 'fourslash-shims': + runners.push(new FourSlashRunner(FourSlashTestType.Shims)); break; case 'fourslash-generated': - runners.push(new GeneratedFourslashRunner()); + runners.push(new GeneratedFourslashRunner(FourSlashTestType.Native)); break; case 'rwc': runners.push(new RWCRunner()); @@ -90,7 +93,8 @@ if (runners.length === 0) { } // language services - runners.push(new FourslashRunner()); + runners.push(new FourSlashRunner(FourSlashTestType.Native)); + runners.push(new FourSlashRunner(FourSlashTestType.Shims)); //runners.push(new GeneratedFourslashRunner()); } diff --git a/tests/baselines/reference/getBreakpointStatementAtPosition.baseline b/tests/baselines/reference/getBreakpointStatementAtPosition.baseline new file mode 100644 index 00000000000..617589b9047 --- /dev/null +++ b/tests/baselines/reference/getBreakpointStatementAtPosition.baseline @@ -0,0 +1,71 @@ + +1 >while (true) { + + ~~~~~~~~~~~~~~~ => Pos: (0 to 14) SpanInfo: {"start":0,"length":12} + >while (true) + >:=> (line 1, col 0) to (line 1, col 12) +-------------------------------- +2 > break; + + ~~~~~~~~~~~ => Pos: (15 to 25) SpanInfo: {"start":19,"length":5} + >break + >:=> (line 2, col 4) to (line 2, col 9) +-------------------------------- +3 >} + + ~~ => Pos: (26 to 27) SpanInfo: {"start":19,"length":5} + >break + >:=> (line 2, col 4) to (line 2, col 9) +-------------------------------- +4 >y: while (true) { + + ~~~~~~~~~~~~~~~~~~ => Pos: (28 to 45) SpanInfo: {"start":31,"length":12} + >while (true) + >:=> (line 4, col 3) to (line 4, col 15) +-------------------------------- +5 > break y; + + ~~~~~~~~~~~~~ => Pos: (46 to 58) SpanInfo: {"start":50,"length":7} + >break y + >:=> (line 5, col 4) to (line 5, col 11) +-------------------------------- +6 >} + + ~~ => Pos: (59 to 60) SpanInfo: {"start":50,"length":7} + >break y + >:=> (line 5, col 4) to (line 5, col 11) +-------------------------------- +7 >while (true) { + + ~~~~~~~~~~~~~~~ => Pos: (61 to 75) SpanInfo: {"start":61,"length":12} + >while (true) + >:=> (line 7, col 0) to (line 7, col 12) +-------------------------------- +8 > continue; + + ~~~~~~~~~~~~~~ => Pos: (76 to 89) SpanInfo: {"start":80,"length":8} + >continue + >:=> (line 8, col 4) to (line 8, col 12) +-------------------------------- +9 >} + + ~~ => Pos: (90 to 91) SpanInfo: {"start":80,"length":8} + >continue + >:=> (line 8, col 4) to (line 8, col 12) +-------------------------------- +10 >z: while (true) { + + ~~~~~~~~~~~~~~~~~~ => Pos: (92 to 109) SpanInfo: {"start":95,"length":12} + >while (true) + >:=> (line 10, col 3) to (line 10, col 15) +-------------------------------- +11 > continue z; + + ~~~~~~~~~~~~~~~~ => Pos: (110 to 125) SpanInfo: {"start":114,"length":10} + >continue z + >:=> (line 11, col 4) to (line 11, col 14) +-------------------------------- +12 >} + ~ => Pos: (126 to 126) SpanInfo: {"start":114,"length":10} + >continue z + >:=> (line 11, col 4) to (line 11, col 14) \ No newline at end of file diff --git a/tests/baselines/reference/getEmitOutput.baseline b/tests/baselines/reference/getEmitOutput.baseline new file mode 100644 index 00000000000..8ca4f6a4100 --- /dev/null +++ b/tests/baselines/reference/getEmitOutput.baseline @@ -0,0 +1,30 @@ +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/shims/inputFile1.js +var x = 5; +var Bar = (function () { + function Bar() { + } + return Bar; +})(); +Filename : tests/cases/fourslash/shims/inputFile1.d.ts +declare var x: number; +declare class Bar { + x: string; + y: number; +} + +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/shims/inputFile2.js +var x1 = "hello world"; +var Foo = (function () { + function Foo() { + } + return Foo; +})(); +Filename : tests/cases/fourslash/shims/inputFile2.d.ts +declare var x1: string; +declare class Foo { + x: string; + y: number; +} + diff --git a/tests/cases/fourslash/indentation.ts b/tests/cases/fourslash/indentation.ts index 32319ae282d..2a2090c1d87 100644 --- a/tests/cases/fourslash/indentation.ts +++ b/tests/cases/fourslash/indentation.ts @@ -179,5 +179,5 @@ ////{| "indent": 0 |} test.markers().forEach((marker) => { - verify.indentationAtPositionIs('tests/cases/fourslash/indentation.ts', marker.position, marker.data.indent); + verify.indentationAtPositionIs(marker.fileName, marker.position, marker.data.indent); }); diff --git a/tests/cases/fourslash/shims/cancellationWhenfindingAllRefsOnDefinition.ts b/tests/cases/fourslash/shims/cancellationWhenfindingAllRefsOnDefinition.ts new file mode 100644 index 00000000000..09f580bb965 --- /dev/null +++ b/tests/cases/fourslash/shims/cancellationWhenfindingAllRefsOnDefinition.ts @@ -0,0 +1,38 @@ +/// + +//@Filename: findAllRefsOnDefinition-import.ts +////export class Test{ +//// +//// constructor(){ +//// +//// } +//// +//// public /*1*/start(){ +//// return this; +//// } +//// +//// public stop(){ +//// return this; +//// } +////} + +//@Filename: findAllRefsOnDefinition.ts +////import Second = require("findAllRefsOnDefinition-import"); +//// +////var second = new Second.Test() +////second.start(); +////second.stop(); + +goTo.file("findAllRefsOnDefinition-import.ts"); +goTo.marker("1"); + +verify.referencesCountIs(2); + +cancellation.setCancelled(); +goTo.marker("1"); +verifyOperationIsCancelled(() => verify.referencesCountIs(0) ); + +// verify that internal state is still correct +cancellation.resetCancelled(); +goTo.marker("1"); +verify.referencesCountIs(2); diff --git a/tests/cases/fourslash/shims/getBraceMatchingAtPosition.ts b/tests/cases/fourslash/shims/getBraceMatchingAtPosition.ts new file mode 100644 index 00000000000..fc8a71197db --- /dev/null +++ b/tests/cases/fourslash/shims/getBraceMatchingAtPosition.ts @@ -0,0 +1,43 @@ +/// + +//////curly braces +////module Foo [|{ +//// class Bar [|{ +//// private f() [|{ +//// }|] +//// +//// private f2() [|{ +//// if (true) [|{ }|] [|{ }|]; +//// }|] +//// }|] +////}|] +//// +//////parenthesis +////class FooBar { +//// private f[|()|] { +//// return [|([|(1 + 1)|])|]; +//// } +//// +//// private f2[|()|] { +//// if [|(true)|] { } +//// } +////} +//// +//////square brackets +////class Baz { +//// private f() { +//// var a: any[|[]|] = [|[[|[1, 2]|], [|[3, 4]|], 5]|]; +//// } +////} +//// +////// angular brackets +////class TemplateTest [||] { +//// public foo(a, b) { +//// return [||] a; +//// } +////} + +test.ranges().forEach((range) => { + verify.matchingBracePositionInCurrentFile(range.start, range.end - 1); + verify.matchingBracePositionInCurrentFile(range.end - 1, range.start); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/getBreakpointStatementAtPosition.ts b/tests/cases/fourslash/shims/getBreakpointStatementAtPosition.ts new file mode 100644 index 00000000000..9e1d075a17f --- /dev/null +++ b/tests/cases/fourslash/shims/getBreakpointStatementAtPosition.ts @@ -0,0 +1,17 @@ +/// + +// @BaselineFile: getBreakpointStatementAtPosition.baseline +// @Filename: getBreakpointStatementAtPosition.ts +////while (true) { +//// break; +////} +////y: while (true) { +//// break y; +////} +////while (true) { +//// continue; +////} +////z: while (true) { +//// continue z; +////} +verify.baselineCurrentFileBreakpointLocations(); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/getCompletionsAtPosition.ts b/tests/cases/fourslash/shims/getCompletionsAtPosition.ts new file mode 100644 index 00000000000..714d3390e76 --- /dev/null +++ b/tests/cases/fourslash/shims/getCompletionsAtPosition.ts @@ -0,0 +1,20 @@ +/// + +////function foo(strOrNum: string | number) { +//// /*1*/ +//// if (typeof strOrNum === "number") { +//// /*2*/ +//// } +//// else { +//// /*3*/ +//// } +////} + +goTo.marker('1'); +verify.completionListContains("strOrNum", "(parameter) strOrNum: string | number"); + +goTo.marker('2'); +verify.completionListContains("strOrNum", "(parameter) strOrNum: number"); + +goTo.marker('3'); +verify.completionListContains("strOrNum", "(parameter) strOrNum: string"); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/getDefinitionAtPosition.ts b/tests/cases/fourslash/shims/getDefinitionAtPosition.ts new file mode 100644 index 00000000000..54b799ba65f --- /dev/null +++ b/tests/cases/fourslash/shims/getDefinitionAtPosition.ts @@ -0,0 +1,29 @@ +/// + +// @Filename: goToDefinitionDifferentFile_Definition.ts +////var /*remoteVariableDefinition*/remoteVariable; +/////*remoteFunctionDefinition*/function remoteFunction() { } +/////*remoteClassDefinition*/class remoteClass { } +/////*remoteInterfaceDefinition*/interface remoteInterface{ } +/////*remoteModuleDefinition*/module remoteModule{ export var foo = 1;} + +// @Filename: goToDefinitionDifferentFile_Consumption.ts +/////*remoteVariableReference*/remoteVariable = 1; +/////*remoteFunctionReference*/remoteFunction(); +////var foo = new /*remoteClassReference*/remoteClass(); +////class fooCls implements /*remoteInterfaceReference*/remoteInterface { } +////var fooVar = /*remoteModuleReference*/remoteModule.foo; + +var markerList = [ + "remoteVariable", + "remoteFunction", + "remoteClass", + "remoteInterface", + "remoteModule", +]; + +markerList.forEach((marker) => { + goTo.marker(marker + 'Reference'); + goTo.definition(); + verify.caretAtMarker(marker + 'Definition'); +}); diff --git a/tests/cases/fourslash/shims/getEmitOutput.ts b/tests/cases/fourslash/shims/getEmitOutput.ts new file mode 100644 index 00000000000..699514521ed --- /dev/null +++ b/tests/cases/fourslash/shims/getEmitOutput.ts @@ -0,0 +1,22 @@ +/// + +// @BaselineFile: getEmitOutput.baseline +// @declaration: true + +// @Filename: inputFile1.ts +// @emitThisFile: true +//// var x: number = 5; +//// class Bar { +//// x : string; +//// y : number +//// } + +// @Filename: inputFile2.ts +// @emitThisFile: true +//// var x1: string = "hello world"; +//// class Foo{ +//// x : string; +//// y : number; +//// } + +verify.baselineGetEmitOutput(); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/getIndentationAtPosition.ts b/tests/cases/fourslash/shims/getIndentationAtPosition.ts new file mode 100644 index 00000000000..5e26781357e --- /dev/null +++ b/tests/cases/fourslash/shims/getIndentationAtPosition.ts @@ -0,0 +1,21 @@ +/// + +////class Bar { +//// {| "indentation": 4|} +//// private foo: string = ""; +//// {| "indentation": 4|} +//// private f() { +//// var a: any[] = [[1, 2], [3, 4], 5]; +//// {| "indentation": 8|} +//// return ((1 + 1)); +//// } +//// {| "indentation": 4|} +//// private f2() { +//// if (true) { } { }; +//// } +////} +////{| "indentation": 0|} + +test.markers().forEach((marker) => { + verify.indentationAtPositionIs(marker.fileName, marker.position, marker.data.indentation); +}); diff --git a/tests/cases/fourslash/shims/getNavigateToItems.ts b/tests/cases/fourslash/shims/getNavigateToItems.ts new file mode 100644 index 00000000000..9658c52324c --- /dev/null +++ b/tests/cases/fourslash/shims/getNavigateToItems.ts @@ -0,0 +1,27 @@ +/// + +/////// Module +////{| "itemName": "Shapes", "kind": "module", "parentName": "" |}module Shapes { +//// +//// // Class +//// {| "itemName": "Point", "kind": "class", "parentName": "Shapes" |}export class Point { +//// // Instance member +//// {| "itemName": "origin", "kind": "property", "parentName": "Point", "matchKind": "exact"|}private origin = 0.0; +//// +//// {| "itemName": "distFromZero", "kind": "property", "parentName": "Point", "matchKind": "exact"|}private distFromZero = 0.0; +//// +//// // Getter +//// {| "itemName": "distance", "kind": "getter", "parentName": "Point", "matchKind": "exact" |}get distance(): number { return 0; } +//// } +////} +//// +////// Local variables +////{| "itemName": "point", "kind": "var", "parentName": "", "matchKind": "exact"|}var point = new Shapes.Point(); + +//// Testing for exact matching of navigationItems + +test.markers().forEach((marker) => { + if (marker.data) { + verify.navigationItemsListContains(marker.data.itemName, marker.data.kind, marker.data.itemName, marker.data.matchKind, marker.fileName, marker.data.parentName); + } +}); diff --git a/tests/cases/fourslash/shims/getNavigationBarItems.ts b/tests/cases/fourslash/shims/getNavigationBarItems.ts new file mode 100644 index 00000000000..6c0738747f3 --- /dev/null +++ b/tests/cases/fourslash/shims/getNavigationBarItems.ts @@ -0,0 +1,13 @@ +/// + +//// {| "itemName": "c", "kind": "const", "parentName": "" |}const c = 0; + +test.markers().forEach(marker => { + verify.getScriptLexicalStructureListContains( + marker.data.itemName, + marker.data.kind, + marker.fileName, + marker.data.parentName, + marker.data.isAdditionalRange, + marker.position); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/getOccurrencesAtPosition.ts b/tests/cases/fourslash/shims/getOccurrencesAtPosition.ts new file mode 100644 index 00000000000..0654cc3962c --- /dev/null +++ b/tests/cases/fourslash/shims/getOccurrencesAtPosition.ts @@ -0,0 +1,18 @@ +/// + +/////*0*/ +////interface A { +//// foo: string; +////} +////function foo(x: A) { +//// x.f/*1*/oo +////} + +goTo.marker("1"); +verify.occurrencesAtPositionCount(2); + +goTo.marker("0"); +edit.insert("\r\n"); + +goTo.marker("1"); +verify.occurrencesAtPositionCount(2); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/getOutliningSpans.ts b/tests/cases/fourslash/shims/getOutliningSpans.ts new file mode 100644 index 00000000000..93665889eb4 --- /dev/null +++ b/tests/cases/fourslash/shims/getOutliningSpans.ts @@ -0,0 +1,113 @@ +/// + +////// interface +////interface IFoo[| { +//// getDist(): number; +////}|] +//// +////// class members +////class Foo[| { +//// constructor()[| { +//// }|] +//// +//// public foo(): number[| { +//// return 0; +//// }|] +//// +//// public get X()[| { +//// return 1; +//// }|] +//// +//// public set X(v: number)[| { +//// }|] +//// +//// public member = function f()[| { +//// +//// }|] +////}|] +////switch(1)[| { +//// case 1: break; +////}|] +//// +////var array =[| [ +//// 1, +//// 2 +////]|] +//// +////// modules +////module m1[| { +//// module m2[| { }|] +//// module m3[| { +//// function foo()[| { +//// +//// }|] +//// +//// interface IFoo2[| { +//// +//// }|] +//// +//// class foo2 implements IFoo2[| { +//// +//// }|] +//// }|] +////}|] +//// +////// function declaration +////function foo(): number[| { +//// return 0; +////}|] +//// +////// function expressions +////(function f()[| { +//// +////}|]) +//// +////// trivia handeling +////class ClassFooWithTrivia[| /* some comments */ +//// /* more trivia */ { +//// +//// +//// /*some trailing trivia */ +////}|] /* even more */ +//// +////// object literals +////var x =[|{ +//// a:1, +//// b:2, +//// get foo()[| { +//// return 1; +//// }|] +////}|] +//////outline with deep nesting +////module m1[|{ +//// module m2[| { +//// module m3[| { +//// module m4[| { +//// module m5[| { +//// module m6[| { +//// module m7[| { +//// module m8[| { +//// module m9[| { +//// module m10[| { +//// module m11 { +//// module m12 { +//// export interface IFoo { +//// } +//// } +//// } +//// }|] +//// }|] +//// }|] +//// }|] +//// }|] +//// }|] +//// }|] +//// }|] +//// }|] +////}|] +//// +//////outline after a deeply nested node +////class AfterNestedNodes[| { +////}|] + +verify.outliningSpansInCurrentFile(test.ranges()); diff --git a/tests/cases/fourslash/shims/getPreProcessedFile.ts b/tests/cases/fourslash/shims/getPreProcessedFile.ts new file mode 100644 index 00000000000..abd26bb6e4b --- /dev/null +++ b/tests/cases/fourslash/shims/getPreProcessedFile.ts @@ -0,0 +1,32 @@ +/// + +// @Filename: refFile1.ts +//// class D { } + +// @Filename: refFile2.ts +//// export class E {} + +// @Filename: main.ts +// @ResolveReference: true +//// /// +//// /*1*/////*2*/ +//// /*3*/////*4*/ +//// import ref2 = require("refFile2"); +//// import noExistref2 = require(/*5*/"NotExistRefFile2"/*6*/); +//// import invalidRef1 /*7*/require/*8*/("refFile2"); +//// /*9*/import invalidRef2 = requi/*10*/("refFile2"); +//// var obj: /*11*/C/*12*/; +//// var obj1: D; +//// var obj2: ref2.E; + +goTo.file("main.ts"); +verify.numberOfErrorsInCurrentFile(7); +verify.errorExistsBetweenMarkers("1", "2"); +verify.errorExistsBetweenMarkers("3", "4"); +verify.errorExistsBetweenMarkers("5", "6"); +verify.errorExistsBetweenMarkers("7", "8"); +verify.errorExistsBetweenMarkers("9", "10"); // At this position, there are two diagnostic messages: ';' expected, Cannot find name 'requi' +verify.errorExistsBetweenMarkers("11", "12"); + + + diff --git a/tests/cases/fourslash/shims/getQuickInfoAtPosition.ts b/tests/cases/fourslash/shims/getQuickInfoAtPosition.ts new file mode 100644 index 00000000000..6c9fc7cf795 --- /dev/null +++ b/tests/cases/fourslash/shims/getQuickInfoAtPosition.ts @@ -0,0 +1,16 @@ +/// + +////class SS{} +//// +////var x/*1*/1 = new SS(); +////var x/*2*/2 = new SS(); +////var x/*3*/3 = new SS; + +goTo.marker('1'); +verify.quickInfoIs('(var) x1: SS'); + +goTo.marker('2'); +verify.quickInfoIs('(var) x2: SS<{}>'); + +goTo.marker('3'); +verify.quickInfoIs('(var) x3: SS<{}>'); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/getReferencesAtPosition.ts b/tests/cases/fourslash/shims/getReferencesAtPosition.ts new file mode 100644 index 00000000000..34144b74899 --- /dev/null +++ b/tests/cases/fourslash/shims/getReferencesAtPosition.ts @@ -0,0 +1,29 @@ +/// + +//@Filename: findAllRefsOnDefinition-import.ts +////export class Test{ +//// +//// constructor(){ +//// +//// } +//// +//// public /*1*/start(){ +//// return this; +//// } +//// +//// public stop(){ +//// return this; +//// } +////} + +//@Filename: findAllRefsOnDefinition.ts +////import Second = require("findAllRefsOnDefinition-import"); +//// +////var second = new Second.Test() +////second.start(); +////second.stop(); + +goTo.file("findAllRefsOnDefinition-import.ts"); +goTo.marker("1"); + +verify.referencesCountIs(2); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/getRenameInfo.ts b/tests/cases/fourslash/shims/getRenameInfo.ts new file mode 100644 index 00000000000..b5c8ac6aacc --- /dev/null +++ b/tests/cases/fourslash/shims/getRenameInfo.ts @@ -0,0 +1,11 @@ +/// + +/////// + +////function /**/[|Bar|]() { +//// // This is a reference to Bar in a comment. +//// "this is a reference to Bar in a string" +////} + +goTo.marker(); +verify.renameLocations(/*findInStrings:*/ false, /*findInComments:*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/getSemanticClassifications.ts b/tests/cases/fourslash/shims/getSemanticClassifications.ts new file mode 100644 index 00000000000..4eb7f2a32ed --- /dev/null +++ b/tests/cases/fourslash/shims/getSemanticClassifications.ts @@ -0,0 +1,15 @@ +/// + +//// module /*0*/M { +//// export interface /*1*/I { +//// } +//// } +//// interface /*2*/X extends /*3*/M./*4*/I { } + +var c = classification; +verify.semanticClassificationsAre( + c.moduleName("M", test.marker("0").position), + c.interfaceName("I", test.marker("1").position), + c.interfaceName("X", test.marker("2").position), + c.moduleName("M", test.marker("3").position), + c.interfaceName("I", test.marker("4").position)); diff --git a/tests/cases/fourslash/shims/getSemanticDiagnostics.ts b/tests/cases/fourslash/shims/getSemanticDiagnostics.ts new file mode 100644 index 00000000000..6345c464213 --- /dev/null +++ b/tests/cases/fourslash/shims/getSemanticDiagnostics.ts @@ -0,0 +1,11 @@ +/// + +// @module: CommonJS +// @declaration: true +//// interface privateInterface {} +//// export class Bar implements /*1*/privateInterface/*2*/{ } + +verify.errorExistsBetweenMarkers("1", "2"); +verify.numberOfErrorsInCurrentFile(1); + + diff --git a/tests/cases/fourslash/shims/getSignatureHelpItems.ts b/tests/cases/fourslash/shims/getSignatureHelpItems.ts new file mode 100644 index 00000000000..846c2d5244a --- /dev/null +++ b/tests/cases/fourslash/shims/getSignatureHelpItems.ts @@ -0,0 +1,13 @@ +/// + +// @Filename: signatureHelpInFunctionCallOnFunctionDeclarationInMultipleFiles_file0.ts +////declare function fn(x: string, y: number); + +// @Filename: signatureHelpInFunctionCallOnFunctionDeclarationInMultipleFiles_file1.ts +////declare function fn(x: string); + +// @Filename: signatureHelpInFunctionCallOnFunctionDeclarationInMultipleFiles_file2.ts +////fn(/*1*/ + +goTo.marker('1'); +verify.signatureHelpCountIs(2); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/getSyntacticClassifications.ts b/tests/cases/fourslash/shims/getSyntacticClassifications.ts new file mode 100644 index 00000000000..88f655683a3 --- /dev/null +++ b/tests/cases/fourslash/shims/getSyntacticClassifications.ts @@ -0,0 +1,35 @@ +/// + +//// // comment +//// module M { +//// var v = 0 + 1; +//// var s = "string"; +//// +//// class C { +//// } +//// +//// enum E { +//// } +//// +//// interface I { +//// } +//// +//// module M1.M2 { +//// } +//// } + +var c = classification; +verify.syntacticClassificationsAre( + c.comment("// comment"), + c.keyword("module"), c.moduleName("M"), c.punctuation("{"), + c.keyword("var"), c.text("v"), c.operator("="), c.numericLiteral("0"), c.operator("+"), c.numericLiteral("1"), c.punctuation(";"), + c.keyword("var"), c.text("s"), c.operator("="), c.stringLiteral('"string"'), c.punctuation(";"), + c.keyword("class"), c.className("C"), c.punctuation("<"), c.typeParameterName("T"), c.punctuation(">"), c.punctuation("{"), + c.punctuation("}"), + c.keyword("enum"), c.enumName("E"), c.punctuation("{"), + c.punctuation("}"), + c.keyword("interface"), c.interfaceName("I"), c.punctuation("{"), + c.punctuation("}"), + c.keyword("module"), c.moduleName("M1"), c.punctuation("."), c.moduleName("M2"), c.punctuation("{"), + c.punctuation("}"), + c.punctuation("}")); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/getTodoComments.ts b/tests/cases/fourslash/shims/getTodoComments.ts new file mode 100644 index 00000000000..b1e0086b93f --- /dev/null +++ b/tests/cases/fourslash/shims/getTodoComments.ts @@ -0,0 +1,3 @@ +//// // [|TODO|] + +verify.todoCommentsInCurrentFile(["TODO"]); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/quickInfoDisplayPartsVar.ts b/tests/cases/fourslash/shims/quickInfoDisplayPartsVar.ts new file mode 100644 index 00000000000..56ccceb3ab3 --- /dev/null +++ b/tests/cases/fourslash/shims/quickInfoDisplayPartsVar.ts @@ -0,0 +1,76 @@ +/// + +////var /*1*/a = 10; +////function foo() { +//// var /*2*/b = /*3*/a; +////} +////module m { +//// var /*4*/c = 10; +//// export var /*5*/d = 10; +////} +////var /*6*/f: () => number; +////var /*7*/g = /*8*/f; +/////*9*/f(); +////var /*10*/h: { (a: string): number; (a: number): string; }; +////var /*11*/i = /*12*/h; +/////*13*/h(10); +/////*14*/h("hello"); + +var marker = 0; +function verifyVar(name: string, isLocal: boolean, typeDisplay: ts.SymbolDisplayPart[], optionalNameDisplay?: ts.SymbolDisplayPart[], optionalKindModifiers?: string) { + marker++; + goTo.marker(marker.toString()); + var kind = isLocal ? "local var" : "var"; + verify.verifyQuickInfoDisplayParts(kind, optionalKindModifiers || "", { start: test.markerByName(marker.toString()).position, length: name.length }, + [{ text: "(", kind: "punctuation" }, { text: kind, kind: "text" }, { text: ")", kind: "punctuation" }, + { text: " ", kind: "space" }].concat(optionalNameDisplay || [{ text: name, kind: "localName" }]).concat( + { text: ":", kind: "punctuation" }, { text: " ", kind: "space" }).concat(typeDisplay), + []); +} + +var numberTypeDisplay: ts.SymbolDisplayPart[] = [{ text: "number", kind: "keyword" }]; + +verifyVar("a", /*isLocal*/false, numberTypeDisplay); +verifyVar("b", /*isLocal*/true, numberTypeDisplay); +verifyVar("a", /*isLocal*/false, numberTypeDisplay); +verifyVar("c", /*isLocal*/false, numberTypeDisplay); +verifyVar("d", /*isLocal*/false, numberTypeDisplay, [{ text: "m", kind: "moduleName" }, { text: ".", kind: "punctuation" }, { text: "d", kind: "localName" }], "export"); + +var functionTypeReturningNumber: ts.SymbolDisplayPart[] = [{ text: "(", kind: "punctuation" }, { text: ")", kind: "punctuation" }, + { text: " ", kind: "space" }, { text: "=>", kind: "punctuation" }, { text: " ", kind: "space" }, { text: "number", kind: "keyword" }]; +verifyVar("f", /*isLocal*/ false, functionTypeReturningNumber); +verifyVar("g", /*isLocal*/ false, functionTypeReturningNumber); +verifyVar("f", /*isLocal*/ false, functionTypeReturningNumber); +verifyVar("f", /*isLocal*/ false, functionTypeReturningNumber); + + +function getFunctionType(parametertype: string, returnType: string, isArrow?: boolean): ts.SymbolDisplayPart[] { + var functionTypeDisplay = [{ text: "(", kind: "punctuation" }, { text: "a", kind: "parameterName" }, { text: ":", kind: "punctuation" }, + { text: " ", kind: "space" }, { text: parametertype, kind: "keyword" }, { text: ")", kind: "punctuation" }]; + + if (isArrow) { + functionTypeDisplay = functionTypeDisplay.concat({ text: " ", kind: "space" }, { text: "=>", kind: "punctuation" }); + } + else { + functionTypeDisplay = functionTypeDisplay.concat({ text: ":", kind: "punctuation" }); + } + + return functionTypeDisplay.concat({ text: " ", kind: "space" }, { text: returnType, kind: "keyword" }); +} + +var typeLiteralWithOverloadCall: ts.SymbolDisplayPart[] = [{ text: "{", kind: "punctuation" }, { text: "\n", kind: "lineBreak" }, + { text: " ", kind: "space" }].concat(getFunctionType("string", "number")).concat( + { text: ";", kind: "punctuation" }, { text: "\n", kind: "lineBreak" }, + { text: " ", kind: "space" }).concat(getFunctionType("number", "string")).concat( + { text: ";", kind: "punctuation" }, { text: "\n", kind: "lineBreak" }, { text: "}", kind: "punctuation" }); + +verifyVar("h", /*isLocal*/ false, typeLiteralWithOverloadCall); +verifyVar("i", /*isLocal*/ false, typeLiteralWithOverloadCall); +verifyVar("h", /*isLocal*/ false, typeLiteralWithOverloadCall); + +var overloadDisplay: ts.SymbolDisplayPart[] = [{ text: " ", kind: "space" }, { text: "(", kind: "punctuation" }, + { text: "+", kind: "operator" }, { text: "1", kind: "numericLiteral" }, + { text: " ", kind: "space" }, { text: "overload", kind: "text" }, { text: ")", kind: "punctuation" }]; + +verifyVar("h", /*isLocal*/ false, getFunctionType("number", "string", /*isArrow*/true).concat(overloadDisplay)); +verifyVar("h", /*isLocal*/ false, getFunctionType("string", "number", /*isArrow*/true).concat(overloadDisplay)); \ No newline at end of file From fd2518dcddd664fbad7663e293ba9ecf8a7fc4a0 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 4 Feb 2015 20:07:12 -0800 Subject: [PATCH 12/14] rename type --- src/harness/harnessLanguageService.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 2fce141bbf3..15baafb0429 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -78,7 +78,7 @@ module Harness.LanguageService { } } - class ScriptSnapshotShim implements ts.ScriptSnapshotShim { + class ScriptSnapshotProxy implements ts.ScriptSnapshotShim { constructor(public scriptSnapshot: ts.IScriptSnapshot) { } @@ -91,7 +91,7 @@ module Harness.LanguageService { } public getChangeRange(oldScript: ts.ScriptSnapshotShim): string { - var oldShim = oldScript; + var oldShim = oldScript; var range = this.scriptSnapshot.getChangeRange(oldShim.scriptSnapshot); if (range === null) { @@ -248,7 +248,7 @@ module Harness.LanguageService { getScriptFileNames(): string { return JSON.stringify(this.nativeHost.getScriptFileNames()); } getScriptSnapshot(filename: string): ts.ScriptSnapshotShim { var nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(filename); - return nativeScriptSnapshot && new ScriptSnapshotShim(nativeScriptSnapshot); + return nativeScriptSnapshot && new ScriptSnapshotProxy(nativeScriptSnapshot); } getScriptVersion(filename: string): string { return this.nativeHost.getScriptVersion(filename); } getLocalizedDiagnosticMessages(): string { return JSON.stringify({}); } From 68beccc4802d7f294a93e53f52301b7e73568970 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Wed, 4 Feb 2015 20:35:21 -0800 Subject: [PATCH 13/14] Fix getFileContents so as not to always return the current file --- src/harness/fourslash.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index eae34cfc082..19ea8927910 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -376,7 +376,7 @@ module FourSlash { } private getFileContent(fileName: string): string { - var script = this.languageServiceAdaptorHost.getScriptInfo(this.activeFile.fileName); + var script = this.languageServiceAdaptorHost.getScriptInfo(fileName); return script.content; } From 08f51b90704d399161ae44d872bc0c0ecb4676c6 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 9 Feb 2015 09:19:50 -0800 Subject: [PATCH 14/14] Respond to code review comments --- src/harness/fourslash.ts | 66 +++++++------- src/harness/harnessLanguageService.ts | 87 +++++++++---------- .../cases/unittests/services/colorization.ts | 4 +- 3 files changed, 76 insertions(+), 81 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index ca860d4cd8a..603a78b5f75 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -246,7 +246,7 @@ module FourSlash { export class TestState { // Language service instance - private languageServiceAdaptorHost: Harness.LanguageService.LanguageServiceAdaptorHost; + private languageServiceAdapterHost: Harness.LanguageService.LanguageServiceAdapterHost; private languageService: ts.LanguageService; private cancellationToken: TestCancellationToken; @@ -272,32 +272,28 @@ module FourSlash { private addMatchedInputFile(referenceFilePath: string) { var inputFile = this.inputFiles[referenceFilePath]; if (inputFile && !Harness.isLibraryFile(referenceFilePath)) { - this.languageServiceAdaptorHost.addScript(referenceFilePath, inputFile); + this.languageServiceAdapterHost.addScript(referenceFilePath, inputFile); } } - private getLanguageServiceAdaptor(testType: FourSlashTestType): - { new (cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions): Harness.LanguageService.LanguageServiceAdaptor } { + private getLanguageServiceAdapter(testType: FourSlashTestType, cancellationToken: TestCancellationToken, compilationOptions: ts.CompilerOptions): Harness.LanguageService.LanguageServiceAdapter { switch (testType) { case FourSlashTestType.Native: - return Harness.LanguageService.NativeLanugageServiceAdaptor; - break; + return new Harness.LanguageService.NativeLanugageServiceAdapter(cancellationToken, compilationOptions); case FourSlashTestType.Shims: - return Harness.LanguageService.ShimLanugageServiceAdaptor; - break; + return new Harness.LanguageService.ShimLanugageServiceAdapter(cancellationToken, compilationOptions); default: throw new Error("Unknown FourSlash test type: "); } } constructor(private basePath: string, private testType: FourSlashTestType, public testData: FourSlashData) { - // Create a new Services Adaptor + // Create a new Services Adapter this.cancellationToken = new TestCancellationToken(); var compilationOptions = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions); - var languageserviceAdaptorFactory = this.getLanguageServiceAdaptor(testType); - var languageServiceAdaptor = new languageserviceAdaptorFactory(this.cancellationToken, compilationOptions); - this.languageServiceAdaptorHost = languageServiceAdaptor.getHost(); - this.languageService = languageServiceAdaptor.getLanguageService(); + var languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions); + this.languageServiceAdapterHost = languageServiceAdapter.getHost(); + this.languageService = languageServiceAdapter.getLanguageService(); // Initialize the language service with all the scripts var startResolveFileRef: FourSlashFile; @@ -315,16 +311,16 @@ module FourSlash { if (startResolveFileRef) { // Add the entry-point file itself into the languageServiceShimHost - this.languageServiceAdaptorHost.addScript(startResolveFileRef.fileName, startResolveFileRef.content); + this.languageServiceAdapterHost.addScript(startResolveFileRef.fileName, startResolveFileRef.content); - var resolvedResult = languageServiceAdaptor.getPreProcessedFileInfo(startResolveFileRef.fileName, startResolveFileRef.content); + var resolvedResult = languageServiceAdapter.getPreProcessedFileInfo(startResolveFileRef.fileName, startResolveFileRef.content); var referencedFiles: ts.FileReference[] = resolvedResult.referencedFiles; var importedFiles: ts.FileReference[] = resolvedResult.importedFiles; // Add triple reference files into language-service host ts.forEach(referencedFiles, referenceFile => { // Fourslash insert tests/cases/fourslash into inputFile.unitName so we will properly append the same base directory to refFile path - var referenceFilePath = this.basePath+ '/' + referenceFile.fileName; + var referenceFilePath = this.basePath + '/' + referenceFile.fileName; this.addMatchedInputFile(referenceFilePath); }); @@ -338,16 +334,16 @@ module FourSlash { // Check if no-default-lib flag is false and if so add default library if (!resolvedResult.isLibFile) { - this.languageServiceAdaptorHost.addScript(Harness.Compiler.defaultLibFileName, Harness.Compiler.defaultLibSourceFile.text); + this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName, Harness.Compiler.defaultLibSourceFile.text); } } else { // resolveReference file-option is not specified then do not resolve any files and include all inputFiles ts.forEachKey(this.inputFiles, fileName => { if (!Harness.isLibraryFile(fileName)) { - this.languageServiceAdaptorHost.addScript(fileName, this.inputFiles[fileName]); + this.languageServiceAdapterHost.addScript(fileName, this.inputFiles[fileName]); } }); - this.languageServiceAdaptorHost.addScript(Harness.Compiler.defaultLibFileName, Harness.Compiler.defaultLibSourceFile.text); + this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName, Harness.Compiler.defaultLibSourceFile.text); } this.formatCodeOptions = { @@ -376,7 +372,7 @@ module FourSlash { } private getFileContent(fileName: string): string { - var script = this.languageServiceAdaptorHost.getScriptInfo(fileName); + var script = this.languageServiceAdapterHost.getScriptInfo(fileName); return script.content; } @@ -464,7 +460,7 @@ module FourSlash { private getAllDiagnostics(): ts.Diagnostic[] { var diagnostics: ts.Diagnostic[] = []; - var fileNames = this.languageServiceAdaptorHost.getFilenames(); + var fileNames = this.languageServiceAdapterHost.getFilenames(); for (var i = 0, n = fileNames.length; i < n; i++) { diagnostics.push.apply(this.getDiagnostics(fileNames[i])); } @@ -1255,7 +1251,7 @@ module FourSlash { } public printContext() { - ts.forEach(this.languageServiceAdaptorHost.getFilenames(), Harness.IO.log); + ts.forEach(this.languageServiceAdapterHost.getFilenames(), Harness.IO.log); } public deleteChar(count = 1) { @@ -1268,7 +1264,7 @@ module FourSlash { for (var i = 0; i < count; i++) { // Make the edit - this.languageServiceAdaptorHost.editScript(this.activeFile.fileName, offset, offset + 1, ch); + this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset + 1, ch); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset + 1, ch); if (i % checkCadence === 0) { @@ -1295,7 +1291,7 @@ module FourSlash { public replace(start: number, length: number, text: string) { this.taoInvalidReason = 'replace NYI'; - this.languageServiceAdaptorHost.editScript(this.activeFile.fileName, start, start + length, text); + this.languageServiceAdapterHost.editScript(this.activeFile.fileName, start, start + length, text); this.updateMarkersForEdit(this.activeFile.fileName, start, start + length, text); this.checkPostEditInvariants(); } @@ -1310,7 +1306,7 @@ module FourSlash { for (var i = 0; i < count; i++) { offset--; // Make the edit - this.languageServiceAdaptorHost.editScript(this.activeFile.fileName, offset, offset + 1, ch); + this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset + 1, ch); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset + 1, ch); if (i % checkCadence === 0) { @@ -1355,7 +1351,7 @@ module FourSlash { for (var i = 0; i < text.length; i++) { // Make the edit var ch = text.charAt(i); - this.languageServiceAdaptorHost.editScript(this.activeFile.fileName, offset, offset, ch); + this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset, ch); this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, offset); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, ch); @@ -1398,7 +1394,7 @@ module FourSlash { var start = this.currentCaretPosition; var offset = this.currentCaretPosition; - this.languageServiceAdaptorHost.editScript(this.activeFile.fileName, offset, offset, text); + this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset, text); this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, text); this.checkPostEditInvariants(); offset += text.length; @@ -1461,7 +1457,7 @@ module FourSlash { // Get a snapshot of the content of the file so we can make sure any formatting edits didn't destroy non-whitespace characters var oldContent = this.getFileContent(this.activeFile.fileName); for (var j = 0; j < edits.length; j++) { - this.languageServiceAdaptorHost.editScript(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText); + this.languageServiceAdapterHost.editScript(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText); this.updateMarkersForEdit(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText); var change = (edits[j].span.start - ts.textSpanEnd(edits[j].span)) + edits[j].newText.length; runningOffset += change; @@ -1742,8 +1738,8 @@ module FourSlash { function jsonMismatchString() { return ts.sys.newLine + - "expected: '" + ts.sys.newLine + JSON.stringify(expected,(k, v) => v, 2) + "'" + ts.sys.newLine + - "actual: '" + ts.sys.newLine + JSON.stringify(actual,(k, v) => v, 2) + "'"; + "expected: '" + ts.sys.newLine + JSON.stringify(expected, (k, v) => v, 2) + "'" + ts.sys.newLine + + "actual: '" + ts.sys.newLine + JSON.stringify(actual, (k, v) => v, 2) + "'"; } } @@ -2017,7 +2013,7 @@ module FourSlash { // The current caret position (in line/col terms) var line = this.getCurrentCaretFilePosition().line; // The line/col of the start of this line - var pos = this.languageServiceAdaptorHost.lineColToPosition(this.activeFile.fileName, line, 1); + var pos = this.languageServiceAdapterHost.lineColToPosition(this.activeFile.fileName, line, 1); // The index of the current file // The text from the start of the line to the end of the file @@ -2037,7 +2033,7 @@ module FourSlash { } private getCurrentCaretFilePosition() { - var result = this.languageServiceAdaptorHost.positionToZeroBasedLineCol(this.activeFile.fileName, this.currentCaretPosition); + var result = this.languageServiceAdapterHost.positionToZeroBasedLineCol(this.activeFile.fileName, this.currentCaretPosition); if (result.line >= 0) { result.line++; } @@ -2097,7 +2093,7 @@ module FourSlash { var name = indexOrName; // names are stored in the compiler with this relative path, this allows people to use goTo.file on just the fileName - name = name.indexOf('/') === -1 ? (this.basePath + '/' + name) : name; + name = name.indexOf('/') === -1 ? (this.basePath + '/' + name) : name; var availableNames: string[] = []; var foundIt = false; @@ -2124,7 +2120,7 @@ module FourSlash { } private getLineColStringAtPosition(position: number) { - var pos = this.languageServiceAdaptorHost.positionToZeroBasedLineCol(this.activeFile.fileName, position); + var pos = this.languageServiceAdapterHost.positionToZeroBasedLineCol(this.activeFile.fileName, position); return 'line ' + (pos.line + 1) + ', col ' + pos.character; } @@ -2285,7 +2281,7 @@ module FourSlash { currentFileName = fileName; } - currentFileName = basePath + '/' + match[2]; + currentFileName = basePath + '/' + match[2]; currentFileOptions[match[1]] = match[2]; } else { // Add other fileMetadata flag diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 4ada92e0172..2f95f5072d0 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -113,14 +113,14 @@ module Harness.LanguageService { } } - export interface LanguageServiceAdaptor { - getHost(): LanguageServiceAdaptorHost; + export interface LanguageServiceAdapter { + getHost(): LanguageServiceAdapterHost; getLanguageService(): ts.LanguageService; getClassifier(): ts.Classifier; getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo; } - class LanguageServiceHostBase { + export class LanguageServiceAdapterHost { protected fileNameToScript: ts.Map = {}; constructor(protected cancellationToken: ts.CancellationToken = CancellationToken.None, @@ -194,11 +194,8 @@ module Harness.LanguageService { } } - export interface LanguageServiceAdaptorHost extends LanguageServiceHostBase { - } - - /// Native adabtor - class NativeLanguageServiceHost extends LanguageServiceHostBase implements ts.LanguageServiceHost { + /// Native adapter + class NativeLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceHost { getCompilationSettings(): ts.CompilerOptions { return this.settings; } getCancellationToken(): ts.CancellationToken { return this.cancellationToken; } getCurrentDirectory(): string { return ""; } @@ -217,7 +214,7 @@ module Harness.LanguageService { error(s: string): void { } } - export class NativeLanugageServiceAdaptor implements LanguageServiceAdaptor { + export class NativeLanugageServiceAdapter implements LanguageServiceAdapter { private host: NativeLanguageServiceHost; constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { this.host = new NativeLanguageServiceHost(cancellationToken, options); @@ -228,8 +225,8 @@ module Harness.LanguageService { getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { return ts.preProcessFile(fileContents); } } - /// Shim adabtor - class ShimLanguageServiceHost extends LanguageServiceHostBase implements ts.LanguageServiceShimHost { + /// Shim adapter + class ShimLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceShimHost { private nativeHost: NativeLanguageServiceHost; constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { super(cancellationToken, options); @@ -261,7 +258,8 @@ module Harness.LanguageService { } class ClassifierShimProxy implements ts.Classifier { - constructor(private shim: ts.ClassifierShim) { } + constructor(private shim: ts.ClassifierShim) { + } getClassificationsForLine(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.ClassificationResult { var result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split('\n'); var entries: ts.ClassificationInfo[] = []; @@ -288,7 +286,7 @@ module Harness.LanguageService { } } - function unwrappJSONCallResult(result: string): any { + function unwrapJSONCallResult(result: string): any { var parsedResult = JSON.parse(result); if (parsedResult.error) { throw new Error("Language Service Shim Error: " + JSON.stringify(parsedResult.error)); @@ -300,7 +298,8 @@ module Harness.LanguageService { } class LanguageServiceShimProxy implements ts.LanguageService { - constructor(private shim: ts.LanguageServiceShim) { } + constructor(private shim: ts.LanguageServiceShim) { + } private unwrappJSONCallResult(result: string): any { var parsedResult = JSON.parse(result); if (parsedResult.error) { @@ -312,93 +311,93 @@ module Harness.LanguageService { this.shim.cleanupSemanticCache(); } getSyntacticDiagnostics(fileName: string): ts.Diagnostic[] { - return unwrappJSONCallResult(this.shim.getSyntacticDiagnostics(fileName)); + return unwrapJSONCallResult(this.shim.getSyntacticDiagnostics(fileName)); } getSemanticDiagnostics(fileName: string): ts.Diagnostic[] { - return unwrappJSONCallResult(this.shim.getSemanticDiagnostics(fileName)); + return unwrapJSONCallResult(this.shim.getSemanticDiagnostics(fileName)); } getCompilerOptionsDiagnostics(): ts.Diagnostic[] { - return unwrappJSONCallResult(this.shim.getCompilerOptionsDiagnostics()); + return unwrapJSONCallResult(this.shim.getCompilerOptionsDiagnostics()); } getSyntacticClassifications(fileName: string, span: ts.TextSpan): ts.ClassifiedSpan[] { - return unwrappJSONCallResult(this.shim.getSyntacticClassifications(fileName, span.start, span.length)); + return unwrapJSONCallResult(this.shim.getSyntacticClassifications(fileName, span.start, span.length)); } getSemanticClassifications(fileName: string, span: ts.TextSpan): ts.ClassifiedSpan[] { - return unwrappJSONCallResult(this.shim.getSemanticClassifications(fileName, span.start, span.length)); + return unwrapJSONCallResult(this.shim.getSemanticClassifications(fileName, span.start, span.length)); } getCompletionsAtPosition(fileName: string, position: number): ts.CompletionInfo { - return unwrappJSONCallResult(this.shim.getCompletionsAtPosition(fileName, position)); + return unwrapJSONCallResult(this.shim.getCompletionsAtPosition(fileName, position)); } getCompletionEntryDetails(fileName: string, position: number, entryName: string): ts.CompletionEntryDetails { - return unwrappJSONCallResult(this.shim.getCompletionEntryDetails(fileName, position, entryName)); + return unwrapJSONCallResult(this.shim.getCompletionEntryDetails(fileName, position, entryName)); } getQuickInfoAtPosition(fileName: string, position: number): ts.QuickInfo { - return unwrappJSONCallResult(this.shim.getQuickInfoAtPosition(fileName, position)); + return unwrapJSONCallResult(this.shim.getQuickInfoAtPosition(fileName, position)); } getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): ts.TextSpan { - return unwrappJSONCallResult(this.shim.getNameOrDottedNameSpan(fileName, startPos, endPos)); + return unwrapJSONCallResult(this.shim.getNameOrDottedNameSpan(fileName, startPos, endPos)); } getBreakpointStatementAtPosition(fileName: string, position: number): ts.TextSpan { - return unwrappJSONCallResult(this.shim.getBreakpointStatementAtPosition(fileName, position)); + return unwrapJSONCallResult(this.shim.getBreakpointStatementAtPosition(fileName, position)); } getSignatureHelpItems(fileName: string, position: number): ts.SignatureHelpItems { - return unwrappJSONCallResult(this.shim.getSignatureHelpItems(fileName, position)); + return unwrapJSONCallResult(this.shim.getSignatureHelpItems(fileName, position)); } getRenameInfo(fileName: string, position: number): ts.RenameInfo { - return unwrappJSONCallResult(this.shim.getRenameInfo(fileName, position)); + return unwrapJSONCallResult(this.shim.getRenameInfo(fileName, position)); } findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): ts.RenameLocation[] { - return unwrappJSONCallResult(this.shim.findRenameLocations(fileName, position, findInStrings, findInComments)); + return unwrapJSONCallResult(this.shim.findRenameLocations(fileName, position, findInStrings, findInComments)); } getDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] { - return unwrappJSONCallResult(this.shim.getDefinitionAtPosition(fileName, position)); + return unwrapJSONCallResult(this.shim.getDefinitionAtPosition(fileName, position)); } getReferencesAtPosition(fileName: string, position: number): ts.ReferenceEntry[] { - return unwrappJSONCallResult(this.shim.getReferencesAtPosition(fileName, position)); + return unwrapJSONCallResult(this.shim.getReferencesAtPosition(fileName, position)); } getOccurrencesAtPosition(fileName: string, position: number): ts.ReferenceEntry[] { - return unwrappJSONCallResult(this.shim.getOccurrencesAtPosition(fileName, position)); + return unwrapJSONCallResult(this.shim.getOccurrencesAtPosition(fileName, position)); } getNavigateToItems(searchValue: string): ts.NavigateToItem[] { - return unwrappJSONCallResult(this.shim.getNavigateToItems(searchValue)); + return unwrapJSONCallResult(this.shim.getNavigateToItems(searchValue)); } getNavigationBarItems(fileName: string): ts.NavigationBarItem[] { - return unwrappJSONCallResult(this.shim.getNavigationBarItems(fileName)); + return unwrapJSONCallResult(this.shim.getNavigationBarItems(fileName)); } getOutliningSpans(fileName: string): ts.OutliningSpan[] { - return unwrappJSONCallResult(this.shim.getOutliningSpans(fileName)); + return unwrapJSONCallResult(this.shim.getOutliningSpans(fileName)); } getTodoComments(fileName: string, descriptors: ts.TodoCommentDescriptor[]): ts.TodoComment[] { - return unwrappJSONCallResult(this.shim.getTodoComments(fileName, JSON.stringify(descriptors))); + return unwrapJSONCallResult(this.shim.getTodoComments(fileName, JSON.stringify(descriptors))); } getBraceMatchingAtPosition(fileName: string, position: number): ts.TextSpan[] { - return unwrappJSONCallResult(this.shim.getBraceMatchingAtPosition(fileName, position)); + return unwrapJSONCallResult(this.shim.getBraceMatchingAtPosition(fileName, position)); } getIndentationAtPosition(fileName: string, position: number, options: ts.EditorOptions): number { - return unwrappJSONCallResult(this.shim.getIndentationAtPosition(fileName, position, JSON.stringify(options))); + return unwrapJSONCallResult(this.shim.getIndentationAtPosition(fileName, position, JSON.stringify(options))); } getFormattingEditsForRange(fileName: string, start: number, end: number, options: ts.FormatCodeOptions): ts.TextChange[] { - return unwrappJSONCallResult(this.shim.getFormattingEditsForRange(fileName, start, end, JSON.stringify(options))); + return unwrapJSONCallResult(this.shim.getFormattingEditsForRange(fileName, start, end, JSON.stringify(options))); } getFormattingEditsForDocument(fileName: string, options: ts.FormatCodeOptions): ts.TextChange[] { - return unwrappJSONCallResult(this.shim.getFormattingEditsForDocument(fileName, JSON.stringify(options))); + return unwrapJSONCallResult(this.shim.getFormattingEditsForDocument(fileName, JSON.stringify(options))); } getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: ts.FormatCodeOptions): ts.TextChange[] { - return unwrappJSONCallResult(this.shim.getFormattingEditsAfterKeystroke(fileName, position, key, JSON.stringify(options))); + return unwrapJSONCallResult(this.shim.getFormattingEditsAfterKeystroke(fileName, position, key, JSON.stringify(options))); } getEmitOutput(fileName: string): ts.EmitOutput { - return unwrappJSONCallResult(this.shim.getEmitOutput(fileName)); + return unwrapJSONCallResult(this.shim.getEmitOutput(fileName)); } getProgram(): ts.Program { - throw new Error("Program can not be marshalled accross the shim layer."); + throw new Error("Program can not be marshaled across the shim layer."); } getSourceFile(fileName: string): ts.SourceFile { - throw new Error("SourceFile can not be marshalled accross the shim layer."); + throw new Error("SourceFile can not be marshaled across the shim layer."); } dispose(): void { this.shim.dispose({}); } } - export class ShimLanugageServiceAdaptor implements LanguageServiceAdaptor { + export class ShimLanugageServiceAdapter implements LanguageServiceAdapter { private host: ShimLanguageServiceHost; private factory: ts.TypeScriptServicesFactory; constructor(cancellationToken?: ts.CancellationToken, options?: ts.CompilerOptions) { @@ -416,7 +415,7 @@ module Harness.LanguageService { }; var coreServicesShim = this.factory.createCoreServicesShim(this.host); - shimResult = unwrappJSONCallResult(coreServicesShim.getPreProcessedFileInfo(fileName, ts.ScriptSnapshot.fromString(fileContents))); + shimResult = unwrapJSONCallResult(coreServicesShim.getPreProcessedFileInfo(fileName, ts.ScriptSnapshot.fromString(fileContents))); var convertResult: ts.PreProcessedFileInfo = { referencedFiles: [], diff --git a/tests/cases/unittests/services/colorization.ts b/tests/cases/unittests/services/colorization.ts index b744b65608b..01149764305 100644 --- a/tests/cases/unittests/services/colorization.ts +++ b/tests/cases/unittests/services/colorization.ts @@ -7,8 +7,8 @@ interface ClassificationEntry { } describe('Colorization', function () { - // Use the shim adaptor to ensure test coverage of the shim layer for the classifier - var languageServiceAdabtor = new Harness.LanguageService.ShimLanugageServiceAdaptor(); + // Use the shim adapter to ensure test coverage of the shim layer for the classifier + var languageServiceAdabtor = new Harness.LanguageService.ShimLanugageServiceAdapter(); var classifier = languageServiceAdabtor.getClassifier(); function getEntryAtPosistion(result: ts.ClassificationResult, position: number) {