Skip to content

Commit 847acf3

Browse files
Add "Export as JSON" feature
1 parent 7a0a2b1 commit 847acf3

11 files changed

+177
-17
lines changed

ILSpy/Images/DictionaryContain.svg

Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!-- This file was generated by the AiToXaml tool.-->
2+
<!-- Tool Version: 14.0.22307.0 -->
3+
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ClipGeometry="M0,0 V16 H16 V0 H0 Z">
4+
<DrawingGroup.Children>
5+
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
6+
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M15,2L15,11 11,11C10.836,11.005,10,12,10,12L8,12C8,12,7.164,11.005,7,11L7,13 2,13 2,8 3,8 3,2 7.5,2C8.146,2.004 8.62,2.191 9,2.5 9.381,2.191 9.863,2 10.5,2z" />
7+
<GeometryDrawing Brush="#FF424242" Geometry="F1M13,9L11,9C10.565,9,10.33,8.795,10,9L10,5C10,4.615,10.41,4,11,4L13,4z M10.5,3C9.876,3 9.516,3.365 9,4 8.492,3.374 8.139,3.004 7.5,3L4,3 4,8 5,8 5,4 7,4C7.566,4,8,4.663,8,5L8,9C7.67,8.795,7.436,9,7,9L7,10C7.549,10 8.778,9.975 9,10.5 9.221,9.975 10.451,10 11,10L14,10 14,3z" />
8+
<GeometryDrawing Brush="#FF424242" Geometry="F1M3,11L6,11 6,12 3,12z" />
9+
<GeometryDrawing Brush="#FF424242" Geometry="F1M3,10L6,10 6,9 3,9z" />
10+
<GeometryDrawing Brush="#FFEFEFF0" Geometry="F1M7,4L5,4 5,8 7,8 7,9C7.436,9,7.67,8.795,8,9L8,5C8,4.663,7.566,4,7,4" />
11+
<GeometryDrawing Brush="#FFEFEFF0" Geometry="F1M11,4C10.41,4,10,4.615,10,5L10,9C10.33,8.795,10.565,9,11,9L13,9 13,4z" />
12+
</DrawingGroup.Children>
13+
</DrawingGroup>

ILSpy/Images/ExpandAll.svg

Lines changed: 1 addition & 0 deletions
Loading

ILSpy/Images/ExpandAll.xaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!-- This file was generated by the AiToXaml tool.-->
2+
<!-- Tool Version: 14.0.22307.0 -->
3+
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
4+
<DrawingGroup.Children>
5+
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
6+
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M15,10L13,10 13,12 11,12 11,14 2,14 2,5 4,5 4,3 6,3 6,1 15,1z" />
7+
<GeometryDrawing Brush="#FF424242" Geometry="F1M9,7L4,7 4,12 9,12z M10,13L3,13 3,6 10,6z M5,4L5,5 6,5 11,5 11,10 11,11 12,11 12,4z M14,2L14,9 13,9 13,8 13,3 8,3 7,3 7,2z" />
8+
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M8,10L7,10 7,11 6.984,11 6,11 6,10 5,10 5,9 6,9 6,8 7,8 7,9 8,9z M4,12L9,12 9,7 4,7z" />
9+
<GeometryDrawing Brush="#FF00539C" Geometry="F1M7,9L8,9 8,10 6.995,10 6.984,11 6,11 6,10 5,10 5,9 6,9 6,8 7,8z" />
10+
</DrawingGroup.Children>
11+
</DrawingGroup>

ILSpy/Images/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ Icons used in ILSpy:
1515
| Copy | x | x | VS 2017 Icon Pack (Copy) | |
1616
| Delegate | x | x | VS 2017 Icon Pack (Delegate) | |
1717
| Delete | x | x | VS 2017 Icon Pack (Remove_color) | |
18+
| DictionaryContain | x | x | VS 2017 Icon Pack (DictionaryContain) | |
1819
| Enum | x | x | VS 2017 Icon Pack (Enumerator) | |
1920
| EnumValue | x | x | VS 2017 Icon Pack (EnumItem) | |
2021
| Event | x | x | VS 2017 Icon Pack (Event) | |
22+
| ExpandAll | x | x | VS 2017 Icon Pack (ExpandAll) | |
2123
| ExportOverlay | x | x | slightly modified VS 2017 Icon Pack (Export) | |
2224
| ExtensionMethod | x | x | VS 2017 Icon Pack (ExtensionMethod) | |
2325
| Field | x | x | VS 2017 Icon Pack (Field) | |
@@ -62,6 +64,7 @@ Icons used in ILSpy:
6264
| ResourceXml | x | x | VS 2017 Icon Pack (XMLFile) | |
6365
| ResourceXsd | x | x | combined VS 2017 Icon Pack (XMLSchema) with the file symbol in ResourceXslt | |
6466
| ResourceXsl | x | x | VS 2017 Icon Pack (XMLTransformation) | |
67+
| ResultToJSON | x | x | VS 2017 Icon Pack (ResultToJSON) | |
6568
| ResourceXslt | x | x | VS 2017 Icon Pack (XSLTTemplate) | |
6669
| Save | x | x | VS 2017 Icon Pack (Save) | |
6770
| Search | x | x | VS 2017 Icon Pack (Search) | |
@@ -73,6 +76,7 @@ Icons used in ILSpy:
7376
| Struct | x | x | VS 2017 Icon Pack (Structure) | |
7477
| SubTypes | x | x | based on VS 2017 Icon Pack (BaseType) rotated +90° | |
7578
| SuperTypes | x | x | based on VS 2017 Icon Pack (BaseType) rotated -90° | |
79+
| SwitchSourceOrTarget | x | x | VS 2017 Icon Pack (SwitchSourceOrTarget) | |
7680
| ViewCode | x | x | VS 2017 Icon Pack (GoToSourceCode) | |
7781
| VirtualMethod | x | x | combined VS 2017 Icon Pack (Method) two times | |
7882
| Warning | x | x | VS 2017 Icon Pack (StatusWarning) | |

ILSpy/Images/ResultToJSON.svg

Lines changed: 1 addition & 0 deletions
Loading

ILSpy/Images/ResultToJSON.xaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!-- This file was generated by the AiToXaml tool.-->
2+
<!-- Tool Version: 14.0.22307.0 -->
3+
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ClipGeometry="M0,0 V16 H16 V0 H0 Z">
4+
<DrawingGroup.Children>
5+
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
6+
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M9.4141,4L5.4141,0 0.5861,0 2.5861,2 9.99999999997669E-05,2 9.99999999997669E-05,6 2.0001,6 2.0001,6.586 1.5861,7 1.0001,7 1.0001,7.586 0.5861,8 1.0001,8 1.0001,9.638 1.3291,11 2.0001,11 2.0001,12.536C2.0001,13.783 2.4951,14.686 3.1901,15.247 3.8311,15.764 4.8871,16 6.1271,16L7.0001,16 7.0001,12.753C7.0001,12.753 5.9891,12.752 5.9671,12.75 5.9591,12.697 6.0001,12.623 6.0001,12.522L6.0001,11.121C6.0001,10.159 5.7761,9.484 5.4571,9.01 5.7131,8.632 5.9011,8.119 5.9681,7.446z M16.0001,8.38L16.0001,10.638C16.0001,10.638 15.0081,10.637 15.0031,10.635 14.9911,10.687 15.0001,10.775 15.0001,10.916L15.0001,12.495C15.0001,13.766 14.6301,14.68 13.9461,15.241 13.3081,15.763 12.3701,16 11.1241,16L10.0001,16 10.0001,12.753C10.0001,12.753 11.0141,12.752 11.0371,12.75 11.0411,12.704 11.0001,12.633 11.0001,12.536L11.0001,11.08C11.0001,10.137 11.2221,9.474 11.5391,9.008 11.2231,8.527 11.0001,7.843 11.0001,6.869L11.0001,5.468C11.0001,5.38 11.1021,5.182 11.0941,5.143 11.0741,5.141 11.1571,5 11.1241,5L10.0001,5 10.0001,2 11.1241,2C12.3751,2 13.3171,2.265 13.9561,2.81 14.6331,3.387 15.0001,4.3 15.0001,5.522L15.0001,7 15.9191,7z" />
7+
<GeometryDrawing Brush="#FF424242" Geometry="F1M5.0332,12.5225L5.0332,11.1215C5.0332,10.0045,4.6822,9.3055,3.9802,9.0225L3.9802,8.9955C4.4092,8.8195,4.6902,8.4755,4.8572,8.0005L3.0492,8.0005C2.8762,8.2475,2.6132,8.3795,2.2442,8.3795L2.2442,9.6375C2.9362,9.6375,3.2832,10.0575,3.2832,10.8955L3.2832,12.5365C3.2832,13.4705 3.5092,14.1205 3.9602,14.4845 4.4112,14.8485 5.1342,15.0315 6.1272,15.0315L6.1272,13.7525C5.7392,13.7525 5.4612,13.6595 5.2892,13.4725 5.1192,13.2855 5.0332,12.9695 5.0332,12.5225 M15.0002,8.3795L15.0002,9.6375C14.3032,9.6375,13.9542,10.0645,13.9542,10.9165L13.9542,12.4955C13.9542,13.4565 13.7312,14.1205 13.2882,14.4845 12.8432,14.8485 12.1222,15.0315 11.1242,15.0315L11.1242,13.7525C11.5072,13.7525 11.7852,13.6605 11.9582,13.4765 12.1312,13.2915 12.2182,12.9785 12.2182,12.5365L12.2182,11.0805C12.2182,9.9905,12.5662,9.3095,13.2632,9.0365L13.2632,9.0085C12.5662,8.7215,12.2182,8.0085,12.2182,6.8695L12.2182,5.4675C12.2182,4.6745,11.8532,4.2785,11.1242,4.2785L11.1242,3.0005C12.1172,3.0005 12.8382,3.1905 13.2842,3.5705 13.7302,3.9515 13.9542,4.6025 13.9542,5.5225L13.9542,7.0875C13.9542,7.9495,14.3032,8.3795,15.0002,8.3795" />
8+
<GeometryDrawing Brush="#FF00529C" Geometry="F1M8,4L5,7 3,7 5,5 1,5 1,3 5,3 3,1 5,1z" />
9+
</DrawingGroup.Children>
10+
</DrawingGroup>
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!-- This file was generated by the AiToXaml tool.-->
2+
<!-- Tool Version: 14.0.22307.0 -->
3+
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ClipGeometry="M0,0 V16 H16 V0 H0 Z">
4+
<DrawingGroup.Children>
5+
<GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" />
6+
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M4.5855,1.9996L0.5855,6.0006 2.5855,7.9996 2.9995,7.9996 2.9995,12.0006 8.5865,12.0006 6.5865,14.0006 11.4135,14.0006 15.4145,9.9996 13.4145,7.9996 12.9995,7.9996 12.9995,4.0006 7.4145,4.0006 9.4145,1.9996z" />
7+
<GeometryDrawing Brush="#FF424242" Geometry="F1M13,9L4,9 4,11 11,11 9,13 11,13 14,10z M12,7L3,7 2,6 5,3 7,3 5,5 12,5z" />
8+
</DrawingGroup.Children>
9+
</DrawingGroup>

ILSpy/ViewModels/CompareViewModel.cs

Lines changed: 89 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,30 @@
2020
using System.Collections.Generic;
2121
using System.Diagnostics;
2222
using System.Diagnostics.CodeAnalysis;
23+
using System.Linq;
2324
using System.Reflection.Metadata;
25+
using System.Text.Json;
26+
using System.Threading.Tasks;
27+
using System.Windows;
28+
using System.Windows.Input;
29+
using System.Windows.Media;
2430

31+
using ICSharpCode.Decompiler;
2532
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
33+
using ICSharpCode.Decompiler.Util;
2634
using ICSharpCode.ILSpy.AssemblyTree;
35+
using ICSharpCode.ILSpy.TreeNodes;
36+
using ICSharpCode.ILSpy.Views;
2737
using ICSharpCode.ILSpyX;
28-
29-
using TomsToolbox.Wpf;
38+
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
3039

3140
#nullable enable
3241

3342
namespace ICSharpCode.ILSpy.ViewModels
3443
{
35-
using System.Linq;
36-
using System.Threading.Tasks;
37-
using System.Windows.Input;
38-
using System.Windows.Media;
39-
40-
using ICSharpCode.Decompiler;
4144
using ICSharpCode.Decompiler.TypeSystem;
42-
using ICSharpCode.ILSpy.Commands;
43-
using ICSharpCode.ILSpy.TreeNodes;
44-
using ICSharpCode.ILSpy.Views;
45-
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
45+
46+
using TomsToolbox.Wpf;
4647

4748
class CompareViewModel : ObservableObject
4849
{
@@ -70,6 +71,7 @@ public CompareViewModel(TabPageModel tabPage, AssemblyTreeModel assemblyTreeMode
7071

7172
this.SwapAssembliesCommand = new DelegateCommand(OnSwapAssemblies);
7273
this.ExpandAllCommand = new DelegateCommand(OnExpandAll);
74+
this.CopyToClipboardAsJSONCommand = new DelegateCommand(OnCopyToClipboardAsJSON);
7375

7476
this.PropertyChanged += CompareViewModel_PropertyChanged;
7577
}
@@ -153,6 +155,7 @@ public bool ShowIdentical {
153155

154156
public ICommand SwapAssembliesCommand { get; set; }
155157
public ICommand ExpandAllCommand { get; set; }
158+
public ICommand CopyToClipboardAsJSONCommand { get; set; }
156159

157160
void OnSwapAssemblies()
158161
{
@@ -163,14 +166,85 @@ void OnSwapAssemblies()
163166
OnPropertyChanged(nameof(RightAssembly));
164167
}
165168

166-
public void OnExpandAll()
169+
void OnExpandAll()
167170
{
168171
foreach (var node in RootEntry.DescendantsAndSelf())
169172
{
170173
node.IsExpanded = true;
171174
}
172175
}
173176

177+
void OnCopyToClipboardAsJSON()
178+
{
179+
var options = new JsonSerializerOptions {
180+
WriteIndented = true
181+
};
182+
183+
var jsonEntry = ConvertToJson(this.root.Entry);
184+
var json = JsonSerializer.Serialize(jsonEntry, options);
185+
Clipboard.SetText(json);
186+
}
187+
188+
private object ConvertToJson(Entry entry)
189+
{
190+
List<Entry> changedTypes = new();
191+
List<Entry> addedTypes = new();
192+
List<Entry> removedTypes = new();
193+
194+
foreach (var item in TreeTraversal.PreOrder(entry, entry => entry.Children))
195+
{
196+
if (item.Entity is ITypeDefinition)
197+
{
198+
switch (item.RecursiveKind)
199+
{
200+
case DiffKind.Add:
201+
addedTypes.Add(item);
202+
break;
203+
case DiffKind.Remove:
204+
removedTypes.Add(item);
205+
break;
206+
case DiffKind.Update:
207+
changedTypes.Add(item);
208+
break;
209+
}
210+
}
211+
}
212+
var result = new {
213+
left = LeftAssembly.FileName.Replace('\\', '/'),
214+
right = RightAssembly.FileName.Replace('\\', '/'),
215+
changedTypes = changedTypes.SelectArray(t => new { typeName = ((ITypeDefinition)t.Entity).FullName, changes = GetChanges(t.Children) }),
216+
addedTypes = addedTypes.SelectArray(t => new { typeName = ((ITypeDefinition)t.Entity).FullName, changes = GetChanges(t.Children) }),
217+
removedTypes = removedTypes.SelectArray(t => new { typeName = ((ITypeDefinition)t.Entity).FullName, changes = GetChanges(t.Children) })
218+
};
219+
return result;
220+
221+
string? GetEntityText(ISymbol? symbol) => symbol switch {
222+
ITypeDefinition t => this.assemblyTreeModel.CurrentLanguage.TypeToString(t, includeNamespace: true),
223+
IMethod m => this.assemblyTreeModel.CurrentLanguage.MethodToString(m, false, false, false),
224+
IField f => this.assemblyTreeModel.CurrentLanguage.FieldToString(f, false, false, false),
225+
IProperty p => this.assemblyTreeModel.CurrentLanguage.PropertyToString(p, false, false, false),
226+
IEvent e => this.assemblyTreeModel.CurrentLanguage.EventToString(e, false, false, false),
227+
INamespace n => n.FullName,
228+
IModule m => m.FullAssemblyName,
229+
_ => null,
230+
};
231+
232+
IEnumerable<object> GetChanges(List<Entry>? entries)
233+
{
234+
if (entries == null)
235+
yield break;
236+
foreach (var item in entries)
237+
{
238+
if (item.Kind is not (DiffKind.Add or DiffKind.Remove or DiffKind.Update))
239+
continue;
240+
yield return new {
241+
name = GetEntityText(item.Entity),
242+
operation = item.Kind switch { DiffKind.Add => "added", DiffKind.Remove => "removed", DiffKind.Update => "changed" }
243+
};
244+
}
245+
}
246+
}
247+
174248
Entry MergeTrees(Entry a, Entry b)
175249
{
176250
var m = new Entry() {
@@ -546,6 +620,8 @@ class ComparisonEntryTreeNode : ILSpyTreeNode
546620
private readonly Entry entry;
547621
private readonly CompareViewModel compareViewModel;
548622

623+
internal Entry Entry => entry;
624+
549625
public ComparisonEntryTreeNode(Entry entry, CompareViewModel compareViewModel)
550626
{
551627
this.entry = entry;

0 commit comments

Comments
 (0)