Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(865)

Side by Side Diff: pkg/analyzer/lib/source/package_map_resolver.dart

Issue 2812093002: Simplify PackageMapUriResolver - one folder, return any file, or null. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 analyzer.source.package_map_resolver; 5 library analyzer.source.package_map_resolver;
6 6
7 import 'dart:core'; 7 import 'dart:core';
8 8
9 import 'package:analyzer/file_system/file_system.dart'; 9 import 'package:analyzer/file_system/file_system.dart';
10 import 'package:analyzer/src/generated/source.dart'; 10 import 'package:analyzer/src/generated/source.dart';
(...skipping 23 matching lines...) Expand all
34 34
35 /** 35 /**
36 * Create a new [PackageMapUriResolver]. 36 * Create a new [PackageMapUriResolver].
37 * 37 *
38 * [packageMap] is a table mapping package names to the paths of the 38 * [packageMap] is a table mapping package names to the paths of the
39 * directories containing the package 39 * directories containing the package
40 */ 40 */
41 PackageMapUriResolver(this.resourceProvider, this.packageMap) { 41 PackageMapUriResolver(this.resourceProvider, this.packageMap) {
42 asserts.notNull(resourceProvider); 42 asserts.notNull(resourceProvider);
43 asserts.notNull(packageMap); 43 asserts.notNull(packageMap);
44 packageMap.forEach((name, folders) {
45 if (folders.length != 1) {
46 throw new ArgumentError(
47 'Exactly one folder must be specified for a package.'
48 'Found $name = $folders');
49 }
50 });
44 } 51 }
45 52
46 @override 53 @override
47 Source resolveAbsolute(Uri uri, [Uri actualUri]) { 54 Source resolveAbsolute(Uri uri, [Uri actualUri]) {
48 if (!isPackageUri(uri)) { 55 if (!isPackageUri(uri)) {
49 return null; 56 return null;
50 } 57 }
51 // Prepare path. 58 // Prepare path.
52 String path = uri.path; 59 String path = uri.path;
53 // Prepare path components. 60 // Prepare path components.
54 int index = path.indexOf('/'); 61 int index = path.indexOf('/');
55 if (index == -1 || index == 0) { 62 if (index == -1 || index == 0) {
56 return null; 63 return null;
57 } 64 }
58 // <pkgName>/<relPath> 65 // <pkgName>/<relPath>
59 String pkgName = path.substring(0, index); 66 String pkgName = path.substring(0, index);
60 String relPath = path.substring(index + 1); 67 String relPath = path.substring(index + 1);
61 // Try to find an existing file. 68 // If the package is known, return the corresponding file.
62 List<Folder> packageDirs = packageMap[pkgName]; 69 List<Folder> packageDirs = packageMap[pkgName];
63 if (packageDirs != null) { 70 if (packageDirs != null) {
64 for (Folder packageDir in packageDirs) { 71 Folder packageDir = packageDirs.single;
65 if (packageDir.exists) { 72 File file = packageDir.getChildAssumingFile(relPath);
66 Resource result = packageDir.getChild(relPath); 73 return file.createSource(uri);
67 if (result is File && result.exists) {
68 return result.createSource(uri);
69 }
70 }
71 }
72 } 74 }
73 // Return a NonExistingSource instance. 75 return null;
74 // This helps provide more meaningful error messages to users
75 // (a missing file error, as opposed to an invalid URI error).
76 String fullPath = packageDirs != null && packageDirs.isNotEmpty
77 ? packageDirs.first.canonicalizePath(relPath)
78 : relPath;
79 return new NonExistingSource(fullPath, uri, UriKind.PACKAGE_URI);
80 } 76 }
81 77
82 @override 78 @override
83 Uri restoreAbsolute(Source source) { 79 Uri restoreAbsolute(Source source) {
84 String sourcePath = source.fullName; 80 String sourcePath = source.fullName;
85 Uri bestMatch;
86 int bestMatchLength = -1;
87 pathos.Context pathContext = resourceProvider.pathContext; 81 pathos.Context pathContext = resourceProvider.pathContext;
88 for (String pkgName in packageMap.keys) { 82 for (String pkgName in packageMap.keys) {
89 List<Folder> pkgFolders = packageMap[pkgName]; 83 Folder pkgFolder = packageMap[pkgName][0];
90 for (int i = 0; i < pkgFolders.length; i++) { 84 String pkgFolderPath = pkgFolder.path;
91 Folder pkgFolder = pkgFolders[i]; 85 if (sourcePath.startsWith(pkgFolderPath + pathContext.separator)) {
92 String pkgFolderPath = pkgFolder.path; 86 String relPath = sourcePath.substring(pkgFolderPath.length + 1);
93 if (pkgFolderPath.length > bestMatchLength && 87 List<String> relPathComponents = pathContext.split(relPath);
94 sourcePath.startsWith(pkgFolderPath + pathContext.separator)) { 88 String relUriPath = pathos.posix.joinAll(relPathComponents);
95 String relPath = sourcePath.substring(pkgFolderPath.length + 1); 89 return Uri.parse('$PACKAGE_SCHEME:$pkgName/$relUriPath');
96 if (_isReversibleTranslation(pkgFolders, i, relPath)) {
97 List<String> relPathComponents = pathContext.split(relPath);
98 String relUriPath = pathos.posix.joinAll(relPathComponents);
99 bestMatch = Uri.parse('$PACKAGE_SCHEME:$pkgName/$relUriPath');
100 bestMatchLength = pkgFolderPath.length;
101 }
102 }
103 } 90 }
104 } 91 }
105 return bestMatch; 92 return null;
106 } 93 }
107 94
108 /** 95 /**
109 * A translation from file path to package URI has just been found for
110 * using the [packageDirIndex]th element of [packageDirs], and appending the
111 * relative path [relPath]. Determine whether the translation is reversible;
112 * that is, whether translating the package URI pack to a file path will
113 * produce the file path we started with.
114 */
115 bool _isReversibleTranslation(
116 List<Folder> packageDirs, int packageDirIndex, String relPath) {
117 // The translation is reversible provided there is no prior element of
118 // [packageDirs] containing a file matching [relPath].
119 for (int i = 0; i < packageDirIndex; i++) {
120 Folder packageDir = packageDirs[i];
121 if (packageDir.exists) {
122 Resource result = packageDir.getChild(relPath);
123 if (result is File && result.exists) {
124 return false;
125 }
126 }
127 }
128 return true;
129 }
130
131 /**
132 * Returns `true` if [uri] is a `package` URI. 96 * Returns `true` if [uri] is a `package` URI.
133 */ 97 */
134 static bool isPackageUri(Uri uri) { 98 static bool isPackageUri(Uri uri) {
135 return uri.scheme == PACKAGE_SCHEME; 99 return uri.scheme == PACKAGE_SCHEME;
136 } 100 }
137 } 101 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/test/context_manager_test.dart ('k') | pkg/analyzer/test/source/package_map_resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698