dot-language-support 1.7.0 → 2.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/.github/workflows/CD.yml +3 -3
- package/.github/workflows/CI.yml +2 -2
- package/README.md +5 -4
- package/jest.config.mjs +19 -0
- package/lib/{binder.d.ts → cjs/binder.d.ts} +1 -1
- package/lib/{binder.js → cjs/binder.js} +34 -34
- package/lib/{checker.d.ts → cjs/checker.d.ts} +1 -1
- package/lib/{checker.js → cjs/checker.js} +28 -28
- package/lib/{core.d.ts → cjs/core.d.ts} +0 -0
- package/lib/{core.js → cjs/core.js} +0 -0
- package/lib/{error.d.ts → cjs/error.d.ts} +1 -1
- package/lib/{error.js → cjs/error.js} +0 -0
- package/lib/cjs/index.d.ts +5 -0
- package/lib/{index.js → cjs/index.js} +5 -5
- package/lib/{parser.d.ts → cjs/parser.d.ts} +1 -1
- package/lib/{parser.js → cjs/parser.js} +11 -11
- package/lib/{scanner.d.ts → cjs/scanner.d.ts} +1 -1
- package/lib/{scanner.js → cjs/scanner.js} +67 -67
- package/lib/{service → cjs/service}/codeAction.d.ts +2 -2
- package/lib/{service → cjs/service}/codeAction.js +34 -34
- package/lib/{service → cjs/service}/colorProvider.d.ts +3 -3
- package/lib/{service → cjs/service}/colorProvider.js +3 -3
- package/lib/{service → cjs/service}/command/ChangeAllOtherEdgeOpsAndFixGraphCommand.d.ts +3 -3
- package/lib/{service → cjs/service}/command/ChangeAllOtherEdgeOpsAndFixGraphCommand.js +6 -6
- package/lib/{service → cjs/service}/command/ChangeEdgeOpCommand.d.ts +3 -3
- package/lib/{service → cjs/service}/command/ChangeEdgeOpCommand.js +3 -3
- package/lib/{service → cjs/service}/command/ConsolidateDescendantsCommand.d.ts +3 -3
- package/lib/{service → cjs/service}/command/ConsolidateDescendantsCommand.js +7 -7
- package/lib/{service → cjs/service}/command/RemoveSemicolons.d.ts +3 -3
- package/lib/{service → cjs/service}/command/RemoveSemicolons.js +4 -4
- package/lib/{service → cjs/service}/command/common.d.ts +2 -2
- package/lib/{service → cjs/service}/command/common.js +6 -6
- package/lib/{service → cjs/service}/completion.d.ts +2 -2
- package/lib/{service → cjs/service}/completion.js +25 -25
- package/lib/{service → cjs/service}/hover.d.ts +2 -2
- package/lib/{service → cjs/service}/hover.js +38 -38
- package/lib/{service → cjs/service}/languageFacts.d.ts +0 -0
- package/lib/{service → cjs/service}/languageFacts.js +0 -0
- package/lib/{service → cjs/service}/polyfill.d.ts +0 -0
- package/lib/{service → cjs/service}/polyfill.js +0 -0
- package/lib/{service → cjs/service}/reference.d.ts +2 -2
- package/lib/{service → cjs/service}/reference.js +9 -9
- package/lib/{service → cjs/service}/rename.d.ts +2 -2
- package/lib/{service → cjs/service}/rename.js +11 -11
- package/lib/{service → cjs/service}/service.d.ts +2 -2
- package/lib/cjs/service/service.js +39 -0
- package/lib/{service → cjs/service}/util.d.ts +2 -2
- package/lib/{service → cjs/service}/util.js +5 -5
- package/lib/{service → cjs/service}/validation.d.ts +2 -2
- package/lib/{service → cjs/service}/validation.js +3 -3
- package/lib/cjs/tester.d.ts +1 -0
- package/lib/cjs/tester.js +23 -0
- package/lib/{types.d.ts → cjs/types.d.ts} +0 -0
- package/lib/{types.js → cjs/types.js} +0 -0
- package/lib/{visitor.d.ts → cjs/visitor.d.ts} +1 -1
- package/lib/{visitor.js → cjs/visitor.js} +17 -17
- package/lib/esm/binder.d.ts +2 -0
- package/lib/esm/binder.js +296 -0
- package/lib/esm/checker.d.ts +14 -0
- package/lib/esm/checker.js +169 -0
- package/lib/esm/core.d.ts +1 -0
- package/lib/esm/core.js +10 -0
- package/lib/esm/error.d.ts +3 -0
- package/lib/esm/error.js +10 -0
- package/lib/esm/index.d.ts +5 -0
- package/lib/esm/index.js +6 -0
- package/lib/esm/parser.d.ts +84 -0
- package/lib/esm/parser.js +700 -0
- package/lib/esm/scanner.d.ts +52 -0
- package/lib/esm/scanner.js +581 -0
- package/lib/esm/service/codeAction.d.ts +12 -0
- package/lib/esm/service/codeAction.js +208 -0
- package/lib/esm/service/colorProvider.d.ts +6 -0
- package/lib/esm/service/colorProvider.js +69 -0
- package/lib/esm/service/command/ChangeAllOtherEdgeOpsAndFixGraphCommand.d.ts +10 -0
- package/lib/esm/service/command/ChangeAllOtherEdgeOpsAndFixGraphCommand.js +38 -0
- package/lib/esm/service/command/ChangeEdgeOpCommand.d.ts +10 -0
- package/lib/esm/service/command/ChangeEdgeOpCommand.js +32 -0
- package/lib/esm/service/command/ConsolidateDescendantsCommand.d.ts +10 -0
- package/lib/esm/service/command/ConsolidateDescendantsCommand.js +83 -0
- package/lib/esm/service/command/RemoveSemicolons.d.ts +10 -0
- package/lib/esm/service/command/RemoveSemicolons.js +37 -0
- package/lib/esm/service/command/common.d.ts +31 -0
- package/lib/esm/service/command/common.js +22 -0
- package/lib/esm/service/completion.d.ts +4 -0
- package/lib/esm/service/completion.js +137 -0
- package/lib/esm/service/hover.d.ts +4 -0
- package/lib/esm/service/hover.js +119 -0
- package/lib/esm/service/languageFacts.d.ts +683 -0
- package/lib/esm/service/languageFacts.js +997 -0
- package/lib/esm/service/polyfill.d.ts +16 -0
- package/lib/esm/service/polyfill.js +2 -0
- package/lib/esm/service/reference.d.ts +5 -0
- package/lib/esm/service/reference.js +66 -0
- package/lib/esm/service/rename.d.ts +4 -0
- package/lib/esm/service/rename.js +45 -0
- package/lib/esm/service/service.d.ts +28 -0
- package/lib/esm/service/service.js +35 -0
- package/lib/esm/service/util.d.ts +11 -0
- package/lib/esm/service/util.js +44 -0
- package/lib/esm/service/validation.d.ts +4 -0
- package/lib/esm/service/validation.js +20 -0
- package/lib/esm/tester.d.ts +1 -0
- package/lib/esm/tester.js +21 -0
- package/lib/esm/types.d.ts +396 -0
- package/lib/esm/types.js +71 -0
- package/lib/esm/visitor.d.ts +2 -0
- package/lib/esm/visitor.js +74 -0
- package/package.json +13 -10
- package/lib/index.d.ts +0 -5
- package/lib/service/service.js +0 -39
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { SyntaxKind, TokenFlags, DiagnosticCategory, ScanError } from "./types.js";
|
|
2
|
+
export interface Scanner {
|
|
3
|
+
readonly end: number;
|
|
4
|
+
readonly pos: number;
|
|
5
|
+
readonly startPos: number;
|
|
6
|
+
readonly tokenPos: number;
|
|
7
|
+
readonly token: SyntaxKind;
|
|
8
|
+
readonly tokenValue: string | undefined;
|
|
9
|
+
readonly isUnterminated: boolean;
|
|
10
|
+
readonly text: string;
|
|
11
|
+
readonly onError: ErrorCallback | null;
|
|
12
|
+
setText(newText?: string, start?: number, length?: number): void;
|
|
13
|
+
setErrorCallback(cb: ErrorCallback): void;
|
|
14
|
+
scan(skipTrivia: boolean): SyntaxKind;
|
|
15
|
+
lookAhead(callback: () => SyntaxKind | boolean): SyntaxKind | boolean;
|
|
16
|
+
tryScan(callback: () => SyntaxKind | boolean): SyntaxKind | boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function getTokenAsText(token: SyntaxKind): string | undefined;
|
|
19
|
+
export declare function getTextAsToken(token: string): SyntaxKind | undefined;
|
|
20
|
+
export declare type ErrorCallback = (message: string, category: DiagnosticCategory, sub: ScanError, length: number) => void;
|
|
21
|
+
export declare class DefaultScanner implements Scanner {
|
|
22
|
+
end: number;
|
|
23
|
+
pos: number;
|
|
24
|
+
startPos: number;
|
|
25
|
+
tokenPos: number;
|
|
26
|
+
token: SyntaxKind;
|
|
27
|
+
tokenValue: string | undefined;
|
|
28
|
+
tokenFlags: TokenFlags;
|
|
29
|
+
isUnterminated: boolean;
|
|
30
|
+
text: string;
|
|
31
|
+
onError: ErrorCallback | null;
|
|
32
|
+
setText(newText?: string, start?: number, length?: number): void;
|
|
33
|
+
setErrorCallback(cb: ErrorCallback | null): void;
|
|
34
|
+
private setTextPos;
|
|
35
|
+
scan(skipTrivia?: boolean): SyntaxKind;
|
|
36
|
+
private error;
|
|
37
|
+
private isWhiteSpaceSingleLine;
|
|
38
|
+
private isAtMultiLineCommentEnd;
|
|
39
|
+
private scanHashCommentTrivia;
|
|
40
|
+
private scanSingleLineCommentTrivia;
|
|
41
|
+
private scanMultiLineCommentTrivia;
|
|
42
|
+
private scanHtml;
|
|
43
|
+
private scanString;
|
|
44
|
+
private scanNumber;
|
|
45
|
+
private getIdentifierToken;
|
|
46
|
+
lookAhead<T extends SyntaxKind>(callback: () => T): T;
|
|
47
|
+
tryScan<T extends SyntaxKind>(callback: () => T): T;
|
|
48
|
+
private speculationHelper;
|
|
49
|
+
}
|
|
50
|
+
export declare function isIdentifierStart(ch: number): boolean;
|
|
51
|
+
export declare function skipTrivia(text: string, pos: number): number;
|
|
52
|
+
export declare function isLineBreak(ch: number): boolean;
|
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
import { createMapFromTemplate } from "./core.js";
|
|
2
|
+
import { SyntaxKind, DiagnosticCategory } from "./types.js";
|
|
3
|
+
import { assertNever } from "./service/util.js";
|
|
4
|
+
const textToToken = createMapFromTemplate({
|
|
5
|
+
"digraph": SyntaxKind.DigraphKeyword,
|
|
6
|
+
"graph": SyntaxKind.GraphKeyword,
|
|
7
|
+
"edge": SyntaxKind.EdgeKeyword,
|
|
8
|
+
"node": SyntaxKind.NodeKeyword,
|
|
9
|
+
"strict": SyntaxKind.StrictKeyword,
|
|
10
|
+
"subgraph": SyntaxKind.SubgraphKeyword,
|
|
11
|
+
"n": SyntaxKind.CompassNorthToken,
|
|
12
|
+
"ne": SyntaxKind.CompassNorthEastToken,
|
|
13
|
+
"e": SyntaxKind.CompassEastToken,
|
|
14
|
+
"se": SyntaxKind.CompassSouthEastToken,
|
|
15
|
+
"s": SyntaxKind.CompassSouthToken,
|
|
16
|
+
"sw": SyntaxKind.CompassSouthWestToken,
|
|
17
|
+
"w": SyntaxKind.CompassWestToken,
|
|
18
|
+
"nw": SyntaxKind.CompassNorthWestToken,
|
|
19
|
+
"c": SyntaxKind.CompassCenterToken,
|
|
20
|
+
"+": SyntaxKind.PlusToken,
|
|
21
|
+
"=": SyntaxKind.EqualsToken,
|
|
22
|
+
"->": SyntaxKind.DirectedEdgeOp,
|
|
23
|
+
"--": SyntaxKind.UndirectedEdgeOp,
|
|
24
|
+
"{": SyntaxKind.OpenBraceToken,
|
|
25
|
+
"}": SyntaxKind.CloseBraceToken,
|
|
26
|
+
"[": SyntaxKind.OpenBracketToken,
|
|
27
|
+
"]": SyntaxKind.CloseBracketToken,
|
|
28
|
+
";": SyntaxKind.SemicolonToken,
|
|
29
|
+
":": SyntaxKind.ColonToken,
|
|
30
|
+
"_": SyntaxKind.UnderscoreToken,
|
|
31
|
+
",": SyntaxKind.CommaToken,
|
|
32
|
+
"<": SyntaxKind.LessThan,
|
|
33
|
+
">": SyntaxKind.GreaterThan,
|
|
34
|
+
});
|
|
35
|
+
function makeReverseMap(source) {
|
|
36
|
+
const result = new Map();
|
|
37
|
+
source.forEach((value, key) => {
|
|
38
|
+
result.set(value, key);
|
|
39
|
+
});
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
const tokenToText = makeReverseMap(textToToken);
|
|
43
|
+
export function getTokenAsText(token) {
|
|
44
|
+
return tokenToText.get(token);
|
|
45
|
+
}
|
|
46
|
+
export function getTextAsToken(token) {
|
|
47
|
+
return textToToken.get(token);
|
|
48
|
+
}
|
|
49
|
+
export class DefaultScanner {
|
|
50
|
+
end;
|
|
51
|
+
pos;
|
|
52
|
+
startPos;
|
|
53
|
+
tokenPos;
|
|
54
|
+
token;
|
|
55
|
+
tokenValue;
|
|
56
|
+
tokenFlags;
|
|
57
|
+
isUnterminated;
|
|
58
|
+
text;
|
|
59
|
+
onError;
|
|
60
|
+
setText(newText, start = 0, length) {
|
|
61
|
+
this.text = newText || "";
|
|
62
|
+
this.end = length === undefined ? this.text.length : start + length;
|
|
63
|
+
this.setTextPos(start || 0);
|
|
64
|
+
}
|
|
65
|
+
setErrorCallback(cb) {
|
|
66
|
+
this.onError = cb;
|
|
67
|
+
}
|
|
68
|
+
setTextPos(textPos) {
|
|
69
|
+
console.assert(textPos >= 0);
|
|
70
|
+
this.pos = textPos;
|
|
71
|
+
this.startPos = textPos;
|
|
72
|
+
this.tokenPos = textPos;
|
|
73
|
+
this.token = SyntaxKind.Unknown;
|
|
74
|
+
this.tokenValue = undefined;
|
|
75
|
+
this.tokenFlags = 0;
|
|
76
|
+
}
|
|
77
|
+
scan(skipTrivia = true) {
|
|
78
|
+
this.startPos = this.pos;
|
|
79
|
+
this.tokenFlags = 0;
|
|
80
|
+
this.isUnterminated = false;
|
|
81
|
+
while (true) {
|
|
82
|
+
this.tokenPos = this.pos;
|
|
83
|
+
if (this.pos >= this.end) {
|
|
84
|
+
return this.token = SyntaxKind.EndOfFileToken;
|
|
85
|
+
}
|
|
86
|
+
let ch = this.text.charCodeAt(this.pos);
|
|
87
|
+
switch (ch) {
|
|
88
|
+
case 10:
|
|
89
|
+
case 13:
|
|
90
|
+
this.tokenFlags |= 4;
|
|
91
|
+
if (skipTrivia) {
|
|
92
|
+
this.pos++;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (ch === 13
|
|
96
|
+
&& this.pos + 1 < this.end
|
|
97
|
+
&& this.text.charCodeAt(this.pos + 1) === 10) {
|
|
98
|
+
this.pos += 2;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.pos++;
|
|
102
|
+
}
|
|
103
|
+
return this.token = SyntaxKind.NewLineTrivia;
|
|
104
|
+
case 9:
|
|
105
|
+
case 11:
|
|
106
|
+
case 12:
|
|
107
|
+
case 32:
|
|
108
|
+
if (skipTrivia) {
|
|
109
|
+
this.pos++;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
while (this.pos < this.end && this.isWhiteSpaceSingleLine(this.text.charCodeAt(this.pos)))
|
|
113
|
+
this.pos++;
|
|
114
|
+
return this.token = SyntaxKind.WhitespaceTrivia;
|
|
115
|
+
case 35: {
|
|
116
|
+
const content = this.scanHashCommentTrivia(skipTrivia);
|
|
117
|
+
if (skipTrivia)
|
|
118
|
+
continue;
|
|
119
|
+
this.tokenValue = content;
|
|
120
|
+
return this.token = SyntaxKind.HashCommentTrivia;
|
|
121
|
+
}
|
|
122
|
+
case 47: {
|
|
123
|
+
if (this.pos + 1 < this.end) {
|
|
124
|
+
const nextChar = this.text.charCodeAt(this.pos + 1);
|
|
125
|
+
switch (nextChar) {
|
|
126
|
+
case 47: {
|
|
127
|
+
const commentContent = this.scanSingleLineCommentTrivia(skipTrivia);
|
|
128
|
+
if (skipTrivia)
|
|
129
|
+
continue;
|
|
130
|
+
this.tokenValue = commentContent;
|
|
131
|
+
return this.token = SyntaxKind.SingleLineCommentTrivia;
|
|
132
|
+
}
|
|
133
|
+
case 42: {
|
|
134
|
+
const commentContent = this.scanMultiLineCommentTrivia(skipTrivia);
|
|
135
|
+
if (skipTrivia)
|
|
136
|
+
continue;
|
|
137
|
+
this.tokenValue = commentContent;
|
|
138
|
+
return this.token = SyntaxKind.MultiLineCommentTrivia;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
this.error('Unexpected "/". Did you mean to start a comment like "/*" or "//"? If you wanted to use it as an identifier, put it in double quotes.', 0);
|
|
143
|
+
++this.pos;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
case 123:
|
|
147
|
+
this.pos++;
|
|
148
|
+
return this.token = SyntaxKind.OpenBraceToken;
|
|
149
|
+
case 125:
|
|
150
|
+
this.pos++;
|
|
151
|
+
return this.token = SyntaxKind.CloseBraceToken;
|
|
152
|
+
case 91:
|
|
153
|
+
this.pos++;
|
|
154
|
+
return this.token = SyntaxKind.OpenBracketToken;
|
|
155
|
+
case 93:
|
|
156
|
+
this.pos++;
|
|
157
|
+
return this.token = SyntaxKind.CloseBracketToken;
|
|
158
|
+
case 43:
|
|
159
|
+
this.pos++;
|
|
160
|
+
return this.token = SyntaxKind.PlusToken;
|
|
161
|
+
case 61:
|
|
162
|
+
this.pos++;
|
|
163
|
+
return this.token = SyntaxKind.EqualsToken;
|
|
164
|
+
case 48:
|
|
165
|
+
case 49:
|
|
166
|
+
case 50:
|
|
167
|
+
case 51:
|
|
168
|
+
case 52:
|
|
169
|
+
case 53:
|
|
170
|
+
case 54:
|
|
171
|
+
case 55:
|
|
172
|
+
case 56:
|
|
173
|
+
case 57:
|
|
174
|
+
case 46:
|
|
175
|
+
this.tokenValue = this.scanNumber();
|
|
176
|
+
return this.token = SyntaxKind.NumericIdentifier;
|
|
177
|
+
case 45: {
|
|
178
|
+
const nextChar = this.text.charCodeAt(this.pos + 1);
|
|
179
|
+
switch (nextChar) {
|
|
180
|
+
case 45:
|
|
181
|
+
return this.pos += 2, this.token = SyntaxKind.UndirectedEdgeOp;
|
|
182
|
+
case 62:
|
|
183
|
+
return this.pos += 2, this.token = SyntaxKind.DirectedEdgeOp;
|
|
184
|
+
case 48:
|
|
185
|
+
case 49:
|
|
186
|
+
case 50:
|
|
187
|
+
case 51:
|
|
188
|
+
case 52:
|
|
189
|
+
case 53:
|
|
190
|
+
case 54:
|
|
191
|
+
case 55:
|
|
192
|
+
case 56:
|
|
193
|
+
case 57:
|
|
194
|
+
case 46:
|
|
195
|
+
this.tokenValue = this.scanNumber();
|
|
196
|
+
return this.token = SyntaxKind.NumericIdentifier;
|
|
197
|
+
default:
|
|
198
|
+
const chr = this.text.charAt(this.pos + 1);
|
|
199
|
+
this.error(`Unexpected "${chr}". Did you mean to define an edge? Depending on the type of graph you are defining, use "->" or "--".`, 0);
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
this.pos++;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
case 95:
|
|
206
|
+
this.pos++;
|
|
207
|
+
return this.token = SyntaxKind.UnderscoreToken;
|
|
208
|
+
case 59:
|
|
209
|
+
this.pos++;
|
|
210
|
+
return this.token = SyntaxKind.SemicolonToken;
|
|
211
|
+
case 58:
|
|
212
|
+
this.pos++;
|
|
213
|
+
return this.token = SyntaxKind.ColonToken;
|
|
214
|
+
case 44:
|
|
215
|
+
this.pos++;
|
|
216
|
+
return this.token = SyntaxKind.CommaToken;
|
|
217
|
+
case 60:
|
|
218
|
+
this.tokenValue = this.scanHtml();
|
|
219
|
+
return this.token = SyntaxKind.HtmlIdentifier;
|
|
220
|
+
case 34:
|
|
221
|
+
this.tokenValue = this.scanString();
|
|
222
|
+
return this.token = SyntaxKind.StringLiteral;
|
|
223
|
+
default:
|
|
224
|
+
{
|
|
225
|
+
if (isIdentifierStart(ch)) {
|
|
226
|
+
this.pos++;
|
|
227
|
+
while (this.pos < this.end && isIdentifierPart(ch = this.text.charCodeAt(this.pos)))
|
|
228
|
+
this.pos++;
|
|
229
|
+
const value = this.text.substring(this.tokenPos, this.pos);
|
|
230
|
+
this.tokenValue = value;
|
|
231
|
+
return this.token = this.getIdentifierToken(value);
|
|
232
|
+
}
|
|
233
|
+
if (this.isWhiteSpaceSingleLine(ch)) {
|
|
234
|
+
this.pos++;
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
const chr = this.text.charAt(this.pos);
|
|
238
|
+
this.error(`Unexpected "${chr}". Did you mean to start an identifier? Node names cannot start with "${chr}".`, 0);
|
|
239
|
+
this.pos++;
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
error(message, sub, category = DiagnosticCategory.Error, errPos = this.pos, length = 0) {
|
|
246
|
+
const cb = this.onError;
|
|
247
|
+
if (cb) {
|
|
248
|
+
const posSave = this.pos;
|
|
249
|
+
this.pos = errPos;
|
|
250
|
+
cb(message, category, sub, length);
|
|
251
|
+
this.pos = posSave;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
isWhiteSpaceSingleLine(ch) {
|
|
255
|
+
return ch === 32 ||
|
|
256
|
+
ch === 9 ||
|
|
257
|
+
ch === 11 ||
|
|
258
|
+
ch === 12 ||
|
|
259
|
+
ch === 160 ||
|
|
260
|
+
ch === 133 ||
|
|
261
|
+
ch === 5760 ||
|
|
262
|
+
ch >= 8192 && ch <= 8203 ||
|
|
263
|
+
ch === 8239 ||
|
|
264
|
+
ch === 8287 ||
|
|
265
|
+
ch === 12288 ||
|
|
266
|
+
ch === 65279;
|
|
267
|
+
}
|
|
268
|
+
isAtMultiLineCommentEnd(pos) {
|
|
269
|
+
return pos + 1 < this.end
|
|
270
|
+
&& this.text.charCodeAt(pos) === 42
|
|
271
|
+
&& this.text.charCodeAt(pos + 1) === 47;
|
|
272
|
+
}
|
|
273
|
+
scanHashCommentTrivia(skip) {
|
|
274
|
+
++this.pos;
|
|
275
|
+
const start = this.pos;
|
|
276
|
+
while (this.pos < this.end && !isLineBreak(this.text.charCodeAt(this.pos)))
|
|
277
|
+
this.pos++;
|
|
278
|
+
return skip ? undefined : this.text.substring(start, this.pos);
|
|
279
|
+
}
|
|
280
|
+
scanSingleLineCommentTrivia(skip) {
|
|
281
|
+
this.pos += 2;
|
|
282
|
+
const start = this.pos;
|
|
283
|
+
while (this.pos < this.end && !isLineBreak(this.text.charCodeAt(this.pos)))
|
|
284
|
+
this.pos++;
|
|
285
|
+
return skip ? undefined : this.text.substring(start, this.pos);
|
|
286
|
+
}
|
|
287
|
+
scanMultiLineCommentTrivia(skip) {
|
|
288
|
+
this.pos += 2;
|
|
289
|
+
const start = this.pos;
|
|
290
|
+
while (this.pos < this.end && !this.isAtMultiLineCommentEnd(this.pos))
|
|
291
|
+
this.pos++;
|
|
292
|
+
const commentEnd = this.pos;
|
|
293
|
+
if (this.isAtMultiLineCommentEnd(this.pos)) {
|
|
294
|
+
this.pos += 2;
|
|
295
|
+
}
|
|
296
|
+
return skip ? undefined : this.text.substring(start, commentEnd);
|
|
297
|
+
}
|
|
298
|
+
scanHtml() {
|
|
299
|
+
const htmlOpen = this.text.charCodeAt(this.pos);
|
|
300
|
+
this.pos++;
|
|
301
|
+
let result = "";
|
|
302
|
+
let start = this.pos;
|
|
303
|
+
let subTagsLevel = 0;
|
|
304
|
+
while (true) {
|
|
305
|
+
if (this.pos >= this.end) {
|
|
306
|
+
result += this.text.substring(start, this.pos);
|
|
307
|
+
this.tokenFlags |= 2;
|
|
308
|
+
this.isUnterminated = true;
|
|
309
|
+
this.error("Unterminated html literal", 1);
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
const ch = this.text.charCodeAt(this.pos);
|
|
313
|
+
if (ch === 60) {
|
|
314
|
+
++subTagsLevel;
|
|
315
|
+
this.pos++;
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
if (ch === 62) {
|
|
319
|
+
this.pos++;
|
|
320
|
+
console.assert(subTagsLevel >= 0);
|
|
321
|
+
if (subTagsLevel === 0) {
|
|
322
|
+
result += this.text.substring(start, this.pos);
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
--subTagsLevel;
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
this.pos++;
|
|
331
|
+
}
|
|
332
|
+
return result;
|
|
333
|
+
}
|
|
334
|
+
scanString(allowEscapes = true) {
|
|
335
|
+
const quote = this.text.charCodeAt(this.pos);
|
|
336
|
+
this.pos++;
|
|
337
|
+
let result = "";
|
|
338
|
+
let start = this.pos;
|
|
339
|
+
let hasBackslash = false;
|
|
340
|
+
while (true) {
|
|
341
|
+
if (this.pos >= this.end) {
|
|
342
|
+
result += this.text.substring(start, this.pos);
|
|
343
|
+
this.tokenFlags |= 2;
|
|
344
|
+
this.isUnterminated = true;
|
|
345
|
+
this.error("Unterminated string", 1);
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
const ch = this.text.charCodeAt(this.pos);
|
|
349
|
+
if (ch === 92) {
|
|
350
|
+
hasBackslash = true;
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
if (hasBackslash) {
|
|
354
|
+
hasBackslash = false;
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
if (ch === quote) {
|
|
358
|
+
result += this.text.substring(start, this.pos);
|
|
359
|
+
this.pos++;
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
362
|
+
else if (isLineBreak(ch)) {
|
|
363
|
+
result += this.text.substring(start, this.pos);
|
|
364
|
+
this.tokenFlags |= 2;
|
|
365
|
+
this.isUnterminated = true;
|
|
366
|
+
this.error("Unterminated string", 1);
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
this.pos++;
|
|
372
|
+
}
|
|
373
|
+
const removedEscapes = result
|
|
374
|
+
.replace(/\\"/g, '"')
|
|
375
|
+
.replace(/\\(\r?\n)/g, '$1');
|
|
376
|
+
return removedEscapes;
|
|
377
|
+
}
|
|
378
|
+
scanNumber() {
|
|
379
|
+
let result = "";
|
|
380
|
+
let hadDot = false;
|
|
381
|
+
let hadMinus = false;
|
|
382
|
+
const start = this.pos;
|
|
383
|
+
while (true) {
|
|
384
|
+
const ch = this.text.charCodeAt(this.pos);
|
|
385
|
+
switch (ch) {
|
|
386
|
+
case 48:
|
|
387
|
+
case 49:
|
|
388
|
+
case 50:
|
|
389
|
+
case 51:
|
|
390
|
+
case 52:
|
|
391
|
+
case 53:
|
|
392
|
+
case 54:
|
|
393
|
+
case 55:
|
|
394
|
+
case 56:
|
|
395
|
+
case 57:
|
|
396
|
+
break;
|
|
397
|
+
case 46:
|
|
398
|
+
if (hadDot) {
|
|
399
|
+
result += this.text.substring(start, this.pos);
|
|
400
|
+
return result;
|
|
401
|
+
}
|
|
402
|
+
hadDot = true;
|
|
403
|
+
hadMinus = true;
|
|
404
|
+
break;
|
|
405
|
+
case 45:
|
|
406
|
+
if (this.pos !== start || hadMinus) {
|
|
407
|
+
result += this.text.substring(start, this.pos);
|
|
408
|
+
return result;
|
|
409
|
+
}
|
|
410
|
+
hadMinus = true;
|
|
411
|
+
break;
|
|
412
|
+
default:
|
|
413
|
+
result += this.text.substring(start, this.pos);
|
|
414
|
+
return result;
|
|
415
|
+
}
|
|
416
|
+
++this.pos;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
getIdentifierToken(tokenValue) {
|
|
420
|
+
const len = tokenValue.length;
|
|
421
|
+
if (len >= 4 && len <= 8) {
|
|
422
|
+
const ch = tokenValue.charCodeAt(0);
|
|
423
|
+
if ((ch >= 97 && ch <= 122)
|
|
424
|
+
|| (ch >= 65 && ch <= 90)) {
|
|
425
|
+
const lowerCaseToken = tokenValue.toLowerCase();
|
|
426
|
+
const t = textToToken.get(lowerCaseToken);
|
|
427
|
+
if (t !== undefined) {
|
|
428
|
+
this.token = t;
|
|
429
|
+
return t;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return this.token = SyntaxKind.TextIdentifier;
|
|
434
|
+
}
|
|
435
|
+
lookAhead(callback) {
|
|
436
|
+
return this.speculationHelper(callback, true);
|
|
437
|
+
}
|
|
438
|
+
tryScan(callback) {
|
|
439
|
+
return this.speculationHelper(callback, false);
|
|
440
|
+
}
|
|
441
|
+
speculationHelper(callback, isLookahead) {
|
|
442
|
+
const savePos = this.pos;
|
|
443
|
+
const saveStartPos = this.startPos;
|
|
444
|
+
const saveTokenPos = this.tokenPos;
|
|
445
|
+
const saveToken = this.token;
|
|
446
|
+
const saveTokenValue = this.tokenValue;
|
|
447
|
+
const saveTokenFlags = this.tokenFlags;
|
|
448
|
+
const result = callback();
|
|
449
|
+
if (!result || isLookahead) {
|
|
450
|
+
this.pos = savePos;
|
|
451
|
+
this.startPos = saveStartPos;
|
|
452
|
+
this.tokenPos = saveTokenPos;
|
|
453
|
+
this.token = saveToken;
|
|
454
|
+
this.tokenValue = saveTokenValue;
|
|
455
|
+
this.tokenFlags = saveTokenFlags;
|
|
456
|
+
}
|
|
457
|
+
return result;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
function isIdentifierPartOf(ch, idType) {
|
|
461
|
+
switch (idType) {
|
|
462
|
+
case SyntaxKind.TextIdentifier:
|
|
463
|
+
return ch === 95
|
|
464
|
+
|| 65 <= ch && ch <= 90
|
|
465
|
+
|| 97 <= ch && ch <= 122
|
|
466
|
+
|| 48 <= ch && ch <= 57;
|
|
467
|
+
case SyntaxKind.HtmlIdentifier:
|
|
468
|
+
return ch === 95
|
|
469
|
+
|| ch === 60
|
|
470
|
+
|| ch === 61
|
|
471
|
+
|| ch === 34
|
|
472
|
+
|| 65 <= ch && ch <= 90
|
|
473
|
+
|| 97 <= ch && ch <= 122
|
|
474
|
+
|| 48 <= ch && ch <= 57;
|
|
475
|
+
case SyntaxKind.StringLiteral:
|
|
476
|
+
return ch === 95
|
|
477
|
+
|| ch === 92
|
|
478
|
+
|| ch === 60
|
|
479
|
+
|| ch === 61
|
|
480
|
+
|| ch === 34
|
|
481
|
+
|| 65 <= ch && ch <= 90
|
|
482
|
+
|| 97 <= ch && ch <= 122
|
|
483
|
+
|| 48 <= ch && ch <= 57;
|
|
484
|
+
case SyntaxKind.NumericIdentifier:
|
|
485
|
+
return ch === 45
|
|
486
|
+
|| ch === 46
|
|
487
|
+
|| 48 <= ch && ch <= 57;
|
|
488
|
+
default: return assertNever(idType);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
function getIdentifierStart(ch) {
|
|
492
|
+
if (ch === 60)
|
|
493
|
+
return SyntaxKind.HtmlIdentifier;
|
|
494
|
+
if (ch === 34)
|
|
495
|
+
return SyntaxKind.StringLiteral;
|
|
496
|
+
if (ch === 95
|
|
497
|
+
|| 65 <= ch && ch <= 90
|
|
498
|
+
|| 97 <= ch && ch <= 122)
|
|
499
|
+
return SyntaxKind.TextIdentifier;
|
|
500
|
+
if (ch === 45
|
|
501
|
+
|| ch === 46
|
|
502
|
+
|| 48 <= ch && ch <= 57)
|
|
503
|
+
return SyntaxKind.NumericIdentifier;
|
|
504
|
+
return undefined;
|
|
505
|
+
}
|
|
506
|
+
export function isIdentifierStart(ch) {
|
|
507
|
+
return ch >= 65 && ch <= 90
|
|
508
|
+
|| ch >= 97 && ch <= 122
|
|
509
|
+
|| ch >= 48 && ch <= 57
|
|
510
|
+
|| ch === 95
|
|
511
|
+
|| ch === 60
|
|
512
|
+
|| ch === 34;
|
|
513
|
+
}
|
|
514
|
+
function isIdentifierPart(ch) {
|
|
515
|
+
return ch >= 65 && ch <= 90
|
|
516
|
+
|| ch >= 97 && ch <= 122
|
|
517
|
+
|| ch >= 48 && ch <= 57
|
|
518
|
+
|| ch === 36
|
|
519
|
+
|| ch === 95
|
|
520
|
+
|| ch > 127;
|
|
521
|
+
}
|
|
522
|
+
export function skipTrivia(text, pos) {
|
|
523
|
+
while (true) {
|
|
524
|
+
const ch = text.charCodeAt(pos);
|
|
525
|
+
switch (ch) {
|
|
526
|
+
case 13:
|
|
527
|
+
if (text.charCodeAt(pos + 1) === 10)
|
|
528
|
+
++pos;
|
|
529
|
+
continue;
|
|
530
|
+
case 10:
|
|
531
|
+
case 9:
|
|
532
|
+
case 11:
|
|
533
|
+
case 12:
|
|
534
|
+
case 32:
|
|
535
|
+
++pos;
|
|
536
|
+
continue;
|
|
537
|
+
case 35: {
|
|
538
|
+
++pos;
|
|
539
|
+
while (pos < text.length) {
|
|
540
|
+
if (isLineBreak(text.charCodeAt(pos)))
|
|
541
|
+
break;
|
|
542
|
+
++pos;
|
|
543
|
+
}
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
546
|
+
case 47:
|
|
547
|
+
if (pos + 1 < text.length) {
|
|
548
|
+
const nextChar = text.charCodeAt(pos + 1);
|
|
549
|
+
switch (nextChar) {
|
|
550
|
+
case 47: {
|
|
551
|
+
pos += 2;
|
|
552
|
+
while (pos < text.length) {
|
|
553
|
+
if (isLineBreak(text.charCodeAt(pos)))
|
|
554
|
+
break;
|
|
555
|
+
++pos;
|
|
556
|
+
}
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
case 42: {
|
|
560
|
+
pos += 2;
|
|
561
|
+
while (pos < text.length) {
|
|
562
|
+
if (text.charCodeAt(pos) === 42 && text.charCodeAt(pos + 1) === 47) {
|
|
563
|
+
pos += 2;
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
++pos;
|
|
567
|
+
}
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
break;
|
|
573
|
+
}
|
|
574
|
+
return pos;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
export function isLineBreak(ch) {
|
|
578
|
+
return ch === 10
|
|
579
|
+
|| ch === 13;
|
|
580
|
+
}
|
|
581
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type * as lst from "vscode-languageserver-types";
|
|
2
|
+
import { DocumentLike, SourceFile, CommandApplication } from "../index.js";
|
|
3
|
+
import { ExecutableCommand } from "./command/common.js";
|
|
4
|
+
export declare function getCodeActions(doc: DocumentLike, sourceFile: SourceFile, range: lst.Range, _context?: lst.CodeActionContext): lst.Command[] | undefined;
|
|
5
|
+
export declare const enum CommandIds {
|
|
6
|
+
ChangeEdgeOp = "DOT.changeEdgeOp",
|
|
7
|
+
ConvertGraphType = "DOT.convertGraphType",
|
|
8
|
+
ConsolidateDescendants = "DOT.consolidateDescendants",
|
|
9
|
+
RemoveSemicolons = "DOT.removeSemicolons"
|
|
10
|
+
}
|
|
11
|
+
export declare function getAvailableCommands(): string[];
|
|
12
|
+
export declare function executeCommand(doc: DocumentLike, sourceFile: SourceFile, cmd: ExecutableCommand): CommandApplication | undefined;
|