| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 import 'package:analyzer/dart/element/element.dart' | |
| 6 show CompilationUnitElement, LibraryElement; | |
| 7 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext; | |
| 8 import 'package:path/path.dart' as path; | |
| 9 | |
| 10 import '../compiler.dart' show AbstractCompiler; | |
| 11 import '../info.dart'; | |
| 12 import '../utils.dart' show canonicalLibraryName; | |
| 13 import '../options.dart' show CodegenOptions; | |
| 14 | |
| 15 abstract class CodeGenerator { | |
| 16 final AbstractCompiler compiler; | |
| 17 final AnalysisContext context; | |
| 18 final CodegenOptions options; | |
| 19 | |
| 20 CodeGenerator(AbstractCompiler compiler) | |
| 21 : compiler = compiler, | |
| 22 context = compiler.context, | |
| 23 options = compiler.options.codegenOptions; | |
| 24 | |
| 25 /// Return a hash, if any, that can be used for caching purposes. When two | |
| 26 /// invocations to this function return the same hash, the underlying | |
| 27 /// code-generator generated the same code. | |
| 28 String generateLibrary(LibraryUnit unit); | |
| 29 | |
| 30 static List<String> _searchPaths = () { | |
| 31 // TODO(vsm): Can we remove redundancy with multi_package_resolver logic? | |
| 32 var packagePaths = | |
| 33 new String.fromEnvironment('package_paths', defaultValue: null); | |
| 34 if (packagePaths == null) return null; | |
| 35 var list = packagePaths.split(','); | |
| 36 // Normalize the paths. | |
| 37 list = new List<String>.from(list.map(_dirToPrefix)); | |
| 38 // The current directory is implicitly in the search path. | |
| 39 list.add(_dirToPrefix(path.current)); | |
| 40 // Sort by reverse length to prefer longer prefixes. | |
| 41 // This ensures that we get the minimum valid suffix. E.g., if we have: | |
| 42 // - root/ | |
| 43 // - root/generated/ | |
| 44 // in our search path, and the path "root/generated/foo/bar.dart", we'll | |
| 45 // compute "foo/bar.dart" instead of "generated/foo/bar.dart" in the search | |
| 46 // below. | |
| 47 list.sort((s1, s2) => s2.length - s1.length); | |
| 48 return list; | |
| 49 }() as List<String>; | |
| 50 | |
| 51 static String _dirToPrefix(String dir) { | |
| 52 dir = path.absolute(dir); | |
| 53 dir = path.normalize(dir); | |
| 54 if (!dir.endsWith(path.separator)) { | |
| 55 dir = dir + path.separator; | |
| 56 } | |
| 57 return dir; | |
| 58 } | |
| 59 | |
| 60 static String _convertIfPackage(String dir) { | |
| 61 assert(path.isRelative(dir)); | |
| 62 var parts = path.split(dir); | |
| 63 var index = parts.indexOf('lib'); | |
| 64 if (index < 0) { | |
| 65 // Not a package. | |
| 66 return dir; | |
| 67 } | |
| 68 // This is a package. | |
| 69 // Convert: foo/bar/lib/baz/hi | |
| 70 // to: packages/foo.bar/baz/hi | |
| 71 var packageName = parts.sublist(0, index).join('.'); | |
| 72 var prefix = path.join('packages', packageName); | |
| 73 var suffix = path.joinAll(parts.sublist(index + 1)); | |
| 74 return path.join(prefix, suffix); | |
| 75 } | |
| 76 | |
| 77 static String _getOutputDirectory( | |
| 78 String name, CompilationUnitElement unitElement) { | |
| 79 var uri = unitElement.source.uri.toString(); | |
| 80 String suffix; | |
| 81 if (uri.startsWith('dart:') || _searchPaths == null) { | |
| 82 // Use the library name as the directory. | |
| 83 suffix = name; | |
| 84 } else if (uri.startsWith('package:')) { | |
| 85 suffix = uri.replaceFirst('package:', 'packages/'); | |
| 86 suffix = path.dirname(suffix); | |
| 87 } else { | |
| 88 // Recover the original search path and use the relative path | |
| 89 // from there as the directory. | |
| 90 // TODO(vsm): Is there a better way to get the resolved path? | |
| 91 var resolvedPath = unitElement.toString(); | |
| 92 var resolvedDir = path.dirname(resolvedPath); | |
| 93 for (var prefix in _searchPaths) { | |
| 94 if (resolvedDir.startsWith(prefix)) { | |
| 95 suffix = resolvedDir.substring(prefix.length); | |
| 96 break; | |
| 97 } | |
| 98 } | |
| 99 } | |
| 100 assert(suffix != null); | |
| 101 assert(path.isRelative(suffix)); | |
| 102 return _convertIfPackage(suffix); | |
| 103 } | |
| 104 | |
| 105 static Uri uriFor(LibraryElement lib) { | |
| 106 var unitElement = lib.definingCompilationUnit; | |
| 107 var uri = unitElement.source.uri; | |
| 108 if (uri.scheme == 'dart') return uri; | |
| 109 if (uri.scheme == 'package') return uri; | |
| 110 var suffix = _getOutputDirectory(canonicalLibraryName(lib), unitElement); | |
| 111 suffix = path.join(suffix, uri.pathSegments.last); | |
| 112 var parts = path.split(suffix); | |
| 113 var index = parts.indexOf('packages'); | |
| 114 if (index < 0) { | |
| 115 // Not a package. | |
| 116 // TODO(leafp) These may need to be adjusted | |
| 117 // relative to the import location | |
| 118 return new Uri(path: suffix); | |
| 119 } | |
| 120 assert(index == 0); | |
| 121 return new Uri( | |
| 122 scheme: 'package', path: path.joinAll(parts.sublist(index + 1))); | |
| 123 } | |
| 124 } | |
| OLD | NEW |