Skip to content

Commit b1f406f

Browse files
committed
Don't reuse bracket pair AST nodes that touch the edit, as brackets at the end could be extended.
1 parent e9e861f commit b1f406f

File tree

2 files changed

+13
-34
lines changed

2 files changed

+13
-34
lines changed

src/vs/editor/common/model/bracketPairs/impl/ast.ts

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ abstract class BaseAstNode {
6565
* @param openBracketIds The set of all opening brackets that have not yet been closed.
6666
*/
6767
public abstract canBeReused(
68-
openBracketIds: SmallImmutableSet<OpeningBracketId>,
69-
endLineDidChange: boolean
68+
openBracketIds: SmallImmutableSet<OpeningBracketId>
7069
): boolean;
7170

7271
/**
@@ -146,10 +145,7 @@ export class PairAstNode extends BaseAstNode {
146145
super(length);
147146
}
148147

149-
public canBeReused(
150-
openBracketIds: SmallImmutableSet<OpeningBracketId>,
151-
_endLineDidChange: boolean
152-
) {
148+
public canBeReused(openBracketIds: SmallImmutableSet<OpeningBracketId>) {
153149
if (this.closingBracket === null) {
154150
// Unclosed pair ast nodes only
155151
// end at the end of the document
@@ -293,10 +289,7 @@ export abstract class ListAstNode extends BaseAstNode {
293289
return mutable;
294290
}
295291

296-
public canBeReused(
297-
openBracketIds: SmallImmutableSet<OpeningBracketId>,
298-
endLineDidChange: boolean
299-
): boolean {
292+
public canBeReused(openBracketIds: SmallImmutableSet<OpeningBracketId>): boolean {
300293
if (openBracketIds.intersects(this.missingOpeningBracketIds)) {
301294
return false;
302295
}
@@ -307,10 +300,7 @@ export abstract class ListAstNode extends BaseAstNode {
307300
lastChild = lastChild.getChild(lastLength! - 1) as ListAstNode;
308301
}
309302

310-
return lastChild.canBeReused(
311-
openBracketIds,
312-
endLineDidChange
313-
);
303+
return lastChild.canBeReused(openBracketIds);
314304
}
315305

316306
public handleChildrenChanged(): void {
@@ -605,13 +595,8 @@ export class TextAstNode extends ImmutableLeafAstNode {
605595
return SmallImmutableSet.getEmpty();
606596
}
607597

608-
public canBeReused(
609-
_openedBracketIds: SmallImmutableSet<OpeningBracketId>,
610-
endLineDidChange: boolean
611-
) {
612-
// Don't reuse text from a line that got changed.
613-
// Otherwise, long brackets might not be detected.
614-
return !endLineDidChange;
598+
public canBeReused(_openedBracketIds: SmallImmutableSet<OpeningBracketId>) {
599+
return true;
615600
}
616601

617602
public computeMinIndentation(offset: Length, textModel: ITextModel): number {
@@ -665,10 +650,7 @@ export class BracketAstNode extends ImmutableLeafAstNode {
665650
super(length);
666651
}
667652

668-
public canBeReused(
669-
_openedBracketIds: SmallImmutableSet<OpeningBracketId>,
670-
_endLineDidChange: boolean
671-
) {
653+
public canBeReused(_openedBracketIds: SmallImmutableSet<OpeningBracketId>) {
672654
// These nodes could be reused,
673655
// but not in a general way.
674656
// Their parent may be reused.
@@ -692,10 +674,7 @@ export class InvalidBracketAstNode extends ImmutableLeafAstNode {
692674
this.missingOpeningBracketIds = closingBrackets;
693675
}
694676

695-
public canBeReused(
696-
openedBracketIds: SmallImmutableSet<OpeningBracketId>,
697-
_endLineDidChange: boolean
698-
) {
677+
public canBeReused(openedBracketIds: SmallImmutableSet<OpeningBracketId>) {
699678
return !openedBracketIds.intersects(this.missingOpeningBracketIds);
700679
}
701680

src/vs/editor/common/model/bracketPairs/impl/parser.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { AstNode, AstNodeKind, BracketAstNode, InvalidBracketAstNode, ListAstNode, PairAstNode, TextAstNode } from './ast';
77
import { BeforeEditPositionMapper, TextEditInfo } from './beforeEditPositionMapper';
88
import { SmallImmutableSet } from './smallImmutableSet';
9-
import { lengthGetLineCount, lengthIsZero, lengthLessThanEqual } from './length';
9+
import { lengthIsZero, lengthLessThan } from './length';
1010
import { concat23Trees, concat23TreesOfSameHeight } from './concat23Trees';
1111
import { NodeReader } from './nodeReader';
1212
import { OpeningBracketId, Tokenizer, TokenKind } from './tokenizer';
@@ -103,12 +103,12 @@ class Parser {
103103
const maxCacheableLength = this.positionMapper.getDistanceToNextChange(this.tokenizer.offset);
104104
if (!lengthIsZero(maxCacheableLength)) {
105105
const cachedNode = this.oldNodeReader.readLongestNodeAt(this.positionMapper.getOffsetBeforeChange(this.tokenizer.offset), curNode => {
106-
if (!lengthLessThanEqual(curNode.length, maxCacheableLength)) {
106+
if (!lengthLessThan(curNode.length, maxCacheableLength)) {
107+
// Either the node contains edited text or touches edited text.
108+
// In the latter case, brackets might have been extended (`end` -> `ending`), so even touching nodes cannot be reused.
107109
return false;
108110
}
109-
110-
const endLineDidChange = lengthGetLineCount(curNode.length) === lengthGetLineCount(maxCacheableLength);
111-
const canBeReused = curNode.canBeReused(openedBracketIds, endLineDidChange);
111+
const canBeReused = curNode.canBeReused(openedBracketIds);
112112
return canBeReused;
113113
});
114114

0 commit comments

Comments
 (0)