Skip to content

Commit 6717c79

Browse files
Merge branch 'master' into cancellableDiagnostics
2 parents e015b17 + dd671ed commit 6717c79

File tree

4 files changed

+74
-34
lines changed

4 files changed

+74
-34
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
@@ -2090,6 +2090,12 @@ namespace ts {
20902090
return start <= textSpanEnd(span) && end >= span.start;
20912091
}
20922092

2093+
export function decodedTextSpanIntersectsWith(start1: number, length1: number, start2: number, length2: number) {
2094+
let end1 = start1 + length1;
2095+
let end2 = start2 + length2;
2096+
return start2 <= end1 && end2 >= start1;
2097+
}
2098+
20932099
export function textSpanIntersectsWithPosition(span: TextSpan, position: number) {
20942100
return position <= textSpanEnd(span) && position >= span.start;
20952101
}

src/services/services.ts

Lines changed: 45 additions & 33 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 {
@@ -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
}

tests/cases/fourslash/syntacticClassificationsDocComment3.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ verify.syntacticClassificationsAre(
1414
c.punctuation("{"),
1515
c.keyword("number"),
1616
c.comment(" /* } */"),
17-
c.comment("/* } */"),
1817
c.keyword("var"),
1918
c.text("v"),
2019
c.punctuation(";"));

0 commit comments

Comments
 (0)