@@ -167,7 +167,7 @@ namespace ts {
167167 }
168168
169169 public getFullWidth ( ) : number {
170- return this . end - this . getFullStart ( ) ;
170+ return this . end - this . pos ;
171171 }
172172
173173 public getLeadingTriviaWidth ( sourceFile ?: SourceFile ) : number {
@@ -6096,6 +6096,8 @@ namespace ts {
60966096 function getEncodedSyntacticClassifications ( fileName : string , span : TextSpan ) : Classifications {
60976097 // doesn't use compiler - no need to synchronize with host
60986098 let sourceFile = syntaxTreeCache . getCurrentSourceFile ( fileName ) ;
6099+ let spanStart = span . start ;
6100+ let spanLength = span . length ;
60996101
61006102 // Make a scanner we can get trivia from.
61016103 let triviaScanner = createScanner ( ScriptTarget . Latest , /*skipTrivia:*/ false , sourceFile . text ) ;
@@ -6112,48 +6114,55 @@ namespace ts {
61126114 result . push ( type ) ;
61136115 }
61146116
6115- function classifyLeadingTrivia ( token : Node ) : void {
6116- let tokenStart = skipTrivia ( sourceFile . text , token . pos , /*stopAfterLineBreak:*/ false ) ;
6117- if ( tokenStart === token . pos ) {
6118- return ;
6119- }
6120-
6121- // token has trivia. Classify them appropriately.
6117+ function classifyLeadingTriviaAndGetTokenStart ( token : Node ) : number {
61226118 triviaScanner . setTextPos ( token . pos ) ;
61236119 while ( true ) {
61246120 let start = triviaScanner . getTextPos ( ) ;
6121+ // only bother scanning if we have something that could be trivia.
6122+ if ( ! couldStartTrivia ( sourceFile . text , start ) ) {
6123+ return start ;
6124+ }
6125+
61256126 let kind = triviaScanner . scan ( ) ;
61266127 let end = triviaScanner . getTextPos ( ) ;
61276128 let width = end - start ;
61286129
61296130 // The moment we get something that isn't trivia, then stop processing.
61306131 if ( ! isTrivia ( kind ) ) {
6131- return ;
6132+ return start ;
61326133 }
61336134
6134- // Only bother with the trivia if it at least intersects the span of interest.
6135- if ( textSpanIntersectsWith ( span , start , width ) ) {
6136- if ( isComment ( kind ) ) {
6137- classifyComment ( token , kind , start , width ) ;
6138- continue ;
6139- }
6135+ // Don't bother with newlines/whitespace.
6136+ if ( kind === SyntaxKind . NewLineTrivia || kind === SyntaxKind . WhitespaceTrivia ) {
6137+ continue ;
6138+ }
61406139
6141- if ( kind === SyntaxKind . ConflictMarkerTrivia ) {
6142- let text = sourceFile . text ;
6143- let ch = text . charCodeAt ( start ) ;
6140+ // Only bother with the trivia if it at least intersects the span of interest.
6141+ if ( isComment ( kind ) ) {
6142+ classifyComment ( token , kind , start , width ) ;
6143+
6144+ // Classifying a comment might cause us to reuse the trivia scanner
6145+ // (because of jsdoc comments). So after we classify the comment make
6146+ // sure we set the scanner position back to where it needs to be.
6147+ triviaScanner . setTextPos ( end ) ;
6148+ continue ;
6149+ }
61446150
6145- // for the <<<<<<< and >>>>>>> markers, we just add them in as comments
6146- // in the classification stream.
6147- if ( ch === CharacterCodes . lessThan || ch === CharacterCodes . greaterThan ) {
6148- pushClassification ( start , width , ClassificationType . comment ) ;
6149- continue ;
6150- }
6151+ if ( kind === SyntaxKind . ConflictMarkerTrivia ) {
6152+ let text = sourceFile . text ;
6153+ let ch = text . charCodeAt ( start ) ;
61516154
6152- // for the ======== add a comment for the first line, and then lex all
6153- // subsequent lines up until the end of the conflict marker.
6154- Debug . assert ( ch === CharacterCodes . equals ) ;
6155- classifyDisabledMergeCode ( text , start , end ) ;
6155+ // for the <<<<<<< and >>>>>>> markers, we just add them in as comments
6156+ // in the classification stream.
6157+ if ( ch === CharacterCodes . lessThan || ch === CharacterCodes . greaterThan ) {
6158+ pushClassification ( start , width , ClassificationType . comment ) ;
6159+ continue ;
61566160 }
6161+
6162+ // for the ======== add a comment for the first line, and then lex all
6163+ // subsequent lines up until the end of the conflict marker.
6164+ Debug . assert ( ch === CharacterCodes . equals ) ;
6165+ classifyDisabledMergeCode ( text , start , end ) ;
61576166 }
61586167 }
61596168 }
@@ -6272,12 +6281,14 @@ namespace ts {
62726281 }
62736282
62746283 function classifyToken ( token : Node ) : void {
6275- classifyLeadingTrivia ( token ) ;
6284+ let tokenStart = classifyLeadingTriviaAndGetTokenStart ( token ) ;
62766285
6277- if ( token . getWidth ( ) > 0 ) {
6286+ let tokenWidth = token . end - tokenStart ;
6287+ Debug . assert ( tokenWidth >= 0 ) ;
6288+ if ( tokenWidth > 0 ) {
62786289 let type = classifyTokenType ( token . kind , token ) ;
62796290 if ( type ) {
6280- pushClassification ( token . getStart ( ) , token . getWidth ( ) , type ) ;
6291+ pushClassification ( tokenStart , tokenWidth , type ) ;
62816292 }
62826293 }
62836294 }
@@ -6382,9 +6393,10 @@ namespace ts {
63826393 }
63836394
63846395 // Ignore nodes that don't intersect the original span to classify.
6385- if ( textSpanIntersectsWith ( span , element . getFullStart ( ) , element . getFullWidth ( ) ) ) {
6396+ if ( decodedTextSpanIntersectsWith ( spanStart , spanLength , element . pos , element . getFullWidth ( ) ) ) {
63866397 let children = element . getChildren ( sourceFile ) ;
6387- for ( let child of children ) {
6398+ for ( let i = 0 , n = children . length ; i < n ; i ++ ) {
6399+ let child = children [ i ] ;
63886400 if ( isToken ( child ) ) {
63896401 classifyToken ( child ) ;
63906402 }
0 commit comments