Как вы обнаруживаете нулевое присвоение обобщенного типа c с помощью анализатора кода? - PullRequest
0 голосов
/ 06 апреля 2020

Требования

Я пытаюсь написать анализатор, который помечает любое присвоение нуля типу c.

Он должен обнаружить инициализацию нового типа generi c в null:

MyGenericType<T> someGeneric = null;  // compiler should complain about null initialization

Кроме того, он также должен обнаружить любое последующее переназначение типа generi c в null:

MyGenericType<T> someGeneric = new MyGenericType<T>();
someGeneric = null;  // compiler should also complain about null reassignment

Попытка решения

В файле Analyzer.cs я регистрирую два типа действий - одно для объявления переменной и одно для назначения переменной.

public override void Initialize(AnalysisContext context)
{
    context.RegisterSyntaxNodeAction(AnalyzeAssignmentExpressionNode, SyntaxKind.SimpleAssignmentExpression);
    context.RegisterSyntaxNodeAction(AnalyzeDeclarationNode, SyntaxKind.LocalDeclarationStatement);
}

А вот действия, зарегистрированные выше:

private void AnalyzeDeclarationNode(SyntaxNodeAnalysisContext context)
{
    var declaration = (LocalDeclarationStatementSyntax)context.Node;

    if (declaration.Declaration.Type.GetFirstToken().Text == "MyGenericType")
    {
        context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation()));
    }
}

private void AnalyzeAssignmentExpressionNode(SyntaxNodeAnalysisContext context)
{
    var assignment = (AssignmentExpressionSyntax)context.Node;

    // If the right-hand side isn't a null, we're not interested.
    if (context.SemanticModel.GetTypeInfo(assignment.Right).Type != null)
    {
        return;
    }

    if (context.SemanticModel.GetTypeInfo(assignment.Left).ConvertedType.Name == "MyGenericType")
    {
        context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation()));
    }
}

Проблемы

Ниже приведен тестовый код для анализатора. У него есть как минимум две проблемы, которые упоминаются в комментариях ниже. Как я могу их исправить?

public class SomeClass
{
    // Problem (1) -- This is not getting flagged.
    private MyGenericType<int> privateField = null;

    private void DoSomething()
    {
        // Problem (2) -- This is getting flagged incorrectly. The right hand side is not null.
        // I don't know how to check for null on the right hand side of this declaration.
        MyGenericType<int> myInt = new MyGenericType<int>();
    }

    // Problem (3) -- I'm sure this code is not foolproof by any means. How can I make it more robust?
}

Заранее спасибо!

...