[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():