Linter `0.1.21`

* New `only_throw_errors` lint.
* New lint to check for `empty_statements` (#259).
* Fixed NSME when file contents cannot be read (#260).
* Fixed unsafe cast in `iterable_contains_unrelated_type` (#267).

R=alexeidiaz@google.com, brianwilkerson@google.com

Review URL: https://codereview.chromium.org//2100013005 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fab69ea..96087ee 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+# 0.1.21
+
+* New `only_throw_errors` lint.
+* New lint to check for `empty_statements` (#259).
+* Fixed NSME when file contents cannot be read (#260).
+* Fixed unsafe cast in `iterable_contains_unrelated_type` (#267).
+
 # 0.1.20
 
 * New `cancel_subscriptions` lint.
diff --git a/lib/src/rules.dart b/lib/src/rules.dart
index c526f56..18ed76b 100644
--- a/lib/src/rules.dart
+++ b/lib/src/rules.dart
@@ -31,7 +31,7 @@
 import 'package:linter/src/rules/library_prefixes.dart';
 import 'package:linter/src/rules/non_constant_identifier_names.dart';
 import 'package:linter/src/rules/one_member_abstracts.dart';
-import 'package:linter/src/rules/only_throw_error.dart';
+import 'package:linter/src/rules/only_throw_errors.dart';
 import 'package:linter/src/rules/overridden_fields.dart';
 import 'package:linter/src/rules/package_api_docs.dart';
 import 'package:linter/src/rules/package_prefixed_library_names.dart';
@@ -69,7 +69,7 @@
   ..register(new EmptyConstructorBodies())
   ..register(new EmptyStatements())
   ..register(new TestTypesInEquals())
-  ..register(new OnlyThrowError())
+  ..register(new OnlyThrowErrors())
   ..register(new OverriddenFields())
   ..register(new HashAndEquals())
   ..register(new ImplementationImports())
diff --git a/lib/src/rules/only_throw_error.dart b/lib/src/rules/only_throw_errors.dart
similarity index 76%
rename from lib/src/rules/only_throw_error.dart
rename to lib/src/rules/only_throw_errors.dart
index 6b8c532..1010599 100644
--- a/lib/src/rules/only_throw_error.dart
+++ b/lib/src/rules/only_throw_errors.dart
@@ -6,18 +6,20 @@
 library linter.src.rules.only_throw_error;
 
 import 'dart:collection';
+
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:linter/src/linter.dart';
 import 'package:linter/src/util/dart_type_utilities.dart';
 
-const _desc = r'Only throw instaces of classes extending either Exception or Error';
+const _desc =
+    r'Only throw instances of classes extending either Exception or Error';
 
 const _details = r'''
 
-**DO** throw only instances of classes that extend dart.core.Error or
-dart.core.Exception.
+**DO** throw only instances of classes that extend `dart.core.Error` or
+`dart.core.Exception`.
 
 **BAD:**
 ```
@@ -35,15 +37,30 @@
 ```
 ''';
 
-class OnlyThrowError extends LintRule {
+const _errorClassName = 'Error';
+
+const _exceptionClassName = 'Exception';
+
+const _library = 'dart.core';
+final LinkedHashSet<InterfaceTypeDefinition> _interfaceDefinitions =
+    new LinkedHashSet<InterfaceTypeDefinition>.from([
+  new InterfaceTypeDefinition(_exceptionClassName, _library),
+  new InterfaceTypeDefinition(_errorClassName, _library)
+]);
+bool _isThrowable(DartType type) {
+  return type.isDynamic ||
+      DartTypeUtilities.implementsAnyInterface(type, _interfaceDefinitions);
+}
+class OnlyThrowErrors extends LintRule {
   _Visitor _visitor;
 
-  OnlyThrowError() : super(
-      name: 'only_throw_error',
-      description: _desc,
-      details: _details,
-      group: Group.style,
-      maturity: Maturity.experimental) {
+  OnlyThrowErrors()
+      : super(
+            name: 'only_throw_errors',
+            description: _desc,
+            details: _details,
+            group: Group.style,
+            maturity: Maturity.experimental) {
     _visitor = new _Visitor(this);
   }
 
@@ -68,17 +85,3 @@
     }
   }
 }
-
-const _library = 'dart.core';
-const _errorClassName = 'Error';
-const _exceptionClassName = 'Exception';
-final LinkedHashSet<InterfaceTypeDefinition> _interfaceDefinitions =
-new LinkedHashSet<InterfaceTypeDefinition>.from([
-  new InterfaceTypeDefinition(_exceptionClassName, _library),
-  new InterfaceTypeDefinition(_errorClassName, _library)
-]);
-
-bool _isThrowable(DartType type) {
-  return type.isDynamic ||
-      DartTypeUtilities.implementsAnyInterface(type, _interfaceDefinitions);
-}
diff --git a/pubspec.yaml b/pubspec.yaml
index 3f5e756..971e66e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: linter
-version: 0.1.20
+version: 0.1.21
 author: Dart Team <misc@dartlang.org>
 description: Style linter for Dart.
 homepage: https://github.com/dart-lang/linter
diff --git a/test/_data/only_throw_error/only_throw_error.dart b/test/_data/only_throw_errors/only_throw_errors.dart
similarity index 100%
rename from test/_data/only_throw_error/only_throw_error.dart
rename to test/_data/only_throw_errors/only_throw_errors.dart
diff --git a/test/integration_test.dart b/test/integration_test.dart
index e041c92..24cb8e5 100644
--- a/test/integration_test.dart
+++ b/test/integration_test.dart
@@ -192,19 +192,15 @@
       });
 
       test('close sinks', () {
-        dartlint.main([
-          'test/_data/close_sinks',
-          '--rules=close_sinks'
-        ]);
+        dartlint.main(['test/_data/close_sinks', '--rules=close_sinks']);
         expect(exitCode, 1);
         expect(
             collectingOut.trim(),
-            stringContainsInOrder(
-                [
-                  'IOSink _sinkA; // LINT',
-                  'IOSink _sinkF; // LINT',
-                  '1 file analyzed, 2 issues found, in'
-                ]));
+            stringContainsInOrder([
+              'IOSink _sinkA; // LINT',
+              'IOSink _sinkF; // LINT',
+              '1 file analyzed, 2 issues found, in'
+            ]));
       });
     });
 
@@ -229,16 +225,15 @@
         expect(exitCode, 1);
         expect(
             collectingOut.trim(),
-            stringContainsInOrder(
-                [
-                  'StreamSubscription _subscriptionA; // LINT',
-                  'StreamSubscription _subscriptionF; // LINT',
-                  '1 file analyzed, 2 issues found, in'
-                ]));
+            stringContainsInOrder([
+              'StreamSubscription _subscriptionA; // LINT',
+              'StreamSubscription _subscriptionF; // LINT',
+              '1 file analyzed, 2 issues found, in'
+            ]));
       });
     });
 
-    group('only_throw_error', () {
+    group('only_throw_errors', () {
       IOSink currentOut = outSink;
       CollectingSink collectingOut = new CollectingSink();
       setUp(() {
@@ -251,23 +246,20 @@
         exitCode = 0;
       });
 
-      test('only throw error', () {
-        dartlint.main([
-          'test/_data/only_throw_error',
-          '--rules=only_throw_error'
-        ]);
+      test('only throw errors', () {
+        dartlint.main(
+            ['test/_data/only_throw_errors', '--rules=only_throw_errors']);
         expect(exitCode, 1);
         expect(
             collectingOut.trim(),
-            stringContainsInOrder(
-                [
-                  "throw 'hello world!'; // LINT",
-                  'throw null; // LINT',
-                  'throw 7; // LINT',
-                  'throw new Object(); // LINT',
-                  'throw returnString(); // LINT',
-                  '1 file analyzed, 5 issues found, in'
-                ]));
+            stringContainsInOrder([
+              "throw 'hello world!'; // LINT",
+              'throw null; // LINT',
+              'throw 7; // LINT',
+              'throw new Object(); // LINT',
+              'throw returnString(); // LINT',
+              '1 file analyzed, 5 issues found, in'
+            ]));
       });
     });