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

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: Updated cf. comments + small fix. Created 6 years, 10 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
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 /// Returns `true` if [cls] is declared in a private dart library. 225 /// Returns `true` if [cls] is declared in a private dart library.
176 bool isFromPrivateDartLibrary(ClassMirror cls) { 226 bool isFromPrivateDartLibrary(ClassMirror cls) {
177 if (isMixinApplication(cls)) cls = cls.mixin; 227 if (isMixinApplication(cls)) cls = cls.mixin;
178 var uri = cls.library.uri; 228 var uri = getLibrary(cls).uri;
179 return uri.scheme == 'dart' && uri.path.startsWith('_'); 229 return uri.scheme == 'dart' && uri.path.startsWith('_');
180 } 230 }
181 231
182 /// Returns `true` if [mirror] reflects a mixin application. 232 /// Returns `true` if [mirror] reflects a mixin application.
183 bool isMixinApplication(Mirror mirror) { 233 bool isMixinApplication(Mirror mirror) {
184 return mirror is ClassMirror && mirror.mixin != mirror; 234 return mirror is ClassMirror && mirror.mixin != mirror;
185 } 235 }
186 236
187 /** 237 /**
188 * Returns the superclass of [cls] skipping unnamed mixin applications. 238 * Returns the superclass of [cls] skipping unnamed mixin applications.
189 * 239 *
190 * For instance, for all of the following definitions this method returns [:B:]. 240 * For instance, for all of the following definitions this method returns [:B:].
191 * 241 *
192 * class A extends B {} 242 * class A extends B {}
193 * class A extends B with C1, C2 {} 243 * class A extends B with C1, C2 {}
194 * class A extends B implements D1, D2 {} 244 * class A extends B implements D1, D2 {}
195 * class A extends B with C1, C2 implements D1, D2 {} 245 * class A extends B with C1, C2 implements D1, D2 {}
196 * class A = B with C1, C2; 246 * class A = B with C1, C2;
197 * abstract class A = B with C1, C2 implements D1, D2; 247 * abstract class A = B with C1, C2 implements D1, D2;
198 */ 248 */
199 ClassMirror getSuperclass(ClassMirror cls) { 249 ClassSourceMirror getSuperclass(ClassSourceMirror cls) {
200 ClassMirror superclass = cls.superclass; 250 ClassSourceMirror superclass = cls.superclass;
201 while (isMixinApplication(superclass) && superclass.isNameSynthetic) { 251 while (isMixinApplication(superclass) && superclass.isNameSynthetic) {
202 superclass = superclass.superclass; 252 superclass = superclass.superclass;
203 } 253 }
204 return superclass; 254 return superclass;
205 } 255 }
206 256
207 /** 257 /**
208 * Returns the mixins directly applied to [cls]. 258 * Returns the mixins directly applied to [cls].
209 * 259 *
210 * For instance, for all of the following definitions this method returns 260 * For instance, for all of the following definitions this method returns
211 * [:C1, C2:]. 261 * [:C1, C2:].
212 * 262 *
213 * class A extends B with C1, C2 {} 263 * class A extends B with C1, C2 {}
214 * class A extends B with C1, C2 implements D1, D2 {} 264 * class A extends B with C1, C2 implements D1, D2 {}
215 * class A = B with C1, C2; 265 * class A = B with C1, C2;
216 * abstract class A = B with C1, C2 implements D1, D2; 266 * abstract class A = B with C1, C2 implements D1, D2;
217 */ 267 */
218 Iterable<ClassMirror> getAppliedMixins(ClassMirror cls) { 268 Iterable<ClassSourceMirror> getAppliedMixins(ClassSourceMirror cls) {
219 List<ClassMirror> mixins = <ClassMirror>[]; 269 List<ClassSourceMirror> mixins = <ClassSourceMirror>[];
220 ClassMirror superclass = cls.superclass; 270 ClassSourceMirror superclass = cls.superclass;
221 while (isMixinApplication(superclass) && superclass.isNameSynthetic) { 271 while (isMixinApplication(superclass) && superclass.isNameSynthetic) {
222 mixins.add(superclass.mixin); 272 mixins.add(superclass.mixin);
223 superclass = superclass.superclass; 273 superclass = superclass.superclass;
224 } 274 }
225 if (mixins.length > 1) { 275 if (mixins.length > 1) {
226 mixins = new List<ClassMirror>.from(mixins.reversed); 276 mixins = new List<ClassSourceMirror>.from(mixins.reversed);
227 } 277 }
228 if (isMixinApplication(cls)) { 278 if (isMixinApplication(cls)) {
229 mixins.add(cls.mixin); 279 mixins.add(cls.mixin);
230 } 280 }
231 return mixins; 281 return mixins;
232 } 282 }
233 283
234 /** 284 /**
235 * Returns the superinterfaces directly and explicitly implemented by [cls]. 285 * Returns the superinterfaces directly and explicitly implemented by [cls].
236 * 286 *
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 * If [name] is of the form 'a.b.c', 'a' is looked up in the scope of 357 * If [name] is of the form 'a.b.c', 'a' is looked up in the scope of
308 * [declaration] and if unresolved 'a.b' is looked in the scope of 358 * [declaration] and if unresolved 'a.b' is looked in the scope of
309 * [declaration]. Each identifier of the remaining suffix, 'c' or 'b.c', is 359 * [declaration]. Each identifier of the remaining suffix, 'c' or 'b.c', is
310 * then looked up in the local scope of the previous result. 360 * then looked up in the local scope of the previous result.
311 * 361 *
312 * For instance, assumming that [:Iterable:] is imported into the scope of 362 * For instance, assumming that [:Iterable:] is imported into the scope of
313 * [declaration] via the prefix 'col', 'col.Iterable.E' finds the type 363 * [declaration] via the prefix 'col', 'col.Iterable.E' finds the type
314 * variable of [:Iterable:] and 'col.Iterable.contains.element' finds the 364 * variable of [:Iterable:] and 'col.Iterable.contains.element' finds the
315 * [:element:] parameter of the [:contains:] method on [:Iterable:]. 365 * [:element:] parameter of the [:contains:] method on [:Iterable:].
316 */ 366 */
317 DeclarationMirror lookupQualifiedInScope(DeclarationMirror declaration, 367 DeclarationMirror lookupQualifiedInScope(DeclarationSourceMirror declaration,
318 String name) { 368 String name) {
319 // TODO(11653): Support lookup of constructors using the [:new Foo:] 369 // TODO(11653): Support lookup of constructors using the [:new Foo:]
320 // syntax. 370 // syntax.
321 int offset = 1; 371 int offset = 1;
322 List<String> parts = name.split('.'); 372 List<String> parts = name.split('.');
323 DeclarationMirror result = declaration.lookupInScope(parts[0]); 373 DeclarationMirror result = declaration.lookupInScope(parts[0]);
324 if (result == null && parts.length > 1) { 374 if (result == null && parts.length > 1) {
325 // Try lookup of `prefix.id`. 375 // Try lookup of `prefix.id`.
326 result = declaration.lookupInScope('${parts[0]}.${parts[1]}'); 376 result = declaration.lookupInScope('${parts[0]}.${parts[1]}');
327 offset = 2; 377 offset = 2;
328 } 378 }
329 if (result == null) return null; 379 if (result == null) return null;
380 LibraryMirror library = getLibrary(result);
330 while (result != null && offset < parts.length) { 381 while (result != null && offset < parts.length) {
331 result = _lookupLocal(result, parts[offset++]); 382 result = _lookupLocal(result, symbolOf(parts[offset++], library));
332 } 383 }
333 return result; 384 return result;
334 } 385 }
335 386
336 DeclarationMirror _lookupLocal(Mirror mirror, String id) { 387 DeclarationMirror _lookupLocal(Mirror mirror, Symbol id) {
337 DeclarationMirror result; 388 DeclarationMirror result;
338 if (mirror is ContainerMirror) { 389 if (mirror is LibraryMirror) {
339 ContainerMirror containerMirror = mirror;
340 // Try member lookup. 390 // Try member lookup.
341 result = containerMirror.members[id]; 391 result = mirror.declarations[id];
342 } 392 } else if (mirror is ClassMirror) {
343 if (result != null) return result; 393 // Try member lookup.
344 if (mirror is ClassMirror) { 394 result = mirror.declarations[id];
345 ClassMirror classMirror = mirror; 395 if (result != null) return result;
346 // Try type variables. 396 // Try type variables.
347 result = classMirror.typeVariables.firstWhere( 397 result = mirror.typeVariables.firstWhere(
348 (TypeVariableMirror v) => v.simpleName == id, orElse: () => null); 398 (TypeVariableMirror v) => v.simpleName == id, orElse: () => null);
349 } else if (mirror is MethodMirror) { 399 } else if (mirror is MethodMirror) {
350 MethodMirror methodMirror = mirror; 400 result = mirror.parameters.firstWhere(
351 result = methodMirror.parameters.firstWhere(
352 (ParameterMirror p) => p.simpleName == id, orElse: () => null); 401 (ParameterMirror p) => p.simpleName == id, orElse: () => null);
353 } 402 }
354 return result; 403 return result;
355 404
356 } 405 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698