Browse Source

Added a support for instructions.

Assembly stats are now hidden when no assembly is opened.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6386 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Tomáš Linhart 16 years ago
parent
commit
11454252ad
  1. 10
      src/AddIns/Analysis/CodeQuality/CodeQualityAnalysis.csproj
  2. 13
      src/AddIns/Analysis/CodeQuality/Src/Instruction.cs
  3. 4
      src/AddIns/Analysis/CodeQuality/Src/MainWindow.xaml
  4. 20
      src/AddIns/Analysis/CodeQuality/Src/MainWindow.xaml.cs
  5. 412
      src/AddIns/Analysis/CodeQuality/Src/Method.cs
  6. 108
      src/AddIns/Analysis/CodeQuality/Src/MetricsReader.cs
  7. 7
      src/AddIns/Analysis/CodeQuality/Src/Module.cs

10
src/AddIns/Analysis/CodeQuality/CodeQualityAnalysis.csproj

@ -113,13 +113,13 @@
<Compile Include="Src\Controls\DependencyEdge.cs" /> <Compile Include="Src\Controls\DependencyEdge.cs" />
<Compile Include="Src\Controls\DependencyGraph.cs" /> <Compile Include="Src\Controls\DependencyGraph.cs" />
<Compile Include="Src\Controls\DependencyGraphLayout.cs" /> <Compile Include="Src\Controls\DependencyGraphLayout.cs" />
<Compile Include="Src\Controls\DependencyMatrixControl.cs" /> <Compile Include="Src\Controls\DependencyMatrixControl.cs">
<Compile Include="Src\Controls\DependencyMatrix.cs" /> <SubType>Component</SubType> </Compile> <Compile Include="Src\Controls\DependencyMatrix.cs" />
<Compile Include="Src\Controls\DependencyVertex.cs" /> <Compile Include="Src\Controls\DependencyVertex.cs" />
<Compile Include="Src\Controls\DependencyIconVertexConverter.cs" /> <Compile Include="Src\Controls\DependencyIconVertexConverter.cs" />
<Compile Include="Src\Controls\Matrix.cs" /> <Compile Include="Src\Controls\Matrix.cs" />
<Compile Include="Src\Controls\MatrixControl.cs" /> <Compile Include="Src\Controls\MatrixControl.cs">
<Compile Include="Src\Controls\TreeMatrixControl.xaml.cs"> <SubType>Component</SubType> </Compile> <Compile Include="Src\Controls\TreeMatrixControl.xaml.cs">
<DependentUpon>TreeMatrixControl.xaml</DependentUpon> <DependentUpon>TreeMatrixControl.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
@ -127,7 +127,7 @@
<Compile Include="Src\Event.cs" /> <Compile Include="Src\Event.cs" />
<Compile Include="Src\Field.cs" /> <Compile Include="Src\Field.cs" />
<Compile Include="Src\INode.cs" /> <Compile Include="Src\INode.cs" />
<Compile Include="Src\NodeIconService.cs" /> <Compile Include="Src\Instruction.cs" /> <Compile Include="Src\NodeIconService.cs" />
<Compile Include="Src\IDependency.cs" /> <Compile Include="Src\IDependency.cs" />
<Compile Include="Src\MetricsReader.cs" /> <Compile Include="Src\MetricsReader.cs" />
<Compile Include="Src\Method.cs" /> <Compile Include="Src\Method.cs" />

13
src/AddIns/Analysis/CodeQuality/Src/Instruction.cs

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ICSharpCode.CodeQualityAnalysis
{
public class Instruction
{
public Method DeclaringMethod { get; set; }
public string Operand { get; set; }
}
}

4
src/AddIns/Analysis/CodeQuality/Src/MainWindow.xaml

@ -113,7 +113,7 @@
<ProgressBar IsIndeterminate="True" Width="95" Height="15" /> <ProgressBar IsIndeterminate="True" Width="95" Height="15" />
</StackPanel> </StackPanel>
</StatusBarItem> </StatusBarItem>
<StatusBarItem HorizontalAlignment="Right"> <StatusBarItem HorizontalAlignment="Right" x:Name="assemblyStats" Visibility="Hidden">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<StatusBarItem> <StatusBarItem>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
@ -142,7 +142,7 @@
<StatusBarItem> <StatusBarItem>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock Text="IL instructions: " /> <TextBlock Text="IL instructions: " />
<TextBlock Text="TBD" /> <TextBlock Text="{Binding Path=MetricsReader.MainModule.InstructionsCount}" />
</StackPanel> </StackPanel>
</StatusBarItem> </StatusBarItem>
</StackPanel> </StackPanel>

20
src/AddIns/Analysis/CodeQuality/Src/MainWindow.xaml.cs

@ -34,10 +34,10 @@ namespace ICSharpCode.CodeQualityAnalysis
private MetricsReader metricsReader; private MetricsReader metricsReader;
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
public MetricsReader MetricsReader public MetricsReader MetricsReader
{ {
get get
{ {
return metricsReader; return metricsReader;
} }
@ -54,10 +54,10 @@ namespace ICSharpCode.CodeQualityAnalysis
} }
private void NotifyPropertyChanged(string propertyName) private void NotifyPropertyChanged(string propertyName)
{ {
if (PropertyChanged != null) if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
} }
private void btnOpenAssembly_Click(object sender, RoutedEventArgs e) private void btnOpenAssembly_Click(object sender, RoutedEventArgs e)
{ {
@ -72,12 +72,14 @@ namespace ICSharpCode.CodeQualityAnalysis
return; return;
progressBar.Visibility = Visibility.Visible; progressBar.Visibility = Visibility.Visible;
assemblyStats.Visibility = Visibility.Hidden;
fileAssemblyLoading.Text = System.IO.Path.GetFileName(fileDialog.FileName); fileAssemblyLoading.Text = System.IO.Path.GetFileName(fileDialog.FileName);
var worker = new BackgroundWorker(); var worker = new BackgroundWorker();
worker.DoWork += (source, args) => MetricsReader = new MetricsReader(fileDialog.FileName); worker.DoWork += (source, args) => MetricsReader = new MetricsReader(fileDialog.FileName);
worker.RunWorkerCompleted += (source, args) => { worker.RunWorkerCompleted += (source, args) => {
progressBar.Visibility = Visibility.Hidden; progressBar.Visibility = Visibility.Hidden;
assemblyStats.Visibility = Visibility.Visible;
FillMatrix(); FillMatrix();
}; };

412
src/AddIns/Analysis/CodeQuality/Src/Method.cs

@ -9,207 +9,213 @@ using QuickGraph;
namespace ICSharpCode.CodeQualityAnalysis namespace ICSharpCode.CodeQualityAnalysis
{ {
public class Method : INode public class Method : INode
{ {
/// <summary> /// <summary>
/// Parameters which are used by method /// Parameters which are used by method
/// </summary> /// </summary>
public ISet<MethodParameter> Parameters { get; private set; } public ISet<MethodParameter> Parameters { get; private set; }
/// <summary> /// <summary>
/// Types which are used in body of method /// Types which are used in body of method
/// </summary> /// </summary>
public ISet<Type> TypeUses { get; private set; } public ISet<Type> TypeUses { get; private set; }
/// <summary> /// <summary>
/// Methods which are called in body of method /// Methods which are called in body of method
/// </summary> /// </summary>
public ISet<Method> MethodUses { get; private set; } public ISet<Method> MethodUses { get; private set; }
/// <summary> /// <summary>
/// Fields which are accesed in body of method /// Fields which are accesed in body of method
/// </summary> /// </summary>
public ISet<Field> FieldUses { get; private set; } public ISet<Field> FieldUses { get; private set; }
/// <summary> /// <summary>
/// A name of method /// Instructions inside of the method
/// </summary> /// </summary>
public string Name { get; set; } public ISet<Instruction> Instructions { get; private set; }
/// <summary> /// <summary>
/// A return type of method /// A name of method
/// </summary> /// </summary>
public Type ReturnType { get; set; } public string Name { get; set; }
/// <summary> /// <summary>
/// Type which owns this method /// A return type of method
/// </summary> /// </summary>
public Type Owner { get; set; } public Type ReturnType { get; set; }
/// <summary> /// <summary>
/// Whether the method is constructor or not /// Type which owns this method
/// </summary> /// </summary>
public bool IsConstructor { get; set; } public Type Owner { get; set; }
/// <summary> /// <summary>
/// Whether the method is public /// Whether the method is constructor or not
/// </summary> /// </summary>
public bool IsPublic { get; set; } public bool IsConstructor { get; set; }
/// <summary> /// <summary>
/// Whether the method is private /// Whether the method is public
/// </summary> /// </summary>
public bool IsPrivate { get; set; } public bool IsPublic { get; set; }
/// <summary> /// <summary>
/// Whether the method is protected /// Whether the method is private
/// </summary> /// </summary>
public bool IsProtected { get; set; } public bool IsPrivate { get; set; }
/// <summary> /// <summary>
/// Whether the method is static /// Whether the method is protected
/// </summary> /// </summary>
public bool IsStatic { get; set; } public bool IsProtected { get; set; }
/// <summary> /// <summary>
/// Whether the method is sealed /// Whether the method is static
/// </summary> /// </summary>
public bool IsSealed { get; set; } public bool IsStatic { get; set; }
/// <summary> /// <summary>
/// Whether the method is abstract /// Whether the method is sealed
/// </summary> /// </summary>
public bool IsAbstract { get; set; } public bool IsSealed { get; set; }
/// <summary> /// <summary>
/// Whether the method is setter /// Whether the method is abstract
/// </summary> /// </summary>
public bool IsSetter { get; set; } public bool IsAbstract { get; set; }
/// <summary> /// <summary>
/// Whether the method is getter /// Whether the method is setter
/// </summary> /// </summary>
public bool IsGetter { get; set; } public bool IsSetter { get; set; }
/// <summary> /// <summary>
/// Whether the method is virtual /// Whether the method is getter
/// </summary> /// </summary>
public bool IsVirtual { get; set; } public bool IsGetter { get; set; }
/// <summary> /// <summary>
/// If the return type is generic instance so all types used in generic are presented in this set. /// Whether the method is virtual
/// </summary> /// </summary>
public ISet<Type> GenericReturnTypes { get; private set; } public bool IsVirtual { get; set; }
/// <summary> /// <summary>
/// Whether the return type is generic instance /// If the return type is generic instance so all types used in generic are presented in this set.
/// </summary> /// </summary>
public bool IsReturnTypeGenericInstance { get; set; } public ISet<Type> GenericReturnTypes { get; private set; }
public Method() /// <summary>
{ /// Whether the return type is generic instance
Parameters = new HashSet<MethodParameter>(); /// </summary>
public bool IsReturnTypeGenericInstance { get; set; }
TypeUses = new HashSet<Type>();
MethodUses = new HashSet<Method>(); public Method()
FieldUses = new HashSet<Field>(); {
GenericReturnTypes = new HashSet<Type>(); Parameters = new HashSet<MethodParameter>();
ReturnType = null; TypeUses = new HashSet<Type>();
Owner = null; MethodUses = new HashSet<Method>();
FieldUses = new HashSet<Field>();
IsReturnTypeGenericInstance = false; Instructions = new HashSet<Instruction>();
GenericReturnTypes = new HashSet<Type>();
Dependency = null;
} ReturnType = null;
Owner = null;
public Relationship GetRelationship(INode node)
{ IsReturnTypeGenericInstance = false;
Relationship relationship = new Relationship();
return relationship; Dependency = null;
} }
public override string ToString() public Relationship GetRelationship(INode node)
{ {
return Name; Relationship relationship = new Relationship();
} return relationship;
}
public IDependency Dependency { get; set; }
public override string ToString()
public string GetInfo() {
{ return Name;
var builder = new StringBuilder(); }
builder.AppendLine("Method Summary");
builder.Append(Environment.NewLine); public IDependency Dependency { get; set; }
builder.AppendLine(String.Format("Name: {0}", Name));
builder.AppendLine(String.Format("Parameters: {0}", Parameters.Count)); public string GetInfo()
// more to come {
var builder = new StringBuilder();
builder.Append(Environment.NewLine); builder.AppendLine("Method Summary");
builder.Append(Environment.NewLine);
if (IsAbstract) builder.AppendLine(String.Format("Name: {0}", Name));
builder.AppendLine("IsAbstract"); builder.AppendLine(String.Format("Parameters: {0}", Parameters.Count));
if (IsConstructor) // more to come
builder.AppendLine("IsConstructor");
if (IsGetter) builder.Append(Environment.NewLine);
builder.AppendLine("IsGetter");
if (IsSetter) if (IsAbstract)
builder.AppendLine("IsSetter"); builder.AppendLine("IsAbstract");
if (IsPrivate) if (IsConstructor)
builder.AppendLine("IsPrivate"); builder.AppendLine("IsConstructor");
if (IsProtected) if (IsGetter)
builder.AppendLine("IsProtected"); builder.AppendLine("IsGetter");
if (IsPublic) if (IsSetter)
builder.AppendLine("IsPublic"); builder.AppendLine("IsSetter");
if (IsSealed) if (IsPrivate)
builder.AppendLine("IsSealed"); builder.AppendLine("IsPrivate");
if (IsStatic) if (IsProtected)
builder.AppendLine("IsStatic"); builder.AppendLine("IsProtected");
if (IsVirtual) if (IsPublic)
builder.AppendLine("IsVirtual"); builder.AppendLine("IsPublic");
if (IsSealed)
return builder.ToString(); builder.AppendLine("IsSealed");
} if (IsStatic)
builder.AppendLine("IsStatic");
public BitmapSource Icon { get { return NodeIconService.GetIcon(this); } } if (IsVirtual)
} builder.AppendLine("IsVirtual");
public class MethodParameter return builder.ToString();
{ }
/// <summary>
/// The type of the parameter public BitmapSource Icon { get { return NodeIconService.GetIcon(this); } }
/// </summary> }
public Type ParameterType { get; set; }
public class MethodParameter
/// <summary> {
/// Whether the parameter is generic instance /// <summary>
/// </summary> /// The type of the parameter
public bool IsGenericInstance { get; set; } /// </summary>
public Type ParameterType { get; set; }
/// <summary>
/// Whether the parameter is in /// <summary>
/// </summary> /// Whether the parameter is generic instance
public bool IsIn { get; set; } /// </summary>
public bool IsGenericInstance { get; set; }
/// <summary>
/// Whether the parameter is out /// <summary>
/// </summary> /// Whether the parameter is in
public bool IsOut { get; set; } /// </summary>
public bool IsIn { get; set; }
/// <summary>
/// Whether the parameter is optional /// <summary>
/// </summary> /// Whether the parameter is out
public bool IsOptional { get; set; } /// </summary>
public bool IsOut { get; set; }
/// <summary>
/// If the parameter is generic instance so all types used in generic are presented in this set. /// <summary>
/// </summary> /// Whether the parameter is optional
public ISet<Type> GenericTypes { get; set; } /// </summary>
public bool IsOptional { get; set; }
public MethodParameter()
{ /// <summary>
GenericTypes = new HashSet<Type>(); /// If the parameter is generic instance so all types used in generic are presented in this set.
IsGenericInstance = false; /// </summary>
} public ISet<Type> GenericTypes { get; set; }
}
public MethodParameter()
{
GenericTypes = new HashSet<Type>();
IsGenericInstance = false;
}
}
} }

108
src/AddIns/Analysis/CodeQuality/Src/MetricsReader.cs

@ -131,19 +131,19 @@ namespace ICSharpCode.CodeQualityAnalysis
IsStruct = typeDefinition.IsValueType && !typeDefinition.IsEnum && typeDefinition.IsSealed, IsStruct = typeDefinition.IsValueType && !typeDefinition.IsEnum && typeDefinition.IsSealed,
IsInternal = typeDefinition.IsNotPublic, IsInternal = typeDefinition.IsNotPublic,
IsDelegate = (typeDefinition.BaseType != null ? IsDelegate = (typeDefinition.BaseType != null ?
typeDefinition.BaseType.FullName == "System.MulticastDelegate" : false), typeDefinition.BaseType.FullName == "System.MulticastDelegate" : false),
IsNestedPrivate = typeDefinition.IsNestedPrivate, IsNestedPrivate = typeDefinition.IsNestedPrivate,
IsNestedPublic = typeDefinition.IsNestedPublic, IsNestedPublic = typeDefinition.IsNestedPublic,
IsNestedProtected = (!typeDefinition.IsNestedPrivate && !typeDefinition.IsNestedPublic && IsNestedProtected = (!typeDefinition.IsNestedPrivate && !typeDefinition.IsNestedPublic &&
typeDefinition.IsNestedFamily) typeDefinition.IsNestedFamily)
}; };
// try find namespace // try find namespace
var nsName = GetNamespaceName(typeDefinition); var nsName = GetNamespaceName(typeDefinition);
var ns = (from n in module.Namespaces var ns = (from n in module.Namespaces
where n.Name == nsName where n.Name == nsName
select n).SingleOrDefault(); select n).SingleOrDefault();
if (ns == null) if (ns == null)
{ {
@ -182,9 +182,9 @@ namespace ICSharpCode.CodeQualityAnalysis
if (typeDefinition.BaseType != null) if (typeDefinition.BaseType != null)
{ {
var baseType = (from n in module.Namespaces var baseType = (from n in module.Namespaces
from t in n.Types from t in n.Types
where (t.FullName == FormatTypeName(typeDefinition.BaseType, true)) where (t.FullName == FormatTypeName(typeDefinition.BaseType, true))
select t).SingleOrDefault(); select t).SingleOrDefault();
type.BaseType = baseType; // if baseType is null so propably inherits from another assembly type.BaseType = baseType; // if baseType is null so propably inherits from another assembly
@ -192,7 +192,7 @@ namespace ICSharpCode.CodeQualityAnalysis
{ {
type.IsBaseTypeGenericInstance = true; type.IsBaseTypeGenericInstance = true;
type.GenericBaseTypes.UnionWith(ReadGenericArguments(type.Namespace.Module, type.GenericBaseTypes.UnionWith(ReadGenericArguments(type.Namespace.Module,
(GenericInstanceType)typeDefinition.BaseType)); (GenericInstanceType)typeDefinition.BaseType));
} }
} }
@ -202,9 +202,9 @@ namespace ICSharpCode.CodeQualityAnalysis
foreach (var ic in typeDefinition.Interfaces) foreach (var ic in typeDefinition.Interfaces)
{ {
var implementedIc = (from n in module.Namespaces var implementedIc = (from n in module.Namespaces
from t in n.Types from t in n.Types
where (t.FullName == FormatTypeName(ic, true)) where (t.FullName == FormatTypeName(ic, true))
select t).SingleOrDefault(); select t).SingleOrDefault();
if (implementedIc != null) if (implementedIc != null)
type.ImplementedInterfaces.Add(implementedIc); type.ImplementedInterfaces.Add(implementedIc);
@ -212,7 +212,7 @@ namespace ICSharpCode.CodeQualityAnalysis
if (ic.IsGenericInstance) if (ic.IsGenericInstance)
{ {
type.GenericBaseTypes.UnionWith(ReadGenericArguments(type.Namespace.Module, type.GenericBaseTypes.UnionWith(ReadGenericArguments(type.Namespace.Module,
(GenericInstanceType)ic)); (GenericInstanceType)ic));
} }
} }
} }
@ -307,7 +307,7 @@ namespace ICSharpCode.CodeQualityAnalysis
{ {
field.IsGenericInstance = true; field.IsGenericInstance = true;
field.GenericTypes.UnionWith(ReadGenericArguments(type.Namespace.Module, field.GenericTypes.UnionWith(ReadGenericArguments(type.Namespace.Module,
(GenericInstanceType)fieldDefinition.FieldType)); (GenericInstanceType)fieldDefinition.FieldType));
} }
field.FieldType = fieldType; field.FieldType = fieldType;
@ -351,7 +351,7 @@ namespace ICSharpCode.CodeQualityAnalysis
{ {
method.IsReturnTypeGenericInstance = true; method.IsReturnTypeGenericInstance = true;
method.GenericReturnTypes.UnionWith(ReadGenericArguments(type.Namespace.Module, method.GenericReturnTypes.UnionWith(ReadGenericArguments(type.Namespace.Module,
(GenericInstanceType) methodDefinition.ReturnType)); (GenericInstanceType) methodDefinition.ReturnType));
} }
// reading types from parameters // reading types from parameters
@ -378,7 +378,7 @@ namespace ICSharpCode.CodeQualityAnalysis
{ {
param.IsGenericInstance = true; param.IsGenericInstance = true;
param.GenericTypes = ReadGenericArguments(type.Namespace.Module, param.GenericTypes = ReadGenericArguments(type.Namespace.Module,
(GenericInstanceType) parameter.ParameterType); (GenericInstanceType) parameter.ParameterType);
} }
method.Parameters.Add(param); method.Parameters.Add(param);
@ -391,8 +391,8 @@ namespace ICSharpCode.CodeQualityAnalysis
foreach (MethodDefinition methodDefinition in methods) foreach (MethodDefinition methodDefinition in methods)
{ {
var method = (from m in type.Methods var method = (from m in type.Methods
where m.Name == FormatMethodName(methodDefinition) where m.Name == FormatMethodName(methodDefinition)
select m).SingleOrDefault(); select m).SingleOrDefault();
if (methodDefinition.Body != null) if (methodDefinition.Body != null)
{ {
@ -408,36 +408,42 @@ namespace ICSharpCode.CodeQualityAnalysis
/// <param name="methodDefinition">A method definition with instructions</param> /// <param name="methodDefinition">A method definition with instructions</param>
/// <param name="instructions">A collection of instructions</param> /// <param name="instructions">A collection of instructions</param>
public void ReadInstructions(Method method, MethodDefinition methodDefinition, public void ReadInstructions(Method method, MethodDefinition methodDefinition,
Collection<Instruction> instructions) Collection<Mono.Cecil.Cil.Instruction> instructions)
{ {
foreach (Instruction instruction in instructions) foreach (var instruction in instructions)
{ {
var instr = ReadInstruction(instruction); method.Instructions.Add(new Instruction
{
DeclaringMethod = method,
// Operand = instruction.Operand.ToString() // for now operand as string should be enough
});
if (instr is MethodDefinition) var operand = ReadOperand(instruction);
if (operand is MethodDefinition)
{ {
var md = instr as MethodDefinition; var md = operand as MethodDefinition;
var type = (from n in method.Owner.Namespace.Module.Namespaces var type = (from n in method.Owner.Namespace.Module.Namespaces
from t in n.Types from t in n.Types
where t.FullName == FormatTypeName(md.DeclaringType, true) where t.FullName == FormatTypeName(md.DeclaringType, true)
select t).SingleOrDefault(); select t).SingleOrDefault();
method.TypeUses.Add(type); method.TypeUses.Add(type);
var findTargetMethod = (from m in type.Methods var findTargetMethod = (from m in type.Methods
where m.Name == FormatMethodName(md) where m.Name == FormatMethodName(md)
select m).SingleOrDefault(); select m).SingleOrDefault();
if (findTargetMethod != null && type == method.Owner) if (findTargetMethod != null && type == method.Owner)
method.MethodUses.Add(findTargetMethod); method.MethodUses.Add(findTargetMethod);
} }
if (instr is FieldDefinition) if (operand is FieldDefinition)
{ {
var fd = instr as FieldDefinition; var fd = operand as FieldDefinition;
var field = (from f in method.Owner.Fields var field = (from f in method.Owner.Fields
where f.Name == fd.Name where f.Name == fd.Name
select f).SingleOrDefault(); select f).SingleOrDefault();
if (field != null) if (field != null)
method.FieldUses.Add(field); method.FieldUses.Add(field);
@ -445,6 +451,25 @@ namespace ICSharpCode.CodeQualityAnalysis
} }
} }
/// <summary>
/// Reads an instruction operand by recursive calling until non-instruction
/// operand is found
/// </summary>
/// <param name="instruction">An instruction with operand</param>
/// <returns>An instruction operand</returns>
public object ReadOperand(Mono.Cecil.Cil.Instruction instruction)
{
if (instruction.Operand == null)
return null;
var nextInstruction = instruction.Operand as Mono.Cecil.Cil.Instruction;
if (nextInstruction != null)
return ReadOperand(nextInstruction);
return instruction.Operand;
}
/// <summary> /// <summary>
/// Reads generic arguments from type and returns them as a set of types /// Reads generic arguments from type and returns them as a set of types
/// </summary> /// </summary>
@ -473,25 +498,6 @@ namespace ICSharpCode.CodeQualityAnalysis
return types; return types;
} }
/// <summary>
/// Reads instruction operand by recursive calling until non-instruction
/// operand is found
/// </summary>
/// <param name="instruction">An instruction with operand</param>
/// <returns>An instruction operand</returns>
public object ReadInstruction(Instruction instruction)
{
if (instruction.Operand == null)
return null;
var nextInstruction = instruction.Operand as Instruction;
if (nextInstruction != null)
return ReadInstruction(nextInstruction);
return instruction.Operand;
}
/// <summary> /// <summary>
/// Formats method name by adding parameters to it. If there are not any parameters /// Formats method name by adding parameters to it. If there are not any parameters
/// only empty brackers will be added. /// only empty brackers will be added.

7
src/AddIns/Analysis/CodeQuality/Src/Module.cs

@ -95,6 +95,13 @@ namespace ICSharpCode.CodeQualityAnalysis
} }
} }
public int InstructionsCount
{
get {
return Namespaces.Sum(ns => ns.Types.Sum(type => type.Methods.Sum(method => method.Instructions.Count)));
}
}
public string GetInfo() public string GetInfo()
{ {
var builder = new StringBuilder(); var builder = new StringBuilder();

Loading…
Cancel
Save