Fix performance bug in constructors without initializer lists.

The formatter pushed a rule before the initializer list but did not
pop it if there were no initializers. In that case, the rule stuck
around and got entangled with later rules that should be unrelated. This
caused a super-linear performance cost as a the file got larger.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5da05c8..c7b58f1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 1.3.11
+
+* Fix performance issue with constructors that have no initializer list.
+
 # 1.3.10
 
 * Allow analyzer version 0.41.x.
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
diff --git a/pubspec.yaml b/pubspec.yaml
index 09aa3d6..126b35b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
 name: dart_style
 # Note: See tool/grind.dart for how to bump the version.
-version: 1.3.10
+version: 1.3.11-dev
 description: >-
   Opinionated, automatic Dart source code formatter.
   Provides an API and a CLI tool.