Browse Source

Add Where() and OfType() implementations in ModelCollectionLinq; and remove some redundant helper methods in Debugger.AddIn.

pull/32/merge
Daniel Grunwald 13 years ago
parent
commit
8b1fcfa2ba
  1. 4
      src/AddIns/Analysis/MachineSpecifications/MachineSpecifications.Tests/Src/MSpecTestFrameworkTests.cs
  2. 1
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
  3. 3
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/GraphVisualizer/Layout/GraphDiff.cs
  4. 3
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/GraphVisualizer/Layout/GraphMatcher.cs
  5. 5
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/GraphVisualizer/ObjectGraph/ObjectGraphBuilder.cs
  6. 5
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs
  7. 41
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/Multimap.cs
  8. 35
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/Util.cs
  9. 19
      src/Main/Base/Project/Dom/ImmutableModelCollection.cs
  10. 25
      src/Main/Base/Project/Dom/ModelCollectionLinq.cs
  11. 2
      src/Main/Base/Project/Src/Project/AbstractProject.cs
  12. 2
      src/Main/Base/Test/Project/BeforeBuildCustomToolProjectItemsTests.cs
  13. 11
      src/Main/Base/Test/Utils/ProjectHelper.cs

4
src/AddIns/Analysis/MachineSpecifications/MachineSpecifications.Tests/Src/MSpecTestFrameworkTests.cs

@ -31,12 +31,12 @@ namespace ICSharpCode.MachineSpecifications.Tests
testProject = fake.an<IProject>(); testProject = fake.an<IProject>();
var mspecReference = MockRepository.GenerateStub<ReferenceProjectItem>(testProject); var mspecReference = MockRepository.GenerateStub<ReferenceProjectItem>(testProject);
mspecReference.setup(x => x.ShortName).Return(MSpecAssemblyName); mspecReference.setup(x => x.ShortName).Return(MSpecAssemblyName);
testProject.setup(x => x.Items).Return(new ImmutableModelCollection<ProjectItem>(new[] { mspecReference })); testProject.setup(x => x.Items).Return(new SimpleModelCollection<ProjectItem>(new[] { mspecReference }));
nonTestProject = fake.an<IProject>(); nonTestProject = fake.an<IProject>();
var otherReference = MockRepository.GenerateStub<ReferenceProjectItem>(nonTestProject); var otherReference = MockRepository.GenerateStub<ReferenceProjectItem>(nonTestProject);
mspecReference.setup(x => x.ShortName).Return("System.Configuration"); mspecReference.setup(x => x.ShortName).Return("System.Configuration");
nonTestProject.setup(x => x.Items).Return(new ImmutableModelCollection<ProjectItem>(new[] { otherReference })); nonTestProject.setup(x => x.Items).Return(new SimpleModelCollection<ProjectItem>(new[] { otherReference }));
}; };
Because of = () => { Because of = () => {

1
src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj

@ -218,7 +218,6 @@
<Compile Include="Visualizers\TextVisualizer\TextVisualizerWindow.xaml.cs" /> <Compile Include="Visualizers\TextVisualizer\TextVisualizerWindow.xaml.cs" />
<Compile Include="Visualizers\Utils\DebuggerHelpers.cs" /> <Compile Include="Visualizers\Utils\DebuggerHelpers.cs" />
<Compile Include="Visualizers\Utils\Util.cs" /> <Compile Include="Visualizers\Utils\Util.cs" />
<Compile Include="Visualizers\Utils\Multimap.cs" />
<Compile Include="Visualizers\Utils\TreeFlattener.cs" /> <Compile Include="Visualizers\Utils\TreeFlattener.cs" />
<Compile Include="Visualizers\Utils\TypeResolver.cs" /> <Compile Include="Visualizers\Utils\TypeResolver.cs" />
<EmbeddedResource Include="Service\DebuggeeExceptionForm.resx"> <EmbeddedResource Include="Service\DebuggeeExceptionForm.resx">

3
src/AddIns/Debugger/Debugger.AddIn/Visualizers/GraphVisualizer/Layout/GraphDiff.cs

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using ICSharpCode.SharpDevelop;
using Debugger.AddIn.Visualizers.Utils; using Debugger.AddIn.Visualizers.Utils;
namespace Debugger.AddIn.Visualizers.Graph.Layout namespace Debugger.AddIn.Visualizers.Graph.Layout
@ -45,7 +46,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
public PositionedNode GetMatchingNewNode(PositionedNode oldNode) public PositionedNode GetMatchingNewNode(PositionedNode oldNode)
{ {
return matching.GetValue(oldNode); return matching.GetOrDefault(oldNode);
} }
internal void SetAdded(PositionedNode addedNode) internal void SetAdded(PositionedNode addedNode)

3
src/AddIns/Debugger/Debugger.AddIn/Visualizers/GraphVisualizer/Layout/GraphMatcher.cs

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using ICSharpCode.SharpDevelop;
using Debugger.AddIn.Visualizers.Utils; using Debugger.AddIn.Visualizers.Utils;
namespace Debugger.AddIn.Visualizers.Graph.Layout namespace Debugger.AddIn.Visualizers.Graph.Layout
@ -69,7 +70,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
PositionedNode MatchNode(PositionedNode oldNode, Dictionary<int, PositionedNode> newNodeMap) PositionedNode MatchNode(PositionedNode oldNode, Dictionary<int, PositionedNode> newNodeMap)
{ {
PositionedNode newNodeFound = newNodeMap.GetValue(oldNode.ObjectNode.HashCode); PositionedNode newNodeFound = newNodeMap.GetOrDefault(oldNode.ObjectNode.HashCode);
if ((newNodeFound != null) && IsSameAddress(oldNode, newNodeFound)) { if ((newNodeFound != null) && IsSameAddress(oldNode, newNodeFound)) {
return newNodeFound; return newNodeFound;
} else { } else {

5
src/AddIns/Debugger/Debugger.AddIn/Visualizers/GraphVisualizer/ObjectGraph/ObjectGraphBuilder.cs

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using ICSharpCode.NRefactory.Utils;
using Debugger.AddIn.TreeModel; using Debugger.AddIn.TreeModel;
using Debugger.AddIn.Visualizers.Graph.Layout; using Debugger.AddIn.Visualizers.Graph.Layout;
using Debugger.AddIn.Visualizers.Utils; using Debugger.AddIn.Visualizers.Utils;
@ -55,7 +56,7 @@ namespace Debugger.AddIn.Visualizers.Graph
/// <summary> /// <summary>
/// Given hash code, lookup already existing node(s) with this hash code. /// Given hash code, lookup already existing node(s) with this hash code.
/// </summary> /// </summary>
private Multimap<int, ObjectGraphNode> objectNodesForHashCode = new Multimap<int, ObjectGraphNode>(); private MultiDictionary<int, ObjectGraphNode> objectNodesForHashCode = new MultiDictionary<int, ObjectGraphNode>();
/// <summary> /// <summary>
/// Creates ObjectGraphBuilder. /// Creates ObjectGraphBuilder.
@ -302,7 +303,7 @@ namespace Debugger.AddIn.Visualizers.Graph
{ {
int objectHashCode = value.InvokeDefaultGetHashCode(); int objectHashCode = value.InvokeDefaultGetHashCode();
// are there any nodes with the same hash code? // are there any nodes with the same hash code?
IList<ObjectGraphNode> nodesWithSameHashCode = objectNodesForHashCode[objectHashCode]; var nodesWithSameHashCode = objectNodesForHashCode[objectHashCode];
if (nodesWithSameHashCode == null) { if (nodesWithSameHashCode == null) {
return null; return null;
} else { } else {

5
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs

@ -3,6 +3,7 @@
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using ICSharpCode.NRefactory.CSharp;
using Debugger.AddIn.TreeModel; using Debugger.AddIn.TreeModel;
using Debugger.AddIn.Visualizers.Graph; using Debugger.AddIn.Visualizers.Graph;
using Debugger.Interop.CorDebug; using Debugger.Interop.CorDebug;
@ -74,7 +75,7 @@ namespace Debugger.AddIn.Visualizers.Utils
/// </summary> /// </summary>
public static bool IsAtomic(this IType type) public static bool IsAtomic(this IType type)
{ {
return TypeSystemExtensions.IsPrimitiveType(type) || type.FullName == "System.String" || type.Kind == TypeKind.Enum; return TypeSystemExtensions.IsPrimitiveType(type) || type.IsKnownType(KnownTypeCode.String) || type.Kind == TypeKind.Enum;
} }
/// <summary> /// <summary>
@ -121,7 +122,7 @@ namespace Debugger.AddIn.Visualizers.Utils
/// </summary> /// </summary>
public static string FormatNameCSharp(this IType type) public static string FormatNameCSharp(this IType type)
{ {
return type.ToString(); // TODO use an existing C# IType formatter? return new CSharpAmbience().ConvertType(type);
} }
public static IEnumerable<IMember> GetFieldsAndNonIndexedProperties(this IType type, GetMemberOptions options = GetMemberOptions.None) { public static IEnumerable<IMember> GetFieldsAndNonIndexedProperties(this IType type, GetMemberOptions options = GetMemberOptions.None) {

41
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/Multimap.cs

@ -1,41 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
using System;
using System.Collections.Generic;
namespace Debugger.AddIn.Visualizers.Utils
{
/// <summary> Dictionary that can store multiple values for each key.</summary>
public class Multimap<TKey, TValue>
{
/// <summary>Wrapped dictionary</summary>
private Dictionary<TKey, IList<TValue>> dictionary;
public Multimap()
{
dictionary = new Dictionary<TKey, IList<TValue>>();
}
public IList<TValue> this[TKey key]
{
get {
IList<TValue> values = null;
if (dictionary.TryGetValue(key, out values)) {
return values;
}
return null;
}
}
public void Add(TKey key, TValue value)
{
IList<TValue> values = null;
if (!dictionary.TryGetValue(key, out values)) {
values = new List<TValue>();
dictionary.Add(key, values);
}
values.Add(value);
}
}
}

35
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/Util.cs

@ -18,41 +18,6 @@ namespace Debugger.AddIn.Visualizers.Utils
return source.Max(selector); return source.Max(selector);
} }
public static string Repeat(char c, int count)
{
StringBuilder sb = new StringBuilder();
sb.Append(c, count);
return sb.ToString();
}
/// <summary>
/// Gets value from Dictionary. Returns null if not found.
/// </summary>
public static TValue GetValue<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key) where TValue : class
{
TValue outValue;
if (dictionary.TryGetValue(key, out outValue)) {
return outValue;
}
return null;
}
/// <summary>
/// Builds a Dictionary for quickly searching a collection. Item keys must be unique.
/// </summary>
/// <param name="collection">Collection for which to build Dictionary.</param>
/// <param name="keySelector">Function returning key by which to index.</param>
public static Dictionary<K, V> MakeDictionary<K, V>(this IEnumerable<V> collection, Func<V, K> keySelector)
{
Dictionary<K, V> dictionary = new Dictionary<K, V>();
foreach (V item in collection) {
K key = keySelector(item);
if (dictionary.ContainsKey(key)) throw new InvalidOperationException("MakeDictionary: key " + key + " seen twice");
dictionary[key] = item;
}
return dictionary;
}
public static List<T> Sorted<T>(this List<T> list, IComparer<T> comparer) public static List<T> Sorted<T>(this List<T> list, IComparer<T> comparer)
{ {
list.Sort(comparer); list.Sort(comparer);

19
src/Main/Base/Project/Dom/ImmutableModelCollection.cs

@ -5,14 +5,24 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.SharpDevelop.Dom namespace ICSharpCode.SharpDevelop.Dom
{ {
/// <summary> /// <summary>
/// An immutable model collection. /// An immutable model collection.
/// </summary> /// </summary>
public class ImmutableModelCollection<T> : ReadOnlyCollection<T>, IModelCollection<T>, IMutableModelCollection<T> public class ImmutableModelCollection<T> : ReadOnlyCollection<T>, IModelCollection<T>
{ {
static ImmutableModelCollection<T> empty = new ImmutableModelCollection<T>(Enumerable.Empty<T>());
/// <summary>
/// Gets the empty model collection.
/// </summary>
public static ImmutableModelCollection<T> Empty {
get { return empty; }
}
public ImmutableModelCollection(IEnumerable<T> items) public ImmutableModelCollection(IEnumerable<T> items)
: base(items.ToList()) : base(items.ToList())
{ {
@ -24,6 +34,13 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
return this; return this;
} }
}
class ImmutableModelCollectionImplementsMutableInterface<T> : ImmutableModelCollection<T>, IMutableModelCollection<T>
{
public ImmutableModelCollectionImplementsMutableInterface(IEnumerable<T> items) : base(items)
{
}
void IMutableModelCollection<T>.AddRange(IEnumerable<T> items) void IMutableModelCollection<T>.AddRange(IEnumerable<T> items)
{ {

25
src/Main/Base/Project/Dom/ModelCollectionLinq.cs

@ -10,7 +10,7 @@ using System.Runtime.InteropServices.WindowsRuntime;
namespace ICSharpCode.SharpDevelop.Dom namespace ICSharpCode.SharpDevelop.Dom
{ {
/// <summary> /// <summary>
/// Provides LINQ operators for . /// Provides LINQ operators for <see cref="IModelCollection{T}"/>.
/// </summary> /// </summary>
public static class ModelCollectionLinq public static class ModelCollectionLinq
{ {
@ -18,23 +18,34 @@ namespace ICSharpCode.SharpDevelop.Dom
// to implement that without leaking memory. // to implement that without leaking memory.
// The problem is that IModelCollection is unordered; but ObservableCollection requires us to maintain a stable order. // The problem is that IModelCollection is unordered; but ObservableCollection requires us to maintain a stable order.
#region OfType / Cast
public static IModelCollection<TResult> OfType<TResult>(this IModelCollection<object> source)
{
return SelectMany(source, item => item is TResult ? new ImmutableModelCollection<TResult>(new[] { (TResult)item }) : ImmutableModelCollection<TResult>.Empty);
}
public static IModelCollection<TResult> Cast<TResult>(this IModelCollection<object> source)
{
return SelectMany(source, item => new ImmutableModelCollection<TResult>(new[] { (TResult)item }));
}
#endregion
#region Where #region Where
/*public static IModelCollection<TSource> Where<TSource>(this IModelCollection<TSource> source, Func<TSource, bool> predicate) public static IModelCollection<TSource> Where<TSource>(this IModelCollection<TSource> source, Func<TSource, bool> predicate)
{ {
return SelectMany(source, item => predicate(item) ? new ImmutableModelCollection<TSource>(new[] { item }) : ImmutableModelCollection<TSource>.Empty);
}*/ }
#endregion #endregion
#region Select #region Select
public static IModelCollection<TResult> Select<TSource, TResult>(this IModelCollection<TSource> source, Func<TSource, TResult> selector) public static IModelCollection<TResult> Select<TSource, TResult>(this IModelCollection<TSource> source, Func<TSource, TResult> selector)
{ {
// HACK: emulating Select with SelectMany is much less efficient than a direct implementation could be return SelectMany(source, item => new ImmutableModelCollection<TResult>(new[] { selector(item) }));
return SelectMany(source, item => new ImmutableModelCollection<TSource>(new[] { item }), (a, b) => selector(b));
} }
#endregion #endregion
#region SelectMany #region SelectMany
public static IModelCollection<S> SelectMany<T, S>(this IModelCollection<T> input, Func<T, IModelCollection<S>> selector) public static IModelCollection<TResult> SelectMany<TSource, TResult>(this IModelCollection<TSource> input, Func<TSource, IModelCollection<TResult>> selector)
{ {
return SelectMany(input, selector, (a, b) => b); return SelectMany(input, selector, (a, b) => b);
} }

2
src/Main/Base/Project/Src/Project/AbstractProject.cs

@ -311,7 +311,7 @@ namespace ICSharpCode.SharpDevelop.Project
[Browsable(false)] [Browsable(false)]
public virtual IMutableModelCollection<ProjectItem> Items { public virtual IMutableModelCollection<ProjectItem> Items {
get { get {
return new ImmutableModelCollection<ProjectItem>(Enumerable.Empty<ProjectItem>()); return new ImmutableModelCollectionImplementsMutableInterface<ProjectItem>(Enumerable.Empty<ProjectItem>());
} }
} }

2
src/Main/Base/Test/Project/BeforeBuildCustomToolProjectItemsTests.cs

@ -80,7 +80,7 @@ namespace ICSharpCode.SharpDevelop.Project
FileProjectItem AddFileToProject(string include) FileProjectItem AddFileToProject(string include)
{ {
var projectItem = new FileProjectItem(projectHelper.Project, ItemType.Compile, include); var projectItem = new FileProjectItem(projectHelper.Project, ItemType.Compile, include);
projectHelper.AddProjectItem(projectItem); projectHelper.Project.Items.Add(projectItem);
return projectItem; return projectItem;
} }

11
src/Main/Base/Test/Utils/ProjectHelper.cs

@ -14,25 +14,16 @@ namespace ICSharpCode.SharpDevelop.Tests.Utils
public class ProjectHelper public class ProjectHelper
{ {
public IProject Project = MockRepository.GenerateMock<IProject, IBuildable>(); public IProject Project = MockRepository.GenerateMock<IProject, IBuildable>();
public List<ProjectItem> ProjectItems = new List<ProjectItem>();
public ProjectHelper(string fileName) public ProjectHelper(string fileName)
{ {
Project.Stub(p => p.FileName).Return(FileName.Create(fileName)); Project.Stub(p => p.FileName).Return(FileName.Create(fileName));
Project Project.Stub(p => p.Items).Return(new SimpleModelCollection<ProjectItem>());
.Stub(p => p.Items)
.Return(null)
.WhenCalled(mi => mi.ReturnValue = new ImmutableModelCollection<ProjectItem>(ProjectItems));
Project.Stub(p => p.Preferences).Return(new Properties()); Project.Stub(p => p.Preferences).Return(new Properties());
Project.Stub(p => p.SyncRoot).Return(new Object()); Project.Stub(p => p.SyncRoot).Return(new Object());
} }
public void AddProjectItem(ProjectItem projectItem)
{
ProjectItems.Add(projectItem);
}
} }
} }

Loading…
Cancel
Save