clarity-pattern-parser 10.0.6 → 10.0.8

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.
@@ -784,6 +784,7 @@
784
784
  this._name = name;
785
785
  this._parent = null;
786
786
  this._pattern = null;
787
+ this._cachedPattern = null;
787
788
  this._children = [];
788
789
  }
789
790
  test(text) {
@@ -805,7 +806,13 @@
805
806
  }
806
807
  _getPatternSafely() {
807
808
  if (this._pattern === null) {
808
- const pattern = this._findPattern();
809
+ let pattern = null;
810
+ if (this._cachedPattern == null) {
811
+ pattern = this._findPattern();
812
+ }
813
+ else {
814
+ pattern = this._cachedPattern;
815
+ }
809
816
  if (pattern === null) {
810
817
  throw new Error(`Couldn't find '${this._name}' pattern within tree.`);
811
818
  }
@@ -871,6 +878,10 @@
871
878
  clone(name = this._name) {
872
879
  const clone = new Reference(name);
873
880
  clone._id = this._id;
881
+ // Optimize future clones, by caching the pattern we already found.
882
+ if (this._pattern != null) {
883
+ clone._cachedPattern = this._pattern;
884
+ }
874
885
  return clone;
875
886
  }
876
887
  isEqual(pattern) {
@@ -882,6 +893,33 @@
882
893
  return patterns.map(p => p.clone());
883
894
  }
884
895
 
896
+ class DepthCache {
897
+ constructor() {
898
+ this._depthMap = {};
899
+ }
900
+ getDepth(name, cursorIndex) {
901
+ if (this._depthMap[name] == null) {
902
+ this._depthMap[name] = {};
903
+ }
904
+ if (this._depthMap[name][cursorIndex] == null) {
905
+ this._depthMap[name][cursorIndex] = 0;
906
+ }
907
+ return this._depthMap[name][cursorIndex];
908
+ }
909
+ incrementDepth(name, cursorIndex) {
910
+ const depth = this.getDepth(name, cursorIndex);
911
+ this._depthMap[name][cursorIndex] = depth + 1;
912
+ }
913
+ decrementDepth(name, cursorIndex) {
914
+ const depth = this.getDepth(name, cursorIndex);
915
+ this._depthMap[name][cursorIndex] = depth - 1;
916
+ }
917
+ }
918
+
919
+ /*
920
+ The following is created to reduce the overhead of recursion check.
921
+ */
922
+ const depthCache$1 = new DepthCache();
885
923
  let idIndex$6 = 0;
886
924
  class Options {
887
925
  get id() {
@@ -936,8 +974,12 @@
936
974
  };
937
975
  }
938
976
  parse(cursor) {
977
+ // This is a cache to help with speed
978
+ this._firstIndex = cursor.index;
979
+ depthCache$1.incrementDepth(this._id, this._firstIndex);
939
980
  this._firstIndex = cursor.index;
940
981
  const node = this._tryToParse(cursor);
982
+ depthCache$1.decrementDepth(this._id, this._firstIndex);
941
983
  if (node != null) {
942
984
  cursor.moveTo(node.lastIndex);
943
985
  cursor.resolveError();
@@ -947,8 +989,8 @@
947
989
  return null;
948
990
  }
949
991
  _tryToParse(cursor) {
950
- if (this._isBeyondRecursiveLimit()) {
951
- cursor.recordErrorAt(cursor.index, cursor.index, this);
992
+ if (depthCache$1.getDepth(this._id, this._firstIndex) > 2) {
993
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
952
994
  return null;
953
995
  }
954
996
  const results = [];
@@ -968,25 +1010,6 @@
968
1010
  nonNullResults.sort((a, b) => b.endIndex - a.endIndex);
969
1011
  return nonNullResults[0] || null;
970
1012
  }
971
- _isBeyondRecursiveLimit() {
972
- let pattern = this;
973
- const matches = [];
974
- while (pattern.parent != null) {
975
- if (pattern.type !== "options") {
976
- pattern = pattern.parent;
977
- continue;
978
- }
979
- const optionsPattern = pattern;
980
- if (pattern.id === this.id && optionsPattern._firstIndex === this._firstIndex) {
981
- matches.push(pattern);
982
- if (matches.length > 2) {
983
- return true;
984
- }
985
- }
986
- pattern = pattern.parent;
987
- }
988
- return false;
989
- }
990
1013
  getTokens() {
991
1014
  const tokens = [];
992
1015
  for (const child of this._children) {
@@ -1579,6 +1602,7 @@
1579
1602
  return filteredNodes;
1580
1603
  }
1581
1604
 
1605
+ const depthCache = new DepthCache();
1582
1606
  let idIndex$2 = 0;
1583
1607
  class Sequence {
1584
1608
  get id() {
@@ -1633,13 +1657,12 @@
1633
1657
  };
1634
1658
  }
1635
1659
  parse(cursor) {
1660
+ // This is a cache to help with speed
1636
1661
  this._firstIndex = cursor.index;
1662
+ depthCache.incrementDepth(this._id, this._firstIndex);
1637
1663
  this._nodes = [];
1638
- if (this._isBeyondRecursiveLimit()) {
1639
- cursor.recordErrorAt(cursor.index, cursor.index, this);
1640
- return null;
1641
- }
1642
1664
  const passed = this.tryToParse(cursor);
1665
+ depthCache.decrementDepth(this._id, this._firstIndex);
1643
1666
  if (passed) {
1644
1667
  const node = this.createNode(cursor);
1645
1668
  if (node !== null) {
@@ -1650,6 +1673,10 @@
1650
1673
  return null;
1651
1674
  }
1652
1675
  tryToParse(cursor) {
1676
+ if (depthCache.getDepth(this._id, this._firstIndex) > 1) {
1677
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
1678
+ return false;
1679
+ }
1653
1680
  let passed = false;
1654
1681
  for (let i = 0; i < this._children.length; i++) {
1655
1682
  const runningCursorIndex = cursor.index;
@@ -1706,25 +1733,6 @@
1706
1733
  }
1707
1734
  return passed;
1708
1735
  }
1709
- _isBeyondRecursiveLimit() {
1710
- let pattern = this;
1711
- const matches = [];
1712
- while (pattern.parent != null) {
1713
- if (pattern.type !== "sequence") {
1714
- pattern = pattern.parent;
1715
- continue;
1716
- }
1717
- const sequencePattern = pattern;
1718
- if (pattern.id === this.id && sequencePattern._firstIndex === this._firstIndex) {
1719
- matches.push(pattern);
1720
- if (matches.length > 1) {
1721
- return true;
1722
- }
1723
- }
1724
- pattern = pattern.parent;
1725
- }
1726
- return false;
1727
- }
1728
1736
  getLastValidNode() {
1729
1737
  const nodes = filterOutNull(this._nodes);
1730
1738
  if (nodes.length === 0) {