| 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 paths. |
| 8 class AbsolutePathContext { | 8 class AbsolutePathContext { |
| 9 final String separator; | 9 final String separator; |
| 10 | 10 |
| 11 AbsolutePathContext(this.separator); | 11 int _separatorChar; |
| 12 |
| 13 AbsolutePathContext(this.separator) { |
| 14 if (separator.length != 1) { |
| 15 throw new ArgumentError.value( |
| 16 separator, 'separator', 'must be exactly one character long'); |
| 17 } |
| 18 _separatorChar = separator.codeUnitAt(0); |
| 19 } |
| 12 | 20 |
| 13 /// Append the given relative [suffix] to the given absolute [parent]. | 21 /// Append the given relative [suffix] to the given absolute [parent]. |
| 14 /// | 22 /// |
| 15 /// context.append('/path/to', 'foo'); // -> '/path/to/foo' | 23 /// context.append('/path/to', 'foo'); // -> '/path/to/foo' |
| 16 /// | 24 /// |
| 17 /// The given [suffix] cannot be an absolute path or use `..`. | 25 /// The given [suffix] cannot be an absolute path or use `..`. |
| 18 String append(String parent, String suffix) { | 26 String append(String parent, String suffix) { |
| 19 return '$parent$separator$suffix'; | 27 return '$parent$separator$suffix'; |
| 20 } | 28 } |
| 21 | 29 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 47 : path.substring(0, lastIndex); | 55 : path.substring(0, lastIndex); |
| 48 } | 56 } |
| 49 | 57 |
| 50 /// Return `true` if [child] is a path beneath [parent], and `false` | 58 /// Return `true` if [child] is a path beneath [parent], and `false` |
| 51 /// otherwise. Both the [child] and [parent] paths must be absolute paths. | 59 /// otherwise. Both the [child] and [parent] paths must be absolute paths. |
| 52 /// | 60 /// |
| 53 /// context.isWithin('/root/path', '/root/path/a'); // -> true | 61 /// context.isWithin('/root/path', '/root/path/a'); // -> true |
| 54 /// context.isWithin('/root/path', '/root/other'); // -> false | 62 /// context.isWithin('/root/path', '/root/other'); // -> false |
| 55 /// context.isWithin('/root/path', '/root/path'); // -> false | 63 /// context.isWithin('/root/path', '/root/path'); // -> false |
| 56 bool isWithin(String parent, String child) { | 64 bool isWithin(String parent, String child) { |
| 57 return child.startsWith(parent + separator); | 65 int parentLength = parent.length; |
| 66 int childLength = child.length; |
| 67 if (parentLength >= childLength) { |
| 68 return false; |
| 69 } |
| 70 if (child.codeUnitAt(parentLength) != _separatorChar) { |
| 71 return false; |
| 72 } |
| 73 return _startsWithUnsafe(child, parent); |
| 58 } | 74 } |
| 59 | 75 |
| 60 /// Split [path] into its components using [separator]. | 76 /// Split [path] into its components using [separator]. |
| 61 /// | 77 /// |
| 62 /// context.split('/path/to/foo'); // -> ['', 'path', 'to', 'foo'] | 78 /// context.split('/path/to/foo'); // -> ['', 'path', 'to', 'foo'] |
| 63 List<String> split(String path) { | 79 List<String> split(String path) { |
| 64 return path.split(separator); | 80 return path.split(separator); |
| 65 } | 81 } |
| 66 | 82 |
| 67 /// If the given [child] is within the given [parent], then return the | 83 /// If the given [child] is within the given [parent], then return the |
| 68 /// relative path from [parent] to [child]. Otherwise return `null`. Both | 84 /// relative path from [parent] to [child]. Otherwise return `null`. Both |
| 69 /// the [child] and [parent] paths must be absolute paths. | 85 /// the [child] and [parent] paths must be absolute paths. |
| 70 /// | 86 /// |
| 71 /// context.relative('/root/path/a/b.dart', '/root/path'); // -> 'a/b.dart
' | 87 /// context.relative('/root/path', '/root/path/a/b.dart'); // -> 'a/b.dart
' |
| 72 /// context.relative('/root/other.dart', '/root/path'); // -> null | 88 /// context.relative('/root/path', '/root/other.dart'); // -> null |
| 73 String suffix(String child, String parent) { | 89 String suffix(String parent, String child) { |
| 74 String parentPrefix = parent + separator; | 90 String parentPrefix = parent + separator; |
| 75 if (child.startsWith(parentPrefix)) { | 91 if (child.startsWith(parentPrefix)) { |
| 76 return child.substring(parentPrefix.length); | 92 return child.substring(parentPrefix.length); |
| 77 } | 93 } |
| 78 return null; | 94 return null; |
| 79 } | 95 } |
| 96 |
| 97 /// Return `true` if [str] starts with the given [prefix]. |
| 98 /// |
| 99 /// 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. |
| 101 static bool _startsWithUnsafe(String str, String prefix) { |
| 102 int len = prefix.length; |
| 103 for (int i = len - 1; i >= 0; i--) { |
| 104 if (str.codeUnitAt(i) != prefix.codeUnitAt(i)) { |
| 105 return false; |
| 106 } |
| 107 } |
| 108 return true; |
| 109 } |
| 80 } | 110 } |
| OLD | NEW |