clarity-pattern-parser 6.0.2 → 7.0.1

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.
Files changed (88) hide show
  1. package/TODO.md +1 -78
  2. package/dist/ast/Node.d.ts +1 -0
  3. package/dist/grammar/Grammar.d.ts +17 -0
  4. package/dist/grammar/patterns/andLiteral.d.ts +2 -0
  5. package/dist/grammar/patterns/comment.d.ts +2 -0
  6. package/dist/grammar/patterns/grammar.d.ts +2 -0
  7. package/dist/grammar/patterns/literal.d.ts +2 -0
  8. package/dist/grammar/patterns/name.d.ts +2 -0
  9. package/dist/grammar/patterns/orLiteral.d.ts +2 -0
  10. package/dist/grammar/patterns/pattern.d.ts +2 -0
  11. package/dist/grammar/patterns/regexLiteral.d.ts +2 -0
  12. package/dist/grammar/patterns/repeatLiteral.d.ts +3 -0
  13. package/dist/grammar/patterns/spaces.d.ts +2 -0
  14. package/dist/grammar/patterns/statement.d.ts +2 -0
  15. package/dist/index.browser.js +1161 -556
  16. package/dist/index.browser.js.map +1 -1
  17. package/dist/index.d.ts +5 -4
  18. package/dist/index.esm.js +1159 -555
  19. package/dist/index.esm.js.map +1 -1
  20. package/dist/index.js +1159 -554
  21. package/dist/index.js.map +1 -1
  22. package/dist/intellisense/AutoComplete.d.ts +2 -6
  23. package/dist/patterns/And.d.ts +1 -1
  24. package/dist/patterns/Cursor.d.ts +1 -0
  25. package/dist/patterns/CursorHistory.d.ts +2 -1
  26. package/dist/patterns/FiniteRepeat.d.ts +39 -0
  27. package/dist/patterns/InfiniteRepeat.d.ts +47 -0
  28. package/dist/patterns/Literal.d.ts +1 -1
  29. package/dist/patterns/Not.d.ts +1 -1
  30. package/dist/patterns/Or.d.ts +1 -1
  31. package/dist/patterns/Pattern.d.ts +1 -1
  32. package/dist/patterns/Reference.d.ts +1 -1
  33. package/dist/patterns/Regex.d.ts +1 -1
  34. package/dist/patterns/Repeat.d.ts +18 -22
  35. package/jest.config.js +0 -1
  36. package/jest.coverage.config.js +13 -0
  37. package/package.json +3 -3
  38. package/src/ast/Node.test.ts +15 -0
  39. package/src/ast/Node.ts +12 -6
  40. package/src/grammar/Grammar.test.ts +306 -0
  41. package/src/grammar/Grammar.ts +249 -0
  42. package/src/grammar/patterns/andLiteral.ts +8 -0
  43. package/src/grammar/patterns/comment.ts +3 -0
  44. package/src/grammar/patterns/grammar.ts +19 -0
  45. package/src/grammar/patterns/literal.ts +5 -0
  46. package/src/grammar/patterns/name.ts +3 -0
  47. package/src/grammar/patterns/orLiteral.ts +8 -0
  48. package/src/grammar/patterns/pattern.ts +13 -0
  49. package/src/grammar/patterns/regexLiteral.ts +4 -0
  50. package/src/grammar/patterns/repeatLiteral.ts +72 -0
  51. package/src/grammar/patterns/spaces.ts +4 -0
  52. package/src/grammar/patterns/statement.ts +36 -0
  53. package/src/grammar/spec.md +142 -0
  54. package/src/index.ts +6 -3
  55. package/src/intellisense/AutoComplete.test.ts +21 -2
  56. package/src/intellisense/AutoComplete.ts +14 -25
  57. package/src/intellisense/Suggestion.ts +0 -1
  58. package/src/intellisense/css/cssValue.ts +1 -1
  59. package/src/intellisense/css/method.ts +1 -1
  60. package/src/intellisense/css/values.ts +1 -1
  61. package/src/intellisense/javascript/Javascript.test.ts +0 -1
  62. package/src/intellisense/javascript/arrayLiteral.ts +1 -1
  63. package/src/intellisense/javascript/expression.ts +1 -1
  64. package/src/intellisense/javascript/invocation.ts +1 -1
  65. package/src/intellisense/javascript/objectLiteral.ts +1 -1
  66. package/src/intellisense/javascript/parameters.ts +1 -1
  67. package/src/intellisense/javascript/stringLiteral.ts +2 -4
  68. package/src/patterns/And.test.ts +5 -5
  69. package/src/patterns/And.ts +11 -17
  70. package/src/patterns/Cursor.ts +4 -0
  71. package/src/patterns/CursorHistory.ts +34 -5
  72. package/src/patterns/FiniteRepeat.test.ts +481 -0
  73. package/src/patterns/FiniteRepeat.ts +231 -0
  74. package/src/patterns/InfiniteRepeat.test.ts +296 -0
  75. package/src/patterns/InfiniteRepeat.ts +329 -0
  76. package/src/patterns/Literal.test.ts +4 -4
  77. package/src/patterns/Literal.ts +1 -1
  78. package/src/patterns/Not.test.ts +11 -11
  79. package/src/patterns/Not.ts +1 -1
  80. package/src/patterns/Or.test.ts +9 -9
  81. package/src/patterns/Or.ts +1 -1
  82. package/src/patterns/Pattern.ts +1 -1
  83. package/src/patterns/Reference.test.ts +8 -8
  84. package/src/patterns/Reference.ts +1 -1
  85. package/src/patterns/Regex.test.ts +4 -4
  86. package/src/patterns/Regex.ts +1 -1
  87. package/src/patterns/Repeat.test.ts +160 -165
  88. package/src/patterns/Repeat.ts +95 -230
@@ -0,0 +1,329 @@
1
+ import { Node } from "../ast/Node";
2
+ import { Cursor } from "./Cursor";
3
+ import { Pattern } from "./Pattern";
4
+ import { clonePatterns } from "./clonePatterns";
5
+ import { findPattern } from "./findPattern";
6
+
7
+ export interface InfiniteRepeatOptions {
8
+ divider?: Pattern;
9
+ min?: number;
10
+ trimDivider?: boolean;
11
+ }
12
+
13
+ export class InfiniteRepeat implements Pattern {
14
+ private _type: string;
15
+ private _name: string;
16
+ private _parent: Pattern | null;
17
+ private _children: Pattern[];
18
+ private _pattern: Pattern;
19
+ private _divider: Pattern | null;
20
+ private _nodes: Node[];
21
+ private _firstIndex: number;
22
+ private _min: number;
23
+ private _trimDivider: boolean;
24
+
25
+ get type(): string {
26
+ return this._type;
27
+ }
28
+
29
+ get name(): string {
30
+ return this._name;
31
+ }
32
+
33
+ get parent(): Pattern | null {
34
+ return this._parent;
35
+ }
36
+
37
+ set parent(pattern: Pattern | null) {
38
+ this._parent = pattern;
39
+ }
40
+
41
+ get children(): Pattern[] {
42
+ return this._children;
43
+ }
44
+
45
+ get isOptional(): boolean {
46
+ return this._min === 0;
47
+ }
48
+
49
+ get min(): number {
50
+ return this._min;
51
+ }
52
+
53
+ constructor(name: string, pattern: Pattern, options: InfiniteRepeatOptions = {}) {
54
+ const min = options.min != null ? options.min : 1;
55
+ const divider = options.divider;
56
+ let children: Pattern[];
57
+
58
+ if (divider != null) {
59
+ children = [pattern.clone(), divider.clone(divider.name, false)]
60
+ } else {
61
+ children = [pattern.clone()]
62
+ }
63
+
64
+ this._assignChildrenToParent(children);
65
+
66
+ this._type = "infinite-repeat";
67
+ this._name = name;
68
+ this._min = min;
69
+ this._parent = null;
70
+ this._children = children;
71
+ this._pattern = children[0];
72
+ this._divider = children[1];
73
+ this._firstIndex = -1
74
+ this._nodes = [];
75
+ this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
76
+ }
77
+
78
+ private _assignChildrenToParent(children: Pattern[]): void {
79
+ for (const child of children) {
80
+ child.parent = this;
81
+ }
82
+ }
83
+
84
+ test(text: string) {
85
+ const cursor = new Cursor(text);
86
+ const ast = this.parse(cursor);
87
+
88
+ return ast?.value === text;
89
+ }
90
+
91
+ exec(text: string) {
92
+ const cursor = new Cursor(text);
93
+ const ast = this.parse(cursor);
94
+
95
+ return {
96
+ ast: ast?.value === text ? ast : null,
97
+ cursor
98
+ };
99
+ }
100
+
101
+ parse(cursor: Cursor): Node | null {
102
+ this._firstIndex = cursor.index;
103
+ this._nodes = [];
104
+
105
+ const passed = this._tryToParse(cursor);
106
+
107
+ if (passed) {
108
+ cursor.resolveError();
109
+ const node = this._createNode(cursor);
110
+
111
+ if (node != null) {
112
+ cursor.moveTo(node.lastIndex);
113
+ cursor.recordMatch(this, node);
114
+ }
115
+
116
+ return node;
117
+ }
118
+
119
+ if (this._min > 0) {
120
+ return null;
121
+ }
122
+
123
+ cursor.resolveError();
124
+ return null;
125
+ }
126
+
127
+ private _meetsMin() {
128
+ if (this._divider != null) {
129
+ return Math.ceil(this._nodes.length / 2) >= this._min;
130
+ }
131
+ return this._nodes.length >= this._min;
132
+ }
133
+
134
+ private _tryToParse(cursor: Cursor): boolean {
135
+ let passed = false;
136
+
137
+ while (true) {
138
+ const runningCursorIndex = cursor.index;
139
+ const repeatedNode = this._pattern.parse(cursor);
140
+
141
+ if (cursor.hasError) {
142
+ const lastValidNode = this._getLastValidNode();
143
+
144
+ if (lastValidNode != null) {
145
+ passed = true;
146
+ } else {
147
+ cursor.moveTo(runningCursorIndex);
148
+ cursor.recordErrorAt(runningCursorIndex, this._pattern);
149
+ passed = false;
150
+ }
151
+
152
+ break;
153
+ } else {
154
+ if (repeatedNode != null) {
155
+ this._nodes.push(repeatedNode);
156
+
157
+ if (!cursor.hasNext()) {
158
+ passed = true;
159
+ break;
160
+ }
161
+
162
+ cursor.next();
163
+ }
164
+
165
+ if (this._divider != null) {
166
+ const dividerNode = this._divider.parse(cursor);
167
+
168
+ if (cursor.hasError) {
169
+ passed = true;
170
+ break;
171
+ } else if (dividerNode != null) {
172
+ this._nodes.push(dividerNode);
173
+
174
+ if (!cursor.hasNext()) {
175
+ passed = true;
176
+ break;
177
+ }
178
+
179
+ cursor.next();
180
+ }
181
+ }
182
+ }
183
+ }
184
+
185
+ const hasMinimum = this._meetsMin();
186
+
187
+ if (hasMinimum) {
188
+ return passed;
189
+ } else if (!hasMinimum && passed) {
190
+ cursor.recordErrorAt(cursor.index, this);
191
+ cursor.moveTo(this._firstIndex);
192
+ return false;
193
+ }
194
+
195
+ return passed;
196
+ }
197
+
198
+ private _createNode(cursor: Cursor): Node | null {
199
+ const hasDivider = this._divider != null;
200
+
201
+ if (
202
+ hasDivider &&
203
+ this._trimDivider &&
204
+ cursor.leafMatch.pattern === this._divider
205
+ ) {
206
+ const dividerNode = this._nodes.pop() as Node;
207
+ cursor.moveTo(dividerNode.firstIndex);
208
+ }
209
+
210
+ const lastIndex = this._nodes[this._nodes.length - 1].lastIndex;
211
+ cursor.moveTo(lastIndex);
212
+
213
+ return new Node(
214
+ this._type,
215
+ this._name,
216
+ this._firstIndex,
217
+ lastIndex,
218
+ this._nodes
219
+ );
220
+ }
221
+
222
+ private _getLastValidNode(): Node | null {
223
+ const nodes = this._nodes.filter((node) => node !== null);
224
+
225
+ if (nodes.length === 0) {
226
+ return null;
227
+ }
228
+
229
+ return nodes[nodes.length - 1];
230
+ }
231
+
232
+ getTokens(): string[] {
233
+ return this._pattern.getTokens();
234
+ }
235
+
236
+ getTokensAfter(childReference: Pattern): string[] {
237
+ const patterns = this.getPatternsAfter(childReference);
238
+ const tokens: string[] = [];
239
+
240
+ patterns.forEach(p => tokens.push(...p.getTokens()));
241
+
242
+ return tokens;
243
+ }
244
+
245
+ getNextTokens(): string[] {
246
+ if (this._parent == null) {
247
+ return []
248
+ }
249
+
250
+ return this._parent.getTokensAfter(this);
251
+ }
252
+
253
+ getPatterns(): Pattern[] {
254
+ return this._pattern.getPatterns();
255
+ }
256
+
257
+ getPatternsAfter(childReference: Pattern): Pattern[] {
258
+ let index = -1;
259
+ const patterns: Pattern[] = [];
260
+
261
+ for (let i = 0; i < this._children.length; i++) {
262
+ if (this._children[i] === childReference) {
263
+ index = i;
264
+ }
265
+ }
266
+
267
+ // If the last match isn't a child of this pattern.
268
+ if (index === -1) {
269
+ return [];
270
+ }
271
+
272
+ // If the last match was the repeated patterns, then suggest the divider.
273
+ if (index === 0 && this._divider) {
274
+ patterns.push(this._children[1]);
275
+
276
+ if (this._parent) {
277
+ patterns.push(...this._parent.getPatternsAfter(this));
278
+ }
279
+ }
280
+
281
+ // Suggest the pattern because the divider was the last match.
282
+ if (index === 1) {
283
+ patterns.push(this._children[0]);
284
+ }
285
+
286
+ // If there is no divider then suggest the repeating pattern and the next pattern after.
287
+ if (index === 0 && !this._divider && this._parent) {
288
+ patterns.push(this._children[0]);
289
+ patterns.push(...this._parent.getPatternsAfter(this));
290
+ }
291
+
292
+ return patterns;
293
+ }
294
+
295
+ getNextPatterns(): Pattern[] {
296
+ if (this._parent == null) {
297
+ return [];
298
+ }
299
+
300
+ return this._parent.getPatternsAfter(this)
301
+ }
302
+
303
+ find(predicate: (p: Pattern) => boolean): Pattern | null {
304
+ return findPattern(this, predicate);
305
+ }
306
+
307
+ clone(name = this._name, isOptional?: boolean): Pattern {
308
+ let min = this._min;
309
+
310
+ if (isOptional != null) {
311
+ if (isOptional) {
312
+ min = 0
313
+ } else {
314
+ min = Math.max(this._min, 1);
315
+ }
316
+ }
317
+
318
+ return new InfiniteRepeat(
319
+ name,
320
+ this._pattern,
321
+ {
322
+ divider: this._divider == null ? undefined : this._divider,
323
+ min: min,
324
+ trimDivider: this._trimDivider
325
+ }
326
+ );
327
+ }
328
+ }
329
+
@@ -119,7 +119,7 @@ describe("Literal", () => {
119
119
  const sequence = new And("sequence", [new Literal("a", "A")]);
120
120
  const parent = new And("parent", [sequence, new Literal("b", "B")]);
121
121
 
122
- const a = parent.findPattern(p => p.name === "a");
122
+ const a = parent.find(p => p.name === "a");
123
123
  const tokens = a?.getNextTokens() || [];
124
124
 
125
125
  expect(tokens[0]).toBe("B");
@@ -145,9 +145,9 @@ describe("Literal", () => {
145
145
  const sequence = new And("sequence", [new Literal("a", "A")]);
146
146
  const parent = new And("parent", [sequence, new Literal("b", "B")]);
147
147
 
148
- const a = parent.findPattern(p => p.name === "a");
148
+ const a = parent.find(p => p.name === "a");
149
149
  const nextPatterns = a?.getNextPatterns() || [];
150
- const b = parent.findPattern(p => p.name === "b")
150
+ const b = parent.find(p => p.name === "b")
151
151
 
152
152
  expect(nextPatterns[0]).toBe(b);
153
153
  });
@@ -168,7 +168,7 @@ describe("Literal", () => {
168
168
 
169
169
  test("Find Pattern", () => {
170
170
  const a = new Literal("a", "A");
171
- const pattern = a.findPattern(p => p.name === "nada");
171
+ const pattern = a.find(p => p.name === "nada");
172
172
 
173
173
  expect(pattern).toBeNull();
174
174
  });
@@ -167,7 +167,7 @@ export class Literal implements Pattern {
167
167
  return this.parent.getPatternsAfter(this)
168
168
  }
169
169
 
170
- findPattern(_predicate: (p: Pattern) => boolean): Pattern | null {
170
+ find(_predicate: (p: Pattern) => boolean): Pattern | null {
171
171
  return null;
172
172
  }
173
173
 
@@ -88,7 +88,7 @@ describe("Not", () => {
88
88
  const notAboutUs = new Not("not-about-us", new Literal("about-us", "About Us"));
89
89
  const sequence = new And("sequence", [notAboutUs, new Literal("about-them", "About Them")]);
90
90
 
91
- const cloneNotAboutUs = sequence.findPattern(p => p.name === "not-about-us") as Pattern;
91
+ const cloneNotAboutUs = sequence.find(p => p.name === "not-about-us") as Pattern;
92
92
  const nextTokens = cloneNotAboutUs.getNextTokens() || [];
93
93
 
94
94
  expect(nextTokens[0]).toBe("About Them");
@@ -105,7 +105,7 @@ describe("Not", () => {
105
105
  const notAboutUs = new Not("not-about-us", new Literal("about-us", "About Us"));
106
106
  const sequence = new And("sequence", [notAboutUs, new Literal("about-them", "About Them")]);
107
107
 
108
- const cloneNotAboutUs = sequence.findPattern(p => p.name === "not-about-us") as Pattern;
108
+ const cloneNotAboutUs = sequence.find(p => p.name === "not-about-us") as Pattern;
109
109
  const nextTokens = cloneNotAboutUs.getTokens() || [];
110
110
 
111
111
  expect(nextTokens[0]).toBe("About Them");
@@ -114,8 +114,8 @@ describe("Not", () => {
114
114
  test("Get Tokens After", () => {
115
115
  const notAboutUs = new Not("not-about-us", new Literal("about-us", "About Us"));
116
116
  const sequence = new And("sequence", [notAboutUs, new Literal("about-them", "About Them")]);
117
- const notAboutUsClone = sequence.findPattern(p => p.name === "not-about-us") as Pattern;
118
- const aboutUsClone = sequence.findPattern(p => p.name === "about-us") as Pattern;
117
+ const notAboutUsClone = sequence.find(p => p.name === "not-about-us") as Pattern;
118
+ const aboutUsClone = sequence.find(p => p.name === "about-us") as Pattern;
119
119
  const nextTokens = notAboutUsClone.getTokensAfter(aboutUsClone) || [];
120
120
 
121
121
  expect(nextTokens[0]).toBe("About Them");
@@ -123,7 +123,7 @@ describe("Not", () => {
123
123
 
124
124
  test("Find Pattern", () => {
125
125
  const notAboutUs = new Not("not-about-us", new Literal("about-us", "About Us"));
126
- const child = notAboutUs.findPattern(p => p.name === "about-us")
126
+ const child = notAboutUs.find(p => p.name === "about-us")
127
127
 
128
128
  expect(child).not.toBeNull();
129
129
  });
@@ -132,9 +132,9 @@ describe("Not", () => {
132
132
  const notAboutUs = new Not("not-about-us", new Literal("about-us", "About Us"));
133
133
  const sequence = new And("sequence", [notAboutUs, new Literal("about-them", "About Them")]);
134
134
 
135
- const cloneNotAboutUs = sequence.findPattern(p => p.name === "not-about-us") as Pattern;
135
+ const cloneNotAboutUs = sequence.find(p => p.name === "not-about-us") as Pattern;
136
136
  const nextPatterns = cloneNotAboutUs.getPatterns();
137
- const expected = [sequence.findPattern(p=>p.name === "about-them")];
137
+ const expected = [sequence.find(p=>p.name === "about-them")];
138
138
 
139
139
  expect(nextPatterns).toEqual(expected);
140
140
  });
@@ -143,7 +143,7 @@ describe("Not", () => {
143
143
  const notAboutUs = new Not("not-about-us", new Literal("about-us", "About Us"));
144
144
  const sequence = new And("sequence", [notAboutUs, new Literal("about-them", "About Them")]);
145
145
 
146
- const cloneNotAboutUs = sequence.findPattern(p => p.name === "not-about-us") as Pattern;
146
+ const cloneNotAboutUs = sequence.find(p => p.name === "not-about-us") as Pattern;
147
147
  const patterns = cloneNotAboutUs.getNextPatterns() || [];
148
148
 
149
149
  expect(patterns.length).toBe(1);
@@ -160,8 +160,8 @@ describe("Not", () => {
160
160
  test("Get Patterns After", () => {
161
161
  const notAboutUs = new Not("not-about-us", new Literal("about-us", "About Us"));
162
162
  const sequence = new And("sequence", [notAboutUs, new Literal("about-them", "About Them")]);
163
- const notAboutUsClone = sequence.findPattern(p => p.name === "not-about-us") as Pattern;
164
- const aboutUsClone = sequence.findPattern(p => p.name === "about-us") as Pattern;
163
+ const notAboutUsClone = sequence.find(p => p.name === "not-about-us") as Pattern;
164
+ const aboutUsClone = sequence.find(p => p.name === "about-us") as Pattern;
165
165
  const patterns = notAboutUsClone.getPatternsAfter(aboutUsClone) || [];
166
166
 
167
167
  expect(patterns.length).toBe(1);
@@ -170,7 +170,7 @@ describe("Not", () => {
170
170
 
171
171
  test("Get Patterns After With Null Parent", () => {
172
172
  const notAboutUs = new Not("not-about-us", new Literal("about-us", "About Us"));
173
- const aboutUsClone = notAboutUs.findPattern(p => p.name === "about-us") as Pattern;
173
+ const aboutUsClone = notAboutUs.find(p => p.name === "about-us") as Pattern;
174
174
  const patterns = notAboutUs.getPatternsAfter(aboutUsClone) || [];
175
175
 
176
176
  expect(patterns.length).toBe(0);
@@ -128,7 +128,7 @@ export class Not implements Pattern {
128
128
  return this.parent.getPatternsAfter(this)
129
129
  }
130
130
 
131
- findPattern(predicate: (p: Pattern) => boolean): Pattern | null {
131
+ find(predicate: (p: Pattern) => boolean): Pattern | null {
132
132
  return predicate(this._children[0]) ? this._children[0] : null;
133
133
  }
134
134
 
@@ -118,7 +118,7 @@ describe("Or", () => {
118
118
  new Literal("c", "C")
119
119
  ]);
120
120
 
121
- const orClone = sequence.findPattern(p => p.name === "a-or-b") as Pattern;
121
+ const orClone = sequence.find(p => p.name === "a-or-b") as Pattern;
122
122
  const tokens = orClone.getNextTokens();
123
123
 
124
124
  expect(tokens.length).toBe(1);
@@ -145,8 +145,8 @@ describe("Or", () => {
145
145
  new Literal("c", "C")
146
146
  ]);
147
147
 
148
- const aClone = sequence.findPattern(p => p.name === "a") as Pattern;
149
- const orClone = sequence.findPattern(p => p.name === "a-or-b") as Pattern;
148
+ const aClone = sequence.find(p => p.name === "a") as Pattern;
149
+ const orClone = sequence.find(p => p.name === "a-or-b") as Pattern;
150
150
  const tokens = orClone.getTokensAfter(aClone);
151
151
 
152
152
  expect(tokens.length).toBe(1);
@@ -157,8 +157,8 @@ describe("Or", () => {
157
157
  const aOrB = new Or("a-b", [new Literal("a", "A"), new Literal("b", "B")]);
158
158
  const patterns = aOrB.getPatterns();
159
159
  const expected = [
160
- aOrB.findPattern(p => p.name === "a"),
161
- aOrB.findPattern(p => p.name === "b")
160
+ aOrB.find(p => p.name === "a"),
161
+ aOrB.find(p => p.name === "b")
162
162
  ];
163
163
 
164
164
  expect(patterns).toEqual(expected);
@@ -173,8 +173,8 @@ describe("Or", () => {
173
173
  new Literal("c", "C")
174
174
  ]);
175
175
 
176
- const aClone = sequence.findPattern(p => p.name === "a") as Pattern;
177
- const orClone = sequence.findPattern(p => p.name === "a-or-b") as Pattern;
176
+ const aClone = sequence.find(p => p.name === "a") as Pattern;
177
+ const orClone = sequence.find(p => p.name === "a-or-b") as Pattern;
178
178
  const patterns = orClone.getPatternsAfter(aClone);
179
179
 
180
180
  expect(patterns.length).toBe(1);
@@ -186,7 +186,7 @@ describe("Or", () => {
186
186
  new Literal("a", "A"),
187
187
  new Literal("b", "B")
188
188
  ])
189
- const aClone = or.findPattern(p => p.name === "a") as Pattern;
189
+ const aClone = or.find(p => p.name === "a") as Pattern;
190
190
  const patterns = or.getPatternsAfter(aClone);
191
191
 
192
192
  expect(patterns.length).toBe(0);
@@ -201,7 +201,7 @@ describe("Or", () => {
201
201
  new Literal("c", "C")
202
202
  ]);
203
203
 
204
- const orClone = sequence.findPattern(p => p.name === "a-or-b") as Pattern;
204
+ const orClone = sequence.find(p => p.name === "a-or-b") as Pattern;
205
205
  const patterns = orClone.getNextPatterns();
206
206
 
207
207
  expect(patterns.length).toBe(1);
@@ -162,7 +162,7 @@ export class Or implements Pattern {
162
162
  return this.parent.getPatternsAfter(this)
163
163
  }
164
164
 
165
- findPattern(predicate: (p: Pattern) => boolean): Pattern | null {
165
+ find(predicate: (p: Pattern) => boolean): Pattern | null {
166
166
  return findPattern(this, predicate);
167
167
  }
168
168
 
@@ -19,5 +19,5 @@ export interface Pattern {
19
19
  getPatterns(): Pattern[];
20
20
  getPatternsAfter(childReference: Pattern): Pattern[];
21
21
  getNextPatterns(): Pattern[];
22
- findPattern(predicate: (p: Pattern) => boolean): Pattern | null;
22
+ find(predicate: (p: Pattern) => boolean): Pattern | null;
23
23
  }
@@ -19,7 +19,7 @@ function createValuePattern() {
19
19
  divider.setTokens([", "]);
20
20
 
21
21
  const valueRef = new Reference("value");
22
- const values = new Repeat("values", valueRef, divider);
22
+ const values = new Repeat("values", valueRef, { divider });
23
23
  const array = new And("array", [openBracket, values, closeBracket]);
24
24
  const value = new Or("value", [number, array]);
25
25
 
@@ -34,7 +34,7 @@ describe("Reference", () => {
34
34
 
35
35
  const expected = new Node("and", "array", 0, 5, [
36
36
  new Node("literal", "open-bracket", 0, 0, [], "["),
37
- new Node("repeat", "values", 1, 4, [
37
+ new Node("infinite-repeat", "values", 1, 4, [
38
38
  new Node("regex", "number", 1, 1, [], "1"),
39
39
  new Node("regex", "divider", 2, 3, [], ", "),
40
40
  new Node("regex", "number", 4, 4, [], "2")
@@ -114,9 +114,9 @@ describe("Reference", () => {
114
114
 
115
115
  test("Find Pattern", () => {
116
116
  const value = createValuePattern();
117
- const reference = value.findPattern(p => p.type === "reference") as Pattern;
117
+ const reference = value.find(p => p.type === "reference") as Pattern;
118
118
 
119
- const pattern = reference?.findPattern(p => p.name === "Nada");
119
+ const pattern = reference?.find(p => p.name === "Nada");
120
120
 
121
121
  expect(pattern).toBe(null);
122
122
  });
@@ -124,7 +124,7 @@ describe("Reference", () => {
124
124
 
125
125
  test("Get Next Tokens", () => {
126
126
  const value = createValuePattern();
127
- const reference = value.findPattern(p => p.type === "reference") as Pattern;
127
+ const reference = value.find(p => p.type === "reference") as Pattern;
128
128
  const tokens = reference.getNextTokens();
129
129
 
130
130
  expect(tokens).toEqual([", ", "]"]);
@@ -139,7 +139,7 @@ describe("Reference", () => {
139
139
 
140
140
  test("Get Tokens After", () => {
141
141
  const value = createValuePattern();
142
- const reference = value.findPattern(p => p.type === "reference") as Pattern;
142
+ const reference = value.find(p => p.type === "reference") as Pattern;
143
143
  const tokens = reference.getTokensAfter(new Literal("bogus", "Bogus"));
144
144
 
145
145
  expect(tokens).toEqual([", ", "]"]);
@@ -164,7 +164,7 @@ describe("Reference", () => {
164
164
 
165
165
  test("Get Patterns After", () => {
166
166
  const value = createValuePattern();
167
- const reference = value.findPattern(p => p.type === "reference") as Pattern;
167
+ const reference = value.find(p => p.type === "reference") as Pattern;
168
168
  const patterns = reference.getPatternsAfter(new Literal("bogus", "Bogus"));
169
169
 
170
170
  expect(patterns.length).toEqual(2);
@@ -183,7 +183,7 @@ describe("Reference", () => {
183
183
 
184
184
  test("Get Next Patterns", () => {
185
185
  const value = createValuePattern();
186
- const reference = value.findPattern(p => p.type === "reference") as Pattern;
186
+ const reference = value.find(p => p.type === "reference") as Pattern;
187
187
  const patterns = reference.getNextPatterns();
188
188
 
189
189
  expect(patterns.length).toEqual(2);
@@ -147,7 +147,7 @@ export class Reference implements Pattern {
147
147
  return this.parent.getPatternsAfter(this)
148
148
  }
149
149
 
150
- findPattern(_predicate: (p: Pattern) => boolean): Pattern | null {
150
+ find(_predicate: (p: Pattern) => boolean): Pattern | null {
151
151
  return null;
152
152
  }
153
153
 
@@ -86,7 +86,7 @@ describe("Regex", () => {
86
86
 
87
87
  test("Get Next Tokens", () => {
88
88
  const parent = new And("parent", [new Regex("a", "A"), new Literal("b", "B")]);
89
- const aClone = parent.findPattern(p => p.name === "a") as Pattern;
89
+ const aClone = parent.find(p => p.name === "a") as Pattern;
90
90
  const tokens = aClone.getNextTokens();
91
91
 
92
92
  expect(tokens).toEqual(["B"]);
@@ -117,15 +117,15 @@ describe("Regex", () => {
117
117
 
118
118
  test("Find Pattern", () => {
119
119
  const a = new Regex("a", "A")
120
- const pattern = a.findPattern(p => p.name === "other");
120
+ const pattern = a.find(p => p.name === "other");
121
121
 
122
122
  expect(pattern).toBeNull();
123
123
  });
124
124
 
125
125
  test("Get Next Patterns", () => {
126
126
  const parent = new And("parent", [new Regex("a", "A"), new Literal("b", "B")]);
127
- const aClone = parent.findPattern(p => p.name === "a") as Pattern;
128
- const bClone = parent.findPattern(p => p.name === "b") as Pattern;
127
+ const aClone = parent.find(p => p.name === "a") as Pattern;
128
+ const bClone = parent.find(p => p.name === "b") as Pattern;
129
129
  const patterns = aClone.getNextPatterns();
130
130
 
131
131
  expect(patterns.length).toBe(1);
@@ -173,7 +173,7 @@ export class Regex implements Pattern {
173
173
  return this.parent.getPatternsAfter(this)
174
174
  }
175
175
 
176
- findPattern(_predicate: (p: Pattern) => boolean): Pattern | null {
176
+ find(_predicate: (p: Pattern) => boolean): Pattern | null {
177
177
  return null;
178
178
  }
179
179