Version 2.14.0-333.0.dev

Merge commit 'ee38656c0bba6982fecda510fb5c41f35517081d' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index eb40ba7..673386c 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2021-07-15T08:50:03.843620",
+  "generated": "2021-07-16T15:43:40.485506",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -148,7 +148,7 @@
       "name": "build_integration",
       "rootUri": "../pkg/build_integration",
       "packageUri": "lib/",
-      "languageVersion": "2.1"
+      "languageVersion": "2.12"
     },
     {
       "name": "charcode",
@@ -806,4 +806,4 @@
       "languageVersion": "2.12"
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index 0688ab2..71472cc 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -5160,7 +5160,10 @@
         // For example a(b)..<T>(c), where token is '<'.
         token = typeArg.parseArguments(token, this);
         next = token.next!;
-        assert(optional('(', next));
+        if (!optional('(', next)) {
+          listener.handleTypeArgumentApplication(token.next!);
+          typeArg = noTypeParamOrArg;
+        }
       }
       TokenType nextType = next.type;
       if (identical(nextType, TokenType.INDEX)) {
@@ -5307,7 +5310,10 @@
             listener.handleNonNullAssertExpression(bangToken);
           }
           token = typeArg.parseArguments(bangToken, this);
-          assert(optional('(', token.next!));
+          if (!optional('(', token.next!)) {
+            listener.handleTypeArgumentApplication(bangToken.next!);
+            typeArg = noTypeParamOrArg;
+          }
         }
         next = token.next!;
       } else if (optional('(', next)) {
@@ -5327,7 +5333,10 @@
             listener.handleNonNullAssertExpression(bangToken);
           }
           token = typeArg.parseArguments(bangToken, this);
-          assert(optional('(', token.next!));
+          if (!optional('(', token.next!)) {
+            listener.handleTypeArgumentApplication(bangToken.next!);
+            typeArg = noTypeParamOrArg;
+          }
         }
         next = token.next!;
       } else {
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 6a6fa5a..d9cf181 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -146,6 +146,7 @@
   CompileTimeErrorCode.DEFAULT_VALUE_ON_REQUIRED_PARAMETER,
   CompileTimeErrorCode.DEFERRED_IMPORT_OF_EXTENSION,
   CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE,
+  CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION,
   CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
   CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
   CompileTimeErrorCode.DUPLICATE_DEFINITION,
@@ -454,6 +455,7 @@
   CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS,
   CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
   CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
+  CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_ANONYMOUS_FUNCTION,
   CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
   CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_EXTENSION,
   CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION,
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
index 84260a2..5dd33ec 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
@@ -45,6 +45,47 @@
     if (function is SimpleIdentifierImpl) {
       var element = _resolver.nameScope.lookup(function.name).getter;
 
+      if (element == null) {
+        DartType receiverType;
+        var enclosingClass = _resolver.enclosingClass;
+        if (enclosingClass != null) {
+          receiverType = enclosingClass.thisType;
+        } else {
+          // TODO(srawlins): Check `_resolver.enclosingExtension`.
+          _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.UNDEFINED_IDENTIFIER,
+            function,
+            [function.name],
+          );
+          node.staticType = DynamicTypeImpl.instance;
+          return;
+        }
+
+        var result = _resolver.typePropertyResolver.resolve(
+          receiver: null,
+          receiverType: receiverType,
+          name: function.name,
+          propertyErrorEntity: function,
+          nameErrorEntity: function,
+        );
+
+        var method = result.getter;
+        if (method != null) {
+          function.staticElement = method;
+          _resolve(node: node, rawType: method.type, name: function.name);
+          return;
+        } else {
+          // TODO(srawlins): Report CompileTimeErrorCode.UNDEFINED_METHOD.
+          return;
+        }
+
+        // TODO(srawlins): If `target.isStatic`, report an error, something like
+        // [MethodInvocationResolver._reportInstanceAccessToStaticMember].
+
+        // TODO(srawlins): if `(target is PropertyAccessorElement)`, report an
+        // error.
+      }
+
       // Classes and type aliases are checked first so as to include a
       // PropertyAccess parent check, which does not need to be done for
       // functions.
@@ -66,23 +107,32 @@
         }
       } else if (element is ExecutableElement) {
         function.staticElement = element;
-        _resolve(node: node, name: element.name, rawType: element.type);
+        function.staticType = element.type;
+        _resolve(node: node, rawType: element.type, name: element.name);
         return;
       } else if (element is VariableElement) {
-        var functionType = element.type;
-        if (functionType is FunctionType) {
-          function.accept(_resolver);
-          _resolve(node: node, name: element.name ?? '', rawType: functionType);
-          return;
-        }
+        function.staticElement = element;
+        function.staticType = element.type;
+        _resolveDisallowedExpression(node, element.type);
+        return;
       }
-    }
 
-    // TODO(srawlins): Handle `function` being a [SuperExpression].
-
-    if (function is PrefixedIdentifierImpl) {
+      node.staticType = DynamicTypeImpl.instance;
+      return;
+    } else if (function is PrefixedIdentifierImpl) {
       var prefixElement =
           _resolver.nameScope.lookup(function.prefix.name).getter;
+
+      if (prefixElement == null) {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.UNDEFINED_IDENTIFIER,
+          function.prefix,
+          [function.name],
+        );
+        node.staticType = DynamicTypeImpl.instance;
+        return;
+      }
+
       function.prefix.staticElement = prefixElement;
       if (prefixElement is PrefixElement) {
         var functionName = function.identifier.name;
@@ -102,10 +152,21 @@
               node, prefixElement, function, functionElement);
           return;
         }
-      } else if (prefixElement is VariableElement) {
-        function.prefix.staticType = prefixElement.type;
+      }
+
+      DartType? prefixType;
+      if (prefixElement is VariableElement) {
+        prefixType = prefixElement.type;
       } else if (prefixElement is PropertyAccessorElement) {
-        function.prefix.staticType = prefixElement.returnType;
+        prefixType = prefixElement.returnType;
+      }
+
+      function.prefix.staticType = prefixType;
+      if (prefixType != null && prefixType.isDynamic) {
+        // TODO(srawlins): Report error. See spec text: "We do not allow dynamic
+        // explicit instantiation."
+        node.staticType = DynamicTypeImpl.instance;
+        return;
       }
 
       var methodElement = _resolveTypeProperty(
@@ -120,8 +181,8 @@
         function.staticType = methodElement.type;
         _resolve(
           node: node,
-          name: function.identifier.name,
           rawType: methodElement.type,
+          name: function.identifier.name,
         );
         return;
       }
@@ -133,11 +194,17 @@
       function.accept(_resolver);
       node.staticType = DynamicTypeImpl.instance;
       return;
-    }
-
-    if (function is PropertyAccessImpl) {
+    } else if (function is PropertyAccessImpl) {
       function.accept(_resolver);
       var target = function.target;
+      if (target == null) {
+        // TODO(srawlins): Can we get here? Perhaps as part of a cascade, but
+        // there is currently a parsing error with cascades.
+        // https://github.com/dart-lang/sdk/issues/46635
+        node.staticType = DynamicTypeImpl.instance;
+        return;
+      }
+
       DartType targetType;
       if (target is SuperExpressionImpl) {
         targetType = target.typeOrThrow;
@@ -182,9 +249,7 @@
           return;
         }
       } else {
-        // TODO(srawlins): Can we get here?
-        node.staticType = DynamicTypeImpl.instance;
-        return;
+        targetType = target.typeOrThrow;
       }
 
       var propertyElement = _resolver.typePropertyResolver
@@ -197,38 +262,51 @@
           )
           .getter;
 
-      var functionType = function.typeOrThrow;
-      if (functionType is FunctionType && propertyElement != null) {
-        _resolve(
-          node: node,
-          name: propertyElement.name,
-          rawType: functionType,
-        );
+      if (propertyElement is TypeParameterElement) {
+        _resolveDisallowedExpression(node, propertyElement!.type);
         return;
       }
 
-      // TODO(srawlins): Handle type variables bound to function type, like
-      // `T extends void Function<U>(U)`.
-    }
+      _resolve(
+        node: node,
+        rawType: function.staticType,
+        name: propertyElement?.name,
+      );
+      return;
+    } else {
+      // TODO(srawlins): Handle `function` being a [SuperExpression].
 
-    // TODO(srawlins): Enumerate and handle all cases that fall through to
-    // here; ultimately it should just be a case of "unknown identifier."
-    function.accept(_resolver);
-    node.staticType = DynamicTypeImpl.instance;
+      function.accept(_resolver);
+      _resolveDisallowedExpression(node, node.function.staticType);
+      return;
+    }
   }
 
   List<DartType> _checkTypeArguments(
     TypeArgumentList typeArgumentList,
-    String name,
+    String? name,
     List<TypeParameterElement> typeParameters,
     CompileTimeErrorCode errorCode,
   ) {
     if (typeArgumentList.arguments.length != typeParameters.length) {
-      _errorReporter.reportErrorForNode(
-        errorCode,
-        typeArgumentList,
-        [name, typeParameters.length, typeArgumentList.arguments.length],
-      );
+      if (name == null &&
+          errorCode ==
+              CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION) {
+        errorCode = CompileTimeErrorCode
+            .WRONG_NUMBER_OF_TYPE_ARGUMENTS_ANONYMOUS_FUNCTION;
+        _errorReporter.reportErrorForNode(
+          errorCode,
+          typeArgumentList,
+          [typeParameters.length, typeArgumentList.arguments.length],
+        );
+      } else {
+        assert(name != null);
+        _errorReporter.reportErrorForNode(
+          errorCode,
+          typeArgumentList,
+          [name, typeParameters.length, typeArgumentList.arguments.length],
+        );
+      }
       return List.filled(typeParameters.length, DynamicTypeImpl.instance);
     } else {
       return typeArgumentList.arguments
@@ -241,18 +319,33 @@
   /// argument types, using [rawType] as the uninstantiated function type.
   void _resolve({
     required FunctionReferenceImpl node,
-    required String name,
-    required FunctionType rawType,
+    required DartType? rawType,
+    String? name,
   }) {
-    var typeArguments = _checkTypeArguments(
-      // `node.typeArguments`, coming from the parser, is never null.
-      node.typeArguments!, name, rawType.typeFormals,
-      CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION,
-    );
+    if (rawType == null) {
+      node.staticType = DynamicTypeImpl.instance;
+    }
 
-    var invokeType = rawType.instantiate(typeArguments);
-    node.typeArgumentTypes = typeArguments;
-    node.staticType = invokeType;
+    if (rawType is TypeParameterTypeImpl) {
+      // If the type of the function is a type parameter, the tearoff is
+      // disallowed, reported in [_resolveDisallowedExpression]. Use the type
+      // parameter's bound here in an attempt to assign the intended types.
+      rawType = rawType.element.bound;
+    }
+
+    if (rawType is FunctionType) {
+      var typeArguments = _checkTypeArguments(
+        // `node.typeArguments`, coming from the parser, is never null.
+        node.typeArguments!, name, rawType.typeFormals,
+        CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION,
+      );
+
+      var invokeType = rawType.instantiate(typeArguments);
+      node.typeArgumentTypes = typeArguments;
+      node.staticType = invokeType;
+    } else {
+      node.staticType = DynamicTypeImpl.instance;
+    }
   }
 
   void _resolveConstructorReference(FunctionReferenceImpl node) {
@@ -277,6 +370,20 @@
     _resolveTypeLiteral(node: node, instantiatedType: type, name: name);
   }
 
+  /// Resolves [node] as a type instantiation on an illegal expression.
+  ///
+  /// This function attempts to give [node] a static type, to continue working
+  /// with what the user may be intending.
+  void _resolveDisallowedExpression(
+      FunctionReferenceImpl node, DartType? rawType) {
+    _errorReporter.reportErrorForNode(
+      CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION,
+      node.function,
+      [],
+    );
+    _resolve(node: node, rawType: rawType);
+  }
+
   void _resolveReceiverPrefix(
     FunctionReferenceImpl node,
     PrefixElement prefixElement,
@@ -315,8 +422,8 @@
       node.function.accept(_resolver);
       _resolve(
         node: node,
-        name: element.name,
         rawType: node.function.typeOrThrow as FunctionType,
+        name: element.name,
       );
       return;
     }
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index a5fdaf2..fb2881f 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -10505,6 +10505,18 @@
   /**
    * No parameters.
    */
+  static const CompileTimeErrorCode DISALLOWED_TYPE_INSTANTIATION_EXPRESSION =
+      CompileTimeErrorCode(
+          'DISALLOWED_TYPE_INSTANTIATION_EXPRESSION',
+          'Only a generic type, generic function, generic instance method, or '
+              'generic constructor can be type instantiated.',
+          correction:
+              'Try instantiating the type(s) of a generic type, generic '
+              'function, generic instance method, or generic constructor.');
+
+  /**
+   * No parameters.
+   */
   // #### Description
   //
   // The analyzer produces this diagnostic when the static type of the
@@ -14632,6 +14644,22 @@
 
   /**
    * Parameters:
+   * 0: the number of type parameters that were declared
+   * 1: the number of type arguments provided
+   */
+  static const CompileTimeErrorCode
+      WRONG_NUMBER_OF_TYPE_ARGUMENTS_ANONYMOUS_FUNCTION = CompileTimeErrorCode(
+          'WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION',
+          "This function is declared with {0} type parameters, "
+              "but {1} type arguments were given.",
+          correction:
+              "Try adjusting the number of type arguments to match the number "
+              "of type parameters.",
+          hasPublishedDocs: true,
+          uniqueName: 'WRONG_NUMBER_OF_TYPE_ARGUMENTS_ANONYMOUS_FUNCTION');
+
+  /**
+   * Parameters:
    * 0: the name of the class being instantiated
    * 1: the name of the constructor being invoked
    */
diff --git a/pkg/analyzer/test/generated/function_reference_parser_test.dart b/pkg/analyzer/test/generated/function_reference_parser_test.dart
index 13d0d82..c7cc214 100644
--- a/pkg/analyzer/test/generated/function_reference_parser_test.dart
+++ b/pkg/analyzer/test/generated/function_reference_parser_test.dart
@@ -300,6 +300,59 @@
             as MethodInvocation);
   }
 
+  void test_functionReference_after_indexExpression() {
+    // Note: this is not legal Dart, but it's important that we do error
+    // recovery and don't crash the parser.
+    var functionReference =
+        parseExpression('x[0]<a, b>', featureSet: constructorTearoffs)
+            as FunctionReference;
+    expect(functionReference.function, TypeMatcher<IndexExpression>());
+    var typeArgs = functionReference.typeArguments!.arguments;
+    expect(typeArgs, hasLength(2));
+    expect(((typeArgs[0] as TypeName).name as SimpleIdentifier).name, 'a');
+    expect(((typeArgs[1] as TypeName).name as SimpleIdentifier).name, 'b');
+  }
+
+  void test_functionReference_after_indexExpression_bang() {
+    // Note: this is not legal Dart, but it's important that we do error
+    // recovery and don't crash the parser.
+    var functionReference =
+        parseExpression('x[0]!<a, b>', featureSet: constructorTearoffs)
+            as FunctionReference;
+    expect(functionReference.function, TypeMatcher<PostfixExpression>());
+    var typeArgs = functionReference.typeArguments!.arguments;
+    expect(typeArgs, hasLength(2));
+    expect(((typeArgs[0] as TypeName).name as SimpleIdentifier).name, 'a');
+    expect(((typeArgs[1] as TypeName).name as SimpleIdentifier).name, 'b');
+  }
+
+  void test_functionReference_after_indexExpression_functionCall() {
+    // Note: this is not legal Dart, but it's important that we do error
+    // recovery and don't crash the parser.
+    var functionReference =
+        parseExpression('x[0]()<a, b>', featureSet: constructorTearoffs)
+            as FunctionReference;
+    expect(functionReference.function,
+        TypeMatcher<FunctionExpressionInvocation>());
+    var typeArgs = functionReference.typeArguments!.arguments;
+    expect(typeArgs, hasLength(2));
+    expect(((typeArgs[0] as TypeName).name as SimpleIdentifier).name, 'a');
+    expect(((typeArgs[1] as TypeName).name as SimpleIdentifier).name, 'b');
+  }
+
+  void test_functionReference_after_indexExpression_nullAware() {
+    // Note: this is not legal Dart, but it's important that we do error
+    // recovery and don't crash the parser.
+    var functionReference =
+        parseExpression('x?[0]<a, b>', featureSet: constructorTearoffs)
+            as FunctionReference;
+    expect(functionReference.function, TypeMatcher<IndexExpression>());
+    var typeArgs = functionReference.typeArguments!.arguments;
+    expect(typeArgs, hasLength(2));
+    expect(((typeArgs[0] as TypeName).name as SimpleIdentifier).name, 'a');
+    expect(((typeArgs[1] as TypeName).name as SimpleIdentifier).name, 'b');
+  }
+
   void test_methodTearoff() {
     var functionReference =
         parseExpression('f().m<a, b>', featureSet: constructorTearoffs)
@@ -314,6 +367,21 @@
     expect(((typeArgs[1] as TypeName).name as SimpleIdentifier).name, 'b');
   }
 
+  void test_methodTearoff_cascaded() {
+    var cascadeExpression =
+        parseExpression('f()..m<a, b>', featureSet: constructorTearoffs)
+            as CascadeExpression;
+    var functionReference =
+        cascadeExpression.cascadeSections[0] as FunctionReference;
+    var function = functionReference.function as PropertyAccess;
+    expect(function.target, isNull);
+    expect(function.propertyName.name, 'm');
+    var typeArgs = functionReference.typeArguments!.arguments;
+    expect(typeArgs, hasLength(2));
+    expect(((typeArgs[0] as TypeName).name as SimpleIdentifier).name, 'a');
+    expect(((typeArgs[1] as TypeName).name as SimpleIdentifier).name, 'b');
+  }
+
   void test_prefixedIdentifier() {
     var functionReference =
         parseExpression('prefix.f<a, b>', featureSet: constructorTearoffs)
diff --git a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
index 9922d73..b53a4a1 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
@@ -28,6 +28,19 @@
     assertType(reference, 'dynamic');
   }
 
+  test_explicitReceiver_unknown_multipleProperties() async {
+    await assertErrorsInCode('''
+bar() {
+  a.b.foo<int>;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 10, 1),
+    ]);
+
+    var reference = findNode.functionReference('foo<int>;');
+    assertType(reference, 'dynamic');
+  }
+
   test_instanceGetter_explicitReceiver() async {
     // This test is here to assert that the resolver does not throw, but in the
     // future, an error should be reported here as well.
@@ -81,6 +94,21 @@
         reference, findElement.method('foo'), 'void Function(int)');
   }
 
+  test_instanceMethod_explicitReceiver_otherExpression() async {
+    await assertNoErrorsInCode('''
+class A {
+  void foo<T>(T a) {}
+}
+
+void f(A? a, A b) {
+  (a ?? b).foo<int>;
+}
+''');
+
+    var reference = findNode.functionReference('(a ?? b).foo<int>;');
+    assertType(reference, 'void Function(int)');
+  }
+
   test_instanceMethod_explicitReceiver_super() async {
     await assertNoErrorsInCode('''
 class A {
@@ -213,6 +241,41 @@
         reference, findElement.method('foo'), 'void Function(int)');
   }
 
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/46635')
+  test_instanceMethod_explicitReceiver_variable_cascade() async {
+    await assertNoErrorsInCode('''
+class A {
+  void foo<T>(T a) {}
+}
+
+bar(A a) {
+  a..foo<int>;
+}
+''');
+
+    var reference = findNode.functionReference('foo<int>;');
+    assertFunctionReference(
+        reference, findElement.method('foo'), 'void Function(int)');
+  }
+
+  test_instanceMethod_inherited() async {
+    await assertNoErrorsInCode('''
+class A {
+  void foo<T>(T a) {}
+}
+
+class B extends A {
+  bar() {
+    foo<int>;
+  }
+}
+''');
+
+    var reference = findNode.functionReference('foo<int>;');
+    assertFunctionReference(
+        reference, findElement.method('foo'), 'void Function(int)');
+  }
+
   test_localFunction() async {
     await assertNoErrorsInCode('''
 void bar() {
@@ -228,11 +291,29 @@
   }
 
   test_localVariable() async {
-    await assertNoErrorsInCode('''
+    await assertErrorsInCode('''
 void bar(void Function<T>(T a) foo) {
   foo<int>;
 }
-''');
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 40, 3),
+    ]);
+
+    var reference = findNode.functionReference('foo<int>;');
+    assertFunctionReference(
+        reference, findElement.parameter('foo'), 'void Function(int)');
+  }
+
+  test_localVariable_typeVariable() async {
+    await assertErrorsInCode('''
+void bar<T extends void Function<U>(U)>(T foo) {
+  foo<int>;
+}
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 51, 3),
+    ]);
 
     var reference = findNode.functionReference('foo<int>;');
     assertFunctionReference(
@@ -258,6 +339,40 @@
         reference, findElement.method('foo'), 'void Function()');
   }
 
+  test_otherExpression() async {
+    await assertErrorsInCode('''
+void f(void Function<T>(T a) foo, void Function<T>(T a) bar) {
+  (1 == 2 ? foo : bar)<int>;
+}
+''', [
+      error(CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 65,
+          20),
+    ]);
+
+    var reference = findNode.functionReference('(1 == 2 ? foo : bar)<int>;');
+    assertType(reference, 'void Function(int)');
+  }
+
+  test_otherExpression_wrongNumberOfTypeArguments() async {
+    await assertErrorsInCode('''
+void f(void Function<T>(T a) foo, void Function<T>(T a) bar) {
+  (1 == 2 ? foo : bar)<int, String>;
+}
+''', [
+      error(CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 65,
+          20),
+      error(
+          CompileTimeErrorCode
+              .WRONG_NUMBER_OF_TYPE_ARGUMENTS_ANONYMOUS_FUNCTION,
+          85,
+          13),
+    ]);
+
+    var reference =
+        findNode.functionReference('(1 == 2 ? foo : bar)<int, String>;');
+    assertType(reference, 'void Function(dynamic)');
+  }
+
   test_staticMethod() async {
     await assertNoErrorsInCode('''
 class A {
diff --git a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
index 1f43b21..9627043 100644
--- a/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart
@@ -453,17 +453,19 @@
 
   test_functionReference() async {
     await assertErrorsInCode('''
-void bar(void Function<T extends num>(T a) foo) {
+void foo<T extends num>(T a) {}
+void bar() {
   foo<String>;
 }
 ''', [
-      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 6),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 51, 6),
     ]);
   }
 
   test_functionReference_matching() async {
     await assertNoErrorsInCode('''
-void bar(void Function<T extends num>(T a) foo) {
+void foo<T extends num>(T a) {}
+void bar() {
   foo<int>;
 }
 ''');
@@ -471,7 +473,8 @@
 
   test_functionReference_regularBounded() async {
     await assertNoErrorsInCode('''
-void bar(void Function<T>(T a) foo) {
+void foo<T>(T a) {}
+void bar() {
   foo<String>;
 }
 ''');
diff --git a/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart b/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart
index ae55d6f..d743c6e 100644
--- a/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart
@@ -95,23 +95,52 @@
 
   test_functionReference_tooFew() async {
     await assertErrorsInCode('''
-f(void Function<T, U>() foo) {
+f() {
+  void foo<T, U>() {}
   foo<int>;
 }
 ''', [
       error(
-          CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION, 36, 5),
+          CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION, 33, 5),
     ]);
   }
 
   test_functionReference_tooMany() async {
     await assertErrorsInCode('''
-f(void Function<T>() foo) {
+f() {
+  void foo<T>() {}
   foo<int, int>;
 }
 ''', [
       error(
-          CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION, 33, 10),
+          CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_FUNCTION, 30, 10),
+    ]);
+  }
+
+  test_functionTypeExpression_tooFew() async {
+    await assertErrorsInCode('''
+f(void Function<T, U>() foo, void Function<T, U>() bar) {
+  (1 == 2 ? foo : bar)<int>;
+}
+''', [
+      error(CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 60,
+          20),
+      error(
+          CompileTimeErrorCode
+              .WRONG_NUMBER_OF_TYPE_ARGUMENTS_ANONYMOUS_FUNCTION,
+          80,
+          5),
+    ]);
+  }
+
+  test_functionTypeExpression_tooMany() async {
+    await assertErrorsInCode('''
+f(void Function<T>() foo, void Function<T, U>() bar) {
+  (1 == 2 ? foo : bar)<int, String>;
+}
+''', [
+      error(CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 57,
+          20),
     ]);
   }
 
diff --git a/pkg/build_integration/lib/file_system/multi_root.dart b/pkg/build_integration/lib/file_system/multi_root.dart
index bfaead5..14772cc 100644
--- a/pkg/build_integration/lib/file_system/multi_root.dart
+++ b/pkg/build_integration/lib/file_system/multi_root.dart
@@ -47,7 +47,7 @@
 class MultiRootFileSystemEntity implements FileSystemEntity {
   final MultiRootFileSystem multiRootFileSystem;
   final Uri uri;
-  FileSystemEntity _delegate;
+  FileSystemEntity? _delegate;
   Future<FileSystemEntity> get delegate async =>
       _delegate ??= await _resolveEntity();
 
diff --git a/pkg/build_integration/pubspec.yaml b/pkg/build_integration/pubspec.yaml
index a7b79b1..899a5ed 100644
--- a/pkg/build_integration/pubspec.yaml
+++ b/pkg/build_integration/pubspec.yaml
@@ -6,7 +6,7 @@
 publish_to: none
 
 environment:
-  sdk: '>=2.1.0 <3.0.0'
+  sdk: '>=2.12.0 <3.0.0'
 
 dependencies:
   front_end:
diff --git a/pkg/build_integration/test/file_system/multi_root_test.dart b/pkg/build_integration/test/file_system/multi_root_test.dart
index e92249a..09d3cc9 100644
--- a/pkg/build_integration/test/file_system/multi_root_test.dart
+++ b/pkg/build_integration/test/file_system/multi_root_test.dart
@@ -15,9 +15,8 @@
 var root = Uri.parse('org-dartlang-test:///');
 
 main() {
-  var memoryFs;
-  var rootUris;
-  var multiRoot;
+  late MemoryFileSystem memoryFs;
+  late MultiRootFileSystem multiRoot;
 
   write(String multiRoot, String path) {
     var realPath = multiRoot == '' ? path : '$multiRoot/$path';
@@ -32,11 +31,15 @@
       multiRoot.entityForUri(Uri.parse(uri)).exists();
 
   Future<String> effectiveUriOf(String uri) async =>
-      (await multiRoot.entityForUri(Uri.parse(uri)).delegate).uri.toString();
+      (await (multiRoot.entityForUri(Uri.parse(uri))
+                  as MultiRootFileSystemEntity)
+              .delegate)
+          .uri
+          .toString();
 
   setUp(() {
     memoryFs = new MemoryFileSystem(root);
-    rootUris = ['r1', 'r2/', 'A/B/', ''].map((r) => root.resolve(r)).toList();
+    final rootUris = ['r1', 'r2/', 'A/B/', ''].map((r) => root.resolve(r)).toList();
     multiRoot = new MultiRootFileSystem('multi-root', rootUris, memoryFs);
   });
 
diff --git a/pkg/build_integration/test/file_system/single_root_test.dart b/pkg/build_integration/test/file_system/single_root_test.dart
index 38ed4f8..50fb984 100644
--- a/pkg/build_integration/test/file_system/single_root_test.dart
+++ b/pkg/build_integration/test/file_system/single_root_test.dart
@@ -13,7 +13,7 @@
       'single-root', root.resolve('A/B'), new MemoryFileSystem(root));
 
   SingleRootFileSystemEntity entityOf(String uri) =>
-      fileSystem.entityForUri(Uri.parse(uri));
+      fileSystem.entityForUri(Uri.parse(uri)) as SingleRootFileSystemEntity;
 
   String effectiveUriOf(String uri) => '${entityOf(uri).delegate.uri}';
 
diff --git a/tools/VERSION b/tools/VERSION
index b2f8f07..435c26f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 332
+PRERELEASE 333
 PRERELEASE_PATCH 0
\ No newline at end of file