2015-08-04 56 views
6

EnvDTE.ProjectItem'den Roslyn'in SyntaxTree sürümünü elde etmenin en iyi yolu nedir? Diğer yol için bir yöntem buldum (Roslyn'in ProjectItem belgesine).VSIX komutundan Roslyn çağrılıyor

Açılan belgeden çağrılan VSIX komutunu aldım ve burada Roslyn'in sözdizimi ağacını denemek istiyorum.

Bu kod çalışır, ancak bana garip görünüyor:

var pi = GetProjectItem(); 
    var piName = pi.get_FileNames(1); 

    var componentModel = (IComponentModel)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SComponentModel)); 
    var workspace = componentModel.GetService<Microsoft.VisualStudio.LanguageServices.VisualStudioWorkspace>(); 
    var ids = workspace.GetOpenDocumentIds(); 
    var id1 = ids.First(id => workspace.GetFilePath(id) == piName); 

     Microsoft.CodeAnalysis.Solution sln = workspace.CurrentSolution; 
     var doc = sln.GetDocument(id1); 
     //var w = await doc.GetSyntaxTreeAsync(); 
     Microsoft.CodeAnalysis.SyntaxTree syntaxTree; 
     if (doc.TryGetSyntaxTree(out syntaxTree)) 

aktif belgeden Roslyn en Belgesi almak için daha iyi bir yolu var mı?

cevap

1

Bir ProjectItem numaralı editörden ITextSnapshot bir editöre nasıl ulaşabileceğinizi öğrenirseniz, snapshot.AsText().GetOpenDocumentInCurrentContextWithChanges()'u kullanmak daha iyi olur.

Ayrıca, yukarıdaki kodunuzda, TryGetSyntaxTree numaralı telefonu kullanarak, sizden önce ayrıştırıcı ağacını istemiş birisine güveniyorsanız, unutmayın.

+1

AsText uzantısı yöntemi çok yararlı görünüyor. Maalesef henüz ITextSnapshot dosyasını bulmanın bir yolunu bulamadım. Bir ipucu? – maliger

+0

bunu buldu [link] (http://stackoverflow.com/questions/2413530/find-an-ivstextview-or-iwpftextview-for-a-given-projectitem-in-vs-2010-rc-exten) – maliger

7

Bir dosya yolu ile eşleşen DocumentId (ler) i almak için workspace.CurrentSolution.GetDocumentIdsWithFilePath() öğesini kullanabilirsiniz. Eğer workspace.CurrentSolution.GetDocument kullanarak belgeyi kendisini() alabilirsiniz itibaren

private Document GetActiveDocument() 
{ 
    var dte = Package.GetGlobalService(typeof(DTE)) as DTE; 
    var activeDocument = dte?.ActiveDocument; 
    if (activeDocument == null) return null; 

    var componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel)); 
    var workspace = (Workspace) componentModel.GetService<VisualStudioWorkspace>(); 

    var documentid = workspace.CurrentSolution.GetDocumentIdsWithFilePath(activeDocument.FullName).FirstOrDefault(); 
    if (documentid == null) return null; 

    return workspace.CurrentSolution.GetDocument(documentid); 
} 
5

Frank cevabı iyi çalışıyor.

using System.Linq; 

var dte = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(EnvDTE.DTE)) as EnvDTE.DTE; 
var activeDocument = dte?.ActiveDocument; 
if (activeDocument != null) 
{ 
    var componentModel = (Microsoft.VisualStudio.ComponentModelHost.IComponentModel)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(Microsoft.VisualStudio.ComponentModelHost.SComponentModel)); 
    var workspace = (Microsoft.CodeAnalysis.Workspace)componentModel.GetService<Microsoft.VisualStudio.LanguageServices.VisualStudioWorkspace>(); 
    var documentId = workspace.CurrentSolution.GetDocumentIdsWithFilePath(activeDocument.FullName).FirstOrDefault(); 
    if (documentId != null) 
    { 
     var document = workspace.CurrentSolution.GetDocument(documentId); 
    } 
} 

Ve burada bu tür bulmak için başvurular şunlardır:

iki çerçeve referansları VSSDK.DTE ve VSSDK.ComponentModelHost için Nuget referanslarla değiştirilebilir umut, ama ben çalıştım vazgeçtim bu yüzden, bu derleme sürümü uyuşmazlıkları hakkında uyarılar inşa verdi .