Требования
Я пытаюсь написать анализатор, который помечает любое присвоение нуля типу 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?
}
Заранее спасибо!