clarity-pattern-parser 11.4.1 → 11.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast/Node.d.ts +5 -5
- package/dist/index.browser.js +118 -58
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +118 -58
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +118 -58
- package/dist/index.js.map +1 -1
- package/dist/intellisense/AutoComplete.d.ts +1 -1
- package/dist/patterns/Cursor.d.ts +7 -2
- package/dist/patterns/Literal.d.ts +0 -2
- package/package.json +1 -1
- package/src/ast/Node.test.ts +38 -0
- package/src/ast/Node.ts +41 -14
- package/src/intellisense/AutoComplete.test.ts +3 -3
- package/src/intellisense/AutoComplete.ts +86 -86
- package/src/intellisense/javascript/stringLiteral.ts +2 -2
- package/src/patterns/Cursor.test.ts +10 -2
- package/src/patterns/Cursor.ts +52 -12
- package/src/patterns/Literal.test.ts +41 -1
- package/src/patterns/Literal.ts +20 -28
- package/src/patterns/Regex.ts +6 -6
- package/src/patterns/TakeUntil.ts +1 -1
- package/src/patterns/generate_error_message.ts +1 -1
- package/tsconfig.json +1 -1
package/dist/ast/Node.d.ts
CHANGED
|
@@ -40,13 +40,13 @@ export declare class Node {
|
|
|
40
40
|
append(...nodes: Node[]): void;
|
|
41
41
|
nextSibling(): Node | null;
|
|
42
42
|
previousSibling(): Node | null;
|
|
43
|
-
find(predicate: (node: Node) => boolean): Node | null;
|
|
44
|
-
findAll(predicate: (node: Node) => boolean): Node[];
|
|
43
|
+
find(predicate: (node: Node) => boolean, breadthFirst?: boolean): Node | null;
|
|
44
|
+
findAll(predicate: (node: Node) => boolean, breadthFirst?: boolean): Node[];
|
|
45
45
|
findRoot(): Node;
|
|
46
46
|
findAncestor(predicate: (node: Node) => boolean): Node | null;
|
|
47
|
-
walkUp(callback: (node: Node) => void):
|
|
48
|
-
walkDown(callback: (node: Node) => void):
|
|
49
|
-
walkBreadthFirst(callback: (node: Node) => void):
|
|
47
|
+
walkUp(callback: (node: Node) => boolean | void): boolean;
|
|
48
|
+
walkDown(callback: (node: Node) => boolean | void): boolean;
|
|
49
|
+
walkBreadthFirst(callback: (node: Node) => boolean | void): boolean;
|
|
50
50
|
transform(visitors: Record<string, (node: Node) => Node>): Node;
|
|
51
51
|
flatten(): Node[];
|
|
52
52
|
compact(): void;
|
package/dist/index.browser.js
CHANGED
|
@@ -130,16 +130,42 @@
|
|
|
130
130
|
}
|
|
131
131
|
return null;
|
|
132
132
|
}
|
|
133
|
-
find(predicate) {
|
|
134
|
-
|
|
133
|
+
find(predicate, breadthFirst = false) {
|
|
134
|
+
let match = null;
|
|
135
|
+
if (breadthFirst) {
|
|
136
|
+
this.walkBreadthFirst(n => {
|
|
137
|
+
if (predicate(n)) {
|
|
138
|
+
match = n;
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
this.walkUp(n => {
|
|
145
|
+
if (predicate(n)) {
|
|
146
|
+
match = n;
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return match;
|
|
135
152
|
}
|
|
136
|
-
findAll(predicate) {
|
|
153
|
+
findAll(predicate, breadthFirst = false) {
|
|
137
154
|
const matches = [];
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
155
|
+
if (breadthFirst) {
|
|
156
|
+
this.walkBreadthFirst(n => {
|
|
157
|
+
if (predicate(n)) {
|
|
158
|
+
matches.push(n);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
this.walkUp(n => {
|
|
164
|
+
if (predicate(n)) {
|
|
165
|
+
matches.push(n);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
143
169
|
return matches;
|
|
144
170
|
}
|
|
145
171
|
findRoot() {
|
|
@@ -162,22 +188,26 @@
|
|
|
162
188
|
return null;
|
|
163
189
|
}
|
|
164
190
|
walkUp(callback) {
|
|
191
|
+
var _a;
|
|
165
192
|
const childrenCopy = this._children.slice();
|
|
166
|
-
childrenCopy.
|
|
167
|
-
callback(this);
|
|
193
|
+
const result = childrenCopy.every(c => c.walkUp(callback));
|
|
194
|
+
return ((_a = callback(this)) !== null && _a !== void 0 ? _a : true) && result;
|
|
168
195
|
}
|
|
169
196
|
walkDown(callback) {
|
|
197
|
+
var _a;
|
|
170
198
|
const childrenCopy = this._children.slice();
|
|
171
|
-
callback(this);
|
|
172
|
-
childrenCopy.forEach(c => c.walkDown(callback));
|
|
199
|
+
return ((_a = callback(this)) !== null && _a !== void 0 ? _a : true) && childrenCopy.every(c => c.walkDown(callback));
|
|
173
200
|
}
|
|
174
201
|
walkBreadthFirst(callback) {
|
|
175
202
|
const queue = [this];
|
|
176
203
|
while (queue.length > 0) {
|
|
177
204
|
const current = queue.shift();
|
|
178
|
-
callback(current)
|
|
205
|
+
if (callback(current) === false) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
179
208
|
queue.push(...current.children);
|
|
180
209
|
}
|
|
210
|
+
return true;
|
|
181
211
|
}
|
|
182
212
|
transform(visitors) {
|
|
183
213
|
const childrenCopy = this._children.slice();
|
|
@@ -433,9 +463,10 @@
|
|
|
433
463
|
}
|
|
434
464
|
}
|
|
435
465
|
|
|
466
|
+
const segmenter = new Intl.Segmenter("und", { granularity: "grapheme" });
|
|
436
467
|
class Cursor {
|
|
437
468
|
get text() {
|
|
438
|
-
return this.
|
|
469
|
+
return this._text;
|
|
439
470
|
}
|
|
440
471
|
get isOnFirst() {
|
|
441
472
|
return this._index === 0;
|
|
@@ -483,33 +514,55 @@
|
|
|
483
514
|
return this._history.error != null;
|
|
484
515
|
}
|
|
485
516
|
get currentChar() {
|
|
486
|
-
|
|
517
|
+
const index = this.getCharStartIndex(this._index);
|
|
518
|
+
return this.text.slice(index, index + this._charSize[index]);
|
|
487
519
|
}
|
|
488
520
|
constructor(text) {
|
|
489
|
-
this.
|
|
521
|
+
this._text = text;
|
|
522
|
+
this._length = text.length;
|
|
523
|
+
this._charSize = [];
|
|
524
|
+
this._charMap = [];
|
|
490
525
|
this._index = 0;
|
|
491
|
-
this._length = this._chars.length;
|
|
492
526
|
this._history = new CursorHistory();
|
|
527
|
+
let index = 0;
|
|
528
|
+
for (const segment of segmenter.segment(text)) {
|
|
529
|
+
const size = segment.segment.length;
|
|
530
|
+
for (let i = 0; i < size; i++) {
|
|
531
|
+
this._charMap.push(index);
|
|
532
|
+
this._charSize.push(size);
|
|
533
|
+
}
|
|
534
|
+
index += size;
|
|
535
|
+
}
|
|
493
536
|
}
|
|
494
537
|
hasNext() {
|
|
495
|
-
|
|
538
|
+
const index = this._charMap[this._index];
|
|
539
|
+
const charSize = this._charSize[index];
|
|
540
|
+
return index + charSize < this._length;
|
|
496
541
|
}
|
|
497
542
|
next() {
|
|
498
543
|
if (this.hasNext()) {
|
|
499
|
-
this._index
|
|
544
|
+
const index = this._charMap[this._index];
|
|
545
|
+
const size = this._charSize[index];
|
|
546
|
+
this.moveTo(index + size);
|
|
500
547
|
}
|
|
501
548
|
}
|
|
502
549
|
hasPrevious() {
|
|
503
|
-
|
|
550
|
+
var _a;
|
|
551
|
+
const index = this._charMap[this._index];
|
|
552
|
+
const previousIndex = (_a = this._charMap[index - 1]) !== null && _a !== void 0 ? _a : -1;
|
|
553
|
+
return previousIndex >= 0;
|
|
504
554
|
}
|
|
505
555
|
previous() {
|
|
556
|
+
var _a;
|
|
506
557
|
if (this.hasPrevious()) {
|
|
507
|
-
this._index
|
|
558
|
+
const index = this._charMap[this._index];
|
|
559
|
+
const previousIndex = (_a = this._charMap[index - 1]) !== null && _a !== void 0 ? _a : -1;
|
|
560
|
+
this.moveTo(previousIndex);
|
|
508
561
|
}
|
|
509
562
|
}
|
|
510
563
|
moveTo(position) {
|
|
511
564
|
if (position >= 0 && position < this._length) {
|
|
512
|
-
this._index = position;
|
|
565
|
+
this._index = this._charMap[position];
|
|
513
566
|
}
|
|
514
567
|
}
|
|
515
568
|
moveToFirstChar() {
|
|
@@ -521,8 +574,8 @@
|
|
|
521
574
|
getLastIndex() {
|
|
522
575
|
return this._length - 1;
|
|
523
576
|
}
|
|
524
|
-
|
|
525
|
-
return this.
|
|
577
|
+
substring(first, last) {
|
|
578
|
+
return this._text.slice(first, last + 1);
|
|
526
579
|
}
|
|
527
580
|
recordMatch(pattern, node) {
|
|
528
581
|
this._history.recordMatch(pattern, node);
|
|
@@ -539,6 +592,18 @@
|
|
|
539
592
|
stopRecording() {
|
|
540
593
|
this._history.stopRecording();
|
|
541
594
|
}
|
|
595
|
+
getCharStartIndex(index) {
|
|
596
|
+
return this._charMap[index];
|
|
597
|
+
}
|
|
598
|
+
getCharEndIndex(index) {
|
|
599
|
+
var _a;
|
|
600
|
+
let startIndex = this.getCharStartIndex(index);
|
|
601
|
+
return (_a = startIndex + this._charSize[startIndex]) !== null && _a !== void 0 ? _a : 1;
|
|
602
|
+
}
|
|
603
|
+
getCharLastIndex(index) {
|
|
604
|
+
var _a;
|
|
605
|
+
return (_a = this.getCharEndIndex(index) - 1) !== null && _a !== void 0 ? _a : 0;
|
|
606
|
+
}
|
|
542
607
|
}
|
|
543
608
|
|
|
544
609
|
function execPattern(pattern, text, record = false) {
|
|
@@ -604,11 +669,9 @@
|
|
|
604
669
|
this._type = "literal";
|
|
605
670
|
this._name = name;
|
|
606
671
|
this._token = value;
|
|
607
|
-
this._runes = Array.from(value);
|
|
608
672
|
this._parent = null;
|
|
609
673
|
this._firstIndex = 0;
|
|
610
674
|
this._lastIndex = 0;
|
|
611
|
-
this._endIndex = 0;
|
|
612
675
|
}
|
|
613
676
|
test(text, record = false) {
|
|
614
677
|
return testPattern(this, text, record);
|
|
@@ -618,6 +681,7 @@
|
|
|
618
681
|
}
|
|
619
682
|
parse(cursor) {
|
|
620
683
|
this._firstIndex = cursor.index;
|
|
684
|
+
this._lastIndex = cursor.index;
|
|
621
685
|
const passed = this._tryToParse(cursor);
|
|
622
686
|
if (passed) {
|
|
623
687
|
cursor.resolveError();
|
|
@@ -625,31 +689,28 @@
|
|
|
625
689
|
cursor.recordMatch(this, node);
|
|
626
690
|
return node;
|
|
627
691
|
}
|
|
628
|
-
cursor.recordErrorAt(this._firstIndex, this.
|
|
692
|
+
cursor.recordErrorAt(this._firstIndex, this._lastIndex, this);
|
|
629
693
|
return null;
|
|
630
694
|
}
|
|
631
695
|
_tryToParse(cursor) {
|
|
632
|
-
|
|
633
|
-
const
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
this.
|
|
639
|
-
|
|
640
|
-
}
|
|
641
|
-
if (i + 1 === literalRuneLength) {
|
|
642
|
-
this._lastIndex = this._firstIndex + this._token.length - 1;
|
|
643
|
-
passed = true;
|
|
644
|
-
break;
|
|
645
|
-
}
|
|
646
|
-
if (!cursor.hasNext()) {
|
|
647
|
-
this._endIndex = cursor.index + 1;
|
|
648
|
-
break;
|
|
696
|
+
const token = this._token;
|
|
697
|
+
const compareToToken = cursor.text.slice(this._firstIndex, this._firstIndex + this._token.length);
|
|
698
|
+
const length = Math.min(token.length, compareToToken.length);
|
|
699
|
+
for (let i = 0; i < length; i++) {
|
|
700
|
+
if (token[i] !== compareToToken[i]) {
|
|
701
|
+
this._lastIndex = this._firstIndex + i;
|
|
702
|
+
cursor.moveTo(this._lastIndex);
|
|
703
|
+
return false;
|
|
649
704
|
}
|
|
650
|
-
cursor.next();
|
|
651
705
|
}
|
|
652
|
-
|
|
706
|
+
if (token != compareToToken) {
|
|
707
|
+
this._lastIndex = this._firstIndex + compareToToken.length - 1;
|
|
708
|
+
cursor.moveTo(this._lastIndex);
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
711
|
+
this._lastIndex = this._firstIndex + this._token.length - 1;
|
|
712
|
+
cursor.moveTo(this._lastIndex);
|
|
713
|
+
return true;
|
|
653
714
|
}
|
|
654
715
|
_createNode() {
|
|
655
716
|
return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this._token);
|
|
@@ -728,7 +789,7 @@
|
|
|
728
789
|
this._name = name;
|
|
729
790
|
this._parent = null;
|
|
730
791
|
this._originalRegexString = regex;
|
|
731
|
-
this._regex = new RegExp(`^${regex}`, "
|
|
792
|
+
this._regex = new RegExp(`^${regex}`, "gu");
|
|
732
793
|
this.assertArguments();
|
|
733
794
|
}
|
|
734
795
|
assertArguments() {
|
|
@@ -757,7 +818,7 @@
|
|
|
757
818
|
resetState(cursor) {
|
|
758
819
|
this._cursor = cursor;
|
|
759
820
|
this._regex.lastIndex = 0;
|
|
760
|
-
this._substring = this._cursor.text.
|
|
821
|
+
this._substring = this._cursor.text.slice(this._cursor.index);
|
|
761
822
|
this._node = null;
|
|
762
823
|
}
|
|
763
824
|
tryToParse(cursor) {
|
|
@@ -772,10 +833,9 @@
|
|
|
772
833
|
processResult(cursor, result) {
|
|
773
834
|
const currentIndex = cursor.index;
|
|
774
835
|
const match = result[0];
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
cursor.moveTo(newIndex);
|
|
836
|
+
const lastIndex = cursor.getCharLastIndex(currentIndex + match.length - 1);
|
|
837
|
+
this._node = new Node("regex", this._name, currentIndex, lastIndex, undefined, result[0]);
|
|
838
|
+
cursor.moveTo(lastIndex);
|
|
779
839
|
cursor.recordMatch(this, this._node);
|
|
780
840
|
}
|
|
781
841
|
processError(cursor) {
|
|
@@ -3303,7 +3363,7 @@
|
|
|
3303
3363
|
}
|
|
3304
3364
|
if (foundMatch) {
|
|
3305
3365
|
cursor.moveTo(cursorIndex - 1);
|
|
3306
|
-
const value = cursor.
|
|
3366
|
+
const value = cursor.substring(this.startedOnIndex, cursorIndex - 1);
|
|
3307
3367
|
const node = Node.createValueNode(this._type, this._name, value);
|
|
3308
3368
|
cursor.recordMatch(this, node);
|
|
3309
3369
|
return node;
|
|
@@ -3455,7 +3515,7 @@
|
|
|
3455
3515
|
}
|
|
3456
3516
|
const lastPattern = furthestMatch.pattern;
|
|
3457
3517
|
const suggestions = cleanSuggestions(lastPattern.getNextTokens());
|
|
3458
|
-
const strUpToError = cursor.
|
|
3518
|
+
const strUpToError = cursor.substring(0, endIndex);
|
|
3459
3519
|
const lines = strUpToError.split("\n");
|
|
3460
3520
|
const lastLine = lines[lines.length - 1];
|
|
3461
3521
|
const line = lines.length;
|
|
@@ -4193,9 +4253,9 @@
|
|
|
4193
4253
|
}
|
|
4194
4254
|
_createSuggestionOptionsFromErrors() {
|
|
4195
4255
|
// These errored because the length of the string.
|
|
4196
|
-
const errors = this._cursor.errors.filter(e => e.lastIndex === this._cursor.length);
|
|
4256
|
+
const errors = this._cursor.errors.filter(e => e.lastIndex === this._cursor.length - 1);
|
|
4197
4257
|
const errorSuggestionOptions = errors.map(parseError => {
|
|
4198
|
-
const currentText = this._cursor.
|
|
4258
|
+
const currentText = this._cursor.substring(parseError.startIndex, parseError.lastIndex);
|
|
4199
4259
|
const compositeSuggestions = this._getCompositeSuggestionsForPattern(parseError.pattern);
|
|
4200
4260
|
const trimmedErrorCompositeSuggestions = this._trimSuggestionsByExistingText(currentText, compositeSuggestions);
|
|
4201
4261
|
return this._createSuggestions(parseError.lastIndex, trimmedErrorCompositeSuggestions);
|
|
@@ -4251,7 +4311,7 @@
|
|
|
4251
4311
|
* ie. sequence pattern segments ≈ [{look}, {an example}, {phrase}]
|
|
4252
4312
|
* fullText = "look an"
|
|
4253
4313
|
* remove {look} segment as its already been completed by the existing text.
|
|
4254
|
-
|
|
4314
|
+
*/
|
|
4255
4315
|
_filterCompletedSubSegments(currentText, compositeSuggestion) {
|
|
4256
4316
|
let elementsToRemove = [];
|
|
4257
4317
|
let workingText = currentText;
|
|
@@ -4354,7 +4414,7 @@
|
|
|
4354
4414
|
return unique;
|
|
4355
4415
|
}
|
|
4356
4416
|
_createSuggestions(lastIndex, compositeSuggestionList) {
|
|
4357
|
-
let textToIndex = lastIndex === -1 ? "" : this._cursor.
|
|
4417
|
+
let textToIndex = lastIndex === -1 ? "" : this._cursor.substring(0, lastIndex);
|
|
4358
4418
|
const options = [];
|
|
4359
4419
|
for (const compositeSuggestion of compositeSuggestionList) {
|
|
4360
4420
|
// concatenated for start index identification inside createSuggestion
|