2013-11-01 87 views
0

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

这里是注释

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

我的水晶球告诉我,.Replace节点只会调用AnnotateClass,但是失败。看看你回来的新根是否与老根完全相同。

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

您有几种方法来处理这个问题:

  1. 使用SyntaxRewriter,您可以在一个阶段完成重写。您重写VisitClass,VisitProperty等,并一次性生成带有注释的新节点。
  2. 不是调用ReplaceNode,而是调用ReplaceNodes,一次替换所有三个节点。

在任一情况下,做一个单一的重写是总是优选一堆重写出于性能原因的。就像我说过的,一旦你替换了树中的一个节点并取回一个新的根,所有的实例都发生了变化,可能需要重新创建。这是昂贵的并且产生内存压力。

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

+0

我明白,它是更高性能做你所描述的,但我想了解创建新节点时注释发生了什么?比方说,我在类声明中创建了一个注释,然后将该注释传递给另一个注释该属性的方法。如果我发现类声明并注释该属性,然后替换类节点,我的类注释消失了。也许如果我能告诉你代码,它会更容易... – epitka

+0

...像这样的东西http://pastebin.com/4WzemcTp – epitka

相关问题