Skip to content

Commit

Permalink
Add option for breaking expression on new line #1575
Browse files Browse the repository at this point in the history
* Add option roslynator_expression_body_style_on_next_line to enable breaking of expression bodies on new line.
  The line position is determined by option roslynator_arrow_token_new_line.
  • Loading branch information
cbersch committed Dec 9, 2024
1 parent 0cea640 commit 736c1a7
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 49 deletions.
1 change: 1 addition & 0 deletions src/Analyzers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1995,6 +1995,7 @@ foreach (var item in items)
<Option Key="body_style" IsRequired="true" />
<Option Key="use_block_body_when_declaration_spans_over_multiple_lines" IsRequired="true" />
<Option Key="use_block_body_when_expression_spans_over_multiple_lines" IsRequired="true" />
<Option Key="expression_body_style_on_next_line" IsRequired="true" />
</ConfigOptions>
<Options>
<Option Identifier="ConvertExpressionBodyToBlockBodyWhenExpressionIsMultiLine">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ internal sealed class RequiredConfigOptionNotSetAnalyzer : AbstractRequiredConfi

private static readonly ConfigOptionDescriptor[] _useBlockBodyOrExpressionBodyOptions = [
ConfigOptions.BodyStyle,
ConfigOptions.ExpressionBodyStyleOnNextLine,
ConfigOptions.UseBlockBodyWhenDeclarationSpansOverMultipleLines,
ConfigOptions.UseBlockBodyWhenExpressionSpansOverMultipleLines,
];
Expand Down
31 changes: 31 additions & 0 deletions src/Common/CSharp/Analysis/ConvertExpressionBodyAnalysis.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;

namespace Roslynator.CSharp.Analysis;
internal static class ConvertExpressionBodyAnalysis
{
public static bool BreakExpressionOnNewLine(SyntaxKind syntaxKind, AnalyzerConfigOptions configOptions)
{
if (!configOptions.TryGetValueAsBool(ConfigOptions.ExpressionBodyStyleOnNextLine, out bool breakOnNewLine)
|| !breakOnNewLine)
{
return false;
}

switch (syntaxKind)
{
case SyntaxKind.MethodDeclaration:
case SyntaxKind.ConstructorDeclaration:
case SyntaxKind.DestructorDeclaration:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.IndexerDeclaration:
case SyntaxKind.OperatorDeclaration:
case SyntaxKind.ConversionOperatorDeclaration:
return true;

default:
return false;
}
}
}
1 change: 1 addition & 0 deletions src/Common/ConfigOptionKeys.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ internal static partial class ConfigOptionKeys
public const string EnumFlagValueStyle = "roslynator_enum_flag_value_style";
public const string EnumHasFlagStyle = "roslynator_enum_has_flag_style";
public const string EqualsTokenNewLine = "roslynator_equals_token_new_line";
public const string ExpressionBodyStyleOnNextLine = "roslynator_expression_body_style_on_next_line";
public const string InfiniteLoopStyle = "roslynator_infinite_loop_style";
public const string MaxLineLength = "roslynator_max_line_length";
public const string NewLineAtEndOfFile = "roslynator_new_line_at_end_of_file";
Expand Down
8 changes: 7 additions & 1 deletion src/Common/ConfigOptions.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ public static partial class ConfigOptions
defaultValuePlaceholder: "after|before",
description: "Place new line after/before equals sign");

public static readonly ConfigOptionDescriptor ExpressionBodyStyleOnNextLine = new(
key: ConfigOptionKeys.ExpressionBodyStyleOnNextLine,
defaultValue: null,
defaultValuePlaceholder: "true|false",
description: "Place expression body always on next/same line");

public static readonly ConfigOptionDescriptor InfiniteLoopStyle = new(
key: ConfigOptionKeys.InfiniteLoopStyle,
defaultValue: null,
Expand Down Expand Up @@ -260,7 +266,7 @@ private static IEnumerable<KeyValuePair<string, string>> GetRequiredOptions()
yield return new KeyValuePair<string, string>("RCS0060", JoinOptionKeys(ConfigOptionKeys.BlankLineAfterFileScopedNamespaceDeclaration));
yield return new KeyValuePair<string, string>("RCS0061", JoinOptionKeys(ConfigOptionKeys.BlankLineBetweenSwitchSections));
yield return new KeyValuePair<string, string>("RCS1014", JoinOptionKeys(ConfigOptionKeys.ArrayCreationTypeStyle));
yield return new KeyValuePair<string, string>("RCS1016", JoinOptionKeys(ConfigOptionKeys.BodyStyle, ConfigOptionKeys.UseBlockBodyWhenDeclarationSpansOverMultipleLines, ConfigOptionKeys.UseBlockBodyWhenExpressionSpansOverMultipleLines));
yield return new KeyValuePair<string, string>("RCS1016", JoinOptionKeys(ConfigOptionKeys.BodyStyle, ConfigOptionKeys.UseBlockBodyWhenDeclarationSpansOverMultipleLines, ConfigOptionKeys.UseBlockBodyWhenExpressionSpansOverMultipleLines, ConfigOptionKeys.ExpressionBodyStyleOnNextLine));
yield return new KeyValuePair<string, string>("RCS1018", JoinOptionKeys(ConfigOptionKeys.AccessibilityModifiers));
yield return new KeyValuePair<string, string>("RCS1050", JoinOptionKeys(ConfigOptionKeys.ObjectCreationParenthesesStyle));
yield return new KeyValuePair<string, string>("RCS1051", JoinOptionKeys(ConfigOptionKeys.ConditionalOperatorConditionParenthesesStyle));
Expand Down
4 changes: 4 additions & 0 deletions src/ConfigOptions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@
<Value>before</Value>
</Values>
</Option>
<Option Id="ExpressionBodyStyleOnNextLine">
<ValuePlaceholder>true|false</ValuePlaceholder>
<Description>Place expression body always on next/same line</Description>
</Option>
<Option Id="MaxLineLength">
<DefaultValue>140</DefaultValue>
<ValuePlaceholder>&lt;NUM&gt;</ValuePlaceholder>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
// Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Immutable;
using System.Reflection.Metadata;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Roslynator.CSharp;
using Roslynator.CSharp.Analysis;
using Roslynator.CSharp.CodeStyle;

namespace Roslynator.Formatting.CSharp;
Expand Down Expand Up @@ -36,18 +38,11 @@ public override void Initialize(AnalysisContext context)
private static void AnalyzeArrowExpressionClause(SyntaxNodeAnalysisContext context)
{
var arrowExpressionClause = (ArrowExpressionClauseSyntax)context.Node;
AnalyzerConfigOptions configOptions = context.GetConfigOptions();

switch (arrowExpressionClause.Parent.Kind())
if (ConvertExpressionBodyAnalysis.BreakExpressionOnNewLine(arrowExpressionClause.Parent.Kind(), configOptions))
{
case SyntaxKind.MethodDeclaration:
case SyntaxKind.ConstructorDeclaration:
case SyntaxKind.DestructorDeclaration:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.IndexerDeclaration:
case SyntaxKind.OperatorDeclaration:
case SyntaxKind.ConversionOperatorDeclaration:
AnalyzeArrowExpressionClause(arrowExpressionClause.ArrowToken, context);
break;
AnalyzeArrowExpressionClause(arrowExpressionClause.ArrowToken, context);
}
}

Expand Down
Loading

0 comments on commit 736c1a7

Please sign in to comment.