-
Notifications
You must be signed in to change notification settings - Fork 418
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1672 from OmniSharp/feature/implement-type-options
added implement type options
- Loading branch information
Showing
4 changed files
with
210 additions
and
0 deletions.
There are no files selected for viewing
51 changes: 51 additions & 0 deletions
51
src/OmniSharp.Roslyn.CSharp/Services/ImplementTypeWorkspaceOptionsProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
using System; | ||
using System.Composition; | ||
using System.Reflection; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.Options; | ||
using OmniSharp.Options; | ||
using OmniSharp.Roslyn.Options; | ||
using OmniSharp.Services; | ||
using OmniSharp.Utilities; | ||
|
||
namespace OmniSharp.Roslyn.CSharp.Services | ||
{ | ||
[Export(typeof(IWorkspaceOptionsProvider)), Shared] | ||
public class ImplementTypeWorkspaceOptionsProvider : IWorkspaceOptionsProvider | ||
{ | ||
private readonly IAssemblyLoader _assemblyLoader; | ||
private readonly Lazy<Assembly> _csharpFeatureAssembly; | ||
private readonly Lazy<Type> _implementTypeOptions; | ||
|
||
[ImportingConstructor] | ||
public ImplementTypeWorkspaceOptionsProvider(IAssemblyLoader assemblyLoader) | ||
{ | ||
_assemblyLoader = assemblyLoader; | ||
_csharpFeatureAssembly = _assemblyLoader.LazyLoad(Configuration.RoslynFeatures); | ||
_implementTypeOptions = _csharpFeatureAssembly.LazyGetType("Microsoft.CodeAnalysis.ImplementType.ImplementTypeOptions"); | ||
} | ||
|
||
public int Order => 110; | ||
|
||
public OptionSet Process(OptionSet currentOptionSet, OmniSharpOptions omniSharpOptions, IOmniSharpEnvironment omnisharpEnvironment) | ||
{ | ||
if (omniSharpOptions.ImplementTypeOptions.InsertionBehavior != null) | ||
{ | ||
if (_implementTypeOptions.Value.GetField("InsertionBehavior", BindingFlags.Public | BindingFlags.Static)?.GetValue(null) is IOption insertionBehaviorOptionValue) | ||
{ | ||
currentOptionSet = currentOptionSet.WithChangedOption(new OptionKey(insertionBehaviorOptionValue, LanguageNames.CSharp), (int)omniSharpOptions.ImplementTypeOptions.InsertionBehavior); | ||
} | ||
} | ||
|
||
if (omniSharpOptions.ImplementTypeOptions.PropertyGenerationBehavior != null) | ||
{ | ||
if (_implementTypeOptions.Value.GetField("PropertyGenerationBehavior", BindingFlags.Public | BindingFlags.Static)?.GetValue(null) is IOption propertyGenerationBehaviorOptionValue) | ||
{ | ||
currentOptionSet = currentOptionSet.WithChangedOption(new OptionKey(propertyGenerationBehaviorOptionValue, LanguageNames.CSharp), (int)omniSharpOptions.ImplementTypeOptions.PropertyGenerationBehavior); | ||
} | ||
} | ||
|
||
return currentOptionSet; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace OmniSharp.Options | ||
{ | ||
public class ImplementTypeOptions | ||
{ | ||
public ImplementTypeInsertionBehavior? InsertionBehavior { get; set; } | ||
public ImplementTypePropertyGenerationBehavior? PropertyGenerationBehavior { get; set; } | ||
} | ||
|
||
public enum ImplementTypeInsertionBehavior | ||
{ | ||
WithOtherMembersOfTheSameKind = 0, | ||
AtTheEnd = 1, | ||
} | ||
|
||
public enum ImplementTypePropertyGenerationBehavior | ||
{ | ||
PreferThrowingProperties = 0, | ||
PreferAutoProperties = 1, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
tests/OmniSharp.Roslyn.CSharp.Tests/ImplementTypeFacts.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using OmniSharp.Models; | ||
using OmniSharp.Models.V2.CodeActions; | ||
using OmniSharp.Roslyn.CSharp.Services.Refactoring.V2; | ||
using TestUtility; | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
|
||
namespace OmniSharp.Roslyn.CSharp.Tests | ||
{ | ||
public class ImplementTypeFacts : AbstractCodeActionsTestFixture | ||
{ | ||
public ImplementTypeFacts(ITestOutputHelper output) | ||
: base(output) | ||
{ | ||
} | ||
|
||
[Theory] | ||
[InlineData("PreferAutoProperties", "public string Name { get; set; }")] | ||
[InlineData("PreferThrowingProperties", "public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }")] | ||
[InlineData(null, "public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }")] | ||
public async Task ImplementInterface_PropertyGeneration(string implementTypePropertyGenerationBehavior, string expectedChange) | ||
{ | ||
const string code = @" | ||
interface IFoo | ||
{ | ||
string Name { get; set; } | ||
} | ||
class Foo : I$$Foo | ||
{ | ||
}"; | ||
|
||
var hostProperties = implementTypePropertyGenerationBehavior != null ? new Dictionary<string, string> | ||
{ | ||
["ImplementTypeOptions:PropertyGenerationBehavior"] = implementTypePropertyGenerationBehavior | ||
} : null; | ||
await VerifyImplementType(code, expectedChange, hostProperties); | ||
} | ||
|
||
[Fact] | ||
public async Task ImplementInterface_Insertion_AtTheEnd() | ||
{ | ||
const string code = @" | ||
public interface IFoo | ||
{ | ||
string Name { get; set; } | ||
void Do(); | ||
string Name2 { get; set; } | ||
} | ||
public class Foo : I$$Foo | ||
{ | ||
}"; | ||
|
||
const string expectedChange = @" | ||
public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } | ||
public void Do() | ||
{ | ||
throw new System.NotImplementedException(); | ||
} | ||
public string Name2 { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } | ||
"; | ||
|
||
await VerifyImplementType(code, expectedChange, new Dictionary<string, string> | ||
{ | ||
["ImplementTypeOptions:InsertionBehavior"] = "AtTheEnd" | ||
}); | ||
} | ||
|
||
[Theory] | ||
[InlineData("WithOtherMembersOfTheSameKind")] | ||
[InlineData(null)] | ||
public async Task ImplementInterface_Insertion_WithOtherMembersOfTheSameKind(string implementTypeInsertionBehavior) | ||
{ | ||
const string code = @" | ||
public interface IFoo | ||
{ | ||
string Name { get; set; } | ||
void Do(); | ||
string Name2 { get; set; } | ||
} | ||
public class Foo : I$$Foo | ||
{ | ||
}"; | ||
|
||
const string expectedChange = @" | ||
public string Name { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } | ||
public string Name2 { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); } | ||
public void Do() | ||
{ | ||
throw new System.NotImplementedException(); | ||
} | ||
"; | ||
|
||
var hostProperties = implementTypeInsertionBehavior != null ? new Dictionary<string, string> | ||
{ | ||
["ImplementTypeOptions:InsertionBehavior"] = implementTypeInsertionBehavior | ||
} : null; | ||
await VerifyImplementType(code, expectedChange, hostProperties); | ||
} | ||
|
||
private async Task VerifyImplementType(string code, string expectedChange, Dictionary<string, string> hostProperties) | ||
{ | ||
var testFile = new TestFile("test.cs", code); | ||
using (var host = CreateOmniSharpHost(new[] { testFile }, hostProperties)) | ||
{ | ||
var requestHandler = host.GetRequestHandler<RunCodeActionService>(OmniSharpEndpoints.V2.RunCodeAction); | ||
var point = testFile.Content.GetPointFromPosition(); | ||
|
||
var request = new RunCodeActionRequest | ||
{ | ||
Line = point.Line, | ||
Column = point.Offset, | ||
FileName = testFile.FileName, | ||
Buffer = testFile.Content.Code, | ||
Identifier = "False;False;AssemblyName;global::IFoo;Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService+ImplementInterfaceCodeAction", | ||
WantsTextChanges = true, | ||
WantsAllCodeActionOperations = true | ||
}; | ||
|
||
var response = await requestHandler.Handle(request); | ||
var changes = response.Changes.ToArray(); | ||
|
||
Assert.Single(changes); | ||
Assert.NotNull(changes[0].FileName); | ||
AssertIgnoringIndent(expectedChange, ((ModifiedFileResponse)changes[0]).Changes.First().NewText); | ||
} | ||
} | ||
} | ||
} |