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

Side by Side Diff: packages/analyzer/lib/src/util/absolute_path.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 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
« no previous file with comments | « packages/analyzer/lib/src/task/yaml.dart ('k') | packages/analyzer/lib/src/util/asserts.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library analyzer.src.util.absolute_path;
6
7 /// The class for manipulating absolute, normalized paths.
8 class AbsolutePathContext {
9 static const int _COLON = 0x3A;
10 static const int _LOWER_A = 0x61;
11 static const int _LOWER_Z = 0x7A;
12 static const int _UPPER_A = 0x41;
13 static const int _UPPER_Z = 0x5A;
14
15 final bool _isWindows;
16 String separator;
17 int _separatorChar;
18 String _singlePeriodComponent;
19 String _doublePeriodComponent;
20 String _singlePeriodEnding;
21 String _doublePeriodEnding;
22
23 AbsolutePathContext(this._isWindows) {
24 separator = _isWindows ? r'\' : '/';
25 _separatorChar = separator.codeUnitAt(0);
26 _singlePeriodComponent = separator + '.' + separator;
27 _doublePeriodComponent = separator + '..' + separator;
28 _singlePeriodEnding = separator + '.';
29 _doublePeriodEnding = separator + '..';
30 }
31
32 /// Append the given relative [suffix] to the given absolute [parent].
33 ///
34 /// context.append('/path/to', 'foo'); // -> '/path/to/foo'
35 ///
36 /// The given [suffix] cannot be an absolute path or use `..`.
37 String append(String parent, String suffix) {
38 return '$parent$separator$suffix';
39 }
40
41 /// Return the part of the absolute [path] after the last separator on the
42 /// context's platform.
43 ///
44 /// context.basename('/path/to/foo.dart'); // -> 'foo.dart'
45 /// context.basename('/path/to'); // -> 'to'
46 /// context.basename('/path'); // -> 'path'
47 /// context.basename('/'); // -> ''
48 String basename(String path) {
49 int index = path.lastIndexOf(separator);
50 return path.substring(index + 1);
51 }
52
53 /// Return the part of the absolute [path] before the last separator.
54 ///
55 /// context.dirname('/path/to/foo.dart'); // -> '/path/to'
56 /// context.dirname('/path/to'); // -> '/path'
57 /// context.dirname(r'/path'); // -> '/'
58 /// context.dirname(r'/'); // -> '/'
59 /// context.dirname(r'C:\path'); // -> 'C:\'
60 /// context.dirname(r'C:\'); // -> 'C:\'
61 String dirname(String path) {
62 int firstIndex = path.indexOf(separator);
63 int lastIndex = path.lastIndexOf(separator);
64 return lastIndex == firstIndex
65 ? path.substring(0, firstIndex + 1)
66 : path.substring(0, lastIndex);
67 }
68
69 /// Return `true` if the given [path] is valid.
70 ///
71 /// context.isNormalized('/foo/bar'); // -> true
72 /// context.isNormalized('/foo/bar/../baz'); // -> false
73 bool isValid(String path) {
74 return _isAbsolute(path) && _isNormalized(path);
75 }
76
77 /// Return `true` if [child] is a path beneath [parent], and `false`
78 /// otherwise. Both the [child] and [parent] paths must be absolute paths.
79 ///
80 /// context.isWithin('/root/path', '/root/path/a'); // -> true
81 /// context.isWithin('/root/path', '/root/other'); // -> false
82 /// context.isWithin('/root/path', '/root/path'); // -> false
83 bool isWithin(String parent, String child) {
84 int parentLength = parent.length;
85 int childLength = child.length;
86 if (parentLength >= childLength) {
87 return false;
88 }
89 if (child.codeUnitAt(parentLength) != _separatorChar) {
90 return false;
91 }
92 return _startsWithUnsafe(child, parent);
93 }
94
95 /// Split [path] into its components using [separator].
96 ///
97 /// context.split('/path/to/foo'); // -> ['', 'path', 'to', 'foo']
98 List<String> split(String path) {
99 return path.split(separator);
100 }
101
102 /// If the given [child] is within the given [parent], then return the
103 /// relative path from [parent] to [child]. Otherwise return `null`. Both
104 /// the [child] and [parent] paths must be absolute paths.
105 ///
106 /// context.relative('/root/path', '/root/path/a/b.dart'); // -> 'a/b.dart '
107 /// context.relative('/root/path', '/root/other.dart'); // -> null
108 String suffix(String parent, String child) {
109 String parentPrefix = parent + separator;
110 if (child.startsWith(parentPrefix)) {
111 return child.substring(parentPrefix.length);
112 }
113 return null;
114 }
115
116 /// Return `true` if the given [path] is absolute.
117 ///
118 /// _isAbsolute('/foo/bar'); // -> true
119 /// _isAbsolute('/'); // -> true
120 /// _isAbsolute('foo/bar'); // -> false
121 /// _isAbsolute('C:\foo\bar'); // -> true
122 /// _isAbsolute('C:\'); // -> true
123 /// _isAbsolute('foo\bar'); // -> false
124 bool _isAbsolute(String path) {
125 if (_isWindows) {
126 return path.length >= 3 &&
127 _isAlphabetic(path.codeUnitAt(0)) &&
128 path.codeUnitAt(1) == _COLON &&
129 path.codeUnitAt(2) == _separatorChar;
130 } else {
131 return path.isNotEmpty && path.codeUnitAt(0) == _separatorChar;
132 }
133 }
134
135 /// Return `true` if the given absolute [path] is normalized.
136 ///
137 /// _isNormalized('/foo/bar'); // -> true
138 /// _isNormalized('/foo/..bar'); // -> true
139 /// _isNormalized('/foo/bar..'); // -> true
140 /// _isNormalized('/'); // -> true
141 /// _isNormalized('/foo/bar/../baz'); // -> false
142 /// _isNormalized('/foo/bar/..'); // -> false
143 bool _isNormalized(String path) {
144 return !path.contains(_singlePeriodComponent) &&
145 !path.contains(_doublePeriodComponent) &&
146 !path.endsWith(_singlePeriodEnding) &&
147 !path.endsWith(_doublePeriodEnding);
148 }
149
150 /// Returns whether [char] is the code for an ASCII letter (uppercase or
151 /// lowercase).
152 static bool _isAlphabetic(int char) {
153 return char >= _UPPER_A && char <= _UPPER_Z ||
154 char >= _LOWER_A && char <= _LOWER_Z;
155 }
156
157 /// Return `true` if [str] starts with the given [prefix].
158 ///
159 /// The check is done from the end of [prefix], because absolute paths
160 /// usually have the same prefix, e.g. the user's home directory.
161 static bool _startsWithUnsafe(String str, String prefix) {
162 int len = prefix.length;
163 for (int i = len - 1; i >= 0; i--) {
164 if (str.codeUnitAt(i) != prefix.codeUnitAt(i)) {
165 return false;
166 }
167 }
168 return true;
169 }
170 }
OLDNEW
« no previous file with comments | « packages/analyzer/lib/src/task/yaml.dart ('k') | packages/analyzer/lib/src/util/asserts.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698