Skip to content

Commit dbe9e3d

Browse files
authored
Merge pull request microsoft#32565 from amcasey/TripleSlashClassification
Support classification of triple-slash references
2 parents 4cc6618 + 9647506 commit dbe9e3d

17 files changed

+302
-0
lines changed

src/services/classifier.ts

+83
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,11 @@ namespace ts {
683683
return;
684684
}
685685
}
686+
else if (kind === SyntaxKind.SingleLineCommentTrivia) {
687+
if (tryClassifyTripleSlashComment(start, width)) {
688+
return;
689+
}
690+
}
686691

687692
// Simple comment. Just add as is.
688693
pushCommentRange(start, width);
@@ -755,6 +760,84 @@ namespace ts {
755760
}
756761
}
757762

763+
function tryClassifyTripleSlashComment(start: number, width: number): boolean {
764+
const tripleSlashXMLCommentRegEx = /^(\/\/\/\s*)(<)(?:(\S+)((?:[^/]|\/[^>])*)(\/>)?)?/im;
765+
const attributeRegex = /(\S+)(\s*)(=)(\s*)('[^']+'|"[^"]+")/img;
766+
767+
const text = sourceFile.text.substr(start, width);
768+
const match = tripleSlashXMLCommentRegEx.exec(text);
769+
if (!match) {
770+
return false;
771+
}
772+
773+
let pos = start;
774+
775+
pushCommentRange(pos, match[1].length); // ///
776+
pos += match[1].length;
777+
778+
pushClassification(pos, match[2].length, ClassificationType.punctuation); // <
779+
pos += match[2].length;
780+
781+
if (!match[3]) {
782+
return true;
783+
}
784+
785+
pushClassification(pos, match[3].length, ClassificationType.jsxSelfClosingTagName); // element name
786+
pos += match[3].length;
787+
788+
const attrText = match[4];
789+
let attrPos = pos;
790+
while (true) {
791+
const attrMatch = attributeRegex.exec(attrText);
792+
if (!attrMatch) {
793+
break;
794+
}
795+
796+
const newAttrPos = pos + attrMatch.index;
797+
if (newAttrPos > attrPos) {
798+
pushCommentRange(attrPos, newAttrPos - attrPos);
799+
attrPos = newAttrPos;
800+
}
801+
802+
pushClassification(attrPos, attrMatch[1].length, ClassificationType.jsxAttribute); // attribute name
803+
attrPos += attrMatch[1].length;
804+
805+
if (attrMatch[2].length) {
806+
pushCommentRange(attrPos, attrMatch[2].length); // whitespace
807+
attrPos += attrMatch[2].length;
808+
}
809+
810+
pushClassification(attrPos, attrMatch[3].length, ClassificationType.operator); // =
811+
attrPos += attrMatch[3].length;
812+
813+
if (attrMatch[4].length) {
814+
pushCommentRange(attrPos, attrMatch[4].length); // whitespace
815+
attrPos += attrMatch[4].length;
816+
}
817+
818+
pushClassification(attrPos, attrMatch[5].length, ClassificationType.jsxAttributeStringLiteralValue); // attribute value
819+
attrPos += attrMatch[5].length;
820+
}
821+
822+
pos += match[4].length;
823+
824+
if (pos > attrPos) {
825+
pushCommentRange(attrPos, pos - attrPos);
826+
}
827+
828+
if (match[5]) {
829+
pushClassification(pos, match[5].length, ClassificationType.punctuation); // />
830+
pos += match[5].length;
831+
}
832+
833+
const end = start + width;
834+
if (pos < end) {
835+
pushCommentRange(pos, end - pos);
836+
}
837+
838+
return true;
839+
}
840+
758841
function processJSDocTemplateTag(tag: JSDocTemplateTag) {
759842
for (const child of tag.getChildren()) {
760843
processElement(child);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference path="./module.ts" />
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// "),
8+
c.punctuation("<"),
9+
c.jsxSelfClosingTagName("reference"),
10+
c.comment(" "),
11+
c.jsxAttribute("path"),
12+
c.operator("="),
13+
c.jsxAttributeStringLiteralValue("\"./module.ts\""),
14+
c.comment(" "),
15+
c.punctuation("/>"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference path="./module.ts"
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// "),
8+
c.punctuation("<"),
9+
c.jsxSelfClosingTagName("reference"),
10+
c.comment(" "),
11+
c.jsxAttribute("path"),
12+
c.operator("="),
13+
c.jsxAttributeStringLiteralValue("\"./module.ts\""));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference path="./module.ts" /
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// "),
8+
c.punctuation("<"),
9+
c.jsxSelfClosingTagName("reference"),
10+
c.comment(" "),
11+
c.jsxAttribute("path"),
12+
c.operator("="),
13+
c.jsxAttributeStringLiteralValue("\"./module.ts\""),
14+
c.comment(" "),
15+
c.comment("/"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference path="./module.ts" bad types="node" />
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// "),
8+
c.punctuation("<"),
9+
c.jsxSelfClosingTagName("reference"),
10+
c.comment(" "),
11+
c.jsxAttribute("path"),
12+
c.operator("="),
13+
c.jsxAttributeStringLiteralValue("\"./module.ts\""),
14+
c.comment(" bad "),
15+
c.jsxAttribute("types"),
16+
c.operator("="),
17+
c.jsxAttributeStringLiteralValue("\"node\""),
18+
c.comment(" "),
19+
c.punctuation("/>"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference path="./module.ts" /> trailing
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// "),
8+
c.punctuation("<"),
9+
c.jsxSelfClosingTagName("reference"),
10+
c.comment(" "),
11+
c.jsxAttribute("path"),
12+
c.operator("="),
13+
c.jsxAttributeStringLiteralValue("\"./module.ts\""),
14+
c.comment(" "),
15+
c.punctuation("/>"),
16+
c.comment(" trailing"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// nonElement
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// nonElement"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference path="./module1.ts" />
4+
//// /// <reference path="./module2.ts" />
5+
6+
var c = classification;
7+
verify.syntacticClassificationsAre(
8+
c.comment("/// "),
9+
c.punctuation("<"),
10+
c.jsxSelfClosingTagName("reference"),
11+
c.comment(" "),
12+
c.jsxAttribute("path"),
13+
c.operator("="),
14+
c.jsxAttributeStringLiteralValue("\"./module1.ts\""),
15+
c.comment(" "),
16+
c.punctuation("/>"),
17+
c.comment("/// "),
18+
c.punctuation("<"),
19+
c.jsxSelfClosingTagName("reference"),
20+
c.comment(" "),
21+
c.jsxAttribute("path"),
22+
c.operator("="),
23+
c.jsxAttributeStringLiteralValue("\"./module2.ts\""),
24+
c.comment(" "),
25+
c.punctuation("/>"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference path="./module.ts" />
4+
//// 1
5+
6+
var c = classification;
7+
verify.syntacticClassificationsAre(
8+
c.comment("/// "),
9+
c.punctuation("<"),
10+
c.jsxSelfClosingTagName("reference"),
11+
c.comment(" "),
12+
c.jsxAttribute("path"),
13+
c.operator("="),
14+
c.jsxAttributeStringLiteralValue("\"./module.ts\""),
15+
c.comment(" "),
16+
c.punctuation("/>"),
17+
c.numericLiteral("1"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// ///<reference path = "./module.ts"/>
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("///"),
8+
c.punctuation("<"),
9+
c.jsxSelfClosingTagName("reference"),
10+
c.comment(" "),
11+
c.jsxAttribute("path"),
12+
c.comment(" "),
13+
c.operator("="),
14+
c.comment(" "),
15+
c.jsxAttributeStringLiteralValue("\"./module.ts\""),
16+
c.punctuation("/>"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference path="./module.ts" types="node" />
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// "),
8+
c.punctuation("<"),
9+
c.jsxSelfClosingTagName("reference"),
10+
c.comment(" "),
11+
c.jsxAttribute("path"),
12+
c.operator("="),
13+
c.jsxAttributeStringLiteralValue("\"./module.ts\""),
14+
c.comment(" "),
15+
c.jsxAttribute("types"),
16+
c.operator("="),
17+
c.jsxAttributeStringLiteralValue("\"node\""),
18+
c.comment(" "),
19+
c.punctuation("/>"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// "),
8+
c.punctuation("<"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// "),
8+
c.punctuation("<"),
9+
c.jsxSelfClosingTagName("reference"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference path
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// "),
8+
c.punctuation("<"),
9+
c.jsxSelfClosingTagName("reference"),
10+
c.comment(" path"));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference path=
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// "),
8+
c.punctuation("<"),
9+
c.jsxSelfClosingTagName("reference"),
10+
c.comment(" path="));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference path="
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// "),
8+
c.punctuation("<"),
9+
c.jsxSelfClosingTagName("reference"),
10+
c.comment(" path=\""));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//// /// <reference path="./module.ts
4+
5+
var c = classification;
6+
verify.syntacticClassificationsAre(
7+
c.comment("/// "),
8+
c.punctuation("<"),
9+
c.jsxSelfClosingTagName("reference"),
10+
c.comment(" path=\"./module.ts"));

0 commit comments

Comments
 (0)