| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * The [ConstantHandler] keeps track of compile-time constants, | 6 * The [ConstantHandler] keeps track of compile-time constants, |
| 7 * initializations of global and static fields, and default values of | 7 * initializations of global and static fields, and default values of |
| 8 * optional parameters. | 8 * optional parameters. |
| 9 */ | 9 */ |
| 10 class ConstantHandler extends CompilerTask { | 10 class ConstantHandler extends CompilerTask { |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 return folded; | 523 return folded; |
| 524 } | 524 } |
| 525 return signalNotCompileTimeConstant(send); | 525 return signalNotCompileTimeConstant(send); |
| 526 } | 526 } |
| 527 | 527 |
| 528 Constant visitSendSet(SendSet node) { | 528 Constant visitSendSet(SendSet node) { |
| 529 return signalNotCompileTimeConstant(node); | 529 return signalNotCompileTimeConstant(node); |
| 530 } | 530 } |
| 531 | 531 |
| 532 /** Returns the list of constants that are passed to the static function. */ | 532 /** Returns the list of constants that are passed to the static function. */ |
| 533 List<Constant> evaluateArgumentsToConstructor(Selector selector, | 533 List<Constant> evaluateArgumentsToConstructor(Node node, |
| 534 Selector selector, |
| 534 Link<Node> arguments, | 535 Link<Node> arguments, |
| 535 FunctionElement target) { | 536 FunctionElement target) { |
| 536 List<Constant> compiledArguments = <Constant>[]; | 537 List<Constant> compiledArguments = <Constant>[]; |
| 537 | 538 |
| 538 Function compileArgument = evaluateConstant; | 539 Function compileArgument = evaluateConstant; |
| 539 Function compileConstant = compiler.compileConstant; | 540 Function compileConstant = compiler.compileConstant; |
| 540 bool succeeded = selector.addArgumentsToList(arguments, | 541 bool succeeded = selector.addArgumentsToList(arguments, |
| 541 compiledArguments, | 542 compiledArguments, |
| 542 target, | 543 target, |
| 543 compileArgument, | 544 compileArgument, |
| 544 compileConstant, | 545 compileConstant, |
| 545 compiler); | 546 compiler); |
| 546 assert(succeeded); | 547 if (!succeeded) { |
| 548 MessageKind kind = MessageKind.INVALID_ARGUMENTS; |
| 549 compiler.reportError(node, |
| 550 new CompileTimeConstantError(kind, [target.name.slowToString()])); |
| 551 } |
| 547 return compiledArguments; | 552 return compiledArguments; |
| 548 } | 553 } |
| 549 | 554 |
| 550 Constant visitNewExpression(NewExpression node) { | 555 Constant visitNewExpression(NewExpression node) { |
| 551 if (!node.isConst()) { | 556 if (!node.isConst()) { |
| 552 return signalNotCompileTimeConstant(node); | 557 return signalNotCompileTimeConstant(node); |
| 553 } | 558 } |
| 554 | 559 |
| 555 Send send = node.send; | 560 Send send = node.send; |
| 556 FunctionElement constructor = elements[send]; | 561 FunctionElement constructor = elements[send]; |
| 557 ClassElement classElement = constructor.getEnclosingClass(); | 562 ClassElement classElement = constructor.getEnclosingClass(); |
| 558 if (classElement.isInterface()) { | 563 if (classElement.isInterface()) { |
| 559 compiler.resolver.resolveMethodElement(constructor); | 564 compiler.resolver.resolveMethodElement(constructor); |
| 560 constructor = constructor.defaultImplementation; | 565 constructor = constructor.defaultImplementation; |
| 561 classElement = constructor.getEnclosingClass(); | 566 classElement = constructor.getEnclosingClass(); |
| 562 } | 567 } |
| 563 | 568 |
| 564 Selector selector = elements.getSelector(send); | 569 Selector selector = elements.getSelector(send); |
| 565 List<Constant> arguments = | 570 List<Constant> arguments = evaluateArgumentsToConstructor( |
| 566 evaluateArgumentsToConstructor(selector, send.arguments, constructor); | 571 node, selector, send.arguments, constructor); |
| 567 ConstructorEvaluator evaluator = | 572 ConstructorEvaluator evaluator = |
| 568 new ConstructorEvaluator(constructor, constantSystem, compiler); | 573 new ConstructorEvaluator(constructor, constantSystem, compiler); |
| 569 evaluator.evaluateConstructorFieldValues(arguments); | 574 evaluator.evaluateConstructorFieldValues(arguments); |
| 570 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement); | 575 List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement); |
| 571 | 576 |
| 572 compiler.enqueuer.codegen.registerInstantiatedClass(classElement); | 577 compiler.enqueuer.codegen.registerInstantiatedClass(classElement); |
| 573 // TODO(floitsch): take generic types into account. | 578 // TODO(floitsch): take generic types into account. |
| 574 DartType type = classElement.computeType(compiler); | 579 DartType type = classElement.computeType(compiler); |
| 575 Constant constant = new ConstructedConstant(type, jsNewArguments); | 580 Constant constant = new ConstructedConstant(type, jsNewArguments); |
| 576 compiler.constantHandler.registerCompileTimeConstant(constant); | 581 compiler.constantHandler.registerCompileTimeConstant(constant); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 Node node = parameter.parseNode(compiler); | 680 Node node = parameter.parseNode(compiler); |
| 676 potentiallyCheckType(node, parameter, argument); | 681 potentiallyCheckType(node, parameter, argument); |
| 677 definitions[parameter] = argument; | 682 definitions[parameter] = argument; |
| 678 if (parameter.kind == ElementKind.FIELD_PARAMETER) { | 683 if (parameter.kind == ElementKind.FIELD_PARAMETER) { |
| 679 FieldParameterElement fieldParameterElement = parameter; | 684 FieldParameterElement fieldParameterElement = parameter; |
| 680 updateFieldValue(node, fieldParameterElement.fieldElement, argument); | 685 updateFieldValue(node, fieldParameterElement.fieldElement, argument); |
| 681 } | 686 } |
| 682 }); | 687 }); |
| 683 } | 688 } |
| 684 | 689 |
| 685 void evaluateSuperOrRedirectSend(Selector selector, | 690 void evaluateSuperOrRedirectSend(Node currentNode, |
| 691 Selector selector, |
| 686 Link<Node> arguments, | 692 Link<Node> arguments, |
| 687 FunctionElement targetConstructor) { | 693 FunctionElement targetConstructor) { |
| 688 List<Constant> compiledArguments = | 694 List<Constant> compiledArguments = evaluateArgumentsToConstructor( |
| 689 evaluateArgumentsToConstructor(selector, arguments, targetConstructor); | 695 currentNode, selector, arguments, targetConstructor); |
| 690 | 696 |
| 691 ConstructorEvaluator evaluator = new ConstructorEvaluator( | 697 ConstructorEvaluator evaluator = new ConstructorEvaluator( |
| 692 targetConstructor, constantSystem, compiler); | 698 targetConstructor, constantSystem, compiler); |
| 693 evaluator.evaluateConstructorFieldValues(compiledArguments); | 699 evaluator.evaluateConstructorFieldValues(compiledArguments); |
| 694 // Copy over the fieldValues from the super/redirect-constructor. | 700 // Copy over the fieldValues from the super/redirect-constructor. |
| 695 // No need to go through [updateFieldValue] because the | 701 // No need to go through [updateFieldValue] because the |
| 696 // assignments have already been checked in checked mode. | 702 // assignments have already been checked in checked mode. |
| 697 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value); | 703 evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value); |
| 698 } | 704 } |
| 699 | 705 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 711 for (Link<Node> link = initializerList.nodes; | 717 for (Link<Node> link = initializerList.nodes; |
| 712 !link.isEmpty(); | 718 !link.isEmpty(); |
| 713 link = link.tail) { | 719 link = link.tail) { |
| 714 assert(link.head is Send); | 720 assert(link.head is Send); |
| 715 if (link.head is !SendSet) { | 721 if (link.head is !SendSet) { |
| 716 // A super initializer or constructor redirection. | 722 // A super initializer or constructor redirection. |
| 717 Send call = link.head; | 723 Send call = link.head; |
| 718 FunctionElement targetConstructor = elements[call]; | 724 FunctionElement targetConstructor = elements[call]; |
| 719 Selector selector = elements.getSelector(call); | 725 Selector selector = elements.getSelector(call); |
| 720 Link<Node> arguments = call.arguments; | 726 Link<Node> arguments = call.arguments; |
| 721 evaluateSuperOrRedirectSend(selector, arguments, targetConstructor); | 727 evaluateSuperOrRedirectSend( |
| 728 call, selector, arguments, targetConstructor); |
| 722 foundSuperOrRedirect = true; | 729 foundSuperOrRedirect = true; |
| 723 } else { | 730 } else { |
| 724 // A field initializer. | 731 // A field initializer. |
| 725 SendSet init = link.head; | 732 SendSet init = link.head; |
| 726 Link<Node> initArguments = init.arguments; | 733 Link<Node> initArguments = init.arguments; |
| 727 assert(!initArguments.isEmpty() && initArguments.tail.isEmpty()); | 734 assert(!initArguments.isEmpty() && initArguments.tail.isEmpty()); |
| 728 Constant fieldValue = evaluate(initArguments.head); | 735 Constant fieldValue = evaluate(initArguments.head); |
| 729 updateFieldValue(init, elements[init], fieldValue); | 736 updateFieldValue(init, elements[init], fieldValue); |
| 730 } | 737 } |
| 731 } | 738 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 742 FunctionElement targetConstructor = | 749 FunctionElement targetConstructor = |
| 743 superClass.lookupConstructor(superClass.name); | 750 superClass.lookupConstructor(superClass.name); |
| 744 if (targetConstructor === null) { | 751 if (targetConstructor === null) { |
| 745 compiler.internalError("no default constructor available", | 752 compiler.internalError("no default constructor available", |
| 746 node: functionNode); | 753 node: functionNode); |
| 747 } | 754 } |
| 748 | 755 |
| 749 Selector selector = new Selector.call(superClass.name, | 756 Selector selector = new Selector.call(superClass.name, |
| 750 enclosingClass.getLibrary(), | 757 enclosingClass.getLibrary(), |
| 751 0); | 758 0); |
| 752 evaluateSuperOrRedirectSend(selector, | 759 evaluateSuperOrRedirectSend(functionNode, |
| 760 selector, |
| 753 const EmptyLink<Node>(), | 761 const EmptyLink<Node>(), |
| 754 targetConstructor); | 762 targetConstructor); |
| 755 } | 763 } |
| 756 } | 764 } |
| 757 } | 765 } |
| 758 | 766 |
| 759 /** | 767 /** |
| 760 * Simulates the execution of the [constructor] with the given | 768 * Simulates the execution of the [constructor] with the given |
| 761 * [arguments] to obtain the field values that need to be passed to the | 769 * [arguments] to obtain the field values that need to be passed to the |
| 762 * native JavaScript constructor. | 770 * native JavaScript constructor. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 777 Constant fieldValue = fieldValues[field]; | 785 Constant fieldValue = fieldValues[field]; |
| 778 if (fieldValue === null) { | 786 if (fieldValue === null) { |
| 779 // Use the default value. | 787 // Use the default value. |
| 780 fieldValue = compiler.compileConstant(field); | 788 fieldValue = compiler.compileConstant(field); |
| 781 } | 789 } |
| 782 jsNewArguments.add(fieldValue); | 790 jsNewArguments.add(fieldValue); |
| 783 }); | 791 }); |
| 784 return jsNewArguments; | 792 return jsNewArguments; |
| 785 } | 793 } |
| 786 } | 794 } |
| OLD | NEW |