Skip to content

Commit 61d029a

Browse files
DocumentUri adjustments (#237)
* DocumentUri adjustments * break apart tests for more clarity (ie stop being lazy) and added support for UNC paths Co-authored-by: David Driscoll <[email protected]>
1 parent eb09697 commit 61d029a

9 files changed

+559
-316
lines changed

src/Protocol/DocumentUri.cs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,25 @@ public DocumentUri(string url)
2323
var delimiterIndex = url.IndexOf(SchemeDelimiter, StringComparison.Ordinal);
2424
if (delimiterIndex == -1)
2525
{
26-
url = Uri.UnescapeDataString(url).Replace('\\', '/');
26+
// Unc path
27+
if (url.StartsWith("\\\\"))
28+
{
29+
var authorityEndIndex = url.IndexOf('\\', 2);
30+
Authority = url.Substring(2, authorityEndIndex - 2);
31+
url = url.Substring(authorityEndIndex);
32+
// Path = Uri.UnescapeDataString(url);
33+
}
34+
else
35+
{
36+
Authority = string.Empty;
37+
}
38+
39+
url = url.Replace('\\', '/');
2740

2841
Scheme = UriSchemeFile;
29-
Authority = string.Empty;
3042
Query = string.Empty;
3143
Fragment = string.Empty;
32-
Path = Uri.UnescapeDataString(url).TrimStart('/');
44+
Path = Uri.UnescapeDataString(url.StartsWith("/") ? url : "/" + url);
3345

3446
return;
3547
}
@@ -40,6 +52,15 @@ public DocumentUri(string url)
4052
Authority = url.Substring(delimiterIndex + SchemeDelimiter.Length,
4153
authorityIndex - (delimiterIndex + SchemeDelimiter.Length));
4254

55+
// this is a possible windows path without the proper tripple slash
56+
// file://c:/some/path.file.cs
57+
// We need deal with this case.
58+
if (Authority.IndexOf(':') > -1 || Authority.IndexOf("%3a", StringComparison.OrdinalIgnoreCase) > -1)
59+
{
60+
Authority = string.Empty;
61+
authorityIndex = delimiterIndex + SchemeDelimiter.Length;
62+
}
63+
4364
var fragmentIndex = url.IndexOf('#');
4465
if (fragmentIndex > -1)
4566
{
@@ -62,8 +83,7 @@ public DocumentUri(string url)
6283
queryIndex = fragmentIndex;
6384
}
6485

65-
Path = Uri.UnescapeDataString(url.Substring(authorityIndex + 1, queryIndex - (authorityIndex)))
66-
.TrimStart('/');
86+
Path = Uri.UnescapeDataString(url.Substring(authorityIndex, queryIndex - (authorityIndex) + 1));
6787
}
6888

6989
/// <summary>
@@ -133,7 +153,7 @@ public Uri ToUri()
133153
/// <returns></returns>
134154
/// <remarks>This will not a uri encode asian and cyrillic characters</remarks>
135155
public override string ToString() =>
136-
$"{Scheme}{SchemeDelimiter}{Authority}/{Path}{(string.IsNullOrWhiteSpace(Query) ? "" : "?" + Query)}{(string.IsNullOrWhiteSpace(Fragment) ? "" : "#" + Fragment)}";
156+
$"{Scheme}{SchemeDelimiter}{Authority}{Path}{(string.IsNullOrWhiteSpace(Query) ? "" : "?" + Query)}{(string.IsNullOrWhiteSpace(Fragment) ? "" : "#" + Fragment)}";
137157

138158
/// <summary>
139159
/// Gets the file system path prefixed with / for unix platforms
@@ -143,7 +163,11 @@ public override string ToString() =>
143163
public string GetFileSystemPath()
144164
{
145165
// The language server protocol represents "C:\Foo\Bar" as "file:///c:/foo/bar".
146-
return Path.IndexOf(':') == -1 ? "/" + Path : Path.Replace('/', '\\');
166+
if (Path.IndexOf(':') == -1 && !(Scheme == UriSchemeFile && !string.IsNullOrWhiteSpace(Authority)))
167+
return Path;
168+
if (!string.IsNullOrWhiteSpace(Authority))
169+
return $"\\\\{Authority}{Path}".Replace('/', '\\');
170+
return Path.TrimStart('/').Replace('/', '\\');
147171
}
148172

149173
/// <inheritdoc />

src/Protocol/Models/DocumentFilter.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,19 @@ public bool IsMatch(TextDocumentAttributes attributes)
7878
{
7979
if (HasLanguage && HasPattern && HasScheme)
8080
{
81-
return Language == attributes.LanguageId && Scheme == attributes.Scheme && _minimatcher.IsMatch(attributes.Uri.Path);
81+
return Language == attributes.LanguageId && Scheme == attributes.Scheme && _minimatcher.IsMatch(attributes.Uri.ToString());
8282
}
8383
if (HasLanguage && HasPattern)
8484
{
85-
return Language == attributes.LanguageId && _minimatcher.IsMatch(attributes.Uri.Path);
85+
return Language == attributes.LanguageId && _minimatcher.IsMatch(attributes.Uri.ToString());
8686
}
8787
if (HasLanguage && HasScheme)
8888
{
8989
return Language == attributes.LanguageId && Scheme == attributes.Scheme;
9090
}
9191
if (HasPattern && HasScheme)
9292
{
93-
return Scheme == attributes.Scheme && _minimatcher.IsMatch(attributes.Uri.Path);
93+
return Scheme == attributes.Scheme && _minimatcher.IsMatch(attributes.Uri.ToString());
9494
}
9595
if (HasLanguage)
9696
{
@@ -102,7 +102,7 @@ public bool IsMatch(TextDocumentAttributes attributes)
102102
}
103103
if (HasPattern)
104104
{
105-
return _minimatcher.IsMatch(attributes.Uri.Path);
105+
return _minimatcher.IsMatch(attributes.Uri.ToString());
106106
}
107107

108108
return false;

test/Lsp.Tests/AbsoluteUriConverterTests.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ public AbsoluteUriConverterTests(ITestOutputHelper testOutputHelper)
1717
}
1818

1919
[Theory]
20-
[ClassData(typeof(DocumentUriTestData.StringUris))]
20+
[ClassData(typeof(DocumentUriTests.WindowsPathStringUris))]
21+
[ClassData(typeof(DocumentUriTests.WindowsPathAltStringUris))]
22+
[ClassData(typeof(DocumentUriTests.UncPathStringUris))]
23+
[ClassData(typeof(DocumentUriTests.UnixPathStringUris))]
2124
public void Should_Deserialize_VSCode_Style_Uris(string uri, DocumentUri expected)
2225
{
2326
_testOutputHelper.WriteLine($"Given: {uri}");
@@ -29,7 +32,10 @@ public void Should_Deserialize_VSCode_Style_Uris(string uri, DocumentUri expecte
2932
}
3033

3134
[Theory]
32-
[ClassData(typeof(DocumentUriTestData.StringUris))]
35+
[ClassData(typeof(DocumentUriTests.WindowsPathStringUris))]
36+
[ClassData(typeof(DocumentUriTests.WindowsPathAltStringUris))]
37+
[ClassData(typeof(DocumentUriTests.UncPathStringUris))]
38+
[ClassData(typeof(DocumentUriTests.UnixPathStringUris))]
3339
public void Should_Serialize_VSCode_Style_Uris(string uri, DocumentUri expected)
3440
{
3541
_testOutputHelper.WriteLine($"Given: {uri}");

0 commit comments

Comments
 (0)