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.esm.js
CHANGED
|
@@ -427,9 +427,10 @@ class CursorHistory {
|
|
|
427
427
|
}
|
|
428
428
|
}
|
|
429
429
|
|
|
430
|
+
const segmenter = new Intl.Segmenter("und", { granularity: "grapheme" });
|
|
430
431
|
class Cursor {
|
|
431
432
|
get text() {
|
|
432
|
-
return this.
|
|
433
|
+
return this._text;
|
|
433
434
|
}
|
|
434
435
|
get isOnFirst() {
|
|
435
436
|
return this._index === 0;
|
|
@@ -477,33 +478,55 @@ class Cursor {
|
|
|
477
478
|
return this._history.error != null;
|
|
478
479
|
}
|
|
479
480
|
get currentChar() {
|
|
480
|
-
|
|
481
|
+
const index = this.getCharStartIndex(this._index);
|
|
482
|
+
return this.text.slice(index, index + this._charSize[index]);
|
|
481
483
|
}
|
|
482
484
|
constructor(text) {
|
|
483
|
-
this.
|
|
485
|
+
this._text = text;
|
|
486
|
+
this._length = text.length;
|
|
487
|
+
this._charSize = [];
|
|
488
|
+
this._charMap = [];
|
|
484
489
|
this._index = 0;
|
|
485
|
-
this._length = this._chars.length;
|
|
486
490
|
this._history = new CursorHistory();
|
|
491
|
+
let index = 0;
|
|
492
|
+
for (const segment of segmenter.segment(text)) {
|
|
493
|
+
const size = segment.segment.length;
|
|
494
|
+
for (let i = 0; i < size; i++) {
|
|
495
|
+
this._charMap.push(index);
|
|
496
|
+
this._charSize.push(size);
|
|
497
|
+
}
|
|
498
|
+
index += size;
|
|
499
|
+
}
|
|
487
500
|
}
|
|
488
501
|
hasNext() {
|
|
489
|
-
|
|
502
|
+
const index = this._charMap[this._index];
|
|
503
|
+
const charSize = this._charSize[index];
|
|
504
|
+
return index + charSize < this._length;
|
|
490
505
|
}
|
|
491
506
|
next() {
|
|
492
507
|
if (this.hasNext()) {
|
|
493
|
-
this._index
|
|
508
|
+
const index = this._charMap[this._index];
|
|
509
|
+
const size = this._charSize[index];
|
|
510
|
+
this.moveTo(index + size);
|
|
494
511
|
}
|
|
495
512
|
}
|
|
496
513
|
hasPrevious() {
|
|
497
|
-
|
|
514
|
+
var _a;
|
|
515
|
+
const index = this._charMap[this._index];
|
|
516
|
+
const previousIndex = (_a = this._charMap[index - 1]) !== null && _a !== void 0 ? _a : -1;
|
|
517
|
+
return previousIndex >= 0;
|
|
498
518
|
}
|
|
499
519
|
previous() {
|
|
520
|
+
var _a;
|
|
500
521
|
if (this.hasPrevious()) {
|
|
501
|
-
this._index
|
|
522
|
+
const index = this._charMap[this._index];
|
|
523
|
+
const previousIndex = (_a = this._charMap[index - 1]) !== null && _a !== void 0 ? _a : -1;
|
|
524
|
+
this.moveTo(previousIndex);
|
|
502
525
|
}
|
|
503
526
|
}
|
|
504
527
|
moveTo(position) {
|
|
505
528
|
if (position >= 0 && position < this._length) {
|
|
506
|
-
this._index = position;
|
|
529
|
+
this._index = this._charMap[position];
|
|
507
530
|
}
|
|
508
531
|
}
|
|
509
532
|
moveToFirstChar() {
|
|
@@ -515,8 +538,8 @@ class Cursor {
|
|
|
515
538
|
getLastIndex() {
|
|
516
539
|
return this._length - 1;
|
|
517
540
|
}
|
|
518
|
-
|
|
519
|
-
return this.
|
|
541
|
+
substring(first, last) {
|
|
542
|
+
return this._text.slice(first, last + 1);
|
|
520
543
|
}
|
|
521
544
|
recordMatch(pattern, node) {
|
|
522
545
|
this._history.recordMatch(pattern, node);
|
|
@@ -533,6 +556,18 @@ class Cursor {
|
|
|
533
556
|
stopRecording() {
|
|
534
557
|
this._history.stopRecording();
|
|
535
558
|
}
|
|
559
|
+
getCharStartIndex(index) {
|
|
560
|
+
return this._charMap[index];
|
|
561
|
+
}
|
|
562
|
+
getCharEndIndex(index) {
|
|
563
|
+
var _a;
|
|
564
|
+
let startIndex = this.getCharStartIndex(index);
|
|
565
|
+
return (_a = startIndex + this._charSize[startIndex]) !== null && _a !== void 0 ? _a : 1;
|
|
566
|
+
}
|
|
567
|
+
getCharLastIndex(index) {
|
|
568
|
+
var _a;
|
|
569
|
+
return (_a = this.getCharEndIndex(index) - 1) !== null && _a !== void 0 ? _a : 0;
|
|
570
|
+
}
|
|
536
571
|
}
|
|
537
572
|
|
|
538
573
|
function execPattern(pattern, text, record = false) {
|
|
@@ -598,11 +633,9 @@ class Literal {
|
|
|
598
633
|
this._type = "literal";
|
|
599
634
|
this._name = name;
|
|
600
635
|
this._token = value;
|
|
601
|
-
this._runes = Array.from(value);
|
|
602
636
|
this._parent = null;
|
|
603
637
|
this._firstIndex = 0;
|
|
604
638
|
this._lastIndex = 0;
|
|
605
|
-
this._endIndex = 0;
|
|
606
639
|
}
|
|
607
640
|
test(text, record = false) {
|
|
608
641
|
return testPattern(this, text, record);
|
|
@@ -612,6 +645,7 @@ class Literal {
|
|
|
612
645
|
}
|
|
613
646
|
parse(cursor) {
|
|
614
647
|
this._firstIndex = cursor.index;
|
|
648
|
+
this._lastIndex = cursor.index;
|
|
615
649
|
const passed = this._tryToParse(cursor);
|
|
616
650
|
if (passed) {
|
|
617
651
|
cursor.resolveError();
|
|
@@ -619,31 +653,28 @@ class Literal {
|
|
|
619
653
|
cursor.recordMatch(this, node);
|
|
620
654
|
return node;
|
|
621
655
|
}
|
|
622
|
-
cursor.recordErrorAt(this._firstIndex, this.
|
|
656
|
+
cursor.recordErrorAt(this._firstIndex, this._lastIndex, this);
|
|
623
657
|
return null;
|
|
624
658
|
}
|
|
625
659
|
_tryToParse(cursor) {
|
|
626
|
-
|
|
627
|
-
const
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
this.
|
|
633
|
-
|
|
634
|
-
}
|
|
635
|
-
if (i + 1 === literalRuneLength) {
|
|
636
|
-
this._lastIndex = this._firstIndex + this._token.length - 1;
|
|
637
|
-
passed = true;
|
|
638
|
-
break;
|
|
639
|
-
}
|
|
640
|
-
if (!cursor.hasNext()) {
|
|
641
|
-
this._endIndex = cursor.index + 1;
|
|
642
|
-
break;
|
|
660
|
+
const token = this._token;
|
|
661
|
+
const compareToToken = cursor.text.slice(this._firstIndex, this._firstIndex + this._token.length);
|
|
662
|
+
const length = Math.min(token.length, compareToToken.length);
|
|
663
|
+
for (let i = 0; i < length; i++) {
|
|
664
|
+
if (token[i] !== compareToToken[i]) {
|
|
665
|
+
this._lastIndex = this._firstIndex + i;
|
|
666
|
+
cursor.moveTo(this._lastIndex);
|
|
667
|
+
return false;
|
|
643
668
|
}
|
|
644
|
-
cursor.next();
|
|
645
669
|
}
|
|
646
|
-
|
|
670
|
+
if (token != compareToToken) {
|
|
671
|
+
this._lastIndex = this._firstIndex + compareToToken.length - 1;
|
|
672
|
+
cursor.moveTo(this._lastIndex);
|
|
673
|
+
return false;
|
|
674
|
+
}
|
|
675
|
+
this._lastIndex = this._firstIndex + this._token.length - 1;
|
|
676
|
+
cursor.moveTo(this._lastIndex);
|
|
677
|
+
return true;
|
|
647
678
|
}
|
|
648
679
|
_createNode() {
|
|
649
680
|
return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this._token);
|
|
@@ -722,7 +753,7 @@ class Regex {
|
|
|
722
753
|
this._name = name;
|
|
723
754
|
this._parent = null;
|
|
724
755
|
this._originalRegexString = regex;
|
|
725
|
-
this._regex = new RegExp(`^${regex}`, "
|
|
756
|
+
this._regex = new RegExp(`^${regex}`, "gu");
|
|
726
757
|
this.assertArguments();
|
|
727
758
|
}
|
|
728
759
|
assertArguments() {
|
|
@@ -751,7 +782,7 @@ class Regex {
|
|
|
751
782
|
resetState(cursor) {
|
|
752
783
|
this._cursor = cursor;
|
|
753
784
|
this._regex.lastIndex = 0;
|
|
754
|
-
this._substring = this._cursor.text.
|
|
785
|
+
this._substring = this._cursor.text.slice(this._cursor.index);
|
|
755
786
|
this._node = null;
|
|
756
787
|
}
|
|
757
788
|
tryToParse(cursor) {
|
|
@@ -766,10 +797,9 @@ class Regex {
|
|
|
766
797
|
processResult(cursor, result) {
|
|
767
798
|
const currentIndex = cursor.index;
|
|
768
799
|
const match = result[0];
|
|
769
|
-
const
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
cursor.moveTo(newIndex);
|
|
800
|
+
const lastIndex = cursor.getCharLastIndex(currentIndex + match.length - 1);
|
|
801
|
+
this._node = new Node("regex", this._name, currentIndex, lastIndex, undefined, result[0]);
|
|
802
|
+
cursor.moveTo(lastIndex);
|
|
773
803
|
cursor.recordMatch(this, this._node);
|
|
774
804
|
}
|
|
775
805
|
processError(cursor) {
|
|
@@ -3297,7 +3327,7 @@ class TakeUntil {
|
|
|
3297
3327
|
}
|
|
3298
3328
|
if (foundMatch) {
|
|
3299
3329
|
cursor.moveTo(cursorIndex - 1);
|
|
3300
|
-
const value = cursor.
|
|
3330
|
+
const value = cursor.substring(this.startedOnIndex, cursorIndex - 1);
|
|
3301
3331
|
const node = Node.createValueNode(this._type, this._name, value);
|
|
3302
3332
|
cursor.recordMatch(this, node);
|
|
3303
3333
|
return node;
|
|
@@ -3449,7 +3479,7 @@ function generateErrorMessage(pattern, cursor) {
|
|
|
3449
3479
|
}
|
|
3450
3480
|
const lastPattern = furthestMatch.pattern;
|
|
3451
3481
|
const suggestions = cleanSuggestions(lastPattern.getNextTokens());
|
|
3452
|
-
const strUpToError = cursor.
|
|
3482
|
+
const strUpToError = cursor.substring(0, endIndex);
|
|
3453
3483
|
const lines = strUpToError.split("\n");
|
|
3454
3484
|
const lastLine = lines[lines.length - 1];
|
|
3455
3485
|
const line = lines.length;
|
|
@@ -4187,9 +4217,9 @@ class AutoComplete {
|
|
|
4187
4217
|
}
|
|
4188
4218
|
_createSuggestionOptionsFromErrors() {
|
|
4189
4219
|
// These errored because the length of the string.
|
|
4190
|
-
const errors = this._cursor.errors.filter(e => e.lastIndex === this._cursor.length);
|
|
4220
|
+
const errors = this._cursor.errors.filter(e => e.lastIndex === this._cursor.length - 1);
|
|
4191
4221
|
const errorSuggestionOptions = errors.map(parseError => {
|
|
4192
|
-
const currentText = this._cursor.
|
|
4222
|
+
const currentText = this._cursor.substring(parseError.startIndex, parseError.lastIndex);
|
|
4193
4223
|
const compositeSuggestions = this._getCompositeSuggestionsForPattern(parseError.pattern);
|
|
4194
4224
|
const trimmedErrorCompositeSuggestions = this._trimSuggestionsByExistingText(currentText, compositeSuggestions);
|
|
4195
4225
|
return this._createSuggestions(parseError.lastIndex, trimmedErrorCompositeSuggestions);
|
|
@@ -4245,7 +4275,7 @@ class AutoComplete {
|
|
|
4245
4275
|
* ie. sequence pattern segments ≈ [{look}, {an example}, {phrase}]
|
|
4246
4276
|
* fullText = "look an"
|
|
4247
4277
|
* remove {look} segment as its already been completed by the existing text.
|
|
4248
|
-
|
|
4278
|
+
*/
|
|
4249
4279
|
_filterCompletedSubSegments(currentText, compositeSuggestion) {
|
|
4250
4280
|
let elementsToRemove = [];
|
|
4251
4281
|
let workingText = currentText;
|
|
@@ -4348,7 +4378,7 @@ class AutoComplete {
|
|
|
4348
4378
|
return unique;
|
|
4349
4379
|
}
|
|
4350
4380
|
_createSuggestions(lastIndex, compositeSuggestionList) {
|
|
4351
|
-
let textToIndex = lastIndex === -1 ? "" : this._cursor.
|
|
4381
|
+
let textToIndex = lastIndex === -1 ? "" : this._cursor.substring(0, lastIndex);
|
|
4352
4382
|
const options = [];
|
|
4353
4383
|
for (const compositeSuggestion of compositeSuggestionList) {
|
|
4354
4384
|
// concatenated for start index identification inside createSuggestion
|