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

Side by Side Diff: utils/pub/path.dart

Issue 11471048: Revise path library. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years 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 | Annotate | Revision Log
« no previous file with comments | « utils/pub/io.dart ('k') | utils/pub/validator/name.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 /// A comprehensive, cross-platform path manipulation library. 5 /// A comprehensive, cross-platform path manipulation library.
6 library path; 6 library path;
7 7
8 import 'dart:io' as io; 8 import 'dart:io' as io;
9 9
10 /// An internal builder for the current OS so we can provide a straight 10 /// An internal builder for the current OS so we can provide a straight
11 /// functional interface and not require users to create one. 11 /// functional interface and not require users to create one.
12 final _builder = new Builder(); 12 final _builder = new Builder();
13 13
14 /// Gets the path to the current working directory. 14 /// Gets the path to the current working directory.
15 String get current => new io.Directory.current().path; 15 String get current => new io.Directory.current().path;
16 16
17 /// Gets the path separator for the current platform. On Mac and Linux, this 17 /// Gets the path separator for the current platform. On Mac and Linux, this
18 /// is `/`. On Windows, it's `\`. 18 /// is `/`. On Windows, it's `\`.
19 String get separator => _builder.separator; 19 String get separator => _builder.separator;
20 20
21 /// Converts [path] to an absolute path by resolving it relative to the current 21 /// Converts [path] to an absolute path by resolving it relative to the current
22 /// working directory. If [path] is already an absolute path, just returns it. 22 /// working directory. If [path] is already an absolute path, just returns it.
23 /// 23 ///
24 /// path.absolute('foo/bar.txt'); // -> /your/current/dir/foo/bar.txt 24 /// path.absolute('foo/bar.txt'); // -> /your/current/dir/foo/bar.txt
25 String absolute(String path) => join(current, path); 25 String absolute(String path) => join(current, path);
26 26
27 /// Gets the file extension of [path]; the portion after the last `.` in the 27 /// Gets the part of [path] after the last separator.
28 /// [basename] of the path. 28 ///
29 /// path.basename('path/to/foo.dart'); // -> 'foo.dart'
30 /// path.basename('path/to'); // -> 'to'
31 String basename(String path) => _builder.basename(path);
32
33 /// Gets the part of [path] after the last separator, and without any trailing
34 /// file extension.
35 ///
36 /// path.basenameWithoutExtension('path/to/foo.dart'); // -> 'foo'
37 String basenameWithoutExtension(String path) =>
38 _builder.basenameWithoutExtension(path);
39
40 /// Gets the file extension of [path]: the portion of [basename] from the last
41 /// `.` to the end (including the `.` itself).
29 /// 42 ///
30 /// path.extension('path/to/foo.dart'); // -> '.dart' 43 /// path.extension('path/to/foo.dart'); // -> '.dart'
31 /// path.extension('path/to/foo'); // -> '' 44 /// path.extension('path/to/foo'); // -> ''
32 /// path.extension('path.to/foo'); // -> '' 45 /// path.extension('path.to/foo'); // -> ''
33 /// path.extension('path/to/foo.dart.js'); // -> '.js' 46 /// path.extension('path/to/foo.dart.js'); // -> '.js'
34 /// 47 ///
35 /// If the file name starts with a `.`, then it is not considered an extension: 48 /// If the file name starts with a `.`, then that is not considered the
49 /// extension:
36 /// 50 ///
37 /// path.extension('~/.bashrc'); // -> '' 51 /// path.extension('~/.bashrc'); // -> ''
52 /// path.extension('~/.notes.txt'); // -> '.txt'
38 String extension(String path) => _builder.extension(path); 53 String extension(String path) => _builder.extension(path);
39 54
40 /// Gets the part of [path] after the last separator on the current platform.
41 ///
42 /// path.filename('path/to/foo.dart'); // -> 'foo.dart'
43 /// path.filename('path/to'); // -> 'to'
44 String filename(String path) => _builder.filename(path);
45
46 /// Gets the part of [path] after the last separator on the current platform,
47 /// and without any trailing file extension.
48 ///
49 /// path.filenameWithoutExtension('path/to/foo.dart'); // -> 'foo'
50 String filenameWithoutExtension(String path) =>
51 _builder.filenameWithoutExtension(path);
52
53 /// Returns `true` if [path] is an absolute path and `false` if it is a 55 /// Returns `true` if [path] is an absolute path and `false` if it is a
54 /// relative path. On Mac and Unix systems, relative paths start with a `/` 56 /// relative path. On POSIX systems, absolute paths start with a `/` (forward
55 /// (forward slash). On Windows, an absolute path starts with `\\`, or a drive 57 /// slash). On Windows, an absolute path starts with `\\`, or a drive letter
56 /// letter followed by `:/` or `:\`. 58 /// followed by `:/` or `:\`.
57 bool isAbsolute(String path) => _builder.isAbsolute(path); 59 bool isAbsolute(String path) => _builder.isAbsolute(path);
58 60
59 /// Returns `true` if [path] is a relative path and `false` if it is absolute. 61 /// Returns `true` if [path] is a relative path and `false` if it is absolute.
60 /// On Mac and Unix systems, relative paths start with a `/` (forward slash). 62 /// On POSIX systems, absolute paths start with a `/` (forward slash). On
61 /// On Windows, an absolute path starts with `\\`, or a drive letter followed 63 /// Windows, an absolute path starts with `\\`, or a drive letter followed by
62 /// by `:/` or `:\`. 64 /// `:/` or `:\`.
63 bool isRelative(String path) => _builder.isRelative(path); 65 bool isRelative(String path) => _builder.isRelative(path);
64 66
65 /// Joins the given path parts into a single path using the current platform's 67 /// Joins the given path parts into a single path using the current platform's
66 /// [separator]. Example: 68 /// [separator]. Example:
67 /// 69 ///
68 /// path.join('path', 'to', 'foo'); // -> 'path/to/foo' 70 /// path.join('path', 'to', 'foo'); // -> 'path/to/foo'
69 /// 71 ///
70 /// If any part ends in a path separator, then a redundant separator will not 72 /// If any part ends in a path separator, then a redundant separator will not
71 /// be added: 73 /// be added:
72 /// 74 ///
73 /// path.join('path/', 'to', 'foo'); // -> 'path/to/foo 75 /// path.join('path/', 'to', 'foo'); // -> 'path/to/foo
74 /// 76 ///
75 /// If a part is an absolute path, then anything before that will be ignored: 77 /// If a part is an absolute path, then anything before that will be ignored:
76 /// 78 ///
77 /// path.join('path', '/to', 'foo'); // -> '/to/foo' 79 /// path.join('path', '/to', 'foo'); // -> '/to/foo'
78 ///
79 String join(String part1, [String part2, String part3, String part4, 80 String join(String part1, [String part2, String part3, String part4,
80 String part5, String part6, String part7, String part8]) { 81 String part5, String part6, String part7, String part8]) {
81 if (!?part2) return _builder.join(part1); 82 if (!?part2) return _builder.join(part1);
82 if (!?part3) return _builder.join(part1, part2); 83 if (!?part3) return _builder.join(part1, part2);
83 if (!?part4) return _builder.join(part1, part2, part3); 84 if (!?part4) return _builder.join(part1, part2, part3);
84 if (!?part5) return _builder.join(part1, part2, part3, part4); 85 if (!?part5) return _builder.join(part1, part2, part3, part4);
85 if (!?part6) return _builder.join(part1, part2, part3, part4, part5); 86 if (!?part6) return _builder.join(part1, part2, part3, part4, part5);
86 if (!?part7) return _builder.join(part1, part2, part3, part4, part5, part6); 87 if (!?part7) return _builder.join(part1, part2, part3, part4, part5, part6);
87 if (!?part8) return _builder.join(part1, part2, part3, part4, part5, part6, 88 if (!?part8) return _builder.join(part1, part2, part3, part4, part5, part6,
88 part7); 89 part7);
89 return _builder.join(part1, part2, part3, part4, part5, part6, part7, part8); 90 return _builder.join(part1, part2, part3, part4, part5, part6, part7, part8);
90 } 91 }
91 92
92 /// Normalizes [path], simplifying it by handling `..`, and `.`, and 93 /// Normalizes [path], simplifying it by handling `..`, and `.`, and
93 /// removing redundant path separators whenever possible. 94 /// removing redundant path separators whenever possible.
94 /// 95 ///
95 /// path.normalize('path/./to/..//file.text'); // -> 'path/file.txt' 96 /// path.normalize('path/./to/..//file.text'); // -> 'path/file.txt'
96 String normalize(String path) => _builder.normalize(path); 97 String normalize(String path) => _builder.normalize(path);
97 98
98 /// Converts [path] to an equivalent relative path from the current directory. 99 /// Attempts to convert [path] to an equivalent relative path from the current
100 /// directory.
99 /// 101 ///
100 /// // Given current directory is /root/path: 102 /// // Given current directory is /root/path:
101 /// path.relative('/root/path/a/b.dart'); // -> 'a/b.dart' 103 /// path.relative('/root/path/a/b.dart'); // -> 'a/b.dart'
102 /// path.relative('/root/other.dart'); // -> '../other.dart' 104 /// path.relative('/root/other.dart'); // -> '../other.dart'
105 ///
106 /// Since there is no relative path from one drive letter to another on Windows,
107 /// this will return an absolute path in that case.
108 ///
109 /// // Given current directory is C:\home:
110 /// path.relative(r'D:\other'); // -> 'D:\other'
103 String relative(String path) => _builder.relative(path); 111 String relative(String path) => _builder.relative(path);
104 112
105 /// Removes a trailing extension from the last part of [path]. 113 /// Removes a trailing extension from the last part of [path].
106 /// 114 ///
107 /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' 115 /// withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
108 String withoutExtension(String path) => _builder.withoutExtension(path); 116 String withoutExtension(String path) => _builder.withoutExtension(path);
109 117
110 /// An instantiable class for manipulating paths. Unlike the top-level 118 /// An instantiable class for manipulating paths. Unlike the top-level
111 /// functions, this lets you explicitly select what platform the paths will use. 119 /// functions, this lets you explicitly select what platform the paths will use.
112 class Builder { 120 class Builder {
113 /// Creates a new path builder for the given style and root directory. 121 /// Creates a new path builder for the given style and root directory.
114 /// 122 ///
115 /// If [style] is omitted, it uses the host operating system's path style. If 123 /// If [style] is omitted, it uses the host operating system's path style. If
116 /// [root] is omitted, it defaults to the current working directory. 124 /// [root] is omitted, it defaults to the current working directory. If [root]
125 /// is relative, it is considered relative to the current working directory.
117 factory Builder({Style style, String root}) { 126 factory Builder({Style style, String root}) {
118 if (style == null) { 127 if (style == null) {
119 if (io.Platform.operatingSystem == 'windows') { 128 if (io.Platform.operatingSystem == 'windows') {
120 style = Style.windows; 129 style = Style.windows;
121 } else { 130 } else {
122 style = Style.posix; 131 style = Style.posix;
123 } 132 }
124 } 133 }
125 134
126 if (root == null) root = new io.Directory.current().path; 135 if (root == null) root = current;
127 136
128 return new Builder._(style, root); 137 return new Builder._(style, root);
129 } 138 }
130 139
131 Builder._(this.style, this.root); 140 Builder._(this.style, this.root);
132 141
133 /// The style of path that this builder works with. 142 /// The style of path that this builder works with.
134 final Style style; 143 final Style style;
135 144
136 /// The root directory that relative paths will be relative to. 145 /// The root directory that relative paths will be relative to.
137 final String root; 146 final String root;
138 147
139 /// Gets the path separator for the builder's [style]. On Mac and Linux, 148 /// Gets the path separator for the builder's [style]. On Mac and Linux,
140 /// this is `/`. On Windows, it's `\`. 149 /// this is `/`. On Windows, it's `\`.
141 String get separator => style.separator; 150 String get separator => style.separator;
142 151
143 /// Gets the file extension of [path]; the portion after the last `.` in the 152 /// Gets the part of [path] after the last separator on the builder's
144 /// [basename] of the path. 153 /// platform.
154 ///
155 /// builder.basename('path/to/foo.dart'); // -> 'foo.dart'
156 /// builder.basename('path/to'); // -> 'to'
157 String basename(String path) => _parse(path).basename;
158
159 /// Gets the part of [path] after the last separator on the builder's
160 /// platform, and without any trailing file extension.
161 ///
162 /// builder.basenameWithoutExtension('path/to/foo.dart'); // -> 'foo'
163 String basenameWithoutExtension(String path) =>
164 _parse(path).basenameWithoutExtension;
165
166 /// Gets the file extension of [path]: the portion of [basename] from the last
167 /// `.` to the end (including the `.` itself).
145 /// 168 ///
146 /// builder.extension('path/to/foo.dart'); // -> '.dart' 169 /// builder.extension('path/to/foo.dart'); // -> '.dart'
147 /// builder.extension('path/to/foo'); // -> '' 170 /// builder.extension('path/to/foo'); // -> ''
148 /// builder.extension('path.to/foo'); // -> '' 171 /// builder.extension('path.to/foo'); // -> ''
149 /// builder.extension('path/to/foo.dart.js'); // -> '.js' 172 /// builder.extension('path/to/foo.dart.js'); // -> '.js'
150 /// 173 ///
151 /// If the file name starts with a `.`, then it is not considered an 174 /// If the file name starts with a `.`, then it is not considered an
152 /// extension: 175 /// extension:
153 /// 176 ///
154 /// builder.extension('~/.bashrc'); // -> '' 177 /// builder.extension('~/.bashrc'); // -> ''
178 /// builder.extension('~/.notes.txt'); // -> '.txt'
155 String extension(String path) => _parse(path).extension; 179 String extension(String path) => _parse(path).extension;
156 180
157 /// Gets the part of [path] after the last separator on the builder's
158 /// platform.
159 ///
160 /// builder.filename('path/to/foo.dart'); // -> 'foo.dart'
161 /// builder.filename('path/to'); // -> 'to'
162 String filename(String path) => _parse(path).filename;
163
164 /// Gets the part of [path] after the last separator on the builder's
165 /// platform, and without any trailing file extension.
166 ///
167 /// builder.filenameWithoutExtension('path/to/foo.dart'); // -> 'foo'
168 String filenameWithoutExtension(String path) =>
169 _parse(path).filenameWithoutExtension;
170
171 /// Returns `true` if [path] is an absolute path and `false` if it is a 181 /// Returns `true` if [path] is an absolute path and `false` if it is a
172 /// relative path. On Mac and Unix systems, relative paths start with a `/` 182 /// relative path. On POSIX systems, absolute paths start with a `/` (forward
173 /// (forward slash). On Windows, an absolute path starts with `\\`, or a drive 183 /// slash). On Windows, an absolute path starts with `\\`, or a drive letter
174 /// letter followed by `:/` or `:\`. 184 /// followed by `:/` or `:\`.
175 bool isAbsolute(String path) => _parse(path).isAbsolute; 185 bool isAbsolute(String path) => _parse(path).isAbsolute;
176 186
177 /// Returns `true` if [path] is a relative path and `false` if it is absolute. 187 /// Returns `true` if [path] is a relative path and `false` if it is absolute.
178 /// On Mac and Unix systems, relative paths start with a `/` (forward slash). 188 /// On POSIX systems, absolute paths start with a `/` (forward slash). On
179 /// On Windows, an absolute path starts with `\\`, or a drive letter followed 189 /// Windows, an absolute path starts with `\\`, or a drive letter followed by
180 /// by `:/` or `:\`. 190 /// `:/` or `:\`.
181 bool isRelative(String path) => !isAbsolute(path); 191 bool isRelative(String path) => !isAbsolute(path);
182 192
183 /// Joins the given path parts into a single path. Example: 193 /// Joins the given path parts into a single path. Example:
184 /// 194 ///
185 /// builder.join('path', 'to', 'foo'); // -> 'path/to/foo' 195 /// builder.join('path', 'to', 'foo'); // -> 'path/to/foo'
186 /// 196 ///
187 /// If any part ends in a path separator, then a redundant separator will not 197 /// If any part ends in a path separator, then a redundant separator will not
188 /// be added: 198 /// be added:
189 /// 199 ///
190 /// builder.join('path/', 'to', 'foo'); // -> 'path/to/foo 200 /// builder.join('path/', 'to', 'foo'); // -> 'path/to/foo
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 252
243 var parsed = _parse(path); 253 var parsed = _parse(path);
244 parsed.normalize(); 254 parsed.normalize();
245 return parsed.toString(); 255 return parsed.toString();
246 } 256 }
247 257
248 /// Creates a new path by appending the given path parts to the [root]. 258 /// Creates a new path by appending the given path parts to the [root].
249 /// Equivalent to [join()] with [root] as the first argument. Example: 259 /// Equivalent to [join()] with [root] as the first argument. Example:
250 /// 260 ///
251 /// var builder = new Builder(root: 'root'); 261 /// var builder = new Builder(root: 'root');
252 /// builder.join('path', 'to', 'foo'); // -> 'root/path/to/foo' 262 /// builder.resolve('path', 'to', 'foo'); // -> 'root/path/to/foo'
253 String resolve(String part1, [String part2, String part3, String part4, 263 String resolve(String part1, [String part2, String part3, String part4,
254 String part5, String part6, String part7]) { 264 String part5, String part6, String part7]) {
255 if (!?part2) return join(root, part1); 265 if (!?part2) return join(root, part1);
256 if (!?part3) return join(root, part1, part2); 266 if (!?part3) return join(root, part1, part2);
257 if (!?part4) return join(root, part1, part2, part3); 267 if (!?part4) return join(root, part1, part2, part3);
258 if (!?part5) return join(root, part1, part2, part3, part4); 268 if (!?part5) return join(root, part1, part2, part3, part4);
259 if (!?part6) return join(root, part1, part2, part3, part4, part5); 269 if (!?part6) return join(root, part1, part2, part3, part4, part5);
260 if (!?part7) return join(root, part1, part2, part3, part4, part5, part6); 270 if (!?part7) return join(root, part1, part2, part3, part4, part5, part6);
261 return join(root, part1, part2, part3, part4, part5, part6, part7); 271 return join(root, part1, part2, part3, part4, part5, part6, part7);
262 } 272 }
263 273
264 /// Converts [path] to an equivalent relative path starting at [root]. 274 /// Attempts to convert [path] to an equivalent relative path relative to
275 /// [root].
265 /// 276 ///
266 /// var builder = new Builder(root: '/root/path'); 277 /// var builder = new Builder(root: '/root/path');
267 /// builder.relative('/root/path/a/b.dart'); // -> 'a/b.dart' 278 /// builder.relative('/root/path/a/b.dart'); // -> 'a/b.dart'
268 /// builder.relative('/root/other.dart'); // -> '../other.dart' 279 /// builder.relative('/root/other.dart'); // -> '../other.dart'
280 ///
281 /// Since there is no relative path from one drive letter to another on
282 /// Windows, this will return an absolute path in that case.
283 ///
284 /// var builder = new Builder(root: r'C:\home');
285 /// builder.relative(r'D:\other'); // -> 'D:\other'
269 String relative(String path) { 286 String relative(String path) {
287 if (path == '') return '.';
288
270 // If the base path is relative, resolve it relative to the current 289 // If the base path is relative, resolve it relative to the current
271 // directory. 290 // directory.
272 var base = root; 291 var base = root;
273 if (this.isRelative(base)) base = absolute(base); 292 if (this.isRelative(base)) base = absolute(base);
274 293
275 // If the given path is relative, resolve it relative to the base. 294 // If the given path is relative, resolve it relative to the base.
276 path = this.join(base, path); 295 if (this.isRelative(path)) return this.normalize(path);
277 296
278 var baseParsed = _parse(base)..normalize(); 297 var baseParsed = _parse(base)..normalize();
279 var pathParsed = _parse(path)..normalize(); 298 var pathParsed = _parse(path)..normalize();
280 299
281 // If the root prefixes don't match (for example, different drive letters 300 // If the root prefixes don't match (for example, different drive letters
282 // on Windows), then there is no relative path, so just return the absolute 301 // on Windows), then there is no relative path, so just return the absolute
283 // one. 302 // one.
303 // TODO(rnystrom): Drive letters are case-insentive on Windows. Should
304 // handle "C:\" and "c:\" being the same root.
284 if (baseParsed.root != pathParsed.root) return pathParsed.toString(); 305 if (baseParsed.root != pathParsed.root) return pathParsed.toString();
285 306
286 // Strip off their common prefix. 307 // Strip off their common prefix.
287 while (baseParsed.parts.length > 0 && pathParsed.parts.length > 0) { 308 while (baseParsed.parts.length > 0 && pathParsed.parts.length > 0 &&
288 if (baseParsed.parts[0] != pathParsed.parts[0]) break; 309 baseParsed.parts[0] == pathParsed.parts[0]) {
289 baseParsed.parts.removeAt(0); 310 baseParsed.parts.removeAt(0);
290 baseParsed.separators.removeAt(0); 311 baseParsed.separators.removeAt(0);
291 pathParsed.parts.removeAt(0); 312 pathParsed.parts.removeAt(0);
292 pathParsed.separators.removeAt(0); 313 pathParsed.separators.removeAt(0);
293 } 314 }
294 315
295 // If there are any directories left in the root path, we need to walk up 316 // If there are any directories left in the root path, we need to walk up
296 // out of them. 317 // out of them.
297 pathParsed.parts.insertRange(0, baseParsed.parts.length, '..'); 318 pathParsed.parts.insertRange(0, baseParsed.parts.length, '..');
298 pathParsed.separators.insertRange(0, baseParsed.parts.length, 319 pathParsed.separators.insertRange(0, baseParsed.parts.length,
299 style.separator); 320 style.separator);
300 321
301 // Corner case: the paths completely collapsed. 322 // Corner case: the paths completely collapsed.
302 if (pathParsed.parts.length == 0) return '.'; 323 if (pathParsed.parts.length == 0) return '.';
303 324
304 // Make it relative. 325 // Make it relative.
305 pathParsed.root = ''; 326 pathParsed.root = '';
306 pathParsed.removeTrailingSeparator(); 327 pathParsed.removeTrailingSeparator();
307 328
308 return pathParsed.toString(); 329 return pathParsed.toString();
309 } 330 }
310 331
311 /// Removes a trailing extension from the last part of [path]. 332 /// Removes a trailing extension from the last part of [path].
312 /// 333 ///
313 /// builder.withoutExtension('path/to/foo.dart'); // -> 'path/to/foo' 334 /// builder.withoutExtension('path/to/foo.dart'); // -> 'path/to/foo'
314 String withoutExtension(String path) { 335 String withoutExtension(String path) {
315 var lastSeparator = path.lastIndexOf(separator); 336 var parsed = _parse(path);
316 var lastDot = path.lastIndexOf('.'); 337 parsed.extension = null;
317 338 return parsed.toString();
318 // Ignore '.' in anything but the last component.
319 if (lastSeparator != -1 && lastDot <= lastSeparator + 1) lastDot = -1;
320
321 if (lastDot <= 0) return path;
322 return path.substring(0, lastDot);
323 } 339 }
324 340
325 _ParsedPath _parse(String path) { 341 _ParsedPath _parse(String path) {
326 var before = path; 342 var before = path;
327 343
328 // Remove the root prefix, if any. 344 // Remove the root prefix, if any.
329 var root = style.getRoot(path); 345 var root = style.getRoot(path);
330 if (root != null) path = path.substring(root.length); 346 if (root != null) path = path.substring(root.length);
331 347
332 // Split the parts on path separators. 348 // Split the parts on path separators.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 382
367 /// An enum type describing a "flavor" of path. 383 /// An enum type describing a "flavor" of path.
368 class Style { 384 class Style {
369 /// POSIX-style paths use "/" (forward slash) as separators. Absolute paths 385 /// POSIX-style paths use "/" (forward slash) as separators. Absolute paths
370 /// start with "/". Used by UNIX, Linux, Mac OS X, and others. 386 /// start with "/". Used by UNIX, Linux, Mac OS X, and others.
371 static final posix = new Style._('posix', '/', '/', '/'); 387 static final posix = new Style._('posix', '/', '/', '/');
372 388
373 /// Windows paths use "\" (backslash) as separators. Absolute paths start with 389 /// Windows paths use "\" (backslash) as separators. Absolute paths start with
374 /// a drive letter followed by a colon (example, "C:") or two backslashes 390 /// a drive letter followed by a colon (example, "C:") or two backslashes
375 /// ("\\") for UNC paths. 391 /// ("\\") for UNC paths.
392 // TODO(rnystrom): The UNC root prefix should include the drive name too, not
393 // just the "\\".
376 static final windows = new Style._('windows', '\\', r'[/\\]', 394 static final windows = new Style._('windows', '\\', r'[/\\]',
377 r'\\\\|[a-zA-Z]:[/\\]'); 395 r'\\\\|[a-zA-Z]:[/\\]');
378 396
379 Style._(this.name, this.separator, String separatorPattern, String rootPattern ) 397 Style._(this.name, this.separator, String separatorPattern,
398 String rootPattern)
380 : separatorPattern = new RegExp(separatorPattern), 399 : separatorPattern = new RegExp(separatorPattern),
381 _rootPattern = new RegExp('^$rootPattern'); 400 _rootPattern = new RegExp('^$rootPattern');
382 401
383 /// The name of this path style. Will be "posix" or "windows". 402 /// The name of this path style. Will be "posix" or "windows".
384 final String name; 403 final String name;
385 404
386 /// The path separator for this style. On POSIX, this is `/`. On Windows, 405 /// The path separator for this style. On POSIX, this is `/`. On Windows,
387 /// it's `\`. 406 /// it's `\`.
388 final String separator; 407 final String separator;
389 408
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 if (separators.length == 0) return false; 454 if (separators.length == 0) return false;
436 return separators[separators.length - 1] != ''; 455 return separators[separators.length - 1] != '';
437 } 456 }
438 457
439 /// `true` if this is an absolute path. 458 /// `true` if this is an absolute path.
440 bool get isAbsolute => root != null; 459 bool get isAbsolute => root != null;
441 460
442 _ParsedPath(this.style, this.root, this.parts, this.separators, 461 _ParsedPath(this.style, this.root, this.parts, this.separators,
443 this.extension); 462 this.extension);
444 463
445 String get filename { 464 String get basename {
446 if (parts.length == 0) return extension; 465 if (parts.length == 0) return extension;
447 if (hasTrailingSeparator) return ''; 466 if (hasTrailingSeparator) return '';
448 return '${parts.last}$extension'; 467 return '${parts.last}$extension';
449 } 468 }
450 469
451 String get filenameWithoutExtension { 470 String get basenameWithoutExtension {
452 if (parts.length == 0) return ''; 471 if (parts.length == 0) return '';
453 if (hasTrailingSeparator) return ''; 472 if (hasTrailingSeparator) return '';
454 return parts.last; 473 return parts.last;
455 } 474 }
456 475
457 void removeTrailingSeparator() { 476 void removeTrailingSeparator() {
458 if (separators.length > 0) { 477 if (separators.length > 0) {
459 separators[separators.length - 1] = ''; 478 separators[separators.length - 1] = '';
460 } 479 }
461 } 480 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 if (root != null) builder.add(root); 524 if (root != null) builder.add(root);
506 for (var i = 0; i < parts.length; i++) { 525 for (var i = 0; i < parts.length; i++) {
507 builder.add(parts[i]); 526 builder.add(parts[i]);
508 if (extension != null && i == parts.length - 1) builder.add(extension); 527 if (extension != null && i == parts.length - 1) builder.add(extension);
509 builder.add(separators[i]); 528 builder.add(separators[i]);
510 } 529 }
511 530
512 return builder.toString(); 531 return builder.toString();
513 } 532 }
514 } 533 }
OLDNEW
« no previous file with comments | « utils/pub/io.dart ('k') | utils/pub/validator/name.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698