clarity-pattern-parser 5.0.0 → 6.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/README.md +328 -38
- package/TODO.md +55 -1
- package/dist/ast/Node.d.ts +8 -2
- package/dist/index.browser.js +470 -205
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.esm.js +469 -206
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +470 -205
- package/dist/index.js.map +1 -1
- package/dist/intellisense/AutoComplete.d.ts +28 -0
- package/dist/intellisense/Suggestion.d.ts +11 -0
- package/dist/intellisense/SuggestionOption.d.ts +4 -0
- package/dist/patterns/And.d.ts +7 -7
- package/dist/patterns/Cursor.d.ts +6 -4
- package/dist/patterns/CursorHistory.d.ts +2 -2
- package/dist/patterns/Literal.d.ts +7 -8
- package/dist/patterns/Not.d.ts +8 -5
- package/dist/patterns/Or.d.ts +7 -5
- package/dist/patterns/Pattern.d.ts +7 -4
- package/dist/patterns/Reference.d.ts +10 -7
- package/dist/patterns/Regex.d.ts +7 -8
- package/dist/patterns/Repeat.d.ts +7 -7
- package/package.json +1 -1
- package/src/ast/Node.test.ts +110 -0
- package/src/ast/Node.ts +71 -5
- package/src/index.ts +14 -3
- package/src/intellisense/AutoComplete.test.ts +90 -12
- package/src/intellisense/AutoComplete.ts +66 -12
- package/src/intellisense/Suggestion.ts +3 -4
- package/src/intellisense/javascript/Javascript.test.ts +56 -56
- package/src/intellisense/javascript/escapedCharacter.ts +0 -1
- package/src/intellisense/javascript/exponent.ts +0 -2
- package/src/intellisense/javascript/fraction.ts +0 -2
- package/src/patterns/And.test.ts +63 -52
- package/src/patterns/And.ts +58 -36
- package/src/patterns/Cursor.ts +17 -14
- package/src/patterns/CursorHistory.ts +8 -8
- package/src/patterns/Literal.test.ts +70 -38
- package/src/patterns/Literal.ts +31 -42
- package/src/patterns/Not.test.ts +88 -8
- package/src/patterns/Not.ts +54 -14
- package/src/patterns/Or.test.ts +117 -13
- package/src/patterns/Or.ts +36 -13
- package/src/patterns/Pattern.ts +7 -4
- package/src/patterns/Reference.test.ts +117 -28
- package/src/patterns/Reference.ts +58 -32
- package/src/patterns/Regex.test.ts +67 -35
- package/src/patterns/Regex.ts +31 -43
- package/src/patterns/Repeat.test.ts +63 -41
- package/src/patterns/Repeat.ts +51 -38
- package/src/patterns/getNextPattern.test.ts +0 -39
- package/src/patterns/getNextPattern.ts +0 -18
package/dist/index.browser.js
CHANGED
|
@@ -29,6 +29,9 @@
|
|
|
29
29
|
get children() {
|
|
30
30
|
return this._children;
|
|
31
31
|
}
|
|
32
|
+
get hasChildren() {
|
|
33
|
+
return this._children.length > 0;
|
|
34
|
+
}
|
|
32
35
|
get value() {
|
|
33
36
|
return this.toString();
|
|
34
37
|
}
|
|
@@ -78,22 +81,54 @@
|
|
|
78
81
|
}
|
|
79
82
|
spliceChildren(index, deleteCount, ...items) {
|
|
80
83
|
const removedItems = this._children.splice(index, deleteCount, ...items);
|
|
81
|
-
items.forEach(i => i._parent = this);
|
|
82
84
|
removedItems.forEach(i => i._parent = null);
|
|
85
|
+
items.forEach(i => i._parent = this);
|
|
83
86
|
return removedItems;
|
|
84
87
|
}
|
|
85
|
-
|
|
86
|
-
|
|
88
|
+
nextSibling() {
|
|
89
|
+
if (this._parent == null) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
const children = this._parent._children;
|
|
93
|
+
const index = children.indexOf(this);
|
|
94
|
+
if (index > -1 && index < children.length - 1) {
|
|
95
|
+
return children[index + 1];
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
previousSibling() {
|
|
100
|
+
if (this._parent == null) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const children = this._parent._children;
|
|
104
|
+
const index = children.indexOf(this);
|
|
105
|
+
if (index > -1 && index > 0) {
|
|
106
|
+
return children[index - 1];
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
87
109
|
}
|
|
88
|
-
|
|
110
|
+
find(predicate) {
|
|
111
|
+
return this.findAll(predicate)[0] || null;
|
|
112
|
+
}
|
|
113
|
+
findAll(predicate) {
|
|
89
114
|
const matches = [];
|
|
90
115
|
this.walkUp(n => {
|
|
91
|
-
if (
|
|
116
|
+
if (predicate(n)) {
|
|
92
117
|
matches.push(n);
|
|
93
118
|
}
|
|
94
119
|
});
|
|
95
120
|
return matches;
|
|
96
121
|
}
|
|
122
|
+
findAncester(predicate) {
|
|
123
|
+
let parent = this._parent;
|
|
124
|
+
while (parent != null) {
|
|
125
|
+
if (predicate(parent)) {
|
|
126
|
+
return parent;
|
|
127
|
+
}
|
|
128
|
+
parent = parent._parent;
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
97
132
|
walkUp(callback) {
|
|
98
133
|
this.children.forEach(c => c.walkUp(callback));
|
|
99
134
|
callback(this);
|
|
@@ -102,6 +137,20 @@
|
|
|
102
137
|
callback(this);
|
|
103
138
|
this.children.forEach(c => c.walkDown(callback));
|
|
104
139
|
}
|
|
140
|
+
flatten() {
|
|
141
|
+
const nodes = [];
|
|
142
|
+
this.walkDown((node) => {
|
|
143
|
+
if (!node.hasChildren) {
|
|
144
|
+
nodes.push(node);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
return nodes;
|
|
148
|
+
}
|
|
149
|
+
reduce() {
|
|
150
|
+
const value = this.toString();
|
|
151
|
+
this.removeAllChildren();
|
|
152
|
+
this._value = value;
|
|
153
|
+
}
|
|
105
154
|
clone() {
|
|
106
155
|
return new Node(this._type, this._name, this._firstIndex, this._lastIndex, this._children.map((c) => c.clone()), this._value);
|
|
107
156
|
}
|
|
@@ -146,15 +195,18 @@
|
|
|
146
195
|
this._nodes = [];
|
|
147
196
|
this._errors = [];
|
|
148
197
|
}
|
|
198
|
+
get isRecording() {
|
|
199
|
+
return this._isRecording;
|
|
200
|
+
}
|
|
201
|
+
get rootMatch() {
|
|
202
|
+
return this._rootMatch;
|
|
203
|
+
}
|
|
149
204
|
get leafMatch() {
|
|
150
205
|
return this._leafMatch;
|
|
151
206
|
}
|
|
152
207
|
get furthestError() {
|
|
153
208
|
return this._furthestError;
|
|
154
209
|
}
|
|
155
|
-
get isRecording() {
|
|
156
|
-
return this._isRecording;
|
|
157
|
-
}
|
|
158
210
|
get errors() {
|
|
159
211
|
return this._errors;
|
|
160
212
|
}
|
|
@@ -167,9 +219,6 @@
|
|
|
167
219
|
get patterns() {
|
|
168
220
|
return this._patterns;
|
|
169
221
|
}
|
|
170
|
-
get rootMatch() {
|
|
171
|
-
return this._rootMatch;
|
|
172
|
-
}
|
|
173
222
|
recordMatch(pattern, node) {
|
|
174
223
|
if (this._isRecording) {
|
|
175
224
|
this._patterns.push(pattern);
|
|
@@ -212,17 +261,17 @@
|
|
|
212
261
|
return this._index === 0;
|
|
213
262
|
}
|
|
214
263
|
get isOnLast() {
|
|
215
|
-
return this._index === this.
|
|
264
|
+
return this._index === this.getLastIndex();
|
|
216
265
|
}
|
|
217
266
|
get isRecording() {
|
|
218
267
|
return this._history.isRecording;
|
|
219
268
|
}
|
|
220
|
-
get leafMatch() {
|
|
221
|
-
return this._history.leafMatch;
|
|
222
|
-
}
|
|
223
269
|
get rootMatch() {
|
|
224
270
|
return this._history.rootMatch;
|
|
225
271
|
}
|
|
272
|
+
get leafMatch() {
|
|
273
|
+
return this._history.leafMatch;
|
|
274
|
+
}
|
|
226
275
|
get furthestError() {
|
|
227
276
|
return this._history.furthestError;
|
|
228
277
|
}
|
|
@@ -253,14 +302,14 @@
|
|
|
253
302
|
hasNext() {
|
|
254
303
|
return this._index + 1 < this._length;
|
|
255
304
|
}
|
|
256
|
-
hasPrevious() {
|
|
257
|
-
return this._index - 1 >= 0;
|
|
258
|
-
}
|
|
259
305
|
next() {
|
|
260
306
|
if (this.hasNext()) {
|
|
261
307
|
this._index++;
|
|
262
308
|
}
|
|
263
309
|
}
|
|
310
|
+
hasPrevious() {
|
|
311
|
+
return this._index - 1 >= 0;
|
|
312
|
+
}
|
|
264
313
|
previous() {
|
|
265
314
|
if (this.hasPrevious()) {
|
|
266
315
|
this._index--;
|
|
@@ -275,7 +324,10 @@
|
|
|
275
324
|
this._index = 0;
|
|
276
325
|
}
|
|
277
326
|
moveToLastChar() {
|
|
278
|
-
this._index = this.
|
|
327
|
+
this._index = this.getLastIndex();
|
|
328
|
+
}
|
|
329
|
+
getLastIndex() {
|
|
330
|
+
return this._length - 1;
|
|
279
331
|
}
|
|
280
332
|
getChars(first, last) {
|
|
281
333
|
return this._text.slice(first, last + 1);
|
|
@@ -295,22 +347,6 @@
|
|
|
295
347
|
stopRecording() {
|
|
296
348
|
this._history.stopRecording();
|
|
297
349
|
}
|
|
298
|
-
_getLastIndex() {
|
|
299
|
-
return this._length - 1;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
function getNextPattern(pattern) {
|
|
304
|
-
const parent = pattern.parent;
|
|
305
|
-
if (parent == null) {
|
|
306
|
-
return null;
|
|
307
|
-
}
|
|
308
|
-
const patternIndex = parent.children.indexOf(pattern);
|
|
309
|
-
const nextPattern = parent.children[patternIndex + 1] || null;
|
|
310
|
-
if (nextPattern == null) {
|
|
311
|
-
return parent.getNextPattern();
|
|
312
|
-
}
|
|
313
|
-
return nextPattern;
|
|
314
350
|
}
|
|
315
351
|
|
|
316
352
|
class Regex {
|
|
@@ -337,8 +373,6 @@
|
|
|
337
373
|
this._cursor = null;
|
|
338
374
|
this._substring = "";
|
|
339
375
|
this._tokens = [];
|
|
340
|
-
this._hasContextualTokenAggregation = false;
|
|
341
|
-
this._isRetrievingContextualTokens = false;
|
|
342
376
|
this._type = "regex";
|
|
343
377
|
this._name = name;
|
|
344
378
|
this._isOptional = isOptional;
|
|
@@ -358,11 +392,16 @@
|
|
|
358
392
|
throw new Error("Invalid Arguments: The regex string cannot end with a '$' because it is expected to be in the middle of a string.");
|
|
359
393
|
}
|
|
360
394
|
}
|
|
361
|
-
|
|
395
|
+
test(text) {
|
|
396
|
+
const cursor = new Cursor(text);
|
|
397
|
+
const ast = this.parse(cursor);
|
|
398
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
399
|
+
}
|
|
400
|
+
exec(text) {
|
|
362
401
|
const cursor = new Cursor(text);
|
|
363
402
|
const ast = this.parse(cursor);
|
|
364
403
|
return {
|
|
365
|
-
ast,
|
|
404
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
366
405
|
cursor
|
|
367
406
|
};
|
|
368
407
|
}
|
|
@@ -389,7 +428,7 @@
|
|
|
389
428
|
processResult(cursor, result) {
|
|
390
429
|
const currentIndex = cursor.index;
|
|
391
430
|
const newIndex = currentIndex + result[0].length - 1;
|
|
392
|
-
this._node = new Node("regex", this._name, currentIndex, newIndex,
|
|
431
|
+
this._node = new Node("regex", this._name, currentIndex, newIndex, undefined, result[0]);
|
|
393
432
|
cursor.moveTo(newIndex);
|
|
394
433
|
cursor.recordMatch(this, this._node);
|
|
395
434
|
}
|
|
@@ -402,47 +441,35 @@
|
|
|
402
441
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
403
442
|
const pattern = new Regex(name, this._originalRegexString, isOptional);
|
|
404
443
|
pattern._tokens = this._tokens.slice();
|
|
405
|
-
pattern._hasContextualTokenAggregation =
|
|
406
|
-
this._hasContextualTokenAggregation;
|
|
407
444
|
return pattern;
|
|
408
445
|
}
|
|
409
446
|
getTokens() {
|
|
410
|
-
const parent = this._parent;
|
|
411
|
-
if (this._hasContextualTokenAggregation &&
|
|
412
|
-
parent != null &&
|
|
413
|
-
!this._isRetrievingContextualTokens) {
|
|
414
|
-
this._isRetrievingContextualTokens = true;
|
|
415
|
-
const tokens = this._tokens;
|
|
416
|
-
const aggregateTokens = [];
|
|
417
|
-
const nextTokens = parent.getNextTokens(this);
|
|
418
|
-
for (let nextToken of nextTokens) {
|
|
419
|
-
for (let token of tokens) {
|
|
420
|
-
aggregateTokens.push(token + nextToken);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
this._isRetrievingContextualTokens = false;
|
|
424
|
-
return aggregateTokens;
|
|
425
|
-
}
|
|
426
447
|
return this._tokens;
|
|
427
448
|
}
|
|
428
|
-
|
|
449
|
+
getTokensAfter(_childReference) {
|
|
429
450
|
return [];
|
|
430
451
|
}
|
|
431
|
-
|
|
432
|
-
|
|
452
|
+
getNextTokens() {
|
|
453
|
+
if (this.parent == null) {
|
|
454
|
+
return [];
|
|
455
|
+
}
|
|
456
|
+
return this.parent.getTokensAfter(this);
|
|
457
|
+
}
|
|
458
|
+
getPatternsAfter(_childReference) {
|
|
459
|
+
return [];
|
|
460
|
+
}
|
|
461
|
+
getNextPatterns() {
|
|
462
|
+
if (this.parent == null) {
|
|
463
|
+
return [];
|
|
464
|
+
}
|
|
465
|
+
return this.parent.getPatternsAfter(this);
|
|
433
466
|
}
|
|
434
|
-
findPattern(
|
|
467
|
+
findPattern(_predicate) {
|
|
435
468
|
return null;
|
|
436
469
|
}
|
|
437
470
|
setTokens(tokens) {
|
|
438
471
|
this._tokens = tokens;
|
|
439
472
|
}
|
|
440
|
-
enableContextualTokenAggregation() {
|
|
441
|
-
this._hasContextualTokenAggregation = true;
|
|
442
|
-
}
|
|
443
|
-
disableContextualTokenAggregation() {
|
|
444
|
-
this._hasContextualTokenAggregation = false;
|
|
445
|
-
}
|
|
446
473
|
}
|
|
447
474
|
|
|
448
475
|
function clonePatterns(patterns, isOptional) {
|
|
@@ -512,7 +539,6 @@
|
|
|
512
539
|
this._parent = null;
|
|
513
540
|
this._children = children;
|
|
514
541
|
this._firstIndex = -1;
|
|
515
|
-
this._shouldReduceAst = false;
|
|
516
542
|
this._nodes = [];
|
|
517
543
|
}
|
|
518
544
|
_assignChildrenToParent(children) {
|
|
@@ -520,11 +546,16 @@
|
|
|
520
546
|
child.parent = this;
|
|
521
547
|
}
|
|
522
548
|
}
|
|
523
|
-
|
|
549
|
+
test(text) {
|
|
550
|
+
const cursor = new Cursor(text);
|
|
551
|
+
const ast = this.parse(cursor);
|
|
552
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
553
|
+
}
|
|
554
|
+
exec(text) {
|
|
524
555
|
const cursor = new Cursor(text);
|
|
525
556
|
const ast = this.parse(cursor);
|
|
526
557
|
return {
|
|
527
|
-
ast,
|
|
558
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
528
559
|
cursor
|
|
529
560
|
};
|
|
530
561
|
}
|
|
@@ -558,34 +589,43 @@
|
|
|
558
589
|
if (hasMorePatterns) {
|
|
559
590
|
if (hadMatch) {
|
|
560
591
|
if (cursor.hasNext()) {
|
|
592
|
+
// We had a match. Increment the cursor and use the next pattern.
|
|
561
593
|
cursor.next();
|
|
562
594
|
continue;
|
|
563
595
|
}
|
|
564
596
|
else {
|
|
597
|
+
// We are at the end of the text, it may still be valid, if all the
|
|
598
|
+
// following patterns are optional.
|
|
565
599
|
if (this.areRemainingPatternsOptional(i)) {
|
|
566
600
|
passed = true;
|
|
567
601
|
break;
|
|
568
602
|
}
|
|
603
|
+
// We didn't finish the parsing sequence.
|
|
569
604
|
cursor.recordErrorAt(cursor.index + 1, this);
|
|
570
605
|
break;
|
|
571
606
|
}
|
|
572
607
|
}
|
|
573
608
|
else {
|
|
609
|
+
// An optional pattern did not matched, try from the same spot on the next
|
|
610
|
+
// pattern.
|
|
574
611
|
cursor.moveTo(runningCursorIndex);
|
|
575
612
|
continue;
|
|
576
613
|
}
|
|
577
614
|
}
|
|
578
615
|
else {
|
|
616
|
+
// If we don't have any results from what we parsed then record error.
|
|
579
617
|
const lastNode = this.getLastValidNode();
|
|
580
618
|
if (lastNode === null) {
|
|
581
619
|
cursor.recordErrorAt(cursor.index, this);
|
|
582
620
|
break;
|
|
583
621
|
}
|
|
622
|
+
// The sequence was parsed fully.
|
|
584
623
|
passed = true;
|
|
585
624
|
break;
|
|
586
625
|
}
|
|
587
626
|
}
|
|
588
627
|
else {
|
|
628
|
+
// The pattern failed.
|
|
589
629
|
cursor.moveTo(this._firstIndex);
|
|
590
630
|
break;
|
|
591
631
|
}
|
|
@@ -613,18 +653,9 @@
|
|
|
613
653
|
createNode(cursor) {
|
|
614
654
|
const children = filterOutNull(this._nodes);
|
|
615
655
|
const lastIndex = children[children.length - 1].lastIndex;
|
|
616
|
-
|
|
656
|
+
cursor.getChars(this._firstIndex, lastIndex);
|
|
617
657
|
cursor.moveTo(lastIndex);
|
|
618
|
-
|
|
619
|
-
children.length = 0;
|
|
620
|
-
}
|
|
621
|
-
return new Node("and", this._name, this._firstIndex, lastIndex, children, this._shouldReduceAst ? value : undefined);
|
|
622
|
-
}
|
|
623
|
-
enableAstReduction() {
|
|
624
|
-
this._shouldReduceAst = true;
|
|
625
|
-
}
|
|
626
|
-
disableAstReduction() {
|
|
627
|
-
this._shouldReduceAst = false;
|
|
658
|
+
return new Node("and", this._name, this._firstIndex, lastIndex, children);
|
|
628
659
|
}
|
|
629
660
|
getTokens() {
|
|
630
661
|
const tokens = [];
|
|
@@ -636,13 +667,25 @@
|
|
|
636
667
|
}
|
|
637
668
|
return tokens;
|
|
638
669
|
}
|
|
639
|
-
|
|
670
|
+
getTokensAfter(childReference) {
|
|
671
|
+
const patterns = this.getPatternsAfter(childReference);
|
|
672
|
+
const tokens = [];
|
|
673
|
+
patterns.forEach(p => tokens.push(...p.getTokens()));
|
|
674
|
+
return tokens;
|
|
675
|
+
}
|
|
676
|
+
getNextTokens() {
|
|
677
|
+
if (this.parent == null) {
|
|
678
|
+
return [];
|
|
679
|
+
}
|
|
680
|
+
return this.parent.getTokensAfter(this);
|
|
681
|
+
}
|
|
682
|
+
getPatternsAfter(childReference) {
|
|
640
683
|
let nextSibling = null;
|
|
641
684
|
let nextSiblingIndex = -1;
|
|
642
685
|
let index = -1;
|
|
643
|
-
const
|
|
686
|
+
const patterns = [];
|
|
644
687
|
for (let i = 0; i < this._children.length; i++) {
|
|
645
|
-
if (this._children[i] ===
|
|
688
|
+
if (this._children[i] === childReference) {
|
|
646
689
|
if (i + 1 < this._children.length) {
|
|
647
690
|
nextSibling = this._children[i + 1];
|
|
648
691
|
}
|
|
@@ -651,39 +694,44 @@
|
|
|
651
694
|
break;
|
|
652
695
|
}
|
|
653
696
|
}
|
|
697
|
+
// The child reference isn't one of the child patterns.
|
|
654
698
|
if (index === -1) {
|
|
655
699
|
return [];
|
|
656
700
|
}
|
|
701
|
+
// The reference pattern is the last child. So ask the parent for the next pattern.
|
|
657
702
|
if (nextSiblingIndex === this._children.length && this._parent !== null) {
|
|
658
|
-
return this._parent.
|
|
703
|
+
return this._parent.getPatternsAfter(this);
|
|
659
704
|
}
|
|
705
|
+
// Next pattern isn't optional so send it back as the next patterns.
|
|
660
706
|
if (nextSibling !== null && !nextSibling.isOptional) {
|
|
661
|
-
return nextSibling
|
|
707
|
+
return [nextSibling];
|
|
662
708
|
}
|
|
709
|
+
// Send back as many optional patterns as possible.
|
|
663
710
|
if (nextSibling !== null && nextSibling.isOptional) {
|
|
664
711
|
for (let i = nextSiblingIndex; i < this._children.length; i++) {
|
|
665
712
|
const child = this._children[i];
|
|
666
|
-
|
|
713
|
+
patterns.push(child);
|
|
667
714
|
if (!child.isOptional) {
|
|
668
715
|
break;
|
|
669
716
|
}
|
|
670
717
|
if (i === this._children.length - 1 && this._parent !== null) {
|
|
671
|
-
|
|
718
|
+
patterns.push(...this._parent.getPatternsAfter(this));
|
|
672
719
|
}
|
|
673
720
|
}
|
|
674
721
|
}
|
|
675
|
-
return
|
|
722
|
+
return patterns;
|
|
676
723
|
}
|
|
677
|
-
|
|
678
|
-
|
|
724
|
+
getNextPatterns() {
|
|
725
|
+
if (this.parent == null) {
|
|
726
|
+
return [];
|
|
727
|
+
}
|
|
728
|
+
return this.parent.getPatternsAfter(this);
|
|
679
729
|
}
|
|
680
|
-
findPattern(
|
|
681
|
-
return findPattern(this,
|
|
730
|
+
findPattern(predicate) {
|
|
731
|
+
return findPattern(this, predicate);
|
|
682
732
|
}
|
|
683
733
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
684
|
-
|
|
685
|
-
and._shouldReduceAst = this._shouldReduceAst;
|
|
686
|
-
return and;
|
|
734
|
+
return new And(name, this._children, isOptional);
|
|
687
735
|
}
|
|
688
736
|
}
|
|
689
737
|
|
|
@@ -718,14 +766,17 @@
|
|
|
718
766
|
this._parent = null;
|
|
719
767
|
this._firstIndex = 0;
|
|
720
768
|
this._lastIndex = 0;
|
|
721
|
-
this._hasContextualTokenAggregation = false;
|
|
722
|
-
this._isRetrievingContextualTokens = false;
|
|
723
769
|
}
|
|
724
|
-
|
|
770
|
+
test(text) {
|
|
771
|
+
const cursor = new Cursor(text);
|
|
772
|
+
const ast = this.parse(cursor);
|
|
773
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
774
|
+
}
|
|
775
|
+
exec(text) {
|
|
725
776
|
const cursor = new Cursor(text);
|
|
726
777
|
const ast = this.parse(cursor);
|
|
727
778
|
return {
|
|
728
|
-
ast,
|
|
779
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
729
780
|
cursor
|
|
730
781
|
};
|
|
731
782
|
}
|
|
@@ -768,45 +819,35 @@
|
|
|
768
819
|
return passed;
|
|
769
820
|
}
|
|
770
821
|
_createNode() {
|
|
771
|
-
return new Node("literal", this._name, this._firstIndex, this._lastIndex,
|
|
822
|
+
return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this._literal);
|
|
772
823
|
}
|
|
773
824
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
774
825
|
const clone = new Literal(name, this._literal, isOptional);
|
|
775
|
-
clone._hasContextualTokenAggregation = this._hasContextualTokenAggregation;
|
|
776
826
|
return clone;
|
|
777
827
|
}
|
|
778
828
|
getTokens() {
|
|
779
|
-
|
|
780
|
-
if (this._hasContextualTokenAggregation &&
|
|
781
|
-
parent != null &&
|
|
782
|
-
!this._isRetrievingContextualTokens) {
|
|
783
|
-
this._isRetrievingContextualTokens = true;
|
|
784
|
-
const aggregateTokens = [];
|
|
785
|
-
const nextTokens = parent.getNextTokens(this);
|
|
786
|
-
for (const nextToken of nextTokens) {
|
|
787
|
-
aggregateTokens.push(this._literal + nextToken);
|
|
788
|
-
}
|
|
789
|
-
this._isRetrievingContextualTokens = false;
|
|
790
|
-
return aggregateTokens;
|
|
791
|
-
}
|
|
792
|
-
else {
|
|
793
|
-
return [this._literal];
|
|
794
|
-
}
|
|
829
|
+
return [this._literal];
|
|
795
830
|
}
|
|
796
|
-
|
|
831
|
+
getTokensAfter(_lastMatched) {
|
|
797
832
|
return [];
|
|
798
833
|
}
|
|
799
|
-
|
|
800
|
-
|
|
834
|
+
getNextTokens() {
|
|
835
|
+
if (this.parent == null) {
|
|
836
|
+
return [];
|
|
837
|
+
}
|
|
838
|
+
return this.parent.getTokensAfter(this);
|
|
801
839
|
}
|
|
802
|
-
|
|
803
|
-
return
|
|
840
|
+
getPatternsAfter() {
|
|
841
|
+
return [];
|
|
804
842
|
}
|
|
805
|
-
|
|
806
|
-
this.
|
|
843
|
+
getNextPatterns() {
|
|
844
|
+
if (this.parent == null) {
|
|
845
|
+
return [];
|
|
846
|
+
}
|
|
847
|
+
return this.parent.getPatternsAfter(this);
|
|
807
848
|
}
|
|
808
|
-
|
|
809
|
-
|
|
849
|
+
findPattern(_predicate) {
|
|
850
|
+
return null;
|
|
810
851
|
}
|
|
811
852
|
}
|
|
812
853
|
|
|
@@ -817,9 +858,6 @@
|
|
|
817
858
|
get name() {
|
|
818
859
|
return this._name;
|
|
819
860
|
}
|
|
820
|
-
get isOptional() {
|
|
821
|
-
return false;
|
|
822
|
-
}
|
|
823
861
|
get parent() {
|
|
824
862
|
return this._parent;
|
|
825
863
|
}
|
|
@@ -829,6 +867,9 @@
|
|
|
829
867
|
get children() {
|
|
830
868
|
return this._children;
|
|
831
869
|
}
|
|
870
|
+
get isOptional() {
|
|
871
|
+
return false;
|
|
872
|
+
}
|
|
832
873
|
constructor(name, pattern) {
|
|
833
874
|
this._type = "not";
|
|
834
875
|
this._name = name;
|
|
@@ -836,7 +877,12 @@
|
|
|
836
877
|
this._children = [pattern.clone(pattern.name, false)];
|
|
837
878
|
this._children[0].parent = this;
|
|
838
879
|
}
|
|
839
|
-
|
|
880
|
+
test(text) {
|
|
881
|
+
const cursor = new Cursor(text);
|
|
882
|
+
this.parse(cursor);
|
|
883
|
+
return !cursor.hasError;
|
|
884
|
+
}
|
|
885
|
+
exec(text) {
|
|
840
886
|
const cursor = new Cursor(text);
|
|
841
887
|
const ast = this.parse(cursor);
|
|
842
888
|
return {
|
|
@@ -862,17 +908,41 @@
|
|
|
862
908
|
const not = new Not(name, this._children[0]);
|
|
863
909
|
return not;
|
|
864
910
|
}
|
|
865
|
-
getNextPattern() {
|
|
866
|
-
return getNextPattern(this);
|
|
867
|
-
}
|
|
868
911
|
getTokens() {
|
|
912
|
+
const parent = this._parent;
|
|
913
|
+
if (parent != null) {
|
|
914
|
+
return parent.getTokensAfter(this);
|
|
915
|
+
}
|
|
869
916
|
return [];
|
|
870
917
|
}
|
|
871
|
-
|
|
918
|
+
getTokensAfter(_childReference) {
|
|
919
|
+
const parent = this._parent;
|
|
920
|
+
if (parent != null) {
|
|
921
|
+
return parent.getTokensAfter(this);
|
|
922
|
+
}
|
|
872
923
|
return [];
|
|
873
924
|
}
|
|
874
|
-
|
|
875
|
-
|
|
925
|
+
getNextTokens() {
|
|
926
|
+
if (this.parent == null) {
|
|
927
|
+
return [];
|
|
928
|
+
}
|
|
929
|
+
return this.parent.getTokensAfter(this);
|
|
930
|
+
}
|
|
931
|
+
getPatternsAfter(_childReference) {
|
|
932
|
+
const parent = this._parent;
|
|
933
|
+
if (parent != null) {
|
|
934
|
+
return parent.getPatternsAfter(this);
|
|
935
|
+
}
|
|
936
|
+
return [];
|
|
937
|
+
}
|
|
938
|
+
getNextPatterns() {
|
|
939
|
+
if (this.parent == null) {
|
|
940
|
+
return [];
|
|
941
|
+
}
|
|
942
|
+
return this.parent.getPatternsAfter(this);
|
|
943
|
+
}
|
|
944
|
+
findPattern(predicate) {
|
|
945
|
+
return predicate(this._children[0]) ? this._children[0] : null;
|
|
876
946
|
}
|
|
877
947
|
}
|
|
878
948
|
|
|
@@ -906,7 +976,6 @@
|
|
|
906
976
|
this._parent = null;
|
|
907
977
|
this._children = children;
|
|
908
978
|
this._isOptional = isOptional;
|
|
909
|
-
this._node = null;
|
|
910
979
|
this._firstIndex = 0;
|
|
911
980
|
}
|
|
912
981
|
_assignChildrenToParent(children) {
|
|
@@ -914,17 +983,21 @@
|
|
|
914
983
|
child.parent = this;
|
|
915
984
|
}
|
|
916
985
|
}
|
|
917
|
-
|
|
986
|
+
test(text) {
|
|
987
|
+
const cursor = new Cursor(text);
|
|
988
|
+
const ast = this.parse(cursor);
|
|
989
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
990
|
+
}
|
|
991
|
+
exec(text) {
|
|
918
992
|
const cursor = new Cursor(text);
|
|
919
993
|
const ast = this.parse(cursor);
|
|
920
994
|
return {
|
|
921
|
-
ast,
|
|
995
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
922
996
|
cursor
|
|
923
997
|
};
|
|
924
998
|
}
|
|
925
999
|
parse(cursor) {
|
|
926
1000
|
this._firstIndex = cursor.index;
|
|
927
|
-
this._node = null;
|
|
928
1001
|
const node = this._tryToParse(cursor);
|
|
929
1002
|
if (node != null) {
|
|
930
1003
|
cursor.resolveError();
|
|
@@ -956,17 +1029,32 @@
|
|
|
956
1029
|
}
|
|
957
1030
|
return tokens;
|
|
958
1031
|
}
|
|
959
|
-
|
|
1032
|
+
getTokensAfter(_childReference) {
|
|
960
1033
|
if (this._parent === null) {
|
|
961
1034
|
return [];
|
|
962
1035
|
}
|
|
963
|
-
return this._parent.
|
|
1036
|
+
return this._parent.getTokensAfter(this);
|
|
964
1037
|
}
|
|
965
|
-
|
|
966
|
-
|
|
1038
|
+
getNextTokens() {
|
|
1039
|
+
if (this._parent == null) {
|
|
1040
|
+
return [];
|
|
1041
|
+
}
|
|
1042
|
+
return this._parent.getTokensAfter(this);
|
|
1043
|
+
}
|
|
1044
|
+
getPatternsAfter(_childReference) {
|
|
1045
|
+
if (this._parent === null) {
|
|
1046
|
+
return [];
|
|
1047
|
+
}
|
|
1048
|
+
return this._parent.getPatternsAfter(this);
|
|
1049
|
+
}
|
|
1050
|
+
getNextPatterns() {
|
|
1051
|
+
if (this.parent == null) {
|
|
1052
|
+
return [];
|
|
1053
|
+
}
|
|
1054
|
+
return this.parent.getPatternsAfter(this);
|
|
967
1055
|
}
|
|
968
|
-
findPattern(
|
|
969
|
-
return findPattern(this,
|
|
1056
|
+
findPattern(predicate) {
|
|
1057
|
+
return findPattern(this, predicate);
|
|
970
1058
|
}
|
|
971
1059
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
972
1060
|
const or = new Or(name, this._children, isOptional);
|
|
@@ -1005,7 +1093,6 @@
|
|
|
1005
1093
|
this._pattern = children[0];
|
|
1006
1094
|
this._divider = children[1];
|
|
1007
1095
|
this._firstIndex = -1;
|
|
1008
|
-
this._shouldReduceAst = false;
|
|
1009
1096
|
this._nodes = [];
|
|
1010
1097
|
}
|
|
1011
1098
|
_assignChildrenToParent(children) {
|
|
@@ -1013,11 +1100,16 @@
|
|
|
1013
1100
|
child.parent = this;
|
|
1014
1101
|
}
|
|
1015
1102
|
}
|
|
1016
|
-
|
|
1103
|
+
test(text) {
|
|
1104
|
+
const cursor = new Cursor(text);
|
|
1105
|
+
const ast = this.parse(cursor);
|
|
1106
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1107
|
+
}
|
|
1108
|
+
exec(text) {
|
|
1017
1109
|
const cursor = new Cursor(text);
|
|
1018
1110
|
const ast = this.parse(cursor);
|
|
1019
1111
|
return {
|
|
1020
|
-
ast,
|
|
1112
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
1021
1113
|
cursor
|
|
1022
1114
|
};
|
|
1023
1115
|
}
|
|
@@ -1028,7 +1120,7 @@
|
|
|
1028
1120
|
if (passed) {
|
|
1029
1121
|
cursor.resolveError();
|
|
1030
1122
|
const node = this.createNode(cursor);
|
|
1031
|
-
if (node) {
|
|
1123
|
+
if (node != null) {
|
|
1032
1124
|
cursor.recordMatch(this, node);
|
|
1033
1125
|
}
|
|
1034
1126
|
return node;
|
|
@@ -1047,7 +1139,7 @@
|
|
|
1047
1139
|
const repeatedNode = this._pattern.parse(cursor);
|
|
1048
1140
|
if (cursor.hasError) {
|
|
1049
1141
|
const lastValidNode = this.getLastValidNode();
|
|
1050
|
-
if (lastValidNode) {
|
|
1142
|
+
if (lastValidNode != null) {
|
|
1051
1143
|
passed = true;
|
|
1052
1144
|
}
|
|
1053
1145
|
else {
|
|
@@ -1064,13 +1156,13 @@
|
|
|
1064
1156
|
break;
|
|
1065
1157
|
}
|
|
1066
1158
|
cursor.next();
|
|
1067
|
-
if (this._divider) {
|
|
1159
|
+
if (this._divider != null) {
|
|
1068
1160
|
const dividerNode = this._divider.parse(cursor);
|
|
1069
1161
|
if (cursor.hasError) {
|
|
1070
1162
|
passed = true;
|
|
1071
1163
|
break;
|
|
1072
1164
|
}
|
|
1073
|
-
else if (dividerNode) {
|
|
1165
|
+
else if (dividerNode != null) {
|
|
1074
1166
|
this._nodes.push(dividerNode);
|
|
1075
1167
|
if (!cursor.hasNext()) {
|
|
1076
1168
|
passed = true;
|
|
@@ -1099,12 +1191,9 @@
|
|
|
1099
1191
|
}
|
|
1100
1192
|
}
|
|
1101
1193
|
const lastIndex = children[children.length - 1].lastIndex;
|
|
1102
|
-
|
|
1194
|
+
cursor.getChars(this._firstIndex, lastIndex);
|
|
1103
1195
|
cursor.moveTo(lastIndex);
|
|
1104
|
-
|
|
1105
|
-
children = [];
|
|
1106
|
-
}
|
|
1107
|
-
return new Node("repeat", this._name, this._firstIndex, lastIndex, children, this._shouldReduceAst ? value : undefined);
|
|
1196
|
+
return new Node("repeat", this._name, this._firstIndex, lastIndex, children, undefined);
|
|
1108
1197
|
}
|
|
1109
1198
|
getLastValidNode() {
|
|
1110
1199
|
const nodes = this._nodes.filter((node) => node !== null);
|
|
@@ -1113,51 +1202,61 @@
|
|
|
1113
1202
|
}
|
|
1114
1203
|
return nodes[nodes.length - 1];
|
|
1115
1204
|
}
|
|
1116
|
-
enableAstReduction() {
|
|
1117
|
-
this._shouldReduceAst = true;
|
|
1118
|
-
}
|
|
1119
|
-
disableAstReduction() {
|
|
1120
|
-
this._shouldReduceAst = false;
|
|
1121
|
-
}
|
|
1122
1205
|
getTokens() {
|
|
1123
1206
|
return this._pattern.getTokens();
|
|
1124
1207
|
}
|
|
1125
|
-
|
|
1126
|
-
|
|
1208
|
+
getTokensAfter(childReference) {
|
|
1209
|
+
const patterns = this.getPatternsAfter(childReference);
|
|
1127
1210
|
const tokens = [];
|
|
1211
|
+
patterns.forEach(p => tokens.push(...p.getTokens()));
|
|
1212
|
+
return tokens;
|
|
1213
|
+
}
|
|
1214
|
+
getNextTokens() {
|
|
1215
|
+
if (this.parent == null) {
|
|
1216
|
+
return [];
|
|
1217
|
+
}
|
|
1218
|
+
return this.parent.getTokensAfter(this);
|
|
1219
|
+
}
|
|
1220
|
+
getPatternsAfter(childReference) {
|
|
1221
|
+
let index = -1;
|
|
1222
|
+
const patterns = [];
|
|
1128
1223
|
for (let i = 0; i < this._children.length; i++) {
|
|
1129
|
-
if (this._children[i] ===
|
|
1224
|
+
if (this._children[i] === childReference) {
|
|
1130
1225
|
index = i;
|
|
1131
1226
|
}
|
|
1132
1227
|
}
|
|
1228
|
+
// If the last match isn't a child of this pattern.
|
|
1133
1229
|
if (index === -1) {
|
|
1134
1230
|
return [];
|
|
1135
1231
|
}
|
|
1232
|
+
// If the last match was the repeated patterns, then suggest the divider.
|
|
1136
1233
|
if (index === 0 && this._divider) {
|
|
1137
|
-
|
|
1234
|
+
patterns.push(this._children[1]);
|
|
1138
1235
|
if (this._parent) {
|
|
1139
|
-
|
|
1236
|
+
patterns.push(...this._parent.getPatternsAfter(this));
|
|
1140
1237
|
}
|
|
1141
1238
|
}
|
|
1239
|
+
// Suggest the pattern because the divider was the last match.
|
|
1142
1240
|
if (index === 1) {
|
|
1143
|
-
|
|
1241
|
+
patterns.push(this._children[0]);
|
|
1144
1242
|
}
|
|
1145
1243
|
if (index === 0 && !this._divider && this._parent) {
|
|
1146
|
-
|
|
1147
|
-
|
|
1244
|
+
patterns.push(this._children[0]);
|
|
1245
|
+
patterns.push(...this._parent.getPatternsAfter(this));
|
|
1148
1246
|
}
|
|
1149
|
-
return
|
|
1247
|
+
return patterns;
|
|
1150
1248
|
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1249
|
+
getNextPatterns() {
|
|
1250
|
+
if (this.parent == null) {
|
|
1251
|
+
return [];
|
|
1252
|
+
}
|
|
1253
|
+
return this.parent.getPatternsAfter(this);
|
|
1153
1254
|
}
|
|
1154
|
-
findPattern(
|
|
1155
|
-
return findPattern(this,
|
|
1255
|
+
findPattern(predicate) {
|
|
1256
|
+
return findPattern(this, predicate);
|
|
1156
1257
|
}
|
|
1157
1258
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
1158
|
-
|
|
1159
|
-
repeat._shouldReduceAst = this._shouldReduceAst;
|
|
1160
|
-
return repeat;
|
|
1259
|
+
return new Repeat(name, this._pattern, this._divider, isOptional);
|
|
1161
1260
|
}
|
|
1162
1261
|
}
|
|
1163
1262
|
|
|
@@ -1168,9 +1267,6 @@
|
|
|
1168
1267
|
get name() {
|
|
1169
1268
|
return this._name;
|
|
1170
1269
|
}
|
|
1171
|
-
get isOptional() {
|
|
1172
|
-
return this._isOptional;
|
|
1173
|
-
}
|
|
1174
1270
|
get parent() {
|
|
1175
1271
|
return this._parent;
|
|
1176
1272
|
}
|
|
@@ -1180,6 +1276,9 @@
|
|
|
1180
1276
|
get children() {
|
|
1181
1277
|
return this._children;
|
|
1182
1278
|
}
|
|
1279
|
+
get isOptional() {
|
|
1280
|
+
return this._isOptional;
|
|
1281
|
+
}
|
|
1183
1282
|
constructor(name, isOptional = false) {
|
|
1184
1283
|
this._type = "reference";
|
|
1185
1284
|
this._name = name;
|
|
@@ -1188,35 +1287,22 @@
|
|
|
1188
1287
|
this._pattern = null;
|
|
1189
1288
|
this._children = [];
|
|
1190
1289
|
}
|
|
1191
|
-
|
|
1290
|
+
test(text) {
|
|
1291
|
+
const cursor = new Cursor(text);
|
|
1292
|
+
const ast = this.parse(cursor);
|
|
1293
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1294
|
+
}
|
|
1295
|
+
exec(text) {
|
|
1192
1296
|
const cursor = new Cursor(text);
|
|
1193
1297
|
const ast = this.parse(cursor);
|
|
1194
1298
|
return {
|
|
1195
|
-
ast,
|
|
1299
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
1196
1300
|
cursor
|
|
1197
1301
|
};
|
|
1198
1302
|
}
|
|
1199
1303
|
parse(cursor) {
|
|
1200
1304
|
return this._getPatternSafely().parse(cursor);
|
|
1201
1305
|
}
|
|
1202
|
-
clone(name = this._name, isOptional = this._isOptional) {
|
|
1203
|
-
return new Reference(name, isOptional);
|
|
1204
|
-
}
|
|
1205
|
-
getTokens() {
|
|
1206
|
-
return this._getPatternSafely().getTokens();
|
|
1207
|
-
}
|
|
1208
|
-
getNextTokens(_lastMatched) {
|
|
1209
|
-
if (this.parent == null) {
|
|
1210
|
-
return [];
|
|
1211
|
-
}
|
|
1212
|
-
return this.parent.getNextTokens(this);
|
|
1213
|
-
}
|
|
1214
|
-
getNextPattern() {
|
|
1215
|
-
return getNextPattern(this);
|
|
1216
|
-
}
|
|
1217
|
-
findPattern(_isMatch) {
|
|
1218
|
-
return null;
|
|
1219
|
-
}
|
|
1220
1306
|
_getPatternSafely() {
|
|
1221
1307
|
if (this._pattern === null) {
|
|
1222
1308
|
const pattern = this._findPattern();
|
|
@@ -1249,10 +1335,189 @@
|
|
|
1249
1335
|
}
|
|
1250
1336
|
return node;
|
|
1251
1337
|
}
|
|
1338
|
+
getTokens() {
|
|
1339
|
+
return this._getPatternSafely().getTokens();
|
|
1340
|
+
}
|
|
1341
|
+
getTokensAfter(_lastMatched) {
|
|
1342
|
+
if (this._parent == null) {
|
|
1343
|
+
return [];
|
|
1344
|
+
}
|
|
1345
|
+
return this._parent.getTokensAfter(this);
|
|
1346
|
+
}
|
|
1347
|
+
getNextTokens() {
|
|
1348
|
+
if (this.parent == null) {
|
|
1349
|
+
return [];
|
|
1350
|
+
}
|
|
1351
|
+
return this.parent.getTokensAfter(this);
|
|
1352
|
+
}
|
|
1353
|
+
getPatternsAfter(_childReference) {
|
|
1354
|
+
if (this._parent == null) {
|
|
1355
|
+
return [];
|
|
1356
|
+
}
|
|
1357
|
+
return this._parent.getPatternsAfter(this);
|
|
1358
|
+
}
|
|
1359
|
+
getNextPatterns() {
|
|
1360
|
+
if (this.parent == null) {
|
|
1361
|
+
return [];
|
|
1362
|
+
}
|
|
1363
|
+
return this.parent.getPatternsAfter(this);
|
|
1364
|
+
}
|
|
1365
|
+
findPattern(_predicate) {
|
|
1366
|
+
return null;
|
|
1367
|
+
}
|
|
1368
|
+
clone(name = this._name, isOptional = this._isOptional) {
|
|
1369
|
+
return new Reference(name, isOptional);
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
const defaultOptions = { greedyPatternNames: [], customTokens: {} };
|
|
1374
|
+
class AutoComplete {
|
|
1375
|
+
constructor(pattern, options = defaultOptions) {
|
|
1376
|
+
this._pattern = pattern;
|
|
1377
|
+
this._options = options;
|
|
1378
|
+
this._text = "";
|
|
1379
|
+
}
|
|
1380
|
+
suggest(text) {
|
|
1381
|
+
if (text.length === 0) {
|
|
1382
|
+
return {
|
|
1383
|
+
isComplete: false,
|
|
1384
|
+
options: this.createSuggestionsFromRoot(),
|
|
1385
|
+
nextPatterns: [this._pattern],
|
|
1386
|
+
cursor: null,
|
|
1387
|
+
ast: null
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1390
|
+
this._text = text;
|
|
1391
|
+
this._cursor = new Cursor(text);
|
|
1392
|
+
const ast = this._pattern.parse(this._cursor);
|
|
1393
|
+
const leafPattern = this._cursor.leafMatch.pattern;
|
|
1394
|
+
const isComplete = (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1395
|
+
const options = this.createSuggestionsFromTokens();
|
|
1396
|
+
let nextPatterns = [this._pattern];
|
|
1397
|
+
if (leafPattern != null) {
|
|
1398
|
+
nextPatterns = leafPattern.getNextPatterns();
|
|
1399
|
+
}
|
|
1400
|
+
return {
|
|
1401
|
+
isComplete: isComplete,
|
|
1402
|
+
options: options,
|
|
1403
|
+
nextPatterns,
|
|
1404
|
+
cursor: this._cursor,
|
|
1405
|
+
ast,
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1408
|
+
createSuggestionsFromRoot() {
|
|
1409
|
+
const suggestions = [];
|
|
1410
|
+
const tokens = this._pattern.getTokens();
|
|
1411
|
+
for (const token of tokens) {
|
|
1412
|
+
suggestions.push(this.createSuggestion("", token));
|
|
1413
|
+
}
|
|
1414
|
+
return suggestions;
|
|
1415
|
+
}
|
|
1416
|
+
createSuggestionsFromTokens() {
|
|
1417
|
+
const leafMatch = this._cursor.leafMatch;
|
|
1418
|
+
if (!leafMatch.pattern) {
|
|
1419
|
+
return this.createSuggestions(-1, this._getTokensForPattern(this._pattern));
|
|
1420
|
+
}
|
|
1421
|
+
const leafPattern = leafMatch.pattern;
|
|
1422
|
+
leafMatch.node;
|
|
1423
|
+
const parent = leafMatch.pattern.parent;
|
|
1424
|
+
if (parent !== null && leafMatch.node != null) {
|
|
1425
|
+
const patterns = leafPattern.getNextPatterns();
|
|
1426
|
+
const tokens = patterns.reduce((acc, pattern) => {
|
|
1427
|
+
acc.push(...this._getTokensForPattern(pattern));
|
|
1428
|
+
return acc;
|
|
1429
|
+
}, []);
|
|
1430
|
+
return this.createSuggestions(leafMatch.node.lastIndex, tokens);
|
|
1431
|
+
}
|
|
1432
|
+
else {
|
|
1433
|
+
return [];
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
_getTokensForPattern(pattern) {
|
|
1437
|
+
if (this._options.greedyPatternNames.includes(pattern.name)) {
|
|
1438
|
+
const greedyTokens = pattern.getTokens();
|
|
1439
|
+
const nextPatterns = pattern.getNextPatterns();
|
|
1440
|
+
const tokens = [];
|
|
1441
|
+
const nextPatternTokens = nextPatterns.reduce((acc, pattern) => {
|
|
1442
|
+
acc.push(...this._getTokensForPattern(pattern));
|
|
1443
|
+
return acc;
|
|
1444
|
+
}, []);
|
|
1445
|
+
for (let token of greedyTokens) {
|
|
1446
|
+
for (let nextPatternToken of nextPatternTokens) {
|
|
1447
|
+
tokens.push(token + nextPatternToken);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
return tokens;
|
|
1451
|
+
}
|
|
1452
|
+
else {
|
|
1453
|
+
const tokens = pattern.getTokens();
|
|
1454
|
+
const customTokens = this._options.customTokens[pattern.name] || [];
|
|
1455
|
+
tokens.push(...customTokens);
|
|
1456
|
+
return tokens;
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
createSuggestions(lastIndex, tokens) {
|
|
1460
|
+
let substring = lastIndex === -1 ? "" : this._cursor.getChars(0, lastIndex);
|
|
1461
|
+
const suggestionStrings = [];
|
|
1462
|
+
const options = [];
|
|
1463
|
+
for (const token of tokens) {
|
|
1464
|
+
const suggestion = substring + token;
|
|
1465
|
+
const startsWith = suggestion.startsWith(substring);
|
|
1466
|
+
const alreadyExist = suggestionStrings.includes(suggestion);
|
|
1467
|
+
const isSameAsText = suggestion === this._text;
|
|
1468
|
+
if (startsWith && !alreadyExist && !isSameAsText) {
|
|
1469
|
+
suggestionStrings.push(suggestion);
|
|
1470
|
+
options.push(this.createSuggestion(this._cursor.text, suggestion));
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
const reducedOptions = getFurthestOptions(options);
|
|
1474
|
+
reducedOptions.sort((a, b) => a.text.localeCompare(b.text));
|
|
1475
|
+
return reducedOptions;
|
|
1476
|
+
}
|
|
1477
|
+
createSuggestion(fullText, suggestion) {
|
|
1478
|
+
const furthestMatch = findMatchIndex(suggestion, fullText);
|
|
1479
|
+
const text = suggestion.slice(furthestMatch);
|
|
1480
|
+
return {
|
|
1481
|
+
text: text,
|
|
1482
|
+
startIndex: furthestMatch,
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
function findMatchIndex(str1, str2) {
|
|
1487
|
+
let matchCount = 0;
|
|
1488
|
+
let minLength = str1.length;
|
|
1489
|
+
if (str2.length < minLength) {
|
|
1490
|
+
minLength = str2.length;
|
|
1491
|
+
}
|
|
1492
|
+
for (let i = 0; i < minLength; i++) {
|
|
1493
|
+
if (str1[i] === str2[i]) {
|
|
1494
|
+
matchCount++;
|
|
1495
|
+
}
|
|
1496
|
+
else {
|
|
1497
|
+
break;
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
return matchCount;
|
|
1501
|
+
}
|
|
1502
|
+
function getFurthestOptions(options) {
|
|
1503
|
+
let furthestOptions = [];
|
|
1504
|
+
let furthestIndex = -1;
|
|
1505
|
+
for (const option of options) {
|
|
1506
|
+
if (option.startIndex > furthestIndex) {
|
|
1507
|
+
furthestIndex = option.startIndex;
|
|
1508
|
+
furthestOptions = [];
|
|
1509
|
+
}
|
|
1510
|
+
if (option.startIndex === furthestIndex) {
|
|
1511
|
+
furthestOptions.push(option);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
return furthestOptions;
|
|
1252
1515
|
}
|
|
1253
1516
|
|
|
1254
1517
|
exports.And = And;
|
|
1518
|
+
exports.AutoComplete = AutoComplete;
|
|
1255
1519
|
exports.Cursor = Cursor;
|
|
1520
|
+
exports.CursorHistory = CursorHistory;
|
|
1256
1521
|
exports.Literal = Literal;
|
|
1257
1522
|
exports.Node = Node;
|
|
1258
1523
|
exports.Not = Not;
|