Index: pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart |
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart |
index 2962837dd758d53d7b918c86bb6b1d78edb742e9..41b7bcda507566afd1ae51043dc2fd654d819fc0 100644 |
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart |
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart |
@@ -14,6 +14,13 @@ import '../universe/universe.dart' show Selector; |
import '../cps_ir/builtin_operator.dart'; |
export '../cps_ir/builtin_operator.dart'; |
+// These imports are only used for the JavaScript specific nodes. If we want to |
+// support more than one native backend, we should probably create better |
+// abstractions for native code and its type and effect system. |
+import '../js/js.dart' as js show Template; |
+import '../native/native.dart' as native show NativeBehavior; |
+import '../types/types.dart' as types show TypeMask; |
+ |
// The Tree language is the target of translation out of the CPS-based IR. |
// |
// The translation from CPS to Dart consists of several stages. Among the |
@@ -776,6 +783,55 @@ class CreateInvocationMirror extends Expression { |
} |
} |
+class ForeignCode extends Node { |
+ final js.Template codeTemplate; |
+ final types.TypeMask type; |
+ final List<Expression> arguments; |
+ final native.NativeBehavior nativeBehavior; |
+ final Element dependency; |
+ |
+ ForeignCode(this.codeTemplate, this.type, this.arguments, this.nativeBehavior, |
+ this.dependency); |
+} |
+ |
+class ForeignExpression extends ForeignCode implements Expression { |
+ ForeignExpression(js.Template codeTemplate, types.TypeMask type, |
+ List<Expression> arguments, native.NativeBehavior nativeBehavior, |
+ Element dependency) |
+ : super(codeTemplate, type, arguments, nativeBehavior, |
+ dependency); |
+ |
+ accept(ExpressionVisitor visitor) { |
+ return visitor.visitForeignExpression(this); |
+ } |
+ |
+ accept1(ExpressionVisitor1 visitor, arg) { |
+ return visitor.visitForeignExpression(this, arg); |
+ } |
+} |
+ |
+class ForeignStatement extends ForeignCode implements Statement { |
+ ForeignStatement(js.Template codeTemplate, types.TypeMask type, |
+ List<Expression> arguments, native.NativeBehavior nativeBehavior, |
+ Element dependency) |
+ : super(codeTemplate, type, arguments, nativeBehavior, |
+ dependency); |
+ |
+ accept(StatementVisitor visitor) { |
+ return visitor.visitForeignStatement(this); |
+ } |
+ |
+ accept1(StatementVisitor1 visitor, arg) { |
+ return visitor.visitForeignStatement(this, arg); |
+ } |
+ |
+ @override |
+ Statement get next => null; |
+ |
+ @override |
+ void set next(Statement s) => throw 'UNREACHABLE'; |
+} |
+ |
/// Denotes the internal representation of [dartType], where all type variables |
/// are replaced by the values in [arguments]. |
/// (See documentation on the TypeExpression CPS node for more details.) |
@@ -823,6 +879,7 @@ abstract class ExpressionVisitor<E> { |
E visitTypeExpression(TypeExpression node); |
E visitCreateInvocationMirror(CreateInvocationMirror node); |
E visitApplyBuiltinOperator(ApplyBuiltinOperator node); |
+ E visitForeignExpression(ForeignExpression node); |
} |
abstract class ExpressionVisitor1<E, A> { |
@@ -854,6 +911,7 @@ abstract class ExpressionVisitor1<E, A> { |
E visitTypeExpression(TypeExpression node, A arg); |
E visitCreateInvocationMirror(CreateInvocationMirror node, A arg); |
E visitApplyBuiltinOperator(ApplyBuiltinOperator node, A arg); |
+ E visitForeignExpression(ForeignExpression node, A arg); |
} |
abstract class StatementVisitor<S> { |
@@ -870,6 +928,7 @@ abstract class StatementVisitor<S> { |
S visitExpressionStatement(ExpressionStatement node); |
S visitTry(Try node); |
S visitUnreachable(Unreachable node); |
+ S visitForeignStatement(ForeignStatement node); |
} |
abstract class StatementVisitor1<S, A> { |
@@ -886,6 +945,7 @@ abstract class StatementVisitor1<S, A> { |
S visitExpressionStatement(ExpressionStatement node, A arg); |
S visitTry(Try node, A arg); |
S visitUnreachable(Unreachable node, A arg); |
+ S visitForeignStatement(ForeignStatement node, A arg); |
} |
abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor { |
@@ -1051,11 +1111,19 @@ abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor { |
node.arguments.forEach(visitExpression); |
} |
- visitUnreachable(Unreachable node) {} |
+ visitUnreachable(Unreachable node) { |
+ } |
visitApplyBuiltinOperator(ApplyBuiltinOperator node) { |
node.arguments.forEach(visitExpression); |
} |
+ |
+ visitForeignCode(ForeignCode node) { |
+ node.arguments.forEach(visitExpression); |
+ } |
+ |
+ visitForeignExpression(ForeignExpression node) => visitForeignCode(node); |
+ visitForeignStatement(ForeignStatement node) => visitForeignCode(node); |
} |
abstract class Transformer implements ExpressionVisitor<Expression>, |
@@ -1253,6 +1321,16 @@ class RecursiveTransformer extends Transformer { |
return node; |
} |
+ visitForeignExpression(ForeignExpression node) { |
+ _replaceExpressions(node.arguments); |
+ return node; |
+ } |
+ |
+ visitForeignStatement(ForeignStatement node) { |
+ _replaceExpressions(node.arguments); |
+ return node; |
+ } |
+ |
visitUnreachable(Unreachable node) { |
return node; |
} |