Fix a deadlock.

Closes #64
See dart-lang/pub#1306, dart-lang/test#303

R=rnystrom@google.com

Review URL: https://codereview.chromium.org//1262483002 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2206513..a5040e3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.15.2+6
+
+* Fix a deadlock that occurred occasionally when a declaring transformer was
+  followed by a lazy transformer (most commonly `$dart2js`).
+
 ## 0.15.2+5
 
 * If a transformer requests a non-existent asset from another package, it will
diff --git a/lib/src/graph/transform_node.dart b/lib/src/graph/transform_node.dart
index f715814..61bab3f 100644
--- a/lib/src/graph/transform_node.dart
+++ b/lib/src/graph/transform_node.dart
@@ -334,6 +334,13 @@
       // transformation.
       _restartRun();
     } else if (input.state.isAvailable) {
+      if (_state == _State.DECLARED) {
+        // If we're passing through this input and its contents don't matter,
+        // update the pass-through controller.
+        var controller = _passThroughControllers[input.id];
+        if (controller != null) controller.setAvailable(input.asset);
+      }
+
       if (_state == _State.DECLARED && _canRunDeclaringEagerly) {
         // If [this] is fully declared but hasn't started applying, this input
         // becoming available may mean that all inputs are available, in which
@@ -358,6 +365,10 @@
       }
     } else {
       if (_forced) input.force();
+
+      var controller = _passThroughControllers[input.id];
+      if (controller != null) controller.setDirty();
+
       if (_state == _State.APPLYING && !_applyController.addedId(input.id) &&
           (_forced || !input.isLazy)) {
         // If the input hasn't yet been added to the transform's input stream,
diff --git a/pubspec.yaml b/pubspec.yaml
index 81ef584..41e7cdf 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -7,7 +7,7 @@
 #
 # When the minor or patch version of this is upgraded, you *must* update that
 # version constraint in pub to stay in sync with this.
-version: 0.15.2+5
+version: 0.15.2+6
 
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://github.com/dart-lang/barback
diff --git a/test/package_graph/declaring_transformer_test.dart b/test/package_graph/declaring_transformer_test.dart
index 88f2a83..aa830df 100644
--- a/test/package_graph/declaring_transformer_test.dart
+++ b/test/package_graph/declaring_transformer_test.dart
@@ -165,6 +165,35 @@
     buildShouldSucceed();
   });
 
+  // Regression test for #64.
+  test("a declaring transformer's output passes through a lazy transformer",
+      () {
+    var declaring = new DeclaringRewriteTransformer("one", "two");
+    initGraph(["app|foo.one"], {"app": [
+      [declaring],
+      [new LazyRewriteTransformer("two", "three")]
+    ]});
+
+    updateSources(["app|foo.one"]);
+    // Give the transformers time to declare their assets.
+    schedule(pumpEventQueue);
+
+    expectAsset("app|foo.one", "foo");
+    expectAsset("app|foo.two", "foo.two");
+    expectAsset("app|foo.three", "foo.two.three");
+    buildShouldSucceed();
+
+    modifyAsset("app|foo.one", "bar");
+    updateSources(["app|foo.one"]);
+
+    expectAsset("app|foo.one", "bar");
+    expectAsset("app|foo.two", "bar.two");
+    expectAsset("app|foo.three", "bar.two.three");
+    buildShouldSucceed();
+
+    expect(declaring.numRuns, completion(equals(2)));
+  });
+
   test("a declaring transformer following a lazy transformer runs eagerly once "
       "its input is available", () {
     var declaring = new DeclaringRewriteTransformer("two", "three");