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

Side by Side Diff: pkg/compiler/lib/src/compile_time_constants.dart

Issue 1068233002: Revert "Extract CallStructure from Selector." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 months 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
« no previous file with comments | « pkg/compiler/lib/src/common.dart ('k') | pkg/compiler/lib/src/constants/expressions.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of dart2js; 5 part of dart2js;
6 6
7 /// A [ConstantEnvironment] provides access for constants compiled for variable 7 /// A [ConstantEnvironment] provides access for constants compiled for variable
8 /// initializers. 8 /// initializers.
9 abstract class ConstantEnvironment { 9 abstract class ConstantEnvironment {
10 /// Returns the constant for the initializer of [element]. 10 /// Returns the constant for the initializer of [element].
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 437
438 AstConstant visitLiteralSymbol(LiteralSymbol node) { 438 AstConstant visitLiteralSymbol(LiteralSymbol node) {
439 InterfaceType type = compiler.symbolClass.rawType; 439 InterfaceType type = compiler.symbolClass.rawType;
440 String text = node.slowNameString; 440 String text = node.slowNameString;
441 List<AstConstant> arguments = 441 List<AstConstant> arguments =
442 <AstConstant>[new AstConstant(context, node, 442 <AstConstant>[new AstConstant(context, node,
443 new PrimitiveConstantExpression(constantSystem.createString( 443 new PrimitiveConstantExpression(constantSystem.createString(
444 new DartString.literal(text))))]; 444 new DartString.literal(text))))];
445 AstConstant constant = makeConstructedConstant( 445 AstConstant constant = makeConstructedConstant(
446 compiler, handler, context, node, type, compiler.symbolConstructor, 446 compiler, handler, context, node, type, compiler.symbolConstructor,
447 CallStructure.ONE_ARG, 447 new Selector.callConstructor('', null, 1),
448 arguments, arguments); 448 arguments, arguments);
449 return new AstConstant( 449 return new AstConstant(
450 context, node, new SymbolConstantExpression(constant.value, text)); 450 context, node, new SymbolConstantExpression(constant.value, text));
451 } 451 }
452 452
453 AstConstant makeTypeConstant(Node node, DartType elementType) { 453 AstConstant makeTypeConstant(Node node, DartType elementType) {
454 DartType constantType = 454 DartType constantType =
455 compiler.backend.typeImplementation.computeType(compiler); 455 compiler.backend.typeImplementation.computeType(compiler);
456 return new AstConstant( 456 return new AstConstant(
457 context, node, new TypeConstantExpression( 457 context, node, new TypeConstantExpression(
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 645
646 /** 646 /**
647 * Returns the normalized list of constant arguments that are passed to the 647 * Returns the normalized list of constant arguments that are passed to the
648 * constructor including both the concrete arguments and default values for 648 * constructor including both the concrete arguments and default values for
649 * omitted optional arguments. 649 * omitted optional arguments.
650 * 650 *
651 * Invariant: [target] must be an implementation element. 651 * Invariant: [target] must be an implementation element.
652 */ 652 */
653 List<AstConstant> evaluateArgumentsToConstructor( 653 List<AstConstant> evaluateArgumentsToConstructor(
654 Node node, 654 Node node,
655 CallStructure callStructure, 655 Selector selector,
656 Link<Node> arguments, 656 Link<Node> arguments,
657 FunctionElement target, 657 FunctionElement target,
658 {AstConstant compileArgument(Node node)}) { 658 {AstConstant compileArgument(Node node)}) {
659 assert(invariant(node, target.isImplementation)); 659 assert(invariant(node, target.isImplementation));
660 660
661 AstConstant compileDefaultValue(VariableElement element) { 661 AstConstant compileDefaultValue(VariableElement element) {
662 ConstantExpression constant = handler.compileConstant(element); 662 ConstantExpression constant = handler.compileConstant(element);
663 return new AstConstant.fromDefaultValue(element, constant); 663 return new AstConstant.fromDefaultValue(element, constant);
664 } 664 }
665 target.computeSignature(compiler); 665 target.computeSignature(compiler);
666 666
667 if (!callStructure.signatureApplies(target)) { 667 if (!selector.applies(target, compiler.world)) {
668 String name = Elements.constructorNameForDiagnostics( 668 String name = Elements.constructorNameForDiagnostics(
669 target.enclosingClass.name, target.name); 669 target.enclosingClass.name, target.name);
670 compiler.reportError( 670 compiler.reportError(
671 node, 671 node,
672 MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS, 672 MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS,
673 {'constructorName': name}); 673 {'constructorName': name});
674 674
675 return new List<AstConstant>.filled( 675 return new List<AstConstant>.filled(
676 target.functionSignature.parameterCount, 676 target.functionSignature.parameterCount,
677 new ErroneousAstConstant(context, node)); 677 new ErroneousAstConstant(context, node));
678 } 678 }
679 return callStructure.makeArgumentsList( 679 return selector.makeArgumentsList(arguments,
680 arguments, 680 target,
681 target, 681 compileArgument,
682 compileArgument, 682 compileDefaultValue);
683 compileDefaultValue);
684 } 683 }
685 684
686 AstConstant visitNewExpression(NewExpression node) { 685 AstConstant visitNewExpression(NewExpression node) {
687 if (!node.isConst) { 686 if (!node.isConst) {
688 return signalNotCompileTimeConstant(node); 687 return signalNotCompileTimeConstant(node);
689 } 688 }
690 689
691 Send send = node.send; 690 Send send = node.send;
692 FunctionElement constructor = elements[send]; 691 FunctionElement constructor = elements[send];
693 if (Elements.isUnresolved(constructor)) { 692 if (Elements.isUnresolved(constructor)) {
694 return signalNotCompileTimeConstant(node); 693 return signalNotCompileTimeConstant(node);
695 } 694 }
696 695
697 // Deferred types can not be used in const instance creation expressions. 696 // Deferred types can not be used in const instance creation expressions.
698 // Check if the constructor comes from a deferred library. 697 // Check if the constructor comes from a deferred library.
699 if (isDeferredUse(node.send.selector.asSend())) { 698 if (isDeferredUse(node.send.selector.asSend())) {
700 return signalNotCompileTimeConstant(node, 699 return signalNotCompileTimeConstant(node,
701 message: MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION); 700 message: MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION);
702 } 701 }
703 702
704 // TODO(ahe): This is nasty: we must eagerly analyze the 703 // TODO(ahe): This is nasty: we must eagerly analyze the
705 // constructor to ensure the redirectionTarget has been computed 704 // constructor to ensure the redirectionTarget has been computed
706 // correctly. Find a way to avoid this. 705 // correctly. Find a way to avoid this.
707 compiler.analyzeElement(constructor.declaration); 706 compiler.analyzeElement(constructor.declaration);
708 707
709 InterfaceType type = elements.getType(node); 708 InterfaceType type = elements.getType(node);
710 CallStructure callStructure = elements.getSelector(send).callStructure; 709 Selector selector = elements.getSelector(send);
711 710
712 Map<Node, AstConstant> concreteArgumentMap = 711 Map<Node, AstConstant> concreteArgumentMap =
713 <Node, AstConstant>{}; 712 <Node, AstConstant>{};
714 for (Link<Node> link = send.arguments; !link.isEmpty; link = link.tail) { 713 for (Link<Node> link = send.arguments; !link.isEmpty; link = link.tail) {
715 Node argument = link.head; 714 Node argument = link.head;
716 NamedArgument namedArgument = argument.asNamedArgument(); 715 NamedArgument namedArgument = argument.asNamedArgument();
717 if (namedArgument != null) { 716 if (namedArgument != null) {
718 argument = namedArgument.expression; 717 argument = namedArgument.expression;
719 } 718 }
720 concreteArgumentMap[argument] = evaluateConstant(argument); 719 concreteArgumentMap[argument] = evaluateConstant(argument);
721 } 720 }
722 721
723 List<AstConstant> normalizedArguments = 722 List<AstConstant> normalizedArguments =
724 evaluateArgumentsToConstructor( 723 evaluateArgumentsToConstructor(
725 node, callStructure, send.arguments, constructor.implementation, 724 node, selector, send.arguments, constructor.implementation,
726 compileArgument: (node) => concreteArgumentMap[node]); 725 compileArgument: (node) => concreteArgumentMap[node]);
727 List<AstConstant> concreteArguments = 726 List<AstConstant> concreteArguments =
728 concreteArgumentMap.values.toList(); 727 concreteArgumentMap.values.toList();
729 728
730 if (constructor == compiler.intEnvironment || 729 if (constructor == compiler.intEnvironment ||
731 constructor == compiler.boolEnvironment || 730 constructor == compiler.boolEnvironment ||
732 constructor == compiler.stringEnvironment) { 731 constructor == compiler.stringEnvironment) {
733 732
734 AstConstant createEvaluatedConstant(ConstantValue value) { 733 AstConstant createEvaluatedConstant(ConstantValue value) {
735 return new AstConstant( 734 return new AstConstant(
736 context, node, new ConstructedConstantExpression( 735 context, node, new ConstructedConstantExpression(
737 value, 736 value,
738 type, 737 type,
739 constructor, 738 constructor,
740 elements.getSelector(send).callStructure, 739 elements.getSelector(send),
741 concreteArguments.map((e) => e.expression).toList())); 740 concreteArguments.map((e) => e.expression).toList()));
742 } 741 }
743 742
744 var firstArgument = normalizedArguments[0].value; 743 var firstArgument = normalizedArguments[0].value;
745 ConstantValue defaultValue = normalizedArguments[1].value; 744 ConstantValue defaultValue = normalizedArguments[1].value;
746 745
747 if (firstArgument.isNull) { 746 if (firstArgument.isNull) {
748 compiler.reportError( 747 compiler.reportError(
749 send.arguments.head, MessageKind.NULL_NOT_ALLOWED); 748 send.arguments.head, MessageKind.NULL_NOT_ALLOWED);
750 return null; 749 return null;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 return createEvaluatedConstant(defaultValue); 804 return createEvaluatedConstant(defaultValue);
806 } 805 }
807 } else { 806 } else {
808 assert(constructor == compiler.stringEnvironment); 807 assert(constructor == compiler.stringEnvironment);
809 return createEvaluatedConstant( 808 return createEvaluatedConstant(
810 constantSystem.createString(new DartString.literal(value))); 809 constantSystem.createString(new DartString.literal(value)));
811 } 810 }
812 } else { 811 } else {
813 return makeConstructedConstant( 812 return makeConstructedConstant(
814 compiler, handler, context, 813 compiler, handler, context,
815 node, type, constructor, callStructure, 814 node, type, constructor, selector,
816 concreteArguments, normalizedArguments); 815 concreteArguments, normalizedArguments);
817 } 816 }
818 } 817 }
819 818
820 static AstConstant makeConstructedConstant( 819 static AstConstant makeConstructedConstant(
821 Compiler compiler, 820 Compiler compiler,
822 ConstantCompilerBase handler, 821 ConstantCompilerBase handler,
823 Element context, 822 Element context,
824 Node node, 823 Node node,
825 InterfaceType type, 824 InterfaceType type,
826 ConstructorElement constructor, 825 ConstructorElement constructor,
827 CallStructure callStructure, 826 Selector selector,
828 List<AstConstant> concreteArguments, 827 List<AstConstant> concreteArguments,
829 List<AstConstant> normalizedArguments) { 828 List<AstConstant> normalizedArguments) {
830 assert(invariant(node, callStructure.signatureApplies(constructor) || 829 assert(invariant(node, selector.applies(constructor, compiler.world) ||
831 compiler.compilationFailed, 830 compiler.compilationFailed,
832 message: "Call structure $callStructure does not apply to constructor " 831 message: "Selector $selector does not apply to constructor "
833 "$constructor.")); 832 "$constructor."));
834 833
835 // The redirection chain of this element may not have been resolved through 834 // The redirection chain of this element may not have been resolved through
836 // a post-process action, so we have to make sure it is done here. 835 // a post-process action, so we have to make sure it is done here.
837 compiler.resolver.resolveRedirectionChain(constructor, node); 836 compiler.resolver.resolveRedirectionChain(constructor, node);
838 InterfaceType constructedType = 837 InterfaceType constructedType =
839 constructor.computeEffectiveTargetType(type); 838 constructor.computeEffectiveTargetType(type);
840 ConstructorElement target = constructor.effectiveTarget; 839 ConstructorElement target = constructor.effectiveTarget;
841 ClassElement classElement = target.enclosingClass; 840 ClassElement classElement = target.enclosingClass;
842 // The constructor must be an implementation to ensure that field 841 // The constructor must be an implementation to ensure that field
843 // initializers are handled correctly. 842 // initializers are handled correctly.
844 target = target.implementation; 843 target = target.implementation;
845 assert(invariant(node, target.isImplementation)); 844 assert(invariant(node, target.isImplementation));
846 845
847 ConstructorEvaluator evaluator = new ConstructorEvaluator( 846 ConstructorEvaluator evaluator = new ConstructorEvaluator(
848 constructedType, target, handler, compiler); 847 constructedType, target, handler, compiler);
849 evaluator.evaluateConstructorFieldValues(normalizedArguments); 848 evaluator.evaluateConstructorFieldValues(normalizedArguments);
850 List<AstConstant> fieldConstants = 849 List<AstConstant> fieldConstants =
851 evaluator.buildFieldConstants(classElement); 850 evaluator.buildFieldConstants(classElement);
852 851
853 return new AstConstant( 852 return new AstConstant(
854 context, node, new ConstructedConstantExpression( 853 context, node, new ConstructedConstantExpression(
855 new ConstructedConstantValue( 854 new ConstructedConstantValue(
856 constructedType, 855 constructedType,
857 fieldConstants.map((e) => e.value).toList()), 856 fieldConstants.map((e) => e.value).toList()),
858 type, 857 type,
859 constructor, 858 constructor,
860 callStructure, 859 selector,
861 concreteArguments.map((e) => e.expression).toList())); 860 concreteArguments.map((e) => e.expression).toList()));
862 } 861 }
863 862
864 AstConstant visitParenthesizedExpression(ParenthesizedExpression node) { 863 AstConstant visitParenthesizedExpression(ParenthesizedExpression node) {
865 return node.expression.accept(this); 864 return node.expression.accept(this);
866 } 865 }
867 866
868 error(Node node, MessageKind message) { 867 error(Node node, MessageKind message) {
869 // TODO(floitsch): get the list of constants that are currently compiled 868 // TODO(floitsch): get the list of constants that are currently compiled
870 // and present some kind of stack-trace. 869 // and present some kind of stack-trace.
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 * Runs through the initializers of the given [constructor] and updates 987 * Runs through the initializers of the given [constructor] and updates
989 * the [fieldValues] map. 988 * the [fieldValues] map.
990 */ 989 */
991 void evaluateConstructorInitializers() { 990 void evaluateConstructorInitializers() {
992 if (constructor.isSynthesized) { 991 if (constructor.isSynthesized) {
993 List<AstConstant> compiledArguments = <AstConstant>[]; 992 List<AstConstant> compiledArguments = <AstConstant>[];
994 993
995 Function compileArgument = (element) => definitions[element]; 994 Function compileArgument = (element) => definitions[element];
996 Function compileConstant = handler.compileConstant; 995 Function compileConstant = handler.compileConstant;
997 FunctionElement target = constructor.definingConstructor.implementation; 996 FunctionElement target = constructor.definingConstructor.implementation;
998 CallStructure.addForwardingElementArgumentsToList( 997 Selector.addForwardingElementArgumentsToList(constructor,
999 constructor, 998 compiledArguments,
1000 compiledArguments, 999 target,
1001 target, 1000 compileArgument,
1002 compileArgument, 1001 compileConstant,
1003 compileConstant); 1002 compiler.world);
1004 evaluateSuperOrRedirectSend(compiledArguments, target); 1003 evaluateSuperOrRedirectSend(compiledArguments, target);
1005 return; 1004 return;
1006 } 1005 }
1007 FunctionExpression functionNode = constructor.node; 1006 FunctionExpression functionNode = constructor.node;
1008 NodeList initializerList = functionNode.initializers; 1007 NodeList initializerList = functionNode.initializers;
1009 1008
1010 bool foundSuperOrRedirect = false; 1009 bool foundSuperOrRedirect = false;
1011 1010
1012 if (initializerList != null) { 1011 if (initializerList != null) {
1013 for (Link<Node> link = initializerList.nodes; 1012 for (Link<Node> link = initializerList.nodes;
1014 !link.isEmpty; 1013 !link.isEmpty;
1015 link = link.tail) { 1014 link = link.tail) {
1016 assert(link.head is Send); 1015 assert(link.head is Send);
1017 if (link.head is !SendSet) { 1016 if (link.head is !SendSet) {
1018 // A super initializer or constructor redirection. 1017 // A super initializer or constructor redirection.
1019 Send call = link.head; 1018 Send call = link.head;
1020 FunctionElement target = elements[call]; 1019 FunctionElement target = elements[call];
1021 List<AstConstant> compiledArguments = 1020 List<AstConstant> compiledArguments =
1022 evaluateArgumentsToConstructor( 1021 evaluateArgumentsToConstructor(
1023 call, elements.getSelector(call).callStructure, 1022 call, elements.getSelector(call), call.arguments, target,
1024 call.arguments, target,
1025 compileArgument: evaluateConstant); 1023 compileArgument: evaluateConstant);
1026 evaluateSuperOrRedirectSend(compiledArguments, target); 1024 evaluateSuperOrRedirectSend(compiledArguments, target);
1027 foundSuperOrRedirect = true; 1025 foundSuperOrRedirect = true;
1028 } else { 1026 } else {
1029 // A field initializer. 1027 // A field initializer.
1030 SendSet init = link.head; 1028 SendSet init = link.head;
1031 Link<Node> initArguments = init.arguments; 1029 Link<Node> initArguments = init.arguments;
1032 assert(!initArguments.isEmpty && initArguments.tail.isEmpty); 1030 assert(!initArguments.isEmpty && initArguments.tail.isEmpty);
1033 AstConstant fieldValue = evaluate(initArguments.head); 1031 AstConstant fieldValue = evaluate(initArguments.head);
1034 updateFieldValue(init, elements[init], fieldValue); 1032 updateFieldValue(init, elements[init], fieldValue);
1035 } 1033 }
1036 } 1034 }
1037 } 1035 }
1038 1036
1039 if (!foundSuperOrRedirect) { 1037 if (!foundSuperOrRedirect) {
1040 // No super initializer found. Try to find the default constructor if 1038 // No super initializer found. Try to find the default constructor if
1041 // the class is not Object. 1039 // the class is not Object.
1042 ClassElement enclosingClass = constructor.enclosingClass; 1040 ClassElement enclosingClass = constructor.enclosingClass;
1043 ClassElement superClass = enclosingClass.superclass; 1041 ClassElement superClass = enclosingClass.superclass;
1044 if (enclosingClass != compiler.objectClass) { 1042 if (enclosingClass != compiler.objectClass) {
1045 assert(superClass != null); 1043 assert(superClass != null);
1046 assert(superClass.resolutionState == STATE_DONE); 1044 assert(superClass.resolutionState == STATE_DONE);
1047 1045
1048 FunctionElement targetConstructor = 1046 FunctionElement targetConstructor =
1049 superClass.lookupDefaultConstructor(); 1047 superClass.lookupDefaultConstructor();
1050 // If we do not find a default constructor, an error was reported 1048 // If we do not find a default constructor, an error was reported
1051 // already and compilation will fail anyway. So just ignore that case. 1049 // already and compilation will fail anyway. So just ignore that case.
1052 if (targetConstructor != null) { 1050 if (targetConstructor != null) {
1051 Selector selector = new Selector.callDefaultConstructor();
1053 List<AstConstant> compiledArguments = evaluateArgumentsToConstructor( 1052 List<AstConstant> compiledArguments = evaluateArgumentsToConstructor(
1054 functionNode, CallStructure.NO_ARGS, 1053 functionNode, selector, const Link<Node>(), targetConstructor);
1055 const Link<Node>(), targetConstructor);
1056 evaluateSuperOrRedirectSend(compiledArguments, targetConstructor); 1054 evaluateSuperOrRedirectSend(compiledArguments, targetConstructor);
1057 } 1055 }
1058 } 1056 }
1059 } 1057 }
1060 } 1058 }
1061 1059
1062 /** 1060 /**
1063 * Simulates the execution of the [constructor] with the given 1061 * Simulates the execution of the [constructor] with the given
1064 * [arguments] to obtain the field values that need to be passed to the 1062 * [arguments] to obtain the field values that need to be passed to the
1065 * native JavaScript constructor. 1063 * native JavaScript constructor.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 ConstantValue get value => expression.value; 1117 ConstantValue get value => expression.value;
1120 1118
1121 String toString() => expression.toString(); 1119 String toString() => expression.toString();
1122 } 1120 }
1123 1121
1124 /// A synthetic constant used to recover from errors. 1122 /// A synthetic constant used to recover from errors.
1125 class ErroneousAstConstant extends AstConstant { 1123 class ErroneousAstConstant extends AstConstant {
1126 ErroneousAstConstant(Element element, Node node) 1124 ErroneousAstConstant(Element element, Node node)
1127 : super(element, node, new ErroneousConstantExpression()); 1125 : super(element, node, new ErroneousConstantExpression());
1128 } 1126 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/common.dart ('k') | pkg/compiler/lib/src/constants/expressions.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698