Browse Source

Reimplement AttributeAppliedToAnalyzer, add AnalyzedModuleTreeNode

pull/1213/head
Siegfried Pammer 7 years ago
parent
commit
2fc12ed507
  1. 4
      ILSpy/Analyzers/AnalyzerSearchTreeNode.cs
  2. 79
      ILSpy/Analyzers/Builtin/AttributeAppliedToAnalyzer.cs
  3. 53
      ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs
  4. 2
      ILSpy/ILSpy.csproj

4
ILSpy/Analyzers/AnalyzerSearchTreeNode.cs

@ -75,6 +75,10 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -75,6 +75,10 @@ namespace ICSharpCode.ILSpy.Analyzers
}
switch (symbol) {
case IModule module:
return new AnalyzedModuleTreeNode(module) {
Language = this.Language
};
case ITypeDefinition td:
return new AnalyzedTypeTreeNode(td) {
Language = this.Language

79
ILSpy/Analyzers/Builtin/AttributeAppliedToAnalyzer.cs

@ -0,0 +1,79 @@ @@ -0,0 +1,79 @@
// Copyright (c) 2018 Siegfried Pammer
//
// 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.ComponentModel.Composition;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy.Analyzers.Builtin
{
[ExportAnalyzer(Header = "Applied To", Order = 10)]
class AttributeAppliedToAnalyzer : IAnalyzer
{
public IEnumerable<ISymbol> Analyze(ISymbol analyzedSymbol, AnalyzerContext context)
{
if (!(analyzedSymbol is IEntity attributeEntity))
yield break;
var scope = context.GetScopeOf(attributeEntity);
var genericContext = new GenericContext(); // type arguments do not matter for this analyzer.
foreach (var module in scope.GetModulesInScope(context.CancellationToken)) {
var ts = new DecompilerTypeSystem(module, module.GetAssemblyResolver());
foreach (var h in module.Metadata.CustomAttributes) {
var customAttribute = module.Metadata.GetCustomAttribute(h);
var attributeCtor = ts.MainModule.ResolveMethod(customAttribute.Constructor, genericContext);
if (attributeCtor.DeclaringTypeDefinition != null
&& attributeCtor.ParentModule.PEFile == attributeEntity.ParentModule.PEFile
&& attributeCtor.DeclaringTypeDefinition.MetadataToken == attributeEntity.MetadataToken) {
var parent = GetParentEntity(ts, customAttribute);
if (parent != null)
yield return parent;
}
}
}
}
ISymbol GetParentEntity(DecompilerTypeSystem ts, CustomAttribute customAttribute)
{
switch (customAttribute.Parent.Kind) {
case HandleKind.MethodDefinition:
case HandleKind.FieldDefinition:
case HandleKind.PropertyDefinition:
case HandleKind.EventDefinition:
case HandleKind.TypeDefinition:
return ts.MainModule.ResolveEntity(customAttribute.Parent);
case HandleKind.AssemblyDefinition:
case HandleKind.ModuleDefinition:
return ts.MainModule;
default:
return null;
}
}
public bool Show(ISymbol symbol)
{
return symbol is ITypeDefinition type && type.GetNonInterfaceBaseTypes()
.Any(t => t.IsKnownType(KnownTypeCode.Attribute));
}
}
}

53
ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs

@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
// 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.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
internal class AnalyzedModuleTreeNode : AnalyzerEntityTreeNode
{
readonly IModule analyzedModule;
public AnalyzedModuleTreeNode(IModule analyzedModule)
{
this.analyzedModule = analyzedModule ?? throw new ArgumentNullException(nameof(analyzedModule));
this.LazyLoading = true;
}
public override object Icon => Images.Assembly;
public override object Text => analyzedModule.AssemblyName;
protected override void LoadChildren()
{
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(analyzedModule)) {
this.Children.Add(new AnalyzerSearchTreeNode(analyzedModule, analyzer, lazy.Metadata.Header));
}
}
}
public override IEntity Member => null;
}
}

2
ILSpy/ILSpy.csproj

@ -67,6 +67,7 @@ @@ -67,6 +67,7 @@
<ItemGroup>
<Compile Include="AboutPage.cs" />
<Compile Include="Analyzers\AnalyzerScope.cs" />
<Compile Include="Analyzers\Builtin\AttributeAppliedToAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\EventImplementsInterfaceAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\EventOverriddenByAnalyzer.cs" />
<Compile Include="Analyzers\Builtin\MethodImplementsInterfaceAnalyzer.cs" />
@ -87,6 +88,7 @@ @@ -87,6 +88,7 @@
<Compile Include="Analyzers\TreeNodes\AnalyzedEventTreeNode.cs" />
<Compile Include="Analyzers\TreeNodes\AnalyzedMethodTreeNode.cs" />
<Compile Include="Analyzers\TreeNodes\AnalyzedPropertyTreeNode.cs" />
<Compile Include="Analyzers\TreeNodes\AnalyzedModuleTreeNode.cs" />
<Compile Include="Analyzers\TreeNodes\AnalyzedTypeTreeNode.cs" />
<Compile Include="App.xaml.cs">
<SubType>Code</SubType>

Loading…
Cancel
Save