【问题标题】:Why is this Roslyn analyzer test failing?为什么此 Roslyn 分析仪测试失败?
【发布时间】:2021-10-17 18:51:37
【问题描述】:

我试图理解为什么这个测试失败了:

Maak.Test.InitializeNewUnitTest.NoPropertiesInitialized_Diagnostic

Assert.AreEqual 失败。预期:。实际:。语境: 测试状态诊断 预期诊断将在“38”列结束 实际上在“39”列

预期诊断: // /0/Test0.cs(13,9,13,38): 警告 MaakInitializeNew VerifyCS.Diagnostic().WithSpan(13, 9, 13, 38),

实际诊断: // /0/Test0.cs(13,9): 警告 MaakInitializeNew: 可以完全初始化 VerifyCS.Diagnostic().WithSpan(13, 9, 13, 39),

测试:

[TestMethod]
        public async Task NoPropertiesInitialized_Diagnostic()
        {
            await VerifyCS.VerifyCodeFixAsync(@"
using System;

public class MyClass
{
    public string Name { get; set; }
}

class Program
{
    static void Main()
    {
        [|var myClass = new MyClass { }|];
    }
}
", @"
using System;

public class MyClass
{
    public string Name { get; set; }
}

class Program
{
    static void Main()
    {
        var myClass = new MyClass { Name = ""Stan"" };
    }
}
");
        }

分析器代码:

public override void Initialize(AnalysisContext context)
        {
            // See https://github.com/dotnet/roslyn/blob/main/docs/analyzers/Analyzer%20Actions%20Semantics.md for more information
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.EnableConcurrentExecution();
            context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.LocalDeclarationStatement);
        }

        private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            var localDeclaration = (LocalDeclarationStatementSyntax)context.Node;
            var typeDeclaration = localDeclaration.Declaration.Type;
            var symbolInfo = context.SemanticModel.GetSymbolInfo(typeDeclaration);
            var typeSymbol = symbolInfo.Symbol;
            
            if(typeSymbol == null)
                return;

            // Special case: Ensure that 'var' isn't actually an alias to another type. (e.g. using var = System.String).
            var aliasInfo = context.SemanticModel.GetAliasInfo(typeDeclaration);
            if (aliasInfo != null)
                return;

            var namedSymbol = context.Compilation.GetTypeByMetadataName(typeSymbol.MetadataName);

            if (namedSymbol?.TypeKind != TypeKind.Class)
                return;

            var hasDefaultConstructor = (namedSymbol?.Constructors)?.SingleOrDefault(c => !c.Parameters.Any()) != null;
            var properties = namedSymbol?.GetMembers()
                .Where(m => m.Kind == SymbolKind.Property
                            && m.DeclaredAccessibility == Accessibility.Public
                            && !((IPropertySymbol)m).IsReadOnly
                            && !((IPropertySymbol)m).IsStatic)
                .Select(m => new
                {
                    Name = m.Name,
                    Type = ((IPropertySymbol)m).Type
                })
                .ToList();
            var hasValidProperties = properties?.Any() != false;

            if (!hasValidProperties)
                return;

            var initializerExpressions = (localDeclaration.Declaration.Variables.FirstOrDefault().Initializer.Value
                    as ObjectCreationExpressionSyntax)?.Initializer.Expressions.ToList();
            var except = properties.Select(p => p.Name)
                .Except(initializerExpressions.Select(e => (e as AssignmentExpressionSyntax)?.Left.ToString()))
                .ToList();
            
            if(except.Count == 0)
                return;

            context.ReportDiagnostic(Diagnostic.Create(Rule, context.Node.GetLocation()));
        }

【问题讨论】:

    标签: c# code-generation roslyn roslyn-code-analysis


    【解决方案1】:

    报告正确的位置修复了它:

    context.ReportDiagnostic(Diagnostic.Create(Rule, localDeclaration.Declaration.GetLocation()));

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-26
      • 2018-04-04
      • 2012-12-03
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-27
      相关资源
      最近更新 更多