| Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| index 13f4306d5b4951b1d675f368dc074f05beb5ac5d..868126ddef5b24ec823ca2a03823f9b5b6fc231b 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| @@ -18,6 +18,7 @@ import '../resolution/semantic_visitor.dart';
|
| import '../resolution/operators.dart' as op;
|
| import '../tree/tree.dart' as ast;
|
| import '../universe/universe.dart' show SelectorKind, CallStructure;
|
| +import '../constants/values.dart' show ConstantValue;
|
| import 'cps_ir_nodes.dart' as ir;
|
| import 'cps_ir_builder.dart';
|
| import '../native/native.dart' show NativeBehavior;
|
| @@ -353,13 +354,8 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) {
|
| assert(irBuilder.isOpen);
|
| if (node.modifiers.isConst) {
|
| - for (ast.SendSet definition in node.definitions.nodes) {
|
| - assert(!definition.arguments.isEmpty);
|
| - assert(definition.arguments.tail.isEmpty);
|
| - VariableElement element = elements[definition];
|
| - ConstantExpression value = getConstantForVariable(element);
|
| - irBuilder.declareLocalConstant(element, value);
|
| - }
|
| + // Do nothing.
|
| + // handleLocalConstantGet inlines the constant at use-site.
|
| } else {
|
| for (ast.Node definition in node.definitions.nodes) {
|
| Element element = elements[definition];
|
| @@ -499,27 +495,16 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| return irBuilder.buildDartStringConstant(node.dartString);
|
| }
|
|
|
| - ConstantExpression getConstantForNode(ast.Node node) {
|
| - ConstantExpression constant =
|
| - irBuilder.state.constants.getConstantForNode(node, elements);
|
| - assert(invariant(node, constant != null,
|
| - message: 'No constant computed for $node'));
|
| - return constant;
|
| + ConstantValue getConstantForNode(ast.Node node) {
|
| + return irBuilder.state.constants.getConstantValueForNode(node, elements);
|
| }
|
|
|
| - ConstantExpression getConstantForVariable(VariableElement element) {
|
| - ConstantExpression constant =
|
| - irBuilder.state.constants.getConstantForVariable(element);
|
| - assert(invariant(element, constant != null,
|
| - message: 'No constant computed for $element'));
|
| - return constant;
|
| + ConstantValue getConstantForVariable(VariableElement element) {
|
| + return irBuilder.state.constants.getConstantValueForVariable(element);
|
| }
|
|
|
| - /// Builds a constant pulling the value from the constant environment.
|
| - // TODO(johnniwinther): Remove this when [IrBuilder.buildConstant] only takes
|
| - // a [ConstantExpression].
|
| - ir.Primitive buildConstant(ConstantExpression expression) {
|
| - return irBuilder.buildConstant(expression,
|
| + ir.Primitive buildConstantExpression(ConstantExpression expression) {
|
| + return irBuilder.buildConstant(
|
| irBuilder.state.constants.getConstantValue(expression));
|
| }
|
|
|
| @@ -617,7 +602,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ir.Primitive handleConstantGet(
|
| ast.Node node,
|
| ConstantExpression constant, _) {
|
| - return buildConstant(constant);
|
| + return buildConstantExpression(constant);
|
| }
|
|
|
| /// If [node] is null, returns this.
|
| @@ -654,7 +639,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ast.Send node,
|
| ConstantExpression constant,
|
| _) {
|
| - return buildConstant(constant);
|
| + return buildConstantExpression(constant);
|
| }
|
|
|
| @override
|
| @@ -663,7 +648,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| LocalVariableElement element,
|
| _) {
|
| return element.isConst
|
| - ? buildConstant(getConstantForVariable(element))
|
| + ? irBuilder.buildConstant(getConstantForVariable(element))
|
| : irBuilder.buildLocalVariableGet(element);
|
| }
|
|
|
| @@ -973,7 +958,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| ast.NodeList arguments,
|
| CallStructure callStructure,
|
| _) {
|
| - ir.Primitive target = buildConstant(constant);
|
| + ir.Primitive target = buildConstantExpression(constant);
|
| return translateCallInvoke(target, arguments, callStructure);
|
| }
|
|
|
| @@ -1302,7 +1287,7 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| CompoundRhs rhs,
|
| arg) {
|
| return translateCompounds(
|
| - getValue: () => buildConstant(constant),
|
| + getValue: () => buildConstantExpression(constant),
|
| rhs: rhs,
|
| setValue: (value) {}); // The binary operator will throw before this.
|
| }
|
| @@ -1523,29 +1508,49 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
|
| });
|
| }
|
|
|
| + /// Evaluates a string interpolation and appends each part to [accumulator]
|
| + /// (after stringify conversion).
|
| + void buildStringParts(ast.Node node, List<ir.Primitive> accumulator) {
|
| + if (node is ast.StringJuxtaposition) {
|
| + buildStringParts(node.first, accumulator);
|
| + buildStringParts(node.second, accumulator);
|
| + } else if (node is ast.StringInterpolation) {
|
| + buildStringParts(node.string, accumulator);
|
| + for (ast.StringInterpolationPart part in node.parts) {
|
| + buildStringParts(part.expression, accumulator);
|
| + buildStringParts(part.string, accumulator);
|
| + }
|
| + } else if (node is ast.LiteralString) {
|
| + // Empty strings often occur at the end of a string interpolation,
|
| + // do not bother to include them.
|
| + if (!node.dartString.isEmpty) {
|
| + accumulator.add(irBuilder.buildDartStringConstant(node.dartString));
|
| + }
|
| + } else if (node is ast.ParenthesizedExpression) {
|
| + buildStringParts(node.expression, accumulator);
|
| + } else {
|
| + ir.Primitive value = visit(node);
|
| + accumulator.add(irBuilder.buildStringify(value));
|
| + }
|
| + }
|
| +
|
| ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) {
|
| assert(irBuilder.isOpen);
|
| - ir.Primitive first = visit(node.first);
|
| - ir.Primitive second = visit(node.second);
|
| - return irBuilder.buildStringConcatenation([first, second]);
|
| + List<ir.Primitive> parts = <ir.Primitive>[];
|
| + buildStringParts(node, parts);
|
| + return irBuilder.buildStringConcatenation(parts);
|
| }
|
|
|
| ir.Primitive visitStringInterpolation(ast.StringInterpolation node) {
|
| assert(irBuilder.isOpen);
|
| - List<ir.Primitive> arguments = [];
|
| - arguments.add(visitLiteralString(node.string));
|
| - var it = node.parts.iterator;
|
| - while (it.moveNext()) {
|
| - ast.StringInterpolationPart part = it.current;
|
| - arguments.add(visit(part.expression));
|
| - arguments.add(visitLiteralString(part.string));
|
| - }
|
| - return irBuilder.buildStringConcatenation(arguments);
|
| + List<ir.Primitive> parts = <ir.Primitive>[];
|
| + buildStringParts(node, parts);
|
| + return irBuilder.buildStringConcatenation(parts);
|
| }
|
|
|
| ir.Primitive translateConstant(ast.Node node) {
|
| assert(irBuilder.isOpen);
|
| - return buildConstant(getConstantForNode(node));
|
| + return irBuilder.buildConstant(getConstantForNode(node));
|
| }
|
|
|
| ir.Primitive visitThrow(ast.Throw node) {
|
| @@ -2099,6 +2104,10 @@ class GlobalProgramInformation {
|
| return cls.typeVariables.isNotEmpty && _backend.classNeedsRti(cls);
|
| }
|
|
|
| + FunctionElement get stringifyFunction {
|
| + return _backend.getStringInterpolationHelper();
|
| + }
|
| +
|
| FunctionElement get throwTypeErrorHelper => _backend.getThrowTypeError();
|
|
|
| ClassElement get nullClass => _compiler.nullClass;
|
| @@ -2881,10 +2890,9 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
|
| }
|
|
|
| ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) {
|
| - ConstantExpression constant =
|
| - backend.constants.getConstantForVariable(field);
|
| + ConstantValue constant = getConstantForVariable(field);
|
| if (constant != null && !field.isAssignable) {
|
| - return buildConstant(constant);
|
| + return irBuilder.buildConstant(constant);
|
| } else if (backend.constants.lazyStatics.contains(field)) {
|
| return irBuilder.buildStaticFieldLazyGet(field, src);
|
| } else {
|
| @@ -3028,8 +3036,7 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
|
| TypeConstantValue constant = argumentValue.value;
|
| ConstantValue interceptorValue =
|
| new InterceptorConstantValue(constant.representedType);
|
| - return irBuilder.buildConstant(argumentValue.expression,
|
| - interceptorValue);
|
| + return irBuilder.buildConstant(interceptorValue);
|
| } else {
|
| internalError(argument, 'expected Type as argument');
|
| }
|
|
|