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
/// </summary> /// </summary>
public bool IsReadOnly { get; set; } 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() public Field()
{ {
FieldType = null; FieldType = null;

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

@ -35,7 +35,7 @@
<TreeView Name="definitionTree" Grid.Row="1" Grid.Column="0" SelectedItemChanged="definitionTree_SelectedItemChanged" /> <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" <graphsharp:GraphLayout x:Name="graphLayout"
LayoutAlgorithmType="LinLog" LayoutAlgorithmType="LinLog"
OverlapRemovalAlgorithmType="FSA" OverlapRemovalAlgorithmType="FSA"

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

@ -8,6 +8,11 @@ namespace ICSharpCode.CodeQualityAnalysis
{ {
public class Method : IDependency public class Method : IDependency
{ {
/// <summary>
/// Parameters which are used by method
/// </summary>
public ISet<MethodParameter> Parameters { get; set; }
/// <summary> /// <summary>
/// Types which are used in body of method /// Types which are used in body of method
/// </summary> /// </summary>
@ -88,14 +93,29 @@ namespace ICSharpCode.CodeQualityAnalysis
/// </summary> /// </summary>
public bool IsVirtual { get; set; } 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() public Method()
{ {
Parameters = new HashSet<MethodParameter>();
TypeUses = new HashSet<Type>(); TypeUses = new HashSet<Type>();
MethodUses = new HashSet<Method>(); MethodUses = new HashSet<Method>();
FieldUses = new HashSet<Field>(); FieldUses = new HashSet<Field>();
GenericReturnTypes = new HashSet<Type>();
ReturnType = null; ReturnType = null;
Owner = null; Owner = null;
IsReturnTypeGenericInstance = false;
} }
public BidirectionalGraph<object, IEdge<object>> BuildDependencyGraph() public BidirectionalGraph<object, IEdge<object>> BuildDependencyGraph()
@ -108,4 +128,43 @@ namespace ICSharpCode.CodeQualityAnalysis
return Name; 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 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Mono.Cecil; using Mono.Cecil;
@ -175,6 +176,13 @@ namespace ICSharpCode.CodeQualityAnalysis
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
if (typeDefinition.BaseType.IsGenericInstance)
{
type.IsBaseTypeGenericInstance = true;
type.GenericBaseTypes = ReadGenericArguments(type.Namespace.Module,
(GenericInstanceType)typeDefinition.BaseType);
}
} }
// looks for implemented interfaces // looks for implemented interfaces
@ -189,6 +197,12 @@ namespace ICSharpCode.CodeQualityAnalysis
if (implementedIc != null) if (implementedIc != null)
type.ImplementedInterfaces.Add(implementedIc); type.ImplementedInterfaces.Add(implementedIc);
if (ic.IsGenericInstance)
{
type.GenericBaseTypes.UnionWith(ReadGenericArguments(type.Namespace.Module,
(GenericInstanceType)typeDefinition.BaseType));
}
} }
} }
@ -227,11 +241,13 @@ namespace ICSharpCode.CodeQualityAnalysis
var declaringType = var declaringType =
(from n in type.Namespace.Module.Namespaces (from n in type.Namespace.Module.Namespaces
from t in n.Types from t in n.Types
where t.Name == e.Name where t.Name == FormatTypeName(eventDefinition.EventType)
select t).SingleOrDefault(); select t).SingleOrDefault();
e.EventType = declaringType; e.EventType = declaringType;
// TODO:check eventDefinition.OtherMethods
// Mono.Cecil threats Events as regular fields // Mono.Cecil threats Events as regular fields
// so I have to find a field and set IsEvent to true // so I have to find a field and set IsEvent to true
@ -270,13 +286,20 @@ namespace ICSharpCode.CodeQualityAnalysis
type.Fields.Add(field); type.Fields.Add(field);
var declaringType = var fieldType =
(from n in type.Namespace.Module.Namespaces (from n in type.Namespace.Module.Namespaces
from t in n.Types from t in n.Types
where t.Name == FormatTypeName(fieldDefinition.DeclaringType) where t.Name == FormatTypeName(fieldDefinition.FieldType)
select t).SingleOrDefault(); 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
method.ReturnType = returnType; // if null so return type is outside of assembly 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); type.Methods.Add(method);
} }
@ -357,7 +418,7 @@ namespace ICSharpCode.CodeQualityAnalysis
where m.Name == FormatMethodName(md) where m.Name == FormatMethodName(md)
select m).SingleOrDefault(); select m).SingleOrDefault();
if (findTargetMethod != null && type == method.ReturnType) if (findTargetMethod != null && type == method.Owner)
method.MethodUses.Add(findTargetMethod); method.MethodUses.Add(findTargetMethod);
} }
@ -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> /// <summary>
/// Reads instruction operand by recursive calling until non-instruction /// Reads instruction operand by recursive calling until non-instruction
/// operand is found /// operand is found
@ -427,6 +516,8 @@ namespace ICSharpCode.CodeQualityAnalysis
/// <returns>A type name</returns> /// <returns>A type name</returns>
public string FormatTypeName(TypeReference type) public string FormatTypeName(TypeReference type)
{ {
type = type.GetElementType();
if (type.IsNested && type.DeclaringType != null) if (type.IsNested && type.DeclaringType != null)
{ {
return FormatTypeName(type.DeclaringType) + "+" + type.Name; return FormatTypeName(type.DeclaringType) + "+" + type.Name;
@ -439,7 +530,7 @@ namespace ICSharpCode.CodeQualityAnalysis
bool hasNext = enumerator.MoveNext(); bool hasNext = enumerator.MoveNext();
while (hasNext) while (hasNext)
{ {
builder.Append((enumerator.Current).Name); builder.Append(enumerator.Current.Name);
hasNext = enumerator.MoveNext(); hasNext = enumerator.MoveNext();
if (hasNext) if (hasNext)
builder.Append(","); builder.Append(",");

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

@ -124,6 +124,20 @@ namespace ICSharpCode.CodeQualityAnalysis
/// </summary> /// </summary>
public bool IsNestedProtected { get; set; } 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() public Type()
{ {
@ -132,9 +146,13 @@ namespace ICSharpCode.CodeQualityAnalysis
Events = new HashSet<Event>(); Events = new HashSet<Event>();
NestedTypes = new HashSet<Type>(); NestedTypes = new HashSet<Type>();
ImplementedInterfaces = new HashSet<Type>(); ImplementedInterfaces = new HashSet<Type>();
GenericBaseTypes = new HashSet<Type>();
GenericImplementedInterfacesTypes = new HashSet<Type>();
Owner = null; Owner = null;
BaseType = null; BaseType = null;
IsBaseTypeGenericInstance = false;
} }
/// <summary> /// <summary>
@ -148,14 +166,41 @@ namespace ICSharpCode.CodeQualityAnalysis
foreach (var method in Methods) foreach (var method in Methods)
{ {
set.UnionWith(method.TypeUses); 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) 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 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 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; return set;
} }

Loading…
Cancel
Save