@cparra/apex-reflection 0.1.0-alpha.0 → 0.1.1-alpha.10

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 (158) hide show
  1. package/__tests__/end-to-end.test.ts +256 -0
  2. package/coverage/clover.xml +12857 -0
  3. package/coverage/coverage-final.json +3 -0
  4. package/coverage/lcov-report/base.css +224 -0
  5. package/coverage/lcov-report/block-navigation.js +79 -0
  6. package/coverage/lcov-report/favicon.png +0 -0
  7. package/coverage/lcov-report/index.html +126 -0
  8. package/coverage/lcov-report/index.js.html +104 -0
  9. package/coverage/lcov-report/out.js.html +41126 -0
  10. package/coverage/lcov-report/prettify.css +1 -0
  11. package/coverage/lcov-report/prettify.js +2 -0
  12. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  13. package/coverage/lcov-report/sorter.js +170 -0
  14. package/coverage/lcov.info +24801 -0
  15. package/index.d.ts +118 -0
  16. package/index.js +8 -0
  17. package/index.ts +141 -0
  18. package/jest.config.js +11 -0
  19. package/out.js +13708 -0
  20. package/package.json +22 -17
  21. package/tsconfig.json +5 -3
  22. package/.idea/apexdocs-dart.iml +0 -18
  23. package/.idea/jsLibraryMappings.xml +0 -6
  24. package/.idea/libraries/Dart_Packages.xml +0 -556
  25. package/.idea/libraries/Dart_SDK.xml +0 -28
  26. package/.idea/misc.xml +0 -6
  27. package/.idea/modules.xml +0 -8
  28. package/.idea/runConfigurations/_template__of_Dart_Test.xml +0 -6
  29. package/.idea/vcs.xml +0 -6
  30. package/CHANGELOG.md +0 -3
  31. package/README.md +0 -26
  32. package/TODO.md +0 -5
  33. package/analysis_options.yaml +0 -30
  34. package/antlr4-4.9.2/CHANGELOG.md +0 -4
  35. package/antlr4-4.9.2/LICENSE +0 -52
  36. package/antlr4-4.9.2/README.md +0 -11
  37. package/antlr4-4.9.2/analysis_options.yaml +0 -1
  38. package/antlr4-4.9.2/lib/antlr4.dart +0 -21
  39. package/antlr4-4.9.2/lib/src/atn/atn.dart +0 -18
  40. package/antlr4-4.9.2/lib/src/atn/src/atn.dart +0 -170
  41. package/antlr4-4.9.2/lib/src/atn/src/atn_config.dart +0 -242
  42. package/antlr4-4.9.2/lib/src/atn/src/atn_config_set.dart +0 -283
  43. package/antlr4-4.9.2/lib/src/atn/src/atn_deserializer.dart +0 -809
  44. package/antlr4-4.9.2/lib/src/atn/src/atn_simulator.dart +0 -95
  45. package/antlr4-4.9.2/lib/src/atn/src/atn_state.dart +0 -296
  46. package/antlr4-4.9.2/lib/src/atn/src/atn_type.dart +0 -14
  47. package/antlr4-4.9.2/lib/src/atn/src/info.dart +0 -553
  48. package/antlr4-4.9.2/lib/src/atn/src/lexer_action.dart +0 -601
  49. package/antlr4-4.9.2/lib/src/atn/src/lexer_action_executor.dart +0 -167
  50. package/antlr4-4.9.2/lib/src/atn/src/lexer_atn_simulator.dart +0 -731
  51. package/antlr4-4.9.2/lib/src/atn/src/parser_atn_simulator.dart +0 -2630
  52. package/antlr4-4.9.2/lib/src/atn/src/profiling_atn_simulator.dart +0 -229
  53. package/antlr4-4.9.2/lib/src/atn/src/semantic_context.dart +0 -404
  54. package/antlr4-4.9.2/lib/src/atn/src/transition.dart +0 -305
  55. package/antlr4-4.9.2/lib/src/dfa/dfa.dart +0 -8
  56. package/antlr4-4.9.2/lib/src/dfa/src/dfa.dart +0 -138
  57. package/antlr4-4.9.2/lib/src/dfa/src/dfa_serializer.dart +0 -76
  58. package/antlr4-4.9.2/lib/src/dfa/src/dfa_state.dart +0 -151
  59. package/antlr4-4.9.2/lib/src/error/error.dart +0 -10
  60. package/antlr4-4.9.2/lib/src/error/src/diagnostic_error_listener.dart +0 -116
  61. package/antlr4-4.9.2/lib/src/error/src/error_listener.dart +0 -241
  62. package/antlr4-4.9.2/lib/src/error/src/error_strategy.dart +0 -902
  63. package/antlr4-4.9.2/lib/src/error/src/errors.dart +0 -204
  64. package/antlr4-4.9.2/lib/src/input_stream.dart +0 -335
  65. package/antlr4-4.9.2/lib/src/interval_set.dart +0 -735
  66. package/antlr4-4.9.2/lib/src/lexer.dart +0 -343
  67. package/antlr4-4.9.2/lib/src/ll1_analyzer.dart +0 -204
  68. package/antlr4-4.9.2/lib/src/misc/multi_map.dart +0 -32
  69. package/antlr4-4.9.2/lib/src/misc/pair.dart +0 -34
  70. package/antlr4-4.9.2/lib/src/parser.dart +0 -777
  71. package/antlr4-4.9.2/lib/src/parser_interpreter.dart +0 -393
  72. package/antlr4-4.9.2/lib/src/parser_rule_context.dart +0 -275
  73. package/antlr4-4.9.2/lib/src/prediction_context.dart +0 -877
  74. package/antlr4-4.9.2/lib/src/recognizer.dart +0 -182
  75. package/antlr4-4.9.2/lib/src/rule_context.dart +0 -192
  76. package/antlr4-4.9.2/lib/src/runtime_meta_data.dart +0 -188
  77. package/antlr4-4.9.2/lib/src/token.dart +0 -431
  78. package/antlr4-4.9.2/lib/src/token_factory.dart +0 -88
  79. package/antlr4-4.9.2/lib/src/token_source.dart +0 -241
  80. package/antlr4-4.9.2/lib/src/token_stream.dart +0 -627
  81. package/antlr4-4.9.2/lib/src/tree/src/pattern/chunk.dart +0 -90
  82. package/antlr4-4.9.2/lib/src/tree/src/pattern/parse_tree_match.dart +0 -635
  83. package/antlr4-4.9.2/lib/src/tree/src/tree.dart +0 -370
  84. package/antlr4-4.9.2/lib/src/tree/src/trees.dart +0 -226
  85. package/antlr4-4.9.2/lib/src/tree/tree.dart +0 -10
  86. package/antlr4-4.9.2/lib/src/util/bit_set.dart +0 -308
  87. package/antlr4-4.9.2/lib/src/util/murmur_hash.dart +0 -77
  88. package/antlr4-4.9.2/lib/src/util/utils.dart +0 -31
  89. package/antlr4-4.9.2/lib/src/vocabulary.dart +0 -254
  90. package/antlr4-4.9.2/pubspec.yaml +0 -13
  91. package/example/node_example/index.js +0 -8
  92. package/example/node_example/package.json +0 -12
  93. package/example/node_example_ts/package-lock.json +0 -70
  94. package/example/node_example_ts/package.json +0 -19
  95. package/example/node_example_ts/src/index.js +0 -5
  96. package/example/node_example_ts/src/index.ts +0 -9
  97. package/example/node_example_ts/tsconfig.json +0 -79
  98. package/js/dart2jsout.js +0 -25898
  99. package/js/dart2jsout.js.map +0 -16
  100. package/js/index.d.ts +0 -1
  101. package/js/index.js +0 -4
  102. package/js/out.js +0 -26023
  103. package/js/out.js.map +0 -16
  104. package/js/package-lock.json +0 -57
  105. package/js/preamble.js +0 -125
  106. package/lib/apexdocs_dart.dart +0 -28
  107. package/lib/src/antlr/grammars/Apexdoc/ApexdocLexer.g4 +0 -120
  108. package/lib/src/antlr/grammars/Apexdoc/ApexdocParser.g4 +0 -158
  109. package/lib/src/antlr/grammars/Apexdoc/gen/ApexdocLexer.interp +0 -95
  110. package/lib/src/antlr/grammars/Apexdoc/gen/ApexdocLexer.java +0 -238
  111. package/lib/src/antlr/grammars/Apexdoc/gen/ApexdocLexer.tokens +0 -23
  112. package/lib/src/antlr/grammars/apex/ApexLexer.g4 +0 -255
  113. package/lib/src/antlr/grammars/apex/ApexParser.g4 +0 -567
  114. package/lib/src/antlr/grammars/apex/examples/ApexClass.cls +0 -6
  115. package/lib/src/antlr/lib/apex/ApexLexer.dart +0 -1223
  116. package/lib/src/antlr/lib/apex/ApexLexer.interp +0 -393
  117. package/lib/src/antlr/lib/apex/ApexLexer.tokens +0 -212
  118. package/lib/src/antlr/lib/apex/ApexParser.dart +0 -9349
  119. package/lib/src/antlr/lib/apex/ApexParser.interp +0 -326
  120. package/lib/src/antlr/lib/apex/ApexParser.tokens +0 -212
  121. package/lib/src/antlr/lib/apex/ApexParserBaseListener.dart +0 -1036
  122. package/lib/src/antlr/lib/apex/ApexParserListener.dart +0 -975
  123. package/lib/src/antlr/lib/apexdoc/ApexdocLexer.dart +0 -373
  124. package/lib/src/antlr/lib/apexdoc/ApexdocLexer.interp +0 -95
  125. package/lib/src/antlr/lib/apexdoc/ApexdocLexer.tokens +0 -23
  126. package/lib/src/antlr/lib/apexdoc/ApexdocParser.dart +0 -2471
  127. package/lib/src/antlr/lib/apexdoc/ApexdocParser.interp +0 -69
  128. package/lib/src/antlr/lib/apexdoc/ApexdocParser.tokens +0 -23
  129. package/lib/src/antlr/lib/apexdoc/ApexdocParserBaseListener.dart +0 -252
  130. package/lib/src/antlr/lib/apexdoc/ApexdocParserListener.dart +0 -215
  131. package/lib/src/builders/builders.dart +0 -32
  132. package/lib/src/model/apex_file_manifest.dart +0 -37
  133. package/lib/src/model/apex_file_manifest.g.dart +0 -18
  134. package/lib/src/model/declaration.dart +0 -50
  135. package/lib/src/model/doc_comment.dart +0 -117
  136. package/lib/src/model/doc_comment.g.dart +0 -118
  137. package/lib/src/model/members.dart +0 -143
  138. package/lib/src/model/members.g.dart +0 -105
  139. package/lib/src/model/types.dart +0 -159
  140. package/lib/src/model/types.g.dart +0 -111
  141. package/lib/src/service/apex_listener.dart +0 -226
  142. package/lib/src/service/apexdoc_listener.dart +0 -82
  143. package/lib/src/service/parsers.dart +0 -33
  144. package/lib/src/service/utils/parsing/access_modifiers_parser.dart +0 -33
  145. package/lib/src/service/utils/parsing/parameters_parser.dart +0 -18
  146. package/lib/src/service/utils/parsing/parsing_utils.dart +0 -2
  147. package/lib/src/service/walker.dart +0 -82
  148. package/pubspec.yaml +0 -19
  149. package/test/apex_file_manifest_test.dart +0 -16
  150. package/test/apex_listener_test.dart +0 -703
  151. package/test/apexdoc_parser_test.dart +0 -179
  152. package/test/doc_comment_test.dart +0 -89
  153. package/test/members_serialization_test.dart +0 -158
  154. package/test/members_test.dart +0 -178
  155. package/test/types_serialization_test.dart +0 -191
  156. package/test/types_test.dart +0 -311
  157. package/test/walker_test.dart +0 -58
  158. package/tool/grind.dart +0 -20
@@ -1,635 +0,0 @@
1
- /*
2
- * Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
3
- * Use of this file is governed by the BSD 3-clause license that
4
- * can be found in the LICENSE.txt file in the project root.
5
- */
6
-
7
- import '../../../error/error.dart';
8
- import '../../../input_stream.dart';
9
- import '../../../lexer.dart';
10
- import '../../../misc/multi_map.dart';
11
- import '../../../parser.dart';
12
- import '../../../parser_interpreter.dart';
13
- import '../../../parser_rule_context.dart';
14
- import '../../../token.dart';
15
- import '../../../token_source.dart';
16
- import '../../../token_stream.dart';
17
- import '../../../util/utils.dart';
18
- import '../tree.dart';
19
- import 'chunk.dart';
20
-
21
- /// Represents the result of matching a [ParseTree] against a tree pattern.
22
- class ParseTreeMatch {
23
- /// Get the parse tree we are trying to match to a pattern.
24
- ///
25
- /// @return The [ParseTree] we are trying to match to a pattern.
26
- final ParseTree tree;
27
-
28
- /// Get the tree pattern we are matching against.
29
- ///
30
- /// @return The tree pattern we are matching against.
31
- final ParseTreePattern pattern;
32
-
33
-
34
- /// Return a mapping from label → [list of nodes].
35
- ///
36
- /// <p>The map includes special entries corresponding to the names of rules and
37
- /// tokens referenced in tags in the original pattern. For additional
38
- /// information, see the description of {@link #getAll(String)}.</p>
39
- ///
40
- /// @return A mapping from labels to parse tree nodes. If the parse tree
41
- /// pattern did not contain any rule or token tags, this map will be empty.
42
- final MultiMap<String, ParseTree> labels;
43
-
44
- /// Get the node at which we first detected a mismatch.
45
- ///
46
- /// @return the node at which we first detected a mismatch, or null
47
- /// if the match was successful.
48
- final ParseTree mismatchedNode;
49
-
50
- /// Constructs a new instance of [ParseTreeMatch] from the specified
51
- /// parse tree and pattern.
52
- ///
53
- /// @param tree The parse tree to match against the pattern.
54
- /// @param pattern The parse tree pattern.
55
- /// @param labels A mapping from label names to collections of
56
- /// [ParseTree] objects located by the tree pattern matching process.
57
- /// @param mismatchedNode The first node which failed to match the tree
58
- /// pattern during the matching process.
59
- ///
60
- /// @exception ArgumentError.notNull) if [tree] is null
61
- /// @exception ArgumentError.notNull) if [pattern] is null
62
- /// @exception ArgumentError.notNull) if [labels] is null
63
- ParseTreeMatch(this.tree, this.pattern, this.labels, this.mismatchedNode) {
64
- if (tree == null) {
65
- throw ArgumentError.notNull('tree');
66
- }
67
-
68
- if (pattern == null) {
69
- throw ArgumentError.notNull('pattern');
70
- }
71
-
72
- if (labels == null) {
73
- throw ArgumentError.notNull('labels');
74
- }
75
- }
76
-
77
- /// Get the last node associated with a specific [label].
78
- ///
79
- /// <p>For example, for pattern {@code <id:ID>}, {@code get("id")} returns the
80
- /// node matched for that [ID]. If more than one node
81
- /// matched the specified label, only the last is returned. If there is
82
- /// no node associated with the label, this returns null.</p>
83
- ///
84
- /// <p>Pattern tags like {@code <ID>} and {@code <expr>} without labels are
85
- /// considered to be labeled with [ID] and [expr], respectively.</p>
86
- ///
87
- /// @param label The label to check.
88
- ///
89
- /// @return The last [ParseTree] to match a tag with the specified
90
- /// label, or null if no parse tree matched a tag with the label.
91
-
92
- ParseTree get(String label) {
93
- final parseTrees = labels[label];
94
- if (parseTrees == null || parseTrees.isEmpty) {
95
- return null;
96
- }
97
-
98
- return parseTrees[parseTrees.length - 1]; // return last if multiple
99
- }
100
-
101
- /// Return all nodes matching a rule or token tag with the specified label.
102
- ///
103
- /// <p>If the [label] is the name of a parser rule or token in the
104
- /// grammar, the resulting list will contain both the parse trees matching
105
- /// rule or tags explicitly labeled with the label and the complete set of
106
- /// parse trees matching the labeled and unlabeled tags in the pattern for
107
- /// the parser rule or token. For example, if [label] is {@code "foo"},
108
- /// the result will contain <em>all</em> of the following.</p>
109
- ///
110
- /// <ul>
111
- /// <li>Parse tree nodes matching tags of the form {@code <foo:anyRuleName>} and
112
- /// {@code <foo:AnyTokenName>}.</li>
113
- /// <li>Parse tree nodes matching tags of the form {@code <anyLabel:foo>}.</li>
114
- /// <li>Parse tree nodes matching tags of the form {@code <foo>}.</li>
115
- /// </ul>
116
- ///
117
- /// @param label The label.
118
- ///
119
- /// @return A collection of all [ParseTree] nodes matching tags with
120
- /// the specified [label]. If no nodes matched the label, an empty list
121
- /// is returned.
122
-
123
- List<ParseTree> getAll(String label) {
124
- final nodes = labels[label];
125
- if (nodes == null) {
126
- return [];
127
- }
128
-
129
- return nodes;
130
- }
131
-
132
- /// Gets a value indicating whether the match operation succeeded.
133
- ///
134
- /// @return [true] if the match operation succeeded; otherwise,
135
- /// [false].
136
- bool get succeeded => mismatchedNode == null;
137
-
138
- /// {@inheritDoc}
139
- @override
140
- String toString() {
141
- return "Match ${succeeded ? "succeeded" : "failed"}; found ${labels.length} labels";
142
- }
143
- }
144
-
145
- /// A pattern like {@code <ID> = <expr>;} converted to a [ParseTree] by
146
- /// {@link ParseTreePatternMatcher#compile(String, int)}.
147
- class ParseTreePattern {
148
- /// Get the parser rule which serves as the outermost rule for the tree
149
- /// pattern.
150
- ///
151
- /// @return The parser rule which serves as the outermost rule for the tree
152
- /// pattern.
153
- final int patternRuleIndex;
154
-
155
- /// Get the tree pattern in concrete syntax form.
156
- ///
157
- /// @return The tree pattern in concrete syntax form.
158
- final String pattern;
159
-
160
-
161
- /// Get the tree pattern as a [ParseTree]. The rule and token tags from
162
- /// the pattern are present in the parse tree as terminal nodes with a symbol
163
- /// of type [RuleTagToken] or [TokenTagToken].
164
- ///
165
- /// @return The tree pattern as a [ParseTree].
166
- final ParseTree patternTree;
167
-
168
- /// Get the [ParseTreePatternMatcher] which created this tree pattern.
169
- ///
170
- /// @return The [ParseTreePatternMatcher] which created this tree
171
- /// pattern.
172
- final ParseTreePatternMatcher matcher;
173
-
174
- /// Construct a new instance of the [ParseTreePattern] class.
175
- ///
176
- /// @param matcher The [ParseTreePatternMatcher] which created this
177
- /// tree pattern.
178
- /// @param pattern The tree pattern in concrete syntax form.
179
- /// @param patternRuleIndex The parser rule which serves as the root of the
180
- /// tree pattern.
181
- /// @param patternTree The tree pattern in [ParseTree] form.
182
- ParseTreePattern(
183
- this.matcher, this.pattern, this.patternRuleIndex, this.patternTree);
184
-
185
- /// Match a specific parse tree against this tree pattern.
186
- ///
187
- /// @param tree The parse tree to match against this tree pattern.
188
- /// @return A [ParseTreeMatch] object describing the result of the
189
- /// match operation. The {@link ParseTreeMatch#succeeded()} method can be
190
- /// used to determine whether or not the match was successful.
191
-
192
- ParseTreeMatch match(ParseTree tree) {
193
- return matcher.match(tree, pattern: this);
194
- }
195
-
196
- /// Determine whether or not a parse tree matches this tree pattern.
197
- ///
198
- /// @param tree The parse tree to match against this tree pattern.
199
- /// @return [true] if [tree] is a match for the current tree
200
- /// pattern; otherwise, [false].
201
- bool matches(ParseTree tree) {
202
- return matcher.match(tree, pattern: this).succeeded;
203
- }
204
- }
205
-
206
- /// A tree pattern matching mechanism for ANTLR [ParseTree]s.
207
- ///
208
- /// <p>Patterns are strings of source input text with special tags representing
209
- /// token or rule references such as:</p>
210
- ///
211
- /// <p>{@code <ID> = <expr>;}</p>
212
- ///
213
- /// <p>Given a pattern start rule such as [statement], this object constructs
214
- /// a [ParseTree] with placeholders for the [ID] and [expr]
215
- /// subtree. Then the {@link #match} routines can compare an actual
216
- /// [ParseTree] from a parse with this pattern. Tag {@code <ID>} matches
217
- /// any [ID] token and tag {@code <expr>} references the result of the
218
- /// [expr] rule (generally an instance of [ExprContext].</p>
219
- ///
220
- /// <p>Pattern {@code x = 0;} is a similar pattern that matches the same pattern
221
- /// except that it requires the identifier to be [x] and the expression to
222
- /// be {@code 0}.</p>
223
- ///
224
- /// <p>The {@link #matches} routines return [true] or [false] based
225
- /// upon a match for the tree rooted at the parameter sent in. The
226
- /// {@link #match} routines return a [ParseTreeMatch] object that
227
- /// contains the parse tree, the parse tree pattern, and a map from tag name to
228
- /// matched nodes (more below). A subtree that fails to match, returns with
229
- /// {@link ParseTreeMatch#mismatchedNode} set to the first tree node that did not
230
- /// match.</p>
231
- ///
232
- /// <p>For efficiency, you can compile a tree pattern in string form to a
233
- /// [ParseTreePattern] object.</p>
234
- ///
235
- /// <p>See [TestParseTreeMatcher] for lots of examples.
236
- /// [ParseTreePattern] has two static helper methods:
237
- /// {@link ParseTreePattern#findAll} and {@link ParseTreePattern#match} that
238
- /// are easy to use but not super efficient because they create new
239
- /// [ParseTreePatternMatcher] objects each time and have to compile the
240
- /// pattern in string form before using it.</p>
241
- ///
242
- /// <p>The lexer and parser that you pass into the [ParseTreePatternMatcher]
243
- /// constructor are used to parse the pattern in string form. The lexer converts
244
- /// the {@code <ID> = <expr>;} into a sequence of four tokens (assuming lexer
245
- /// throws out whitespace or puts it on a hidden channel). Be aware that the
246
- /// input stream is reset for the lexer (but not the parser; a
247
- /// [ParserInterpreter] is created to parse the input.). Any user-defined
248
- /// fields you have put into the lexer might get changed when this mechanism asks
249
- /// it to scan the pattern string.</p>
250
- ///
251
- /// <p>Normally a parser does not accept token {@code <expr>} as a valid
252
- /// [expr] but, from the parser passed in, we create a special version of
253
- /// the underlying grammar representation (an [ATN]) that allows imaginary
254
- /// tokens representing rules ({@code <expr>}) to match entire rules. We call
255
- /// these <em>bypass alternatives</em>.</p>
256
- ///
257
- /// <p>Delimiters are {@code <} and {@code >}, with {@code \} as the escape string
258
- /// by default, but you can set them to whatever you want using
259
- /// {@link #setDelimiters}. You must escape both start and stop strings
260
- /// {@code \<} and {@code \>}.</p>
261
- class ParseTreePatternMatcher {
262
- /// Used to convert the tree pattern string into a series of tokens. The
263
- /// input stream is reset.
264
- final Lexer lexer;
265
-
266
- /// Used to collect to the grammar file name, token names, rule names for
267
- /// used to parse the pattern into a parse tree.
268
- final Parser parser;
269
-
270
- String start = '<';
271
- String stop = '>';
272
- String escape = '\\'; // e.g., \< and \> must escape BOTH!
273
-
274
- /// Constructs a [ParseTreePatternMatcher] or from a [Lexer] and
275
- /// [Parser] object. The lexer input stream is altered for tokenizing
276
- /// the tree patterns. The parser is used as a convenient mechanism to get
277
- /// the grammar name, plus token, rule names.
278
- ParseTreePatternMatcher(this.lexer, this.parser);
279
-
280
- /// Set the delimiters used for marking rule and token tags within concrete
281
- /// syntax used by the tree pattern parser.
282
- ///
283
- /// @param start The start delimiter.
284
- /// @param stop The stop delimiter.
285
- /// @param escapeLeft The escape sequence to use for escaping a start or stop delimiter.
286
- ///
287
- /// @exception ArgumentError if [start] is null or empty.
288
- /// @exception ArgumentError if [stop] is null or empty.
289
- void setDelimiters(String start, String stop, String escapeLeft) {
290
- if (start == null || start.isEmpty) {
291
- throw ArgumentError.value(start, 'start', 'cannot be null or empty');
292
- }
293
-
294
- if (stop == null || stop.isEmpty) {
295
- throw ArgumentError.value(stop, 'stop', 'cannot be null or empty');
296
- }
297
-
298
- this.start = start;
299
- this.stop = stop;
300
- escape = escapeLeft;
301
- }
302
-
303
- /// Does [pattern] matched as rule patternRuleIndex match tree? Pass in a
304
- /// compiled pattern instead of a string representation of a tree pattern.
305
- bool matches(ParseTree tree,
306
- {ParseTreePattern pattern, String patternStr, int patternRuleIndex}) {
307
- pattern ??= compile(patternStr, patternRuleIndex);
308
-
309
- final labels = MultiMap<String, ParseTree>();
310
- final mismatchedNode =
311
- matchImpl(tree, pattern.patternTree, labels);
312
- return mismatchedNode == null;
313
- }
314
-
315
- /// Compare [pattern] matched against [tree] and return a
316
- /// [ParseTreeMatch] object that contains the matched elements, or the
317
- /// node at which the match failed. Pass in a compiled pattern instead of a
318
- /// string representation of a tree pattern.
319
-
320
- ParseTreeMatch match(ParseTree tree,
321
- {ParseTreePattern pattern, String patternStr, int patternRuleIndex}) {
322
- pattern ??= compile(patternStr, patternRuleIndex);
323
-
324
- final labels = MultiMap<String, ParseTree>();
325
- final mismatchedNode =
326
- matchImpl(tree, pattern.patternTree, labels);
327
- return ParseTreeMatch(tree, pattern, labels, mismatchedNode);
328
- }
329
-
330
- /// For repeated use of a tree pattern, compile it to a
331
- /// [ParseTreePattern] using this method.
332
- ParseTreePattern compile(String pattern, int patternRuleIndex) {
333
- final tokenList = tokenize(pattern);
334
- final tokenSrc = ListTokenSource(tokenList);
335
- final tokens = CommonTokenStream(tokenSrc);
336
-
337
- final parserInterp = ParserInterpreter(
338
- parser.grammarFileName,
339
- parser.vocabulary,
340
- parser.ruleNames,
341
- parser.ATNWithBypassAlts,
342
- tokens);
343
-
344
- ParseTree tree;
345
- try {
346
- parserInterp.errorHandler = BailErrorStrategy();
347
- tree = parserInterp.parse(patternRuleIndex);
348
- // System.out.println("pattern tree = "+tree.toStringTree(parserInterp));
349
- } on ParseCancellationException {
350
- rethrow;
351
- } on RecognitionException {
352
- rethrow;
353
- } catch (e) {
354
- throw CannotInvokeStartRule(e);
355
- }
356
-
357
- // Make sure tree pattern compilation checks for a complete parse
358
- if (tokens.LA(1) != Token.EOF) {
359
- throw StartRuleDoesNotConsumeFullPattern();
360
- }
361
-
362
- return ParseTreePattern(this, pattern, patternRuleIndex, tree);
363
- }
364
-
365
- // ---- SUPPORT CODE ----
366
-
367
- /// Recursively walk [tree] against [patternTree], filling
368
- /// {@code match.}{@link ParseTreeMatch#labels labels}.
369
- ///
370
- /// @return the first node encountered in [tree] which does not match
371
- /// a corresponding node in [patternTree], or null if the match
372
- /// was successful. The specific node returned depends on the matching
373
- /// algorithm used by the implementation, and may be overridden.
374
-
375
- ParseTree matchImpl(ParseTree tree, ParseTree patternTree,
376
- MultiMap<String, ParseTree> labels) {
377
- if (tree == null) {
378
- throw ArgumentError('tree cannot be null');
379
- }
380
-
381
- if (patternTree == null) {
382
- throw ArgumentError('patternTree cannot be null');
383
- }
384
-
385
- // x and <ID>, x and y, or x and x; or could be mismatched types
386
- if (tree is TerminalNode && patternTree is TerminalNode) {
387
- final t1 = tree;
388
- final t2 = patternTree;
389
- ParseTree mismatchedNode;
390
- // both are tokens and they have same type
391
- if (t1.symbol.type == t2.symbol.type) {
392
- if (t2.symbol is TokenTagToken) {
393
- // x and <ID>
394
- TokenTagToken tokenTagToken = t2.symbol;
395
- // track label->list-of-nodes for both token name and label (if any)
396
- labels.put(tokenTagToken.tokenName, tree);
397
- if (tokenTagToken.label != null) {
398
- labels.put(tokenTagToken.label, tree);
399
- }
400
- } else if (t1.text == t2.text) {
401
- // x and x
402
- } else {
403
- // x and y
404
- mismatchedNode ??= t1;
405
- }
406
- } else {
407
- mismatchedNode ??= t1;
408
- }
409
-
410
- return mismatchedNode;
411
- }
412
-
413
- if (tree is ParserRuleContext && patternTree is ParserRuleContext) {
414
- final r1 = tree;
415
- final r2 = patternTree;
416
- ParseTree mismatchedNode;
417
- // (expr ...) and <expr>
418
- final ruleTagToken = getRuleTagToken(r2);
419
- if (ruleTagToken != null) {
420
- if (r1.ruleContext.ruleIndex == r2.ruleContext.ruleIndex) {
421
- // track label->list-of-nodes for both rule name and label (if any)
422
- labels.put(ruleTagToken.ruleName, tree);
423
- if (ruleTagToken.label != null) {
424
- labels.put(ruleTagToken.label, tree);
425
- }
426
- } else {
427
- mismatchedNode ??= r1;
428
- }
429
-
430
- return mismatchedNode;
431
- }
432
-
433
- // (expr ...) and (expr ...)
434
- if (r1.childCount != r2.childCount) {
435
- mismatchedNode ??= r1;
436
-
437
- return mismatchedNode;
438
- }
439
-
440
- final n = r1.childCount;
441
- for (var i = 0; i < n; i++) {
442
- final childMatch =
443
- matchImpl(r1.getChild(i), patternTree.getChild(i), labels);
444
- if (childMatch != null) {
445
- return childMatch;
446
- }
447
- }
448
-
449
- return mismatchedNode;
450
- }
451
-
452
- // if nodes aren't both tokens or both rule nodes, can't match
453
- return tree;
454
- }
455
-
456
- /// Is [t] {@code (expr <expr>)} subtree? */
457
- RuleTagToken getRuleTagToken(ParseTree t) {
458
- if (t is RuleNode) {
459
- final r = t;
460
- if (r.childCount == 1 && r.getChild(0) is TerminalNode) {
461
- TerminalNode c = r.getChild(0);
462
- if (c.symbol is RuleTagToken) {
463
- // System.out.println("rule tag subtree "+t.toStringTree(parser));
464
- return c.symbol;
465
- }
466
- }
467
- }
468
- return null;
469
- }
470
-
471
- List<Token> tokenize(String pattern) {
472
- // split pattern into chunks: sea (raw input) and islands (<ID>, <expr>)
473
- final chunks = split(pattern);
474
-
475
- // create token stream from text and tags
476
- final tokens = <Token>[];
477
- for (var chunk in chunks) {
478
- if (chunk is TagChunk) {
479
- final tagChunk = chunk;
480
- // add special rule token or conjure up new token from name
481
- if (isUpperCase(tagChunk.tag[0])) {
482
- final ttype = parser.getTokenType(tagChunk.tag);
483
- if (ttype == Token.INVALID_TYPE) {
484
- throw ArgumentError('Unknown token ' +
485
- tagChunk.tag +
486
- ' in pattern: ' +
487
- pattern);
488
- }
489
- final t =
490
- TokenTagToken(tagChunk.tag, ttype, tagChunk.label);
491
- tokens.add(t);
492
- } else if (isLowerCase(tagChunk.tag[0])) {
493
- final ruleIndex = parser.getRuleIndex(tagChunk.tag);
494
- if (ruleIndex == -1) {
495
- throw ArgumentError('Unknown rule ' +
496
- tagChunk.tag +
497
- ' in pattern: ' +
498
- pattern);
499
- }
500
- final ruleImaginaryTokenType =
501
- parser.ATNWithBypassAlts.ruleToTokenType[ruleIndex];
502
- tokens.add(RuleTagToken(
503
- tagChunk.tag, ruleImaginaryTokenType, tagChunk.label));
504
- } else {
505
- throw ArgumentError(
506
- 'invalid tag: ' + tagChunk.tag + ' in pattern: ' + pattern);
507
- }
508
- } else {
509
- TextChunk textChunk = chunk;
510
- final inputStream =
511
- InputStream.fromString(textChunk.text);
512
- lexer.inputStream = inputStream;
513
- var t = lexer.nextToken();
514
- while (t.type != Token.EOF) {
515
- tokens.add(t);
516
- t = lexer.nextToken();
517
- }
518
- }
519
- }
520
-
521
- // System.out.println("tokens="+tokens);
522
- return tokens;
523
- }
524
-
525
- /// Split {@code <ID> = <e:expr> ;} into 4 chunks for tokenizing by {@link #tokenize}. */
526
- List<Chunk> split(String pattern) {
527
- var p = 0;
528
- final n = pattern.length;
529
- final chunks = <Chunk>[];
530
- // find all start and stop indexes first, then collect
531
- final starts = <int>[];
532
- final stops = <int>[];
533
- while (p < n) {
534
- if (p == pattern.indexOf(escape + start, p)) {
535
- p += escape.length + start.length;
536
- } else if (p == pattern.indexOf(escape + stop, p)) {
537
- p += escape.length + stop.length;
538
- } else if (p == pattern.indexOf(start, p)) {
539
- starts.add(p);
540
- p += start.length;
541
- } else if (p == pattern.indexOf(stop, p)) {
542
- stops.add(p);
543
- p += stop.length;
544
- } else {
545
- p++;
546
- }
547
- }
548
-
549
- // System.out.println("");
550
- // System.out.println(starts);
551
- // System.out.println(stops);
552
- if (starts.length > stops.length) {
553
- throw ArgumentError('unterminated tag in pattern: ' + pattern);
554
- }
555
-
556
- if (starts.length < stops.length) {
557
- throw ArgumentError('missing start tag in pattern: ' + pattern);
558
- }
559
-
560
- final ntags = starts.length;
561
- for (var i = 0; i < ntags; i++) {
562
- if (starts[i] >= stops[i]) {
563
- throw ArgumentError(
564
- 'tag delimiters out of order in pattern: ' + pattern);
565
- }
566
- }
567
-
568
- // collect into chunks now
569
- if (ntags == 0) {
570
- final text = pattern.substring(0, n);
571
- chunks.add(TextChunk(text));
572
- }
573
-
574
- if (ntags > 0 && starts[0] > 0) {
575
- // copy text up to first tag into chunks
576
- final text = pattern.substring(0, starts[0]);
577
- chunks.add(TextChunk(text));
578
- }
579
- for (var i = 0; i < ntags; i++) {
580
- // copy inside of <tag>
581
- final tag = pattern.substring(starts[i] + start.length, stops[i]);
582
- var ruleOrToken = tag;
583
- String label;
584
- final colon = tag.indexOf(':');
585
- if (colon >= 0) {
586
- label = tag.substring(0, colon);
587
- ruleOrToken = tag.substring(colon + 1, tag.length);
588
- }
589
- chunks.add(TagChunk(ruleOrToken, label: label));
590
- if (i + 1 < ntags) {
591
- // copy from end of <tag> to start of next
592
- final text = pattern.substring(stops[i] + stop.length, starts[i + 1]);
593
- chunks.add(TextChunk(text));
594
- }
595
- }
596
- if (ntags > 0) {
597
- final afterLastTag = stops[ntags - 1] + stop.length;
598
- if (afterLastTag < n) {
599
- // copy text from end of last tag to end
600
- final text = pattern.substring(afterLastTag, n);
601
- chunks.add(TextChunk(text));
602
- }
603
- }
604
-
605
- // strip out the escape sequences from text chunks but not tags
606
- for (var i = 0; i < chunks.length; i++) {
607
- final c = chunks[i];
608
- if (c is TextChunk) {
609
- final tc = c;
610
- final unescaped = tc.text.replaceAll(escape, '');
611
- if (unescaped.length < tc.text.length) {
612
- chunks[i] = TextChunk(unescaped);
613
- }
614
- }
615
- }
616
-
617
- return chunks;
618
- }
619
- }
620
-
621
- class CannotInvokeStartRule extends StateError {
622
- CannotInvokeStartRule(String message) : super(message);
623
- }
624
-
625
- // Fixes https://github.com/antlr/antlr4/issues/413
626
- // "Tree pattern compilation doesn't check for a complete parse"
627
- class StartRuleDoesNotConsumeFullPattern extends Error {}
628
-
629
- /// This exception is thrown to cancel a parsing operation. This exception does
630
- /// not extend [RecognitionException], allowing it to bypass the standard
631
- /// error recovery mechanisms. [BailErrorStrategy] throws this exception in
632
- /// response to a parse error.
633
- class ParseCancellationException extends StateError {
634
- ParseCancellationException(String message) : super(message);
635
- }