Rework plugin API to work better with strong mode

R=scheglov@google.com

Review URL: https://codereview.chromium.org//1959373002 .
diff --git a/lib/plugin.dart b/lib/plugin.dart
index 66cebb0..2dcd96e 100644
--- a/lib/plugin.dart
+++ b/lib/plugin.dart
@@ -4,6 +4,8 @@
 
 library plugin;
 
+import 'package:plugin/src/plugin_impl.dart';
+
 /**
  * A function used to register the given [extension] to the extension point with
  * the given unique [identifier].
@@ -15,16 +17,13 @@
 typedef void RegisterExtension(String identifier, Object extension);
 
 /**
- * A function used to register an extension point with the given simple
- * [identifier]. If given, the [validator] will be used to validate extensions
- * to the extension point.
+ * A function used to register the given [extensionPoint].
  *
  * An [ExtensionError] will be thrown if the extension point cannot be
  * registered, such as when a plugin attempts to define two extension points
- * with the same simple identifier.
+ * with the same identifier.
  */
-typedef ExtensionPoint RegisterExtensionPoint(String identifier,
-    [ValidateExtension validateExtension]);
+typedef void RegisterExtensionPoint(ExtensionPoint extensionPoint);
 
 /**
  * A function used by a plugin to validate an [extension] to a extension point.
@@ -58,12 +57,20 @@
  *
  * Clients may not extend, implement or mix-in this class.
  */
-abstract class ExtensionPoint {
+abstract class ExtensionPoint<E> {
+  /**
+   * Initialize a newly created extension point to be defined by the given
+   * [plugin] with the given [simpleIdentifier]. The [validateExtension]
+   * function will be used to validate extensions for this extension point.
+   */
+  factory ExtensionPoint(Plugin plugin, String simpleIdentifier,
+      ValidateExtension validateExtension) = ExtensionPointImpl<E>;
+
   /**
    * Return an immutable list containing all of the extensions that were
    * registered for this extension point.
    */
-  List<Object> get extensions;
+  List<E> get extensions;
 
   /**
    * Return the plugin that defined this extension point.
diff --git a/lib/src/plugin_impl.dart b/lib/src/plugin_impl.dart
index a65a0d3..a3358bf 100644
--- a/lib/src/plugin_impl.dart
+++ b/lib/src/plugin_impl.dart
@@ -23,9 +23,7 @@
   @override
   void processPlugins(List<Plugin> plugins) {
     for (Plugin plugin in plugins) {
-      plugin.registerExtensionPoints((String identifier,
-              [ValidateExtension validateExtension]) =>
-          registerExtensionPoint(plugin, identifier, validateExtension));
+      plugin.registerExtensionPoints(registerExtensionPoint);
     }
     for (Plugin plugin in plugins) {
       plugin.registerExtensions(registerExtension);
@@ -46,27 +44,22 @@
   }
 
   /**
-   * Register an extension point being defined by the given [plugin] with the
-   * given simple [identifier] and [validateExtension].
+   * Register the given [extensionPoint].
    */
-  ExtensionPoint registerExtensionPoint(
-      Plugin plugin, String identifier, ValidateExtension validateExtension) {
-    String uniqueIdentifier = Plugin.buildUniqueIdentifier(plugin, identifier);
+  void registerExtensionPoint(ExtensionPoint extensionPoint) {
+    String uniqueIdentifier = extensionPoint.uniqueIdentifier;
     if (extensionPoints.containsKey(uniqueIdentifier)) {
       throw new ExtensionError(
-          'There is already an extension point with the id "$identifier"');
+          'There is already an extension point with the id "$uniqueIdentifier"');
     }
-    ExtensionPointImpl extensionPoint =
-        new ExtensionPointImpl(plugin, identifier, validateExtension);
-    extensionPoints[uniqueIdentifier] = extensionPoint;
-    return extensionPoint;
+    extensionPoints[uniqueIdentifier] = extensionPoint as ExtensionPointImpl;
   }
 }
 
 /**
  * A concrete representation of an extension point.
  */
-class ExtensionPointImpl implements ExtensionPoint {
+class ExtensionPointImpl<E> implements ExtensionPoint<E> {
   @override
   final Plugin plugin;
 
@@ -81,7 +74,7 @@
   /**
    * The list of extensions to this extension point.
    */
-  final List<Object> _extensions = <Object>[];
+  final List<E> _extensions = <E>[];
 
   /**
    * Initialize a newly create extension point to belong to the given [plugin]
@@ -96,7 +89,7 @@
    * Return a list containing all of the extensions that have been registered
    * for this extension point.
    */
-  List<Object> get extensions => new UnmodifiableListView(_extensions);
+  List<E> get extensions => new UnmodifiableListView<E>(_extensions);
 
   /**
    * Return the identifier used to uniquely identify this extension point. The
@@ -114,6 +107,6 @@
     if (validateExtension != null) {
       validateExtension(extension);
     }
-    _extensions.add(extension);
+    _extensions.add(extension as E);
   }
 }
diff --git a/pubspec.yaml b/pubspec.yaml
index 886bd86..92f0932 100755
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: plugin
-version: 0.1.0
+version: 0.2.0
 author: Dart Team <misc@dartlang.org>
 description: Support for building plugins.
 homepage: https://github.com/dart-lang/plugin
diff --git a/test/plugin_impl_test.dart b/test/plugin_impl_test.dart
index 5d2902f..c8603af 100644
--- a/test/plugin_impl_test.dart
+++ b/test/plugin_impl_test.dart
@@ -26,8 +26,8 @@
     test('registerExtension - valid', () {
       Plugin plugin = new TestPlugin('plugin');
       ExtensionManagerImpl manager = new ExtensionManagerImpl();
-      ExtensionPoint point =
-          manager.registerExtensionPoint(plugin, 'point', null);
+      ExtensionPoint point = new ExtensionPoint(plugin, 'point', null);
+      manager.registerExtensionPoint(point);
       expect(point, isNotNull);
       Object extension = 'extension';
       manager.registerExtension('plugin.point', extension);
@@ -48,22 +48,24 @@
       Plugin plugin1 = new TestPlugin('plugin1');
       Plugin plugin2 = new TestPlugin('plugin2');
       ExtensionManagerImpl manager = new ExtensionManagerImpl();
-      expect(
-          manager.registerExtensionPoint(plugin1, 'point1', null), isNotNull);
-      expect(
-          manager.registerExtensionPoint(plugin1, 'point2', null), isNotNull);
-      expect(
-          manager.registerExtensionPoint(plugin2, 'point1', null), isNotNull);
-      expect(
-          manager.registerExtensionPoint(plugin2, 'point2', null), isNotNull);
+      manager
+          .registerExtensionPoint(new ExtensionPoint(plugin1, 'point1', null));
+      manager
+          .registerExtensionPoint(new ExtensionPoint(plugin1, 'point2', null));
+      manager
+          .registerExtensionPoint(new ExtensionPoint(plugin2, 'point1', null));
+      manager
+          .registerExtensionPoint(new ExtensionPoint(plugin2, 'point2', null));
     });
 
     test('registerExtensionPoint - conflicting - same plugin', () {
       Plugin plugin1 = new TestPlugin('plugin1');
       ExtensionManagerImpl manager = new ExtensionManagerImpl();
+      manager
+          .registerExtensionPoint(new ExtensionPoint(plugin1, 'point1', null));
       expect(
-          manager.registerExtensionPoint(plugin1, 'point1', null), isNotNull);
-      expect(() => manager.registerExtensionPoint(plugin1, 'point1', null),
+          () => manager.registerExtensionPoint(
+              new ExtensionPoint(plugin1, 'point1', null)),
           throwsA(new isInstanceOf<ExtensionError>()));
     });
 
@@ -71,9 +73,11 @@
       Plugin plugin1 = new TestPlugin('plugin1');
       Plugin plugin2 = new TestPlugin('plugin1');
       ExtensionManagerImpl manager = new ExtensionManagerImpl();
+      manager
+          .registerExtensionPoint(new ExtensionPoint(plugin1, 'point1', null));
       expect(
-          manager.registerExtensionPoint(plugin1, 'point1', null), isNotNull);
-      expect(() => manager.registerExtensionPoint(plugin2, 'point1', null),
+          () => manager.registerExtensionPoint(
+              new ExtensionPoint(plugin2, 'point1', null)),
           throwsA(new isInstanceOf<ExtensionError>()));
     });
   });
@@ -117,8 +121,8 @@
 
     test('add - with validator - valid', () {
       Plugin plugin = new TestPlugin('plugin');
-      ExtensionPointImpl point = new ExtensionPointImpl(plugin, 'point',
-          (Object extension) {
+      ExtensionPointImpl point =
+          new ExtensionPointImpl(plugin, 'point', (Object extension) {
         if (extension is! String) {
           throw new ExtensionError('');
         }
@@ -128,8 +132,8 @@
 
     test('add - with validator - invalid', () {
       Plugin plugin = new TestPlugin('plugin');
-      ExtensionPointImpl point = new ExtensionPointImpl(plugin, 'point',
-          (Object extension) {
+      ExtensionPointImpl point =
+          new ExtensionPointImpl(plugin, 'point', (Object extension) {
         if (extension is! String) {
           throw new ExtensionError('');
         }