clarity-pattern-parser 10.1.16 → 10.1.20
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 +64 -73
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +64 -73
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +64 -73
- package/dist/index.js.map +1 -1
- package/dist/intellisense/AutoComplete.d.ts +1 -0
- package/dist/patterns/Options.d.ts +0 -3
- package/dist/patterns/Sequence.d.ts +0 -1
- package/package.json +1 -1
- package/src/grammar/Grammar.test.ts +0 -3
- package/src/intellisense/AutoComplete.test.ts +1 -28
- package/src/intellisense/AutoComplete.ts +34 -18
- package/src/intellisense/javascript/Javascript.test.ts +3 -1
- package/src/patterns/DepthCache.ts +26 -0
- package/src/patterns/ExpressionPattern.ts +98 -0
- package/src/patterns/Options.ts +11 -62
- package/src/patterns/Sequence.ts +7 -20
- package/src/grammar/ComplexGrammar.test.ts +0 -16
package/dist/index.browser.js
CHANGED
|
@@ -931,9 +931,33 @@
|
|
|
931
931
|
return patterns.map(p => p.clone());
|
|
932
932
|
}
|
|
933
933
|
|
|
934
|
+
class DepthCache {
|
|
935
|
+
constructor() {
|
|
936
|
+
this._depthMap = {};
|
|
937
|
+
}
|
|
938
|
+
getDepth(name, cursorIndex) {
|
|
939
|
+
if (this._depthMap[name] == null) {
|
|
940
|
+
this._depthMap[name] = {};
|
|
941
|
+
}
|
|
942
|
+
if (this._depthMap[name][cursorIndex] == null) {
|
|
943
|
+
this._depthMap[name][cursorIndex] = 0;
|
|
944
|
+
}
|
|
945
|
+
return this._depthMap[name][cursorIndex];
|
|
946
|
+
}
|
|
947
|
+
incrementDepth(name, cursorIndex) {
|
|
948
|
+
const depth = this.getDepth(name, cursorIndex);
|
|
949
|
+
this._depthMap[name][cursorIndex] = depth + 1;
|
|
950
|
+
}
|
|
951
|
+
decrementDepth(name, cursorIndex) {
|
|
952
|
+
const depth = this.getDepth(name, cursorIndex);
|
|
953
|
+
this._depthMap[name][cursorIndex] = depth - 1;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
934
957
|
/*
|
|
935
958
|
The following is created to reduce the overhead of recursion check.
|
|
936
959
|
*/
|
|
960
|
+
const depthCache$1 = new DepthCache();
|
|
937
961
|
let idIndex$6 = 0;
|
|
938
962
|
class Options {
|
|
939
963
|
get id() {
|
|
@@ -967,34 +991,6 @@
|
|
|
967
991
|
this._children = children;
|
|
968
992
|
this._firstIndex = 0;
|
|
969
993
|
this._isGreedy = isGreedy;
|
|
970
|
-
this._recursiveDepth = this._calculateRecursiveDepth();
|
|
971
|
-
}
|
|
972
|
-
_calculateRecursiveDepth() {
|
|
973
|
-
let depth = 0;
|
|
974
|
-
this._children.forEach((child) => {
|
|
975
|
-
let hasReference = false;
|
|
976
|
-
let descendant = child.children[0];
|
|
977
|
-
while (descendant != null) {
|
|
978
|
-
if (descendant.type === "reference" && descendant.name === this.name) {
|
|
979
|
-
hasReference = true;
|
|
980
|
-
break;
|
|
981
|
-
}
|
|
982
|
-
if (descendant.type === "context") {
|
|
983
|
-
const pattern = descendant.getPatternWithinContext(this.name);
|
|
984
|
-
if (pattern != null) {
|
|
985
|
-
break;
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
descendant = descendant.children[0];
|
|
989
|
-
}
|
|
990
|
-
if (hasReference) {
|
|
991
|
-
depth++;
|
|
992
|
-
}
|
|
993
|
-
});
|
|
994
|
-
if (depth === 0) {
|
|
995
|
-
depth = this.children.length;
|
|
996
|
-
}
|
|
997
|
-
return depth;
|
|
998
994
|
}
|
|
999
995
|
_assignChildrenToParent(children) {
|
|
1000
996
|
for (const child of children) {
|
|
@@ -1018,7 +1014,10 @@
|
|
|
1018
1014
|
parse(cursor) {
|
|
1019
1015
|
// This is a cache to help with speed
|
|
1020
1016
|
this._firstIndex = cursor.index;
|
|
1017
|
+
depthCache$1.incrementDepth(this._id, this._firstIndex);
|
|
1018
|
+
this._firstIndex = cursor.index;
|
|
1021
1019
|
const node = this._tryToParse(cursor);
|
|
1020
|
+
depthCache$1.decrementDepth(this._id, this._firstIndex);
|
|
1022
1021
|
if (node != null) {
|
|
1023
1022
|
cursor.moveTo(node.lastIndex);
|
|
1024
1023
|
cursor.resolveError();
|
|
@@ -1028,12 +1027,12 @@
|
|
|
1028
1027
|
return null;
|
|
1029
1028
|
}
|
|
1030
1029
|
_tryToParse(cursor) {
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1030
|
+
if (depthCache$1.getDepth(this._id, this._firstIndex) > 2) {
|
|
1031
|
+
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
1032
|
+
return null;
|
|
1034
1033
|
}
|
|
1035
1034
|
const results = [];
|
|
1036
|
-
for (const pattern of
|
|
1035
|
+
for (const pattern of this._children) {
|
|
1037
1036
|
cursor.moveTo(this._firstIndex);
|
|
1038
1037
|
let result = null;
|
|
1039
1038
|
result = pattern.parse(cursor);
|
|
@@ -1049,20 +1048,6 @@
|
|
|
1049
1048
|
nonNullResults.sort((a, b) => b.endIndex - a.endIndex);
|
|
1050
1049
|
return nonNullResults[0] || null;
|
|
1051
1050
|
}
|
|
1052
|
-
_isBeyondRecursiveDepth() {
|
|
1053
|
-
let depth = 0;
|
|
1054
|
-
let pattern = this;
|
|
1055
|
-
while (pattern != null) {
|
|
1056
|
-
if (pattern.id === this.id) {
|
|
1057
|
-
depth++;
|
|
1058
|
-
}
|
|
1059
|
-
if (depth > this._recursiveDepth) {
|
|
1060
|
-
return true;
|
|
1061
|
-
}
|
|
1062
|
-
pattern = pattern.parent;
|
|
1063
|
-
}
|
|
1064
|
-
return false;
|
|
1065
|
-
}
|
|
1066
1051
|
getTokens() {
|
|
1067
1052
|
const tokens = [];
|
|
1068
1053
|
for (const child of this._children) {
|
|
@@ -1655,6 +1640,7 @@
|
|
|
1655
1640
|
return filteredNodes;
|
|
1656
1641
|
}
|
|
1657
1642
|
|
|
1643
|
+
const depthCache = new DepthCache();
|
|
1658
1644
|
let idIndex$2 = 0;
|
|
1659
1645
|
class Sequence {
|
|
1660
1646
|
get id() {
|
|
@@ -1711,8 +1697,10 @@
|
|
|
1711
1697
|
parse(cursor) {
|
|
1712
1698
|
// This is a cache to help with speed
|
|
1713
1699
|
this._firstIndex = cursor.index;
|
|
1700
|
+
depthCache.incrementDepth(this._id, this._firstIndex);
|
|
1714
1701
|
this._nodes = [];
|
|
1715
1702
|
const passed = this.tryToParse(cursor);
|
|
1703
|
+
depthCache.decrementDepth(this._id, this._firstIndex);
|
|
1716
1704
|
if (passed) {
|
|
1717
1705
|
const node = this.createNode(cursor);
|
|
1718
1706
|
if (node !== null) {
|
|
@@ -1723,7 +1711,7 @@
|
|
|
1723
1711
|
return null;
|
|
1724
1712
|
}
|
|
1725
1713
|
tryToParse(cursor) {
|
|
1726
|
-
if (this.
|
|
1714
|
+
if (depthCache.getDepth(this._id, this._firstIndex) > 1) {
|
|
1727
1715
|
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
1728
1716
|
return false;
|
|
1729
1717
|
}
|
|
@@ -1783,20 +1771,6 @@
|
|
|
1783
1771
|
}
|
|
1784
1772
|
return passed;
|
|
1785
1773
|
}
|
|
1786
|
-
_isBeyondRecursiveDepth() {
|
|
1787
|
-
let depth = 0;
|
|
1788
|
-
let pattern = this;
|
|
1789
|
-
while (pattern != null) {
|
|
1790
|
-
if (pattern.id === this.id && this._firstIndex === pattern._firstIndex) {
|
|
1791
|
-
depth++;
|
|
1792
|
-
}
|
|
1793
|
-
if (depth > 1) {
|
|
1794
|
-
return true;
|
|
1795
|
-
}
|
|
1796
|
-
pattern = pattern.parent;
|
|
1797
|
-
}
|
|
1798
|
-
return false;
|
|
1799
|
-
}
|
|
1800
1774
|
getLastValidNode() {
|
|
1801
1775
|
const nodes = filterOutNull(this._nodes);
|
|
1802
1776
|
if (nodes.length === 0) {
|
|
@@ -2395,9 +2369,8 @@
|
|
|
2395
2369
|
errorAtIndex = startIndex;
|
|
2396
2370
|
}
|
|
2397
2371
|
else if (!isComplete && this._cursor.hasError && this._cursor.furthestError != null) {
|
|
2398
|
-
errorAtIndex = this.
|
|
2399
|
-
error = this.
|
|
2400
|
-
errorAtIndex = options.reduce((errorAtIndex, option) => Math.max(errorAtIndex, option.startIndex), errorAtIndex);
|
|
2372
|
+
errorAtIndex = this.getFurthestPosition(cursor);
|
|
2373
|
+
error = new ParseError(errorAtIndex, errorAtIndex, this._pattern);
|
|
2401
2374
|
}
|
|
2402
2375
|
return {
|
|
2403
2376
|
isComplete: isComplete,
|
|
@@ -2408,21 +2381,39 @@
|
|
|
2408
2381
|
ast,
|
|
2409
2382
|
};
|
|
2410
2383
|
}
|
|
2384
|
+
getFurthestPosition(cursor) {
|
|
2385
|
+
const furthestError = cursor.furthestError;
|
|
2386
|
+
const furthestMatch = cursor.allMatchedNodes[cursor.allMatchedNodes.length - 1];
|
|
2387
|
+
if (furthestError && furthestMatch) {
|
|
2388
|
+
if (furthestError.endIndex > furthestMatch.endIndex) {
|
|
2389
|
+
return furthestMatch.endIndex;
|
|
2390
|
+
}
|
|
2391
|
+
else {
|
|
2392
|
+
return furthestError.endIndex;
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
if (furthestError == null && furthestMatch != null) {
|
|
2396
|
+
return furthestMatch.endIndex;
|
|
2397
|
+
}
|
|
2398
|
+
if (furthestMatch == null && furthestError != null) {
|
|
2399
|
+
return furthestError.endIndex;
|
|
2400
|
+
}
|
|
2401
|
+
return 0;
|
|
2402
|
+
}
|
|
2411
2403
|
suggestFor(text) {
|
|
2412
2404
|
return this.suggestForWithCursor(new Cursor(text));
|
|
2413
2405
|
}
|
|
2414
2406
|
_getAllOptions() {
|
|
2415
2407
|
const errorMatches = this._getOptionsFromErrors();
|
|
2416
|
-
const
|
|
2417
|
-
const
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
const index = uniqueResults.findIndex(f => m.text === f.text);
|
|
2408
|
+
const leafMatches = this._cursor.leafMatches.map((m) => this._createSuggestionsFromMatch(m)).flat();
|
|
2409
|
+
const finalResults = [];
|
|
2410
|
+
[...leafMatches, ...errorMatches].forEach(m => {
|
|
2411
|
+
const index = finalResults.findIndex(f => m.text === f.text);
|
|
2421
2412
|
if (index === -1) {
|
|
2422
|
-
|
|
2413
|
+
finalResults.push(m);
|
|
2423
2414
|
}
|
|
2424
2415
|
});
|
|
2425
|
-
return
|
|
2416
|
+
return finalResults;
|
|
2426
2417
|
}
|
|
2427
2418
|
_getOptionsFromErrors() {
|
|
2428
2419
|
// These errored because the length of the string.
|
|
@@ -2431,8 +2422,8 @@
|
|
|
2431
2422
|
const tokens = this._getTokensForPattern(e.pattern);
|
|
2432
2423
|
const adjustedTokens = tokens.map(t => t.slice(e.endIndex - e.startIndex));
|
|
2433
2424
|
return this._createSuggestions(e.endIndex, adjustedTokens);
|
|
2434
|
-
})
|
|
2435
|
-
return suggestions;
|
|
2425
|
+
});
|
|
2426
|
+
return suggestions.flat();
|
|
2436
2427
|
}
|
|
2437
2428
|
_createSuggestionsFromRoot() {
|
|
2438
2429
|
const suggestions = [];
|