blob: 5282c6b996079534a41ddbad35ac2c928563ec37 [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' as dart2js 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 Node implements Spannable {
static int hashCount = 0;
final int hashCode = hashCount = (hashCount + 1) & 0x3fffffff;
final /* int | PositionWithIdentifierName */ position;
const Node(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(NodesVisitor visitor);
}
abstract class Expression extends Node {
Expression(position) : super(position);
}
class Function extends Expression {
final List<Node> statements;
final int endOffset;
final int namePosition;
Function(position, this.endOffset, this.namePosition, this.statements)
: super(position);
accept(NodesVisitor visitor) => visitor.visitFunction(this);
}
class Return extends Node {
final Expression value;
Return(position, this.value) : super(position);
accept(NodesVisitor visitor) => visitor.visitReturn(this);
}
class Constant extends Expression {
final dart2js.Constant value;
Constant(position, this.value) : super(position);
accept(NodesVisitor visitor) => visitor.visitConstant(this);
}
class InvokeStatic extends Expression {
final FunctionElement target;
final List<Expression> 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;
InvokeStatic(position, this.target, this.selector, this.arguments)
: super(position) {
assert(selector.kind == SelectorKind.CALL);
assert(selector.name == target.name);
}
accept(NodesVisitor visitor) => visitor.visitInvokeStatic(this);
}
/**
* This class is only used during SSA generation, its instances never appear in
* the representation of a function.
*/
class InlinedInvocationDummy extends Expression {
InlinedInvocationDummy() : super(0);
accept(NodesVisitor visitor) => throw "IrInlinedInvocationDummy.accept";
}
abstract class NodesVisitor<T> {
T visit(Node node) => node.accept(this);
void visitAll(List<Node> nodes) {
for (Node n in nodes) visit(n);
}
T visitNode(Node node);
T visitExpression(Expression node) => visitNode(node);
T visitFunction(Function node) => visitExpression(node);
T visitReturn(Return node) => visitNode(node);
T visitConstant(Constant node) => visitExpression(node);
T visitInvokeStatic(InvokeStatic node) => visitExpression(node);
}