1
>
/*---------------------------------------------------------------------------------------------
ast.ts
2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { BugIndicatingError } from '../../../../../base/common/errors.js';
7
>
import { CursorColumns } from '../../../core/cursorColumns.js';
8
>
import { BracketKind } from '../../../languages/supports/languageBracketsConfiguration.js';
9
>
import { ITextModel } from '../../../model.js';
10
>
import { Length, lengthAdd, lengthGetLineCount, lengthToObj, lengthZero } from './length.js';
11
>
import { SmallImmutableSet } from './smallImmutableSet.js';
12
>
import { OpeningBracketId } from './tokenizer.js';
13
>
14
>
export const enum AstNodeKind {
15
>
Text = 0,
16
>
Bracket = 1,
17
>
Pair = 2,
18
>
UnexpectedClosingBracket = 3,
19
>
List = 4,
20
>
}
21
>
22
>
export type AstNode = PairAstNode | ListAstNode | BracketAstNode | InvalidBracketAstNode | TextAstNode;
23
>
24
>
/**
25
>
* The base implementation for all AST nodes.
26
>
*/
27
>
abstract class BaseAstNode {
28
>
public abstract readonly kind: AstNodeKind;
29
>
30
>
public abstract readonly childrenLength: number;
31
>
32
>
/**
33
>
* Might return null even if {@link idx} is smaller than {@link BaseAstNode.childrenLength}.
34
>
*/
35
>
public abstract getChild(idx: number): AstNode | null;
36
>
37
>
/**
38
>
* Try to avoid using this property, as implementations might need to allocate the resulting array.
39
>
*/
40
>
public abstract readonly children: readonly AstNode[];
41
>
42
>
/**
43
>
* Represents the set of all (potentially) missing opening bracket ids in this node.
44
>
* E.g. in `{ ] ) }` that set is {`[`, `(` }.
45
>
*/
46
>
public abstract readonly missingOpeningBracketIds: SmallImmutableSet<OpeningBracketId>;
47
>
48
>
/**
49
>
* In case of a list, determines the height of the (2,3) tree.
50
>
*/
51
>
public abstract readonly listHeight: number;
52
>
53
>
protected _length: Length;
54
>
55
>
/**
56
>
* The length of the entire node, which should equal the sum of lengths of all children.
57
>
*/
58
>
public get length(): Length {
59
return this._length;
60
}
62
>
public constructor(length: Length) {
63
this._length = length;
64
}
66
>
/**
67
>
* @param openBracketIds The set of all opening brackets that have not yet been closed.
68
>
*/
69
>
public abstract canBeReused(
70
>
openBracketIds: SmallImmutableSet<OpeningBracketId>
71
>
): boolean;
72
>
73
>
/**
74
>
* Flattens all lists in this AST. Only for debugging.
75
>
*/
76
>
public abstract flattenLists(): AstNode;
77
>
78
>
/**
79
>
* Creates a deep clone.
80
>
*/
81
>
public abstract deepClone(): AstNode;
82
>
83
>
public abstract computeMinIndentation(offset: Length, textModel: ITextModel): number;
84
>
}
85
>
86
>
/**
87
>
* Represents a bracket pair including its child (e.g. `{ ... }`).
88
>
* Might be unclosed.
89
>
* Immutable, if all children are immutable.
90
>
*/
91
>
export class PairAstNode extends BaseAstNode {
92
>
public static create(
93
>
openingBracket: BracketAstNode,
94
>
child: AstNode | null,
95
>
closingBracket: BracketAstNode | null
96
>
) {
97
>
let length = openingBracket.length;
98
>
if (child) {
99
>
length = lengthAdd(length, child.length);
100
>
}
101
>
if (closingBracket) {
102
>
length = lengthAdd(length, closingBracket.length);
103
>
}
104
>
return new PairAstNode(length, openingBracket, child, closingBracket, child ? child.missingOpeningBracketIds : SmallImmutableSet.getEmpty());
105
>
}
106
>
107
>
public get kind(): AstNodeKind.Pair {
108
return AstNodeKind.Pair;
109
}
110
>
public get listHeight() {
ast.ts
111
return 0;
112
}
113
>
public get childrenLength(): number {
ast.ts
114
return 3;
115
}
116
>
public getChild(idx: number): AstNode | null {
ast.ts
117
switch (idx) {
118
case 0: return this.openingBracket;