OLD | NEW |
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 import 'source_mirrors.dart'; | 9 import 'source_mirrors.dart'; |
10 | 10 |
(...skipping 24 matching lines...) Expand all Loading... |
35 String displayName(DeclarationMirror mirror) { | 35 String displayName(DeclarationMirror mirror) { |
36 if (mirror is LibraryMirror) { | 36 if (mirror is LibraryMirror) { |
37 LibraryMirror library = mirror; | 37 LibraryMirror library = mirror; |
38 if (library.uri.scheme == 'dart') { | 38 if (library.uri.scheme == 'dart') { |
39 return library.uri.toString(); | 39 return library.uri.toString(); |
40 } | 40 } |
41 } else if (mirror is MethodMirror) { | 41 } else if (mirror is MethodMirror) { |
42 String simpleName = nameOf(mirror); | 42 String simpleName = nameOf(mirror); |
43 if (mirror.isSetter) { | 43 if (mirror.isSetter) { |
44 // Remove trailing '='. | 44 // Remove trailing '='. |
45 return simpleName.substring(0, simpleName.length-1); | 45 return simpleName.substring(0, simpleName.length - 1); |
46 } else if (mirror.isOperator) { | 46 } else if (mirror.isOperator) { |
47 return 'operator ${operatorName(mirror)}'; | 47 return 'operator ${operatorName(mirror)}'; |
48 } else if (mirror.isConstructor) { | 48 } else if (mirror.isConstructor) { |
49 String className = displayName(mirror.owner); | 49 String className = displayName(mirror.owner); |
50 if (simpleName == '') { | 50 if (simpleName == '') { |
51 return className; | 51 return className; |
52 } else { | 52 } else { |
53 return '$className.$simpleName'; | 53 return '$className.$simpleName'; |
54 } | 54 } |
55 } | 55 } |
(...skipping 14 matching lines...) Expand all Loading... |
70 return nameOf(methodMirror); | 70 return nameOf(methodMirror); |
71 } | 71 } |
72 } | 72 } |
73 return null; | 73 return null; |
74 } | 74 } |
75 | 75 |
76 /** | 76 /** |
77 * Returns an iterable over the type declarations directly inheriting from | 77 * Returns an iterable over the type declarations directly inheriting from |
78 * the declaration of [type] within [mirrors]. | 78 * the declaration of [type] within [mirrors]. |
79 */ | 79 */ |
80 Iterable<ClassMirror> computeSubdeclarations(MirrorSystem mirrors, | 80 Iterable<ClassMirror> computeSubdeclarations( |
81 ClassMirror type) { | 81 MirrorSystem mirrors, ClassMirror type) { |
82 type = type.originalDeclaration; | 82 type = type.originalDeclaration; |
83 var subtypes = <ClassMirror>[]; | 83 var subtypes = <ClassMirror>[]; |
84 mirrors.libraries.forEach((_, library) { | 84 mirrors.libraries.forEach((_, library) { |
85 library.declarations.values | 85 library.declarations.values |
86 .where((mirror) => mirror is ClassMirror) | 86 .where((mirror) => mirror is ClassMirror) |
87 .forEach((ClassMirror otherType) { | 87 .forEach((ClassMirror otherType) { |
88 var superClass = otherType.superclass; | 88 var superClass = otherType.superclass; |
89 if (superClass != null) { | 89 if (superClass != null) { |
90 superClass = superClass.originalDeclaration; | 90 superClass = superClass.originalDeclaration; |
91 if (superClass == type) { | 91 if (superClass == type) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 | 167 |
168 LibraryMirror getLibrary(DeclarationMirror declaration) { | 168 LibraryMirror getLibrary(DeclarationMirror declaration) { |
169 while (declaration != null && declaration is! LibraryMirror) { | 169 while (declaration != null && declaration is! LibraryMirror) { |
170 declaration = declaration.owner; | 170 declaration = declaration.owner; |
171 } | 171 } |
172 return declaration; | 172 return declaration; |
173 } | 173 } |
174 | 174 |
175 Iterable<DeclarationMirror> membersOf( | 175 Iterable<DeclarationMirror> membersOf( |
176 Map<Symbol, DeclarationMirror> declarations) { | 176 Map<Symbol, DeclarationMirror> declarations) { |
177 return declarations.values.where( | 177 return declarations.values |
178 (mirror) => mirror is MethodMirror || mirror is VariableMirror); | 178 .where((mirror) => mirror is MethodMirror || mirror is VariableMirror); |
179 } | 179 } |
180 | 180 |
181 Iterable<TypeMirror> classesOf( | 181 Iterable<TypeMirror> classesOf(Map<Symbol, DeclarationMirror> declarations) { |
182 Map<Symbol, DeclarationMirror> declarations) { | |
183 return new _TypeOfIterable<ClassMirror>(declarations.values); | 182 return new _TypeOfIterable<ClassMirror>(declarations.values); |
184 } | 183 } |
185 | 184 |
186 Iterable<TypeMirror> typesOf( | 185 Iterable<TypeMirror> typesOf(Map<Symbol, DeclarationMirror> declarations) { |
187 Map<Symbol, DeclarationMirror> declarations) { | |
188 return new _TypeOfIterable<TypeMirror>(declarations.values); | 186 return new _TypeOfIterable<TypeMirror>(declarations.values); |
189 } | 187 } |
190 | 188 |
191 Iterable<MethodMirror> methodsOf( | 189 Iterable<MethodMirror> methodsOf(Map<Symbol, DeclarationMirror> declarations) { |
192 Map<Symbol, DeclarationMirror> declarations) { | |
193 return anyMethodOf(declarations).where((mirror) => mirror.isRegularMethod); | 190 return anyMethodOf(declarations).where((mirror) => mirror.isRegularMethod); |
194 } | 191 } |
195 | 192 |
196 Iterable<MethodMirror> constructorsOf( | 193 Iterable<MethodMirror> constructorsOf( |
197 Map<Symbol, DeclarationMirror> declarations) { | 194 Map<Symbol, DeclarationMirror> declarations) { |
198 return anyMethodOf(declarations).where((mirror) => mirror.isConstructor); | 195 return anyMethodOf(declarations).where((mirror) => mirror.isConstructor); |
199 } | 196 } |
200 | 197 |
201 Iterable<MethodMirror> settersOf( | 198 Iterable<MethodMirror> settersOf(Map<Symbol, DeclarationMirror> declarations) { |
202 Map<Symbol, DeclarationMirror> declarations) { | |
203 return anyMethodOf(declarations).where((mirror) => mirror.isSetter); | 199 return anyMethodOf(declarations).where((mirror) => mirror.isSetter); |
204 } | 200 } |
205 | 201 |
206 Iterable<MethodMirror> gettersOf( | 202 Iterable<MethodMirror> gettersOf(Map<Symbol, DeclarationMirror> declarations) { |
207 Map<Symbol, DeclarationMirror> declarations) { | |
208 return anyMethodOf(declarations).where((mirror) => mirror.isGetter); | 203 return anyMethodOf(declarations).where((mirror) => mirror.isGetter); |
209 } | 204 } |
210 | 205 |
211 Iterable<MethodMirror> anyMethodOf( | 206 Iterable<MethodMirror> anyMethodOf( |
212 Map<Symbol, DeclarationMirror> declarations) { | 207 Map<Symbol, DeclarationMirror> declarations) { |
213 return new _TypeOfIterable<MethodMirror>(declarations.values); | 208 return new _TypeOfIterable<MethodMirror>(declarations.values); |
214 } | 209 } |
215 | 210 |
216 Iterable<VariableMirror> variablesOf( | 211 Iterable<VariableMirror> variablesOf( |
217 Map<Symbol, DeclarationMirror> declarations) { | 212 Map<Symbol, DeclarationMirror> declarations) { |
218 return new _TypeOfIterable<VariableMirror>(declarations.values); | 213 return new _TypeOfIterable<VariableMirror>(declarations.values); |
219 } | 214 } |
220 | 215 |
221 class _TypeOfIterable<T> extends IterableBase<T> { | 216 class _TypeOfIterable<T> extends IterableBase<T> { |
222 final Iterable _source; | 217 final Iterable _source; |
223 | 218 |
224 _TypeOfIterable(this._source); | 219 _TypeOfIterable(this._source); |
225 | 220 |
226 Iterator<T> get iterator => new _TypeOfIterator<T>(_source.iterator); | 221 Iterator<T> get iterator => new _TypeOfIterator<T>(_source.iterator); |
227 } | 222 } |
228 | 223 |
229 class _TypeOfIterator<T> implements Iterator<T> { | 224 class _TypeOfIterator<T> implements Iterator<T> { |
230 final Iterator _source; | 225 final Iterator _source; |
231 | 226 |
232 T get current => _source.current; | 227 T get current => _source.current; |
233 | 228 |
234 _TypeOfIterator(this._source); | 229 _TypeOfIterator(this._source); |
235 | 230 |
236 bool moveNext() { | 231 bool moveNext() { |
237 while(_source.moveNext()) { | 232 while (_source.moveNext()) { |
238 if (_source.current is T) { | 233 if (_source.current is T) { |
239 return true; | 234 return true; |
240 } | 235 } |
241 } | 236 } |
242 return false; | 237 return false; |
243 } | 238 } |
244 } | 239 } |
245 | 240 |
246 bool isObject(TypeMirror mirror) => | 241 bool isObject(TypeMirror mirror) => |
247 mirror is ClassMirror && mirror.superclass == null; | 242 mirror is ClassMirror && mirror.superclass == null; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 String stripComment(String comment) { | 338 String stripComment(String comment) { |
344 Match match = _singleLineCommentStart.firstMatch(comment); | 339 Match match = _singleLineCommentStart.firstMatch(comment); |
345 if (match != null) { | 340 if (match != null) { |
346 return match[1]; | 341 return match[1]; |
347 } | 342 } |
348 match = _multiLineCommentStartEnd.firstMatch(comment); | 343 match = _multiLineCommentStartEnd.firstMatch(comment); |
349 if (match != null) { | 344 if (match != null) { |
350 comment = match[1]; | 345 comment = match[1]; |
351 var sb = new StringBuffer(); | 346 var sb = new StringBuffer(); |
352 List<String> lines = comment.split('\n'); | 347 List<String> lines = comment.split('\n'); |
353 for (int index = 0 ; index < lines.length ; index++) { | 348 for (int index = 0; index < lines.length; index++) { |
354 String line = lines[index]; | 349 String line = lines[index]; |
355 if (index == 0) { | 350 if (index == 0) { |
356 sb.write(line); // Add the first line unprocessed. | 351 sb.write(line); // Add the first line unprocessed. |
357 continue; | 352 continue; |
358 } | 353 } |
359 sb.write('\n'); | 354 sb.write('\n'); |
360 match = _multiLineCommentLineStart.firstMatch(line); | 355 match = _multiLineCommentLineStart.firstMatch(line); |
361 if (match != null) { | 356 if (match != null) { |
362 sb.write(match[1]); | 357 sb.write(match[1]); |
363 } else if (index < lines.length-1 || !line.trim().isEmpty) { | 358 } else if (index < lines.length - 1 || !line.trim().isEmpty) { |
364 // Do not add the last line if it only contains white space. | 359 // Do not add the last line if it only contains white space. |
365 // This interprets cases like | 360 // This interprets cases like |
366 // /* | 361 // /* |
367 // * Foo | 362 // * Foo |
368 // */ | 363 // */ |
369 // as "\nFoo\n" and not as "\nFoo\n ". | 364 // as "\nFoo\n" and not as "\nFoo\n ". |
370 sb.write(line); | 365 sb.write(line); |
371 } | 366 } |
372 } | 367 } |
373 return sb.toString(); | 368 return sb.toString(); |
374 } | 369 } |
375 throw new ArgumentError('Invalid comment $comment'); | 370 throw new ArgumentError('Invalid comment $comment'); |
376 } | 371 } |
377 | 372 |
378 /** | 373 /** |
379 * Looks up [name] in the scope [declaration]. | 374 * Looks up [name] in the scope [declaration]. |
380 * | 375 * |
381 * If [name] is of the form 'a.b.c', 'a' is looked up in the scope of | 376 * If [name] is of the form 'a.b.c', 'a' is looked up in the scope of |
382 * [declaration] and if unresolved 'a.b' is looked in the scope of | 377 * [declaration] and if unresolved 'a.b' is looked in the scope of |
383 * [declaration]. Each identifier of the remaining suffix, 'c' or 'b.c', is | 378 * [declaration]. Each identifier of the remaining suffix, 'c' or 'b.c', is |
384 * then looked up in the local scope of the previous result. | 379 * then looked up in the local scope of the previous result. |
385 * | 380 * |
386 * For instance, assumming that [:Iterable:] is imported into the scope of | 381 * For instance, assumming that [:Iterable:] is imported into the scope of |
387 * [declaration] via the prefix 'col', 'col.Iterable.E' finds the type | 382 * [declaration] via the prefix 'col', 'col.Iterable.E' finds the type |
388 * variable of [:Iterable:] and 'col.Iterable.contains.element' finds the | 383 * variable of [:Iterable:] and 'col.Iterable.contains.element' finds the |
389 * [:element:] parameter of the [:contains:] method on [:Iterable:]. | 384 * [:element:] parameter of the [:contains:] method on [:Iterable:]. |
390 */ | 385 */ |
391 DeclarationMirror lookupQualifiedInScope(DeclarationSourceMirror declaration, | 386 DeclarationMirror lookupQualifiedInScope( |
392 String name) { | 387 DeclarationSourceMirror declaration, String name) { |
393 // TODO(11653): Support lookup of constructors using the [:new Foo:] | 388 // TODO(11653): Support lookup of constructors using the [:new Foo:] |
394 // syntax. | 389 // syntax. |
395 int offset = 1; | 390 int offset = 1; |
396 List<String> parts = name.split('.'); | 391 List<String> parts = name.split('.'); |
397 DeclarationMirror result = declaration.lookupInScope(parts[0]); | 392 DeclarationMirror result = declaration.lookupInScope(parts[0]); |
398 if (result == null && parts.length > 1) { | 393 if (result == null && parts.length > 1) { |
399 // Try lookup of `prefix.id`. | 394 // Try lookup of `prefix.id`. |
400 result = declaration.lookupInScope('${parts[0]}.${parts[1]}'); | 395 result = declaration.lookupInScope('${parts[0]}.${parts[1]}'); |
401 offset = 2; | 396 offset = 2; |
402 } | 397 } |
403 if (result == null) return null; | 398 if (result == null) return null; |
404 LibraryMirror library = getLibrary(result); | 399 LibraryMirror library = getLibrary(result); |
405 while (result != null && offset < parts.length) { | 400 while (result != null && offset < parts.length) { |
406 result = _lookupLocal(result, symbolOf(parts[offset++], library)); | 401 result = _lookupLocal(result, symbolOf(parts[offset++], library)); |
407 } | 402 } |
408 return result; | 403 return result; |
409 } | 404 } |
410 | 405 |
411 DeclarationMirror _lookupLocal(Mirror mirror, Symbol id) { | 406 DeclarationMirror _lookupLocal(Mirror mirror, Symbol id) { |
412 DeclarationMirror result; | 407 DeclarationMirror result; |
413 if (mirror is LibraryMirror) { | 408 if (mirror is LibraryMirror) { |
414 // Try member lookup. | 409 // Try member lookup. |
415 result = mirror.declarations[id]; | 410 result = mirror.declarations[id]; |
416 } else if (mirror is ClassMirror) { | 411 } else if (mirror is ClassMirror) { |
417 // Try member lookup. | 412 // Try member lookup. |
418 result = mirror.declarations[id]; | 413 result = mirror.declarations[id]; |
419 if (result != null) return result; | 414 if (result != null) return result; |
420 // Try type variables. | 415 // Try type variables. |
421 result = mirror.typeVariables.firstWhere( | 416 result = mirror.typeVariables.firstWhere( |
422 (TypeVariableMirror v) => v.simpleName == id, orElse: () => null); | 417 (TypeVariableMirror v) => v.simpleName == id, |
| 418 orElse: () => null); |
423 } else if (mirror is MethodMirror) { | 419 } else if (mirror is MethodMirror) { |
424 result = mirror.parameters.firstWhere( | 420 result = mirror.parameters.firstWhere( |
425 (ParameterMirror p) => p.simpleName == id, orElse: () => null); | 421 (ParameterMirror p) => p.simpleName == id, |
| 422 orElse: () => null); |
426 } | 423 } |
427 return result; | 424 return result; |
428 | 425 } |
429 } | |
OLD | NEW |