@@ -683,6 +683,11 @@ namespace ts {
683
683
return ;
684
684
}
685
685
}
686
+ else if ( kind === SyntaxKind . SingleLineCommentTrivia ) {
687
+ if ( tryClassifyTripleSlashComment ( start , width ) ) {
688
+ return ;
689
+ }
690
+ }
686
691
687
692
// Simple comment. Just add as is.
688
693
pushCommentRange ( start , width ) ;
@@ -755,6 +760,84 @@ namespace ts {
755
760
}
756
761
}
757
762
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
+
758
841
function processJSDocTemplateTag ( tag : JSDocTemplateTag ) {
759
842
for ( const child of tag . getChildren ( ) ) {
760
843
processElement ( child ) ;
0 commit comments