Home > Code Samples > Creating a command line tool for source code metrics analysis

Creating a command line tool for source code metrics analysis

August 10th, 2011

Recently, we have created a console application that parses an entire solution and shows summary information about declared types and the number of members in each type. Let’s tweak it a bit, so it provides more meaningful and useful information, such as a report of Maintenance Complexity (MC) code metric for a solution source code.

The report will contain the list of declared types and its methods, which do not meet the metrics requirement. For example, the requirement for a method is to have an MC value of less than 200. We will skip methods such as InitializeComponent, because they nearly always get a score higher than 200.

You can use this application in your build scripts to provide a warning if any complex methods exist. Such a warning may motivate you to refactor your source code, for example.

To get the MC metric value for a method, simply call the GetMaintenanceComplexity on its instance. The GetMaintenanceComplexity method is available for any language element, so you can calculate the value for any declarations you need.

Here is the code that calculates code metrics and reporting complex methods found (method’s MC value is greater than 200). The program will print a file name, a type name and method’s signature with the MC value. The two boolean flags are required to avoid printing unnecessary information, such as file names and type names that do not contain complex methods.

bool fileNamePrinted;
bool typeNamePrinted;
const int MAX_MC_VALUE = 200;

foreach (ProjectElement project in solution.AllProjects)
{
  foreach (SourceFile file in project.AllFiles)
  {
    fileNamePrinted = false;
    foreach (TypeDeclaration type in file.AllTypes)
    {
      typeNamePrinted = false;
      foreach (Method method in type.AllMethods)
      {
        if (method.IsInitializeComponent())
          continue;

        int maintenanceComplexity = method.GetMaintenanceComplexity();
        if (maintenanceComplexity > MAX_MC_VALUE)
        {
          if (!fileNamePrinted)
          {
            Console.WriteLine("File name: " + file.Name);
            fileNamePrinted = true;
          }
          if (!typeNamePrinted)
          {
            Console.WriteLine("- Type name: " + type.FullName);
            typeNamePrinted = true;
          }

          Console.WriteLine(String.Format("  Found complex method (MC = {0}): {1}",
          maintenanceComplexity,
          method.Signature));
        }
      }
    }
  }
}

The source code is attached (22,207 bytes, C#, Visual Studio 2010). Don’t forget that you can create your own code metric and use it for source code analysis. If you put the source code into the “C:\Projects” folder, compile it and run the program – it will analyze itself (its source code) and you will get the following output:

Parsing solution... Done.
 File name: c:\Projects\TestDXCoreConsoleApp\TestDXCoreConsoleApp\Program.cs
 - Type name: TestDXCoreConsoleApp.Program
 Found complex method (MC = 234): TestDXCoreConsoleApp.Program/Main
 File name: c:\Projects\TestDXCoreConsoleApp\TestDXCoreConsoleApp\Loaders\ProjectLoaderBase.cs
 - Type name: TestDXCoreConsoleApp.Vs2002VSLangProjectLoader
 Found complex method (MC = 256): TestDXCoreConsoleApp.Vs2002VSLangProjectLoader/LoadReferences

Bear in mind, that DXCore parsers are not supposed to be used outside of the Visual Studio environment, and this program may not work correctly for some solutions.

—–
Products: DXCore
Versions: 11.1 and up
VS IDEs: any
Updated: Aug/10/2011
ID: D104

Similar Posts: