Advertisement
FrayxRulez

Untitled

Dec 1st, 2021
1,239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.45 KB | None | 0 0
  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.FindSymbols;
  7. using Microsoft.CodeAnalysis.MSBuild;
  8. using Microsoft.CodeAnalysis.Text;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Threading.Tasks;
  15.  
  16. namespace CodeAnalysisApp1
  17. {
  18.     internal class Program
  19.     {
  20.         static async Task Main(string[] args)
  21.         {
  22.             // Attempt to set the version of MSBuild.
  23.             var visualStudioInstances = MSBuildLocator.QueryVisualStudioInstances().ToArray();
  24.             var instance = visualStudioInstances.Length == 1
  25.                 // If there is only one instance of MSBuild on this machine, set that as the one to use.
  26.                 ? visualStudioInstances[0]
  27.                 // Handle selecting the version of MSBuild you want to use.
  28.                 : SelectVisualStudioInstance(visualStudioInstances);
  29.  
  30.             Console.WriteLine($"Using MSBuild at '{instance.MSBuildPath}' to load projects.");
  31.  
  32.             // NOTE: Be sure to register an instance with the MSBuildLocator
  33.             //       before calling MSBuildWorkspace.Create()
  34.             //       otherwise, MSBuildWorkspace won't MEF compose.
  35.             MSBuildLocator.RegisterInstance(instance);
  36.  
  37.             using (var workspace = MSBuildWorkspace.Create())
  38.             {
  39.                 // Print message for WorkspaceFailed event to help diagnosing project load failures.
  40.                 workspace.WorkspaceFailed += (o, e) => Console.WriteLine(e.Diagnostic.Message);
  41.  
  42.                 var solutionPath = args[0];
  43.                 Console.WriteLine($"Loading solution '{solutionPath}'");
  44.  
  45.                 // Attach progress reporter so we print projects as they are loaded.
  46.                 var solution = await workspace.OpenSolutionAsync(solutionPath, new ConsoleProgressReporter());
  47.                 Console.WriteLine($"Finished loading solution '{solutionPath}'");
  48.  
  49.                 var dynamicMethods = new Dictionary<string, List<string>>();
  50.  
  51.                 // TODO: Do analysis on the projects in the loaded solution
  52.                 foreach (var project in solution.Projects)
  53.                 {
  54.                     if (project.Name != "Unigram")
  55.                     {
  56.                         continue;
  57.                     }
  58.  
  59.                     foreach (var document in project.Documents)
  60.                     {
  61.                         if (!document.Name.EndsWith("UpdateManager.cs"))
  62.                         {
  63.                             continue;
  64.                         }
  65.  
  66.                         var first = true;
  67.  
  68.                         var rootNode = await document.GetSyntaxRootAsync();
  69.                         var semanticModel = await document.GetSemanticModelAsync();
  70.  
  71.                         var methods = rootNode
  72.                             .DescendantNodes()
  73.                             .OfType<MethodDeclarationSyntax>();
  74.  
  75.                         foreach (var method in methods)
  76.                         {
  77.                             if (method.Identifier.ValueText != "Subscribe")
  78.                             {
  79.                                 continue;
  80.                             }
  81.  
  82.                             var methodSymbol = semanticModel.GetDeclaredSymbol(method);
  83.                             var callers = await SymbolFinder.FindCallersAsync(methodSymbol, solution);
  84.  
  85.                             foreach (var result in callers)
  86.                             {
  87.                                 if (result.CallingSymbol.Name == "Subscribe")
  88.                                 {
  89.                                     continue;
  90.                                 }
  91.  
  92.                                 foreach (var definition in result.CallingSymbol.DeclaringSyntaxReferences)
  93.                                 {
  94.                                     var callerDeclarationSyntax = await definition.GetSyntaxAsync();
  95.                                     if (callerDeclarationSyntax != null)
  96.                                     {
  97.                                         var callerDocument = project.GetDocument(callerDeclarationSyntax.SyntaxTree);
  98.                                         var callerSemanticModel = await callerDocument.GetSemanticModelAsync();
  99.  
  100.                                         var invocations = callerDeclarationSyntax
  101.                                             .DescendantNodes()
  102.                                             .OfType<InvocationExpressionSyntax>();
  103.  
  104.                                         foreach (var invocation in invocations)
  105.                                         {
  106.                                             var invocationSymbol = callerSemanticModel.GetSymbolInfo(invocation);
  107.                                             if (SymbolEqualityComparer.Default.Equals(invocationSymbol.Symbol, methodSymbol))
  108.                                             {
  109.                                                 foreach (var argument in invocation.ArgumentList.Arguments)
  110.                                                 {
  111.                                                     var argumentSymbol = callerSemanticModel.GetSymbolInfo(argument.Expression);
  112.                                                     if (argumentSymbol.Symbol is IMethodSymbol sourceMethodSymbol)
  113.                                                     {
  114.                                                         if (sourceMethodSymbol.MethodKind == MethodKind.AnonymousFunction)
  115.                                                         {
  116.                                                             var receiver = sourceMethodSymbol.ReceiverType.ToDisplayString();
  117.  
  118.                                                             Console.WriteLine(receiver);
  119.  
  120.                                                             dynamicMethods[receiver] = null;
  121.                                                         }
  122.                                                         else if (sourceMethodSymbol.MethodKind == MethodKind.Ordinary)
  123.                                                         {
  124.                                                             var receiver = sourceMethodSymbol.ReceiverType.ToDisplayString();
  125.                                                             var name = string.Format("{0}.{1}", receiver, sourceMethodSymbol.Name);
  126.  
  127.                                                             Console.WriteLine(name);
  128.  
  129.                                                             dynamicMethods.TryGetValue(receiver, out var data);
  130.                                                             if (data == null)
  131.                                                             {
  132.                                                                 data = dynamicMethods[receiver] = new List<string>();
  133.                                                             }
  134.  
  135.                                                             if (!data.Contains(sourceMethodSymbol.Name))
  136.                                                             {
  137.                                                                 data.Add(sourceMethodSymbol.Name);
  138.                                                             }
  139.                                                         }
  140.                                                     }
  141.                                                 }
  142.                                             }
  143.                                         }
  144.                                     }
  145.                                 }
  146.                             }
  147.                         }
  148.  
  149.                         var builder = new StringBuilder();
  150.  
  151.                         foreach (var type in dynamicMethods.OrderBy(x => x.Key))
  152.                         {
  153.                             if (type.Value != null)
  154.                             {
  155.                                 builder.AppendFormat("    <Type Name=\"{0}\">\n", type.Key);
  156.                                 foreach (var method in type.Value)
  157.                                 {
  158.                                     builder.AppendFormat("      <Method Name=\"{0}\" Dynamic=\"Required\"/>\n", method);
  159.                                 }
  160.                                 builder.AppendFormat("    </Type>\n\n");
  161.                             }
  162.                             else
  163.                             {
  164.                                 builder.AppendFormat("    <Type Name=\"{0}\" Dynamic=\"Required All\"/>\n\n", type.Key);
  165.                             }
  166.                         }
  167.  
  168.                         var a = builder.ToString();
  169.                         Console.ReadLine();
  170.                     }
  171.                 }
  172.             }
  173.         }
  174.  
  175.         private static VisualStudioInstance SelectVisualStudioInstance(VisualStudioInstance[] visualStudioInstances)
  176.         {
  177.             Console.WriteLine("Multiple installs of MSBuild detected please select one:");
  178.             for (int i = 0; i < visualStudioInstances.Length; i++)
  179.             {
  180.                 Console.WriteLine($"Instance {i + 1}");
  181.                 Console.WriteLine($"    Name: {visualStudioInstances[i].Name}");
  182.                 Console.WriteLine($"    Version: {visualStudioInstances[i].Version}");
  183.                 Console.WriteLine($"    MSBuild Path: {visualStudioInstances[i].MSBuildPath}");
  184.             }
  185.  
  186.             while (true)
  187.             {
  188.                 var userResponse = Console.ReadLine();
  189.                 if (int.TryParse(userResponse, out int instanceNumber) &&
  190.                     instanceNumber > 0 &&
  191.                     instanceNumber <= visualStudioInstances.Length)
  192.                 {
  193.                     return visualStudioInstances[instanceNumber - 1];
  194.                 }
  195.                 Console.WriteLine("Input not accepted, try again.");
  196.             }
  197.         }
  198.  
  199.         private class ConsoleProgressReporter : IProgress<ProjectLoadProgress>
  200.         {
  201.             public void Report(ProjectLoadProgress loadProgress)
  202.             {
  203.                 var projectDisplay = Path.GetFileName(loadProgress.FilePath);
  204.                 if (loadProgress.TargetFramework != null)
  205.                 {
  206.                     projectDisplay += $" ({loadProgress.TargetFramework})";
  207.                 }
  208.  
  209.                 Console.WriteLine($"{loadProgress.Operation,-15} {loadProgress.ElapsedTime,-15:m\\:ss\\.fffffff} {projectDisplay}");
  210.             }
  211.         }
  212.     }
  213. }
  214.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement