blob: 1f9570cf08d6f5f1d8e5237e7a2c9fa249389b75 [file] [log] [blame]
// Copyright (c) 2023, 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.
// ignore_for_file: analyzer_use_new_elements
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:meta/meta.dart';
class MockLibraryImportElement implements Element2, PrefixFragment {
final LibraryImportElementImpl import;
MockLibraryImportElement(LibraryImport import)
: import = import as LibraryImportElementImpl;
@override
LibraryElement2 get enclosingElement2 => library2;
@override
ElementKind get kind => ElementKind.IMPORT;
@override
LibraryElementImpl get library2 => libraryFragment.element;
@override
CompilationUnitElementImpl get libraryFragment => import.libraryFragment;
@override
String? get name3 => import.prefix2?.name2;
@override
noSuchMethod(invocation) => super.noSuchMethod(invocation);
}
extension BindPatternVariableElementImpl2Extension
on BindPatternVariableElementImpl2 {
BindPatternVariableElementImpl get asElement {
return firstFragment;
}
}
extension BindPatternVariableElementImplExtension
on BindPatternVariableElementImpl {
BindPatternVariableElementImpl2 get asElement2 {
return element;
}
}
extension ClassElementImpl2Extension on ClassElementImpl2 {
ClassElementImpl get asElement {
return firstFragment;
}
}
extension ClassElementImplExtension on ClassElementImpl {
ClassElementImpl2 get asElement2 {
return element;
}
}
extension CompilationUnitElementImplExtension on CompilationUnitElementImpl {
/// Returns this library fragment, and all its enclosing fragments.
List<CompilationUnitElementImpl> get withEnclosing {
var result = <CompilationUnitElementImpl>[];
var current = this;
while (true) {
result.add(current);
if (current.enclosingElement3 case var enclosing?) {
current = enclosing;
} else {
break;
}
}
return result;
}
}
@Deprecated('Use ConstructorElement2 instead')
extension ConstructorElement2Extension on ConstructorElement2 {
ConstructorElement get asElement {
if (this case ConstructorMember member) {
return member;
}
return (this as ConstructorElementImpl2).lastFragment;
}
}
extension ConstructorElementImpl2Extension on ConstructorElementImpl2 {
ConstructorElementImpl get asElement {
return lastFragment;
}
}
extension ConstructorElementImplExtension on ConstructorElementImpl {
ConstructorElementImpl2 get asElement2 {
return element;
}
}
extension ConstructorElementMixin2Extension on ConstructorElementMixin2 {
ConstructorElementMixin get asElement {
if (this case ConstructorMember member) {
return member;
}
return (this as ConstructorElementImpl2).lastFragment;
}
}
extension ConstructorElementMixinExtension on ConstructorElementMixin {
ConstructorElementMixin2 get asElement2 {
return switch (this) {
ConstructorElementImpl(:var element) => element,
ConstructorMember member => member,
_ => throw UnsupportedError('Unsupported type: $runtimeType'),
};
}
ElementImpl? get enclosingElementImpl => enclosingElement3 as ElementImpl?;
}
extension Element2Extension on Element2 {
/// Whether the element is effectively [internal].
bool get isInternal {
if (this case Annotatable annotatable) {
if (annotatable.metadata2.hasInternal) {
return true;
}
}
if (this case PropertyAccessorElement2 accessor) {
var variable = accessor.variable3;
if (variable != null && variable.metadata2.hasInternal) {
return true;
}
}
return false;
}
/// Whether the element is effectively [protected].
bool get isProtected {
var self = this;
if (self is PropertyAccessorElement2 &&
self.enclosingElement2 is InterfaceElement2) {
if (self.metadata2.hasProtected) {
return true;
}
var variable = self.variable3;
if (variable != null && variable.metadata2.hasProtected) {
return true;
}
}
if (self is MethodElement2 &&
self.enclosingElement2 is InterfaceElement2 &&
self.metadata2.hasProtected) {
return true;
}
return false;
}
/// Whether the element is effectively [visibleForTesting].
bool get isVisibleForTesting {
if (this case Annotatable annotatable) {
if (annotatable.metadata2.hasVisibleForTesting) {
return true;
}
}
if (this case PropertyAccessorElement2 accessor) {
var variable = accessor.variable3;
if (variable != null && variable.metadata2.hasVisibleForTesting) {
return true;
}
}
return false;
}
List<ElementAnnotation> get metadata {
if (this case Annotatable annotatable) {
return annotatable.metadata2.annotations;
}
return [];
}
}
extension Element2OrNullExtension on Element2? {
Element? get asElement {
var self = this;
switch (self) {
case null:
return null;
case BindPatternVariableElementImpl2 element2:
return element2.asElement;
case ConstructorElementImpl2 element2:
return element2.asElement;
case DynamicElementImpl2():
return self.firstFragment;
case ExecutableMember element2:
return element2.asElement;
case ExtensionElementImpl2 element2:
return element2.asElement;
case FieldElementImpl2 element2:
return element2.asElement;
case FieldMember():
return self.declaration as Element;
case FormalParameterElement element2:
return element2.asElement;
case GetterElementImpl element2:
return element2.asElement;
case LabelElementImpl2 element2:
return element2.asElement;
case LibraryElementImpl():
return self as Element;
case LibraryImportElementImpl():
return self as Element;
case LocalFunctionElementImpl element2:
return element2.asElement;
case LocalVariableElementImpl2():
return self.wrappedElement as Element;
case MethodElementImpl2 element2:
return element2.asElement;
case MultiplyDefinedElementImpl2 element2:
return element2.asElement;
case NeverElementImpl2():
return NeverElementImpl.instance;
case PrefixElement2 element2:
return element2.asElement;
case SetterElementImpl element2:
return element2.asElement;
case TopLevelFunctionElementImpl element2:
return element2.asElement;
case TopLevelVariableElementImpl2 element2:
return element2.asElement;
case TypeDefiningElement2():
return self.firstFragment as Element;
case MockLibraryImportElement():
return self.import;
default:
throw UnsupportedError('Unsupported type: $runtimeType');
}
}
ElementImpl? get asElementImpl => asElement as ElementImpl;
}
extension ElementImplExtension on ElementImpl {
ElementImpl? get enclosingElementImpl => enclosingElement3;
AnnotationImpl annotationAst(int index) {
return metadata[index].annotationAst;
}
}
extension ElementOrNullExtension on Element? {
Element2? get asElement2 {
var self = this;
if (self == null) {
return null;
} else if (self is DynamicElementImpl) {
return DynamicElementImpl2.instance;
} else if (self is ExtensionElementImpl) {
return (self as ExtensionFragment).element;
} else if (self is ExecutableMember) {
return self as ExecutableElement2;
} else if (self is FieldMember) {
return self as FieldElement2;
} else if (self is FieldElementImpl) {
return (self as FieldFragment).element;
} else if (self is FunctionElementImpl) {
if (self.enclosingElement3 is! CompilationUnitElementImpl) {
// TODO(scheglov): update `FunctionElementImpl.element` return type?
return self.element;
} else {
return (self as Fragment).element;
}
} else if (self is InterfaceElementImpl) {
return self.element;
} else if (self is LabelElementImpl) {
return self.element2;
} else if (self is LibraryElementImpl) {
return self;
} else if (self is LocalVariableElementImpl) {
return self.element;
} else if (self is MultiplyDefinedElementImpl) {
return MultiplyDefinedElementImpl2(
self.libraryFragment,
self.name,
self.conflictingElements.map((e) => e.asElement2).nonNulls.toList(),
);
} else if (self is NeverElementImpl) {
return NeverElementImpl2.instance;
} else if (self is ParameterMember) {
return self;
} else if (self is PrefixElementImpl) {
return self.element2;
} else if (self is LibraryImportElementImpl ||
self is LibraryExportElementImpl ||
self is PartElementImpl) {
// There is no equivalent in the new element model.
return null;
} else {
return (self as Fragment?)?.element;
}
}
}
extension EnumElementImplExtension on EnumElementImpl {
EnumElementImpl2 get asElement2 {
return element;
}
}
extension ExecutableElement2Extension on ExecutableElement2 {
ExecutableElementOrMember get asElement {
if (this case ExecutableMember member) {
return member;
}
return firstFragment as ExecutableElementOrMember;
}
}
extension ExecutableElement2OrNullExtension on ExecutableElement2? {
ExecutableElement? get asElement {
return this?.asElement;
}
}
extension ExecutableElementExtension on ExecutableElement {
ExecutableElement2OrMember get asElement2 {
return switch (this) {
ExecutableFragment(:var element) => element,
ExecutableMember member => member,
_ => throw UnsupportedError('Unsupported type: $runtimeType'),
}
// TODO(paulberry): eliminate this cast by using impl types in the
// switch patterns above.
as ExecutableElement2OrMember;
}
ExecutableElementImpl get declarationImpl =>
declaration as ExecutableElementImpl;
}
extension ExecutableElementImpl2Extension on ExecutableElementImpl2 {
ExecutableElementImpl get asElement {
return lastFragment;
}
}
extension ExecutableElementImplExtension on ExecutableElementImpl {
ExecutableElementImpl2 get asElement2 {
return element;
}
}
extension ExecutableElementOrMemberExtension on ExecutableElementOrMember {
ExecutableElement2OrMember get asElement2 {
return switch (this) {
ExecutableElementImpl(:var element) => element,
ExecutableMember member => member,
_ => throw UnsupportedError('Unsupported type: $runtimeType'),
};
}
ElementImpl get enclosingElementImpl => enclosingElement3 as ElementImpl;
}
extension ExecutableElementOrNullExtension on ExecutableElement? {
ExecutableElement2? get asElement2 {
return this?.asElement2;
}
}
extension ExtensionElementImpl2Extension on ExtensionElementImpl2 {
ExtensionElementImpl get asElement {
return firstFragment;
}
}
extension ExtensionElementImplExtension on ExtensionElementImpl {
ExtensionElementImpl2 get asElement2 {
return element;
}
}
extension ExtensionTypeElementImpl2Extension on ExtensionTypeElementImpl2 {
ExtensionTypeElementImpl get asElement {
return firstFragment;
}
}
extension FieldElementImpl2Extension on FieldElementImpl2 {
FieldElementImpl get asElement {
return firstFragment;
}
}
extension FieldElementOrMemberExtension on FieldElementOrMember {
FieldElement2OrMember get asElement2 {
return switch (this) {
FieldElementImpl(:var element) => element,
FieldMember member => member,
_ => throw UnsupportedError('Unsupported type: $runtimeType'),
};
}
}
extension FormalParameterElementExtension on FormalParameterElement {
ParameterElement get asElement {
if (this case ParameterMember member) {
return member;
}
return firstFragment as ParameterElement;
}
void appendToWithoutDelimiters(
StringBuffer buffer, {
@Deprecated('Only non-nullable by default mode is supported')
bool withNullability = true,
}) {
buffer.write(
type.getDisplayString(
// ignore:deprecated_member_use_from_same_package
withNullability: withNullability,
),
);
buffer.write(' ');
buffer.write(displayName);
if (defaultValueCode != null) {
buffer.write(' = ');
buffer.write(defaultValueCode);
}
}
}
extension FormalParameterElementImplExtension on FormalParameterElementImpl {
ParameterElementImpl get asElement {
return firstFragment;
}
}
extension FormalParameterElementMixinExtension on FormalParameterElementMixin {
ParameterElementMixin get asElement {
return switch (this) {
FormalParameterElementImpl(:var firstFragment) => firstFragment,
ParameterMember member => member,
_ => throw UnsupportedError('Unsupported type: $runtimeType'),
};
}
}
extension GetterElementImplExtension on GetterElementImpl {
PropertyAccessorElementImpl get asElement {
return lastFragment;
}
}
extension InstanceElementImpl2Extension on InstanceElementImpl2 {
InstanceElementImpl get asElement {
return firstFragment;
}
}
extension InstanceElementImplExtension on InstanceElementImpl {
InstanceElementImpl2 get asElement2 {
return element;
}
}
extension InterfaceElementImpl2Extension on InterfaceElementImpl2 {
InterfaceElementImpl get asElement {
return firstFragment;
}
}
extension InterfaceElementImplExtension on InterfaceElementImpl {
InterfaceElementImpl2 get asElement2 {
return element;
}
}
extension InterfaceTypeImplExtension on InterfaceTypeImpl {
InterfaceElementImpl get elementImpl => element;
}
extension JoinPatternVariableElementImplExtension
on JoinPatternVariableElementImpl {
JoinPatternVariableElementImpl2 get asElement2 {
return element;
}
}
extension LabelElement2Extension on LabelElement2 {
LabelElement get asElement {
return firstFragment as LabelElement;
}
}
extension LibraryElement2Extension on LibraryElement2 {
LibraryElement get asElement {
return this as LibraryElement;
}
}
extension LibraryElementExtension on LibraryElement {
LibraryElement2 get asElement2 {
return this as LibraryElement2;
}
}
extension LibraryElementOrNullExtension on LibraryElement? {
LibraryElement2? get asElement2 {
return this as LibraryElement2?;
}
}
extension LibraryFragmentExtension on LibraryFragment {
/// Returns a list containing this library fragment and all of its enclosing
/// fragments.
List<LibraryFragment> get withEnclosing2 {
var result = <LibraryFragment>[];
var current = this;
while (true) {
result.add(current);
if (current.enclosingFragment case var enclosing?) {
current = enclosing;
} else {
break;
}
}
return result;
}
}
extension ListOfTypeParameterElement2Extension on List<TypeParameterElement2> {
List<TypeParameterType> instantiateNone() {
return map((e) {
return e.instantiate(
nullabilitySuffix: NullabilitySuffix.none,
);
}).toList();
}
}
extension LocalVariableElementImplExtension on LocalVariableElementImpl {
LocalVariableElementImpl2 get asElement2 {
return element;
}
}
extension MethodElement2Extension on MethodElement2 {
MethodElement get asElement {
if (this case MethodMember member) {
return member;
}
return (this as MethodElementImpl2).lastFragment;
}
}
extension MethodElement2OrMemberExtension on MethodElement2OrMember {
MethodElementOrMember get asElement {
if (this case MethodMember member) {
return member;
}
return (this as MethodElementImpl2).lastFragment;
}
}
extension MethodElementExtension on MethodElement {
MethodElement2 get asElement2 {
return switch (this) {
MethodFragment(:var element) => element,
MethodMember member => member,
_ => throw UnsupportedError('Unsupported type: $runtimeType'),
};
}
}
extension MethodElementImpl2Extension on MethodElementImpl2 {
MethodElementImpl get asElement {
return lastFragment;
}
}
extension MethodElementImplExtension on MethodElementImpl {
MethodElementImpl2 get asElement2 {
return element;
}
}
extension MethodElementOrMemberExtension on MethodElementOrMember {
MethodElement2OrMember get asElement2 {
return switch (this) {
MethodElementImpl(:var element) => element,
MethodMember member => member,
_ => throw UnsupportedError('Unsupported type: $runtimeType'),
};
}
}
extension MixinElementImplExtension on MixinElementImpl {
MixinElementImpl2 get asElement2 {
return element;
}
}
extension ParameterElementExtension on ParameterElement {
FormalParameterElementMixin get asElement2 {
return switch (this) {
ParameterElementImpl(:var element) => element,
ParameterMember member => member,
_ => throw UnsupportedError('Unsupported type: $runtimeType'),
};
}
ParameterElementImpl get declarationImpl {
return declaration as ParameterElementImpl;
}
}
extension ParameterElementImplExtension on ParameterElementImpl {
FormalParameterElementImpl get asElement2 {
return element;
}
}
extension PatternVariableElementImpl2Extension on PatternVariableElementImpl2 {
PatternVariableElementImpl get asElement {
return firstFragment;
}
}
extension PatternVariableElementImplExtension on PatternVariableElementImpl {
PatternVariableElementImpl2 get asElement2 {
return element;
}
}
extension PrefixElement2Extension on PrefixElement2 {
PrefixElement get asElement {
return (this as PrefixElementImpl2).asElement;
}
}
extension PrefixElementExtension on PrefixElement {
PrefixElement2 get asElement2 {
return (this as PrefixElementImpl).element2;
}
}
extension PropertyAccessorElement2Extension on PropertyAccessorElement2 {
PropertyAccessorElement get asElement {
if (this case PropertyAccessorMember member) {
return member;
}
return (this as PropertyAccessorElementImpl2).lastFragment;
}
}
extension PropertyAccessorElement2OrMemberExtension
on PropertyAccessorElement2OrMember {
PropertyAccessorElementOrMember get asElement {
if (this case PropertyAccessorMember member) {
return member;
}
return (this as PropertyAccessorElementImpl2).lastFragment;
}
}
extension PropertyAccessorElementExtension on PropertyAccessorElement {
PropertyAccessorElement2 get asElement2 {
return switch (this) {
PropertyAccessorFragment(:var element) => element,
PropertyAccessorMember member => member,
_ => throw UnsupportedError('Unsupported type: $runtimeType'),
};
}
}
extension PropertyAccessorElementImplExtension on PropertyAccessorElementImpl {
PropertyAccessorElementImpl2 get asElement2 {
return element;
}
}
extension PropertyAccessorElementOrMemberExtension
on PropertyAccessorElementOrMember {
PropertyAccessorElement2OrMember get asElement2 {
return switch (this) {
PropertyAccessorElementImpl(:var element) => element,
PropertyAccessorMember member => member,
_ => throw UnsupportedError('Unsupported type: $runtimeType'),
};
}
}
extension PropertyInducingElementExtension on PropertyInducingElement2 {
bool get definesSetter {
if (isConst) {
return false;
}
if (isFinal) {
return isLate && !hasInitializer;
} else {
return true;
}
}
}
extension SetterElementImplExtension on SetterElementImpl {
PropertyAccessorElementImpl get asElement {
return lastFragment;
}
}
extension TopLevelFunctionElementExtension on TopLevelFunctionElement {
FunctionElement get asElement {
return (this as TopLevelFunctionElementImpl).lastFragment;
}
}
extension TopLevelFunctionElementImplExtension on TopLevelFunctionElementImpl {
FunctionElementImpl get asElement {
return lastFragment;
}
}
extension TopLevelVariableElement2Extension on TopLevelVariableElement2 {
TopLevelVariableElement get asElement {
return baseElement.firstFragment as TopLevelVariableElement;
}
}
extension TopLevelVariableElementExtension on TopLevelVariableElement {
TopLevelVariableElement2 get asElement2 {
return (this as TopLevelVariableElementImpl).element;
}
}
extension TopLevelVariableElementImpl2Extension
on TopLevelVariableElementImpl2 {
TopLevelVariableElementImpl get asElement {
return firstFragment;
}
}
extension TypeAliasElement2Extension on TypeAliasElement2 {
TypeAliasElement get asElement {
return firstFragment as TypeAliasElement;
}
}
extension TypeAliasElementExtension on TypeAliasElement {
TypeAliasElement2 get asElement2 {
return (this as TypeAliasElementImpl).element;
}
}
extension TypeAliasElementImpl2Extension on TypeAliasElementImpl2 {
TypeAliasElementImpl get asElement {
return firstFragment;
}
}
extension TypeAliasElementImplExtension on TypeAliasElementImpl {
TypeAliasElementImpl2 get asElement2 {
return element;
}
}
extension TypeParameterElement2Extension on TypeParameterElement2 {
TypeParameterElement get asElement {
return firstFragment as TypeParameterElement;
}
TypeParameterElementImpl2 freshCopy() {
var fragment = TypeParameterElementImpl(
name3 ?? '',
-1,
);
fragment.bound = bound;
return TypeParameterElementImpl2(
firstFragment: fragment,
name3: name3,
);
}
}
extension TypeParameterElementExtension on TypeParameterElement {
TypeParameterElement2 get asElement2 {
return (this as TypeParameterElementImpl).asElement2;
}
}
extension TypeParameterElementImpl2Extension on TypeParameterElementImpl2 {
TypeParameterElementImpl get asElement {
return firstFragment;
}
}
extension TypeParameterElementImplExtension on TypeParameterElementImpl {
TypeParameterElementImpl2 get asElement2 {
return element;
}
}