Clean up FunctionTypeImpl constructors.

Previously, FunctionTypeImpl.elementWithNameAndArgs was used for two
purposes: (1) when creating a FunctionTypeImpl for an executable
element, to initialize _typeArguments to the types of the type
parameters that are in scope, and (2) when creating a FunctionTypeImpl
for a typedef, to supply the type arguments necessary to instantiate
the typedef.  (1) turns out to be unnecessary, since the
FunctionTypeImpl.typeArguments getter automatically gathers type
arguments from enclosing elements if necessary, and (2) makes more
sense to do as part of the .forTypedef constructor.  So this CL
removes FunctionTypeImpl.elementWithNameAndArgs and updates its
callers to use the unnamed constructor or the .forTypedef constructor,
as appropriate.

Also, a check is added to make sure that the unnamed constructor is
never accidentally used for typedefs.  So now FunctionTypeImpl has
just three public constructors, each with a clear use case, enforced
either by an assertion or by the type system:

- The unnamed constructor (for executable elements, not typedefs)

- The .forTypedef constructor (for typedefs only)

- The .fresh constructor (for creating one FunctionTypeImpl from
  another by binding fresh type parameters)

Finally, the public constructors for FunctionTypeImpl are all changed
to factories so that client code can't inadvertently FunctionTypeImpl.
(It shouldn't anyway, since FunctionTypeImpl is defined inside src/,
but this gives an extra level of safety).

Change-Id: I5f7abc1ca114eb612cbf539c1d61fc0cace5a4dd
Reviewed-on: https://dart-review.googlesource.com/58043
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 822d245..883fb08 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -4411,8 +4411,7 @@
   @override
   FunctionType get type {
     if (_kernel != null || serializedExecutable != null) {
-      _type ??= new FunctionTypeImpl.elementWithNameAndArgs(
-          this, null, allEnclosingTypeParameterTypes, false);
+      _type ??= new FunctionTypeImpl(this);
     }
     return _type;
   }
@@ -5155,8 +5154,7 @@
 
   @override
   FunctionType get type {
-    return _type ??=
-        new FunctionTypeImpl.elementWithNameAndArgs(this, null, null, false);
+    return _type ??= new FunctionTypeImpl(this);
   }
 
   @override
@@ -5299,8 +5297,7 @@
 
   @override
   FunctionType get type {
-    _type ??= new FunctionTypeImpl.elementWithNameAndArgs(
-        this, null, allEnclosingTypeParameterTypes, false);
+    _type ??= new FunctionTypeImpl(this);
     return _type;
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 500212a..e0a73ba 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -377,25 +377,24 @@
    * [element], and also initialize [typeArguments] to match the
    * [typeParameters], which permits later substitution.
    */
-  FunctionTypeImpl(FunctionTypedElement element,
-      [List<FunctionTypeAliasElement> prunedTypedefs])
-      : this._(element, null, prunedTypedefs, null, null, null, false);
-
-  /**
-   * Initialize a newly created function type to be declared by the given
-   * [element], with the given [name] and [typeArguments].
-   */
-  FunctionTypeImpl.elementWithNameAndArgs(Element element, String name,
-      List<DartType> typeArguments, bool isInstantiated)
-      : this._(element, name, null, typeArguments, null, null, isInstantiated);
+  factory FunctionTypeImpl(FunctionTypedElement element) {
+    if (element is FunctionTypeAliasElement) {
+      throw new StateError('Use FunctionTypeImpl.forTypedef for typedefs');
+    }
+    return new FunctionTypeImpl._(element, null, null, null, null, null, false);
+  }
 
   /**
    * Initialize a newly created function type to be declared by the given
    * [element].
+   *
+   * If [typeArguments] are provided, they are used to instantiate the typedef.
    */
-  FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element,
-      [List<FunctionTypeAliasElement> prunedTypedefs])
-      : this._(element, element?.name, prunedTypedefs, null, null, null, false);
+  factory FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element,
+      {List<DartType> typeArguments}) {
+    return new FunctionTypeImpl._(element, element?.name, null, typeArguments,
+        null, null, typeArguments != null);
+  }
 
   /**
    * Initialize a newly created function type that is semantically the same as
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index fa604ed..3c6353c 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -2913,8 +2913,8 @@
         return context.typeSystem
             .instantiateToBounds(new FunctionTypeImpl.forTypedef(this));
       } else {
-        return new FunctionTypeImpl.elementWithNameAndArgs(
-            this, name, typeArguments, true);
+        return new FunctionTypeImpl.forTypedef(this,
+            typeArguments: typeArguments);
       }
     } else {
       return _type ??= new FunctionTypeImpl.forTypedef(this);
@@ -2989,8 +2989,7 @@
 
   @override
   FunctionType get type {
-    return _type ??= new FunctionTypeImpl.elementWithNameAndArgs(
-        this, null, allEnclosingTypeParameterTypes, false);
+    return _type ??= new FunctionTypeImpl(this);
   }
 
   @override
@@ -3087,8 +3086,8 @@
         return context.typeSystem
             .instantiateToBounds(new FunctionTypeImpl.forTypedef(this));
       } else {
-        return new FunctionTypeImpl.elementWithNameAndArgs(
-            this, name, typeArguments, true);
+        return new FunctionTypeImpl.forTypedef(this,
+            typeArguments: typeArguments);
       }
     } else {
       return new FunctionTypeImpl.forTypedef(this);
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 2271c0c..170a534 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -1075,8 +1075,8 @@
         } else {
           typeArguments = _dynamicTypeArguments;
         }
-        return new FunctionTypeImpl.elementWithNameAndArgs(
-            element, name, typeArguments, numTypeParameters != 0);
+        return new FunctionTypeImpl.forTypedef(element,
+            typeArguments: typeArguments);
       } else {
         FunctionTypedElementComputer computer;
         if (implicitFunctionTypeIndices.isNotEmpty) {
diff --git a/pkg/analyzer/test/src/dart/element/function_type_test.dart b/pkg/analyzer/test/src/dart/element/function_type_test.dart
index 047473b..8c1e001 100644
--- a/pkg/analyzer/test/src/dart/element/function_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/function_type_test.dart
@@ -80,19 +80,17 @@
   DartType mapOf(DartType keyType, DartType valueType) =>
       mapType.instantiate([keyType, valueType]);
 
-  test_elementWithNameAndArgs_nonTypedef_noTypeArguments() {
+  test_unnamedConstructor_nonTypedef_noTypeArguments() {
     var e = new MockFunctionTypedElement();
-    FunctionType f =
-        new FunctionTypeImpl.elementWithNameAndArgs(e, null, [], false);
+    FunctionType f = new FunctionTypeImpl(e);
     basicChecks(f, element: same(e));
   }
 
-  test_elementWithNameAndArgs_nonTypedef_withTypeArguments() {
+  test_unnamedConstructor_nonTypedef_withTypeArguments() {
     var t = new MockTypeParameterElement('T');
     var c = new MockClassElement('C', typeParameters: [t]);
     var e = new MockMethodElement(c, returnType: t.type);
-    FunctionType f =
-        new FunctionTypeImpl.elementWithNameAndArgs(e, null, [t.type], false);
+    FunctionType f = new FunctionTypeImpl(e);
     basicChecks(f,
         element: same(e),
         typeArguments: [same(t.type)],
@@ -101,7 +99,7 @@
         returnType: same(t.type));
   }
 
-  test_elementWithNameAndArgs_typedef_bothTypeParameters() {
+  test_forInstantiatedTypedef_bothTypeParameters() {
     var t = new MockTypeParameterElement('T');
     var u = new MockTypeParameterElement('U');
     var e = new MockGenericTypeAliasElement('F',
@@ -109,7 +107,7 @@
         innerTypeParameters: [u],
         returnType: mapOf(t.type, u.type));
     FunctionType f =
-        new FunctionTypeImpl.elementWithNameAndArgs(e, 'F', [objectType], true);
+        new FunctionTypeImpl.forTypedef(e, typeArguments: [objectType]);
     basicChecks(f,
         element: same(e),
         displayName: 'F<Object>',
@@ -119,12 +117,11 @@
         returnType: mapOf(objectType, u.type));
   }
 
-  test_elementWithNameAndArgs_typedef_innerTypeParameter() {
+  test_forInstantiatedTypedef_innerTypeParameter() {
     var t = new MockTypeParameterElement('T');
     var e = new MockGenericTypeAliasElement('F',
         innerTypeParameters: [t], returnType: t.type);
-    FunctionType f =
-        new FunctionTypeImpl.elementWithNameAndArgs(e, 'F', [], true);
+    FunctionType f = new FunctionTypeImpl.forTypedef(e, typeArguments: []);
     basicChecks(f,
         element: same(e),
         displayName: 'F',
@@ -132,19 +129,18 @@
         returnType: same(t.type));
   }
 
-  test_elementWithNameAndArgs_typedef_noTypeParameters() {
+  test_forInstantiatedTypedef_noTypeParameters() {
     var e = new MockGenericTypeAliasElement('F');
-    FunctionType f =
-        new FunctionTypeImpl.elementWithNameAndArgs(e, 'F', [], true);
+    FunctionType f = new FunctionTypeImpl.forTypedef(e, typeArguments: []);
     basicChecks(f, element: same(e), displayName: 'F', name: 'F');
   }
 
-  test_elementWithNameAndArgs_typedef_outerTypeParameters() {
+  test_forInstantiatedTypedef_outerTypeParameters() {
     var t = new MockTypeParameterElement('T');
     var e = new MockGenericTypeAliasElement('F',
         typeParameters: [t], returnType: t.type);
     FunctionType f =
-        new FunctionTypeImpl.elementWithNameAndArgs(e, 'F', [objectType], true);
+        new FunctionTypeImpl.forTypedef(e, typeArguments: [objectType]);
     basicChecks(f,
         element: same(e),
         displayName: 'F<Object>',
@@ -860,8 +856,7 @@
   get returnType => enclosingElement.returnType;
 
   @override
-  get type => _type ??= new FunctionTypeImpl.elementWithNameAndArgs(this, null,
-      enclosingElement.typeParameters.map((e) => e.type).toList(), false);
+  get type => _type ??= new FunctionTypeImpl(this);
 
   @override
   get typeParameters => enclosingElement.innerTypeParameters;