| 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 | 3 |
| 4 library engine.constant; | 4 library engine.constant; |
| 5 | 5 |
| 6 import 'java_core.dart'; | 6 import 'java_core.dart'; |
| 7 import 'source.dart' show Source; | 7 import 'source.dart' show Source; |
| 8 import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode; | 8 import 'error.dart' show AnalysisError, ErrorCode, CompileTimeErrorCode; |
| 9 import 'scanner.dart' show TokenType; | 9 import 'scanner.dart' show TokenType; |
| 10 import 'ast.dart'; | 10 import 'ast.dart'; |
| 11 import 'element.dart'; | 11 import 'element.dart'; |
| 12 import 'engine.dart' show AnalysisEngine; |
| 12 | 13 |
| 13 /** | 14 /** |
| 14 * Instances of the class {@code ConstantEvaluator} evaluate constant expression
s to produce their | 15 * Instances of the class {@code ConstantEvaluator} evaluate constant expression
s to produce their |
| 15 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant | 16 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant |
| 16 * expression is one of the following: | 17 * expression is one of the following: |
| 17 * <ul> | 18 * <ul> |
| 18 * <li>A literal number.</li> | 19 * <li>A literal number.</li> |
| 19 * <li>A literal boolean.</li> | 20 * <li>A literal boolean.</li> |
| 20 * <li>A literal string where any interpolated expression is a compile-time cons
tant that evaluates | 21 * <li>A literal string where any interpolated expression is a compile-time cons
tant that evaluates |
| 21 * to a numeric, string or boolean value or to {@code null}.</li> | 22 * to a numeric, string or boolean value or to {@code null}.</li> |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 */ | 118 */ |
| 118 Object get value => _value; | 119 Object get value => _value; |
| 119 /** | 120 /** |
| 120 * Return {@code true} if the expression is a compile-time constant expression
that would not | 121 * Return {@code true} if the expression is a compile-time constant expression
that would not |
| 121 * throw an exception when evaluated. | 122 * throw an exception when evaluated. |
| 122 * @return {@code true} if the expression is a valid compile-time constant exp
ression | 123 * @return {@code true} if the expression is a valid compile-time constant exp
ression |
| 123 */ | 124 */ |
| 124 bool isValid() => _errors == null; | 125 bool isValid() => _errors == null; |
| 125 } | 126 } |
| 126 /** | 127 /** |
| 128 * Instances of the class {@code ConstantFinder} are used to traverse the AST st
ructures of all of |
| 129 * the compilation units being resolved and build a table mapping constant varia
ble elements to the |
| 130 * declarations of those variables. |
| 131 */ |
| 132 class ConstantFinder extends RecursiveASTVisitor<Object> { |
| 133 /** |
| 134 * A table mapping constant variable elements to the declarations of those var
iables. |
| 135 */ |
| 136 Map<VariableElement, VariableDeclaration> _variableMap = new Map<VariableEleme
nt, VariableDeclaration>(); |
| 137 /** |
| 138 * Initialize a newly created constant finder. |
| 139 */ |
| 140 ConstantFinder() : super() { |
| 141 } |
| 142 /** |
| 143 * Return a table mapping constant variable elements to the declarations of th
ose variables. |
| 144 * @return a table mapping constant variable elements to the declarations of t
hose variables |
| 145 */ |
| 146 Map<VariableElement, VariableDeclaration> get variableMap => _variableMap; |
| 147 Object visitVariableDeclaration(VariableDeclaration node) { |
| 148 super.visitVariableDeclaration(node); |
| 149 Expression initializer4 = node.initializer; |
| 150 if (initializer4 != null && node.isConst()) { |
| 151 VariableElement element23 = node.element; |
| 152 if (element23 != null) { |
| 153 _variableMap[element23] = node; |
| 154 } |
| 155 } |
| 156 return null; |
| 157 } |
| 158 } |
| 159 /** |
| 160 * Instances of the class {@code ConstantValueComputer} compute the values of co
nstant variables in |
| 161 * one or more compilation units. The expected usage pattern is for the compilat
ion units to be |
| 162 * added to this computer using the method {@link #add(CompilationUnit)} and the
n for the method{@link #computeValues()} to invoked exactly once. Any use of an
instance after invoking the |
| 163 * method {@link #computeValues()} will result in unpredictable behavior. |
| 164 */ |
| 165 class ConstantValueComputer { |
| 166 /** |
| 167 * The object used to find constant variables in the compilation units that we
re added. |
| 168 */ |
| 169 ConstantFinder _constantFinder = new ConstantFinder(); |
| 170 /** |
| 171 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to |
| 172 * the other constant variables that are referenced in the head's initializer. |
| 173 */ |
| 174 DirectedGraph<VariableElement> _referenceGraph = new DirectedGraph<VariableEle
ment>(); |
| 175 /** |
| 176 * A table mapping constant variables to the declarations of those variables. |
| 177 */ |
| 178 Map<VariableElement, VariableDeclaration> _declarationMap; |
| 179 /** |
| 180 * Initialize a newly created constant value computer. |
| 181 */ |
| 182 ConstantValueComputer() : super() { |
| 183 } |
| 184 /** |
| 185 * Add the constant variables in the given compilation unit to the list of con
stant variables |
| 186 * whose value needs to be computed. |
| 187 * @param unit the compilation unit defining the constant variables to be adde
d |
| 188 */ |
| 189 void add(CompilationUnit unit) { |
| 190 unit.accept(_constantFinder); |
| 191 } |
| 192 /** |
| 193 * Compute values for all of the constant variables in the compilation units t
hat were added. |
| 194 */ |
| 195 void computeValues() { |
| 196 _declarationMap = _constantFinder.variableMap; |
| 197 for (MapEntry<VariableElement, VariableDeclaration> entry in getMapEntrySet(
_declarationMap)) { |
| 198 VariableElement element = entry.getKey(); |
| 199 ReferenceFinder referenceFinder = new ReferenceFinder(element, _referenceG
raph); |
| 200 _referenceGraph.addNode(element); |
| 201 entry.getValue().initializer.accept(referenceFinder); |
| 202 } |
| 203 while (!_referenceGraph.isEmpty()) { |
| 204 VariableElement element = _referenceGraph.removeSink(); |
| 205 while (element != null) { |
| 206 computeValueFor(element); |
| 207 element = _referenceGraph.removeSink(); |
| 208 } |
| 209 if (!_referenceGraph.isEmpty()) { |
| 210 List<VariableElement> variablesInCycle = _referenceGraph.findCycle(); |
| 211 if (variablesInCycle == null) { |
| 212 AnalysisEngine.instance.logger.logError("Exiting constant value comput
er with ${_referenceGraph.nodeCount} variables that are neither sinks no in a cy
cle"); |
| 213 return; |
| 214 } |
| 215 for (VariableElement variable in variablesInCycle) { |
| 216 generateCycleError(variablesInCycle, variable); |
| 217 } |
| 218 _referenceGraph.removeAllNodes(variablesInCycle); |
| 219 } |
| 220 } |
| 221 } |
| 222 /** |
| 223 * Compute a value for the given variable. |
| 224 * @param variable the variable for which a value is to be computed |
| 225 */ |
| 226 void computeValueFor(VariableElement variable) { |
| 227 VariableDeclaration declaration = _declarationMap[variable]; |
| 228 if (declaration == null) { |
| 229 return; |
| 230 } |
| 231 EvaluationResultImpl result = declaration.initializer.accept(new ConstantVis
itor()); |
| 232 ((variable as VariableElementImpl)).evaluationResult = result; |
| 233 if (result is ErrorResult) { |
| 234 List<AnalysisError> errors = new List<AnalysisError>(); |
| 235 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { |
| 236 ASTNode node3 = data.node; |
| 237 Source source10 = variable.getAncestor(CompilationUnitElement).source; |
| 238 errors.add(new AnalysisError.con2(source10, node3.offset, node3.length,
data.errorCode, [])); |
| 239 } |
| 240 } |
| 241 } |
| 242 /** |
| 243 * Generate an error indicating that the given variable is not a valid compile
-time constant |
| 244 * because it references at least one of the variables in the given cycle, eac
h of which directly |
| 245 * or indirectly references the variable. |
| 246 * @param variablesInCycle the variables in the cycle that includes the given
variable |
| 247 * @param variable the variable that is not a valid compile-time constant |
| 248 */ |
| 249 void generateCycleError(List<VariableElement> variablesInCycle, VariableElemen
t variable) { |
| 250 } |
| 251 } |
| 252 /** |
| 127 * Instances of the class {@code ConstantVisitor} evaluate constant expressions
to produce their | 253 * Instances of the class {@code ConstantVisitor} evaluate constant expressions
to produce their |
| 128 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant | 254 * compile-time value. According to the Dart Language Specification: <blockquote
> A constant |
| 129 * expression is one of the following: | 255 * expression is one of the following: |
| 130 * <ul> | 256 * <ul> |
| 131 * <li>A literal number.</li> | 257 * <li>A literal number.</li> |
| 132 * <li>A literal boolean.</li> | 258 * <li>A literal boolean.</li> |
| 133 * <li>A literal string where any interpolated expression is a compile-time cons
tant that evaluates | 259 * <li>A literal string where any interpolated expression is a compile-time cons
tant that evaluates |
| 134 * to a numeric, string or boolean value or to {@code null}.</li> | 260 * to a numeric, string or boolean value or to {@code null}.</li> |
| 135 * <li>{@code null}.</li> | 261 * <li>{@code null}.</li> |
| 136 * <li>A reference to a static constant variable.</li> | 262 * <li>A reference to a static constant variable.</li> |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 for (MapLiteralEntry entry in node.entries) { | 370 for (MapLiteralEntry entry in node.entries) { |
| 245 result = union(result, entry.key.accept(this)); | 371 result = union(result, entry.key.accept(this)); |
| 246 result = union(result, entry.value.accept(this)); | 372 result = union(result, entry.value.accept(this)); |
| 247 } | 373 } |
| 248 if (result != null) { | 374 if (result != null) { |
| 249 return result; | 375 return result; |
| 250 } | 376 } |
| 251 return ValidResult.RESULT_OBJECT; | 377 return ValidResult.RESULT_OBJECT; |
| 252 } | 378 } |
| 253 EvaluationResultImpl visitMethodInvocation(MethodInvocation node) { | 379 EvaluationResultImpl visitMethodInvocation(MethodInvocation node) { |
| 254 Element element23 = node.methodName.element; | 380 Element element24 = node.methodName.element; |
| 255 if (element23 is FunctionElement) { | 381 if (element24 is FunctionElement) { |
| 256 FunctionElement function = element23 as FunctionElement; | 382 FunctionElement function = element24 as FunctionElement; |
| 257 if (function.name == "identical") { | 383 if (function.name == "identical") { |
| 258 NodeList<Expression> arguments3 = node.argumentList.arguments; | 384 NodeList<Expression> arguments3 = node.argumentList.arguments; |
| 259 if (arguments3.length == 2) { | 385 if (arguments3.length == 2) { |
| 260 Element enclosingElement2 = function.enclosingElement; | 386 Element enclosingElement2 = function.enclosingElement; |
| 261 if (enclosingElement2 is CompilationUnitElement) { | 387 if (enclosingElement2 is CompilationUnitElement) { |
| 262 LibraryElement library20 = ((enclosingElement2 as CompilationUnitEle
ment)).library; | 388 LibraryElement library30 = ((enclosingElement2 as CompilationUnitEle
ment)).library; |
| 263 if (library20.isDartCore()) { | 389 if (library30.isDartCore()) { |
| 264 EvaluationResultImpl leftArgument = arguments3[0].accept(this); | 390 EvaluationResultImpl leftArgument = arguments3[0].accept(this); |
| 265 EvaluationResultImpl rightArgument = arguments3[1].accept(this); | 391 EvaluationResultImpl rightArgument = arguments3[1].accept(this); |
| 266 return leftArgument.equalEqual(node, rightArgument); | 392 return leftArgument.equalEqual(node, rightArgument); |
| 267 } | 393 } |
| 268 } | 394 } |
| 269 } | 395 } |
| 270 } | 396 } |
| 271 } | 397 } |
| 272 return error(node, null); | 398 return error(node, null); |
| 273 } | 399 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 * @return a result object representing an error associated with the given nod
e | 436 * @return a result object representing an error associated with the given nod
e |
| 311 */ | 437 */ |
| 312 ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code); | 438 ErrorResult error(ASTNode node, ErrorCode code) => new ErrorResult.con1(node,
code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code); |
| 313 /** | 439 /** |
| 314 * Return the constant value of the static constant represented by the given e
lement. | 440 * Return the constant value of the static constant represented by the given e
lement. |
| 315 * @param node the node to be used if an error needs to be reported | 441 * @param node the node to be used if an error needs to be reported |
| 316 * @param element the element whose value is to be returned | 442 * @param element the element whose value is to be returned |
| 317 * @return the constant value of the static constant | 443 * @return the constant value of the static constant |
| 318 */ | 444 */ |
| 319 EvaluationResultImpl getConstantValue(ASTNode node, Element element) { | 445 EvaluationResultImpl getConstantValue(ASTNode node, Element element) { |
| 320 if (element is PropertyAccessorElementImpl) { | 446 if (element is PropertyAccessorElement) { |
| 321 element = ((element as PropertyAccessorElementImpl)).variable; | 447 element = ((element as PropertyAccessorElement)).variable; |
| 322 } | 448 } |
| 323 if (element is VariableElementImpl) { | 449 if (element is VariableElementImpl) { |
| 324 EvaluationResultImpl value = ((element as VariableElementImpl)).evaluation
Result; | 450 EvaluationResultImpl value = ((element as VariableElementImpl)).evaluation
Result; |
| 325 if (value != null) { | 451 if (value != null) { |
| 326 return value; | 452 return value; |
| 327 } | 453 } |
| 454 } else if (element is ExecutableElement) { |
| 455 return new ValidResult(element); |
| 328 } | 456 } |
| 329 return error(node, null); | 457 return error(node, null); |
| 330 } | 458 } |
| 331 /** | 459 /** |
| 332 * Return the union of the errors encoded in the given results. | 460 * Return the union of the errors encoded in the given results. |
| 333 * @param leftResult the first set of errors, or {@code null} if there was no
previous collection | 461 * @param leftResult the first set of errors, or {@code null} if there was no
previous collection |
| 334 * of errors | 462 * of errors |
| 335 * @param rightResult the errors to be added to the collection, or a valid res
ult if there are no | 463 * @param rightResult the errors to be added to the collection, or a valid res
ult if there are no |
| 336 * errors to be added | 464 * errors to be added |
| 337 * @return the union of the errors encoded in the given results | 465 * @return the union of the errors encoded in the given results |
| 338 */ | 466 */ |
| 339 ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) { | 467 ErrorResult union(ErrorResult leftResult, EvaluationResultImpl rightResult) { |
| 340 if (rightResult is ErrorResult) { | 468 if (rightResult is ErrorResult) { |
| 341 if (leftResult != null) { | 469 if (leftResult != null) { |
| 342 return new ErrorResult.con2(leftResult, (rightResult as ErrorResult)); | 470 return new ErrorResult.con2(leftResult, (rightResult as ErrorResult)); |
| 343 } else { | 471 } else { |
| 344 return rightResult as ErrorResult; | 472 return rightResult as ErrorResult; |
| 345 } | 473 } |
| 346 } | 474 } |
| 347 return leftResult; | 475 return leftResult; |
| 348 } | 476 } |
| 349 } | 477 } |
| 350 /** | 478 /** |
| 479 * Instances of the class {@code DirectedGraph} implement a directed graph in wh
ich the nodes are |
| 480 * arbitrary (client provided) objects and edges are represented implicitly. The
graph will allow an |
| 481 * edge from any node to any other node, including itself, but will not represen
t multiple edges |
| 482 * between the same pair of nodes. |
| 483 * @param N the type of the nodes in the graph |
| 484 */ |
| 485 class DirectedGraph<N> { |
| 486 /** |
| 487 * The table encoding the edges in the graph. An edge is represented by an ent
ry mapping the head |
| 488 * to a set of tails. Nodes that are not the head of any edge are represented
by an entry mapping |
| 489 * the node to an empty set of tails. |
| 490 */ |
| 491 Map<N, Set<N>> _edges = new Map<N, Set<N>>(); |
| 492 /** |
| 493 * Initialize a newly create directed graph to be empty. |
| 494 */ |
| 495 DirectedGraph() : super() { |
| 496 } |
| 497 /** |
| 498 * Add an edge from the given head node to the given tail node. Both nodes wil
l be a part of the |
| 499 * graph after this method is invoked, whether or not they were before. |
| 500 * @param head the node at the head of the edge |
| 501 * @param tail the node at the tail of the edge |
| 502 */ |
| 503 void addEdge(N head, N tail) { |
| 504 Set<N> tails = _edges[tail]; |
| 505 if (tails == null) { |
| 506 _edges[tail] = new Set<N>(); |
| 507 } |
| 508 tails = _edges[head]; |
| 509 if (tails == null) { |
| 510 tails = new Set<N>(); |
| 511 _edges[head] = tails; |
| 512 } |
| 513 javaSetAdd(tails, tail); |
| 514 } |
| 515 /** |
| 516 * Add the given node to the set of nodes in the graph. |
| 517 * @param node the node to be added |
| 518 */ |
| 519 void addNode(N node) { |
| 520 Set<N> tails = _edges[node]; |
| 521 if (tails == null) { |
| 522 _edges[node] = new Set<N>(); |
| 523 } |
| 524 } |
| 525 /** |
| 526 * Return a list of nodes that form a cycle, or {@code null} if there are no c
ycles in this graph. |
| 527 * @return a list of nodes that form a cycle |
| 528 */ |
| 529 List<N> findCycle() => null; |
| 530 /** |
| 531 * Return the number of nodes in this graph. |
| 532 * @return the number of nodes in this graph |
| 533 */ |
| 534 int get nodeCount => _edges.length; |
| 535 /** |
| 536 * Return a set containing the tails of edges that have the given node as thei
r head. The set will |
| 537 * be empty if there are no such edges or if the node is not part of the graph
. Clients must not |
| 538 * modify the returned set. |
| 539 * @param head the node at the head of all of the edges whose tails are to be
returned |
| 540 * @return a set containing the tails of edges that have the given node as the
ir head |
| 541 */ |
| 542 Set<N> getTails(N head) { |
| 543 Set<N> tails = _edges[head]; |
| 544 if (tails == null) { |
| 545 return new Set<N>(); |
| 546 } |
| 547 return tails; |
| 548 } |
| 549 /** |
| 550 * Return {@code true} if this graph is empty. |
| 551 * @return {@code true} if this graph is empty |
| 552 */ |
| 553 bool isEmpty() => _edges.isEmpty; |
| 554 /** |
| 555 * Remove all of the given nodes from this graph. As a consequence, any edges
for which those |
| 556 * nodes were either a head or a tail will also be removed. |
| 557 * @param nodes the nodes to be removed |
| 558 */ |
| 559 void removeAllNodes(List<N> nodes) { |
| 560 for (N node in nodes) { |
| 561 removeNode(node); |
| 562 } |
| 563 } |
| 564 /** |
| 565 * Remove the edge from the given head node to the given tail node. If there w
as no such edge then |
| 566 * the graph will be unmodified: the number of edges will be the same and the
set of nodes will be |
| 567 * the same (neither node will either be added or removed). |
| 568 * @param head the node at the head of the edge |
| 569 * @param tail the node at the tail of the edge |
| 570 * @return {@code true} if the graph was modified as a result of this operatio
n |
| 571 */ |
| 572 void removeEdge(N head, N tail) { |
| 573 Set<N> tails = _edges[head]; |
| 574 if (tails != null) { |
| 575 tails.remove(tail); |
| 576 } |
| 577 } |
| 578 /** |
| 579 * Remove the given node from this graph. As a consequence, any edges for whic
h that node was |
| 580 * either a head or a tail will also be removed. |
| 581 * @param node the node to be removed |
| 582 */ |
| 583 void removeNode(N node) { |
| 584 _edges.remove(node); |
| 585 for (Set<N> tails in _edges.values) { |
| 586 tails.remove(node); |
| 587 } |
| 588 } |
| 589 /** |
| 590 * Find one node (referred to as a sink node) that has no outgoing edges (that
is, for which there |
| 591 * are no edges that have that node as the head of the edge) and remove it fro
m this graph. Return |
| 592 * the node that was removed, or {@code null} if there are no such nodes eithe
r because the graph |
| 593 * is empty or because every node in the graph has at least one outgoing edge.
As a consequence of |
| 594 * removing the node from the graph any edges for which that node was a tail w
ill also be removed. |
| 595 * @return the sink node that was removed |
| 596 */ |
| 597 N removeSink() { |
| 598 N sink = findSink(); |
| 599 if (sink == null) { |
| 600 return null; |
| 601 } |
| 602 removeNode(sink); |
| 603 return sink; |
| 604 } |
| 605 /** |
| 606 * Return one node that has no outgoing edges (that is, for which there are no
edges that have |
| 607 * that node as the head of the edge), or {@code null} if there are no such no
des. |
| 608 * @return a sink node |
| 609 */ |
| 610 N findSink() { |
| 611 for (MapEntry<N, Set<N>> entry in getMapEntrySet(_edges)) { |
| 612 if (entry.getValue().isEmpty) { |
| 613 return entry.getKey(); |
| 614 } |
| 615 } |
| 616 return null; |
| 617 } |
| 618 } |
| 619 /** |
| 351 * Instances of the class {@code ErrorResult} represent the result of evaluating
an expression that | 620 * Instances of the class {@code ErrorResult} represent the result of evaluating
an expression that |
| 352 * is not a valid compile time constant. | 621 * is not a valid compile time constant. |
| 353 */ | 622 */ |
| 354 class ErrorResult extends EvaluationResultImpl { | 623 class ErrorResult extends EvaluationResultImpl { |
| 355 /** | 624 /** |
| 356 * The errors that prevent the expression from being a valid compile time cons
tant. | 625 * The errors that prevent the expression from being a valid compile time cons
tant. |
| 357 */ | 626 */ |
| 358 List<ErrorResult_ErrorData> _errors = new List<ErrorResult_ErrorData>(); | 627 List<ErrorResult_ErrorData> _errors = new List<ErrorResult_ErrorData>(); |
| 359 /** | 628 /** |
| 360 * Initialize a newly created result representing the error with the given cod
e reported against | 629 * Initialize a newly created result representing the error with the given cod
e reported against |
| 361 * the given node. | 630 * the given node. |
| 362 * @param node the node against which the error should be reported | 631 * @param node the node against which the error should be reported |
| 363 * @param errorCode the error code for the error to be generated | 632 * @param errorCode the error code for the error to be generated |
| 364 */ | 633 */ |
| 365 ErrorResult.con1(ASTNode node, ErrorCode errorCode) { | 634 ErrorResult.con1(ASTNode node, ErrorCode errorCode) { |
| 366 _jtd_constructor_157_impl(node, errorCode); | 635 _jtd_constructor_162_impl(node, errorCode); |
| 367 } | 636 } |
| 368 _jtd_constructor_157_impl(ASTNode node, ErrorCode errorCode) { | 637 _jtd_constructor_162_impl(ASTNode node, ErrorCode errorCode) { |
| 369 _errors.add(new ErrorResult_ErrorData(node, errorCode)); | 638 _errors.add(new ErrorResult_ErrorData(node, errorCode)); |
| 370 } | 639 } |
| 371 /** | 640 /** |
| 372 * Initialize a newly created result to represent the union of the errors in t
he given result | 641 * Initialize a newly created result to represent the union of the errors in t
he given result |
| 373 * objects. | 642 * objects. |
| 374 * @param firstResult the first set of results being merged | 643 * @param firstResult the first set of results being merged |
| 375 * @param secondResult the second set of results being merged | 644 * @param secondResult the second set of results being merged |
| 376 */ | 645 */ |
| 377 ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) { | 646 ErrorResult.con2(ErrorResult firstResult, ErrorResult secondResult) { |
| 378 _jtd_constructor_158_impl(firstResult, secondResult); | 647 _jtd_constructor_163_impl(firstResult, secondResult); |
| 379 } | 648 } |
| 380 _jtd_constructor_158_impl(ErrorResult firstResult, ErrorResult secondResult) { | 649 _jtd_constructor_163_impl(ErrorResult firstResult, ErrorResult secondResult) { |
| 381 _errors.addAll(firstResult._errors); | 650 _errors.addAll(firstResult._errors); |
| 382 _errors.addAll(secondResult._errors); | 651 _errors.addAll(secondResult._errors); |
| 383 } | 652 } |
| 384 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and) => rightOperand.addToError(node, this); | 653 EvaluationResultImpl add(BinaryExpression node, EvaluationResultImpl rightOper
and) => rightOperand.addToError(node, this); |
| 385 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitAndError(node, this); | 654 EvaluationResultImpl bitAnd(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitAndError(node, this); |
| 386 EvaluationResultImpl bitNot(Expression node) => this; | 655 EvaluationResultImpl bitNot(Expression node) => this; |
| 387 EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOp
erand) => rightOperand.bitOrError(node, this); | 656 EvaluationResultImpl bitOr(BinaryExpression node, EvaluationResultImpl rightOp
erand) => rightOperand.bitOrError(node, this); |
| 388 EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitXorError(node, this); | 657 EvaluationResultImpl bitXor(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.bitXorError(node, this); |
| 389 EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOp
erand) => rightOperand.concatenateError(node, this); | 658 EvaluationResultImpl concatenate(Expression node, EvaluationResultImpl rightOp
erand) => rightOperand.concatenateError(node, this); |
| 390 EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.divideError(node, this); | 659 EvaluationResultImpl divide(BinaryExpression node, EvaluationResultImpl rightO
perand) => rightOperand.divideError(node, this); |
| 391 EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOpe
rand) => rightOperand.equalEqualError(node, this); | 660 EvaluationResultImpl equalEqual(Expression node, EvaluationResultImpl rightOpe
rand) => rightOperand.equalEqualError(node, this); |
| 392 List<ErrorResult_ErrorData> get errorData => _errors; | 661 List<ErrorResult_ErrorData> get errorData => _errors; |
| 393 List<AnalysisError> get errors => new List.from(_errors); | |
| 394 EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl r
ightOperand) => rightOperand.greaterThanError(node, this); | 662 EvaluationResultImpl greaterThan(BinaryExpression node, EvaluationResultImpl r
ightOperand) => rightOperand.greaterThanError(node, this); |
| 395 EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResul
tImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this); | 663 EvaluationResultImpl greaterThanOrEqual(BinaryExpression node, EvaluationResul
tImpl rightOperand) => rightOperand.greaterThanOrEqualError(node, this); |
| 396 EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl
rightOperand) => rightOperand.integerDivideError(node, this); | 664 EvaluationResultImpl integerDivide(BinaryExpression node, EvaluationResultImpl
rightOperand) => rightOperand.integerDivideError(node, this); |
| 397 EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult lef
tOperand) => this; | 665 EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult lef
tOperand) => this; |
| 398 EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl righ
tOperand) => rightOperand.lessThanError(node, this); | 666 EvaluationResultImpl lessThan(BinaryExpression node, EvaluationResultImpl righ
tOperand) => rightOperand.lessThanError(node, this); |
| 399 EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultIm
pl rightOperand) => rightOperand.lessThanOrEqualError(node, this); | 667 EvaluationResultImpl lessThanOrEqual(BinaryExpression node, EvaluationResultIm
pl rightOperand) => rightOperand.lessThanOrEqualError(node, this); |
| 400 EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl ri
ghtOperand) => rightOperand.logicalAndError(node, this); | 668 EvaluationResultImpl logicalAnd(BinaryExpression node, EvaluationResultImpl ri
ghtOperand) => rightOperand.logicalAndError(node, this); |
| 401 EvaluationResultImpl logicalNot(Expression node) => this; | 669 EvaluationResultImpl logicalNot(Expression node) => this; |
| 402 EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rig
htOperand) => rightOperand.logicalOrError(node, this); | 670 EvaluationResultImpl logicalOr(BinaryExpression node, EvaluationResultImpl rig
htOperand) => rightOperand.logicalOrError(node, this); |
| 403 EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOp
erand) => rightOperand.minusError(node, this); | 671 EvaluationResultImpl minus(BinaryExpression node, EvaluationResultImpl rightOp
erand) => rightOperand.minusError(node, this); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand); | 810 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand); |
| 543 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe
rand); | 811 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe
rand); |
| 544 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe
rand); | 812 EvaluationResultImpl shiftLeftError(BinaryExpression node, ErrorResult leftOpe
rand); |
| 545 EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOpe
rand); | 813 EvaluationResultImpl shiftLeftValid(BinaryExpression node, ValidResult leftOpe
rand); |
| 546 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp
erand); | 814 EvaluationResultImpl shiftRightError(BinaryExpression node, ErrorResult leftOp
erand); |
| 547 EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOp
erand); | 815 EvaluationResultImpl shiftRightValid(BinaryExpression node, ValidResult leftOp
erand); |
| 548 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand
); | 816 EvaluationResultImpl timesError(BinaryExpression node, ErrorResult leftOperand
); |
| 549 EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand
); | 817 EvaluationResultImpl timesValid(BinaryExpression node, ValidResult leftOperand
); |
| 550 } | 818 } |
| 551 /** | 819 /** |
| 820 * Instances of the class {@code ReferenceFinder} add reference information for
a given variable to |
| 821 * the bi-directional mapping used to order the evaluation of constants. |
| 822 */ |
| 823 class ReferenceFinder extends RecursiveASTVisitor<Object> { |
| 824 /** |
| 825 * The element representing the variable whose initializer will be visited. |
| 826 */ |
| 827 VariableElement _source; |
| 828 /** |
| 829 * A graph in which the nodes are the constant variables and the edges are fro
m each variable to |
| 830 * the other constant variables that are referenced in the head's initializer. |
| 831 */ |
| 832 DirectedGraph<VariableElement> _referenceGraph; |
| 833 /** |
| 834 * Initialize a newly created reference finder to find references from the giv
en variable to other |
| 835 * variables and to add those references to the given graph. |
| 836 * @param source the element representing the variable whose initializer will
be visited |
| 837 * @param referenceGraph a graph recording which variables (heads) reference w
hich other variables |
| 838 * (tails) in their initializers |
| 839 */ |
| 840 ReferenceFinder(VariableElement source, DirectedGraph<VariableElement> referen
ceGraph) { |
| 841 this._source = source; |
| 842 this._referenceGraph = referenceGraph; |
| 843 } |
| 844 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 845 Element element25 = node.element; |
| 846 if (element25 is PropertyAccessorElement) { |
| 847 element25 = ((element25 as PropertyAccessorElement)).variable; |
| 848 } |
| 849 if (element25 is VariableElement) { |
| 850 VariableElement variable = element25 as VariableElement; |
| 851 if (variable.isConst()) { |
| 852 _referenceGraph.addEdge(_source, variable); |
| 853 } |
| 854 } |
| 855 return null; |
| 856 } |
| 857 } |
| 858 /** |
| 552 * Instances of the class {@code ValidResult} represent the result of attempting
to evaluate a valid | 859 * Instances of the class {@code ValidResult} represent the result of attempting
to evaluate a valid |
| 553 * compile time constant expression. | 860 * compile time constant expression. |
| 554 */ | 861 */ |
| 555 class ValidResult extends EvaluationResultImpl { | 862 class ValidResult extends EvaluationResultImpl { |
| 556 /** | 863 /** |
| 557 * A result object representing the value 'false'. | 864 * A result object representing the value 'false'. |
| 558 */ | 865 */ |
| 559 static ValidResult RESULT_FALSE = new ValidResult(false); | 866 static ValidResult RESULT_FALSE = new ValidResult(false); |
| 560 /** | 867 /** |
| 561 * A result object representing the an arbitrary object on which no further op
erations can be | 868 * A result object representing the an arbitrary object on which no further op
erations can be |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperan
d) => leftOperand; | 1042 EvaluationResultImpl divideError(BinaryExpression node, ErrorResult leftOperan
d) => leftOperand; |
| 736 EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperan
d7) { | 1043 EvaluationResultImpl divideValid(BinaryExpression node, ValidResult leftOperan
d7) { |
| 737 Object leftValue = leftOperand7.value; | 1044 Object leftValue = leftOperand7.value; |
| 738 if (leftValue == null) { | 1045 if (leftValue == null) { |
| 739 return error(node.leftOperand); | 1046 return error(node.leftOperand); |
| 740 } else if (_value == null) { | 1047 } else if (_value == null) { |
| 741 return error(node.rightOperand); | 1048 return error(node.rightOperand); |
| 742 } else if (leftValue is int) { | 1049 } else if (leftValue is int) { |
| 743 if (_value is int) { | 1050 if (_value is int) { |
| 744 if (((_value as int)) == 0) { | 1051 if (((_value as int)) == 0) { |
| 745 return error2(node.rightOperand, CompileTimeErrorCode.COMPILE_TIME_CON
STANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO); | 1052 return valueOf3(((leftValue as int)).toDouble() / ((_value as int)).to
Double()); |
| 746 } | 1053 } |
| 747 return valueOf(((leftValue as int)) ~/ (_value as int)); | 1054 return valueOf(((leftValue as int)) ~/ (_value as int)); |
| 748 } else if (_value is double) { | 1055 } else if (_value is double) { |
| 749 return valueOf3(((leftValue as int)).toDouble() / ((_value as double))); | 1056 return valueOf3(((leftValue as int)).toDouble() / ((_value as double))); |
| 750 } | 1057 } |
| 751 } else if (leftValue is double) { | 1058 } else if (leftValue is double) { |
| 752 if (_value is int) { | 1059 if (_value is int) { |
| 753 return valueOf3(((leftValue as double)) / ((_value as int)).toDouble()); | 1060 return valueOf3(((leftValue as double)) / ((_value as int)).toDouble()); |
| 754 } else if (_value is double) { | 1061 } else if (_value is double) { |
| 755 return valueOf3(((leftValue as double)) / ((_value as double))); | 1062 return valueOf3(((leftValue as double)) / ((_value as double))); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult lef
tOperand) => leftOperand; | 1143 EvaluationResultImpl integerDivideError(BinaryExpression node, ErrorResult lef
tOperand) => leftOperand; |
| 837 EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult lef
tOperand10) { | 1144 EvaluationResultImpl integerDivideValid(BinaryExpression node, ValidResult lef
tOperand10) { |
| 838 Object leftValue = leftOperand10.value; | 1145 Object leftValue = leftOperand10.value; |
| 839 if (leftValue == null) { | 1146 if (leftValue == null) { |
| 840 return error(node.leftOperand); | 1147 return error(node.leftOperand); |
| 841 } else if (_value == null) { | 1148 } else if (_value == null) { |
| 842 return error(node.rightOperand); | 1149 return error(node.rightOperand); |
| 843 } else if (leftValue is int) { | 1150 } else if (leftValue is int) { |
| 844 if (_value is int) { | 1151 if (_value is int) { |
| 845 if (((_value as int)) == 0) { | 1152 if (((_value as int)) == 0) { |
| 846 return error2(node.rightOperand, CompileTimeErrorCode.COMPILE_TIME_CON
STANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO); | 1153 return valueOf3(((leftValue as int)).toDouble() / ((_value as int)).to
Double()); |
| 847 } | 1154 } |
| 848 return valueOf(((leftValue as int)) ~/ (_value as int)); | 1155 return valueOf(((leftValue as int)) ~/ (_value as int)); |
| 849 } else if (_value is double) { | 1156 } else if (_value is double) { |
| 850 double result = ((leftValue as int)).toDouble() / ((_value as double)); | 1157 double result = ((leftValue as int)).toDouble() / ((_value as double)); |
| 851 return valueOf((result as int)); | 1158 return valueOf((result as int)); |
| 852 } | 1159 } |
| 853 } else if (leftValue is double) { | 1160 } else if (leftValue is double) { |
| 854 if (_value is int) { | 1161 if (_value is int) { |
| 855 double result = ((leftValue as double)) / ((_value as int)).toDouble(); | 1162 double result = ((leftValue as double)) / ((_value as int)).toDouble(); |
| 856 return valueOf((result as int)); | 1163 return valueOf((result as int)); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 976 return RESULT_TRUE; | 1283 return RESULT_TRUE; |
| 977 } | 1284 } |
| 978 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand) => leftOperand; | 1285 EvaluationResultImpl remainderError(BinaryExpression node, ErrorResult leftOpe
rand) => leftOperand; |
| 979 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe
rand14) { | 1286 EvaluationResultImpl remainderValid(BinaryExpression node, ValidResult leftOpe
rand14) { |
| 980 Object leftValue = leftOperand14.value; | 1287 Object leftValue = leftOperand14.value; |
| 981 if (leftValue == null) { | 1288 if (leftValue == null) { |
| 982 return error(node.leftOperand); | 1289 return error(node.leftOperand); |
| 983 } else if (_value == null) { | 1290 } else if (_value == null) { |
| 984 return error(node.rightOperand); | 1291 return error(node.rightOperand); |
| 985 } else if (leftValue is int) { | 1292 } else if (leftValue is int) { |
| 986 if (((_value as int)) == 0) { | |
| 987 return error2(node.rightOperand, CompileTimeErrorCode.COMPILE_TIME_CONST
ANT_RAISES_EXCEPTION_DIVIDE_BY_ZERO); | |
| 988 } | |
| 989 if (_value is int) { | 1293 if (_value is int) { |
| 1294 if (((_value as int)) == 0) { |
| 1295 return valueOf3(((leftValue as int)).toDouble() % ((_value as int)).to
Double()); |
| 1296 } |
| 990 return valueOf(((leftValue as int)).remainder((_value as int))); | 1297 return valueOf(((leftValue as int)).remainder((_value as int))); |
| 991 } else if (_value is double) { | 1298 } else if (_value is double) { |
| 992 return valueOf3(((leftValue as int)).toDouble() % ((_value as double))); | 1299 return valueOf3(((leftValue as int)).toDouble() % ((_value as double))); |
| 993 } | 1300 } |
| 994 } else if (leftValue is double) { | 1301 } else if (leftValue is double) { |
| 995 if (_value is int) { | 1302 if (_value is int) { |
| 996 return valueOf3(((leftValue as double)) % ((_value as int)).toDouble()); | 1303 return valueOf3(((leftValue as double)) % ((_value as int)).toDouble()); |
| 997 } else if (_value is double) { | 1304 } else if (_value is double) { |
| 998 return valueOf3(((leftValue as double)) % ((_value as double))); | 1305 return valueOf3(((leftValue as double)) % ((_value as double))); |
| 999 } | 1306 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1106 * @return a result object representing the given value | 1413 * @return a result object representing the given value |
| 1107 */ | 1414 */ |
| 1108 ValidResult valueOf3(double value) => new ValidResult(value); | 1415 ValidResult valueOf3(double value) => new ValidResult(value); |
| 1109 /** | 1416 /** |
| 1110 * Return a result object representing the given value. | 1417 * Return a result object representing the given value. |
| 1111 * @param value the value to be represented as a result object | 1418 * @param value the value to be represented as a result object |
| 1112 * @return a result object representing the given value | 1419 * @return a result object representing the given value |
| 1113 */ | 1420 */ |
| 1114 ValidResult valueOf4(String value) => new ValidResult(value); | 1421 ValidResult valueOf4(String value) => new ValidResult(value); |
| 1115 } | 1422 } |
| OLD | NEW |