[Elements.migrate] Migrate InScopeCompletionPass.

Change-Id: I5801f9882487e4f3255d75f5e44b7a5e9fdb3b79
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/398941
Commit-Queue: Keerti Parthasarathy <keertip@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/analyzer_use_new_elements.txt b/pkg/analysis_server/analyzer_use_new_elements.txt
index 5d8eef3..e9b92bc 100644
--- a/pkg/analysis_server/analyzer_use_new_elements.txt
+++ b/pkg/analysis_server/analyzer_use_new_elements.txt
@@ -30,7 +30,6 @@
 lib/src/services/completion/dart/completion_manager.dart
 lib/src/services/completion/dart/declaration_helper.dart
 lib/src/services/completion/dart/identifier_helper.dart
-lib/src/services/completion/dart/in_scope_completion_pass.dart
 lib/src/services/completion/dart/visibility_tracker.dart
 lib/src/services/correction/dart/import_library.dart
 lib/src/services/correction/dart/use_different_division_operator.dart
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart b/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart
index d3a2278..1349f92c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart
@@ -173,6 +173,11 @@
     }
   }
 
+  /// Add suggestions for all constructors of [element].
+  void addConstructorNamesForElement2({required InterfaceElement2 element}) {
+    addConstructorNamesForElement(element: element.asElement);
+  }
+
   /// Add suggestions for all of the named constructors in the [type]. If
   /// [exclude] is not `null` it is the name of a constructor that should be
   /// omitted from the list, typically because suggesting it would result in an
@@ -229,6 +234,11 @@
     }
   }
 
+  /// Add suggestions for declarations through [prefixElement].
+  void addDeclarationsThroughImportPrefix2(PrefixElement2 prefixElement) {
+    addDeclarationsThroughImportPrefix(prefixElement.asElement);
+  }
+
   /// Add any fields that can be initialized in the initializer list of the
   /// given [constructor]. If a [fieldToInclude] is provided, then it should not
   /// be skipped because the cursor is inside that field's name.
@@ -277,6 +287,19 @@
     }
   }
 
+  /// Add any fields that can be initialized in the initializer list of the
+  /// given [constructor]. If a [fieldToInclude] is provided, then it should not
+  /// be skipped because the cursor is inside that field's name.
+  void addFieldsForInitializers2(
+    ConstructorDeclaration constructor,
+    FieldElement2? fieldToInclude,
+  ) {
+    addFieldsForInitializers(
+      constructor,
+      fieldToInclude == null ? null : fieldToInclude.asElement as FieldElement,
+    );
+  }
+
   /// Add suggestions for all of the top-level declarations that are exported
   /// from the [library] except for those whose name is in the set of
   /// [excludedNames].
@@ -288,6 +311,17 @@
     }
   }
 
+  /// Add suggestions for all of the top-level declarations that are exported
+  /// from the [library] except for those whose name is in the set of
+  /// [excludedNames].
+  void addFromLibrary2(LibraryElement2 library, Set<String> excludedNames) {
+    for (var entry in library.exportNamespace.definedNames.entries) {
+      if (!excludedNames.contains(entry.key)) {
+        _addImportedElement(entry.value);
+      }
+    }
+  }
+
   /// Adds suggestions for the getters defined by the [type], except for those
   /// whose names are in the set of [excludedGetters].
   void addGetters({
@@ -457,6 +491,17 @@
     }
   }
 
+  /// Add members from the given [ExtensionElement2].
+  void addMembersFromExtensionElement2(
+    ExtensionElement2 extension, {
+    ImportData? importData,
+  }) {
+    addMembersFromExtensionElement(
+      extension.asElement as ExtensionElement,
+      importData: importData,
+    );
+  }
+
   /// Adds suggestions for any constructors that are visible within the not yet
   /// imported [library].
   void addNotImportedConstructors(LibraryElement2 library) {
@@ -599,6 +644,18 @@
     }
   }
 
+  /// Add suggestions for all of the constructor in the [library] that could be
+  /// a redirection target for the [redirectingConstructor].
+  void addPossibleRedirectionsInLibrary2(
+    ConstructorElement2 redirectingConstructor,
+    LibraryElement2 library,
+  ) {
+    addPossibleRedirectionsInLibrary(
+      redirectingConstructor.asElement,
+      library.asElement,
+    );
+  }
+
   /// Add any static members defined by the given [element].
   void addStaticMembersOfElement(Element element) {
     if (element is TypeAliasElement) {
@@ -638,6 +695,11 @@
     }
   }
 
+  /// Add any static members defined by the given [element].
+  void addStaticMembersOfElement2(Element2 element) {
+    addStaticMembersOfElement(element.asElement!);
+  }
+
   /// Adds suggestions for any constructors that are declared within the
   /// [library].
   void _addConstructors(LibraryElement library, ImportData importData) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart b/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart
index 3074717..283e10e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart
@@ -22,7 +22,6 @@
 import 'package:analyzer/dart/ast/syntactic_entity.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/element2.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/source/source_range.dart';
@@ -30,7 +29,6 @@
 import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/utilities/extensions/ast.dart';
-import 'package:analyzer/src/utilities/extensions/element.dart';
 import 'package:analyzer/src/utilities/extensions/flutter.dart';
 
 /// A completion pass that will create candidate suggestions based on the
@@ -309,11 +307,11 @@
       var parameters = node.invokedFormalParameters;
       if (parameters != null) {
         var positionalParameterCount = 0;
-        var availableNamedParameters = <ParameterElement>[];
+        var availableNamedParameters = <FormalParameterElement>[];
         for (int i = 0; i < parameters.length; i++) {
           var parameter = parameters[i];
           if (parameter.isNamed) {
-            if (!usedNames.contains(parameter.name)) {
+            if (!usedNames.contains(parameter.name3)) {
               availableNamedParameters.add(parameter);
             }
           } else {
@@ -377,10 +375,10 @@
         for (var parameter in availableNamedParameters) {
           var matcherScore = state.matcher.score(parameter.displayName);
           if (matcherScore != -1) {
-            var isWidget = isFlutterWidgetParameter(parameter.asElement2);
+            var isWidget = isFlutterWidgetParameter(parameter);
             collector.addSuggestion(
               NamedArgumentSuggestion(
-                parameter: parameter.asElement2,
+                parameter: parameter,
                 appendColon: true,
                 appendComma: appendComma,
                 replacementLength: replacementLength,
@@ -738,14 +736,14 @@
         _forConstructorInitializer(node, null);
       }
     } else if (type == TokenType.EQ) {
-      var constructorElement = node.declaredElement;
+      var constructorElement = node.declaredFragment?.element;
       if (constructorElement == null) {
         return;
       }
-      var libraryElement = state.libraryElement.asElement;
+      var libraryElement = state.libraryElement;
       declarationHelper(
         mustBeConstant: constructorElement.isConst,
-      ).addPossibleRedirectionsInLibrary(constructorElement, libraryElement);
+      ).addPossibleRedirectionsInLibrary2(constructorElement, libraryElement);
     }
   }
 
@@ -785,14 +783,14 @@
   @override
   void visitConstructorName(ConstructorName node) {
     if (node.parent is ConstructorReference) {
-      var element = node.type.element;
-      if (element is InterfaceElement) {
+      var element = node.type.element2;
+      if (element is InterfaceElement2) {
         declarationHelper(
           preferNonInvocation: true,
-        ).addConstructorNamesForElement(element: element);
+        ).addConstructorNamesForElement2(element: element);
         declarationHelper(
           preferNonInvocation: true,
-        ).addStaticMembersOfElement(element);
+        ).addStaticMembersOfElement2(element);
       }
     } else {
       var type = node.type.type;
@@ -846,10 +844,10 @@
       return;
     }
 
-    var enumElement = enumDeclaration.declaredElement!;
+    var enumElement = enumDeclaration.declaredFragment!.element;
     declarationHelper(
       suggestUnnamedAsNew: true,
-    ).addConstructorNamesForElement(element: enumElement);
+    ).addConstructorNamesForElement2(element: enumElement);
   }
 
   @override
@@ -1275,12 +1273,12 @@
       constructor = constructor.parent;
     }
     if (constructor is ConstructorDeclaration) {
-      var declaredElement = node.declaredElement;
-      FieldElement? field;
-      if (declaredElement is FieldFormalParameterElement) {
-        field = declaredElement.field;
+      var declaredElement = node.declaredFragment?.element;
+      FieldElement2? field;
+      if (declaredElement is FieldFormalParameterElement2) {
+        field = declaredElement.field2;
       }
-      declarationHelper().addFieldsForInitializers(constructor, field);
+      declarationHelper().addFieldsForInitializers2(constructor, field);
     }
   }
 
@@ -1664,29 +1662,29 @@
   void visitImportPrefixReference(ImportPrefixReference node) {
     var parent = node.parent;
     if (parent is NamedType && offset <= parent.name2.offset) {
-      var element = node.element;
+      var element = node.element2;
       DartType type;
       collector.completionLocation = 'PropertyAccess_propertyName';
-      if (element is FunctionTypedElement) {
-        if (element is PropertyAccessorElement && element.isGetter) {
+      if (element is FunctionTypedElement2) {
+        if (element is GetterElement) {
           type = element.type.returnType;
         } else {
           type = element.type;
         }
-      } else if (element is PrefixElement) {
+      } else if (element is PrefixElement2) {
         var isInstanceCreation =
             node.parent?.parent?.parent is InstanceCreationExpression;
         declarationHelper(
           excludeTypeNames: isInstanceCreation,
           mustBeType: !isInstanceCreation,
           mustBeNonVoid: isInstanceCreation,
-        ).addDeclarationsThroughImportPrefix(element);
+        ).addDeclarationsThroughImportPrefix2(element);
         return;
-      } else if (element is VariableElement) {
+      } else if (element is VariableElement2) {
         type = element.type;
       } else {
-        if (element is InterfaceElement || element is ExtensionElement) {
-          declarationHelper().addStaticMembersOfElement(element!);
+        if (element is InterfaceElement2 || element is ExtensionElement2) {
+          declarationHelper().addStaticMembersOfElement2(element!);
         }
         return;
       }
@@ -1931,12 +1929,12 @@
       if ((type == null || type is InvalidType || type.isDartCoreType) &&
           target is Identifier &&
           (!node.isCascaded || offset == operator.offset + 1)) {
-        var element = target.staticElement;
-        if (element is InterfaceElement || element is ExtensionTypeElement) {
-          declarationHelper().addStaticMembersOfElement(element!);
+        var element = target.element;
+        if (element is InterfaceElement2 || element is ExtensionTypeElement2) {
+          declarationHelper().addStaticMembersOfElement2(element!);
         }
-        if (element is PrefixElement) {
-          declarationHelper().addDeclarationsThroughImportPrefix(element);
+        if (element is PrefixElement2) {
+          declarationHelper().addDeclarationsThroughImportPrefix2(element);
         }
       }
     }
@@ -2015,15 +2013,14 @@
             for (int i = 0; i < parameters.length; i++) {
               var parameter = parameters[i];
               if (parameter.isNamed) {
-                if (!usedNames.contains(parameter.name)) {
+                if (!usedNames.contains(parameter.name3)) {
                   var matcherScore = state.matcher.score(parameter.displayName);
                   if (matcherScore != -1) {
-                    var isWidget = isFlutterWidgetParameter(
-                      parameter.asElement2,
-                    );
+                    var isWidget = isFlutterWidgetParameter(parameter);
                     collector.addSuggestion(
                       NamedArgumentSuggestion(
-                        parameter: parameter.asElement2,
+                        parameter:
+                            parameter,
                         matcherScore: matcherScore,
                         appendColon: appendColon,
                         appendComma: false,
@@ -2052,7 +2049,7 @@
         collector.completionLocation = 'ArgumentList_method_named';
       }
       _forExpression(node, mustBeNonVoid: inArgumentList);
-      var parameterType = node.staticParameterElement?.type;
+      var parameterType = node.element2?.type;
       if (parameterType is FunctionType) {
         var includeTrailingComma = !node.isFollowedByComma;
         _addClosureSuggestion(parameterType, includeTrailingComma);
@@ -2063,14 +2060,14 @@
   @override
   void visitNamedType(NamedType node) {
     var importPrefix = node.importPrefix;
-    var prefixElement = importPrefix?.element;
+    var prefixElement = importPrefix?.element2;
 
     // `prefix.x^ print(0);` is recovered as `prefix.x print; (0);`.
-    if (prefixElement is PrefixElement) {
+    if (prefixElement is PrefixElement2) {
       if (node.parent case VariableDeclarationList variableList) {
         if (variableList.parent case VariableDeclarationStatement statement) {
           if (statement.semicolon.isSynthetic) {
-            declarationHelper().addDeclarationsThroughImportPrefix(
+            declarationHelper().addDeclarationsThroughImportPrefix2(
               prefixElement,
             );
             return;
@@ -2258,14 +2255,14 @@
           if (element is PrefixElement2) {
             declarationHelper(
               mustBeAssignable: mustBeAssignable,
-            ).addDeclarationsThroughImportPrefix(element.asElement);
+            ).addDeclarationsThroughImportPrefix2(element);
           } else {
             declarationHelper(
               mustBeAssignable: mustBeAssignable,
               preferNonInvocation:
                   element is InterfaceElement2 &&
-                  state.request.shouldSuggestTearOff(element),
-            ).addStaticMembersOfElement(element.asElement!);
+                  state.request.shouldSuggestTearOff2(element),
+            ).addStaticMembersOfElement2(element);
           }
         }
       }
@@ -2308,16 +2305,16 @@
       if ((type == null || type is InvalidType || type.isDartCoreType) &&
           target is Identifier &&
           (!node.isCascaded || offset == operator.offset + 1)) {
-        var element = target.staticElement;
-        if (element is InterfaceElement || element is ExtensionTypeElement) {
-          declarationHelper().addStaticMembersOfElement(element!);
+        var element = target.element;
+        if (element is InterfaceElement2 || element is ExtensionTypeElement2) {
+          declarationHelper().addStaticMembersOfElement2(element!);
         }
-        if (element is PrefixElement) {
-          declarationHelper().addDeclarationsThroughImportPrefix(element);
+        if (element is PrefixElement2) {
+          declarationHelper().addDeclarationsThroughImportPrefix2(element);
         }
       }
       if (type == null && target is ExtensionOverride) {
-        declarationHelper().addMembersFromExtensionElement(target.element);
+        declarationHelper().addMembersFromExtensionElement2(target.element2);
       }
     }
   }
@@ -2555,12 +2552,12 @@
       collector.completionLocation = 'FormalParameterList_parameter';
       if (type is NamedType) {
         if (type.importPrefix case var importPrefix?) {
-          var prefixElement = importPrefix.element;
-          if (prefixElement is PrefixElement) {
+          var prefixElement = importPrefix.element2;
+          if (prefixElement is PrefixElement2) {
             if (type.name2.coversOffset(offset)) {
               declarationHelper(
                 mustBeType: true,
-              ).addDeclarationsThroughImportPrefix(prefixElement);
+              ).addDeclarationsThroughImportPrefix2(prefixElement);
             }
           }
         }
@@ -2637,8 +2634,8 @@
         offset <= node.argumentList.offset) {
       var container = constructor.parent;
       var superType = switch (container) {
-        ClassDeclaration() => container.declaredElement?.supertype,
-        EnumDeclaration() => container.declaredElement?.supertype,
+        ClassDeclaration() => container.declaredFragment?.supertype,
+        EnumDeclaration() => container.declaredFragment?.supertype,
         _ => null,
       };
       if (superType != null) {
@@ -3070,8 +3067,8 @@
           }
           _suggestOverridesFor(
             element: switch (container) {
-              ClassDeclaration() => container.declaredElement,
-              MixinDeclaration() => container.declaredElement,
+              ClassDeclaration() => container.declaredFragment?.element,
+              MixinDeclaration() => container.declaredFragment?.element,
               _ => null,
             },
           );
@@ -3090,7 +3087,7 @@
     if (equals != null && offset >= equals.end) {
       collector.completionLocation = 'VariableDeclaration_initializer';
       _forExpression(node, mustBeNonVoid: true);
-      var variableType = node.declaredElement?.type;
+      var variableType = node.declaredFragment?.element.type;
       if (variableType is FunctionType) {
         _addClosureSuggestion(variableType, false);
       }
@@ -3279,7 +3276,7 @@
   void _forClassMember(ClassDeclaration node) {
     keywordHelper.addClassMemberKeywords();
     declarationHelper(mustBeType: true).addLexicalDeclarations(node);
-    _suggestOverridesFor(element: node.declaredElement);
+    _suggestOverridesFor(element: node.declaredFragment?.element);
   }
 
   /// Adds the suggestions that are appropriate when the selection is at the
@@ -3314,7 +3311,7 @@
     if (directive is! NamespaceDirective) {
       return;
     }
-    var library = directive.referencedLibrary?.asElement;
+    var library = directive.referencedLibrary;
     if (library == null) {
       return;
     }
@@ -3330,7 +3327,7 @@
             .toSet();
     declarationHelper(
       preferNonInvocation: true,
-    ).addFromLibrary(library, excludedNames);
+    ).addFromLibrary2(library, excludedNames);
   }
 
   /// Adds the suggestions that are appropriate when the selection is at the
@@ -3385,13 +3382,13 @@
     ConstructorDeclaration constructor,
     ConstructorFieldInitializer? initializer,
   ) {
-    var element = initializer?.fieldName.staticElement;
-    FieldElement? field;
-    if (element is FieldElement) {
+    var element = initializer?.fieldName.element;
+    FieldElement2? field;
+    if (element is FieldElement2) {
       field = element;
     }
     keywordHelper.addConstructorInitializerKeywords(constructor, initializer);
-    declarationHelper().addFieldsForInitializers(constructor, field);
+    declarationHelper().addFieldsForInitializers2(constructor, field);
   }
 
   /// Adds the suggestions that are appropriate when the selection is at the
@@ -3538,7 +3535,7 @@
   void _forMixinMember(MixinDeclaration node) {
     keywordHelper.addMixinMemberKeywords();
     declarationHelper(mustBeType: true).addLexicalDeclarations(node);
-    _suggestOverridesFor(element: node.declaredElement);
+    _suggestOverridesFor(element: node.declaredFragment?.element);
   }
 
   /// Adds the suggestions that are appropriate when the selection is in the
@@ -3665,9 +3662,10 @@
   ) {
     var container = constructor.parent;
     var thisType = switch (container) {
-      ClassDeclaration() => container.declaredElement?.thisType,
-      EnumDeclaration() => container.declaredElement?.thisType,
-      ExtensionTypeDeclaration() => container.declaredElement?.thisType,
+      ClassDeclaration() => container.declaredFragment?.element.thisType,
+      EnumDeclaration() => container.declaredFragment?.element.thisType,
+      ExtensionTypeDeclaration() =>
+        container.declaredFragment?.element.thisType,
       _ => null,
     };
     if (thisType != null) {
@@ -3706,8 +3704,8 @@
 
     if (node is NamedType) {
       if (node.importPrefix case var importPrefix?) {
-        var prefixElement = importPrefix.element;
-        if (prefixElement is PrefixElement) {
+        var prefixElement = importPrefix.element2;
+        if (prefixElement is PrefixElement2) {
           declarationHelper(
             mustBeExtensible: mustBeExtensible,
             mustBeImplementable: mustBeImplementable,
@@ -3715,7 +3713,7 @@
             mustBeNonVoid: mustBeNonVoid,
             excludedNodes: excludedNodes,
             excludeTypeNames: excludeTypeNames,
-          ).addDeclarationsThroughImportPrefix(prefixElement);
+          ).addDeclarationsThroughImportPrefix2(prefixElement);
         }
         return;
       }
@@ -3890,7 +3888,7 @@
   /// If the budget has been exceeded, then the results are marked as incomplete
   /// and no suggestions are added.
   void _suggestOverridesFor({
-    required InterfaceElement? element,
+    required InterfaceElement2? element,
     bool skipAt = false,
   }) {
     if (state.budget.isEmpty) {
@@ -3900,7 +3898,7 @@
     }
     if (suggestOverrides && element != null) {
       overrideHelper.computeOverridesFor(
-        interfaceElement: element.asElement2,
+        interfaceElement: element,
         replacementRange: SourceRange(offset, 0),
         skipAt: skipAt,
       );
@@ -3981,8 +3979,8 @@
   void _tryOverrideAnnotation(Token identifier, Declaration node) {
     var lexeme = identifier.lexeme;
     if (lexeme.isNotEmpty && 'override'.startsWith(lexeme)) {
-      var declaredElement = node.declaredElement;
-      if (declaredElement is InterfaceElement) {
+      var declaredElement = node.declaredFragment?.element;
+      if (declaredElement is InterfaceElement2) {
         _suggestOverridesFor(element: declaredElement, skipAt: true);
       }
     }
@@ -4178,37 +4176,37 @@
 extension on ArgumentList {
   /// The element being invoked by the expression containing this argument list,
   /// or `null` if the element is not known.
-  Element? get invokedElement {
+  Element2? get invokedElement {
     switch (parent) {
       case Annotation invocation:
-        return invocation.element;
+        return invocation.element2;
       case EnumConstantArguments invocation:
         var grandParent = invocation.parent;
         if (grandParent is EnumConstantDeclaration) {
-          return grandParent.constructorElement;
+          return grandParent.constructorElement2;
         }
       case FunctionExpressionInvocation invocation:
-        var element = invocation.staticElement;
+        var element = invocation.element;
         if (element == null) {
           var function = invocation.function.unParenthesized;
           if (function is SimpleIdentifier) {
-            return function.staticElement;
+            return function.element;
           }
         }
         return element;
       case InstanceCreationExpression invocation:
-        return invocation.constructorName.staticElement;
+        return invocation.constructorName.element;
       case MethodInvocation invocation:
-        return invocation.methodName.staticElement;
+        return invocation.methodName.element;
       case SuperConstructorInvocation invocation:
-        return invocation.staticElement;
+        return invocation.element;
       case RedirectingConstructorInvocation invocation:
-        return invocation.staticElement;
+        return invocation.element;
     }
     return null;
   }
 
-  List<ParameterElement>? get invokedFormalParameters {
+  List<FormalParameterElement>? get invokedFormalParameters {
     var result = invokedElement?.getParameters();
     if (result != null) {
       return result;
@@ -4218,7 +4216,7 @@
       case FunctionExpressionInvocation invocation:
         var functionType = invocation.function.staticType;
         if (functionType is FunctionType) {
-          return functionType.parameters;
+          return functionType.formalParameters;
         }
     }
 
@@ -4300,7 +4298,7 @@
   }
 }
 
-extension on Element? {
+extension on Element2? {
   /// Returns the parameters associated with this element, or `null` if this
   /// element doesn't have any parameters associated with it.
   ///
@@ -4308,16 +4306,16 @@
   /// the method / function's parameters. If this element is a variable and the
   /// variable's type is a function type, then return the parameters from the
   /// function type.
-  List<ParameterElement>? getParameters() {
+  List<FormalParameterElement>? getParameters() {
     var self = this;
-    if (self is PropertyAccessorElement && self.isGetter) {
-      return self.returnType.ifTypeOrNull<FunctionType>()?.parameters;
-    } else if (self is ExecutableElement) {
-      return self.parameters;
-    } else if (self is VariableElement) {
+    if (self is GetterElement) {
+      return self.returnType.ifTypeOrNull<FunctionType>()?.formalParameters;
+    } else if (self is ExecutableElement2) {
+      return self.formalParameters;
+    } else if (self is VariableElement2) {
       var type = self.type;
       if (type is FunctionType) {
-        return type.parameters;
+        return type.formalParameters;
       }
     }
     return null;
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/ast.dart b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
index 0be97a9..d23f8e5 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
@@ -280,6 +280,7 @@
     }
   }
 
+
   /// If [referencedUri] is a [DirectiveUriWithSource], returns the [Source]
   /// from it.
   Source? get referencedSource {
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/completion_request.dart b/pkg/analysis_server/lib/src/utilities/extensions/completion_request.dart
index bdec577..452beca 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/completion_request.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/completion_request.dart
@@ -38,4 +38,13 @@
       contextType.returnType,
     );
   }
+
+  /// Return `true` if the constructor tear-offs feature is enabled, and the
+  /// context type is a function type that matches an instantiation of the
+  /// [element].
+  ///
+  // TODO(scheglov): Validate that suggesting a tear-off instead of invocation
+  // is statistically a good choice.
+  bool shouldSuggestTearOff2(InterfaceElement2 element) =>
+      shouldSuggestTearOff(element);
 }
diff --git a/pkg/analyzer/lib/src/utilities/extensions/element.dart b/pkg/analyzer/lib/src/utilities/extensions/element.dart
index 8c8c85c..bbdeae0 100644
--- a/pkg/analyzer/lib/src/utilities/extensions/element.dart
+++ b/pkg/analyzer/lib/src/utilities/extensions/element.dart
@@ -81,6 +81,8 @@
         return self;
       case ExecutableMember():
         return self.declaration as Element;
+      case ExtensionElementImpl2():
+        return self.firstFragment as Element;
       case FieldElementImpl2():
         return self.firstFragment as Element;
       case FieldMember():