Browse Source

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

pull/32/merge
Daniel Grunwald 12 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 @@ -31,12 +31,12 @@ namespace ICSharpCode.MachineSpecifications.Tests
testProject = fake.an<IProject>();
var mspecReference = MockRepository.GenerateStub<ReferenceProjectItem>(testProject);
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>();
var otherReference = MockRepository.GenerateStub<ReferenceProjectItem>(nonTestProject);
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 = () => {

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

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

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

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

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

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

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

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

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

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System.Linq;
using System.Runtime.InteropServices;
using ICSharpCode.NRefactory.CSharp;
using Debugger.AddIn.TreeModel;
using Debugger.AddIn.Visualizers.Graph;
using Debugger.Interop.CorDebug;
@ -74,7 +75,7 @@ namespace Debugger.AddIn.Visualizers.Utils @@ -74,7 +75,7 @@ namespace Debugger.AddIn.Visualizers.Utils
/// </summary>
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>
@ -121,7 +122,7 @@ namespace Debugger.AddIn.Visualizers.Utils @@ -121,7 +122,7 @@ namespace Debugger.AddIn.Visualizers.Utils
/// </summary>
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) {

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

@ -1,41 +0,0 @@ @@ -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 @@ -18,41 +18,6 @@ namespace Debugger.AddIn.Visualizers.Utils
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)
{
list.Sort(comparer);

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

@ -5,14 +5,24 @@ using System; @@ -5,14 +5,24 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.SharpDevelop.Dom
{
/// <summary>
/// An immutable model collection.
/// </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)
: base(items.ToList())
{
@ -24,6 +34,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -24,6 +34,13 @@ namespace ICSharpCode.SharpDevelop.Dom
{
return this;
}
}
class ImmutableModelCollectionImplementsMutableInterface<T> : ImmutableModelCollection<T>, IMutableModelCollection<T>
{
public ImmutableModelCollectionImplementsMutableInterface(IEnumerable<T> items) : base(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; @@ -10,7 +10,7 @@ using System.Runtime.InteropServices.WindowsRuntime;
namespace ICSharpCode.SharpDevelop.Dom
{
/// <summary>
/// Provides LINQ operators for .
/// Provides LINQ operators for <see cref="IModelCollection{T}"/>.
/// </summary>
public static class ModelCollectionLinq
{
@ -18,23 +18,34 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -18,23 +18,34 @@ namespace ICSharpCode.SharpDevelop.Dom
// to implement that without leaking memory.
// The problem is that IModelCollection is unordered; but ObservableCollection requires us to maintain a stable order.
#region Where
/*public static IModelCollection<TSource> Where<TSource>(this IModelCollection<TSource> source, Func<TSource, bool> predicate)
#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
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
#region Select
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<TSource>(new[] { item }), (a, b) => selector(b));
return SelectMany(source, item => new ImmutableModelCollection<TResult>(new[] { selector(item) }));
}
#endregion
#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);
}

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

@ -311,7 +311,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -311,7 +311,7 @@ namespace ICSharpCode.SharpDevelop.Project
[Browsable(false)]
public virtual IMutableModelCollection<ProjectItem> Items {
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 @@ -80,7 +80,7 @@ namespace ICSharpCode.SharpDevelop.Project
FileProjectItem AddFileToProject(string include)
{
var projectItem = new FileProjectItem(projectHelper.Project, ItemType.Compile, include);
projectHelper.AddProjectItem(projectItem);
projectHelper.Project.Items.Add(projectItem);
return projectItem;
}

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

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

Loading…
Cancel
Save