Chromium Code Reviews| Index: sdk/lib/io/path_impl.dart |
| diff --git a/sdk/lib/io/path_impl.dart b/sdk/lib/io/path_impl.dart |
| index a42a290e5215d7c5361fc57f79ad5dc3e4ffa965..62d6e93ee41a002e4a1a4b091d600a69103124f8 100644 |
| --- a/sdk/lib/io/path_impl.dart |
| +++ b/sdk/lib/io/path_impl.dart |
| @@ -46,17 +46,47 @@ class _Path implements Path { |
| Path relativeTo(Path base) { |
| // Returns a path "relative" such that |
| - // base.join(relative) == this.canonicalize. |
| + // base.join(relative) == this.canonicalize. |
| // Throws exception if an impossible case is reached. |
| if (base.isAbsolute != isAbsolute || |
| base.isWindowsShare != isWindowsShare) { |
| - throw new ArgumentError( |
| - "Invalid case of Path.relativeTo(base):\n" |
| - " Path and base must both be relative, or both absolute.\n" |
| - " Arguments: $_path.relativeTo($base)"); |
| + throw new ArgumentError(""" |
|
Søren Gjesse
2013/03/14 13:53:32
Please keep using concatenation of adjacent string
|
| +Invalid case of Path.relativeTo(base): |
| + Path and base must both be relative, or both absolute. |
| + Arguments: $_path.relativeTo($base)"""); |
| } |
| var basePath = base.toString(); |
| + // Handle drive letters specially on Windows. |
| + if (base.isAbsolute && Platform.operatingSystem == 'windows') { |
| + bool baseHasDrive = |
| + basePath.length >= 4 && basePath[2] == ':' && basePath[3] == '/'; |
| + bool pathHasDrive = |
| + _path.length >= 4 && _path[2] == ':' && _path[3] == '/'; |
| + if (baseHasDrive && pathHasDrive) { |
| + int baseDrive = basePath.codeUnitAt(1) | 32; // Convert to uppercase. |
| + if (baseDrive >= 'a'.codeUnitAt(0) && |
| + baseDrive <= 'z'.codeUnitAt(0) && |
| + baseDrive == (_path.codeUnitAt(1) | 32)) { |
| + if(basePath[1] != _path[1]) { |
| + // Replace the drive letter in basePath with that from _path. |
| + basePath = '/${_path[1]}:/${basePath.substring(4)}'; |
| + base = new Path(basePath); |
| + } |
| + } else { |
| + throw new ArgumentError(""" |
| +Invalid case of Path.relativeTo(base): |
| + Base path and target path are on different Windows drives. |
| + Arguments: $_path.relativeTo($base)"""); |
| + } |
| + } else if (baseHasDrive != pathHasDrive) { |
| + throw new ArgumentError(""" |
| +Invalid case of Path.relativeTo(base): |
| + Base path must start with a drive letter if and only if target path does. |
| + Arguments: $_path.relativeTo($base)"""); |
| + } |
| + |
| + } |
| if (_path.startsWith(basePath)) { |
| if (_path == basePath) return new Path('.'); |
| // There must be a '/' at the end of the match, or immediately after. |
| @@ -86,10 +116,10 @@ class _Path implements Path { |
| final segments = new List<String>(); |
| if (common < baseSegments.length && baseSegments[common] == '..') { |
| - throw new ArgumentError( |
| - "Invalid case of Path.relativeTo(base):\n" |
| - " Base path has more '..'s than path does." |
| - " Arguments: $_path.relativeTo($base)"); |
| + throw new ArgumentError(""" |
| +Invalid case of Path.relativeTo(base): |
| + Base path has more '..'s than path does. |
| + Arguments: $_path.relativeTo($base)"""); |
| } |
| for (int i = common; i < baseSegments.length; i++) { |
| segments.add('..'); |