diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1013CSharp11UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1013CSharp11UnitTests.cs index 5e4657dce..250d2cd0b 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1013CSharp11UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1013CSharp11UnitTests.cs @@ -3,9 +3,39 @@ namespace StyleCop.Analyzers.Test.CSharp11.SpacingRules { + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp10.SpacingRules; + using Xunit; + + using static StyleCop.Analyzers.Test.Verifiers.StyleCopDiagnosticVerifier< + StyleCop.Analyzers.SpacingRules.SA1013ClosingBracesMustBeSpacedCorrectly>; public partial class SA1013CSharp11UnitTests : SA1013CSharp10UnitTests { + /// + /// Verifies the behavior of closing braces in interpolated strings. + /// + /// A representing the asynchronous unit test. + [Fact] + [WorkItem(3914, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3914")] + public async Task TestSpacingAroundClosingBraceInInterpolatedStringsAsync() + { + const string testCode = @"using System; + +public class Foo +{ + public string TestMethod(object value) + { + // The space before '}' is not checked + return $""Some random text { + value + } and some more random text.""; + } +}"; + + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1013ClosingBracesMustBeSpacedCorrectly.cs b/StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1013ClosingBracesMustBeSpacedCorrectly.cs index b9a741487..161ad6f4b 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1013ClosingBracesMustBeSpacedCorrectly.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1013ClosingBracesMustBeSpacedCorrectly.cs @@ -76,11 +76,12 @@ private static void HandleCloseBraceToken(SyntaxTreeAnalysisContext context, Syn return; } - bool precededBySpace = token.IsFirstInLine() || token.IsPrecededByWhitespace(context.CancellationToken); + var firstInLine = token.IsFirstInLine(); + bool precededBySpace = token.IsPrecededByWhitespace(context.CancellationToken); if (token.Parent is InterpolationSyntax) { - if (precededBySpace) + if (precededBySpace && !firstInLine) { // Closing brace should{ not} be {preceded} by a space. var properties = TokenSpacingProperties.RemovePreceding; @@ -113,7 +114,7 @@ private static void HandleCloseBraceToken(SyntaxTreeAnalysisContext context, Syn precedesSpecialCharacter = false; } - if (!precededBySpace) + if (!firstInLine && !precededBySpace) { // Closing brace should{} be {preceded} by a space. var properties = TokenSpacingProperties.InsertPreceding;