Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Unified Diff: pkg/analysis_server/lib/src/computer/computer_overrides.dart

Issue 1632033002: Issue 25542. If an element does not have its own documentation, use the documentation from the over… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: New test cases and tweaks. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analysis_server/lib/src/computer/computer_overrides.dart
diff --git a/pkg/analysis_server/lib/src/computer/computer_overrides.dart b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
index 8a742125b21e28845847ea3b577d685899296f28..4eb93d1bf22a0d97fcfbd1c2a0576a02f9c2dbae 100644
--- a/pkg/analysis_server/lib/src/computer/computer_overrides.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
@@ -5,65 +5,42 @@
library computer.overrides;
import 'package:analysis_server/src/collections.dart';
-import 'package:analysis_server/src/protocol_server.dart';
-import 'package:analyzer/dart/element/element.dart' as engine;
-import 'package:analyzer/dart/element/type.dart' as engine;
+import 'package:analysis_server/src/protocol_server.dart' as proto;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/ast.dart';
/**
+ * Return the elements that the given [element] overrides.
+ */
+OverriddenElements findOverriddenElements(Element element) {
+ if (element?.enclosingElement is ClassElement) {
+ return new _OverriddenElementsFinder(element).find();
+ }
+ return new OverriddenElements(element, <Element>[], <Element>[]);
+}
+
+/**
* A computer for class member overrides in a Dart [CompilationUnit].
*/
class DartUnitOverridesComputer {
- static const List<ElementKind> FIELD_KINDS = const <ElementKind>[
- ElementKind.FIELD,
- ElementKind.GETTER,
- ElementKind.SETTER
- ];
-
- static const List<ElementKind> GETTER_KINDS = const <ElementKind>[
- ElementKind.FIELD,
- ElementKind.GETTER
- ];
-
- static const List<ElementKind> METHOD_KINDS = const <ElementKind>[
- ElementKind.METHOD
- ];
-
- static const List<ElementKind> SETTER_KINDS = const <ElementKind>[
- ElementKind.FIELD,
- ElementKind.SETTER
- ];
-
final CompilationUnit _unit;
-
- final List<Override> _overrides = <Override>[];
- engine.ClassElement _currentClass;
+ final List<proto.Override> _overrides = <proto.Override>[];
DartUnitOverridesComputer(this._unit);
/**
* Returns the computed occurrences, not `null`.
*/
- List<Override> compute() {
+ List<proto.Override> compute() {
for (CompilationUnitMember unitMember in _unit.declarations) {
if (unitMember is ClassDeclaration) {
- _currentClass = unitMember.element;
for (ClassMember classMember in unitMember.members) {
if (classMember is MethodDeclaration) {
if (classMember.isStatic) {
continue;
}
- SimpleIdentifier name = classMember.name;
- List<ElementKind> kinds;
- if (classMember.isGetter) {
- kinds = GETTER_KINDS;
- } else if (classMember.isSetter) {
- kinds = SETTER_KINDS;
- } else {
- kinds = METHOD_KINDS;
- }
- new _SingleOverrideComputer(_currentClass, name, kinds)
- .addOverrideTo(_overrides);
+ _addOverride(classMember.name);
}
if (classMember is FieldDeclaration) {
if (classMember.isStatic) {
@@ -71,9 +48,7 @@ class DartUnitOverridesComputer {
}
List<VariableDeclaration> fields = classMember.fields.variables;
for (VariableDeclaration field in fields) {
- SimpleIdentifier name = field.name;
- new _SingleOverrideComputer(_currentClass, name, FIELD_KINDS)
- .addOverrideTo(_overrides);
+ _addOverride(field.name);
}
}
}
@@ -81,105 +56,171 @@ class DartUnitOverridesComputer {
}
return _overrides;
}
-}
-
-/**
- * Computer for [Override] for a single declaration.
- */
-class _SingleOverrideComputer {
- final engine.LibraryElement currentLibrary;
- final engine.ClassElement currentClass;
- final SimpleIdentifier node;
- final String name;
- final List<ElementKind> kinds;
-
- _SingleOverrideComputer(
- engine.ClassElement currentClass, SimpleIdentifier node, this.kinds)
- : currentClass = currentClass,
- currentLibrary = currentClass.library,
- node = node,
- name = node.name;
/**
- * Add a new [Override] for this declaration to the given [overrides].
+ * Add a new [Override] for the declaration with the given name [node].
*/
- void addOverrideTo(List<Override> overrides) {
- // super
- engine.Element superEngineElement;
- {
- engine.InterfaceType superType = currentClass.supertype;
- if (superType != null) {
- superEngineElement = _lookupMember(superType.element);
- }
- }
- // interfaces
- Set<engine.Element> interfaceEngineElements = new Set<engine.Element>();
- _addInterfaceOverrides(interfaceEngineElements, currentClass.type, false,
- new Set<engine.InterfaceType>());
- interfaceEngineElements.remove(superEngineElement);
- // is there any override?
- if (superEngineElement != null || interfaceEngineElements.isNotEmpty) {
- OverriddenMember superMember = superEngineElement != null
- ? newOverriddenMember_fromEngine(superEngineElement)
+ void _addOverride(SimpleIdentifier node) {
+ Element element = node.staticElement;
+ OverriddenElements overridesResult =
+ new _OverriddenElementsFinder(element).find();
+ List<Element> superElements = overridesResult.superElements;
+ List<Element> interfaceElements = overridesResult.interfaceElements;
+ if (superElements.isNotEmpty || interfaceElements.isNotEmpty) {
+ proto.OverriddenMember superMember = superElements.isNotEmpty
+ ? proto.newOverriddenMember_fromEngine(superElements.first)
: null;
- List<OverriddenMember> interfaceMembers = interfaceEngineElements
- .map((member) => newOverriddenMember_fromEngine(member))
+ List<proto.OverriddenMember> interfaceMembers = interfaceElements
+ .map((member) => proto.newOverriddenMember_fromEngine(member))
.toList();
- overrides.add(new Override(node.offset, node.length,
+ _overrides.add(new proto.Override(node.offset, node.length,
superclassMember: superMember,
interfaceMembers: nullIfEmpty(interfaceMembers)));
}
}
+}
- void _addInterfaceOverrides(
- Set<engine.Element> elements,
- engine.InterfaceType type,
- bool checkType,
- Set<engine.InterfaceType> visited) {
+/**
+ * The container with elements that a class member overrides.
+ */
+class OverriddenElements {
+ /**
+ * The element that overrides other class members.
+ */
+ final Element element;
+
+ /**
+ * The elements that [element] overrides and which is defined in a class that
+ * is a superclass of the class that defines [element].
+ */
+ final List<Element> superElements;
+
+ /**
+ * The elements that [element] overrides and which is defined in a class that
+ * which is implemented by the class that defines [element].
+ */
+ final List<Element> interfaceElements;
+
+ OverriddenElements(this.element, this.superElements, this.interfaceElements);
+}
+
+class _OverriddenElementsFinder {
+ static const List<ElementKind> FIELD_KINDS = const <ElementKind>[
+ ElementKind.FIELD,
+ ElementKind.GETTER,
+ ElementKind.SETTER
+ ];
+
+ static const List<ElementKind> GETTER_KINDS = const <ElementKind>[
+ ElementKind.FIELD,
+ ElementKind.GETTER
+ ];
+
+ static const List<ElementKind> METHOD_KINDS = const <ElementKind>[
+ ElementKind.METHOD
+ ];
+
+ static const List<ElementKind> SETTER_KINDS = const <ElementKind>[
+ ElementKind.FIELD,
+ ElementKind.SETTER
+ ];
+
+ Element _seed;
+ LibraryElement _library;
+ ClassElement _class;
+ String _name;
+ List<ElementKind> _kinds;
+
+ List<Element> _superElements = <Element>[];
+ List<Element> _interfaceElements = <Element>[];
+ Set<InterfaceType> _visited = new Set<InterfaceType>();
+
+ _OverriddenElementsFinder(Element seed) {
+ _seed = seed;
+ _class = seed.enclosingElement;
+ _library = _class.library;
+ _name = seed.displayName;
+ if (seed is MethodElement) {
+ _kinds = METHOD_KINDS;
+ } else if (seed is PropertyAccessorElement) {
+ _kinds = seed.isGetter ? GETTER_KINDS : SETTER_KINDS;
+ } else {
+ _kinds = FIELD_KINDS;
+ }
+ }
+
+ /**
+ * Add the [OverriddenElements] for this element.
+ */
+ OverriddenElements find() {
+ _visited.clear();
+ _addSuperOverrides(_class.supertype);
+ _visited.clear();
+ _addInterfaceOverrides(_class.type, false);
+ _superElements.forEach(_interfaceElements.remove);
+ return new OverriddenElements(_seed, _superElements, _interfaceElements);
+ }
+
+ void _addInterfaceOverrides(InterfaceType type, bool checkType) {
if (type == null) {
return;
}
- if (!visited.add(type)) {
+ if (!_visited.add(type)) {
return;
}
- // check type
+ // this type
if (checkType) {
- engine.Element element = _lookupMember(type.element);
- if (element != null) {
- elements.add(element);
- return;
+ Element element = _lookupMember(type.element);
+ if (element != null && !_interfaceElements.contains(element)) {
+ _interfaceElements.add(element);
}
}
- // check interfaces
- for (engine.InterfaceType interfaceType in type.interfaces) {
- _addInterfaceOverrides(elements, interfaceType, true, visited);
+ // interfaces
+ for (InterfaceType interfaceType in type.interfaces) {
+ _addInterfaceOverrides(interfaceType, true);
}
- // check super
- _addInterfaceOverrides(elements, type.superclass, checkType, visited);
+ // super
+ _addInterfaceOverrides(type.superclass, checkType);
+ }
+
+ void _addSuperOverrides(InterfaceType type) {
+ if (type == null) {
+ return;
+ }
+ if (!_visited.add(type)) {
+ return;
+ }
+ // this type
+ Element element = _lookupMember(type.element);
+ if (element != null && !_superElements.contains(element)) {
+ _superElements.add(element);
+ }
+ // super
+ _addSuperOverrides(type.superclass);
}
- engine.Element _lookupMember(engine.ClassElement classElement) {
+ Element _lookupMember(ClassElement classElement) {
if (classElement == null) {
return null;
}
- engine.Element member;
+ Element member;
// method
- if (kinds.contains(ElementKind.METHOD)) {
- member = classElement.lookUpMethod(name, currentLibrary);
+ if (_kinds.contains(ElementKind.METHOD)) {
+ member = classElement.lookUpMethod(_name, _library);
if (member != null) {
return member;
}
}
// getter
- if (kinds.contains(ElementKind.GETTER)) {
- member = classElement.lookUpGetter(name, currentLibrary);
+ if (_kinds.contains(ElementKind.GETTER)) {
+ member = classElement.lookUpGetter(_name, _library);
if (member != null) {
return member;
}
}
// setter
- if (kinds.contains(ElementKind.SETTER)) {
- member = classElement.lookUpSetter(name + '=', currentLibrary);
+ if (_kinds.contains(ElementKind.SETTER)) {
+ member = classElement.lookUpSetter(_name + '=', _library);
if (member != null) {
return member;
}
« no previous file with comments | « pkg/analysis_server/lib/src/computer/computer_hover.dart ('k') | pkg/analysis_server/test/analysis/get_hover_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698