Browse Source

Add ExportAnalyzerAttribute

pull/1213/head
Siegfried Pammer 7 years ago
parent
commit
2839724e8d
  1. 6
      ILSpy/Analyzers/AnalyzerSearchTreeNode.cs
  2. 4
      ILSpy/Analyzers/Builtin/EventImplementsInterfaceAnalyzer.cs
  3. 4
      ILSpy/Analyzers/Builtin/EventOverriddenByAnalyzer.cs
  4. 6
      ILSpy/Analyzers/Builtin/FieldAccessAnalyzer.cs
  5. 4
      ILSpy/Analyzers/Builtin/MethodImplementsInterfaceAnalyzer.cs
  6. 4
      ILSpy/Analyzers/Builtin/MethodOverriddenByAnalyzer.cs
  7. 4
      ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs
  8. 6
      ILSpy/Analyzers/Builtin/MethodUsesAnalyzer.cs
  9. 4
      ILSpy/Analyzers/Builtin/MethodVirtualUsedByAnalyzer.cs
  10. 4
      ILSpy/Analyzers/Builtin/PropertyImplementsInterfaceAnalyzer.cs
  11. 4
      ILSpy/Analyzers/Builtin/PropertyOverriddenByAnalyzer.cs
  12. 4
      ILSpy/Analyzers/Builtin/TypeExposedByAnalyzer.cs
  13. 4
      ILSpy/Analyzers/Builtin/TypeExtensionMethodsAnalyzer.cs
  14. 4
      ILSpy/Analyzers/Builtin/TypeInstantiatedByAnalyzer.cs
  15. 4
      ILSpy/Analyzers/Builtin/TypeUsedByAnalyzer.cs
  16. 24
      ILSpy/Analyzers/IAnalyzer.cs
  17. 5
      ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs
  18. 6
      ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs
  19. 6
      ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs
  20. 6
      ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs
  21. 6
      ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs

6
ILSpy/Analyzers/AnalyzerSearchTreeNode.cs

@ -31,15 +31,17 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -31,15 +31,17 @@ namespace ICSharpCode.ILSpy.Analyzers
private readonly ThreadingSupport threading = new ThreadingSupport();
readonly ISymbol symbol;
readonly IAnalyzer analyzer;
readonly string analyzerHeader;
public AnalyzerSearchTreeNode(ISymbol symbol, IAnalyzer analyzer)
public AnalyzerSearchTreeNode(ISymbol symbol, IAnalyzer analyzer, string analyzerHeader)
{
this.symbol = symbol;
this.analyzer = analyzer ?? throw new ArgumentNullException(nameof(analyzer));
this.LazyLoading = true;
this.analyzerHeader = analyzerHeader;
}
public override object Text => analyzer.Text + (Children.Count > 0 ? " (" + Children.Count + ")" : "");
public override object Text => analyzerHeader + (Children.Count > 0 ? " (" + Children.Count + ")" : "");
public override object Icon => Images.Search;

4
ILSpy/Analyzers/Builtin/EventImplementsInterfaceAnalyzer.cs

@ -27,11 +27,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -27,11 +27,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Shows events that implement an interface event.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Implemented By", Order = 10)]
class EventImplementsInterfaceAnalyzer : IAnalyzer
{
public string Text => "Implemented By";
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)
{
Debug.Assert(analyzedSymbol is IEvent);

4
ILSpy/Analyzers/Builtin/EventOverriddenByAnalyzer.cs

@ -27,11 +27,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -27,11 +27,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Shows events that override an event.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Overridden By", Order = 20)]
class EventOverriddenByAnalyzer : IAnalyzer
{
public string Text => "Overridden By";
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)
{
Debug.Assert(analyzedSymbol is IEvent);

6
ILSpy/Analyzers/Builtin/FieldAccessAnalyzer.cs

@ -37,7 +37,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -37,7 +37,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Finds methods where this field is read.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Assigned By", Order = 20)]
class AssignedByFieldAccessAnalyzer : FieldAccessAnalyzer
{
public AssignedByFieldAccessAnalyzer() : base(true) { }
@ -46,7 +46,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -46,7 +46,7 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Finds methods where this field is written.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Read By", Order = 10)]
class ReadByFieldAccessAnalyzer : FieldAccessAnalyzer
{
public ReadByFieldAccessAnalyzer() : base(false) { }
@ -61,8 +61,6 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -61,8 +61,6 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
readonly bool showWrites; // true: show writes; false: show read access
public string Text => showWrites ? "Assigned By" : "Read By";
public FieldAccessAnalyzer(bool showWrites)
{
this.showWrites = showWrites;

4
ILSpy/Analyzers/Builtin/MethodImplementsInterfaceAnalyzer.cs

@ -30,11 +30,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -30,11 +30,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Shows methods that implement an interface method.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Implemented By", Order = 40)]
class MethodImplementsInterfaceAnalyzer : IAnalyzer
{
public string Text => "Implemented By";
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)
{
Debug.Assert(analyzedSymbol is IMethod);

4
ILSpy/Analyzers/Builtin/MethodOverriddenByAnalyzer.cs

@ -27,13 +27,11 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -27,13 +27,11 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Shows methods that override a method.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Overridden By", Order = 30)]
class MethodOverriddenByAnalyzer : IAnalyzer
{
const GetMemberOptions Options = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;
public string Text => "Overridden By";
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)
{
Debug.Assert(analyzedSymbol is IMethod);

4
ILSpy/Analyzers/Builtin/MethodUsedByAnalyzer.cs

@ -31,13 +31,11 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -31,13 +31,11 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Shows entities that are used by a method.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Used By", Order = 20)]
class MethodUsedByAnalyzer : IAnalyzer
{
const GetMemberOptions Options = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;
public string Text => "Used By";
public bool Show(ISymbol symbol) => symbol is IMethod method && !method.IsVirtual;
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)

6
ILSpy/Analyzers/Builtin/MethodUsesAnalyzer.cs

@ -33,12 +33,10 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -33,12 +33,10 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Shows entities that are used by a method.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Uses", Order = 10)]
class MethodUsesAnalyzer : IAnalyzer
{
public string Text => "Uses";
public bool Show(ISymbol symbol) => symbol is IMethod method && !method.IsVirtual;
public bool Show(ISymbol symbol) => symbol is IMethod method && method.HasBody;
public IEnumerable<ISymbol> Analyze(ISymbol symbol, AnalyzerContext context)
{

4
ILSpy/Analyzers/Builtin/MethodVirtualUsedByAnalyzer.cs

@ -31,13 +31,11 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -31,13 +31,11 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Shows entities that are used by a method.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Used By", Order = 20)]
class MethodVirtualUsedByAnalyzer : IAnalyzer
{
const GetMemberOptions Options = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;
public string Text => "Used By";
public bool Show(ISymbol symbol) => symbol is IMethod method && method.IsVirtual;
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)

4
ILSpy/Analyzers/Builtin/PropertyImplementsInterfaceAnalyzer.cs

@ -27,11 +27,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -27,11 +27,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Shows properties that implement an interface property.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Implemented By", Order = 10)]
class PropertyImplementsInterfaceAnalyzer : IAnalyzer
{
public string Text => "Implemented By";
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)
{
Debug.Assert(analyzedSymbol is IProperty);

4
ILSpy/Analyzers/Builtin/PropertyOverriddenByAnalyzer.cs

@ -30,11 +30,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -30,11 +30,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Shows properties that override a property.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Overridden By", Order = 20)]
class PropertyOverriddenByAnalyzer : IAnalyzer
{
public string Text => "Overridden By";
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)
{
Debug.Assert(analyzedSymbol is IProperty);

4
ILSpy/Analyzers/Builtin/TypeExposedByAnalyzer.cs

@ -30,11 +30,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -30,11 +30,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Finds all entities that expose a type.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Exposed By", Order = 40)]
class TypeExposedByAnalyzer : IAnalyzer
{
public string Text => "Exposed By";
public bool Show(ISymbol entity) => entity is ITypeDefinition;
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)

4
ILSpy/Analyzers/Builtin/TypeExtensionMethodsAnalyzer.cs

@ -8,11 +8,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -8,11 +8,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Finds all extension methods defined for a type.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Extension Methods", Order = 50)]
class TypeExtensionMethodsAnalyzer : IAnalyzer
{
public string Text => "Extension Methods";
public bool Show(ISymbol symbol) => symbol is ITypeDefinition entity && !entity.IsStatic;
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)

4
ILSpy/Analyzers/Builtin/TypeInstantiatedByAnalyzer.cs

@ -34,13 +34,11 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -34,13 +34,11 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Shows methods that instantiate a type.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Instantiated By", Order = 20)]
class TypeInstantiatedByAnalyzer : IAnalyzer
{
const GetMemberOptions Options = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;
public string Text => "Instantiated By";
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)
{
Debug.Assert(analyzedSymbol is ITypeDefinition);

4
ILSpy/Analyzers/Builtin/TypeUsedByAnalyzer.cs

@ -32,11 +32,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin @@ -32,11 +32,9 @@ namespace ICSharpCode.ILSpy.Analyzers.Builtin
/// <summary>
/// Shows entities that use a type.
/// </summary>
[Export(typeof(IAnalyzer))]
[ExportAnalyzer(Header = "Used By", Order = 30)]
class TypeUsedByAnalyzer : IAnalyzer
{
public string Text => "Used By";
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)
{
Debug.Assert(analyzedSymbol is ITypeDefinition);

24
ILSpy/Analyzers/IAnalyzer.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Reflection.Metadata;
using System.Threading;
@ -33,11 +34,6 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -33,11 +34,6 @@ namespace ICSharpCode.ILSpy.Analyzers
/// </summary>
public interface IAnalyzer
{
/// <summary>
/// The caption used in the analyzer tree view.
/// </summary>
string Text { get; }
/// <summary>
/// Returns true, if the analyzer should be shown for a symbol, otherwise false.
/// </summary>
@ -80,4 +76,22 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -80,4 +76,22 @@ namespace ICSharpCode.ILSpy.Analyzers
return new AnalyzerScope(AssemblyList, entity);
}
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ExportAnalyzerAttribute : ExportAttribute, IAnalyzerMetadata
{
public ExportAnalyzerAttribute() : base("Analyzer", typeof(IAnalyzer))
{ }
public string Header { get; set; }
public int Order { get; set; }
}
public interface IAnalyzerMetadata
{
string Header { get; }
int Order { get; }
}
}

5
ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs

@ -54,10 +54,11 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -54,10 +54,11 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
//foreach (var accessor in analyzedEvent.OtherMethods)
// this.Children.Add(new AnalyzedAccessorTreeNode(accessor, null));
foreach (var lazy in App.ExportProvider.GetExports<IAnalyzer>()) {
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order)) {
var analyzer = lazy.Value;
if (analyzer.Show(analyzedEvent)) {
this.Children.Add(new AnalyzerSearchTreeNode(analyzedEvent, analyzer));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedEvent, analyzer, lazy.Metadata.Header));
}
}
}

6
ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
@ -38,10 +39,11 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -38,10 +39,11 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
protected override void LoadChildren()
{
foreach (var lazy in App.ExportProvider.GetExports<IAnalyzer>()) {
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order)) {
var analyzer = lazy.Value;
if (analyzer.Show(analyzedField)) {
this.Children.Add(new AnalyzerSearchTreeNode(analyzedField, analyzer));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedField, analyzer, lazy.Metadata.Header));
}
}
}

6
ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
@ -40,10 +41,11 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -40,10 +41,11 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
protected override void LoadChildren()
{
foreach (var lazy in App.ExportProvider.GetExports<IAnalyzer>()) {
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order)) {
var analyzer = lazy.Value;
if (analyzer.Show(analyzedMethod)) {
this.Children.Add(new AnalyzerSearchTreeNode(analyzedMethod, analyzer));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedMethod, analyzer, lazy.Metadata.Header));
}
}
}

6
ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
@ -48,10 +49,11 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -48,10 +49,11 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
//foreach (var accessor in analyzedProperty.OtherMethods)
// this.Children.Add(new AnalyzedPropertyAccessorTreeNode(accessor, null));
foreach (var lazy in App.ExportProvider.GetExports<IAnalyzer>()) {
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order)) {
var analyzer = lazy.Value;
if (analyzer.Show(analyzedProperty)) {
this.Children.Add(new AnalyzerSearchTreeNode(analyzedProperty, analyzer));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedProperty, analyzer, lazy.Metadata.Header));
}
}
}

6
ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
@ -38,10 +39,11 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -38,10 +39,11 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
protected override void LoadChildren()
{
foreach (var lazy in App.ExportProvider.GetExports<IAnalyzer>()) {
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order)) {
var analyzer = lazy.Value;
if (analyzer.Show(analyzedType)) {
this.Children.Add(new AnalyzerSearchTreeNode(analyzedType, analyzer));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedType, analyzer, lazy.Metadata.Header));
}
}
}

Loading…
Cancel
Save