Code Monkey home page Code Monkey logo

roentgen's Introduction

Roentgen

Roentgen is a small, simple and extendible Roslyn-based static code analyzer tool for .NET Framework.
(.NET Standard version is currently WIP)

Usage

First steps

Create a RoslynAnalyzer, add one or more solutions to it with AddSolution or AddSolutions and call Analyze to get immediate result:

var result = new RoslynAnalyzer().AddSolution(path).Analyze();

Then you can find the parsed solutions hierarchy in the result's Solutions property.
Or if you want to iterate through all parent-child relations found in the source then please use the Links property.

But wait, there's more!

Roentgen's true power is in its extensibility where it can be taught to find more interesting links between the code parts.

MethodInvocationsFinder

var result = new RoslynAnalyzer().AddSolution(path).RegisterPostProcessor<MethodInvocationsFinder>().Analyze();

MethodInvocationsFinder is a built-in post-processor that can collect all method invocations in the code.
It can collect the following link types:

Link type Description
InternalCall Something calls a method within the code base
ExternalCall Something calls an external method outside of the code base (i.e. .NET Framework dependencies)
UnknownCall Something calls an unknown method, typically of a Nuget package where the method symbol cannot be found

Custom post-processor

The most typical use-case of Roentgen is when you want to collect specific external calls like SQL queries and command calls.

Just simply create your own post-processor by deriving from the PostProcessorBase class. It comes with one important constructor parameter, the AnalysisWorkspace where you can find all interim analysis data.
Using this you can easily teach your post-processor to collect certain method invocations.

Visitors

However, method calls are often not enough, we need to analyze their arguments as well.

FindLiteralVisitor

The FindLiteralVisitor can find ALL literals in the code the given method was called with, even if this value comes from a chain of method invocations.
For example, the creator of the original code wrapped a SQL command call with a method and he used that in the code everywhere to pass a string query to that method. Sometimes with a string literal argument directly, sometimes with a variable or an argument of another method, and sometimes with a string concatenation to build up a certain SQL query. This visitor collects them all! Of course, it won't be able to figure out runtime values, because it's a static code analyzer, but still it's a very powerful thing to find all SQL calls within a huge code base.

FindVariableVisitor

The FindLiteralVisitor heavily relies on the FindVariableVisitor to jump from one part of the code to another, and you can use this too if it helps your discovery. Typically when the method you found was invoked on a variable and you are more interested in the object creation than the actual method call. Like when someone calls an ExecuteReader on an SqlCommand typed variable declared somewhere above the method invocation.

public class SqlCommandExecutionFinder : PostProcessorBase
{
  private readonly FindVariableVisitor _findVariableVisitor;
  private readonly FindLiteralVisitor _findLiteralVisitor;

  public SqlCommandExecutionFinder(AnalysisWorkspace workspace, FindVariableVisitor findVariableVisitor, FindLiteralVisitor findLiteralVisitor) : base(workspace)
  {
     _findVariableVisitor = findVariableVisitor;
     _findLiteralVisitor = findLiteralVisitor;
  }

  public override void Process()
  {
    var invocations = Workspace.Links.InternalCalls();
    foreach (var call in Workspace.Links.ExternalCalls("System.Data.SqlClient.SqlCommand.ExecuteReader"))
    {
      if (_findVariableVisitor.FindReferenceVariable(call) as ObjectCreationExpressionSyntax objectCreation)
      {
        var literals = _findLiteralVisitor.FindLiteral(objectCreation.GetArgument(0), invocations);
        foundLiterals?.ForEach(literal => Workspace.Register(new SqlCommandCall(call.Caller, literal)));
      }
    }
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.