0

クラス、プロパティ、およびメソッドに注釈を付けてから、注釈付きノードを取得しようとすると、クラス 1 のみが返されます。なんで?

注釈を付けるコードは次のとおりです

SyntaxAnnotation propertyAnnotation = null;
SyntaxAnnotation classAnnotation = null;
SyntaxAnnotation setMethodAnnotation = null;

document = document
    .AnnotateClass(classDeclaration, out classAnnotation)
    .AnnotateProperty(propertyDeclaration, out propertyAnnotation)
    .AnnotateSetMethod(setMethodDeclaration, out setMethodAnnotation);

IDocument にこれらの拡張メソッドが定義されています

    internal static IDocument AnnotateSetMethod(this IDocument document, MethodDeclarationSyntax method,
                                                                        out SyntaxAnnotation annotation)
    {
        annotation = new SyntaxAnnotation();

        var newRoot = document.GetSyntaxRoot()
                                .ReplaceNode(method, method.WithAdditionalAnnotations(annotation));

        return document.UpdateSyntaxRoot(newRoot);

    }

    internal static IDocument AnnotateProperty(this IDocument document, PropertyDeclarationSyntax property,
                                               out SyntaxAnnotation annotation)
    {
        annotation = new SyntaxAnnotation();

        var newRoot = document.GetSyntaxRoot()
                                .ReplaceNode(property, property.WithAdditionalAnnotations(annotation));

        return document.UpdateSyntaxRoot(newRoot);
    }

    internal static IDocument AnnotateClass(this IDocument document, ClassDeclarationSyntax classDeclaration,
                                              out 

        SyntaxAnnotation annotation)
        {
            annotation = new SyntaxAnnotation();

            var newRoot = document.GetSyntaxRoot()
                                    .ReplaceNode(classDeclaration, classDeclaration.WithAdditionalAnnotations(annotation));

            return document.UpdateSyntaxRoot(newRoot);
        }

public static TSyntaxNode GetAnnotatedNode<TSyntaxNode>(this IDocument document, SyntaxAnnotation annotation)
                where TSyntaxNode : CommonSyntaxNode
            {
                return document.GetSyntaxRoot().GetAnnotatedNode<TSyntaxNode>(annotation);
            }

もしそうなら

var propertyDeclaration = document.GetAnnotatedNode<PropertyDeclarationSyntax>(propertyAnnotation);

エラーが発生しますが、ClassDeclarationSyntax で試してみると問題なく動作します。

4

1 に答える 1

1

私の水晶玉は、AnnotateClass 以外のすべての .Replace ノード呼び出しが失敗していることを教えてくれます。返された新しいルートが古いルートとまったく同じオブジェクトであるかどうかを確認します。

これは、クラスに注釈を追加すると、新しいツリーが作成され、プロパティ構文がそのツリーの「中に」存在しなくなり、新しいノードになるためです。これが不変性の方法です。新しいノードがどこかに作成されると、他のノードから任意のノードにアクセスできるため、ツリー内のすべてのノードが事実上新しいものになります。(最初に構文注釈を追加したのは、この問題のためです....そうしないと、いくつかのノードを作成し、それらに戻る方法がありません.)

これにアプローチするには、いくつかの方法があります。

  1. 書き換えをすべて 1 段階で行う SyntaxRewriter を使用します。VisitClass、VisitProperty などをオーバーライドし、注釈付きの新しいノードを一度に生成します。
  2. ReplaceNode を呼び出すのではなく、ReplaceNodes を呼び出して、3 つのノードすべてを一度に置き換えます。

どちらの場合でも、パフォーマンス上の理由から、一度の書き換えを行う方が、大量の書き換えよりも常に望ましいです。前述したように、ツリー内のノードを置き換えて新しいルートに戻すと、すべてのインスタンスが変更され、再作成が必要になる場合があります。これはコストが高く、メモリ不足を引き起こします。

[技術的には、その発言は嘘です。私たちは怠惰に構築し、多くのものを再利用します。しかし、書き換えが少ないほど良い。]

于 2013-11-01T21:57:26.223 に答える