clarity-pattern-parser 11.0.26 → 11.0.28

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.d.ts CHANGED
@@ -23,4 +23,6 @@ import { patterns } from "./grammar/patterns";
23
23
  import { Context } from "./patterns/Context";
24
24
  import { Expression } from "./patterns/Expression";
25
25
  import { RightAssociated } from "./patterns/RightAssociated";
26
- export { Node, Grammar, AutoComplete, AutoCompleteOptions, Suggestion, SuggestionOption, Sequence, Cursor, CursorHistory, Match, Context, Expression, Literal, Not, Options, Optional, ParseError, ParseResult, Pattern, Reference, RightAssociated, Regex, Repeat, grammar, patterns, compact, remove };
26
+ import { Selector } from "./query/selector";
27
+ import { Query } from "./query/query";
28
+ export { Node, Grammar, AutoComplete, AutoCompleteOptions, Suggestion, SuggestionOption, Sequence, Cursor, CursorHistory, Match, Context, Expression, Literal, Not, Options, Optional, ParseError, ParseResult, Pattern, Reference, RightAssociated, Regex, Repeat, Query, Selector, grammar, patterns, compact, remove };
package/dist/index.esm.js CHANGED
@@ -846,10 +846,11 @@ class Reference {
846
846
  get startedOnIndex() {
847
847
  return this._firstIndex;
848
848
  }
849
- constructor(name) {
849
+ constructor(name, referencePatternName) {
850
850
  this._id = `reference-${idIndex$7++}`;
851
851
  this._type = "reference";
852
852
  this._name = name;
853
+ this._referencePatternName = referencePatternName || name;
853
854
  this._parent = null;
854
855
  this._pattern = null;
855
856
  this._cachedPattern = null;
@@ -908,9 +909,9 @@ class Reference {
908
909
  pattern = this._cachedPattern;
909
910
  }
910
911
  if (pattern === null) {
911
- throw new Error(`Couldn't find '${this._name}' pattern within tree.`);
912
+ throw new Error(`Couldn't find '${this._referencePatternName}' pattern within tree.`);
912
913
  }
913
- const clonedPattern = pattern.clone();
914
+ const clonedPattern = pattern.clone(this._name);
914
915
  clonedPattern.parent = this;
915
916
  this._pattern = clonedPattern;
916
917
  this._children = [this._pattern];
@@ -924,7 +925,7 @@ class Reference {
924
925
  pattern = pattern.parent;
925
926
  continue;
926
927
  }
927
- const foundPattern = pattern.getPatternWithinContext(this.name);
928
+ const foundPattern = pattern.getPatternWithinContext(this._referencePatternName);
928
929
  if (foundPattern != null && this._isValidPattern(foundPattern)) {
929
930
  return foundPattern;
930
931
  }
@@ -932,7 +933,7 @@ class Reference {
932
933
  }
933
934
  const root = this._getRoot();
934
935
  return findPattern(root, (pattern) => {
935
- return pattern.name === this._name && this._isValidPattern(pattern);
936
+ return pattern.name === this._referencePatternName && this._isValidPattern(pattern);
936
937
  });
937
938
  }
938
939
  _isValidPattern(pattern) {
@@ -991,7 +992,7 @@ class Reference {
991
992
  return null;
992
993
  }
993
994
  clone(name = this._name) {
994
- const clone = new Reference(name);
995
+ const clone = new Reference(name, this._referencePatternName);
995
996
  clone._id = this._id;
996
997
  // Optimize future clones, by caching the pattern we already found.
997
998
  if (this._pattern != null) {
@@ -1613,6 +1614,12 @@ class Repeat {
1613
1614
  get startedOnIndex() {
1614
1615
  return this._repeatPattern.startedOnIndex;
1615
1616
  }
1617
+ get pattern() {
1618
+ return this._pattern;
1619
+ }
1620
+ get options() {
1621
+ return this._options;
1622
+ }
1616
1623
  constructor(name, pattern, options = {}) {
1617
1624
  this._id = `repeat-${idIndex$3++}`;
1618
1625
  this._pattern = pattern;
@@ -2674,6 +2681,9 @@ class Expression {
2674
2681
  get binaryPatterns() {
2675
2682
  return this._binaryPatterns;
2676
2683
  }
2684
+ get originalPatterns() {
2685
+ return this._originalPatterns;
2686
+ }
2677
2687
  get startedOnIndex() {
2678
2688
  return this._firstIndex;
2679
2689
  }
@@ -3585,8 +3595,8 @@ class Grammar {
3585
3595
  const aliasPattern = this._getPattern(aliasName);
3586
3596
  // This solves the problem for an alias pointing to a reference.
3587
3597
  if (aliasPattern.type === "reference") {
3588
- const sequence = new Sequence(name, [aliasPattern]);
3589
- this._parseContext.patternsByName.set(name, sequence);
3598
+ const reference = new Reference(name, aliasName);
3599
+ this._parseContext.patternsByName.set(name, reference);
3590
3600
  }
3591
3601
  else {
3592
3602
  const alias = aliasPattern.clone(name);
@@ -3854,5 +3864,434 @@ function patterns(strings, ...values) {
3854
3864
  return result;
3855
3865
  }
3856
3866
 
3857
- export { AutoComplete, Context, Cursor, CursorHistory, Expression, Grammar, Literal, Node, Not, Optional, Options, ParseError, Reference, Regex, Repeat, RightAssociated, Sequence, compact, grammar, patterns, remove };
3867
+ const { expression } = patterns `
3868
+ number = /[+-]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+)?/
3869
+ spaces = /\\s+/
3870
+ single-quote-string-literal = /'(?:\\\\.|[^'\\\\])*'/
3871
+ name = /[a-zA-Z_-]+[a-zA-Z0-9_-]*/
3872
+ comma = /\\s*,\\s*/
3873
+ wild-card = "*"
3874
+ equal = "="
3875
+ not-equal = "!="
3876
+ starts-with = "^="
3877
+ ends-with = "$="
3878
+ contains = "*="
3879
+ greater-than-or-equal = ">="
3880
+ less-than-or-equal = "<="
3881
+ greater-than = ">"
3882
+ less-than = "<"
3883
+ operators = equal |
3884
+ not-equal |
3885
+ starts-with |
3886
+ ends-with |
3887
+ contains |
3888
+ greater-than-or-equal |
3889
+ less-than-or-equal |
3890
+ greater-than |
3891
+ less-than
3892
+
3893
+ attribute-name = name
3894
+ value = name
3895
+ attribute-value = single-quote-string-literal | number | value
3896
+ attribute-selector = "[" + spaces? + attribute-name + spaces? + operators + spaces? + attribute-value + "]"
3897
+
3898
+ adjacent = spaces? + "+" + spaces?
3899
+ after = spaces? + "~" + spaces?
3900
+ direct-child = spaces? + ">" + spaces?
3901
+ descendant = spaces
3902
+
3903
+ combinators = adjacent | after | direct-child | descendant
3904
+ name-selector = name-selector-expression + attribute-selector
3905
+ name-selector-expression = name-selector | name
3906
+ node-selector = wild-card | attribute-selector | name-selector-expression
3907
+ or-selector = (node-selector, comma){2}
3908
+
3909
+ selector-expression = expression + combinators + expression
3910
+ expression = selector-expression | or-selector | node-selector
3911
+ `;
3912
+ const selectorParser = expression;
3913
+
3914
+ const combinatorMap = {
3915
+ "adjacent": true,
3916
+ "after": true,
3917
+ "descendant": true,
3918
+ "direct-child": true
3919
+ };
3920
+ const operatorMap = {
3921
+ "equal": true,
3922
+ "not-equal": true,
3923
+ "starts-with": true,
3924
+ "ends-with": true,
3925
+ "contains": true,
3926
+ "greater-than-or-equal": true,
3927
+ "less-than-or-equal": true,
3928
+ "greater-than": true,
3929
+ "less-than": true
3930
+ };
3931
+ class Selector {
3932
+ constructor(selector) {
3933
+ this._selectedNodes = [];
3934
+ this._combinator = null;
3935
+ const result = selectorParser.exec(selector);
3936
+ if (result.ast == null) {
3937
+ const message = generateErrorMessage(selectorParser, result.cursor);
3938
+ throw new Error(`[Invalid Selector] ${message}`);
3939
+ }
3940
+ this._selectorAst = result.ast;
3941
+ }
3942
+ find(nodes) {
3943
+ this._selectedNodes = nodes;
3944
+ const ast = this._selectorAst;
3945
+ ast.walkUp((node) => {
3946
+ this._process(node);
3947
+ });
3948
+ return this._selectedNodes;
3949
+ }
3950
+ filter(nodes) {
3951
+ if (nodes.length < 1) {
3952
+ return [];
3953
+ }
3954
+ const nodeMap = new Map();
3955
+ nodes.forEach(n => nodeMap.set(n, n));
3956
+ this._selectedNodes = [nodes[0].findRoot()];
3957
+ const ast = this._selectorAst;
3958
+ ast.walkUp((node) => {
3959
+ this._process(node);
3960
+ });
3961
+ return this._selectedNodes.filter(n => nodeMap.has(n));
3962
+ }
3963
+ not(nodes) {
3964
+ if (nodes.length < 1) {
3965
+ return [];
3966
+ }
3967
+ this._selectedNodes = [nodes[0].findRoot()];
3968
+ const ast = this._selectorAst;
3969
+ ast.walkUp((node) => {
3970
+ this._process(node);
3971
+ });
3972
+ const selectedNodeMap = new Map();
3973
+ this._selectedNodes.forEach(n => selectedNodeMap.set(n, n));
3974
+ return nodes.filter(n => !selectedNodeMap.has(n));
3975
+ }
3976
+ parents(nodes) {
3977
+ if (nodes.length < 1) {
3978
+ return [];
3979
+ }
3980
+ this._selectedNodes = [nodes[0].findRoot()];
3981
+ const ast = this._selectorAst;
3982
+ ast.walkUp((node) => {
3983
+ this._process(node);
3984
+ });
3985
+ const result = new Set();
3986
+ const ancestorMap = new Map();
3987
+ this._selectedNodes.forEach(n => ancestorMap.set(n, true));
3988
+ nodes.forEach(n => {
3989
+ const ancestor = n.findAncestor(a => ancestorMap.has(a));
3990
+ if (ancestor != null) {
3991
+ result.add(ancestor);
3992
+ }
3993
+ });
3994
+ return Array.from(result);
3995
+ }
3996
+ _process(ast) {
3997
+ const nodeName = ast.name;
3998
+ if (nodeName === "wild-card") {
3999
+ this._selectedNodes = this._processWildCard();
4000
+ }
4001
+ else if (nodeName === "or-selector") {
4002
+ this._selectedNodes = this._processOrSelector(ast);
4003
+ }
4004
+ else if (nodeName === "name-selector" || (nodeName === "name" && (ast.parent == null || ast.parent.name === "selector-expression"))) {
4005
+ this._selectedNodes = this._processNameSelector(ast);
4006
+ }
4007
+ else if (nodeName === "attribute-selector" && (ast.parent == null || ast.parent.name === "selector-expression")) {
4008
+ this._selectedNodes = this._processAttributeSelector(ast);
4009
+ }
4010
+ else if (combinatorMap[nodeName]) {
4011
+ this._combinator = nodeName;
4012
+ }
4013
+ else if (nodeName === "selector-expression") {
4014
+ this._combinator = null;
4015
+ }
4016
+ }
4017
+ _processWildCard() {
4018
+ return this._selectedNodes.map(n => {
4019
+ return this._selectWithCombinator(n, () => true);
4020
+ }).flat();
4021
+ }
4022
+ _processOrSelector(ast) {
4023
+ const selectorNodes = ast.children.filter(n => n.name !== "comma");
4024
+ const set = new Set();
4025
+ const selectors = selectorNodes.map(n => new Selector(n.toString()));
4026
+ selectors.map(s => {
4027
+ return s.find(this._selectedNodes.slice());
4028
+ }).flat().forEach((node) => {
4029
+ set.add(node);
4030
+ });
4031
+ return Array.from(set);
4032
+ }
4033
+ _processNameSelector(ast) {
4034
+ if (ast.children.length > 1) {
4035
+ return this._selectedNodes.map(n => {
4036
+ const name = ast.children[0].value;
4037
+ return this._selectWithCombinator(n, (node) => {
4038
+ return node.name === name && this._isAttributeMatch(node, ast);
4039
+ });
4040
+ }).flat();
4041
+ }
4042
+ else {
4043
+ return this._selectedNodes.map(n => {
4044
+ return this._selectWithCombinator(n, (node) => node.name === ast.value);
4045
+ }).flat();
4046
+ }
4047
+ }
4048
+ _processAttributeSelector(ast) {
4049
+ return this._selectedNodes.map(n => {
4050
+ return this._selectWithCombinator(n, (node) => {
4051
+ return this._isAttributeMatch(node, ast);
4052
+ });
4053
+ }).flat();
4054
+ }
4055
+ _selectWithCombinator(node, predicate) {
4056
+ if (this._combinator === "adjacent") {
4057
+ const sibling = node.nextSibling();
4058
+ if (sibling == null) {
4059
+ return [];
4060
+ }
4061
+ if (predicate(sibling)) {
4062
+ return [sibling];
4063
+ }
4064
+ else {
4065
+ return [];
4066
+ }
4067
+ }
4068
+ else if (this._combinator === "after") {
4069
+ const parent = node.parent;
4070
+ if (parent == null) {
4071
+ return [];
4072
+ }
4073
+ const index = parent.findChildIndex(node);
4074
+ const after = parent.children.slice(index + 1);
4075
+ return after.filter(predicate);
4076
+ }
4077
+ else if (this._combinator === "direct-child") {
4078
+ return node.children.filter(predicate);
4079
+ }
4080
+ else if (this._combinator === "descendant" || this._combinator == null) {
4081
+ return node.findAll(predicate);
4082
+ }
4083
+ else {
4084
+ return [];
4085
+ }
4086
+ }
4087
+ _isAttributeMatch(node, ast) {
4088
+ const name = this._getAttributeName(ast);
4089
+ const operator = this._getAttributeOperator(ast);
4090
+ const value = this._getAttributeValue(ast);
4091
+ const anyNode = node;
4092
+ if (anyNode[name] == null) {
4093
+ return false;
4094
+ }
4095
+ if (operator === "equal") {
4096
+ return anyNode[name] === value;
4097
+ }
4098
+ else if (operator === "not-equal") {
4099
+ return anyNode[name] !== value;
4100
+ }
4101
+ else if (operator === "starts-with") {
4102
+ return anyNode[name].toString().startsWith(value);
4103
+ }
4104
+ else if (operator === "ends-with") {
4105
+ return anyNode[name].toString().endsWith(value);
4106
+ }
4107
+ else if (operator === "contains") {
4108
+ return anyNode[name].toString().includes(value);
4109
+ }
4110
+ else if (operator === "greater-than-or-equal") {
4111
+ return anyNode[name] >= value;
4112
+ }
4113
+ else if (operator === "less-than-or-equal") {
4114
+ return anyNode[name] <= value;
4115
+ }
4116
+ else if (operator === "greater-than") {
4117
+ return anyNode[name] > value;
4118
+ }
4119
+ else if (operator === "less-than") {
4120
+ return anyNode[name] < value;
4121
+ }
4122
+ return false;
4123
+ }
4124
+ _getAttributeName(ast) {
4125
+ return ast.find(n => n.name === "attribute-name").value;
4126
+ }
4127
+ _getAttributeValue(ast) {
4128
+ let valueNode = ast.find(n => n.name === "single-quote-string-literal");
4129
+ if (valueNode != null) {
4130
+ return valueNode.value.slice(1, -1);
4131
+ }
4132
+ else {
4133
+ valueNode = ast.find(n => n.name === "value");
4134
+ }
4135
+ if (valueNode != null) {
4136
+ return valueNode.value;
4137
+ }
4138
+ else {
4139
+ valueNode = ast.find(n => n.name === "number");
4140
+ }
4141
+ return valueNode.value;
4142
+ }
4143
+ _getAttributeOperator(ast) {
4144
+ return ast.find(n => operatorMap[n.name]).name;
4145
+ }
4146
+ }
4147
+
4148
+ class Query {
4149
+ constructor(context, prevQuery = null) {
4150
+ this._context = context;
4151
+ this._prevQuery = prevQuery;
4152
+ }
4153
+ toArray() {
4154
+ return this._context.slice();
4155
+ }
4156
+ // Modifiers
4157
+ append(visitor) {
4158
+ this._context.forEach(n => {
4159
+ const parent = n.parent;
4160
+ if (parent == null) {
4161
+ return;
4162
+ }
4163
+ const newNode = visitor(n);
4164
+ n.appendChild(newNode);
4165
+ });
4166
+ return this;
4167
+ }
4168
+ prepend(visitor) {
4169
+ this._context.forEach(n => {
4170
+ const parent = n.parent;
4171
+ if (parent == null) {
4172
+ return;
4173
+ }
4174
+ const newNode = visitor(n);
4175
+ n.insertBefore(newNode, n.children[0]);
4176
+ });
4177
+ return this;
4178
+ }
4179
+ after(visitor) {
4180
+ this._context.forEach(n => {
4181
+ const parent = n.parent;
4182
+ if (parent == null) {
4183
+ return;
4184
+ }
4185
+ const index = parent.findChildIndex(n);
4186
+ const newNode = visitor(n);
4187
+ parent.spliceChildren(index + 1, 0, newNode);
4188
+ });
4189
+ return this;
4190
+ }
4191
+ before(visitor) {
4192
+ this._context.forEach(n => {
4193
+ const parent = n.parent;
4194
+ if (parent == null) {
4195
+ return;
4196
+ }
4197
+ const index = parent.findChildIndex(n);
4198
+ const newNode = visitor(n);
4199
+ parent.spliceChildren(index, 0, newNode);
4200
+ });
4201
+ return this;
4202
+ }
4203
+ replaceWith(visitor) {
4204
+ this._context.forEach(n => {
4205
+ const newNode = visitor(n);
4206
+ n.replaceWith(newNode);
4207
+ });
4208
+ return this;
4209
+ }
4210
+ compact() {
4211
+ this._context.forEach(n => {
4212
+ n.compact();
4213
+ });
4214
+ return this;
4215
+ }
4216
+ setValue(value) {
4217
+ this.replaceWith((n) => {
4218
+ return Node.createValueNode(n.type, n.name, value);
4219
+ });
4220
+ return this;
4221
+ }
4222
+ normalize() {
4223
+ const first = this._context[0];
4224
+ if (first != null) {
4225
+ first.findRoot().normalize();
4226
+ }
4227
+ }
4228
+ remove() {
4229
+ this._context.forEach(n => {
4230
+ n.remove();
4231
+ });
4232
+ return this;
4233
+ }
4234
+ // Filters from the currently matched nodes
4235
+ slice(start, end) {
4236
+ return new Query(this._context.slice(start, end));
4237
+ }
4238
+ filter(selectorString) {
4239
+ const selector = new Selector(selectorString);
4240
+ const newContext = selector.filter(this._context);
4241
+ return new Query(newContext, this);
4242
+ }
4243
+ // Selects out of all descedants of currently matched nodes
4244
+ find(selectorString) {
4245
+ const selector = new Selector(selectorString);
4246
+ const newContext = selector.find(this._context);
4247
+ return new Query(newContext, this);
4248
+ }
4249
+ // Remove nodes from the set of matched nodes.
4250
+ not(selectorString) {
4251
+ const selector = new Selector(selectorString);
4252
+ const newContext = selector.not(this._context);
4253
+ return new Query(newContext, this);
4254
+ }
4255
+ // Select the parent of currently matched nodes
4256
+ parent() {
4257
+ const parents = this._context.map(n => n.parent);
4258
+ const result = new Set();
4259
+ parents.forEach((n) => {
4260
+ if (n != null) {
4261
+ result.add(n);
4262
+ }
4263
+ });
4264
+ return new Query(Array.from(result), this);
4265
+ }
4266
+ // Select the ancestors of currently matched nodes
4267
+ parents(selectorString) {
4268
+ const selector = new Selector(selectorString);
4269
+ const newContext = selector.parents(this._context);
4270
+ const result = new Set();
4271
+ newContext.forEach((n) => {
4272
+ if (n != null) {
4273
+ result.add(n);
4274
+ }
4275
+ });
4276
+ return new Query(Array.from(result), this);
4277
+ }
4278
+ first() {
4279
+ return new Query(this._context.slice(0, 1), this);
4280
+ }
4281
+ last() {
4282
+ return new Query(this._context.slice(-1), this);
4283
+ }
4284
+ // Pop query stack
4285
+ end() {
4286
+ if (this._prevQuery) {
4287
+ return this._prevQuery;
4288
+ }
4289
+ return this;
4290
+ }
4291
+ length() {
4292
+ return this._context.length;
4293
+ }
4294
+ }
4295
+
4296
+ export { AutoComplete, Context, Cursor, CursorHistory, Expression, Grammar, Literal, Node, Not, Optional, Options, ParseError, Query, Reference, Regex, Repeat, RightAssociated, Selector, Sequence, compact, grammar, patterns, remove };
3858
4297
  //# sourceMappingURL=index.esm.js.map