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 2ca8fdf0c624e8dde3495dda29bd4629fd0d2948..14b457dbf499c03e34faafdd6cdb3f1bf0d0b5a9 100644 |
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart |
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart |
@@ -11,6 +11,13 @@ import '../elements/elements.dart'; |
import '../io/source_information.dart' show SourceInformation; |
import '../universe/universe.dart' show Selector; |
+// 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 |
@@ -171,6 +178,7 @@ class InvokeStatic extends Expression implements Invoke { |
final Selector selector; |
final SourceInformation sourceInformation; |
+ // TODO(karlklose): this should be a named constructor argument. |
/// True if the [target] is known not to diverge or read or write any |
/// mutable state. |
/// |
@@ -751,6 +759,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.) |
@@ -797,6 +854,7 @@ abstract class ExpressionVisitor<E> { |
E visitReadTypeVariable(ReadTypeVariable node); |
E visitTypeExpression(TypeExpression node); |
E visitCreateInvocationMirror(CreateInvocationMirror node); |
+ E visitForeignExpression(ForeignExpression node); |
} |
abstract class ExpressionVisitor1<E, A> { |
@@ -827,6 +885,7 @@ abstract class ExpressionVisitor1<E, A> { |
E visitReadTypeVariable(ReadTypeVariable node, A arg); |
E visitTypeExpression(TypeExpression node, A arg); |
E visitCreateInvocationMirror(CreateInvocationMirror node, A arg); |
+ E visitForeignExpression(ForeignExpression node, A arg); |
} |
abstract class StatementVisitor<S> { |
@@ -843,6 +902,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> { |
@@ -859,6 +919,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 { |
@@ -1024,7 +1085,15 @@ abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor { |
node.arguments.forEach(visitExpression); |
} |
- visitUnreachable(Unreachable node) {} |
+ visitUnreachable(Unreachable node) { |
+ } |
+ |
+ visitForeignCode(ForeignCode node) { |
+ node.arguments.forEach(visitExpression); |
+ } |
+ |
+ visitForeignExpression(ForeignExpression node) => visitForeignCode(node); |
+ visitForeignStatement(ForeignStatement node) => visitForeignCode(node); |
} |
abstract class Transformer implements ExpressionVisitor<Expression>, |
@@ -1222,6 +1291,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; |
} |