blob: ddef20aa35bf7412e7eeddfacb57dd7e67d7bf77 [file] [log] [blame]
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:kernel/ast.dart' as ir;
import '../compiler.dart';
import 'builder_kernel.dart';
import 'kernel_ast_adapter.dart';
import 'nodes.dart';
/// Visits and concatenates the expressions in a string concatenation.
class KernelStringBuilder extends ir.Visitor {
final KernelSsaBuilder builder;
Compiler get compiler => builder.compiler;
KernelAstAdapter get astAdapter => builder.astAdapter;
/// The string value generated so far.
HInstruction result = null;
KernelStringBuilder(this.builder);
@override
void defaultNode(ir.Node node) {
compiler.reporter
.internalError(astAdapter.getNode(node), 'Unexpected node.');
}
@override
void defaultExpression(ir.Expression node) {
node.accept(builder);
HInstruction expression = builder.pop();
// We want to use HStringify when:
// 1. The value is known to be a primitive type, because it might get
// constant-folded and codegen has some tricks with JavaScript
// conversions.
// 2. The value can be primitive, because the library stringifier has
// fast-path code for most primitives.
if (expression.canBePrimitive(builder.closedWorld)) {
append(stringify(expression));
return;
}
// TODO(efortuna): If we decide to do inlining before finishing constructing
// the control flow graph, we'd want to do the optimization of
// calling toString here if the type is provably a string rather than in the
// optimization phase (which is where we currently do it).
append(stringify(expression));
}
@override
void visitStringConcatenation(ir.StringConcatenation node) {
node.visitChildren(this);
}
void append(HInstruction expression) {
result = (result == null) ? expression : concat(result, expression);
}
HInstruction concat(HInstruction left, HInstruction right) {
HInstruction instruction =
new HStringConcat(left, right, builder.commonMasks.stringType);
builder.add(instruction);
return instruction;
}
HInstruction stringify(HInstruction expression) {
HInstruction instruction =
new HStringify(expression, builder.commonMasks.stringType);
builder.add(instruction);
return instruction;
}
}