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

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

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