blob: dfdadaf60ea53d3884c064d606307a7d7f96f9ce [file] [log] [blame]
// Copyright (c) 2013, 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.
// IrNodes are kept in a separate library to have precise control over their
// dependencies on other parts of the system.
library dart2js.ir_nodes;
import '../dart2jslib.dart' show Constant;
import '../elements/elements.dart' show FunctionElement, LibraryElement;
import 'ir_pickler.dart' show Pickler, IrConstantPool;
import '../universe/universe.dart' show Selector, SelectorKind;
import '../util/util.dart' show Spannable;
/**
* A pair of source offset and an identifier name. Identifier names are used in
* the Javascript backend to generate source maps.
*/
class PositionWithIdentifierName {
final int offset;
final String sourceName;
PositionWithIdentifierName(this.offset, this.sourceName);
}
abstract class IrNode implements Spannable {
static int hashCount = 0;
final int hashCode = hashCount = (hashCount + 1) & 0x3fffffff;
final /* int | PositionWithIdentifierName */ position;
const IrNode(this.position);
int get offset => (position is int) ? position : position.offset;
String get sourceName => (position is int) ? null : position.sourceName;
List<int> pickle(IrConstantPool constantPool) {
return new Pickler(constantPool).pickle(this);
}
accept(IrNodesVisitor visitor);
}
abstract class IrExpression extends IrNode {
IrExpression(position) : super(position);
}
class IrFunction extends IrExpression {
final List<IrNode> statements;
final int endOffset;
final int namePosition;
IrFunction(position, this.endOffset, this.namePosition, this.statements)
: super(position);
accept(IrNodesVisitor visitor) => visitor.visitIrFunction(this);
}
class IrReturn extends IrNode {
final IrExpression value;
IrReturn(position, this.value) : super(position);
accept(IrNodesVisitor visitor) => visitor.visitIrReturn(this);
}
class IrConstant extends IrExpression {
final Constant value;
IrConstant(position, this.value) : super(position);
accept(IrNodesVisitor visitor) => visitor.visitIrConstant(this);
}
class IrInvokeStatic extends IrExpression {
final FunctionElement target;
final List<IrExpression> arguments;
/**
* The selector encodes how the function is invoked: number of positional
* arguments, names used in named arguments. This information is required
* to build the [StaticCallSiteTypeInformation] for the inference graph.
*/
final Selector selector;
IrInvokeStatic(position, this.target, this.selector, this.arguments)
: super(position) {
assert(selector.kind == SelectorKind.CALL);
assert(selector.name == target.name);
}
accept(IrNodesVisitor visitor) => visitor.visitIrInvokeStatic(this);
}
/**
* This class is only used during SSA generation, its instances never appear in
* the representation of a function. See [SsaFromAstInliner.enterInlinedMethod].
*/
class IrInlinedInvocationDummy extends IrExpression {
IrInlinedInvocationDummy() : super(0);
accept(IrNodesVisitor visitor) => throw "IrInlinedInvocationDummy.accept";
}
abstract class IrNodesVisitor<T> {
T visit(IrNode node) => node.accept(this);
void visitAll(List<IrNode> nodes) {
for (IrNode n in nodes) visit(n);
}
T visitIrNode(IrNode node);
T visitIrExpression(IrExpression node) => visitIrNode(node);
T visitIrFunction(IrFunction node) => visitIrExpression(node);
T visitIrReturn(IrReturn node) => visitIrNode(node);
T visitIrConstant(IrConstant node) => visitIrExpression(node);
T visitIrInvokeStatic(IrInvokeStatic node) => visitIrExpression(node);
}