Browse Source

implement method usage in method bodies

pull/18/head
Siegfried Pammer 14 years ago
parent
commit
13965a78f9
  1. 9
      SharpDevelop.sln
  2. 4
      src/AddIns/Analysis/CodeQuality/CodeQuality.csproj
  3. 87
      src/AddIns/Analysis/CodeQuality/Engine/AssemblyAnalyzer.cs
  4. 25
      src/AddIns/Analysis/CodeQuality/Engine/Dom/AssemblyNode.cs
  5. 10
      src/AddIns/Analysis/CodeQuality/Engine/Dom/EventNode.cs
  6. 24
      src/AddIns/Analysis/CodeQuality/Engine/Dom/FieldNode.cs
  7. 33
      src/AddIns/Analysis/CodeQuality/Engine/Dom/MethodNode.cs
  8. 19
      src/AddIns/Analysis/CodeQuality/Engine/Dom/NamespaceNode.cs
  9. 4
      src/AddIns/Analysis/CodeQuality/Engine/Dom/PropertyNode.cs
  10. 29
      src/AddIns/Analysis/CodeQuality/Engine/Dom/Relationship.cs
  11. 28
      src/AddIns/Analysis/CodeQuality/Engine/Dom/TypeNode.cs
  12. 72
      src/AddIns/Analysis/CodeQuality/Engine/ILAnalyzer.cs
  13. 2
      src/AddIns/Analysis/CodeQuality/Gui/Controls/DependencyMatrix.cs
  14. 2
      src/AddIns/Analysis/CodeQuality/Gui/DependencyMatrixView.xaml
  15. 33
      src/AddIns/Analysis/CodeQuality/Gui/DependencyMatrixView.xaml.cs
  16. 2
      src/AddIns/Analysis/CodeQuality/Gui/NodeIconService.cs
  17. 6
      src/AddIns/Analysis/CodeQuality/Utils/DependencyColorizer.cs
  18. 16
      src/AddIns/Analysis/CodeQuality/Utils/Extensions.cs
  19. 20
      src/AddIns/Analysis/CodeQuality/Utils/Utils.cs

9
SharpDevelop.sln

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.2.0.8363-alpha
# SharpDevelop 4.2.0.8380-alpha
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{256F5C28-532C-44C0-8AB8-D8EC5E492E01}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
@ -505,10 +505,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceAnalysis", "src\AddIn @@ -505,10 +505,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceAnalysis", "src\AddIn
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MachineSpecifications", "src\AddIns\Analysis\MachineSpecifications\MachineSpecifications\MachineSpecifications.csproj", "{D1DA3B8F-7313-4BDA-8880-461C5F007751}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CodeQuality", "CodeQuality", "{558479FB-A397-4EE9-A1AD-879F80D1FCD0}"
ProjectSection(SolutionItems) = postProject
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeQuality", "src\AddIns\Analysis\CodeQuality\CodeQuality.csproj", "{3C532D80-32B4-40E5-B5FE-BC6BAE1A00E7}"
EndProject
Project("{00000000-0000-0000-0000-000000000000}") = "Tools", "src\Tools\Tools.build", "{3DF4060F-5EE0-41CF-8096-F27355FD5511}"
@ -1266,7 +1262,6 @@ Global @@ -1266,7 +1262,6 @@ Global
{08CE9972-283B-44F4-82FA-966F7DFA6B7A} = {F355E45F-F54F-4B42-8916-9A633A392789}
{CE498514-D12D-4B6E-AE0E-FEC29BD43748} = {F355E45F-F54F-4B42-8916-9A633A392789}
{D1DA3B8F-7313-4BDA-8880-461C5F007751} = {F355E45F-F54F-4B42-8916-9A633A392789}
{558479FB-A397-4EE9-A1AD-879F80D1FCD0} = {F355E45F-F54F-4B42-8916-9A633A392789}
{3C532D80-32B4-40E5-B5FE-BC6BAE1A00E7} = {558479FB-A397-4EE9-A1AD-879F80D1FCD0}
{3C532D80-32B4-40E5-B5FE-BC6BAE1A00E7} = {F355E45F-F54F-4B42-8916-9A633A392789}
EndGlobalSection
EndGlobal

4
src/AddIns/Analysis/CodeQuality/CodeQuality.csproj

@ -106,6 +106,10 @@ @@ -106,6 +106,10 @@
<Name>Mono.Cecil</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\Libraries\NewNRefactory\ICSharpCode.NRefactory.CSharp\ICSharpCode.NRefactory.CSharp.csproj">
<Project>{53DCA265-3C3C-42F9-B647-F72BA678122B}</Project>
<Name>ICSharpCode.NRefactory.CSharp</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Libraries\NewNRefactory\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
<Project>{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}</Project>
<Name>ICSharpCode.NRefactory</Name>

87
src/AddIns/Analysis/CodeQuality/Engine/AssemblyAnalyzer.cs

@ -5,7 +5,6 @@ using System; @@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using ICSharpCode.CodeQuality.Engine.Dom;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
@ -18,13 +17,14 @@ namespace ICSharpCode.CodeQuality.Engine @@ -18,13 +17,14 @@ namespace ICSharpCode.CodeQuality.Engine
/// </summary>
public class AssemblyAnalyzer
{
CecilLoader loader = new CecilLoader(true);
CecilLoader loader = new CecilLoader(true) { IncludeInternalMembers = true };
ICompilation compilation;
Dictionary<IAssembly, AssemblyNode> assemblyMappings;
Dictionary<string, NamespaceNode> namespaceMappings;
Dictionary<ITypeDefinition, TypeNode> typeMappings;
Dictionary<IMethod, MethodNode> methodMappings;
Dictionary<IField, FieldNode> fieldMappings;
internal Dictionary<IAssembly, AssemblyNode> assemblyMappings;
internal Dictionary<string, NamespaceNode> namespaceMappings;
internal Dictionary<ITypeDefinition, TypeNode> typeMappings;
internal Dictionary<IMethod, MethodNode> methodMappings;
internal Dictionary<IField, FieldNode> fieldMappings;
internal Dictionary<MemberReference, IEntity> cecilMappings;
List<string> fileNames;
public AssemblyAnalyzer()
@ -45,25 +45,54 @@ namespace ICSharpCode.CodeQuality.Engine @@ -45,25 +45,54 @@ namespace ICSharpCode.CodeQuality.Engine
assemblyMappings = new Dictionary<IAssembly, AssemblyNode>();
namespaceMappings = new Dictionary<string, NamespaceNode>();
typeMappings = new Dictionary<ITypeDefinition, TypeNode>();
fieldMappings = new Dictionary<IField, FieldNode>();
methodMappings = new Dictionary<IMethod, MethodNode>();
cecilMappings = new Dictionary<MemberReference, IEntity>();
foreach (var type in compilation.GetAllTypeDefinitions()) {
AnalyzeType(type);
ReadType(type);
}
foreach (TypeNode type in typeMappings.Values) {
foreach (var field in type.TypeDefinition.Fields) {
var node = new FieldNode(field);
fieldMappings.Add(field, node);
try {
var cecilObj = loader.GetCecilObject((IUnresolvedField)field.UnresolvedMember);
cecilMappings[cecilObj] = field;
} catch (InvalidOperationException) {}
type.Children.Add(node);
}
foreach (var method in type.TypeDefinition.Methods) {
var node = new MethodNode(method);
methodMappings.Add(method, node);
try {
var cecilObj = loader.GetCecilObject((IUnresolvedMethod)method.UnresolvedMember);
cecilMappings[cecilObj] = method;
} catch (InvalidOperationException) {}
type.Children.Add(node);
}
}
ILAnalyzer analyzer = new ILAnalyzer(loadedAssemblies.Select(asm => loader.GetCecilObject(asm)).ToArray(), this);
foreach (var element in methodMappings) {
int cc;
try {
var cecilObj = loader.GetCecilObject((IUnresolvedMethod)element.Key.UnresolvedMember);
analyzer.Analyze(cecilObj.Body, element.Value, out cc);
} catch (InvalidOperationException) {}
}
return new ReadOnlyCollection<AssemblyNode>(assemblyMappings.Values.ToList());
}
IEnumerable<IUnresolvedAssembly> LoadAssemblies()
{
var resolver = new DefaultAssemblyResolver();
foreach (var file in fileNames) {
var mainAsm = loader.LoadAssemblyFile(file);
yield return mainAsm;
var referencedAssemblies = loader.GetCecilObject(mainAsm).Modules
.SelectMany(m => m.AssemblyReferences)
.Select(r => resolver.Resolve(r));
foreach (var asm in referencedAssemblies)
yield return loader.LoadAssembly(asm);
}
var resolver = new AssemblyResolver();
List<AssemblyDefinition> assemblies = new List<AssemblyDefinition>();
foreach (var file in fileNames.Distinct(StringComparer.OrdinalIgnoreCase))
assemblies.Add(resolver.LoadAssemblyFile(file));
foreach (var asm in assemblies.ToArray())
assemblies.AddRange(asm.Modules.SelectMany(m => m.AssemblyReferences).Select(r => resolver.Resolve(r)));
return assemblies.Distinct().Select(asm => loader.LoadAssembly(asm));
}
NamespaceNode GetOrCreateNamespace(AssemblyNode assembly, string namespaceName)
@ -88,13 +117,31 @@ namespace ICSharpCode.CodeQuality.Engine @@ -88,13 +117,31 @@ namespace ICSharpCode.CodeQuality.Engine
return result;
}
void AnalyzeType(ITypeDefinition type)
void ReadType(ITypeDefinition type)
{
var asm = GetOrCreateAssembly(type.ParentAssembly);
var ns = GetOrCreateNamespace(asm, type.Namespace);
TypeNode parent;
var node = new TypeNode(type);
if (type.DeclaringTypeDefinition != null) {
if (typeMappings.TryGetValue(type.DeclaringTypeDefinition, out parent))
parent.Children.Add(node);
else
throw new Exception("TypeNode not found: " + type.DeclaringTypeDefinition.FullName);
} else
ns.Children.Add(node);
cecilMappings[loader.GetCecilObject(type.Parts.First())] = type;
typeMappings.Add(type, node);
ns.Children.Add(node);
}
class AssemblyResolver : DefaultAssemblyResolver
{
public AssemblyDefinition LoadAssemblyFile(string fileName)
{
var assembly = AssemblyDefinition.ReadAssembly(fileName, new ReaderParameters { AssemblyResolver = this });
RegisterAssembly(assembly);
return assembly;
}
}
}
}

25
src/AddIns/Analysis/CodeQuality/Engine/Dom/AssemblyNode.cs

@ -3,7 +3,9 @@ @@ -3,7 +3,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.CodeQuality.Engine.Dom
{
@ -27,21 +29,16 @@ namespace ICSharpCode.CodeQuality.Engine.Dom @@ -27,21 +29,16 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
get { return namespaces; }
}
public IEnumerable<INode> Uses {
get {
throw new NotImplementedException();
}
public IEnumerable<INode> Descendants {
get { return TreeTraversal.PreOrder(Children, node => node.Children); }
}
public IEnumerable<INode> UsedBy {
get {
throw new NotImplementedException();
}
public IEnumerable<INode> Uses {
get { return Descendants.SelectMany(node => node.Uses); }
}
public void CalculateMetricsAndFreeze(IEnumerable<AssemblyNode> assemblies)
{
public IEnumerable<INode> UsedBy {
get { return Descendants.SelectMany(node => node.UsedBy); }
}
public Relationship GetRelationship(INode value)
@ -49,6 +46,12 @@ namespace ICSharpCode.CodeQuality.Engine.Dom @@ -49,6 +46,12 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
Relationship r = new Relationship();
if (value == this)
r.AddRelationship(RelationshipType.Same);
if (Uses.Contains(value))
r.AddRelationship(RelationshipType.Uses);
if (UsedBy.Contains(value))
r.AddRelationship(RelationshipType.UsedBy);
if (Descendants.Contains(value))
r.AddRelationship(RelationshipType.Contains);
return r;
}
}

10
src/AddIns/Analysis/CodeQuality/Engine/Dom/EventNode.cs

@ -3,6 +3,8 @@ @@ -3,6 +3,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.CodeQuality.Engine.Dom
@ -16,9 +18,7 @@ namespace ICSharpCode.CodeQuality.Engine.Dom @@ -16,9 +18,7 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
}
public IList<INode> Children {
get {
throw new NotImplementedException();
}
get { return null; }
}
public IEnumerable<INode> Uses {
@ -38,6 +38,10 @@ namespace ICSharpCode.CodeQuality.Engine.Dom @@ -38,6 +38,10 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
Relationship r = new Relationship();
if (value == this)
r.AddRelationship(RelationshipType.Same);
if (Uses.Contains(value))
r.AddRelationship(RelationshipType.Uses);
if (UsedBy.Contains(value))
r.AddRelationship(RelationshipType.UsedBy);
return r;
}
}

24
src/AddIns/Analysis/CodeQuality/Engine/Dom/FieldNode.cs

@ -3,34 +3,34 @@ @@ -3,34 +3,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.CodeQuality.Engine.Dom
{
public class FieldNode : INode
{
public IField FieldDefinition { get; private set; }
public FieldNode(IField fieldDefinition)
{
this.FieldDefinition = fieldDefinition;
}
public string Name {
get {
throw new NotImplementedException();
}
get { return FieldDefinition.PrintFullName(); }
}
public IList<INode> Children {
get {
throw new NotImplementedException();
}
get { return null; }
}
public IEnumerable<INode> Uses {
get {
throw new NotImplementedException();
}
get { return Enumerable.Empty<INode>(); }
}
public IEnumerable<INode> UsedBy {
get {
throw new NotImplementedException();
}
get { return Enumerable.Empty<INode>(); }
}
public Relationship GetRelationship(INode value)

33
src/AddIns/Analysis/CodeQuality/Engine/Dom/MethodNode.cs

@ -3,34 +3,39 @@ @@ -3,34 +3,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.CodeQuality.Engine.Dom
{
public class MethodNode : INode
{
public IMethod MethodDefinition { get; private set; }
public MethodNode(IMethod methodDefinition)
{
this.MethodDefinition = methodDefinition;
uses = new List<INode>();
usedBy = new List<INode>();
}
public string Name {
get {
throw new NotImplementedException();
}
get { return MethodDefinition.PrintFullName(); }
}
public IList<INode> Children {
get {
throw new NotImplementedException();
}
get { return null; }
}
internal IList<INode> uses, usedBy;
public IEnumerable<INode> Uses {
get {
throw new NotImplementedException();
}
get { return uses; }
}
public IEnumerable<INode> UsedBy {
get {
throw new NotImplementedException();
}
get { return usedBy; }
}
public Relationship GetRelationship(INode value)
@ -38,6 +43,10 @@ namespace ICSharpCode.CodeQuality.Engine.Dom @@ -38,6 +43,10 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
Relationship r = new Relationship();
if (value == this)
r.AddRelationship(RelationshipType.Same);
if (Uses.Contains(value))
r.AddRelationship(RelationshipType.Uses);
if (UsedBy.Contains(value))
r.AddRelationship(RelationshipType.UsedBy);
return r;
}
}

19
src/AddIns/Analysis/CodeQuality/Engine/Dom/NamespaceNode.cs

@ -6,6 +6,7 @@ using System.Collections.Generic; @@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.CodeQuality.Engine.Dom
{
@ -25,16 +26,16 @@ namespace ICSharpCode.CodeQuality.Engine.Dom @@ -25,16 +26,16 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
get { return types; }
}
public IEnumerable<INode> Descendants {
get { return TreeTraversal.PreOrder(Children, node => node.Children); }
}
public IEnumerable<INode> Uses {
get {
throw new NotImplementedException();
}
get { return Descendants.SelectMany(node => node.Uses); }
}
public IEnumerable<INode> UsedBy {
get {
throw new NotImplementedException();
}
get { return Descendants.SelectMany(node => node.UsedBy); }
}
public Relationship GetRelationship(INode value)
@ -42,6 +43,12 @@ namespace ICSharpCode.CodeQuality.Engine.Dom @@ -42,6 +43,12 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
Relationship r = new Relationship();
if (value == this)
r.AddRelationship(RelationshipType.Same);
if (Uses.Contains(value))
r.AddRelationship(RelationshipType.Uses);
if (UsedBy.Contains(value))
r.AddRelationship(RelationshipType.UsedBy);
if (Descendants.Contains(value))
r.AddRelationship(RelationshipType.Contains);
return r;
}
}

4
src/AddIns/Analysis/CodeQuality/Engine/Dom/PropertyNode.cs

@ -16,9 +16,7 @@ namespace ICSharpCode.CodeQuality.Engine.Dom @@ -16,9 +16,7 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
}
public IList<INode> Children {
get {
throw new NotImplementedException();
}
get { return null; }
}
public IEnumerable<INode> Uses {

29
src/AddIns/Analysis/CodeQuality/Engine/Dom/Relationship.cs

@ -30,7 +30,7 @@ namespace ICSharpCode.CodeQuality.Engine.Dom @@ -30,7 +30,7 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
public void AddRelationship(RelationshipType type)
{
if (type == RelationshipType.UseThis || type == RelationshipType.UsedBy)
if (type == RelationshipType.Uses || type == RelationshipType.UsedBy)
OccurrenceCount++;
Relationships.Add(type);
@ -48,13 +48,30 @@ namespace ICSharpCode.CodeQuality.Engine.Dom @@ -48,13 +48,30 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
}
}
/// <summary>
/// Type of relationship between two INodes.
/// </summary>
public enum RelationshipType
{
OneWayTo,
UseThis,
UsedBy,
Same,
/// <summary>
/// a and b are not related to each other.
/// </summary>
None,
/// <summary>
/// a contains b.
/// </summary>
Contains,
None
/// <summary>
/// a uses b.
/// </summary>
Uses,
/// <summary>
/// a is used by b.
/// </summary>
UsedBy,
/// <summary>
/// a and b are the same INode
/// </summary>
Same
}
}

28
src/AddIns/Analysis/CodeQuality/Engine/Dom/TypeNode.cs

@ -3,7 +3,10 @@ @@ -3,7 +3,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.CodeQuality.Engine.Dom
{
@ -14,28 +17,29 @@ namespace ICSharpCode.CodeQuality.Engine.Dom @@ -14,28 +17,29 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
public TypeNode(ITypeDefinition typeDefinition)
{
this.TypeDefinition = typeDefinition;
children = new List<INode>();
}
public string Name {
get { return TypeDefinition.Name; }
}
List<INode> children;
public IList<INode> Children {
get {
return new List<INode>();
}
get { return children; }
}
public IEnumerable<INode> Descendants {
get { return TreeTraversal.PreOrder(Children, node => node.Children); }
}
public IEnumerable<INode> Uses {
get {
throw new NotImplementedException();
}
get { return Descendants.SelectMany(node => node.Uses); }
}
public IEnumerable<INode> UsedBy {
get {
throw new NotImplementedException();
}
get { return Descendants.SelectMany(node => node.UsedBy); }
}
public Relationship GetRelationship(INode value)
@ -43,6 +47,12 @@ namespace ICSharpCode.CodeQuality.Engine.Dom @@ -43,6 +47,12 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
Relationship r = new Relationship();
if (value == this)
r.AddRelationship(RelationshipType.Same);
if (Uses.Contains(value))
r.AddRelationship(RelationshipType.Uses);
if (UsedBy.Contains(value))
r.AddRelationship(RelationshipType.UsedBy);
if (Descendants.Contains(value))
r.AddRelationship(RelationshipType.Contains);
return r;
}
}

72
src/AddIns/Analysis/CodeQuality/Engine/ILAnalyzer.cs

@ -2,6 +2,12 @@ @@ -2,6 +2,12 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.CodeQuality.Engine.Dom;
using ICSharpCode.NRefactory.TypeSystem;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace ICSharpCode.CodeQuality.Engine
{
@ -10,8 +16,72 @@ namespace ICSharpCode.CodeQuality.Engine @@ -10,8 +16,72 @@ namespace ICSharpCode.CodeQuality.Engine
/// </summary>
public class ILAnalyzer
{
public ILAnalyzer()
AssemblyDefinition[] assemblies;
AssemblyAnalyzer mappings;
public ILAnalyzer(AssemblyDefinition[] assemblies, AssemblyAnalyzer mappings)
{
if (assemblies == null)
throw new ArgumentNullException("assemblies");
this.assemblies = assemblies;
this.mappings = mappings;
}
public void Analyze(MethodBody body, MethodNode analyzedMethod, out int cyclomaticComplexity)
{
cyclomaticComplexity = 0;
if (body == null)
return;
foreach (var instruction in body.Instructions) {
// IL cyclomatic complexity
if (instruction.OpCode.FlowControl == FlowControl.Cond_Branch)
cyclomaticComplexity++;
var operand = ReadOperand(instruction);
if (operand is MethodDefinition) {
var md = (MethodDefinition)operand;
if (assemblies.Contains(md.DeclaringType.Module.Assembly) && mappings.cecilMappings.ContainsKey(md)) {
var opMethod = (IMethod)mappings.cecilMappings[md];
var methodNode = mappings.methodMappings[opMethod];
analyzedMethod.uses.Add(methodNode);
methodNode.usedBy.Add(analyzedMethod);
}
}
//
// if (operand is MethodDefinition && ((MethodDefinition)operand).DeclaringType.Module.Assembly == assemblyDefinition) {
// var md = (MethodDefinition)operand;
// if (md.DeclaringType.Name == "" || md.DeclaringType.Name.StartsWith("<")) {
// // TODO : Handle generated members
// } else {
// var opMethod = (IMethod)cecilMappings[md];
// var methodNode = methodMappings[opMethod];
// m.typeUses.Add(methodNode.DeclaringType);
// m.methodUses.Add(methodNode);
// }
// }
//
// if (operand is FieldDefinition && ((FieldDefinition)operand).DeclaringType.Module.Assembly == assemblyDefinition) {
// var fd = (FieldDefinition)operand;
// if (fd.DeclaringType.Name == "" || fd.DeclaringType.Name.StartsWith("<")) {
// // TODO : Handle generated members
// } else {
// var field = (IField)cecilMappings[fd];
// var fieldNode = fieldMappings[field];
// m.fieldUses.Add(fieldNode);
// }
// }
}
}
public object ReadOperand(Instruction instruction)
{
while (instruction.Operand is Instruction)
instruction = (Instruction)instruction.Operand;
return instruction.Operand;
}
}
}

2
src/AddIns/Analysis/CodeQuality/Gui/Controls/DependencyMatrix.cs

@ -22,7 +22,7 @@ namespace ICSharpCode.CodeQuality.Gui @@ -22,7 +22,7 @@ namespace ICSharpCode.CodeQuality.Gui
// add other way
foreach (var relationship in fromRelationship.Relationships) {
if (relationship == RelationshipType.UseThis)
if (relationship == RelationshipType.Uses)
toRelationship.AddRelationship(RelationshipType.UsedBy);
}

2
src/AddIns/Analysis/CodeQuality/Gui/DependencyMatrixView.xaml

@ -70,7 +70,7 @@ @@ -70,7 +70,7 @@
Grid.Row="2" Grid.Column="2"
CanContentScroll="True"
ScrollChanged="ViewScrollChanged">
<gui:DependencyMatrixControl x:Name="matrix" HoveredCellChanged="MatrixHoveredCellChanged"/>
<gui:DependencyMatrixControl x:Name="matrix" HoveredCellChanged="MatrixHoveredCellChanged" MouseMove="MatrixMouseMove" MouseLeave="MatrixMouseLeave" />
</ScrollViewer>
</Grid>

33
src/AddIns/Analysis/CodeQuality/Gui/DependencyMatrixView.xaml.cs

@ -15,7 +15,6 @@ using System.Windows.Input; @@ -15,7 +15,6 @@ using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;
using ICSharpCode.CodeQuality;
using ICSharpCode.CodeQuality.Engine.Dom;
using ICSharpCode.SharpDevelop;
@ -30,6 +29,7 @@ namespace ICSharpCode.CodeQuality.Gui @@ -30,6 +29,7 @@ namespace ICSharpCode.CodeQuality.Gui
{
ScrollViewer topTreeScrollViewer, leftTreeScrollViewer;
NodeDescriptionViewModel nodeDescriptionViewModel;
ToolTip infoTooltip;
public DependencyMatrixView()
{
@ -44,6 +44,7 @@ namespace ICSharpCode.CodeQuality.Gui @@ -44,6 +44,7 @@ namespace ICSharpCode.CodeQuality.Gui
matrix.Colorizer = new DependencyColorizer();
matrix.ScrollOwner = scrollViewer;
infoTooltip = new ToolTip() { StaysOpen = false };
}
@ -64,6 +65,7 @@ namespace ICSharpCode.CodeQuality.Gui @@ -64,6 +65,7 @@ namespace ICSharpCode.CodeQuality.Gui
topCol.CollectionChanged += BuildTopINodeList;
var matrix = new DependencyMatrix();
if (nodes != null)
AddChildrenToMatrix(matrix, nodes);
this.matrix.Matrix = matrix;
BuildLeftINodeList(null, null);
@ -76,6 +78,7 @@ namespace ICSharpCode.CodeQuality.Gui @@ -76,6 +78,7 @@ namespace ICSharpCode.CodeQuality.Gui
foreach (var node in nodes) {
matrix.AddColumn(node);
matrix.AddRow(node);
if (node.Children != null)
AddChildrenToMatrix(matrix, node.Children);
}
}
@ -145,6 +148,7 @@ namespace ICSharpCode.CodeQuality.Gui @@ -145,6 +148,7 @@ namespace ICSharpCode.CodeQuality.Gui
matrix.HighlightLine(HeaderType.Rows, n.Node);
leftTree.SelectedItem = n;
}
infoTooltip.IsOpen = false;
}
void TopTreeMouseMove(object sender, System.Windows.Input.MouseEventArgs e)
@ -155,6 +159,7 @@ namespace ICSharpCode.CodeQuality.Gui @@ -155,6 +159,7 @@ namespace ICSharpCode.CodeQuality.Gui
matrix.HighlightLine(HeaderType.Columns, n.Node);
topTree.SelectedItem = n;
}
infoTooltip.IsOpen = false;
}
MatrixTreeNode ConvertNode(DependencyObject node)
@ -175,6 +180,32 @@ namespace ICSharpCode.CodeQuality.Gui @@ -175,6 +180,32 @@ namespace ICSharpCode.CodeQuality.Gui
topTree.SelectedItem = topTree.Items[e.HoveredCell.ColumnIndex + 1];
}
}
void MatrixMouseMove(object sender, MouseEventArgs e)
{
infoTooltip.Placement = PlacementMode.Relative;
infoTooltip.VerticalOffset = 15;
infoTooltip.PlacementTarget = this;
infoTooltip.Content = GetTooltip(matrix.HoveredCell.Value);
infoTooltip.IsOpen = true;
}
object GetTooltip(Relationship relationship)
{
string text = "is not related to";
if (relationship.Relationships.Any(r => r == RelationshipType.Uses))
text = "uses";
else if (relationship.Relationships.Any(r => r == RelationshipType.UsedBy))
text = "is used by";
else if (relationship.Relationships.Any(r => r == RelationshipType.Same))
text = "is the same as";
return string.Format("{0} {1} {2}", relationship.From.Name, text, relationship.To.Name);
}
void MatrixMouseLeave(object sender, MouseEventArgs e)
{
infoTooltip.IsOpen = false;
}
#endregion
}
}

2
src/AddIns/Analysis/CodeQuality/Gui/NodeIconService.cs

@ -15,7 +15,7 @@ namespace ICSharpCode.CodeQuality.Gui @@ -15,7 +15,7 @@ namespace ICSharpCode.CodeQuality.Gui
public static class NodeIconService
{
static readonly BitmapSource NamespaceNode = GetImage("Icons.16x16.NameSpace");
static readonly BitmapSource Assembly = GetImage("Icons.16x16.Assembly");
static readonly BitmapSource Assembly = GetImage("Icons.16x16.Reference");
static readonly BitmapSource Class = GetImage("Icons.16x16.Class");
static readonly BitmapSource InternalClass = GetImage("Icons.16x16.InternalClass");

6
src/AddIns/Analysis/CodeQuality/Utils/DependencyColorizer.cs

@ -41,10 +41,10 @@ namespace ICSharpCode.CodeQuality @@ -41,10 +41,10 @@ namespace ICSharpCode.CodeQuality
if (relationship == null)
return Colors.Transparent;
if (relationship.Relationships.Any(r => r == RelationshipType.UseThis))
return Colors.LightBlue;
if (relationship.Relationships.Any(r => r == RelationshipType.Uses))
return Colors.LightGreen;
if (relationship.Relationships.Any(r => r == RelationshipType.UsedBy))
return Colors.Violet;
return Colors.LightBlue;
if (relationship.Relationships.Any(r => r == RelationshipType.Same))
return Colors.Gray;

16
src/AddIns/Analysis/CodeQuality/Utils/Extensions.cs

@ -6,9 +6,10 @@ using System.Collections.Generic; @@ -6,9 +6,10 @@ using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using ICSharpCode.CodeQuality.Engine.Dom;
using ICSharpCode.CodeQuality.Gui;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.TreeView;
namespace ICSharpCode.CodeQuality
@ -21,7 +22,8 @@ namespace ICSharpCode.CodeQuality @@ -21,7 +22,8 @@ namespace ICSharpCode.CodeQuality
public static void FillTree(SharpTreeView tree, IEnumerable<INode> rootNodes)
{
tree.Root = new SharpTreeNode();
CreateItems(rootNodes, tree.Root);
if (rootNodes != null)
CreateItems(rootNodes, tree.Root);
}
static void CreateItems(IEnumerable<INode> nodes, SharpTreeNode parent)
@ -29,7 +31,8 @@ namespace ICSharpCode.CodeQuality @@ -29,7 +31,8 @@ namespace ICSharpCode.CodeQuality
foreach (INode node in nodes) {
var item = new MatrixTreeNode(node);
parent.Children.Add(item);
CreateItems(node.Children, item);
if (node.Children != null)
CreateItems(node.Children, item);
}
}
@ -73,5 +76,12 @@ namespace ICSharpCode.CodeQuality @@ -73,5 +76,12 @@ namespace ICSharpCode.CodeQuality
(byte)(c1.G * amountFrom + c2.G * percent),
(byte)(c1.B * amountFrom + c2.B * percent));
}
static readonly IAmbience amb = new CSharpAmbience() { ConversionFlags = ConversionFlags.ShowParameterList | ConversionFlags.ShowParameterNames | ConversionFlags.ShowReturnType | ConversionFlags.ShowTypeParameterList };
public static string PrintFullName(this IEntity entity)
{
return amb.ConvertEntity(entity);
}
}
}

20
src/AddIns/Analysis/CodeQuality/Utils/Utils.cs

@ -2,8 +2,11 @@ @@ -2,8 +2,11 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Mono.Cecil;
namespace ICSharpCode.CodeQuality
{
/// <summary>
@ -14,4 +17,21 @@ namespace ICSharpCode.CodeQuality @@ -14,4 +17,21 @@ namespace ICSharpCode.CodeQuality
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
}
public class AssemblyNameReferenceComparer : IEqualityComparer<AssemblyNameReference>
{
public bool Equals(AssemblyNameReference x, AssemblyNameReference y)
{
if (x == y) return true;
if (x != null && y != null)
return x.FullName == y.FullName;
return false;
}
public int GetHashCode(AssemblyNameReference obj)
{
if (obj == null) return 0;
return obj.FullName.GetHashCode();
}
}
}

Loading…
Cancel
Save