Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for Roslyn rename options #1495

Merged
merged 10 commits into from
Jun 14, 2019
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@
All changes to the project will be documented in this file.

## [1.32.21] - not yet released
* Added support for various renaming options - renaming any symbol can now propagate to comments or strings, and renaming a method symbol can also rename its overloads. They can be set via OmniSharp configuration, such as `omnisharp.json` file (they are disabled by default). (PR: [#1495](https://github.com/OmniSharp/omnisharp-roslyn/pull/1495))

```JSON
{
"RenameOptions": {
"RenameInComments": true,
"RenameOverloads": true,
"RenameInStrings": true
}
}
```
* Fixed a regression on declaration name completion (PR: [#1520](https://github.com/OmniSharp/omnisharp-roslyn/pull/1520))

## [1.32.20] - 2019-06-03
Expand Down
2 changes: 1 addition & 1 deletion src/OmniSharp.Host/WorkspaceInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static void Initialize(IServiceProvider serviceProvider, CompositionHost
try
{
LoggerExtensions.LogInformation(logger, $"Invoking Workspace Options Provider: {providerName}");
workspace.Options = workspaceOptionsProvider.Process(workspace.Options, options.CurrentValue.FormattingOptions);
workspace.Options = workspaceOptionsProvider.Process(workspace.Options, options.CurrentValue);
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace OmniSharp.Roslyn.CSharp.Services
{
[Export(typeof(IWorkspaceOptionsProvider)), Shared]
public class CSharpWorkspaceOptionsProvider : IWorkspaceOptionsProvider
public class CSharpFormattingWorkspaceOptionsProvider : IWorkspaceOptionsProvider
{
private static OptionSet GetOptions(OptionSet optionSet, FormattingOptions formattingOptions)
{
Expand Down Expand Up @@ -93,9 +93,6 @@ private static BinaryOperatorSpacingOptions BinaryOperatorSpacingOptionForString
}
}

public OptionSet Process(OptionSet workOptionSet, FormattingOptions options)
{
return GetOptions(workOptionSet, options);
}
public OptionSet Process(OptionSet workOptionSet, OmniSharpOptions omniSharpOptions) => GetOptions(workOptionSet, omniSharpOptions.FormattingOptions);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Composition;
using Microsoft.CodeAnalysis.Options;
using OmniSharp.Options;
using OmniSharp.Roslyn.Options;
using RoslynRenameOptions = Microsoft.CodeAnalysis.Rename.RenameOptions;

namespace OmniSharp.Roslyn.CSharp.Services
{
[Export(typeof(IWorkspaceOptionsProvider)), Shared]
public class RenameWorkspaceOptionsProvider : IWorkspaceOptionsProvider
{
public OptionSet Process(OptionSet currentOptionSet, OmniSharpOptions omniSharpOptions) =>
currentOptionSet
.WithChangedOption(RoslynRenameOptions.RenameInComments, omniSharpOptions.RenameOptions.RenameInComments)
.WithChangedOption(RoslynRenameOptions.RenameInStrings, omniSharpOptions.RenameOptions.RenameInStrings)
.WithChangedOption(RoslynRenameOptions.RenameOverloads, omniSharpOptions.RenameOptions.RenameOverloads);
}
}
4 changes: 2 additions & 2 deletions src/OmniSharp.Roslyn/Options/IWorkspaceOptionsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ namespace OmniSharp.Roslyn.Options
{
public interface IWorkspaceOptionsProvider
{
OptionSet Process(OptionSet optionSet, FormattingOptions options);
OptionSet Process(OptionSet currentOptionSet, OmniSharpOptions omniSharpOptions);
}
}
}
8 changes: 5 additions & 3 deletions src/OmniSharp.Shared/Options/OmniSharpOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ namespace OmniSharp.Options
{
public class OmniSharpOptions
{
public RoslynExtensionsOptions RoslynExtensionsOptions { get; } = new RoslynExtensionsOptions();
public RoslynExtensionsOptions RoslynExtensionsOptions { get; set; } = new RoslynExtensionsOptions();

public FormattingOptions FormattingOptions { get; } = new FormattingOptions();
public FormattingOptions FormattingOptions { get; set; } = new FormattingOptions();

public FileOptions FileOptions { get; } = new FileOptions();
public FileOptions FileOptions { get; set; } = new FileOptions();

public RenameOptions RenameOptions { get; set; } = new RenameOptions();
}
}
9 changes: 9 additions & 0 deletions src/OmniSharp.Shared/Options/RenameOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace OmniSharp.Options
{
public class RenameOptions
{
public bool RenameOverloads { get; set; } = false;
public bool RenameInStrings { get; set; } = false;
public bool RenameInComments { get; set; } = false;
}
}
11 changes: 7 additions & 4 deletions tests/OmniSharp.Roslyn.CSharp.Tests/FormattingFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,16 @@ public async Task FormatRespectsIndentationSize()

using (var host = CreateOmniSharpHost(testFile))
{
var optionsProvider = new CSharpWorkspaceOptionsProvider();
var optionsProvider = new CSharpFormattingWorkspaceOptionsProvider();

host.Workspace.Options = optionsProvider.Process(host.Workspace.Options,
new FormattingOptions
new OmniSharpOptions
{
NewLine = "\n",
IndentationSize = 1
FormattingOptions = new FormattingOptions
{
NewLine = "\n",
IndentationSize = 1
}
});

var requestHandler = host.GetRequestHandler<CodeFormatService>(OmniSharpEndpoints.CodeFormat);
Expand Down
146 changes: 129 additions & 17 deletions tests/OmniSharp.Roslyn.CSharp.Tests/RenameFacts.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OmniSharp.Models.Rename;
Expand Down Expand Up @@ -46,23 +48,7 @@ public class foo

using (var host = CreateOmniSharpHost(testFile))
{
var result = await PerformRename(host, testFile, "foo", applyTextChanges: true);

var solution = host.Workspace.CurrentSolution;
var documentId = solution.GetDocumentIdsWithFilePath(testFile.FileName).First();
var document = solution.GetDocument(documentId);
var sourceText = await document.GetTextAsync();

var change = result.Changes.Single();

// compare workspace change with response
Assert.Equal(change.Buffer, sourceText.ToString());

// check that response refers to correct modified file
Assert.Equal(change.FileName, testFile.FileName);

// check response for change
Assert.Equal(expectedCode, change.Buffer);
await ValidateRename(host, testFile, expectedCode, async () => await PerformRename(host, testFile, "foo", applyTextChanges: true));
}
}

Expand Down Expand Up @@ -248,6 +234,132 @@ public void Main(bool aBool$$ean)
Assert.Equal(2, changes[0].Changes.Count());
}

[Fact]
public async Task Rename_CanRenameInComments()
{
const string code = @"
using System;

namespace ConsoleApplication
{
/// <summary>
/// This program performs an important work and calls Bar.
/// </summary>
public class Program
{
static void Ba$$r() {}
}
}";

const string expectedCode = @"
using System;

namespace ConsoleApplication
{
/// <summary>
/// This program performs an important work and calls Foo.
/// </summary>
public class Program
{
static void Foo() {}
}
}";

var testFile = new TestFile("test.cs", code);
using (var host = CreateOmniSharpHost(new[] { testFile }, new Dictionary<string, string>
{
["RenameOptions:RenameInComments"] = "true"
}))
{
await ValidateRename(host, testFile, expectedCode, async () => await PerformRename(host, testFile, "Foo", applyTextChanges: true));
}
}

[Fact]
public async Task Rename_CanRenameInOverloads()
{
const string code = @"
public class Foo
{
public void Do$$Stuff() {}

public void DoStuff(int foo) {}

public void DoStuff(int foo, int bar) {}
}";

const string expectedCode = @"
public class Foo
{
public void DoFunnyStuff() {}

public void DoFunnyStuff(int foo) {}

public void DoFunnyStuff(int foo, int bar) {}
}";

var testFile = new TestFile("test.cs", code);
using (var host = CreateOmniSharpHost(new[] { testFile }, new Dictionary<string, string>
{
["RenameOptions:RenameOverloads"] = "true"
}))
{
await ValidateRename(host, testFile, expectedCode, async () => await PerformRename(host, testFile, "DoFunnyStuff", applyTextChanges: true));
}
}

[Fact]
public async Task Rename_CanRenameInStrings()
{
const string code = @"
namespace ConsoleApplication
{
public class Ba$$r
{
public static string Name = ""Bar"";
}
}";

const string expectedCode = @"
namespace ConsoleApplication
{
public class Foo
{
public static string Name = ""Foo"";
}
}";

var testFile = new TestFile("test.cs", code);
using (var host = CreateOmniSharpHost(new[] { testFile }, new Dictionary<string, string>
{
["RenameOptions:RenameInStrings"] = "true"
}))
{
await ValidateRename(host, testFile, expectedCode, async () => await PerformRename(host, testFile, "Foo", applyTextChanges: true));
}
}

private async Task ValidateRename(OmniSharpTestHost host, TestFile testFile, string expectedCode, Func<Task<RenameResponse>> rename)
{
var result = await rename();

var solution = host.Workspace.CurrentSolution;
var documentId = solution.GetDocumentIdsWithFilePath(testFile.FileName).First();
var document = solution.GetDocument(documentId);
var sourceText = await document.GetTextAsync();

var change = result.Changes.Single();

// compare workspace change with response
Assert.Equal(change.Buffer, sourceText.ToString());

// check that response refers to correct modified file
Assert.Equal(change.FileName, testFile.FileName);

// check response for change
Assert.Equal(expectedCode, change.Buffer);
}

private Task<RenameResponse> PerformRename(
TestFile testFile, string renameTo,
bool wantsTextChanges = false,
Expand Down