Skip to content

Commit

Permalink
Correctly apply anchor indentation adjustments in the presence of trivia
Browse files Browse the repository at this point in the history
Fixes #57465
  • Loading branch information
sharwell committed Feb 18, 2022
1 parent 6206f0d commit b41f0e9
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 22 deletions.
54 changes: 51 additions & 3 deletions src/EditorFeatures/CSharpTest/Formatting/FormattingEngineTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.BraceCompletion;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Formatting;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Editor.Implementation.Formatting;
using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities;
Expand Down Expand Up @@ -1585,6 +1583,56 @@ public void FormatArbitraryNodeParenthesizedLambdaExpression()
AssertFormatOnArbitraryNode(node, expected);
}

[WpfFact]
[WorkItem(57465, "https://github.com/dotnet/roslyn/issues/57465")]
public async Task FormatLambdaWithDirective()
{
var code = @"namespace N
{
public class C
{
protected void Render()
{
if (outer)
{
M(() =>
{
#nullable enable
if (inner)
{
}
}
);
}
}
}
}
";
var expected = @"namespace N
{
public class C
{
protected void Render()
{
if (outer)
{
M(() =>
{
#nullable enable
if (inner)
{
}
}
);
}
}
}
}
";

await AssertFormatAsync(expected, code, spans: null);
}

[WorkItem(30787, "https://github.com/dotnet/roslyn/issues/30787")]
[WpfFact]
public void DoSmartIndentOpenBraceEvenWithFormatWhileTypingOff1()
Expand Down Expand Up @@ -2246,7 +2294,7 @@ private static void AssertFormatAfterTypeChar(string code, string expected, Dict

var newSnapshot = subjectDocument.GetTextBuffer().CurrentSnapshot;

Assert.Equal(expected, newSnapshot.GetText());
AssertEx.EqualOrDiff(expected, newSnapshot.GetText());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#nullable disable

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -18,6 +19,7 @@
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using Microsoft.VisualStudio.Text;
Expand Down Expand Up @@ -176,7 +178,7 @@ protected async Task AssertFormatAsync(string expected, string code, IEnumerable
{
var factory = (TestFormattingRuleFactoryServiceFactory.Factory)formattingRuleProvider;
factory.BaseIndentation = baseIndentation.Value;
factory.TextSpan = spans.First();
factory.TextSpan = spans?.First() ?? syntaxTree.GetRoot(CancellationToken.None).FullSpan;
}

var optionSet = workspace.Options;
Expand Down Expand Up @@ -220,7 +222,7 @@ internal void AssertFormat(Workspace workspace, string expected, SyntaxFormattin
if (actual != expected)
{
_output.WriteLine(actual);
Assert.Equal(expected, actual);
AssertEx.EqualOrDiff(expected, actual);
}
}

Expand Down Expand Up @@ -264,12 +266,12 @@ protected async Task AssertFormatWithBaseIndentAsync(
string expected, string markupCode, int baseIndentation,
Dictionary<OptionKey, object> options = null)
{
MarkupTestFile.GetSpan(markupCode, out var code, out var span);
TestFileMarkupParser.GetSpans(markupCode, out var code, out ImmutableArray<TextSpan> spans);

await AssertFormatAsync(
expected,
code,
new List<TextSpan> { span },
spans,
changedOptionSet: options,
baseIndentation: baseIndentation);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ protected override LineColumnRule GetLineColumnRuleBetween(SyntaxTrivia trivia1,

if (insertNewLine)
{
return LineColumnRule.PreserveLinesWithDefaultIndentation(lines: 0);
if (existingWhitespaceBetween.Spaces != this.Spaces)
return LineColumnRule.PreserveWithGivenSpaces(spaces: this.Spaces);
else
return LineColumnRule.PreserveLinesWithDefaultIndentation(lines: 0);
}

if (existingWhitespaceBetween.Lines > 0 && existingWhitespaceBetween.Spaces != this.Spaces)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,21 @@ private class AnchorData
{
private readonly AnchorIndentationOperation _operation;

public AnchorData(AnchorIndentationOperation operation, int originalColumn)
public AnchorData(AnchorIndentationOperation operation, SyntaxToken anchorToken, int originalColumn)
{
_operation = operation;
this.AnchorToken = anchorToken;
this.OriginalColumn = originalColumn;
}

public TextSpan TextSpan => _operation.TextSpan;

public SyntaxToken AnchorToken => _operation.AnchorToken;

public SyntaxToken StartToken => _operation.StartToken;

public SyntaxToken EndToken => _operation.EndToken;

public SyntaxToken AnchorToken { get; }

public int OriginalColumn { get; }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,9 @@ public void AddAnchorIndentationOperation(AnchorIndentationOperation operation)
return;
}

var originalSpace = _tokenStream.GetOriginalColumn(operation.StartToken);
var data = new AnchorData(operation, originalSpace);
var anchorToken = _tokenStream.FirstTokenOfBaseTokenLine(operation.AnchorToken);
var originalSpace = _tokenStream.GetOriginalColumn(anchorToken);
var data = new AnchorData(operation, anchorToken, originalSpace);

_anchorTree.AddIntervalInPlace(data);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,23 @@ namespace Microsoft.CodeAnalysis.Formatting.Rules
/// </summary>
internal sealed class AnchorIndentationOperation
{
internal AnchorIndentationOperation(SyntaxToken anchorToken, SyntaxToken startToken, SyntaxToken endToken, TextSpan textSpan)
internal AnchorIndentationOperation(SyntaxToken anchorToken, SyntaxToken endToken, TextSpan textSpan)
{
Contract.ThrowIfTrue(anchorToken.RawKind == 0);
Contract.ThrowIfTrue(textSpan.Start < 0 || textSpan.Length < 0);

Contract.ThrowIfTrue(startToken.RawKind == 0);
Contract.ThrowIfTrue(endToken.RawKind == 0);

this.AnchorToken = anchorToken;
this.TextSpan = textSpan;

this.StartToken = startToken;
this.EndToken = endToken;
}

public SyntaxToken AnchorToken { get; }
public TextSpan TextSpan { get; }

public SyntaxToken StartToken { get; }
public SyntaxToken StartToken => AnchorToken;
public SyntaxToken EndToken { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ internal static class FormattingOperations

/// <summary>
/// create anchor indentation region around start and end token
/// start token will act as anchor token and right after anchor token to end of end token will become anchor region
/// right after anchor token to end of end token will become anchor region
/// </summary>
public static AnchorIndentationOperation CreateAnchorIndentationOperation(SyntaxToken startToken, SyntaxToken endToken)
=> CreateAnchorIndentationOperation(startToken, startToken, endToken, TextSpan.FromBounds(startToken.Span.End, endToken.Span.End));
public static AnchorIndentationOperation CreateAnchorIndentationOperation(SyntaxToken anchorToken, SyntaxToken endToken)
=> CreateAnchorIndentationOperation(anchorToken, endToken, TextSpan.FromBounds(anchorToken.Span.End, endToken.Span.End));

/// <summary>
/// create anchor indentation region more explicitly by providing all necessary information.
/// </summary>
public static AnchorIndentationOperation CreateAnchorIndentationOperation(SyntaxToken anchorToken, SyntaxToken startToken, SyntaxToken endToken, TextSpan textSpan)
=> new(anchorToken, startToken, endToken, textSpan);
public static AnchorIndentationOperation CreateAnchorIndentationOperation(SyntaxToken anchorToken, SyntaxToken endToken, TextSpan textSpan)
=> new(anchorToken, endToken, textSpan);

/// <summary>
/// create suppress region around start and end token
Expand Down

0 comments on commit b41f0e9

Please sign in to comment.