OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 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 | 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.src.util.absolute_path; | 5 library analyzer.src.util.absolute_path; |
6 | 6 |
7 /// The class for manipulating absolute, normalized paths. | 7 /// The class for manipulating absolute, normalized paths. |
8 class AbsolutePathContext { | 8 class AbsolutePathContext { |
9 static const int _COLON = 0x3A; | 9 static const int _COLON = 0x3A; |
10 static const int _PERIOD = 0x2e; | |
11 static const int _LOWER_A = 0x61; | 10 static const int _LOWER_A = 0x61; |
12 static const int _LOWER_Z = 0x7A; | 11 static const int _LOWER_Z = 0x7A; |
13 static const int _UPPER_A = 0x41; | 12 static const int _UPPER_A = 0x41; |
14 static const int _UPPER_Z = 0x5A; | 13 static const int _UPPER_Z = 0x5A; |
15 | 14 |
16 final bool _isWindows; | 15 final bool _isWindows; |
17 String separator; | 16 String separator; |
18 int _separatorChar; | 17 int _separatorChar; |
| 18 String _singlePeriodComponent; |
| 19 String _doublePeriodComponent; |
| 20 String _singlePeriodEnding; |
| 21 String _doublePeriodEnding; |
19 | 22 |
20 AbsolutePathContext(this._isWindows) { | 23 AbsolutePathContext(this._isWindows) { |
21 separator = _isWindows ? r'\' : '/'; | 24 separator = _isWindows ? r'\' : '/'; |
22 _separatorChar = separator.codeUnitAt(0); | 25 _separatorChar = separator.codeUnitAt(0); |
| 26 _singlePeriodComponent = separator + '.' + separator; |
| 27 _doublePeriodComponent = separator + '..' + separator; |
| 28 _singlePeriodEnding = separator + '.'; |
| 29 _doublePeriodEnding = separator + '..'; |
23 } | 30 } |
24 | 31 |
25 /// Append the given relative [suffix] to the given absolute [parent]. | 32 /// Append the given relative [suffix] to the given absolute [parent]. |
26 /// | 33 /// |
27 /// context.append('/path/to', 'foo'); // -> '/path/to/foo' | 34 /// context.append('/path/to', 'foo'); // -> '/path/to/foo' |
28 /// | 35 /// |
29 /// The given [suffix] cannot be an absolute path or use `..`. | 36 /// The given [suffix] cannot be an absolute path or use `..`. |
30 String append(String parent, String suffix) { | 37 String append(String parent, String suffix) { |
31 return '$parent$separator$suffix'; | 38 return '$parent$separator$suffix'; |
32 } | 39 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 if (_isWindows) { | 125 if (_isWindows) { |
119 return path.length >= 3 && | 126 return path.length >= 3 && |
120 _isAlphabetic(path.codeUnitAt(0)) && | 127 _isAlphabetic(path.codeUnitAt(0)) && |
121 path.codeUnitAt(1) == _COLON && | 128 path.codeUnitAt(1) == _COLON && |
122 path.codeUnitAt(2) == _separatorChar; | 129 path.codeUnitAt(2) == _separatorChar; |
123 } else { | 130 } else { |
124 return path.isNotEmpty && path.codeUnitAt(0) == _separatorChar; | 131 return path.isNotEmpty && path.codeUnitAt(0) == _separatorChar; |
125 } | 132 } |
126 } | 133 } |
127 | 134 |
128 | |
129 /// Return `true` if the given absolute [path] is normalized. | 135 /// Return `true` if the given absolute [path] is normalized. |
130 /// | 136 /// |
131 /// _isNormalized('/foo/bar'); // -> true | 137 /// _isNormalized('/foo/bar'); // -> true |
132 /// _isNormalized('/foo/..bar'); // -> true | 138 /// _isNormalized('/foo/..bar'); // -> true |
| 139 /// _isNormalized('/foo/bar..'); // -> true |
133 /// _isNormalized('/'); // -> true | 140 /// _isNormalized('/'); // -> true |
134 /// _isNormalized('/foo/bar/../baz'); // -> false | 141 /// _isNormalized('/foo/bar/../baz'); // -> false |
135 /// _isNormalized('/foo/bar/..'); // -> false | 142 /// _isNormalized('/foo/bar/..'); // -> false |
136 bool _isNormalized(String path) { | 143 bool _isNormalized(String path) { |
137 int periodCount = 0; | 144 return !path.contains(_singlePeriodComponent) && |
138 for (int c in path.codeUnits) { | 145 !path.contains(_doublePeriodComponent) && |
139 if (c == _PERIOD) { | 146 !path.endsWith(_singlePeriodEnding) && |
140 periodCount++; | 147 !path.endsWith(_doublePeriodEnding); |
141 continue; | |
142 } | |
143 if (c == _separatorChar) { | |
144 if (periodCount == 1 || periodCount == 2) { | |
145 return false; | |
146 } | |
147 } | |
148 periodCount = 0; | |
149 } | |
150 return periodCount != 1 && periodCount != 2; | |
151 } | 148 } |
152 | 149 |
153 /// Returns whether [char] is the code for an ASCII letter (uppercase or | 150 /// Returns whether [char] is the code for an ASCII letter (uppercase or |
154 /// lowercase). | 151 /// lowercase). |
155 static bool _isAlphabetic(int char) { | 152 static bool _isAlphabetic(int char) { |
156 return char >= _UPPER_A && char <= _UPPER_Z || | 153 return char >= _UPPER_A && char <= _UPPER_Z || |
157 char >= _LOWER_A && char <= _LOWER_Z; | 154 char >= _LOWER_A && char <= _LOWER_Z; |
158 } | 155 } |
159 | 156 |
160 /// Return `true` if [str] starts with the given [prefix]. | 157 /// Return `true` if [str] starts with the given [prefix]. |
161 /// | 158 /// |
162 /// The check is done from the end of [prefix], because absolute paths | 159 /// The check is done from the end of [prefix], because absolute paths |
163 /// usually have the same prefix, e.g. the user's home directory. | 160 /// usually have the same prefix, e.g. the user's home directory. |
164 static bool _startsWithUnsafe(String str, String prefix) { | 161 static bool _startsWithUnsafe(String str, String prefix) { |
165 int len = prefix.length; | 162 int len = prefix.length; |
166 for (int i = len - 1; i >= 0; i--) { | 163 for (int i = len - 1; i >= 0; i--) { |
167 if (str.codeUnitAt(i) != prefix.codeUnitAt(i)) { | 164 if (str.codeUnitAt(i) != prefix.codeUnitAt(i)) { |
168 return false; | 165 return false; |
169 } | 166 } |
170 } | 167 } |
171 return true; | 168 return true; |
172 } | 169 } |
173 } | 170 } |
OLD | NEW |