Index: lib/src/codegen/js_codegen.dart |
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart |
index 554b4bbea171189c09aafbb4f6d3c4e3c3c1048c..81166e316a183f91531a59a2153e2b305fa155f5 100644 |
--- a/lib/src/codegen/js_codegen.dart |
+++ b/lib/src/codegen/js_codegen.dart |
@@ -757,9 +757,12 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor { |
JS.Block visitBlock(Block node) => new JS.Block(_visitList(node.statements)); |
@override |
- JS.Expression visitMethodInvocation(MethodInvocation node) { |
+ visitMethodInvocation(MethodInvocation node) { |
var target = node.isCascaded ? _cascadeTarget : node.target; |
+ var result = _emitForeignJS(node); |
+ if (result != null) return result; |
+ |
if (rules.isDynamicCall(node.methodName)) { |
var args = node.argumentList.accept(this); |
if (target != null) { |
@@ -787,6 +790,25 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor { |
return js.call('#(#)', [targetJs, node.argumentList.accept(this)]); |
} |
+ /// Emits code for the `JS(...)` builtin. |
+ _emitForeignJS(MethodInvocation node) { |
+ var e = node.methodName.staticElement; |
+ if (e is FunctionElement && |
+ e.library.name == '_foreign_helper' && |
+ e.name == 'JS') { |
+ var args = node.argumentList.arguments; |
+ // arg[0] is static return type, used in `RestrictedStaticTypeAnalyzer` |
+ var code = args[1] as StringLiteral; |
+ |
+ var template = js.parseForeignJS(code.stringValue); |
+ var result = template.instantiate(_visitList(args.skip(2))); |
+ // `throw` is emitted as a statement by `parseForeignJS`. |
+ assert(result is JS.Expression || node.parent is ExpressionStatement); |
+ return result; |
+ } |
+ return null; |
+ } |
+ |
@override |
JS.Expression visitFunctionExpressionInvocation( |
FunctionExpressionInvocation node) { |