2012-07-03 64 views
9

我正在編寫Visual Studio intellisense的擴展,並希望在C#編輯器中的光標之前獲取該項目的類型。在C#編輯器窗口中的當前位置查找項目的類型

我目前有一個ITextBuffer我可以用它來獲取當前的源文件。

我也可以得到如下的編輯器的當前位置:

var dte = Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE._DTE)) as EnvDTE.DTE;    
TextSelection sel = (TextSelection)dte.ActiveDocument.Selection; 

不過我也不太清楚如何檢測目前暫列光標在編輯器中的項目類型。我試過使用Roslyn,但它似乎應該是一個比這更簡單的事情。 Roslyn是做這件事的最佳工具(通過編譯文檔並導航到文檔中的正確位置)還是有更好的方法。

下面是我在尋找項目的使用羅斯林類型的嘗試:(無模糊)

ITextSnapshot snapshot = m_textBuffer.CurrentSnapshot; 
SnapshotPoint? triggerPoint = session.GetTriggerPoint(snapshot); 

var tree = SyntaxTree.ParseCompilationUnit(m_textBuffer.CurrentSnapshot.GetText()); 

var nodes = tree.GetRoot().DescendantNodes(); 

var element = nodes.Where(n => n.Span.End <= triggerPoint.Value.Position).Last(); 

var comp = Compilation.Create("test", syntaxTrees: new[] { tree }); 
var semModel = comp.GetSemanticModel(tree); 

//I cant work out what to do here to get the type as the element doesnt seem to be of the required type 
var s = semModel.GetTypeInfo((AttributeSyntax)element); 
+0

+1聽到Eric對此有何評論會很有趣。 – MoonKnight

+2

爲什麼你不使用'ITextView.Caret.Position'? – leppie

+0

@leppie即時通訊相當新的VS sdk,但這聽起來像一個更簡單的方法來獲取當前的光標位置,我會改變它 –

回答

3

編譯器API的是非常謹慎的,並要求你提出正確的問題,簡單地找到的類型光標位置上的東西需要一些上下文,並且最初看起來很明顯的答案可能不是其他用途的正確答案。

對於一般表達式,你可以做這樣的事情:(請注意,是不是很強勁)

var root = tree.GetRoot(); 
var token = root.FindToken(pos); 
var nearestExpr = token.Parent.AncestorsAndSelf().OfType<ExpressionSyntax>().First(); 
var type = semModel.GetTypeInfo(nearestExpr).Type; 

一個更全面的解決方案將檢查令牌的父節點,並從那裏:

var node = token.Parent; 
if (node is ExpressionSyntax) 
{ 
    type = semModel.GetTypeInfo((ExpressionSyntax)node).Type; 
} 
else if (node is VariableDeclaratorSyntax && ((VariableDeclaratorSyntax)node).Identifier == token) 
{ 
    type = (TypeSymbol)semModel.GetDeclaredSymbol((VariableDeclaratorSyntax)node); 
} 

...

有很多有趣的情況,並且要顯示對應於任何特定標識的類型或源˚F令牌什麼ile可以根據你想要完成的事情而有所不同。

+0

真棒,看起來像什麼即時通訊後,生病今晚試用它。 –

+0

我給了一個去,但我遇到了GetTypeInfo(IdentifierNameSyntax)調用的麻煩,當我運行它時,我得到一個ExtendedErrorTypeSymbol回來,任何想法如何解決這個問題? –

相關問題