clarity-pattern-parser 11.4.1 → 11.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.browser.js +75 -45
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +75 -45
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +75 -45
- 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/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/index.js
CHANGED
|
@@ -431,9 +431,10 @@ class CursorHistory {
|
|
|
431
431
|
}
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
+
const segmenter = new Intl.Segmenter("und", { granularity: "grapheme" });
|
|
434
435
|
class Cursor {
|
|
435
436
|
get text() {
|
|
436
|
-
return this.
|
|
437
|
+
return this._text;
|
|
437
438
|
}
|
|
438
439
|
get isOnFirst() {
|
|
439
440
|
return this._index === 0;
|
|
@@ -481,33 +482,55 @@ class Cursor {
|
|
|
481
482
|
return this._history.error != null;
|
|
482
483
|
}
|
|
483
484
|
get currentChar() {
|
|
484
|
-
|
|
485
|
+
const index = this.getCharStartIndex(this._index);
|
|
486
|
+
return this.text.slice(index, index + this._charSize[index]);
|
|
485
487
|
}
|
|
486
488
|
constructor(text) {
|
|
487
|
-
this.
|
|
489
|
+
this._text = text;
|
|
490
|
+
this._length = text.length;
|
|
491
|
+
this._charSize = [];
|
|
492
|
+
this._charMap = [];
|
|
488
493
|
this._index = 0;
|
|
489
|
-
this._length = this._chars.length;
|
|
490
494
|
this._history = new CursorHistory();
|
|
495
|
+
let index = 0;
|
|
496
|
+
for (const segment of segmenter.segment(text)) {
|
|
497
|
+
const size = segment.segment.length;
|
|
498
|
+
for (let i = 0; i < size; i++) {
|
|
499
|
+
this._charMap.push(index);
|
|
500
|
+
this._charSize.push(size);
|
|
501
|
+
}
|
|
502
|
+
index += size;
|
|
503
|
+
}
|
|
491
504
|
}
|
|
492
505
|
hasNext() {
|
|
493
|
-
|
|
506
|
+
const index = this._charMap[this._index];
|
|
507
|
+
const charSize = this._charSize[index];
|
|
508
|
+
return index + charSize < this._length;
|
|
494
509
|
}
|
|
495
510
|
next() {
|
|
496
511
|
if (this.hasNext()) {
|
|
497
|
-
this._index
|
|
512
|
+
const index = this._charMap[this._index];
|
|
513
|
+
const size = this._charSize[index];
|
|
514
|
+
this.moveTo(index + size);
|
|
498
515
|
}
|
|
499
516
|
}
|
|
500
517
|
hasPrevious() {
|
|
501
|
-
|
|
518
|
+
var _a;
|
|
519
|
+
const index = this._charMap[this._index];
|
|
520
|
+
const previousIndex = (_a = this._charMap[index - 1]) !== null && _a !== void 0 ? _a : -1;
|
|
521
|
+
return previousIndex >= 0;
|
|
502
522
|
}
|
|
503
523
|
previous() {
|
|
524
|
+
var _a;
|
|
504
525
|
if (this.hasPrevious()) {
|
|
505
|
-
this._index
|
|
526
|
+
const index = this._charMap[this._index];
|
|
527
|
+
const previousIndex = (_a = this._charMap[index - 1]) !== null && _a !== void 0 ? _a : -1;
|
|
528
|
+
this.moveTo(previousIndex);
|
|
506
529
|
}
|
|
507
530
|
}
|
|
508
531
|
moveTo(position) {
|
|
509
532
|
if (position >= 0 && position < this._length) {
|
|
510
|
-
this._index = position;
|
|
533
|
+
this._index = this._charMap[position];
|
|
511
534
|
}
|
|
512
535
|
}
|
|
513
536
|
moveToFirstChar() {
|
|
@@ -519,8 +542,8 @@ class Cursor {
|
|
|
519
542
|
getLastIndex() {
|
|
520
543
|
return this._length - 1;
|
|
521
544
|
}
|
|
522
|
-
|
|
523
|
-
return this.
|
|
545
|
+
substring(first, last) {
|
|
546
|
+
return this._text.slice(first, last + 1);
|
|
524
547
|
}
|
|
525
548
|
recordMatch(pattern, node) {
|
|
526
549
|
this._history.recordMatch(pattern, node);
|
|
@@ -537,6 +560,18 @@ class Cursor {
|
|
|
537
560
|
stopRecording() {
|
|
538
561
|
this._history.stopRecording();
|
|
539
562
|
}
|
|
563
|
+
getCharStartIndex(index) {
|
|
564
|
+
return this._charMap[index];
|
|
565
|
+
}
|
|
566
|
+
getCharEndIndex(index) {
|
|
567
|
+
var _a;
|
|
568
|
+
let startIndex = this.getCharStartIndex(index);
|
|
569
|
+
return (_a = startIndex + this._charSize[startIndex]) !== null && _a !== void 0 ? _a : 1;
|
|
570
|
+
}
|
|
571
|
+
getCharLastIndex(index) {
|
|
572
|
+
var _a;
|
|
573
|
+
return (_a = this.getCharEndIndex(index) - 1) !== null && _a !== void 0 ? _a : 0;
|
|
574
|
+
}
|
|
540
575
|
}
|
|
541
576
|
|
|
542
577
|
function execPattern(pattern, text, record = false) {
|
|
@@ -602,11 +637,9 @@ class Literal {
|
|
|
602
637
|
this._type = "literal";
|
|
603
638
|
this._name = name;
|
|
604
639
|
this._token = value;
|
|
605
|
-
this._runes = Array.from(value);
|
|
606
640
|
this._parent = null;
|
|
607
641
|
this._firstIndex = 0;
|
|
608
642
|
this._lastIndex = 0;
|
|
609
|
-
this._endIndex = 0;
|
|
610
643
|
}
|
|
611
644
|
test(text, record = false) {
|
|
612
645
|
return testPattern(this, text, record);
|
|
@@ -616,6 +649,7 @@ class Literal {
|
|
|
616
649
|
}
|
|
617
650
|
parse(cursor) {
|
|
618
651
|
this._firstIndex = cursor.index;
|
|
652
|
+
this._lastIndex = cursor.index;
|
|
619
653
|
const passed = this._tryToParse(cursor);
|
|
620
654
|
if (passed) {
|
|
621
655
|
cursor.resolveError();
|
|
@@ -623,31 +657,28 @@ class Literal {
|
|
|
623
657
|
cursor.recordMatch(this, node);
|
|
624
658
|
return node;
|
|
625
659
|
}
|
|
626
|
-
cursor.recordErrorAt(this._firstIndex, this.
|
|
660
|
+
cursor.recordErrorAt(this._firstIndex, this._lastIndex, this);
|
|
627
661
|
return null;
|
|
628
662
|
}
|
|
629
663
|
_tryToParse(cursor) {
|
|
630
|
-
|
|
631
|
-
const
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
this.
|
|
637
|
-
|
|
638
|
-
}
|
|
639
|
-
if (i + 1 === literalRuneLength) {
|
|
640
|
-
this._lastIndex = this._firstIndex + this._token.length - 1;
|
|
641
|
-
passed = true;
|
|
642
|
-
break;
|
|
643
|
-
}
|
|
644
|
-
if (!cursor.hasNext()) {
|
|
645
|
-
this._endIndex = cursor.index + 1;
|
|
646
|
-
break;
|
|
664
|
+
const token = this._token;
|
|
665
|
+
const compareToToken = cursor.text.slice(this._firstIndex, this._firstIndex + this._token.length);
|
|
666
|
+
const length = Math.min(token.length, compareToToken.length);
|
|
667
|
+
for (let i = 0; i < length; i++) {
|
|
668
|
+
if (token[i] !== compareToToken[i]) {
|
|
669
|
+
this._lastIndex = this._firstIndex + i;
|
|
670
|
+
cursor.moveTo(this._lastIndex);
|
|
671
|
+
return false;
|
|
647
672
|
}
|
|
648
|
-
cursor.next();
|
|
649
673
|
}
|
|
650
|
-
|
|
674
|
+
if (token != compareToToken) {
|
|
675
|
+
this._lastIndex = this._firstIndex + compareToToken.length - 1;
|
|
676
|
+
cursor.moveTo(this._lastIndex);
|
|
677
|
+
return false;
|
|
678
|
+
}
|
|
679
|
+
this._lastIndex = this._firstIndex + this._token.length - 1;
|
|
680
|
+
cursor.moveTo(this._lastIndex);
|
|
681
|
+
return true;
|
|
651
682
|
}
|
|
652
683
|
_createNode() {
|
|
653
684
|
return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this._token);
|
|
@@ -726,7 +757,7 @@ class Regex {
|
|
|
726
757
|
this._name = name;
|
|
727
758
|
this._parent = null;
|
|
728
759
|
this._originalRegexString = regex;
|
|
729
|
-
this._regex = new RegExp(`^${regex}`, "
|
|
760
|
+
this._regex = new RegExp(`^${regex}`, "gu");
|
|
730
761
|
this.assertArguments();
|
|
731
762
|
}
|
|
732
763
|
assertArguments() {
|
|
@@ -755,7 +786,7 @@ class Regex {
|
|
|
755
786
|
resetState(cursor) {
|
|
756
787
|
this._cursor = cursor;
|
|
757
788
|
this._regex.lastIndex = 0;
|
|
758
|
-
this._substring = this._cursor.text.
|
|
789
|
+
this._substring = this._cursor.text.slice(this._cursor.index);
|
|
759
790
|
this._node = null;
|
|
760
791
|
}
|
|
761
792
|
tryToParse(cursor) {
|
|
@@ -770,10 +801,9 @@ class Regex {
|
|
|
770
801
|
processResult(cursor, result) {
|
|
771
802
|
const currentIndex = cursor.index;
|
|
772
803
|
const match = result[0];
|
|
773
|
-
const
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
cursor.moveTo(newIndex);
|
|
804
|
+
const lastIndex = cursor.getCharLastIndex(currentIndex + match.length - 1);
|
|
805
|
+
this._node = new Node("regex", this._name, currentIndex, lastIndex, undefined, result[0]);
|
|
806
|
+
cursor.moveTo(lastIndex);
|
|
777
807
|
cursor.recordMatch(this, this._node);
|
|
778
808
|
}
|
|
779
809
|
processError(cursor) {
|
|
@@ -3301,7 +3331,7 @@ class TakeUntil {
|
|
|
3301
3331
|
}
|
|
3302
3332
|
if (foundMatch) {
|
|
3303
3333
|
cursor.moveTo(cursorIndex - 1);
|
|
3304
|
-
const value = cursor.
|
|
3334
|
+
const value = cursor.substring(this.startedOnIndex, cursorIndex - 1);
|
|
3305
3335
|
const node = Node.createValueNode(this._type, this._name, value);
|
|
3306
3336
|
cursor.recordMatch(this, node);
|
|
3307
3337
|
return node;
|
|
@@ -3453,7 +3483,7 @@ function generateErrorMessage(pattern, cursor) {
|
|
|
3453
3483
|
}
|
|
3454
3484
|
const lastPattern = furthestMatch.pattern;
|
|
3455
3485
|
const suggestions = cleanSuggestions(lastPattern.getNextTokens());
|
|
3456
|
-
const strUpToError = cursor.
|
|
3486
|
+
const strUpToError = cursor.substring(0, endIndex);
|
|
3457
3487
|
const lines = strUpToError.split("\n");
|
|
3458
3488
|
const lastLine = lines[lines.length - 1];
|
|
3459
3489
|
const line = lines.length;
|
|
@@ -4191,9 +4221,9 @@ class AutoComplete {
|
|
|
4191
4221
|
}
|
|
4192
4222
|
_createSuggestionOptionsFromErrors() {
|
|
4193
4223
|
// These errored because the length of the string.
|
|
4194
|
-
const errors = this._cursor.errors.filter(e => e.lastIndex === this._cursor.length);
|
|
4224
|
+
const errors = this._cursor.errors.filter(e => e.lastIndex === this._cursor.length - 1);
|
|
4195
4225
|
const errorSuggestionOptions = errors.map(parseError => {
|
|
4196
|
-
const currentText = this._cursor.
|
|
4226
|
+
const currentText = this._cursor.substring(parseError.startIndex, parseError.lastIndex);
|
|
4197
4227
|
const compositeSuggestions = this._getCompositeSuggestionsForPattern(parseError.pattern);
|
|
4198
4228
|
const trimmedErrorCompositeSuggestions = this._trimSuggestionsByExistingText(currentText, compositeSuggestions);
|
|
4199
4229
|
return this._createSuggestions(parseError.lastIndex, trimmedErrorCompositeSuggestions);
|
|
@@ -4249,7 +4279,7 @@ class AutoComplete {
|
|
|
4249
4279
|
* ie. sequence pattern segments ≈ [{look}, {an example}, {phrase}]
|
|
4250
4280
|
* fullText = "look an"
|
|
4251
4281
|
* remove {look} segment as its already been completed by the existing text.
|
|
4252
|
-
|
|
4282
|
+
*/
|
|
4253
4283
|
_filterCompletedSubSegments(currentText, compositeSuggestion) {
|
|
4254
4284
|
let elementsToRemove = [];
|
|
4255
4285
|
let workingText = currentText;
|
|
@@ -4352,7 +4382,7 @@ class AutoComplete {
|
|
|
4352
4382
|
return unique;
|
|
4353
4383
|
}
|
|
4354
4384
|
_createSuggestions(lastIndex, compositeSuggestionList) {
|
|
4355
|
-
let textToIndex = lastIndex === -1 ? "" : this._cursor.
|
|
4385
|
+
let textToIndex = lastIndex === -1 ? "" : this._cursor.substring(0, lastIndex);
|
|
4356
4386
|
const options = [];
|
|
4357
4387
|
for (const compositeSuggestion of compositeSuggestionList) {
|
|
4358
4388
|
// concatenated for start index identification inside createSuggestion
|