C#通过Roslyn获取代码中的引用及签名
2022/6/28 1:20:17
本文主要是介绍C#通过Roslyn获取代码中的引用及签名,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Roslyn可以对代码进行分析,查找代码并替换代码。参考文档如下:
https://roslynquoter.azurewebsites.net/
https://devblogs.microsoft.com/visualstudio/roslyn-syntax-visualizers/
https://jonskeet.uk/csharp/index.html
https://joshvarty.com/2014/07/06/learn-roslyn-now-part-2-analyzing-syntax-trees-with-linq/
https://joshvarty.com/learn-roslyn-now/
有这么一个需求:找到代码中所有的引用并打印出来。
如果是手动查找的话,容易出错且工作量比较大,因此通过Roslyn可以自动地将代码的信息提取出来。步骤如下:
1.DemoApp,一个简单的函数,有四个地方引用这个函数,现在需要做的是通过Roslyn查找四个引用
class Program { /// <summary> /// 方法入口123 /// </summary> /// <param name="args"></param> static void Main(string[] args) { var c1 = Plus(1, 2); var c2 = Plus(3, 4); var c3 = Plus(5,55); var c4 = Plus(6, 666); } static int Plus(int a,int b) { return a + b; } }
2.初始化Roslyn
初始化包含: MSBuildLocator.RegisterDefaults(); MSBuildWorkspace.Create(); workspace.OpenSolutionAsync() 等方法。
Init(); var workspace = MSBuildWorkspace.Create(); workspace.SkipUnrecognizedProjects = true; workspace.LoadMetadataForReferencedProjects = false; workspace.WorkspaceFailed += Workspace_WorkspaceFailed; var solution = workspace.OpenSolutionAsync(@"D:\测试代码\2022-06-27-DemoApp\2022-06-27-DemoApp.sln").Result;
3.找到引用:
var machineMgrProj = solution.Projects.FirstOrDefault(x => x.Name == projectName); var sysLogDoc = machineMgrProj.Documents.FirstOrDefault(x => x.Name == csFileName); var semanticModel2 = sysLogDoc.GetSemanticModelAsync().Result; var rootNode2 = sysLogDoc.GetSyntaxRootAsync().Result; var nodeClass = rootNode2.DescendantNodes().OfType<ClassDeclarationSyntax>() .FirstOrDefault(x => x.Identifier.ToString() == className1); var nodeMethod = nodeClass.DescendantNodes() .OfType<MethodDeclarationSyntax>().FirstOrDefault(x => x.Identifier.ToString() == methodName && x.ParameterList.ToString() == methodParListString); var sampleMethodSymbol1 = semanticModel2.GetDeclaredSymbol(nodeMethod); var referencesToSampleMethod2 = SymbolFinder.FindReferencesAsync(sampleMethodSymbol1, solution).Result;
4.解析引用:
//文件名 var fileName = location.Document.Name; //syntex tree var syntaxTree = location.Location.SourceTree; var root = syntaxTree.GetRoot(); //class node var cc1c = root.DescendantNodes().OfType<ClassDeclarationSyntax>().First(); //类名 var className = cc1c.Identifier.ValueText; if (!fileName.Contains(".cs")) { } //location node-inovation node var nodeFind = syntaxTree.GetRoot().FindNode(location.Location.SourceSpan); //method node var parentMethod = GetParentMethod<MethodDeclarationSyntax>(nodeFind); //方法名 var methodName1 = parentMethod.Identifier.ValueText; //方法注释 //method token var t1 = parentMethod.DescendantTokens(); var t2 = t1 .Where(x => x.IsKind(SyntaxKind.PrivateKeyword) || x.IsKind(SyntaxKind.PublicKeyword) || x.IsKind(SyntaxKind.ProtectedKeyword)||x.IsKind(SyntaxKind.StaticKeyword)).FirstOrDefault(); //token的细节信息 var trivia = t2.LeadingTrivia.Where(x => x.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia) || x.IsKind(SyntaxKind.MultiLineCommentTrivia)) .FirstOrDefault(); var comment = GetComment(trivia); //参数 var invocation = GetParentMethod<InvocationExpressionSyntax>(nodeFind); var parameter = invocation.DescendantNodes().OfType<ArgumentListSyntax>() .Where(x => x.Span.Start >= nodeFind.Span.End).First(); var argumentss = parameter.DescendantNodes().OfType<ArgumentSyntax>().ToList();
最后,效果如下图,查找到了4个引用,及引用的参数值
源码下载:https://files.cnblogs.com/files/congqiandehoulai/%E6%B5%8B%E8%AF%95N%E6%96%B9%E6%B3%95%E6%AC%A1%E6%95%B0_2.rar
https://files.cnblogs.com/files/congqiandehoulai/2022-06-27-DemoApp.rar
这篇关于C#通过Roslyn获取代码中的引用及签名的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2022-08-11C# 中 DateTime 的各种使用(增加一年、一月、一个季度等等用法)
- 2022-08-11【学习打卡】第7天 C#高级编程 第7讲下篇
- 2022-08-11Asp.Net Core 使用JWT,Swagger中带报文头
- 2022-08-09.net 调用spring boot rest api 的100-Continue问题
- 2022-08-09C#控件随窗体大小变化
- 2022-08-09C# Json和对象的转换,序列化和反序列化
- 2022-08-09C# Task.Run() 启动方法总结
- 2022-08-08C#《原CSharp》第四回 人常见岁月更替 却难知人文相继
- 2022-08-08C#获取调用文件名,行号,方法