Browse Source

Added a support for method parameters. Added a support for generic instance of types.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6041 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Tomáš Linhart 15 years ago
parent
commit
fbad56428a
  1. 10
      src/AddIns/Analysis/CodeQuality/Src/Field.cs
  2. 2
      src/AddIns/Analysis/CodeQuality/Src/MainWindow.xaml
  3. 59
      src/AddIns/Analysis/CodeQuality/Src/Method.cs
  4. 103
      src/AddIns/Analysis/CodeQuality/Src/MetricsReader.cs
  5. 45
      src/AddIns/Analysis/CodeQuality/Src/Type.cs

10
src/AddIns/Analysis/CodeQuality/Src/Field.cs

@ -58,6 +58,16 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -58,6 +58,16 @@ namespace ICSharpCode.CodeQualityAnalysis
/// </summary>
public bool IsReadOnly { get; set; }
/// <summary>
/// Whether the type of field is generic
/// </summary>
public bool IsGenericInstance { get; set; }
/// <summary>
/// If the field has generic instance so all types used in generic are presented in this set.
/// </summary>
public ISet<Type> GenericTypes { get; set; }
public Field()
{
FieldType = null;

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

@ -35,7 +35,7 @@ @@ -35,7 +35,7 @@
<TreeView Name="definitionTree" Grid.Row="1" Grid.Column="0" SelectedItemChanged="definitionTree_SelectedItemChanged" />
<Controls:ZoomControl Grid.Row="1" Grid.Column="1" Name="zoom" AlwaysShowZoomButtons="True" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<Controls:ZoomControl Grid.Row="1" Grid.Column="1" Name="zoom" AlwaysShowZoomButtons="True" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
<graphsharp:GraphLayout x:Name="graphLayout"
LayoutAlgorithmType="LinLog"
OverlapRemovalAlgorithmType="FSA"

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

@ -8,6 +8,11 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -8,6 +8,11 @@ namespace ICSharpCode.CodeQualityAnalysis
{
public class Method : IDependency
{
/// <summary>
/// Parameters which are used by method
/// </summary>
public ISet<MethodParameter> Parameters { get; set; }
/// <summary>
/// Types which are used in body of method
/// </summary>
@ -88,14 +93,29 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -88,14 +93,29 @@ namespace ICSharpCode.CodeQualityAnalysis
/// </summary>
public bool IsVirtual { get; set; }
/// <summary>
/// If the return type is generic instance so all types used in generic are presented in this set.
/// </summary>
public ISet<Type> GenericReturnTypes { get; set; }
/// <summary>
/// Whether the return type is generic instance
/// </summary>
public bool IsReturnTypeGenericInstance { get; set; }
public Method()
{
Parameters = new HashSet<MethodParameter>();
TypeUses = new HashSet<Type>();
MethodUses = new HashSet<Method>();
FieldUses = new HashSet<Field>();
GenericReturnTypes = new HashSet<Type>();
ReturnType = null;
Owner = null;
IsReturnTypeGenericInstance = false;
}
public BidirectionalGraph<object, IEdge<object>> BuildDependencyGraph()
@ -108,4 +128,43 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -108,4 +128,43 @@ namespace ICSharpCode.CodeQualityAnalysis
return Name;
}
}
public class MethodParameter
{
/// <summary>
/// The type of the parameter
/// </summary>
public Type ParameterType { get; set; }
/// <summary>
/// Whether the parameter is generic instance
/// </summary>
public bool IsGenericInstance { get; set; }
/// <summary>
/// Whether the parameter is in
/// </summary>
public bool IsIn { get; set; }
/// <summary>
/// Whether the parameter is out
/// </summary>
public bool IsOut { get; set; }
/// <summary>
/// Whether the parameter is optional
/// </summary>
public bool IsOptional { get; set; }
/// <summary>
/// If the parameter is generic instance so all types used in generic are presented in this set.
/// </summary>
public ISet<Type> GenericTypes { get; set; }
public MethodParameter()
{
GenericTypes = new HashSet<Type>();
IsGenericInstance = false;
}
}
}

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

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mono.Cecil;
@ -175,6 +176,13 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -175,6 +176,13 @@ namespace ICSharpCode.CodeQualityAnalysis
select t).SingleOrDefault();
type.BaseType = baseType; // if baseType is null so propably inherits from another assembly
if (typeDefinition.BaseType.IsGenericInstance)
{
type.IsBaseTypeGenericInstance = true;
type.GenericBaseTypes = ReadGenericArguments(type.Namespace.Module,
(GenericInstanceType)typeDefinition.BaseType);
}
}
// looks for implemented interfaces
@ -189,6 +197,12 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -189,6 +197,12 @@ namespace ICSharpCode.CodeQualityAnalysis
if (implementedIc != null)
type.ImplementedInterfaces.Add(implementedIc);
if (ic.IsGenericInstance)
{
type.GenericBaseTypes.UnionWith(ReadGenericArguments(type.Namespace.Module,
(GenericInstanceType)typeDefinition.BaseType));
}
}
}
@ -227,11 +241,13 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -227,11 +241,13 @@ namespace ICSharpCode.CodeQualityAnalysis
var declaringType =
(from n in type.Namespace.Module.Namespaces
from t in n.Types
where t.Name == e.Name
where t.Name == FormatTypeName(eventDefinition.EventType)
select t).SingleOrDefault();
e.EventType = declaringType;
// TODO:check eventDefinition.OtherMethods
// Mono.Cecil threats Events as regular fields
// so I have to find a field and set IsEvent to true
@ -270,13 +286,20 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -270,13 +286,20 @@ namespace ICSharpCode.CodeQualityAnalysis
type.Fields.Add(field);
var declaringType =
var fieldType =
(from n in type.Namespace.Module.Namespaces
from t in n.Types
where t.Name == FormatTypeName(fieldDefinition.DeclaringType)
where t.Name == FormatTypeName(fieldDefinition.FieldType)
select t).SingleOrDefault();
field.FieldType = declaringType;
if (fieldDefinition.FieldType.IsGenericInstance)
{
field.IsGenericInstance = true;
field.GenericTypes = ReadGenericArguments(type.Namespace.Module,
(GenericInstanceType)fieldDefinition.FieldType);
}
field.FieldType = fieldType;
}
}
@ -313,6 +336,44 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -313,6 +336,44 @@ namespace ICSharpCode.CodeQualityAnalysis
method.ReturnType = returnType; // if null so return type is outside of assembly
if (methodDefinition.ReturnType.IsGenericInstance)
{
method.IsReturnTypeGenericInstance = true;
method.GenericReturnTypes = ReadGenericArguments(type.Namespace.Module,
(GenericInstanceType) methodDefinition.ReturnType);
}
// reading types from parameters
foreach (var parameter in methodDefinition.Parameters)
{
var parameterType =
(from n in type.Namespace.Module.Namespaces
from t in n.Types
where t.Name == FormatTypeName(parameter.ParameterType)
select t).SingleOrDefault();
if (parameterType != null)
{
var param = new MethodParameter
{
ParameterType = parameterType,
IsIn = parameter.IsIn,
IsOut = parameter.IsOut,
IsOptional = parameter.IsOptional,
};
// generic parameters
if (parameter.ParameterType.IsGenericInstance)
{
param.IsGenericInstance = true;
param.GenericTypes = ReadGenericArguments(type.Namespace.Module,
(GenericInstanceType) parameter.ParameterType);
}
method.Parameters.Add(param);
}
}
type.Methods.Add(method);
}
@ -357,7 +418,7 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -357,7 +418,7 @@ namespace ICSharpCode.CodeQualityAnalysis
where m.Name == FormatMethodName(md)
select m).SingleOrDefault();
if (findTargetMethod != null && type == method.ReturnType)
if (findTargetMethod != null && type == method.Owner)
method.MethodUses.Add(findTargetMethod);
}
@ -374,6 +435,34 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -374,6 +435,34 @@ namespace ICSharpCode.CodeQualityAnalysis
}
}
/// <summary>
/// Reads generic arguments from type and returns them as a set of types
/// </summary>
/// <param name="module">The module where are types located</param>
/// <param name="genericInstance">The instance type</param>
/// <returns>A set of types used by generic instance</returns>
public ISet<Type> ReadGenericArguments(Module module, GenericInstanceType genericInstance)
{
var types = new HashSet<Type>();
foreach (var parameter in genericInstance.GenericArguments)
{
var type =
(from n in module.Namespaces
from t in n.Types
where t.Name == FormatTypeName(parameter)
select t).SingleOrDefault();
if (type != null) //
types.Add(type);
if (parameter.IsGenericInstance)
types.UnionWith(ReadGenericArguments(module, (GenericInstanceType) parameter));
}
return types;
}
/// <summary>
/// Reads instruction operand by recursive calling until non-instruction
/// operand is found
@ -427,6 +516,8 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -427,6 +516,8 @@ namespace ICSharpCode.CodeQualityAnalysis
/// <returns>A type name</returns>
public string FormatTypeName(TypeReference type)
{
type = type.GetElementType();
if (type.IsNested && type.DeclaringType != null)
{
return FormatTypeName(type.DeclaringType) + "+" + type.Name;
@ -439,7 +530,7 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -439,7 +530,7 @@ namespace ICSharpCode.CodeQualityAnalysis
bool hasNext = enumerator.MoveNext();
while (hasNext)
{
builder.Append((enumerator.Current).Name);
builder.Append(enumerator.Current.Name);
hasNext = enumerator.MoveNext();
if (hasNext)
builder.Append(",");

45
src/AddIns/Analysis/CodeQuality/Src/Type.cs

@ -124,6 +124,20 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -124,6 +124,20 @@ namespace ICSharpCode.CodeQualityAnalysis
/// </summary>
public bool IsNestedProtected { get; set; }
/// <summary>
/// Whether the base type is generic instance
/// </summary>
public bool IsBaseTypeGenericInstance { get; set; }
/// <summary>
/// If the base type is generic instance so all types used in generic are presented in this set.
/// </summary>
public ISet<Type> GenericBaseTypes { get; set; }
/// <summary>
/// If one of implemented interfaces is generic instance so all types used in generic are presented in this set.
/// </summary>
public ISet<Type> GenericImplementedInterfacesTypes { get; set; }
public Type()
{
@ -132,9 +146,13 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -132,9 +146,13 @@ namespace ICSharpCode.CodeQualityAnalysis
Events = new HashSet<Event>();
NestedTypes = new HashSet<Type>();
ImplementedInterfaces = new HashSet<Type>();
GenericBaseTypes = new HashSet<Type>();
GenericImplementedInterfacesTypes = new HashSet<Type>();
Owner = null;
BaseType = null;
IsBaseTypeGenericInstance = false;
}
/// <summary>
@ -148,14 +166,41 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -148,14 +166,41 @@ namespace ICSharpCode.CodeQualityAnalysis
foreach (var method in Methods)
{
set.UnionWith(method.TypeUses);
foreach (var parameter in method.Parameters)
{
if (parameter.IsGenericInstance)
set.UnionWith(parameter.GenericTypes);
if (parameter.ParameterType != null)
set.Add(parameter.ParameterType);
}
if (method.IsReturnTypeGenericInstance)
set.UnionWith(method.GenericReturnTypes);
if (method.ReturnType != null)
set.Add(method.ReturnType);
}
foreach (var field in Fields)
{
if (field.IsGenericInstance)
set.UnionWith(field.GenericTypes);
if (field.FieldType != null) // if it is null so it is type from outside of this assembly
set.Add(field.FieldType); // TODO: find solution to handle them
}
if (BaseType != null)
set.Add(BaseType);
if (IsBaseTypeGenericInstance)
set.UnionWith(GenericBaseTypes);
set.UnionWith(ImplementedInterfaces);
set.UnionWith(GenericImplementedInterfacesTypes);
return set;
}

Loading…
Cancel
Save