我的注释在哪里?

时间:2013-11-01 19:43:25

标签: c# roslyn

当我尝试注释类,属性和方法,然后尝试检索带注释的节点时,只返回第一类。为什么呢?

以下是注释的代码

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就可以了。

1 个答案:

答案 0 :(得分:1)

我的水晶球告诉我除了你的AnnotateClass之外,.Replace节点都会调用失败。看看你得到的新根是否与旧根完全相同。

这是因为一旦你为类添加了一个注释,你现在就有了一个新树,所以你拥有的属性语法不再“在”那个树中 - 它是一个新节点。这是不变的方式 - 一旦在某个地方创建了新节点,树中的所有节点都是新的,因为您可以从任何其他节点到达任何节点。 (正是由于这个问题,我们首先添加了语法注释......否则你会创建一些节点并且无法回复它们。)

您有几种方法可以解决这个问题:

  1. 使用SyntaxRewriter,您可以在一个阶段中重写所有内容。您重写了VisitClass,VisitProperty等,并一次性生成带注释的新节点。
  2. 不是调用ReplaceNode,而是调用ReplaceNodes,一次替换所有三个节点。
  3. 在任何一种情况下,出于性能原因,进行单次重写始终优于一堆重写。就像我说的,一旦你替换树中的节点并获得一个新的根,你的所有实例都已经改变,可能不得不重新创建。这很昂贵并且会产生记忆压力。

    [从技术上讲,这种说法是谎言:我们会懒散地构建东西并重用很多东西。但重写得越少越好。]