| // Copyright (c) 2020, 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. | |
| import 'package:analyzer/dart/element/element.dart'; | |
| extension ClassElementExtensions on ClassElement { | |
| /// Return `true` if this element represents the class `LinkedHashSet` from | |
| /// `dart:collection`. | |
| bool get isDartCollectionLinkedHashSet => | |
| name == 'LinkedHashSet' && library.isDartCollection; | |
| /// Return `true` if this element represents the class `Iterable` from | |
| /// `dart:core`. | |
| bool get isDartCoreIterable => name == 'Iterable' && library.isDartCore; | |
| /// Return `true` if this element represents the class `List` from | |
| /// `dart:core`. | |
| bool get isDartCoreList => name == 'List' && library.isDartCore; | |
| /// Return `true` if this element represents the class `Map` from | |
| /// `dart:core`. | |
| bool get isDartCoreMap => name == 'Map' && library.isDartCore; | |
| /// Return `true` if this element represents the class `Set` from | |
| /// `dart:core`. | |
| bool get isDartCoreSet => name == 'Set' && library.isDartCore; | |
| } | |
| extension ElementExtensions on Element { | |
| /// Canonicalizes an element so that field formal parameters map to their | |
| /// fields and property accessors map to their variables. | |
| // TODO(FMorschel): Move this when the occurrences are removed and only LSP is | |
| // supported. | |
| Element? get canonical => switch (this) { | |
| FieldFormalParameterElement(:var field) when field?.name == name => | |
| field?.baseElement, | |
| PropertyAccessorElement(:var variable, :var isOriginVariable) | |
| when isOriginVariable || | |
| variable is FieldElement && | |
| variable.isOriginDeclaringFormalParameter => | |
| variable.baseElement, | |
| _ => baseElement, | |
| }; | |
| /// Whether this element, the enclosing class (if there is one), or | |
| /// the enclosing library, has been annotated with the `@Deprecated()` | |
| /// annotation. | |
| bool get hasOrInheritsDeprecated { | |
| if (isDeprecatedWithKind('use')) { | |
| return true; | |
| } | |
| var ancestor = enclosingElement; | |
| if (ancestor is InterfaceElement) { | |
| if (ancestor.isDeprecatedWithKind('use')) { | |
| return true; | |
| } | |
| ancestor = ancestor.enclosingElement; | |
| } | |
| return ancestor is LibraryElement && ancestor.isDeprecatedWithKind('use'); | |
| } | |
| /// Return this element and all its enclosing elements. | |
| Iterable<Element> get withAncestors sync* { | |
| var current = this; | |
| while (true) { | |
| yield current; | |
| var enclosing = current.enclosingElement; | |
| if (enclosing == null) { | |
| break; | |
| } | |
| current = enclosing; | |
| } | |
| } | |
| } | |
| extension FragmentExtensions on Fragment { | |
| /// Return this fragment and all its enclosing fragment. | |
| Iterable<Fragment> get withAncestors sync* { | |
| var current = this; | |
| while (true) { | |
| yield current; | |
| var enclosing = current.enclosingFragment; | |
| if (enclosing == null) { | |
| break; | |
| } | |
| current = enclosing; | |
| } | |
| } | |
| } | |
| extension LibraryElementExtensions on LibraryElement { | |
| /// Return `true` if this element represents `dart:collection`. | |
| bool get isDartCollection => uri.toString() == 'dart:collection'; | |
| } | |
| extension MethodElementExtensions on MethodElement { | |
| /// Return `true` if this element represents the method `cast` from either | |
| /// `Iterable`, `List`, `Map`, or `Set`. | |
| bool get isCastMethod { | |
| if (name != 'cast') { | |
| return false; | |
| } | |
| var definingClass = enclosingElement; | |
| if (definingClass is! ClassElement) { | |
| return false; | |
| } | |
| return definingClass.isDartCoreIterable || | |
| definingClass.isDartCoreList || | |
| definingClass.isDartCoreMap || | |
| definingClass.isDartCoreSet; | |
| } | |
| } |