Merge pull request #983 from dart-lang/factory-perf

Fix performance bug in constructors without initializer lists.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 863ab1b..33c06fb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
 # 1.3.11
 
 * Remove use of deprecated analyzer API and List constructor.
+* Fix performance issue with constructors that have no initializer list.
 
 # 1.3.10
 
diff --git a/lib/src/chunk_builder.dart b/lib/src/chunk_builder.dart
index bab9151..ec1c589 100644
--- a/lib/src/chunk_builder.dart
+++ b/lib/src/chunk_builder.dart
@@ -488,10 +488,10 @@
 
   void _activateRule(Rule rule) {
     // See if any of the rules that contain this one care if it splits.
-    _rules.forEach((outer) {
-      if (!outer.splitsOnInnerRules) return;
+    for (var outer in _rules) {
+      if (!outer.splitsOnInnerRules) continue;
       rule.imply(outer);
-    });
+    }
     _rules.add(rule);
   }
 
@@ -658,6 +658,8 @@
   /// Finishes writing and returns a [SourceCode] containing the final output
   /// and updated selection, if any.
   SourceCode end() {
+    assert(_rules.isEmpty);
+
     _writeHardSplit();
     _divideChunks();
 
diff --git a/lib/src/source_visitor.dart b/lib/src/source_visitor.dart
index 6a54395..64be1a5 100644
--- a/lib/src/source_visitor.dart
+++ b/lib/src/source_visitor.dart
@@ -894,7 +894,7 @@
     // Make the rule for the ":" span both the preceding parameter list and
     // the entire initialization list. This ensures that we split before the
     // ":" if the parameters and initialization list don't all fit on one line.
-    builder.startRule();
+    if (node.initializers.isNotEmpty) builder.startRule();
 
     // If the redirecting constructor happens to wrap, we want to make sure
     // the parameter list gets more deeply indented.
@@ -907,6 +907,9 @@
         builder.unnest();
       } else if (node.initializers.isNotEmpty) {
         _visitConstructorInitializers(node);
+
+        // End the rule for ":" after all of the initializers.
+        builder.endRule();
       }
     });
   }
@@ -987,9 +990,6 @@
 
     builder.unindent();
     if (!hasTrailingComma) builder.unindent();
-
-    // End the rule for ":" after all of the initializers.
-    builder.endRule();
   }
 
   @override