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

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: 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 non-synthetic children of the given [ClassElement].
19 *
20 * Includes: fields, accessors and methods.
21 * Excludes: constructors and synthetic elements.
22 */
23 List<Element> getClassMembers(ClassElement clazz, [String name]) {
24 List<Element> members = <Element>[];
25 clazz.accept(new _ElementVisitorAdapter((Element element) {
Brian Wilkerson 2014/07/15 19:56:16 If you used 'visitChildren' instead of 'accept' yo
scheglov 2014/07/15 20:30:12 Done.
26 if (element == clazz) {
27 return true;
28 }
29 if (element.isSynthetic) {
30 return false;
31 }
32 if (element is ConstructorElement) {
33 return false;
34 }
35 if (name != null && element.displayName != name) {
36 return false;
37 }
38 if (element is ExecutableElement) {
39 members.add(element);
40 }
41 if (element is FieldElement) {
42 members.add(element);
43 }
44 return false;
45 }));
46 return members;
47 }
48
49
50 /**
51 * Returns direct children of [parent].
52 */
53 List<Element> getChildren(Element parent, [String name]) {
54 List<Element> children = <Element>[];
55 parent.accept(new _ElementVisitorAdapter((Element element) {
Brian Wilkerson 2014/07/15 19:56:16 If you used 'visitChildren' instead of 'accept' yo
scheglov 2014/07/15 20:30:12 Done.
56 if (element == parent) {
57 return true;
58 } else {
59 if (name == null || element.displayName == name) {
60 children.add(element);
61 }
62 return false;
63 }
64 }));
65 return children;
66 }
67
68
69 /**
70 * Returns a [Set] with direct subclasses of [seed].
71 */
72 Future<Set<ClassElement>> getDirectSubClasses(SearchEngine searchEngine,
73 ClassElement seed) {
74 return searchEngine.searchSubtypes(seed).then((List<SearchMatch> matches) {
75 Set<ClassElement> subClasses = new HashSet<ClassElement>();
76 for (SearchMatch match in matches) {
77 ClassElement subClass = match.element;
78 if (subClass.context == seed.context) {
79 subClasses.add(subClass);
80 }
81 }
82 return subClasses;
83 });
84 }
85
86
87 /**
88 * Returns a [Set] with all direct and indirect subclasses of [seed].
89 */
90 Future<Set<ClassElement>> getSubClasses(SearchEngine searchEngine,
91 ClassElement seed) {
92 Set<ClassElement> subs = new HashSet<ClassElement>();
93 // prepare queue
94 List<ClassElement> queue = new List<ClassElement>();
95 queue.add(seed);
96 // schedule subclasss search
97 addSubClasses() {
98 // queue is empty, done
99 if (queue.isEmpty) {
100 subs.remove(seed);
101 return subs;
102 }
103 // add direct subclasses of the next class
104 while (true) {
105 ClassElement clazz = queue.removeLast();
106 if (subs.add(clazz)) {
107 return getDirectSubClasses(searchEngine, clazz).then((directSubs) {
108 queue.addAll(directSubs);
109 return new Future(addSubClasses);
110 });
111 }
112 }
113 }
114 return new Future(addSubClasses);
115 }
116
117
118 /**
119 * @return all implementations of the given {@link ClassMemberElement} is its su perclasses and
120 * their subclasses.
121 */
122 Future<Set<ClassMemberElement>> getHierarchyMembers(SearchEngine searchEngine,
123 ClassMemberElement member) {
124 Set<ClassMemberElement> result = new HashSet<ClassMemberElement>();
125 // constructor
126 if (member is ConstructorElement) {
127 result.add(member);
128 return new Future.value(result);
129 }
130 // method, field, etc
131 String name = member.displayName;
132 ClassElement memberClass = member.enclosingElement;
133 List<Future> futures = <Future>[];
134 Set<ClassElement> searchClasses = getSuperClasses(memberClass);
135 searchClasses.add(memberClass);
136 for (ClassElement superClass in searchClasses) {
137 // ignore if super- class does not declare member
138 if (getClassMembers(superClass, name).isEmpty) {
139 continue;
140 }
141 // check all sub- classes
142 var subClassFuture = getSubClasses(searchEngine, superClass);
143 var membersFuture = subClassFuture.then((Set<ClassElement> subClasses) {
144 subClasses.add(superClass);
145 for (ClassElement subClass in subClasses) {
146 List<Element> subClassMembers = getChildren(subClass, name);
147 for (Element member in subClassMembers) {
148 if (member is ClassMemberElement) {
149 result.add(member);
150 }
151 }
152 }
153 });
154 futures.add(membersFuture);
155 }
156 return Future.wait(futures).then((_) {
157 return result;
158 });
159 }
160
161
162 /**
163 * Returns a [Set] with all direct and indirect superclasses of [seed].
164 */
165 Set<ClassElement> getSuperClasses(ClassElement seed) {
166 Set<ClassElement> result = new HashSet<ClassElement>();
167 // prepare queue
168 List<ClassElement> queue = new List<ClassElement>();
169 queue.add(seed);
170 // process queue
171 while (!queue.isEmpty) {
172 ClassElement current = queue.removeLast();
173 // add if not checked already
174 if (!result.add(current)) {
175 continue;
176 }
177 // append supertype
178 {
179 InterfaceType superType = current.supertype;
180 if (superType != null) {
181 queue.add(superType.element);
182 }
183 }
184 // append interfaces
185 for (InterfaceType intf in current.interfaces) {
186 queue.add(intf.element);
187 }
188 }
189 // we don't need "seed" itself
190 result.remove(seed);
191 return result;
192 }
193
194
195 typedef bool ElementProcessor(Element element);
196
197 /**
198 * A [GeneralizingElementVisitor] that adapter for [ElementProcessor].
199 */
200 class _ElementVisitorAdapter extends GeneralizingElementVisitor {
201 final ElementProcessor processor;
202
203 _ElementVisitorAdapter(this.processor);
204
205 @override
206 void visitElement(Element element) {
207 bool visitChildren = processor(element);
208 if (visitChildren) {
209 super.visitElement(element);
210 }
211 }
212 }
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