基于roslyn实现函数与函数之间的依赖关系
样本:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Threading.Tasks; 5 6 namespace Student_mangent 7 { 8 public class Test 9 { 10 public static void Test_1(string val) 11 { 12 Console.WriteLine(val + "1"); 13 } 14 public static void Test_2(string val) 15 { 16 Console.WriteLine(val + "2"); 17 } 18 public static void Test_main() 19 { 20 string val = "3"; 21 Test_2(val); 22 Test_1(val); 23 Console.WriteLine(val + "2"); 24 } 25 } 26 }
识别代码:
1 using Microsoft.Build.Locator; 2 using Microsoft.CodeAnalysis; 3 using Microsoft.CodeAnalysis.CSharp; 4 using Microsoft.CodeAnalysis.CSharp.Symbols; 5 using Microsoft.CodeAnalysis.CSharp.Syntax; 6 using Microsoft.CodeAnalysis.MSBuild; 7 using Microsoft.CodeAnalysis.Text; 8 using System; 9 using System.Collections.Generic; 10 using System.IO; 11 using System.Linq; 12 using System.Text; 13 using System.Threading.Tasks; 14 using Newtonsoft.Json; 15 16 namespace Test_Roslyn 17 { 18 class Program 19 { 20 static async Task Main(string[] args) 21 { 22 var file = @"E:\VS2017\WorkSpace\Learn\Student_mangent\Student_mangent\Test.cs"; 23 var programText = File.ReadAllText(file); 24 // 构建语法树 25 SyntaxTree tree = CSharpSyntaxTree.ParseText(programText); 26 CompilationUnitSyntax root = tree.GetCompilationUnitRoot(); 27 CSharpCompilation Compilation = CSharpCompilation 28 .Create("test") 29 .AddSyntaxTrees(tree) 30 .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)); 31 //添加语义模型 32 SemanticModel model = Compilation.GetSemanticModel(tree); 33 var Value_methods = from methodDeclaration in root.DescendantNodes() 34 .OfType<MethodDeclarationSyntax>() 35 select methodDeclaration; 36 List<JsonModel> json_data = new List<JsonModel>(); 37 foreach (var method in Value_methods) 38 {//构建字典 39 Console.WriteLine("*************************"); 40 IMethodSymbol Symbol_method = model.GetDeclaredSymbol(method); 41 Console.WriteLine(Symbol_method); 42 Console.WriteLine(Symbol_method.Locations.Single()); 43 var nodes = from methodDeclaration in root.DescendantNodes() 44 .OfType<InvocationExpressionSyntax>() 45 where methodDeclaration.Parent.Parent.Parent== method 46 select methodDeclaration; 47 foreach (var node in nodes.Distinct()) 48 { 49 Console.WriteLine("&&&&&&&&&&&&&&&&&&&"); 50 Console.WriteLine($"To=>{node}"); 51 IMethodSymbol Symbol_node = (IMethodSymbol)model.GetSymbolInfo(node).Symbol; 52 Console.WriteLine(Symbol_node); 53 Console.WriteLine(Symbol_node.Locations.Single()); 54 //进行 55 56 57 //json制造 58 //JsonModel JsonValue = new JsonModel(); 59 //JsonValue.Source = method.Identifier.ValueText; 60 //JsonValue.Target = node + ""; 61 //json_data.Add(JsonValue); 62 } 63 } 64 /*json制造 65 string json = JsonConvert.SerializeObject(json_data); 66 Console.WriteLine(json); 67 // 获取当前程序所在路径,并将要创建的文件命名为info.json 68 string fp = "E:/VS2017/WorkSpace/Learn/Roslyn/Test_Roslyn/Test_Roslyn/data/info.json"; 69 Save_json(fp,json); 70 */ 71 } 72 public static IEnumerable<InvocationExpressionSyntax> Get_SescendantNodes(string Text_code) 73 { 74 75 var Tree = CSharpSyntaxTree.ParseText(Text_code); 76 CompilationUnitSyntax Root = Tree.GetCompilationUnitRoot(); 77 var Nodes = Root.DescendantNodes() 78 .OfType<InvocationExpressionSyntax>(); 79 return Nodes; 80 } 81 public static Boolean Save_json(string Path,string value) 82 { 83 if (!File.Exists(Path)) // 判断是否已有相同文件 84 { 85 FileStream fs1 = new FileStream(Path, FileMode.Create, FileAccess.ReadWrite); 86 fs1.Close(); 87 } 88 File.WriteAllText(Path, value); 89 return true; 90 } 91 public static object Read_json(string Path) 92 { 93 Object obji = JsonConvert.DeserializeObject<Object>(File.ReadAllText(Path)); // 尖括号<>中填入对象的类名 94 return obji; 95 } 96 public static void Get_syntax() 97 { 98 var file = @"E:\VS2017\WorkSpace\Learn\Roslyn\Data\Startup.cs"; 99 var programText = File.ReadAllText(file); 100 // 构建语法树 101 SyntaxTree tree = CSharpSyntaxTree.ParseText(programText); 102 CompilationUnitSyntax root = tree.GetCompilationUnitRoot(); 103 var Value_methods = from methodDeclaration in root.DescendantNodes() 104 .OfType<MethodDeclarationSyntax>() 105 //where methodDeclaration.Identifier.ValueText == "ConfigureServices" 106 //select methodDeclaration.Identifier.ValueText+"__==__"+methodDeclaration.Body.ToFullString(); 107 select methodDeclaration; 108 foreach (var method in Value_methods) 109 {//构建字典 110 Console.WriteLine("*************************"); 111 Console.WriteLine(method.Identifier.ValueText); 112 Console.WriteLine(method.ParameterList); 113 //Console.WriteLine(method.Body.ToFullString()); 114 SyntaxTree tree_method = CSharpSyntaxTree.ParseText(method.Body.ToFullString()); 115 CompilationUnitSyntax root_method = tree_method.GetCompilationUnitRoot(); 116 var nodes = from methodDeclaration in root_method.DescendantNodes() 117 .OfType<ExpressionStatementSyntax>() 118 select methodDeclaration; 119 nodes.Distinct().ToList().ForEach(s => Console.WriteLine(s)); 120 foreach (var node in nodes) 121 { 122 //Console.WriteLine(node); 123 } 124 125 } 126 } 127 128 public static void Just_test() 129 { 130 var file = @"E:\VS2017\WorkSpace\Learn\Roslyn\Data\Startup.cs"; 131 var programText = File.ReadAllText(file); 132 // 构建语法树 133 SyntaxTree tree = CSharpSyntaxTree.ParseText(programText); 134 CompilationUnitSyntax root = tree.GetCompilationUnitRoot(); 135 //添加引用类型=>String,Console 136 var compilation = CSharpCompilation.Create("Starup") 137 .AddReferences(MetadataReference.CreateFromFile( 138 typeof(string).Assembly.Location)) 139 .AddSyntaxTrees(tree); 140 141 //添加语义模型 142 SemanticModel model = compilation.GetSemanticModel(tree); 143 144 var helloWorldStrings = root.DescendantNodes() 145 .OfType<MethodDeclarationSyntax>(); 146 147 foreach (var helloWorldString in helloWorldStrings) 148 { 149 Console.WriteLine("HHHHH"); 150 Console.WriteLine(helloWorldString.Identifier.ValueText); 151 // Use the semantic model for type information: 152 TypeInfo literalInfo = model.GetTypeInfo(helloWorldString); 153 var stringTypeSymbol = (INamedTypeSymbol)literalInfo.Type; 154 Console.WriteLine(stringTypeSymbol); 155 //进行查询 156 var allMembers = stringTypeSymbol.GetMembers(); 157 Console.WriteLine(allMembers); 158 var methods = allMembers.OfType<IMethodSymbol>(); 159 var publicStringReturningMethods = methods 160 .Where(m => m.DeclaredAccessibility == Accessibility.Public); 161 //删除重载 162 var distinctMethods = publicStringReturningMethods.Select(m => m.Name).Distinct(); 163 foreach (var me in distinctMethods) 164 { 165 Console.WriteLine(me); 166 } 167 } 168 } 169 } 170 }
效果: