Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 class _PathImpl implements Path { | |
| 6 final String path; | |
| 7 _PathImpl(String source) : path = _clean(source); | |
| 8 const _PathImpl.c(String source) : path = source; | |
|
Mads Ager (google)
2012/05/29 07:36:02
const _PathImpl.c(String this.path);
?
Where do y
Bill Hesse
2012/05/31 15:55:10
Done.
| |
| 9 | |
| 10 static String _clean(String source) { | |
| 11 switch (Platform.operatingSystem) { | |
| 12 case 'windows': | |
| 13 return _cleanWindows(source); | |
| 14 default: | |
| 15 return _cleanPosix(source); | |
| 16 } | |
| 17 } | |
| 18 | |
| 19 static String _cleanWindows(source) { | |
| 20 // Change \ to /. | |
| 21 var clean = source.replaceAll('\\', '/'); | |
| 22 // Add / before intial [Drive letter]: | |
| 23 if (const RegExp(@'^[a-zA-Z]:').hasMatch(clean)) { | |
|
Søren Gjesse
2012/05/29 07:18:01
Just
if (clean.length > 1 && clean[1] = ":")
i
Bill Hesse
2012/05/31 15:55:10
Done.
| |
| 24 clean = '/$clean'; | |
| 25 } | |
| 26 return _cleanPosix(clean); | |
| 27 } | |
| 28 | |
| 29 static String _cleanPosix(source) { | |
| 30 // Change //+ to / (remove all consecutive / marks). | |
| 31 var clean = source.replaceAll(const RegExp('//+'), '/'); | |
| 32 return clean; | |
| 33 } | |
| 34 | |
| 35 bool isEmpty() => path == ''; | |
|
Mads Ager (google)
2012/05/29 07:36:02
Add 'get' and either remove the blank line below o
Bill Hesse
2012/05/31 15:55:10
Done.
| |
| 36 | |
| 37 bool get isAbsolute() => path.startsWith('/'); | |
| 38 bool get isDirectory() => path.endsWith('/') || isEmpty(); | |
|
Bob Nystrom
2012/05/30 17:58:37
When you make isEmpty a getter, don't forget to re
Bill Hesse
2012/05/31 15:55:10
Removed this case from hasTrailingSlash.
| |
| 39 | |
| 40 String toString() => path; | |
| 41 | |
| 42 Path relativeTo(Path base) { | |
| 43 // Throws exception if not doable. | |
| 44 // Unimplemented | |
| 45 if (base.isAbsolute && path.startsWith(base.path)) { | |
| 46 if (path == base.path) return new Path('.'); | |
| 47 if (path[base.path.length] == '/') { | |
| 48 return new Path(path.substring(base.path.length + 1)); | |
| 49 } | |
| 50 } | |
| 51 throw "Unimplemented case ofPath.relativeTo(base):" | |
|
Bill Hesse
2012/05/25 13:14:38
Switch to throw PathException (or UnimplementedExc
Mads Ager (google)
2012/05/29 07:36:02
I would throw a PathException and be very clear ab
Bill Hesse
2012/05/31 15:55:10
The PathException class is removed. Throwing an U
| |
| 52 "Path $path relative to ${base.path}"; | |
| 53 } | |
| 54 | |
| 55 Path join(Path further) { | |
| 56 if (further.isAbsolute) { | |
|
Bill Hesse
2012/05/25 13:14:38
PathException.
Bob Nystrom
2012/05/30 17:58:37
Better: IllegalArgumentException.
Bill Hesse
2012/05/31 15:55:10
Done.
| |
| 57 throw "Make a path exception class, and throw it: join with absolute"; | |
| 58 } | |
| 59 return new Path('$path/${further.path}'); | |
| 60 // Canonicalize? | |
|
Mads Ager (google)
2012/05/29 07:36:02
Add TODO(whesse):
Bill Hesse
2012/05/31 15:55:10
Done.
| |
| 61 } | |
| 62 | |
| 63 Path safeJoin(Path further) => join(further); | |
|
Mads Ager (google)
2012/05/29 07:36:02
This is not in the interface. What is it used for?
Bill Hesse
2012/05/31 15:55:10
Added to the interface. It joins two paths, check
| |
| 64 | |
| 65 Path canonicalize() { | |
| 66 if (isCanonical) return this; | |
| 67 return makeCanonical(); | |
| 68 } | |
| 69 | |
| 70 bool get isCanonical() { | |
| 71 // Contains no consecutive /s. | |
| 72 // Contains no . components. | |
| 73 // Absolute paths have no .. components. | |
| 74 // All .. components of a relative path are initial. | |
| 75 List components = path.split('/'); | |
| 76 if (components[0] == '') { // Absolute path | |
| 77 components.removeRange(0, 1); | |
|
Mads Ager (google)
2012/05/29 07:36:02
I would use indices instead of copying 'components
Bill Hesse
2012/05/31 15:55:10
Yes, that would be better.
Bill Hesse
2012/05/31 15:55:10
Fixed using indices, but keeping the components.so
| |
| 78 } else { // Relative path starting with .. components. | |
| 79 while (!components.isEmpty() && components[0] == '..') { | |
| 80 components.removeRange(0, 1); | |
| 81 } | |
| 82 } | |
| 83 if (components.isEmpty()) return true; | |
| 84 if (components.last() == '') components.removeLast(); // Path ends with /. | |
| 85 // No remaining components can be ., .., or empty. | |
| 86 return !components.some((c) => c == '..' || c == '.' || c == ''); | |
| 87 } | |
| 88 | |
| 89 Path makeCanonical() { | |
| 90 bool absolute = isAbsolute; | |
| 91 // Unimplemented. | |
| 92 throw "Unimplemented Path.makeCanonical()"; | |
|
Mads Ager (google)
2012/05/29 07:36:02
NotImplementedException, but it doesn't really mat
Bill Hesse
2012/05/31 15:55:10
Done.
| |
| 93 return this; | |
| 94 } | |
| 95 | |
| 96 String toNativePath() { | |
| 97 if (Platform.operatingSystem == 'windows') { | |
| 98 String nativePath = path; | |
| 99 if (const RegExp(@'^/[a-zA-z]:').hasMatch(nativePath)) { | |
|
Mads Ager (google)
2012/05/29 07:36:02
I guess you could just check for '/' and maybe ':'
Bill Hesse
2012/05/31 15:55:10
Done.
Bill Hesse
2012/05/31 15:55:10
Done.
| |
| 100 nativePath = nativePath = substring(1); | |
| 101 } | |
| 102 nativePath = nativePath.replace('/', '\\'); | |
| 103 return nativePath; | |
| 104 } | |
| 105 return path; | |
| 106 } | |
| 107 | |
| 108 String last() { | |
|
Mads Ager (google)
2012/05/29 07:36:02
Make this private since it is not part of the inte
Bill Hesse
2012/05/31 15:55:10
removed.
| |
| 109 int pos = path.lastIndexOf('/'); | |
| 110 return path.substring(pos+1); | |
|
Søren Gjesse
2012/05/29 07:18:01
Spaces on both sides of +.
Bill Hesse
2012/05/31 15:55:10
Done.
Bill Hesse
2012/05/31 15:55:10
Done.
| |
| 111 } | |
| 112 | |
| 113 Path dropLast() { | |
|
Mads Ager (google)
2012/05/29 07:36:02
Move the code to dirname which is the only user. I
Bill Hesse
2012/05/31 15:55:10
Done.
Bill Hesse
2012/05/31 15:55:10
Done.
| |
| 114 int pos = path.lastIndexOf('/'); | |
| 115 if (pos < 0) return new Path(''); | |
| 116 // while (pos > 0 && path[pos - 1] == '/') --pos; | |
|
Mads Ager (google)
2012/05/29 07:36:02
Code in comments.
Bill Hesse
2012/05/31 15:55:10
Uncommented, because we don't always clean consecu
| |
| 117 return new Path((pos > 0) ? path.substring(0, pos) : '/'); | |
| 118 } | |
| 119 | |
| 120 String basename() { | |
| 121 var name = last(); | |
| 122 int pos = name.lastIndexOf('.'); | |
| 123 return (pos < 0) ? name : name.substring(0, pos); | |
| 124 } | |
| 125 | |
| 126 String extension() { | |
| 127 var name = last(); | |
| 128 int pos = name.lastIndexOf('.'); | |
| 129 return (pos < 0) ? '' : name.substring(pos + 1); | |
| 130 } | |
| 131 | |
| 132 Path dirname() { | |
| 133 return dropLast(); | |
| 134 } | |
| 135 | |
| 136 String filename() { | |
| 137 return last(); | |
| 138 } | |
| 139 } | |
| OLD | NEW |