Chromium Code Reviews| Index: pkg/compiler/lib/src/kernel/element_adapter.dart |
| diff --git a/pkg/compiler/lib/src/kernel/element_adapter.dart b/pkg/compiler/lib/src/kernel/element_adapter.dart |
| index 9a40304d256db7bddb2f32bf0d22bd521f5216c5..7fb303ede1c416f56ac0d42ea9932abfd219734f 100644 |
| --- a/pkg/compiler/lib/src/kernel/element_adapter.dart |
| +++ b/pkg/compiler/lib/src/kernel/element_adapter.dart |
| @@ -15,6 +15,7 @@ import '../elements/entities.dart'; |
| import '../elements/types.dart'; |
| import '../js_backend/backend.dart' show JavaScriptBackend; |
| import '../native/native.dart' as native; |
| +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.
|
| import '../universe/call_structure.dart'; |
| import '../universe/selector.dart'; |
| import 'kernel_debug.dart'; |
| @@ -469,6 +470,8 @@ class Constantifier extends ir.ExpressionVisitor<ConstantExpression> { |
| Constantifier(this.elementAdapter, {this.requireConstant: true}); |
| + CommonElements get _commonElements => elementAdapter.commonElements; |
| + |
| ConstantExpression visit(ir.Expression node) { |
| ConstantExpression constant = node.accept(this); |
| if (constant == null && requireConstant) { |
| @@ -541,7 +544,35 @@ class Constantifier extends ir.ExpressionVisitor<ConstantExpression> { |
| @override |
| ConstantExpression visitStaticGet(ir.StaticGet node) { |
| - return new FieldConstantExpression(elementAdapter.getField(node.target)); |
| + if (node.target is ir.Field) { |
| + return new FieldConstantExpression(elementAdapter.getField(node.target)); |
| + } else if (node.target is ir.Procedure) { |
| + FunctionEntity function = elementAdapter.getMethod(node.target); |
| + 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.
|
| + return new FunctionConstantExpression(function, type); |
| + } |
| + throw new UnimplementedError( |
| + 'Unexpected constant expression $node (${node.runtimeType})'); |
| + } |
| + |
| + @override |
| + ConstantExpression visitNullLiteral(ir.NullLiteral node) { |
| + return new NullConstantExpression(); |
| + } |
| + |
| + @override |
| + ConstantExpression visitBoolLiteral(ir.BoolLiteral node) { |
| + return new BoolConstantExpression(node.value); |
| + } |
| + |
| + @override |
| + ConstantExpression visitIntLiteral(ir.IntLiteral node) { |
| + return new IntConstantExpression(node.value); |
| + } |
| + |
| + @override |
| + ConstantExpression visitDoubleLiteral(ir.DoubleLiteral node) { |
| + return new DoubleConstantExpression(node.value); |
| } |
| @override |
| @@ -550,10 +581,141 @@ class Constantifier extends ir.ExpressionVisitor<ConstantExpression> { |
| } |
| @override |
| + ConstantExpression visitSymbolLiteral(ir.SymbolLiteral node) { |
| + return new SymbolConstantExpression(node.value); |
| + } |
| + |
| + @override |
| ConstantExpression visitStringConcatenation(ir.StringConcatenation node) { |
| return new ConcatenateConstantExpression(_computeList(node.expressions)); |
| } |
| + @override |
| + ConstantExpression visitMapLiteral(ir.MapLiteral node) { |
| + if (!node.isConst) { |
| + throw new UnimplementedError( |
| + 'Unexpected constant expression $node (${node.runtimeType})'); |
| + } |
| + DartType keyType = elementAdapter.getDartType(node.keyType); |
| + DartType valueType = elementAdapter.getDartType(node.valueType); |
| + List<ConstantExpression> keys = <ConstantExpression>[]; |
| + List<ConstantExpression> values = <ConstantExpression>[]; |
| + for (ir.MapEntry entry in node.entries) { |
| + keys.add(visit(entry.key)); |
| + values.add(visit(entry.value)); |
| + } |
| + return new MapConstantExpression( |
| + _commonElements.mapType(keyType, valueType), keys, values); |
| + } |
| + |
| + @override |
| + ConstantExpression visitListLiteral(ir.ListLiteral node) { |
| + if (!node.isConst) { |
| + throw new UnimplementedError( |
| + 'Unexpected constant expression $node (${node.runtimeType})'); |
| + } |
| + DartType elementType = elementAdapter.getDartType(node.typeArgument); |
| + List<ConstantExpression> values = <ConstantExpression>[]; |
| + for (ir.Expression value in node.expressions) { |
| + values.add(visit(value)); |
| + } |
| + return new ListConstantExpression( |
| + _commonElements.listType(elementType), values); |
| + } |
| + |
| + @override |
| + ConstantExpression visitConditionalExpression(ir.ConditionalExpression node) { |
| + ConstantExpression condition = visit(node.condition); |
| + ConstantExpression trueExp = visit(node.then); |
| + ConstantExpression falseExp = visit(node.otherwise); |
| + return new ConditionalConstantExpression(condition, trueExp, falseExp); |
| + } |
| + |
| + @override |
| + ConstantExpression visitPropertyGet(ir.PropertyGet node) { |
| + if (node.name.name != 'length') { |
| + throw new UnimplementedError( |
| + 'Unexpected constant expression $node (${node.runtimeType})'); |
| + } |
| + 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
|
| + return new StringLengthConstantExpression(receiver); |
| + } |
| + |
| + @override |
| + 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
|
| + if (node.arguments.named.isNotEmpty) { |
| + throw new UnimplementedError( |
| + 'Unexpected constant expression $node (${node.runtimeType})'); |
| + } |
| + if (node.arguments.positional.length == 0) { |
| + UnaryOperator operator; |
| + if (node.name.name == UnaryOperator.NEGATE.selectorName) { |
| + operator = UnaryOperator.NEGATE; |
| + } else { |
| + operator = UnaryOperator.parse(node.name.name); |
| + } |
| + if (operator != null) { |
| + ConstantExpression expression = visit(node.receiver); |
| + return new UnaryConstantExpression(operator, expression); |
| + } |
| + } |
| + if (node.arguments.positional.length == 1) { |
| + BinaryOperator operator = BinaryOperator.parse(node.name.name); |
| + if (operator != null) { |
| + ConstantExpression left = visit(node.receiver); |
| + ConstantExpression right = visit(node.arguments.positional.single); |
| + return new BinaryConstantExpression(left, operator, right); |
| + } |
| + } |
| + throw new UnimplementedError( |
| + 'Unexpected constant expression $node (${node.runtimeType})'); |
| + } |
| + |
| + @override |
| + ConstantExpression visitStaticInvocation(ir.StaticInvocation node) { |
| + MemberEntity member = elementAdapter.getMember(node.target); |
| + if (member == _commonElements.identicalFunction) { |
| + if (node.arguments.positional.length == 2 && |
| + node.arguments.named.isEmpty) { |
| + ConstantExpression left = visit(node.arguments.positional[0]); |
| + ConstantExpression right = visit(node.arguments.positional[1]); |
| + return new IdenticalConstantExpression(left, right); |
| + } |
| + } else if (member.name == 'fromEnvironment' && |
| + node.arguments.positional.length == 1) { |
| + ConstantExpression name = visit(node.arguments.positional.single); |
| + ConstantExpression defaultValue; |
| + if (node.arguments.named.length == 1) { |
| + if (node.arguments.named.single.name != 'defaultValue') { |
| + throw new UnimplementedError( |
| + 'Unexpected constant expression $node (${node.runtimeType})'); |
| + } |
| + defaultValue = visit(node.arguments.named.single.value); |
| + } |
| + if (member.enclosingClass == _commonElements.boolClass) { |
| + return new BoolFromEnvironmentConstantExpression(name, defaultValue); |
| + } else if (member.enclosingClass == _commonElements.intClass) { |
| + return new IntFromEnvironmentConstantExpression(name, defaultValue); |
| + } else if (member.enclosingClass == _commonElements.stringClass) { |
| + return new StringFromEnvironmentConstantExpression(name, defaultValue); |
| + } |
| + } |
| + throw new UnimplementedError( |
| + 'Unexpected constant expression $node (${node.runtimeType})'); |
| + } |
| + |
| + @override |
| + ConstantExpression visitLogicalExpression(ir.LogicalExpression node) { |
| + BinaryOperator operator = BinaryOperator.parse(node.operator); |
| + if (operator != null) { |
| + ConstantExpression left = visit(node.left); |
| + ConstantExpression right = visit(node.right); |
| + return new BinaryConstantExpression(left, operator, right); |
| + } |
| + throw new UnimplementedError( |
| + 'Unexpected constant expression $node (${node.runtimeType})'); |
| + } |
| + |
| /// Compute the [ConstantConstructor] corresponding to the const constructor |
| /// [node]. |
| ConstantConstructor computeConstantConstructor(ir.Constructor node) { |