Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: pkg/analyzer_experimental/lib/src/generated/constant.dart

Issue 45573002: Rename analyzer_experimental to analyzer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Tweaks before publishing. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
3 library engine.constant;
4 import 'java_core.dart';
5 import 'source.dart' show Source;
6 import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode;
7 import 'scanner.dart' show TokenType;
8 import 'ast.dart';
9 import 'element.dart';
10 import 'engine.dart' show AnalysisEngine;
11 /**
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
14 * expression is one of the following:
15 *
16 * * A literal number.
17 * * A literal boolean.
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`.
20 * * `null`.
21 * * A reference to a static constant variable.
22 * * An identifier expression that denotes a constant variable, a class or a typ e parameter.
23 * * A constant constructor invocation.
24 * * A constant list literal.
25 * * A constant map literal.
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.
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
30 * numeric, string or boolean value or to `null`.
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
33 * to `null`.
34 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,
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`.
41 *
42 * </blockquote> The values returned by instances of this class are therefore `n ull` and
43 * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and
44 * `DartObject`.
45 *
46 * In addition, this class defines several values that can be returned to indica te various
47 * conditions encountered during evaluation. These are documented with the stati c field that define
48 * those values.
49 */
50 class ConstantEvaluator {
51
52 /**
53 * The source containing the expression(s) that will be evaluated.
54 */
55 Source _source;
56
57 /**
58 * Initialize a newly created evaluator to evaluate expressions in the given s ource.
59 *
60 * @param source the source containing the expression(s) that will be evaluate d
61 */
62 ConstantEvaluator(Source source) {
63 this._source = source;
64 }
65 EvaluationResult evaluate(Expression expression) {
66 EvaluationResultImpl result = expression.accept(new ConstantVisitor());
67 if (result is ValidResult) {
68 return EvaluationResult.forValue(((result as ValidResult)).value);
69 }
70 List<AnalysisError> errors = new List<AnalysisError>();
71 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) {
72 ASTNode node = data.node;
73 errors.add(new AnalysisError.con2(_source, node.offset, node.length, data. errorCode, []));
74 }
75 return EvaluationResult.forErrors(new List.from(errors));
76 }
77 }
78 /**
79 * Instances of the class `EvaluationResult` represent the result of attempting to evaluate an
80 * expression.
81 */
82 class EvaluationResult {
83
84 /**
85 * Return an evaluation result representing the result of evaluating an expres sion that is not a
86 * compile-time constant because of the given errors.
87 *
88 * @param errors the errors that should be reported for the expression(s) that were evaluated
89 * @return the result of evaluating an expression that is not a compile-time c onstant
90 */
91 static EvaluationResult forErrors(List<AnalysisError> errors) => new Evaluatio nResult(null, errors);
92
93 /**
94 * Return an evaluation result representing the result of evaluating an expres sion that is a
95 * compile-time constant that evaluates to the given value.
96 *
97 * @param value the value of the expression
98 * @return the result of evaluating an expression that is a compile-time const ant
99 */
100 static EvaluationResult forValue(Object value) => new EvaluationResult(value, null);
101
102 /**
103 * The value of the expression.
104 */
105 Object value;
106
107 /**
108 * The errors that should be reported for the expression(s) that were evaluate d.
109 */
110 List<AnalysisError> _errors;
111
112 /**
113 * Initialize a newly created result object with the given state. Clients shou ld use one of the
114 * factory methods: [forErrors] and [forValue].
115 *
116 * @param value the value of the expression
117 * @param errors the errors that should be reported for the expression(s) that were evaluated
118 */
119 EvaluationResult(Object value, List<AnalysisError> errors) {
120 this.value = value;
121 this._errors = errors;
122 }
123
124 /**
125 * Return an array containing the errors that should be reported for the expre ssion(s) that were
126 * evaluated. If there are no such errors, the array will be empty. The array can be empty even if
127 * the expression is not a valid compile time constant if the errors would hav e been reported by
128 * other parts of the analysis engine.
129 */
130 List<AnalysisError> get errors => _errors == null ? AnalysisError.NO_ERRORS : _errors;
131
132 /**
133 * Return `true` if the expression is a compile-time constant expression that would not
134 * throw an exception when evaluated.
135 *
136 * @return `true` if the expression is a valid compile-time constant expressio n
137 */
138 bool get isValid => _errors == null;
139 }
140 /**
141 * Instances of the class `ConstantFinder` are used to traverse the AST structur es of all of
142 * the compilation units being resolved and build a table mapping constant varia ble elements to the
143 * declarations of those variables.
144 */
145 class ConstantFinder extends RecursiveASTVisitor<Object> {
146
147 /**
148 * A table mapping constant variable elements to the declarations of those var iables.
149 */
150 final Map<VariableElement, VariableDeclaration> variableMap = new Map<Variable Element, VariableDeclaration>();
151 Object visitVariableDeclaration(VariableDeclaration node) {
152 super.visitVariableDeclaration(node);
153 Expression initializer = node.initializer;
154 if (initializer != null && node.isConst) {
155 VariableElement element = node.element;
156 if (element != null) {
157 variableMap[element] = node;
158 }
159 }
160 return null;
161 }
162 }
163 /**
164 * 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
166 * added to this computer using the method [add] and then for the method
167 * [computeValues] to invoked exactly once. Any use of an instance after invokin g the
168 * method [computeValues] will result in unpredictable behavior.
169 */
170 class ConstantValueComputer {
171
172 /**
173 * The object used to find constant variables in the compilation units that we re added.
174 */
175 ConstantFinder _constantFinder = new ConstantFinder();
176
177 /**
178 * A graph in which the nodes are the constant variables and the edges are fro m each variable to
179 * the other constant variables that are referenced in the head's initializer.
180 */
181 DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableEle ment>();
182
183 /**
184 * A table mapping constant variables to the declarations of those variables.
185 */
186 Map<VariableElement, VariableDeclaration> _declarationMap;
187
188 /**
189 * Add the constant variables in the given compilation unit to the list of con stant variables
190 * whose value needs to be computed.
191 *
192 * @param unit the compilation unit defining the constant variables to be adde d
193 */
194 void add(CompilationUnit unit) {
195 unit.accept(_constantFinder);
196 }
197
198 /**
199 * Compute values for all of the constant variables in the compilation units t hat were added.
200 */
201 void computeValues() {
202 _declarationMap = _constantFinder.variableMap;
203 for (MapEntry<VariableElement, VariableDeclaration> entry in getMapEntrySet( _declarationMap)) {
204 VariableElement element = entry.getKey();
205 ReferenceFinder referenceFinder = new ReferenceFinder(element, _referenceG raph);
206 _referenceGraph.addNode(element);
207 entry.getValue().initializer.accept(referenceFinder);
208 }
209 while (!_referenceGraph.isEmpty) {
210 VariableElement element = _referenceGraph.removeSink();
211 while (element != null) {
212 computeValueFor(element);
213 element = _referenceGraph.removeSink();
214 }
215 if (!_referenceGraph.isEmpty) {
216 List<VariableElement> variablesInCycle = _referenceGraph.findCycle();
217 if (variablesInCycle == null) {
218 AnalysisEngine.instance.logger.logError("Exiting constant value comput er with ${_referenceGraph.nodeCount} variables that are neither sinks no in a cy cle");
219 return;
220 }
221 for (VariableElement variable in variablesInCycle) {
222 generateCycleError(variablesInCycle, variable);
223 }
224 _referenceGraph.removeAllNodes(variablesInCycle);
225 }
226 }
227 }
228
229 /**
230 * Compute a value for the given variable.
231 *
232 * @param variable the variable for which a value is to be computed
233 */
234 void computeValueFor(VariableElement variable) {
235 VariableDeclaration declaration = _declarationMap[variable];
236 if (declaration == null) {
237 return;
238 }
239 EvaluationResultImpl result = declaration.initializer.accept(new ConstantVis itor());
240 ((variable as VariableElementImpl)).evaluationResult = result;
241 if (result is ErrorResult) {
242 List<AnalysisError> errors = new List<AnalysisError>();
243 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) {
244 ASTNode node = data.node;
245 Source source = variable.getAncestor(CompilationUnitElement).source;
246 errors.add(new AnalysisError.con2(source, node.offset, node.length, data .errorCode, []));
247 }
248 }
249 }
250
251 /**
252 * Generate an error indicating that the given variable is not a valid compile -time constant
253 * because it references at least one of the variables in the given cycle, eac h of which directly
254 * or indirectly references the variable.
255 *
256 * @param variablesInCycle the variables in the cycle that includes the given variable
257 * @param variable the variable that is not a valid compile-time constant
258 */
259 void generateCycleError(List<VariableElement> variablesInCycle, VariableElemen t variable) {
260 }
261 }
262 /**
263 * Instances of the class `ConstantVisitor` evaluate constant expressions to pro duce their
264 * compile-time value. According to the Dart Language Specification: <blockquote > A constant
265 * expression is one of the following:
266 *
267 * * A literal number.
268 * * A literal boolean.
269 * * A literal string where any interpolated expression is a compile-time consta nt that evaluates
270 * to a numeric, string or boolean value or to `null`.
271 * * `null`.
272 * * A reference to a static constant variable.
273 * * An identifier expression that denotes a constant variable, a class or a typ e parameter.
274 * * A constant constructor invocation.
275 * * A constant list literal.
276 * * A constant map literal.
277 * * A simple or qualified identifier denoting a top-level function or a static method.
278 * * A parenthesized expression `(e)` where `e` is a constant expression.
279 * * An expression of one of the forms `identical(e1, e2)`, `e1 == e2`,
280 * `e1 != e2` where `e1` and `e2` are constant expressions that evaluate to a
281 * numeric, string or boolean value or to `null`.
282 * * An expression of one of the forms `!e`, `e1 && e2` or `e1 || e2`, where
283 * `e`, `e1` and `e2` are constant expressions that evaluate to a boolean value or
284 * to `null`.
285 * * An expression of one of the forms `~e`, `e1 ^ e2`, `e1 & e2`,
286 * `e1 | e2`, `e1 >> e2` or `e1 << e2`, where `e`, `e1` and `e2`
287 * are constant expressions that evaluate to an integer value or to `null`.
288 * * An expression of one of the forms `-e`, `e1 + e2`, `e1 - e2`,
289 * `e1 * e2`, `e1 / e2`, `e1 ~/ e2`, `e1 > e2`, `e1 < e2`,
290 * `e1 >= e2`, `e1 <= e2` or `e1 % e2`, where `e`, `e1` and `e2`
291 * are constant expressions that evaluate to a numeric value or to `null`.
292 *
293 * </blockquote>
294 */
295 class ConstantVisitor extends UnifyingASTVisitor<EvaluationResultImpl> {
296 EvaluationResultImpl visitAdjacentStrings(AdjacentStrings node) {
297 EvaluationResultImpl result = null;
298 for (StringLiteral string in node.strings) {
299 if (result == null) {
300 result = string.accept(this);
301 } else {
302 result = result.concatenate(node, string.accept(this));
303 }
304 }
305 return result;
306 }
307 EvaluationResultImpl visitBinaryExpression(BinaryExpression node) {
308 EvaluationResultImpl leftResult = node.leftOperand.accept(this);
309 EvaluationResultImpl rightResult = node.rightOperand.accept(this);
310 TokenType operatorType = node.operator.type;
311 if (operatorType != TokenType.BANG_EQ && operatorType != TokenType.EQ_EQ) {
312 if (leftResult is ValidResult && ((leftResult as ValidResult)).isNull || r ightResult is ValidResult && ((rightResult as ValidResult)).isNull) {
313 return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
314 }
315 }
316 while (true) {
317 if (operatorType == TokenType.AMPERSAND) {
318 return leftResult.bitAnd(node, rightResult);
319 } else if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
320 return leftResult.logicalAnd(node, rightResult);
321 } else if (operatorType == TokenType.BANG_EQ) {
322 return leftResult.notEqual(node, rightResult);
323 } else if (operatorType == TokenType.BAR) {
324 return leftResult.bitOr(node, rightResult);
325 } else if (operatorType == TokenType.BAR_BAR) {
326 return leftResult.logicalOr(node, rightResult);
327 } else if (operatorType == TokenType.CARET) {
328 return leftResult.bitXor(node, rightResult);
329 } else if (operatorType == TokenType.EQ_EQ) {
330 return leftResult.equalEqual(node, rightResult);
331 } else if (operatorType == TokenType.GT) {
332 return leftResult.greaterThan(node, rightResult);
333 } else if (operatorType == TokenType.GT_EQ) {
334 return leftResult.greaterThanOrEqual(node, rightResult);
335 } else if (operatorType == TokenType.GT_GT) {
336 return leftResult.shiftRight(node, rightResult);
337 } else if (operatorType == TokenType.LT) {
338 return leftResult.lessThan(node, rightResult);
339 } else if (operatorType == TokenType.LT_EQ) {
340 return leftResult.lessThanOrEqual(node, rightResult);
341 } else if (operatorType == TokenType.LT_LT) {
342 return leftResult.shiftLeft(node, rightResult);
343 } else if (operatorType == TokenType.MINUS) {
344 return leftResult.minus(node, rightResult);
345 } else if (operatorType == TokenType.PERCENT) {
346 return leftResult.remainder(node, rightResult);
347 } else if (operatorType == TokenType.PLUS) {
348 return leftResult.add(node, rightResult);
349 } else if (operatorType == TokenType.STAR) {
350 return leftResult.times(node, rightResult);
351 } else if (operatorType == TokenType.SLASH) {
352 return leftResult.divide(node, rightResult);
353 } else if (operatorType == TokenType.TILDE_SLASH) {
354 return leftResult.integerDivide(node, rightResult);
355 }
356 break;
357 }
358 return error(node, null);
359 }
360 EvaluationResultImpl visitBooleanLiteral(BooleanLiteral node) => node.value ? ValidResult.RESULT_TRUE : ValidResult.RESULT_FALSE;
361 EvaluationResultImpl visitConditionalExpression(ConditionalExpression node) {
362 Expression condition = node.condition;
363 EvaluationResultImpl conditionResult = condition.accept(this);
364 conditionResult = conditionResult.applyBooleanConversion(condition);
365 if (conditionResult is ErrorResult) {
366 return conditionResult;
367 }
368 EvaluationResultImpl thenResult = node.thenExpression.accept(this);
369 if (thenResult is ErrorResult) {
370 return thenResult;
371 }
372 EvaluationResultImpl elseResult = node.elseExpression.accept(this);
373 if (elseResult is ErrorResult) {
374 return elseResult;
375 }
376 return (identical(conditionResult, ValidResult.RESULT_TRUE)) ? thenResult : elseResult;
377 }
378 EvaluationResultImpl visitDoubleLiteral(DoubleLiteral node) => new ValidResult (node.value);
379 EvaluationResultImpl visitInstanceCreationExpression(InstanceCreationExpressio n node) {
380 if (!node.isConst) {
381 return error(node, null);
382 }
383 ConstructorElement constructor = node.staticElement;
384 if (constructor != null && constructor.isConst) {
385 node.argumentList.accept(this);
386 return ValidResult.RESULT_OBJECT;
387 }
388 return error(node, null);
389 }
390 EvaluationResultImpl visitIntegerLiteral(IntegerLiteral node) => new ValidResu lt(node.value);
391 EvaluationResultImpl visitInterpolationExpression(InterpolationExpression node ) {
392 EvaluationResultImpl result = node.expression.accept(this);
393 return result.performToString(node);
394 }
395 EvaluationResultImpl visitInterpolationString(InterpolationString node) => new ValidResult(node.value);
396 EvaluationResultImpl visitListLiteral(ListLiteral node) {
397 if (node.constKeyword == null) {
398 return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_LI ST_LITERAL);
399 }
400 ErrorResult result = null;
401 for (Expression element in node.elements) {
402 result = union(result, element.accept(this));
403 }
404 if (result != null) {
405 return result;
406 }
407 return ValidResult.RESULT_OBJECT;
408 }
409 EvaluationResultImpl visitMapLiteral(MapLiteral node) {
410 if (node.constKeyword == null) {
411 return new ErrorResult.con1(node, CompileTimeErrorCode.MISSING_CONST_IN_MA P_LITERAL);
412 }
413 ErrorResult result = null;
414 for (MapLiteralEntry entry in node.entries) {
415 result = union(result, entry.key.accept(this));
416 result = union(result, entry.value.accept(this));
417 }
418 if (result != null) {
419 return result;
420 }
421 return ValidResult.RESULT_OBJECT;
422 }
423 EvaluationResultImpl visitMethodInvocation(MethodInvocation node) {
424 Element element = node.methodName.staticElement;
425 if (element is FunctionElement) {
426 FunctionElement function = element as FunctionElement;
427 if (function.name == "identical") {
428 NodeList<Expression> arguments = node.argumentList.arguments;
429 if (arguments.length == 2) {
430 Element enclosingElement = function.enclosingElement;
431 if (enclosingElement is CompilationUnitElement) {
432 LibraryElement library = ((enclosingElement as CompilationUnitElemen t)).library;
433 if (library.isDartCore) {
434 EvaluationResultImpl leftArgument = arguments[0].accept(this);
435 EvaluationResultImpl rightArgument = arguments[1].accept(this);
436 return leftArgument.equalEqual(node, rightArgument);
437 }
438 }
439 }
440 }
441 }
442 return error(node, null);
443 }
444 EvaluationResultImpl visitNamedExpression(NamedExpression node) => node.expres sion.accept(this);
445 EvaluationResultImpl visitNode(ASTNode node) => error(node, null);
446 EvaluationResultImpl visitNullLiteral(NullLiteral node) => ValidResult.RESULT_ NULL;
447 EvaluationResultImpl visitParenthesizedExpression(ParenthesizedExpression node ) => node.expression.accept(this);
448 EvaluationResultImpl visitPrefixedIdentifier(PrefixedIdentifier node) {
449 SimpleIdentifier prefixNode = node.prefix;
450 Element prefixElement = prefixNode.staticElement;
451 if (prefixElement is! PrefixElement) {
452 EvaluationResultImpl prefixResult = prefixNode.accept(this);
453 if (prefixResult is! ValidResult) {
454 return error(node, null);
455 }
456 }
457 return getConstantValue(node, node.staticElement);
458 }
459 EvaluationResultImpl visitPrefixExpression(PrefixExpression node) {
460 EvaluationResultImpl operand = node.operand.accept(this);
461 if (operand is ValidResult && ((operand as ValidResult)).isNull) {
462 return error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
463 }
464 while (true) {
465 if (node.operator.type == TokenType.BANG) {
466 return operand.logicalNot(node);
467 } else if (node.operator.type == TokenType.TILDE) {
468 return operand.bitNot(node);
469 } else if (node.operator.type == TokenType.MINUS) {
470 return operand.negated(node);
471 }
472 break;
473 }
474 return error(node, null);
475 }
476 EvaluationResultImpl visitPropertyAccess(PropertyAccess node) => getConstantVa lue(node, node.propertyName.staticElement);
477 EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) => getConsta ntValue(node, node.staticElement);
478 EvaluationResultImpl visitSimpleStringLiteral(SimpleStringLiteral node) => new ValidResult(node.value);
479 EvaluationResultImpl visitStringInterpolation(StringInterpolation node) {
480 EvaluationResultImpl result = null;
481 for (InterpolationElement element in node.elements) {
482 if (result == null) {
483 result = element.accept(this);
484 } else {
485 result = result.concatenate(node, element.accept(this));
486 }
487 }
488 return result;
489 }
490 EvaluationResultImpl visitSymbolLiteral(SymbolLiteral node) => ValidResult.RES ULT_SYMBOL;
491
492 /**
493 * Return a result object representing an error associated with the given node .
494 *
495 * @param node the AST node associated with the error
496 * @param code the error code indicating the nature of the error
497 * @return a result object representing an error associated with the given nod e
498 */
499 ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node, code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code);
500
501 /**
502 * Return the constant value of the static constant represented by the given e lement.
503 *
504 * @param node the node to be used if an error needs to be reported
505 * @param element the element whose value is to be returned
506 * @return the constant value of the static constant
507 */
508 EvaluationResultImpl getConstantValue(ASTNode node, Element element) {
509 if (element is PropertyAccessorElement) {
510 element = ((element as PropertyAccessorElement)).variable;
511 }
512 if (element is VariableElementImpl) {
513 VariableElementImpl variableElementImpl = element as VariableElementImpl;
514 EvaluationResultImpl value = variableElementImpl.evaluationResult;
515 if (variableElementImpl.isConst && value != null) {
516 return value;
517 }
518 } else if (element is ExecutableElement) {
519 if (((element as ExecutableElement)).isStatic) {
520 return new ValidResult(element);
521 }
522 } else if (element is ClassElement) {
523 return ValidResult.RESULT_OBJECT;
524 }
525 return error(node, null);
526 }
527
528 /**
529 * Return the union of the errors encoded in the given results.
530 *
531 * @param leftResult the first set of errors, or `null` if there was no previo us collection
532 * of errors
533 * @param rightResult the errors to be added to the collection, or a valid res ult if there are no
534 * errors to be added
535 * @return the union of the errors encoded in the given results
536 */
537 ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) {
538 if (rightResult is ErrorResult) {
539 if (leftResult != null) {
540 return new ErrorResult.con2(leftResult, rightResult as ErrorResult);
541 } else {
542 return rightResult as ErrorResult;
543 }
544 }
545 return leftResult;
546 }
547 }
548 /**
549 * Instances of the class `DirectedGraph` implement a directed graph in which th e nodes are
550 * arbitrary (client provided) objects and edges are represented implicitly. The graph will allow an
551 * edge from any node to any other node, including itself, but will not represen t multiple edges
552 * between the same pair of nodes.
553 *
554 * @param N the type of the nodes in the graph
555 */
556 class DirectedGraph<N> {
557
558 /**
559 * The table encoding the edges in the graph. An edge is represented by an ent ry mapping the head
560 * to a set of tails. Nodes that are not the head of any edge are represented by an entry mapping
561 * the node to an empty set of tails.
562 */
563 Map<N, Set<N>> _edges = new Map<N, Set<N>>();
564
565 /**
566 * Add an edge from the given head node to the given tail node. Both nodes wil l be a part of the
567 * graph after this method is invoked, whether or not they were before.
568 *
569 * @param head the node at the head of the edge
570 * @param tail the node at the tail of the edge
571 */
572 void addEdge(N head, N tail) {
573 Set<N> tails = _edges[tail];
574 if (tails == null) {
575 _edges[tail] = new Set<N>();
576 }
577 tails = _edges[head];
578 if (tails == null) {
579 tails = new Set<N>();
580 _edges[head] = tails;
581 }
582 javaSetAdd(tails, tail);
583 }
584
585 /**
586 * Add the given node to the set of nodes in the graph.
587 *
588 * @param node the node to be added
589 */
590 void addNode(N node) {
591 Set<N> tails = _edges[node];
592 if (tails == null) {
593 _edges[node] = new Set<N>();
594 }
595 }
596
597 /**
598 * Return a list of nodes that form a cycle, or `null` if there are no cycles in this graph.
599 *
600 * @return a list of nodes that form a cycle
601 */
602 List<N> findCycle() => null;
603
604 /**
605 * Return the number of nodes in this graph.
606 *
607 * @return the number of nodes in this graph
608 */
609 int get nodeCount => _edges.length;
610
611 /**
612 * Return a set containing the tails of edges that have the given node as thei r head. The set will
613 * be empty if there are no such edges or if the node is not part of the graph . Clients must not
614 * modify the returned set.
615 *
616 * @param head the node at the head of all of the edges whose tails are to be returned
617 * @return a set containing the tails of edges that have the given node as the ir head
618 */
619 Set<N> getTails(N head) {
620 Set<N> tails = _edges[head];
621 if (tails == null) {
622 return new Set<N>();
623 }
624 return tails;
625 }
626
627 /**
628 * Return `true` if this graph is empty.
629 *
630 * @return `true` if this graph is empty
631 */
632 bool get isEmpty => _edges.isEmpty;
633
634 /**
635 * Remove all of the given nodes from this graph. As a consequence, any edges for which those
636 * nodes were either a head or a tail will also be removed.
637 *
638 * @param nodes the nodes to be removed
639 */
640 void removeAllNodes(List<N> nodes) {
641 for (N node in nodes) {
642 removeNode(node);
643 }
644 }
645
646 /**
647 * Remove the edge from the given head node to the given tail node. If there w as no such edge then
648 * the graph will be unmodified: the number of edges will be the same and the set of nodes will be
649 * the same (neither node will either be added or removed).
650 *
651 * @param head the node at the head of the edge
652 * @param tail the node at the tail of the edge
653 * @return `true` if the graph was modified as a result of this operation
654 */
655 void removeEdge(N head, N tail) {
656 Set<N> tails = _edges[head];
657 if (tails != null) {
658 tails.remove(tail);
659 }
660 }
661
662 /**
663 * Remove the given node from this graph. As a consequence, any edges for whic h that node was
664 * either a head or a tail will also be removed.
665 *
666 * @param node the node to be removed
667 */
668 void removeNode(N node) {
669 _edges.remove(node);
670 for (Set<N> tails in _edges.values) {
671 tails.remove(node);
672 }
673 }
674
675 /**
676 * Find one node (referred to as a sink node) that has no outgoing edges (that is, for which there
677 * are no edges that have that node as the head of the edge) and remove it fro m this graph. Return
678 * the node that was removed, or `null` if there are no such nodes either beca use the graph
679 * is empty or because every node in the graph has at least one outgoing edge. As a consequence of
680 * removing the node from the graph any edges for which that node was a tail w ill also be removed.
681 *
682 * @return the sink node that was removed
683 */
684 N removeSink() {
685 N sink = findSink();
686 if (sink == null) {
687 return null;
688 }
689 removeNode(sink);
690 return sink;
691 }
692
693 /**
694 * Return one node that has no outgoing edges (that is, for which there are no edges that have
695 * that node as the head of the edge), or `null` if there are no such nodes.
696 *
697 * @return a sink node
698 */
699 N findSink() {
700 for (N key in _edges.keys) {
701 if (_edges[key].isEmpty) return key;
702 }
703 return null;
704 }
705 }
706 /**
707 * Instances of the class `ErrorResult` represent the result of evaluating an ex pression that
708 * is not a valid compile time constant.
709 */
710 class ErrorResult extends EvaluationResultImpl {
711
712 /**
713 * The errors that prevent the expression from being a valid compile time cons tant.
714 */
715 final List<ErrorResult_ErrorData> errorData = new List<ErrorResult_ErrorData>( );
716
717 /**
718 * Initialize a newly created result representing the error with the given cod e reported against
719 * the given node.
720 *
721 * @param node the node against which the error should be reported
722 * @param errorCode the error code for the error to be generated
723 */
724 ErrorResult.con1(ASTNode node, ErrorCode errorCode) {
725 errorData.add(new ErrorResult_ErrorData(node, errorCode));
726 }
727
728 /**
729 * Initialize a newly created result to represent the union of the errors in t he given result
730 * objects.
731 *
732 * @param firstResult the first set of results being merged
733 * @param secondResult the second set of results being merged
734 */
735 ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) {
736 errorData.addAll(firstResult.errorData);
737 errorData.addAll(secondResult.errorData);
738 }
739 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper and) => rightOperand.addToError(node, this);
740 EvaluationResultImpl applyBooleanConversion(ASTNode node) => this;
741 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO perand) => rightOperand.bitAndError(node, this);
742 EvaluationResultImpl bitNot(Expression node) => this;
743 EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOp erand) => rightOperand.bitOrError(node, this);
744 EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightO perand) => rightOperand.bitXorError(node, this);
745 EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOp erand) => rightOperand.concatenateError(node, this);
746 EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightO perand) => rightOperand.divideError(node, this);
747 EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOpe rand) => rightOperand.equalEqualError(node, this);
748 bool equalValues(EvaluationResultImpl result) => false;
749 EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl r ightOperand) => rightOperand.greaterThanError(node, this);
750 EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResul tImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this);
751 EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideError(node, this);
752 EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult lef tOperand) => this;
753 EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl righ tOperand) => rightOperand.lessThanError(node, this);
754 EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultIm pl rightOperand) => rightOperand.lessThanOrEqualError(node, this);
755 EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl ri ghtOperand) => rightOperand.logicalAndError(node, this);
756 EvaluationResultImpl logicalNot(Expression node) => this;
757 EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rig htOperand) => rightOperand.logicalOrError(node, this);
758 EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOp erand) => rightOperand.minusError(node, this);
759 EvaluationResultImpl negated(Expression node) => this;
760 EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl righ tOperand) => rightOperand.notEqualError(node, this);
761 EvaluationResultImpl performToString(ASTNode node) => this;
762 EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rig htOperand) => rightOperand.remainderError(node, this);
763 EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rig htOperand) => rightOperand.shiftLeftError(node, this);
764 EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl ri ghtOperand) => rightOperand.shiftRightError(node, this);
765 EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOp erand) => rightOperand.timesError(node, this);
766 EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand ) => new ErrorResult.con2(this, leftOperand);
767 EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand ) => this;
768 EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperan d) => new ErrorResult.con2(this, leftOperand);
769 EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperan d) => this;
770 EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand ) => new ErrorResult.con2(this, leftOperand);
771 EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand ) => this;
772 EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperan d) => new ErrorResult.con2(this, leftOperand);
773 EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperan d) => this;
774 EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand ) => new ErrorResult.con2(this, leftOperand);
775 EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand ) => this;
776 EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperan d) => new ErrorResult.con2(this, leftOperand);
777 EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperan d) => this;
778 EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => new ErrorResult.con2(this, leftOperand);
779 EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand) => this;
780 EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftO perand) => new ErrorResult.con2(this, leftOperand);
781 EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResul t leftOperand) => new ErrorResult.con2(this, leftOperand);
782 EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResul t leftOperand) => this;
783 EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftO perand) => this;
784 EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult lef tOperand) => new ErrorResult.con2(this, leftOperand);
785 EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOper and) => new ErrorResult.con2(this, leftOperand);
786 EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult l eftOperand) => new ErrorResult.con2(this, leftOperand);
787 EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult l eftOperand) => this;
788 EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOper and) => this;
789 EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOp erand) => new ErrorResult.con2(this, leftOperand);
790 EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOp erand) => this;
791 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe rand) => new ErrorResult.con2(this, leftOperand);
792 EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOpe rand) => this;
793 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand ) => new ErrorResult.con2(this, leftOperand);
794 EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand ) => this;
795 EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOper and) => new ErrorResult.con2(this, leftOperand);
796 EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOper and) => this;
797 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe rand) => new ErrorResult.con2(this, leftOperand);
798 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe rand) => this;
799 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe rand) => new ErrorResult.con2(this, leftOperand);
800 EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOpe rand) => this;
801 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp erand) => new ErrorResult.con2(this, leftOperand);
802 EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOp erand) => this;
803 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand ) => new ErrorResult.con2(this, leftOperand);
804 EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand ) => this;
805 }
806 class ErrorResult_ErrorData {
807
808 /**
809 * The node against which the error should be reported.
810 */
811 ASTNode node;
812
813 /**
814 * The error code for the error to be generated.
815 */
816 ErrorCode errorCode;
817
818 /**
819 * Initialize a newly created data holder to represent the error with the give n code reported
820 * against the given node.
821 *
822 * @param node the node against which the error should be reported
823 * @param errorCode the error code for the error to be generated
824 */
825 ErrorResult_ErrorData(ASTNode node, ErrorCode errorCode) {
826 this.node = node;
827 this.errorCode = errorCode;
828 }
829 }
830 /**
831 * Instances of the class `InternalResult` represent the result of attempting to evaluate a
832 * expression.
833 */
834 abstract class EvaluationResultImpl {
835 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper and);
836
837 /**
838 * Return the result of applying boolean conversion to this result.
839 *
840 * @param node the node against which errors should be reported
841 * @return the result of applying boolean conversion to the given value
842 */
843 EvaluationResultImpl applyBooleanConversion(ASTNode node);
844 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO perand);
845 EvaluationResultImpl bitNot(Expression node);
846 EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOp erand);
847 EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightO perand);
848 EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOp erand);
849 EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightO perand);
850 EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOpe rand);
851 bool equalValues(EvaluationResultImpl result);
852 EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl r ightOperand);
853 EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResul tImpl rightOperand);
854 EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand);
855 EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl righ tOperand);
856 EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultIm pl rightOperand);
857 EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl ri ghtOperand);
858 EvaluationResultImpl logicalNot(Expression node);
859 EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rig htOperand);
860 EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOp erand);
861 EvaluationResultImpl negated(Expression node);
862 EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl righ tOperand);
863 EvaluationResultImpl performToString(ASTNode node);
864 EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rig htOperand);
865 EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rig htOperand);
866 EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl ri ghtOperand);
867 EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOp erand);
868 EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand );
869 EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand );
870 EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperan d);
871 EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperan d);
872 EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand );
873 EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand );
874 EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperan d);
875 EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperan d);
876 EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand );
877 EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand );
878 EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperan d);
879 EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperan d);
880 EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) ;
881 EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand) ;
882 EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftO perand);
883 EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResul t leftOperand);
884 EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResul t leftOperand);
885 EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftO perand);
886 EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult lef tOperand);
887 EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult lef tOperand);
888 EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOper and);
889 EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult l eftOperand);
890 EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult l eftOperand);
891 EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOper and);
892 EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOp erand);
893 EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOp erand);
894 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe rand);
895 EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOpe rand);
896 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand );
897 EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand );
898 EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOper and);
899 EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOper and);
900 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe rand);
901 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe rand);
902 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe rand);
903 EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOpe rand);
904 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp erand);
905 EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOp erand);
906 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand );
907 EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand );
908 }
909 /**
910 * Instances of the class `ReferenceFinder` add reference information for a give n variable to
911 * the bi-directional mapping used to order the evaluation of constants.
912 */
913 class ReferenceFinder extends RecursiveASTVisitor<Object> {
914
915 /**
916 * The element representing the variable whose initializer will be visited.
917 */
918 VariableElement _source;
919
920 /**
921 * A graph in which the nodes are the constant variables and the edges are fro m each variable to
922 * the other constant variables that are referenced in the head's initializer.
923 */
924 DirectedGraph<VariableElement> _referenceGraph;
925
926 /**
927 * Initialize a newly created reference finder to find references from the giv en variable to other
928 * variables and to add those references to the given graph.
929 *
930 * @param source the element representing the variable whose initializer will be visited
931 * @param referenceGraph a graph recording which variables (heads) reference w hich other variables
932 * (tails) in their initializers
933 */
934 ReferenceFinder(VariableElement source, DirectedGraph<VariableElement> referen ceGraph) {
935 this._source = source;
936 this._referenceGraph = referenceGraph;
937 }
938 Object visitSimpleIdentifier(SimpleIdentifier node) {
939 Element element = node.staticElement;
940 if (element is PropertyAccessorElement) {
941 element = ((element as PropertyAccessorElement)).variable;
942 }
943 if (element is VariableElement) {
944 VariableElement variable = element as VariableElement;
945 if (variable.isConst) {
946 _referenceGraph.addEdge(_source, variable);
947 }
948 }
949 return null;
950 }
951 }
952 /**
953 * Instances of the class `ValidResult` represent the result of attempting to ev aluate a valid
954 * compile time constant expression.
955 */
956 class ValidResult extends EvaluationResultImpl {
957
958 /**
959 * A result object representing the value 'false'.
960 */
961 static ValidResult RESULT_FALSE = new ValidResult(false);
962
963 /**
964 * A result object representing the an object without specific type on which n o further operations
965 * can be performed.
966 */
967 static ValidResult RESULT_DYNAMIC = new ValidResult(null);
968
969 /**
970 * A result object representing the an arbitrary integer on which no further o perations can be
971 * performed.
972 */
973 static ValidResult RESULT_INT = new ValidResult(0);
974
975 /**
976 * A result object representing the `null` value.
977 */
978 static ValidResult RESULT_NULL = new ValidResult(null);
979
980 /**
981 * A result object representing the an arbitrary numeric on which no further o perations can be
982 * performed.
983 */
984 static ValidResult RESULT_NUM = new ValidResult(null);
985
986 /**
987 * A result object representing the an arbitrary boolean on which no further o perations can be
988 * performed.
989 */
990 static ValidResult RESULT_BOOL = new ValidResult(null);
991
992 /**
993 * A result object representing the an arbitrary object on which no further op erations can be
994 * performed.
995 */
996 static ValidResult RESULT_OBJECT = new ValidResult(new Object());
997
998 /**
999 * A result object representing the an arbitrary symbol on which no further op erations can be
1000 * performed.
1001 */
1002 static ValidResult RESULT_SYMBOL = new ValidResult(new Object());
1003
1004 /**
1005 * A result object representing the an arbitrary string on which no further op erations can be
1006 * performed.
1007 */
1008 static ValidResult RESULT_STRING = new ValidResult("<string>");
1009
1010 /**
1011 * A result object representing the value 'true'.
1012 */
1013 static ValidResult RESULT_TRUE = new ValidResult(true);
1014
1015 /**
1016 * The value of the expression.
1017 */
1018 Object value;
1019
1020 /**
1021 * Initialize a newly created result to represent the given value.
1022 *
1023 * @param value the value of the expression
1024 */
1025 ValidResult(Object value) {
1026 this.value = value;
1027 }
1028 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper and) => rightOperand.addToValid(node, this);
1029
1030 /**
1031 * Return the result of applying boolean conversion to this result.
1032 *
1033 * @param node the node against which errors should be reported
1034 * @return the result of applying boolean conversion to the given value
1035 */
1036 EvaluationResultImpl applyBooleanConversion(ASTNode node) => booleanConversion (node, value);
1037 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO perand) => rightOperand.bitAndValid(node, this);
1038 EvaluationResultImpl bitNot(Expression node) {
1039 if (isSomeInt) {
1040 return RESULT_INT;
1041 }
1042 if (value == null) {
1043 return error(node);
1044 } else if (value is int) {
1045 return valueOf(~((value as int)));
1046 }
1047 return error(node);
1048 }
1049 EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOp erand) => rightOperand.bitOrValid(node, this);
1050 EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightO perand) => rightOperand.bitXorValid(node, this);
1051 EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOp erand) => rightOperand.concatenateValid(node, this);
1052 EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightO perand) => rightOperand.divideValid(node, this);
1053 EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOpe rand) => rightOperand.equalEqualValid(node, this);
1054 bool equalValues(EvaluationResultImpl result) => identical(equalEqual(null, re sult), RESULT_TRUE);
1055 EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl r ightOperand) => rightOperand.greaterThanValid(node, this);
1056 EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResul tImpl rightOperand) => rightOperand.greaterThanOrEqualValid(node, this);
1057 EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl rightOperand) => rightOperand.integerDivideValid(node, this);
1058 EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl righ tOperand) => rightOperand.lessThanValid(node, this);
1059 EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultIm pl rightOperand) => rightOperand.lessThanOrEqualValid(node, this);
1060 EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl ri ghtOperand) => rightOperand.logicalAndValid(node, this);
1061 EvaluationResultImpl logicalNot(Expression node) {
1062 if (isSomeBool) {
1063 return RESULT_BOOL;
1064 }
1065 if (value == null) {
1066 return RESULT_TRUE;
1067 } else if (value is bool) {
1068 return ((value as bool)) ? RESULT_FALSE : RESULT_TRUE;
1069 }
1070 return error(node);
1071 }
1072 EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rig htOperand) => rightOperand.logicalOrValid(node, this);
1073 EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOp erand) => rightOperand.minusValid(node, this);
1074 EvaluationResultImpl negated(Expression node) {
1075 if (isSomeNum) {
1076 return RESULT_INT;
1077 }
1078 if (value == null) {
1079 return error(node);
1080 } else if (value is int) {
1081 return valueOf(-((value as int)));
1082 } else if (value is double) {
1083 return valueOf3(-((value as double)));
1084 }
1085 return error(node);
1086 }
1087 EvaluationResultImpl notEqual(BinaryExpression node, EvaluationResultImpl righ tOperand) => rightOperand.notEqualValid(node, this);
1088 EvaluationResultImpl performToString(ASTNode node) {
1089 if (value == null) {
1090 return valueOf4("null");
1091 } else if (value is bool) {
1092 return valueOf4(((value as bool)).toString());
1093 } else if (value is int) {
1094 return valueOf4(((value as int)).toString());
1095 } else if (value is double) {
1096 return valueOf4(((value as double)).toString());
1097 } else if (value is String) {
1098 return this;
1099 } else if (isSomeBool) {
1100 return valueOf4("<some bool>");
1101 } else if (isSomeInt) {
1102 return valueOf4("<some int>");
1103 } else if (isSomeNum) {
1104 return valueOf4("<some num>");
1105 }
1106 return error(node);
1107 }
1108 EvaluationResultImpl remainder(BinaryExpression node, EvaluationResultImpl rig htOperand) => rightOperand.remainderValid(node, this);
1109 EvaluationResultImpl shiftLeft(BinaryExpression node, EvaluationResultImpl rig htOperand) => rightOperand.shiftLeftValid(node, this);
1110 EvaluationResultImpl shiftRight(BinaryExpression node, EvaluationResultImpl ri ghtOperand) => rightOperand.shiftRightValid(node, this);
1111 EvaluationResultImpl times(BinaryExpression node, EvaluationResultImpl rightOp erand) => rightOperand.timesValid(node, this);
1112 String toString() {
1113 if (value == null) {
1114 return "null";
1115 }
1116 return value.toString();
1117 }
1118 EvaluationResultImpl addToError(BinaryExpression node, ErrorResult leftOperand ) => leftOperand;
1119 EvaluationResultImpl addToValid(BinaryExpression node, ValidResult leftOperand ) {
1120 if (!isAnyNum || !leftOperand.isAnyNum) {
1121 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
1122 }
1123 if (isSomeInt || leftOperand.isSomeInt) {
1124 return RESULT_INT;
1125 } else if (isSomeNum || leftOperand.isSomeNum) {
1126 return RESULT_NUM;
1127 }
1128 Object leftValue = leftOperand.value;
1129 if (leftValue == null) {
1130 return error(node.leftOperand);
1131 } else if (value == null) {
1132 return error(node.rightOperand);
1133 } else if (leftValue is int) {
1134 if (value is int) {
1135 return valueOf(((leftValue as int)) + (value as int));
1136 } else if (value is double) {
1137 return valueOf3(((leftValue as int)).toDouble() + ((value as double)));
1138 }
1139 } else if (leftValue is double) {
1140 if (value is int) {
1141 return valueOf3(((leftValue as double)) + ((value as int)).toDouble());
1142 } else if (value is double) {
1143 return valueOf3(((leftValue as double)) + ((value as double)));
1144 }
1145 } else if (leftValue is String) {
1146 if (value is String) {
1147 return valueOf4("${((leftValue as String))}${((value as String))}");
1148 }
1149 }
1150 return error(node);
1151 }
1152 EvaluationResultImpl bitAndError(BinaryExpression node, ErrorResult leftOperan d) => leftOperand;
1153 EvaluationResultImpl bitAndValid(BinaryExpression node, ValidResult leftOperan d) {
1154 if (!isAnyInt || !leftOperand.isAnyInt) {
1155 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
1156 }
1157 if (isSomeInt || leftOperand.isSomeInt) {
1158 return RESULT_INT;
1159 }
1160 Object leftValue = leftOperand.value;
1161 if (leftValue == null) {
1162 return error(node.leftOperand);
1163 } else if (value == null) {
1164 return error(node.rightOperand);
1165 } else if (leftValue is int) {
1166 if (value is int) {
1167 return valueOf(((leftValue as int)) & (value as int));
1168 }
1169 return error(node.leftOperand);
1170 }
1171 if (value is int) {
1172 return error(node.rightOperand);
1173 }
1174 return union(error(node.leftOperand), error(node.rightOperand));
1175 }
1176 EvaluationResultImpl bitOrError(BinaryExpression node, ErrorResult leftOperand ) => leftOperand;
1177 EvaluationResultImpl bitOrValid(BinaryExpression node, ValidResult leftOperand ) {
1178 if (!isAnyInt || !leftOperand.isAnyInt) {
1179 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
1180 }
1181 if (isSomeInt || leftOperand.isSomeInt) {
1182 return RESULT_INT;
1183 }
1184 Object leftValue = leftOperand.value;
1185 if (leftValue == null) {
1186 return error(node.leftOperand);
1187 } else if (value == null) {
1188 return error(node.rightOperand);
1189 } else if (leftValue is int) {
1190 if (value is int) {
1191 return valueOf(((leftValue as int)) | (value as int));
1192 }
1193 return error(node.leftOperand);
1194 }
1195 if (value is int) {
1196 return error(node.rightOperand);
1197 }
1198 return union(error(node.leftOperand), error(node.rightOperand));
1199 }
1200 EvaluationResultImpl bitXorError(BinaryExpression node, ErrorResult leftOperan d) => leftOperand;
1201 EvaluationResultImpl bitXorValid(BinaryExpression node, ValidResult leftOperan d) {
1202 if (!isAnyInt || !leftOperand.isAnyInt) {
1203 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
1204 }
1205 if (isSomeInt || leftOperand.isSomeInt) {
1206 return RESULT_INT;
1207 }
1208 Object leftValue = leftOperand.value;
1209 if (leftValue == null) {
1210 return error(node.leftOperand);
1211 } else if (value == null) {
1212 return error(node.rightOperand);
1213 } else if (leftValue is int) {
1214 if (value is int) {
1215 return valueOf(((leftValue as int)) ^ (value as int));
1216 }
1217 return error(node.leftOperand);
1218 }
1219 if (value is int) {
1220 return error(node.rightOperand);
1221 }
1222 return union(error(node.leftOperand), error(node.rightOperand));
1223 }
1224 EvaluationResultImpl concatenateError(Expression node, ErrorResult leftOperand ) => leftOperand;
1225 EvaluationResultImpl concatenateValid(Expression node, ValidResult leftOperand ) {
1226 Object leftValue = leftOperand.value;
1227 if (leftValue is String && value is String) {
1228 return valueOf4("${((leftValue as String))}${((value as String))}");
1229 }
1230 return error(node);
1231 }
1232 EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperan d) => leftOperand;
1233 EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperan d) {
1234 if (!isAnyNum || !leftOperand.isAnyNum) {
1235 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
1236 }
1237 if (isSomeNum || leftOperand.isSomeNum) {
1238 return RESULT_NUM;
1239 }
1240 Object leftValue = leftOperand.value;
1241 if (leftValue == null) {
1242 return error(node.leftOperand);
1243 } else if (value == null) {
1244 return error(node.rightOperand);
1245 } else if (leftValue is int) {
1246 if (value is int) {
1247 if (((value as int)) == 0) {
1248 return valueOf3(((leftValue as int)).toDouble() / ((value as int)).toD ouble());
1249 }
1250 return valueOf(((leftValue as int)) ~/ (value as int));
1251 } else if (value is double) {
1252 return valueOf3(((leftValue as int)).toDouble() / ((value as double)));
1253 }
1254 } else if (leftValue is double) {
1255 if (value is int) {
1256 return valueOf3(((leftValue as double)) / ((value as int)).toDouble());
1257 } else if (value is double) {
1258 return valueOf3(((leftValue as double)) / ((value as double)));
1259 }
1260 }
1261 return error(node);
1262 }
1263 EvaluationResultImpl equalEqualError(Expression node, ErrorResult leftOperand) => leftOperand;
1264 EvaluationResultImpl equalEqualValid(Expression node, ValidResult leftOperand) {
1265 if (node is BinaryExpression) {
1266 if (!isAnyNullBoolNumString || !leftOperand.isAnyNullBoolNumString) {
1267 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING );
1268 }
1269 }
1270 Object leftValue = leftOperand.value;
1271 if (leftValue == null) {
1272 return valueOf2(value == null);
1273 } else if (leftValue is bool) {
1274 if (value is bool) {
1275 return valueOf2(identical(leftValue as bool, value as bool));
1276 }
1277 return RESULT_FALSE;
1278 } else if (leftValue is int) {
1279 if (value is int) {
1280 return valueOf2(((leftValue as int)) == value);
1281 } else if (value is double) {
1282 return valueOf2(toDouble(leftValue as int) == value);
1283 }
1284 return RESULT_FALSE;
1285 } else if (leftValue is double) {
1286 if (value is int) {
1287 return valueOf2(((leftValue as double)) == toDouble(value as int));
1288 } else if (value is double) {
1289 return valueOf2(((leftValue as double)) == value);
1290 }
1291 return RESULT_FALSE;
1292 } else if (leftValue is String) {
1293 if (value is String) {
1294 return valueOf2(((leftValue as String)) == value);
1295 }
1296 return RESULT_FALSE;
1297 }
1298 return RESULT_FALSE;
1299 }
1300 EvaluationResultImpl greaterThanError(BinaryExpression node, ErrorResult leftO perand) => leftOperand;
1301 EvaluationResultImpl greaterThanOrEqualError(BinaryExpression node, ErrorResul t leftOperand) => leftOperand;
1302 EvaluationResultImpl greaterThanOrEqualValid(BinaryExpression node, ValidResul t leftOperand) {
1303 if (!isAnyNum || !leftOperand.isAnyNum) {
1304 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
1305 }
1306 if (isSomeNum || leftOperand.isSomeNum) {
1307 return RESULT_BOOL;
1308 }
1309 Object leftValue = leftOperand.value;
1310 if (leftValue == null) {
1311 return error(node.leftOperand);
1312 } else if (value == null) {
1313 return error(node.rightOperand);
1314 } else if (leftValue is int) {
1315 if (value is int) {
1316 return valueOf2(((leftValue as int)).compareTo(value as int) >= 0);
1317 } else if (value is double) {
1318 return valueOf2(((leftValue as int)).toDouble() >= ((value as double)));
1319 }
1320 } else if (leftValue is double) {
1321 if (value is int) {
1322 return valueOf2(((leftValue as double)) >= ((value as int)).toDouble());
1323 } else if (value is double) {
1324 return valueOf2(((leftValue as double)) >= ((value as double)));
1325 }
1326 }
1327 return error(node);
1328 }
1329 EvaluationResultImpl greaterThanValid(BinaryExpression node, ValidResult leftO perand) {
1330 if (!isAnyNum || !leftOperand.isAnyNum) {
1331 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
1332 }
1333 if (isSomeNum || leftOperand.isSomeNum) {
1334 return RESULT_BOOL;
1335 }
1336 Object leftValue = leftOperand.value;
1337 if (leftValue == null) {
1338 return error(node.leftOperand);
1339 } else if (value == null) {
1340 return error(node.rightOperand);
1341 } else if (leftValue is int) {
1342 if (value is int) {
1343 return valueOf2(((leftValue as int)).compareTo(value as int) > 0);
1344 } else if (value is double) {
1345 return valueOf2(((leftValue as int)).toDouble() > ((value as double)));
1346 }
1347 } else if (leftValue is double) {
1348 if (value is int) {
1349 return valueOf2(((leftValue as double)) > ((value as int)).toDouble());
1350 } else if (value is double) {
1351 return valueOf2(((leftValue as double)) > ((value as double)));
1352 }
1353 }
1354 return error(node);
1355 }
1356 EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult lef tOperand) => leftOperand;
1357 EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult lef tOperand) {
1358 if (!isAnyNum || !leftOperand.isAnyNum) {
1359 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
1360 }
1361 if (isSomeNum || leftOperand.isSomeNum) {
1362 return RESULT_INT;
1363 }
1364 Object leftValue = leftOperand.value;
1365 if (leftValue == null) {
1366 return error(node.leftOperand);
1367 } else if (value == null) {
1368 return error(node.rightOperand);
1369 } else if (leftValue is int) {
1370 if (value is int) {
1371 if (((value as int)) == 0) {
1372 return error2(node, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
1373 }
1374 return valueOf(((leftValue as int)) ~/ (value as int));
1375 } else if (value is double) {
1376 double result = ((leftValue as int)).toDouble() / ((value as double));
1377 return valueOf(result.toInt());
1378 }
1379 } else if (leftValue is double) {
1380 if (value is int) {
1381 double result = ((leftValue as double)) / ((value as int)).toDouble();
1382 return valueOf(result.toInt());
1383 } else if (value is double) {
1384 double result = ((leftValue as double)) / ((value as double));
1385 return valueOf(result.toInt());
1386 }
1387 }
1388 return error(node);
1389 }
1390 EvaluationResultImpl lessThanError(BinaryExpression node, ErrorResult leftOper and) => leftOperand;
1391 EvaluationResultImpl lessThanOrEqualError(BinaryExpression node, ErrorResult l eftOperand) => leftOperand;
1392 EvaluationResultImpl lessThanOrEqualValid(BinaryExpression node, ValidResult l eftOperand) {
1393 if (!isAnyNum || !leftOperand.isAnyNum) {
1394 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
1395 }
1396 if (isSomeNum || leftOperand.isSomeNum) {
1397 return RESULT_BOOL;
1398 }
1399 Object leftValue = leftOperand.value;
1400 if (leftValue == null) {
1401 return error(node.leftOperand);
1402 } else if (value == null) {
1403 return error(node.rightOperand);
1404 } else if (leftValue is int) {
1405 if (value is int) {
1406 return valueOf2(((leftValue as int)).compareTo(value as int) <= 0);
1407 } else if (value is double) {
1408 return valueOf2(((leftValue as int)).toDouble() <= ((value as double)));
1409 }
1410 } else if (leftValue is double) {
1411 if (value is int) {
1412 return valueOf2(((leftValue as double)) <= ((value as int)).toDouble());
1413 } else if (value is double) {
1414 return valueOf2(((leftValue as double)) <= ((value as double)));
1415 }
1416 }
1417 return error(node);
1418 }
1419 EvaluationResultImpl lessThanValid(BinaryExpression node, ValidResult leftOper and) {
1420 if (!isAnyNum || !leftOperand.isAnyNum) {
1421 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
1422 }
1423 if (isSomeNum || leftOperand.isSomeNum) {
1424 return RESULT_BOOL;
1425 }
1426 Object leftValue = leftOperand.value;
1427 if (leftValue == null) {
1428 return error(node.leftOperand);
1429 } else if (value == null) {
1430 return error(node.rightOperand);
1431 } else if (leftValue is int) {
1432 if (value is int) {
1433 return valueOf2(((leftValue as int)).compareTo(value as int) < 0);
1434 } else if (value is double) {
1435 return valueOf2(((leftValue as int)).toDouble() < ((value as double)));
1436 }
1437 } else if (leftValue is double) {
1438 if (value is int) {
1439 return valueOf2(((leftValue as double)) < ((value as int)).toDouble());
1440 } else if (value is double) {
1441 return valueOf2(((leftValue as double)) < ((value as double)));
1442 }
1443 }
1444 return error(node);
1445 }
1446 EvaluationResultImpl logicalAndError(BinaryExpression node, ErrorResult leftOp erand) => leftOperand;
1447 EvaluationResultImpl logicalAndValid(BinaryExpression node, ValidResult leftOp erand) {
1448 if (!isAnyBool || !leftOperand.isAnyBool) {
1449 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
1450 }
1451 if (isSomeBool || leftOperand.isSomeBool) {
1452 return RESULT_BOOL;
1453 }
1454 Object leftValue = leftOperand.value;
1455 if (leftValue is bool) {
1456 if (leftValue as bool) {
1457 return booleanConversion(node.rightOperand, value);
1458 }
1459 return RESULT_FALSE;
1460 }
1461 return error(node);
1462 }
1463 EvaluationResultImpl logicalOrError(BinaryExpression node, ErrorResult leftOpe rand) => leftOperand;
1464 EvaluationResultImpl logicalOrValid(BinaryExpression node, ValidResult leftOpe rand) {
1465 if (!isAnyBool || !leftOperand.isAnyBool) {
1466 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
1467 }
1468 if (isSomeBool || leftOperand.isSomeBool) {
1469 return RESULT_BOOL;
1470 }
1471 Object leftValue = leftOperand.value;
1472 if (leftValue is bool && ((leftValue as bool))) {
1473 return RESULT_TRUE;
1474 }
1475 return booleanConversion(node.rightOperand, value);
1476 }
1477 EvaluationResultImpl minusError(BinaryExpression node, ErrorResult leftOperand ) => leftOperand;
1478 EvaluationResultImpl minusValid(BinaryExpression node, ValidResult leftOperand ) {
1479 if (!isAnyNum || !leftOperand.isAnyNum) {
1480 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
1481 }
1482 if (isSomeInt || leftOperand.isSomeInt) {
1483 return RESULT_INT;
1484 } else if (isSomeNum || leftOperand.isSomeNum) {
1485 return RESULT_NUM;
1486 }
1487 Object leftValue = leftOperand.value;
1488 if (leftValue == null) {
1489 return error(node.leftOperand);
1490 } else if (value == null) {
1491 return error(node.rightOperand);
1492 } else if (leftValue is int) {
1493 if (value is int) {
1494 return valueOf(((leftValue as int)) - (value as int));
1495 } else if (value is double) {
1496 return valueOf3(((leftValue as int)).toDouble() - ((value as double)));
1497 }
1498 } else if (leftValue is double) {
1499 if (value is int) {
1500 return valueOf3(((leftValue as double)) - ((value as int)).toDouble());
1501 } else if (value is double) {
1502 return valueOf3(((leftValue as double)) - ((value as double)));
1503 }
1504 }
1505 return error(node);
1506 }
1507 EvaluationResultImpl notEqualError(BinaryExpression node, ErrorResult leftOper and) => leftOperand;
1508 EvaluationResultImpl notEqualValid(BinaryExpression node, ValidResult leftOper and) {
1509 if (!isAnyNullBoolNumString || !leftOperand.isAnyNullBoolNumString) {
1510 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
1511 }
1512 Object leftValue = leftOperand.value;
1513 if (leftValue == null) {
1514 return valueOf2(value != null);
1515 } else if (leftValue is bool) {
1516 if (value is bool) {
1517 return valueOf2(((leftValue as bool)) != ((value as bool)));
1518 }
1519 return RESULT_TRUE;
1520 } else if (leftValue is int) {
1521 if (value is int) {
1522 return valueOf2(((leftValue as int)) != value);
1523 } else if (value is double) {
1524 return valueOf2(toDouble(leftValue as int) != value);
1525 }
1526 return RESULT_TRUE;
1527 } else if (leftValue is double) {
1528 if (value is int) {
1529 return valueOf2(((leftValue as double)) != toDouble(value as int));
1530 } else if (value is double) {
1531 return valueOf2(((leftValue as double)) != value);
1532 }
1533 return RESULT_TRUE;
1534 } else if (leftValue is String) {
1535 if (value is String) {
1536 return valueOf2(((leftValue as String)) != value);
1537 }
1538 return RESULT_TRUE;
1539 }
1540 return RESULT_TRUE;
1541 }
1542 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe rand) => leftOperand;
1543 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe rand) {
1544 if (!isAnyNum || !leftOperand.isAnyNum) {
1545 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
1546 }
1547 if (isSomeInt || leftOperand.isSomeInt) {
1548 return RESULT_INT;
1549 } else if (isSomeNum || leftOperand.isSomeNum) {
1550 return RESULT_NUM;
1551 }
1552 Object leftValue = leftOperand.value;
1553 if (leftValue == null) {
1554 return error(node.leftOperand);
1555 } else if (value == null) {
1556 return error(node.rightOperand);
1557 } else if (leftValue is int) {
1558 if (value is int) {
1559 if (((value as int)) == 0) {
1560 return valueOf3(((leftValue as int)).toDouble() % ((value as int)).toD ouble());
1561 }
1562 return valueOf(((leftValue as int)).remainder(value as int));
1563 } else if (value is double) {
1564 return valueOf3(((leftValue as int)).toDouble() % ((value as double)));
1565 }
1566 } else if (leftValue is double) {
1567 if (value is int) {
1568 return valueOf3(((leftValue as double)) % ((value as int)).toDouble());
1569 } else if (value is double) {
1570 return valueOf3(((leftValue as double)) % ((value as double)));
1571 }
1572 }
1573 return error(node);
1574 }
1575 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe rand) => leftOperand;
1576 EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOpe rand) {
1577 if (!isAnyInt || !leftOperand.isAnyInt) {
1578 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
1579 }
1580 if (isSomeInt || leftOperand.isSomeInt) {
1581 return RESULT_INT;
1582 }
1583 Object leftValue = leftOperand.value;
1584 if (leftValue == null) {
1585 return error(node.leftOperand);
1586 } else if (value == null) {
1587 return error(node.rightOperand);
1588 } else if (leftValue is int) {
1589 if (value is int) {
1590 return RESULT_INT;
1591 }
1592 return error(node.rightOperand);
1593 }
1594 if (value is int) {
1595 return error(node.leftOperand);
1596 }
1597 return union(error(node.leftOperand), error(node.rightOperand));
1598 }
1599 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp erand) => leftOperand;
1600 EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOp erand) {
1601 if (!isAnyInt || !leftOperand.isAnyInt) {
1602 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
1603 }
1604 if (isSomeInt || leftOperand.isSomeInt) {
1605 return RESULT_INT;
1606 }
1607 Object leftValue = leftOperand.value;
1608 if (leftValue == null) {
1609 return error(node.leftOperand);
1610 } else if (value == null) {
1611 return error(node.rightOperand);
1612 } else if (leftValue is int) {
1613 if (value is int) {
1614 return valueOf(((leftValue as int)) >> ((value as int)));
1615 }
1616 return error(node.rightOperand);
1617 }
1618 if (value is int) {
1619 return error(node.leftOperand);
1620 }
1621 return union(error(node.leftOperand), error(node.rightOperand));
1622 }
1623 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand ) => leftOperand;
1624 EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand ) {
1625 if (!isAnyNum || !leftOperand.isAnyNum) {
1626 return error2(node, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
1627 }
1628 if (isSomeInt || leftOperand.isSomeInt) {
1629 return RESULT_INT;
1630 } else if (isSomeNum || leftOperand.isSomeNum) {
1631 return RESULT_NUM;
1632 }
1633 Object leftValue = leftOperand.value;
1634 if (leftValue == null) {
1635 return error(node.leftOperand);
1636 } else if (value == null) {
1637 return error(node.rightOperand);
1638 } else if (leftValue is int) {
1639 if (value is int) {
1640 return valueOf(((leftValue as int)) * (value as int));
1641 } else if (value is double) {
1642 return valueOf3(((leftValue as int)).toDouble() * ((value as double)));
1643 }
1644 } else if (leftValue is double) {
1645 if (value is int) {
1646 return valueOf3(((leftValue as double)) * ((value as int)).toDouble());
1647 } else if (value is double) {
1648 return valueOf3(((leftValue as double)) * ((value as double)));
1649 }
1650 }
1651 return error(node);
1652 }
1653 bool get isNull => identical(this, RESULT_NULL);
1654
1655 /**
1656 * Return the result of applying boolean conversion to the given value.
1657 *
1658 * @param node the node against which errors should be reported
1659 * @param value the value to be converted to a boolean
1660 * @return the result of applying boolean conversion to the given value
1661 */
1662 EvaluationResultImpl booleanConversion(ASTNode node, Object value) {
1663 if (value is bool) {
1664 if (value as bool) {
1665 return RESULT_TRUE;
1666 } else {
1667 return RESULT_FALSE;
1668 }
1669 }
1670 return error(node);
1671 }
1672 ErrorResult error(ASTNode node) => error2(node, CompileTimeErrorCode.INVALID_C ONSTANT);
1673
1674 /**
1675 * Return a result object representing an error associated with the given node .
1676 *
1677 * @param node the AST node associated with the error
1678 * @param code the error code indicating the nature of the error
1679 * @return a result object representing an error associated with the given nod e
1680 */
1681 ErrorResult error2(ASTNode node, ErrorCode code) => new ErrorResult.con1(node, code);
1682
1683 /**
1684 * Checks if this result has type "bool", with known or unknown value.
1685 */
1686 bool get isAnyBool => isSomeBool || identical(this, RESULT_TRUE) || identical( this, RESULT_FALSE);
1687
1688 /**
1689 * Checks if this result has type "int", with known or unknown value.
1690 */
1691 bool get isAnyInt => identical(this, RESULT_INT) || value is int;
1692
1693 /**
1694 * Checks if this result has one of the types - "bool", "num" or "string"; or may be `null`.
1695 */
1696 bool get isAnyNullBoolNumString => isNull || isAnyBool || isAnyNum || value is String;
1697
1698 /**
1699 * Checks if this result has type "num", with known or unknown value.
1700 */
1701 bool get isAnyNum => isSomeNum || value is num;
1702
1703 /**
1704 * Checks if this result has type "bool", exact value of which we don't know.
1705 */
1706 bool get isSomeBool => identical(this, RESULT_BOOL);
1707
1708 /**
1709 * Checks if this result has type "int", exact value of which we don't know.
1710 */
1711 bool get isSomeInt => identical(this, RESULT_INT);
1712
1713 /**
1714 * Checks if this result has type "num" (or "int"), exact value of which we do n't know.
1715 */
1716 bool get isSomeNum => identical(this, RESULT_DYNAMIC) || identical(this, RESUL T_INT) || identical(this, RESULT_NUM);
1717 double toDouble(int value) => value.toDouble();
1718
1719 /**
1720 * Return an error result that is the union of the two given error results.
1721 *
1722 * @param firstError the first error to be combined
1723 * @param secondError the second error to be combined
1724 * @return an error result that is the union of the two given error results
1725 */
1726 ErrorResult union(ErrorResult firstError, ErrorResult secondError) => new Erro rResult.con2(firstError, secondError);
1727
1728 /**
1729 * Return a result object representing the given value.
1730 *
1731 * @param value the value to be represented as a result object
1732 * @return a result object representing the given value
1733 */
1734 ValidResult valueOf(int value) => new ValidResult(value);
1735
1736 /**
1737 * Return a result object representing the given value.
1738 *
1739 * @param value the value to be represented as a result object
1740 * @return a result object representing the given value
1741 */
1742 ValidResult valueOf2(bool value) => value ? RESULT_TRUE : RESULT_FALSE;
1743
1744 /**
1745 * Return a result object representing the given value.
1746 *
1747 * @param value the value to be represented as a result object
1748 * @return a result object representing the given value
1749 */
1750 ValidResult valueOf3(double value) => new ValidResult(value);
1751
1752 /**
1753 * Return a result object representing the given value.
1754 *
1755 * @param value the value to be represented as a result object
1756 * @return a result object representing the given value
1757 */
1758 ValidResult valueOf4(String value) => new ValidResult(value);
1759 }
OLDNEW
« no previous file with comments | « pkg/analyzer_experimental/lib/src/generated/ast.dart ('k') | pkg/analyzer_experimental/lib/src/generated/element.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698