diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1107UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1107UnitTests.cs index 168e86af4..59a9c46e1 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1107UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1107UnitTests.cs @@ -6,6 +6,7 @@ namespace StyleCop.Analyzers.Test.ReadabilityRules using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; + using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; using StyleCop.Analyzers.ReadabilityRules; @@ -122,6 +123,35 @@ public static void Foo(string a, string b) await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } + [Fact] + public async Task TestThatAnalyzerIgnoresStatementsWithMissingTokenAsync() + { + string testCode = @" +using System; +class ClassName +{ + public static void Foo(string a, string b) + { + int i + if (true) + { + Console.WriteLine(""Bar""); + } + } +} +"; + DiagnosticResult expected = new DiagnosticResult + { + Id = "CS1002", + Message = "; expected", + Severity = DiagnosticSeverity.Error, + }; + + expected = expected.WithLocation(7, 14); + + await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); + } + protected override IEnumerable GetCSharpDiagnosticAnalyzers() { yield return new SA1107CodeMustNotContainMultipleStatementsOnOneLine(); diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1107CodeMustNotContainMultipleStatementsOnOneLine.cs b/StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1107CodeMustNotContainMultipleStatementsOnOneLine.cs index 19cd3801d..9dfa2413c 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1107CodeMustNotContainMultipleStatementsOnOneLine.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1107CodeMustNotContainMultipleStatementsOnOneLine.cs @@ -62,22 +62,31 @@ private static void HandleBlock(SyntaxNodeAnalysisContext context) if (block != null && block.Statements.Any()) { - FileLinePositionSpan previousStatementLocation = block.Statements[0].GetLineSpan(); + var previousStatement = block.Statements[0]; + FileLinePositionSpan previousStatementLocation = previousStatement.GetLineSpan(); FileLinePositionSpan currentStatementLocation; for (int i = 1; i < block.Statements.Count; i++) { - currentStatementLocation = block.Statements[i].GetLineSpan(); + var currentStatement = block.Statements[i]; + currentStatementLocation = currentStatement.GetLineSpan(); if (previousStatementLocation.EndLinePosition.Line - == currentStatementLocation.StartLinePosition.Line) + == currentStatementLocation.StartLinePosition.Line + && !IsLastTokenMissing(previousStatement)) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, block.Statements[i].GetLocation())); } previousStatementLocation = currentStatementLocation; + previousStatement = currentStatement; } } } + + private static bool IsLastTokenMissing(StatementSyntax previousStatement) + { + return previousStatement.GetLastToken(includeZeroWidth: true, includeSkipped: true).IsMissing; + } } }