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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart

Issue 119913002: Align source mirrors with runtime mirrors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years 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
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library mirrors_util; 5 library mirrors_util;
6 6
7 import 'dart:collection' show Queue, IterableBase; 7 import 'dart:collection' show Queue, IterableBase;
8 8
9 // TODO(rnystrom): Use "package:" URL (#4968). 9 import 'source_mirrors.dart';
10 import 'mirrors.dart';
11 10
12 //------------------------------------------------------------------------------ 11 //------------------------------------------------------------------------------
13 // Utility functions for using the Mirror API 12 // Utility functions for using the Mirror API
14 //------------------------------------------------------------------------------ 13 //------------------------------------------------------------------------------
15 14
15 String nameOf(DeclarationMirror mirror) =>
16 MirrorSystem.getName(mirror.simpleName);
17
18 String qualifiedNameOf(DeclarationMirror mirror) =>
19 MirrorSystem.getName(mirror.qualifiedName);
20
21 // TODO(johnniwinther): Handle private names.
22 Symbol symbolOf(String name, LibraryMirror library) => new Symbol(name);
16 23
17 /** 24 /**
18 * Return the display name for [mirror]. 25 * Return the display name for [mirror].
19 * 26 *
20 * The display name is the normal representation of the entity name. In most 27 * The display name is the normal representation of the entity name. In most
21 * cases the display name is the simple name, but for a setter 'foo=' the 28 * cases the display name is the simple name, but for a setter 'foo=' the
22 * display name is simply 'foo' and for the unary minus operator the display 29 * display name is simply 'foo' and for the unary minus operator the display
23 * name is 'operator -'. For 'dart:' libraries the display name is the URI and 30 * name is 'operator -'. For 'dart:' libraries the display name is the URI and
24 * not the library name, for instance 'dart:core' instead of 'dart.core'. 31 * not the library name, for instance 'dart:core' instead of 'dart.core'.
25 * 32 *
26 * The display name is not unique. 33 * The display name is not unique.
27 */ 34 */
28 String displayName(DeclarationMirror mirror) { 35 String displayName(DeclarationMirror mirror) {
29 if (mirror is LibraryMirror) { 36 if (mirror is LibraryMirror) {
30 LibraryMirror library = mirror; 37 LibraryMirror library = mirror;
31 if (library.uri.scheme == 'dart') { 38 if (library.uri.scheme == 'dart') {
32 return library.uri.toString(); 39 return library.uri.toString();
33 } 40 }
34 } else if (mirror is MethodMirror) { 41 } else if (mirror is MethodMirror) {
35 MethodMirror methodMirror = mirror; 42 String simpleName = nameOf(mirror);
36 String simpleName = methodMirror.simpleName; 43 if (mirror.isSetter) {
37 if (methodMirror.isSetter) {
38 // Remove trailing '='. 44 // Remove trailing '='.
39 return simpleName.substring(0, simpleName.length-1); 45 return simpleName.substring(0, simpleName.length-1);
40 } else if (methodMirror.isOperator) { 46 } else if (mirror.isOperator) {
41 return 'operator ${operatorName(methodMirror)}'; 47 return 'operator ${operatorName(mirror)}';
42 } else if (methodMirror.isConstructor) { 48 } else if (mirror.isConstructor) {
43 String className = displayName(methodMirror.owner); 49 String className = displayName(mirror.owner);
44 if (simpleName == '') { 50 if (simpleName == '') {
45 return className; 51 return className;
46 } else { 52 } else {
47 return '$className.$simpleName'; 53 return '$className.$simpleName';
48 } 54 }
49 } 55 }
50 } 56 }
51 return mirror.simpleName; 57 return MirrorSystem.getName(mirror.simpleName);
52 } 58 }
53 59
54 /** 60 /**
55 * Returns the operator name if [methodMirror] is an operator method, 61 * Returns the operator name if [methodMirror] is an operator method,
56 * for instance [:'<':] for [:operator <:] and [:'-':] for the unary minus 62 * for instance [:'<':] for [:operator <:] and [:'-':] for the unary minus
57 * operator. Return [:null:] if [methodMirror] is not an operator method. 63 * operator. Return [:null:] if [methodMirror] is not an operator method.
58 */ 64 */
59 String operatorName(MethodMirror methodMirror) { 65 String operatorName(MethodMirror methodMirror) {
60 String simpleName = methodMirror.simpleName;
61 if (methodMirror.isOperator) { 66 if (methodMirror.isOperator) {
62 if (simpleName == Mirror.UNARY_MINUS) { 67 if (methodMirror.simpleName == const Symbol('unary-')) {
63 return '-'; 68 return '-';
64 } else { 69 } else {
65 return simpleName; 70 return nameOf(methodMirror);
66 } 71 }
67 } 72 }
68 return null; 73 return null;
69 } 74 }
70 75
71 /** 76 /**
72 * Returns an iterable over the type declarations directly inheriting from 77 * Returns an iterable over the type declarations directly inheriting from
73 * the declaration of this type. 78 * the declaration of [type] within [mirrors].
74 */ 79 */
75 Iterable<ClassMirror> computeSubdeclarations(ClassMirror type) { 80 Iterable<ClassMirror> computeSubdeclarations(MirrorSystem mirrors,
81 ClassMirror type) {
76 type = type.originalDeclaration; 82 type = type.originalDeclaration;
77 var subtypes = <ClassMirror>[]; 83 var subtypes = <ClassMirror>[];
78 type.mirrors.libraries.forEach((_, library) { 84 mirrors.libraries.forEach((_, library) {
79 for (ClassMirror otherType in library.classes.values) { 85 library.declarations.values
86 .where((mirror) => mirror is ClassMirror)
87 .forEach((ClassMirror otherType) {
80 var superClass = otherType.superclass; 88 var superClass = otherType.superclass;
81 if (superClass != null) { 89 if (superClass != null) {
82 superClass = superClass.originalDeclaration; 90 superClass = superClass.originalDeclaration;
83 if (type.library == superClass.library) { 91 if (superClass == type) {
84 if (superClass == type) { 92 subtypes.add(otherType);
85 subtypes.add(otherType);
86 }
87 } 93 }
88 } 94 }
89 final superInterfaces = otherType.superinterfaces; 95 final superInterfaces = otherType.superinterfaces;
90 for (ClassMirror superInterface in superInterfaces) { 96 for (ClassMirror superInterface in superInterfaces) {
91 superInterface = superInterface.originalDeclaration; 97 superInterface = superInterface.originalDeclaration;
92 if (type.library == superInterface.library) { 98 if (superInterface == type) {
93 if (superInterface == type) { 99 subtypes.add(otherType);
94 subtypes.add(otherType);
95 }
96 } 100 }
97 } 101 }
98 } 102 });
99 }); 103 });
100 return subtypes; 104 return subtypes;
101 } 105 }
102 106
103 LibraryMirror findLibrary(MemberMirror member) {
104 DeclarationMirror owner = member.owner;
105 if (owner is LibraryMirror) {
106 return owner;
107 } else if (owner is TypeMirror) {
108 TypeMirror mirror = owner;
109 return mirror.library;
110 }
111 throw new Exception('Unexpected owner: ${owner}');
112 }
113
114 class HierarchyIterable extends IterableBase<ClassMirror> { 107 class HierarchyIterable extends IterableBase<ClassMirror> {
115 final bool includeType; 108 final bool includeType;
116 final ClassMirror type; 109 final ClassMirror type;
117 110
118 HierarchyIterable(this.type, {bool includeType}) 111 HierarchyIterable(this.type, {bool includeType})
119 : this.includeType = includeType; 112 : this.includeType = includeType;
120 113
121 Iterator<ClassMirror> get iterator => 114 Iterator<ClassMirror> get iterator =>
122 new HierarchyIterator(type, includeType: includeType); 115 new HierarchyIterator(type, includeType: includeType);
123 } 116 }
(...skipping 15 matching lines...) Expand all
139 HierarchyIterator(ClassMirror type, {bool includeType}) { 132 HierarchyIterator(ClassMirror type, {bool includeType}) {
140 if (includeType) { 133 if (includeType) {
141 queue.add(type); 134 queue.add(type);
142 } else { 135 } else {
143 push(type); 136 push(type);
144 } 137 }
145 } 138 }
146 139
147 ClassMirror push(ClassMirror type) { 140 ClassMirror push(ClassMirror type) {
148 if (type.superclass != null) { 141 if (type.superclass != null) {
149 if (type.superclass.isObject) { 142 if (isObject(type.superclass)) {
150 object = type.superclass; 143 object = type.superclass;
151 } else { 144 } else {
152 queue.addFirst(type.superclass); 145 queue.addFirst(type.superclass);
153 } 146 }
154 } 147 }
155 queue.addAll(type.superinterfaces); 148 queue.addAll(type.superinterfaces);
156 return type; 149 return type;
157 } 150 }
158 151
159 ClassMirror get current => _current; 152 ClassMirror get current => _current;
160 153
161 bool moveNext() { 154 bool moveNext() {
162 _current = null; 155 _current = null;
163 if (queue.isEmpty) { 156 if (queue.isEmpty) {
164 if (object == null) return false; 157 if (object == null) return false;
165 _current = object; 158 _current = object;
166 object = null; 159 object = null;
167 return true; 160 return true;
168 } else { 161 } else {
169 _current = push(queue.removeFirst()); 162 _current = push(queue.removeFirst());
170 return true; 163 return true;
171 } 164 }
172 } 165 }
173 } 166 }
174 167
168 LibraryMirror getLibrary(DeclarationMirror declaration) {
169 while (declaration != null && declaration is! LibraryMirror) {
170 declaration = declaration.owner;
171 }
172 return declaration;
173 }
174
175 Iterable<DeclarationMirror> membersOf(
176 Map<Symbol, DeclarationMirror> declarations) {
177 return declarations.values.where(
178 (mirror) => mirror is MethodMirror || mirror is VariableMirror);
179 }
180
181 Iterable<TypeMirror> classesOf(
182 Map<Symbol, DeclarationMirror> declarations) {
183 return declarations.values.where((mirror) => mirror is ClassMirror);
184 }
185
186 Iterable<TypeMirror> typesOf(
187 Map<Symbol, DeclarationMirror> declarations) {
188 return declarations.values.where((mirror) => mirror is TypeMirror);
189 }
190
191 Iterable<MethodMirror> methodsOf(
192 Map<Symbol, DeclarationMirror> declarations) {
193 return declarations.values.where(
194 (mirror) => mirror is MethodMirror && mirror.isRegularMethod);
195 }
196
197 Iterable<MethodMirror> constructorsOf(
198 Map<Symbol, DeclarationMirror> declarations) {
199 return declarations.values.where(
200 (mirror) => mirror is MethodMirror && mirror.isConstructor);
201 }
202
203 Iterable<MethodMirror> settersOf(
204 Map<Symbol, DeclarationMirror> declarations) {
205 return declarations.values.where(
206 (mirror) => mirror is MethodMirror && mirror.isSetter);
207 }
208
209 Iterable<MethodMirror> gettersOf(
210 Map<Symbol, DeclarationMirror> declarations) {
211 return declarations.values.where(
212 (mirror) => mirror is MethodMirror && mirror.isGetter);
213 }
214
215 Iterable<VariableMirror> variablesOf(
216 Map<Symbol, DeclarationMirror> declarations) {
217 return declarations.values.where((mirror) => mirror is VariableMirror);
218 }
219
220
221
222 bool isObject(TypeMirror mirror) =>
223 mirror is ClassMirror && mirror.superclass == null;
224
175 bool isMixinApplication(Mirror mirror) { 225 bool isMixinApplication(Mirror mirror) {
176 return mirror is ClassMirror && mirror.mixin != mirror; 226 return mirror is ClassMirror && mirror.mixin != mirror;
177 } 227 }
178 228
179 /** 229 /**
180 * Returns the superclass of [cls] skipping unnamed mixin applications. 230 * Returns the superclass of [cls] skipping unnamed mixin applications.
181 * 231 *
182 * For instance, for all of the following definitions this method returns [:B:]. 232 * For instance, for all of the following definitions this method returns [:B:].
183 * 233 *
184 * class A extends B {} 234 * class A extends B {}
185 * class A extends B with C1, C2 {} 235 * class A extends B with C1, C2 {}
186 * class A extends B implements D1, D2 {} 236 * class A extends B implements D1, D2 {}
187 * class A extends B with C1, C2 implements D1, D2 {} 237 * class A extends B with C1, C2 implements D1, D2 {}
188 * class A = B with C1, C2; 238 * class A = B with C1, C2;
189 * abstract class A = B with C1, C2 implements D1, D2; 239 * abstract class A = B with C1, C2 implements D1, D2;
190 */ 240 */
191 ClassMirror getSuperclass(ClassMirror cls) { 241 ClassSourceMirror getSuperclass(ClassSourceMirror cls) {
192 ClassMirror superclass = cls.superclass; 242 ClassSourceMirror superclass = cls.superclass;
193 while (isMixinApplication(superclass) && superclass.isNameSynthetic) { 243 while (isMixinApplication(superclass) && superclass.isNameSynthetic) {
194 superclass = superclass.superclass; 244 superclass = superclass.superclass;
195 } 245 }
196 return superclass; 246 return superclass;
197 } 247 }
198 248
199 /** 249 /**
200 * Returns the mixins directly applied to [cls]. 250 * Returns the mixins directly applied to [cls].
201 * 251 *
202 * For instance, for all of the following definitions this method returns 252 * For instance, for all of the following definitions this method returns
203 * [:C1, C2:]. 253 * [:C1, C2:].
204 * 254 *
205 * class A extends B with C1, C2 {} 255 * class A extends B with C1, C2 {}
206 * class A extends B with C1, C2 implements D1, D2 {} 256 * class A extends B with C1, C2 implements D1, D2 {}
207 * class A = B with C1, C2; 257 * class A = B with C1, C2;
208 * abstract class A = B with C1, C2 implements D1, D2; 258 * abstract class A = B with C1, C2 implements D1, D2;
209 */ 259 */
210 Iterable<ClassMirror> getAppliedMixins(ClassMirror cls) { 260 Iterable<ClassSourceMirror> getAppliedMixins(ClassSourceMirror cls) {
211 List<ClassMirror> mixins = <ClassMirror>[]; 261 List<ClassSourceMirror> mixins = <ClassSourceMirror>[];
212 ClassMirror superclass = cls.superclass; 262 ClassSourceMirror superclass = cls.superclass;
213 while (isMixinApplication(superclass) && superclass.isNameSynthetic) { 263 while (isMixinApplication(superclass) && superclass.isNameSynthetic) {
214 mixins.add(superclass.mixin); 264 mixins.add(superclass.mixin);
215 superclass = superclass.superclass; 265 superclass = superclass.superclass;
216 } 266 }
217 if (mixins.length > 1) { 267 if (mixins.length > 1) {
218 mixins = new List<ClassMirror>.from(mixins.reversed); 268 mixins = new List<ClassSourceMirror>.from(mixins.reversed);
219 } 269 }
220 if (isMixinApplication(cls)) { 270 if (isMixinApplication(cls)) {
221 mixins.add(cls.mixin); 271 mixins.add(cls.mixin);
222 } 272 }
223 return mixins; 273 return mixins;
224 } 274 }
225 275
226 /** 276 /**
227 * Returns the superinterfaces directly and explicitly implemented by [cls]. 277 * Returns the superinterfaces directly and explicitly implemented by [cls].
228 * 278 *
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 * If [name] is of the form 'a.b.c', 'a' is looked up in the scope of 349 * If [name] is of the form 'a.b.c', 'a' is looked up in the scope of
300 * [declaration] and if unresolved 'a.b' is looked in the scope of 350 * [declaration] and if unresolved 'a.b' is looked in the scope of
301 * [declaration]. Each identifier of the remaining suffix, 'c' or 'b.c', is 351 * [declaration]. Each identifier of the remaining suffix, 'c' or 'b.c', is
302 * then looked up in the local scope of the previous result. 352 * then looked up in the local scope of the previous result.
303 * 353 *
304 * For instance, assumming that [:Iterable:] is imported into the scope of 354 * For instance, assumming that [:Iterable:] is imported into the scope of
305 * [declaration] via the prefix 'col', 'col.Iterable.E' finds the type 355 * [declaration] via the prefix 'col', 'col.Iterable.E' finds the type
306 * variable of [:Iterable:] and 'col.Iterable.contains.element' finds the 356 * variable of [:Iterable:] and 'col.Iterable.contains.element' finds the
307 * [:element:] parameter of the [:contains:] method on [:Iterable:]. 357 * [:element:] parameter of the [:contains:] method on [:Iterable:].
308 */ 358 */
309 DeclarationMirror lookupQualifiedInScope(DeclarationMirror declaration, 359 DeclarationMirror lookupQualifiedInScope(DeclarationSourceMirror declaration,
310 String name) { 360 String name) {
311 // TODO(11653): Support lookup of constructors using the [:new Foo:] 361 // TODO(11653): Support lookup of constructors using the [:new Foo:]
312 // syntax. 362 // syntax.
313 int offset = 1; 363 int offset = 1;
314 List<String> parts = name.split('.'); 364 List<String> parts = name.split('.');
315 DeclarationMirror result = declaration.lookupInScope(parts[0]); 365 DeclarationMirror result = declaration.lookupInScope(parts[0]);
316 if (result == null && parts.length > 1) { 366 if (result == null && parts.length > 1) {
317 // Try lookup of `prefix.id`. 367 // Try lookup of `prefix.id`.
318 result = declaration.lookupInScope('${parts[0]}.${parts[1]}'); 368 result = declaration.lookupInScope('${parts[0]}.${parts[1]}');
319 offset = 2; 369 offset = 2;
320 } 370 }
321 if (result == null) return null; 371 if (result == null) return null;
372 LibraryMirror library = getLibrary(result);
322 while (result != null && offset < parts.length) { 373 while (result != null && offset < parts.length) {
323 result = _lookupLocal(result, parts[offset++]); 374 result = _lookupLocal(result, symbolOf(parts[offset++], library));
324 } 375 }
325 return result; 376 return result;
326 } 377 }
327 378
328 DeclarationMirror _lookupLocal(Mirror mirror, String id) { 379 DeclarationMirror _lookupLocal(Mirror mirror, Symbol id) {
329 DeclarationMirror result; 380 DeclarationMirror result;
330 if (mirror is ContainerMirror) { 381 if (mirror is LibraryMirror) {
331 ContainerMirror containerMirror = mirror;
332 // Try member lookup. 382 // Try member lookup.
333 result = containerMirror.members[id]; 383 result = mirror.declarations[id];
floitsch 2014/01/28 19:21:53 You are already returning from the middle of the s
334 } 384 } else if (mirror is ClassMirror) {
335 if (result != null) return result; 385 // Try member lookup.
336 if (mirror is ClassMirror) { 386 result = mirror.declarations[id];
337 ClassMirror classMirror = mirror; 387 if (result != null) return result;
338 // Try type variables. 388 // Try type variables.
339 result = classMirror.typeVariables.firstWhere( 389 result = mirror.typeVariables.firstWhere(
340 (TypeVariableMirror v) => v.simpleName == id, orElse: () => null); 390 (TypeVariableMirror v) => v.simpleName == id, orElse: () => null);
341 } else if (mirror is MethodMirror) { 391 } else if (mirror is MethodMirror) {
342 MethodMirror methodMirror = mirror; 392 result = mirror.parameters.firstWhere(
343 result = methodMirror.parameters.firstWhere(
344 (ParameterMirror p) => p.simpleName == id, orElse: () => null); 393 (ParameterMirror p) => p.simpleName == id, orElse: () => null);
345 } 394 }
346 return result; 395 return result;
347 396
348 } 397 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698