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'); |
} |