2012-07-03 19 views
9

Visual Studio intellisense uygulamasına bir uzantı yazıyorum ve imleçten hemen önce C# düzenleyicisinde öğenin türünü almak istiyorum.Öğenin türünü C# düzenleyicisi penceresinde geçerli konumla bul

Şu anda mevcut kaynak dosyayı almak için kullanabileceğiniz bir ITextBuffer var.

Ben de aşağıda editörü mevcut konumu alabilirsiniz: Şu anda editörü imlecin arkasındaki öğenin türünü tespit etmek için nasıl çok emin değilim Ancak

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

. Roslyn kullanarak denedim ama bu daha yapmak için daha basit bir şey olmalı. Roslyn bunu yapmak için en iyi araçtır (belgeyi derlemek ve belgede doğru konuma gitmek) veya daha iyi bir yol var mı? Aşağıda

Roslyn kullanarak öğenin türünü bulma benim girişimi: (. Hiçbir bulanık mantık)

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'in bunun hakkında söyleyeceklerini duymak ilginç olacak. – MoonKnight

+2

Neden "ITextView.Caret.Position" kullanıyorsunuz? – leppie

+0

@leppie VS sdk için oldukça yeni ama geçerli imleç pos almak için çok daha kolay bir yol gibi geliyor, ben değiştireceğim –

cevap

3

derleyici API en çok kasıtlı ve size doğru soruyu sormak gerek Basitçe türünü bulma İmleç pozisyonundaki şey biraz bağlam gerektirir ve ilk bakışta size açık gibi görünen cevap, diğer kullanımlar için doğru cevap olmayabilir. Eğer böyle bir şey yapabileceği genel ifadeler için

: (it Not çok sağlam değil)

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

belirteci üst düğümüne kontrol edip oradan giderdim daha kapsamlı bir çözüm:

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); 
} 

...

Orada ilginç olguların bir yeri vardır, ve ne herhangi bir tanımlayıcı karşılık gelen türü olarak göstermek veya kaynak f belirteci istiyorum ile yapmaya çalıştığınız şeye bağlı olarak değişebilir.

+0

Müthiş bir şey gibi görünüyor, bu gece onu deneyin. –

+0

Ben bir go verdi ama GetTypeInfo (IdentifierNameSyntax) çağrısı ile sorun yaşıyorum, ben çalıştırdığımda, bir ExtendedErrorTypeSymbol geri almak, bu konuda nasıl bir fikir olsun? –