@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.
- package/__tests__/end-to-end.test.ts +256 -0
- package/coverage/clover.xml +12857 -0
- package/coverage/coverage-final.json +3 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +79 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +126 -0
- package/coverage/lcov-report/index.js.html +104 -0
- package/coverage/lcov-report/out.js.html +41126 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +170 -0
- package/coverage/lcov.info +24801 -0
- package/index.d.ts +118 -0
- package/index.js +8 -0
- package/index.ts +141 -0
- package/jest.config.js +11 -0
- package/out.js +13708 -0
- package/package.json +22 -17
- package/tsconfig.json +5 -3
- package/.idea/apexdocs-dart.iml +0 -18
- package/.idea/jsLibraryMappings.xml +0 -6
- package/.idea/libraries/Dart_Packages.xml +0 -556
- package/.idea/libraries/Dart_SDK.xml +0 -28
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/runConfigurations/_template__of_Dart_Test.xml +0 -6
- package/.idea/vcs.xml +0 -6
- package/CHANGELOG.md +0 -3
- package/README.md +0 -26
- package/TODO.md +0 -5
- package/analysis_options.yaml +0 -30
- package/antlr4-4.9.2/CHANGELOG.md +0 -4
- package/antlr4-4.9.2/LICENSE +0 -52
- package/antlr4-4.9.2/README.md +0 -11
- package/antlr4-4.9.2/analysis_options.yaml +0 -1
- package/antlr4-4.9.2/lib/antlr4.dart +0 -21
- package/antlr4-4.9.2/lib/src/atn/atn.dart +0 -18
- package/antlr4-4.9.2/lib/src/atn/src/atn.dart +0 -170
- package/antlr4-4.9.2/lib/src/atn/src/atn_config.dart +0 -242
- package/antlr4-4.9.2/lib/src/atn/src/atn_config_set.dart +0 -283
- package/antlr4-4.9.2/lib/src/atn/src/atn_deserializer.dart +0 -809
- package/antlr4-4.9.2/lib/src/atn/src/atn_simulator.dart +0 -95
- package/antlr4-4.9.2/lib/src/atn/src/atn_state.dart +0 -296
- package/antlr4-4.9.2/lib/src/atn/src/atn_type.dart +0 -14
- package/antlr4-4.9.2/lib/src/atn/src/info.dart +0 -553
- package/antlr4-4.9.2/lib/src/atn/src/lexer_action.dart +0 -601
- package/antlr4-4.9.2/lib/src/atn/src/lexer_action_executor.dart +0 -167
- package/antlr4-4.9.2/lib/src/atn/src/lexer_atn_simulator.dart +0 -731
- package/antlr4-4.9.2/lib/src/atn/src/parser_atn_simulator.dart +0 -2630
- package/antlr4-4.9.2/lib/src/atn/src/profiling_atn_simulator.dart +0 -229
- package/antlr4-4.9.2/lib/src/atn/src/semantic_context.dart +0 -404
- package/antlr4-4.9.2/lib/src/atn/src/transition.dart +0 -305
- package/antlr4-4.9.2/lib/src/dfa/dfa.dart +0 -8
- package/antlr4-4.9.2/lib/src/dfa/src/dfa.dart +0 -138
- package/antlr4-4.9.2/lib/src/dfa/src/dfa_serializer.dart +0 -76
- package/antlr4-4.9.2/lib/src/dfa/src/dfa_state.dart +0 -151
- package/antlr4-4.9.2/lib/src/error/error.dart +0 -10
- package/antlr4-4.9.2/lib/src/error/src/diagnostic_error_listener.dart +0 -116
- package/antlr4-4.9.2/lib/src/error/src/error_listener.dart +0 -241
- package/antlr4-4.9.2/lib/src/error/src/error_strategy.dart +0 -902
- package/antlr4-4.9.2/lib/src/error/src/errors.dart +0 -204
- package/antlr4-4.9.2/lib/src/input_stream.dart +0 -335
- package/antlr4-4.9.2/lib/src/interval_set.dart +0 -735
- package/antlr4-4.9.2/lib/src/lexer.dart +0 -343
- package/antlr4-4.9.2/lib/src/ll1_analyzer.dart +0 -204
- package/antlr4-4.9.2/lib/src/misc/multi_map.dart +0 -32
- package/antlr4-4.9.2/lib/src/misc/pair.dart +0 -34
- package/antlr4-4.9.2/lib/src/parser.dart +0 -777
- package/antlr4-4.9.2/lib/src/parser_interpreter.dart +0 -393
- package/antlr4-4.9.2/lib/src/parser_rule_context.dart +0 -275
- package/antlr4-4.9.2/lib/src/prediction_context.dart +0 -877
- package/antlr4-4.9.2/lib/src/recognizer.dart +0 -182
- package/antlr4-4.9.2/lib/src/rule_context.dart +0 -192
- package/antlr4-4.9.2/lib/src/runtime_meta_data.dart +0 -188
- package/antlr4-4.9.2/lib/src/token.dart +0 -431
- package/antlr4-4.9.2/lib/src/token_factory.dart +0 -88
- package/antlr4-4.9.2/lib/src/token_source.dart +0 -241
- package/antlr4-4.9.2/lib/src/token_stream.dart +0 -627
- package/antlr4-4.9.2/lib/src/tree/src/pattern/chunk.dart +0 -90
- package/antlr4-4.9.2/lib/src/tree/src/pattern/parse_tree_match.dart +0 -635
- package/antlr4-4.9.2/lib/src/tree/src/tree.dart +0 -370
- package/antlr4-4.9.2/lib/src/tree/src/trees.dart +0 -226
- package/antlr4-4.9.2/lib/src/tree/tree.dart +0 -10
- package/antlr4-4.9.2/lib/src/util/bit_set.dart +0 -308
- package/antlr4-4.9.2/lib/src/util/murmur_hash.dart +0 -77
- package/antlr4-4.9.2/lib/src/util/utils.dart +0 -31
- package/antlr4-4.9.2/lib/src/vocabulary.dart +0 -254
- package/antlr4-4.9.2/pubspec.yaml +0 -13
- package/example/node_example/index.js +0 -8
- package/example/node_example/package.json +0 -12
- package/example/node_example_ts/package-lock.json +0 -70
- package/example/node_example_ts/package.json +0 -19
- package/example/node_example_ts/src/index.js +0 -5
- package/example/node_example_ts/src/index.ts +0 -9
- package/example/node_example_ts/tsconfig.json +0 -79
- package/js/dart2jsout.js +0 -25898
- package/js/dart2jsout.js.map +0 -16
- package/js/index.d.ts +0 -1
- package/js/index.js +0 -4
- package/js/out.js +0 -26023
- package/js/out.js.map +0 -16
- package/js/package-lock.json +0 -57
- package/js/preamble.js +0 -125
- package/lib/apexdocs_dart.dart +0 -28
- package/lib/src/antlr/grammars/Apexdoc/ApexdocLexer.g4 +0 -120
- package/lib/src/antlr/grammars/Apexdoc/ApexdocParser.g4 +0 -158
- package/lib/src/antlr/grammars/Apexdoc/gen/ApexdocLexer.interp +0 -95
- package/lib/src/antlr/grammars/Apexdoc/gen/ApexdocLexer.java +0 -238
- package/lib/src/antlr/grammars/Apexdoc/gen/ApexdocLexer.tokens +0 -23
- package/lib/src/antlr/grammars/apex/ApexLexer.g4 +0 -255
- package/lib/src/antlr/grammars/apex/ApexParser.g4 +0 -567
- package/lib/src/antlr/grammars/apex/examples/ApexClass.cls +0 -6
- package/lib/src/antlr/lib/apex/ApexLexer.dart +0 -1223
- package/lib/src/antlr/lib/apex/ApexLexer.interp +0 -393
- package/lib/src/antlr/lib/apex/ApexLexer.tokens +0 -212
- package/lib/src/antlr/lib/apex/ApexParser.dart +0 -9349
- package/lib/src/antlr/lib/apex/ApexParser.interp +0 -326
- package/lib/src/antlr/lib/apex/ApexParser.tokens +0 -212
- package/lib/src/antlr/lib/apex/ApexParserBaseListener.dart +0 -1036
- package/lib/src/antlr/lib/apex/ApexParserListener.dart +0 -975
- package/lib/src/antlr/lib/apexdoc/ApexdocLexer.dart +0 -373
- package/lib/src/antlr/lib/apexdoc/ApexdocLexer.interp +0 -95
- package/lib/src/antlr/lib/apexdoc/ApexdocLexer.tokens +0 -23
- package/lib/src/antlr/lib/apexdoc/ApexdocParser.dart +0 -2471
- package/lib/src/antlr/lib/apexdoc/ApexdocParser.interp +0 -69
- package/lib/src/antlr/lib/apexdoc/ApexdocParser.tokens +0 -23
- package/lib/src/antlr/lib/apexdoc/ApexdocParserBaseListener.dart +0 -252
- package/lib/src/antlr/lib/apexdoc/ApexdocParserListener.dart +0 -215
- package/lib/src/builders/builders.dart +0 -32
- package/lib/src/model/apex_file_manifest.dart +0 -37
- package/lib/src/model/apex_file_manifest.g.dart +0 -18
- package/lib/src/model/declaration.dart +0 -50
- package/lib/src/model/doc_comment.dart +0 -117
- package/lib/src/model/doc_comment.g.dart +0 -118
- package/lib/src/model/members.dart +0 -143
- package/lib/src/model/members.g.dart +0 -105
- package/lib/src/model/types.dart +0 -159
- package/lib/src/model/types.g.dart +0 -111
- package/lib/src/service/apex_listener.dart +0 -226
- package/lib/src/service/apexdoc_listener.dart +0 -82
- package/lib/src/service/parsers.dart +0 -33
- package/lib/src/service/utils/parsing/access_modifiers_parser.dart +0 -33
- package/lib/src/service/utils/parsing/parameters_parser.dart +0 -18
- package/lib/src/service/utils/parsing/parsing_utils.dart +0 -2
- package/lib/src/service/walker.dart +0 -82
- package/pubspec.yaml +0 -19
- package/test/apex_file_manifest_test.dart +0 -16
- package/test/apex_listener_test.dart +0 -703
- package/test/apexdoc_parser_test.dart +0 -179
- package/test/doc_comment_test.dart +0 -89
- package/test/members_serialization_test.dart +0 -158
- package/test/members_test.dart +0 -178
- package/test/types_serialization_test.dart +0 -191
- package/test/types_test.dart +0 -311
- package/test/walker_test.dart +0 -58
- package/tool/grind.dart +0 -20
|
@@ -1,877 +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 'package:collection/collection.dart';
|
|
8
|
-
|
|
9
|
-
import 'atn/atn.dart';
|
|
10
|
-
import 'misc/pair.dart';
|
|
11
|
-
import 'recognizer.dart';
|
|
12
|
-
import 'rule_context.dart';
|
|
13
|
-
import 'util/murmur_hash.dart';
|
|
14
|
-
|
|
15
|
-
abstract class PredictionContext {
|
|
16
|
-
/// Represents {@code $} in local context prediction, which means wildcard.
|
|
17
|
-
/// {@code *+x = *}.
|
|
18
|
-
static final EmptyPredictionContext EMPTY = EmptyPredictionContext();
|
|
19
|
-
|
|
20
|
-
/// Represents {@code $} in an array in full context mode, when {@code $}
|
|
21
|
-
/// doesn't mean wildcard: {@code $ + x = [$,x]}. Here,
|
|
22
|
-
/// {@code $} = {@link #EMPTY_RETURN_STATE}.
|
|
23
|
-
static final int EMPTY_RETURN_STATE = 0x7FFFFFFF;
|
|
24
|
-
|
|
25
|
-
static final int INITIAL_HASH = 1;
|
|
26
|
-
|
|
27
|
-
static int globalNodeCount = 0;
|
|
28
|
-
int id = globalNodeCount++;
|
|
29
|
-
|
|
30
|
-
/// Stores the computed hash code of this [PredictionContext]. The hash
|
|
31
|
-
/// code is computed in parts to match the following reference algorithm.
|
|
32
|
-
///
|
|
33
|
-
/// <pre>
|
|
34
|
-
/// int referenceHashCode() {
|
|
35
|
-
/// int hash = {@link MurmurHash#initialize MurmurHash.initialize}({@link #INITIAL_HASH});
|
|
36
|
-
///
|
|
37
|
-
/// for (int i = 0; i < {@link #size()}; i++) {
|
|
38
|
-
/// hash = {@link MurmurHash#update MurmurHash.update}(hash, {@link #getParent getParent}(i));
|
|
39
|
-
/// }
|
|
40
|
-
///
|
|
41
|
-
/// for (int i = 0; i < {@link #size()}; i++) {
|
|
42
|
-
/// hash = {@link MurmurHash#update MurmurHash.update}(hash, {@link #getReturnState getReturnState}(i));
|
|
43
|
-
/// }
|
|
44
|
-
///
|
|
45
|
-
/// hash = {@link MurmurHash#finish MurmurHash.finish}(hash, 2 * {@link #size()});
|
|
46
|
-
/// return hash;
|
|
47
|
-
/// }
|
|
48
|
-
/// </pre>
|
|
49
|
-
final int cachedHashCode;
|
|
50
|
-
|
|
51
|
-
PredictionContext(this.cachedHashCode);
|
|
52
|
-
|
|
53
|
-
/// Convert a [RuleContext] tree to a [PredictionContext] graph.
|
|
54
|
-
/// Return {@link #EMPTY} if [outerContext] is empty or null.
|
|
55
|
-
static PredictionContext fromRuleContext(ATN atn, RuleContext outerContext) {
|
|
56
|
-
outerContext ??= RuleContext.EMPTY;
|
|
57
|
-
|
|
58
|
-
// if we are in RuleContext of start rule, s, then PredictionContext
|
|
59
|
-
// is EMPTY. Nobody called us. (if we are empty, return empty)
|
|
60
|
-
if (outerContext.parent == null || outerContext == RuleContext.EMPTY) {
|
|
61
|
-
return PredictionContext.EMPTY;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// If we have a parent, convert it to a PredictionContext graph
|
|
65
|
-
PredictionContext parent = EMPTY;
|
|
66
|
-
parent = PredictionContext.fromRuleContext(atn, outerContext.parent);
|
|
67
|
-
|
|
68
|
-
final state = atn.states[outerContext.invokingState];
|
|
69
|
-
RuleTransition transition = state.transition(0);
|
|
70
|
-
return SingletonPredictionContext.create(
|
|
71
|
-
parent, transition.followState.stateNumber);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
int get length;
|
|
75
|
-
|
|
76
|
-
PredictionContext getParent(int index);
|
|
77
|
-
|
|
78
|
-
int getReturnState(int index);
|
|
79
|
-
|
|
80
|
-
/// This means only the {@link #EMPTY} (wildcard? not sure) context is in set. */
|
|
81
|
-
bool get isEmpty {
|
|
82
|
-
return this == EMPTY;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
bool hasEmptyPath() {
|
|
86
|
-
// since EMPTY_RETURN_STATE can only appear in the last position, we check last one
|
|
87
|
-
return getReturnState(length - 1) == EMPTY_RETURN_STATE;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
@override
|
|
91
|
-
int get hashCode {
|
|
92
|
-
return cachedHashCode;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
@override
|
|
96
|
-
bool operator ==(Object obj);
|
|
97
|
-
|
|
98
|
-
static int calculateEmptyHashCode() {
|
|
99
|
-
var hash = MurmurHash.initialize(INITIAL_HASH);
|
|
100
|
-
hash = MurmurHash.finish(hash, 0);
|
|
101
|
-
return hash;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
static int calculateHashCode(
|
|
105
|
-
List<PredictionContext> parents, List<int> returnStates) {
|
|
106
|
-
var hash = MurmurHash.initialize(INITIAL_HASH);
|
|
107
|
-
|
|
108
|
-
for (var parent in parents) {
|
|
109
|
-
hash = MurmurHash.update(hash, parent);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
for (var returnState in returnStates) {
|
|
113
|
-
hash = MurmurHash.update(hash, returnState);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
hash = MurmurHash.finish(hash, 2 * parents.length);
|
|
117
|
-
return hash;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// dispatch
|
|
121
|
-
static PredictionContext merge(
|
|
122
|
-
PredictionContext a,
|
|
123
|
-
PredictionContext b,
|
|
124
|
-
bool rootIsWildcard,
|
|
125
|
-
Map<Pair<PredictionContext, PredictionContext>, PredictionContext>
|
|
126
|
-
mergeCache) {
|
|
127
|
-
assert(a != null && b != null); // must be empty context, never null
|
|
128
|
-
|
|
129
|
-
// share same graph if both same
|
|
130
|
-
if (a == b || a == b) return a;
|
|
131
|
-
|
|
132
|
-
if (a is SingletonPredictionContext && b is SingletonPredictionContext) {
|
|
133
|
-
return mergeSingletons(a, b, rootIsWildcard, mergeCache);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// At least one of a or b is array
|
|
137
|
-
// If one is $ and rootIsWildcard, return $ as * wildcard
|
|
138
|
-
if (rootIsWildcard) {
|
|
139
|
-
if (a is EmptyPredictionContext) return a;
|
|
140
|
-
if (b is EmptyPredictionContext) return b;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// convert singleton so both are arrays to normalize
|
|
144
|
-
if (a is SingletonPredictionContext) {
|
|
145
|
-
a = ArrayPredictionContext.of(a);
|
|
146
|
-
}
|
|
147
|
-
if (b is SingletonPredictionContext) {
|
|
148
|
-
b = ArrayPredictionContext.of(b);
|
|
149
|
-
}
|
|
150
|
-
return mergeArrays(a, b, rootIsWildcard, mergeCache);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/// Merge two [SingletonPredictionContext] instances.
|
|
154
|
-
///
|
|
155
|
-
/// <p>Stack tops equal, parents merge is same; return left graph.<br>
|
|
156
|
-
/// <embed src="images/SingletonMerge_SameRootSamePar.svg" type="image/svg+xml"/></p>
|
|
157
|
-
///
|
|
158
|
-
/// <p>Same stack top, parents differ; merge parents giving array node, then
|
|
159
|
-
/// remainders of those graphs. A new root node is created to point to the
|
|
160
|
-
/// merged parents.<br>
|
|
161
|
-
/// <embed src="images/SingletonMerge_SameRootDiffPar.svg" type="image/svg+xml"/></p>
|
|
162
|
-
///
|
|
163
|
-
/// <p>Different stack tops pointing to same parent. Make array node for the
|
|
164
|
-
/// root where both element in the root point to the same (original)
|
|
165
|
-
/// parent.<br>
|
|
166
|
-
/// <embed src="images/SingletonMerge_DiffRootSamePar.svg" type="image/svg+xml"/></p>
|
|
167
|
-
///
|
|
168
|
-
/// <p>Different stack tops pointing to different parents. Make array node for
|
|
169
|
-
/// the root where each element points to the corresponding original
|
|
170
|
-
/// parent.<br>
|
|
171
|
-
/// <embed src="images/SingletonMerge_DiffRootDiffPar.svg" type="image/svg+xml"/></p>
|
|
172
|
-
///
|
|
173
|
-
/// @param a the first [SingletonPredictionContext]
|
|
174
|
-
/// @param b the second [SingletonPredictionContext]
|
|
175
|
-
/// @param rootIsWildcard [true] if this is a local-context merge,
|
|
176
|
-
/// otherwise false to indicate a full-context merge
|
|
177
|
-
/// @param mergeCache
|
|
178
|
-
static PredictionContext mergeSingletons(
|
|
179
|
-
SingletonPredictionContext a,
|
|
180
|
-
SingletonPredictionContext b,
|
|
181
|
-
bool rootIsWildcard,
|
|
182
|
-
Map<Pair<PredictionContext, PredictionContext>, PredictionContext>
|
|
183
|
-
mergeCache) {
|
|
184
|
-
if (mergeCache != null) {
|
|
185
|
-
var previous = mergeCache[Pair(a, b)];
|
|
186
|
-
if (previous != null) return previous;
|
|
187
|
-
previous = mergeCache[Pair(b, a)];
|
|
188
|
-
if (previous != null) return previous;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
final rootMerge = mergeRoot(a, b, rootIsWildcard);
|
|
192
|
-
if (rootMerge != null) {
|
|
193
|
-
if (mergeCache != null) mergeCache[Pair(a, b)] = rootMerge;
|
|
194
|
-
return rootMerge;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (a.returnState == b.returnState) {
|
|
198
|
-
// a == b
|
|
199
|
-
final parent =
|
|
200
|
-
merge(a.parent, b.parent, rootIsWildcard, mergeCache);
|
|
201
|
-
// if parent is same as existing a or b parent or reduced to a parent, return it
|
|
202
|
-
if (parent == a.parent) return a; // ax + bx = ax, if a=b
|
|
203
|
-
if (parent == b.parent) return b; // ax + bx = bx, if a=b
|
|
204
|
-
// else: ax + ay = a'[x,y]
|
|
205
|
-
// merge parents x and y, giving array node with x,y then remainders
|
|
206
|
-
// of those graphs. dup a, a' points at merged array
|
|
207
|
-
// new joined parent so create new singleton pointing to it, a'
|
|
208
|
-
PredictionContext a_ =
|
|
209
|
-
SingletonPredictionContext.create(parent, a.returnState);
|
|
210
|
-
if (mergeCache != null) mergeCache[Pair(a, b)] = a_;
|
|
211
|
-
return a_;
|
|
212
|
-
} else {
|
|
213
|
-
// a != b payloads differ
|
|
214
|
-
// see if we can collapse parents due to $+x parents if local ctx
|
|
215
|
-
PredictionContext singleParent;
|
|
216
|
-
if (a == b || (a.parent != null && a.parent == b.parent)) {
|
|
217
|
-
// ax + bx = [a,b]x
|
|
218
|
-
singleParent = a.parent;
|
|
219
|
-
}
|
|
220
|
-
if (singleParent != null) {
|
|
221
|
-
// parents are same
|
|
222
|
-
// sort payloads and use same parent
|
|
223
|
-
final payloads = <int>[a.returnState, b.returnState];
|
|
224
|
-
if (a.returnState > b.returnState) {
|
|
225
|
-
payloads[0] = b.returnState;
|
|
226
|
-
payloads[1] = a.returnState;
|
|
227
|
-
}
|
|
228
|
-
final parents = <PredictionContext>[singleParent, singleParent];
|
|
229
|
-
PredictionContext a_ = ArrayPredictionContext(parents, payloads);
|
|
230
|
-
if (mergeCache != null) mergeCache[Pair(a, b)] = a_;
|
|
231
|
-
return a_;
|
|
232
|
-
}
|
|
233
|
-
// parents differ and can't merge them. Just pack together
|
|
234
|
-
// into array; can't merge.
|
|
235
|
-
// ax + by = [ax,by]
|
|
236
|
-
final payloads = <int>[a.returnState, b.returnState];
|
|
237
|
-
var parents = <PredictionContext>[a.parent, b.parent];
|
|
238
|
-
if (a.returnState > b.returnState) {
|
|
239
|
-
// sort by payload
|
|
240
|
-
payloads[0] = b.returnState;
|
|
241
|
-
payloads[1] = a.returnState;
|
|
242
|
-
parents = [b.parent, a.parent];
|
|
243
|
-
}
|
|
244
|
-
PredictionContext a_ = ArrayPredictionContext(parents, payloads);
|
|
245
|
-
if (mergeCache != null) mergeCache[Pair(a, b)] = a_;
|
|
246
|
-
return a_;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/// Handle case where at least one of [a] or [b] is
|
|
251
|
-
/// {@link #EMPTY}. In the following diagrams, the symbol {@code $} is used
|
|
252
|
-
/// to represent {@link #EMPTY}.
|
|
253
|
-
///
|
|
254
|
-
/// <h2>Local-Context Merges</h2>
|
|
255
|
-
///
|
|
256
|
-
/// <p>These local-context merge operations are used when [rootIsWildcard]
|
|
257
|
-
/// is true.</p>
|
|
258
|
-
///
|
|
259
|
-
/// <p>{@link #EMPTY} is superset of any graph; return {@link #EMPTY}.<br>
|
|
260
|
-
/// <embed src="images/LocalMerge_EmptyRoot.svg" type="image/svg+xml"/></p>
|
|
261
|
-
///
|
|
262
|
-
/// <p>{@link #EMPTY} and anything is {@code #EMPTY}, so merged parent is
|
|
263
|
-
/// {@code #EMPTY}; return left graph.<br>
|
|
264
|
-
/// <embed src="images/LocalMerge_EmptyParent.svg" type="image/svg+xml"/></p>
|
|
265
|
-
///
|
|
266
|
-
/// <p>Special case of last merge if local context.<br>
|
|
267
|
-
/// <embed src="images/LocalMerge_DiffRoots.svg" type="image/svg+xml"/></p>
|
|
268
|
-
///
|
|
269
|
-
/// <h2>Full-Context Merges</h2>
|
|
270
|
-
///
|
|
271
|
-
/// <p>These full-context merge operations are used when [rootIsWildcard]
|
|
272
|
-
/// is false.</p>
|
|
273
|
-
///
|
|
274
|
-
/// <p><embed src="images/FullMerge_EmptyRoots.svg" type="image/svg+xml"/></p>
|
|
275
|
-
///
|
|
276
|
-
/// <p>Must keep all contexts; {@link #EMPTY} in array is a special value (and
|
|
277
|
-
/// null parent).<br>
|
|
278
|
-
/// <embed src="images/FullMerge_EmptyRoot.svg" type="image/svg+xml"/></p>
|
|
279
|
-
///
|
|
280
|
-
/// <p><embed src="images/FullMerge_SameRoot.svg" type="image/svg+xml"/></p>
|
|
281
|
-
///
|
|
282
|
-
/// @param a the first [SingletonPredictionContext]
|
|
283
|
-
/// @param b the second [SingletonPredictionContext]
|
|
284
|
-
/// @param rootIsWildcard [true] if this is a local-context merge,
|
|
285
|
-
/// otherwise false to indicate a full-context merge
|
|
286
|
-
static PredictionContext mergeRoot(SingletonPredictionContext a,
|
|
287
|
-
SingletonPredictionContext b, bool rootIsWildcard) {
|
|
288
|
-
if (rootIsWildcard) {
|
|
289
|
-
if (a == EMPTY) return EMPTY; // * + b = *
|
|
290
|
-
if (b == EMPTY) return EMPTY; // a + * = *
|
|
291
|
-
} else {
|
|
292
|
-
if (a == EMPTY && b == EMPTY) return EMPTY; // $ + $ = $
|
|
293
|
-
if (a == EMPTY) {
|
|
294
|
-
// $ + x = [x,$]
|
|
295
|
-
final payloads = <int>[b.returnState, EMPTY_RETURN_STATE];
|
|
296
|
-
final parents = <PredictionContext>[b.parent, null];
|
|
297
|
-
PredictionContext joined =
|
|
298
|
-
ArrayPredictionContext(parents, payloads);
|
|
299
|
-
return joined;
|
|
300
|
-
}
|
|
301
|
-
if (b == EMPTY) {
|
|
302
|
-
// x + $ = [x,$] ($ is always last if present)
|
|
303
|
-
final payloads = <int>[a.returnState, EMPTY_RETURN_STATE];
|
|
304
|
-
final parents = [a.parent, null];
|
|
305
|
-
PredictionContext joined =
|
|
306
|
-
ArrayPredictionContext(parents, payloads);
|
|
307
|
-
return joined;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
return null;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/// Merge two [ArrayPredictionContext] instances.
|
|
314
|
-
///
|
|
315
|
-
/// <p>Different tops, different parents.<br>
|
|
316
|
-
/// <embed src="images/ArrayMerge_DiffTopDiffPar.svg" type="image/svg+xml"/></p>
|
|
317
|
-
///
|
|
318
|
-
/// <p>Shared top, same parents.<br>
|
|
319
|
-
/// <embed src="images/ArrayMerge_ShareTopSamePar.svg" type="image/svg+xml"/></p>
|
|
320
|
-
///
|
|
321
|
-
/// <p>Shared top, different parents.<br>
|
|
322
|
-
/// <embed src="images/ArrayMerge_ShareTopDiffPar.svg" type="image/svg+xml"/></p>
|
|
323
|
-
///
|
|
324
|
-
/// <p>Shared top, all shared parents.<br>
|
|
325
|
-
/// <embed src="images/ArrayMerge_ShareTopSharePar.svg" type="image/svg+xml"/></p>
|
|
326
|
-
///
|
|
327
|
-
/// <p>Equal tops, merge parents and reduce top to
|
|
328
|
-
/// [SingletonPredictionContext].<br>
|
|
329
|
-
/// <embed src="images/ArrayMerge_EqualTop.svg" type="image/svg+xml"/></p>
|
|
330
|
-
static PredictionContext mergeArrays(
|
|
331
|
-
ArrayPredictionContext a,
|
|
332
|
-
ArrayPredictionContext b,
|
|
333
|
-
bool rootIsWildcard,
|
|
334
|
-
Map<Pair<PredictionContext, PredictionContext>, PredictionContext>
|
|
335
|
-
mergeCache) {
|
|
336
|
-
if (mergeCache != null) {
|
|
337
|
-
var previous = mergeCache[Pair(a, b)];
|
|
338
|
-
if (previous != null) return previous;
|
|
339
|
-
previous = mergeCache[Pair(b, a)];
|
|
340
|
-
if (previous != null) return previous;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// merge sorted payloads a + b => M
|
|
344
|
-
var i = 0; // walks a
|
|
345
|
-
var j = 0; // walks b
|
|
346
|
-
var k = 0; // walks target M array
|
|
347
|
-
|
|
348
|
-
var mergedReturnStates = List<int>(
|
|
349
|
-
a.returnStates.length + b.returnStates.length); // TODO Will it grow?
|
|
350
|
-
var mergedParents = List<PredictionContext>(
|
|
351
|
-
a.returnStates.length + b.returnStates.length); // TODO Will it grow?
|
|
352
|
-
// walk and merge to yield mergedParents, mergedReturnStates
|
|
353
|
-
while (i < a.returnStates.length && j < b.returnStates.length) {
|
|
354
|
-
final a_parent = a.parents[i];
|
|
355
|
-
final b_parent = b.parents[j];
|
|
356
|
-
if (a.returnStates[i] == b.returnStates[j]) {
|
|
357
|
-
// same payload (stack tops are equal), must yield merged singleton
|
|
358
|
-
final payload = a.returnStates[i];
|
|
359
|
-
// $+$ = $
|
|
360
|
-
final both$ = payload == EMPTY_RETURN_STATE &&
|
|
361
|
-
a_parent == null &&
|
|
362
|
-
b_parent == null;
|
|
363
|
-
final ax_ax = (a_parent != null && b_parent != null) &&
|
|
364
|
-
a_parent == b_parent; // ax+ax -> ax
|
|
365
|
-
if (both$ || ax_ax) {
|
|
366
|
-
mergedParents[k] = a_parent; // choose left
|
|
367
|
-
mergedReturnStates[k] = payload;
|
|
368
|
-
} else {
|
|
369
|
-
// ax+ay -> a'[x,y]
|
|
370
|
-
final mergedParent =
|
|
371
|
-
merge(a_parent, b_parent, rootIsWildcard, mergeCache);
|
|
372
|
-
mergedParents[k] = mergedParent;
|
|
373
|
-
mergedReturnStates[k] = payload;
|
|
374
|
-
}
|
|
375
|
-
i++; // hop over left one as usual
|
|
376
|
-
j++; // but also skip one in right side since we merge
|
|
377
|
-
} else if (a.returnStates[i] < b.returnStates[j]) {
|
|
378
|
-
// copy a[i] to M
|
|
379
|
-
mergedParents[k] = a_parent;
|
|
380
|
-
mergedReturnStates[k] = a.returnStates[i];
|
|
381
|
-
i++;
|
|
382
|
-
} else {
|
|
383
|
-
// b > a, copy b[j] to M
|
|
384
|
-
mergedParents[k] = b_parent;
|
|
385
|
-
mergedReturnStates[k] = b.returnStates[j];
|
|
386
|
-
j++;
|
|
387
|
-
}
|
|
388
|
-
k++;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// copy over any payloads remaining in either array
|
|
392
|
-
if (i < a.returnStates.length) {
|
|
393
|
-
for (var p = i; p < a.returnStates.length; p++) {
|
|
394
|
-
mergedParents[k] = a.parents[p];
|
|
395
|
-
mergedReturnStates[k] = a.returnStates[p];
|
|
396
|
-
k++;
|
|
397
|
-
}
|
|
398
|
-
} else {
|
|
399
|
-
for (var p = j; p < b.returnStates.length; p++) {
|
|
400
|
-
mergedParents[k] = b.parents[p];
|
|
401
|
-
mergedReturnStates[k] = b.returnStates[p];
|
|
402
|
-
k++;
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// trim merged if we combined a few that had same stack tops
|
|
407
|
-
if (k < mergedParents.length) {
|
|
408
|
-
// write index < last position; trim
|
|
409
|
-
if (k == 1) {
|
|
410
|
-
// for just one merged element, return singleton top
|
|
411
|
-
PredictionContext a_ = SingletonPredictionContext.create(
|
|
412
|
-
mergedParents[0], mergedReturnStates[0]);
|
|
413
|
-
if (mergeCache != null) mergeCache[Pair(a, b)] = a_;
|
|
414
|
-
return a_;
|
|
415
|
-
}
|
|
416
|
-
mergedParents = List(k)..setRange(0, k, mergedParents);
|
|
417
|
-
mergedReturnStates = List(k)..setRange(0, k, mergedReturnStates);
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
PredictionContext M =
|
|
421
|
-
ArrayPredictionContext(mergedParents, mergedReturnStates);
|
|
422
|
-
|
|
423
|
-
// if we created same array as a or b, return that instead
|
|
424
|
-
// TODO: track whether this is possible above during merge sort for speed
|
|
425
|
-
if (M == a) {
|
|
426
|
-
if (mergeCache != null) mergeCache[Pair(a, b)] = a;
|
|
427
|
-
return a;
|
|
428
|
-
}
|
|
429
|
-
if (M == b) {
|
|
430
|
-
if (mergeCache != null) mergeCache[Pair(a, b)] = b;
|
|
431
|
-
return b;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
combineCommonParents(mergedParents);
|
|
435
|
-
|
|
436
|
-
if (mergeCache != null) mergeCache[Pair(a, b)] = M;
|
|
437
|
-
return M;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
/// Make pass over all <em>M</em> [parents]; merge any {@code equals()}
|
|
441
|
-
/// ones.
|
|
442
|
-
static void combineCommonParents(List<PredictionContext> parents) {
|
|
443
|
-
final uniqueParents =
|
|
444
|
-
<PredictionContext, PredictionContext>{};
|
|
445
|
-
|
|
446
|
-
for (var p = 0; p < parents.length; p++) {
|
|
447
|
-
final parent = parents[p];
|
|
448
|
-
if (!uniqueParents.containsKey(parent)) {
|
|
449
|
-
// don't replace
|
|
450
|
-
uniqueParents[parent] = parent;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
for (var p = 0; p < parents.length; p++) {
|
|
455
|
-
parents[p] = uniqueParents[parents[p]];
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
static String toDOTString(PredictionContext context) {
|
|
460
|
-
if (context == null) return '';
|
|
461
|
-
final buf = StringBuffer();
|
|
462
|
-
buf.write('digraph G {\n');
|
|
463
|
-
buf.write('rankdir=LR;\n');
|
|
464
|
-
|
|
465
|
-
final nodes = getAllContextNodes(context);
|
|
466
|
-
nodes.sort((PredictionContext o1, PredictionContext o2) {
|
|
467
|
-
return o1.id - o2.id;
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
for (var current in nodes) {
|
|
471
|
-
if (current is SingletonPredictionContext) {
|
|
472
|
-
final s = current.id.toString();
|
|
473
|
-
buf.write(' s');
|
|
474
|
-
buf.write(s);
|
|
475
|
-
var returnState = current.getReturnState(0).toString();
|
|
476
|
-
if (current is EmptyPredictionContext) returnState = r'$';
|
|
477
|
-
buf.write(' [label=\"');
|
|
478
|
-
buf.write(returnState);
|
|
479
|
-
buf.write('\"];\n');
|
|
480
|
-
continue;
|
|
481
|
-
}
|
|
482
|
-
ArrayPredictionContext arr = current;
|
|
483
|
-
buf.write(' s');
|
|
484
|
-
buf.write(arr.id);
|
|
485
|
-
buf.write(' [shape=box, label=\"');
|
|
486
|
-
buf.write('[');
|
|
487
|
-
var first = true;
|
|
488
|
-
for (var inv in arr.returnStates) {
|
|
489
|
-
if (!first) buf.write(', ');
|
|
490
|
-
if (inv == EMPTY_RETURN_STATE) {
|
|
491
|
-
buf.write(r'$');
|
|
492
|
-
} else {
|
|
493
|
-
buf.write(inv);
|
|
494
|
-
}
|
|
495
|
-
first = false;
|
|
496
|
-
}
|
|
497
|
-
buf.write(']');
|
|
498
|
-
buf.write('\"];\n');
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
for (var current in nodes) {
|
|
502
|
-
if (current == EMPTY) continue;
|
|
503
|
-
for (var i = 0; i < current.length; i++) {
|
|
504
|
-
if (current.getParent(i) == null) continue;
|
|
505
|
-
final s = current.id.toString();
|
|
506
|
-
buf.write(' s');
|
|
507
|
-
buf.write(s);
|
|
508
|
-
buf.write('->');
|
|
509
|
-
buf.write('s');
|
|
510
|
-
buf.write(current.getParent(i).id);
|
|
511
|
-
if (current.length > 1) {
|
|
512
|
-
buf.write(' [label=\"parent[$i]\"];\n');
|
|
513
|
-
} else {
|
|
514
|
-
buf.write(';\n');
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
buf.write('}\n');
|
|
520
|
-
return buf.toString();
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// From Sam
|
|
524
|
-
static PredictionContext getCachedContext(
|
|
525
|
-
PredictionContext context,
|
|
526
|
-
PredictionContextCache contextCache,
|
|
527
|
-
Map<PredictionContext, PredictionContext> visited) {
|
|
528
|
-
if (context.isEmpty) {
|
|
529
|
-
return context;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
var existing = visited[context];
|
|
533
|
-
if (existing != null) {
|
|
534
|
-
return existing;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
existing = contextCache[context];
|
|
538
|
-
if (existing != null) {
|
|
539
|
-
visited[context] = existing;
|
|
540
|
-
return existing;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
var changed = false;
|
|
544
|
-
var parents = List<PredictionContext>(context.length);
|
|
545
|
-
for (var i = 0; i < parents.length; i++) {
|
|
546
|
-
final parent =
|
|
547
|
-
getCachedContext(context.getParent(i), contextCache, visited);
|
|
548
|
-
if (changed || parent != context.getParent(i)) {
|
|
549
|
-
if (!changed) {
|
|
550
|
-
parents = List<PredictionContext>(context.length);
|
|
551
|
-
for (var j = 0; j < context.length; j++) {
|
|
552
|
-
parents[j] = context.getParent(j);
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
changed = true;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
parents[i] = parent;
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
if (!changed) {
|
|
563
|
-
contextCache.add(context);
|
|
564
|
-
visited[context] = context;
|
|
565
|
-
return context;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
PredictionContext updated;
|
|
569
|
-
if (parents.isEmpty) {
|
|
570
|
-
updated = EMPTY;
|
|
571
|
-
} else if (parents.length == 1) {
|
|
572
|
-
updated = SingletonPredictionContext.create(
|
|
573
|
-
parents[0], context.getReturnState(0));
|
|
574
|
-
} else {
|
|
575
|
-
ArrayPredictionContext arrayPredictionContext = context;
|
|
576
|
-
updated = ArrayPredictionContext(
|
|
577
|
-
parents, arrayPredictionContext.returnStates);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
contextCache.add(updated);
|
|
581
|
-
visited[updated] = updated;
|
|
582
|
-
visited[context] = updated;
|
|
583
|
-
|
|
584
|
-
return updated;
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
// // extra structures, but cut/paste/morphed works, so leave it.
|
|
588
|
-
// // seems to do a breadth-first walk
|
|
589
|
-
// static List<PredictionContext> getAllNodes(PredictionContext context) {
|
|
590
|
-
// Map<PredictionContext, PredictionContext> visited =
|
|
591
|
-
// new IdentityHashMap<PredictionContext, PredictionContext>();
|
|
592
|
-
// Deque<PredictionContext> workList = new ArrayDeque<PredictionContext>();
|
|
593
|
-
// workList.add(context);
|
|
594
|
-
// visited.put(context, context);
|
|
595
|
-
// List<PredictionContext> nodes = new ArrayList<PredictionContext>();
|
|
596
|
-
// while (!workList.isEmpty) {
|
|
597
|
-
// PredictionContext current = workList.pop();
|
|
598
|
-
// nodes.add(current);
|
|
599
|
-
// for (int i = 0; i < current.length; i++) {
|
|
600
|
-
// PredictionContext parent = current.getParent(i);
|
|
601
|
-
// if ( parent!=null && visited.put(parent, parent) == null) {
|
|
602
|
-
// workList.push(parent);
|
|
603
|
-
// }
|
|
604
|
-
// }
|
|
605
|
-
// }
|
|
606
|
-
// return nodes;
|
|
607
|
-
// }
|
|
608
|
-
|
|
609
|
-
// ter's recursive version of Sam's getAllNodes()
|
|
610
|
-
static List<PredictionContext> getAllContextNodes(PredictionContext context) {
|
|
611
|
-
final nodes = <PredictionContext>[];
|
|
612
|
-
final visited =
|
|
613
|
-
<PredictionContext, PredictionContext>{};
|
|
614
|
-
getAllContextNodes_(context, nodes, visited);
|
|
615
|
-
return nodes;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
static void getAllContextNodes_(
|
|
619
|
-
PredictionContext context,
|
|
620
|
-
List<PredictionContext> nodes,
|
|
621
|
-
Map<PredictionContext, PredictionContext> visited) {
|
|
622
|
-
if (context == null || visited.containsKey(context)) return;
|
|
623
|
-
visited[context] = context;
|
|
624
|
-
nodes.add(context);
|
|
625
|
-
for (var i = 0; i < context.length; i++) {
|
|
626
|
-
getAllContextNodes_(context.getParent(i), nodes, visited);
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
// FROM SAM
|
|
631
|
-
List<String> toStrings(
|
|
632
|
-
Recognizer recognizer, PredictionContext stop, int currentState) {
|
|
633
|
-
final result = <String>[];
|
|
634
|
-
|
|
635
|
-
outer:
|
|
636
|
-
for (var perm = 0;; perm++) {
|
|
637
|
-
var offset = 0;
|
|
638
|
-
var last = true;
|
|
639
|
-
var p = this;
|
|
640
|
-
var stateNumber = currentState;
|
|
641
|
-
final localBuffer = StringBuffer();
|
|
642
|
-
localBuffer.write('[');
|
|
643
|
-
while (!p.isEmpty && p != stop) {
|
|
644
|
-
var index = 0;
|
|
645
|
-
if (p.length > 0) {
|
|
646
|
-
var bits = 1;
|
|
647
|
-
while ((1 << bits) < p.length) {
|
|
648
|
-
bits++;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
final mask = (1 << bits) - 1;
|
|
652
|
-
index = (perm >> offset) & mask;
|
|
653
|
-
last &= index >= p.length - 1;
|
|
654
|
-
if (index >= p.length) {
|
|
655
|
-
continue outer;
|
|
656
|
-
}
|
|
657
|
-
offset += bits;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
if (recognizer != null) {
|
|
661
|
-
if (localBuffer.length > 1) {
|
|
662
|
-
// first char is '[', if more than that this isn't the first rule
|
|
663
|
-
localBuffer.write(' ');
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
final atn = recognizer.getATN();
|
|
667
|
-
final s = atn.states[stateNumber];
|
|
668
|
-
final ruleName = recognizer.ruleNames[s.ruleIndex];
|
|
669
|
-
localBuffer.write(ruleName);
|
|
670
|
-
} else if (p.getReturnState(index) != EMPTY_RETURN_STATE) {
|
|
671
|
-
if (!p.isEmpty) {
|
|
672
|
-
if (localBuffer.length > 1) {
|
|
673
|
-
// first char is '[', if more than that this isn't the first rule
|
|
674
|
-
localBuffer.write(' ');
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
localBuffer.write(p.getReturnState(index));
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
stateNumber = p.getReturnState(index);
|
|
681
|
-
p = p.getParent(index);
|
|
682
|
-
}
|
|
683
|
-
localBuffer.write(']');
|
|
684
|
-
result.add(localBuffer.toString());
|
|
685
|
-
|
|
686
|
-
if (last) {
|
|
687
|
-
break;
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
return result;
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
class SingletonPredictionContext extends PredictionContext {
|
|
696
|
-
final PredictionContext parent;
|
|
697
|
-
final int returnState;
|
|
698
|
-
|
|
699
|
-
SingletonPredictionContext(this.parent, this.returnState)
|
|
700
|
-
: super(parent != null
|
|
701
|
-
? PredictionContext.calculateHashCode([parent], [returnState])
|
|
702
|
-
: PredictionContext.calculateEmptyHashCode()) {
|
|
703
|
-
assert(returnState != ATNState.INVALID_STATE_NUMBER);
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
static SingletonPredictionContext create(
|
|
707
|
-
PredictionContext parent, int returnState) {
|
|
708
|
-
if (returnState == PredictionContext.EMPTY_RETURN_STATE && parent == null) {
|
|
709
|
-
// someone can pass in the bits of an array ctx that mean $
|
|
710
|
-
return PredictionContext.EMPTY;
|
|
711
|
-
}
|
|
712
|
-
return SingletonPredictionContext(parent, returnState);
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
@override
|
|
716
|
-
int get length {
|
|
717
|
-
return 1;
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
@override
|
|
721
|
-
PredictionContext getParent(int index) {
|
|
722
|
-
assert(index == 0);
|
|
723
|
-
return parent;
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
@override
|
|
727
|
-
int getReturnState(int index) {
|
|
728
|
-
assert(index == 0);
|
|
729
|
-
return returnState;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
@override
|
|
733
|
-
bool operator ==(Object o) {
|
|
734
|
-
if (identical(this, o)) {
|
|
735
|
-
return true;
|
|
736
|
-
} else if (o is SingletonPredictionContext) {
|
|
737
|
-
if (hashCode != o.hashCode) {
|
|
738
|
-
return false; // can't be same if hash is different
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
final s = o;
|
|
742
|
-
return returnState == s.returnState &&
|
|
743
|
-
(parent != null && parent == s.parent);
|
|
744
|
-
}
|
|
745
|
-
return false;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
@override
|
|
749
|
-
String toString() {
|
|
750
|
-
final up = parent != null ? parent.toString() : '';
|
|
751
|
-
if (up.isEmpty) {
|
|
752
|
-
if (returnState == PredictionContext.EMPTY_RETURN_STATE) {
|
|
753
|
-
return r'$';
|
|
754
|
-
}
|
|
755
|
-
return returnState.toString();
|
|
756
|
-
}
|
|
757
|
-
return '$returnState $up';
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
class EmptyPredictionContext extends SingletonPredictionContext {
|
|
762
|
-
EmptyPredictionContext() : super(null, PredictionContext.EMPTY_RETURN_STATE);
|
|
763
|
-
|
|
764
|
-
@override
|
|
765
|
-
bool get isEmpty {
|
|
766
|
-
return true;
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
@override
|
|
770
|
-
int get length {
|
|
771
|
-
return 1;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
@override
|
|
775
|
-
PredictionContext getParent(int index) {
|
|
776
|
-
return null;
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
@override
|
|
780
|
-
int getReturnState(int index) {
|
|
781
|
-
return returnState;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
@override
|
|
785
|
-
String toString() {
|
|
786
|
-
return r'$';
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
class ArrayPredictionContext extends PredictionContext {
|
|
791
|
-
/// Parent can be null only if full ctx mode and we make an array
|
|
792
|
-
/// from {@link #EMPTY} and non-empty. We merge {@link #EMPTY} by using null parent and
|
|
793
|
-
/// returnState == {@link #EMPTY_RETURN_STATE}.
|
|
794
|
-
List<PredictionContext> parents;
|
|
795
|
-
|
|
796
|
-
/// Sorted for merge, no duplicates; if present,
|
|
797
|
-
/// {@link #EMPTY_RETURN_STATE} is always last.
|
|
798
|
-
List<int> returnStates;
|
|
799
|
-
|
|
800
|
-
ArrayPredictionContext.of(SingletonPredictionContext a)
|
|
801
|
-
: this([a.parent], [a.returnState]);
|
|
802
|
-
|
|
803
|
-
ArrayPredictionContext(
|
|
804
|
-
List<PredictionContext> parents, List<int> returnStates)
|
|
805
|
-
: super(PredictionContext.calculateHashCode(parents, returnStates)) {
|
|
806
|
-
assert(parents != null && parents.isNotEmpty);
|
|
807
|
-
assert(returnStates != null && returnStates.isNotEmpty);
|
|
808
|
-
// System.err.println("CREATE ARRAY: "+Arrays.toString(parents)+", "+Arrays.toString(returnStates));
|
|
809
|
-
this.parents = parents;
|
|
810
|
-
this.returnStates = returnStates;
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
@override
|
|
814
|
-
bool get isEmpty {
|
|
815
|
-
// since EMPTY_RETURN_STATE can only appear in the last position, we
|
|
816
|
-
// don't need to verify that size==1
|
|
817
|
-
return returnStates[0] == PredictionContext.EMPTY_RETURN_STATE;
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
@override
|
|
821
|
-
int get length {
|
|
822
|
-
return returnStates.length;
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
@override
|
|
826
|
-
PredictionContext getParent(int index) {
|
|
827
|
-
return parents[index];
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
@override
|
|
831
|
-
int getReturnState(int index) {
|
|
832
|
-
return returnStates[index];
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
// int findReturnState(int returnState) {
|
|
836
|
-
// return Arrays.binarySearch(returnStates, returnState);
|
|
837
|
-
// }
|
|
838
|
-
|
|
839
|
-
@override
|
|
840
|
-
bool operator ==(Object o) {
|
|
841
|
-
if (identical(this, o)) {
|
|
842
|
-
return true;
|
|
843
|
-
} else if (o is ArrayPredictionContext) {
|
|
844
|
-
if (hashCode != o.hashCode) {
|
|
845
|
-
return false; // can't be same if hash is different
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
final a = o;
|
|
849
|
-
return ListEquality().equals(returnStates, a.returnStates) &&
|
|
850
|
-
ListEquality().equals(parents, a.parents);
|
|
851
|
-
}
|
|
852
|
-
return false;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
@override
|
|
856
|
-
String toString() {
|
|
857
|
-
if (isEmpty) return '[]';
|
|
858
|
-
final buf = StringBuffer();
|
|
859
|
-
buf.write('[');
|
|
860
|
-
for (var i = 0; i < returnStates.length; i++) {
|
|
861
|
-
if (i > 0) buf.write(', ');
|
|
862
|
-
if (returnStates[i] == PredictionContext.EMPTY_RETURN_STATE) {
|
|
863
|
-
buf.write(r'$');
|
|
864
|
-
continue;
|
|
865
|
-
}
|
|
866
|
-
buf.write(returnStates[i]);
|
|
867
|
-
if (parents[i] != null) {
|
|
868
|
-
buf.write(' ');
|
|
869
|
-
buf.write(parents[i].toString());
|
|
870
|
-
} else {
|
|
871
|
-
buf.write('null');
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
buf.write(']');
|
|
875
|
-
return buf.toString();
|
|
876
|
-
}
|
|
877
|
-
}
|