Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library initialize.transformer; | 4 library initialize.transformer; |
| 5 | 5 |
| 6 import 'dart:async'; | 6 import 'dart:async'; |
| 7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
| 8 import 'package:analyzer/src/generated/ast.dart'; | 8 import 'package:analyzer/src/generated/ast.dart'; |
| 9 import 'package:analyzer/src/generated/element.dart'; | 9 import 'package:analyzer/src/generated/element.dart'; |
| 10 import 'package:barback/barback.dart'; | 10 import 'package:barback/barback.dart'; |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 for (var interface in type.interfaces) { | 344 for (var interface in type.interfaces) { |
| 345 if (_isInitializer(interface)) return true; | 345 if (_isInitializer(interface)) return true; |
| 346 } | 346 } |
| 347 return false; | 347 return false; |
| 348 } | 348 } |
| 349 | 349 |
| 350 /// Retrieves all top-level methods that are visible if you were to import | 350 /// Retrieves all top-level methods that are visible if you were to import |
| 351 /// [lib]. This includes exported methods from other libraries too. | 351 /// [lib]. This includes exported methods from other libraries too. |
| 352 List<FunctionElement> _topLevelMethodsOfLibrary( | 352 List<FunctionElement> _topLevelMethodsOfLibrary( |
| 353 LibraryElement library, Set<LibraryElement> seen) { | 353 LibraryElement library, Set<LibraryElement> seen) { |
| 354 var result = []; | 354 var methods = []; |
| 355 result.addAll(library.units.expand((u) => u.functions)); | 355 |
| 356 for (var export in library.exports) { | 356 var orderedExports = new List.from(library.exports) |
| 357 ..sort((a, b) => a.uriOffset.compareTo(b.uriOffset)); | |
| 358 for (var export in orderedExports) { | |
| 357 if (seen.contains(export.exportedLibrary)) continue; | 359 if (seen.contains(export.exportedLibrary)) continue; |
| 358 var exported = _topLevelMethodsOfLibrary(export.exportedLibrary, seen); | 360 methods.addAll(_topLevelMethodsOfLibrary(export.exportedLibrary, seen)); |
| 359 _filter(exported, export.combinators); | |
| 360 result.addAll(exported); | |
| 361 } | 361 } |
| 362 result.sort((a, b) => a.name.compareTo(b.name)); | 362 |
| 363 return result; | 363 for (CompilationUnitElement unit in _orderedUnits(library)) { |
| 364 methods.addAll(new List.from(unit.functions) | |
| 365 ..sort((a, b) => a.nameOffset.compareTo(b.nameOffset))); | |
| 366 } | |
| 367 | |
| 368 return methods; | |
| 364 } | 369 } |
| 365 | 370 |
| 366 /// Retrieves all classes that are visible if you were to import [lib]. This | 371 /// Retrieves all classes that are visible if you were to import [lib]. This |
| 367 /// includes exported classes from other libraries. | 372 /// includes exported classes from other libraries. |
| 368 List<ClassElement> _classesOfLibrary( | 373 List<ClassElement> _classesOfLibrary( |
| 369 LibraryElement library, Set<LibraryElement> seen) { | 374 LibraryElement library, Set<LibraryElement> seen) { |
| 370 var result = []; | 375 var classes = []; |
| 371 result.addAll(library.units.expand((u) => u.types)); | 376 |
| 372 for (var export in library.exports) { | 377 var orderedExports = new List.from(library.exports) |
| 378 ..sort((a, b) => a.uriOffset.compareTo(b.uriOffset)); | |
| 379 for (var export in orderedExports) { | |
| 373 if (seen.contains(export.exportedLibrary)) continue; | 380 if (seen.contains(export.exportedLibrary)) continue; |
| 374 var exported = _classesOfLibrary(export.exportedLibrary, seen); | 381 classes.addAll(_classesOfLibrary(export.exportedLibrary, seen)); |
| 375 _filter(exported, export.combinators); | |
| 376 result.addAll(exported); | |
| 377 } | 382 } |
| 378 result.sort((a, b) => a.name.compareTo(b.name)); | 383 |
| 379 return result; | 384 for (var unit in _orderedUnits(library)) { |
| 385 classes.addAll(new List.from(unit.types) | |
| 386 ..sort((a, b) => a.nameOffset.compareTo(b.nameOffset))); | |
| 387 } | |
| 388 | |
| 389 return classes; | |
| 380 } | 390 } |
| 381 | 391 |
| 382 /// Filters [elements] that come from an export, according to its show/hide | 392 List<CompilationUnitElement> _orderedUnits(LibraryElement library) { |
| 383 /// combinators. This modifies [elements] in place. | 393 // The first item is the source library, remove it for now. |
|
Siggi Cherem (dart-lang)
2015/03/17 22:17:18
actually, you can use library.definingCompilationU
jakemac
2015/03/17 22:50:48
Done.
| |
| 384 void _filter(List<Element> elements, List<NamespaceCombinator> combinators) { | 394 var orderedUnits = new List.from(library.units) |
| 385 for (var c in combinators) { | 395 ..removeAt(0) |
| 386 if (c is ShowElementCombinator) { | 396 ..sort((a, b) => a.uri.compareTo(b.uri)); |
| 387 var show = c.shownNames.toSet(); | 397 |
| 388 elements.retainWhere((e) => show.contains(e.displayName)); | 398 // Add back the main library as the last unit. |
| 389 } else if (c is HideElementCombinator) { | 399 return orderedUnits..add(library.units.first);; |
| 390 var hide = c.hiddenNames.toSet(); | |
| 391 elements.removeWhere((e) => hide.contains(e.displayName)); | |
| 392 } | |
| 393 } | |
| 394 } | 400 } |
| 395 | 401 |
| 396 Iterable<LibraryElement> _sortedLibraryDependencies(LibraryElement library) { | 402 Iterable<LibraryElement> _sortedLibraryDependencies(LibraryElement library) { |
| 397 // TODO(jakemac): Investigate supporting annotations on part-of directives. | 403 // TODO(jakemac): Investigate supporting annotations on part-of directives. |
| 398 getLibrary(UriReferencedElement element) { | 404 getLibrary(UriReferencedElement element) { |
| 399 if (element is ImportElement) return element.importedLibrary; | 405 if (element is ImportElement) return element.importedLibrary; |
| 400 if (element is ExportElement) return element.exportedLibrary; | 406 if (element is ExportElement) return element.exportedLibrary; |
| 401 } | 407 } |
| 402 | 408 |
| 403 return (new List.from(library.imports) | 409 return (new List.from(library.imports) |
| 404 ..addAll(library.exports) | 410 ..addAll(library.exports) |
| 405 ..sort((a, b) { | 411 ..sort((a, b) => a.nameOffset.compareTo(b.nameOffset))).map(getLibrary); |
| 406 // dart: imports don't have a uri | |
| 407 if (a.uri == null && b.uri != null) return -1; | |
| 408 if (b.uri == null && a.uri != null) return 1; | |
| 409 if (a.uri == null && b.uri == null) { | |
| 410 return getLibrary(a).name.compareTo(getLibrary(b).name); | |
| 411 } | |
| 412 | |
| 413 // package: imports next | |
| 414 var aIsPackage = a.uri.startsWith('package:'); | |
| 415 var bIsPackage = b.uri.startsWith('package:'); | |
| 416 if (aIsPackage && !bIsPackage) { | |
| 417 return -1; | |
| 418 } else if (bIsPackage && !aIsPackage) { | |
| 419 return 1; | |
| 420 } else if (bIsPackage && aIsPackage) { | |
| 421 return a.uri.compareTo(b.uri); | |
| 422 } | |
| 423 | |
| 424 // And finally compare based on the relative uri if both are file paths. | |
| 425 var aUri = path.url.relative(a.source.uri.path, | |
| 426 from: path.url.dirname(library.source.uri.path)); | |
| 427 var bUri = path.url.relative(b.source.uri.path, | |
| 428 from: path.url.dirname(library.source.uri.path)); | |
| 429 return aUri.compareTo(bUri); | |
| 430 })).map(getLibrary); | |
| 431 } | 412 } |
| 432 } | 413 } |
| 433 | 414 |
| 434 /// An [Initializer] annotation and the target of that annotation. | 415 /// An [Initializer] annotation and the target of that annotation. |
| 435 class InitializerData { | 416 class InitializerData { |
| 436 /// The target [AstNode] of the annotation. | 417 /// The target [AstNode] of the annotation. |
| 437 final AstNode targetNode; | 418 final AstNode targetNode; |
| 438 | 419 |
| 439 /// The [Annotation] representing the annotation itself. | 420 /// The [Annotation] representing the annotation itself. |
| 440 final Annotation annotationNode; | 421 final Annotation annotationNode; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 error = false; | 453 error = false; |
| 473 } else { | 454 } else { |
| 474 error = true; | 455 error = true; |
| 475 } | 456 } |
| 476 if (error) { | 457 if (error) { |
| 477 print('Bad value for "$field" in the initialize transformer. ' | 458 print('Bad value for "$field" in the initialize transformer. ' |
| 478 'Expected either one String or a list of Strings.'); | 459 'Expected either one String or a list of Strings.'); |
| 479 } | 460 } |
| 480 return files; | 461 return files; |
| 481 } | 462 } |
| OLD | NEW |