Browse Source

WIP

feature/api-diff
Siegfried Pammer 2 months ago
parent
commit
a640e4a712
  1. 20
      ILSpy/Commands/CompareContextMenuEntry.cs
  2. 108
      ILSpy/ViewModels/CompareViewModel.cs
  3. 9
      ILSpy/Views/CompareView.xaml

20
ILSpy/Commands/CompareContextMenuEntry.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System.Composition;
using System.Threading.Tasks;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Docking;
@ -37,12 +38,19 @@ namespace ICSharpCode.ILSpy @@ -37,12 +38,19 @@ namespace ICSharpCode.ILSpy
var tabPage = dockWorkspace.AddTabPage();
tabPage.Title = $"Compare {left.Text} - {right.Text}";
tabPage.SupportsLanguageSwitching = false;
tabPage.FrozenContent = true;
var compareView = new CompareView();
compareView.DataContext = new CompareViewModel(assemblyTreeModel, left, right);
tabPage.Content = compareView;
tabPage.ShowTextView(t => t.RunWithCancellation(token => Task.Run(DoCompare, token), $"Comparing {left.Text} - {right.Text}").Then(vm => {
tabPage.Title = $"Compare {left.Text} - {right.Text}";
tabPage.SupportsLanguageSwitching = false;
tabPage.FrozenContent = true;
var compareView = new CompareView();
compareView.DataContext = vm;
tabPage.Content = compareView;
}));
CompareViewModel DoCompare()
{
return new CompareViewModel(assemblyTreeModel, left, right);
}
}
public bool IsEnabled(TextViewContext context)

108
ILSpy/ViewModels/CompareViewModel.cs

@ -10,6 +10,8 @@ using ICSharpCode.ILSpyX; @@ -10,6 +10,8 @@ using ICSharpCode.ILSpyX;
using TomsToolbox.Wpf;
#nullable enable
namespace ICSharpCode.ILSpy.ViewModels
{
using System.Linq;
@ -142,7 +144,7 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -142,7 +144,7 @@ namespace ICSharpCode.ILSpy.ViewModels
Dictionary<TypeDefinitionHandle, Entry> typeEntries = new();
Dictionary<string, Entry> namespaceEntries = new(StringComparer.Ordinal);
Entry root = new Entry { Entity = null!, Signature = module.FullAssemblyName };
Entry root = new Entry { Entity = module, Signature = module.FullAssemblyName };
// typeEntries need a different signature: must include list of base types
@ -190,7 +192,7 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -190,7 +192,7 @@ namespace ICSharpCode.ILSpy.ViewModels
{
if (!namespaceEntries.TryGetValue(typeDef.Namespace, out var nsEntry))
{
namespaceEntries[typeDef.Namespace] = nsEntry = new Entry { Parent = root, Signature = typeDef.Namespace, Entity = null! };
namespaceEntries[typeDef.Namespace] = nsEntry = new Entry { Parent = root, Signature = typeDef.Namespace, Entity = ResolveNamespace(typeDef.Namespace, typeDef.ParentModule)! };
root.Children ??= new();
root.Children.Add(nsEntry);
}
@ -242,6 +244,27 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -242,6 +244,27 @@ namespace ICSharpCode.ILSpy.ViewModels
}
return (results, root);
INamespace? ResolveNamespace(string namespaceName, IModule module)
{
INamespace current = module.RootNamespace;
string[] parts = namespaceName.Split('.');
for (int i = 0; i < parts.Length; i++)
{
if (i == 0 && string.IsNullOrEmpty(parts[i]))
{
continue;
}
var next = current.GetChildNamespace(parts[i]);
if (next != null)
current = next;
else
return null;
}
return current;
}
}
List<(Entry? Left, Entry? Right)> CalculateDiff(List<Entry> left, List<Entry> right)
@ -279,7 +302,7 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -279,7 +302,7 @@ namespace ICSharpCode.ILSpy.ViewModels
results.Add((item, other));
if (other == null)
{
item.Kind = DiffKind.Remove;
SetKind(item, DiffKind.Remove);
}
}
}
@ -287,7 +310,7 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -287,7 +310,7 @@ namespace ICSharpCode.ILSpy.ViewModels
{
foreach (var item in items)
{
item.Kind = DiffKind.Remove;
SetKind(item, DiffKind.Remove);
results.Add((item, null));
}
}
@ -302,7 +325,7 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -302,7 +325,7 @@ namespace ICSharpCode.ILSpy.ViewModels
if (!leftEntries.Any(_ => EntryComparer.Instance.Equals(_, item)))
{
results.Add((null, item));
item.Kind = DiffKind.Add;
SetKind(item, DiffKind.Add);
}
}
}
@ -310,27 +333,40 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -310,27 +333,40 @@ namespace ICSharpCode.ILSpy.ViewModels
{
foreach (var item in items)
{
item.Kind = DiffKind.Add;
SetKind(item, DiffKind.Add);
results.Add((null, item));
}
}
}
return results;
static void SetKind(Entry item, DiffKind kind)
{
if (item.Children?.Count > 0)
{
foreach (var child in item.Children)
{
SetKind(child, kind);
}
}
else
{
item.Kind = kind;
}
}
}
}
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
public class Entry
{
private DiffKind kind = DiffKind.None;
private DiffKind? kind;
public DiffKind Kind {
public DiffKind RecursiveKind {
get {
if (Children == null || Children.Count == 0)
{
return kind;
}
if (kind != null)
return kind.Value;
int addCount = 0, removeCount = 0, updateCount = 0;
@ -358,15 +394,11 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -358,15 +394,11 @@ namespace ICSharpCode.ILSpy.ViewModels
return DiffKind.Update;
return DiffKind.None;
}
set {
if (Children == null || Children.Count == 0)
{
kind = value;
}
}
}
public DiffKind Kind { get; set; }
public required string Signature { get; init; }
public required IEntity Entity { get; init; }
public required ISymbol Entity { get; init; }
public Entry? Parent { get; set; }
public List<Entry>? Children { get; set; }
@ -421,7 +453,29 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -421,7 +453,29 @@ namespace ICSharpCode.ILSpy.ViewModels
}
}
public override object Text => entry.Signature;
public override object Text {
get {
switch (entry.Entity)
{
case ITypeDefinition t:
return this.Language.TypeToString(t, includeNamespace: false) + GetSuffixString(t.MetadataToken);
case IMethod m:
return this.Language.MethodToString(m, false, false, false) + GetSuffixString(m.MetadataToken);
case IField f:
return this.Language.FieldToString(f, false, false, false) + GetSuffixString(f.MetadataToken);
case IProperty p:
return this.Language.PropertyToString(p, false, false, false) + GetSuffixString(p.MetadataToken);
case IEvent e:
return this.Language.EventToString(e, false, false, false) + GetSuffixString(e.MetadataToken);
case INamespace n:
return n.FullName;
case IModule m:
return m.FullAssemblyName;
default:
return entry.Signature;
}
}
}
public override object Icon {
get {
@ -437,16 +491,28 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -437,16 +491,28 @@ namespace ICSharpCode.ILSpy.ViewModels
return PropertyTreeNode.GetIcon(p);
case IEvent e:
return EventTreeNode.GetIcon(e);
case INamespace n:
return Images.Namespace;
case IModule m:
return Images.Assembly;
default:
throw new NotSupportedException();
}
}
}
public DiffKind Difference => entry.Kind;
public DiffKind RecursiveKind => entry.RecursiveKind;
public DiffKind Kind => entry.Kind;
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
}
//public override FilterResult Filter(LanguageSettings settings)
//{
// return RecursiveKind != DiffKind.None ? FilterResult.Match : FilterResult.Hidden;
//}
}
}

9
ILSpy/Views/CompareView.xaml

@ -30,15 +30,6 @@ @@ -30,15 +30,6 @@
</Border>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Difference}" Value="Update">
<Setter Property="Background" Value="LightBlue" />
</DataTrigger>
<DataTrigger Binding="{Binding Difference}" Value="Add">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
<DataTrigger Binding="{Binding Difference}" Value="Remove">
<Setter Property="Background" Value="LightPink" />
</DataTrigger>
<DataTrigger Binding="{Binding IsPublicAPI}" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</DataTrigger>

Loading…
Cancel
Save