OLD | NEW |
1 // This code was auto-generated, is not intended to be edited, and is subject to | 1 // This code was auto-generated, is not intended to be edited, and is subject to |
2 // significant change. Please see the README file for more information. | 2 // significant change. Please see the README file for more information. |
3 library engine.constant; | 3 library engine.constant; |
4 import 'java_core.dart'; | 4 import 'java_core.dart'; |
5 import 'source.dart' show Source; | 5 import 'source.dart' show Source; |
6 import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode; | 6 import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode; |
7 import 'scanner.dart' show TokenType; | 7 import 'scanner.dart' show TokenType; |
8 import 'ast.dart'; | 8 import 'ast.dart'; |
9 import 'element.dart'; | 9 import 'element.dart'; |
10 import 'engine.dart' show AnalysisEngine; | 10 import 'engine.dart' show AnalysisEngine; |
11 /** | 11 /** |
12 * Instances of the class `ConstantEvaluator` evaluate constant expressions to p
roduce their | 12 * Instances of the class `ConstantEvaluator` evaluate constant expressions to p
roduce their |
13 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant | 13 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant |
14 * expression is one of the following: | 14 * expression is one of the following: |
15 * | 15 * |
16 * * A literal number. | 16 * * A literal number. |
17 * * A literal boolean. | 17 * * A literal boolean. |
18 * * A literal string where any interpolated expression is a compile-time consta
nt that evaluates | 18 * * A literal string where any interpolated expression is a compile-time consta
nt that evaluates |
19 * to a numeric, string or boolean value or to `null`. | 19 * to a numeric, string or boolean value or to `null`. |
20 * * `null`. | 20 * * `null`. |
21 * * A reference to a static constant variable. | 21 * * A reference to a static constant variable. |
22 * * An identifier expression that denotes a constant variable, a class or a typ
e variable. | 22 * * An identifier expression that denotes a constant variable, a class or a typ
e variable. |
23 * * A constant constructor invocation. | 23 * * A constant constructor invocation. |
24 * * A constant list literal. | 24 * * A constant list literal. |
25 * * A constant map literal. | 25 * * A constant map literal. |
26 * * A simple or qualified identifier denoting a top-level function or a static
method. | 26 * * A simple or qualified identifier denoting a top-level function or a static
method. |
27 * * A parenthesized expression `(e)` where `e` is a constant expression. | 27 * * A parenthesized expression `(e)` where `e` is a constant expression. |
28 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`,`e1 != e2
` where `e1` and `e2` are constant expressions that evaluate to a | 28 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`, |
| 29 * `e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a |
29 * numeric, string or boolean value or to `null`. | 30 * numeric, string or boolean value or to `null`. |
30 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where`e`,
`e1` and `e2` are constant expressions that evaluate to a boolean value or | 31 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where |
| 32 * `e`, `e1` and `e2` are constant expressions that evaluate to a boolean value
or |
31 * to `null`. | 33 * to `null`. |
32 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,`e1 | e2`, `e1
>> e2` or `e1 << e2`, where `e`, `e1` and `e2`are constant expressions that eva
luate to an integer value or to `null`. | 34 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`, |
33 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`,`e1 * e2`, `e1
/ e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`,`e1 >= e2`, `e1 <= e2` or `e1 % e2`, wh
ere `e`, `e1` and `e2`are constant expressions that evaluate to a numeric value
or to `null`. | 35 * `e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2` |
| 36 * are constant expressions that evaluate to an integer value or to `null`. |
| 37 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`, |
| 38 * `e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`, |
| 39 * `e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2` |
| 40 * are constant expressions that evaluate to a numeric value or to `null`. |
34 * | 41 * |
35 * </blockquote> The values returned by instances of this class are therefore `n
ull` and | 42 * </blockquote> The values returned by instances of this class are therefore `n
ull` and |
36 * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and`Dar
tObject`. | 43 * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and |
| 44 * `DartObject`. |
37 * | 45 * |
38 * In addition, this class defines several values that can be returned to indica
te various | 46 * In addition, this class defines several values that can be returned to indica
te various |
39 * conditions encountered during evaluation. These are documented with the stati
c field that define | 47 * conditions encountered during evaluation. These are documented with the stati
c field that define |
40 * those values. | 48 * those values. |
41 */ | 49 */ |
42 class ConstantEvaluator { | 50 class ConstantEvaluator { |
43 | 51 |
44 /** | 52 /** |
45 * The source containing the expression(s) that will be evaluated. | 53 * The source containing the expression(s) that will be evaluated. |
46 */ | 54 */ |
47 Source _source; | 55 Source _source; |
48 | 56 |
49 /** | 57 /** |
50 * Initialize a newly created evaluator to evaluate expressions in the given s
ource. | 58 * Initialize a newly created evaluator to evaluate expressions in the given s
ource. |
| 59 * |
51 * @param source the source containing the expression(s) that will be evaluate
d | 60 * @param source the source containing the expression(s) that will be evaluate
d |
52 */ | 61 */ |
53 ConstantEvaluator(Source source) { | 62 ConstantEvaluator(Source source) { |
54 this._source = source; | 63 this._source = source; |
55 } | 64 } |
56 EvaluationResult evaluate(Expression expression) { | 65 EvaluationResult evaluate(Expression expression) { |
57 EvaluationResultImpl result = expression.accept(new ConstantVisitor()); | 66 EvaluationResultImpl result = expression.accept(new ConstantVisitor()); |
58 if (result is ValidResult) { | 67 if (result is ValidResult) { |
59 return EvaluationResult.forValue(((result as ValidResult)).value); | 68 return EvaluationResult.forValue(((result as ValidResult)).value); |
60 } | 69 } |
61 List<AnalysisError> errors = new List<AnalysisError>(); | 70 List<AnalysisError> errors = new List<AnalysisError>(); |
62 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { | 71 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { |
63 ASTNode node = data.node; | 72 ASTNode node = data.node; |
64 errors.add(new AnalysisError.con2(_source, node.offset, node.length, data.
errorCode, [])); | 73 errors.add(new AnalysisError.con2(_source, node.offset, node.length, data.
errorCode, [])); |
65 } | 74 } |
66 return EvaluationResult.forErrors(new List.from(errors)); | 75 return EvaluationResult.forErrors(new List.from(errors)); |
67 } | 76 } |
68 } | 77 } |
69 /** | 78 /** |
70 * Instances of the class `EvaluationResult` represent the result of attempting
to evaluate an | 79 * Instances of the class `EvaluationResult` represent the result of attempting
to evaluate an |
71 * expression. | 80 * expression. |
72 */ | 81 */ |
73 class EvaluationResult { | 82 class EvaluationResult { |
74 | 83 |
75 /** | 84 /** |
76 * Return an evaluation result representing the result of evaluating an expres
sion that is not a | 85 * Return an evaluation result representing the result of evaluating an expres
sion that is not a |
77 * compile-time constant because of the given errors. | 86 * compile-time constant because of the given errors. |
| 87 * |
78 * @param errors the errors that should be reported for the expression(s) that
were evaluated | 88 * @param errors the errors that should be reported for the expression(s) that
were evaluated |
79 * @return the result of evaluating an expression that is not a compile-time c
onstant | 89 * @return the result of evaluating an expression that is not a compile-time c
onstant |
80 */ | 90 */ |
81 static EvaluationResult forErrors(List<AnalysisError> errors) => new Evaluatio
nResult(null, errors); | 91 static EvaluationResult forErrors(List<AnalysisError> errors) => new Evaluatio
nResult(null, errors); |
82 | 92 |
83 /** | 93 /** |
84 * Return an evaluation result representing the result of evaluating an expres
sion that is a | 94 * Return an evaluation result representing the result of evaluating an expres
sion that is a |
85 * compile-time constant that evaluates to the given value. | 95 * compile-time constant that evaluates to the given value. |
| 96 * |
86 * @param value the value of the expression | 97 * @param value the value of the expression |
87 * @return the result of evaluating an expression that is a compile-time const
ant | 98 * @return the result of evaluating an expression that is a compile-time const
ant |
88 */ | 99 */ |
89 static EvaluationResult forValue(Object value) => new EvaluationResult(value,
null); | 100 static EvaluationResult forValue(Object value) => new EvaluationResult(value,
null); |
90 | 101 |
91 /** | 102 /** |
92 * The value of the expression. | 103 * The value of the expression. |
93 */ | 104 */ |
94 Object _value; | 105 Object _value; |
95 | 106 |
96 /** | 107 /** |
97 * The errors that should be reported for the expression(s) that were evaluate
d. | 108 * The errors that should be reported for the expression(s) that were evaluate
d. |
98 */ | 109 */ |
99 List<AnalysisError> _errors; | 110 List<AnalysisError> _errors; |
100 | 111 |
101 /** | 112 /** |
102 * Initialize a newly created result object with the given state. Clients shou
ld use one of the | 113 * Initialize a newly created result object with the given state. Clients shou
ld use one of the |
103 * factory methods: [forErrors] and [forValue]. | 114 * factory methods: [forErrors] and [forValue]. |
| 115 * |
104 * @param value the value of the expression | 116 * @param value the value of the expression |
105 * @param errors the errors that should be reported for the expression(s) that
were evaluated | 117 * @param errors the errors that should be reported for the expression(s) that
were evaluated |
106 */ | 118 */ |
107 EvaluationResult(Object value, List<AnalysisError> errors) { | 119 EvaluationResult(Object value, List<AnalysisError> errors) { |
108 this._value = value; | 120 this._value = value; |
109 this._errors = errors; | 121 this._errors = errors; |
110 } | 122 } |
111 | 123 |
112 /** | 124 /** |
113 * Return an array containing the errors that should be reported for the expre
ssion(s) that were | 125 * Return an array containing the errors that should be reported for the expre
ssion(s) that were |
114 * evaluated. If there are no such errors, the array will be empty. The array
can be empty even if | 126 * evaluated. If there are no such errors, the array will be empty. The array
can be empty even if |
115 * the expression is not a valid compile time constant if the errors would hav
e been reported by | 127 * the expression is not a valid compile time constant if the errors would hav
e been reported by |
116 * other parts of the analysis engine. | 128 * other parts of the analysis engine. |
117 */ | 129 */ |
118 List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS :
_errors; | 130 List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS :
_errors; |
119 | 131 |
120 /** | 132 /** |
121 * Return the value of the expression, or `null` if the expression evaluated t
o `null`or if the expression could not be evaluated, either because it was not a
compile-time constant | 133 * Return the value of the expression, or `null` if the expression evaluated t
o `null` |
| 134 * or if the expression could not be evaluated, either because it was not a co
mpile-time constant |
122 * expression or because it would throw an exception when evaluated. | 135 * expression or because it would throw an exception when evaluated. |
| 136 * |
123 * @return the value of the expression | 137 * @return the value of the expression |
124 */ | 138 */ |
125 Object get value => _value; | 139 Object get value => _value; |
126 | 140 |
127 /** | 141 /** |
128 * Return `true` if the expression is a compile-time constant expression that
would not | 142 * Return `true` if the expression is a compile-time constant expression that
would not |
129 * throw an exception when evaluated. | 143 * throw an exception when evaluated. |
| 144 * |
130 * @return `true` if the expression is a valid compile-time constant expressio
n | 145 * @return `true` if the expression is a valid compile-time constant expressio
n |
131 */ | 146 */ |
132 bool get isValid => _errors == null; | 147 bool get isValid => _errors == null; |
133 } | 148 } |
134 /** | 149 /** |
135 * Instances of the class `ConstantFinder` are used to traverse the AST structur
es of all of | 150 * Instances of the class `ConstantFinder` are used to traverse the AST structur
es of all of |
136 * the compilation units being resolved and build a table mapping constant varia
ble elements to the | 151 * the compilation units being resolved and build a table mapping constant varia
ble elements to the |
137 * declarations of those variables. | 152 * declarations of those variables. |
138 */ | 153 */ |
139 class ConstantFinder extends RecursiveASTVisitor<Object> { | 154 class ConstantFinder extends RecursiveASTVisitor<Object> { |
140 | 155 |
141 /** | 156 /** |
142 * A table mapping constant variable elements to the declarations of those var
iables. | 157 * A table mapping constant variable elements to the declarations of those var
iables. |
143 */ | 158 */ |
144 Map<VariableElement, VariableDeclaration> _variableMap = new Map<VariableEleme
nt, VariableDeclaration>(); | 159 Map<VariableElement, VariableDeclaration> _variableMap = new Map<VariableEleme
nt, VariableDeclaration>(); |
145 | 160 |
146 /** | 161 /** |
147 * Return a table mapping constant variable elements to the declarations of th
ose variables. | 162 * Return a table mapping constant variable elements to the declarations of th
ose variables. |
| 163 * |
148 * @return a table mapping constant variable elements to the declarations of t
hose variables | 164 * @return a table mapping constant variable elements to the declarations of t
hose variables |
149 */ | 165 */ |
150 Map<VariableElement, VariableDeclaration> get variableMap => _variableMap; | 166 Map<VariableElement, VariableDeclaration> get variableMap => _variableMap; |
151 Object visitVariableDeclaration(VariableDeclaration node) { | 167 Object visitVariableDeclaration(VariableDeclaration node) { |
152 super.visitVariableDeclaration(node); | 168 super.visitVariableDeclaration(node); |
153 Expression initializer = node.initializer; | 169 Expression initializer = node.initializer; |
154 if (initializer != null && node.isConst) { | 170 if (initializer != null && node.isConst) { |
155 VariableElement element = node.element; | 171 VariableElement element = node.element; |
156 if (element != null) { | 172 if (element != null) { |
157 _variableMap[element] = node; | 173 _variableMap[element] = node; |
158 } | 174 } |
159 } | 175 } |
160 return null; | 176 return null; |
161 } | 177 } |
162 } | 178 } |
163 /** | 179 /** |
164 * Instances of the class `ConstantValueComputer` compute the values of constant
variables in | 180 * Instances of the class `ConstantValueComputer` compute the values of constant
variables in |
165 * one or more compilation units. The expected usage pattern is for the compilat
ion units to be | 181 * one or more compilation units. The expected usage pattern is for the compilat
ion units to be |
166 * added to this computer using the method [add] and then for the method[compute
Values] to invoked exactly once. Any use of an instance after invoking the | 182 * added to this computer using the method [add] and then for the method |
| 183 * [computeValues] to invoked exactly once. Any use of an instance after invokin
g the |
167 * method [computeValues] will result in unpredictable behavior. | 184 * method [computeValues] will result in unpredictable behavior. |
168 */ | 185 */ |
169 class ConstantValueComputer { | 186 class ConstantValueComputer { |
170 | 187 |
171 /** | 188 /** |
172 * The object used to find constant variables in the compilation units that we
re added. | 189 * The object used to find constant variables in the compilation units that we
re added. |
173 */ | 190 */ |
174 ConstantFinder _constantFinder = new ConstantFinder(); | 191 ConstantFinder _constantFinder = new ConstantFinder(); |
175 | 192 |
176 /** | 193 /** |
177 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to | 194 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to |
178 * the other constant variables that are referenced in the head's initializer. | 195 * the other constant variables that are referenced in the head's initializer. |
179 */ | 196 */ |
180 DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableEle
ment>(); | 197 DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableEle
ment>(); |
181 | 198 |
182 /** | 199 /** |
183 * A table mapping constant variables to the declarations of those variables. | 200 * A table mapping constant variables to the declarations of those variables. |
184 */ | 201 */ |
185 Map<VariableElement, VariableDeclaration> _declarationMap; | 202 Map<VariableElement, VariableDeclaration> _declarationMap; |
186 | 203 |
187 /** | 204 /** |
188 * Add the constant variables in the given compilation unit to the list of con
stant variables | 205 * Add the constant variables in the given compilation unit to the list of con
stant variables |
189 * whose value needs to be computed. | 206 * whose value needs to be computed. |
| 207 * |
190 * @param unit the compilation unit defining the constant variables to be adde
d | 208 * @param unit the compilation unit defining the constant variables to be adde
d |
191 */ | 209 */ |
192 void add(CompilationUnit unit) { | 210 void add(CompilationUnit unit) { |
193 unit.accept(_constantFinder); | 211 unit.accept(_constantFinder); |
194 } | 212 } |
195 | 213 |
196 /** | 214 /** |
197 * Compute values for all of the constant variables in the compilation units t
hat were added. | 215 * Compute values for all of the constant variables in the compilation units t
hat were added. |
198 */ | 216 */ |
199 void computeValues() { | 217 void computeValues() { |
(...skipping 19 matching lines...) Expand all Loading... |
219 for (VariableElement variable in variablesInCycle) { | 237 for (VariableElement variable in variablesInCycle) { |
220 generateCycleError(variablesInCycle, variable); | 238 generateCycleError(variablesInCycle, variable); |
221 } | 239 } |
222 _referenceGraph.removeAllNodes(variablesInCycle); | 240 _referenceGraph.removeAllNodes(variablesInCycle); |
223 } | 241 } |
224 } | 242 } |
225 } | 243 } |
226 | 244 |
227 /** | 245 /** |
228 * Compute a value for the given variable. | 246 * Compute a value for the given variable. |
| 247 * |
229 * @param variable the variable for which a value is to be computed | 248 * @param variable the variable for which a value is to be computed |
230 */ | 249 */ |
231 void computeValueFor(VariableElement variable) { | 250 void computeValueFor(VariableElement variable) { |
232 VariableDeclaration declaration = _declarationMap[variable]; | 251 VariableDeclaration declaration = _declarationMap[variable]; |
233 if (declaration == null) { | 252 if (declaration == null) { |
234 return; | 253 return; |
235 } | 254 } |
236 EvaluationResultImpl result = declaration.initializer.accept(new ConstantVis
itor()); | 255 EvaluationResultImpl result = declaration.initializer.accept(new ConstantVis
itor()); |
237 ((variable as VariableElementImpl)).evaluationResult = result; | 256 ((variable as VariableElementImpl)).evaluationResult = result; |
238 if (result is ErrorResult) { | 257 if (result is ErrorResult) { |
239 List<AnalysisError> errors = new List<AnalysisError>(); | 258 List<AnalysisError> errors = new List<AnalysisError>(); |
240 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { | 259 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { |
241 ASTNode node = data.node; | 260 ASTNode node = data.node; |
242 Source source = variable.getAncestor(CompilationUnitElement).source; | 261 Source source = variable.getAncestor(CompilationUnitElement).source; |
243 errors.add(new AnalysisError.con2(source, node.offset, node.length, data
.errorCode, [])); | 262 errors.add(new AnalysisError.con2(source, node.offset, node.length, data
.errorCode, [])); |
244 } | 263 } |
245 } | 264 } |
246 } | 265 } |
247 | 266 |
248 /** | 267 /** |
249 * Generate an error indicating that the given variable is not a valid compile
-time constant | 268 * Generate an error indicating that the given variable is not a valid compile
-time constant |
250 * because it references at least one of the variables in the given cycle, eac
h of which directly | 269 * because it references at least one of the variables in the given cycle, eac
h of which directly |
251 * or indirectly references the variable. | 270 * or indirectly references the variable. |
| 271 * |
252 * @param variablesInCycle the variables in the cycle that includes the given
variable | 272 * @param variablesInCycle the variables in the cycle that includes the given
variable |
253 * @param variable the variable that is not a valid compile-time constant | 273 * @param variable the variable that is not a valid compile-time constant |
254 */ | 274 */ |
255 void generateCycleError(List<VariableElement> variablesInCycle, VariableElemen
t variable) { | 275 void generateCycleError(List<VariableElement> variablesInCycle, VariableElemen
t variable) { |
256 } | 276 } |
257 } | 277 } |
258 /** | 278 /** |
259 * Instances of the class `ConstantVisitor` evaluate constant expressions to pro
duce their | 279 * Instances of the class `ConstantVisitor` evaluate constant expressions to pro
duce their |
260 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant | 280 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant |
261 * expression is one of the following: | 281 * expression is one of the following: |
262 * | 282 * |
263 * * A literal number. | 283 * * A literal number. |
264 * * A literal boolean. | 284 * * A literal boolean. |
265 * * A literal string where any interpolated expression is a compile-time consta
nt that evaluates | 285 * * A literal string where any interpolated expression is a compile-time consta
nt that evaluates |
266 * to a numeric, string or boolean value or to `null`. | 286 * to a numeric, string or boolean value or to `null`. |
267 * * `null`. | 287 * * `null`. |
268 * * A reference to a static constant variable. | 288 * * A reference to a static constant variable. |
269 * * An identifier expression that denotes a constant variable, a class or a typ
e variable. | 289 * * An identifier expression that denotes a constant variable, a class or a typ
e variable. |
270 * * A constant constructor invocation. | 290 * * A constant constructor invocation. |
271 * * A constant list literal. | 291 * * A constant list literal. |
272 * * A constant map literal. | 292 * * A constant map literal. |
273 * * A simple or qualified identifier denoting a top-level function or a static
method. | 293 * * A simple or qualified identifier denoting a top-level function or a static
method. |
274 * * A parenthesized expression `(e)` where `e` is a constant expression. | 294 * * A parenthesized expression `(e)` where `e` is a constant expression. |
275 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`,`e1 != e2
` where `e1` and `e2` are constant expressions that evaluate to a | 295 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`, |
| 296 * `e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a |
276 * numeric, string or boolean value or to `null`. | 297 * numeric, string or boolean value or to `null`. |
277 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where`e`,
`e1` and `e2` are constant expressions that evaluate to a boolean value or | 298 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where |
| 299 * `e`, `e1` and `e2` are constant expressions that evaluate to a boolean value
or |
278 * to `null`. | 300 * to `null`. |
279 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,`e1 | e2`, `e1
>> e2` or `e1 << e2`, where `e`, `e1` and `e2`are constant expressions that eva
luate to an integer value or to `null`. | 301 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`, |
280 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`,`e1 * e2`, `e1
/ e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`,`e1 >= e2`, `e1 <= e2` or `e1 % e2`, wh
ere `e`, `e1` and `e2`are constant expressions that evaluate to a numeric value
or to `null`. | 302 * `e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2` |
| 303 * are constant expressions that evaluate to an integer value or to `null`. |
| 304 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`, |
| 305 * `e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`, |
| 306 * `e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2` |
| 307 * are constant expressions that evaluate to a numeric value or to `null`. |
281 * | 308 * |
282 * </blockquote> | 309 * </blockquote> |
283 */ | 310 */ |
284 class ConstantVisitor extends GeneralizingASTVisitor<EvaluationResultImpl> { | 311 class ConstantVisitor extends GeneralizingASTVisitor<EvaluationResultImpl> { |
285 EvaluationResultImpl visitAdjacentStrings(AdjacentStrings node) { | 312 EvaluationResultImpl visitAdjacentStrings(AdjacentStrings node) { |
286 EvaluationResultImpl result = null; | 313 EvaluationResultImpl result = null; |
287 for (StringLiteral string in node.strings) { | 314 for (StringLiteral string in node.strings) { |
288 if (result == null) { | 315 if (result == null) { |
289 result = string.accept(this); | 316 result = string.accept(this); |
290 } else { | 317 } else { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 } else if (operatorType == TokenType.TILDE_SLASH) { | 369 } else if (operatorType == TokenType.TILDE_SLASH) { |
343 return leftResult.integerDivide(node, rightResult); | 370 return leftResult.integerDivide(node, rightResult); |
344 } | 371 } |
345 break; | 372 break; |
346 } | 373 } |
347 return error(node, null); | 374 return error(node, null); |
348 } | 375 } |
349 EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => node.value ?
ValidResult.RESULT_TRUE : ValidResult.RESULT_FALSE; | 376 EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => node.value ?
ValidResult.RESULT_TRUE : ValidResult.RESULT_FALSE; |
350 EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => new ValidResult
(node.value); | 377 EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => new ValidResult
(node.value); |
351 EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpressio
n node) { | 378 EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpressio
n node) { |
| 379 if (!node.isConst) { |
| 380 return error(node, null); |
| 381 } |
352 ConstructorElement constructor = node.element; | 382 ConstructorElement constructor = node.element; |
353 if (constructor != null && constructor.isConst) { | 383 if (constructor != null && constructor.isConst) { |
354 node.argumentList.accept(this); | 384 node.argumentList.accept(this); |
355 return ValidResult.RESULT_OBJECT; | 385 return ValidResult.RESULT_OBJECT; |
356 } | 386 } |
357 return error(node, null); | 387 return error(node, null); |
358 } | 388 } |
359 EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => new ValidResu
lt(node.value); | 389 EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => new ValidResu
lt(node.value); |
360 EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node
) { | 390 EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node
) { |
361 EvaluationResultImpl result = node.expression.accept(this); | 391 EvaluationResultImpl result = node.expression.accept(this); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 } | 436 } |
407 } | 437 } |
408 } | 438 } |
409 } | 439 } |
410 } | 440 } |
411 return error(node, null); | 441 return error(node, null); |
412 } | 442 } |
413 EvaluationResultImpl visitNode(ASTNode node) => error(node, null); | 443 EvaluationResultImpl visitNode(ASTNode node) => error(node, null); |
414 EvaluationResultImpl visitNullLiteral(NullLiteral node) => ValidResult.RESULT_
NULL; | 444 EvaluationResultImpl visitNullLiteral(NullLiteral node) => ValidResult.RESULT_
NULL; |
415 EvaluationResultImpl visitParenthesizedExpression(ParenthesizedExpression node
) => node.expression.accept(this); | 445 EvaluationResultImpl visitParenthesizedExpression(ParenthesizedExpression node
) => node.expression.accept(this); |
416 EvaluationResultImpl visitPrefixedIdentifier(PrefixedIdentifier node) => getCo
nstantValue(node, node.element); | 446 EvaluationResultImpl visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 447 SimpleIdentifier prefixNode = node.prefix; |
| 448 Element prefixElement = prefixNode.element; |
| 449 if (prefixElement is! PrefixElement) { |
| 450 EvaluationResultImpl prefixResult = prefixNode.accept(this); |
| 451 if (prefixResult is! ValidResult) { |
| 452 return error(node, null); |
| 453 } |
| 454 } |
| 455 return getConstantValue(node, node.element); |
| 456 } |
417 EvaluationResultImpl visitPrefixExpression(PrefixExpression node) { | 457 EvaluationResultImpl visitPrefixExpression(PrefixExpression node) { |
418 EvaluationResultImpl operand = node.operand.accept(this); | 458 EvaluationResultImpl operand = node.operand.accept(this); |
419 if (operand is ValidResult && ((operand as ValidResult)).isNull) { | 459 if (operand is ValidResult && ((operand as ValidResult)).isNull) { |
420 return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); | 460 return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION); |
421 } | 461 } |
422 while (true) { | 462 while (true) { |
423 if (node.operator.type == TokenType.BANG) { | 463 if (node.operator.type == TokenType.BANG) { |
424 return operand.logicalNot(node); | 464 return operand.logicalNot(node); |
425 } else if (node.operator.type == TokenType.TILDE) { | 465 } else if (node.operator.type == TokenType.TILDE) { |
426 return operand.bitNot(node); | 466 return operand.bitNot(node); |
(...skipping 14 matching lines...) Expand all Loading... |
441 result = element.accept(this); | 481 result = element.accept(this); |
442 } else { | 482 } else { |
443 result = result.concatenate(node, element.accept(this)); | 483 result = result.concatenate(node, element.accept(this)); |
444 } | 484 } |
445 } | 485 } |
446 return result; | 486 return result; |
447 } | 487 } |
448 | 488 |
449 /** | 489 /** |
450 * Return a result object representing an error associated with the given node
. | 490 * Return a result object representing an error associated with the given node
. |
| 491 * |
451 * @param node the AST node associated with the error | 492 * @param node the AST node associated with the error |
452 * @param code the error code indicating the nature of the error | 493 * @param code the error code indicating the nature of the error |
453 * @return a result object representing an error associated with the given nod
e | 494 * @return a result object representing an error associated with the given nod
e |
454 */ | 495 */ |
455 ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code); | 496 ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code); |
456 | 497 |
457 /** | 498 /** |
458 * Return the constant value of the static constant represented by the given e
lement. | 499 * Return the constant value of the static constant represented by the given e
lement. |
| 500 * |
459 * @param node the node to be used if an error needs to be reported | 501 * @param node the node to be used if an error needs to be reported |
460 * @param element the element whose value is to be returned | 502 * @param element the element whose value is to be returned |
461 * @return the constant value of the static constant | 503 * @return the constant value of the static constant |
462 */ | 504 */ |
463 EvaluationResultImpl getConstantValue(ASTNode node, Element element) { | 505 EvaluationResultImpl getConstantValue(ASTNode node, Element element) { |
464 if (element is PropertyAccessorElement) { | 506 if (element is PropertyAccessorElement) { |
465 element = ((element as PropertyAccessorElement)).variable; | 507 element = ((element as PropertyAccessorElement)).variable; |
466 } | 508 } |
467 if (element is VariableElementImpl) { | 509 if (element is VariableElementImpl) { |
468 EvaluationResultImpl value = ((element as VariableElementImpl)).evaluation
Result; | 510 EvaluationResultImpl value = ((element as VariableElementImpl)).evaluation
Result; |
469 if (value != null) { | 511 if (value != null) { |
470 return value; | 512 return value; |
471 } | 513 } |
472 } else if (element is ExecutableElement) { | 514 } else if (element is ExecutableElement) { |
473 return new ValidResult(element); | 515 if (((element as ExecutableElement)).isStatic) { |
| 516 return new ValidResult(element); |
| 517 } |
474 } else if (element is ClassElement) { | 518 } else if (element is ClassElement) { |
475 return ValidResult.RESULT_OBJECT; | 519 return ValidResult.RESULT_OBJECT; |
476 } | 520 } |
477 return error(node, null); | 521 return error(node, null); |
478 } | 522 } |
479 | 523 |
480 /** | 524 /** |
481 * Return the union of the errors encoded in the given results. | 525 * Return the union of the errors encoded in the given results. |
| 526 * |
482 * @param leftResult the first set of errors, or `null` if there was no previo
us collection | 527 * @param leftResult the first set of errors, or `null` if there was no previo
us collection |
483 * of errors | 528 * of errors |
484 * @param rightResult the errors to be added to the collection, or a valid res
ult if there are no | 529 * @param rightResult the errors to be added to the collection, or a valid res
ult if there are no |
485 * errors to be added | 530 * errors to be added |
486 * @return the union of the errors encoded in the given results | 531 * @return the union of the errors encoded in the given results |
487 */ | 532 */ |
488 ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) { | 533 ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) { |
489 if (rightResult is ErrorResult) { | 534 if (rightResult is ErrorResult) { |
490 if (leftResult != null) { | 535 if (leftResult != null) { |
491 return new ErrorResult.con2(leftResult, (rightResult as ErrorResult)); | 536 return new ErrorResult.con2(leftResult, (rightResult as ErrorResult)); |
492 } else { | 537 } else { |
493 return rightResult as ErrorResult; | 538 return rightResult as ErrorResult; |
494 } | 539 } |
495 } | 540 } |
496 return leftResult; | 541 return leftResult; |
497 } | 542 } |
498 } | 543 } |
499 /** | 544 /** |
500 * Instances of the class `DirectedGraph` implement a directed graph in which th
e nodes are | 545 * Instances of the class `DirectedGraph` implement a directed graph in which th
e nodes are |
501 * arbitrary (client provided) objects and edges are represented implicitly. The
graph will allow an | 546 * arbitrary (client provided) objects and edges are represented implicitly. The
graph will allow an |
502 * edge from any node to any other node, including itself, but will not represen
t multiple edges | 547 * edge from any node to any other node, including itself, but will not represen
t multiple edges |
503 * between the same pair of nodes. | 548 * between the same pair of nodes. |
| 549 * |
504 * @param N the type of the nodes in the graph | 550 * @param N the type of the nodes in the graph |
505 */ | 551 */ |
506 class DirectedGraph<N> { | 552 class DirectedGraph<N> { |
507 | 553 |
508 /** | 554 /** |
509 * The table encoding the edges in the graph. An edge is represented by an ent
ry mapping the head | 555 * The table encoding the edges in the graph. An edge is represented by an ent
ry mapping the head |
510 * to a set of tails. Nodes that are not the head of any edge are represented
by an entry mapping | 556 * to a set of tails. Nodes that are not the head of any edge are represented
by an entry mapping |
511 * the node to an empty set of tails. | 557 * the node to an empty set of tails. |
512 */ | 558 */ |
513 Map<N, Set<N>> _edges = new Map<N, Set<N>>(); | 559 Map<N, Set<N>> _edges = new Map<N, Set<N>>(); |
514 | 560 |
515 /** | 561 /** |
516 * Add an edge from the given head node to the given tail node. Both nodes wil
l be a part of the | 562 * Add an edge from the given head node to the given tail node. Both nodes wil
l be a part of the |
517 * graph after this method is invoked, whether or not they were before. | 563 * graph after this method is invoked, whether or not they were before. |
| 564 * |
518 * @param head the node at the head of the edge | 565 * @param head the node at the head of the edge |
519 * @param tail the node at the tail of the edge | 566 * @param tail the node at the tail of the edge |
520 */ | 567 */ |
521 void addEdge(N head, N tail) { | 568 void addEdge(N head, N tail) { |
522 Set<N> tails = _edges[tail]; | 569 Set<N> tails = _edges[tail]; |
523 if (tails == null) { | 570 if (tails == null) { |
524 _edges[tail] = new Set<N>(); | 571 _edges[tail] = new Set<N>(); |
525 } | 572 } |
526 tails = _edges[head]; | 573 tails = _edges[head]; |
527 if (tails == null) { | 574 if (tails == null) { |
528 tails = new Set<N>(); | 575 tails = new Set<N>(); |
529 _edges[head] = tails; | 576 _edges[head] = tails; |
530 } | 577 } |
531 javaSetAdd(tails, tail); | 578 javaSetAdd(tails, tail); |
532 } | 579 } |
533 | 580 |
534 /** | 581 /** |
535 * Add the given node to the set of nodes in the graph. | 582 * Add the given node to the set of nodes in the graph. |
| 583 * |
536 * @param node the node to be added | 584 * @param node the node to be added |
537 */ | 585 */ |
538 void addNode(N node) { | 586 void addNode(N node) { |
539 Set<N> tails = _edges[node]; | 587 Set<N> tails = _edges[node]; |
540 if (tails == null) { | 588 if (tails == null) { |
541 _edges[node] = new Set<N>(); | 589 _edges[node] = new Set<N>(); |
542 } | 590 } |
543 } | 591 } |
544 | 592 |
545 /** | 593 /** |
546 * Return a list of nodes that form a cycle, or `null` if there are no cycles
in this graph. | 594 * Return a list of nodes that form a cycle, or `null` if there are no cycles
in this graph. |
| 595 * |
547 * @return a list of nodes that form a cycle | 596 * @return a list of nodes that form a cycle |
548 */ | 597 */ |
549 List<N> findCycle() => null; | 598 List<N> findCycle() => null; |
550 | 599 |
551 /** | 600 /** |
552 * Return the number of nodes in this graph. | 601 * Return the number of nodes in this graph. |
| 602 * |
553 * @return the number of nodes in this graph | 603 * @return the number of nodes in this graph |
554 */ | 604 */ |
555 int get nodeCount => _edges.length; | 605 int get nodeCount => _edges.length; |
556 | 606 |
557 /** | 607 /** |
558 * Return a set containing the tails of edges that have the given node as thei
r head. The set will | 608 * Return a set containing the tails of edges that have the given node as thei
r head. The set will |
559 * be empty if there are no such edges or if the node is not part of the graph
. Clients must not | 609 * be empty if there are no such edges or if the node is not part of the graph
. Clients must not |
560 * modify the returned set. | 610 * modify the returned set. |
| 611 * |
561 * @param head the node at the head of all of the edges whose tails are to be
returned | 612 * @param head the node at the head of all of the edges whose tails are to be
returned |
562 * @return a set containing the tails of edges that have the given node as the
ir head | 613 * @return a set containing the tails of edges that have the given node as the
ir head |
563 */ | 614 */ |
564 Set<N> getTails(N head) { | 615 Set<N> getTails(N head) { |
565 Set<N> tails = _edges[head]; | 616 Set<N> tails = _edges[head]; |
566 if (tails == null) { | 617 if (tails == null) { |
567 return new Set<N>(); | 618 return new Set<N>(); |
568 } | 619 } |
569 return tails; | 620 return tails; |
570 } | 621 } |
571 | 622 |
572 /** | 623 /** |
573 * Return `true` if this graph is empty. | 624 * Return `true` if this graph is empty. |
| 625 * |
574 * @return `true` if this graph is empty | 626 * @return `true` if this graph is empty |
575 */ | 627 */ |
576 bool get isEmpty => _edges.isEmpty; | 628 bool get isEmpty => _edges.isEmpty; |
577 | 629 |
578 /** | 630 /** |
579 * Remove all of the given nodes from this graph. As a consequence, any edges
for which those | 631 * Remove all of the given nodes from this graph. As a consequence, any edges
for which those |
580 * nodes were either a head or a tail will also be removed. | 632 * nodes were either a head or a tail will also be removed. |
| 633 * |
581 * @param nodes the nodes to be removed | 634 * @param nodes the nodes to be removed |
582 */ | 635 */ |
583 void removeAllNodes(List<N> nodes) { | 636 void removeAllNodes(List<N> nodes) { |
584 for (N node in nodes) { | 637 for (N node in nodes) { |
585 removeNode(node); | 638 removeNode(node); |
586 } | 639 } |
587 } | 640 } |
588 | 641 |
589 /** | 642 /** |
590 * Remove the edge from the given head node to the given tail node. If there w
as no such edge then | 643 * Remove the edge from the given head node to the given tail node. If there w
as no such edge then |
591 * the graph will be unmodified: the number of edges will be the same and the
set of nodes will be | 644 * the graph will be unmodified: the number of edges will be the same and the
set of nodes will be |
592 * the same (neither node will either be added or removed). | 645 * the same (neither node will either be added or removed). |
| 646 * |
593 * @param head the node at the head of the edge | 647 * @param head the node at the head of the edge |
594 * @param tail the node at the tail of the edge | 648 * @param tail the node at the tail of the edge |
595 * @return `true` if the graph was modified as a result of this operation | 649 * @return `true` if the graph was modified as a result of this operation |
596 */ | 650 */ |
597 void removeEdge(N head, N tail) { | 651 void removeEdge(N head, N tail) { |
598 Set<N> tails = _edges[head]; | 652 Set<N> tails = _edges[head]; |
599 if (tails != null) { | 653 if (tails != null) { |
600 tails.remove(tail); | 654 tails.remove(tail); |
601 } | 655 } |
602 } | 656 } |
603 | 657 |
604 /** | 658 /** |
605 * Remove the given node from this graph. As a consequence, any edges for whic
h that node was | 659 * Remove the given node from this graph. As a consequence, any edges for whic
h that node was |
606 * either a head or a tail will also be removed. | 660 * either a head or a tail will also be removed. |
| 661 * |
607 * @param node the node to be removed | 662 * @param node the node to be removed |
608 */ | 663 */ |
609 void removeNode(N node) { | 664 void removeNode(N node) { |
610 _edges.remove(node); | 665 _edges.remove(node); |
611 for (Set<N> tails in _edges.values) { | 666 for (Set<N> tails in _edges.values) { |
612 tails.remove(node); | 667 tails.remove(node); |
613 } | 668 } |
614 } | 669 } |
615 | 670 |
616 /** | 671 /** |
617 * Find one node (referred to as a sink node) that has no outgoing edges (that
is, for which there | 672 * Find one node (referred to as a sink node) that has no outgoing edges (that
is, for which there |
618 * are no edges that have that node as the head of the edge) and remove it fro
m this graph. Return | 673 * are no edges that have that node as the head of the edge) and remove it fro
m this graph. Return |
619 * the node that was removed, or `null` if there are no such nodes either beca
use the graph | 674 * the node that was removed, or `null` if there are no such nodes either beca
use the graph |
620 * is empty or because every node in the graph has at least one outgoing edge.
As a consequence of | 675 * is empty or because every node in the graph has at least one outgoing edge.
As a consequence of |
621 * removing the node from the graph any edges for which that node was a tail w
ill also be removed. | 676 * removing the node from the graph any edges for which that node was a tail w
ill also be removed. |
| 677 * |
622 * @return the sink node that was removed | 678 * @return the sink node that was removed |
623 */ | 679 */ |
624 N removeSink() { | 680 N removeSink() { |
625 N sink = findSink(); | 681 N sink = findSink(); |
626 if (sink == null) { | 682 if (sink == null) { |
627 return null; | 683 return null; |
628 } | 684 } |
629 removeNode(sink); | 685 removeNode(sink); |
630 return sink; | 686 return sink; |
631 } | 687 } |
632 | 688 |
633 /** | 689 /** |
634 * Return one node that has no outgoing edges (that is, for which there are no
edges that have | 690 * Return one node that has no outgoing edges (that is, for which there are no
edges that have |
635 * that node as the head of the edge), or `null` if there are no such nodes. | 691 * that node as the head of the edge), or `null` if there are no such nodes. |
| 692 * |
636 * @return a sink node | 693 * @return a sink node |
637 */ | 694 */ |
638 N findSink() { | 695 N findSink() { |
639 for (N key in _edges.keys) { | 696 for (N key in _edges.keys) { |
640 if (_edges[key].isEmpty) return key; | 697 if (_edges[key].isEmpty) return key; |
641 } | 698 } |
642 return null; | 699 return null; |
643 } | 700 } |
644 } | 701 } |
645 /** | 702 /** |
646 * Instances of the class `ErrorResult` represent the result of evaluating an ex
pression that | 703 * Instances of the class `ErrorResult` represent the result of evaluating an ex
pression that |
647 * is not a valid compile time constant. | 704 * is not a valid compile time constant. |
648 */ | 705 */ |
649 class ErrorResult extends EvaluationResultImpl { | 706 class ErrorResult extends EvaluationResultImpl { |
650 | 707 |
651 /** | 708 /** |
652 * The errors that prevent the expression from being a valid compile time cons
tant. | 709 * The errors that prevent the expression from being a valid compile time cons
tant. |
653 */ | 710 */ |
654 List<ErrorResult_ErrorData> _errors = new List<ErrorResult_ErrorData>(); | 711 List<ErrorResult_ErrorData> _errors = new List<ErrorResult_ErrorData>(); |
655 | 712 |
656 /** | 713 /** |
657 * Initialize a newly created result representing the error with the given cod
e reported against | 714 * Initialize a newly created result representing the error with the given cod
e reported against |
658 * the given node. | 715 * the given node. |
| 716 * |
659 * @param node the node against which the error should be reported | 717 * @param node the node against which the error should be reported |
660 * @param errorCode the error code for the error to be generated | 718 * @param errorCode the error code for the error to be generated |
661 */ | 719 */ |
662 ErrorResult.con1(ASTNode node, ErrorCode errorCode) { | 720 ErrorResult.con1(ASTNode node, ErrorCode errorCode) { |
663 _jtd_constructor_172_impl(node, errorCode); | 721 _jtd_constructor_172_impl(node, errorCode); |
664 } | 722 } |
665 _jtd_constructor_172_impl(ASTNode node, ErrorCode errorCode) { | 723 _jtd_constructor_172_impl(ASTNode node, ErrorCode errorCode) { |
666 _errors.add(new ErrorResult_ErrorData(node, errorCode)); | 724 _errors.add(new ErrorResult_ErrorData(node, errorCode)); |
667 } | 725 } |
668 | 726 |
669 /** | 727 /** |
670 * Initialize a newly created result to represent the union of the errors in t
he given result | 728 * Initialize a newly created result to represent the union of the errors in t
he given result |
671 * objects. | 729 * objects. |
| 730 * |
672 * @param firstResult the first set of results being merged | 731 * @param firstResult the first set of results being merged |
673 * @param secondResult the second set of results being merged | 732 * @param secondResult the second set of results being merged |
674 */ | 733 */ |
675 ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) { | 734 ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) { |
676 _jtd_constructor_173_impl(firstResult, secondResult); | 735 _jtd_constructor_173_impl(firstResult, secondResult); |
677 } | 736 } |
678 _jtd_constructor_173_impl(ErrorResult firstResult, ErrorResult secondResult) { | 737 _jtd_constructor_173_impl(ErrorResult firstResult, ErrorResult secondResult) { |
679 _errors.addAll(firstResult._errors); | 738 _errors.addAll(firstResult._errors); |
680 _errors.addAll(secondResult._errors); | 739 _errors.addAll(secondResult._errors); |
681 } | 740 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 ASTNode _node; | 813 ASTNode _node; |
755 | 814 |
756 /** | 815 /** |
757 * The error code for the error to be generated. | 816 * The error code for the error to be generated. |
758 */ | 817 */ |
759 ErrorCode _errorCode; | 818 ErrorCode _errorCode; |
760 | 819 |
761 /** | 820 /** |
762 * Initialize a newly created data holder to represent the error with the give
n code reported | 821 * Initialize a newly created data holder to represent the error with the give
n code reported |
763 * against the given node. | 822 * against the given node. |
| 823 * |
764 * @param node the node against which the error should be reported | 824 * @param node the node against which the error should be reported |
765 * @param errorCode the error code for the error to be generated | 825 * @param errorCode the error code for the error to be generated |
766 */ | 826 */ |
767 ErrorResult_ErrorData(ASTNode node, ErrorCode errorCode) { | 827 ErrorResult_ErrorData(ASTNode node, ErrorCode errorCode) { |
768 this._node = node; | 828 this._node = node; |
769 this._errorCode = errorCode; | 829 this._errorCode = errorCode; |
770 } | 830 } |
771 | 831 |
772 /** | 832 /** |
773 * Return the error code for the error to be generated. | 833 * Return the error code for the error to be generated. |
| 834 * |
774 * @return the error code for the error to be generated | 835 * @return the error code for the error to be generated |
775 */ | 836 */ |
776 ErrorCode get errorCode => _errorCode; | 837 ErrorCode get errorCode => _errorCode; |
777 | 838 |
778 /** | 839 /** |
779 * Return the node against which the error should be reported. | 840 * Return the node against which the error should be reported. |
| 841 * |
780 * @return the node against which the error should be reported | 842 * @return the node against which the error should be reported |
781 */ | 843 */ |
782 ASTNode get node => _node; | 844 ASTNode get node => _node; |
783 } | 845 } |
784 /** | 846 /** |
785 * Instances of the class `InternalResult` represent the result of attempting to
evaluate a | 847 * Instances of the class `InternalResult` represent the result of attempting to
evaluate a |
786 * expression. | 848 * expression. |
787 */ | 849 */ |
788 abstract class EvaluationResultImpl { | 850 abstract class EvaluationResultImpl { |
789 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and); | 851 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
865 | 927 |
866 /** | 928 /** |
867 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to | 929 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to |
868 * the other constant variables that are referenced in the head's initializer. | 930 * the other constant variables that are referenced in the head's initializer. |
869 */ | 931 */ |
870 DirectedGraph<VariableElement> _referenceGraph; | 932 DirectedGraph<VariableElement> _referenceGraph; |
871 | 933 |
872 /** | 934 /** |
873 * Initialize a newly created reference finder to find references from the giv
en variable to other | 935 * Initialize a newly created reference finder to find references from the giv
en variable to other |
874 * variables and to add those references to the given graph. | 936 * variables and to add those references to the given graph. |
| 937 * |
875 * @param source the element representing the variable whose initializer will
be visited | 938 * @param source the element representing the variable whose initializer will
be visited |
876 * @param referenceGraph a graph recording which variables (heads) reference w
hich other variables | 939 * @param referenceGraph a graph recording which variables (heads) reference w
hich other variables |
877 * (tails) in their initializers | 940 * (tails) in their initializers |
878 */ | 941 */ |
879 ReferenceFinder(VariableElement source, DirectedGraph<VariableElement> referen
ceGraph) { | 942 ReferenceFinder(VariableElement source, DirectedGraph<VariableElement> referen
ceGraph) { |
880 this._source = source; | 943 this._source = source; |
881 this._referenceGraph = referenceGraph; | 944 this._referenceGraph = referenceGraph; |
882 } | 945 } |
883 Object visitSimpleIdentifier(SimpleIdentifier node) { | 946 Object visitSimpleIdentifier(SimpleIdentifier node) { |
884 Element element = node.element; | 947 Element element = node.element; |
885 if (element is PropertyAccessorElement) { | 948 if (element is PropertyAccessorElement) { |
886 element = ((element as PropertyAccessorElement)).variable; | 949 element = ((element as PropertyAccessorElement)).variable; |
887 } | 950 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 */ | 1014 */ |
952 static ValidResult RESULT_TRUE = new ValidResult(true); | 1015 static ValidResult RESULT_TRUE = new ValidResult(true); |
953 | 1016 |
954 /** | 1017 /** |
955 * The value of the expression. | 1018 * The value of the expression. |
956 */ | 1019 */ |
957 Object _value; | 1020 Object _value; |
958 | 1021 |
959 /** | 1022 /** |
960 * Initialize a newly created result to represent the given value. | 1023 * Initialize a newly created result to represent the given value. |
| 1024 * |
961 * @param value the value of the expression | 1025 * @param value the value of the expression |
962 */ | 1026 */ |
963 ValidResult(Object value) { | 1027 ValidResult(Object value) { |
964 this._value = value; | 1028 this._value = value; |
965 } | 1029 } |
966 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and) => rightOperand.addToValid(node, this); | 1030 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and) => rightOperand.addToValid(node, this); |
967 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitAndValid(node, this); | 1031 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitAndValid(node, this); |
968 EvaluationResultImpl bitNot(Expression node) { | 1032 EvaluationResultImpl bitNot(Expression node) { |
969 if (isSomeInt) { | 1033 if (isSomeInt) { |
970 return RESULT_INT; | 1034 return RESULT_INT; |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); | 1349 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM); |
1286 } | 1350 } |
1287 Object leftValue = leftOperand2.value; | 1351 Object leftValue = leftOperand2.value; |
1288 if (leftValue == null) { | 1352 if (leftValue == null) { |
1289 return error(node.leftOperand); | 1353 return error(node.leftOperand); |
1290 } else if (_value == null) { | 1354 } else if (_value == null) { |
1291 return error(node.rightOperand); | 1355 return error(node.rightOperand); |
1292 } else if (leftValue is int) { | 1356 } else if (leftValue is int) { |
1293 if (_value is int) { | 1357 if (_value is int) { |
1294 if (((_value as int)) == 0) { | 1358 if (((_value as int)) == 0) { |
1295 return valueOf3(((leftValue as int)).toDouble() / ((_value as int)).to
Double()); | 1359 return error2(node, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE); |
1296 } | 1360 } |
1297 return valueOf(((leftValue as int)) ~/ (_value as int)); | 1361 return valueOf(((leftValue as int)) ~/ (_value as int)); |
1298 } else if (_value is double) { | 1362 } else if (_value is double) { |
1299 double result = ((leftValue as int)).toDouble() / ((_value as double)); | 1363 double result = ((leftValue as int)).toDouble() / ((_value as double)); |
1300 return valueOf(result.toInt()); | 1364 return valueOf(result.toInt()); |
1301 } | 1365 } |
1302 } else if (leftValue is double) { | 1366 } else if (leftValue is double) { |
1303 if (_value is int) { | 1367 if (_value is int) { |
1304 double result = ((leftValue as double)) / ((_value as int)).toDouble(); | 1368 double result = ((leftValue as double)) / ((_value as int)).toDouble(); |
1305 return valueOf(result.toInt()); | 1369 return valueOf(result.toInt()); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1378 if (leftValue is bool) { | 1442 if (leftValue is bool) { |
1379 if (((leftValue as bool))) { | 1443 if (((leftValue as bool))) { |
1380 return booleanConversion(node.rightOperand, _value); | 1444 return booleanConversion(node.rightOperand, _value); |
1381 } | 1445 } |
1382 return RESULT_FALSE; | 1446 return RESULT_FALSE; |
1383 } | 1447 } |
1384 return error(node); | 1448 return error(node); |
1385 } | 1449 } |
1386 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe
rand) => leftOperand; | 1450 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe
rand) => leftOperand; |
1387 EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOpe
rand) { | 1451 EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOpe
rand) { |
| 1452 if (!isAnyBool || !leftOperand.isAnyBool) { |
| 1453 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL); |
| 1454 } |
1388 if (isSomeBool || leftOperand.isSomeBool) { | 1455 if (isSomeBool || leftOperand.isSomeBool) { |
1389 if (isAnyBool && leftOperand.isAnyBool) { | 1456 return RESULT_BOOL; |
1390 return RESULT_BOOL; | |
1391 } | |
1392 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL); | |
1393 } | 1457 } |
1394 Object leftValue = leftOperand.value; | 1458 Object leftValue = leftOperand.value; |
1395 if (leftValue is bool && ((leftValue as bool))) { | 1459 if (leftValue is bool && ((leftValue as bool))) { |
1396 return RESULT_TRUE; | 1460 return RESULT_TRUE; |
1397 } | 1461 } |
1398 return booleanConversion(node.rightOperand, _value); | 1462 return booleanConversion(node.rightOperand, _value); |
1399 } | 1463 } |
1400 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand
) => leftOperand; | 1464 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand
) => leftOperand; |
1401 EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand
2) { | 1465 EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand
2) { |
1402 if (isSomeNum || leftOperand2.isSomeNum) { | 1466 if (isSomeNum || leftOperand2.isSomeNum) { |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1564 } else if (_value is double) { | 1628 } else if (_value is double) { |
1565 return valueOf3(((leftValue as double)) * ((_value as double))); | 1629 return valueOf3(((leftValue as double)) * ((_value as double))); |
1566 } | 1630 } |
1567 } | 1631 } |
1568 return error(node); | 1632 return error(node); |
1569 } | 1633 } |
1570 bool get isNull => identical(this, RESULT_NULL); | 1634 bool get isNull => identical(this, RESULT_NULL); |
1571 | 1635 |
1572 /** | 1636 /** |
1573 * Return the result of applying boolean conversion to the given value. | 1637 * Return the result of applying boolean conversion to the given value. |
| 1638 * |
1574 * @param node the node against which errors should be reported | 1639 * @param node the node against which errors should be reported |
1575 * @param value the value to be converted to a boolean | 1640 * @param value the value to be converted to a boolean |
1576 * @return the result of applying boolean conversion to the given value | 1641 * @return the result of applying boolean conversion to the given value |
1577 */ | 1642 */ |
1578 EvaluationResultImpl booleanConversion(ASTNode node, Object value) { | 1643 EvaluationResultImpl booleanConversion(ASTNode node, Object value) { |
1579 if (value is bool) { | 1644 if (value is bool) { |
1580 if (((value as bool))) { | 1645 if (((value as bool))) { |
1581 return RESULT_TRUE; | 1646 return RESULT_TRUE; |
1582 } else { | 1647 } else { |
1583 return RESULT_FALSE; | 1648 return RESULT_FALSE; |
1584 } | 1649 } |
1585 } | 1650 } |
1586 return error(node); | 1651 return error(node); |
1587 } | 1652 } |
1588 ErrorResult error(ASTNode node) => error2(node, CompileTimeErrorCode.INVALID_C
ONSTANT); | 1653 ErrorResult error(ASTNode node) => error2(node, CompileTimeErrorCode.INVALID_C
ONSTANT); |
1589 | 1654 |
1590 /** | 1655 /** |
1591 * Return a result object representing an error associated with the given node
. | 1656 * Return a result object representing an error associated with the given node
. |
| 1657 * |
1592 * @param node the AST node associated with the error | 1658 * @param node the AST node associated with the error |
1593 * @param code the error code indicating the nature of the error | 1659 * @param code the error code indicating the nature of the error |
1594 * @return a result object representing an error associated with the given nod
e | 1660 * @return a result object representing an error associated with the given nod
e |
1595 */ | 1661 */ |
1596 ErrorResult error2(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code); | 1662 ErrorResult error2(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code); |
1597 | 1663 |
1598 /** | 1664 /** |
1599 * Checks if this result has type "bool", with known or unknown value. | 1665 * Checks if this result has type "bool", with known or unknown value. |
1600 */ | 1666 */ |
1601 bool get isAnyBool => isSomeBool || identical(this, RESULT_TRUE) || identical(
this, RESULT_FALSE); | 1667 bool get isAnyBool => isSomeBool || identical(this, RESULT_TRUE) || identical(
this, RESULT_FALSE); |
(...skipping 24 matching lines...) Expand all Loading... |
1626 bool get isSomeInt => identical(this, RESULT_INT); | 1692 bool get isSomeInt => identical(this, RESULT_INT); |
1627 | 1693 |
1628 /** | 1694 /** |
1629 * Checks if this result has type "num" (or "int"), exact value of which we do
n't know. | 1695 * Checks if this result has type "num" (or "int"), exact value of which we do
n't know. |
1630 */ | 1696 */ |
1631 bool get isSomeNum => identical(this, RESULT_DYNAMIC) || identical(this, RESUL
T_INT) || identical(this, RESULT_NUM); | 1697 bool get isSomeNum => identical(this, RESULT_DYNAMIC) || identical(this, RESUL
T_INT) || identical(this, RESULT_NUM); |
1632 double toDouble(int value) => value.toDouble(); | 1698 double toDouble(int value) => value.toDouble(); |
1633 | 1699 |
1634 /** | 1700 /** |
1635 * Return an error result that is the union of the two given error results. | 1701 * Return an error result that is the union of the two given error results. |
| 1702 * |
1636 * @param firstError the first error to be combined | 1703 * @param firstError the first error to be combined |
1637 * @param secondError the second error to be combined | 1704 * @param secondError the second error to be combined |
1638 * @return an error result that is the union of the two given error results | 1705 * @return an error result that is the union of the two given error results |
1639 */ | 1706 */ |
1640 ErrorResult union(ErrorResult firstError, ErrorResult secondError) => new Erro
rResult.con2(firstError, secondError); | 1707 ErrorResult union(ErrorResult firstError, ErrorResult secondError) => new Erro
rResult.con2(firstError, secondError); |
1641 | 1708 |
1642 /** | 1709 /** |
1643 * Return a result object representing the given value. | 1710 * Return a result object representing the given value. |
| 1711 * |
1644 * @param value the value to be represented as a result object | 1712 * @param value the value to be represented as a result object |
1645 * @return a result object representing the given value | 1713 * @return a result object representing the given value |
1646 */ | 1714 */ |
1647 ValidResult valueOf(int value) => new ValidResult(value); | 1715 ValidResult valueOf(int value) => new ValidResult(value); |
1648 | 1716 |
1649 /** | 1717 /** |
1650 * Return a result object representing the given value. | 1718 * Return a result object representing the given value. |
| 1719 * |
1651 * @param value the value to be represented as a result object | 1720 * @param value the value to be represented as a result object |
1652 * @return a result object representing the given value | 1721 * @return a result object representing the given value |
1653 */ | 1722 */ |
1654 ValidResult valueOf2(bool value) => value ? RESULT_TRUE : RESULT_FALSE; | 1723 ValidResult valueOf2(bool value) => value ? RESULT_TRUE : RESULT_FALSE; |
1655 | 1724 |
1656 /** | 1725 /** |
1657 * Return a result object representing the given value. | 1726 * Return a result object representing the given value. |
| 1727 * |
1658 * @param value the value to be represented as a result object | 1728 * @param value the value to be represented as a result object |
1659 * @return a result object representing the given value | 1729 * @return a result object representing the given value |
1660 */ | 1730 */ |
1661 ValidResult valueOf3(double value) => new ValidResult(value); | 1731 ValidResult valueOf3(double value) => new ValidResult(value); |
1662 | 1732 |
1663 /** | 1733 /** |
1664 * Return a result object representing the given value. | 1734 * Return a result object representing the given value. |
| 1735 * |
1665 * @param value the value to be represented as a result object | 1736 * @param value the value to be represented as a result object |
1666 * @return a result object representing the given value | 1737 * @return a result object representing the given value |
1667 */ | 1738 */ |
1668 ValidResult valueOf4(String value) => new ValidResult(value); | 1739 ValidResult valueOf4(String value) => new ValidResult(value); |
1669 } | 1740 } |
OLD | NEW |