Skip to content

Commit 387d7cf

Browse files
committed
Ensure unique file paths for non-file Uris
1 parent b8752a0 commit 387d7cf

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/UriExtensions.cs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,25 +37,36 @@ public static string GetAbsoluteOrUNCPath(this Uri uri)
3737
// Absolute paths are usually encoded.
3838
var absolutePath = uri.AbsolutePath.Contains("%") ? WebUtility.UrlDecode(uri.AbsolutePath) : uri.AbsolutePath;
3939

40-
if (string.Equals(uri.Scheme, "git", StringComparison.OrdinalIgnoreCase))
41-
{
42-
// return a normalized path when we want to add to a fake git directory path (hacky fix for https://github.com/dotnet/razor/issues/9365)
43-
return AddToFakeGitDirectoryAtRoot(absolutePath);
44-
}
45-
46-
return absolutePath;
40+
return EnsureUniquePathForScheme(uri.Scheme, absolutePath);
4741
}
4842

49-
private static string AddToFakeGitDirectoryAtRoot(string decodedAbsolutePath)
43+
private static string EnsureUniquePathForScheme(string scheme, string decodedAbsolutePath)
5044
{
45+
// File Uris we leave untouched, as they represent the actual files on disk
46+
if (scheme == Uri.UriSchemeFile)
47+
{
48+
return decodedAbsolutePath;
49+
}
50+
5151
var normalizedPath = FilePathNormalizer.Normalize(decodedAbsolutePath);
5252
var firstSeparatorIndex = normalizedPath.IndexOf('/');
5353
if (firstSeparatorIndex < 0)
5454
{
55-
// no-op
55+
// A path without a separator is unlikely, but we can't add our unique-ness marker anyway, so just return as is
56+
// and hope for the best.
5657
return decodedAbsolutePath;
5758
}
5859

59-
return normalizedPath.Insert(firstSeparatorIndex + 1, "_git_/");
60+
// For any non-file Uri, we add a marker to the path to ensure things won't conflict with the real file on disk.
61+
// This is a somewhat hacky fix to ensure things like a git diff view will work, where the left hand side is a
62+
// Uri like "git://path/to/file.razor" and the right hand side is "file://path/to/file.razor". If we mapped both
63+
// of those to the same file path, then one side would be sending line and character positions that don't match
64+
// our understanding of the document.
65+
// A true fix would be to move away from using file paths in the first place, but instead use the Uris as provided
66+
// by the LSP client as the source of truth.
67+
// See https://github.com/dotnet/razor/issues/9365 and https://github.com/microsoft/vscode-dotnettools/issues/2151
68+
// for examples.
69+
70+
return normalizedPath.Insert(firstSeparatorIndex + 1, $"_{scheme}_/");
6071
}
6172
}

src/Razor/test/Microsoft.CodeAnalysis.Razor.Workspaces.Test/UriExtensionsTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public void GetAbsoluteOrUNCPath_AbsolutePath_HandlesSpacePaths()
6060
[InlineData(@"git:/c%3A/path/to/dir/Index.cshtml", @"c:/_git_/path/to/dir/Index.cshtml")]
6161
[InlineData(@"git:/c:/path%2Fto/dir/Index.cshtml?%7B%22p", @"c:/_git_/path/to/dir/Index.cshtml")]
6262
[InlineData(@"git:/c:/path/to/dir/Index.cshtml", @"c:/_git_/path/to/dir/Index.cshtml")]
63+
[InlineData(@"chat-editing-text-model:/c:/path/to/dir/Index.cshtml", @"c:/_chat-editing-text-model_/path/to/dir/Index.cshtml")]
6364
public void GetAbsoluteOrUNCPath_AbsolutePath_HandlesGitScheme(string filePath, string expected)
6465
{
6566
// Arrange

0 commit comments

Comments
 (0)