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

Side by Side Diff: runtime/bin/path_impl.dart

Issue 10417053: Add Path class to dart:io, and add unit tests for it. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add unit tests for Path, remove test_suite changes. Created 8 years, 7 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 | Annotate | Revision Log
OLDNEW
(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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698