Revert "Redo "Steps towards making dart2js JS AST templates an indepentent library.""

Investigating failure of dart2js_incremental.

TBR=floitsch@google.com

Review URL: https://codereview.chromium.org//922463002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@43710 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index c0e6e0a8..5294261 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -8,13 +8,12 @@
 import '../elements/elements.dart' show AstElement;
 import '../scanner/scannerlib.dart' show Token;
 import '../tree/tree.dart' show Node;
-import '../js/js.dart' show JavaScriptNodeSourceInformation;
 import 'code_output.dart';
 import 'source_file.dart';
 
 /// Interface for passing source information, for instance for use in source
 /// maps, through the backend.
-abstract class SourceInformation extends JavaScriptNodeSourceInformation {
+abstract class SourceInformation {
   SourceSpan get sourceSpan;
   void beginMapping(CodeOutput output);
   void endMapping(CodeOutput output);
diff --git a/pkg/compiler/lib/src/js/builder.dart b/pkg/compiler/lib/src/js/builder.dart
index 72b4507..0fa01cc 100644
--- a/pkg/compiler/lib/src/js/builder.dart
+++ b/pkg/compiler/lib/src/js/builder.dart
@@ -5,7 +5,7 @@
 // Utilities for building JS ASTs at runtime.  Contains a builder class
 // and a parser that parses part of the language.
 
-part of js_ast;
+part of js;
 
 
 /**
diff --git a/pkg/compiler/lib/src/js/characters.dart b/pkg/compiler/lib/src/js/characters.dart
deleted file mode 100644
index ae6740f..0000000
--- a/pkg/compiler/lib/src/js/characters.dart
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2015, 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.
-
-library js_character_codes;
-
-const int $EOF = 0;
-const int $STX = 2;
-const int $BS  = 8;
-const int $TAB = 9;
-const int $LF = 10;
-const int $VTAB = 11;
-const int $FF = 12;
-const int $CR = 13;
-const int $SPACE = 32;
-const int $BANG = 33;
-const int $DQ = 34;
-const int $HASH = 35;
-const int $$ = 36;
-const int $PERCENT = 37;
-const int $AMPERSAND = 38;
-const int $SQ = 39;
-const int $OPEN_PAREN = 40;
-const int $CLOSE_PAREN = 41;
-const int $STAR = 42;
-const int $PLUS = 43;
-const int $COMMA = 44;
-const int $MINUS = 45;
-const int $PERIOD = 46;
-const int $SLASH = 47;
-const int $0 = 48;
-const int $1 = 49;
-const int $2 = 50;
-const int $3 = 51;
-const int $4 = 52;
-const int $5 = 53;
-const int $6 = 54;
-const int $7 = 55;
-const int $8 = 56;
-const int $9 = 57;
-const int $COLON = 58;
-const int $SEMICOLON = 59;
-const int $LT = 60;
-const int $EQ = 61;
-const int $GT = 62;
-const int $QUESTION = 63;
-const int $AT = 64;
-const int $A = 65;
-const int $B = 66;
-const int $C = 67;
-const int $D = 68;
-const int $E = 69;
-const int $F = 70;
-const int $G = 71;
-const int $H = 72;
-const int $I = 73;
-const int $J = 74;
-const int $K = 75;
-const int $L = 76;
-const int $M = 77;
-const int $N = 78;
-const int $O = 79;
-const int $P = 80;
-const int $Q = 81;
-const int $R = 82;
-const int $S = 83;
-const int $T = 84;
-const int $U = 85;
-const int $V = 86;
-const int $W = 87;
-const int $X = 88;
-const int $Y = 89;
-const int $Z = 90;
-const int $OPEN_SQUARE_BRACKET = 91;
-const int $BACKSLASH = 92;
-const int $CLOSE_SQUARE_BRACKET = 93;
-const int $CARET = 94;
-const int $_ = 95;
-const int $BACKPING = 96;
-const int $a = 97;
-const int $b = 98;
-const int $c = 99;
-const int $d = 100;
-const int $e = 101;
-const int $f = 102;
-const int $g = 103;
-const int $h = 104;
-const int $i = 105;
-const int $j = 106;
-const int $k = 107;
-const int $l = 108;
-const int $m = 109;
-const int $n = 110;
-const int $o = 111;
-const int $p = 112;
-const int $q = 113;
-const int $r = 114;
-const int $s = 115;
-const int $t = 116;
-const int $u = 117;
-const int $v = 118;
-const int $w = 119;
-const int $x = 120;
-const int $y = 121;
-const int $z = 122;
-const int $OPEN_CURLY_BRACKET = 123;
-const int $BAR = 124;
-const int $CLOSE_CURLY_BRACKET = 125;
-const int $TILDE = 126;
-const int $DEL = 127;
-const int $NBSP = 160;
-const int $LS = 0x2028;
-const int $PS = 0x2029;
-
-const int $FIRST_SURROGATE = 0xd800;
-const int $LAST_SURROGATE = 0xdfff;
-const int $LAST_CODE_POINT = 0x10ffff;
diff --git a/pkg/compiler/lib/src/js/js.dart b/pkg/compiler/lib/src/js/js.dart
index a5bbec4..fac460d 100644
--- a/pkg/compiler/lib/src/js/js.dart
+++ b/pkg/compiler/lib/src/js/js.dart
@@ -1,64 +1,23 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2012, 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.
 
 library js;
 
-// TODO(sra): This will become a package import.
-import 'js_ast.dart';
-export 'js_ast.dart';
-
+import 'precedence.dart';
+import '../util/characters.dart' as charCodes;
+import '../util/util.dart';
 import '../io/code_output.dart' show CodeBuffer;
 import '../io/source_information.dart' show SourceInformation;
 import '../js_emitter/js_emitter.dart' show USE_NEW_EMITTER;
+
+// TODO(floitsch): remove this dependency (currently necessary for the
+// CodeBuffer).
 import '../dart2jslib.dart' as leg;
-import '../util/util.dart' show NO_LOCATION_SPANNABLE;
-import '../dump_info.dart' show DumpInfoTask;
 
+import '../dump_info.dart';
 
-CodeBuffer prettyPrint(Node node, leg.Compiler compiler,
-                       {DumpInfoTask monitor,
-                        bool allowVariableMinification: true}) {
-  JavaScriptPrintingOptions options = new JavaScriptPrintingOptions(
-      shouldCompressOutput: compiler.enableMinification,
-      minifyLocalVariables: allowVariableMinification,
-      preferSemicolonToNewlineInMinifiedOutput: USE_NEW_EMITTER);
-  Dart2JSJavaScriptPrintingContext context =
-      new Dart2JSJavaScriptPrintingContext(compiler, monitor);
-  Printer printer = new Printer(options, context);
-  printer.visit(node);
-  return context.outBuffer;
-}
-
-class Dart2JSJavaScriptPrintingContext implements JavaScriptPrintingContext {
-  final leg.Compiler compiler;
-  final DumpInfoTask monitor;
-  final CodeBuffer outBuffer = new CodeBuffer();
-
-  Dart2JSJavaScriptPrintingContext(leg.Compiler this.compiler,
-      DumpInfoTask this.monitor);
-
-  void error(String message) {
-    compiler.internalError(NO_LOCATION_SPANNABLE, message);
-  }
-
-  void emit(String string) {
-    outBuffer.add(string);
-  }
-
-  void enterNode(Node node) {
-    SourceInformation sourceInformation = node.sourceInformation;
-    if (sourceInformation != null) {
-      sourceInformation.beginMapping(outBuffer);
-    }
-    if (monitor != null) monitor.enteringAst(node, outBuffer.length);
-  }
-
-  void exitNode(Node node) {
-    if (monitor != null) monitor.exitingAst(node, outBuffer.length);
-    SourceInformation sourceInformation = node.sourceInformation;
-    if (sourceInformation != null) {
-      sourceInformation.endMapping(outBuffer);
-    }
-  }
-}
+part 'nodes.dart';
+part 'builder.dart';
+part 'printer.dart';
+part 'template.dart';
diff --git a/pkg/compiler/lib/src/js/js_ast.dart b/pkg/compiler/lib/src/js/js_ast.dart
deleted file mode 100644
index ee8289e..0000000
--- a/pkg/compiler/lib/src/js/js_ast.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2015, 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.
-
-library js_ast;
-
-import 'precedence.dart';
-import 'characters.dart' as charCodes;
-
-part 'nodes.dart';
-part 'builder.dart';
-part 'printer.dart';
-part 'template.dart';
diff --git a/pkg/compiler/lib/src/js/nodes.dart b/pkg/compiler/lib/src/js/nodes.dart
index 92446fa..60b3a85 100644
--- a/pkg/compiler/lib/src/js/nodes.dart
+++ b/pkg/compiler/lib/src/js/nodes.dart
@@ -2,7 +2,7 @@
 // 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.
 
-part of js_ast;
+part of js;
 
 abstract class NodeVisitor<T> {
   T visitProgram(Program node);
@@ -29,6 +29,7 @@
   T visitLiteralStatement(LiteralStatement node);
   T visitDartYield(DartYield node);
 
+  T visitBlob(Blob node);
   T visitLiteralExpression(LiteralExpression node);
   T visitVariableDeclarationList(VariableDeclarationList node);
   T visitAssignment(Assignment node);
@@ -108,6 +109,7 @@
   T visitDefault(Default node) => visitNode(node);
 
   T visitExpression(Expression node) => visitNode(node);
+  T visitBlob(Blob node) => visitExpression(node);
   T visitVariableReference(VariableReference node) => visitExpression(node);
 
   T visitLiteralExpression(LiteralExpression node) => visitExpression(node);
@@ -171,14 +173,10 @@
   T visitDartYield(DartYield node) => visitStatement(node);
 }
 
-/// This tag interface has no behaviour but must be implemented by any class
-/// that is to be stored on a [Node] as source information.
-abstract class JavaScriptNodeSourceInformation {}
-
 abstract class Node {
-  JavaScriptNodeSourceInformation get sourceInformation => _sourceInformation;
+  SourceInformation get sourceInformation => _sourceInformation;
 
-  JavaScriptNodeSourceInformation _sourceInformation;
+  SourceInformation _sourceInformation;
 
   accept(NodeVisitor visitor);
   void visitChildren(NodeVisitor visitor);
@@ -189,8 +187,7 @@
 
   // Returns a node equivalent to [this], but with new source position and end
   // source position.
-  Node withSourceInformation(
-      JavaScriptNodeSourceInformation sourceInformation) {
+  Node withSourceInformation(SourceInformation sourceInformation) {
     if (sourceInformation == _sourceInformation) {
       return this;
     }
@@ -525,8 +522,8 @@
   LiteralStatement _clone() => new LiteralStatement(code);
 }
 
-// Not a real JavaScript node, but represents the yield statement from a dart
-// program translated to JavaScript.
+// Not a real javascript node, but represents the yield statement from a dart
+// program translated to javascript.
 class DartYield extends Statement {
   final Expression expression;
 
@@ -549,6 +546,25 @@
   Statement toStatement() => new ExpressionStatement(this);
 }
 
+/// Wrap a CodeBuffer as an expression.
+class Blob extends Expression {
+  // TODO(ahe): This class is an aid to convert everything to ASTs, remove when
+  // not needed anymore.
+
+  final CodeBuffer buffer;
+
+  Blob(this.buffer);
+
+  accept(NodeVisitor visitor) => visitor.visitBlob(this);
+
+  void visitChildren(NodeVisitor visitor) {}
+
+  Blob _clone() => new Blob(buffer);
+
+  int get precedenceLevel => PRIMARY;
+
+}
+
 class LiteralExpression extends Expression {
   final String template;
   final List<Expression> inputs;
@@ -931,12 +947,9 @@
   /**
    * Constructs a LiteralString from a string value.
    *
-   * The constructor does not add the required quotes.  If [value] is not
-   * surrounded by quotes and property escaped, the resulting object is invalid
-   * as a JS value.
-   *
-   * TODO(sra): Introduce variants for known valid strings that don't allocate a
-   * new string just to add quotes.
+   * The constructor does not add the required quotes.  If [value] is
+   * not surrounded by quotes, the resulting object is invalid as a JS
+   * value.
    */
   LiteralString(this.value);
 
@@ -945,7 +958,7 @@
 }
 
 class LiteralNumber extends Literal {
-  final String value;  // Must be a valid JavaScript number literal.
+  final String value;
 
   LiteralNumber(this.value);
 
@@ -1114,7 +1127,7 @@
 /**
  * An asynchronous await.
  *
- * Not part of JavaScript. We desugar this expression before outputting.
+ * Not part of javascript. We desugar this expression before outputting.
  * Should only occur in a [Fun] with `asyncModifier` async or asyncStar.
  */
 class Await extends Expression {
diff --git a/pkg/compiler/lib/src/js/printer.dart b/pkg/compiler/lib/src/js/printer.dart
index 6ee3f3e..d359a05 100644
--- a/pkg/compiler/lib/src/js/printer.dart
+++ b/pkg/compiler/lib/src/js/printer.dart
@@ -2,77 +2,32 @@
 // 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.
 
-part of js_ast;
+part of js;
 
-
-class JavaScriptPrintingOptions {
+class Printer extends Indentation implements NodeVisitor {
   final bool shouldCompressOutput;
-  final bool minifyLocalVariables;
-  final bool preferSemicolonToNewlineInMinifiedOutput;
-
-  JavaScriptPrintingOptions(
-      {this.shouldCompressOutput: false,
-       this.minifyLocalVariables: false,
-       this.preferSemicolonToNewlineInMinifiedOutput: false});
-}
-
-
-/// An environment in which JavaScript printing is done.  Provides emitting of
-/// text and pre- and post-visit callbacks.
-abstract class JavaScriptPrintingContext {
-  /// Signals an error.  This should happen only for serious internal errors.
-  void error(String message) { throw message; }
-
-  /// Adds [string] to the output.
-  void emit(String string);
-
-  /// Callback immediately before printing [node].  Whitespace may be printed
-  /// after this callback before the first non-whitespace character for [node].
-  void enterNode(Node node) {}
-  /// Callback after printing the last character representing [node].
-  void exitNode(Node node) {}
-}
-
-/// A simple implementation of [JavaScriptPrintingContext] suitable for tests.
-class SimpleJavaScriptPrintingContext extends JavaScriptPrintingContext {
-  final StringBuffer buffer = new StringBuffer();
-
-  void emit(String string) {
-    buffer.write(string);
-  }
-
-  String getText() => buffer.toString();
-}
-
-
-class Printer implements NodeVisitor {
-  final JavaScriptPrintingOptions options;
-  final JavaScriptPrintingContext context;
-  final bool shouldCompressOutput;
-  final DanglingElseVisitor danglingElseVisitor;
-  final LocalNamer localNamer;
-
+  leg.DiagnosticListener diagnosticListener;
+  CodeBuffer outBuffer;
   bool inForInit = false;
   bool atStatementBegin = false;
+  final DanglingElseVisitor danglingElseVisitor;
+  final LocalNamer localNamer;
   bool pendingSemicolon = false;
   bool pendingSpace = false;
-
-  // The current indentation level.
-  int _indentLevel = 0;
-  // A cache of all indentation strings used so far.
-  List<String> _indentList = <String>[""];
+  DumpInfoTask monitor = null;
 
   static final identifierCharacterRegExp = new RegExp(r'^[a-zA-Z_0-9$]');
   static final expressionContinuationRegExp = new RegExp(r'^[-+([]');
 
-  Printer(JavaScriptPrintingOptions options,
-          JavaScriptPrintingContext context)
-      : options = options,
-        context = context,
-        shouldCompressOutput = options.shouldCompressOutput,
-        danglingElseVisitor = new DanglingElseVisitor(context),
-        localNamer = determineRenamer(options.shouldCompressOutput,
-                                      options.minifyLocalVariables);
+  Printer(leg.DiagnosticListener diagnosticListener, DumpInfoTask monitor,
+          { bool enableMinification: false, allowVariableMinification: true })
+      : shouldCompressOutput = enableMinification,
+        monitor = monitor,
+        diagnosticListener = diagnosticListener,
+        outBuffer = new CodeBuffer(),
+        danglingElseVisitor = new DanglingElseVisitor(diagnosticListener),
+        localNamer = determineRenamer(enableMinification,
+                                      allowVariableMinification);
 
   static LocalNamer determineRenamer(bool shouldCompressOutput,
                                      bool allowVariableMinification) {
@@ -80,25 +35,6 @@
         ? new MinifyRenamer() : new IdentityNamer();
   }
 
-
-  // The current indentation string.
-  String get indentation {
-    // Lazily add new indentation strings as required.
-    while (_indentList.length <= _indentLevel) {
-      _indentList.add(_indentList.last + "  ");
-    }
-    return _indentList[_indentLevel];
-  }
-
-  void indentMore() {
-    _indentLevel++;
-  }
-
-  void indentLess() {
-    _indentLevel--;
-  }
-
-
   /// Always emit a newline, even under `enableMinification`.
   void forceLine() {
     out("\n");
@@ -122,7 +58,7 @@
     if (str != "") {
       if (pendingSemicolon) {
         if (!shouldCompressOutput) {
-          context.emit(";");
+          outBuffer.add(";");
         } else if (str != "}") {
           // We want to output newline instead of semicolon because it makes
           // the raw stack traces much easier to read and it also makes line-
@@ -135,21 +71,20 @@
           // If we're using the new emitter where most pretty printed code
           // is escaped in strings, it is a lot easier to deal with semicolons
           // than newlines because the former doesn't need escaping.
-          if (options.preferSemicolonToNewlineInMinifiedOutput ||
-              expressionContinuationRegExp.hasMatch(str)) {
-            context.emit(";");
+          if (USE_NEW_EMITTER || expressionContinuationRegExp.hasMatch(str)) {
+            outBuffer.add(";");
           } else {
-            context.emit("\n");
+            outBuffer.add("\n");
           }
         }
       }
       if (pendingSpace &&
           (!shouldCompressOutput || identifierCharacterRegExp.hasMatch(str))) {
-        context.emit(" ");
+        outBuffer.add(" ");
       }
       pendingSpace = false;
       pendingSemicolon = false;
-      context.emit(str);
+      outBuffer.add(str);
       lastAddedString = str;
     }
   }
@@ -176,10 +111,26 @@
     }
   }
 
+  void beginSourceRange(Node node) {
+    if (node.sourceInformation != null) {
+      node.sourceInformation.beginMapping(outBuffer);
+    }
+  }
+
+  void endSourceRange(Node node) {
+    if (node.sourceInformation != null) {
+      node.sourceInformation.endMapping(outBuffer);
+    }
+  }
+
   visit(Node node) {
-    context.enterNode(node);
+    beginSourceRange(node);
+    if (monitor != null) monitor.enteringAst(node, outBuffer.length);
+
     node.accept(this);
-    context.exitNode(node);
+
+    if (monitor != null) monitor.exitingAst(node, outBuffer.length);
+    endSourceRange(node);
   }
 
   visitCommaSeparated(List<Node> nodes, int hasRequiredType,
@@ -204,6 +155,10 @@
     visitAll(program.body);
   }
 
+  visitBlob(Blob node) {
+    outBuffer.addBuffer(node.buffer);
+  }
+
   bool blockBody(Node body, {bool needsSeparation, bool needsNewline}) {
     if (body is Block) {
       spaceOut();
@@ -217,18 +172,16 @@
     } else {
       lineOut();
     }
-    indentMore();
-    visit(body);
-    indentLess();
+    indentBlock(() => visit(body));
     return false;
   }
 
   void blockOutWithoutBraces(Node node) {
     if (node is Block) {
-      context.enterNode(node);
+      beginSourceRange(node);
       Block block = node;
       block.statements.forEach(blockOutWithoutBraces);
-      context.exitNode(node);
+      endSourceRange(node);
     } else {
       visit(node);
     }
@@ -236,15 +189,13 @@
 
   void blockOut(Block node, bool shouldIndent, bool needsNewline) {
     if (shouldIndent) indent();
-    context.enterNode(node);
+    beginSourceRange(node);
     out("{");
     lineOut();
-    indentMore();
-    node.statements.forEach(blockOutWithoutBraces);
-    indentLess();
+    indentBlock(() => node.statements.forEach(blockOutWithoutBraces));
     indent();
     out("}");
-    context.exitNode(node);
+    endSourceRange(node);
     if (needsNewline) lineOut();
   }
 
@@ -456,9 +407,7 @@
     out(")");
     spaceOut();
     outLn("{");
-    indentMore();
-    visitAll(node.cases);
-    indentLess();
+    indentBlock(() => visitAll(node.cases));
     outIndentLn("}");
   }
 
@@ -469,18 +418,14 @@
                           newInForInit: false, newAtStatementBegin: false);
     outLn(":");
     if (!node.body.statements.isEmpty) {
-      indentMore();
-      blockOutWithoutBraces(node.body);
-      indentLess();
+      indentBlock(() => blockOutWithoutBraces(node.body));
     }
   }
 
   visitDefault(Default node) {
     outIndentLn("default:");
     if (!node.body.statements.isEmpty) {
-      indentMore();
-      blockOutWithoutBraces(node.body);
-      indentLess();
+      indentBlock(() => blockOutWithoutBraces(node.body));
     }
   }
 
@@ -697,7 +642,8 @@
         rightPrecedenceRequirement = UNARY;
         break;
       default:
-        context.error("Forgot operator: $op");
+        diagnosticListener
+            .internalError(NO_LOCATION_SPANNABLE, "Forgot operator: $op");
     }
 
     visitNestedExpression(left, leftPrecedenceRequirement,
@@ -934,7 +880,8 @@
     List<String> parts = template.split('#');
     int inputsLength = inputs == null ? 0 : inputs.length;
     if (parts.length != inputsLength + 1) {
-      context.error('Wrong number of arguments for JS: $template');
+      diagnosticListener.internalError(NO_LOCATION_SPANNABLE,
+          'Wrong number of arguments for JS: $template');
     }
     // Code that uses JS must take care of operator precedences, and
     // put parenthesis if needed.
@@ -1061,14 +1008,15 @@
  * as then-statement in an [If] that has an else branch.
  */
 class DanglingElseVisitor extends BaseVisitor<bool> {
-  JavaScriptPrintingContext context;
+  leg.DiagnosticListener diagnosticListener;
 
-  DanglingElseVisitor(this.context);
+  DanglingElseVisitor(this.diagnosticListener);
 
   bool visitProgram(Program node) => false;
 
   bool visitNode(Statement node) {
-    context.error("Forgot node: $node");
+    diagnosticListener
+        .internalError(NO_LOCATION_SPANNABLE, "Forgot node: $node");
     return null;
   }
 
@@ -1107,6 +1055,18 @@
 }
 
 
+CodeBuffer prettyPrint(Node node, leg.Compiler compiler,
+                       {DumpInfoTask monitor,
+                        bool allowVariableMinification: true}) {
+  Printer printer =
+      new Printer(compiler, monitor,
+                  enableMinification: compiler.enableMinification,
+                  allowVariableMinification: allowVariableMinification);
+  printer.visit(node);
+  return printer.outBuffer;
+}
+
+
 abstract class LocalNamer {
   String getName(String oldName);
   String declareVariable(String oldName);
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 656b1af..3f5bfaa 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -966,6 +966,11 @@
   }
 
   @override
+  js.Expression visitBlob(js.Blob node) {
+    return node;
+  }
+
+  @override
   void visitBlock(js.Block node) {
     for (js.Statement statement in node.statements) {
       visitStatement(statement);
@@ -1817,6 +1822,11 @@
   }
 
   @override
+  bool visitBlob(js.Blob node) {
+    return false;
+  }
+
+  @override
   bool visitBlock(js.Block node) {
     bool containsAwait = false;
     for (js.Statement statement in node.statements) {
diff --git a/pkg/compiler/lib/src/js/template.dart b/pkg/compiler/lib/src/js/template.dart
index 7740431..f08fe52 100644
--- a/pkg/compiler/lib/src/js/template.dart
+++ b/pkg/compiler/lib/src/js/template.dart
@@ -2,7 +2,7 @@
 // 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.
 
-part of js_ast;
+part of js;
 
 class TemplateManager {
   Map<String, Template> expressionTemplates = new Map<String, Template>();
@@ -499,6 +499,8 @@
 
   Instantiator visitLiteralStatement(LiteralStatement node) =>
       TODO('visitLiteralStatement');
+  Instantiator visitBlob(Blob node) =>
+      TODO('visitBlob');
   Instantiator visitLiteralExpression(LiteralExpression node) =>
       TODO('visitLiteralExpression');
 
@@ -707,12 +709,12 @@
 }
 
 /**
- * InterpolatedNodeAnalysis determines which AST trees contain
- * [InterpolatedNode]s, and the names of the named interpolated nodes.
+ * InterpolatedNodeAnalysis extract [InterpolatedNode]s from AST.
  */
 class InterpolatedNodeAnalysis extends BaseVisitor {
-  final Set<Node> containsInterpolatedNode = new Set<Node>();
-  final Set<String> holeNames = new Set<String>();
+  final Setlet<Node> containsInterpolatedNode = new Setlet<Node>();
+  final List<InterpolatedNode> interpolatedNodes = <InterpolatedNode>[];
+  final Setlet<String> holeNames = new Setlet<String>();
   int count = 0;
 
   InterpolatedNodeAnalysis();
@@ -732,6 +734,7 @@
   }
 
   visitInterpolatedNode(InterpolatedNode node) {
+    interpolatedNodes.add(node);
     containsInterpolatedNode.add(node);
     if (node.isNamed) holeNames.add(node.nameOrPosition);
     ++count;
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
index a575e1c..8b1bcec 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
@@ -868,8 +868,8 @@
         cachedEmittedConstants.add(constantValue);
       }
       jsAst.Expression init = buildConstantInitializer(constantValue);
-      constantOutput.addBuffer(
-          jsAst.prettyPrint(init, compiler, monitor: compiler.dumpInfoTask));
+      constantOutput.addBuffer(jsAst.prettyPrint(init, compiler,
+                                         monitor: compiler.dumpInfoTask));
       constantOutput.add('$N');
     }
     if (compiler.hasIncrementalSupport && isMainFragment) {
diff --git a/pkg/compiler/lib/src/use_unused_api.dart b/pkg/compiler/lib/src/use_unused_api.dart
index 77f0bc9..909b000 100644
--- a/pkg/compiler/lib/src/use_unused_api.dart
+++ b/pkg/compiler/lib/src/use_unused_api.dart
@@ -51,10 +51,10 @@
   useSetlet(null);
   useImmutableEmptySet(null);
   useElementVisitor(new ElementVisitor());
-  useJsNode(new js.Program(null));
-  useJsNode(new js.NamedFunction(null, null));
-  useJsNode(new js.ArrayHole());
-  useJsOther(new js.SimpleJavaScriptPrintingContext());
+  useJs(new js.Program(null));
+  useJs(new js.Blob(null));
+  useJs(new js.NamedFunction(null, null));
+  useJs(new js.ArrayHole());
   useJsBackend(null);
   useConcreteTypesInferrer(null);
   useColor();
@@ -170,14 +170,10 @@
     ..visitWarnOnUseElement(null);
 }
 
-useJsNode(js.Node node) {
+useJs(js.Node node) {
   node.asVariableUse();
 }
 
-useJsOther(js.SimpleJavaScriptPrintingContext context) {
-  context.getText();
-}
-
 useJsBackend(js_backend.JavaScriptBackend backend) {
   backend.assembleCode(null);
   backend.annotations.noInlining(null);
diff --git a/tests/compiler/dart2js/async_await_js_transform_test.dart b/tests/compiler/dart2js/async_await_js_transform_test.dart
index 1006186..bbcec9b 100644
--- a/tests/compiler/dart2js/async_await_js_transform_test.dart
+++ b/tests/compiler/dart2js/async_await_js_transform_test.dart
@@ -18,12 +18,9 @@
       endOfIteration: new VariableUse("endOfIteration"),
       newIterable: new VariableUse("Iterator"),
       safeVariableName: (String name) => "__$name").rewrite(fun);
- 
-  JavaScriptPrintingOptions options = new JavaScriptPrintingOptions();
-  JavaScriptPrintingContext context = new SimpleJavaScriptPrintingContext();
-  Printer printer = new Printer(options, context);
+  Printer printer = new Printer(new PrintDiagnosticListener(), null);
   printer.visit(rewritten);
-  Expect.stringEquals(expected, context.getText());
+  Expect.stringEquals(expected, printer.outBuffer.getText());
 }
 
 main() {
@@ -946,4 +943,4 @@
   }
   return thenHelper(null, __helper, __completer, null);
 }""");
-}
+}
\ No newline at end of file