Skip to content

Commit 4825db1

Browse files
committed
Adds the ability to test modern semantic classification via strings instead of numbers
1 parent 9270454 commit 4825db1

11 files changed

+350
-291
lines changed

src/compiler/types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -6498,6 +6498,11 @@ namespace ts {
64986498
newLength: number;
64996499
}
65006500

6501+
export const enum SemanticClassificationFormat {
6502+
Original = "orginal",
6503+
TwentyTwenty = "2020"
6504+
}
6505+
65016506
/* @internal */
65026507
export interface DiagnosticCollection {
65036508
// Adds a diagnostic to this diagnostic collection.

src/harness/client.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ namespace ts.server {
739739
return notImplemented();
740740
}
741741

742-
getEncodedSemanticClassifications(_fileName: string, _span: TextSpan, _format?: "original" | "2020"): Classifications {
742+
getEncodedSemanticClassifications(_fileName: string, _span: TextSpan, _format?: SemanticClassificationFormat): Classifications {
743743
return notImplemented();
744744
}
745745

src/harness/fourslashImpl.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2514,7 +2514,7 @@ namespace FourSlash {
25142514
}
25152515
}
25162516

2517-
public verifySemanticClassifications(format: "original" | "2020", expected: { classificationType: string | number; text?: string }[]) {
2517+
public verifySemanticClassifications(format: ts.SemanticClassificationFormat, expected: { classificationType: string | number; text?: string }[]) {
25182518
const actual = this.languageService.getSemanticClassifications(this.activeFile.fileName,
25192519
ts.createTextSpan(0, this.activeFile.content.length), format);
25202520

src/harness/fourslashInterfaceImpl.ts

+61-10
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ namespace FourSlashInterface {
500500
/**
501501
* This method *requires* an ordered stream of classifications for a file, and spans are highly recommended.
502502
*/
503-
public semanticClassificationsAre(format: "original" | "2020", ...classifications: Classification[]) {
503+
public semanticClassificationsAre(format: ts.SemanticClassificationFormat, ...classifications: Classification[]) {
504504
this.state.verifySemanticClassifications(format, classifications);
505505
}
506506

@@ -750,22 +750,73 @@ namespace FourSlashInterface {
750750
textSpan?: FourSlash.TextSpan;
751751
}
752752

753-
export function classification(format: "original" | "2020") {
754-
function token(identifier: number, text: string, _position: number): Classification {
753+
754+
export function classification(format: ts.SemanticClassificationFormat) {
755+
756+
function semanticToken(identifier: string, text: string, _position: number): Classification {
757+
758+
const tokenTypes = {
759+
class: ts.classifier.vscode.TokenType.class,
760+
enum: ts.classifier.vscode.TokenType.enum,
761+
interface: ts.classifier.vscode.TokenType.interface,
762+
namespace: ts.classifier.vscode.TokenType.namespace,
763+
typeParameter: ts.classifier.vscode.TokenType.typeParameter,
764+
type: ts.classifier.vscode.TokenType.type,
765+
parameter: ts.classifier.vscode.TokenType.parameter,
766+
variable: ts.classifier.vscode.TokenType.variable,
767+
enumMember: ts.classifier.vscode.TokenType.enumMember,
768+
property: ts.classifier.vscode.TokenType.property,
769+
function: ts.classifier.vscode.TokenType.function,
770+
member: ts.classifier.vscode.TokenType.member
771+
};
772+
773+
const tokenModifiers = {
774+
async: ts.classifier.vscode.TokenModifier.async,
775+
declaration: ts.classifier.vscode.TokenModifier.declaration,
776+
readonly: ts.classifier.vscode.TokenModifier.readonly,
777+
static: ts.classifier.vscode.TokenModifier.static,
778+
local: ts.classifier.vscode.TokenModifier.local,
779+
defaultLibrary: ts.classifier.vscode.TokenModifier.defaultLibrary,
780+
};
781+
782+
function identifierToClassificationID(identifier: string): number {
783+
const [tokenType, ...modifiers] = identifier.split(".");
784+
// @ts-expect-error
785+
const tokenValue = tokenTypes[tokenType];
786+
if (tokenValue === undefined) {
787+
throw new Error(`Did not find ${tokenType} in tokenTypes for classifiers.`);
788+
}
789+
790+
let classification = (tokenValue + 1) << 8;
791+
ts.forEach(modifiers, (modifier) => {
792+
// @ts-expect-error
793+
const modifierValue = tokenModifiers[modifiers];
794+
if (tokenValue === undefined) {
795+
throw new Error(`Did not find ${modifier} in tokenModifiers for classifiers.`);
796+
}
797+
classification += modifierValue + 1;
798+
console.log("adding: ", modifierValue);
799+
});
800+
801+
// debugger;
802+
803+
return classification;
804+
}
805+
755806
return {
756-
classificationType: identifier,
757-
// textSpan: {
807+
classificationType: identifierToClassificationID(identifier),
808+
// textSpan: {
758809
// start: position,
759810
// end: -1
760811
// },
761812
text
762-
}
813+
};
763814
}
764815

765-
if (format === "2020") {
816+
if (format === ts.SemanticClassificationFormat.TwentyTwenty) {
766817
return {
767-
token
768-
}
818+
semanticToken
819+
};
769820
}
770821

771822
function comment(text: string, position?: number): Classification {
@@ -890,7 +941,7 @@ namespace FourSlashInterface {
890941
jsxText,
891942
jsxAttributeStringLiteralValue,
892943
getClassification
893-
}
944+
};
894945
}
895946

896947
export namespace Completion {

src/harness/harnessLanguageService.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -448,14 +448,14 @@ namespace Harness.LanguageService {
448448
getSyntacticClassifications(fileName: string, span: ts.TextSpan): ts.ClassifiedSpan[] {
449449
return unwrapJSONCallResult(this.shim.getSyntacticClassifications(fileName, span.start, span.length));
450450
}
451-
getSemanticClassifications(fileName: string, span: ts.TextSpan, format?: "original" | "2020"): ts.ClassifiedSpan[] {
451+
getSemanticClassifications(fileName: string, span: ts.TextSpan, format?: ts.SemanticClassificationFormat): ts.ClassifiedSpan[] {
452452
return unwrapJSONCallResult(this.shim.getSemanticClassifications(fileName, span.start, span.length, format));
453453
}
454454
getEncodedSyntacticClassifications(fileName: string, span: ts.TextSpan): ts.Classifications {
455455
return unwrapJSONCallResult(this.shim.getEncodedSyntacticClassifications(fileName, span.start, span.length));
456456
}
457-
getEncodedSemanticClassifications(fileName: string, span: ts.TextSpan, format?: "original" | "2020"): ts.Classifications {
458-
const responseFormat = format || "original";
457+
getEncodedSemanticClassifications(fileName: string, span: ts.TextSpan, format?: ts.SemanticClassificationFormat): ts.Classifications {
458+
const responseFormat = format || ts.SemanticClassificationFormat.Original;
459459
return unwrapJSONCallResult(this.shim.getEncodedSemanticClassifications(fileName, span.start, span.length, responseFormat));
460460
}
461461
getCompletionsAtPosition(fileName: string, position: number, preferences: ts.UserPreferences | undefined): ts.CompletionInfo {

0 commit comments

Comments
 (0)