Skip to content

Commit

Permalink
Make SA1500 work with stackalloc arrays (DotNetAnalyzers#3047)
Browse files Browse the repository at this point in the history
  • Loading branch information
pantosha committed Nov 4, 2019
1 parent 8adeaaa commit e0fd5a6
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 0 deletions.
Expand Up @@ -5,6 +5,7 @@ namespace StyleCop.Analyzers.Test.CSharp7.LayoutRules
{
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Testing;
using StyleCop.Analyzers.Test.LayoutRules;
using TestHelper;
Expand Down Expand Up @@ -167,5 +168,173 @@ void LocalFunction6()

await VerifyCSharpFixAsync(testCode, expectedDiagnostics, fixedTestCode, CancellationToken.None).ConfigureAwait(false);
}

/// <summary>
/// Verifies that no diagnostics are reported for the valid stackalloc array initializers defined in this test.
/// </summary>
/// <remarks>
/// <para>These are valid for SA1500 only, some will report other diagnostics.</para>
/// </remarks>
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
[Fact]
public async Task TestStackAllocArrayInitializersValidAsync()
{
var testCode = @"using System;
public class TestClass
{
public unsafe void TestMethod()
{
var array1 = stackalloc int[0] { };
var array2 = stackalloc[] { 0, 1 };
var array3 = stackalloc int[] { 0, 1 };
var array4 = stackalloc int[]
{
};
var array5 = stackalloc int[2]
{
0,
1,
};
}
}";
await VerifyCSharpDiagnosticAsync(LanguageVersion.CSharp7_3, testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

/// <summary>
/// Verifies that diagnostics will be reported for all invalid implicit stackalloc array initializer definitions.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
[Fact]
public async Task TestImplicitStackAllocArrayInitializersInvalidAsync()
{
var testCode = @"
public class TestClass
{
public unsafe void TestMethod()
{
var invalidArray1 = stackalloc[]
{ 0, 1
};
var invalidArray2 = stackalloc[]
{
0, 1 };
var invalidArray3 = stackalloc[]
{ 0, 1 };
var invalidArray4 = stackalloc[]
{ 0, 1
};
var invalidArray5 = stackalloc[]
{
0, 1 };
}
}";

var fixedTestCode = @"
public class TestClass
{
public unsafe void TestMethod()
{
var invalidArray1 = stackalloc[]
{
0, 1
};
var invalidArray2 = stackalloc[]
{
0, 1
};
var invalidArray3 = stackalloc[]
{
0, 1
};
var invalidArray4 = stackalloc[]
{
0, 1
};
var invalidArray5 = stackalloc[]
{
0, 1
};
}
}";

DiagnosticResult[] expectedDiagnostics =
{
Diagnostic().WithLocation(7, 13),
Diagnostic().WithLocation(12, 22),
Diagnostic().WithLocation(15, 13),
Diagnostic().WithLocation(15, 20),
Diagnostic().WithLocation(18, 13),
Diagnostic().WithLocation(23, 22),
};

await VerifyCSharpFixAsync(LanguageVersion.CSharp7_3, testCode, expectedDiagnostics, fixedTestCode, CancellationToken.None).ConfigureAwait(false);
}

/// <summary>
/// Verifies that diagnostics will be reported for all invalid stackalloc array initializer definitions.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
[Fact]
public async Task TestStackAllocArrayInitializersInvalidAsync()
{
var testCode = @"
public class TestClass
{
public unsafe void TestMethod()
{
var invalidArray1 = stackalloc int[]
{ 0, 1 };
var invalidArray2 = stackalloc int[]
{ 0, 1
};
var invalidArray3 = stackalloc int[]
{
0, 1 };
}
}";

var fixedTestCode = @"
public class TestClass
{
public unsafe void TestMethod()
{
var invalidArray1 = stackalloc int[]
{
0, 1
};
var invalidArray2 = stackalloc int[]
{
0, 1
};
var invalidArray3 = stackalloc int[]
{
0, 1
};
}
}";

DiagnosticResult[] expectedDiagnostics =
{
Diagnostic().WithLocation(7, 13),
Diagnostic().WithLocation(7, 20),
Diagnostic().WithLocation(10, 13),
Diagnostic().WithLocation(15, 22),
};

await VerifyCSharpFixAsync(LanguageVersion.CSharp7_3, testCode, expectedDiagnostics, fixedTestCode, CancellationToken.None).ConfigureAwait(false);
}
}
}
Expand Up @@ -10,6 +10,7 @@ namespace StyleCop.Analyzers.LayoutRules
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using StyleCop.Analyzers.Helpers;
using StyleCop.Analyzers.Lightup;

/// <summary>
/// The opening or closing brace within a C# statement, element, or expression is not placed on its own line.
Expand Down Expand Up @@ -172,6 +173,22 @@ private static void CheckBraces(SyntaxNodeAnalysisContext context, SyntaxToken o

break;

case SyntaxKind.StackAllocArrayCreationExpression:
if (((StackAllocArrayCreationExpressionSyntax)context.Node.Parent).StackAllocKeyword.GetLine() == openBraceTokenLine)
{
return;
}

break;

case SyntaxKindEx.ImplicitStackAllocArrayCreationExpression:
if (((ImplicitStackAllocArrayCreationExpressionSyntaxWrapper)context.Node.Parent).StackAllocKeyword.GetLine() == openBraceTokenLine)
{
return;
}

break;

case SyntaxKind.ArrayInitializerExpression:
if (!InitializerExpressionSharesLine((InitializerExpressionSyntax)context.Node))
{
Expand Down

0 comments on commit e0fd5a6

Please sign in to comment.