From 6bb481c9d3ac51f203cee02a4e7a0fed1464e1a1 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Fri, 7 May 2021 20:02:26 +0100 Subject: [PATCH] Support semantic highlights for JS files (#43992) * Switches from never allowing semantic highlight on JS to only doing it if we have a valid source file * Adds a way to test and validate that an arbitrary JS file gets semantic classification results * Revert to just dropping the if statement --- src/harness/client.ts | 6 ++++-- src/harness/fourslashImpl.ts | 6 ++++++ src/harness/fourslashInterfaceImpl.ts | 4 ++++ src/services/services.ts | 13 ------------- tests/cases/fourslash/fourslash.ts | 2 ++ tests/cases/fourslash/semanticClassificationJs.ts | 11 ----------- .../fourslash/server/semanticClassificationJs1.ts | 10 ++++++++++ 7 files changed, 26 insertions(+), 26 deletions(-) delete mode 100644 tests/cases/fourslash/semanticClassificationJs.ts create mode 100644 tests/cases/fourslash/server/semanticClassificationJs1.ts diff --git a/src/harness/client.ts b/src/harness/client.ts index cd46f97a09d..8f56015af23 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -772,8 +772,10 @@ namespace ts.server { return notImplemented(); } - getEncodedSemanticClassifications(_fileName: string, _span: TextSpan, _format?: SemanticClassificationFormat): Classifications { - return notImplemented(); + getEncodedSemanticClassifications(file: string, span: TextSpan, format?: SemanticClassificationFormat): Classifications { + const request = this.processRequest(protocol.CommandTypes.EncodedSemanticClassificationsFull, { file, start: span.start, length: span.length, format }); + const r = this.processResponse(request); + return r.body!; } private convertCallHierarchyItem(item: protocol.CallHierarchyItem): CallHierarchyItem { diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 877e1dc40e7..742dc6bced7 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -2746,6 +2746,12 @@ namespace FourSlash { // fs.writeFileSync(testfilePath, newfile); } + public verifyEncodedSemanticClassificationsLength(format: ts.SemanticClassificationFormat, expected: number) { + const actual = this.languageService.getEncodedSemanticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length), format); + if (actual.spans.length !== expected) { + this.raiseError(`encodedSemanticClassificationsLength failed - expected total spans to be ${expected} got ${actual.spans.length}`); + } + } public verifySemanticClassifications(format: ts.SemanticClassificationFormat, expected: { classificationType: string | number; text?: string }[]) { const actual = this.languageService.getSemanticClassifications(this.activeFile.fileName, diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 736581022dc..0eb1071681a 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -537,6 +537,10 @@ namespace FourSlashInterface { this.state.verifySyntacticClassifications(classifications); } + public encodedSemanticClassificationsLength(format: ts.SemanticClassificationFormat, length: number) { + this.state.verifyEncodedSemanticClassificationsLength(format, length); + } + /** * This method *requires* an ordered stream of classifications for a file, and spans are highly recommended. */ diff --git a/src/services/services.ts b/src/services/services.ts index 09af46f346e..08f6c8897a2 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1882,17 +1882,8 @@ namespace ts { return NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); } - function isTsOrTsxFile(fileName: string): boolean { - const kind = getScriptKind(fileName, host); - return kind === ScriptKind.TS || kind === ScriptKind.TSX; - } - function getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]; function getSemanticClassifications(fileName: string, span: TextSpan, format?: SemanticClassificationFormat): ClassifiedSpan[] | ClassifiedSpan2020[] { - if (!isTsOrTsxFile(fileName)) { - // do not run semantic classification on non-ts-or-tsx files - return []; - } synchronizeHostData(); const responseFormat = format || SemanticClassificationFormat.Original; @@ -1905,10 +1896,6 @@ namespace ts { } function getEncodedSemanticClassifications(fileName: string, span: TextSpan, format?: SemanticClassificationFormat): Classifications { - if (!isTsOrTsxFile(fileName)) { - // do not run semantic classification on non-ts-or-tsx files - return { spans: [], endOfLineState: EndOfLineState.None }; - } synchronizeHostData(); const responseFormat = format || SemanticClassificationFormat.Original; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 295ba1fd142..01b2710f912 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -358,6 +358,8 @@ declare namespace FourSlashInterface { rangesAreDocumentHighlights(ranges?: Range[], options?: VerifyDocumentHighlightsOptions): void; rangesWithSameTextAreDocumentHighlights(): void; documentHighlightsOf(startRange: Range, ranges: Range[], options?: VerifyDocumentHighlightsOptions): void; + /** Prefer semanticClassificationsAre for more descriptive tests */ + encodedSemanticClassificationsLength(format: "original" | "2020", length: number) /** * This method *requires* a contiguous, complete, and ordered stream of classifications for a file. */ diff --git a/tests/cases/fourslash/semanticClassificationJs.ts b/tests/cases/fourslash/semanticClassificationJs.ts deleted file mode 100644 index 69683d66695..00000000000 --- a/tests/cases/fourslash/semanticClassificationJs.ts +++ /dev/null @@ -1,11 +0,0 @@ -/// - -// @Filename: app.js -//// function foo() { -//// } -//// let x = 1; - -// no semantic classification in js file -verify.semanticClassificationsAre("original", ); - - diff --git a/tests/cases/fourslash/server/semanticClassificationJs1.ts b/tests/cases/fourslash/server/semanticClassificationJs1.ts new file mode 100644 index 00000000000..a330acf7ca4 --- /dev/null +++ b/tests/cases/fourslash/server/semanticClassificationJs1.ts @@ -0,0 +1,10 @@ +/// + +//// @Filename: index.js +//// +//// var Thing = 0; +//// Thing.toExponential(); + +// This test validates that an arbitrary JS file gets +// encoded semantic classifications when requested +verify.encodedSemanticClassificationsLength("2020", 9)