@coze-editor/parser-json 0.1.0-alpha.0fd19e
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/LICENSE +21 -0
- package/dist/esm/index.js +778 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.mts +108 -0
- package/dist/index.d.ts +108 -0
- package/dist/index.js +816 -0
- package/dist/index.js.map +1 -0
- package/package.json +42 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,816 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
|
|
29
|
+
// src/index.ts
|
|
30
|
+
var index_exports = {};
|
|
31
|
+
__export(index_exports, {
|
|
32
|
+
ErrorCode: () => ErrorCode,
|
|
33
|
+
findNodeAtOffset: () => findNodeAtOffset,
|
|
34
|
+
parse: () => parse
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(index_exports);
|
|
37
|
+
|
|
38
|
+
// src/parser.ts
|
|
39
|
+
var import_vscode_languageserver_types = require("vscode-languageserver-types");
|
|
40
|
+
var l10n = __toESM(require("@vscode/l10n"));
|
|
41
|
+
|
|
42
|
+
// src/scanner.ts
|
|
43
|
+
function createScanner(text, ignoreTrivia = false) {
|
|
44
|
+
const len = text.length;
|
|
45
|
+
let pos = 0, value = "", tokenOffset = 0, token = 16 /* Unknown */, lineNumber = 0, lineStartOffset = 0, tokenLineStartOffset = 0, prevTokenLineStartOffset = 0, scanError = 0 /* None */;
|
|
46
|
+
function scanHexDigits(count, exact) {
|
|
47
|
+
let digits = 0;
|
|
48
|
+
let value2 = 0;
|
|
49
|
+
while (digits < count || !exact) {
|
|
50
|
+
const ch = text.charCodeAt(pos);
|
|
51
|
+
if (ch >= 48 /* _0 */ && ch <= 57 /* _9 */) {
|
|
52
|
+
value2 = value2 * 16 + ch - 48 /* _0 */;
|
|
53
|
+
} else if (ch >= 65 /* A */ && ch <= 70 /* F */) {
|
|
54
|
+
value2 = value2 * 16 + ch - 65 /* A */ + 10;
|
|
55
|
+
} else if (ch >= 97 /* a */ && ch <= 102 /* f */) {
|
|
56
|
+
value2 = value2 * 16 + ch - 97 /* a */ + 10;
|
|
57
|
+
} else {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
pos++;
|
|
61
|
+
digits++;
|
|
62
|
+
}
|
|
63
|
+
if (digits < count) {
|
|
64
|
+
value2 = -1;
|
|
65
|
+
}
|
|
66
|
+
return value2;
|
|
67
|
+
}
|
|
68
|
+
function setPosition(newPosition) {
|
|
69
|
+
pos = newPosition;
|
|
70
|
+
value = "";
|
|
71
|
+
tokenOffset = 0;
|
|
72
|
+
token = 16 /* Unknown */;
|
|
73
|
+
scanError = 0 /* None */;
|
|
74
|
+
}
|
|
75
|
+
function scanNumber() {
|
|
76
|
+
const start = pos;
|
|
77
|
+
if (text.charCodeAt(pos) === 48 /* _0 */) {
|
|
78
|
+
pos++;
|
|
79
|
+
} else {
|
|
80
|
+
pos++;
|
|
81
|
+
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
82
|
+
pos++;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (pos < text.length && text.charCodeAt(pos) === 46 /* dot */) {
|
|
86
|
+
pos++;
|
|
87
|
+
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
88
|
+
pos++;
|
|
89
|
+
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
90
|
+
pos++;
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
scanError = 3 /* UnexpectedEndOfNumber */;
|
|
94
|
+
return text.substring(start, pos);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
let end = pos;
|
|
98
|
+
if (pos < text.length && (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */)) {
|
|
99
|
+
pos++;
|
|
100
|
+
if (pos < text.length && text.charCodeAt(pos) === 43 /* plus */ || text.charCodeAt(pos) === 45 /* minus */) {
|
|
101
|
+
pos++;
|
|
102
|
+
}
|
|
103
|
+
if (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
104
|
+
pos++;
|
|
105
|
+
while (pos < text.length && isDigit(text.charCodeAt(pos))) {
|
|
106
|
+
pos++;
|
|
107
|
+
}
|
|
108
|
+
end = pos;
|
|
109
|
+
} else {
|
|
110
|
+
scanError = 3 /* UnexpectedEndOfNumber */;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return text.substring(start, end);
|
|
114
|
+
}
|
|
115
|
+
function scanString(endQuote) {
|
|
116
|
+
let result = "", start = pos;
|
|
117
|
+
while (true) {
|
|
118
|
+
if (pos >= len) {
|
|
119
|
+
result += text.substring(start, pos);
|
|
120
|
+
scanError = 2 /* UnexpectedEndOfString */;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
const ch = text.charCodeAt(pos);
|
|
124
|
+
if (ch === endQuote) {
|
|
125
|
+
result += text.substring(start, pos);
|
|
126
|
+
pos++;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
if (ch === 92 /* backslash */) {
|
|
130
|
+
result += text.substring(start, pos);
|
|
131
|
+
pos++;
|
|
132
|
+
if (pos >= len) {
|
|
133
|
+
scanError = 2 /* UnexpectedEndOfString */;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
const ch2 = text.charCodeAt(pos++);
|
|
137
|
+
switch (ch2) {
|
|
138
|
+
case 34 /* doubleQuote */:
|
|
139
|
+
result += '"';
|
|
140
|
+
break;
|
|
141
|
+
case 39 /* singleQuote */:
|
|
142
|
+
result += `'`;
|
|
143
|
+
break;
|
|
144
|
+
case 92 /* backslash */:
|
|
145
|
+
result += "\\";
|
|
146
|
+
break;
|
|
147
|
+
case 47 /* slash */:
|
|
148
|
+
result += "/";
|
|
149
|
+
break;
|
|
150
|
+
case 98 /* b */:
|
|
151
|
+
result += "\b";
|
|
152
|
+
break;
|
|
153
|
+
case 102 /* f */:
|
|
154
|
+
result += "\f";
|
|
155
|
+
break;
|
|
156
|
+
case 110 /* n */:
|
|
157
|
+
result += "\n";
|
|
158
|
+
break;
|
|
159
|
+
case 114 /* r */:
|
|
160
|
+
result += "\r";
|
|
161
|
+
break;
|
|
162
|
+
case 116 /* t */:
|
|
163
|
+
result += " ";
|
|
164
|
+
break;
|
|
165
|
+
case 117 /* u */:
|
|
166
|
+
const ch3 = scanHexDigits(4, true);
|
|
167
|
+
if (ch3 >= 0) {
|
|
168
|
+
result += String.fromCharCode(ch3);
|
|
169
|
+
} else {
|
|
170
|
+
scanError = 4 /* InvalidUnicode */;
|
|
171
|
+
}
|
|
172
|
+
break;
|
|
173
|
+
default:
|
|
174
|
+
scanError = 5 /* InvalidEscapeCharacter */;
|
|
175
|
+
}
|
|
176
|
+
start = pos;
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (ch >= 0 && ch <= 31) {
|
|
180
|
+
if (isLineBreak(ch)) {
|
|
181
|
+
result += text.substring(start, pos);
|
|
182
|
+
scanError = 2 /* UnexpectedEndOfString */;
|
|
183
|
+
break;
|
|
184
|
+
} else {
|
|
185
|
+
scanError = 6 /* InvalidCharacter */;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
pos++;
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
function scanNext() {
|
|
193
|
+
value = "";
|
|
194
|
+
scanError = 0 /* None */;
|
|
195
|
+
tokenOffset = pos;
|
|
196
|
+
lineStartOffset = lineNumber;
|
|
197
|
+
prevTokenLineStartOffset = tokenLineStartOffset;
|
|
198
|
+
if (pos >= len) {
|
|
199
|
+
tokenOffset = len;
|
|
200
|
+
return token = 17 /* EOF */;
|
|
201
|
+
}
|
|
202
|
+
let code = text.charCodeAt(pos);
|
|
203
|
+
if (isWhiteSpace(code)) {
|
|
204
|
+
do {
|
|
205
|
+
pos++;
|
|
206
|
+
value += String.fromCharCode(code);
|
|
207
|
+
code = text.charCodeAt(pos);
|
|
208
|
+
} while (isWhiteSpace(code));
|
|
209
|
+
return token = 15 /* Trivia */;
|
|
210
|
+
}
|
|
211
|
+
if (isLineBreak(code)) {
|
|
212
|
+
pos++;
|
|
213
|
+
value += String.fromCharCode(code);
|
|
214
|
+
if (code === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) {
|
|
215
|
+
pos++;
|
|
216
|
+
value += "\n";
|
|
217
|
+
}
|
|
218
|
+
lineNumber++;
|
|
219
|
+
tokenLineStartOffset = pos;
|
|
220
|
+
return token = 14 /* LineBreakTrivia */;
|
|
221
|
+
}
|
|
222
|
+
switch (code) {
|
|
223
|
+
// tokens: []{}:,
|
|
224
|
+
case 123 /* openBrace */:
|
|
225
|
+
pos++;
|
|
226
|
+
return token = 1 /* OpenBraceToken */;
|
|
227
|
+
case 125 /* closeBrace */:
|
|
228
|
+
pos++;
|
|
229
|
+
return token = 2 /* CloseBraceToken */;
|
|
230
|
+
case 91 /* openBracket */:
|
|
231
|
+
pos++;
|
|
232
|
+
return token = 3 /* OpenBracketToken */;
|
|
233
|
+
case 93 /* closeBracket */:
|
|
234
|
+
pos++;
|
|
235
|
+
return token = 4 /* CloseBracketToken */;
|
|
236
|
+
case 58 /* colon */:
|
|
237
|
+
pos++;
|
|
238
|
+
return token = 6 /* ColonToken */;
|
|
239
|
+
case 44 /* comma */:
|
|
240
|
+
pos++;
|
|
241
|
+
return token = 5 /* CommaToken */;
|
|
242
|
+
// strings
|
|
243
|
+
case 34 /* doubleQuote */:
|
|
244
|
+
pos++;
|
|
245
|
+
value = scanString(34 /* doubleQuote */);
|
|
246
|
+
return token = 19 /* DoubleQuoteStringLiteral */;
|
|
247
|
+
case 39 /* singleQuote */:
|
|
248
|
+
pos++;
|
|
249
|
+
value = scanString(39 /* singleQuote */);
|
|
250
|
+
return token = 18 /* SingleQuoteStringLiteral */;
|
|
251
|
+
// comments
|
|
252
|
+
case 47 /* slash */:
|
|
253
|
+
const start = pos - 1;
|
|
254
|
+
if (text.charCodeAt(pos + 1) === 47 /* slash */) {
|
|
255
|
+
pos += 2;
|
|
256
|
+
while (pos < len) {
|
|
257
|
+
if (isLineBreak(text.charCodeAt(pos))) {
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
pos++;
|
|
261
|
+
}
|
|
262
|
+
value = text.substring(start, pos);
|
|
263
|
+
return token = 12 /* LineCommentTrivia */;
|
|
264
|
+
}
|
|
265
|
+
if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
|
|
266
|
+
pos += 2;
|
|
267
|
+
const safeLength = len - 1;
|
|
268
|
+
let commentClosed = false;
|
|
269
|
+
while (pos < safeLength) {
|
|
270
|
+
const ch = text.charCodeAt(pos);
|
|
271
|
+
if (ch === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
|
|
272
|
+
pos += 2;
|
|
273
|
+
commentClosed = true;
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
pos++;
|
|
277
|
+
if (isLineBreak(ch)) {
|
|
278
|
+
if (ch === 13 /* carriageReturn */ && text.charCodeAt(pos) === 10 /* lineFeed */) {
|
|
279
|
+
pos++;
|
|
280
|
+
}
|
|
281
|
+
lineNumber++;
|
|
282
|
+
tokenLineStartOffset = pos;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
if (!commentClosed) {
|
|
286
|
+
pos++;
|
|
287
|
+
scanError = 1 /* UnexpectedEndOfComment */;
|
|
288
|
+
}
|
|
289
|
+
value = text.substring(start, pos);
|
|
290
|
+
return token = 13 /* BlockCommentTrivia */;
|
|
291
|
+
}
|
|
292
|
+
value += String.fromCharCode(code);
|
|
293
|
+
pos++;
|
|
294
|
+
return token = 16 /* Unknown */;
|
|
295
|
+
// numbers
|
|
296
|
+
// @ts-ignore
|
|
297
|
+
case 45 /* minus */:
|
|
298
|
+
value += String.fromCharCode(code);
|
|
299
|
+
pos++;
|
|
300
|
+
if (pos === len || !isDigit(text.charCodeAt(pos))) {
|
|
301
|
+
return token = 16 /* Unknown */;
|
|
302
|
+
}
|
|
303
|
+
// found a minus, followed by a number so
|
|
304
|
+
// we fall through to proceed with scanning
|
|
305
|
+
// numbers
|
|
306
|
+
case 48 /* _0 */:
|
|
307
|
+
case 49 /* _1 */:
|
|
308
|
+
case 50 /* _2 */:
|
|
309
|
+
case 51 /* _3 */:
|
|
310
|
+
case 52 /* _4 */:
|
|
311
|
+
case 53 /* _5 */:
|
|
312
|
+
case 54 /* _6 */:
|
|
313
|
+
case 55 /* _7 */:
|
|
314
|
+
case 56 /* _8 */:
|
|
315
|
+
case 57 /* _9 */:
|
|
316
|
+
value += scanNumber();
|
|
317
|
+
return token = 11 /* NumericLiteral */;
|
|
318
|
+
// literals and unknown symbols
|
|
319
|
+
default:
|
|
320
|
+
while (pos < len && isUnknownContentCharacter(code)) {
|
|
321
|
+
pos++;
|
|
322
|
+
code = text.charCodeAt(pos);
|
|
323
|
+
}
|
|
324
|
+
if (tokenOffset !== pos) {
|
|
325
|
+
value = text.substring(tokenOffset, pos);
|
|
326
|
+
switch (value) {
|
|
327
|
+
case "true":
|
|
328
|
+
return token = 8 /* TrueKeyword */;
|
|
329
|
+
case "false":
|
|
330
|
+
return token = 9 /* FalseKeyword */;
|
|
331
|
+
case "null":
|
|
332
|
+
return token = 7 /* NullKeyword */;
|
|
333
|
+
}
|
|
334
|
+
return token = 16 /* Unknown */;
|
|
335
|
+
}
|
|
336
|
+
value += String.fromCharCode(code);
|
|
337
|
+
pos++;
|
|
338
|
+
return token = 16 /* Unknown */;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
function isUnknownContentCharacter(code) {
|
|
342
|
+
if (isWhiteSpace(code) || isLineBreak(code)) {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
switch (code) {
|
|
346
|
+
case 125 /* closeBrace */:
|
|
347
|
+
case 93 /* closeBracket */:
|
|
348
|
+
case 123 /* openBrace */:
|
|
349
|
+
case 91 /* openBracket */:
|
|
350
|
+
case 34 /* doubleQuote */:
|
|
351
|
+
case 58 /* colon */:
|
|
352
|
+
case 44 /* comma */:
|
|
353
|
+
case 47 /* slash */:
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
return true;
|
|
357
|
+
}
|
|
358
|
+
function scanNextNonTrivia() {
|
|
359
|
+
let result;
|
|
360
|
+
do {
|
|
361
|
+
result = scanNext();
|
|
362
|
+
} while (result >= 12 /* LineCommentTrivia */ && result <= 15 /* Trivia */);
|
|
363
|
+
return result;
|
|
364
|
+
}
|
|
365
|
+
return {
|
|
366
|
+
setPosition,
|
|
367
|
+
getPosition: () => pos,
|
|
368
|
+
scan: ignoreTrivia ? scanNextNonTrivia : scanNext,
|
|
369
|
+
getToken: () => token,
|
|
370
|
+
getTokenValue: () => value,
|
|
371
|
+
getTokenOffset: () => tokenOffset,
|
|
372
|
+
getTokenLength: () => pos - tokenOffset,
|
|
373
|
+
getTokenStartLine: () => lineStartOffset,
|
|
374
|
+
getTokenStartCharacter: () => tokenOffset - prevTokenLineStartOffset,
|
|
375
|
+
getTokenError: () => scanError
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
function isWhiteSpace(ch) {
|
|
379
|
+
return ch === 32 /* space */ || ch === 9 /* tab */;
|
|
380
|
+
}
|
|
381
|
+
function isLineBreak(ch) {
|
|
382
|
+
return ch === 10 /* lineFeed */ || ch === 13 /* carriageReturn */;
|
|
383
|
+
}
|
|
384
|
+
function isDigit(ch) {
|
|
385
|
+
return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// src/is.ts
|
|
389
|
+
function isNumber(val) {
|
|
390
|
+
return typeof val === "number";
|
|
391
|
+
}
|
|
392
|
+
function isObject(val) {
|
|
393
|
+
return typeof val === "object" && val !== null && !Array.isArray(val);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// src/types.ts
|
|
397
|
+
var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
|
|
398
|
+
ErrorCode2[ErrorCode2["Undefined"] = 0] = "Undefined";
|
|
399
|
+
ErrorCode2[ErrorCode2["EnumValueMismatch"] = 1] = "EnumValueMismatch";
|
|
400
|
+
ErrorCode2[ErrorCode2["Deprecated"] = 2] = "Deprecated";
|
|
401
|
+
ErrorCode2[ErrorCode2["UnexpectedEndOfComment"] = 257] = "UnexpectedEndOfComment";
|
|
402
|
+
ErrorCode2[ErrorCode2["UnexpectedEndOfString"] = 258] = "UnexpectedEndOfString";
|
|
403
|
+
ErrorCode2[ErrorCode2["UnexpectedEndOfNumber"] = 259] = "UnexpectedEndOfNumber";
|
|
404
|
+
ErrorCode2[ErrorCode2["InvalidUnicode"] = 260] = "InvalidUnicode";
|
|
405
|
+
ErrorCode2[ErrorCode2["InvalidEscapeCharacter"] = 261] = "InvalidEscapeCharacter";
|
|
406
|
+
ErrorCode2[ErrorCode2["InvalidCharacter"] = 262] = "InvalidCharacter";
|
|
407
|
+
ErrorCode2[ErrorCode2["PropertyExpected"] = 513] = "PropertyExpected";
|
|
408
|
+
ErrorCode2[ErrorCode2["CommaExpected"] = 514] = "CommaExpected";
|
|
409
|
+
ErrorCode2[ErrorCode2["ColonExpected"] = 515] = "ColonExpected";
|
|
410
|
+
ErrorCode2[ErrorCode2["ValueExpected"] = 516] = "ValueExpected";
|
|
411
|
+
ErrorCode2[ErrorCode2["CommaOrCloseBacketExpected"] = 517] = "CommaOrCloseBacketExpected";
|
|
412
|
+
ErrorCode2[ErrorCode2["CommaOrCloseBraceExpected"] = 518] = "CommaOrCloseBraceExpected";
|
|
413
|
+
ErrorCode2[ErrorCode2["TrailingComma"] = 519] = "TrailingComma";
|
|
414
|
+
ErrorCode2[ErrorCode2["DuplicateKey"] = 520] = "DuplicateKey";
|
|
415
|
+
ErrorCode2[ErrorCode2["CommentNotPermitted"] = 521] = "CommentNotPermitted";
|
|
416
|
+
ErrorCode2[ErrorCode2["PropertyKeysMustBeDoublequoted"] = 528] = "PropertyKeysMustBeDoublequoted";
|
|
417
|
+
ErrorCode2[ErrorCode2["StringValueMustBeDoublequoted"] = 529] = "StringValueMustBeDoublequoted";
|
|
418
|
+
ErrorCode2[ErrorCode2["SchemaResolveError"] = 768] = "SchemaResolveError";
|
|
419
|
+
ErrorCode2[ErrorCode2["SchemaUnsupportedFeature"] = 769] = "SchemaUnsupportedFeature";
|
|
420
|
+
return ErrorCode2;
|
|
421
|
+
})(ErrorCode || {});
|
|
422
|
+
|
|
423
|
+
// src/parser.ts
|
|
424
|
+
var ASTNodeImpl = class {
|
|
425
|
+
offset;
|
|
426
|
+
length;
|
|
427
|
+
parent;
|
|
428
|
+
constructor(parent, offset, length = 0) {
|
|
429
|
+
this.offset = offset;
|
|
430
|
+
this.length = length;
|
|
431
|
+
this.parent = parent;
|
|
432
|
+
}
|
|
433
|
+
get children() {
|
|
434
|
+
return [];
|
|
435
|
+
}
|
|
436
|
+
toString() {
|
|
437
|
+
return "type: " + this.type + " (" + this.offset + "/" + this.length + ")" + (this.parent ? " parent: {" + this.parent.toString() + "}" : "");
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
var NullASTNodeImpl = class extends ASTNodeImpl {
|
|
441
|
+
type = "null";
|
|
442
|
+
value = null;
|
|
443
|
+
constructor(parent, offset) {
|
|
444
|
+
super(parent, offset);
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
var BooleanASTNodeImpl = class extends ASTNodeImpl {
|
|
448
|
+
type = "boolean";
|
|
449
|
+
value;
|
|
450
|
+
constructor(parent, boolValue, offset) {
|
|
451
|
+
super(parent, offset);
|
|
452
|
+
this.value = boolValue;
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
var ArrayASTNodeImpl = class extends ASTNodeImpl {
|
|
456
|
+
type = "array";
|
|
457
|
+
items;
|
|
458
|
+
constructor(parent, offset) {
|
|
459
|
+
super(parent, offset);
|
|
460
|
+
this.items = [];
|
|
461
|
+
}
|
|
462
|
+
get children() {
|
|
463
|
+
return this.items;
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
var NumberASTNodeImpl = class extends ASTNodeImpl {
|
|
467
|
+
type = "number";
|
|
468
|
+
isInteger;
|
|
469
|
+
value;
|
|
470
|
+
constructor(parent, offset) {
|
|
471
|
+
super(parent, offset);
|
|
472
|
+
this.isInteger = true;
|
|
473
|
+
this.value = Number.NaN;
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
var StringASTNodeImpl = class extends ASTNodeImpl {
|
|
477
|
+
type = "string";
|
|
478
|
+
value;
|
|
479
|
+
constructor(parent, offset, length) {
|
|
480
|
+
super(parent, offset, length);
|
|
481
|
+
this.value = "";
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
var PropertyASTNodeImpl = class extends ASTNodeImpl {
|
|
485
|
+
type = "property";
|
|
486
|
+
keyNode;
|
|
487
|
+
valueNode;
|
|
488
|
+
colonOffset;
|
|
489
|
+
constructor(parent, offset, keyNode) {
|
|
490
|
+
super(parent, offset);
|
|
491
|
+
this.colonOffset = -1;
|
|
492
|
+
this.keyNode = keyNode;
|
|
493
|
+
}
|
|
494
|
+
get children() {
|
|
495
|
+
return this.valueNode ? [this.keyNode, this.valueNode] : [this.keyNode];
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
var ObjectASTNodeImpl = class extends ASTNodeImpl {
|
|
499
|
+
type = "object";
|
|
500
|
+
properties;
|
|
501
|
+
constructor(parent, offset) {
|
|
502
|
+
super(parent, offset);
|
|
503
|
+
this.properties = [];
|
|
504
|
+
}
|
|
505
|
+
get children() {
|
|
506
|
+
return this.properties;
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
function parse(textDocument, config) {
|
|
510
|
+
const problems = [];
|
|
511
|
+
let lastProblemOffset = -1;
|
|
512
|
+
const text = textDocument.getText();
|
|
513
|
+
const scanner = createScanner(text, false);
|
|
514
|
+
const commentRanges = config && config.collectComments ? [] : void 0;
|
|
515
|
+
function _scanNext() {
|
|
516
|
+
while (true) {
|
|
517
|
+
const token2 = scanner.scan();
|
|
518
|
+
_checkScanError();
|
|
519
|
+
switch (token2) {
|
|
520
|
+
case 12 /* LineCommentTrivia */:
|
|
521
|
+
case 13 /* BlockCommentTrivia */:
|
|
522
|
+
if (Array.isArray(commentRanges)) {
|
|
523
|
+
commentRanges.push(import_vscode_languageserver_types.Range.create(textDocument.positionAt(scanner.getTokenOffset()), textDocument.positionAt(scanner.getTokenOffset() + scanner.getTokenLength())));
|
|
524
|
+
}
|
|
525
|
+
break;
|
|
526
|
+
case 15 /* Trivia */:
|
|
527
|
+
case 14 /* LineBreakTrivia */:
|
|
528
|
+
break;
|
|
529
|
+
default:
|
|
530
|
+
return token2;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
function _accept(token2) {
|
|
535
|
+
if (scanner.getToken() === token2) {
|
|
536
|
+
_scanNext();
|
|
537
|
+
return true;
|
|
538
|
+
}
|
|
539
|
+
return false;
|
|
540
|
+
}
|
|
541
|
+
function _errorAtRange(message, code, startOffset, endOffset, severity = import_vscode_languageserver_types.DiagnosticSeverity.Error) {
|
|
542
|
+
if (problems.length === 0 || startOffset !== lastProblemOffset) {
|
|
543
|
+
const range = import_vscode_languageserver_types.Range.create(textDocument.positionAt(startOffset), textDocument.positionAt(endOffset));
|
|
544
|
+
problems.push(import_vscode_languageserver_types.Diagnostic.create(range, message, severity, code, textDocument.languageId));
|
|
545
|
+
lastProblemOffset = startOffset;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
function _error(message, code, node = void 0, skipUntilAfter = [], skipUntil = []) {
|
|
549
|
+
let start = scanner.getTokenOffset();
|
|
550
|
+
let end = scanner.getTokenOffset() + scanner.getTokenLength();
|
|
551
|
+
if (start === end && start > 0) {
|
|
552
|
+
start--;
|
|
553
|
+
while (start > 0 && /\s/.test(text.charAt(start))) {
|
|
554
|
+
start--;
|
|
555
|
+
}
|
|
556
|
+
end = start + 1;
|
|
557
|
+
}
|
|
558
|
+
_errorAtRange(message, code, start, end);
|
|
559
|
+
if (node) {
|
|
560
|
+
_finalize(node, false);
|
|
561
|
+
}
|
|
562
|
+
if (skipUntilAfter.length + skipUntil.length > 0) {
|
|
563
|
+
let token2 = scanner.getToken();
|
|
564
|
+
while (token2 !== 17 /* EOF */) {
|
|
565
|
+
if (skipUntilAfter.indexOf(token2) !== -1) {
|
|
566
|
+
_scanNext();
|
|
567
|
+
break;
|
|
568
|
+
} else if (skipUntil.indexOf(token2) !== -1) {
|
|
569
|
+
break;
|
|
570
|
+
}
|
|
571
|
+
token2 = _scanNext();
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
return node;
|
|
575
|
+
}
|
|
576
|
+
function _checkScanError() {
|
|
577
|
+
switch (scanner.getTokenError()) {
|
|
578
|
+
case 4 /* InvalidUnicode */:
|
|
579
|
+
_error(l10n.t("Invalid unicode sequence in string."), 260 /* InvalidUnicode */);
|
|
580
|
+
return true;
|
|
581
|
+
case 5 /* InvalidEscapeCharacter */:
|
|
582
|
+
_error(l10n.t("Invalid escape character in string."), 261 /* InvalidEscapeCharacter */);
|
|
583
|
+
return true;
|
|
584
|
+
case 3 /* UnexpectedEndOfNumber */:
|
|
585
|
+
_error(l10n.t("Unexpected end of number."), 259 /* UnexpectedEndOfNumber */);
|
|
586
|
+
return true;
|
|
587
|
+
case 1 /* UnexpectedEndOfComment */:
|
|
588
|
+
_error(l10n.t("Unexpected end of comment."), 257 /* UnexpectedEndOfComment */);
|
|
589
|
+
return true;
|
|
590
|
+
case 2 /* UnexpectedEndOfString */:
|
|
591
|
+
_error(l10n.t("Unexpected end of string."), 258 /* UnexpectedEndOfString */);
|
|
592
|
+
return true;
|
|
593
|
+
case 6 /* InvalidCharacter */:
|
|
594
|
+
_error(l10n.t("Invalid characters in string. Control characters must be escaped."), 262 /* InvalidCharacter */);
|
|
595
|
+
return true;
|
|
596
|
+
}
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
599
|
+
function _finalize(node, scanNext) {
|
|
600
|
+
node.length = scanner.getTokenOffset() + scanner.getTokenLength() - node.offset;
|
|
601
|
+
if (scanNext) {
|
|
602
|
+
_scanNext();
|
|
603
|
+
}
|
|
604
|
+
return node;
|
|
605
|
+
}
|
|
606
|
+
function _parseArray(parent) {
|
|
607
|
+
if (scanner.getToken() !== 3 /* OpenBracketToken */) {
|
|
608
|
+
return void 0;
|
|
609
|
+
}
|
|
610
|
+
const node = new ArrayASTNodeImpl(parent, scanner.getTokenOffset());
|
|
611
|
+
_scanNext();
|
|
612
|
+
const count = 0;
|
|
613
|
+
let needsComma = false;
|
|
614
|
+
while (scanner.getToken() !== 4 /* CloseBracketToken */ && scanner.getToken() !== 17 /* EOF */) {
|
|
615
|
+
if (scanner.getToken() === 5 /* CommaToken */) {
|
|
616
|
+
if (!needsComma) {
|
|
617
|
+
_error(l10n.t("Value expected"), 516 /* ValueExpected */);
|
|
618
|
+
}
|
|
619
|
+
const commaOffset = scanner.getTokenOffset();
|
|
620
|
+
_scanNext();
|
|
621
|
+
if (scanner.getToken() === 4 /* CloseBracketToken */) {
|
|
622
|
+
if (needsComma) {
|
|
623
|
+
_errorAtRange(l10n.t("Trailing comma"), 519 /* TrailingComma */, commaOffset, commaOffset + 1);
|
|
624
|
+
}
|
|
625
|
+
continue;
|
|
626
|
+
}
|
|
627
|
+
} else if (needsComma) {
|
|
628
|
+
_error(l10n.t("Expected comma"), 514 /* CommaExpected */);
|
|
629
|
+
}
|
|
630
|
+
const item = _parseValue(node);
|
|
631
|
+
if (!item) {
|
|
632
|
+
_error(l10n.t("Value expected"), 516 /* ValueExpected */, void 0, [], [4 /* CloseBracketToken */, 5 /* CommaToken */]);
|
|
633
|
+
} else {
|
|
634
|
+
node.items.push(item);
|
|
635
|
+
}
|
|
636
|
+
needsComma = true;
|
|
637
|
+
}
|
|
638
|
+
if (scanner.getToken() !== 4 /* CloseBracketToken */) {
|
|
639
|
+
return _error(l10n.t("Expected comma or closing bracket"), 517 /* CommaOrCloseBacketExpected */, node);
|
|
640
|
+
}
|
|
641
|
+
return _finalize(node, true);
|
|
642
|
+
}
|
|
643
|
+
const keyPlaceholder = new StringASTNodeImpl(void 0, 0, 0);
|
|
644
|
+
function _parseProperty(parent, keysSeen) {
|
|
645
|
+
const node = new PropertyASTNodeImpl(parent, scanner.getTokenOffset(), keyPlaceholder);
|
|
646
|
+
let key = _parseString(node);
|
|
647
|
+
if (!key) {
|
|
648
|
+
if (scanner.getToken() === 16 /* Unknown */) {
|
|
649
|
+
_error(l10n.t("Property keys must be doublequoted"), 528 /* PropertyKeysMustBeDoublequoted */);
|
|
650
|
+
const keyNode = new StringASTNodeImpl(node, scanner.getTokenOffset(), scanner.getTokenLength());
|
|
651
|
+
keyNode.value = scanner.getTokenValue();
|
|
652
|
+
key = keyNode;
|
|
653
|
+
_scanNext();
|
|
654
|
+
} else {
|
|
655
|
+
return void 0;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
node.keyNode = key;
|
|
659
|
+
if (key.value !== "//") {
|
|
660
|
+
const seen = keysSeen[key.value];
|
|
661
|
+
if (seen) {
|
|
662
|
+
_errorAtRange(l10n.t("Duplicate object key"), 520 /* DuplicateKey */, node.keyNode.offset, node.keyNode.offset + node.keyNode.length, import_vscode_languageserver_types.DiagnosticSeverity.Warning);
|
|
663
|
+
if (isObject(seen)) {
|
|
664
|
+
_errorAtRange(l10n.t("Duplicate object key"), 520 /* DuplicateKey */, seen.keyNode.offset, seen.keyNode.offset + seen.keyNode.length, import_vscode_languageserver_types.DiagnosticSeverity.Warning);
|
|
665
|
+
}
|
|
666
|
+
keysSeen[key.value] = true;
|
|
667
|
+
} else {
|
|
668
|
+
keysSeen[key.value] = node;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
if (scanner.getToken() === 6 /* ColonToken */) {
|
|
672
|
+
node.colonOffset = scanner.getTokenOffset();
|
|
673
|
+
_scanNext();
|
|
674
|
+
} else {
|
|
675
|
+
_error(l10n.t("Colon expected"), 515 /* ColonExpected */);
|
|
676
|
+
if ((scanner.getToken() === 18 /* SingleQuoteStringLiteral */ || scanner.getToken() === 19 /* DoubleQuoteStringLiteral */) && textDocument.positionAt(key.offset + key.length).line < textDocument.positionAt(scanner.getTokenOffset()).line) {
|
|
677
|
+
node.length = key.length;
|
|
678
|
+
return node;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
const value = _parseValue(node);
|
|
682
|
+
if (!value) {
|
|
683
|
+
return _error(l10n.t("Value expected"), 516 /* ValueExpected */, node, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
|
|
684
|
+
}
|
|
685
|
+
node.valueNode = value;
|
|
686
|
+
node.length = value.offset + value.length - node.offset;
|
|
687
|
+
return node;
|
|
688
|
+
}
|
|
689
|
+
function _parseObject(parent) {
|
|
690
|
+
if (scanner.getToken() !== 1 /* OpenBraceToken */) {
|
|
691
|
+
return void 0;
|
|
692
|
+
}
|
|
693
|
+
const node = new ObjectASTNodeImpl(parent, scanner.getTokenOffset());
|
|
694
|
+
const keysSeen = /* @__PURE__ */ Object.create(null);
|
|
695
|
+
_scanNext();
|
|
696
|
+
let needsComma = false;
|
|
697
|
+
while (scanner.getToken() !== 2 /* CloseBraceToken */ && scanner.getToken() !== 17 /* EOF */) {
|
|
698
|
+
if (scanner.getToken() === 5 /* CommaToken */) {
|
|
699
|
+
if (!needsComma) {
|
|
700
|
+
_error(l10n.t("Property expected"), 513 /* PropertyExpected */);
|
|
701
|
+
}
|
|
702
|
+
const commaOffset = scanner.getTokenOffset();
|
|
703
|
+
_scanNext();
|
|
704
|
+
if (scanner.getToken() === 2 /* CloseBraceToken */) {
|
|
705
|
+
if (needsComma) {
|
|
706
|
+
_errorAtRange(l10n.t("Trailing comma"), 519 /* TrailingComma */, commaOffset, commaOffset + 1);
|
|
707
|
+
}
|
|
708
|
+
continue;
|
|
709
|
+
}
|
|
710
|
+
} else if (needsComma) {
|
|
711
|
+
_error(l10n.t("Expected comma"), 514 /* CommaExpected */);
|
|
712
|
+
}
|
|
713
|
+
const property = _parseProperty(node, keysSeen);
|
|
714
|
+
if (!property) {
|
|
715
|
+
_error(l10n.t("Property expected"), 513 /* PropertyExpected */, void 0, [], [2 /* CloseBraceToken */, 5 /* CommaToken */]);
|
|
716
|
+
} else {
|
|
717
|
+
node.properties.push(property);
|
|
718
|
+
}
|
|
719
|
+
needsComma = true;
|
|
720
|
+
}
|
|
721
|
+
if (scanner.getToken() !== 2 /* CloseBraceToken */) {
|
|
722
|
+
return _error(l10n.t("Expected comma or closing brace"), 518 /* CommaOrCloseBraceExpected */, node);
|
|
723
|
+
}
|
|
724
|
+
return _finalize(node, true);
|
|
725
|
+
}
|
|
726
|
+
function _parseString(parent) {
|
|
727
|
+
if (scanner.getToken() !== 18 /* SingleQuoteStringLiteral */ && scanner.getToken() !== 19 /* DoubleQuoteStringLiteral */) {
|
|
728
|
+
return void 0;
|
|
729
|
+
}
|
|
730
|
+
if (scanner.getToken() === 18 /* SingleQuoteStringLiteral */) {
|
|
731
|
+
_error(l10n.t("String value must be doublequoted"), 529 /* StringValueMustBeDoublequoted */);
|
|
732
|
+
}
|
|
733
|
+
const node = new StringASTNodeImpl(parent, scanner.getTokenOffset());
|
|
734
|
+
node.value = scanner.getTokenValue();
|
|
735
|
+
return _finalize(node, true);
|
|
736
|
+
}
|
|
737
|
+
function _parseNumber(parent) {
|
|
738
|
+
if (scanner.getToken() !== 11 /* NumericLiteral */) {
|
|
739
|
+
return void 0;
|
|
740
|
+
}
|
|
741
|
+
const node = new NumberASTNodeImpl(parent, scanner.getTokenOffset());
|
|
742
|
+
if (scanner.getTokenError() === 0 /* None */) {
|
|
743
|
+
const tokenValue = scanner.getTokenValue();
|
|
744
|
+
try {
|
|
745
|
+
const numberValue = JSON.parse(tokenValue);
|
|
746
|
+
if (!isNumber(numberValue)) {
|
|
747
|
+
return _error(l10n.t("Invalid number format."), 0 /* Undefined */, node);
|
|
748
|
+
}
|
|
749
|
+
node.value = numberValue;
|
|
750
|
+
} catch (e) {
|
|
751
|
+
return _error(l10n.t("Invalid number format."), 0 /* Undefined */, node);
|
|
752
|
+
}
|
|
753
|
+
node.isInteger = tokenValue.indexOf(".") === -1;
|
|
754
|
+
}
|
|
755
|
+
return _finalize(node, true);
|
|
756
|
+
}
|
|
757
|
+
function _parseLiteral(parent) {
|
|
758
|
+
let node;
|
|
759
|
+
switch (scanner.getToken()) {
|
|
760
|
+
case 7 /* NullKeyword */:
|
|
761
|
+
return _finalize(new NullASTNodeImpl(parent, scanner.getTokenOffset()), true);
|
|
762
|
+
case 8 /* TrueKeyword */:
|
|
763
|
+
return _finalize(new BooleanASTNodeImpl(parent, true, scanner.getTokenOffset()), true);
|
|
764
|
+
case 9 /* FalseKeyword */:
|
|
765
|
+
return _finalize(new BooleanASTNodeImpl(parent, false, scanner.getTokenOffset()), true);
|
|
766
|
+
default:
|
|
767
|
+
return void 0;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
function _parseValue(parent) {
|
|
771
|
+
return _parseArray(parent) || _parseObject(parent) || _parseString(parent) || _parseNumber(parent) || _parseLiteral(parent);
|
|
772
|
+
}
|
|
773
|
+
let _root = void 0;
|
|
774
|
+
const token = _scanNext();
|
|
775
|
+
if (token !== 17 /* EOF */) {
|
|
776
|
+
_root = _parseValue(_root);
|
|
777
|
+
if (!_root) {
|
|
778
|
+
_error(l10n.t("Expected a JSON object, array or literal."), 0 /* Undefined */);
|
|
779
|
+
} else if (scanner.getToken() !== 17 /* EOF */) {
|
|
780
|
+
_error(l10n.t("End of file expected."), 0 /* Undefined */);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
return {
|
|
784
|
+
// _root is undefined is source is empty string
|
|
785
|
+
ast: _root,
|
|
786
|
+
problems,
|
|
787
|
+
commentRanges
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// src/helpers.ts
|
|
792
|
+
function contains(node, offset, includeRightBound = false) {
|
|
793
|
+
return offset >= node.offset && offset < node.offset + node.length || includeRightBound && offset === node.offset + node.length;
|
|
794
|
+
}
|
|
795
|
+
function findNodeAtOffset(node, offset, includeRightBound = false) {
|
|
796
|
+
if (contains(node, offset, includeRightBound)) {
|
|
797
|
+
const { children } = node;
|
|
798
|
+
if (Array.isArray(children)) {
|
|
799
|
+
for (let i = 0; i < children.length && children[i].offset <= offset; i++) {
|
|
800
|
+
const item = findNodeAtOffset(children[i], offset, includeRightBound);
|
|
801
|
+
if (item) {
|
|
802
|
+
return item;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
return node;
|
|
807
|
+
}
|
|
808
|
+
return void 0;
|
|
809
|
+
}
|
|
810
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
811
|
+
0 && (module.exports = {
|
|
812
|
+
ErrorCode,
|
|
813
|
+
findNodeAtOffset,
|
|
814
|
+
parse
|
|
815
|
+
});
|
|
816
|
+
//# sourceMappingURL=index.js.map
|