Skip to content

Commit a640e4a

Browse files
WIP
1 parent 58c5ca8 commit a640e4a

File tree

3 files changed

+101
-36
lines changed

3 files changed

+101
-36
lines changed

ILSpy/Commands/CompareContextMenuEntry.cs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
// DEALINGS IN THE SOFTWARE.
1818

1919
using System.Composition;
20+
using System.Threading.Tasks;
2021

2122
using ICSharpCode.ILSpy.AssemblyTree;
2223
using ICSharpCode.ILSpy.Docking;
@@ -37,12 +38,19 @@ public void Execute(TextViewContext context)
3738

3839
var tabPage = dockWorkspace.AddTabPage();
3940

40-
tabPage.Title = $"Compare {left.Text} - {right.Text}";
41-
tabPage.SupportsLanguageSwitching = false;
42-
tabPage.FrozenContent = true;
43-
var compareView = new CompareView();
44-
compareView.DataContext = new CompareViewModel(assemblyTreeModel, left, right);
45-
tabPage.Content = compareView;
41+
tabPage.ShowTextView(t => t.RunWithCancellation(token => Task.Run(DoCompare, token), $"Comparing {left.Text} - {right.Text}").Then(vm => {
42+
tabPage.Title = $"Compare {left.Text} - {right.Text}";
43+
tabPage.SupportsLanguageSwitching = false;
44+
tabPage.FrozenContent = true;
45+
var compareView = new CompareView();
46+
compareView.DataContext = vm;
47+
tabPage.Content = compareView;
48+
}));
49+
50+
CompareViewModel DoCompare()
51+
{
52+
return new CompareViewModel(assemblyTreeModel, left, right);
53+
}
4654
}
4755

4856
public bool IsEnabled(TextViewContext context)

ILSpy/ViewModels/CompareViewModel.cs

Lines changed: 87 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
using TomsToolbox.Wpf;
1212

13+
#nullable enable
14+
1315
namespace ICSharpCode.ILSpy.ViewModels
1416
{
1517
using System.Linq;
@@ -142,7 +144,7 @@ Entry MergeTrees(Entry a, Entry b)
142144
Dictionary<TypeDefinitionHandle, Entry> typeEntries = new();
143145
Dictionary<string, Entry> namespaceEntries = new(StringComparer.Ordinal);
144146

145-
Entry root = new Entry { Entity = null!, Signature = module.FullAssemblyName };
147+
Entry root = new Entry { Entity = module, Signature = module.FullAssemblyName };
146148

147149
// typeEntries need a different signature: must include list of base types
148150

@@ -190,7 +192,7 @@ Entry MergeTrees(Entry a, Entry b)
190192
{
191193
if (!namespaceEntries.TryGetValue(typeDef.Namespace, out var nsEntry))
192194
{
193-
namespaceEntries[typeDef.Namespace] = nsEntry = new Entry { Parent = root, Signature = typeDef.Namespace, Entity = null! };
195+
namespaceEntries[typeDef.Namespace] = nsEntry = new Entry { Parent = root, Signature = typeDef.Namespace, Entity = ResolveNamespace(typeDef.Namespace, typeDef.ParentModule)! };
194196
root.Children ??= new();
195197
root.Children.Add(nsEntry);
196198
}
@@ -242,6 +244,27 @@ Entry MergeTrees(Entry a, Entry b)
242244
}
243245

244246
return (results, root);
247+
248+
INamespace? ResolveNamespace(string namespaceName, IModule module)
249+
{
250+
INamespace current = module.RootNamespace;
251+
string[] parts = namespaceName.Split('.');
252+
253+
for (int i = 0; i < parts.Length; i++)
254+
{
255+
if (i == 0 && string.IsNullOrEmpty(parts[i]))
256+
{
257+
continue;
258+
}
259+
var next = current.GetChildNamespace(parts[i]);
260+
if (next != null)
261+
current = next;
262+
else
263+
return null;
264+
}
265+
266+
return current;
267+
}
245268
}
246269

247270
List<(Entry? Left, Entry? Right)> CalculateDiff(List<Entry> left, List<Entry> right)
@@ -279,15 +302,15 @@ Entry MergeTrees(Entry a, Entry b)
279302
results.Add((item, other));
280303
if (other == null)
281304
{
282-
item.Kind = DiffKind.Remove;
305+
SetKind(item, DiffKind.Remove);
283306
}
284307
}
285308
}
286309
else
287310
{
288311
foreach (var item in items)
289312
{
290-
item.Kind = DiffKind.Remove;
313+
SetKind(item, DiffKind.Remove);
291314
results.Add((item, null));
292315
}
293316
}
@@ -302,35 +325,48 @@ Entry MergeTrees(Entry a, Entry b)
302325
if (!leftEntries.Any(_ => EntryComparer.Instance.Equals(_, item)))
303326
{
304327
results.Add((null, item));
305-
item.Kind = DiffKind.Add;
328+
SetKind(item, DiffKind.Add);
306329
}
307330
}
308331
}
309332
else
310333
{
311334
foreach (var item in items)
312335
{
313-
item.Kind = DiffKind.Add;
336+
SetKind(item, DiffKind.Add);
314337
results.Add((null, item));
315338
}
316339
}
317340
}
318341

319342
return results;
343+
344+
static void SetKind(Entry item, DiffKind kind)
345+
{
346+
if (item.Children?.Count > 0)
347+
{
348+
foreach (var child in item.Children)
349+
{
350+
SetKind(child, kind);
351+
}
352+
}
353+
else
354+
{
355+
item.Kind = kind;
356+
}
357+
}
320358
}
321359
}
322360

323361
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
324362
public class Entry
325363
{
326-
private DiffKind kind = DiffKind.None;
364+
private DiffKind? kind;
327365

328-
public DiffKind Kind {
366+
public DiffKind RecursiveKind {
329367
get {
330-
if (Children == null || Children.Count == 0)
331-
{
332-
return kind;
333-
}
368+
if (kind != null)
369+
return kind.Value;
334370

335371
int addCount = 0, removeCount = 0, updateCount = 0;
336372

@@ -358,15 +394,11 @@ public DiffKind Kind {
358394
return DiffKind.Update;
359395
return DiffKind.None;
360396
}
361-
set {
362-
if (Children == null || Children.Count == 0)
363-
{
364-
kind = value;
365-
}
366-
}
367397
}
398+
399+
public DiffKind Kind { get; set; }
368400
public required string Signature { get; init; }
369-
public required IEntity Entity { get; init; }
401+
public required ISymbol Entity { get; init; }
370402

371403
public Entry? Parent { get; set; }
372404
public List<Entry>? Children { get; set; }
@@ -421,7 +453,29 @@ protected override void LoadChildren()
421453
}
422454
}
423455

424-
public override object Text => entry.Signature;
456+
public override object Text {
457+
get {
458+
switch (entry.Entity)
459+
{
460+
case ITypeDefinition t:
461+
return this.Language.TypeToString(t, includeNamespace: false) + GetSuffixString(t.MetadataToken);
462+
case IMethod m:
463+
return this.Language.MethodToString(m, false, false, false) + GetSuffixString(m.MetadataToken);
464+
case IField f:
465+
return this.Language.FieldToString(f, false, false, false) + GetSuffixString(f.MetadataToken);
466+
case IProperty p:
467+
return this.Language.PropertyToString(p, false, false, false) + GetSuffixString(p.MetadataToken);
468+
case IEvent e:
469+
return this.Language.EventToString(e, false, false, false) + GetSuffixString(e.MetadataToken);
470+
case INamespace n:
471+
return n.FullName;
472+
case IModule m:
473+
return m.FullAssemblyName;
474+
default:
475+
return entry.Signature;
476+
}
477+
}
478+
}
425479

426480
public override object Icon {
427481
get {
@@ -437,16 +491,28 @@ public override object Icon {
437491
return PropertyTreeNode.GetIcon(p);
438492
case IEvent e:
439493
return EventTreeNode.GetIcon(e);
494+
case INamespace n:
495+
return Images.Namespace;
496+
case IModule m:
497+
return Images.Assembly;
440498
default:
441499
throw new NotSupportedException();
442500
}
443501
}
444502
}
445503

446-
public DiffKind Difference => entry.Kind;
504+
505+
506+
public DiffKind RecursiveKind => entry.RecursiveKind;
507+
public DiffKind Kind => entry.Kind;
447508

448509
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
449510
{
450511
}
512+
513+
//public override FilterResult Filter(LanguageSettings settings)
514+
//{
515+
// return RecursiveKind != DiffKind.None ? FilterResult.Match : FilterResult.Hidden;
516+
//}
451517
}
452518
}

ILSpy/Views/CompareView.xaml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,6 @@
3030
</Border>
3131
</Border>
3232
<ControlTemplate.Triggers>
33-
<DataTrigger Binding="{Binding Difference}" Value="Update">
34-
<Setter Property="Background" Value="LightBlue" />
35-
</DataTrigger>
36-
<DataTrigger Binding="{Binding Difference}" Value="Add">
37-
<Setter Property="Background" Value="LightGreen" />
38-
</DataTrigger>
39-
<DataTrigger Binding="{Binding Difference}" Value="Remove">
40-
<Setter Property="Background" Value="LightPink" />
41-
</DataTrigger>
4233
<DataTrigger Binding="{Binding IsPublicAPI}" Value="False">
4334
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
4435
</DataTrigger>

0 commit comments

Comments
 (0)