2017-05-07 37 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)'沒有解決問題。 –

相關問題