Chromium Code Reviews| 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 paths. | 7 /// The class for manipulating absolute, normalized paths. |
| 8 class AbsolutePathContext { | 8 class AbsolutePathContext { |
| 9 final String separator; | 9 static const int _COLON = 0x3A; |
| 10 static const int _PERIOD = 0x2e; | |
| 11 static const int _LOWER_A = 0x61; | |
| 12 static const int _LOWER_Z = 0x7A; | |
| 13 static const int _UPPER_A = 0x41; | |
| 14 static const int _UPPER_Z = 0x5A; | |
| 10 | 15 |
| 16 final bool _isWindows; | |
| 17 String separator; | |
| 11 int _separatorChar; | 18 int _separatorChar; |
| 12 | 19 |
| 13 AbsolutePathContext(this.separator) { | 20 AbsolutePathContext(this._isWindows) { |
| 14 if (separator.length != 1) { | 21 separator = _isWindows ? r'\' : '/'; |
| 15 throw new ArgumentError.value( | |
| 16 separator, 'separator', 'must be exactly one character long'); | |
| 17 } | |
| 18 _separatorChar = separator.codeUnitAt(0); | 22 _separatorChar = separator.codeUnitAt(0); |
| 19 } | 23 } |
| 20 | 24 |
| 21 /// Append the given relative [suffix] to the given absolute [parent]. | 25 /// Append the given relative [suffix] to the given absolute [parent]. |
| 22 /// | 26 /// |
| 23 /// context.append('/path/to', 'foo'); // -> '/path/to/foo' | 27 /// context.append('/path/to', 'foo'); // -> '/path/to/foo' |
| 24 /// | 28 /// |
| 25 /// The given [suffix] cannot be an absolute path or use `..`. | 29 /// The given [suffix] cannot be an absolute path or use `..`. |
| 26 String append(String parent, String suffix) { | 30 String append(String parent, String suffix) { |
| 27 return '$parent$separator$suffix'; | 31 return '$parent$separator$suffix'; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 48 /// context.dirname(r'C:\path'); // -> 'C:\' | 52 /// context.dirname(r'C:\path'); // -> 'C:\' |
| 49 /// context.dirname(r'C:\'); // -> 'C:\' | 53 /// context.dirname(r'C:\'); // -> 'C:\' |
| 50 String dirname(String path) { | 54 String dirname(String path) { |
| 51 int firstIndex = path.indexOf(separator); | 55 int firstIndex = path.indexOf(separator); |
| 52 int lastIndex = path.lastIndexOf(separator); | 56 int lastIndex = path.lastIndexOf(separator); |
| 53 return lastIndex == firstIndex | 57 return lastIndex == firstIndex |
| 54 ? path.substring(0, firstIndex + 1) | 58 ? path.substring(0, firstIndex + 1) |
| 55 : path.substring(0, lastIndex); | 59 : path.substring(0, lastIndex); |
| 56 } | 60 } |
| 57 | 61 |
| 62 /// Return `true` if the given [path] is valid. | |
| 63 /// | |
| 64 /// context.isNormalized('/foo/bar'); // -> true | |
| 65 /// context.isNormalized('/foo/bar/../baz'); // -> false | |
| 66 bool isValid(String path) { | |
| 67 return _isAbsolute(path) && _isNormalized(path); | |
| 68 } | |
| 69 | |
| 58 /// Return `true` if [child] is a path beneath [parent], and `false` | 70 /// Return `true` if [child] is a path beneath [parent], and `false` |
| 59 /// otherwise. Both the [child] and [parent] paths must be absolute paths. | 71 /// otherwise. Both the [child] and [parent] paths must be absolute paths. |
| 60 /// | 72 /// |
| 61 /// context.isWithin('/root/path', '/root/path/a'); // -> true | 73 /// context.isWithin('/root/path', '/root/path/a'); // -> true |
| 62 /// context.isWithin('/root/path', '/root/other'); // -> false | 74 /// context.isWithin('/root/path', '/root/other'); // -> false |
| 63 /// context.isWithin('/root/path', '/root/path'); // -> false | 75 /// context.isWithin('/root/path', '/root/path'); // -> false |
| 64 bool isWithin(String parent, String child) { | 76 bool isWithin(String parent, String child) { |
| 65 int parentLength = parent.length; | 77 int parentLength = parent.length; |
| 66 int childLength = child.length; | 78 int childLength = child.length; |
| 67 if (parentLength >= childLength) { | 79 if (parentLength >= childLength) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 87 /// context.relative('/root/path', '/root/path/a/b.dart'); // -> 'a/b.dart ' | 99 /// context.relative('/root/path', '/root/path/a/b.dart'); // -> 'a/b.dart ' |
| 88 /// context.relative('/root/path', '/root/other.dart'); // -> null | 100 /// context.relative('/root/path', '/root/other.dart'); // -> null |
| 89 String suffix(String parent, String child) { | 101 String suffix(String parent, String child) { |
| 90 String parentPrefix = parent + separator; | 102 String parentPrefix = parent + separator; |
| 91 if (child.startsWith(parentPrefix)) { | 103 if (child.startsWith(parentPrefix)) { |
| 92 return child.substring(parentPrefix.length); | 104 return child.substring(parentPrefix.length); |
| 93 } | 105 } |
| 94 return null; | 106 return null; |
| 95 } | 107 } |
| 96 | 108 |
| 109 /// Return `true` if the given [path] is absolute. | |
| 110 /// | |
| 111 /// _isAbsolute('/foo/bar'); // -> true | |
| 112 /// _isAbsolute('/'); // -> true | |
| 113 /// _isAbsolute('foo/bar'); // -> false | |
| 114 /// _isAbsolute('C:\foo\bar'); // -> true | |
| 115 /// _isAbsolute('C:\'); // -> true | |
| 116 /// _isAbsolute('foo\bar'); // -> false | |
| 117 bool _isAbsolute(String path) { | |
| 118 if (_isWindows) { | |
| 119 return path.length >= 3 && | |
| 120 _isAlphabetic(path.codeUnitAt(0)) && | |
| 121 path.codeUnitAt(1) == _COLON && | |
| 122 path.codeUnitAt(2) == _separatorChar; | |
| 123 } else { | |
| 124 return path.isNotEmpty && path.codeUnitAt(0) == _separatorChar; | |
| 125 } | |
| 126 } | |
| 127 | |
| 128 | |
| 129 /// Return `true` if the given absolute [path] is normalized. | |
| 130 /// | |
| 131 /// _isAbsolute('/foo/bar'); // -> true | |
| 132 /// _isAbsolute('/foo/..bar'); // -> true | |
| 133 /// _isAbsolute('/'); // -> true | |
| 134 /// _isAbsolute('/foo/bar/../baz'); // -> false | |
| 135 /// _isAbsolute('/foo/bar/..'); // -> false | |
|
Brian Wilkerson
2015/12/09 22:58:20
Wrong method name in examples.
| |
| 136 bool _isNormalized(String path) { | |
| 137 int periodCount = 0; | |
| 138 for (int c in path.codeUnits) { | |
| 139 if (c == _PERIOD) { | |
| 140 periodCount++; | |
| 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 } | |
| 152 | |
| 153 /// Returns whether [char] is the code for an ASCII letter (uppercase or | |
| 154 /// lowercase). | |
| 155 static bool _isAlphabetic(int char) { | |
| 156 return char >= _UPPER_A && char <= _UPPER_Z || | |
| 157 char >= _LOWER_A && char <= _LOWER_Z; | |
| 158 } | |
| 159 | |
| 97 /// Return `true` if [str] starts with the given [prefix]. | 160 /// Return `true` if [str] starts with the given [prefix]. |
| 98 /// | 161 /// |
| 99 /// The check is done from the end of [prefix], because absolute paths | 162 /// The check is done from the end of [prefix], because absolute paths |
| 100 /// usually have the same prefix, e.g. the user's home directory. | 163 /// usually have the same prefix, e.g. the user's home directory. |
| 101 static bool _startsWithUnsafe(String str, String prefix) { | 164 static bool _startsWithUnsafe(String str, String prefix) { |
| 102 int len = prefix.length; | 165 int len = prefix.length; |
| 103 for (int i = len - 1; i >= 0; i--) { | 166 for (int i = len - 1; i >= 0; i--) { |
| 104 if (str.codeUnitAt(i) != prefix.codeUnitAt(i)) { | 167 if (str.codeUnitAt(i) != prefix.codeUnitAt(i)) { |
| 105 return false; | 168 return false; |
| 106 } | 169 } |
| 107 } | 170 } |
| 108 return true; | 171 return true; |
| 109 } | 172 } |
| 110 } | 173 } |
| OLD | NEW |