clarity-pattern-parser 8.4.15 → 9.1.0

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 (110) hide show
  1. package/TODO.md +4 -1
  2. package/dist/grammar/Grammar.d.ts +20 -12
  3. package/dist/grammar/patterns/andLiteral.d.ts +2 -0
  4. package/dist/grammar/patterns/anonymousPattern.d.ts +2 -0
  5. package/dist/grammar/patterns/grammar.d.ts +2 -2
  6. package/dist/grammar/patterns/import.d.ts +2 -2
  7. package/dist/grammar/patterns/inlinePattern.d.ts +1 -0
  8. package/dist/grammar/patterns/literals.d.ts +3 -0
  9. package/dist/grammar/patterns/optionsLiteral.d.ts +2 -0
  10. package/dist/grammar/patterns/pattern.d.ts +2 -2
  11. package/dist/grammar/patterns/repeatLiteral.d.ts +2 -2
  12. package/dist/grammar/patterns/sequenceLiteral.d.ts +4 -0
  13. package/dist/grammar/patterns/statement.d.ts +2 -2
  14. package/dist/grammar/patterns.d.ts +2 -0
  15. package/dist/index.browser.js +752 -382
  16. package/dist/index.browser.js.map +1 -1
  17. package/dist/index.d.ts +6 -3
  18. package/dist/index.esm.js +748 -381
  19. package/dist/index.esm.js.map +1 -1
  20. package/dist/index.js +752 -382
  21. package/dist/index.js.map +1 -1
  22. package/dist/patterns/And.d.ts +4 -1
  23. package/dist/patterns/Cursor.d.ts +5 -0
  24. package/dist/patterns/CursorHistory.d.ts +7 -0
  25. package/dist/patterns/FiniteRepeat.d.ts +7 -4
  26. package/dist/patterns/InfiniteRepeat.d.ts +6 -6
  27. package/dist/patterns/Literal.d.ts +9 -9
  28. package/dist/patterns/Not.d.ts +5 -4
  29. package/dist/patterns/Optional.d.ts +30 -0
  30. package/dist/patterns/Options.d.ts +34 -0
  31. package/dist/patterns/Or.d.ts +5 -4
  32. package/dist/patterns/Pattern.d.ts +5 -4
  33. package/dist/patterns/Reference.d.ts +7 -8
  34. package/dist/patterns/Regex.d.ts +8 -8
  35. package/dist/patterns/Repeat.d.ts +4 -2
  36. package/dist/patterns/Sequence.d.ts +39 -0
  37. package/dist/patterns/arePatternsEqual.d.ts +2 -0
  38. package/dist/patterns/clonePatterns.d.ts +1 -1
  39. package/package.json +1 -1
  40. package/src/grammar/Grammar.test.ts +117 -74
  41. package/src/grammar/Grammar.ts +241 -158
  42. package/src/grammar/patterns/anonymousPattern.ts +23 -0
  43. package/src/grammar/patterns/body.ts +9 -6
  44. package/src/grammar/patterns/comment.ts +3 -2
  45. package/src/grammar/patterns/grammar.ts +15 -12
  46. package/src/grammar/patterns/import.ts +18 -12
  47. package/src/grammar/patterns/literal.ts +2 -1
  48. package/src/grammar/patterns/literals.ts +20 -0
  49. package/src/grammar/patterns/optionsLiteral.ts +19 -0
  50. package/src/grammar/patterns/pattern.ts +23 -9
  51. package/src/grammar/patterns/regexLiteral.ts +1 -0
  52. package/src/grammar/patterns/repeatLiteral.ts +30 -25
  53. package/src/grammar/patterns/sequenceLiteral.ts +24 -0
  54. package/src/grammar/patterns/spaces.ts +8 -6
  55. package/src/grammar/patterns/statement.ts +8 -20
  56. package/src/grammar/patterns.test.ts +38 -0
  57. package/src/grammar/patterns.ts +24 -0
  58. package/src/grammar/spec.md +4 -12
  59. package/src/index.ts +11 -5
  60. package/src/intellisense/AutoComplete.test.ts +41 -40
  61. package/src/intellisense/css/method.ts +2 -2
  62. package/src/intellisense/css/unit.ts +2 -2
  63. package/src/intellisense/css/value.ts +1 -1
  64. package/src/intellisense/javascript/Javascript.test.ts +31 -32
  65. package/src/intellisense/javascript/arrayLiteral.ts +7 -6
  66. package/src/intellisense/javascript/assignment.ts +6 -6
  67. package/src/intellisense/javascript/deleteStatement.ts +2 -2
  68. package/src/intellisense/javascript/escapedCharacter.ts +6 -6
  69. package/src/intellisense/javascript/exponent.ts +6 -6
  70. package/src/intellisense/javascript/expression.ts +18 -17
  71. package/src/intellisense/javascript/fraction.ts +3 -3
  72. package/src/intellisense/javascript/infixOperator.ts +10 -10
  73. package/src/intellisense/javascript/integer.ts +1 -1
  74. package/src/intellisense/javascript/invocation.ts +8 -7
  75. package/src/intellisense/javascript/literal.ts +3 -3
  76. package/src/intellisense/javascript/numberLiteral.ts +5 -4
  77. package/src/intellisense/javascript/objectAccess.ts +2 -3
  78. package/src/intellisense/javascript/objectLiteral.ts +8 -7
  79. package/src/intellisense/javascript/optionalSpaces.ts +2 -1
  80. package/src/intellisense/javascript/parameters.ts +5 -5
  81. package/src/intellisense/javascript/prefixOperator.ts +3 -4
  82. package/src/intellisense/javascript/propertyAccess.ts +9 -8
  83. package/src/intellisense/javascript/stringLiteral.ts +14 -15
  84. package/src/patterns/Cursor.ts +42 -4
  85. package/src/patterns/CursorHistory.ts +20 -4
  86. package/src/patterns/FiniteRepeat.test.ts +52 -51
  87. package/src/patterns/FiniteRepeat.ts +60 -38
  88. package/src/patterns/InfiniteRepeat.test.ts +36 -49
  89. package/src/patterns/InfiniteRepeat.ts +70 -37
  90. package/src/patterns/Literal.test.ts +16 -27
  91. package/src/patterns/Literal.ts +38 -27
  92. package/src/patterns/Not.test.ts +7 -7
  93. package/src/patterns/Not.ts +24 -6
  94. package/src/patterns/Optional.test.ts +164 -0
  95. package/src/patterns/Optional.ts +143 -0
  96. package/src/patterns/{Or.test.ts → Options.test.ts} +51 -49
  97. package/src/patterns/{Or.ts → Options.ts} +32 -23
  98. package/src/patterns/Pattern.ts +6 -5
  99. package/src/patterns/Reference.test.ts +21 -22
  100. package/src/patterns/Reference.ts +26 -15
  101. package/src/patterns/Regex.test.ts +15 -15
  102. package/src/patterns/Regex.ts +33 -19
  103. package/src/patterns/Repeat.test.ts +12 -22
  104. package/src/patterns/Repeat.ts +22 -21
  105. package/src/patterns/{And.test.ts → Sequence.test.ts} +78 -78
  106. package/src/patterns/{And.ts → Sequence.ts} +40 -29
  107. package/src/patterns/arePatternsEqual.ts +12 -0
  108. package/src/patterns/clonePatterns.ts +2 -2
  109. package/src/grammar/patterns/andLiteral.ts +0 -8
  110. package/src/grammar/patterns/orLiteral.ts +0 -8
@@ -1,21 +1,21 @@
1
1
  import { Cursor } from "./Cursor";
2
2
  import { Regex } from "./Regex";
3
3
  import { Node } from "../ast/Node"
4
- import { And } from "./And";
4
+ import { Sequence } from "./Sequence";
5
5
  import { Literal } from "./Literal";
6
6
  import { Pattern } from "./Pattern";
7
7
 
8
8
  describe("Regex", () => {
9
9
  test("Empty String", () => {
10
- expect(() => new Regex("empty", "")).toThrowError()
10
+ expect(() => new Regex("empty", "")).toThrowError();
11
11
  });
12
12
 
13
13
  test("Starts With ^", () => {
14
- expect(() => new Regex("carrot", "^")).toThrowError()
14
+ expect(() => new Regex("carrot", "^")).toThrowError();
15
15
  });
16
16
 
17
17
  test("Ends With $", () => {
18
- expect(() => new Regex("money", ".$")).toThrowError()
18
+ expect(() => new Regex("money", ".$")).toThrowError();
19
19
  });
20
20
 
21
21
  test("Successful Parse", () => {
@@ -25,8 +25,8 @@ describe("Regex", () => {
25
25
  const expected = new Node("regex", "number", 0, 0, [], "1");
26
26
 
27
27
  expect(result).toEqual(expected);
28
- expect(cursor.hasError).toBeFalsy()
29
- })
28
+ expect(cursor.hasError).toBeFalsy();
29
+ });
30
30
 
31
31
  test("Failed Parse", () => {
32
32
  const number = new Regex("number", "\\d");
@@ -34,7 +34,7 @@ describe("Regex", () => {
34
34
  const result = number.parse(cursor);
35
35
 
36
36
  expect(result).toBeNull();
37
- expect(cursor.hasError).toBeTruthy()
37
+ expect(cursor.hasError).toBeTruthy();
38
38
  });
39
39
 
40
40
 
@@ -54,7 +54,7 @@ describe("Regex", () => {
54
54
  const tokens = regex.getTokensAfter(new Literal("bogus", "bogus"));
55
55
  const expected: string[] = [];
56
56
 
57
- expect(tokens).toEqual(expected)
57
+ expect(tokens).toEqual(expected);
58
58
  });
59
59
 
60
60
  test("Properties", () => {
@@ -85,7 +85,7 @@ describe("Regex", () => {
85
85
  });
86
86
 
87
87
  test("Get Next Tokens", () => {
88
- const parent = new And("parent", [new Regex("a", "A"), new Literal("b", "B")]);
88
+ const parent = new Sequence("parent", [new Regex("a", "A"), new Literal("b", "B")]);
89
89
  const aClone = parent.find(p => p.name === "a") as Pattern;
90
90
  const tokens = aClone.getNextTokens();
91
91
 
@@ -93,7 +93,7 @@ describe("Regex", () => {
93
93
  });
94
94
 
95
95
  test("Get Next Tokens With Null Parent", () => {
96
- const a = new Regex("a", "A")
96
+ const a = new Regex("a", "A");
97
97
  const tokens = a.getNextTokens();
98
98
 
99
99
  expect(tokens).toEqual([]);
@@ -109,21 +109,21 @@ describe("Regex", () => {
109
109
  });
110
110
 
111
111
  test("Get Patterns After", () => {
112
- const a = new Regex("a", "A")
112
+ const a = new Regex("a", "A");
113
113
  const patterns = a.getPatternsAfter(new Literal("bogus", "bogus"));
114
114
 
115
115
  expect(patterns).toEqual([]);
116
116
  });
117
117
 
118
118
  test("Find Pattern", () => {
119
- const a = new Regex("a", "A")
119
+ const a = new Regex("a", "A");
120
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
- const parent = new And("parent", [new Regex("a", "A"), new Literal("b", "B")]);
126
+ const parent = new Sequence("parent", [new Regex("a", "A"), new Literal("b", "B")]);
127
127
  const aClone = parent.find(p => p.name === "a") as Pattern;
128
128
  const bClone = parent.find(p => p.name === "b") as Pattern;
129
129
  const patterns = aClone.getNextPatterns();
@@ -133,10 +133,10 @@ describe("Regex", () => {
133
133
  });
134
134
 
135
135
  test("Get Next Patterns With Null Parent", () => {
136
- const a = new Regex("a", "A")
136
+ const a = new Regex("a", "A");
137
137
  const patterns = a.getNextPatterns();
138
138
 
139
- expect(patterns).toEqual([])
139
+ expect(patterns).toEqual([]);
140
140
  });
141
141
 
142
142
  });
@@ -1,11 +1,14 @@
1
1
  import { Node } from "../ast/Node";
2
2
  import { Pattern } from "./Pattern";
3
3
  import { Cursor } from "./Cursor";
4
+ import { ParseResult } from "./ParseResult";
5
+
6
+ let idIndex = 0;
4
7
 
5
8
  export class Regex implements Pattern {
9
+ private _id: string;
6
10
  private _type: string;
7
11
  private _name: string;
8
- private _isOptional: boolean;
9
12
  private _parent: Pattern | null;
10
13
  private _originalRegexString: string;
11
14
  private _regex: RegExp;
@@ -15,6 +18,10 @@ export class Regex implements Pattern {
15
18
  private _substring = "";
16
19
  private _tokens: string[] = [];
17
20
 
21
+ get id(): string {
22
+ return this._id;
23
+ }
24
+
18
25
  get type(): string {
19
26
  return this._type;
20
27
  }
@@ -23,6 +30,10 @@ export class Regex implements Pattern {
23
30
  return this._name;
24
31
  }
25
32
 
33
+ get value(): string{
34
+ return this._originalRegexString;
35
+ }
36
+
26
37
  get parent(): Pattern | null {
27
38
  return this._parent;
28
39
  }
@@ -35,14 +46,10 @@ export class Regex implements Pattern {
35
46
  return [];
36
47
  }
37
48
 
38
- get isOptional(): boolean {
39
- return this._isOptional;
40
- }
41
-
42
- constructor(name: string, regex: string, isOptional = false) {
43
- this._type = "regex"
49
+ constructor(name: string, regex: string) {
50
+ this._id = `regex-${idIndex++}`;
51
+ this._type = "regex";
44
52
  this._name = name;
45
- this._isOptional = isOptional;
46
53
  this._parent = null;
47
54
  this._originalRegexString = regex;
48
55
  this._regex = new RegExp(`^${regex}`, "g");
@@ -76,8 +83,10 @@ export class Regex implements Pattern {
76
83
  return ast?.value === text;
77
84
  }
78
85
 
79
- exec(text: string) {
86
+ exec(text: string, record = false): ParseResult {
80
87
  const cursor = new Cursor(text);
88
+ record && cursor.startRecording();
89
+
81
90
  const ast = this.parse(cursor);
82
91
 
83
92
  return {
@@ -87,10 +96,13 @@ export class Regex implements Pattern {
87
96
  }
88
97
 
89
98
  parse(cursor: Cursor) {
99
+ cursor.startParseWith(this);
100
+
90
101
  this._firstIndex = cursor.index;
91
102
  this.resetState(cursor);
92
103
  this.tryToParse(cursor);
93
104
 
105
+ cursor.endParse();
94
106
  return this._node;
95
107
  }
96
108
 
@@ -129,18 +141,16 @@ export class Regex implements Pattern {
129
141
  }
130
142
 
131
143
  private processError(cursor: Cursor) {
132
- if (!this._isOptional) {
133
- cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
134
- }
135
-
144
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
136
145
  this._node = null;
137
146
  }
138
147
 
139
- clone(name = this._name, isOptional = this._isOptional) {
140
- const pattern = new Regex(name, this._originalRegexString, isOptional);
141
- pattern._tokens = this._tokens.slice();
148
+ clone(name = this._name) {
149
+ const clone = new Regex(name, this._originalRegexString);
150
+ clone._tokens = this._tokens.slice();
142
151
 
143
- return pattern;
152
+ clone._id = this._id;
153
+ return clone;
144
154
  }
145
155
 
146
156
  getTokens() {
@@ -153,7 +163,7 @@ export class Regex implements Pattern {
153
163
 
154
164
  getNextTokens(): string[] {
155
165
  if (this.parent == null) {
156
- return []
166
+ return [];
157
167
  }
158
168
 
159
169
  return this.parent.getTokensAfter(this);
@@ -172,7 +182,7 @@ export class Regex implements Pattern {
172
182
  return [];
173
183
  }
174
184
 
175
- return this.parent.getPatternsAfter(this)
185
+ return this.parent.getPatternsAfter(this);
176
186
  }
177
187
 
178
188
  find(_predicate: (p: Pattern) => boolean): Pattern | null {
@@ -183,4 +193,8 @@ export class Regex implements Pattern {
183
193
  this._tokens = tokens;
184
194
  }
185
195
 
196
+ isEqual(pattern: Regex): boolean {
197
+ return pattern.type === this.type && pattern._originalRegexString === this._originalRegexString;
198
+ }
199
+
186
200
  }
@@ -1,5 +1,6 @@
1
1
  import { Node } from "../ast/Node";
2
- import { And } from "./And";
2
+ import { Sequence } from "./Sequence";
3
+ import { arePatternsEqual } from "./arePatternsEqual";
3
4
  import { Cursor } from "./Cursor";
4
5
  import { InfiniteRepeat } from "./InfiniteRepeat";
5
6
  import { Literal } from "./Literal";
@@ -26,7 +27,7 @@ describe("Repeat", () => {
26
27
  new Node("regex", "number", 0, 0, [], "1")
27
28
  ]);
28
29
 
29
- expect(result).toEqual(expected);
30
+ expect(result?.toJson()).toEqual(expected.toJson());
30
31
  expect(cursor.hasError).toBeFalsy();
31
32
 
32
33
  cursor = new Cursor("12");
@@ -36,7 +37,7 @@ describe("Repeat", () => {
36
37
  new Node("regex", "number", 1, 1, [], "2")
37
38
  ]);
38
39
 
39
- expect(result).toEqual(expected);
40
+ expect(result?.toJson()).toEqual(expected.toJson());
40
41
  expect(cursor.hasError).toBeFalsy();
41
42
 
42
43
  cursor = new Cursor("123");
@@ -46,7 +47,7 @@ describe("Repeat", () => {
46
47
  new Node("regex", "number", 1, 1, [], "2")
47
48
  ]);
48
49
 
49
- expect(result).toEqual(expected);
50
+ expect(result?.toJson()).toEqual(expected.toJson());
50
51
  expect(cursor.hasError).toBeFalsy();
51
52
  expect(cursor.index).toBe(1);
52
53
  });
@@ -76,7 +77,7 @@ describe("Repeat", () => {
76
77
  new Node("regex", "number", 1, 1, [], "2")
77
78
  ]);
78
79
 
79
- expect(result).toEqual(expected);
80
+ expect(result?.toJson()).toEqual(expected.toJson());
80
81
  expect(cursor.hasError).toBeFalsy();
81
82
 
82
83
  cursor = new Cursor("123");
@@ -86,7 +87,7 @@ describe("Repeat", () => {
86
87
  new Node("regex", "number", 1, 1, [], "2")
87
88
  ]);
88
89
 
89
- expect(result).toEqual(expected);
90
+ expect(result?.toJson()).toEqual(expected.toJson());
90
91
  expect(cursor.hasError).toBeFalsy();
91
92
  expect(cursor.index).toBe(1);
92
93
  });
@@ -115,7 +116,7 @@ describe("Repeat", () => {
115
116
  test("Get Tokens After", () => {
116
117
  const number = new Literal("number", "1");
117
118
  const repeat = new Repeat("numbers", number);
118
- const parent = new And("parent", [repeat, new Literal("b", "B")]);
119
+ const parent = new Sequence("parent", [repeat, new Literal("b", "B")]);
119
120
  const numberClone = parent.find(p => p.name === "number") as Pattern;
120
121
  const repeatClone = parent.children[0];
121
122
 
@@ -128,7 +129,7 @@ describe("Repeat", () => {
128
129
  test("Get Next Tokens", () => {
129
130
  const number = new Literal("number", "1");
130
131
  const repeat = new Repeat("numbers", number);
131
- const parent = new And("parent", [repeat, new Literal("b", "B")]);
132
+ const parent = new Sequence("parent", [repeat, new Literal("b", "B")]);
132
133
  const repeatClone = parent.children[0];
133
134
 
134
135
  let tokens = repeatClone.getNextTokens();
@@ -140,7 +141,7 @@ describe("Repeat", () => {
140
141
  test("Get Next Patterns", () => {
141
142
  const number = new Literal("number", "1");
142
143
  const repeat = new Repeat("numbers", number);
143
- const parent = new And("parent", [repeat, new Literal("b", "B")]);
144
+ const parent = new Sequence("parent", [repeat, new Literal("b", "B")]);
144
145
  const repeatClone = parent.children[0];
145
146
  const bClone = parent.find(p => p.name === "b") as Pattern;
146
147
 
@@ -178,7 +179,6 @@ describe("Repeat", () => {
178
179
  expect(repeat.type).toBe("infinite-repeat");
179
180
  expect(repeat.name).toBe("numbers");
180
181
  expect(repeat.parent).toBeNull();
181
- expect(repeat.isOptional).toBeFalsy();
182
182
  });
183
183
 
184
184
  test("test", () => {
@@ -202,21 +202,11 @@ describe("Repeat", () => {
202
202
  let repeatClone = repeat.clone();
203
203
  let expected = new Repeat("numbers", number);
204
204
 
205
- expect(repeatClone).toEqual(expected);
205
+ expect(arePatternsEqual(repeatClone, expected)).toBeTruthy();
206
206
 
207
207
  repeatClone = repeat.clone("new-name");
208
208
  expected = new Repeat("new-name", number);
209
209
 
210
- expect(repeatClone).toEqual(expected);
211
-
212
- repeatClone = repeat.clone("new-name", false);
213
- expected = new Repeat("new-name", number);
214
-
215
- expect(repeatClone).toEqual(expected);
216
-
217
- repeatClone = repeat.clone("new-name", true);
218
- expected = new Repeat("new-name", number, { min: 0 });
219
-
220
- expect(repeatClone).toEqual(expected);
210
+ expect(arePatternsEqual(repeatClone, expected)).toBeTruthy();
221
211
  });
222
212
  });
@@ -5,6 +5,8 @@ import { InfiniteRepeat } from "./InfiniteRepeat";
5
5
  import { ParseResult } from "./ParseResult";
6
6
  import { Pattern } from "./Pattern";
7
7
 
8
+ let idIndex = 0;
9
+
8
10
  export interface RepeatOptions {
9
11
  min?: number;
10
12
  max?: number;
@@ -19,12 +21,17 @@ interface InternalRepeatOptions {
19
21
  }
20
22
 
21
23
  export class Repeat implements Pattern {
24
+ private _id: string;
22
25
  private _repeatPattern: InfiniteRepeat | FiniteRepeat;
23
26
  private _parent: Pattern | null;
24
27
  private _pattern: Pattern;
25
28
  private _options: InternalRepeatOptions;
26
29
  private _children: Pattern[];
27
30
 
31
+ get id() {
32
+ return this._id;
33
+ }
34
+
28
35
  get type() {
29
36
  return this._repeatPattern.type;
30
37
  }
@@ -45,11 +52,8 @@ export class Repeat implements Pattern {
45
52
  return this._children;
46
53
  }
47
54
 
48
- get isOptional() {
49
- return this._repeatPattern.isOptional;
50
- }
51
-
52
55
  constructor(name: string, pattern: Pattern, options: RepeatOptions = {}) {
56
+ this._id = `repeat-${idIndex++}`;
53
57
  this._pattern = pattern;
54
58
  this._parent = null;
55
59
  this._options = {
@@ -59,12 +63,12 @@ export class Repeat implements Pattern {
59
63
  };
60
64
 
61
65
  if (this._options.max !== Infinity) {
62
- this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
66
+ this._repeatPattern = new FiniteRepeat(name, pattern, this._options);
63
67
  } else {
64
- this._repeatPattern = new InfiniteRepeat(name, pattern, this._options)
68
+ this._repeatPattern = new InfiniteRepeat(name, pattern, this._options);
65
69
  }
66
70
 
67
- this._children = [this._repeatPattern]
71
+ this._children = [this._repeatPattern];
68
72
  this._repeatPattern.parent = this;
69
73
  }
70
74
 
@@ -80,18 +84,12 @@ export class Repeat implements Pattern {
80
84
  return this._repeatPattern.test(text);
81
85
  }
82
86
 
83
- clone(name = this.name, isOptional?: boolean) {
87
+ clone(name = this.name) {
84
88
  let min = this._options.min;
89
+ const clone = new Repeat(name, this._pattern, { ...this._options, min });
85
90
 
86
- if (isOptional != null) {
87
- if (isOptional) {
88
- min = 0
89
- } else {
90
- min = Math.max(this._options.min, 1);
91
- }
92
- }
93
-
94
- return new Repeat(name, this._pattern, { ...this._options, min });
91
+ clone._id = this._id;
92
+ return clone;
95
93
  }
96
94
 
97
95
  getTokens(): string[] {
@@ -100,7 +98,7 @@ export class Repeat implements Pattern {
100
98
 
101
99
  getTokensAfter(_childReference: Pattern): string[] {
102
100
  if (this._parent == null) {
103
- return []
101
+ return [];
104
102
  }
105
103
 
106
104
  return this._parent.getTokensAfter(this);
@@ -108,7 +106,7 @@ export class Repeat implements Pattern {
108
106
 
109
107
  getNextTokens(): string[] {
110
108
  if (this._parent == null) {
111
- return []
109
+ return [];
112
110
  }
113
111
 
114
112
  return this._parent.getTokensAfter(this);
@@ -120,7 +118,7 @@ export class Repeat implements Pattern {
120
118
 
121
119
  getPatternsAfter(_childReference: Pattern): Pattern[] {
122
120
  if (this._parent == null) {
123
- return []
121
+ return [];
124
122
  }
125
123
 
126
124
  return this._parent.getPatternsAfter(this);
@@ -128,7 +126,7 @@ export class Repeat implements Pattern {
128
126
 
129
127
  getNextPatterns(): Pattern[] {
130
128
  if (this._parent == null) {
131
- return []
129
+ return [];
132
130
  }
133
131
 
134
132
  return this._parent.getPatternsAfter(this);
@@ -138,4 +136,7 @@ export class Repeat implements Pattern {
138
136
  return this._repeatPattern.find(predicate);
139
137
  }
140
138
 
139
+ isEqual(pattern: Repeat): boolean {
140
+ return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
141
+ }
141
142
  }