dot-language-support 2.3.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +497 -0
- package/dist/index.js +3853 -0
- package/package.json +10 -11
- package/.github/dependabot.yml +0 -15
- package/.github/workflows/CD.yml +0 -37
- package/.github/workflows/CI.yml +0 -28
- package/.github/workflows/auto-merge.yaml +0 -26
- package/CITATION.cff +0 -14
- package/biome.json +0 -48
- package/lib/cjs/binder.d.ts +0 -2
- package/lib/cjs/binder.js +0 -297
- package/lib/cjs/checker.d.ts +0 -15
- package/lib/cjs/checker.js +0 -228
- package/lib/cjs/core.d.ts +0 -1
- package/lib/cjs/core.js +0 -13
- package/lib/cjs/error.d.ts +0 -3
- package/lib/cjs/error.js +0 -12
- package/lib/cjs/index.d.ts +0 -5
- package/lib/cjs/index.js +0 -22
- package/lib/cjs/parser.d.ts +0 -27
- package/lib/cjs/parser.js +0 -664
- package/lib/cjs/scanner.d.ts +0 -41
- package/lib/cjs/scanner.js +0 -578
- package/lib/cjs/service/codeAction.d.ts +0 -12
- package/lib/cjs/service/codeAction.js +0 -245
- package/lib/cjs/service/colorProvider.d.ts +0 -5
- package/lib/cjs/service/colorProvider.js +0 -91
- package/lib/cjs/service/command/ChangeAllOtherEdgeOpsAndFixGraphCommand.d.ts +0 -10
- package/lib/cjs/service/command/ChangeAllOtherEdgeOpsAndFixGraphCommand.js +0 -42
- package/lib/cjs/service/command/ChangeEdgeOpCommand.d.ts +0 -10
- package/lib/cjs/service/command/ChangeEdgeOpCommand.js +0 -67
- package/lib/cjs/service/command/ConsolidateDescendantsCommand.d.ts +0 -10
- package/lib/cjs/service/command/ConsolidateDescendantsCommand.js +0 -87
- package/lib/cjs/service/command/RemoveSemicolons.d.ts +0 -10
- package/lib/cjs/service/command/RemoveSemicolons.js +0 -39
- package/lib/cjs/service/command/common.d.ts +0 -31
- package/lib/cjs/service/command/common.js +0 -33
- package/lib/cjs/service/completion.d.ts +0 -4
- package/lib/cjs/service/completion.js +0 -173
- package/lib/cjs/service/hover.d.ts +0 -4
- package/lib/cjs/service/hover.js +0 -142
- package/lib/cjs/service/languageFacts.d.ts +0 -683
- package/lib/cjs/service/languageFacts.js +0 -996
- package/lib/cjs/service/reference.d.ts +0 -5
- package/lib/cjs/service/reference.js +0 -67
- package/lib/cjs/service/rename.d.ts +0 -4
- package/lib/cjs/service/rename.js +0 -51
- package/lib/cjs/service/service.d.ts +0 -28
- package/lib/cjs/service/service.js +0 -38
- package/lib/cjs/service/util.d.ts +0 -11
- package/lib/cjs/service/util.js +0 -49
- package/lib/cjs/service/validation.d.ts +0 -4
- package/lib/cjs/service/validation.js +0 -23
- package/lib/cjs/tester.d.ts +0 -1
- package/lib/cjs/tester.js +0 -23
- package/lib/cjs/types.d.ts +0 -397
- package/lib/cjs/types.js +0 -74
- package/lib/cjs/visitor.d.ts +0 -2
- package/lib/cjs/visitor.js +0 -76
- package/lib/esm/binder.d.ts +0 -2
- package/lib/esm/binder.js +0 -294
- package/lib/esm/checker.d.ts +0 -15
- package/lib/esm/checker.js +0 -212
- package/lib/esm/core.d.ts +0 -1
- package/lib/esm/core.js +0 -10
- package/lib/esm/error.d.ts +0 -3
- package/lib/esm/error.js +0 -8
- package/lib/esm/index.d.ts +0 -5
- package/lib/esm/index.js +0 -6
- package/lib/esm/parser.d.ts +0 -27
- package/lib/esm/parser.js +0 -714
- package/lib/esm/scanner.d.ts +0 -41
- package/lib/esm/scanner.js +0 -581
- package/lib/esm/service/codeAction.d.ts +0 -12
- package/lib/esm/service/codeAction.js +0 -207
- package/lib/esm/service/colorProvider.d.ts +0 -5
- package/lib/esm/service/colorProvider.js +0 -54
- package/lib/esm/service/command/ChangeAllOtherEdgeOpsAndFixGraphCommand.d.ts +0 -10
- package/lib/esm/service/command/ChangeAllOtherEdgeOpsAndFixGraphCommand.js +0 -38
- package/lib/esm/service/command/ChangeEdgeOpCommand.d.ts +0 -10
- package/lib/esm/service/command/ChangeEdgeOpCommand.js +0 -30
- package/lib/esm/service/command/ConsolidateDescendantsCommand.d.ts +0 -10
- package/lib/esm/service/command/ConsolidateDescendantsCommand.js +0 -83
- package/lib/esm/service/command/RemoveSemicolons.d.ts +0 -10
- package/lib/esm/service/command/RemoveSemicolons.js +0 -35
- package/lib/esm/service/command/common.d.ts +0 -31
- package/lib/esm/service/command/common.js +0 -25
- package/lib/esm/service/completion.d.ts +0 -4
- package/lib/esm/service/completion.js +0 -137
- package/lib/esm/service/hover.d.ts +0 -4
- package/lib/esm/service/hover.js +0 -135
- package/lib/esm/service/languageFacts.d.ts +0 -683
- package/lib/esm/service/languageFacts.js +0 -993
- package/lib/esm/service/reference.d.ts +0 -5
- package/lib/esm/service/reference.js +0 -63
- package/lib/esm/service/rename.d.ts +0 -4
- package/lib/esm/service/rename.js +0 -48
- package/lib/esm/service/service.d.ts +0 -28
- package/lib/esm/service/service.js +0 -35
- package/lib/esm/service/util.d.ts +0 -11
- package/lib/esm/service/util.js +0 -42
- package/lib/esm/service/validation.d.ts +0 -4
- package/lib/esm/service/validation.js +0 -20
- package/lib/esm/tester.d.ts +0 -1
- package/lib/esm/tester.js +0 -21
- package/lib/esm/types.d.ts +0 -397
- package/lib/esm/types.js +0 -71
- package/lib/esm/visitor.d.ts +0 -2
- package/lib/esm/visitor.js +0 -73
package/lib/esm/parser.js
DELETED
|
@@ -1,714 +0,0 @@
|
|
|
1
|
-
import { DefaultScanner, getTokenAsText } from "./scanner.js";
|
|
2
|
-
import { assertNever } from "./service/util.js";
|
|
3
|
-
import { DiagnosticCategory, SyntaxKind, } from "./types";
|
|
4
|
-
export var ParsingContext;
|
|
5
|
-
(function (ParsingContext) {
|
|
6
|
-
ParsingContext[ParsingContext["None"] = 0] = "None";
|
|
7
|
-
ParsingContext[ParsingContext["StatementList"] = 1] = "StatementList";
|
|
8
|
-
ParsingContext[ParsingContext["AttributeContainerList"] = 2] = "AttributeContainerList";
|
|
9
|
-
ParsingContext[ParsingContext["AssignmentList"] = 3] = "AssignmentList";
|
|
10
|
-
ParsingContext[ParsingContext["EdgeRhsList"] = 4] = "EdgeRhsList";
|
|
11
|
-
ParsingContext[ParsingContext["QuotedTextIdentifierConcatenation"] = 5] = "QuotedTextIdentifierConcatenation";
|
|
12
|
-
ParsingContext[ParsingContext["Count"] = 6] = "Count";
|
|
13
|
-
})(ParsingContext || (ParsingContext = {}));
|
|
14
|
-
export class Parser {
|
|
15
|
-
currentToken = SyntaxKind.Unknown;
|
|
16
|
-
nodeCount;
|
|
17
|
-
identifiers;
|
|
18
|
-
identifierCount = 0;
|
|
19
|
-
sourceText;
|
|
20
|
-
scanner = new DefaultScanner();
|
|
21
|
-
currentNodeHasError;
|
|
22
|
-
currentContext;
|
|
23
|
-
diagnostics;
|
|
24
|
-
constructor() {
|
|
25
|
-
this.#resetState();
|
|
26
|
-
}
|
|
27
|
-
#resetState() {
|
|
28
|
-
this.sourceText = "";
|
|
29
|
-
this.scanner.setText(this.sourceText);
|
|
30
|
-
this.scanner.setErrorCallback(this.#scanError.bind(this));
|
|
31
|
-
this.identifierCount = 0;
|
|
32
|
-
this.identifiers = new Set();
|
|
33
|
-
this.nodeCount = 0;
|
|
34
|
-
this.diagnostics = [];
|
|
35
|
-
this.currentNodeHasError = false;
|
|
36
|
-
this.currentContext = ParsingContext.None;
|
|
37
|
-
}
|
|
38
|
-
#nextToken() {
|
|
39
|
-
this.currentToken = this.scanner.scan(true);
|
|
40
|
-
return this.currentToken;
|
|
41
|
-
}
|
|
42
|
-
#token() {
|
|
43
|
-
return this.currentToken;
|
|
44
|
-
}
|
|
45
|
-
#getLinesFromFile(sourceText) {
|
|
46
|
-
return sourceText.split(/\r?\n/);
|
|
47
|
-
}
|
|
48
|
-
parse(sourceText) {
|
|
49
|
-
this.sourceText = sourceText;
|
|
50
|
-
this.scanner.setText(this.sourceText);
|
|
51
|
-
this.#nextToken();
|
|
52
|
-
let graph;
|
|
53
|
-
if (this.#token() !== SyntaxKind.EndOfFileToken) {
|
|
54
|
-
graph = this.#parseGraph();
|
|
55
|
-
if (this.#token() !== SyntaxKind.EndOfFileToken) {
|
|
56
|
-
this.#parseErrorAtPosition(this.scanner.tokenPos, this.scanner.text.length - 1, "Content after the end of a graph declaration is invalid.", { source: 2, sub: 1 });
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
const result = {
|
|
60
|
-
content: this.sourceText,
|
|
61
|
-
graph,
|
|
62
|
-
identifiers: this.identifiers,
|
|
63
|
-
diagnostics: this.diagnostics,
|
|
64
|
-
};
|
|
65
|
-
this.#resetState();
|
|
66
|
-
return result;
|
|
67
|
-
}
|
|
68
|
-
#parseGraph() {
|
|
69
|
-
const strictToken = this.#parseOptionalToken(SyntaxKind.StrictKeyword);
|
|
70
|
-
const keyword = this.#parseExpectedTokenOneOf(SyntaxKind.DigraphKeyword, [
|
|
71
|
-
SyntaxKind.DigraphKeyword,
|
|
72
|
-
SyntaxKind.GraphKeyword,
|
|
73
|
-
]);
|
|
74
|
-
const kind = keyword === undefined || keyword.kind === SyntaxKind.DigraphKeyword
|
|
75
|
-
? SyntaxKind.DirectedGraph
|
|
76
|
-
: SyntaxKind.UndirectedGraph;
|
|
77
|
-
const graphStart = strictToken ? strictToken.pos : keyword.pos;
|
|
78
|
-
const node = this.#createNode(kind, graphStart);
|
|
79
|
-
node.strict = strictToken;
|
|
80
|
-
node.keyword = keyword;
|
|
81
|
-
node.id = this.#isIdentifier() ? this.#parseIdentifier() : undefined;
|
|
82
|
-
this.#parseExpectedToken(SyntaxKind.OpenBraceToken);
|
|
83
|
-
node.statements = this.#parseList(ParsingContext.StatementList, () => this.#parseStatement());
|
|
84
|
-
this.#parseExpectedToken(SyntaxKind.CloseBraceToken);
|
|
85
|
-
return this.#finishNode(node);
|
|
86
|
-
}
|
|
87
|
-
#parseIdentifier() {
|
|
88
|
-
let result;
|
|
89
|
-
const escapedIdTexts = [];
|
|
90
|
-
switch (this.#token()) {
|
|
91
|
-
case SyntaxKind.TextIdentifier:
|
|
92
|
-
result = this.#parseTextIdentifier();
|
|
93
|
-
escapedIdTexts.push(result.text);
|
|
94
|
-
break;
|
|
95
|
-
case SyntaxKind.StringLiteral:
|
|
96
|
-
result = this.#parseQuotedTextIdentifierConcatenation();
|
|
97
|
-
escapedIdTexts.push(...result.values.map(v => v.text));
|
|
98
|
-
break;
|
|
99
|
-
case SyntaxKind.HtmlIdentifier:
|
|
100
|
-
result = this.#parseHtmlIdentifier();
|
|
101
|
-
escapedIdTexts.push(result.htmlContent);
|
|
102
|
-
break;
|
|
103
|
-
case SyntaxKind.NumericIdentifier:
|
|
104
|
-
result = this.#parseNumericIdentifier();
|
|
105
|
-
escapedIdTexts.push(result.text);
|
|
106
|
-
break;
|
|
107
|
-
default:
|
|
108
|
-
this.#reportExpectedError([SyntaxKind.TextIdentifier]);
|
|
109
|
-
result = this.#createMissingNode(SyntaxKind.TextIdentifier);
|
|
110
|
-
break;
|
|
111
|
-
}
|
|
112
|
-
for (const i of escapedIdTexts) {
|
|
113
|
-
this.#registerIdentifier(i);
|
|
114
|
-
}
|
|
115
|
-
return result;
|
|
116
|
-
}
|
|
117
|
-
#registerIdentifier(id) {
|
|
118
|
-
this.identifierCount++;
|
|
119
|
-
const has = this.identifiers.has(id);
|
|
120
|
-
if (!has)
|
|
121
|
-
this.identifiers.add(id);
|
|
122
|
-
}
|
|
123
|
-
#parseTextIdentifier() {
|
|
124
|
-
const node = this.#createNode(SyntaxKind.TextIdentifier);
|
|
125
|
-
const text = this.scanner.tokenValue;
|
|
126
|
-
this.#nextToken();
|
|
127
|
-
if (text === undefined)
|
|
128
|
-
throw "Satisfy type checker";
|
|
129
|
-
node.text = text;
|
|
130
|
-
return this.#finishNode(node);
|
|
131
|
-
}
|
|
132
|
-
#parseQuotedTextIdentifierConcatenation() {
|
|
133
|
-
const node = this.#createNode(SyntaxKind.QuotedTextIdentifier);
|
|
134
|
-
node.values = this.#parseList(ParsingContext.QuotedTextIdentifierConcatenation, () => this.#parseQuotedTextIdentifier(), true);
|
|
135
|
-
return this.#finishNode(node);
|
|
136
|
-
}
|
|
137
|
-
#parseQuotedTextIdentifier() {
|
|
138
|
-
const node = this.#createNode(SyntaxKind.StringLiteral);
|
|
139
|
-
if (this.#token() === SyntaxKind.PlusToken)
|
|
140
|
-
this.#nextToken();
|
|
141
|
-
const text = this.scanner.tokenValue;
|
|
142
|
-
this.#nextToken();
|
|
143
|
-
if (text === undefined)
|
|
144
|
-
throw "Satisfy type checker";
|
|
145
|
-
node.text = text;
|
|
146
|
-
return this.#finishNode(node);
|
|
147
|
-
}
|
|
148
|
-
#isQuotedStringFollowing() {
|
|
149
|
-
this.#nextToken();
|
|
150
|
-
return this.#token() === SyntaxKind.StringLiteral;
|
|
151
|
-
}
|
|
152
|
-
#parseHtmlIdentifier() {
|
|
153
|
-
const node = this.#createNode(SyntaxKind.HtmlIdentifier);
|
|
154
|
-
const text = this.scanner.tokenValue;
|
|
155
|
-
this.#nextToken();
|
|
156
|
-
if (text === undefined)
|
|
157
|
-
throw "Satisfy type checker";
|
|
158
|
-
node.htmlContent = text;
|
|
159
|
-
return this.#finishNode(node);
|
|
160
|
-
}
|
|
161
|
-
#parseNumericIdentifier() {
|
|
162
|
-
const node = this.#createNode(SyntaxKind.NumericIdentifier);
|
|
163
|
-
const text = this.scanner.tokenValue;
|
|
164
|
-
this.#nextToken();
|
|
165
|
-
if (text === undefined)
|
|
166
|
-
throw "Satisfy type checker";
|
|
167
|
-
node.text = text;
|
|
168
|
-
node.value = Number(text);
|
|
169
|
-
return this.#finishNode(node);
|
|
170
|
-
}
|
|
171
|
-
#parseStatement() {
|
|
172
|
-
switch (this.#token()) {
|
|
173
|
-
case SyntaxKind.GraphKeyword:
|
|
174
|
-
case SyntaxKind.NodeKeyword:
|
|
175
|
-
case SyntaxKind.EdgeKeyword:
|
|
176
|
-
return this.#parseAttributeStatement();
|
|
177
|
-
case SyntaxKind.OpenBraceToken:
|
|
178
|
-
case SyntaxKind.SubgraphKeyword: {
|
|
179
|
-
const subgraph = this.#parseSubGraph();
|
|
180
|
-
if (this.#token() === SyntaxKind.SemicolonToken) {
|
|
181
|
-
const subgraphStatement = this.#createNode(SyntaxKind.SubGraphStatement, subgraph.pos);
|
|
182
|
-
subgraphStatement.subgraph = subgraph;
|
|
183
|
-
subgraphStatement.terminator = this.#parseExpectedToken(SyntaxKind.SemicolonToken);
|
|
184
|
-
return this.#finishNode(subgraphStatement);
|
|
185
|
-
}
|
|
186
|
-
if (this.#isEdgeOp())
|
|
187
|
-
return this.#parseEdgeStatement(subgraph);
|
|
188
|
-
const subgraphStatement = this.#createNode(SyntaxKind.SubGraphStatement, subgraph.pos);
|
|
189
|
-
subgraphStatement.subgraph = subgraph;
|
|
190
|
-
return this.#finishNode(subgraphStatement);
|
|
191
|
-
}
|
|
192
|
-
default: {
|
|
193
|
-
if (!this.#isIdentifier)
|
|
194
|
-
debugger;
|
|
195
|
-
if (this.#lookAhead(() => this.#isIdEqualsIdStatement())) {
|
|
196
|
-
return this.#parseIdEqualsIdStatement();
|
|
197
|
-
}
|
|
198
|
-
const ns = this.#parseNodeStatement();
|
|
199
|
-
if (ns.terminator !== undefined || ns.attributes.length !== 0)
|
|
200
|
-
return ns;
|
|
201
|
-
if (this.#isEdgeOp())
|
|
202
|
-
return this.#parseEdgeStatement(ns.id);
|
|
203
|
-
return ns;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
#parseAttributeStatement() {
|
|
208
|
-
switch (this.#token()) {
|
|
209
|
-
case SyntaxKind.GraphKeyword:
|
|
210
|
-
case SyntaxKind.NodeKeyword:
|
|
211
|
-
case SyntaxKind.EdgeKeyword: {
|
|
212
|
-
const node = this.#createNode(SyntaxKind.AttributeStatement);
|
|
213
|
-
node.subject = this.#parseTokenNode();
|
|
214
|
-
if (this.#token() === SyntaxKind.OpenBracketToken) {
|
|
215
|
-
node.attributes = this.#parseList(ParsingContext.AttributeContainerList, () => this.#parseAttributeContainer());
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
this.#reportExpectedError([SyntaxKind.OpenBracketToken]);
|
|
219
|
-
const missingStatement = this.#createMissingNode(SyntaxKind.AttributeStatement);
|
|
220
|
-
missingStatement.attributes = this.#createNodeArray([this.#createMissingNode(SyntaxKind.AttributeContainer)], this.scanner.tokenPos, this.scanner.tokenPos);
|
|
221
|
-
}
|
|
222
|
-
node.terminator = this.#parseOptionalToken(SyntaxKind.SemicolonToken);
|
|
223
|
-
return this.#finishNode(node);
|
|
224
|
-
}
|
|
225
|
-
default:
|
|
226
|
-
throw "This should never happen";
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
#parseAttributeContainer() {
|
|
230
|
-
if (this.#token() !== SyntaxKind.OpenBracketToken)
|
|
231
|
-
debugger;
|
|
232
|
-
const node = this.#createNode(SyntaxKind.AttributeContainer);
|
|
233
|
-
node.openBracket = this.#parseExpectedToken(SyntaxKind.OpenBracketToken);
|
|
234
|
-
if (this.#isIdentifier() && this.#lookAhead(() => this.#isAssignmentStart())) {
|
|
235
|
-
node.assignments = this.#parseList(ParsingContext.AssignmentList, () => this.#parseAssignment());
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
node.assignments = this.#createEmptyArray();
|
|
239
|
-
}
|
|
240
|
-
node.closeBracket = this.#parseExpectedToken(SyntaxKind.CloseBracketToken);
|
|
241
|
-
return this.#finishNode(node);
|
|
242
|
-
}
|
|
243
|
-
#isAssignmentStart() {
|
|
244
|
-
if (!this.#isIdentifier)
|
|
245
|
-
debugger;
|
|
246
|
-
this.#nextToken();
|
|
247
|
-
return this.#token() === SyntaxKind.EqualsToken;
|
|
248
|
-
}
|
|
249
|
-
#parseIdEqualsIdStatement() {
|
|
250
|
-
if (!this.#isIdentifier)
|
|
251
|
-
debugger;
|
|
252
|
-
const leftIdentifier = this.#parseIdentifier();
|
|
253
|
-
const node = this.#createNode(SyntaxKind.IdEqualsIdStatement, leftIdentifier.pos);
|
|
254
|
-
node.leftId = leftIdentifier;
|
|
255
|
-
if (this.#token() !== SyntaxKind.EqualsToken)
|
|
256
|
-
debugger;
|
|
257
|
-
this.#parseExpectedToken(SyntaxKind.EqualsToken);
|
|
258
|
-
node.rightId = this.#parseIdentifier();
|
|
259
|
-
node.terminator = this.#parseOptionalToken(SyntaxKind.SemicolonToken);
|
|
260
|
-
return this.#finishNode(node);
|
|
261
|
-
}
|
|
262
|
-
#isIdEqualsIdStatement() {
|
|
263
|
-
if (!this.#isIdentifier)
|
|
264
|
-
debugger;
|
|
265
|
-
this.#nextToken();
|
|
266
|
-
return this.#token() === SyntaxKind.EqualsToken;
|
|
267
|
-
}
|
|
268
|
-
#parseNodeStatement() {
|
|
269
|
-
if (!this.#isIdentifier)
|
|
270
|
-
debugger;
|
|
271
|
-
const node = this.#createNode(SyntaxKind.NodeStatement);
|
|
272
|
-
node.id = this.#parseNodeId();
|
|
273
|
-
if (this.#token() === SyntaxKind.OpenBracketToken) {
|
|
274
|
-
node.attributes = this.#parseList(ParsingContext.AttributeContainerList, () => this.#parseAttributeContainer());
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
node.attributes = this.#createEmptyArray();
|
|
278
|
-
}
|
|
279
|
-
node.terminator = this.#parseOptionalToken(SyntaxKind.SemicolonToken);
|
|
280
|
-
return this.#finishNode(node);
|
|
281
|
-
}
|
|
282
|
-
#parseEdgeStatement(precedingItem) {
|
|
283
|
-
console.assert(precedingItem.kind === SyntaxKind.SubGraph || precedingItem.kind === SyntaxKind.NodeId);
|
|
284
|
-
console.assert(precedingItem.pos !== undefined);
|
|
285
|
-
if (!this.#isEdgeOp())
|
|
286
|
-
debugger;
|
|
287
|
-
const node = this.#createNode(SyntaxKind.EdgeStatement, precedingItem.pos);
|
|
288
|
-
node.source = precedingItem;
|
|
289
|
-
node.rhs = this.#parseList(ParsingContext.EdgeRhsList, () => this.#parseEdgeRhs());
|
|
290
|
-
if (this.#token() === SyntaxKind.OpenBracketToken) {
|
|
291
|
-
node.attributes = this.#parseList(ParsingContext.AttributeContainerList, () => this.#parseAttributeContainer());
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
node.attributes = this.#createEmptyArray();
|
|
295
|
-
}
|
|
296
|
-
node.terminator = this.#parseOptionalToken(SyntaxKind.SemicolonToken);
|
|
297
|
-
return this.#finishNode(node);
|
|
298
|
-
}
|
|
299
|
-
#parseEdgeRhs() {
|
|
300
|
-
const node = this.#createNode(SyntaxKind.EdgeRhs);
|
|
301
|
-
const op = this.#parseExpectedTokenOneOf(SyntaxKind.DirectedEdgeOp, [
|
|
302
|
-
SyntaxKind.DirectedEdgeOp,
|
|
303
|
-
SyntaxKind.UndirectedEdgeOp,
|
|
304
|
-
]);
|
|
305
|
-
node.operation = op;
|
|
306
|
-
switch (this.#token()) {
|
|
307
|
-
case SyntaxKind.SubgraphKeyword:
|
|
308
|
-
case SyntaxKind.OpenBraceToken:
|
|
309
|
-
node.target = this.#parseSubGraph();
|
|
310
|
-
break;
|
|
311
|
-
default: {
|
|
312
|
-
node.target = this.#parseNodeId();
|
|
313
|
-
break;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
return this.#finishNode(node);
|
|
317
|
-
}
|
|
318
|
-
#createMissingNode(kind) {
|
|
319
|
-
const result = this.#createNode(kind);
|
|
320
|
-
if (isIdentifierNode(result)) {
|
|
321
|
-
switch (result.kind) {
|
|
322
|
-
case SyntaxKind.QuotedTextIdentifier: {
|
|
323
|
-
const literal = this.#createNode(SyntaxKind.StringLiteral);
|
|
324
|
-
literal.text = "";
|
|
325
|
-
const values = this.#createNodeArray([literal], result.pos, result.pos);
|
|
326
|
-
result.values = values;
|
|
327
|
-
break;
|
|
328
|
-
}
|
|
329
|
-
case SyntaxKind.HtmlIdentifier:
|
|
330
|
-
result.htmlContent = "";
|
|
331
|
-
break;
|
|
332
|
-
case SyntaxKind.TextIdentifier:
|
|
333
|
-
case SyntaxKind.NumericIdentifier:
|
|
334
|
-
result.text = "";
|
|
335
|
-
break;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
return this.#finishNode(result);
|
|
339
|
-
}
|
|
340
|
-
#parseAssignment() {
|
|
341
|
-
if (!this.#isIdentifier)
|
|
342
|
-
debugger;
|
|
343
|
-
const node = this.#createNode(SyntaxKind.Assignment);
|
|
344
|
-
node.leftId = this.#parseIdentifier();
|
|
345
|
-
this.#parseExpectedToken(SyntaxKind.EqualsToken);
|
|
346
|
-
node.rightId = this.#parseIdentifier();
|
|
347
|
-
let terminator = this.#parseOptionalToken(SyntaxKind.CommaToken);
|
|
348
|
-
if (terminator === undefined)
|
|
349
|
-
terminator = this.#parseOptionalToken(SyntaxKind.SemicolonToken);
|
|
350
|
-
node.terminator = terminator;
|
|
351
|
-
return this.#finishNode(node);
|
|
352
|
-
}
|
|
353
|
-
#parseSubGraph() {
|
|
354
|
-
console.assert(this.#token() === SyntaxKind.SubgraphKeyword ||
|
|
355
|
-
this.#token() === SyntaxKind.OpenBraceToken);
|
|
356
|
-
const subGraph = this.#parseOptionalToken(SyntaxKind.SubgraphKeyword);
|
|
357
|
-
const subGraphStart = subGraph !== undefined ? subGraph.pos : undefined;
|
|
358
|
-
const node = this.#createNode(SyntaxKind.SubGraph, subGraphStart);
|
|
359
|
-
const identifier = subGraph !== undefined && this.#isIdentifier() ? this.#parseIdentifier() : undefined;
|
|
360
|
-
node.id = identifier;
|
|
361
|
-
this.#parseExpectedToken(SyntaxKind.OpenBraceToken);
|
|
362
|
-
node.statements = this.#parseList(ParsingContext.StatementList, () => this.#parseStatement());
|
|
363
|
-
this.#parseExpectedToken(SyntaxKind.CloseBraceToken);
|
|
364
|
-
return this.#finishNode(node);
|
|
365
|
-
}
|
|
366
|
-
#parseNodeId() {
|
|
367
|
-
if (!this.#isIdentifier)
|
|
368
|
-
debugger;
|
|
369
|
-
const node = this.#createNode(SyntaxKind.NodeId);
|
|
370
|
-
node.id = this.#parseIdentifier();
|
|
371
|
-
node.port =
|
|
372
|
-
this.#token() === SyntaxKind.ColonToken ? this.#parsePortDeclaration() : undefined;
|
|
373
|
-
return this.#finishNode(node);
|
|
374
|
-
}
|
|
375
|
-
#parseCompassPortDeclaration() {
|
|
376
|
-
console.assert(this.#token() === SyntaxKind.ColonToken);
|
|
377
|
-
const node = this.#createNode(SyntaxKind.CompassPortDeclaration);
|
|
378
|
-
node.colon = this.#parseTokenNode();
|
|
379
|
-
node.compassPt = this.#parseTokenNode();
|
|
380
|
-
return this.#finishNode(node);
|
|
381
|
-
}
|
|
382
|
-
#parseNormalPortDeclaration() {
|
|
383
|
-
console.assert(this.#token() === SyntaxKind.ColonToken);
|
|
384
|
-
const node = this.#createNode(SyntaxKind.NormalPortDeclaration);
|
|
385
|
-
node.colon = this.#parseTokenNode();
|
|
386
|
-
node.id = this.#parseIdentifier();
|
|
387
|
-
node.compassPt =
|
|
388
|
-
this.#token() === SyntaxKind.ColonToken
|
|
389
|
-
? this.#parseCompassPortDeclaration()
|
|
390
|
-
: undefined;
|
|
391
|
-
return this.#finishNode(node);
|
|
392
|
-
}
|
|
393
|
-
#parsePortDeclaration() {
|
|
394
|
-
console.assert(this.#token() === SyntaxKind.ColonToken);
|
|
395
|
-
if (this.#lookAhead(() => this.#isCompassPort()))
|
|
396
|
-
return this.#parseCompassPortDeclaration();
|
|
397
|
-
return this.#parseNormalPortDeclaration();
|
|
398
|
-
}
|
|
399
|
-
#isCompassPort() {
|
|
400
|
-
console.assert(this.#token() === SyntaxKind.ColonToken);
|
|
401
|
-
if (this.#token() !== SyntaxKind.ColonToken)
|
|
402
|
-
return false;
|
|
403
|
-
this.#nextToken();
|
|
404
|
-
return this.#isCompassPortKind(this.#token());
|
|
405
|
-
}
|
|
406
|
-
#parseList(context, parseElement, atLeastOne = false) {
|
|
407
|
-
const saveParsingContext = this.currentContext;
|
|
408
|
-
this.currentContext |= 1 << context;
|
|
409
|
-
let isListTerminated = atLeastOne ? false : this.#isListTerminator(context);
|
|
410
|
-
const startPos = this.scanner.startPos;
|
|
411
|
-
const elements = [];
|
|
412
|
-
while (!isListTerminated) {
|
|
413
|
-
if (this.#isListElement(context, false)) {
|
|
414
|
-
const element = parseElement();
|
|
415
|
-
elements.push(element);
|
|
416
|
-
isListTerminated = this.#isListTerminator(context);
|
|
417
|
-
continue;
|
|
418
|
-
}
|
|
419
|
-
if (this.#abortListParsing(context))
|
|
420
|
-
break;
|
|
421
|
-
}
|
|
422
|
-
this.currentContext = saveParsingContext;
|
|
423
|
-
return this.#createNodeArray(elements, startPos);
|
|
424
|
-
}
|
|
425
|
-
#getContextParseError(context) {
|
|
426
|
-
switch (context) {
|
|
427
|
-
case ParsingContext.StatementList:
|
|
428
|
-
return "Assignment, node definition, graph/node/edge attribute or edge definition expected.";
|
|
429
|
-
case ParsingContext.AssignmentList:
|
|
430
|
-
return "Assignment expected.";
|
|
431
|
-
case ParsingContext.EdgeRhsList:
|
|
432
|
-
return "Edge operation expected.";
|
|
433
|
-
case ParsingContext.QuotedTextIdentifierConcatenation:
|
|
434
|
-
return "Quoted identifier expected";
|
|
435
|
-
case ParsingContext.AttributeContainerList:
|
|
436
|
-
return "Attribute marker expected.";
|
|
437
|
-
case ParsingContext.None:
|
|
438
|
-
return "Wat, no parsing context";
|
|
439
|
-
case ParsingContext.Count:
|
|
440
|
-
return "Wat, 'Count' parsing context";
|
|
441
|
-
default:
|
|
442
|
-
return assertNever(context);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
#isInSomeParsingContext() {
|
|
446
|
-
for (let ctx = 0; ctx < ParsingContext.Count; ctx++) {
|
|
447
|
-
if (this.currentContext & (1 << ctx)) {
|
|
448
|
-
if (this.#isListElement(ctx, true) ||
|
|
449
|
-
this.#isListTerminator(ctx)) {
|
|
450
|
-
return true;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
return false;
|
|
455
|
-
}
|
|
456
|
-
#abortListParsing(context) {
|
|
457
|
-
this.#parseErrorAtCurrentToken(this.#getContextParseError(context), 2);
|
|
458
|
-
if (this.#isInSomeParsingContext()) {
|
|
459
|
-
return true;
|
|
460
|
-
}
|
|
461
|
-
this.#nextToken();
|
|
462
|
-
return false;
|
|
463
|
-
}
|
|
464
|
-
#isListElement(context, _inErrorRecovery) {
|
|
465
|
-
switch (context) {
|
|
466
|
-
case ParsingContext.AssignmentList:
|
|
467
|
-
return this.#isIdentifier();
|
|
468
|
-
case ParsingContext.AttributeContainerList:
|
|
469
|
-
return this.#token() === SyntaxKind.OpenBracketToken;
|
|
470
|
-
case ParsingContext.EdgeRhsList:
|
|
471
|
-
return (this.#token() === SyntaxKind.DirectedEdgeOp ||
|
|
472
|
-
this.#token() === SyntaxKind.UndirectedEdgeOp);
|
|
473
|
-
case ParsingContext.QuotedTextIdentifierConcatenation:
|
|
474
|
-
return (this.#token() === SyntaxKind.StringLiteral ||
|
|
475
|
-
this.#token() === SyntaxKind.PlusToken);
|
|
476
|
-
case ParsingContext.StatementList:
|
|
477
|
-
return (this.#isIdentifier() ||
|
|
478
|
-
this.#token() === SyntaxKind.SubgraphKeyword ||
|
|
479
|
-
this.#token() === SyntaxKind.OpenBraceToken ||
|
|
480
|
-
this.#token() === SyntaxKind.GraphKeyword ||
|
|
481
|
-
this.#token() === SyntaxKind.EdgeKeyword ||
|
|
482
|
-
this.#token() === SyntaxKind.NodeKeyword);
|
|
483
|
-
default:
|
|
484
|
-
throw "This should never happen";
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
#isListTerminator(context) {
|
|
488
|
-
const token = this.#token();
|
|
489
|
-
if (token === SyntaxKind.EndOfFileToken)
|
|
490
|
-
return true;
|
|
491
|
-
switch (context) {
|
|
492
|
-
case ParsingContext.StatementList:
|
|
493
|
-
return token === SyntaxKind.CloseBraceToken;
|
|
494
|
-
case ParsingContext.AttributeContainerList:
|
|
495
|
-
return token !== SyntaxKind.OpenBracketToken;
|
|
496
|
-
case ParsingContext.AssignmentList:
|
|
497
|
-
return token === SyntaxKind.CloseBracketToken;
|
|
498
|
-
case ParsingContext.EdgeRhsList:
|
|
499
|
-
return token !== SyntaxKind.DirectedEdgeOp && token !== SyntaxKind.UndirectedEdgeOp;
|
|
500
|
-
case ParsingContext.QuotedTextIdentifierConcatenation:
|
|
501
|
-
return token !== SyntaxKind.PlusToken;
|
|
502
|
-
default:
|
|
503
|
-
throw "Unsupported parsing context";
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
#createEmptyArray() {
|
|
507
|
-
const startPos = this.scanner.startPos;
|
|
508
|
-
const elements = [];
|
|
509
|
-
return this.#createNodeArray(elements, startPos);
|
|
510
|
-
}
|
|
511
|
-
#finishNode(node, end) {
|
|
512
|
-
node.end = end === undefined ? this.scanner.startPos : end;
|
|
513
|
-
if (this.currentNodeHasError) {
|
|
514
|
-
this.currentNodeHasError = false;
|
|
515
|
-
node.flags |= 2;
|
|
516
|
-
}
|
|
517
|
-
return node;
|
|
518
|
-
}
|
|
519
|
-
#createNode(kind, pos) {
|
|
520
|
-
this.nodeCount++;
|
|
521
|
-
const p = pos !== undefined && pos >= 0 ? pos : this.scanner.startPos;
|
|
522
|
-
if (isNodeKind(kind) || kind === SyntaxKind.Unknown)
|
|
523
|
-
return newNode(kind, p, p);
|
|
524
|
-
return isIdentifier(kind) ? newIdentifier(kind, p, p) : newToken(kind, p, p);
|
|
525
|
-
}
|
|
526
|
-
#createNodeArray(elements, pos, end) {
|
|
527
|
-
const length = elements.length;
|
|
528
|
-
const array = ((length >= 1 && length <= 4 ? elements.slice() : elements));
|
|
529
|
-
array.pos = pos;
|
|
530
|
-
array.end = end === undefined ? this.scanner.startPos : end;
|
|
531
|
-
return array;
|
|
532
|
-
}
|
|
533
|
-
#parseTokenNode() {
|
|
534
|
-
const node = this.#createNode(this.#token());
|
|
535
|
-
this.#nextToken();
|
|
536
|
-
return this.#finishNode(node);
|
|
537
|
-
}
|
|
538
|
-
#getLastError(diagnostics) {
|
|
539
|
-
return diagnostics && diagnostics.length > 0
|
|
540
|
-
? diagnostics[diagnostics.length - 1]
|
|
541
|
-
: undefined;
|
|
542
|
-
}
|
|
543
|
-
#parseErrorAtPosition(start, end, message, code) {
|
|
544
|
-
const ds = this.diagnostics;
|
|
545
|
-
const lastError = this.#getLastError(ds);
|
|
546
|
-
if (!lastError || start !== lastError.start) {
|
|
547
|
-
ds.push({
|
|
548
|
-
category: DiagnosticCategory.Error,
|
|
549
|
-
start,
|
|
550
|
-
end,
|
|
551
|
-
message,
|
|
552
|
-
code,
|
|
553
|
-
});
|
|
554
|
-
}
|
|
555
|
-
this.currentNodeHasError = true;
|
|
556
|
-
}
|
|
557
|
-
#parseErrorAtCurrentToken(message, sub) {
|
|
558
|
-
const error = {
|
|
559
|
-
source: 2,
|
|
560
|
-
sub,
|
|
561
|
-
};
|
|
562
|
-
return this.#parseErrorAtPosition(this.scanner.tokenPos, this.scanner.pos, message, error);
|
|
563
|
-
}
|
|
564
|
-
#scanError(message, _category, sub, length) {
|
|
565
|
-
const errorPos = this.scanner.pos;
|
|
566
|
-
const err = {
|
|
567
|
-
source: 1,
|
|
568
|
-
sub,
|
|
569
|
-
};
|
|
570
|
-
this.#parseErrorAtPosition(errorPos, errorPos + length, message, err);
|
|
571
|
-
}
|
|
572
|
-
#reportExpectedError(expectedKinds) {
|
|
573
|
-
const found = this.#isIdentifier()
|
|
574
|
-
? "identifier"
|
|
575
|
-
: this.#token() === SyntaxKind.EndOfFileToken
|
|
576
|
-
? "end of file"
|
|
577
|
-
: `"${getTokenAsText(this.#token())}"`;
|
|
578
|
-
const expected = expectedKinds.map(k => {
|
|
579
|
-
if (isIdentifier(k)) {
|
|
580
|
-
return "identifier";
|
|
581
|
-
}
|
|
582
|
-
if (k === SyntaxKind.EndOfFileToken) {
|
|
583
|
-
return "end of file";
|
|
584
|
-
}
|
|
585
|
-
return `"${getTokenAsText(k)}"`;
|
|
586
|
-
});
|
|
587
|
-
const lastExpected = expected.pop();
|
|
588
|
-
const expectedJoined = expected.join(", ");
|
|
589
|
-
const msg = expected.length > 0
|
|
590
|
-
? `Expected ${expectedJoined} or ${lastExpected} but found ${found} instead.`
|
|
591
|
-
: `Expected ${lastExpected} but found ${found} instead.`;
|
|
592
|
-
this.#parseErrorAtCurrentToken(msg, 0);
|
|
593
|
-
}
|
|
594
|
-
#parseExpectedOneOf(...kinds) {
|
|
595
|
-
if (kinds.length < 2) {
|
|
596
|
-
console.assert(false);
|
|
597
|
-
debugger;
|
|
598
|
-
}
|
|
599
|
-
for (const kind of kinds) {
|
|
600
|
-
if (this.#token() === kind) {
|
|
601
|
-
this.#nextToken();
|
|
602
|
-
return true;
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
this.#reportExpectedError(kinds);
|
|
606
|
-
return false;
|
|
607
|
-
}
|
|
608
|
-
#parseExpectedTokenOneOf(fallback, kinds) {
|
|
609
|
-
if (kinds.length < 2) {
|
|
610
|
-
console.assert(false);
|
|
611
|
-
debugger;
|
|
612
|
-
}
|
|
613
|
-
for (const kind of kinds) {
|
|
614
|
-
if (this.#token() === kind) {
|
|
615
|
-
const node = this.#createNode(this.#token());
|
|
616
|
-
this.#nextToken();
|
|
617
|
-
return this.#finishNode(node);
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
this.#reportExpectedError(kinds);
|
|
621
|
-
return this.#createMissingNode(fallback);
|
|
622
|
-
}
|
|
623
|
-
#parseExpectedToken(kind) {
|
|
624
|
-
const tokenNode = this.#parseOptionalToken(kind);
|
|
625
|
-
if (tokenNode !== undefined)
|
|
626
|
-
return tokenNode;
|
|
627
|
-
this.#reportExpectedError([kind]);
|
|
628
|
-
return this.#createMissingNode(kind);
|
|
629
|
-
}
|
|
630
|
-
#parseExpected(kind) {
|
|
631
|
-
const res = this.#parseOptional(kind);
|
|
632
|
-
if (!res)
|
|
633
|
-
this.#reportExpectedError([kind]);
|
|
634
|
-
return res;
|
|
635
|
-
}
|
|
636
|
-
#parseOptionalToken(t) {
|
|
637
|
-
if (this.#token() === t) {
|
|
638
|
-
return this.#parseTokenNode();
|
|
639
|
-
}
|
|
640
|
-
return undefined;
|
|
641
|
-
}
|
|
642
|
-
#parseOptional(t) {
|
|
643
|
-
if (this.#token() === t) {
|
|
644
|
-
this.#nextToken();
|
|
645
|
-
return true;
|
|
646
|
-
}
|
|
647
|
-
return false;
|
|
648
|
-
}
|
|
649
|
-
#isEdgeOp() {
|
|
650
|
-
switch (this.#token()) {
|
|
651
|
-
case SyntaxKind.DirectedEdgeOp:
|
|
652
|
-
case SyntaxKind.UndirectedEdgeOp:
|
|
653
|
-
return true;
|
|
654
|
-
default:
|
|
655
|
-
return false;
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
#isIdentifier() {
|
|
659
|
-
switch (this.#token()) {
|
|
660
|
-
case SyntaxKind.TextIdentifier:
|
|
661
|
-
case SyntaxKind.NumericIdentifier:
|
|
662
|
-
case SyntaxKind.StringLiteral:
|
|
663
|
-
case SyntaxKind.HtmlIdentifier:
|
|
664
|
-
return true;
|
|
665
|
-
default:
|
|
666
|
-
return false;
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
#isCompassPortKind(kind) {
|
|
670
|
-
return kind >= SyntaxKind.CompassCenterToken && kind <= SyntaxKind.CompassEnd;
|
|
671
|
-
}
|
|
672
|
-
#speculationHelper(callback, isLookAhead) {
|
|
673
|
-
const saveToken = this.#token();
|
|
674
|
-
const saveDiagnosticsLength = this.diagnostics.length;
|
|
675
|
-
const result = isLookAhead
|
|
676
|
-
? this.scanner.lookAhead(callback)
|
|
677
|
-
: this.scanner.tryScan(callback);
|
|
678
|
-
if (!result || isLookAhead) {
|
|
679
|
-
this.currentToken = saveToken;
|
|
680
|
-
this.diagnostics.length = saveDiagnosticsLength;
|
|
681
|
-
}
|
|
682
|
-
return result;
|
|
683
|
-
}
|
|
684
|
-
#lookAhead(callback) {
|
|
685
|
-
return this.#speculationHelper(callback, true);
|
|
686
|
-
}
|
|
687
|
-
#tryParse(callback) {
|
|
688
|
-
return this.#speculationHelper(callback, false);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
function newNode(kind, pos, end) {
|
|
692
|
-
return {
|
|
693
|
-
kind,
|
|
694
|
-
flags: 0,
|
|
695
|
-
end,
|
|
696
|
-
pos,
|
|
697
|
-
parent: undefined,
|
|
698
|
-
};
|
|
699
|
-
}
|
|
700
|
-
const newIdentifier = newNode;
|
|
701
|
-
const newToken = newNode;
|
|
702
|
-
function isNodeKind(kind) {
|
|
703
|
-
return kind >= SyntaxKind.FirstNode;
|
|
704
|
-
}
|
|
705
|
-
export function isIdentifier(kind) {
|
|
706
|
-
return (kind === SyntaxKind.HtmlIdentifier ||
|
|
707
|
-
kind === SyntaxKind.NumericIdentifier ||
|
|
708
|
-
kind === SyntaxKind.TextIdentifier ||
|
|
709
|
-
kind === SyntaxKind.QuotedTextIdentifier);
|
|
710
|
-
}
|
|
711
|
-
export function isIdentifierNode(node) {
|
|
712
|
-
return isIdentifier(node.kind);
|
|
713
|
-
}
|
|
714
|
-
//# sourceMappingURL=parser.js.map
|