| OLD | NEW |
| (Empty) | |
| 1 library angular.source_crawler_impl; |
| 2 |
| 3 import 'dart:io'; |
| 4 import 'package:analyzer/analyzer.dart'; |
| 5 import 'source_crawler.dart'; |
| 6 |
| 7 const String PACKAGE_PREFIX = 'package:'; |
| 8 |
| 9 /** |
| 10 * Dart source file crawler. As it crawls Dart source, it calls |
| 11 * [CompilationUnitVisitor] on each file. |
| 12 */ |
| 13 class SourceCrawlerImpl implements SourceCrawler { |
| 14 final List<String> packageRoots; |
| 15 |
| 16 SourceCrawlerImpl(this.packageRoots); |
| 17 |
| 18 void crawl(String entryPoint, CompilationUnitVisitor visitor) { |
| 19 List<String> visited = <String>[]; |
| 20 List<String> toVisit = <String>[]; |
| 21 if (entryPoint.startsWith(PACKAGE_PREFIX)) { |
| 22 var path = resolvePackagePath(entryPoint); |
| 23 if (path == null) { |
| 24 throw 'Unable to resolve $entryPoint'; |
| 25 } |
| 26 toVisit.add(path); |
| 27 } else { |
| 28 toVisit.add(entryPoint); |
| 29 } |
| 30 |
| 31 while (toVisit.isNotEmpty) { |
| 32 var currentFile = toVisit.removeAt(0); |
| 33 visited.add(currentFile); |
| 34 var file = new File(currentFile); |
| 35 // Possible source file doesn't exist. For example if it is generated. |
| 36 if (!file.existsSync()) continue; |
| 37 var currentDir = file.parent.path; |
| 38 CompilationUnit cu = parseDartFile(currentFile); |
| 39 processImports(cu, currentDir, currentFile, visited, toVisit); |
| 40 visitor(cu); |
| 41 } |
| 42 } |
| 43 |
| 44 void processImports(CompilationUnit cu, String currentDir, |
| 45 String currentFile, List<String> visited, |
| 46 List<String> toVisit) { |
| 47 cu.directives.forEach((Directive directive) { |
| 48 if (directive is ImportDirective || directive is PartDirective) { |
| 49 UriBasedDirective import = directive; |
| 50 String canonicalFile = canonicalizeImportPath( |
| 51 currentDir, currentFile, import.uri.stringValue); |
| 52 if (canonicalFile == null) return; |
| 53 if (!visited.contains(canonicalFile) && |
| 54 !toVisit.contains(canonicalFile)) { |
| 55 toVisit.add(canonicalFile); |
| 56 } |
| 57 } |
| 58 }); |
| 59 } |
| 60 |
| 61 String canonicalizeImportPath(String currentDir, |
| 62 String currentFile, |
| 63 String uri) { |
| 64 // ignore core libraries |
| 65 if (uri.startsWith('dart:')) { |
| 66 return null; |
| 67 } |
| 68 if (uri.startsWith(PACKAGE_PREFIX)) { |
| 69 return resolvePackagePath(uri); |
| 70 } |
| 71 // relative import. |
| 72 if (uri.startsWith('../')) { |
| 73 while (uri.startsWith('../')) { |
| 74 uri = uri.substring('../'.length); |
| 75 currentDir = currentDir.substring(0, currentDir.lastIndexOf('/')); |
| 76 } |
| 77 } |
| 78 return '$currentDir/$uri'; |
| 79 } |
| 80 |
| 81 String resolvePackagePath(String uri) { |
| 82 for (String packageRoot in packageRoots) { |
| 83 var resolvedPath = _packageUriResolver(uri, packageRoot); |
| 84 if (new File(resolvedPath).existsSync()) { |
| 85 return resolvedPath; |
| 86 } |
| 87 } |
| 88 return null; |
| 89 } |
| 90 |
| 91 String _packageUriResolver(String uri, String packageRoot) { |
| 92 var packagePath = uri.substring(PACKAGE_PREFIX.length); |
| 93 if (!packageRoot.endsWith('/')) { |
| 94 packageRoot = packageRoot + '/'; |
| 95 } |
| 96 return packageRoot + packagePath; |
| 97 } |
| 98 } |
| OLD | NEW |