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

Side by Side Diff: pkg/compiler/lib/src/kernel/element_map.dart

Issue 2916393002: Compute constants from IR nodes (Closed)
Patch Set: Updated cf. comments Created 3 years, 6 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
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../common/names.dart'; 8 import '../common/names.dart';
9 import '../constants/constructors.dart'; 9 import '../constants/constructors.dart';
10 import '../constants/expressions.dart'; 10 import '../constants/expressions.dart';
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 ir.StaticInvocation node); 140 ir.StaticInvocation node);
141 141
142 /// Compute the kind of foreign helper function called by [node], if any. 142 /// Compute the kind of foreign helper function called by [node], if any.
143 ForeignKind getForeignKind(ir.StaticInvocation node); 143 ForeignKind getForeignKind(ir.StaticInvocation node);
144 144
145 /// Computes the [InterfaceType] referenced by a call to the 145 /// Computes the [InterfaceType] referenced by a call to the
146 /// [JS_INTERCEPTOR_CONSTANT] function, if any. 146 /// [JS_INTERCEPTOR_CONSTANT] function, if any.
147 InterfaceType getInterfaceTypeForJsInterceptorCall(ir.StaticInvocation node); 147 InterfaceType getInterfaceTypeForJsInterceptorCall(ir.StaticInvocation node);
148 148
149 /// Computes the [ConstantValue] for the constant [expression]. 149 /// Computes the [ConstantValue] for the constant [expression].
150 ConstantValue getConstantValue(ir.Expression expression); 150 ConstantValue getConstantValue(ir.Expression expression,
151 {bool requireConstant: true});
151 152
152 /// Returns the `noSuchMethod` [FunctionEntity] call from a 153 /// Returns the `noSuchMethod` [FunctionEntity] call from a
153 /// `super.noSuchMethod` invocation within [cls]. 154 /// `super.noSuchMethod` invocation within [cls].
154 FunctionEntity getSuperNoSuchMethod(ClassEntity cls); 155 FunctionEntity getSuperNoSuchMethod(ClassEntity cls);
155 156
156 /// Returns a [Spannable] for a message pointing to the IR [node] in the 157 /// Returns a [Spannable] for a message pointing to the IR [node] in the
157 /// context of [member]. 158 /// context of [member].
158 Spannable getSpannable(MemberEntity member, ir.Node node); 159 Spannable getSpannable(MemberEntity member, ir.Node node);
159 } 160 }
160 161
161 /// Kinds of foreign functions. 162 /// Kinds of foreign functions.
162 enum ForeignKind { 163 enum ForeignKind {
163 JS, 164 JS,
164 JS_BUILTIN, 165 JS_BUILTIN,
165 JS_EMBEDDED_GLOBAL, 166 JS_EMBEDDED_GLOBAL,
166 JS_INTERCEPTOR_CONSTANT, 167 JS_INTERCEPTOR_CONSTANT,
167 NONE, 168 NONE,
168 } 169 }
169 170
170 abstract class KernelToElementMapMixin implements KernelToElementMap { 171 abstract class KernelToElementMapMixin implements KernelToElementMap {
171 DiagnosticReporter get reporter; 172 DiagnosticReporter get reporter;
172 native.BehaviorBuilder get nativeBehaviorBuilder; 173 native.BehaviorBuilder get nativeBehaviorBuilder;
173 ConstantValue computeConstantValue(ConstantExpression constant); 174 ConstantValue computeConstantValue(ConstantExpression constant,
175 {bool requireConstant: true});
174 176
175 @override 177 @override
176 Name getName(ir.Name name) { 178 Name getName(ir.Name name) {
177 return new Name( 179 return new Name(
178 name.name, name.isPrivate ? getLibrary(name.library) : null); 180 name.name, name.isPrivate ? getLibrary(name.library) : null);
179 } 181 }
180 182
181 @override 183 @override
182 CallStructure getCallStructure(ir.Arguments arguments) { 184 CallStructure getCallStructure(ir.Arguments arguments) {
183 int argumentCount = arguments.positional.length + arguments.named.length; 185 int argumentCount = arguments.positional.length + arguments.named.length;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 irName.name, irName.isPrivate ? getLibrary(irName.library) : null); 235 irName.name, irName.isPrivate ? getLibrary(irName.library) : null);
234 return new Selector.getter(name); 236 return new Selector.getter(name);
235 } 237 }
236 238
237 Selector getSetterSelector(ir.Name irName) { 239 Selector getSetterSelector(ir.Name irName) {
238 Name name = new Name( 240 Name name = new Name(
239 irName.name, irName.isPrivate ? getLibrary(irName.library) : null); 241 irName.name, irName.isPrivate ? getLibrary(irName.library) : null);
240 return new Selector.setter(name); 242 return new Selector.setter(name);
241 } 243 }
242 244
243 ConstantValue getConstantValue(ir.Expression node) { 245 ConstantValue getConstantValue(ir.Expression node,
244 ConstantExpression constant = new Constantifier(this).visit(node); 246 {bool requireConstant: true}) {
247 ConstantExpression constant =
248 new Constantifier(this, requireConstant: requireConstant).visit(node);
245 if (constant == null) { 249 if (constant == null) {
246 throw new UnsupportedError( 250 if (requireConstant) {
247 'No constant for ${DebugPrinter.prettyPrint(node)}'); 251 throw new UnsupportedError(
252 'No constant for ${DebugPrinter.prettyPrint(node)}');
253 }
254 return null;
248 } 255 }
249 return computeConstantValue(constant); 256 return computeConstantValue(constant, requireConstant: requireConstant);
250 } 257 }
251 258
252 /// Converts [annotations] into a list of [ConstantValue]s. 259 /// Converts [annotations] into a list of [ConstantValue]s.
253 List<ConstantValue> getMetadata(List<ir.Expression> annotations) { 260 List<ConstantValue> getMetadata(List<ir.Expression> annotations) {
254 if (annotations.isEmpty) return const <ConstantValue>[]; 261 if (annotations.isEmpty) return const <ConstantValue>[];
255 List<ConstantValue> metadata = <ConstantValue>[]; 262 List<ConstantValue> metadata = <ConstantValue>[];
256 annotations.forEach((ir.Expression node) { 263 annotations.forEach((ir.Expression node) {
257 metadata.add(getConstantValue(node)); 264 metadata.add(getConstantValue(node));
258 }); 265 });
259 return metadata; 266 return metadata;
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 ConstantExpression visit(ir.Expression node) { 550 ConstantExpression visit(ir.Expression node) {
544 ConstantExpression constant = node.accept(this); 551 ConstantExpression constant = node.accept(this);
545 if (constant == null && requireConstant) { 552 if (constant == null && requireConstant) {
546 throw new UnsupportedError( 553 throw new UnsupportedError(
547 "No constant computed for $node (${node.runtimeType})"); 554 "No constant computed for $node (${node.runtimeType})");
548 } 555 }
549 return constant; 556 return constant;
550 } 557 }
551 558
552 ConstantExpression defaultExpression(ir.Expression node) { 559 ConstantExpression defaultExpression(ir.Expression node) {
553 throw new UnimplementedError( 560 if (requireConstant) {
554 'Unimplemented constant expression $node (${node.runtimeType})'); 561 throw new UnimplementedError(
562 'Unimplemented constant expression $node (${node.runtimeType})');
563 }
564 return null;
555 } 565 }
556 566
557 List<ConstantExpression> _computeList(List<ir.Expression> expressions) { 567 List<ConstantExpression> _computeList(List<ir.Expression> expressions) {
558 List<ConstantExpression> list = <ConstantExpression>[]; 568 List<ConstantExpression> list = <ConstantExpression>[];
559 for (ir.Expression expression in expressions) { 569 for (ir.Expression expression in expressions) {
560 ConstantExpression constant = visit(expression); 570 ConstantExpression constant = visit(expression);
561 if (constant == null) return null; 571 if (constant == null) return null;
562 list.add(constant); 572 list.add(constant);
563 } 573 }
564 return list; 574 return list;
565 } 575 }
566 576
567 List<ConstantExpression> _computeArguments(ir.Arguments node) { 577 List<ConstantExpression> _computeArguments(ir.Arguments node) {
568 List<ConstantExpression> arguments = <ConstantExpression>[]; 578 List<ConstantExpression> arguments = <ConstantExpression>[];
569 for (ir.Expression argument in node.positional) { 579 for (ir.Expression argument in node.positional) {
570 ConstantExpression constant = visit(argument); 580 ConstantExpression constant = visit(argument);
571 if (constant == null) return null; 581 if (constant == null) return null;
572 arguments.add(constant); 582 arguments.add(constant);
573 } 583 }
574 for (ir.NamedExpression argument in node.named) { 584 for (ir.NamedExpression argument in node.named) {
575 ConstantExpression constant = visit(argument.value); 585 ConstantExpression constant = visit(argument.value);
576 if (constant == null) return null; 586 if (constant == null) return null;
577 arguments.add(constant); 587 arguments.add(constant);
578 } 588 }
579 return arguments; 589 return arguments;
580 } 590 }
581 591
582 ConstructedConstantExpression _computeConstructorInvocation( 592 ConstructedConstantExpression _computeConstructorInvocation(
583 ir.Constructor target, ir.Arguments arguments) { 593 ir.Constructor target, ir.Arguments arguments) {
594 List<ConstantExpression> expressions = _computeArguments(arguments);
595 if (expressions == null) return null;
584 return new ConstructedConstantExpression( 596 return new ConstructedConstantExpression(
585 elementAdapter.createInterfaceType( 597 elementAdapter.createInterfaceType(
586 target.enclosingClass, arguments.types), 598 target.enclosingClass, arguments.types),
587 elementAdapter.getConstructor(target), 599 elementAdapter.getConstructor(target),
588 elementAdapter.getCallStructure(arguments), 600 elementAdapter.getCallStructure(arguments),
589 _computeArguments(arguments)); 601 expressions);
590 } 602 }
591 603
592 @override 604 @override
593 ConstantExpression visitConstructorInvocation(ir.ConstructorInvocation node) { 605 ConstantExpression visitConstructorInvocation(ir.ConstructorInvocation node) {
594 return _computeConstructorInvocation(node.target, node.arguments); 606 return _computeConstructorInvocation(node.target, node.arguments);
595 } 607 }
596 608
597 @override 609 @override
598 ConstantExpression visitVariableGet(ir.VariableGet node) { 610 ConstantExpression visitVariableGet(ir.VariableGet node) {
599 if (node.variable.parent is ir.FunctionNode) { 611 if (node.variable.parent is ir.FunctionNode) {
600 ir.FunctionNode function = node.variable.parent; 612 ir.FunctionNode function = node.variable.parent;
601 int index = function.positionalParameters.indexOf(node.variable); 613 int index = function.positionalParameters.indexOf(node.variable);
602 if (index != -1) { 614 if (index != -1) {
603 return new PositionalArgumentReference(index); 615 return new PositionalArgumentReference(index);
604 } else { 616 } else {
605 assert(function.namedParameters.contains(node.variable)); 617 assert(function.namedParameters.contains(node.variable));
606 return new NamedArgumentReference(node.variable.name); 618 return new NamedArgumentReference(node.variable.name);
607 } 619 }
620 } else if (node.variable.isConst) {
621 return visit(node.variable.initializer);
608 } 622 }
609 throw new UnimplementedError( 623 return defaultExpression(node);
610 'Unimplemented constant expression $node (${node.runtimeType})');
611 } 624 }
612 625
613 @override 626 @override
614 ConstantExpression visitStaticGet(ir.StaticGet node) { 627 ConstantExpression visitStaticGet(ir.StaticGet node) {
615 if (node.target is ir.Field) { 628 ir.Member target = node.target;
629 if (target is ir.Field && target.isConst) {
616 return new FieldConstantExpression(elementAdapter.getField(node.target)); 630 return new FieldConstantExpression(elementAdapter.getField(node.target));
617 } else if (node.target is ir.Procedure) { 631 } else if (node.target is ir.Procedure) {
618 FunctionEntity function = elementAdapter.getMethod(node.target); 632 FunctionEntity function = elementAdapter.getMethod(node.target);
619 DartType type = elementAdapter.getFunctionType(node.target.function); 633 DartType type = elementAdapter.getFunctionType(node.target.function);
620 return new FunctionConstantExpression(function, type); 634 return new FunctionConstantExpression(function, type);
621 } 635 }
622 throw new UnimplementedError( 636 return defaultExpression(node);
623 'Unexpected constant expression $node (${node.runtimeType})');
624 } 637 }
625 638
626 @override 639 @override
627 ConstantExpression visitNullLiteral(ir.NullLiteral node) { 640 ConstantExpression visitNullLiteral(ir.NullLiteral node) {
628 return new NullConstantExpression(); 641 return new NullConstantExpression();
629 } 642 }
630 643
631 @override 644 @override
632 ConstantExpression visitBoolLiteral(ir.BoolLiteral node) { 645 ConstantExpression visitBoolLiteral(ir.BoolLiteral node) {
633 return new BoolConstantExpression(node.value); 646 return new BoolConstantExpression(node.value);
(...skipping 14 matching lines...) Expand all
648 return new StringConstantExpression(node.value); 661 return new StringConstantExpression(node.value);
649 } 662 }
650 663
651 @override 664 @override
652 ConstantExpression visitSymbolLiteral(ir.SymbolLiteral node) { 665 ConstantExpression visitSymbolLiteral(ir.SymbolLiteral node) {
653 return new SymbolConstantExpression(node.value); 666 return new SymbolConstantExpression(node.value);
654 } 667 }
655 668
656 @override 669 @override
657 ConstantExpression visitStringConcatenation(ir.StringConcatenation node) { 670 ConstantExpression visitStringConcatenation(ir.StringConcatenation node) {
658 return new ConcatenateConstantExpression(_computeList(node.expressions)); 671 List<ConstantExpression> expressions = _computeList(node.expressions);
672 if (expressions == null) return null;
673 return new ConcatenateConstantExpression(expressions);
659 } 674 }
660 675
661 @override 676 @override
662 ConstantExpression visitMapLiteral(ir.MapLiteral node) { 677 ConstantExpression visitMapLiteral(ir.MapLiteral node) {
663 if (!node.isConst) { 678 if (!node.isConst) {
664 throw new UnimplementedError( 679 return defaultExpression(node);
665 'Unexpected constant expression $node (${node.runtimeType})');
666 } 680 }
667 DartType keyType = elementAdapter.getDartType(node.keyType); 681 DartType keyType = elementAdapter.getDartType(node.keyType);
668 DartType valueType = elementAdapter.getDartType(node.valueType); 682 DartType valueType = elementAdapter.getDartType(node.valueType);
669 List<ConstantExpression> keys = <ConstantExpression>[]; 683 List<ConstantExpression> keys = <ConstantExpression>[];
670 List<ConstantExpression> values = <ConstantExpression>[]; 684 List<ConstantExpression> values = <ConstantExpression>[];
671 for (ir.MapEntry entry in node.entries) { 685 for (ir.MapEntry entry in node.entries) {
672 keys.add(visit(entry.key)); 686 ConstantExpression key = visit(entry.key);
673 values.add(visit(entry.value)); 687 if (key == null) return null;
688 keys.add(key);
689 ConstantExpression value = visit(entry.value);
690 if (value == null) return null;
691 values.add(value);
674 } 692 }
675 return new MapConstantExpression( 693 return new MapConstantExpression(
676 _commonElements.mapType(keyType, valueType), keys, values); 694 _commonElements.mapType(keyType, valueType), keys, values);
677 } 695 }
678 696
679 @override 697 @override
680 ConstantExpression visitListLiteral(ir.ListLiteral node) { 698 ConstantExpression visitListLiteral(ir.ListLiteral node) {
681 if (!node.isConst) { 699 if (!node.isConst) {
682 throw new UnimplementedError( 700 return defaultExpression(node);
683 'Unexpected constant expression $node (${node.runtimeType})');
684 } 701 }
685 DartType elementType = elementAdapter.getDartType(node.typeArgument); 702 DartType elementType = elementAdapter.getDartType(node.typeArgument);
686 List<ConstantExpression> values = <ConstantExpression>[]; 703 List<ConstantExpression> values = <ConstantExpression>[];
687 for (ir.Expression value in node.expressions) { 704 for (ir.Expression expression in node.expressions) {
688 values.add(visit(value)); 705 ConstantExpression value = visit(expression);
706 if (value == null) return null;
707 values.add(value);
689 } 708 }
690 return new ListConstantExpression( 709 return new ListConstantExpression(
691 _commonElements.listType(elementType), values); 710 _commonElements.listType(elementType), values);
692 } 711 }
693 712
694 @override 713 @override
714 ConstantExpression visitTypeLiteral(ir.TypeLiteral node) {
715 DartType type = elementAdapter.getDartType(node.type);
716 String name;
717 if (type.isDynamic) {
718 name = 'dynamic';
719 } else if (type is InterfaceType) {
720 name = type.element.name;
721 } else if (type.isFunctionType || type.isTypedef) {
722 // TODO(johnniwinther): Compute a name for the type literal? It is only
723 // used in error messages in the old SSA builder.
724 name = '?';
725 } else {
726 return defaultExpression(node);
727 }
728 return new TypeConstantExpression(type, name);
729 }
730
731 @override
732 ConstantExpression visitNot(ir.Not node) {
733 ConstantExpression expression = visit(node.operand);
734 if (expression == null) return null;
735 return new UnaryConstantExpression(UnaryOperator.NOT, expression);
736 }
737
738 @override
695 ConstantExpression visitConditionalExpression(ir.ConditionalExpression node) { 739 ConstantExpression visitConditionalExpression(ir.ConditionalExpression node) {
696 ConstantExpression condition = visit(node.condition); 740 ConstantExpression condition = visit(node.condition);
741 if (condition == null) return null;
697 ConstantExpression trueExp = visit(node.then); 742 ConstantExpression trueExp = visit(node.then);
743 if (trueExp == null) return null;
698 ConstantExpression falseExp = visit(node.otherwise); 744 ConstantExpression falseExp = visit(node.otherwise);
745 if (falseExp == null) return null;
699 return new ConditionalConstantExpression(condition, trueExp, falseExp); 746 return new ConditionalConstantExpression(condition, trueExp, falseExp);
700 } 747 }
701 748
702 @override 749 @override
703 ConstantExpression visitPropertyGet(ir.PropertyGet node) { 750 ConstantExpression visitPropertyGet(ir.PropertyGet node) {
704 if (node.name.name != 'length') { 751 if (node.name.name != 'length') {
705 throw new UnimplementedError( 752 throw new UnimplementedError(
706 'Unexpected constant expression $node (${node.runtimeType})'); 753 'Unexpected constant expression $node (${node.runtimeType})');
707 } 754 }
708 ConstantExpression receiver = visit(node.receiver); 755 ConstantExpression receiver = visit(node.receiver);
756 if (receiver == null) return null;
709 return new StringLengthConstantExpression(receiver); 757 return new StringLengthConstantExpression(receiver);
710 } 758 }
711 759
712 @override 760 @override
713 ConstantExpression visitMethodInvocation(ir.MethodInvocation node) { 761 ConstantExpression visitMethodInvocation(ir.MethodInvocation node) {
714 // Method invocations are generally not constant expressions but unary 762 // Method invocations are generally not constant expressions but unary
715 // and binary expressions are encoded as method invocations in kernel. 763 // and binary expressions are encoded as method invocations in kernel.
716 if (node.arguments.named.isNotEmpty) { 764 if (node.arguments.named.isNotEmpty) {
717 throw new UnimplementedError( 765 return defaultExpression(node);
718 'Unexpected constant expression $node (${node.runtimeType})');
719 } 766 }
720 if (node.arguments.positional.length == 0) { 767 if (node.arguments.positional.length == 0) {
721 UnaryOperator operator; 768 UnaryOperator operator;
722 if (node.name.name == UnaryOperator.NEGATE.selectorName) { 769 if (node.name.name == UnaryOperator.NEGATE.selectorName) {
723 operator = UnaryOperator.NEGATE; 770 operator = UnaryOperator.NEGATE;
724 } else { 771 } else {
725 operator = UnaryOperator.parse(node.name.name); 772 operator = UnaryOperator.parse(node.name.name);
726 } 773 }
727 if (operator != null) { 774 if (operator != null) {
728 ConstantExpression expression = visit(node.receiver); 775 ConstantExpression expression = visit(node.receiver);
776 if (expression == null) return null;
729 return new UnaryConstantExpression(operator, expression); 777 return new UnaryConstantExpression(operator, expression);
730 } 778 }
731 } 779 }
732 if (node.arguments.positional.length == 1) { 780 if (node.arguments.positional.length == 1) {
733 BinaryOperator operator = BinaryOperator.parse(node.name.name); 781 BinaryOperator operator = BinaryOperator.parse(node.name.name);
734 if (operator != null) { 782 if (operator != null) {
735 ConstantExpression left = visit(node.receiver); 783 ConstantExpression left = visit(node.receiver);
784 if (left == null) return null;
736 ConstantExpression right = visit(node.arguments.positional.single); 785 ConstantExpression right = visit(node.arguments.positional.single);
786 if (right == null) return null;
737 return new BinaryConstantExpression(left, operator, right); 787 return new BinaryConstantExpression(left, operator, right);
738 } 788 }
739 } 789 }
740 throw new UnimplementedError( 790 return defaultExpression(node);
741 'Unexpected constant expression $node (${node.runtimeType})');
742 } 791 }
743 792
744 @override 793 @override
745 ConstantExpression visitStaticInvocation(ir.StaticInvocation node) { 794 ConstantExpression visitStaticInvocation(ir.StaticInvocation node) {
746 MemberEntity member = elementAdapter.getMember(node.target); 795 MemberEntity member = elementAdapter.getMember(node.target);
747 if (member == _commonElements.identicalFunction) { 796 if (member == _commonElements.identicalFunction) {
748 if (node.arguments.positional.length == 2 && 797 if (node.arguments.positional.length == 2 &&
749 node.arguments.named.isEmpty) { 798 node.arguments.named.isEmpty) {
750 ConstantExpression left = visit(node.arguments.positional[0]); 799 ConstantExpression left = visit(node.arguments.positional[0]);
800 if (left == null) return null;
751 ConstantExpression right = visit(node.arguments.positional[1]); 801 ConstantExpression right = visit(node.arguments.positional[1]);
802 if (right == null) return null;
752 return new IdenticalConstantExpression(left, right); 803 return new IdenticalConstantExpression(left, right);
753 } 804 }
754 } else if (member.name == 'fromEnvironment' && 805 } else if (member.name == 'fromEnvironment' &&
755 node.arguments.positional.length == 1) { 806 node.arguments.positional.length == 1) {
756 ConstantExpression name = visit(node.arguments.positional.single); 807 ConstantExpression name = visit(node.arguments.positional.single);
808 if (name == null) return null;
757 ConstantExpression defaultValue; 809 ConstantExpression defaultValue;
758 if (node.arguments.named.length == 1) { 810 if (node.arguments.named.length == 1) {
759 if (node.arguments.named.single.name != 'defaultValue') { 811 if (node.arguments.named.single.name != 'defaultValue') {
760 throw new UnimplementedError( 812 return defaultExpression(node);
761 'Unexpected constant expression $node (${node.runtimeType})');
762 } 813 }
763 defaultValue = visit(node.arguments.named.single.value); 814 defaultValue = visit(node.arguments.named.single.value);
815 if (defaultValue == null) return null;
764 } 816 }
765 if (member.enclosingClass == _commonElements.boolClass) { 817 if (member.enclosingClass == _commonElements.boolClass) {
766 return new BoolFromEnvironmentConstantExpression(name, defaultValue); 818 return new BoolFromEnvironmentConstantExpression(name, defaultValue);
767 } else if (member.enclosingClass == _commonElements.intClass) { 819 } else if (member.enclosingClass == _commonElements.intClass) {
768 return new IntFromEnvironmentConstantExpression(name, defaultValue); 820 return new IntFromEnvironmentConstantExpression(name, defaultValue);
769 } else if (member.enclosingClass == _commonElements.stringClass) { 821 } else if (member.enclosingClass == _commonElements.stringClass) {
770 return new StringFromEnvironmentConstantExpression(name, defaultValue); 822 return new StringFromEnvironmentConstantExpression(name, defaultValue);
771 } 823 }
772 } 824 }
773 throw new UnimplementedError( 825 return defaultExpression(node);
774 'Unexpected constant expression $node (${node.runtimeType})');
775 } 826 }
776 827
777 @override 828 @override
778 ConstantExpression visitLogicalExpression(ir.LogicalExpression node) { 829 ConstantExpression visitLogicalExpression(ir.LogicalExpression node) {
779 BinaryOperator operator = BinaryOperator.parse(node.operator); 830 BinaryOperator operator = BinaryOperator.parse(node.operator);
780 if (operator != null) { 831 if (operator != null) {
781 ConstantExpression left = visit(node.left); 832 ConstantExpression left = visit(node.left);
833 if (left == null) return null;
782 ConstantExpression right = visit(node.right); 834 ConstantExpression right = visit(node.right);
835 if (right == null) return null;
783 return new BinaryConstantExpression(left, operator, right); 836 return new BinaryConstantExpression(left, operator, right);
784 } 837 }
785 throw new UnimplementedError( 838 return defaultExpression(node);
786 'Unexpected constant expression $node (${node.runtimeType})');
787 } 839 }
788 840
789 @override 841 @override
790 ConstantExpression visitLet(ir.Let node) { 842 ConstantExpression visitLet(ir.Let node) {
791 ir.Expression body = node.body; 843 ir.Expression body = node.body;
792 if (body is ir.ConditionalExpression) { 844 if (body is ir.ConditionalExpression) {
793 ir.Expression condition = body.condition; 845 ir.Expression condition = body.condition;
794 if (condition is ir.MethodInvocation) { 846 if (condition is ir.MethodInvocation) {
795 ir.Expression receiver = condition.receiver; 847 ir.Expression receiver = condition.receiver;
796 ir.Expression otherwise = body.otherwise; 848 ir.Expression otherwise = body.otherwise;
797 if (condition.name.name == BinaryOperator.EQ.name && 849 if (condition.name.name == BinaryOperator.EQ.name &&
798 receiver is ir.VariableGet && 850 receiver is ir.VariableGet &&
799 condition.arguments.positional.single is ir.NullLiteral && 851 condition.arguments.positional.single is ir.NullLiteral &&
800 otherwise is ir.VariableGet) { 852 otherwise is ir.VariableGet) {
801 if (receiver.variable == node.variable && 853 if (receiver.variable == node.variable &&
802 otherwise.variable == node.variable) { 854 otherwise.variable == node.variable) {
803 // We have <left> ?? <right> encoded as: 855 // We have <left> ?? <right> encoded as:
804 // let #1 = <left> in #1 == null ? <right> : #1 856 // let #1 = <left> in #1 == null ? <right> : #1
805 ConstantExpression left = visit(node.variable.initializer); 857 ConstantExpression left = visit(node.variable.initializer);
858 if (left == null) return null;
806 ConstantExpression right = visit(body.then); 859 ConstantExpression right = visit(body.then);
860 if (right == null) return null;
807 // TODO(johnniwinther): Remove [IF_NULL] binary constant expression 861 // TODO(johnniwinther): Remove [IF_NULL] binary constant expression
808 // when the resolver is removed; then we no longer need the 862 // when the resolver is removed; then we no longer need the
809 // expressions to be structurally equivalence for equivalence 863 // expressions to be structurally equivalence for equivalence
810 // testing. 864 // testing.
811 return new BinaryConstantExpression( 865 return new BinaryConstantExpression(
812 left, BinaryOperator.IF_NULL, right); 866 left, BinaryOperator.IF_NULL, right);
813 } 867 }
814 } 868 }
815 } 869 }
816 } 870 }
817 throw new UnimplementedError( 871 return defaultExpression(node);
818 'Unexpected constant expression $node (${node.runtimeType})');
819 } 872 }
820 873
821 /// Compute the [ConstantConstructor] corresponding to the const constructor 874 /// Compute the [ConstantConstructor] corresponding to the const constructor
822 /// [node]. 875 /// [node].
823 ConstantConstructor computeConstantConstructor(ir.Constructor node) { 876 ConstantConstructor computeConstantConstructor(ir.Constructor node) {
824 assert(node.isConst); 877 assert(node.isConst);
825 ir.Class cls = node.enclosingClass; 878 ir.Class cls = node.enclosingClass;
826 InterfaceType type = elementAdapter.elementEnvironment 879 InterfaceType type = elementAdapter.elementEnvironment
827 .getThisType(elementAdapter.getClass(cls)); 880 .getThisType(elementAdapter.getClass(cls));
828 881
829 Map<dynamic, ConstantExpression> defaultValues = 882 Map<dynamic, ConstantExpression> defaultValues =
830 <dynamic, ConstantExpression>{}; 883 <dynamic, ConstantExpression>{};
831 int parameterIndex = 0; 884 int parameterIndex = 0;
832 node.function.positionalParameters 885 for (ir.VariableDeclaration parameter
833 .forEach((ir.VariableDeclaration parameter) { 886 in node.function.positionalParameters) {
834 if (parameterIndex >= node.function.requiredParameterCount) { 887 if (parameterIndex >= node.function.requiredParameterCount) {
888 ConstantExpression defaultValue;
835 if (parameter.initializer != null) { 889 if (parameter.initializer != null) {
836 defaultValues[parameterIndex] = parameter.initializer.accept(this); 890 defaultValue = parameter.initializer.accept(this);
837 } else { 891 } else {
838 defaultValues[parameterIndex] = new NullConstantExpression(); 892 defaultValue = new NullConstantExpression();
839 } 893 }
894 if (defaultValue == null) return null;
895 defaultValues[parameterIndex] = defaultValue;
840 } 896 }
841 parameterIndex++; 897 parameterIndex++;
842 }); 898 }
843 node.function.namedParameters.forEach((ir.VariableDeclaration parameter) { 899 for (ir.VariableDeclaration parameter in node.function.namedParameters) {
844 defaultValues[parameter.name] = parameter.initializer.accept(this); 900 ConstantExpression defaultValue = parameter.initializer.accept(this);
845 }); 901 if (defaultValue == null) return null;
902 defaultValues[parameter.name] = defaultValue;
903 }
846 904
847 bool isRedirecting = node.initializers.length == 1 && 905 bool isRedirecting = node.initializers.length == 1 &&
848 node.initializers.single is ir.RedirectingInitializer; 906 node.initializers.single is ir.RedirectingInitializer;
849 907
850 Map<FieldEntity, ConstantExpression> fieldMap = 908 Map<FieldEntity, ConstantExpression> fieldMap =
851 <FieldEntity, ConstantExpression>{}; 909 <FieldEntity, ConstantExpression>{};
852 910
853 void registerField(ir.Field field, ConstantExpression constant) { 911 void registerField(ir.Field field, ConstantExpression constant) {
854 fieldMap[elementAdapter.getField(field)] = constant; 912 fieldMap[elementAdapter.getField(field)] = constant;
855 } 913 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 /// Call to notify that [member] is no longer being inlined. 1008 /// Call to notify that [member] is no longer being inlined.
951 void leaveInlinedMember(MemberEntity member); 1009 void leaveInlinedMember(MemberEntity member);
952 1010
953 /// Returns the [Local] for [node]. 1011 /// Returns the [Local] for [node].
954 Local getLocal(ir.VariableDeclaration node); 1012 Local getLocal(ir.VariableDeclaration node);
955 1013
956 /// Returns the [JumpTarget] for the branch in [node]. 1014 /// Returns the [JumpTarget] for the branch in [node].
957 // TODO(johnniwinther): Split this by kind of [node]? 1015 // TODO(johnniwinther): Split this by kind of [node]?
958 JumpTarget getJumpTarget(ir.TreeNode node, {bool isContinueTarget: false}); 1016 JumpTarget getJumpTarget(ir.TreeNode node, {bool isContinueTarget: false});
959 } 1017 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/runtime_types.dart ('k') | pkg/compiler/lib/src/kernel/element_map_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698