| 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 |