Roslyn анализатор: аннулируемые аннотации в Linq - PullRequest
0 голосов
/ 07 апреля 2020

Я новичок в Roslyn, и мне нужно написать анализатор, который поможет улучшить аннулируемые аннотации при использовании Linq. Цель состоит в том, чтобы принудительно хранить любые использования .XYZOrDefault () в переменной типа / подписи типа / подписи. Например: если мы используем «var x = SomeKindOfList.FirstOrDefault ()», «x» должен быть помечен как обнуляемый. Мы будем использовать C# 8, поэтому я имею в виду NRT. Идея достижения этого заключается в следующем:

  1. Определение того, используются ли типы generi c в объявлении переменной или метода
  2. Использование модели semanti c для определения, осталось ли тип стороны выражения имеет тип nullable
  3. Если левая часть выражения не является типом nullable, создайте диагностику c

Я получил это далеко с моя кодировка:

private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
    {
        Compilation compilation = context.Compilation;
        var localDeclarations = context.Node.DescendantNodes().OfType<VariableDeclarationSyntax>(); 
        foreach (var declaration in localDeclarations)
        {
            // Find implicitly typed variable declarations.
            if (declaration.Type.IsVar)
            {
                foreach (var variable in declaration.Variables)
                {
                    var variableSymbol = ((ILocalSymbol)context.SemanticModel.GetDeclaredSymbol(variable)).Type;
                    var invocationSymbol = context.SemanticModel.GetOperation(variable.Initializer.Value).Type;

                    if (!((INamedTypeSymbol)variableSymbol).IsGenericType || declaration.Type.IsVar)
                    {
                        // For all such symbols, produce a diagnostic.
                        var diagnostic = Diagnostic.Create(Rule, variableSymbol.Locations[0], variableSymbol.Name);

                        context.ReportDiagnostic(diagnostic);
                    }
                }
            }
        }

Я много читал о том, что вы можете сделать, что на данном этапе это информационная перегрузка. Будем весьма благодарны за любые статьи, фрагменты кода или советы, которые могут дать мне больше указаний!

1 Ответ

0 голосов
/ 15 апреля 2020

В итоге мы закончили писать свой собственный анализатор в качестве временного решения, пока не сможем перейти к. Net 5. Наиболее базовой c реализацией, которую мы придумали, был следующий код:

    private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
    {
        var localDeclarations = context.Node.DescendantNodes().OfType<VariableDeclarationSyntax>();

        foreach (var declaration in localDeclarations)
        {                
            foreach (var variable in declaration.Variables)
            {
                ITypeSymbol? variableSymbol = ((ILocalSymbol)context.SemanticModel.GetDeclaredSymbol(variable)).Type; 
                IOperation? invocationOperationInfo = context.SemanticModel.GetOperation(variable.Initializer.Value);

                if (invocationOperationInfo is IInvocationOperation op)
                {
                    if (op.TargetMethod.IsGenericMethod)
                    {
                        if (!((INamedTypeSymbol)variableSymbol).IsGenericType || declaration.Type.IsVar)
                        {
                            // For all such symbols, produce a diagnostic.
                            var diagnostic = Diagnostic.Create(Rule, variable.GetLocation());

                            context.ReportDiagnostic(diagnostic);
                        }
                    }
                }
            }
        }
    }

Надеюсь, что это может помочь кому-то, кто, возможно, просто ищет хорошую отправную точку для разработки чего-то подобного.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...