Skip to content

Commit d206f62

Browse files
Squueze perf in syntactic classification.
1 parent 3bb7be9 commit d206f62

File tree

3 files changed

+62
-27
lines changed

3 files changed

+62
-27
lines changed

src/compiler/scanner.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,31 @@ namespace ts {
376376
return ch >= CharacterCodes._0 && ch <= CharacterCodes._7;
377377
}
378378

379+
export function couldStartTrivia(text: string, pos: number): boolean {
380+
// Keep in sync with skipTrivia
381+
let ch = text.charCodeAt(pos);
382+
switch (ch) {
383+
case CharacterCodes.carriageReturn:
384+
case CharacterCodes.lineFeed:
385+
case CharacterCodes.tab:
386+
case CharacterCodes.verticalTab:
387+
case CharacterCodes.formFeed:
388+
case CharacterCodes.space:
389+
case CharacterCodes.slash:
390+
// starts of normal trivia
391+
case CharacterCodes.lessThan:
392+
case CharacterCodes.equals:
393+
case CharacterCodes.greaterThan:
394+
// Starts of conflict marker trivia
395+
return true;
396+
default:
397+
return ch > CharacterCodes.maxAsciiCharacter;
398+
}
399+
}
400+
379401
/* @internal */
380402
export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boolean): number {
403+
// Keep in sync with couldStartTrivia
381404
while (true) {
382405
let ch = text.charCodeAt(pos);
383406
switch (ch) {

src/compiler/utilities.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,12 @@ namespace ts {
20832083
return start <= textSpanEnd(span) && end >= span.start;
20842084
}
20852085

2086+
export function textSpanIntersectsWith2(start1: number, length1: number, start2: number, length2: number) {
2087+
let end1 = start1 + length1;
2088+
let end2 = start2 + length2;
2089+
return start2 <= end1 && end2 >= start1;
2090+
}
2091+
20862092
export function textSpanIntersectsWithPosition(span: TextSpan, position: number) {
20872093
return position <= textSpanEnd(span) && position >= span.start;
20882094
}

src/services/services.ts

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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 {
@@ -6116,6 +6116,8 @@ namespace ts {
61166116
function getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications {
61176117
// doesn't use compiler - no need to synchronize with host
61186118
let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
6119+
let spanStart = span.start;
6120+
let spanLength = span.length;
61196121

61206122
// Make a scanner we can get trivia from.
61216123
let triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.text);
@@ -6136,6 +6138,11 @@ namespace ts {
61366138
triviaScanner.setTextPos(token.pos);
61376139
while (true) {
61386140
let start = triviaScanner.getTextPos();
6141+
// only bother scanning if we have something that could be trivia.
6142+
if (!couldStartTrivia(sourceFile.text, start)) {
6143+
return start;
6144+
}
6145+
61396146
let kind = triviaScanner.scan();
61406147
let end = triviaScanner.getTextPos();
61416148
let width = end - start;
@@ -6151,33 +6158,31 @@ namespace ts {
61516158
}
61526159

61536160
// Only bother with the trivia if it at least intersects the span of interest.
6154-
if (textSpanIntersectsWith(span, start, width)) {
6155-
if (isComment(kind)) {
6156-
classifyComment(token, kind, start, width);
6161+
if (isComment(kind)) {
6162+
classifyComment(token, kind, start, width);
61576163

6158-
// Classifying a comment might cause us to reuse the trivia scanner
6159-
// (because of jsdoc comments). So after we classify the comment make
6160-
// sure we set the scanner position back to where it needs to be.
6161-
triviaScanner.setTextPos(end);
6162-
continue;
6163-
}
6164-
6165-
if (kind === SyntaxKind.ConflictMarkerTrivia) {
6166-
let text = sourceFile.text;
6167-
let ch = text.charCodeAt(start);
6164+
// Classifying a comment might cause us to reuse the trivia scanner
6165+
// (because of jsdoc comments). So after we classify the comment make
6166+
// sure we set the scanner position back to where it needs to be.
6167+
triviaScanner.setTextPos(end);
6168+
continue;
6169+
}
61686170

6169-
// for the <<<<<<< and >>>>>>> markers, we just add them in as comments
6170-
// in the classification stream.
6171-
if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
6172-
pushClassification(start, width, ClassificationType.comment);
6173-
continue;
6174-
}
6171+
if (kind === SyntaxKind.ConflictMarkerTrivia) {
6172+
let text = sourceFile.text;
6173+
let ch = text.charCodeAt(start);
61756174

6176-
// for the ======== add a comment for the first line, and then lex all
6177-
// subsequent lines up until the end of the conflict marker.
6178-
Debug.assert(ch === CharacterCodes.equals);
6179-
classifyDisabledMergeCode(text, start, end);
6175+
// for the <<<<<<< and >>>>>>> markers, we just add them in as comments
6176+
// in the classification stream.
6177+
if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
6178+
pushClassification(start, width, ClassificationType.comment);
6179+
continue;
61806180
}
6181+
6182+
// for the ======== add a comment for the first line, and then lex all
6183+
// subsequent lines up until the end of the conflict marker.
6184+
Debug.assert(ch === CharacterCodes.equals);
6185+
classifyDisabledMergeCode(text, start, end);
61816186
}
61826187
}
61836188
}
@@ -6298,7 +6303,7 @@ namespace ts {
62986303
function classifyToken(token: Node): void {
62996304
let tokenStart = classifyLeadingTriviaAndGetTokenStart(token);
63006305

6301-
let tokenWidth = token.getEnd() - tokenStart;
6306+
let tokenWidth = token.end - tokenStart;
63026307
Debug.assert(tokenWidth >= 0);
63036308
if (tokenWidth > 0) {
63046309
let type = classifyTokenType(token.kind, token);
@@ -6408,9 +6413,10 @@ namespace ts {
64086413
}
64096414

64106415
// Ignore nodes that don't intersect the original span to classify.
6411-
if (textSpanIntersectsWith(span, element.getFullStart(), element.getFullWidth())) {
6416+
if (textSpanIntersectsWith2(spanStart, spanLength, element.pos, element.getFullWidth())) {
64126417
let children = element.getChildren(sourceFile);
6413-
for (let child of children) {
6418+
for (let i = 0, n = children.length; i < n; i++) {
6419+
let child = children[i];
64146420
if (isToken(child)) {
64156421
classifyToken(child);
64166422
}

0 commit comments

Comments
 (0)