Version 2.15.0-106.0.dev

Merge commit 'e08ee7abecd889a55bee49afe635ea620b28b93e' into 'dev'
diff --git a/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart b/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart
index 8180f0b..c5c8763 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart
@@ -75,7 +75,7 @@
 
   Future<void> test_isInConstContext() async {
     await testUpdate(content: '''
-const a = 0;
+const num a = 0;
 const c = a is int;
 ''', to: '^2.2.2');
   }
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 9c671fc..f037f8b 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -440,13 +440,16 @@
   CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER,
   CompileTimeErrorCode.UNDEFINED_FUNCTION,
   CompileTimeErrorCode.UNDEFINED_GETTER,
+  CompileTimeErrorCode.UNDEFINED_GETTER_ON_FUNCTION_TYPE,
   CompileTimeErrorCode.UNDEFINED_IDENTIFIER,
   CompileTimeErrorCode.UNDEFINED_IDENTIFIER_AWAIT,
   CompileTimeErrorCode.UNDEFINED_METHOD,
+  CompileTimeErrorCode.UNDEFINED_METHOD_ON_FUNCTION_TYPE,
   CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER,
   CompileTimeErrorCode.UNDEFINED_OPERATOR,
   CompileTimeErrorCode.UNDEFINED_PREFIXED_NAME,
   CompileTimeErrorCode.UNDEFINED_SETTER,
+  CompileTimeErrorCode.UNDEFINED_SETTER_ON_FUNCTION_TYPE,
   CompileTimeErrorCode.UNDEFINED_SUPER_GETTER,
   CompileTimeErrorCode.UNDEFINED_SUPER_METHOD,
   CompileTimeErrorCode.UNDEFINED_SUPER_OPERATOR,
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index f0583b2..bc6446c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -80,7 +80,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 177;
+  static const int DATA_VERSION = 178;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 0032336..66bc7a5 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -1007,8 +1007,10 @@
     _uriToFile.clear();
     knownFilePaths.clear();
     knownFiles.clear();
+    _hasUriForPath.clear();
     _pathToFiles.clear();
     _pathToCanonicalFile.clear();
+    _librariesWithoutPartsRead.clear();
     _partToLibraries.clear();
     _subtypedNameToFiles.clear();
   }
diff --git a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
index 1731023..12c0ab3 100644
--- a/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart
@@ -264,11 +264,12 @@
   @override
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
     _visitNode(node.parameter);
-    if (node.separator != null) {
-      if (node.separator!.lexeme != ':') {
+    var separator = node.separator;
+    if (separator != null) {
+      if (separator.lexeme != ':') {
         sink.write(' ');
       }
-      sink.write(node.separator!.lexeme);
+      sink.write(separator.lexeme);
       _visitNode(node.defaultValue, prefix: ' ');
     }
   }
@@ -728,14 +729,8 @@
 
   @override
   void visitMethodInvocation(MethodInvocation node) {
-    if (node.isCascaded) {
-      sink.write(node.operator!.lexeme);
-    } else {
-      if (node.target != null) {
-        node.target!.accept(this);
-        sink.write(node.operator!.lexeme);
-      }
-    }
+    _visitNode(node.target);
+    _visitToken(node.operator);
     _visitNode(node.methodName);
     _visitNode(node.typeArguments);
     _visitNode(node.argumentList);
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index 513220e..1dc3670 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/scope.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
@@ -26,7 +27,9 @@
 class AstRewriter {
   final ErrorReporter _errorReporter;
 
-  AstRewriter(this._errorReporter);
+  final TypeProvider _typeProvider;
+
+  AstRewriter(this._errorReporter, this._typeProvider);
 
   /// Possibly rewrites [node] as a [MethodInvocation] with a
   /// [FunctionReference] target.
@@ -45,9 +48,15 @@
     var typeName = node.constructorName.type.name;
     if (typeName is SimpleIdentifier) {
       var element = nameScope.lookup(typeName.name).getter;
-      if (element is FunctionElement || element is MethodElement) {
+      if (element is FunctionElement ||
+          element is MethodElement ||
+          element is PropertyAccessorElement) {
         return _toMethodInvocationOfFunctionReference(
             node: node, function: typeName);
+      } else if (element is TypeAliasElement &&
+          element.aliasedElement is GenericFunctionTypeElement) {
+        return _toMethodInvocationOfAliasedTypeLiteral(
+            node: node, function: typeName, element: element);
       }
     } else if (typeName is PrefixedIdentifier) {
       var prefixElement = nameScope.lookup(typeName.prefix.name).getter;
@@ -57,6 +66,10 @@
         if (element is FunctionElement) {
           return _toMethodInvocationOfFunctionReference(
               node: node, function: typeName);
+        } else if (element is TypeAliasElement &&
+            element.aliasedElement is GenericFunctionTypeElement) {
+          return _toMethodInvocationOfAliasedTypeLiteral(
+              node: node, function: typeName, element: element);
         }
 
         // If `element` is a [ClassElement], or a [TypeAliasElement] aliasing
@@ -490,6 +503,28 @@
     return instanceCreationExpression;
   }
 
+  MethodInvocation _toMethodInvocationOfAliasedTypeLiteral({
+    required InstanceCreationExpression node,
+    required Identifier function,
+    required TypeAliasElement element,
+  }) {
+    var typeName = astFactory.typeName(node.constructorName.type.name,
+        node.constructorName.type.typeArguments);
+    typeName.type = element.aliasedType;
+    typeName.name.staticType = element.aliasedType;
+    var typeLiteral = astFactory.typeLiteral(typeName: typeName);
+    typeLiteral.staticType = _typeProvider.typeType;
+    var methodInvocation = astFactory.methodInvocation(
+      typeLiteral,
+      node.constructorName.period,
+      node.constructorName.name!,
+      null,
+      node.argumentList,
+    );
+    NodeReplacer.replace(node, methodInvocation);
+    return methodInvocation;
+  }
+
   MethodInvocation _toMethodInvocationOfFunctionReference({
     required InstanceCreationExpression node,
     required Identifier 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 aabb65f..790cd79 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
@@ -564,7 +564,13 @@
       // `prefix.C<int>.name` is initially represented as a [PropertyAccess]
       // with a [FunctionReference] target.
       if (node.parent is PropertyAccess) {
-        _resolveConstructorReference(node);
+        if (element is TypeAliasElement &&
+            element.aliasedType is FunctionType) {
+          function.staticElement = element;
+          _resolveTypeAlias(node: node, element: element, typeAlias: function);
+        } else {
+          _resolveConstructorReference(node);
+        }
         return;
       } else if (element is ClassElement) {
         function.staticElement = element;
@@ -649,6 +655,10 @@
     required DartType instantiatedType,
     required Identifier name,
   }) {
+    // TODO(srawlins): set the static element of [typeName].
+    // This involves a fair amount of resolution, as [name] may be a prefixed
+    // identifier, etc. [TypeName]s should be resolved in [ResolutionVisitor],
+    // and this could be done for nodes like this via [AstRewriter].
     var typeName = astFactory.typeName(name, node.typeArguments);
     typeName.type = instantiatedType;
     typeName.name.staticType = instantiatedType;
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index d5d7b50..190ab31 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -164,6 +164,21 @@
       return;
     }
 
+    if (receiver is TypeLiteralImpl &&
+        receiver.typeName.typeArguments != null &&
+        receiver.typeName.type is FunctionType) {
+      // There is no possible resolution for a property access of a function
+      // type literal (which can only be a type instantiation of a type alias
+      // of a function type).
+      _resolver.errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.UNDEFINED_METHOD_ON_FUNCTION_TYPE,
+        nameNode,
+        [name, receiver.typeName.name.name],
+      );
+      _setDynamicResolution(node, whyNotPromotedList: whyNotPromotedList);
+      return;
+    }
+
     _resolveReceiverType(
       node: node,
       receiver: receiver,
diff --git a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
index 84c1ec2..86f1008 100644
--- a/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/property_element_resolver.dart
@@ -368,6 +368,26 @@
       targetType = _typeSystem.promoteToNonNull(targetType);
     }
 
+    if (target is TypeLiteral && target.typeName.type is FunctionType) {
+      // There is no possible resolution for a property access of a function
+      // type literal (which can only be a type instantiation of a type alias
+      // of a function type).
+      if (hasRead) {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.UNDEFINED_GETTER_ON_FUNCTION_TYPE,
+          propertyName,
+          [propertyName.name, target.typeName.name.name],
+        );
+      } else {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.UNDEFINED_SETTER_ON_FUNCTION_TYPE,
+          propertyName,
+          [propertyName.name, target.typeName.name.name],
+        );
+      }
+      return PropertyElementResolverResult();
+    }
+
     var result = _resolver.typePropertyResolver.resolve(
       receiver: target,
       receiverType: targetType,
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 9efde38..d25fcf6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -116,7 +116,7 @@
       unitElement,
       isNonNullableByDefault,
       errorReporter,
-      AstRewriter(errorReporter),
+      AstRewriter(errorReporter, typeProvider),
       typeNameResolver,
       nameScope,
       elementWalker,
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index f7988fd1..c93f71d 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -13838,6 +13838,19 @@
 
   /**
    * Parameters:
+   * 0: the name of the getter
+   * 1: the name of the function type alias
+   */
+  static const CompileTimeErrorCode UNDEFINED_GETTER_ON_FUNCTION_TYPE =
+      CompileTimeErrorCode('UNDEFINED_GETTER',
+          "The getter '{0}' isn't defined for the '{1}' function type.",
+          correction: "Try wrapping the function type alias in parentheses in "
+              "order to access '{0}' as an extension getter on 'Type'.",
+          hasPublishedDocs: true,
+          uniqueName: 'UNDEFINED_GETTER_ON_FUNCTION_TYPE');
+
+  /**
+   * Parameters:
    * 0: the name of the identifier
    */
   // #### Description
@@ -13947,6 +13960,19 @@
 
   /**
    * Parameters:
+   * 0: the name of the method
+   * 1: the name of the function type alias
+   */
+  static const CompileTimeErrorCode UNDEFINED_METHOD_ON_FUNCTION_TYPE =
+      CompileTimeErrorCode('UNDEFINED_METHOD',
+          "The method '{0}' isn't defined for the '{1}' function type.",
+          correction: "Try wrapping the function type alias in parentheses in "
+              "order to access '{0}' as an extension method on 'Type'.",
+          hasPublishedDocs: true,
+          uniqueName: 'UNDEFINED_METHOD_ON_FUNCTION_TYPE');
+
+  /**
+   * Parameters:
    * 0: the name of the requested named parameter
    */
   // #### Description
@@ -14150,6 +14176,19 @@
 
   /**
    * Parameters:
+   * 0: the name of the setter
+   * 1: the name of the function type alias
+   */
+  static const CompileTimeErrorCode UNDEFINED_SETTER_ON_FUNCTION_TYPE =
+      CompileTimeErrorCode('UNDEFINED_SETTER',
+          "The setter '{0}' isn't defined for the '{1}' function type.",
+          correction: "Try wrapping the function type alias in parentheses in "
+              "order to access '{0}' as an extension getter on 'Type'.",
+          hasPublishedDocs: true,
+          uniqueName: 'UNDEFINED_SETTER_ON_FUNCTION_TYPE');
+
+  /**
+   * Parameters:
    * 0: the name of the getter
    * 1: the name of the enclosing type where the getter is being looked for
    */
@@ -15108,7 +15147,7 @@
           isUnresolvedIdentifier: isUnresolvedIdentifier,
           message: message,
           name: name,
-          uniqueName: uniqueName ?? 'CompileTimeErrorCode.$name',
+          uniqueName: 'CompileTimeErrorCode.${uniqueName ?? name}',
         );
 
   @override
@@ -15539,7 +15578,7 @@
           isUnresolvedIdentifier: isUnresolvedIdentifier,
           message: message,
           name: name,
-          uniqueName: uniqueName ?? 'StaticWarningCode.$name',
+          uniqueName: 'StaticWarningCode.${uniqueName ?? name}',
         );
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index a75433d..61f2728 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -805,14 +805,20 @@
     var typeArguments = _readOptionalNode() as TypeArgumentList?;
     var arguments = readNode() as ArgumentList;
 
+    Token? operator;
+    if (AstBinaryFlags.hasQuestion(flags)) {
+      operator = AstBinaryFlags.hasPeriod(flags)
+          ? Tokens.questionPeriod()
+          : Tokens.questionPeriodPeriod();
+    } else if (AstBinaryFlags.hasPeriod(flags)) {
+      operator = Tokens.period();
+    } else if (AstBinaryFlags.hasPeriod2(flags)) {
+      operator = Tokens.periodPeriod();
+    }
+
     var node = astFactory.methodInvocation(
       target,
-      Tokens.choose(
-        AstBinaryFlags.hasPeriod(flags),
-        Tokens.period(),
-        AstBinaryFlags.hasPeriod2(flags),
-        Tokens.periodPeriod(),
-      ),
+      operator,
       methodName,
       typeArguments,
       arguments,
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 6287bc4..11fcb12 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -485,12 +485,18 @@
   void visitMethodInvocation(MethodInvocation node) {
     _writeByte(Tag.MethodInvocation);
 
+    var operatorType = node.operator?.type;
     _writeByte(
       AstBinaryFlags.encode(
-        hasPeriod: node.operator?.type == TokenType.PERIOD,
-        hasPeriod2: node.operator?.type == TokenType.PERIOD_PERIOD,
+        hasPeriod: operatorType == TokenType.PERIOD ||
+            operatorType == TokenType.QUESTION_PERIOD,
+        hasPeriod2: operatorType == TokenType.PERIOD_PERIOD ||
+            operatorType == TokenType.QUESTION_PERIOD_PERIOD,
+        hasQuestion: operatorType == TokenType.QUESTION_PERIOD ||
+            operatorType == TokenType.QUESTION_PERIOD_PERIOD,
       ),
     );
+
     _writeOptionalNode(node.target);
     _writeNode(node.methodName);
     _storeInvocationExpression(node);
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 aa9f1fe..37dddf5 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
@@ -60,25 +60,52 @@
         findElement.constructor('foo'), 'dynamic');
   }
 
+  test_dynamicTyped() async {
+    await assertErrorsInCode('''
+dynamic i = 1;
+
+void bar() {
+  i<int>;
+}
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 31, 1),
+    ]);
+
+    assertFunctionReference(findNode.functionReference('i<int>;'),
+        findElement.topGet('i'), 'dynamic');
+  }
+
+  test_dynamicTyped_targetOfMethodCall() async {
+    await assertErrorsInCode('''
+dynamic i = 1;
+
+void bar() {
+  i<int>.foo();
+}
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 31, 1),
+    ]);
+
+    assertFunctionReference(findNode.functionReference('i<int>.foo();'),
+        findElement.topGet('i'), 'dynamic');
+  }
+
   test_explicitReceiver_dynamicTyped() async {
     await assertErrorsInCode('''
-dynamic f(dynamic x) => x;
+dynamic f() => 1;
 
-class C {
-  T instanceMethod<T>(T t) => t;
-}
-
-main() {
-  C c = new C();
-  f(c).instanceMethod<int>;
+foo() {
+  f().instanceMethod<int>;
 }
 ''', [
       error(CompileTimeErrorCode.GENERIC_METHOD_TYPE_INSTANTIATION_ON_DYNAMIC,
-          102, 24),
+          29, 23),
     ]);
 
     assertFunctionReference(
-        findNode.functionReference('f(c).instanceMethod<int>;'),
+        findNode.functionReference('f().instanceMethod<int>;'),
         null,
         'dynamic');
   }
@@ -702,6 +729,22 @@
     assertFunctionReference(reference, findElement.parameter('foo'), 'dynamic');
   }
 
+  test_neverTyped() async {
+    await assertErrorsInCode('''
+external Never get i;
+
+void bar() {
+  i<int>;
+}
+''', [
+      error(
+          CompileTimeErrorCode.DISALLOWED_TYPE_INSTANTIATION_EXPRESSION, 38, 1),
+    ]);
+
+    assertFunctionReference(findNode.functionReference('i<int>;'),
+        findElement.topGet('i'), 'dynamic');
+  }
+
   test_nonGenericFunction() async {
     await assertErrorsInCode('''
 class A {
diff --git a/pkg/analyzer/test/src/dart/resolution/type_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_literal_test.dart
index 5391331..8172670 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_literal_test.dart
@@ -70,6 +70,18 @@
     assertTypeLiteral(typeLiteral, findElement.class_('C'), 'C<dynamic>');
   }
 
+  test_class_typeArgumentDoesNotMatchBound() async {
+    await assertErrorsInCode('''
+class C<T extends num> {}
+var t = C<String>;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 36, 6),
+    ]);
+
+    var typeLiteral = findNode.typeLiteral('C<String>;');
+    assertTypeLiteral(typeLiteral, findElement.class_('C'), 'C<String>');
+  }
+
   test_classAlias() async {
     await assertNoErrorsInCode('''
 class C<T> {}
@@ -124,6 +136,19 @@
     );
   }
 
+  test_classAlias_typeArgumentDoesNotMatchBound() async {
+    await assertErrorsInCode('''
+class C<T> {}
+typedef CA<T extends num> = C<T>;
+var t = CA<String>;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 59, 6),
+    ]);
+
+    var typeLiteral = findNode.typeLiteral('CA<String>;');
+    assertTypeLiteral(typeLiteral, findElement.typeAlias('CA'), 'C<String>');
+  }
+
   test_functionAlias() async {
     await assertNoErrorsInCode('''
 typedef Fn<T> = void Function(T);
@@ -135,6 +160,231 @@
         typeLiteral, findElement.typeAlias('Fn'), 'void Function(int)');
   }
 
+  test_functionAlias_importPrefix() async {
+    newFile('$testPackageLibPath/a.dart', content: '''
+typedef Fn<T> = void Function(T);
+''');
+    await assertNoErrorsInCode('''
+import 'a.dart' as a;
+var t = a.Fn<int>;
+''');
+
+    var typeLiteral = findNode.typeLiteral('Fn<int>;');
+    assertTypeLiteral(
+      typeLiteral,
+      findElement.importFind('package:test/a.dart').typeAlias('Fn'),
+      'void Function(int)',
+      expectedPrefix: findElement.prefix('a'),
+    );
+  }
+
+  test_functionAlias_targetOfMethodCall() async {
+    await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  Fn<int>.foo();
+}
+
+extension E on Type {
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_METHOD_ON_FUNCTION_TYPE, 58, 3),
+    ]);
+
+    var typeLiteral = findNode.typeLiteral('Fn<int>');
+    assertTypeLiteral(
+      typeLiteral,
+      findElement.typeAlias('Fn'),
+      'void Function(int)',
+    );
+  }
+
+  test_functionAlias_targetOfMethodCall_importPrefix() async {
+    newFile('$testPackageLibPath/a.dart', content: '''
+typedef Fn<T> = void Function(T);
+''');
+    await assertErrorsInCode('''
+import 'a.dart' as a;
+
+void bar() {
+  a.Fn<int>.foo();
+}
+
+extension E on Type {
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_METHOD_ON_FUNCTION_TYPE, 48, 3),
+    ]);
+
+    var typeLiteral = findNode.typeLiteral('Fn<int>');
+    assertTypeLiteral(
+      typeLiteral,
+      findElement.importFind('package:test/a.dart').typeAlias('Fn'),
+      'void Function(int)',
+      expectedPrefix: findElement.prefix('a'),
+    );
+  }
+
+  test_functionAlias_targetOfMethodCall_parenthesized() async {
+    await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  (Fn<int>).foo();
+}
+
+extension E on Type {
+  void foo() {}
+}
+''');
+
+    var typeLiteral = findNode.typeLiteral('Fn<int>');
+    assertTypeLiteral(
+      typeLiteral,
+      findElement.typeAlias('Fn'),
+      'void Function(int)',
+    );
+  }
+
+  test_functionAlias_targetOfPropertyAccess_getter() async {
+    await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  Fn<int>.foo;
+}
+
+extension E on Type {
+  int get foo => 1;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_GETTER_ON_FUNCTION_TYPE, 58, 3),
+    ]);
+
+    var typeLiteral = findNode.typeLiteral('Fn<int>');
+    assertTypeLiteral(
+      typeLiteral,
+      findElement.typeAlias('Fn'),
+      'void Function(int)',
+    );
+  }
+
+  test_functionAlias_targetOfPropertyAccess_getter_parenthesized() async {
+    await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  (Fn<int>).foo;
+}
+
+extension E on Type {
+  int get foo => 1;
+}
+''');
+
+    var typeLiteral = findNode.typeLiteral('Fn<int>');
+    assertTypeLiteral(
+      typeLiteral,
+      findElement.typeAlias('Fn'),
+      'void Function(int)',
+    );
+  }
+
+  test_functionAlias_targetOfPropertyAccess_setter() async {
+    await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  Fn<int>.foo = 7;
+}
+
+extension E on Type {
+  set foo(int value) {}
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER_ON_FUNCTION_TYPE, 58, 3),
+    ]);
+
+    var typeLiteral = findNode.typeLiteral('Fn<int>');
+    assertTypeLiteral(
+      typeLiteral,
+      findElement.typeAlias('Fn'),
+      'void Function(int)',
+    );
+  }
+
+  test_functionAlias_targetOfPropertyAccess_setter_parenthesized() async {
+    await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  (Fn<int>).foo = 7;
+}
+
+extension E on Type {
+  set foo(int value) {}
+}
+''');
+
+    var typeLiteral = findNode.typeLiteral('Fn<int>');
+    assertTypeLiteral(
+      typeLiteral,
+      findElement.typeAlias('Fn'),
+      'void Function(int)',
+    );
+  }
+
+  test_functionAlias_tooFewTypeArgs() async {
+    await assertErrorsInCode('''
+typedef Fn<T, U> = void Function(T, U);
+var t = Fn<int>;
+''', [
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 50, 5),
+    ]);
+
+    var typeLiteral = findNode.typeLiteral('Fn<int>;');
+    assertTypeLiteral(
+      typeLiteral,
+      findElement.typeAlias('Fn'),
+      'void Function(dynamic, dynamic)',
+    );
+  }
+
+  test_functionAlias_tooManyTypeArgs() async {
+    await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+var t = Fn<int, String>;
+''', [
+      error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 44, 13),
+    ]);
+
+    var typeLiteral = findNode.typeLiteral('Fn<int, String>;');
+    assertTypeLiteral(
+      typeLiteral,
+      findElement.typeAlias('Fn'),
+      'void Function(dynamic)',
+    );
+  }
+
+  test_functionAlias_typeArgumentDoesNotMatchBound() async {
+    await assertErrorsInCode('''
+typedef Fn<T extends num> = void Function(T);
+var t = Fn<String>;
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 57, 6),
+    ]);
+
+    var typeLiteral = findNode.typeLiteral('Fn<String>;');
+    assertTypeLiteral(
+      typeLiteral,
+      findElement.typeAlias('Fn'),
+      'void Function(String)',
+    );
+  }
+
   test_mixin() async {
     await assertNoErrorsInCode('''
 mixin M<T> {}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
index cb85d4f..ae2410c 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
@@ -388,6 +388,36 @@
 @reflectiveTest
 class UndefinedGetterWithNullSafetyTest extends PubPackageResolutionTest
     with UndefinedGetterTestCases {
+  test_functionAlias_typeInstantiated_getter() async {
+    await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  Fn<int>.foo;
+}
+
+extension E on Type {
+  int get foo => 1;
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_GETTER_ON_FUNCTION_TYPE, 58, 3),
+    ]);
+  }
+
+  test_functionAlias_typeInstantiated_getter_parenthesized() async {
+    await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  (Fn<int>).foo;
+}
+
+extension E on Type {
+  int get foo => 1;
+}
+''');
+  }
+
   test_get_from_abstract_field_final_valid() async {
     await assertNoErrorsInCode('''
 abstract class A {
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
index 34c7247..483d1dc 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
@@ -62,6 +62,50 @@
     ]);
   }
 
+  test_functionAlias_notInstantiated() async {
+    await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  Fn.foo();
+}
+
+extension E on Type {
+  void foo() {}
+}
+''');
+  }
+
+  test_functionAlias_typeInstantiated() async {
+    await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  Fn<int>.foo();
+}
+
+extension E on Type {
+  void foo() {}
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_METHOD_ON_FUNCTION_TYPE, 58, 3),
+    ]);
+  }
+
+  test_functionAlias_typeInstantiated_parenthesized() async {
+    await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  (Fn<int>).foo();
+}
+
+extension E on Type {
+  void foo() {}
+}
+''');
+  }
+
   test_functionExpression_callMethod_defined() async {
     await assertNoErrorsInCode(r'''
 main() {
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
index d1674c6..d97a894 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
@@ -143,6 +143,36 @@
 @reflectiveTest
 class UndefinedSetterWithNullSafetyTest extends PubPackageResolutionTest
     with UndefinedSetterTestCases {
+  test_functionAlias_typeInstantiated() async {
+    await assertErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  Fn<int>.foo = 7;
+}
+
+extension E on Type {
+  set foo(int value) {}
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_SETTER_ON_FUNCTION_TYPE, 58, 3),
+    ]);
+  }
+
+  test_functionAlias_typeInstantiated_parenthesized() async {
+    await assertNoErrorsInCode('''
+typedef Fn<T> = void Function(T);
+
+void bar() {
+  (Fn<int>).foo = 7;
+}
+
+extension E on Type {
+  set foo(int value) {}
+}
+''');
+  }
+
   test_new_cascade() async {
     await assertErrorsInCode('''
 class C {}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 41c6205..685f2f4 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -11008,6 +11008,91 @@
 ''');
   }
 
+  test_const_topLevel_methodInvocation_questionPeriod() async {
+    var library = await checkLibrary(r'''
+const int? a = 0;
+const b = a?.toString();
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    topLevelVariables
+      static const a @11
+        type: int?
+        constantInitializer
+          IntegerLiteral
+            literal: 0 @15
+            staticType: int
+      static const b @24
+        type: String?
+        constantInitializer
+          MethodInvocation
+            argumentList: ArgumentList
+              leftParenthesis: ( @39
+              rightParenthesis: ) @40
+            methodName: SimpleIdentifier
+              staticElement: dart:core::@class::int::@method::toString
+              staticType: String Function()
+              token: toString @31
+            operator: ?. @29
+            staticInvokeType: String Function()
+            staticType: String?
+            target: SimpleIdentifier
+              staticElement: self::@getter::a
+              staticType: int?
+              token: a @28
+    accessors
+      synthetic static get a @-1
+        returnType: int?
+      synthetic static get b @-1
+        returnType: String?
+''');
+  }
+
+  test_const_topLevel_methodInvocation_questionPeriodPeriod() async {
+    var library = await checkLibrary(r'''
+const int? a = 0;
+const b = a?..toString();
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    topLevelVariables
+      static const a @11
+        type: int?
+        constantInitializer
+          IntegerLiteral
+            literal: 0 @15
+            staticType: int
+      static const b @24
+        type: int?
+        constantInitializer
+          CascadeExpression
+            cascadeSections
+              MethodInvocation
+                argumentList: ArgumentList
+                  leftParenthesis: ( @40
+                  rightParenthesis: ) @41
+                methodName: SimpleIdentifier
+                  staticElement: dart:core::@class::int::@method::toString
+                  staticType: String Function()
+                  token: toString @32
+                operator: ?.. @29
+                staticInvokeType: String Function()
+                staticType: String
+            staticType: int?
+            target: SimpleIdentifier
+              staticElement: self::@getter::a
+              staticType: int?
+              token: a @28
+    accessors
+      synthetic static get a @-1
+        returnType: int?
+      synthetic static get b @-1
+        returnType: int?
+''');
+  }
+
   test_const_topLevel_nullSafe_nullAware_propertyAccess() async {
     var library = await checkLibrary(r'''
 const String? a = '';
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 60b5987..3b82cae 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -13547,6 +13547,8 @@
 
 ### undefined_getter
 
+_The getter '{0}' isn't defined for the '{1}' function type._
+
 _The getter '{0}' isn't defined for the type '{1}'._
 
 #### Description
@@ -13668,6 +13670,8 @@
 
 ### undefined_method
 
+_The method '{0}' isn't defined for the '{1}' function type._
+
 _The method '{0}' isn't defined for the type '{1}'._
 
 #### Description
@@ -13830,6 +13834,8 @@
 
 ### undefined_setter
 
+_The setter '{0}' isn't defined for the '{1}' function type._
+
 _The setter '{0}' isn't defined for the type '{1}'._
 
 #### Description
diff --git a/pkg/analyzer/tool/messages/generate.dart b/pkg/analyzer/tool/messages/generate.dart
index 4ca88ae..8740d46 100644
--- a/pkg/analyzer/tool/messages/generate.dart
+++ b/pkg/analyzer/tool/messages/generate.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 /// This file contains code to generate scanner and parser message
 /// based on the information in pkg/front_end/messages.yaml.
 ///
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index fdb24b7..496393a 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -1707,7 +1707,7 @@
 
   DartType nullableType(DartType baseType) {
     bool _isNullable(DartType t) =>
-        // Note that we can assume NNBD is enabled here.
+        // Note that we can assume null safety is enabled here.
         t.isNull ||
         t is NullableType ||
         t is LegacyType && _isNullable(t.baseType) ||
diff --git a/pkg/compiler/lib/src/js_backend/specialized_checks.dart b/pkg/compiler/lib/src/js_backend/specialized_checks.dart
index 431ebe7..9a887aa 100644
--- a/pkg/compiler/lib/src/js_backend/specialized_checks.dart
+++ b/pkg/compiler/lib/src/js_backend/specialized_checks.dart
@@ -72,8 +72,8 @@
       }
 
       DartTypes dartTypes = closedWorld.dartTypes;
-      // Top types (here it could be Object in non-NNBD mode) should be constant
-      // folded outside the specializer. This test protects logic below.
+      // Top types should be constant folded outside the specializer. This test
+      // protects logic below.
       if (dartTypes.isTopType(dartType)) return null;
       ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
       if (!dartTypes.isSubtype(
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index 7fd39d4..37531a5 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -61,7 +61,8 @@
       String targetName =
           _options.compileForServer ? "dart2js_server" : "dart2js";
 
-      // We defer selecting the platform until we've resolved the NNBD mode.
+      // We defer selecting the platform until we've resolved the null safety
+      // mode.
       String getPlatformFilename() {
         String platform = targetName;
         if (!_options.useLegacySubtyping) {
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index 194c2b1..e81dda1 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -838,7 +838,7 @@
     _behavior.typesReturned.add(type.withoutNullability);
 
     // Breakdown nullable type into TypeWithoutNullability|Null.
-    // Pre-nnbd Declared types are nullable, so we also add null in that case.
+    // Unsound declared types are nullable, so we also add null in that case.
     // TODO(41960): Remove check for legacy subtyping. This was added as a
     // temporary workaround to unblock the null-safe unfork. At this time some
     // native APIs are typed unsoundly because they don't consider browser
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 9000dab..3c5ee61 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -69,10 +69,10 @@
   FeatureOption newHolders = FeatureOption('new-holders');
 
   /// [FeatureOption]s which default to enabled.
-  late final List<FeatureOption> shipping = [legacyJavaScript];
+  late final List<FeatureOption> shipping = [legacyJavaScript, newHolders];
 
   /// [FeatureOption]s which default to disabled.
-  late final List<FeatureOption> canary = [newHolders];
+  late final List<FeatureOption> canary = [];
 
   /// Forces canary feature on. This must run after [Option].parse.
   void forceCanary() {
@@ -708,7 +708,7 @@
 
     if (benchmarkingExperiment) {
       // Set flags implied by '--benchmarking-x'.
-      // TODO(sra): Use this for some NNBD variant.
+      // TODO(sra): Use this for some null safety variant.
       useContentSecurityPolicy = true;
       features.forceCanary();
     }
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index ef0a3fa..886f1f0 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -3517,10 +3517,10 @@
 /// Check for receiver or argument type when lowering operation to a primitive,
 /// e.g. lowering `+` to [HAdd].
 ///
-/// After NNBD, `a + b` will require `a` and `b` are non-nullable and these
-/// checks will become explicit in the source (e.g. `a! + b!`). At that time,
-/// this check should be removed.  If needed, the `!` check can be optimized
-/// give the same signals to the JavaScript VM.
+/// With sound null safety, `a + b` will require `a` and `b` to be non-nullable
+/// and these checks will become explicit in the source (e.g. `a! + b!`). At
+/// that time, this check should be removed. If needed, the `!` check can be
+/// optimized to give the same signals to the JavaScript VM.
 class HPrimitiveCheck extends HCheck {
   // Values for [kind].
   static const int ARGUMENT_TYPE_CHECK = 1;
@@ -3590,8 +3590,8 @@
 }
 
 /// A check that the input to a condition (if, ?:, while, etc) is non-null. The
-/// front-end generates 'as bool' checks, but until the transition to NNBD is
-/// complete, this allows `null` to be passed to the condition.
+/// front-end generates 'as bool' checks, but until the transition to null
+/// safety is complete, this allows `null` to be passed to the condition.
 ///
 // TODO(sra): Once NNDB is far enough along that the front-end can generate `as
 // bool!` checks and the backend checks them correctly, this instruction will
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index bf83ffc..8877f33 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -1926,8 +1926,8 @@
   @override
   HInstruction visitAsCheck(HAsCheck node) {
     // TODO(fishythefish): Correctly constant fold `null as T` (also in
-    // [visitAsCheckSimple]) when running with strong NNBD. We might get this
-    // for free if nullability is precisely propagated to the typemasks.
+    // [visitAsCheckSimple]) when running with sound null safety. We might get
+    // this for free if nullability is precisely propagated to the typemasks.
 
     HInstruction typeInput = node.typeInput;
     if (typeInput is HLoadType) {
diff --git a/pkg/compiler/test/closure/data/test_type_class.dart b/pkg/compiler/test/closure/data/test_type_class.dart
index 2d090d6..eff36b1 100644
--- a/pkg/compiler/test/closure/data/test_type_class.dart
+++ b/pkg/compiler/test/closure/data/test_type_class.dart
@@ -33,7 +33,7 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// Implicit as-cast is only required in spec:nnbd-off mode.
+/// Implicit as-cast is only required in spec mode.
 ////////////////////////////////////////////////////////////////////////////////
 
 /*member: Class3.:hasThis*/
diff --git a/pkg/compiler/test/closure/data/test_type_method.dart b/pkg/compiler/test/closure/data/test_type_method.dart
index 495ac1b..ee02292 100644
--- a/pkg/compiler/test/closure/data/test_type_method.dart
+++ b/pkg/compiler/test/closure/data/test_type_method.dart
@@ -27,7 +27,7 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// Implicit as-cast is only required in spec:nnbd-off mode.
+/// Implicit as-cast is only required in spec mode.
 ////////////////////////////////////////////////////////////////////////////////
 
 /*member: method3:*/
diff --git a/pkg/compiler/test/closure/data/type_annotations_class.dart b/pkg/compiler/test/closure/data/type_annotations_class.dart
index 6c0d99e..f7557f7 100644
--- a/pkg/compiler/test/closure/data/type_annotations_class.dart
+++ b/pkg/compiler/test/closure/data/type_annotations_class.dart
@@ -43,7 +43,7 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// A local function parameter type is only captured in spec:nnbd-off mode.
+/// A local function parameter type is only captured in spec mode.
 ////////////////////////////////////////////////////////////////////////////////
 
 /*member: Class2.:hasThis*/
@@ -58,7 +58,7 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// A local function return type is only captured in spec:nnbd-off mode.
+/// A local function return type is only captured in spec mode.
 ////////////////////////////////////////////////////////////////////////////////
 
 /*member: Class3.:hasThis*/
diff --git a/pkg/compiler/test/closure/data/type_annotations_method.dart b/pkg/compiler/test/closure/data/type_annotations_method.dart
index 4da1fae..1468024 100644
--- a/pkg/compiler/test/closure/data/type_annotations_method.dart
+++ b/pkg/compiler/test/closure/data/type_annotations_method.dart
@@ -19,7 +19,7 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// A local function parameter type is captured in spec:nnbd-off mode.
+/// A local function parameter type is captured in spec mode.
 ////////////////////////////////////////////////////////////////////////////////
 
 method2<T>() {
@@ -29,7 +29,7 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-/// A local function return type is captured in spec:nnbd-off mode.
+/// A local function return type is captured in spec mode.
 ////////////////////////////////////////////////////////////////////////////////
 
 method3<T>(dynamic o) {
diff --git a/pkg/compiler/test/codegen/data/array_add.dart b/pkg/compiler/test/codegen/data/array_add.dart
index 635192c..81ecb40 100644
--- a/pkg/compiler/test/codegen/data/array_add.dart
+++ b/pkg/compiler/test/codegen/data/array_add.dart
@@ -6,9 +6,9 @@
 //
 // TODO(sra): Lower when type of input does not need a generic covariant check.
 @pragma('dart2js:noInline')
-/*spec.member: test1:function() {
-  var t1 = H._setArrayType([], type$.JSArray_int);
-  C.JSArray_methods.add$1(t1, 1);
+/*spec|canary.member: test1:function() {
+  var t1 = A._setArrayType([], type$.JSArray_int);
+  B.JSArray_methods.add$1(t1, 1);
   return t1;
 }*/
 /*prod.member: test1:function() {
@@ -16,19 +16,11 @@
   t1.push(1);
   return t1;
 }*/
-/*canary.member: test1:function() {
-  var t1 = A._setArrayType([], type$.JSArray_int);
-  B.JSArray_methods.add$1(t1, 1);
-  return t1;
-}*/
 test1() {
   return <int>[]..add(1);
 }
 
-/*spec|prod.member: main:function() {
-  F.test1();
-}*/
-/*canary.member: main:function() {
+/*member: main:function() {
   A.test1();
 }*/
 main() {
diff --git a/pkg/compiler/test/codegen/data/codeUnitAt_folding.dart b/pkg/compiler/test/codegen/data/codeUnitAt_folding.dart
index 4b47674..993e670 100644
--- a/pkg/compiler/test/codegen/data/codeUnitAt_folding.dart
+++ b/pkg/compiler/test/codegen/data/codeUnitAt_folding.dart
@@ -14,14 +14,11 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec.member: foo2:function() {
-  return C.JSString_methods.codeUnitAt$1("Hello", H._asInt(1.5));
+/*spec|canary.member: foo2:function() {
+  return B.JSString_methods.codeUnitAt$1("Hello", A._asInt(1.5));
 }*/
 /*prod.member: foo2:function() {
-  return C.JSString_methods.codeUnitAt$1("Hello", 1.5);
-}*/
-/*canary.member: foo2:function() {
-  return B.JSString_methods.codeUnitAt$1("Hello", A._asInt(1.5));
+  return B.JSString_methods.codeUnitAt$1("Hello", 1.5);
 }*/
 foo2() {
   var a = 'Hello';
@@ -31,10 +28,7 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec|prod.member: foo3:function() {
-  return C.JSString_methods._codeUnitAt$1("Hello", 55);
-}*/
-/*canary.member: foo3:function() {
+/*member: foo3:function() {
   return B.JSString_methods._codeUnitAt$1("Hello", 55);
 }*/
 foo3() {
diff --git a/pkg/compiler/test/codegen/data/shift_right_unsigned.dart b/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
index b473933..521f9d3 100644
--- a/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
+++ b/pkg/compiler/test/codegen/data/shift_right_unsigned.dart
@@ -24,24 +24,18 @@
 Object? sink;
 
 @pragma('dart2js:noInline')
-/*spec.member: cannotRecognize:function(thing) {
-  return H._asInt(J.$shru$n(thing, 1));
+/*spec|canary.member: cannotRecognize:function(thing) {
+  return A._asInt(J.$shru$n(thing, 1));
 }*/
 /*prod.member: cannotRecognize:function(thing) {
   return J.$shru$n(thing, 1);
 }*/
-/*canary.member: cannotRecognize:function(thing) {
-  return A._asInt(J.$shru$n(thing, 1));
-}*/
 int cannotRecognize(dynamic thing) {
   return thing >>> 1;
 }
 
 @pragma('dart2js:noInline')
-/*spec|prod.member: cannotConstantFold:function() {
-  return C.JSInt_methods.$shru(1, -1);
-}*/
-/*canary.member: cannotConstantFold:function() {
+/*member: cannotConstantFold:function() {
   return B.JSInt_methods.$shru(1, -1);
 }*/
 int cannotConstantFold() {
@@ -68,10 +62,7 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec|prod.member: unspecialized:function(a) {
-  return C.JSInt_methods.$shru(1, a);
-}*/
-/*canary.member: unspecialized:function(a) {
+/*member: unspecialized:function(a) {
   return B.JSInt_methods.$shru(1, a);
 }*/
 int unspecialized(int a) {
@@ -79,10 +70,7 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec|prod.member: otherPositive2:function(param) {
-  return C.JSInt_methods._shruOtherPositive$1(1, param ? 1 : 2);
-}*/
-/*canary.member: otherPositive2:function(param) {
+/*member: otherPositive2:function(param) {
   return B.JSInt_methods._shruOtherPositive$1(1, param ? 1 : 2);
 }*/
 int otherPositive2(bool param) {
@@ -110,10 +98,7 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec|prod.member: otherPositive6:function(a, b) {
-  return C.JSInt_methods._shruOtherPositive$1(a, b);
-}*/
-/*canary.member: otherPositive6:function(a, b) {
+/*member: otherPositive6:function(a, b) {
   return B.JSInt_methods._shruOtherPositive$1(a, b);
 }*/
 int otherPositive6(int a, int b) {
diff --git a/pkg/compiler/test/codegen/data/tdiv1.dart b/pkg/compiler/test/codegen/data/tdiv1.dart
index 9c83d58..fe6e9f6 100644
--- a/pkg/compiler/test/codegen/data/tdiv1.dart
+++ b/pkg/compiler/test/codegen/data/tdiv1.dart
@@ -45,10 +45,7 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec|prod.member: foo3:function(param) {
-  return C.JSInt_methods._tdivFast$1(param ? 4294967295 : -1, 2);
-}*/
-/*canary.member: foo3:function(param) {
+/*member: foo3:function(param) {
   return B.JSInt_methods._tdivFast$1(param ? 4294967295 : -1, 2);
 }*/
 int foo3(bool param) {
@@ -59,10 +56,7 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec|prod.member: foo4:function(param1, param2) {
-  return C.JSInt_methods.$tdiv(param1 ? 4294967295 : 0, param2);
-}*/
-/*canary.member: foo4:function(param1, param2) {
+/*member: foo4:function(param1, param2) {
   return B.JSInt_methods.$tdiv(param1 ? 4294967295 : 0, param2);
 }*/
 int foo4(bool param1, int param2) {
@@ -74,11 +68,7 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec|prod.member: foo5:function(param1, param2) {
-  var a = param1 ? 4294967295 : 0;
-  return C.JSInt_methods.$tdiv(a, param2 ? 3 : 4);
-}*/
-/*canary.member: foo5:function(param1, param2) {
+/*member: foo5:function(param1, param2) {
   var a = param1 ? 4294967295 : 0;
   return B.JSInt_methods.$tdiv(a, param2 ? 3 : 4);
 }*/
@@ -93,11 +83,7 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec|prod.member: foo_regress_37502:function(param1, param2) {
-  var a = param1 ? 1.2 : 12.3;
-  return C.JSInt_methods.gcd$1(C.JSNumber_methods.$tdiv(a, param2 ? 3.14 : 2.81), 2);
-}*/
-/*canary.member: foo_regress_37502:function(param1, param2) {
+/*member: foo_regress_37502:function(param1, param2) {
   var a = param1 ? 1.2 : 12.3;
   return B.JSInt_methods.gcd$1(B.JSNumber_methods.$tdiv(a, param2 ? 3.14 : 2.81), 2);
 }*/
diff --git a/pkg/compiler/test/codegen/data_2/tdiv1.dart b/pkg/compiler/test/codegen/data_2/tdiv1.dart
index 3c3e6b7..27d6c65 100644
--- a/pkg/compiler/test/codegen/data_2/tdiv1.dart
+++ b/pkg/compiler/test/codegen/data_2/tdiv1.dart
@@ -23,15 +23,12 @@
 Object sink;
 
 @pragma('dart2js:noInline')
-/*spec.member: foo1:function(param) {
-  return (H.boolConversionCheck(param) ? 4294967295 : 1) / 2 | 0;
+/*spec|canary.member: foo1:function(param) {
+  return (A.boolConversionCheck(param) ? 4294967295 : 1) / 2 | 0;
 }*/
 /*prod.member: foo1:function(param) {
   return (param ? 4294967295 : 1) / 2 | 0;
 }*/
-/*canary.member: foo1:function(param) {
-  return (A.boolConversionCheck(param) ? 4294967295 : 1) / 2 | 0;
-}*/
 int foo1(bool param) {
   var a = param ? 0xFFFFFFFF : 1;
   return a ~/ 2;
@@ -40,15 +37,12 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec.member: foo2:function(param) {
-  return (H.boolConversionCheck(param) ? 4294967295 : 1) / 3 | 0;
+/*spec|canary.member: foo2:function(param) {
+  return (A.boolConversionCheck(param) ? 4294967295 : 1) / 3 | 0;
 }*/
 /*prod.member: foo2:function(param) {
   return (param ? 4294967295 : 1) / 3 | 0;
 }*/
-/*canary.member: foo2:function(param) {
-  return (A.boolConversionCheck(param) ? 4294967295 : 1) / 3 | 0;
-}*/
 int foo2(bool param) {
   var a = param ? 0xFFFFFFFF : 1;
   return a ~/ 3;
@@ -57,14 +51,11 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec.member: foo3:function(param) {
-  return C.JSInt_methods._tdivFast$1(H.boolConversionCheck(param) ? 4294967295 : -1, 2);
+/*spec|canary.member: foo3:function(param) {
+  return B.JSInt_methods._tdivFast$1(A.boolConversionCheck(param) ? 4294967295 : -1, 2);
 }*/
 /*prod.member: foo3:function(param) {
-  return C.JSInt_methods._tdivFast$1(param ? 4294967295 : -1, 2);
-}*/
-/*canary.member: foo3:function(param) {
-  return B.JSInt_methods._tdivFast$1(A.boolConversionCheck(param) ? 4294967295 : -1, 2);
+  return B.JSInt_methods._tdivFast$1(param ? 4294967295 : -1, 2);
 }*/
 int foo3(bool param) {
   var a = param ? 0xFFFFFFFF : -1;
@@ -74,14 +65,11 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec.member: foo4:function(param1, param2) {
-  return C.JSInt_methods.$tdiv(H.boolConversionCheck(param1) ? 4294967295 : 0, param2);
+/*spec|canary.member: foo4:function(param1, param2) {
+  return B.JSInt_methods.$tdiv(A.boolConversionCheck(param1) ? 4294967295 : 0, param2);
 }*/
 /*prod.member: foo4:function(param1, param2) {
-  return C.JSInt_methods.$tdiv(param1 ? 4294967295 : 0, param2);
-}*/
-/*canary.member: foo4:function(param1, param2) {
-  return B.JSInt_methods.$tdiv(A.boolConversionCheck(param1) ? 4294967295 : 0, param2);
+  return B.JSInt_methods.$tdiv(param1 ? 4294967295 : 0, param2);
 }*/
 int foo4(bool param1, int param2) {
   var a = param1 ? 0xFFFFFFFF : 0;
@@ -92,17 +80,13 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec.member: foo5:function(param1, param2) {
-  var a = H.boolConversionCheck(param1) ? 4294967295 : 0;
-  return C.JSInt_methods.$tdiv(a, H.boolConversionCheck(param2) ? 3 : 4);
+/*spec|canary.member: foo5:function(param1, param2) {
+  var a = A.boolConversionCheck(param1) ? 4294967295 : 0;
+  return B.JSInt_methods.$tdiv(a, A.boolConversionCheck(param2) ? 3 : 4);
 }*/
 /*prod.member: foo5:function(param1, param2) {
   var a = param1 ? 4294967295 : 0;
-  return C.JSInt_methods.$tdiv(a, param2 ? 3 : 4);
-}*/
-/*canary.member: foo5:function(param1, param2) {
-  var a = A.boolConversionCheck(param1) ? 4294967295 : 0;
-  return B.JSInt_methods.$tdiv(a, A.boolConversionCheck(param2) ? 3 : 4);
+  return B.JSInt_methods.$tdiv(a, param2 ? 3 : 4);
 }*/
 int foo5(bool param1, bool param2) {
   var a = param1 ? 0xFFFFFFFF : 0;
@@ -115,17 +99,13 @@
 }
 
 @pragma('dart2js:noInline')
-/*spec.member: foo_regress_37502:function(param1, param2) {
-  var a = H.boolConversionCheck(param1) ? 1.2 : 12.3;
-  return C.JSInt_methods.gcd$1(C.JSNumber_methods.$tdiv(a, H.boolConversionCheck(param2) ? 3.14 : 2.81), 2);
+/*spec|canary.member: foo_regress_37502:function(param1, param2) {
+  var a = A.boolConversionCheck(param1) ? 1.2 : 12.3;
+  return B.JSInt_methods.gcd$1(B.JSNumber_methods.$tdiv(a, A.boolConversionCheck(param2) ? 3.14 : 2.81), 2);
 }*/
 /*prod.member: foo_regress_37502:function(param1, param2) {
   var a = param1 ? 1.2 : 12.3;
-  return C.JSInt_methods.gcd$1(C.JSNumber_methods.$tdiv(a, param2 ? 3.14 : 2.81), 2);
-}*/
-/*canary.member: foo_regress_37502:function(param1, param2) {
-  var a = A.boolConversionCheck(param1) ? 1.2 : 12.3;
-  return B.JSInt_methods.gcd$1(B.JSNumber_methods.$tdiv(a, A.boolConversionCheck(param2) ? 3.14 : 2.81), 2);
+  return B.JSInt_methods.gcd$1(B.JSNumber_methods.$tdiv(a, param2 ? 3.14 : 2.81), 2);
 }*/
 foo_regress_37502(param1, param2) {
   var a = param1 ? 1.2 : 12.3;
diff --git a/pkg/compiler/test/codegen/new_rti_is_test.dart b/pkg/compiler/test/codegen/new_rti_is_test.dart
index 1ce65e9..b6d2b53 100644
--- a/pkg/compiler/test/codegen/new_rti_is_test.dart
+++ b/pkg/compiler/test/codegen/new_rti_is_test.dart
@@ -11,7 +11,7 @@
 import '../helpers/compiler_helper.dart';
 
 // 'N' tests all have a nullable input so should not reduce is-test.
-// TODO(NNBD): Add tests with non-nullable input types.
+// TODO(sra): Add tests with non-nullable input types.
 
 const TEST1N = r"""
 foo(int a) {
diff --git a/pkg/compiler/test/inference/data/list_tracer_typed_data_length.dart b/pkg/compiler/test/inference/data/list_tracer_typed_data_length.dart
index a08ef1a..f47e3ca 100644
--- a/pkg/compiler/test/inference/data/list_tracer_typed_data_length.dart
+++ b/pkg/compiler/test/inference/data/list_tracer_typed_data_length.dart
@@ -6,8 +6,8 @@
 
 import 'dart:typed_data';
 
-// TODO(johnniwinther): Fix inference for spec:nnbd-off mode. List elements should not
-// be [empty].
+// TODO(johnniwinther): Fix inference for spec mode. List elements should not be
+// [empty].
 
 /*member: myList:Container([null|exact=NativeFloat32List], element: [subclass=JSNumber], length: 42)*/
 var myList = new Float32List(42);
diff --git a/pkg/compiler/test/kernel/goldens_test.dart b/pkg/compiler/test/kernel/goldens_test.dart
index a945729..dcef219 100644
--- a/pkg/compiler/test/kernel/goldens_test.dart
+++ b/pkg/compiler/test/kernel/goldens_test.dart
@@ -14,9 +14,9 @@
 final String testRootDir = Platform.script.resolve('.').toFilePath();
 
 runTestCase(
-    Uri source, List<String> experimentalFlags, bool enableNullSafety) async {
+    Uri source, List<String> experimentalFlags, bool soundNullSafety) async {
   final target =
-      TestingDart2jsTarget(TargetFlags(enableNullSafety: enableNullSafety));
+      TestingDart2jsTarget(TargetFlags(enableNullSafety: soundNullSafety));
   Component component = await compileTestCaseToKernelProgram(source,
       target: target, experimentalFlags: experimentalFlags);
 
@@ -33,13 +33,11 @@
         in testCasesDir.listSync(recursive: true, followLinks: false)) {
       final path = entry.path;
       if (path.endsWith('.dart')) {
-        final bool enableNullSafety = path.endsWith('_nnbd_strong.dart');
-        final bool enableNNBD = enableNullSafety || path.endsWith('_nnbd.dart');
-        final List<String> experimentalFlags = [
-          if (enableNNBD) 'non-nullable',
-        ];
-        test(path,
-            () => runTestCase(entry.uri, experimentalFlags, enableNullSafety));
+        final bool unsoundNullSafety = path.endsWith('_unsound.dart');
+        test(
+            path,
+            () => runTestCase(
+                entry.uri, const ['non-nullable'], !unsoundNullSafety));
       }
     }
   }, timeout: Timeout.none);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 422e2be..02c28b2 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -3450,17 +3450,6 @@
                            intptr_t kernel_buffer_size);
 
 /**
- * Returns a flattened list of pairs. The first element in each pair is the
- * importing library and and the second element is the imported library for each
- * import in the isolate of a library whose URI's scheme is [scheme].
- *
- * Requires there to be a current isolate.
- *
- * \return A handle to a list of flattened pairs of importer-importee.
- */
-DART_EXPORT Dart_Handle Dart_GetImportsOfScheme(Dart_Handle scheme);
-
-/**
  * Indicates that all outstanding load requests have been satisfied.
  * This finalizes all the new classes loaded and optionally completes
  * deferred library futures.
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 5d21abf..94c0f77 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -5802,41 +5802,6 @@
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
-DART_EXPORT Dart_Handle Dart_GetImportsOfScheme(Dart_Handle scheme) {
-  DARTSCOPE(Thread::Current());
-  auto IG = T->isolate_group();
-  const String& scheme_vm = Api::UnwrapStringHandle(Z, scheme);
-  if (scheme_vm.IsNull()) {
-    RETURN_TYPE_ERROR(Z, scheme, String);
-  }
-
-  const GrowableObjectArray& libraries =
-      GrowableObjectArray::Handle(Z, IG->object_store()->libraries());
-  const GrowableObjectArray& result =
-      GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
-  Library& importer = Library::Handle(Z);
-  Array& imports = Array::Handle(Z);
-  Namespace& ns = Namespace::Handle(Z);
-  Library& importee = Library::Handle(Z);
-  String& importee_uri = String::Handle(Z);
-  for (intptr_t i = 0; i < libraries.Length(); i++) {
-    importer ^= libraries.At(i);
-    imports = importer.imports();
-    for (intptr_t j = 0; j < imports.Length(); j++) {
-      ns ^= imports.At(j);
-      if (ns.IsNull()) continue;
-      importee = ns.target();
-      importee_uri = importee.url();
-      if (importee_uri.StartsWith(scheme_vm)) {
-        result.Add(importer);
-        result.Add(importee);
-      }
-    }
-  }
-
-  return Api::NewHandle(T, Array::MakeFixedLength(result));
-}
-
 // Finalizes classes and invokes Dart core library function that completes
 // futures of loadLibrary calls (deferred library loading).
 DART_EXPORT Dart_Handle Dart_FinalizeLoading(bool complete_futures) {
diff --git a/tools/VERSION b/tools/VERSION
index 89f18db..5f3e116 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 105
+PRERELEASE 106
 PRERELEASE_PATCH 0
\ No newline at end of file