[英]Get all method calls
假设我有简单的项目
class Program : TestBase
{
static void Main(string[] args)
{
}
public void Test()
{
AddItem(new Item());
AddItem(new Item());
}
}
public class Item { }
public class TestBase
{
public virtual void AddItem(Item vertex) { }
}
如何提取AddItem(new Item());
使用VSSDK? 我想知道传递给它的参数以及它在文本编辑器中的哪一行。
我试过寻找CodeElement.Kind
,但遗憾的是vsCMElement.vsCMElementFunctionInvokeStmt
没有返回任何内容。 有没有其他方法来提取这些信息?
public static async Task InitializeAsync(AsyncPackage package)
{
// ...
_dte = (await package.GetServiceAsync(typeof(DTE))) as DTE2;
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);
var sandboxProject = _dte.Solution.Projects;
var codeItems = new List<string>();
if (!ThreadHelper.CheckAccess())
return;
foreach (Project project in sandboxProject)
{
var projectItems = GetProjectItemsRecursively(project.ProjectItems);
foreach (ProjectItem projectItem in projectItems)
{
foreach (CodeElement element in projectItem.FileCodeModel.CodeElements)
{
codeItems.AddRange(GetItems(element).Select(codeItem => $"{codeItem.FullName} : {codeItem.Kind.ToString()}"));
}
}
}
}
private static IEnumerable<CodeElement> GetItems(CodeElement items)
{
var ret = new List<CodeElement>();
if (items == null)
return ret;
foreach (CodeElement item in items.Children)
{
ret.Add(item);
ret.AddRange(GetItems(item));
}
return ret;
}
private static List<ProjectItem> GetProjectItemsRecursively(ProjectItems items)
{
var ret = new List<EnvDTE.ProjectItem>();
if (items == null) return ret;
foreach (ProjectItem item in items)
{
ret.Add(item);
ret.AddRange(GetProjectItemsRecursively(item.ProjectItems));
}
return ret;
}
使用现代版本的Visual Studio,如果您对语言服务感兴趣,那么您不必使用DTE和旧的FileCodeModel,但您可以利用.NET编译器平台SDK (又名Roslyn)进行解析骨干现在。
因此,首先要做的是将最新的Microsoft.CodeAnalysis.CSharp.Workspaces nuget包(roslyn for C#)和Microsoft.VisualStudio.LanguageServices nuget(Visual Studio Roslyn工作空间)添加到您的包项目中。 请注意,您可能需要修复现在常见的nuget乱...
完成后,您可以编写此类代码而不是您的代码:
// get component model & Visual Studio Roslyn workspace
var componentModel = await package.GetServiceAsync<SComponentModel, IComponentModel>();
var workspace = componentModel.GetService<VisualStudioWorkspace>(); // requires "Microsoft.VisualStudio.LanguageServices" nuget package
// enum all the projects
foreach (var project in workspace.CurrentSolution.Projects)
{
// enum all the documents in the project
foreach (var doc in project.Documents)
{
// get the semantic model & syntax tree root
var model = await doc.GetSemanticModelAsync();
var root = await model.SyntaxTree.GetRootAsync();
// find a class named "TestBase"
// ClassDeclarationSyntax etc. requires "Microsoft.CodeAnalysis.CSharp.Workspaces" nuget package
var myClass = root.DescendantNodes()
.OfType<ClassDeclarationSyntax>()
.FirstOrDefault(c => c.Identifier.Text == "TestBase");
if (myClass != null)
{
// find a method named "AddItem"
var myMethod = myClass.Members.Where(m => m.Kind() == SyntaxKind.MethodDeclaration)
.OfType<MethodDeclarationSyntax>()
.FirstOrDefault(m => m.Identifier.Text == "AddItem");
if (myMethod != null)
{
// get the list of method parameters
var parameters = myMethod.ParameterList.Parameters;
...
// get the start line for the method declaration
var lineSpan = model.SyntaxTree.GetLineSpan(myMethod.Span);
int startLine = lineSpan.StartLinePosition.Line;
...
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.