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

Side by Side Diff: pkg/analysis_services/lib/search/hierarchy.dart

Issue 395623006: Add hierarchy utils and use them in search. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: tweaks Created 6 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information.
7
8 library services.hierarchy;
9
10 import 'dart:async';
11 import 'dart:collection';
12
13 import 'package:analysis_services/search/search_engine.dart';
14 import 'package:analyzer/src/generated/element.dart';
15
16
17 /**
18 * Returns direct children of [parent].
19 */
20 List<Element> getChildren(Element parent, [String name]) {
21 List<Element> children = <Element>[];
22 parent.visitChildren(new _ElementVisitorAdapter((Element element) {
23 if (name == null || element.displayName == name) {
24 children.add(element);
25 }
26 }));
27 return children;
28 }
29
30
31 /**
32 * Returns direct non-synthetic children of the given [ClassElement].
33 *
34 * Includes: fields, accessors and methods.
35 * Excludes: constructors and synthetic elements.
36 */
37 List<Element> getClassMembers(ClassElement clazz, [String name]) {
38 List<Element> members = <Element>[];
39 clazz.visitChildren(new _ElementVisitorAdapter((Element element) {
40 if (element.isSynthetic) {
41 return;
42 }
43 if (element is ConstructorElement) {
44 return;
45 }
46 if (name != null && element.displayName != name) {
47 return;
48 }
49 if (element is ExecutableElement) {
50 members.add(element);
51 }
52 if (element is FieldElement) {
53 members.add(element);
54 }
55 }));
56 return members;
57 }
58
59
60 /**
61 * Returns a [Set] with direct subclasses of [seed].
62 */
63 Future<Set<ClassElement>> getDirectSubClasses(SearchEngine searchEngine,
64 ClassElement seed) {
65 return searchEngine.searchSubtypes(seed).then((List<SearchMatch> matches) {
66 Set<ClassElement> subClasses = new HashSet<ClassElement>();
67 for (SearchMatch match in matches) {
68 ClassElement subClass = match.element;
69 if (subClass.context == seed.context) {
70 subClasses.add(subClass);
71 }
72 }
73 return subClasses;
74 });
75 }
76
77
78 /**
79 * @return all implementations of the given {@link ClassMemberElement} is its su perclasses and
80 * their subclasses.
81 */
82 Future<Set<ClassMemberElement>> getHierarchyMembers(SearchEngine searchEngine,
83 ClassMemberElement member) {
84 Set<ClassMemberElement> result = new HashSet<ClassMemberElement>();
85 // constructor
86 if (member is ConstructorElement) {
87 result.add(member);
88 return new Future.value(result);
89 }
90 // method, field, etc
91 String name = member.displayName;
92 ClassElement memberClass = member.enclosingElement;
93 List<Future> futures = <Future>[];
94 Set<ClassElement> searchClasses = getSuperClasses(memberClass);
95 searchClasses.add(memberClass);
96 for (ClassElement superClass in searchClasses) {
97 // ignore if super- class does not declare member
98 if (getClassMembers(superClass, name).isEmpty) {
99 continue;
100 }
101 // check all sub- classes
102 var subClassFuture = getSubClasses(searchEngine, superClass);
103 var membersFuture = subClassFuture.then((Set<ClassElement> subClasses) {
104 subClasses.add(superClass);
105 for (ClassElement subClass in subClasses) {
106 List<Element> subClassMembers = getChildren(subClass, name);
107 for (Element member in subClassMembers) {
108 if (member is ClassMemberElement) {
109 result.add(member);
110 }
111 }
112 }
113 });
114 futures.add(membersFuture);
115 }
116 return Future.wait(futures).then((_) {
117 return result;
118 });
119 }
120
121
122 /**
123 * Returns a [Set] with all direct and indirect subclasses of [seed].
124 */
125 Future<Set<ClassElement>> getSubClasses(SearchEngine searchEngine,
126 ClassElement seed) {
127 Set<ClassElement> subs = new HashSet<ClassElement>();
128 // prepare queue
129 List<ClassElement> queue = new List<ClassElement>();
130 queue.add(seed);
131 // schedule subclasss search
132 addSubClasses() {
133 // add direct subclasses of the next class
134 while (queue.isNotEmpty) {
135 ClassElement clazz = queue.removeLast();
136 if (subs.add(clazz)) {
137 return getDirectSubClasses(searchEngine, clazz).then((directSubs) {
138 queue.addAll(directSubs);
139 return new Future(addSubClasses);
140 });
141 }
142 }
143 // done
144 subs.remove(seed);
145 return subs;
146 }
147 return new Future(addSubClasses);
148 }
149
150
151 /**
152 * Returns a [Set] with all direct and indirect superclasses of [seed].
153 */
154 Set<ClassElement> getSuperClasses(ClassElement seed) {
155 Set<ClassElement> result = new HashSet<ClassElement>();
156 // prepare queue
157 List<ClassElement> queue = new List<ClassElement>();
158 queue.add(seed);
159 // process queue
160 while (!queue.isEmpty) {
161 ClassElement current = queue.removeLast();
162 // add if not checked already
163 if (!result.add(current)) {
164 continue;
165 }
166 // append supertype
167 {
168 InterfaceType superType = current.supertype;
169 if (superType != null) {
170 queue.add(superType.element);
171 }
172 }
173 // append interfaces
174 for (InterfaceType intf in current.interfaces) {
175 queue.add(intf.element);
176 }
177 }
178 // we don't need "seed" itself
179 result.remove(seed);
180 return result;
181 }
182
183
184 typedef void ElementProcessor(Element element);
185
186 /**
187 * A [GeneralizingElementVisitor] adapter for [ElementProcessor].
188 */
189 class _ElementVisitorAdapter extends GeneralizingElementVisitor {
190 final ElementProcessor processor;
191
192 _ElementVisitorAdapter(this.processor);
193
194 @override
195 void visitElement(Element element) {
196 processor(element);
197 }
198 }
OLDNEW
« no previous file with comments | « pkg/analysis_services/lib/index/local_memory_index.dart ('k') | pkg/analysis_services/lib/search/search_engine.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698