|
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using Microsoft.Cci;
namespace NotUsedFinder
{
/// <summary>
/// This class spins through Modules and catalogs every type, method and field in that module.
/// These catalogs will be used later by the analyzer in order to determine what members are not used
/// </summary>
public class AssemblyCataloger
{
private Dictionary<string, MyTypeNode> typeCatalog = new Dictionary<string, MyTypeNode>();
private Dictionary<string, MyMethodNode> methodCatalog = new Dictionary<string, MyMethodNode>();
private Dictionary<string, MyFieldNode> fieldCatalog = new Dictionary<string, MyFieldNode>();
private AnalysisOptions options;
public AssemblyCataloger(AnalysisOptions options)
{
this.options = options;
}
public void Catalog(Microsoft.Cci.Module module)
{
//spin through the module and catalog each type
foreach (TypeNode type in module.Types)
{
CatalogType(type);
}
}
private void CatalogType(TypeNode type)
{
//Filter out types that start with < because these are generated by the compiler
if (type.FullName.StartsWith("<"))
return;
//rip through the type and catalog all its parts
this.VisitTypeNode(type);
//check for and catalog nested types recursivly
foreach (TypeNode nestedType in type.NestedTypes)
this.CatalogType(nestedType);
}
private void VisitTypeNode(TypeNode type)
{
//Filter out types that start with < because these are generated by the compiler
if (!type.FullName.StartsWith("<"))
{
//use MyTypeNode wrapper in order to use full type hierarchy
MyTypeNode myType = new MyTypeNode(type);
//Add type to catalog
if (!typeCatalog.ContainsKey(myType.FullName))
typeCatalog.Add(myType.FullName, myType);
//now catalog entire type hierarchy, from lowest base class to all sub classes
CatalogTypeHierarcy(myType);
//look for and catalog every method and field
foreach (Member member in type.Members)
{
Field field = member as Field;
if (field != null)
{
VisitField(field);
continue;
}
Method method = member as Method;
if (method != null)
{
VisitMethod(method);
continue;
}
}
}
}
/// <summary>
/// Catalog the entire inheritance hierarchy
/// </summary>
Type objType = typeof(System.Object);
private void CatalogTypeHierarcy(MyTypeNode myType)
{
//dont worry about it if type doesnt have a base or base is object
if (myType.thisType.BaseType != null && myType.thisType.BaseType.FullName != objType.FullName)
{
MyTypeNode baseType = null;
if (typeCatalog.ContainsKey(myType.thisType.BaseType.FullName))
{
//get base type
baseType = typeCatalog[myType.thisType.BaseType.FullName];
}
else
{
//create base type
baseType = new MyTypeNode(myType.thisType.BaseType);
//Add base type to catalog
typeCatalog.Add(baseType.FullName, baseType);
}
//add base as sub's base
myType.baseType = baseType;
//add sub as base's sub
if (!baseType.subTypes.Contains(myType))
baseType.subTypes.Add(myType);
//recursivly catalog base types
CatalogTypeHierarcy(baseType);
}
}
private void VisitMethod(Method method)
{
if (options.AnalyzeForMethods)
{
//Filter out static ctors
if (method.Name.Name == ".cctor")
return;
if (method.Name.Name == ".ctor")
{
//Filter out default instance ctors. These are either required or generated by the compiler
if (method.Parameters.Length == 0)
return;
else if (method.DeclaringType.BaseType != null)
{
//Filter out ctor if it has parms AND its base class has a matching ctor
Method baseCtor = method.DeclaringType.BaseType.GetMatchingMethod(method);
if (baseCtor != null)
return;
}
}
//Filter out finalizers since they are not called explicitly
if (method.Name.Name == "Finalize")
return;
if (!methodCatalog.ContainsKey(method.FullName))
methodCatalog.Add(method.FullName, new MyMethodNode(method));
}
}
private void VisitField(Field field)
{
//Check for literal (const) because the value just gets put into the IL and you cant check for the field name.
//Also check for "value__" for a field name. not sure what this is, but every enum has a field with this name.
if (options.AnalyzeForFields &&
!field.IsLiteral &&
field.Name.Name != "value__")
{
if (!fieldCatalog.ContainsKey(field.FullName))
fieldCatalog.Add(field.FullName, new MyFieldNode(field));
}
}
public Dictionary<string, MyTypeNode> TypeCatalog
{
get { return typeCatalog; }
}
public Dictionary<string, MyMethodNode> MethodCatalog
{
get { return methodCatalog; }
}
public Dictionary<string, MyFieldNode> FieldCatalog
{
get { return fieldCatalog; }
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I have been a professional developer since 1996. My experience comes from many different industries; Data Mining Software, Consulting, E-Commerce, Wholesale Operations, Clinical Software, Insurance, Energy.
I started programming in the military, trying to find better ways to analyze database data, eventually automating my entire job. Later, in college, I automated my way out of another job. This gave me the great idea to switch majors to the only thing that seemed natural…Programming!