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

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

Issue 2857373002: Handle more constants in Constantifier (Closed)
Patch Set: Updated cf. comments. 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';
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 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 sb.write(value); 459 sb.write(value);
459 } 460 }
460 return sb.toString(); 461 return sb.toString();
461 } 462 }
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 KernelElementAdapterMixin 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(node.target.function);
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);
641 return new StringLengthConstantExpression(receiver);
642 }
643
644 @override
645 ConstantExpression visitMethodInvocation(ir.MethodInvocation node) {
646 // Method invocations are generally not constant expressions but unary
647 // and binary expressions are encoded as method invocations in kernel.
648 if (node.arguments.named.isNotEmpty) {
649 throw new UnimplementedError(
650 'Unexpected constant expression $node (${node.runtimeType})');
651 }
652 if (node.arguments.positional.length == 0) {
653 UnaryOperator operator;
654 if (node.name.name == UnaryOperator.NEGATE.selectorName) {
655 operator = UnaryOperator.NEGATE;
656 } else {
657 operator = UnaryOperator.parse(node.name.name);
658 }
659 if (operator != null) {
660 ConstantExpression expression = visit(node.receiver);
661 return new UnaryConstantExpression(operator, expression);
662 }
663 }
664 if (node.arguments.positional.length == 1) {
665 BinaryOperator operator = BinaryOperator.parse(node.name.name);
666 if (operator != null) {
667 ConstantExpression left = visit(node.receiver);
668 ConstantExpression right = visit(node.arguments.positional.single);
669 return new BinaryConstantExpression(left, operator, right);
670 }
671 }
672 throw new UnimplementedError(
673 'Unexpected constant expression $node (${node.runtimeType})');
674 }
675
676 @override
677 ConstantExpression visitStaticInvocation(ir.StaticInvocation node) {
678 MemberEntity member = elementAdapter.getMember(node.target);
679 if (member == _commonElements.identicalFunction) {
680 if (node.arguments.positional.length == 2 &&
681 node.arguments.named.isEmpty) {
682 ConstantExpression left = visit(node.arguments.positional[0]);
683 ConstantExpression right = visit(node.arguments.positional[1]);
684 return new IdenticalConstantExpression(left, right);
685 }
686 } else if (member.name == 'fromEnvironment' &&
687 node.arguments.positional.length == 1) {
688 ConstantExpression name = visit(node.arguments.positional.single);
689 ConstantExpression defaultValue;
690 if (node.arguments.named.length == 1) {
691 if (node.arguments.named.single.name != 'defaultValue') {
692 throw new UnimplementedError(
693 'Unexpected constant expression $node (${node.runtimeType})');
694 }
695 defaultValue = visit(node.arguments.named.single.value);
696 }
697 if (member.enclosingClass == _commonElements.boolClass) {
698 return new BoolFromEnvironmentConstantExpression(name, defaultValue);
699 } else if (member.enclosingClass == _commonElements.intClass) {
700 return new IntFromEnvironmentConstantExpression(name, defaultValue);
701 } else if (member.enclosingClass == _commonElements.stringClass) {
702 return new StringFromEnvironmentConstantExpression(name, defaultValue);
703 }
704 }
705 throw new UnimplementedError(
706 'Unexpected constant expression $node (${node.runtimeType})');
707 }
708
709 @override
710 ConstantExpression visitLogicalExpression(ir.LogicalExpression node) {
711 BinaryOperator operator = BinaryOperator.parse(node.operator);
712 if (operator != null) {
713 ConstantExpression left = visit(node.left);
714 ConstantExpression right = visit(node.right);
715 return new BinaryConstantExpression(left, operator, right);
716 }
717 throw new UnimplementedError(
718 'Unexpected constant expression $node (${node.runtimeType})');
719 }
720
557 /// Compute the [ConstantConstructor] corresponding to the const constructor 721 /// Compute the [ConstantConstructor] corresponding to the const constructor
558 /// [node]. 722 /// [node].
559 ConstantConstructor computeConstantConstructor(ir.Constructor node) { 723 ConstantConstructor computeConstantConstructor(ir.Constructor node) {
560 assert(node.isConst); 724 assert(node.isConst);
561 ir.Class cls = node.enclosingClass; 725 ir.Class cls = node.enclosingClass;
562 InterfaceType type = elementAdapter.elementEnvironment 726 InterfaceType type = elementAdapter.elementEnvironment
563 .getThisType(elementAdapter.getClass(cls)); 727 .getThisType(elementAdapter.getClass(cls));
564 728
565 Map<dynamic, ConstantExpression> defaultValues = 729 Map<dynamic, ConstantExpression> defaultValues =
566 <dynamic, ConstantExpression>{}; 730 <dynamic, ConstantExpression>{};
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 } 779 }
616 if (isRedirecting) { 780 if (isRedirecting) {
617 return new RedirectingGenerativeConstantConstructor( 781 return new RedirectingGenerativeConstantConstructor(
618 defaultValues, superConstructorInvocation); 782 defaultValues, superConstructorInvocation);
619 } else { 783 } else {
620 return new GenerativeConstantConstructor( 784 return new GenerativeConstantConstructor(
621 type, defaultValues, fieldMap, superConstructorInvocation); 785 type, defaultValues, fieldMap, superConstructorInvocation);
622 } 786 }
623 } 787 }
624 } 788 }
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