diff --git a/src/AddIns/Analysis/CodeQuality/CodeQualityAnalysis.csproj b/src/AddIns/Analysis/CodeQuality/CodeQualityAnalysis.csproj
index b66b643ae0..ddd9e0ec3c 100644
--- a/src/AddIns/Analysis/CodeQuality/CodeQualityAnalysis.csproj
+++ b/src/AddIns/Analysis/CodeQuality/CodeQualityAnalysis.csproj
@@ -120,17 +120,17 @@
-
- TreeMatrixControl.xaml
Code
+ TreeMatrixControl.xaml
+
@@ -139,6 +139,8 @@
+
+
Designer
MSBuild:Compile
@@ -243,7 +245,9 @@
Always
-
+
+
+
@@ -74,7 +81,6 @@
-
@@ -147,7 +153,7 @@
-
+
diff --git a/src/AddIns/Analysis/CodeQuality/Src/MainWindow.xaml.cs b/src/AddIns/Analysis/CodeQuality/Src/MainWindow.xaml.cs
index 11367374a8..34bcac635d 100644
--- a/src/AddIns/Analysis/CodeQuality/Src/MainWindow.xaml.cs
+++ b/src/AddIns/Analysis/CodeQuality/Src/MainWindow.xaml.cs
@@ -14,6 +14,7 @@ using System.Windows.Media.Imaging;
using GraphSharp.Controls;
using ICSharpCode.CodeQualityAnalysis.Controls;
+using ICSharpCode.CodeQualityAnalysis.Utility;
using Microsoft.Win32;
namespace ICSharpCode.CodeQualityAnalysis
@@ -72,6 +73,7 @@ namespace ICSharpCode.CodeQualityAnalysis
worker.RunWorkerCompleted += (source, args) => {
progressBar.Visibility = Visibility.Hidden;
assemblyStats.Visibility = Visibility.Visible;
+ mainTabs.IsEnabled = true;
FillMatrix();
};
@@ -93,13 +95,13 @@ namespace ICSharpCode.CodeQualityAnalysis
var matrix = new DependencyMatrix();
foreach (var ns in metricsReader.MainModule.Namespaces) {
- matrix.HeaderRows.Add(new MatrixCell(ns));
+ matrix.HeaderRows.Add(new Cell(ns));
foreach (var type in ns.Types) {
- matrix.HeaderRows.Add(new MatrixCell(type));
+ matrix.HeaderRows.Add(new Cell(type));
}
- matrix.HeaderColumns.Add(new MatrixCell(ns));
+ matrix.HeaderColumns.Add(new Cell(ns));
foreach (var type in ns.Types) {
- matrix.HeaderColumns.Add(new MatrixCell(type));
+ matrix.HeaderColumns.Add(new Cell(type));
}
}
diff --git a/src/AddIns/Analysis/CodeQuality/Src/Namespace.cs b/src/AddIns/Analysis/CodeQuality/Src/Namespace.cs
index c9cb1e9a80..2a9904dc59 100644
--- a/src/AddIns/Analysis/CodeQuality/Src/Namespace.cs
+++ b/src/AddIns/Analysis/CodeQuality/Src/Namespace.cs
@@ -80,8 +80,7 @@ namespace ICSharpCode.CodeQualityAnalysis
foreach (var type in ns.Types)
{
if (Types.Contains(type)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
}
}
@@ -91,26 +90,23 @@ namespace ICSharpCode.CodeQualityAnalysis
Type type = (Type)node;
if (this.Types.Contains(type.BaseType)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
foreach (var thisType in type.GenericImplementedInterfacesTypes) {
if (this.Types.Contains(thisType)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
}
foreach (var thisType in type.ImplementedInterfaces) {
if (this.Types.Contains(thisType)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
}
if (this.Types.Contains(type)) {
- relationship.Relationships.Add(RelationshipType.Contains);
+ relationship.AddRelationship(RelationshipType.Contains);
}
}
@@ -118,51 +114,44 @@ namespace ICSharpCode.CodeQualityAnalysis
Method method = (Method)node;
if (this.Types.Contains(method.ReturnType)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
foreach (var type in method.GenericReturnTypes) {
if (this.Types.Contains(type)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
}
foreach (var parameter in method.Parameters) {
if (this.Types.Contains(parameter.ParameterType)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
foreach (var type in parameter.GenericTypes) {
if (this.Types.Contains(type)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
}
}
foreach (var type in method.TypeUses) {
if (this.Types.Contains(type)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
}
foreach (var type in method.TypeUses) {
if (this.Types.Contains(type)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
}
foreach (var field in method.FieldUses) {
foreach (var type in this.Types) {
if (type.Fields.Contains(field)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
}
}
@@ -170,40 +159,36 @@ namespace ICSharpCode.CodeQualityAnalysis
foreach (var meth in method.MethodUses) {
foreach (var type in this.Types) {
if (type.Methods.Contains(meth)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
}
}
foreach (var type in method.TypeUses) {
if (this.Types.Contains(type)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
}
if (this.Types.Contains(method.DeclaringType))
- relationship.Relationships.Add(RelationshipType.Contains);
+ relationship.AddRelationship(RelationshipType.Contains);
}
if (node is Field) {
Field field = (Field)node;
if (this.Types.Contains(field.FieldType)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
foreach (var type in field.GenericTypes) {
if (this.Types.Contains(type)) {
- relationship.NumberOfOccurrences++;
- relationship.Relationships.Add(RelationshipType.UseThis);
+ relationship.AddRelationship(RelationshipType.UseThis);
}
}
if (this.Types.Contains(field.DeclaringType))
- relationship.Relationships.Add(RelationshipType.Contains);
+ relationship.AddRelationship(RelationshipType.Contains);
}
return relationship;
diff --git a/src/AddIns/Analysis/CodeQuality/Src/Relationship.cs b/src/AddIns/Analysis/CodeQuality/Src/Relationship.cs
index 939cd6c16b..25213474dc 100644
--- a/src/AddIns/Analysis/CodeQuality/Src/Relationship.cs
+++ b/src/AddIns/Analysis/CodeQuality/Src/Relationship.cs
@@ -10,15 +10,25 @@ namespace ICSharpCode.CodeQualityAnalysis
///
/// Description of Relationship.
///
- public class Relationship
+ public class Relationship : IValue
{
public ISet Relationships { get; private set; }
- public int NumberOfOccurrences { get; set; }
+
+ public int OccurrenceCount { get; private set; }
+
+ public string Text { get { return OccurrenceCount.ToString(); } }
public Relationship()
{
Relationships = new HashSet();
- NumberOfOccurrences = 0;
+ }
+
+ public void AddRelationship(RelationshipType type)
+ {
+ if (type == RelationshipType.UseThis)
+ OccurrenceCount++;
+
+ Relationships.Add(type);
}
public override string ToString()
@@ -28,7 +38,7 @@ namespace ICSharpCode.CodeQualityAnalysis
foreach (var relationship in Relationships)
builder.Append(relationship + " ");
- builder.Append(NumberOfOccurrences);
+ builder.Append(OccurrenceCount);
return builder.ToString();
}
}
diff --git a/src/AddIns/Analysis/CodeQuality/Src/Utility/DoubleKeyDictionary.cs b/src/AddIns/Analysis/CodeQuality/Src/Utility/DoubleKeyDictionary.cs
new file mode 100644
index 0000000000..397d758f86
--- /dev/null
+++ b/src/AddIns/Analysis/CodeQuality/Src/Utility/DoubleKeyDictionary.cs
@@ -0,0 +1,138 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace ICSharpCode.CodeQualityAnalysis.Utility
+{
+ public class DoubleKeyDictionary :
+ IEnumerable>,
+ IEquatable>
+ {
+ private Dictionary innerDictionary;
+
+ public DoubleKeyDictionary()
+ {
+ OuterDictionary = new Dictionary>();
+ }
+
+ private Dictionary> OuterDictionary { get; set; }
+
+ public void Add(K key1, T key2, V value)
+ {
+ if (OuterDictionary.ContainsKey(key1)) {
+ if (innerDictionary.ContainsKey(key2)) {
+ OuterDictionary[key1][key2] = value;
+ }
+ else {
+ innerDictionary = OuterDictionary[key1];
+ innerDictionary.Add(key2, value);
+ OuterDictionary[key1] = innerDictionary;
+ }
+ }
+ else {
+ innerDictionary = new Dictionary();
+ innerDictionary[key2] = value;
+ OuterDictionary.Add(key1, innerDictionary);
+ }
+ }
+
+ public V this[K index1, T index2]
+ {
+ get
+ {
+ Dictionary value1;
+ OuterDictionary.TryGetValue(index1, out value1);
+ if (value1 == null)
+ return default(V);
+
+ V value2;
+ value1.TryGetValue(index2, out value2);
+ if (value2 == null)
+ return default(V);
+
+ return value2;
+ }
+
+ set
+ {
+ Add(index1, index2, value);
+ }
+ }
+
+ #region IEnumerable> Members
+
+ public IEnumerator> GetEnumerator()
+ {
+ foreach (KeyValuePair> outer in OuterDictionary)
+ foreach (KeyValuePair inner in outer.Value)
+ yield return new DoubleKeyPairValue(outer.Key, inner.Key, inner.Value);
+ }
+
+ #endregion
+
+ #region IEnumerable Members
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ #endregion
+
+ #region IEquatable> Members
+
+ public bool Equals(DoubleKeyDictionary other)
+ {
+ if (OuterDictionary.Keys.Count != other.OuterDictionary.Keys.Count)
+ return false;
+
+ bool isEqual = true;
+
+ foreach (KeyValuePair> innerItems in OuterDictionary) {
+ if (!other.OuterDictionary.ContainsKey(innerItems.Key))
+ isEqual = false;
+
+ if (!isEqual)
+ break;
+
+ // here we can be sure that the key is in both lists,
+ // but we need to check the contents of the inner dictionary
+ Dictionary otherInnerDictionary = other.OuterDictionary[innerItems.Key];
+ foreach (KeyValuePair innerValue in innerItems.Value) {
+ if (!otherInnerDictionary.ContainsValue(innerValue.Value))
+ isEqual = false;
+ if (!otherInnerDictionary.ContainsKey(innerValue.Key))
+ isEqual = false;
+ }
+
+ if (!isEqual)
+ break;
+ }
+
+ return isEqual;
+ }
+
+ #endregion
+ }
+
+ public class DoubleKeyPairValue
+ {
+ public K Key1 { get; set; }
+ public T Key2 { get; set; }
+ public V Value { get; set; }
+
+ public DoubleKeyPairValue(K key1, T key2, V value) {
+ Key1 = key1;
+ Key2 = key2;
+ Value = value;
+ }
+
+ public override string ToString()
+ {
+ return Key1.ToString() + " - " + Key2.ToString() + " - " + Value.ToString();
+ }
+ }
+}
diff --git a/src/AddIns/Analysis/CodeQuality/Src/Utility/Matrix.cs b/src/AddIns/Analysis/CodeQuality/Src/Utility/Matrix.cs
new file mode 100644
index 0000000000..73fa9bc4f1
--- /dev/null
+++ b/src/AddIns/Analysis/CodeQuality/Src/Utility/Matrix.cs
@@ -0,0 +1,61 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// 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 System.Text;
+
+namespace ICSharpCode.CodeQualityAnalysis.Utility
+{
+ public abstract class Matrix
+ {
+ public List> HeaderRows { get; set; }
+ public List> HeaderColumns { get; set; }
+
+ private DoubleKeyDictionary cache;
+
+ protected Matrix()
+ {
+ HeaderRows = new List>();
+ HeaderColumns = new List| >();
+ cache = new DoubleKeyDictionary();
+ }
+
+ private TValue GetFromCache(int rowIndex, int columnIndex)
+ {
+ return cache[rowIndex, columnIndex];
+ }
+
+ private void SaveToCache(int rowIndex, int columnIndex, TValue result)
+ {
+ cache.Add(rowIndex, columnIndex, result);
+ }
+
+ public TValue this[int rowIndex, int columnIndex]
+ {
+ get
+ {
+ var cacheResult = GetFromCache(rowIndex, columnIndex);
+ if (cacheResult != null)
+ return cacheResult;
+
+ var result = GetCellValue(rowIndex, columnIndex);
+ SaveToCache(rowIndex, columnIndex, result);
+ return result;
+ }
+ }
+
+ protected abstract TValue GetCellValue(int rowIndex, int columnIndex);
+ }
+
+ public class Cell
+ {
+ public TItem Value { get; set; }
+
+ public Cell(TItem value)
+ {
+ Value = value;
+ }
+ }
+}
| | | |