Skip to content

Commit

Permalink
Generalize using placement option in AddImportPlacementOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
tmat committed Apr 25, 2022
1 parent e2f0810 commit 9f72144
Show file tree
Hide file tree
Showing 21 changed files with 86 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public CSharpAnalyzerOptionsProvider(AnalyzerConfigOptions options, AnalyzerOpti
public CodeStyleOption2<NamespaceDeclarationPreference> NamespaceDeclarations => GetOption(CSharpCodeStyleOptions.NamespaceDeclarations, FallbackSyntaxFormattingOptions.NamespaceDeclarations);
public CodeStyleOption2<bool> PreferTopLevelStatements => GetOption(CSharpCodeStyleOptions.PreferTopLevelStatements, FallbackSyntaxFormattingOptions.PreferTopLevelStatements);

// AddImportPlacementOptions

public CodeStyleOption2<AddImportPlacement> UsingDirectivePlacement => GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, FallbackAddImportPlacementOptions.UsingDirectivePlacement);

// CodeStyleOptions

public CodeStyleOption2<bool> ImplicitObjectCreationWhenTypeIsApparent => GetOption(CSharpCodeStyleOptions.ImplicitObjectCreationWhenTypeIsApparent, FallbackCodeStyleOptions.ImplicitObjectCreationWhenTypeIsApparent);
Expand Down Expand Up @@ -83,7 +87,6 @@ public CSharpAnalyzerOptionsProvider(AnalyzerConfigOptions options, AnalyzerOpti

public CodeStyleOption2<ExpressionBodyPreference> PreferExpressionBodiedLambdas => GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedLambdas, FallbackCodeStyleOptions.PreferExpressionBodiedLambdas);
public CodeStyleOption2<bool> PreferStaticLocalFunction => GetOption(CSharpCodeStyleOptions.PreferStaticLocalFunction, FallbackCodeStyleOptions.PreferStaticLocalFunction);
public CodeStyleOption2<AddImportPlacement> PreferredUsingDirectivePlacement => GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, FallbackCodeStyleOptions.PreferredUsingDirectivePlacement);

private TValue GetOption<TValue>(Option2<TValue> option, TValue defaultValue)
=> _options.GetEditorConfigOption(option, defaultValue);
Expand All @@ -97,6 +100,9 @@ private CSharpSimplifierOptions FallbackSimplifierOptions
private CSharpSyntaxFormattingOptions FallbackSyntaxFormattingOptions
=> (CSharpSyntaxFormattingOptions?)_fallbackOptions.CleanupOptions?.FormattingOptions ?? CSharpSyntaxFormattingOptions.Default;

private AddImportPlacementOptions FallbackAddImportPlacementOptions
=> _fallbackOptions.CleanupOptions?.AddImportOptions ?? AddImportPlacementOptions.Default;

public static explicit operator CSharpAnalyzerOptionsProvider(AnalyzerOptionsProvider provider)
=> new(provider.GetAnalyzerConfigOptions(), provider.GetFallbackOptions());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ protected override void InitializeWorker(AnalysisContext context)

private void AnalyzeNamespaceNode(SyntaxNodeAnalysisContext context)
{
var option = context.GetCSharpAnalyzerOptions().PreferredUsingDirectivePlacement;
var option = context.GetCSharpAnalyzerOptions().UsingDirectivePlacement;
if (option.Value != AddImportPlacement.OutsideNamespace)
return;

Expand All @@ -66,7 +66,7 @@ private void AnalyzeNamespaceNode(SyntaxNodeAnalysisContext context)

private static void AnalyzeCompilationUnitNode(SyntaxNodeAnalysisContext context)
{
var option = context.GetCSharpAnalyzerOptions().PreferredUsingDirectivePlacement;
var option = context.GetCSharpAnalyzerOptions().UsingDirectivePlacement;
var compilationUnit = (CompilationUnitSyntax)context.Node;

if (option.Value != AddImportPlacement.InsideNamespace
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
// Read the preferred placement option and verify if it can be applied to this code file.
// There are cases where we will not be able to fix the diagnostic and the user will need to resolve
// it manually.
var (placement, preferPreservation) = DeterminePlacement(compilationUnit, options.PreferredUsingDirectivePlacement);
var (placement, preferPreservation) = DeterminePlacement(compilationUnit, options.UsingDirectivePlacement);
if (preferPreservation)
return;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ public AddImportPlacementOptions GetOptions(IGlobalOptionService globalOptions)
internal static AddImportPlacementOptions GetCSharpAddImportPlacementOptions(IGlobalOptionService globalOptions)
=> new(
PlaceSystemNamespaceFirst: globalOptions.GetOption(GenerationOptions.PlaceSystemNamespaceFirst, LanguageNames.CSharp),
PlaceImportsInsideNamespaces: globalOptions.GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement).Value == AddImportPlacement.InsideNamespace,
AllowInHiddenRegions: false); // no global option available);
UsingDirectivePlacement: globalOptions.GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement),
AllowInHiddenRegions: AddImportPlacementOptions.Default.AllowInHiddenRegions); // no global option available);
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,5 @@ public static CSharpIdeCodeStyleOptions GetCSharpCodeStyleOptions(this IGlobalOp
UnusedValueAssignment: globalOptions.GetOption(CSharpCodeStyleOptions.UnusedValueAssignment),
PreferMethodGroupConversion: globalOptions.GetOption(CSharpCodeStyleOptions.PreferMethodGroupConversion),
PreferExpressionBodiedLambdas: globalOptions.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedLambdas),
PreferStaticLocalFunction: globalOptions.GetOption(CSharpCodeStyleOptions.PreferStaticLocalFunction),
PreferredUsingDirectivePlacement: globalOptions.GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement));
PreferStaticLocalFunction: globalOptions.GetOption(CSharpCodeStyleOptions.PreferStaticLocalFunction));
}
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ TestWorkspace GetTestWorkspaceForLanguage(string language)
/// <param name="separateUsingGroups">Indicates whether '<c>using</c>' directives should be organized into separated groups. Default is <c>true</c>.</param>
/// <returns>The <see cref="Task"/> to test code cleanup.</returns>
private protected static Task AssertCodeCleanupResult(string expected, string code, bool systemUsingsFirst = true, bool separateUsingGroups = false)
=> AssertCodeCleanupResult(expected, code, CSharpCodeStyleOptions.PreferOutsidePlacementWithSilentEnforcement, systemUsingsFirst, separateUsingGroups);
=> AssertCodeCleanupResult(expected, code, new(AddImportPlacement.OutsideNamespace, NotificationOption2.Silent), systemUsingsFirst, separateUsingGroups);

/// <summary>
/// Assert the expected code value equals the actual processed input <paramref name="code"/>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddImport
Public Function GetVisualBasicAddImportPlacementOptions(globalOptions As IGlobalOptionService) As AddImportPlacementOptions
Return New AddImportPlacementOptions(
PlaceSystemNamespaceFirst:=globalOptions.GetOption(GenerationOptions.PlaceSystemNamespaceFirst, LanguageNames.VisualBasic),
PlaceImportsInsideNamespaces:=False, ' VB does not support imports in namespace declarations
AllowInHiddenRegions:=False) ' no global option available
UsingDirectivePlacement:=AddImportPlacementOptions.Default.UsingDirectivePlacement, ' VB does not support imports in namespace declarations
AllowInHiddenRegions:=AddImportPlacementOptions.Default.AllowInHiddenRegions) ' no global option available
End Function
End Module
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ public async Task<Document> FormatNewDocumentAsync(Document document, Document?
{
var organizeImportsService = document.GetRequiredLanguageService<IOrganizeImportsService>();

var organizeOptions = await OrganizeImportsOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false);
var documentOptions = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
var codeStyleOption = documentOptions.GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement);
var organizeOptions = new OrganizeImportsOptions(
options.AddImportOptions.PlaceSystemNamespaceFirst,
options.FormattingOptions.SeparateImportDirectiveGroups,
options.FormattingOptions.LineFormatting.NewLine);

var organizedDocument = await organizeImportsService.OrganizeImportsAsync(document, organizeOptions, cancellationToken).ConfigureAwait(false);

return await MisplacedUsingDirectivesCodeFixProvider.TransformDocumentIfRequiredAsync(organizedDocument, options.SimplifierOptions, codeStyleOption, cancellationToken).ConfigureAwait(false);
return await MisplacedUsingDirectivesCodeFixProvider.TransformDocumentIfRequiredAsync(
organizedDocument, options.SimplifierOptions, options.AddImportOptions.UsingDirectivePlacement, cancellationToken).ConfigureAwait(false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,8 @@ using G= H.I;
Dim document = workspace.CurrentSolution.Projects.Single().Documents.Single()
Dim addImportOptions = New AddImportPlacementOptions(
PlaceSystemNamespaceFirst:=placeSystemNamespaceFirst,
PlaceImportsInsideNamespaces:=False,
AllowInHiddenRegions:=False)
UsingDirectivePlacement:=AddImportPlacementOptions.Default.UsingDirectivePlacement,
AllowInHiddenRegions:=AddImportPlacementOptions.Default.AllowInHiddenRegions)

Dim formattingOptions = CSharpSyntaxFormattingOptions.Default

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,8 @@ End Class</Test>

Dim addImportOptions = New AddImportPlacementOptions(
PlaceSystemNamespaceFirst:=placeSystemNamespaceFirst,
PlaceImportsInsideNamespaces:=False,
AllowInHiddenRegions:=False)
UsingDirectivePlacement:=AddImportPlacementOptions.Default.UsingDirectivePlacement,
AllowInHiddenRegions:=AddImportPlacementOptions.Default.AllowInHiddenRegions)

Dim formattingOptions = VisualBasicSyntaxFormattingOptions.Default

Expand Down
3 changes: 2 additions & 1 deletion src/Workspaces/CSharpTest/CodeGeneration/AddImportsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.AddImport;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Formatting;
using Microsoft.CodeAnalysis.CSharp.Simplification;
using Microsoft.CodeAnalysis.CSharp.Syntax;
Expand Down Expand Up @@ -77,7 +78,7 @@ private static async Task TestAsync(

var addImportOptions = new AddImportPlacementOptions(
PlaceSystemNamespaceFirst: placeSystemNamespaceFirst,
PlaceImportsInsideNamespaces: placeImportsInsideNamespaces,
UsingDirectivePlacement: new CodeStyleOption2<AddImportPlacement>(placeImportsInsideNamespaces ? AddImportPlacement.InsideNamespace : AddImportPlacement.OutsideNamespace, NotificationOption2.None),
AllowInHiddenRegions: false);

var formattingOptions = CSharpSyntaxFormattingOptions.Default;
Expand Down
1 change: 1 addition & 0 deletions src/Workspaces/Core/Portable/Formatting/Formatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Formatting.Rules;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Options;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ private static Option2<CodeStyleOption2<AddImportPlacement>> CreateUsingDirectiv
new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{optionName}"));

public static readonly Option2<CodeStyleOption2<AddImportPlacement>> PreferredUsingDirectivePlacement = CreateUsingDirectivePlacementOption(
"PreferredUsingDirectivePlacement", defaultValue: PreferOutsidePlacementWithSilentEnforcement, "csharp_using_directive_placement");
"PreferredUsingDirectivePlacement", AddImportPlacementOptions.Default.UsingDirectivePlacement, "csharp_using_directive_placement");

internal static readonly Option2<CodeStyleOption2<UnusedValuePreference>> UnusedValueExpressionStatement =
CodeStyleHelpers.CreateUnusedExpressionAssignmentOption(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ internal sealed class CSharpIdeCodeStyleOptions : IdeCodeStyleOptions
// the following are also used in code generation features, consider sharing:
[DataMember(Order = BaseMemberCount + 25)] public readonly CodeStyleOption2<bool> PreferStaticLocalFunction;
[DataMember(Order = BaseMemberCount + 26)] public readonly CodeStyleOption2<ExpressionBodyPreference> PreferExpressionBodiedLambdas;
[DataMember(Order = BaseMemberCount + 27)] public readonly CodeStyleOption2<AddImportPlacement> PreferredUsingDirectivePlacement;

#pragma warning disable IDE1006 // Record naming style
public CSharpIdeCodeStyleOptions(
Expand Down Expand Up @@ -98,8 +97,7 @@ public CSharpIdeCodeStyleOptions(
CodeStyleOption2<UnusedValuePreference>? UnusedValueAssignment = null,
CodeStyleOption2<bool>? PreferMethodGroupConversion = null,
CodeStyleOption2<ExpressionBodyPreference>? PreferExpressionBodiedLambdas = null,
CodeStyleOption2<bool>? PreferStaticLocalFunction = null,
CodeStyleOption2<AddImportPlacement>? PreferredUsingDirectivePlacement = null)
CodeStyleOption2<bool>? PreferStaticLocalFunction = null)
#pragma warning restore
: base(Common)
{
Expand Down Expand Up @@ -130,6 +128,5 @@ public CSharpIdeCodeStyleOptions(
this.PreferMethodGroupConversion = PreferMethodGroupConversion ?? s_trueWithSilentEnforcement;
this.PreferExpressionBodiedLambdas = PreferExpressionBodiedLambdas ?? s_whenPossibleWithSilentEnforcement;
this.PreferStaticLocalFunction = PreferStaticLocalFunction ?? s_trueWithSuggestionEnforcement;
this.PreferredUsingDirectivePlacement = PreferredUsingDirectivePlacement ?? s_outsideNamespacePlacementWithSilentEnforcement;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,42 @@
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Shared.Extensions;

namespace Microsoft.CodeAnalysis.AddImport;

[DataContract]
internal readonly record struct AddImportPlacementOptions(
[property: DataMember(Order = 0)] bool PlaceSystemNamespaceFirst = true,
[property: DataMember(Order = 1)] bool PlaceImportsInsideNamespaces = false,
[property: DataMember(Order = 2)] bool AllowInHiddenRegions = false)
internal sealed record class AddImportPlacementOptions
{
public AddImportPlacementOptions()
: this(PlaceSystemNamespaceFirst: true)
public static readonly CodeStyleOption2<AddImportPlacement> s_outsideNamespacePlacementWithSilentEnforcement =
new(AddImportPlacement.OutsideNamespace, NotificationOption2.Silent);

[property: DataMember(Order = 0)]
public bool PlaceSystemNamespaceFirst { get; init; }

/// <summary>
/// Where to place C# usings relative to namespace declaration, ignored by VB.
/// </summary>
[property: DataMember(Order = 1)]
public CodeStyleOption2<AddImportPlacement> UsingDirectivePlacement { get; init; }

[property: DataMember(Order = 2)]
public bool AllowInHiddenRegions { get; init; }

public AddImportPlacementOptions(
bool PlaceSystemNamespaceFirst = true,
CodeStyleOption2<AddImportPlacement>? UsingDirectivePlacement = null,
bool AllowInHiddenRegions = false)
{
this.PlaceSystemNamespaceFirst = PlaceSystemNamespaceFirst;
this.UsingDirectivePlacement = UsingDirectivePlacement ?? s_outsideNamespacePlacementWithSilentEnforcement;
this.AllowInHiddenRegions = AllowInHiddenRegions;
}

public bool PlaceImportsInsideNamespaces => UsingDirectivePlacement.Value == AddImportPlacement.InsideNamespace;

public static readonly AddImportPlacementOptions Default = new();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,52 +64,60 @@ public SimplifierOptions GetSimplifierOptions()
internal SyntaxFormattingOptions GetFormattingOptions()
=> CSharpSyntaxFormattingOptions.Create(_options, FallbackSyntaxFormattingOptions);

// AddImportPlacementOptions

public CodeStyleOption2<AddImportPlacement> UsingDirectivePlacement => GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, FallbackAddImportPlacementOptions.UsingDirectivePlacement);

// CodeStyleOptions

public CodeStyleOption2<string> PreferredModifierOrder => GetOption(CSharpCodeStyleOptions.PreferredModifierOrder, FallbackCodeStyleOptions.PreferredModifierOrder);
public CodeStyleOption2<AccessibilityModifiersRequired> RequireAccessibilityModifiers => GetOption(CodeStyleOptions2.RequireAccessibilityModifiers, FallbackCodeStyleOptions.Common.RequireAccessibilityModifiers);

// CodeGenerationOptions

public CodeStyleOption2<AddImportPlacement> PreferredUsingDirectivePlacement => GetOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, FallbackCodeStyleOptions.PreferredUsingDirectivePlacement);

private TValue GetOption<TValue>(Option2<TValue> option, TValue defaultValue)
=> _options.GetEditorConfigOption(option, defaultValue);

private TValue GetOption<TValue>(PerLanguageOption2<TValue> option, TValue defaultValue)
=> _options.GetEditorConfigOption(option, defaultValue);

#if CODE_STYLE
private CSharpIdeCodeStyleOptions FallbackCodeStyleOptions
private static CSharpIdeCodeStyleOptions FallbackCodeStyleOptions
=> CSharpIdeCodeStyleOptions.Default;
#else
private CSharpIdeCodeStyleOptions FallbackCodeStyleOptions
=> (CSharpIdeCodeStyleOptions)_fallbackOptions.GetOptions(_languageServices).CodeStyleOptions;
#endif

#if CODE_STYLE
private CSharpSimplifierOptions FallbackSimplifierOptions
private static CSharpSimplifierOptions FallbackSimplifierOptions
=> CSharpSimplifierOptions.Default;
#else
private CSharpSimplifierOptions FallbackSimplifierOptions
=> (CSharpSimplifierOptions)_fallbackOptions.GetOptions(_languageServices).CleanupOptions.SimplifierOptions;
#endif

#if CODE_STYLE
private CSharpSyntaxFormattingOptions FallbackSyntaxFormattingOptions
private static CSharpSyntaxFormattingOptions FallbackSyntaxFormattingOptions
=> CSharpSyntaxFormattingOptions.Default;
#else
private CSharpSyntaxFormattingOptions FallbackSyntaxFormattingOptions
=> (CSharpSyntaxFormattingOptions)_fallbackOptions.GetOptions(_languageServices).CleanupOptions.FormattingOptions;
#endif

#if CODE_STYLE
private LineFormattingOptions FallbackLineFormattingOptions
private static LineFormattingOptions FallbackLineFormattingOptions
=> LineFormattingOptions.Default;
#else
private LineFormattingOptions FallbackLineFormattingOptions
=> _fallbackOptions.GetOptions(_languageServices).CleanupOptions.FormattingOptions.LineFormatting;
#endif

#if CODE_STYLE
private static AddImportPlacementOptions FallbackAddImportPlacementOptions
=> AddImportPlacementOptions.Default;
#else
private AddImportPlacementOptions FallbackAddImportPlacementOptions
=> _fallbackOptions.GetOptions(_languageServices).CleanupOptions.AddImportOptions;
#endif
}

internal static class CSharpCodeFixOptionsProviders
Expand Down
Loading

0 comments on commit 9f72144

Please sign in to comment.