Skip to content

Commit ebb0beb

Browse files
Adding classification tests.
1 parent 9825342 commit ebb0beb

File tree

4 files changed

+120
-8
lines changed

4 files changed

+120
-8
lines changed

src/harness/fourslash.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,6 +1428,46 @@ module FourSlash {
14281428
Harness.IO.log(this.getNameOrDottedNameSpan(pos));
14291429
}
14301430

1431+
private verifyClassifications(expected: { classificationType: string; text: string }[], actual: ts.ClassifiedSpan[]) {
1432+
if (actual.length !== expected.length) {
1433+
throw new Error('verifySyntacticClassification failed - expected total classifications to be ' + expected.length + ', but was ' + actual.length);
1434+
}
1435+
1436+
for (var i = 0; i < expected.length; i++) {
1437+
var expectedClassification = expected[i];
1438+
var actualClassification = actual[i];
1439+
1440+
var expectedType: string = (<any>ts.ClassificationTypeNames)[expectedClassification.classificationType];
1441+
if (expectedType !== actualClassification.classificationType) {
1442+
throw new Error('verifySyntacticClassification failed - expected classifications type to be ' +
1443+
expectedType + ', but was ' +
1444+
actualClassification.classificationType);
1445+
}
1446+
1447+
var actualSpan = actualClassification.textSpan;
1448+
var actualText = this.activeFile.content.substr(actualSpan.start(), actualSpan.length());
1449+
if (expectedClassification.text !== actualText) {
1450+
throw new Error('verifySyntacticClassification failed - expected classificatied text to be ' +
1451+
expectedClassification.text + ', but was ' +
1452+
actualText);
1453+
}
1454+
}
1455+
}
1456+
1457+
public verifySemanticClassifications(expected: { classificationType: string; text: string }[]) {
1458+
var actual = this.languageService.getSemanticClassifications(this.activeFile.fileName,
1459+
new TypeScript.TextSpan(0, this.activeFile.content.length));
1460+
1461+
this.verifyClassifications(expected, actual);
1462+
}
1463+
1464+
public verifySyntacticClassifications(expected: { classificationType: string; text: string }[]) {
1465+
var actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName,
1466+
new TypeScript.TextSpan(0, this.activeFile.content.length));
1467+
1468+
this.verifyClassifications(expected, actual);
1469+
}
1470+
14311471
public verifyOutliningSpans(spans: TextSpan[]) {
14321472
this.taoInvalidReason = 'verifyOutliningSpans NYI';
14331473

src/services/services.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ module ts {
470470
dispose(): void;
471471
}
472472

473-
class ClassificationTypeNames {
473+
export class ClassificationTypeNames {
474474
public static comment = "comment";
475475
public static identifier = "identifier";
476476
public static keyword = "keyword";
@@ -3185,14 +3185,16 @@ module ts {
31853185
}
31863186

31873187
function processNode(node: Node) {
3188-
if (span.intersectsWith(node.getStart(), node.getWidth())) {
3189-
if (node.kind === SyntaxKind.Identifier && node.getWidth()) {
3188+
// Only walk into nodes that intersect the requested span.
3189+
if (node && span.intersectsWith(node.getStart(), node.getWidth())) {
3190+
if (node.kind === SyntaxKind.Identifier && node.getWidth() > 0) {
31903191
var symbol = typeInfoResolver.getSymbolInfo(node);
31913192
if (symbol) {
3192-
var span = new TypeScript.TextSpan(node.getStart(), node.getWidth());
31933193
var type = classifySymbol(symbol);
31943194
if (type) {
3195-
result.push(new ClassifiedSpan(span, type));
3195+
result.push(new ClassifiedSpan(
3196+
new TypeScript.TextSpan(node.getStart(), node.getWidth()),
3197+
type));
31963198
}
31973199
}
31983200
}
@@ -3213,7 +3215,7 @@ module ts {
32133215
return result;
32143216

32153217
function classifyTrivia(trivia: TypeScript.ISyntaxTrivia) {
3216-
if (span.intersectsWith(trivia.fullStart(), trivia.fullWidth())) {
3218+
if (trivia.isComment() && span.intersectsWith(trivia.fullStart(), trivia.fullWidth())) {
32173219
result.push(new ClassifiedSpan(
32183220
new TypeScript.TextSpan(trivia.fullStart(), trivia.fullWidth()),
32193221
ClassificationTypeNames.comment));
@@ -3232,10 +3234,11 @@ module ts {
32323234
}
32333235

32343236
if (TypeScript.width(token) > 0) {
3235-
var span = new TypeScript.TextSpan(TypeScript.start(token), TypeScript.width(token));
32363237
var type = classifyTokenType(token);
32373238
if (type) {
3238-
result.push(new ClassifiedSpan(span, type));
3239+
result.push(new ClassifiedSpan(
3240+
new TypeScript.TextSpan(TypeScript.start(token), TypeScript.width(token)),
3241+
type));
32393242
}
32403243
}
32413244

@@ -3287,6 +3290,11 @@ module ts {
32873290
}
32883291

32893292
switch (parent.kind()) {
3293+
case TypeScript.SyntaxKind.SimplePropertyAssignment:
3294+
if ((<TypeScript.SimplePropertyAssignmentSyntax>parent).propertyName === token) {
3295+
return ClassificationTypeNames.identifier;
3296+
}
3297+
return;
32903298
case TypeScript.SyntaxKind.ClassDeclaration:
32913299
if ((<TypeScript.ClassDeclarationSyntax>parent).identifier === token) {
32923300
return ClassificationTypeNames.className;

src/services/text/textSpan.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
///<reference path='references.ts' />
22

33
module TypeScript {
4+
45
export interface ISpan {
56
start(): number;
67
end(): number;

tests/cases/fourslash/fourslash.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@ module FourSlashInterface {
382382
public completionEntryDetailIs(entryName: string, type: string, docComment?: string, fullSymbolName?: string, kind?: string) {
383383
FourSlash.currentTestState.verifyCompletionEntryDetails(entryName, type, docComment, fullSymbolName, kind);
384384
}
385+
386+
public syntacticClassificationsAre(...classifications: { classificationType: string; text: string }[]) {
387+
FourSlash.currentTestState.verifySyntacticClassifications(classifications);
388+
}
385389
}
386390

387391
export class edit {
@@ -524,6 +528,64 @@ module FourSlashInterface {
524528
FourSlash.currentTestState.cancellationToken.setCancelled(numberOfCalls);
525529
}
526530
}
531+
532+
export class classification {
533+
public static comment(text: string): { classificationType: string; text: string } {
534+
return { classificationType: "comment", text: text };
535+
}
536+
537+
public static identifier(text: string): { classificationType: string; text: string } {
538+
return { classificationType: "identifier", text: text };
539+
}
540+
541+
public static keyword(text: string): { classificationType: string; text: string } {
542+
return { classificationType: "keyword", text: text };
543+
}
544+
545+
public static numericLiteral(text: string): { classificationType: string; text: string } {
546+
return { classificationType: "numericLiteral", text: text };
547+
}
548+
549+
public static operator(text: string): { classificationType: string; text: string } {
550+
return { classificationType: "operator", text: text };
551+
}
552+
553+
public static stringLiteral(text: string): { classificationType: string; text: string } {
554+
return { classificationType: "stringLiteral", text: text };
555+
}
556+
557+
public static whiteSpace(text: string): { classificationType: string; text: string } {
558+
return { classificationType: "whiteSpace", text: text };
559+
}
560+
561+
public static text(text: string): { classificationType: string; text: string } {
562+
return { classificationType: "text", text: text };
563+
}
564+
565+
public static punctuation(text: string): { classificationType: string; text: string } {
566+
return { classificationType: "punctuation", text: text };
567+
}
568+
569+
public static className(text: string): { classificationType: string; text: string } {
570+
return { classificationType: "className", text: text };
571+
}
572+
573+
public static enumName(text: string): { classificationType: string; text: string } {
574+
return { classificationType: "enumName", text: text };
575+
}
576+
577+
public static interfaceName(text: string): { classificationType: string; text: string } {
578+
return { classificationType: "interfaceName", text: text };
579+
}
580+
581+
public static moduleName(text: string): { classificationType: string; text: string } {
582+
return { classificationType: "moduleName", text: text };
583+
}
584+
585+
public static typeParameterName(text: string): { classificationType: string; text: string } {
586+
return { classificationType: "typeParameterName", text: text };
587+
}
588+
}
527589
}
528590

529591
module fs {
@@ -547,3 +609,4 @@ var debug = new FourSlashInterface.debug();
547609
var format = new FourSlashInterface.format();
548610
var diagnostics = new FourSlashInterface.diagnostics();
549611
var cancellation = new FourSlashInterface.cancellation();
612+
var classification = FourSlashInterface.classification;

0 commit comments

Comments
 (0)