首页 文章

如何在roslyn中将字段声明转换为单独的自动属性?

提问于
浏览
-1

我正在使用.NET编译器平台(Roslyn)编写带有代码修复的代码分析器 . 我需要将所有(非密封的)公共字段转换为单独的自动属性,因为我知道FieldDeclarationSyntax可以在一行中有多个字段声明,基于下面的Stackoverflow问题中的代码示例 .

这里讨论了多场声明的事实:How to get a Roslyn FieldSymbol from a FieldDeclarationSyntax node?

我要分析的示例代码是:

public int AnyNumericField = 0;
    public string AnyStringField = "";
    // multiple field declaration sample
    public int field1, field2, field3 = 0;
    public StringBuilder sb1 = new StringBuilder();

我希望将代码修复程序纳入此内容:

public int AnyNumericField { get; set; } = 0;
    public string AnyStringField { get; set; } = "";
    // multiple field declaration sample
    public int field1 { get; set; } = 0; 
    public int field2 { get; set; } = 0; 
    public int field3 { get; set; } = 0;
    public StringBuilder sb1 { get; set; } = new StringBuilder();

我目前的分析器代码是这样的:

private void AnalyzePublicField(SymbolAnalysisContext context)
    {
        var aPublicField = (IFieldSymbol)context.Symbol;
        if ((aPublicField.DeclaredAccessibility == Accessibility.Public) && (!aPublicField.IsSealed))
        {
            var diagnostic = Diagnostic.Create(RuleCA1501, aPublicField.Locations[0], aPublicField.Name);

            context.ReportDiagnostic(diagnostic);
        }
    }

我的问题是,如何为此编写代码修复程序?我是否需要更改分析器以传递FieldDeclarationSyntax而不是字段符号?我找不到任何具体的示例,如何将多行字段声明转换/转换为单独的自动属性 .

UPDATE 1: 到目前为止,我的理解是使用此代码构建一个自动属性:

PropertyDeclarationSyntax @propSymbol = SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName(fieldSymbol.MetadataName), memberName).AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword));

                @propSymbol = @propSymbol.AddAccessorListAccessors(
                    SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
                        .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)
                        ));
                @propSymbol = @propSymbol.AddAccessorListAccessors(
                    SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
                    .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)
                    ));

PropertyDeclarationSyntax 的代码受本文的启发:https://dogschasingsquirrels.com/2014/08/04/code-generation-with-roslyn-fields-and-properties/

1 回答

  • 0

    在codefix中,您可以使用以下代码访问 VariableDeclarationSyntax

    var diagnostic = context.Diagnostics.First();
    var diagnosticSpan = diagnostic.Location.SourceSpan;
    var syntaxNode = root.FindNode(diagnosticSpan);
    var variableDeclarator = syntaxNode.FirstAncestorOrSelf<VariableDeclaratorSyntax>();
    var variableDeclaration = variableDeclarator?.Parent as VariableDeclarationSyntax;
    

    此声明可能有许多声明符,但它们共享相同的可见性和修饰符,因此您将为它们生成相应的属性,然后您需要将上面的 variableDeclaration 替换为生成的属性 .

    您可能希望在此处查看同一声明中的多个变量如何分成它们自己的声明的示例:https://github.com/SonarSource-VisualStudio/sonaranalyzer-dotnet/blob/master/src/SonarAnalyzer.CSharp/Rules/MultipleVariableDeclarationCodeFixProvider.cs

    顺便说一下,我想

    public int field1, field2, field3 = 0;
    

    应转换为

    public int field1 { get; set; }
    public int field2 { get; set; }
    public int field3 { get; set; } = 0;
    

    并不是

    public int field1 { get; set; } = 0; 
    public int field2 { get; set; } = 0; 
    public int field3 { get; set; } = 0;
    

    另请注意,此转换可能会破坏您的代码 . 例如,如果您将字段作为 refout 传递,则它将无法更改为属性 .

相关问题