Browse Source

Merge remote branch 'EdHarvey/Analysis'

pull/166/head
Daniel Grunwald 15 years ago
parent
commit
ad685e0e35
  1. 16
      ICSharpCode.Decompiler/Ast/TypesHierarchyHelpers.cs
  2. 4
      ILSpy/BamlDecompiler.cs
  3. 15
      ILSpy/ILSpy.csproj
  4. 13
      ILSpy/TreeNodes/Analyzer/AnalyzeContextMenuEntry.cs
  5. 9
      ILSpy/TreeNodes/Analyzer/AnalyzedEventAccessorsTreeNode.cs
  6. 18
      ILSpy/TreeNodes/Analyzer/AnalyzedEventOverridesTreeNode.cs
  7. 29
      ILSpy/TreeNodes/Analyzer/AnalyzedEventTreeNode.cs
  8. 26
      ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessTreeNode.cs
  9. 22
      ILSpy/TreeNodes/Analyzer/AnalyzedFieldTreeNode.cs
  10. 105
      ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceEventImplementedByTreeNode.cs
  11. 101
      ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceMethodImplementedByTreeNode.cs
  12. 105
      ILSpy/TreeNodes/Analyzer/AnalyzedInterfacePropertyImplementedByTreeNode.cs
  13. 29
      ILSpy/TreeNodes/Analyzer/AnalyzedMethodOverridesTreeNode.cs
  14. 29
      ILSpy/TreeNodes/Analyzer/AnalyzedMethodTreeNode.cs
  15. 21
      ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsedByTreeNode.cs
  16. 19
      ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsesTreeNode.cs
  17. 18
      ILSpy/TreeNodes/Analyzer/AnalyzedPropertyAccessorsTreeNode.cs
  18. 16
      ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs
  19. 35
      ILSpy/TreeNodes/Analyzer/AnalyzedPropertyTreeNode.cs
  20. 184
      ILSpy/TreeNodes/Analyzer/AnalyzedTypeExposedByTreeNode.cs
  21. 93
      ILSpy/TreeNodes/Analyzer/AnalyzedTypeExtensionMethodsTreeNode.cs
  22. 118
      ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs
  23. 72
      ILSpy/TreeNodes/Analyzer/AnalyzedTypeTreeNode.cs
  24. 8
      ILSpy/TreeNodes/Analyzer/AnalyzerTreeNode.cs
  25. 2
      ILSpy/TreeNodes/Analyzer/Helpers.cs
  26. 23
      ILSpy/TreeNodes/Analyzer/ScopedWhereUsedAnalyzer.cs
  27. 24
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  28. 26
      ILSpy/TreeNodes/ResourceEntryNode.cs
  29. 2
      ILSpy/TreeNodes/XamlResourceNode.cs

16
ICSharpCode.Decompiler/Ast/TypesHierarchyHelpers.cs

@ -182,6 +182,22 @@ namespace ICSharpCode.Decompiler.Ast @@ -182,6 +182,22 @@ namespace ICSharpCode.Decompiler.Ast
return true;
}
public static bool MatchInterfaceMethod(MethodDefinition candidate, MethodDefinition method, TypeReference interfaceContextType)
{
var candidateContext = CreateGenericContext(candidate.DeclaringType);
var gCandidate = candidateContext.ApplyTo(candidate);
if (interfaceContextType is GenericInstanceType) {
var methodContext = new GenericContext<TypeDefinition>(interfaceContextType.Resolve(), ((GenericInstanceType)interfaceContextType).GenericArguments);
var gMethod = methodContext.ApplyTo(method);
return MatchMethod(gCandidate, gMethod);
} else {
var methodContext = CreateGenericContext(interfaceContextType.Resolve());
var gMethod = candidateContext.ApplyTo(method);
return MatchMethod(gCandidate, gMethod);
}
}
private static bool MatchProperty(GenericContext<PropertyDefinition> candidate, GenericContext<PropertyDefinition> property)
{
var mCandidate = candidate.Item;

4
ILSpy/BamlDecompiler.cs

@ -415,8 +415,8 @@ namespace ICSharpCode.ILSpy.Baml @@ -415,8 +415,8 @@ namespace ICSharpCode.ILSpy.Baml
BamlDecompiler decompiler = CreateBamlDecompilerInAppDomain(ref bamlDecompilerAppDomain, asm.FileName);
MemoryStream bamlStream = new MemoryStream();
data.Position = 0;
data.CopyTo(bamlStream);
Data.Position = 0;
Data.CopyTo(bamlStream);
output.Write(decompiler.DecompileBaml(bamlStream, asm.FileName, new ConnectMethodDecompiler(asm), new AssemblyResolver(asm)));
return true;

15
ILSpy/ILSpy.csproj

@ -135,6 +135,13 @@ @@ -135,6 +135,13 @@
<Compile Include="TreeNodes\Analyzer\AnalyzedEventAccessorsTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedEventOverridesTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedEventTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedInterfacePropertyImplementedByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedInterfaceMethodImplementedByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedInterfaceEventImplementedByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeExposedByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeExtensionMethodsTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeInstantiationsTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\Helpers.cs" />
<Compile Include="TreeNodes\Analyzer\ScopedWhereUsedAnalyzer.cs" />
<Compile Include="TreeNodes\IMemberTreeNode.cs" />
@ -177,13 +184,13 @@ @@ -177,13 +184,13 @@
<Compile Include="TextView\ReferenceElementGenerator.cs" />
<Compile Include="TextView\AvalonEditTextOutput.cs" />
<Compile Include="TextView\UIElementGenerator.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedFieldAccessNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedFieldNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedFieldAccessTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedFieldTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodUsedByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodUsesNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodUsesTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzerTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzerMethodOverridesTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodOverridesTreeNode.cs" />
<Compile Include="TreeNodes\AssemblyListTreeNode.cs" />
<Compile Include="TreeNodes\AssemblyReferenceTreeNode.cs" />
<Compile Include="TreeNodes\AssemblyTreeNode.cs" />

13
ILSpy/TreeNodes/Analyzer/AnalyzeContextMenuEntry.cs

@ -24,7 +24,7 @@ using Mono.Cecil; @@ -24,7 +24,7 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
[ExportContextMenuEntry(Header = "Analyze", Icon = "images/Search.png")]
sealed class AnalyzeContextMenuEntry : IContextMenuEntry
internal sealed class AnalyzeContextMenuEntry : IContextMenuEntry
{
public bool IsVisible(SharpTreeNode[] selectedNodes)
{
@ -34,12 +34,14 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -34,12 +34,14 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public bool IsEnabled(SharpTreeNode[] selectedNodes)
{
foreach (IMemberTreeNode node in selectedNodes) {
if (!(node.Member is FieldDefinition
if (!(node.Member is TypeDefinition
|| node.Member is FieldDefinition
|| node.Member is MethodDefinition
|| Analyzer.AnalyzedPropertyTreeNode.CanShow(node.Member)
|| Analyzer.AnalyzedEventTreeNode.CanShow(node.Member)))
return false;
}
return true;
}
@ -48,14 +50,17 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -48,14 +50,17 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
// TODO: figure out when equivalent nodes are already present
// and focus those instead.
foreach (IMemberTreeNode node in selectedNodes) {
TypeDefinition type = node.Member as TypeDefinition;
if (type != null)
MainWindow.Instance.AddToAnalyzer(new AnalyzedTypeTreeNode(type));
FieldDefinition field = node.Member as FieldDefinition;
if (field != null)
MainWindow.Instance.AddToAnalyzer(new AnalyzedFieldNode(field));
MainWindow.Instance.AddToAnalyzer(new AnalyzedFieldTreeNode(field));
MethodDefinition method = node.Member as MethodDefinition;
if (method != null)
MainWindow.Instance.AddToAnalyzer(new AnalyzedMethodTreeNode(method));
var propertyAnalyzer = Analyzer.AnalyzedPropertyTreeNode.TryCreateAnalyzer(node.Member);
if(propertyAnalyzer != null)
if (propertyAnalyzer != null)
MainWindow.Instance.AddToAnalyzer(propertyAnalyzer);
var eventAnalyzer = Analyzer.AnalyzedEventTreeNode.TryCreateAnalyzer(node.Member);
if (eventAnalyzer != null)

9
ILSpy/TreeNodes/Analyzer/AnalyzedEventAccessorsTreeNode.cs

@ -21,15 +21,12 @@ using Mono.Cecil; @@ -21,15 +21,12 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
class AnalyzedEventAccessorsTreeNode : AnalyzerTreeNode
internal sealed class AnalyzedEventAccessorsTreeNode : AnalyzerTreeNode
{
EventDefinition analyzedEvent;
public AnalyzedEventAccessorsTreeNode(EventDefinition analyzedEvent)
{
if (analyzedEvent == null)
throw new ArgumentNullException("analyzedEvent");
this.analyzedEvent = analyzedEvent;
if (analyzedEvent.AddMethod != null)
this.Children.Add(new AnalyzedEventAccessorTreeNode(analyzedEvent.AddMethod, "add"));
@ -54,9 +51,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -54,9 +51,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
return !MainWindow.Instance.CurrentLanguage.ShowMember(property.AddMethod ?? property.RemoveMethod);
}
class AnalyzedEventAccessorTreeNode : AnalyzedMethodTreeNode
internal class AnalyzedEventAccessorTreeNode : AnalyzedMethodTreeNode
{
string name;
private string name;
public AnalyzedEventAccessorTreeNode(MethodDefinition analyzedMethod, string name)
: base(analyzedMethod)

18
ILSpy/TreeNodes/Analyzer/AnalyzedEventOverridesTreeNode.cs

@ -19,7 +19,6 @@ @@ -19,7 +19,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.NRefactory.Utils;
@ -28,10 +27,10 @@ using Mono.Cecil; @@ -28,10 +27,10 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
class AnalyzedEventOverridesTreeNode : AnalyzerTreeNode
internal sealed class AnalyzedEventOverridesTreeNode : AnalyzerTreeNode
{
readonly EventDefinition analyzedEvent;
readonly ThreadingSupport threading;
private readonly EventDefinition analyzedEvent;
private readonly ThreadingSupport threading;
public AnalyzedEventOverridesTreeNode(EventDefinition analyzedEvent)
{
@ -45,7 +44,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -45,7 +44,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public override object Text
{
get { return "Overriden By"; }
get { return "Overridden By"; }
}
public override object Icon
@ -67,19 +66,20 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -67,19 +66,20 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
private IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
{
return FindReferences(MainWindow.Instance.CurrentAssemblyList.GetAssemblies(), ct);
}
IEnumerable<SharpTreeNode> FindReferences(IEnumerable<LoadedAssembly> assemblies, CancellationToken ct)
private IEnumerable<SharpTreeNode> FindReferences(IEnumerable<LoadedAssembly> assemblies, CancellationToken ct)
{
assemblies = assemblies.Where(asm => asm.AssemblyDefinition != null);
// use parallelism only on the assembly level (avoid locks within Cecil)
return assemblies.AsParallel().WithCancellation(ct).SelectMany((LoadedAssembly asm) => FindReferences(asm, ct));
}
IEnumerable<SharpTreeNode> FindReferences(LoadedAssembly asm, CancellationToken ct)
private IEnumerable<SharpTreeNode> FindReferences(LoadedAssembly asm, CancellationToken ct)
{
string asmName = asm.AssemblyDefinition.Name.Name;
string name = analyzedEvent.Name;
@ -102,7 +102,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -102,7 +102,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
public static bool CanShowAnalyzer(EventDefinition property)
public static bool CanShow(EventDefinition property)
{
var accessor = property.AddMethod ?? property.RemoveMethod;
return accessor.IsVirtual && !accessor.IsFinal && !accessor.DeclaringType.IsInterface;

29
ILSpy/TreeNodes/Analyzer/AnalyzedEventTreeNode.cs

@ -18,32 +18,35 @@ @@ -18,32 +18,35 @@
using System;
using Mono.Cecil;
using ICSharpCode.Decompiler;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
class AnalyzedEventTreeNode : AnalyzerTreeNode
internal sealed class AnalyzedEventTreeNode : AnalyzerTreeNode
{
EventDefinition analyzedEvent;
string prefix;
private readonly EventDefinition analyzedEvent;
private readonly string prefix;
public AnalyzedEventTreeNode(EventDefinition analyzedEvent, string prefix = "")
{
if (analyzedEvent == null)
throw new ArgumentNullException("analyzedMethod");
throw new ArgumentNullException("analyzedEvent");
this.analyzedEvent = analyzedEvent;
this.prefix = prefix;
this.LazyLoading = true;
}
public override object Icon {
public override object Icon
{
get { return EventTreeNode.GetIcon(analyzedEvent); }
}
public override object Text {
get {
public override object Text
{
get
{
// TODO: This way of formatting is not suitable for events which explicitly implement interfaces.
return prefix + Language.TypeToString(analyzedEvent.DeclaringType, true) + "." + EventTreeNode.GetText(analyzedEvent, Language); }
return prefix + Language.TypeToString(analyzedEvent.DeclaringType, true) + "." + EventTreeNode.GetText(analyzedEvent, Language);
}
}
public override void ActivateItem(System.Windows.RoutedEventArgs e)
@ -54,10 +57,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -54,10 +57,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
protected override void LoadChildren()
{
if(AnalyzedEventAccessorsTreeNode.CanShow(analyzedEvent))
if (AnalyzedEventAccessorsTreeNode.CanShow(analyzedEvent))
this.Children.Add(new AnalyzedEventAccessorsTreeNode(analyzedEvent));
if (AnalyzedEventOverridesTreeNode.CanShowAnalyzer(analyzedEvent))
if (AnalyzedEventOverridesTreeNode.CanShow(analyzedEvent))
this.Children.Add(new AnalyzedEventOverridesTreeNode(analyzedEvent));
if (AnalyzedInterfaceEventImplementedByTreeNode.CanShow(analyzedEvent))
this.Children.Add(new AnalyzedInterfaceEventImplementedByTreeNode(analyzedEvent));
}
public static AnalyzerTreeNode TryCreateAnalyzer(MemberReference member)
@ -75,7 +80,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -75,7 +80,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
return false;
return AnalyzedEventAccessorsTreeNode.CanShow(property)
|| AnalyzedEventOverridesTreeNode.CanShowAnalyzer(property);
|| AnalyzedEventOverridesTreeNode.CanShow(property);
}
}
}

26
ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessNode.cs → ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessTreeNode.cs

@ -18,23 +18,20 @@ @@ -18,23 +18,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.TreeView;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
class AnalyzedFieldAccessNode : AnalyzerTreeNode
internal sealed class AnalyzedFieldAccessTreeNode : AnalyzerTreeNode
{
readonly bool showWrites; // true: show writes; false: show read access
readonly FieldDefinition analyzedField;
readonly ThreadingSupport threading;
private readonly bool showWrites; // true: show writes; false: show read access
private readonly FieldDefinition analyzedField;
private readonly ThreadingSupport threading;
public AnalyzedFieldAccessNode(FieldDefinition analyzedField, bool showWrites)
public AnalyzedFieldAccessTreeNode(FieldDefinition analyzedField, bool showWrites)
{
if (analyzedField == null)
throw new ArgumentNullException("analyzedField");
@ -69,13 +66,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -69,13 +66,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
private IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
{
var analyzer = new ScopedWhereUsedScopeAnalyzer<SharpTreeNode>(analyzedField, FindReferencesInType);
return analyzer.PerformAnalysis(ct);
}
IEnumerable<SharpTreeNode> FindReferencesInType(TypeDefinition type)
private IEnumerable<SharpTreeNode> FindReferencesInType(TypeDefinition type)
{
string name = analyzedField.Name;
string declTypeName = analyzedField.DeclaringType.FullName;
@ -87,18 +84,23 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -87,18 +84,23 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
foreach (Instruction instr in method.Body.Instructions) {
if (CanBeReference(instr.OpCode.Code)) {
FieldReference fr = instr.Operand as FieldReference;
if (fr != null && fr.Name == name && Helpers.IsReferencedBy(analyzedField.DeclaringType, fr.DeclaringType) && fr.Resolve() == analyzedField) {
if (fr != null && fr.Name == name &&
Helpers.IsReferencedBy(analyzedField.DeclaringType, fr.DeclaringType) &&
fr.Resolve() == analyzedField) {
found = true;
break;
}
}
}
method.Body = null;
if (found)
yield return new AnalyzedMethodTreeNode(method);
}
}
bool CanBeReference(Code code)
private bool CanBeReference(Code code)
{
switch (code) {
case Code.Ldfld:

22
ILSpy/TreeNodes/Analyzer/AnalyzedFieldNode.cs → ILSpy/TreeNodes/Analyzer/AnalyzedFieldTreeNode.cs

@ -21,11 +21,11 @@ using Mono.Cecil; @@ -21,11 +21,11 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
class AnalyzedFieldNode : AnalyzerTreeNode, IMemberTreeNode
internal class AnalyzedFieldTreeNode : AnalyzerTreeNode, IMemberTreeNode
{
FieldDefinition analyzedField;
private readonly FieldDefinition analyzedField;
public AnalyzedFieldNode(FieldDefinition analyzedField)
public AnalyzedFieldTreeNode(FieldDefinition analyzedField)
{
if (analyzedField == null)
throw new ArgumentNullException("analyzedField");
@ -33,12 +33,15 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -33,12 +33,15 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
this.LazyLoading = true;
}
public override object Icon {
public override object Icon
{
get { return FieldTreeNode.GetIcon(analyzedField); }
}
public override object Text {
get {
public override object Text
{
get
{
return Language.TypeToString(analyzedField.DeclaringType, true) +
"." + analyzedField.Name + " : " + this.Language.TypeToString(analyzedField.FieldType, false, analyzedField);
}
@ -52,12 +55,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -52,12 +55,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
protected override void LoadChildren()
{
this.Children.Add(new AnalyzedFieldAccessNode(analyzedField, false));
this.Children.Add(new AnalyzedFieldAccessTreeNode(analyzedField, false));
if (!analyzedField.IsLiteral)
this.Children.Add(new AnalyzedFieldAccessNode(analyzedField, true));
this.Children.Add(new AnalyzedFieldAccessTreeNode(analyzedField, true));
}
MemberReference IMemberTreeNode.Member {
MemberReference IMemberTreeNode.Member
{
get { return analyzedField; }
}
}

105
ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceEventImplementedByTreeNode.cs

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
internal sealed class AnalyzedInterfaceEventImplementedByTreeNode : AnalyzerTreeNode
{
private readonly EventDefinition analyzedEvent;
private readonly MethodDefinition analyzedMethod;
private readonly ThreadingSupport threading;
public AnalyzedInterfaceEventImplementedByTreeNode(EventDefinition analyzedEvent)
{
if (analyzedEvent == null)
throw new ArgumentNullException("analyzedEvent");
this.analyzedEvent = analyzedEvent;
this.analyzedMethod = this.analyzedEvent.AddMethod ?? this.analyzedEvent.RemoveMethod;
this.threading = new ThreadingSupport();
this.LazyLoading = true;
}
public override object Text
{
get { return "Implemented By"; }
}
public override object Icon
{
get { return Images.Search; }
}
protected override void LoadChildren()
{
threading.LoadChildren(this, FetchChildren);
}
protected override void OnCollapsing()
{
if (threading.IsRunning) {
this.LazyLoading = true;
threading.Cancel();
this.Children.Clear();
}
}
private IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
{
ScopedWhereUsedScopeAnalyzer<SharpTreeNode> analyzer;
analyzer = new ScopedWhereUsedScopeAnalyzer<SharpTreeNode>(analyzedMethod, FindReferencesInType);
return analyzer.PerformAnalysis(ct);
}
private IEnumerable<SharpTreeNode> FindReferencesInType(TypeDefinition type)
{
if (!type.HasInterfaces)
yield break;
TypeReference implementedInterfaceRef = type.Interfaces.FirstOrDefault(i => i.Resolve() == analyzedMethod.DeclaringType);
if (implementedInterfaceRef == null)
yield break;
foreach (EventDefinition ev in type.Events.Where(e => e.Name == analyzedEvent.Name)) {
MethodDefinition accessor = ev.AddMethod ?? ev.RemoveMethod;
if (TypesHierarchyHelpers.MatchInterfaceMethod(accessor, analyzedMethod, implementedInterfaceRef))
yield return new AnalyzedEventTreeNode(ev);
yield break;
}
foreach (EventDefinition ev in type.Events.Where(e => e.Name.EndsWith(analyzedEvent.Name))) {
MethodDefinition accessor = ev.AddMethod ?? ev.RemoveMethod;
if (accessor.HasOverrides && accessor.Overrides.Any(m => m.Resolve() == analyzedMethod)) {
yield return new AnalyzedEventTreeNode(ev);
}
}
}
public static bool CanShow(EventDefinition ev)
{
return ev.DeclaringType.IsInterface;
}
}
}

101
ILSpy/TreeNodes/Analyzer/AnalyzedInterfaceMethodImplementedByTreeNode.cs

@ -0,0 +1,101 @@ @@ -0,0 +1,101 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
internal sealed class AnalyzedInterfaceMethodImplementedByTreeNode : AnalyzerTreeNode
{
private readonly MethodDefinition analyzedMethod;
private readonly ThreadingSupport threading;
public AnalyzedInterfaceMethodImplementedByTreeNode(MethodDefinition analyzedMethod)
{
if (analyzedMethod == null)
throw new ArgumentNullException("analyzedMethod");
this.analyzedMethod = analyzedMethod;
this.threading = new ThreadingSupport();
this.LazyLoading = true;
}
public override object Text
{
get { return "Implemented By"; }
}
public override object Icon
{
get { return Images.Search; }
}
protected override void LoadChildren()
{
threading.LoadChildren(this, FetchChildren);
}
protected override void OnCollapsing()
{
if (threading.IsRunning) {
this.LazyLoading = true;
threading.Cancel();
this.Children.Clear();
}
}
private IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
{
ScopedWhereUsedScopeAnalyzer<SharpTreeNode> analyzer;
analyzer = new ScopedWhereUsedScopeAnalyzer<SharpTreeNode>(analyzedMethod, FindReferencesInType);
return analyzer.PerformAnalysis(ct);
}
private IEnumerable<SharpTreeNode> FindReferencesInType(TypeDefinition type)
{
if (!type.HasInterfaces)
yield break;
TypeReference implementedInterfaceRef = type.Interfaces.FirstOrDefault(i => i.Resolve() == analyzedMethod.DeclaringType);
if (implementedInterfaceRef == null)
yield break;
foreach (MethodDefinition method in type.Methods.Where(m => m.Name == analyzedMethod.Name)) {
if (TypesHierarchyHelpers.MatchInterfaceMethod(method, analyzedMethod, implementedInterfaceRef))
yield return new AnalyzedMethodTreeNode(method);
yield break;
}
foreach (MethodDefinition method in type.Methods) {
if (method.HasOverrides && method.Overrides.Any(m => m.Resolve() == analyzedMethod)) {
yield return new AnalyzedMethodTreeNode(method);
}
}
}
public static bool CanShow(MethodDefinition method)
{
return method.DeclaringType.IsInterface;
}
}
}

105
ILSpy/TreeNodes/Analyzer/AnalyzedInterfacePropertyImplementedByTreeNode.cs

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
internal sealed class AnalyzedInterfacePropertyImplementedByTreeNode : AnalyzerTreeNode
{
private readonly PropertyDefinition analyzedProperty;
private readonly MethodDefinition analyzedMethod;
private readonly ThreadingSupport threading;
public AnalyzedInterfacePropertyImplementedByTreeNode(PropertyDefinition analyzedProperty)
{
if (analyzedProperty == null)
throw new ArgumentNullException("analyzedProperty");
this.analyzedProperty = analyzedProperty;
this.analyzedMethod = this.analyzedProperty.GetMethod ?? this.analyzedProperty.SetMethod;
this.threading = new ThreadingSupport();
this.LazyLoading = true;
}
public override object Text
{
get { return "Implemented By"; }
}
public override object Icon
{
get { return Images.Search; }
}
protected override void LoadChildren()
{
threading.LoadChildren(this, FetchChildren);
}
protected override void OnCollapsing()
{
if (threading.IsRunning) {
this.LazyLoading = true;
threading.Cancel();
this.Children.Clear();
}
}
private IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
{
ScopedWhereUsedScopeAnalyzer<SharpTreeNode> analyzer;
analyzer = new ScopedWhereUsedScopeAnalyzer<SharpTreeNode>(analyzedMethod, FindReferencesInType);
return analyzer.PerformAnalysis(ct);
}
private IEnumerable<SharpTreeNode> FindReferencesInType(TypeDefinition type)
{
if (!type.HasInterfaces)
yield break;
TypeReference implementedInterfaceRef = type.Interfaces.FirstOrDefault(i => i.Resolve() == analyzedMethod.DeclaringType);
if (implementedInterfaceRef == null)
yield break;
foreach (PropertyDefinition property in type.Properties.Where(e => e.Name == analyzedProperty.Name)) {
MethodDefinition accessor = property.GetMethod ?? property.SetMethod;
if (TypesHierarchyHelpers.MatchInterfaceMethod(accessor, analyzedMethod, implementedInterfaceRef))
yield return new AnalyzedPropertyTreeNode(property);
yield break;
}
foreach (PropertyDefinition property in type.Properties.Where(e => e.Name.EndsWith(analyzedProperty.Name))) {
MethodDefinition accessor = property.GetMethod ?? property.SetMethod;
if (accessor.HasOverrides && accessor.Overrides.Any(m => m.Resolve() == analyzedMethod)) {
yield return new AnalyzedPropertyTreeNode(property);
}
}
}
public static bool CanShow(PropertyDefinition property)
{
return property.DeclaringType.IsInterface;
}
}
}

29
ILSpy/TreeNodes/Analyzer/AnalyzerMethodOverridesTreeNode.cs → ILSpy/TreeNodes/Analyzer/AnalyzedMethodOverridesTreeNode.cs

@ -32,12 +32,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -32,12 +32,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
/// <summary>
/// Searches for overrides of the analyzed method.
/// </summary>
class AnalyzerMethodOverridesTreeNode : AnalyzerTreeNode
internal sealed class AnalyzedMethodOverridesTreeNode : AnalyzerTreeNode
{
readonly MethodDefinition analyzedMethod;
readonly ThreadingSupport threading;
private readonly MethodDefinition analyzedMethod;
private readonly ThreadingSupport threading;
public AnalyzerMethodOverridesTreeNode(MethodDefinition analyzedMethod)
public AnalyzedMethodOverridesTreeNode(MethodDefinition analyzedMethod)
{
if (analyzedMethod == null)
throw new ArgumentNullException("analyzedMethod");
@ -64,33 +64,32 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -64,33 +64,32 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
protected override void OnCollapsing()
{
if (threading.IsRunning)
{
if (threading.IsRunning) {
this.LazyLoading = true;
threading.Cancel();
this.Children.Clear();
}
}
IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
private IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
{
return FindReferences(MainWindow.Instance.CurrentAssemblyList.GetAssemblies(), ct);
}
IEnumerable<SharpTreeNode> FindReferences(IEnumerable<LoadedAssembly> assemblies, CancellationToken ct)
private IEnumerable<SharpTreeNode> FindReferences(IEnumerable<LoadedAssembly> assemblies, CancellationToken ct)
{
assemblies = assemblies.Where(asm => asm.AssemblyDefinition != null);
// use parallelism only on the assembly level (avoid locks within Cecil)
return assemblies.AsParallel().WithCancellation(ct).SelectMany((LoadedAssembly asm) => FindReferences(asm, ct));
}
IEnumerable<SharpTreeNode> FindReferences(LoadedAssembly asm, CancellationToken ct)
private IEnumerable<SharpTreeNode> FindReferences(LoadedAssembly asm, CancellationToken ct)
{
string asmName = asm.AssemblyDefinition.Name.Name;
string name = analyzedMethod.Name;
string declTypeName = analyzedMethod.DeclaringType.FullName;
foreach (TypeDefinition type in TreeTraversal.PreOrder(asm.AssemblyDefinition.MainModule.Types, t => t.NestedTypes))
{
foreach (TypeDefinition type in TreeTraversal.PreOrder(asm.AssemblyDefinition.MainModule.Types, t => t.NestedTypes)) {
ct.ThrowIfCancellationRequested();
SharpTreeNode newNode = null;
try {
@ -109,14 +108,18 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -109,14 +108,18 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
catch (ReferenceResolvingException) {
// ignore this type definition. maybe add a notification about such cases.
}
if (newNode != null)
yield return newNode;
}
}
public static bool CanShowAnalyzer(MethodDefinition method)
public static bool CanShow(MethodDefinition method)
{
return method.IsVirtual && !method.IsFinal && !method.DeclaringType.IsSealed && !method.DeclaringType.IsInterface; // interfaces are temporarly disabled
return method.IsVirtual &&
!method.IsFinal &&
!method.DeclaringType.IsSealed &&
!method.DeclaringType.IsInterface; // interface methods are definitions not implementations - cannot be overridden
}
}
}

29
ILSpy/TreeNodes/Analyzer/AnalyzedMethodTreeNode.cs

@ -21,10 +21,10 @@ using Mono.Cecil; @@ -21,10 +21,10 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
class AnalyzedMethodTreeNode : AnalyzerTreeNode, IMemberTreeNode
internal class AnalyzedMethodTreeNode : AnalyzerTreeNode, IMemberTreeNode
{
MethodDefinition analyzedMethod;
string prefix;
private readonly MethodDefinition analyzedMethod;
private readonly string prefix;
public AnalyzedMethodTreeNode(MethodDefinition analyzedMethod, string prefix = "")
{
@ -35,13 +35,17 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -35,13 +35,17 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
this.LazyLoading = true;
}
public override object Icon {
public override object Icon
{
get { return MethodTreeNode.GetIcon(analyzedMethod); }
}
public override object Text {
get {
return prefix + Language.TypeToString(analyzedMethod.DeclaringType, true) + "." + MethodTreeNode.GetText(analyzedMethod, Language); }
public override object Text
{
get
{
return prefix + Language.TypeToString(analyzedMethod.DeclaringType, true) + "." + MethodTreeNode.GetText(analyzedMethod, Language);
}
}
public override void ActivateItem(System.Windows.RoutedEventArgs e)
@ -53,13 +57,16 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -53,13 +57,16 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
protected override void LoadChildren()
{
if (analyzedMethod.HasBody)
this.Children.Add(new AnalyzedMethodUsesNode(analyzedMethod));
this.Children.Add(new AnalyzedMethodUsesTreeNode(analyzedMethod));
this.Children.Add(new AnalyzedMethodUsedByTreeNode(analyzedMethod));
if (AnalyzerMethodOverridesTreeNode.CanShowAnalyzer(analyzedMethod))
this.Children.Add(new AnalyzerMethodOverridesTreeNode(analyzedMethod));
if (AnalyzedMethodOverridesTreeNode.CanShow(analyzedMethod))
this.Children.Add(new AnalyzedMethodOverridesTreeNode(analyzedMethod));
if (AnalyzedInterfaceMethodImplementedByTreeNode.CanShow(analyzedMethod))
this.Children.Add(new AnalyzedInterfaceMethodImplementedByTreeNode(analyzedMethod));
}
MemberReference IMemberTreeNode.Member {
MemberReference IMemberTreeNode.Member
{
get { return analyzedMethod; }
}
}

21
ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsedByTreeNode.cs

@ -18,20 +18,17 @@ @@ -18,20 +18,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.TreeView;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
class AnalyzedMethodUsedByTreeNode : AnalyzerTreeNode
internal sealed class AnalyzedMethodUsedByTreeNode : AnalyzerTreeNode
{
MethodDefinition analyzedMethod;
ThreadingSupport threading;
private readonly MethodDefinition analyzedMethod;
private readonly ThreadingSupport threading;
public AnalyzedMethodUsedByTreeNode(MethodDefinition analyzedMethod)
{
@ -67,7 +64,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -67,7 +64,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
private IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
{
ScopedWhereUsedScopeAnalyzer<SharpTreeNode> analyzer;
@ -75,7 +72,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -75,7 +72,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
return analyzer.PerformAnalysis(ct);
}
IEnumerable<SharpTreeNode> FindReferencesInType(TypeDefinition type)
private IEnumerable<SharpTreeNode> FindReferencesInType(TypeDefinition type)
{
string name = analyzedMethod.Name;
foreach (MethodDefinition method in type.Methods) {
@ -84,11 +81,17 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -84,11 +81,17 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
continue;
foreach (Instruction instr in method.Body.Instructions) {
MethodReference mr = instr.Operand as MethodReference;
if (mr != null && mr.Name == name && Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) && mr.Resolve() == analyzedMethod) {
if (mr != null &&
mr.Name == name &&
Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) &&
mr.Resolve() == analyzedMethod) {
found = true;
break;
}
}
method.Body = null;
if (found)
yield return new AnalyzedMethodTreeNode(method);
}

19
ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsesNode.cs → ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsesTreeNode.cs

@ -27,11 +27,11 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -27,11 +27,11 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
/// <summary>
/// Shows the methods that are used by this method.
/// </summary>
sealed class AnalyzedMethodUsesNode : AnalyzerTreeNode
internal sealed class AnalyzedMethodUsesTreeNode : AnalyzerTreeNode
{
MethodDefinition analyzedMethod;
private readonly MethodDefinition analyzedMethod;
public AnalyzedMethodUsesNode(MethodDefinition analyzedMethod)
public AnalyzedMethodUsesTreeNode(MethodDefinition analyzedMethod)
{
if (analyzedMethod == null)
throw new ArgumentNullException("analyzedMethod");
@ -40,25 +40,28 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -40,25 +40,28 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
this.LazyLoading = true;
}
public override object Text {
public override object Text
{
get { return "Uses"; }
}
public override object Icon {
public override object Icon
{
get { return Images.Search; }
}
protected override void LoadChildren()
{
foreach (var f in GetUsedFields().Distinct()) {
this.Children.Add(new AnalyzedFieldNode(f));
this.Children.Add(new AnalyzedFieldTreeNode(f));
}
foreach (var m in GetUsedMethods().Distinct()) {
this.Children.Add(new AnalyzedMethodTreeNode(m));
}
analyzedMethod.Body = null;
}
IEnumerable<MethodDefinition> GetUsedMethods()
private IEnumerable<MethodDefinition> GetUsedMethods()
{
foreach (Instruction instr in analyzedMethod.Body.Instructions) {
MethodReference mr = instr.Operand as MethodReference;
@ -70,7 +73,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -70,7 +73,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
IEnumerable<FieldDefinition> GetUsedFields()
private IEnumerable<FieldDefinition> GetUsedFields()
{
foreach (Instruction instr in analyzedMethod.Body.Instructions) {
FieldReference fr = instr.Operand as FieldReference;

18
ILSpy/TreeNodes/Analyzer/AnalyzedPropertyAccessorsTreeNode.cs

@ -21,15 +21,12 @@ using Mono.Cecil; @@ -21,15 +21,12 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
class AnalyzedPropertyAccessorsTreeNode : AnalyzerTreeNode
public sealed class AnalyzedPropertyAccessorsTreeNode : AnalyzerTreeNode
{
PropertyDefinition analyzedProperty;
public AnalyzedPropertyAccessorsTreeNode(PropertyDefinition analyzedProperty)
{
if (analyzedProperty == null)
throw new ArgumentNullException("analyzedProperty");
this.analyzedProperty = analyzedProperty;
if (analyzedProperty.GetMethod != null)
this.Children.Add(new AnalyzedPropertyAccessorTreeNode(analyzedProperty.GetMethod, "get"));
@ -39,11 +36,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -39,11 +36,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
this.Children.Add(new AnalyzedPropertyAccessorTreeNode(accessor, null));
}
public override object Icon {
public override object Icon
{
get { return Images.Search; }
}
public override object Text {
public override object Text
{
get { return "Accessors"; }
}
@ -52,9 +51,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -52,9 +51,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
return !MainWindow.Instance.CurrentLanguage.ShowMember(property.GetMethod ?? property.SetMethod);
}
class AnalyzedPropertyAccessorTreeNode : AnalyzedMethodTreeNode
private class AnalyzedPropertyAccessorTreeNode : AnalyzedMethodTreeNode
{
string name;
private readonly string name;
public AnalyzedPropertyAccessorTreeNode(MethodDefinition analyzedMethod, string name)
: base(analyzedMethod)
@ -62,7 +61,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -62,7 +61,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
this.name = name;
}
public override object Text {
public override object Text
{
get { return name ?? base.Text; }
}
}

16
ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs

@ -19,7 +19,6 @@ @@ -19,7 +19,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast;
@ -29,10 +28,10 @@ using Mono.Cecil; @@ -29,10 +28,10 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
class AnalyzedPropertyOverridesTreeNode : AnalyzerTreeNode
internal sealed class AnalyzedPropertyOverridesTreeNode : AnalyzerTreeNode
{
readonly PropertyDefinition analyzedProperty;
readonly ThreadingSupport threading;
private readonly PropertyDefinition analyzedProperty;
private readonly ThreadingSupport threading;
public AnalyzedPropertyOverridesTreeNode(PropertyDefinition analyzedProperty)
{
@ -68,19 +67,20 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -68,19 +67,20 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
private IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
{
return FindReferences(MainWindow.Instance.CurrentAssemblyList.GetAssemblies(), ct);
}
IEnumerable<SharpTreeNode> FindReferences(IEnumerable<LoadedAssembly> assemblies, CancellationToken ct)
private IEnumerable<SharpTreeNode> FindReferences(IEnumerable<LoadedAssembly> assemblies, CancellationToken ct)
{
assemblies = assemblies.Where(asm => asm.AssemblyDefinition != null);
// use parallelism only on the assembly level (avoid locks within Cecil)
return assemblies.AsParallel().WithCancellation(ct).SelectMany((LoadedAssembly asm) => FindReferences(asm, ct));
}
IEnumerable<SharpTreeNode> FindReferences(LoadedAssembly asm, CancellationToken ct)
private IEnumerable<SharpTreeNode> FindReferences(LoadedAssembly asm, CancellationToken ct)
{
string asmName = asm.AssemblyDefinition.Name.Name;
string name = analyzedProperty.Name;
@ -111,7 +111,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -111,7 +111,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
public static bool CanShowAnalyzer(PropertyDefinition property)
public static bool CanShow(PropertyDefinition property)
{
var accessor = property.GetMethod ?? property.SetMethod;
return accessor.IsVirtual && !accessor.IsFinal && !accessor.DeclaringType.IsInterface;

35
ILSpy/TreeNodes/Analyzer/AnalyzedPropertyTreeNode.cs

@ -17,35 +17,39 @@ @@ -17,35 +17,39 @@
// DEALINGS IN THE SOFTWARE.
using System;
using Mono.Cecil;
using ICSharpCode.Decompiler;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
class AnalyzedPropertyTreeNode : AnalyzerTreeNode
internal sealed class AnalyzedPropertyTreeNode : AnalyzerTreeNode
{
PropertyDefinition analyzedProperty;
bool isIndexer;
string prefix;
private readonly PropertyDefinition analyzedProperty;
private readonly bool isIndexer;
private readonly string prefix;
public AnalyzedPropertyTreeNode(PropertyDefinition analyzedProperty, string prefix = "")
{
if (analyzedProperty == null)
throw new ArgumentNullException("analyzedMethod");
throw new ArgumentNullException("analyzedProperty");
this.isIndexer = analyzedProperty.IsIndexer();
this.analyzedProperty = analyzedProperty;
this.prefix = prefix;
this.LazyLoading = true;
}
public override object Icon {
public override object Icon
{
get { return PropertyTreeNode.GetIcon(analyzedProperty, isIndexer); }
}
public override object Text {
get {
public override object Text
{
get
{
// TODO: This way of formatting is not suitable for properties which explicitly implement interfaces.
return prefix + Language.TypeToString(analyzedProperty.DeclaringType, true) + "." + PropertyTreeNode.GetText(analyzedProperty, Language, isIndexer); }
return prefix + Language.TypeToString(analyzedProperty.DeclaringType, true) + "." + PropertyTreeNode.GetText(analyzedProperty, Language, isIndexer);
}
}
public override void ActivateItem(System.Windows.RoutedEventArgs e)
@ -56,13 +60,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -56,13 +60,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
protected override void LoadChildren()
{
if(AnalyzedPropertyAccessorsTreeNode.CanShow(analyzedProperty))
if (AnalyzedPropertyAccessorsTreeNode.CanShow(analyzedProperty))
this.Children.Add(new AnalyzedPropertyAccessorsTreeNode(analyzedProperty));
if (AnalyzedPropertyOverridesTreeNode.CanShowAnalyzer(analyzedProperty))
if (AnalyzedPropertyOverridesTreeNode.CanShow(analyzedProperty))
this.Children.Add(new AnalyzedPropertyOverridesTreeNode(analyzedProperty));
//if (analyzedProperty.HasBody)
// this.Children.Add(new AnalyzedMethodUsesNode(analyzedProperty));
//this.Children.Add(new AnalyzedMethodUsedByTreeNode(analyzedProperty));
if (AnalyzedInterfacePropertyImplementedByTreeNode.CanShow(analyzedProperty))
this.Children.Add(new AnalyzedInterfacePropertyImplementedByTreeNode(analyzedProperty));
}
public static AnalyzerTreeNode TryCreateAnalyzer(MemberReference member)
@ -80,7 +83,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -80,7 +83,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
return false;
return AnalyzedPropertyAccessorsTreeNode.CanShow(property)
|| AnalyzedPropertyOverridesTreeNode.CanShowAnalyzer(property);
|| AnalyzedPropertyOverridesTreeNode.CanShow(property);
}
}
}

184
ILSpy/TreeNodes/Analyzer/AnalyzedTypeExposedByTreeNode.cs

@ -0,0 +1,184 @@ @@ -0,0 +1,184 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Threading;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
internal sealed class AnalyzedTypeExposedByTreeNode : AnalyzerTreeNode
{
private readonly TypeDefinition analyzedType;
private readonly ThreadingSupport threading;
public AnalyzedTypeExposedByTreeNode(TypeDefinition analyzedType)
{
if (analyzedType == null)
throw new ArgumentNullException("analyzedType");
this.analyzedType = analyzedType;
this.threading = new ThreadingSupport();
this.LazyLoading = true;
}
public override object Text
{
get { return "Exposed By"; }
}
public override object Icon
{
get { return Images.Search; }
}
protected override void LoadChildren()
{
threading.LoadChildren(this, FetchChildren);
}
protected override void OnCollapsing()
{
if (threading.IsRunning) {
this.LazyLoading = true;
threading.Cancel();
this.Children.Clear();
}
}
private IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
{
ScopedWhereUsedScopeAnalyzer<SharpTreeNode> analyzer;
analyzer = new ScopedWhereUsedScopeAnalyzer<SharpTreeNode>(analyzedType, FindReferencesInType);
return analyzer.PerformAnalysis(ct);
}
private IEnumerable<SharpTreeNode> FindReferencesInType(TypeDefinition type)
{
if (analyzedType.IsEnum && type == analyzedType)
yield break;
if (!this.Language.ShowMember(type))
yield break;
foreach (FieldDefinition field in type.Fields) {
if (TypeIsExposedBy(field))
yield return new AnalyzedFieldTreeNode(field);
}
foreach (PropertyDefinition property in type.Properties) {
if (TypeIsExposedBy(property))
yield return new AnalyzedPropertyTreeNode(property);
}
foreach (EventDefinition eventDef in type.Events) {
if (TypeIsExposedBy(eventDef))
yield return new AnalyzedEventTreeNode(eventDef);
}
foreach (MethodDefinition method in type.Methods) {
if (TypeIsExposedBy(method))
yield return new AnalyzedMethodTreeNode(method);
}
}
private bool TypeIsExposedBy(FieldDefinition field)
{
if (field.IsPrivate)
return false;
if (field.FieldType.Resolve() == analyzedType)
return true;
return false;
}
private bool TypeIsExposedBy(PropertyDefinition property)
{
if (IsPrivate(property))
return false;
if (property.PropertyType.Resolve() == analyzedType)
return true;
return false;
}
private bool TypeIsExposedBy(EventDefinition eventDef)
{
if (IsPrivate(eventDef))
return false;
if (eventDef.EventType.Resolve() == analyzedType)
return true;
return false;
}
private bool TypeIsExposedBy(MethodDefinition method)
{
// if the method has overrides, it is probably an explicit interface member
// and should be considered part of the public API even though it is marked private.
if (method.IsPrivate) {
if (!method.HasOverrides)
return false;
else if (!method.Overrides[0].DeclaringType.Resolve().IsInterface)
return false;
}
// exclude methods with 'semantics'. for example, property getters & setters.
// HACK: this is a potentially fragile implementation, as the MethodSemantics may be extended to other uses at a later date.
if (method.SemanticsAttributes != MethodSemanticsAttributes.None)
return false;
if (method.ReturnType.Resolve() == analyzedType)
return true;
if (method.HasParameters) {
foreach (var parameter in method.Parameters) {
if (parameter.ParameterType.Resolve() == analyzedType)
return true;
}
}
return false;
}
private static bool IsPrivate(PropertyDefinition property)
{
bool isGetterPublic = (property.GetMethod != null && !property.GetMethod.IsPrivate);
bool isSetterPublic = (property.SetMethod != null && !property.SetMethod.IsPrivate);
return !(isGetterPublic || isSetterPublic);
}
private static bool IsPrivate(EventDefinition eventDef)
{
bool isAdderPublic = (eventDef.AddMethod != null && !eventDef.AddMethod.IsPrivate);
bool isRemoverPublic = (eventDef.RemoveMethod != null && !eventDef.RemoveMethod.IsPrivate);
return !(isAdderPublic || isRemoverPublic);
}
public static bool CanShow(TypeDefinition type)
{
return true;
}
}
}

93
ILSpy/TreeNodes/Analyzer/AnalyzedTypeExtensionMethodsTreeNode.cs

@ -0,0 +1,93 @@ @@ -0,0 +1,93 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
internal class AnalyzedTypeExtensionMethodsTreeNode : AnalyzerTreeNode
{
private readonly TypeDefinition analyzedType;
private readonly ThreadingSupport threading;
public AnalyzedTypeExtensionMethodsTreeNode(TypeDefinition analyzedType)
{
if (analyzedType == null)
throw new ArgumentNullException("analyzedType");
this.analyzedType = analyzedType;
this.threading = new ThreadingSupport();
this.LazyLoading = true;
}
public override object Text
{
get { return "Extension Methods"; }
}
public override object Icon
{
get { return Images.Search; }
}
protected override void LoadChildren()
{
threading.LoadChildren(this, FetchChildren);
}
protected override void OnCollapsing()
{
if (threading.IsRunning) {
this.LazyLoading = true;
threading.Cancel();
this.Children.Clear();
}
}
private IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
{
ScopedWhereUsedScopeAnalyzer<SharpTreeNode> analyzer;
analyzer = new ScopedWhereUsedScopeAnalyzer<SharpTreeNode>(analyzedType, FindReferencesInType);
return analyzer.PerformAnalysis(ct);
}
private IEnumerable<SharpTreeNode> FindReferencesInType(TypeDefinition type)
{
foreach (MethodDefinition method in type.Methods) {
if (method.IsStatic && method.HasCustomAttributes) {
if (method.CustomAttributes.Any(ca => ca.AttributeType.FullName == "System.Runtime.CompilerServices.ExtensionAttribute")) {
if (method.HasParameters && method.Parameters[0].ParameterType.Resolve() == analyzedType) {
yield return new AnalyzedMethodTreeNode(method);
}
}
}
}
}
public static bool CanShow(TypeDefinition type)
{
return !(type.IsEnum);
}
}
}

118
ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs

@ -0,0 +1,118 @@ @@ -0,0 +1,118 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.TreeView;
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
internal sealed class AnalyzedTypeInstantiationsTreeNode : AnalyzerTreeNode
{
private readonly TypeDefinition analyzedType;
private readonly ThreadingSupport threading;
private readonly bool isSystemObject;
public AnalyzedTypeInstantiationsTreeNode(TypeDefinition analyzedType)
{
if (analyzedType == null)
throw new ArgumentNullException("analyzedType");
this.analyzedType = analyzedType;
this.threading = new ThreadingSupport();
this.LazyLoading = true;
this.isSystemObject = (analyzedType.FullName == "System.Object");
}
public override object Text
{
get { return "Instantiated By"; }
}
public override object Icon
{
get { return Images.Search; }
}
protected override void LoadChildren()
{
threading.LoadChildren(this, FetchChildren);
}
protected override void OnCollapsing()
{
if (threading.IsRunning) {
this.LazyLoading = true;
threading.Cancel();
this.Children.Clear();
}
}
private IEnumerable<SharpTreeNode> FetchChildren(CancellationToken ct)
{
ScopedWhereUsedScopeAnalyzer<SharpTreeNode> analyzer;
analyzer = new ScopedWhereUsedScopeAnalyzer<SharpTreeNode>(analyzedType, FindReferencesInType);
return analyzer.PerformAnalysis(ct);
}
private IEnumerable<SharpTreeNode> FindReferencesInType(TypeDefinition type)
{
foreach (MethodDefinition method in type.Methods) {
bool found = false;
if (!method.HasBody)
continue;
// ignore chained constructors
// (since object is the root of everything, we can short circuit the test in this case)
if (method.Name == ".ctor" &&
(isSystemObject || analyzedType == type || TypesHierarchyHelpers.IsBaseType(analyzedType, type, false)))
continue;
foreach (Instruction instr in method.Body.Instructions) {
MethodReference mr = instr.Operand as MethodReference;
if (mr != null && mr.Name == ".ctor") {
if (Helpers.IsReferencedBy(analyzedType, mr.DeclaringType)) {
found = true;
break;
}
}
}
method.Body = null;
if (found)
yield return new AnalyzedMethodTreeNode(method);
}
}
public static bool CanShow(TypeDefinition type)
{
if (type.IsClass && !type.IsEnum) {
return type.Methods.Where(m => m.Name == ".ctor").Any(m => !m.IsPrivate);
}
return false;
}
}
}

72
ILSpy/TreeNodes/Analyzer/AnalyzedTypeTreeNode.cs

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
internal class AnalyzedTypeTreeNode : AnalyzerTreeNode, IMemberTreeNode
{
private readonly TypeDefinition analyzedType;
public AnalyzedTypeTreeNode(TypeDefinition analyzedType)
{
if (analyzedType == null)
throw new ArgumentNullException("analyzedType");
this.analyzedType = analyzedType;
this.LazyLoading = true;
}
public override object Icon
{
get { return TypeTreeNode.GetIcon(analyzedType); }
}
public override object Text
{
get
{
return Language.TypeToString(analyzedType, true);
}
}
public override void ActivateItem(System.Windows.RoutedEventArgs e)
{
e.Handled = true;
MainWindow.Instance.JumpToReference(analyzedType);
}
protected override void LoadChildren()
{
if (AnalyzedTypeInstantiationsTreeNode.CanShow(analyzedType))
this.Children.Add(new AnalyzedTypeInstantiationsTreeNode(analyzedType));
if (AnalyzedTypeExposedByTreeNode.CanShow(analyzedType))
this.Children.Add(new AnalyzedTypeExposedByTreeNode(analyzedType));
if (AnalyzedTypeExtensionMethodsTreeNode.CanShow(analyzedType))
this.Children.Add(new AnalyzedTypeExtensionMethodsTreeNode(analyzedType));
}
MemberReference IMemberTreeNode.Member
{
get { return analyzedType; }
}
}
}

8
ILSpy/TreeNodes/Analyzer/AnalyzerTreeNode.cs

@ -24,11 +24,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -24,11 +24,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
public class AnalyzerTreeNode : SharpTreeNode
{
Language language;
private Language language;
public Language Language {
public Language Language
{
get { return language; }
set {
set
{
if (language != value) {
language = value;
foreach (var child in this.Children.OfType<AnalyzerTreeNode>())

2
ILSpy/TreeNodes/Analyzer/Helpers.cs

@ -24,7 +24,7 @@ using Mono.Cecil; @@ -24,7 +24,7 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
static class Helpers
internal static class Helpers
{
public static bool IsReferencedBy(TypeDefinition type, TypeReference typeRef)
{

23
ILSpy/TreeNodes/Analyzer/ScopedWhereUsedAnalyzer.cs

@ -20,9 +20,8 @@ using System; @@ -20,9 +20,8 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Mono.Cecil;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -38,7 +37,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -38,7 +37,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
private Accessibility typeAccessibility = Accessibility.Public;
private Func<TypeDefinition, IEnumerable<T>> typeAnalysisFunction;
private ScopedWhereUsedScopeAnalyzer(TypeDefinition type, Func<TypeDefinition, IEnumerable<T>> typeAnalysisFunction)
public ScopedWhereUsedScopeAnalyzer(TypeDefinition type, Func<TypeDefinition, IEnumerable<T>> typeAnalysisFunction)
{
this.typeScope = type;
this.assemblyScope = type.Module.Assembly;
@ -109,7 +108,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -109,7 +108,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
return FindReferencesInTypeScope(ct);
}
if (memberAccessibility == Accessibility.Internal ||
memberAccessibility == Accessibility.FamilyAndInternal ||
typeAccessibility == Accessibility.Internal ||
@ -137,7 +135,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -137,7 +135,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
private Accessibility GetNestedTypeAccessibility(TypeDefinition type)
private static Accessibility GetNestedTypeAccessibility(TypeDefinition type)
{
Accessibility result;
switch (type.Attributes & TypeAttributes.VisibilityMask) {
@ -178,22 +176,23 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -178,22 +176,23 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
Public
}
IEnumerable<T> FindReferencesInAssemblyAndFriends(CancellationToken ct)
private IEnumerable<T> FindReferencesInAssemblyAndFriends(CancellationToken ct)
{
var assemblies = GetAssemblyAndAnyFriends(assemblyScope, ct);
// use parallelism only on the assembly level (avoid locks within Cecil)
return assemblies.AsParallel().WithCancellation(ct).SelectMany((AssemblyDefinition a) => FindReferencesInAssembly(a, ct));
}
IEnumerable<T> FindReferencesGlobal(CancellationToken ct)
private IEnumerable<T> FindReferencesGlobal(CancellationToken ct)
{
var assemblies = GetReferencingAssemblies(assemblyScope, ct);
// use parallelism only on the assembly level (avoid locks within Cecil)
return assemblies.AsParallel().WithCancellation(ct).SelectMany((AssemblyDefinition asm) => FindReferencesInAssembly(asm, ct));
}
IEnumerable<T> FindReferencesInAssembly(AssemblyDefinition asm, CancellationToken ct)
private IEnumerable<T> FindReferencesInAssembly(AssemblyDefinition asm, CancellationToken ct)
{
foreach (TypeDefinition type in TreeTraversal.PreOrder(asm.MainModule.Types, t => t.NestedTypes)) {
ct.ThrowIfCancellationRequested();
@ -204,7 +203,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -204,7 +203,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
IEnumerable<T> FindReferencesInTypeScope(CancellationToken ct)
private IEnumerable<T> FindReferencesInTypeScope(CancellationToken ct)
{
foreach (TypeDefinition type in TreeTraversal.PreOrder(typeScope, t => t.NestedTypes)) {
ct.ThrowIfCancellationRequested();
@ -215,7 +214,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -215,7 +214,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
IEnumerable<AssemblyDefinition> GetReferencingAssemblies(AssemblyDefinition asm, CancellationToken ct)
private IEnumerable<AssemblyDefinition> GetReferencingAssemblies(AssemblyDefinition asm, CancellationToken ct)
{
yield return asm;
@ -237,7 +236,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -237,7 +236,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
IEnumerable<AssemblyDefinition> GetAssemblyAndAnyFriends(AssemblyDefinition asm, CancellationToken ct)
private IEnumerable<AssemblyDefinition> GetAssemblyAndAnyFriends(AssemblyDefinition asm, CancellationToken ct)
{
yield return asm;

24
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -41,7 +41,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -41,7 +41,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
public sealed class AssemblyTreeNode : ILSpyTreeNode
{
readonly LoadedAssembly assembly;
readonly List<TypeTreeNode> classes = new List<TypeTreeNode>();
readonly Dictionary<string, NamespaceTreeNode> namespaces = new Dictionary<string, NamespaceTreeNode>();
public AssemblyTreeNode(LoadedAssembly assembly)
@ -56,20 +55,25 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -56,20 +55,25 @@ namespace ICSharpCode.ILSpy.TreeNodes
this.LazyLoading = true;
}
public AssemblyList AssemblyList {
public AssemblyList AssemblyList
{
get { return assembly.AssemblyList; }
}
public LoadedAssembly LoadedAssembly {
public LoadedAssembly LoadedAssembly
{
get { return assembly; }
}
public override object Text {
public override object Text
{
get { return HighlightSearchMatch(assembly.ShortName); }
}
public override object Icon {
get {
public override object Icon
{
get
{
if (assembly.IsLoaded) {
return assembly.HasLoadError ? Images.AssemblyWarning : Images.Assembly;
} else {
@ -78,7 +82,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -78,7 +82,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
public override bool ShowExpander {
public override bool ShowExpander
{
get { return !assembly.HasLoadError; }
}
@ -90,7 +95,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -90,7 +95,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (assemblyTask.IsFaulted) {
RaisePropertyChanged("ShowExpander"); // cannot expand assemblies with load error
// observe the exception so that the Task's finalizer doesn't re-throw it
try { assemblyTask.Wait(); } catch (AggregateException) {}
try { assemblyTask.Wait(); }
catch (AggregateException) { }
} else {
RaisePropertyChanged("Text"); // shortname might have changed
}
@ -215,7 +221,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -215,7 +221,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
}
textView.SaveToDisk(language, new[]{this}, options, dlg.FileName);
textView.SaveToDisk(language, new[] { this }, options, dlg.FileName);
}
return true;
}

26
ILSpy/TreeNodes/ResourceEntryNode.cs

@ -37,17 +37,25 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -37,17 +37,25 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public class ResourceEntryNode : ILSpyTreeNode
{
protected readonly string key;
protected readonly Stream data;
private readonly string key;
private readonly Stream data;
public override object Text {
public override object Text
{
get { return key.ToString(); }
}
public override object Icon {
public override object Icon
{
get { return Images.Resource; }
}
protected Stream Data
{
get { return data; }
}
public ResourceEntryNode(string key, Stream data)
{
if (key == null)
@ -114,7 +122,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -114,7 +122,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
sealed class ImageResourceEntryNode : ResourceEntryNode
{
public ImageResourceEntryNode(string key, Stream data) : base(key, data)
public ImageResourceEntryNode(string key, Stream data)
: base(key, data)
{
}
@ -127,17 +136,18 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -127,17 +136,18 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
try {
AvalonEditTextOutput output = new AvalonEditTextOutput();
data.Position = 0;
Data.Position = 0;
BitmapImage image = new BitmapImage();
image.BeginInit();
image.StreamSource = data;
image.StreamSource = Data;
image.EndInit();
output.AddUIElement(() => new Image { Source = image });
output.WriteLine();
output.AddButton(Images.Save, "Save", delegate { Save(null); });
textView.Show(output, null);
return true;
} catch (Exception) {
}
catch (Exception) {
return false;
}
}

2
ILSpy/TreeNodes/XamlResourceNode.cs

@ -63,7 +63,7 @@ namespace ICSharpCode.ILSpy.Xaml @@ -63,7 +63,7 @@ namespace ICSharpCode.ILSpy.Xaml
try {
// cache read XAML because stream will be closed after first read
if (xaml == null) {
using (var reader = new StreamReader(data)) {
using (var reader = new StreamReader(Data)) {
xaml = reader.ReadToEnd();
}
}

Loading…
Cancel
Save