diff --git a/SharpDevelop.sln b/SharpDevelop.sln
index 9ba2db847d..d87da710fa 100644
--- a/SharpDevelop.sln
+++ b/SharpDevelop.sln
@@ -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
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
{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
diff --git a/src/AddIns/Analysis/CodeQuality/CodeQuality.csproj b/src/AddIns/Analysis/CodeQuality/CodeQuality.csproj
index 6331b5f74a..2c8ac115de 100644
--- a/src/AddIns/Analysis/CodeQuality/CodeQuality.csproj
+++ b/src/AddIns/Analysis/CodeQuality/CodeQuality.csproj
@@ -106,6 +106,10 @@
Mono.Cecil
False
+
+ {53DCA265-3C3C-42F9-B647-F72BA678122B}
+ ICSharpCode.NRefactory.CSharp
+
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}
ICSharpCode.NRefactory
diff --git a/src/AddIns/Analysis/CodeQuality/Engine/AssemblyAnalyzer.cs b/src/AddIns/Analysis/CodeQuality/Engine/AssemblyAnalyzer.cs
index dd9b40a31b..9b893a3893 100644
--- a/src/AddIns/Analysis/CodeQuality/Engine/AssemblyAnalyzer.cs
+++ b/src/AddIns/Analysis/CodeQuality/Engine/AssemblyAnalyzer.cs
@@ -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
///
public class AssemblyAnalyzer
{
- CecilLoader loader = new CecilLoader(true);
+ CecilLoader loader = new CecilLoader(true) { IncludeInternalMembers = true };
ICompilation compilation;
- Dictionary assemblyMappings;
- Dictionary namespaceMappings;
- Dictionary typeMappings;
- Dictionary methodMappings;
- Dictionary fieldMappings;
+ internal Dictionary assemblyMappings;
+ internal Dictionary namespaceMappings;
+ internal Dictionary typeMappings;
+ internal Dictionary methodMappings;
+ internal Dictionary fieldMappings;
+ internal Dictionary cecilMappings;
List fileNames;
public AssemblyAnalyzer()
@@ -45,25 +45,54 @@ namespace ICSharpCode.CodeQuality.Engine
assemblyMappings = new Dictionary();
namespaceMappings = new Dictionary();
typeMappings = new Dictionary();
+ fieldMappings = new Dictionary();
+ methodMappings = new Dictionary();
+ cecilMappings = new Dictionary();
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(assemblyMappings.Values.ToList());
}
IEnumerable 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 assemblies = new List();
+ 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
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;
+ }
}
}
}
diff --git a/src/AddIns/Analysis/CodeQuality/Engine/Dom/AssemblyNode.cs b/src/AddIns/Analysis/CodeQuality/Engine/Dom/AssemblyNode.cs
index 68ff36d5dd..f3f8d001f0 100644
--- a/src/AddIns/Analysis/CodeQuality/Engine/Dom/AssemblyNode.cs
+++ b/src/AddIns/Analysis/CodeQuality/Engine/Dom/AssemblyNode.cs
@@ -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
get { return namespaces; }
}
- public IEnumerable Uses {
- get {
- throw new NotImplementedException();
- }
+ public IEnumerable Descendants {
+ get { return TreeTraversal.PreOrder(Children, node => node.Children); }
}
- public IEnumerable UsedBy {
- get {
- throw new NotImplementedException();
- }
+ public IEnumerable Uses {
+ get { return Descendants.SelectMany(node => node.Uses); }
}
- public void CalculateMetricsAndFreeze(IEnumerable assemblies)
- {
-
+ public IEnumerable UsedBy {
+ get { return Descendants.SelectMany(node => node.UsedBy); }
}
public Relationship GetRelationship(INode value)
@@ -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;
}
}
diff --git a/src/AddIns/Analysis/CodeQuality/Engine/Dom/EventNode.cs b/src/AddIns/Analysis/CodeQuality/Engine/Dom/EventNode.cs
index a9256f36c5..af5ccdfb65 100644
--- a/src/AddIns/Analysis/CodeQuality/Engine/Dom/EventNode.cs
+++ b/src/AddIns/Analysis/CodeQuality/Engine/Dom/EventNode.cs
@@ -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
}
public IList Children {
- get {
- throw new NotImplementedException();
- }
+ get { return null; }
}
public IEnumerable Uses {
@@ -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;
}
}
diff --git a/src/AddIns/Analysis/CodeQuality/Engine/Dom/FieldNode.cs b/src/AddIns/Analysis/CodeQuality/Engine/Dom/FieldNode.cs
index 08e43f0450..800f426c1b 100644
--- a/src/AddIns/Analysis/CodeQuality/Engine/Dom/FieldNode.cs
+++ b/src/AddIns/Analysis/CodeQuality/Engine/Dom/FieldNode.cs
@@ -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 Children {
- get {
- throw new NotImplementedException();
- }
+ get { return null; }
}
public IEnumerable Uses {
- get {
- throw new NotImplementedException();
- }
+ get { return Enumerable.Empty(); }
}
public IEnumerable UsedBy {
- get {
- throw new NotImplementedException();
- }
+ get { return Enumerable.Empty(); }
}
public Relationship GetRelationship(INode value)
diff --git a/src/AddIns/Analysis/CodeQuality/Engine/Dom/MethodNode.cs b/src/AddIns/Analysis/CodeQuality/Engine/Dom/MethodNode.cs
index e729c108e3..bb024ede2b 100644
--- a/src/AddIns/Analysis/CodeQuality/Engine/Dom/MethodNode.cs
+++ b/src/AddIns/Analysis/CodeQuality/Engine/Dom/MethodNode.cs
@@ -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();
+ usedBy = new List();
+ }
+
public string Name {
- get {
- throw new NotImplementedException();
- }
+ get { return MethodDefinition.PrintFullName(); }
}
public IList Children {
- get {
- throw new NotImplementedException();
- }
+ get { return null; }
}
+ internal IList uses, usedBy;
+
public IEnumerable Uses {
- get {
- throw new NotImplementedException();
- }
+ get { return uses; }
}
public IEnumerable UsedBy {
- get {
- throw new NotImplementedException();
- }
+ get { return usedBy; }
}
public Relationship GetRelationship(INode value)
@@ -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;
}
}
diff --git a/src/AddIns/Analysis/CodeQuality/Engine/Dom/NamespaceNode.cs b/src/AddIns/Analysis/CodeQuality/Engine/Dom/NamespaceNode.cs
index c8ee0824cc..8a65ef4a23 100644
--- a/src/AddIns/Analysis/CodeQuality/Engine/Dom/NamespaceNode.cs
+++ b/src/AddIns/Analysis/CodeQuality/Engine/Dom/NamespaceNode.cs
@@ -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
get { return types; }
}
+ public IEnumerable Descendants {
+ get { return TreeTraversal.PreOrder(Children, node => node.Children); }
+ }
+
public IEnumerable Uses {
- get {
- throw new NotImplementedException();
- }
+ get { return Descendants.SelectMany(node => node.Uses); }
}
public IEnumerable 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
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;
}
}
diff --git a/src/AddIns/Analysis/CodeQuality/Engine/Dom/PropertyNode.cs b/src/AddIns/Analysis/CodeQuality/Engine/Dom/PropertyNode.cs
index 945e230518..8381ec0c95 100644
--- a/src/AddIns/Analysis/CodeQuality/Engine/Dom/PropertyNode.cs
+++ b/src/AddIns/Analysis/CodeQuality/Engine/Dom/PropertyNode.cs
@@ -16,9 +16,7 @@ namespace ICSharpCode.CodeQuality.Engine.Dom
}
public IList Children {
- get {
- throw new NotImplementedException();
- }
+ get { return null; }
}
public IEnumerable Uses {
diff --git a/src/AddIns/Analysis/CodeQuality/Engine/Dom/Relationship.cs b/src/AddIns/Analysis/CodeQuality/Engine/Dom/Relationship.cs
index 33342f5f80..47bf1f8f01 100644
--- a/src/AddIns/Analysis/CodeQuality/Engine/Dom/Relationship.cs
+++ b/src/AddIns/Analysis/CodeQuality/Engine/Dom/Relationship.cs
@@ -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
}
}
+ ///
+ /// Type of relationship between two INodes.
+ ///
public enum RelationshipType
{
- OneWayTo,
- UseThis,
- UsedBy,
- Same,
+ ///
+ /// a and b are not related to each other.
+ ///
+ None,
+ ///
+ /// a contains b.
+ ///
Contains,
- None
+ ///
+ /// a uses b.
+ ///
+ Uses,
+ ///
+ /// a is used by b.
+ ///
+ UsedBy,
+ ///
+ /// a and b are the same INode
+ ///
+ Same
}
}
diff --git a/src/AddIns/Analysis/CodeQuality/Engine/Dom/TypeNode.cs b/src/AddIns/Analysis/CodeQuality/Engine/Dom/TypeNode.cs
index c0e0294c02..12c92fa88e 100644
--- a/src/AddIns/Analysis/CodeQuality/Engine/Dom/TypeNode.cs
+++ b/src/AddIns/Analysis/CodeQuality/Engine/Dom/TypeNode.cs
@@ -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
public TypeNode(ITypeDefinition typeDefinition)
{
this.TypeDefinition = typeDefinition;
+ children = new List();
}
public string Name {
get { return TypeDefinition.Name; }
}
+ List children;
+
public IList Children {
- get {
- return new List();
- }
+ get { return children; }
+ }
+
+ public IEnumerable Descendants {
+ get { return TreeTraversal.PreOrder(Children, node => node.Children); }
}
public IEnumerable Uses {
- get {
- throw new NotImplementedException();
- }
+ get { return Descendants.SelectMany(node => node.Uses); }
}
public IEnumerable 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
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;
}
}
diff --git a/src/AddIns/Analysis/CodeQuality/Engine/ILAnalyzer.cs b/src/AddIns/Analysis/CodeQuality/Engine/ILAnalyzer.cs
index 9de0b6fffa..23b832b9d8 100644
--- a/src/AddIns/Analysis/CodeQuality/Engine/ILAnalyzer.cs
+++ b/src/AddIns/Analysis/CodeQuality/Engine/ILAnalyzer.cs
@@ -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
///
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;
}
}
}
diff --git a/src/AddIns/Analysis/CodeQuality/Gui/Controls/DependencyMatrix.cs b/src/AddIns/Analysis/CodeQuality/Gui/Controls/DependencyMatrix.cs
index c0d2941db1..3c57c70d2c 100644
--- a/src/AddIns/Analysis/CodeQuality/Gui/Controls/DependencyMatrix.cs
+++ b/src/AddIns/Analysis/CodeQuality/Gui/Controls/DependencyMatrix.cs
@@ -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);
}
diff --git a/src/AddIns/Analysis/CodeQuality/Gui/DependencyMatrixView.xaml b/src/AddIns/Analysis/CodeQuality/Gui/DependencyMatrixView.xaml
index 30cfce8ffd..56bb99808f 100644
--- a/src/AddIns/Analysis/CodeQuality/Gui/DependencyMatrixView.xaml
+++ b/src/AddIns/Analysis/CodeQuality/Gui/DependencyMatrixView.xaml
@@ -70,7 +70,7 @@
Grid.Row="2" Grid.Column="2"
CanContentScroll="True"
ScrollChanged="ViewScrollChanged">
-
+
diff --git a/src/AddIns/Analysis/CodeQuality/Gui/DependencyMatrixView.xaml.cs b/src/AddIns/Analysis/CodeQuality/Gui/DependencyMatrixView.xaml.cs
index 3f447b2132..09e68811c2 100644
--- a/src/AddIns/Analysis/CodeQuality/Gui/DependencyMatrixView.xaml.cs
+++ b/src/AddIns/Analysis/CodeQuality/Gui/DependencyMatrixView.xaml.cs
@@ -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
{
ScrollViewer topTreeScrollViewer, leftTreeScrollViewer;
NodeDescriptionViewModel nodeDescriptionViewModel;
+ ToolTip infoTooltip;
public DependencyMatrixView()
{
@@ -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
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
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
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
matrix.HighlightLine(HeaderType.Columns, n.Node);
topTree.SelectedItem = n;
}
+ infoTooltip.IsOpen = false;
}
MatrixTreeNode ConvertNode(DependencyObject node)
@@ -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
}
}
\ No newline at end of file
diff --git a/src/AddIns/Analysis/CodeQuality/Gui/NodeIconService.cs b/src/AddIns/Analysis/CodeQuality/Gui/NodeIconService.cs
index a058ffb22b..00e719018b 100644
--- a/src/AddIns/Analysis/CodeQuality/Gui/NodeIconService.cs
+++ b/src/AddIns/Analysis/CodeQuality/Gui/NodeIconService.cs
@@ -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");
diff --git a/src/AddIns/Analysis/CodeQuality/Utils/DependencyColorizer.cs b/src/AddIns/Analysis/CodeQuality/Utils/DependencyColorizer.cs
index d8adc83e5e..ed0b8cb06d 100644
--- a/src/AddIns/Analysis/CodeQuality/Utils/DependencyColorizer.cs
+++ b/src/AddIns/Analysis/CodeQuality/Utils/DependencyColorizer.cs
@@ -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;
diff --git a/src/AddIns/Analysis/CodeQuality/Utils/Extensions.cs b/src/AddIns/Analysis/CodeQuality/Utils/Extensions.cs
index a8eec0e71d..5e9c7ec98b 100644
--- a/src/AddIns/Analysis/CodeQuality/Utils/Extensions.cs
+++ b/src/AddIns/Analysis/CodeQuality/Utils/Extensions.cs
@@ -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
public static void FillTree(SharpTreeView tree, IEnumerable rootNodes)
{
tree.Root = new SharpTreeNode();
- CreateItems(rootNodes, tree.Root);
+ if (rootNodes != null)
+ CreateItems(rootNodes, tree.Root);
}
static void CreateItems(IEnumerable nodes, SharpTreeNode parent)
@@ -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
(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);
+ }
}
}
\ No newline at end of file
diff --git a/src/AddIns/Analysis/CodeQuality/Utils/Utils.cs b/src/AddIns/Analysis/CodeQuality/Utils/Utils.cs
index 6ac7d8e334..7c1be9d0b8 100644
--- a/src/AddIns/Analysis/CodeQuality/Utils/Utils.cs
+++ b/src/AddIns/Analysis/CodeQuality/Utils/Utils.cs
@@ -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
{
///
@@ -14,4 +17,21 @@ namespace ICSharpCode.CodeQuality
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
}
+
+ public class AssemblyNameReferenceComparer : IEqualityComparer
+ {
+ 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();
+ }
+ }
}