Skip to content

Commit

Permalink
Add ImplementTypeOptions to CodeActionOptions.
Browse files Browse the repository at this point in the history
  • Loading branch information
tmat committed Feb 19, 2022
1 parent 8b1fa9c commit 2994e9f
Show file tree
Hide file tree
Showing 30 changed files with 185 additions and 119 deletions.
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<!-- Versions used by several individual references below -->
<RoslynDiagnosticsNugetPackageVersion>3.3.3-beta1.21105.3</RoslynDiagnosticsNugetPackageVersion>
<MicrosoftCodeAnalysisNetAnalyzersVersion>6.0.0-rc1.21366.2</MicrosoftCodeAnalysisNetAnalyzersVersion>
<MicrosoftCodeAnalysisTestingVersion>1.1.1-beta1.22081.4</MicrosoftCodeAnalysisTestingVersion>
<MicrosoftCodeAnalysisTestingVersion>1.1.2-beta1.22111.2</MicrosoftCodeAnalysisTestingVersion>
<MicrosoftVisualStudioExtensibilityTestingVersion>0.1.127-beta</MicrosoftVisualStudioExtensibilityTestingVersion>
<!-- CodeStyleAnalyzerVersion should we updated together with version of dotnet-format in dotnet-tools.json -->
<CodeStyleAnalyzerVersion>4.0.1</CodeStyleAnalyzerVersion>
Expand Down
4 changes: 2 additions & 2 deletions global.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"xcopy-msbuild": "16.10.0-preview2"
},
"msbuild-sdks": {
"Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22117.2",
"Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22117.2"
"Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22080.1",
"Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22080.1"
}
}
26 changes: 18 additions & 8 deletions src/Analyzers/Core/Analyzers/Helpers/AnalyzerHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@
namespace Microsoft.CodeAnalysis.Diagnostics
{
internal readonly record struct IdeAnalyzerOptions(
bool FadeOutUnusedImports,
bool FadeOutUnreachableCode,
bool ReportInvalidPlaceholdersInStringDotFormatCalls,
bool ReportInvalidRegexPatterns)
bool FadeOutUnusedImports = true,
bool FadeOutUnreachableCode = true,
bool ReportInvalidPlaceholdersInStringDotFormatCalls = true,
bool ReportInvalidRegexPatterns = true)
{
public IdeAnalyzerOptions()
: this(FadeOutUnusedImports: true)
{
}

public static readonly IdeAnalyzerOptions Default = new();

public static readonly IdeAnalyzerOptions CodeStyleDefault = new(
FadeOutUnusedImports: false,
FadeOutUnreachableCode: false,
Expand All @@ -27,11 +34,14 @@ internal readonly record struct IdeAnalyzerOptions(

#if !CODE_STYLE
public static IdeAnalyzerOptions FromProject(Project project)
=> From(project.Solution.Options, project.Language);

public static IdeAnalyzerOptions From(OptionSet options, string language)
=> new(
FadeOutUnusedImports: project.Solution.Options.GetOption(Microsoft.CodeAnalysis.Fading.FadingOptions.Metadata.FadeOutUnusedImports, project.Language),
FadeOutUnreachableCode: project.Solution.Options.GetOption(Microsoft.CodeAnalysis.Fading.FadingOptions.Metadata.FadeOutUnreachableCode, project.Language),
ReportInvalidPlaceholdersInStringDotFormatCalls: project.Solution.Options.GetOption(Microsoft.CodeAnalysis.ValidateFormatString.ValidateFormatStringOption.ReportInvalidPlaceholdersInStringDotFormatCalls, project.Language),
ReportInvalidRegexPatterns: project.Solution.Options.GetOption(Microsoft.CodeAnalysis.Features.EmbeddedLanguages.RegularExpressions.LanguageServices.RegularExpressionsOptions.ReportInvalidRegexPatterns, project.Language));
FadeOutUnusedImports: options.GetOption(Microsoft.CodeAnalysis.Fading.FadingOptions.Metadata.FadeOutUnusedImports, language),
FadeOutUnreachableCode: options.GetOption(Microsoft.CodeAnalysis.Fading.FadingOptions.Metadata.FadeOutUnreachableCode, language),
ReportInvalidPlaceholdersInStringDotFormatCalls: options.GetOption(Microsoft.CodeAnalysis.ValidateFormatString.ValidateFormatStringOption.ReportInvalidPlaceholdersInStringDotFormatCalls, language),
ReportInvalidRegexPatterns: options.GetOption(Microsoft.CodeAnalysis.Features.EmbeddedLanguages.RegularExpressions.LanguageServices.RegularExpressionsOptions.ReportInvalidRegexPatterns, language));
#endif
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Options;

namespace Microsoft.CodeAnalysis.ValidateFormatString
Expand All @@ -12,7 +13,7 @@ internal class ValidateFormatStringOption
new(
nameof(ValidateFormatStringOption),
nameof(ReportInvalidPlaceholdersInStringDotFormatCalls),
defaultValue: true,
IdeAnalyzerOptions.Default.ReportInvalidPlaceholdersInStringDotFormatCalls,
storageLocation: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.WarnOnInvalidStringDotFormatCalls"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#nullable disable

using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp;
Expand Down Expand Up @@ -1468,6 +1469,11 @@ class T : A
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementAbstractClass)]
public async Task TestWithGroupingOff1()
{
var options = CodeActionOptions.Default with
{
ImplementTypeOptions = new ImplementTypeOptions(InsertionBehavior: ImplementTypeInsertionBehavior.AtTheEnd)
};

await TestInRegularAndScriptAsync(
@"abstract class Base
{
Expand All @@ -1488,7 +1494,7 @@ class Derived : Base
void Goo() { }
public override int Prop => throw new System.NotImplementedException();
}", options: Option(ImplementTypeOptions.Metadata.InsertionBehavior, ImplementTypeInsertionBehavior.AtTheEnd));
}", codeActionOptions: options);
}

[WorkItem(17274, "https://github.com/dotnet/roslyn/issues/17274")]
Expand Down Expand Up @@ -1641,6 +1647,11 @@ public override void M2<T>(T? i = null)
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementAbstractClass)]
public async Task TestAutoProperties()
{
var options = CodeActionOptions.Default with
{
ImplementTypeOptions = new ImplementTypeOptions(InsertionBehavior: ImplementTypeInsertionBehavior.AtTheEnd)
};

await TestInRegularAndScript1Async(
@"abstract class AbstractClass
{
Expand All @@ -1664,9 +1675,7 @@ class C : AbstractClass
public override int ReadOnlyProp { get; }
public override int ReadWriteProp { get; set; }
public override int WriteOnlyProp { set => throw new System.NotImplementedException(); }
}", parameters: new TestParameters(options: Option(
ImplementTypeOptions.Metadata.PropertyGenerationBehavior,
ImplementTypePropertyGenerationBehavior.PreferAutoProperties)));
}", parameters: new TestParameters(codeActionOptions: options));
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementAbstractClass)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
Expand Down Expand Up @@ -7286,11 +7287,11 @@ void M() { }
public int Prop => throw new System.NotImplementedException();
}",
Options =
CodeActionOptions = CodeActionOptions.Default with
{
{ ImplementTypeOptions.Metadata.InsertionBehavior, ImplementTypeInsertionBehavior.AtTheEnd },
},
}.RunAsync();
ImplementTypeOptions = new ImplementTypeOptions(InsertionBehavior: ImplementTypeInsertionBehavior.AtTheEnd)
}
}.RunAsync();
}

[WorkItem(15387, "https://github.com/dotnet/roslyn/issues/15387")]
Expand Down Expand Up @@ -7461,10 +7462,10 @@ class Class : IInterface
public int ReadWriteProp { get; set; }
public int WriteOnlyProp { set => throw new System.NotImplementedException(); }
}",
Options =
CodeActionOptions = CodeActionOptions.Default with
{
{ ImplementTypeOptions.Metadata.PropertyGenerationBehavior, ImplementTypePropertyGenerationBehavior.PreferAutoProperties },
},
ImplementTypeOptions = new ImplementTypeOptions(InsertionBehavior: ImplementTypeInsertionBehavior.AtTheEnd)
}
}.RunAsync();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.CodeAnalysis.Options;

namespace Microsoft.CodeAnalysis.ImplementType
{
internal static class ImplementTypeOptionsStorage
{
public static ImplementTypeOptions GetImplementTypeOptions(this IGlobalOptionService globalOptions, string language)
=> new(
InsertionBehavior: globalOptions.GetOption(InsertionBehavior, language),
PropertyGenerationBehavior: globalOptions.GetOption(PropertyGenerationBehavior, language));

private const string FeatureName = "ImplementTypeOptions";

public static readonly PerLanguageOption2<ImplementTypeInsertionBehavior> InsertionBehavior =
new(FeatureName,
"InsertionBehavior",
defaultValue: ImplementTypeOptions.Default.InsertionBehavior,
storageLocation: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.ImplementTypeOptions.InsertionBehavior"));

public static readonly PerLanguageOption2<ImplementTypePropertyGenerationBehavior> PropertyGenerationBehavior =
new(FeatureName,
"PropertyGenerationBehavior",
defaultValue: ImplementTypeOptions.Default.PropertyGenerationBehavior,
storageLocation: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.ImplementTypeOptions.PropertyGenerationBehavior"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using System.Collections.Immutable;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.ImplementType;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.SymbolSearch;

Expand All @@ -20,6 +21,7 @@ internal static CodeActionOptions GetBlockingCodeActionOptions(this IGlobalOptio
private static CodeActionOptions GetCodeActionOptions(this IGlobalOptionService globalOptions, string language, bool isBlocking)
=> new(
SearchOptions: globalOptions.GetSymbolSearchOptions(language),
ImplementTypeOptions: globalOptions.GetImplementTypeOptions(language),
HideAdvancedMembers: globalOptions.GetOption(CompletionOptionsStorage.HideAdvancedMembers, language),
IsBlocking: isBlocking);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,14 +376,15 @@ internal Task TestInRegularAndScriptAsync(
CodeActionPriority? priority = null,
CompilationOptions compilationOptions = null,
OptionsCollection options = null,
CodeActionOptions? codeActionOptions = null,
object fixProviderData = null,
ParseOptions parseOptions = null,
string title = null,
TestHost testHost = TestHost.InProcess)
{
return TestInRegularAndScript1Async(
initialMarkup, expectedMarkup, index,
new TestParameters(parseOptions, compilationOptions, options, CodeActionOptions.Default, fixProviderData, index, priority, title: title, testHost: testHost));
new TestParameters(parseOptions, compilationOptions, options, codeActionOptions ?? CodeActionOptions.Default, fixProviderData, index, priority, title: title, testHost: testHost));
}

internal Task TestInRegularAndScript1Async(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ public Test()
/// <inheritdoc cref="SharedVerifierState.Options"/>
internal OptionsCollection Options => _sharedState.Options;

#if !CODE_STYLE
internal CodeActionOptions CodeActionOptions
{
get => _sharedState.CodeActionOptions;
set => _sharedState.CodeActionOptions = value;
}
#endif
/// <inheritdoc cref="SharedVerifierState.EditorConfig"/>
public string? EditorConfig
{
Expand All @@ -98,6 +105,9 @@ protected override async Task RunImplAsync(CancellationToken cancellationToken =
#if !CODE_STYLE
protected override AnalyzerOptions GetAnalyzerOptions(Project project)
=> new WorkspaceAnalyzerOptions(base.GetAnalyzerOptions(project), project);

protected override CodeFixContext CreateCodeFixContext(Document document, TextSpan span, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction, ImmutableArray<Diagnostic>> registerCodeFix, CancellationToken cancellationToken)
=> new(document, span, diagnostics, registerCodeFix, _sharedState.CodeActionOptions, cancellationToken);
#endif

protected override Diagnostic? TrySelectDiagnosticToFix(ImmutableArray<Diagnostic> fixableDiagnostics)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.CodeAnalysis.Testing.Verifiers;

#if !CODE_STYLE
using Microsoft.CodeAnalysis.CodeActions;
using Roslyn.Utilities;
#endif

Expand Down Expand Up @@ -45,6 +46,9 @@ public SharedVerifierState(AnalyzerTest<XUnitVerifier> test, string defaultFileE
/// </summary>
internal OptionsCollection Options { get; }

#if !CODE_STYLE
internal CodeActionOptions CodeActionOptions { get; set; }
#endif
internal void Apply()
{
var (analyzerConfigSource, remainingOptions) = CodeFixVerifierHelper.ConvertOptionsToAnalyzerConfig(_defaultFileExt, EditorConfig, Options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.Utilities.CommandHandlers
Return False
End If

Dim options = ImplementTypeOptions.From(document.Project)
Dim options = _globalOptions.GetImplementTypeOptions(document.Project.Language)
Dim newDocument = TryGetNewDocument(document, options, identifier, cancellationToken)

If newDocument Is Nothing Then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.

Imports Microsoft.CodeAnalysis.CodeActions
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics
Imports Microsoft.CodeAnalysis.ImplementType
Imports Microsoft.CodeAnalysis.SymbolSearch
Imports Microsoft.CodeAnalysis.VisualBasic.ImplementAbstractClass

Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ImplementAbstractClass
Expand Down Expand Up @@ -630,9 +632,9 @@ Class C
Throw New System.NotImplementedException()
End Set
End Property
End Class", parameters:=New TestParameters(options:=[Option](
ImplementTypeOptions.Metadata.PropertyGenerationBehavior,
ImplementTypePropertyGenerationBehavior.PreferAutoProperties)))
End Class", parameters:=New TestParameters(codeActionOptions:=New CodeActionOptions(
SearchOptions:=SymbolSearchOptions.Default,
ImplementTypeOptions:=New ImplementTypeOptions(PropertyGenerationBehavior:=ImplementTypePropertyGenerationBehavior.PreferAutoProperties))))
End Function
End Class
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.

Imports Microsoft.CodeAnalysis.CodeActions
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics
Imports Microsoft.CodeAnalysis.ImplementType
Imports Microsoft.CodeAnalysis.SymbolSearch
Imports Microsoft.CodeAnalysis.VisualBasic.ImplementInterface

Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ImplementInterface
Expand Down Expand Up @@ -4646,9 +4648,9 @@ class Class
Throw New System.NotImplementedException()
End Set
End Property
end class", parameters:=New TestParameters(options:=[Option](
ImplementTypeOptions.Metadata.PropertyGenerationBehavior,
ImplementTypePropertyGenerationBehavior.PreferAutoProperties)))
end class", parameters:=New TestParameters(codeActionOptions:=New CodeActionOptions(
SearchOptions:=SymbolSearchOptions.Default,
ImplementTypeOptions:=New ImplementTypeOptions(PropertyGenerationBehavior:=ImplementTypePropertyGenerationBehavior.PreferAutoProperties))))
End Function
End Class
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,10 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)

var service = document.GetRequiredLanguageService<IImplementInterfaceService>();
var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var options = ImplementTypeOptions.From(document.Project);

var actions = token.Parent.GetAncestorsOrThis<TypeSyntax>()
.Where(_interfaceName)
.Select(n => service.GetCodeActions(document, options, model, n, cancellationToken))
.Select(n => service.GetCodeActions(document, context.Options.ImplementTypeOptions, model, n, cancellationToken))
.FirstOrDefault(a => !a.IsEmpty);

if (actions.IsDefaultOrEmpty)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections.Immutable;
using System.Composition;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Options.Providers;
Expand All @@ -17,7 +18,7 @@ internal class RegularExpressionsOptions
new(
nameof(RegularExpressionsOptions),
nameof(ReportInvalidRegexPatterns),
defaultValue: true,
IdeAnalyzerOptions.Default.ReportInvalidRegexPatterns,
storageLocation: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.ReportInvalidRegexPatterns"));

public static PerLanguageOption2<bool> HighlightRelatedRegexComponentsUnderCursor =
Expand Down
5 changes: 3 additions & 2 deletions src/Features/Core/Portable/Fading/FadingOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections.Immutable;
using System.Composition;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Options.Providers;
Expand All @@ -29,11 +30,11 @@ public Metadata()
private const string FeatureName = "FadingOptions";

public static readonly PerLanguageOption2<bool> FadeOutUnusedImports = new(
FeatureName, "FadeOutUnusedImports", defaultValue: true,
FeatureName, "FadeOutUnusedImports", IdeAnalyzerOptions.Default.FadeOutUnusedImports,
storageLocation: new RoamingProfileStorageLocation($"TextEditor.%LANGUAGE%.Specific.FadeOutUnusedImports"));

public static readonly PerLanguageOption2<bool> FadeOutUnreachableCode = new(
FeatureName, "FadeOutUnreachableCode", defaultValue: true,
FeatureName, "FadeOutUnreachableCode", IdeAnalyzerOptions.Default.FadeOutUnreachableCode,
storageLocation: new RoamingProfileStorageLocation($"TextEditor.%LANGUAGE%.Specific.FadeOutUnreachableCode"));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
if (classNode == null)
return;

var options = ImplementTypeOptions.From(document.Project);
var data = await ImplementAbstractClassData.TryGetDataAsync(
document, classNode, GetClassIdentifier(classNode), options, cancellationToken).ConfigureAwait(false);
document, classNode, GetClassIdentifier(classNode), context.Options.ImplementTypeOptions, cancellationToken).ConfigureAwait(false);
if (data == null)
return;

Expand Down
Loading

0 comments on commit 2994e9f

Please sign in to comment.