2017-05-07 114 views
0

我正在构建使用Roslyn API着色各种语言构造的Visual Studio扩展,我想要更改属性声明的颜色,如Asp.Net MVC [Require]属性for例。我有机会获得SyntaxNodeISymbol,我目前的检查,以找出是否当前节点是一个属性声明:确定当前跨度是否是使用Roslyn API的属性删除

public static bool IsCSharpAttributeSyntaxKind(this SyntaxNode node) 
{ 
     return node.Kind() == SyntaxKind.Attribute; 
} 

而且使用它像:

if (node.IsCSharpAttributeSyntaxKind()) 
    { 
    classificationTypeDictionary.TryGetValue(ColorCoderClassificationName.Attribute, out IClassificationType classificationValue); 

    return new TagSpan<IClassificationTag>(new SnapshotSpan(snapshot, span.TextSpan.Start, span.TextSpan.Length), new ClassificationTag(classificationValue)); 
    } 

我用得到罗斯林信息:

public IEnumerable<ITagSpan<IClassificationTag>> GetTags(NormalizedSnapshotSpanCollection spans) 
    { 
     if (spans.Count == 0) 
     { 
      return Enumerable.Empty<ITagSpan<IClassificationTag>>(); 
     } 

     var cacheStatus = _colorCoderTaggerServices.ManageCache(ref _cache, spans, _buffer); 

     if (cacheStatus == CacheState.NotResolved) 
     { 
      return Enumerable.Empty<ITagSpan<IClassificationTag>>(); 
     } 

     return _colorCoderTaggerServices.GetClassificationTags(_cache, spans, classificationTypeDictionary); 
    } 

而且用于检索所述标识符方法:

internal IEnumerable<ClassifiedSpan> GetIdentifiersInSpans(Workspace workspace, SemanticModel model, NormalizedSnapshotSpanCollection spans) 
{ 
    var comparer = StringComparer.InvariantCultureIgnoreCase; 

    var classifiedSpans = spans.SelectMany(span => 
    { 
     var textSpan = TextSpan.FromBounds(span.Start, span.End); 
     return Classifier.GetClassifiedSpans(model, textSpan, workspace); 
    }); 

    return classifiedSpans.Where(c => comparer.Compare(c.ClassificationType, "identifier") == 0); 
} 

我不知道属性声明是否是我从GetIdentifiersInSpans返回的标识符的一部分,但是我没有使用Where而没有成功。

而对于我的缓存机制,我用:

public class ProviderCache 
{ 
    public Workspace Workspace { get; private set; } 
    public Document Document { get; private set; } 
    public SemanticModel SemanticModel { get; private set; } 
    public SyntaxNode SyntaxRoot { get; private set; } 
    public ITextSnapshot Snapshot { get; private set; } 

    public static async Task<ProviderCache> Resolve(ITextBuffer buffer, ITextSnapshot snapshot) 
    { 
     var workspace = buffer.GetWorkspace(); 
     var document = snapshot.GetOpenDocumentInCurrentContextWithChanges(); 
     if (document == null) 
     { 
      return null; 
     } 

     var semanticModel = await document.GetSemanticModelAsync().ConfigureAwait(false); 
     var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false); 
     return new ProviderCache 
     { 
      Workspace = workspace, 
      Document = document, 
      SemanticModel = semanticModel, 
      SyntaxRoot = syntaxRoot, 
      Snapshot = snapshot 
     }; 
    } 
} 

我已经试过各种其他的东西,但他们没有工作,我相信我会错过别的东西在这里。我明白我的问题不够好,我很抱歉,那是因为我缺乏提出一个好问题的术语,而且Visual Studio的可扩展性框架通常没有详细记录,如果您需要更多详细信息,请让我知道。

+0

我不明白,是什么问题? – svick

+0

@svick你说得对,问题并不清楚,我已经更新了这个问题。 –

回答

0

你不提你是如何让您的扩展罗斯林信息,而是因为你提到你的代码样本中SyntaxNodeWorkspaceSemanticModel,我认为你可以得到当前Document。我会采取的方法是获取您尝试分类的文档的根节点。一个好的开始地点将会像下面的代码和 VSSDK样本一样。

public static async Task<IEnumerable<ClassificationSpan>> ClassifyAttributes(Document currentDocument, CancellationToken token) 
{ 
    // Get all attribute nodes in the current document 
    var rootNode = await currentDocument.GetSyntaxRootAsync(token).ConfigureAwait(false); 
    var attributesInDocument = from descendantNode in rootNode.DescendantNodesAndSelf() 
           where descendantNode.IsKind(SyntaxKind.Attribute) 
           select (AttributeSyntax)descendantNode; 

    // Check to see if the attribute binds to a type (I assume you do not want to classify attributes with errors) 
    var model = await currentDocument.GetSemanticModelAsync(token).ConfigureAwait(false); 
    var attributeSpans = from attributeNode in attributesInDocument 
         let typeInfo = model.GetTypeInfo(attributeNode, token) 
         where typeInfo.Type.Kind != SymbolKind.ErrorType 
         select new ClassificationSpan(attributeNode.Span, _classificationType); 

    // returns a set of ClassifiedSpans that your extensions classifer will colorize 
    return attributeSpans; 
} 
+0

谢谢你的回答,抱歉,因为没有充分解释我所追求的是什么,我添加了一些更多信息,我想要确定当前节点是否属于属性声明,如海关属性,我在机制中没有问题用于执行此操作,还检查'rootNode.DescendantNodesAndSelf(),其中descendantNode.IsKind(SyntaxKind.Attribute)'没有解决问题。 –

相关问题