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

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

Issue 2857373002: Handle more constants in Constantifier (Closed)
Patch Set: Created 3 years, 7 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';
11 import '../constants/values.dart'; 11 import '../constants/values.dart';
12 import '../common_elements.dart'; 12 import '../common_elements.dart';
13 import '../elements/elements.dart'; 13 import '../elements/elements.dart';
14 import '../elements/entities.dart'; 14 import '../elements/entities.dart';
15 import '../elements/types.dart'; 15 import '../elements/types.dart';
16 import '../js_backend/backend.dart' show JavaScriptBackend; 16 import '../js_backend/backend.dart' show JavaScriptBackend;
17 import '../native/native.dart' as native; 17 import '../native/native.dart' as native;
18 import '../resolution/operators.dart';
Siggi Cherem (dart-lang) 2017/05/04 19:13:40 minor: it would be good to move the operators file
Johnni Winther 2017/05/05 08:17:25 Will do in a follow-up.
18 import '../universe/call_structure.dart'; 19 import '../universe/call_structure.dart';
19 import '../universe/selector.dart'; 20 import '../universe/selector.dart';
20 import 'kernel_debug.dart'; 21 import 'kernel_debug.dart';
21 22
22 /// Interface that translates between Kernel IR nodes and entities. 23 /// Interface that translates between Kernel IR nodes and entities.
23 abstract class KernelElementAdapter { 24 abstract class KernelElementAdapter {
24 /// Access to the commonly used elements and types. 25 /// Access to the commonly used elements and types.
25 CommonElements get commonElements; 26 CommonElements get commonElements;
26 27
27 /// [ElementEnvironment] for library, class and member lookup. 28 /// [ElementEnvironment] for library, class and member lookup.
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 } 463 }
463 464
464 /// Visitor that converts a kernel constant expression into a 465 /// Visitor that converts a kernel constant expression into a
465 /// [ConstantExpression]. 466 /// [ConstantExpression].
466 class Constantifier extends ir.ExpressionVisitor<ConstantExpression> { 467 class Constantifier extends ir.ExpressionVisitor<ConstantExpression> {
467 final bool requireConstant; 468 final bool requireConstant;
468 final KernelElementAdapter elementAdapter; 469 final KernelElementAdapter elementAdapter;
469 470
470 Constantifier(this.elementAdapter, {this.requireConstant: true}); 471 Constantifier(this.elementAdapter, {this.requireConstant: true});
471 472
473 CommonElements get _commonElements => elementAdapter.commonElements;
474
472 ConstantExpression visit(ir.Expression node) { 475 ConstantExpression visit(ir.Expression node) {
473 ConstantExpression constant = node.accept(this); 476 ConstantExpression constant = node.accept(this);
474 if (constant == null && requireConstant) { 477 if (constant == null && requireConstant) {
475 throw new UnsupportedError( 478 throw new UnsupportedError(
476 "No constant computed for $node (${node.runtimeType})"); 479 "No constant computed for $node (${node.runtimeType})");
477 } 480 }
478 return constant; 481 return constant;
479 } 482 }
480 483
481 ConstantExpression defaultExpression(ir.Expression node) { 484 ConstantExpression defaultExpression(ir.Expression node) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 assert(function.namedParameters.contains(node.variable)); 537 assert(function.namedParameters.contains(node.variable));
535 return new NamedArgumentReference(node.variable.name); 538 return new NamedArgumentReference(node.variable.name);
536 } 539 }
537 } 540 }
538 throw new UnimplementedError( 541 throw new UnimplementedError(
539 'Unimplemented constant expression $node (${node.runtimeType})'); 542 'Unimplemented constant expression $node (${node.runtimeType})');
540 } 543 }
541 544
542 @override 545 @override
543 ConstantExpression visitStaticGet(ir.StaticGet node) { 546 ConstantExpression visitStaticGet(ir.StaticGet node) {
544 return new FieldConstantExpression(elementAdapter.getField(node.target)); 547 if (node.target is ir.Field) {
548 return new FieldConstantExpression(elementAdapter.getField(node.target));
549 } else if (node.target is ir.Procedure) {
550 FunctionEntity function = elementAdapter.getMethod(node.target);
551 DartType type /* = elementAdapter.getFunctionType(function)*/;
Siggi Cherem (dart-lang) 2017/05/04 19:13:40 uncomment?
Johnni Winther 2017/05/05 08:17:25 Done.
552 return new FunctionConstantExpression(function, type);
553 }
554 throw new UnimplementedError(
555 'Unexpected constant expression $node (${node.runtimeType})');
545 } 556 }
546 557
547 @override 558 @override
559 ConstantExpression visitNullLiteral(ir.NullLiteral node) {
560 return new NullConstantExpression();
561 }
562
563 @override
564 ConstantExpression visitBoolLiteral(ir.BoolLiteral node) {
565 return new BoolConstantExpression(node.value);
566 }
567
568 @override
569 ConstantExpression visitIntLiteral(ir.IntLiteral node) {
570 return new IntConstantExpression(node.value);
571 }
572
573 @override
574 ConstantExpression visitDoubleLiteral(ir.DoubleLiteral node) {
575 return new DoubleConstantExpression(node.value);
576 }
577
578 @override
548 ConstantExpression visitStringLiteral(ir.StringLiteral node) { 579 ConstantExpression visitStringLiteral(ir.StringLiteral node) {
549 return new StringConstantExpression(node.value); 580 return new StringConstantExpression(node.value);
550 } 581 }
551 582
552 @override 583 @override
584 ConstantExpression visitSymbolLiteral(ir.SymbolLiteral node) {
585 return new SymbolConstantExpression(node.value);
586 }
587
588 @override
553 ConstantExpression visitStringConcatenation(ir.StringConcatenation node) { 589 ConstantExpression visitStringConcatenation(ir.StringConcatenation node) {
554 return new ConcatenateConstantExpression(_computeList(node.expressions)); 590 return new ConcatenateConstantExpression(_computeList(node.expressions));
555 } 591 }
556 592
593 @override
594 ConstantExpression visitMapLiteral(ir.MapLiteral node) {
595 if (!node.isConst) {
596 throw new UnimplementedError(
597 'Unexpected constant expression $node (${node.runtimeType})');
598 }
599 DartType keyType = elementAdapter.getDartType(node.keyType);
600 DartType valueType = elementAdapter.getDartType(node.valueType);
601 List<ConstantExpression> keys = <ConstantExpression>[];
602 List<ConstantExpression> values = <ConstantExpression>[];
603 for (ir.MapEntry entry in node.entries) {
604 keys.add(visit(entry.key));
605 values.add(visit(entry.value));
606 }
607 return new MapConstantExpression(
608 _commonElements.mapType(keyType, valueType), keys, values);
609 }
610
611 @override
612 ConstantExpression visitListLiteral(ir.ListLiteral node) {
613 if (!node.isConst) {
614 throw new UnimplementedError(
615 'Unexpected constant expression $node (${node.runtimeType})');
616 }
617 DartType elementType = elementAdapter.getDartType(node.typeArgument);
618 List<ConstantExpression> values = <ConstantExpression>[];
619 for (ir.Expression value in node.expressions) {
620 values.add(visit(value));
621 }
622 return new ListConstantExpression(
623 _commonElements.listType(elementType), values);
624 }
625
626 @override
627 ConstantExpression visitConditionalExpression(ir.ConditionalExpression node) {
628 ConstantExpression condition = visit(node.condition);
629 ConstantExpression trueExp = visit(node.then);
630 ConstantExpression falseExp = visit(node.otherwise);
631 return new ConditionalConstantExpression(condition, trueExp, falseExp);
632 }
633
634 @override
635 ConstantExpression visitPropertyGet(ir.PropertyGet node) {
636 if (node.name.name != 'length') {
637 throw new UnimplementedError(
638 'Unexpected constant expression $node (${node.runtimeType})');
639 }
640 ConstantExpression receiver = visit(node.receiver);
Siggi Cherem (dart-lang) 2017/05/04 19:13:39 do we need to check that receiver is String?
Johnni Winther 2017/05/05 08:17:25 We can't tell. Only when you evaluate can you dete
641 return new StringLengthConstantExpression(receiver);
642 }
643
644 @override
645 ConstantExpression visitMethodInvocation(ir.MethodInvocation node) {
Siggi Cherem (dart-lang) 2017/05/04 19:13:39 minor: it might be worth adding a 1-line comment h
646 if (node.arguments.named.isNotEmpty) {
647 throw new UnimplementedError(
648 'Unexpected constant expression $node (${node.runtimeType})');
649 }
650 if (node.arguments.positional.length == 0) {
651 UnaryOperator operator;
652 if (node.name.name == UnaryOperator.NEGATE.selectorName) {
653 operator = UnaryOperator.NEGATE;
654 } else {
655 operator = UnaryOperator.parse(node.name.name);
656 }
657 if (operator != null) {
658 ConstantExpression expression = visit(node.receiver);
659 return new UnaryConstantExpression(operator, expression);
660 }
661 }
662 if (node.arguments.positional.length == 1) {
663 BinaryOperator operator = BinaryOperator.parse(node.name.name);
664 if (operator != null) {
665 ConstantExpression left = visit(node.receiver);
666 ConstantExpression right = visit(node.arguments.positional.single);
667 return new BinaryConstantExpression(left, operator, right);
668 }
669 }
670 throw new UnimplementedError(
671 'Unexpected constant expression $node (${node.runtimeType})');
672 }
673
674 @override
675 ConstantExpression visitStaticInvocation(ir.StaticInvocation node) {
676 MemberEntity member = elementAdapter.getMember(node.target);
677 if (member == _commonElements.identicalFunction) {
678 if (node.arguments.positional.length == 2 &&
679 node.arguments.named.isEmpty) {
680 ConstantExpression left = visit(node.arguments.positional[0]);
681 ConstantExpression right = visit(node.arguments.positional[1]);
682 return new IdenticalConstantExpression(left, right);
683 }
684 } else if (member.name == 'fromEnvironment' &&
685 node.arguments.positional.length == 1) {
686 ConstantExpression name = visit(node.arguments.positional.single);
687 ConstantExpression defaultValue;
688 if (node.arguments.named.length == 1) {
689 if (node.arguments.named.single.name != 'defaultValue') {
690 throw new UnimplementedError(
691 'Unexpected constant expression $node (${node.runtimeType})');
692 }
693 defaultValue = visit(node.arguments.named.single.value);
694 }
695 if (member.enclosingClass == _commonElements.boolClass) {
696 return new BoolFromEnvironmentConstantExpression(name, defaultValue);
697 } else if (member.enclosingClass == _commonElements.intClass) {
698 return new IntFromEnvironmentConstantExpression(name, defaultValue);
699 } else if (member.enclosingClass == _commonElements.stringClass) {
700 return new StringFromEnvironmentConstantExpression(name, defaultValue);
701 }
702 }
703 throw new UnimplementedError(
704 'Unexpected constant expression $node (${node.runtimeType})');
705 }
706
707 @override
708 ConstantExpression visitLogicalExpression(ir.LogicalExpression node) {
709 BinaryOperator operator = BinaryOperator.parse(node.operator);
710 if (operator != null) {
711 ConstantExpression left = visit(node.left);
712 ConstantExpression right = visit(node.right);
713 return new BinaryConstantExpression(left, operator, right);
714 }
715 throw new UnimplementedError(
716 'Unexpected constant expression $node (${node.runtimeType})');
717 }
718
557 /// Compute the [ConstantConstructor] corresponding to the const constructor 719 /// Compute the [ConstantConstructor] corresponding to the const constructor
558 /// [node]. 720 /// [node].
559 ConstantConstructor computeConstantConstructor(ir.Constructor node) { 721 ConstantConstructor computeConstantConstructor(ir.Constructor node) {
560 assert(node.isConst); 722 assert(node.isConst);
561 ir.Class cls = node.enclosingClass; 723 ir.Class cls = node.enclosingClass;
562 InterfaceType type = elementAdapter.elementEnvironment 724 InterfaceType type = elementAdapter.elementEnvironment
563 .getThisType(elementAdapter.getClass(cls)); 725 .getThisType(elementAdapter.getClass(cls));
564 726
565 Map<dynamic, ConstantExpression> defaultValues = 727 Map<dynamic, ConstantExpression> defaultValues =
566 <dynamic, ConstantExpression>{}; 728 <dynamic, ConstantExpression>{};
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 } 777 }
616 if (isRedirecting) { 778 if (isRedirecting) {
617 return new RedirectingGenerativeConstantConstructor( 779 return new RedirectingGenerativeConstantConstructor(
618 defaultValues, superConstructorInvocation); 780 defaultValues, superConstructorInvocation);
619 } else { 781 } else {
620 return new GenerativeConstantConstructor( 782 return new GenerativeConstantConstructor(
621 type, defaultValues, fieldMap, superConstructorInvocation); 783 type, defaultValues, fieldMap, superConstructorInvocation);
622 } 784 }
623 } 785 }
624 } 786 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/constants/expressions.dart ('k') | pkg/compiler/lib/src/kernel/element_map.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698