diff --git a/CHANGELOG.md b/CHANGELOG.md index 4515a91339..e04ba66d2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ All changes to the project will be documented in this file. ## [1.34.9] - not yet released +* Line pragma is now respected in find references ([#1649](https://github.com/OmniSharp/omnisharp-roslyn/issues/1649), PR:[#1660](https://github.com/OmniSharp/omnisharp-roslyn/pull/1660)) * Do not set mono paths when running in standalone mode ([omnisharp-vscode#3410](https://github.com/OmniSharp/omnisharp-vscode/issues/3410), [omnisharp-vscode#3340](https://github.com/OmniSharp/omnisharp-vscode/issues/3340), [#1650](https://github.com/OmniSharp/omnisharp-roslyn/issues/1650), PR:[#1656](https://github.com/OmniSharp/omnisharp-roslyn/pull/1656)) * Fixed a bug where OmniSharp would crash on startup if the path contained `=` sign ([omnisharp-vscode#3436](https://github.com/OmniSharp/omnisharp-vscode/issues/3436), PR:[#1661](https://github.com/OmniSharp/omnisharp-roslyn/pull/1661)) diff --git a/src/OmniSharp.Roslyn.CSharp/Helpers/LocationExtensions.cs b/src/OmniSharp.Roslyn.CSharp/Helpers/LocationExtensions.cs index c844c2c6c3..bbc1e8e082 100644 --- a/src/OmniSharp.Roslyn.CSharp/Helpers/LocationExtensions.cs +++ b/src/OmniSharp.Roslyn.CSharp/Helpers/LocationExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis; @@ -13,7 +14,9 @@ public static QuickFix GetQuickFix(this Location location, OmniSharpWorkspace wo if (!location.IsInSource) throw new Exception("Location is not in the source tree"); - var lineSpan = location.GetLineSpan(); + var lineSpan = Path.GetExtension(location.SourceTree.FilePath).Equals(".cake", StringComparison.OrdinalIgnoreCase) + ? location.GetLineSpan() + : location.GetMappedLineSpan(); var path = lineSpan.Path; var documents = workspace.GetDocuments(path); @@ -25,9 +28,9 @@ public static QuickFix GetQuickFix(this Location location, OmniSharpWorkspace wo Text = text.Trim(), FileName = path, Line = line, - Column = lineSpan.StartLinePosition.Character, + Column = lineSpan.HasMappedPath ? 0 : lineSpan.StartLinePosition.Character, // when a #line directive maps into a separate file, assume columns (0,0) EndLine = lineSpan.EndLinePosition.Line, - EndColumn = lineSpan.EndLinePosition.Character, + EndColumn = lineSpan.HasMappedPath ? 0 : lineSpan.EndLinePosition.Character, Projects = documents.Select(document => document.Project.Name).ToArray() }; } diff --git a/tests/OmniSharp.Roslyn.CSharp.Tests/FindReferencesFacts.cs b/tests/OmniSharp.Roslyn.CSharp.Tests/FindReferencesFacts.cs index 1c39a37c5c..962e16eb00 100644 --- a/tests/OmniSharp.Roslyn.CSharp.Tests/FindReferencesFacts.cs +++ b/tests/OmniSharp.Roslyn.CSharp.Tests/FindReferencesFacts.cs @@ -116,6 +116,79 @@ public FooConsumer() Assert.Equal(2, usages.QuickFixes.Count()); } + [Fact] + public async Task CanFindReferencesWithLineMapping() + { + const string code = @" + public class Foo + { + public void b$$ar() { } + } + + public class FooConsumer + { + public FooConsumer() + { +#line 1 + new Foo().bar(); +#line default + } + }"; + + var usages = await FindUsagesAsync(code); + Assert.Equal(2, usages.QuickFixes.Count()); + + var mappedResult = usages.QuickFixes.FirstOrDefault(x => x.Line == 0); + var regularResult = usages.QuickFixes.FirstOrDefault(x => x.Line == 3); + Assert.NotNull(mappedResult); + Assert.NotNull(regularResult); + + // regular result has regular postition + Assert.Equal(32, regularResult.Column); + Assert.Equal(35, regularResult.EndColumn); + } + + [Fact] + public async Task CanFindReferencesWithLineMappingAcrossFiles() + { + var testFiles = new[] + { + new TestFile("a.cs", @" + public class Foo + { + public void b$$ar() { } + } + + public class FooConsumer + { + public FooConsumer() + { +#line 1 ""b.cs"" + new Foo().bar(); +#line default + } + }"), + new TestFile("b.cs", + @"// hello") + }; + + var usages = await FindUsagesAsync(testFiles, onlyThisFile: false); + Assert.Equal(2, usages.QuickFixes.Count()); + + var mappedResult = usages.QuickFixes.FirstOrDefault(x => x.Line == 0 && x.FileName == "b.cs"); + var regularResult = usages.QuickFixes.FirstOrDefault(x => x.Line == 3 && x.FileName == "a.cs"); + Assert.NotNull(mappedResult); + Assert.NotNull(regularResult); + + // regular result has regular postition + Assert.Equal(32, regularResult.Column); + Assert.Equal(35, regularResult.EndColumn); + + // mapped result has column 0,0 + Assert.Equal(0, mappedResult.Column); + Assert.Equal(0, mappedResult.EndColumn); + } + [Fact] public async Task ExcludesMethodDefinition() {