Skip to content

Commit

Permalink
GU0023 don't warn when used in lambda. Fix DotNetAnalyzers#186.
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanLarsson committed Aug 14, 2018
1 parent d1e67dd commit bcf68e2
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
18 changes: 18 additions & 0 deletions Gu.Analyzers.Test/GU0023StaticMemberOrderTests/HappyPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ public class Foo
AnalyzerAssert.Valid(Analyzer, code);
}

[Test]
public void FieldInitializedWithFuncUsingField()
{
var code = @"
namespace RoslynSandbox
{
using System;
public class Foo
{
public static readonly Func<int> Value1 = () => Value2;
public static readonly int Value2 = 2;
}
}";
AnalyzerAssert.Valid(Analyzer, code);
}

[Test]
public void FieldInitializedWithStaticProperty()
{
Expand Down
53 changes: 52 additions & 1 deletion Gu.Analyzers/GU0023StaticMemberOrderAnalyzer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
namespace Gu.Analyzers
{
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using Gu.Roslyn.AnalyzerExtensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
Expand Down Expand Up @@ -55,7 +57,7 @@ variable.Initializer.Value is ExpressionSyntax fieldValue &&

private static bool IsInitializedWithUninitialized(ExpressionSyntax value, SyntaxNodeAnalysisContext context, out FieldOrProperty other)
{
using (var walker = IdentifierNameExecutionWalker.Borrow(value, Scope.Type, context.SemanticModel, context.CancellationToken))
using (var walker = Walker.Borrow(value, context.SemanticModel, context.CancellationToken))
{
foreach (var identifierName in walker.IdentifierNames)
{
Expand Down Expand Up @@ -98,5 +100,54 @@ private static bool IsInitialized(MemberDeclarationSyntax declaration)
return false;
}
}

private sealed class Walker : ExecutionWalker<Walker>
{
private readonly List<IdentifierNameSyntax> identifierNames = new List<IdentifierNameSyntax>();

private Walker()
{
}

/// <summary>
/// Gets the <see cref="IdentifierNameSyntax"/>s found in the scope.
/// </summary>
public IReadOnlyList<IdentifierNameSyntax> IdentifierNames => this.identifierNames;

/// <summary>
/// Get a walker that has visited <paramref name="node"/>
/// </summary>
/// <param name="node">The node</param>
/// <param name="semanticModel">The <see cref="SemanticModel"/></param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/></param>
/// <returns>A walker that has visited <paramref name="node"/></returns>
public static Walker Borrow(SyntaxNode node, SemanticModel semanticModel, CancellationToken cancellationToken)
{
return BorrowAndVisit(node, Scope.Type, semanticModel, cancellationToken, () => new Walker());
}

public override void VisitParenthesizedLambdaExpression(ParenthesizedLambdaExpressionSyntax node)
{
// don't walk lambda
}

public override void VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
{
// don't walk lambda
}

/// <inheritdoc />
public override void VisitIdentifierName(IdentifierNameSyntax node)
{
this.identifierNames.Add(node);
base.VisitIdentifierName(node);
}

/// <inheritdoc />
protected override void Clear()
{
this.identifierNames.Clear();
}
}
}
}

0 comments on commit bcf68e2

Please sign in to comment.