Browse Source

Commit of non-compiling WIP

pull/1198/head
Siegfried Pammer 8 years ago
parent
commit
02b7dc98be
  1. 16
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  2. 1
      ICSharpCode.Decompiler/CSharp/Transforms/CustomPatterns.cs
  3. 1
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs
  4. 144
      ICSharpCode.Decompiler/CecilExtensions.cs
  5. 1
      ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs
  6. 1109
      ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  7. 92
      ICSharpCode.Decompiler/Disassembler/OpCodeInfo.cs
  8. 1302
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  9. 6
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  10. 3
      ICSharpCode.Decompiler/IL/ILOpCodes.cs
  11. 3
      ICSharpCode.Decompiler/IL/ILOpCodes.tt
  12. 4
      ICSharpCode.Decompiler/IL/ILReader.cs
  13. 87
      ICSharpCode.Decompiler/TypeSystem/AssemblyLoader.cs
  14. 585
      ICSharpCode.Decompiler/TypeSystem/CecilLoader.cs
  15. 4
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  16. 6
      ICSharpCode.Decompiler/TypeSystem/IAssembly.cs
  17. 11
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs
  18. 214
      ICSharpCode.Decompiler/TypeSystem/Implementation/TypeSpecification.cs
  19. 13
      ICSharpCode.Decompiler/TypeSystem/KnownTypeReference.cs
  20. 199
      ICSharpCode.Decompiler/TypeSystem/MetadataExtensions.cs
  21. 65
      ILSpy/Cecil/CecilExtensions.cs
  22. 2
      ILSpy/Cecil/TypesHierarchyHelpers.cs
  23. 2
      ILSpy/ILSpy.csproj
  24. 2
      ILSpy/Languages/CSharpILMixedLanguage.cs
  25. 2
      ILSpy/Languages/ILAstLanguage.cs
  26. 132
      ILSpy/Languages/ILLanguage.cs
  27. 5
      ILSpy/MainWindow.xaml.cs
  28. 11
      ILSpy/TextView/DecompilerTextView.cs

16
ICSharpCode.Decompiler.Tests/Helpers/Tester.cs

@ -22,6 +22,8 @@ using System.Collections.Generic; @@ -22,6 +22,8 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
@ -108,19 +110,19 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -108,19 +110,19 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
public static string Disassemble(string sourceFileName, string outputFile, AssemblerOptions asmOptions)
{
if (asmOptions.HasFlag(AssemblerOptions.UseOwnDisassembler)) {
using (ModuleDefinition module = ModuleDefinition.ReadModule(sourceFileName))
using (var module = new PEReader(new FileStream(sourceFileName, FileMode.Open)))
using (var writer = new StreamWriter(outputFile)) {
module.Name = Path.GetFileNameWithoutExtension(outputFile);
//module.Name = Path.GetFileNameWithoutExtension(outputFile);
var output = new PlainTextOutput(writer);
ReflectionDisassembler rd = new ReflectionDisassembler(output, CancellationToken.None);
ReflectionDisassembler rd = new ReflectionDisassembler(output, module.GetMetadataReader(), CancellationToken.None);
rd.DetectControlStructure = false;
rd.WriteAssemblyReferences(module);
if (module.Assembly != null)
//rd.WriteAssemblyReferences(module);
/*if (module.Assembly != null)
rd.WriteAssemblyHeader(module.Assembly);
output.WriteLine();
rd.WriteModuleHeader(module);
output.WriteLine();
rd.WriteModuleContents(module);
rd.WriteModuleContents(module);*/
}
return outputFile;
}
@ -275,7 +277,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -275,7 +277,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
public static string DecompileCSharp(string assemblyFileName, DecompilerSettings settings = null)
{
using (var module = ModuleDefinition.ReadModule(assemblyFileName)) {
using (var module = Mono.Cecil.ModuleDefinition.ReadModule(assemblyFileName)) {
var typeSystem = new DecompilerTypeSystem(module);
CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, settings ?? new DecompilerSettings());
decompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute());

1
ICSharpCode.Decompiler/CSharp/Transforms/CustomPatterns.cs

@ -21,7 +21,6 @@ using System.Linq; @@ -21,7 +21,6 @@ using System.Linq;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
using ICSharpCode.Decompiler.Semantics;
using Mono.Cecil;
namespace ICSharpCode.Decompiler.CSharp.Transforms
{

1
ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

@ -24,7 +24,6 @@ using ICSharpCode.Decompiler.CSharp.Syntax; @@ -24,7 +24,6 @@ using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
using ICSharpCode.Decompiler.CSharp.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
using ICSharpCode.Decompiler.Semantics;
namespace ICSharpCode.Decompiler.CSharp.Transforms

144
ICSharpCode.Decompiler/CecilExtensions.cs

@ -31,119 +31,6 @@ namespace ICSharpCode.Decompiler @@ -31,119 +31,6 @@ namespace ICSharpCode.Decompiler
/// </summary>
public static class CecilExtensions
{
#region GetPushDelta / GetPopDelta
public static int GetPushDelta(this Instruction instruction)
{
OpCode code = instruction.OpCode;
switch (code.StackBehaviourPush) {
case StackBehaviour.Push0:
return 0;
case StackBehaviour.Push1:
case StackBehaviour.Pushi:
case StackBehaviour.Pushi8:
case StackBehaviour.Pushr4:
case StackBehaviour.Pushr8:
case StackBehaviour.Pushref:
return 1;
case StackBehaviour.Push1_push1:
return 2;
case StackBehaviour.Varpush:
if (code.FlowControl != FlowControl.Call)
break;
IMethodSignature method = (IMethodSignature) instruction.Operand;
return IsVoid (method.ReturnType) ? 0 : 1;
}
throw new NotSupportedException ();
}
public static int? GetPopDelta(this Instruction instruction, MethodDefinition methodDef)
{
OpCode code = instruction.OpCode;
switch (code.StackBehaviourPop) {
case StackBehaviour.Pop0:
return 0;
case StackBehaviour.Popi:
case StackBehaviour.Popref:
case StackBehaviour.Pop1:
return 1;
case StackBehaviour.Pop1_pop1:
case StackBehaviour.Popi_pop1:
case StackBehaviour.Popi_popi:
case StackBehaviour.Popi_popi8:
case StackBehaviour.Popi_popr4:
case StackBehaviour.Popi_popr8:
case StackBehaviour.Popref_pop1:
case StackBehaviour.Popref_popi:
return 2;
case StackBehaviour.Popi_popi_popi:
case StackBehaviour.Popref_popi_popi:
case StackBehaviour.Popref_popi_popi8:
case StackBehaviour.Popref_popi_popr4:
case StackBehaviour.Popref_popi_popr8:
case StackBehaviour.Popref_popi_popref:
return 3;
case StackBehaviour.PopAll:
return null;
case StackBehaviour.Varpop:
if (code == OpCodes.Ret)
return methodDef.ReturnType.IsVoid() ? 0 : 1;
if (code.FlowControl != FlowControl.Call)
break;
IMethodSignature method = (IMethodSignature) instruction.Operand;
int count = method.HasParameters ? method.Parameters.Count : 0;
if (method.HasThis && code != OpCodes.Newobj)
++count;
if (code == OpCodes.Calli)
++count; // calli takes a function pointer in additional to the normal args
return count;
}
throw new NotSupportedException ();
}
public static bool IsVoid(this TypeReference type)
{
while (type is OptionalModifierType || type is RequiredModifierType)
type = ((TypeSpecification)type).ElementType;
return type.MetadataType == MetadataType.Void;
}
public static bool IsValueTypeOrVoid(this TypeReference type)
{
while (type is OptionalModifierType || type is RequiredModifierType)
type = ((TypeSpecification)type).ElementType;
if (type is ArrayType)
return false;
return type.IsValueType || type.IsVoid();
}
/// <summary>
/// checks if the given TypeReference is one of the following types:
/// [sbyte, short, int, long, IntPtr]
/// </summary>
public static bool IsSignedIntegralType(this TypeReference type)
{
return type.MetadataType == MetadataType.SByte ||
type.MetadataType == MetadataType.Int16 ||
type.MetadataType == MetadataType.Int32 ||
type.MetadataType == MetadataType.Int64 ||
type.MetadataType == MetadataType.IntPtr;
}
#endregion
/// <summary>
/// Gets the (exclusive) end offset of this instruction.
/// </summary>
@ -164,37 +51,6 @@ namespace ICSharpCode.Decompiler @@ -164,37 +51,6 @@ namespace ICSharpCode.Decompiler
return string.Format("IL_{0:x4}", offset);
}
public static HashSet<MethodDefinition> GetAccessorMethods(this TypeDefinition type)
{
HashSet<MethodDefinition> accessorMethods = new HashSet<MethodDefinition>();
foreach (var property in type.Properties) {
accessorMethods.Add(property.GetMethod);
accessorMethods.Add(property.SetMethod);
if (property.HasOtherMethods) {
foreach (var m in property.OtherMethods)
accessorMethods.Add(m);
}
}
foreach (EventDefinition ev in type.Events) {
accessorMethods.Add(ev.AddMethod);
accessorMethods.Add(ev.RemoveMethod);
accessorMethods.Add(ev.InvokeMethod);
if (ev.HasOtherMethods) {
foreach (var m in ev.OtherMethods)
accessorMethods.Add(m);
}
}
return accessorMethods;
}
public static TypeDefinition ResolveWithinSameModule(this TypeReference type)
{
if (type != null && type.GetElementType().Module == type.Module)
return type.Resolve();
else
return null;
}
public static FieldDefinition ResolveWithinSameModule(this FieldReference field)
{
if (field != null && field.DeclaringType.GetElementType().Module == field.Module)

1
ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs

@ -21,6 +21,7 @@ using System.Collections.Generic; @@ -21,6 +21,7 @@ using System.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Cil;
using System.Text;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.Decompiler.Disassembler
{

1109
ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

File diff suppressed because it is too large Load Diff

92
ICSharpCode.Decompiler/Disassembler/OpCodeInfo.cs

@ -0,0 +1,92 @@ @@ -0,0 +1,92 @@
// 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.Text;
using System.Threading.Tasks;
namespace ICSharpCode.Decompiler.Disassembler
{
public struct OpCodeInfo : IEquatable<OpCodeInfo>
{
public readonly int Code;
public readonly string Name;
string encodedName;
public OpCodeInfo(int code, string name)
{
this.Code = code;
this.Name = name;
this.encodedName = null;
}
public bool Equals(OpCodeInfo other)
{
return other.Code == this.Code && other.Name == this.Name;
}
public static bool operator ==(OpCodeInfo lhs, OpCodeInfo rhs) => lhs.Equals(rhs);
public static bool operator !=(OpCodeInfo lhs, OpCodeInfo rhs) => !(lhs == rhs);
public string Link => "http://msdn.microsoft.com/library/system.reflection.emit.opcodes." + EncodedName.ToLowerInvariant() + ".aspx";
public string EncodedName {
get {
if (encodedName != null)
return encodedName;
switch (Name) {
case "constrained.":
encodedName = "Constrained";
return encodedName;
case "no.":
encodedName = "No";
return encodedName;
case "readonly.":
encodedName = "Reaonly";
return encodedName;
case "tail.":
encodedName = "Tailcall";
return encodedName;
case "unaligned.":
encodedName = "Unaligned";
return encodedName;
case "volatile.":
encodedName = "Volatile";
return encodedName;
}
string text = "";
bool toUpperCase = true;
foreach (var ch in Name) {
if (ch == '.') {
text += '_';
toUpperCase = true;
} else if (toUpperCase) {
text += char.ToUpperInvariant(ch);
toUpperCase = false;
} else {
text += ch;
}
}
encodedName = text;
return encodedName;
}
}
}
}

1302
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

File diff suppressed because it is too large Load Diff

6
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -55,6 +55,7 @@ @@ -55,6 +55,7 @@
<PackageReference Include="Humanizer.Core" Version="2.2.0" />
<PackageReference Include="Mono.Cecil" Version="0.10.0-beta7" />
<PackageReference Include="System.Collections.Immutable" Version="1.3.1" />
<PackageReference Include="System.Reflection.Metadata" Version="1.4.2" />
<PackageReference Include="System.ValueTuple" Version="4.3.0" />
</ItemGroup>
@ -267,6 +268,7 @@ @@ -267,6 +268,7 @@
<Compile Include="CSharp\Transforms\ReplaceMethodCallsWithOperators.cs" />
<Compile Include="CSharp\WholeProjectDecompiler.cs" />
<Compile Include="CSharp\Transforms\AddXmlDocumentationTransform.cs" />
<Compile Include="Disassembler\OpCodeInfo.cs" />
<Compile Include="Documentation\GetPotentiallyNestedClassTypeReference.cs" />
<Compile Include="Documentation\IdStringMemberReference.cs" />
<Compile Include="Documentation\IdStringProvider.cs" />
@ -323,6 +325,8 @@ @@ -323,6 +325,8 @@
<Compile Include="IL\Transforms\StatementTransform.cs" />
<Compile Include="IL\Transforms\TransformCollectionAndObjectInitializers.cs" />
<Compile Include="Output\TextTokenWriter.cs" />
<Compile Include="TypeSystem\Implementation\TypeSpecification.cs" />
<Compile Include="TypeSystem\MetadataExtensions.cs" />
<Compile Include="Util\GraphVizGraph.cs" />
<Compile Include="Util\KeyComparer.cs" />
<Compile Include="Util\LongDict.cs" />
@ -432,7 +436,6 @@ @@ -432,7 +436,6 @@
<Compile Include="TypeSystem\Accessibility.cs" />
<Compile Include="TypeSystem\AnonymousType.cs" />
<Compile Include="TypeSystem\ArrayType.cs" />
<Compile Include="TypeSystem\AssemblyLoader.cs" />
<Compile Include="TypeSystem\AssemblyQualifiedTypeName.cs" />
<Compile Include="TypeSystem\ByReferenceType.cs" />
<Compile Include="TypeSystem\CecilLoader.cs" />
@ -545,7 +548,6 @@ @@ -545,7 +548,6 @@
<Compile Include="TypeSystem\SpecializingDecompilerTypeSystem.cs" />
<Compile Include="TypeSystem\IDecompilerTypeSystem.cs" />
<Compile Include="TypeSystem\ReferenceResolvingException.cs" />
<Compile Include="TypeSystem\TypesHierarchyHelpers.cs" />
<Compile Include="TypeSystem\TypeVisitor.cs" />
<Compile Include="TypeSystem\VarArgInstanceMethod.cs" />
<Compile Include="Util\BitVector16.cs" />

3
ICSharpCode.Decompiler/IL/ILOpCodes.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Reflection.Emit;
namespace ICSharpCode.Decompiler.IL
{
enum ILOpCode : ushort
@ -249,7 +250,6 @@ namespace ICSharpCode.Decompiler.IL @@ -249,7 +250,6 @@ namespace ICSharpCode.Decompiler.IL
Readonly = 0x11e,
}
/*
static class ILOpCodeExtensions
{
// We use a byte array instead of an enum array because it can be initialized more efficiently
@ -260,5 +260,4 @@ namespace ICSharpCode.Decompiler.IL @@ -260,5 +260,4 @@ namespace ICSharpCode.Decompiler.IL
return (OperandType)operandTypes[(ushort)opCode];
}
}
*/
}

3
ICSharpCode.Decompiler/IL/ILOpCodes.tt

@ -24,6 +24,7 @@ @@ -24,6 +24,7 @@
<#@ import namespace="System.Reflection.Emit" #>
<#@ output extension=".cs" #>
using System;
using System.Reflection.Emit;
<#
var operandTypes = new OperandType[0x11f];
@ -41,7 +42,6 @@ namespace ICSharpCode.Decompiler.IL @@ -41,7 +42,6 @@ namespace ICSharpCode.Decompiler.IL
<# } // end foreach #>
}
/*
static class ILOpCodeExtensions
{
// We use a byte array instead of an enum array because it can be initialized more efficiently
@ -57,5 +57,4 @@ namespace ICSharpCode.Decompiler.IL @@ -57,5 +57,4 @@ namespace ICSharpCode.Decompiler.IL
return (OperandType)operandTypes[(ushort)opCode];
}
}
*/
}

4
ICSharpCode.Decompiler/IL/ILReader.cs

@ -412,8 +412,8 @@ namespace ICSharpCode.Decompiler.IL @@ -412,8 +412,8 @@ namespace ICSharpCode.Decompiler.IL
inst.WriteTo(output, new ILAstWritingOptions());
output.WriteLine();
}
new Disassembler.MethodBodyDisassembler(output, cancellationToken) { DetectControlStructure = false }
.WriteExceptionHandlers(body);
/*new Disassembler.MethodBodyDisassembler(output, cancellationToken) { DetectControlStructure = false }
.WriteExceptionHandlers(body);*/
}
/// <summary>

87
ICSharpCode.Decompiler/TypeSystem/AssemblyLoader.cs

@ -1,87 +0,0 @@ @@ -1,87 +0,0 @@
//
// AssemblyLoader.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2013 Xamarin Inc. (http://xamarin.com)
//
// 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.Reflection;
using System.Threading;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
namespace ICSharpCode.Decompiler.TypeSystem
{
public enum AssemblyLoaderBackend {
Auto,
Cecil,
IKVM
}
public abstract class AssemblyLoader
{
public static AssemblyLoader Create ()
{
return Create (AssemblyLoaderBackend.Auto);
}
public static AssemblyLoader Create (AssemblyLoaderBackend backend)
{
switch (backend) {
case AssemblyLoaderBackend.Auto:
case AssemblyLoaderBackend.Cecil:
return (AssemblyLoader)Assembly.Load ("ICSharpCode.Decompiler.Cecil").CreateInstance ("ICSharpCode.Decompiler.TypeSystem.CecilLoader");
case AssemblyLoaderBackend.IKVM:
return (AssemblyLoader)Assembly.Load ("ICSharpCode.Decompiler.IKVM").CreateInstance ("ICSharpCode.Decompiler.TypeSystem.IkvmLoader");
default:
throw new ArgumentOutOfRangeException ();
}
}
/// <summary>
/// Specifies whether to include internal members. The default is false.
/// </summary>
public bool IncludeInternalMembers { get; set; }
/// <summary>
/// Gets/Sets the cancellation token used by the assembly loader.
/// </summary>
public CancellationToken CancellationToken { get; set; }
protected InterningProvider interningProvider = new SimpleInterningProvider();
/// <summary>
/// Gets/Sets the interning provider.
/// </summary>
public InterningProvider InterningProvider {
get { return interningProvider; }
set {
if (value == null)
throw new ArgumentNullException();
interningProvider = value;
}
}
public abstract IUnresolvedAssembly LoadAssemblyFile(string fileName);
}
}

585
ICSharpCode.Decompiler/TypeSystem/CecilLoader.cs

@ -20,34 +20,49 @@ using System; @@ -20,34 +20,49 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
using Mono.Cecil;
namespace ICSharpCode.Decompiler.TypeSystem
{
using BlobReader = BlobReader;
/// <summary>
/// Allows loading an IProjectContent from an already compiled assembly.
/// </summary>
/// <remarks>Instance methods are not thread-safe; you need to create multiple instances of CecilLoader
/// if you want to load multiple project contents in parallel.</remarks>
public sealed class CecilLoader : AssemblyLoader
public sealed class MetadataLoader
{
#region Options
/// <summary>
/// Version number of the cecil loader.
/// Should be incremented when fixing bugs in the cecil loader so that project contents cached on disk
/// (which might be incorrect due to the bug) are re-created.
/// Specifies whether to include internal members. The default is false.
/// </summary>
const int cecilLoaderVersion = 1;
#region Options
// Most options are defined in the AssemblyLoader base class
public bool IncludeInternalMembers { get; set; }
/// <summary>
/// Gets/Sets the cancellation token used by the assembly loader.
/// </summary>
public CancellationToken CancellationToken { get; set; }
InterningProvider interningProvider = new SimpleInterningProvider();
/// <summary>
/// Gets/Sets the interning provider.
/// </summary>
public InterningProvider InterningProvider {
get { return interningProvider; }
set {
if (value == null)
throw new ArgumentNullException();
interningProvider = value;
}
}
/// <summary>
/// Specifies whether to use lazy loading. The default is false.
/// If this property is set to true, the CecilLoader will not copy all the relevant information
@ -73,7 +88,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -73,7 +88,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// Warning: if delay-loading is used and the type system is accessed by multiple threads,
/// the callback may be invoked concurrently on multiple threads.
/// </remarks>
public Action<IUnresolvedEntity, MemberReference> OnEntityLoaded { get; set; }
public Action<IUnresolvedEntity, EntityHandle> OnEntityLoaded { get; set; }
/// <summary>
/// Gets a value indicating whether this instance stores references to the cecil objects.
@ -98,21 +113,21 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -98,21 +113,21 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
#endregion
ModuleDefinition currentModule;
MetadataReader currentModule;
DefaultUnresolvedAssembly currentAssembly;
/// <summary>
/// Initializes a new instance of the <see cref="CecilLoader"/> class.
/// Initializes a new instance of the <see cref="MetadataLoader"/> class.
/// </summary>
public CecilLoader()
public MetadataLoader()
{
}
/// <summary>
/// Creates a nested CecilLoader for lazy-loading.
/// </summary>
private CecilLoader(CecilLoader loader)
private MetadataLoader(MetadataLoader loader)
{
// use a shared typeSystemTranslationTable
this.typeSystemTranslationTable = loader.typeSystemTranslationTable;
@ -129,74 +144,72 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -129,74 +144,72 @@ namespace ICSharpCode.Decompiler.TypeSystem
#region Load From AssemblyDefinition
/// <summary>
/// Loads the assembly definition into a project content.
/// </summary>
/// <returns>Unresolved type system representing the assembly</returns>
public IUnresolvedAssembly LoadAssembly(AssemblyDefinition assemblyDefinition)
{
if (assemblyDefinition == null)
throw new ArgumentNullException("assemblyDefinition");
return LoadModule(assemblyDefinition.MainModule);
}
/// <summary>
/// Loads the module definition into a project content.
/// Loads a module definition into a project content.
/// </summary>
/// <returns>Unresolved type system representing the assembly</returns>
public IUnresolvedAssembly LoadModule(ModuleDefinition moduleDefinition)
public IUnresolvedAssembly LoadModule(MetadataReader module)
{
if (moduleDefinition == null)
throw new ArgumentNullException("moduleDefinition");
this.currentModule = moduleDefinition;
this.currentModule = module;
// Read assembly and module attributes
IList<IUnresolvedAttribute> assemblyAttributes = new List<IUnresolvedAttribute>();
IList<IUnresolvedAttribute> moduleAttributes = new List<IUnresolvedAttribute>();
AssemblyDefinition assemblyDefinition = moduleDefinition.Assembly;
if (assemblyDefinition != null) {
AddAttributes(assemblyDefinition, assemblyAttributes);
AssemblyDefinition assemblyDefinition = default(AssemblyDefinition);
if (currentModule.IsAssembly) {
AddAttributes(currentModule.GetAssemblyDefinition(), assemblyAttributes);
}
AddAttributes(moduleDefinition, moduleAttributes);
AddAttributes(Handle.ModuleDefinition, moduleAttributes);
assemblyAttributes = interningProvider.InternList(assemblyAttributes);
moduleAttributes = interningProvider.InternList(moduleAttributes);
this.currentAssembly = new DefaultUnresolvedAssembly(assemblyDefinition != null ? assemblyDefinition.Name.FullName : moduleDefinition.Name);
currentAssembly.Location = moduleDefinition.FileName;
this.currentAssembly = new DefaultUnresolvedAssembly(currentModule.IsAssembly ? assemblyDefinition.GetFullName(currentModule) : currentModule.GetString(currentModule.GetModuleDefinition().Name));
currentAssembly.AssemblyAttributes.AddRange(assemblyAttributes);
currentAssembly.ModuleAttributes.AddRange(assemblyAttributes);
// Register type forwarders:
foreach (ExportedType type in moduleDefinition.ExportedTypes) {
foreach (ExportedTypeHandle t in currentModule.ExportedTypes) {
var type = currentModule.GetExportedType(t);
if (type.IsForwarder) {
throw new NotImplementedException();/*
switch (type.Implementation.Kind) {
case HandleKind.AssemblyFile:
throw new NotImplementedException(); // type is defined in another module.
case HandleKind.ExportedType:
break;
case HandleKind.AssemblyReference:
break;
}
int typeParameterCount;
string ns = type.Namespace;
string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out typeParameterCount);
string ns = currentModule.GetString(type.Namespace);
string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(currentModule.GetString(type.Name), out typeParameterCount);
ns = interningProvider.Intern(ns);
name = interningProvider.Intern(name);
var typeRef = new GetClassTypeReference(GetAssemblyReference(type.Scope), ns, name, typeParameterCount);
var typeRef = new GetClassTypeReference(, ns, name, typeParameterCount);
typeRef = interningProvider.Intern(typeRef);
var key = new TopLevelTypeName(ns, name, typeParameterCount);
currentAssembly.AddTypeForwarder(key, typeRef);
currentAssembly.AddTypeForwarder(key, typeRef);*/
}
}
// Create and register all types:
CecilLoader cecilLoaderCloneForLazyLoading = LazyLoad ? new CecilLoader(this) : null;
MetadataLoader cecilLoaderCloneForLazyLoading = LazyLoad ? new MetadataLoader(this) : null;
List<TypeDefinition> cecilTypeDefs = new List<TypeDefinition>();
List<DefaultUnresolvedTypeDefinition> typeDefs = new List<DefaultUnresolvedTypeDefinition>();
foreach (TypeDefinition td in moduleDefinition.Types) {
foreach (TypeDefinitionHandle h in module.TypeDefinitions) {
this.CancellationToken.ThrowIfCancellationRequested();
var td = module.GetTypeDefinition(h);
if (this.IncludeInternalMembers || (td.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public) {
string name = td.Name;
string name = module.GetString(td.Name);
if (name.Length == 0)
continue;
if (this.LazyLoad) {
var t = new LazyCecilTypeDefinition(cecilLoaderCloneForLazyLoading, td);
currentAssembly.AddTypeDefinition(t);
RegisterCecilObject(t, td);
RegisterCecilObject(t, h);
} else {
var t = CreateTopLevelTypeDefinition(td);
cecilTypeDefs.Add(td);
@ -210,7 +223,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -210,7 +223,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
for (int i = 0; i < typeDefs.Count; i++) {
InitTypeDefinition(cecilTypeDefs[i], typeDefs[i]);
}
AddToTypeSystemTranslationTable(this.currentAssembly, assemblyDefinition);
// Freezing the assembly here is important:
// otherwise it will be frozen when a compilation is first created
@ -221,7 +234,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -221,7 +234,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
// By freezing the assembly now, we ensure it is usable on multiple
// threads without issues.
currentAssembly.Freeze();
var result = this.currentAssembly;
this.currentAssembly = null;
this.currentModule = null;
@ -233,7 +246,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -233,7 +246,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// This causes ReadTypeReference() to use <see cref="DefaultAssemblyReference.CurrentAssembly"/> for references
/// in that module.
/// </summary>
public void SetCurrentModule(ModuleDefinition module)
public void SetCurrentModule(MetadataReader module)
{
this.currentModule = module;
}
@ -243,12 +256,12 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -243,12 +256,12 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
/// <param name="typeDefinition">The Cecil TypeDefinition.</param>
/// <returns>ITypeDefinition representing the Cecil type.</returns>
public IUnresolvedTypeDefinition LoadType(TypeDefinition typeDefinition)
public IUnresolvedTypeDefinition LoadType(TypeDefinitionHandle typeDefinition)
{
if (typeDefinition == null)
throw new ArgumentNullException("typeDefinition");
var td = CreateTopLevelTypeDefinition(typeDefinition);
InitTypeDefinition(typeDefinition, td);
if (typeDefinition.IsNil)
throw new ArgumentNullException(nameof(typeDefinition));
var td = CreateTopLevelTypeDefinition(currentModule.GetTypeDefinition(typeDefinition));
InitTypeDefinition(currentModule.GetTypeDefinition(typeDefinition), td);
return td;
}
#endregion
@ -263,34 +276,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -263,34 +276,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
return LoadModule(module);
}
}
// used to prevent Cecil from loading referenced assemblies
sealed class DummyAssemblyResolver : IAssemblyResolver
{
public AssemblyDefinition Resolve(AssemblyNameReference name)
{
return null;
}
public AssemblyDefinition Resolve(string fullName)
{
return null;
}
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
{
return null;
}
public AssemblyDefinition Resolve(string fullName, ReaderParameters parameters)
{
return null;
}
public void Dispose()
{
}
}
#endregion
#region Read Type Reference
@ -301,101 +286,51 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -301,101 +286,51 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// a type system type reference.</param>
/// <param name="typeAttributes">Attributes associated with the Cecil type reference.
/// This is used to support the 'dynamic' type.</param>
public ITypeReference ReadTypeReference(TypeReference type, ICustomAttributeProvider typeAttributes = null)
public ITypeReference ReadTypeReference(EntityHandle type, CustomAttributeHandleCollection typeAttributes = default(CustomAttributeHandleCollection))
{
int typeIndex = 0;
return CreateType(type, typeAttributes, ref typeIndex);
}
ITypeReference CreateType(TypeReference type, ICustomAttributeProvider typeAttributes, ref int typeIndex)
class DynamicTypeVisitor : TypeVisitor
{
while (type is OptionalModifierType || type is RequiredModifierType) {
type = ((TypeSpecification)type).ElementType;
}
if (type == null) {
return SpecialType.UnknownType;
}
if (type is Mono.Cecil.ByReferenceType) {
typeIndex++;
return interningProvider.Intern(
new ByReferenceTypeReference(
CreateType(
(type as Mono.Cecil.ByReferenceType).ElementType,
typeAttributes, ref typeIndex)));
} else if (type is Mono.Cecil.PointerType) {
typeIndex++;
return interningProvider.Intern(
new PointerTypeReference(
CreateType(
(type as Mono.Cecil.PointerType).ElementType,
typeAttributes, ref typeIndex)));
} else if (type is Mono.Cecil.ArrayType) {
typeIndex++;
return interningProvider.Intern(
new ArrayTypeReference(
CreateType(
(type as Mono.Cecil.ArrayType).ElementType,
typeAttributes, ref typeIndex),
(type as Mono.Cecil.ArrayType).Rank));
} else if (type is GenericInstanceType) {
GenericInstanceType gType = (GenericInstanceType)type;
ITypeReference baseType = CreateType(gType.ElementType, typeAttributes, ref typeIndex);
ITypeReference[] para = new ITypeReference[gType.GenericArguments.Count];
for (int i = 0; i < para.Length; ++i) {
typeIndex++;
para[i] = CreateType(gType.GenericArguments[i], typeAttributes, ref typeIndex);
}
return interningProvider.Intern(new ParameterizedTypeReference(baseType, para));
} else if (type is GenericParameter) {
GenericParameter typeGP = (GenericParameter)type;
return TypeParameterReference.Create(typeGP.Owner is MethodReference ? SymbolKind.Method : SymbolKind.TypeDefinition, typeGP.Position);
} else if (type is FunctionPointerType) {
return KnownTypeReference.Get(KnownTypeCode.IntPtr);
} else if (type.IsNested) {
ITypeReference typeRef = CreateType(type.DeclaringType, typeAttributes, ref typeIndex);
int partTypeParameterCount;
string namepart = ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out partTypeParameterCount);
namepart = interningProvider.Intern(namepart);
return interningProvider.Intern(new NestedTypeReference(typeRef, namepart, partTypeParameterCount));
} else {
string ns = interningProvider.Intern(type.Namespace ?? string.Empty);
string name = type.Name;
if (name == null)
throw new InvalidOperationException("type.Name returned null. Type: " + type.ToString());
if (name == "Object" && ns == "System" && HasDynamicAttribute(typeAttributes, typeIndex)) {
return SpecialType.Dynamic;
} else {
int typeParameterCount;
name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(name, out typeParameterCount);
name = interningProvider.Intern(name);
if (currentAssembly != null) {
IUnresolvedTypeDefinition c = currentAssembly.GetTypeDefinition(ns, name, typeParameterCount);
if (c != null)
return c;
}
return interningProvider.Intern(new GetClassTypeReference(GetAssemblyReference(type.Scope), ns, name, typeParameterCount));
}
public override IType VisitPointerType(PointerType type)
{
return base.VisitPointerType(type);
}
}
IAssemblyReference GetAssemblyReference(IMetadataScope scope)
ITypeReference CreateType(EntityHandle type, CustomAttributeHandleCollection typeAttributes, ref int typeIndex)
{
if (scope == null || scope == currentModule)
return DefaultAssemblyReference.CurrentAssembly;
else
return interningProvider.Intern(new DefaultAssemblyReference(scope.Name));
ITypeReference CreateTypeReference(TypeReferenceHandle handle)
{
var t = currentModule.GetTypeReference(handle);
var asmref = handle.GetDeclaringAssembly(currentModule);
if (asmref.IsNil)
return new GetClassTypeReference(handle.GetFullTypeName(currentModule), DefaultAssemblyReference.CurrentAssembly);
var asm = currentModule.GetAssemblyReference(asmref);
return new GetClassTypeReference(handle.GetFullTypeName(currentModule), new DefaultAssemblyReference(currentModule.GetString(asm.Name)));
}
switch (type.Kind) {
case HandleKind.TypeSpecification:
return new SignatureTypeReference((TypeSpecificationHandle)type, currentModule);
case HandleKind.TypeReference:
return CreateTypeReference((TypeReferenceHandle)type);
case HandleKind.TypeDefinition:
return new DefaultUnresolvedTypeDefinition(type.GetFullTypeName(currentModule).ReflectionName);
}
}
static bool HasDynamicAttribute(ICustomAttributeProvider attributeProvider, int typeIndex)
{
if (attributeProvider == null || !attributeProvider.HasCustomAttributes)
return false;
foreach (CustomAttribute a in attributeProvider.CustomAttributes) {
TypeReference type = a.AttributeType;
if (type.Name == "DynamicAttribute" && type.Namespace == "System.Runtime.CompilerServices") {
if (a.ConstructorArguments.Count == 1) {
bool HasDynamicAttribute(CustomAttributeHandleCollection attributes, int typeIndex)
{
foreach (CustomAttributeHandle handle in attributes) {
var a = currentModule.GetCustomAttribute(handle);
var type = a.GetAttributeType(currentModule);
if (type.GetFullTypeName(currentModule).ToString() == "System.Runtime.CompilerServices.DynamicAttribute") {
var ctor = a.DecodeValue(new TypeSystemAttributeTypeProvider());
ctor.FixedArguments[0].
if (a..Count == 1) {
CustomAttributeArgument[] values = a.ConstructorArguments[0].Value as CustomAttributeArgument[];
if (values != null && typeIndex < values.Length && values[typeIndex].Value is bool)
return (bool)values[typeIndex].Value;
@ -413,17 +348,13 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -413,17 +348,13 @@ namespace ICSharpCode.Decompiler.TypeSystem
void AddAttributes(AssemblyDefinition assembly, IList<IUnresolvedAttribute> outputList)
{
if (assembly.HasCustomAttributes) {
AddCustomAttributes(assembly.CustomAttributes, outputList);
}
if (assembly.HasSecurityDeclarations) {
AddSecurityAttributes(assembly.SecurityDeclarations, outputList);
}
AddCustomAttributes(currentModule.GetCustomAttributes((EntityHandle)Handle.AssemblyDefinition), outputList);
AddSecurityAttributes(assembly.GetDeclarativeSecurityAttributes(), outputList);
// AssemblyVersionAttribute
if (assembly.Name.Version != null) {
if (assembly.Version != null) {
var assemblyVersion = new DefaultUnresolvedAttribute(assemblyVersionAttributeTypeRef, new[] { KnownTypeReference.String });
assemblyVersion.PositionalArguments.Add(CreateSimpleConstantValue(KnownTypeReference.String, assembly.Name.Version.ToString()));
assemblyVersion.PositionalArguments.Add(CreateSimpleConstantValue(KnownTypeReference.String, assembly.Version.ToString()));
outputList.Add(interningProvider.Intern(assemblyVersion));
}
}
@ -435,11 +366,9 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -435,11 +366,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
#endregion
#region Module Attributes
void AddAttributes(ModuleDefinition module, IList<IUnresolvedAttribute> outputList)
void AddAttributes(ModuleDefinitionHandle module, IList<IUnresolvedAttribute> outputList)
{
if (module.HasCustomAttributes) {
AddCustomAttributes(module.CustomAttributes, outputList);
}
AddCustomAttributes(currentModule.GetCustomAttributes(module), outputList);
}
#endregion
@ -447,20 +376,16 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -447,20 +376,16 @@ namespace ICSharpCode.Decompiler.TypeSystem
static readonly IUnresolvedAttribute inAttribute = new DefaultUnresolvedAttribute(typeof(InAttribute).ToTypeReference());
static readonly IUnresolvedAttribute outAttribute = new DefaultUnresolvedAttribute(typeof(OutAttribute).ToTypeReference());
void AddAttributes(ParameterDefinition parameter, DefaultUnresolvedParameter targetParameter)
void AddAttributes(Parameter parameter, DefaultUnresolvedParameter targetParameter)
{
if (!targetParameter.IsOut) {
if (parameter.IsIn)
if ((parameter.Attributes & ParameterAttributes.In) == ParameterAttributes.In)
targetParameter.Attributes.Add(inAttribute);
if (parameter.IsOut)
if ((parameter.Attributes & ParameterAttributes.Out) == ParameterAttributes.Out)
targetParameter.Attributes.Add(outAttribute);
}
if (parameter.HasCustomAttributes) {
AddCustomAttributes(parameter.CustomAttributes, targetParameter.Attributes);
}
if (parameter.HasMarshalInfo) {
targetParameter.Attributes.Add(ConvertMarshalInfo(parameter.MarshalInfo));
}
AddCustomAttributes(parameter.GetCustomAttributes(), targetParameter.Attributes);
AddMarshalInfo(parameter.GetMarshallingDescriptor(), targetParameter.Attributes);
}
#endregion
@ -475,7 +400,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -475,7 +400,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
static bool HasAnyAttributes(MethodDefinition methodDefinition)
{
if (methodDefinition.HasPInvokeInfo)
if (!methodDefinition.Attributes )
return true;
if ((methodDefinition.ImplAttributes & ~MethodImplAttributes.CodeTypeMask) != 0)
return true;
@ -604,11 +529,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -604,11 +529,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
void AddAttributes(TypeDefinition typeDefinition, IUnresolvedTypeDefinition targetEntity)
{
// SerializableAttribute
if (typeDefinition.IsSerializable)
if ((typeDefinition.Attributes & TypeAttributes.Serializable) != 0)
targetEntity.Attributes.Add(serializableAttribute);
// ComImportAttribute
if (typeDefinition.IsImport)
if ((typeDefinition.Attributes & TypeAttributes.Import) != 0)
targetEntity.Attributes.Add(comImportAttribute);
#region StructLayoutAttribute
@ -633,29 +558,26 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -633,29 +558,26 @@ namespace ICSharpCode.Decompiler.TypeSystem
charSet = CharSet.Unicode;
break;
}
LayoutKind defaultLayoutKind = (typeDefinition.IsValueType && !typeDefinition.IsEnum) ? LayoutKind.Sequential: LayoutKind.Auto;
if (layoutKind != defaultLayoutKind || charSet != CharSet.Ansi || typeDefinition.PackingSize > 0 || typeDefinition.ClassSize > 0) {
var layout = typeDefinition.GetLayout();
LayoutKind defaultLayoutKind = (typeDefinition.IsValueType(currentModule) && !typeDefinition.IsEnum(currentModule)) ? LayoutKind.Sequential : LayoutKind.Auto;
if (layoutKind != defaultLayoutKind || charSet != CharSet.Ansi || layout.PackingSize > 0 || layout.Size > 0) {
DefaultUnresolvedAttribute structLayout = new DefaultUnresolvedAttribute(structLayoutAttributeTypeRef, new[] { layoutKindTypeRef });
structLayout.PositionalArguments.Add(CreateSimpleConstantValue(layoutKindTypeRef, (int)layoutKind));
if (charSet != CharSet.Ansi) {
structLayout.AddNamedFieldArgument("CharSet", CreateSimpleConstantValue(charSetTypeRef, (int)charSet));
}
if (typeDefinition.PackingSize > 0) {
structLayout.AddNamedFieldArgument("Pack", CreateSimpleConstantValue(KnownTypeReference.Int32, (int)typeDefinition.PackingSize));
if (layout.PackingSize > 0) {
structLayout.AddNamedFieldArgument("Pack", CreateSimpleConstantValue(KnownTypeReference.Int32, (int)layout.PackingSize));
}
if (typeDefinition.ClassSize > 0) {
structLayout.AddNamedFieldArgument("Size", CreateSimpleConstantValue(KnownTypeReference.Int32, (int)typeDefinition.ClassSize));
if (layout.Size > 0) {
structLayout.AddNamedFieldArgument("Size", CreateSimpleConstantValue(KnownTypeReference.Int32, (int)layout.Size));
}
targetEntity.Attributes.Add(interningProvider.Intern(structLayout));
}
#endregion
if (typeDefinition.HasCustomAttributes) {
AddCustomAttributes(typeDefinition.CustomAttributes, targetEntity.Attributes);
}
if (typeDefinition.HasSecurityDeclarations) {
AddSecurityAttributes(typeDefinition.SecurityDeclarations, targetEntity.Attributes);
}
AddCustomAttributes(typeDefinition.GetCustomAttributes(), targetEntity.Attributes);
AddSecurityAttributes(typeDefinition.GetDeclarativeSecurityAttributes(), targetEntity.Attributes);
}
#endregion
@ -678,7 +600,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -678,7 +600,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
if (fieldDefinition.HasMarshalInfo) {
targetEntity.Attributes.Add(ConvertMarshalInfo(fieldDefinition.MarshalInfo));
targetEntity.Attributes.Add(ConvertMarshalInfo(fieldDefinition.GetMarshallingDescriptor()));
}
if (fieldDefinition.HasCustomAttributes) {
@ -717,8 +639,14 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -717,8 +639,14 @@ namespace ICSharpCode.Decompiler.TypeSystem
#region MarshalAsAttribute (ConvertMarshalInfo)
static readonly ITypeReference marshalAsAttributeTypeRef = typeof(MarshalAsAttribute).ToTypeReference();
static readonly ITypeReference unmanagedTypeTypeRef = typeof(UnmanagedType).ToTypeReference();
void AddMarshalInfo(BlobHandle marshalInfo, IList<IUnresolvedAttribute> target)
{
if (marshalInfo.IsNil) return;
}
IUnresolvedAttribute ConvertMarshalInfo(MarshalInfo marshalInfo)
IUnresolvedAttribute ConvertMarshalInfo(System.Reflection.Metadata.BlobReader marshalInfo)
{
DefaultUnresolvedAttribute attr = new DefaultUnresolvedAttribute(marshalAsAttributeTypeRef, new[] { unmanagedTypeTypeRef });
attr.PositionalArguments.Add(CreateSimpleConstantValue(unmanagedTypeTypeRef, (int)marshalInfo.NativeType));
@ -759,26 +687,27 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -759,26 +687,27 @@ namespace ICSharpCode.Decompiler.TypeSystem
#endregion
#region Custom Attributes (ReadAttribute)
void AddCustomAttributes(Mono.Collections.Generic.Collection<CustomAttribute> attributes, IList<IUnresolvedAttribute> targetCollection)
{
foreach (var cecilAttribute in attributes) {
TypeReference type = cecilAttribute.AttributeType;
if (type.Namespace == "System.Runtime.CompilerServices") {
if (type.Name == "DynamicAttribute" || type.Name == "ExtensionAttribute" || type.Name == "DecimalConstantAttribute")
void AddCustomAttributes(CustomAttributeHandleCollection attributes, IList<IUnresolvedAttribute> targetCollection)
{
foreach (var handle in attributes) {
var attribute = currentModule.GetCustomAttribute(handle);
var typeHandle = attribute.GetAttributeType(currentModule);
switch (typeHandle.GetFullTypeName(currentModule).ReflectionName) {
case "System.Runtime.CompilerServices.DynamicAttribute":
case "System.Runtime.CompilerServices.ExtensionAttribute":
case "System.Runtime.CompilerServices.DecimalConstantAttribute":
case "System.ParamArrayAttribute":
continue;
} else if (type.Name == "ParamArrayAttribute" && type.Namespace == "System") {
continue;
}
targetCollection.Add(ReadAttribute(cecilAttribute));
targetCollection.Add(ReadAttribute(attribute));
}
}
public IUnresolvedAttribute ReadAttribute(CustomAttribute attribute)
{
if (attribute == null)
throw new ArgumentNullException("attribute");
MethodReference ctor = attribute.Constructor;
ITypeReference attributeType = ReadTypeReference(attribute.AttributeType);
var ctor = attribute.Constructor;
ITypeReference attributeType = ReadTypeReference(attribute.GetAttributeType(currentModule));
IList<ITypeReference> ctorParameterTypes = EmptyList<ITypeReference>.Instance;
if (ctor.HasParameters) {
ctorParameterTypes = new ITypeReference[ctor.Parameters.Count];
@ -804,21 +733,17 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -804,21 +733,17 @@ namespace ICSharpCode.Decompiler.TypeSystem
return result;
}
void AddSecurityAttributes(Mono.Collections.Generic.Collection<SecurityDeclaration> securityDeclarations, IList<IUnresolvedAttribute> targetCollection)
void AddSecurityAttributes(DeclarativeSecurityAttributeHandleCollection securityDeclarations, IList<IUnresolvedAttribute> targetCollection)
{
foreach (var secDecl in securityDeclarations) {
AddSecurityAttributes(secDecl, targetCollection);
if (secDecl.IsNil) continue;
AddSecurityAttributes(currentModule.GetDeclarativeSecurityAttribute(secDecl), targetCollection);
}
}
void AddSecurityAttributes(SecurityDeclaration secDecl, IList<IUnresolvedAttribute> targetCollection)
void AddSecurityAttributes(DeclarativeSecurityAttribute secDecl, IList<IUnresolvedAttribute> targetCollection)
{
byte[] blob;
try {
blob = secDecl.GetBlob();
} catch (NotSupportedException) {
return; // https://github.com/icsharpcode/SharpDevelop/issues/284
}
var blob = currentModule.GetBlobBytes(secDecl.PermissionSet);
var blobSecDecl = new UnresolvedSecurityDeclarationBlob((int)secDecl.Action, blob);
targetCollection.AddRange(blobSecDecl.UnresolvedAttributes);
}
@ -828,27 +753,29 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -828,27 +753,29 @@ namespace ICSharpCode.Decompiler.TypeSystem
#region Read Type Definition
DefaultUnresolvedTypeDefinition CreateTopLevelTypeDefinition(TypeDefinition typeDefinition)
{
string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(typeDefinition.Name);
var td = new DefaultUnresolvedTypeDefinition(typeDefinition.Namespace, name);
if (typeDefinition.HasGenericParameters)
InitTypeParameters(typeDefinition, td.TypeParameters);
string name = ReflectionHelper.SplitTypeParameterCountFromReflectionName(currentModule.GetString(typeDefinition.Name));
var td = new DefaultUnresolvedTypeDefinition(currentModule.GetString(typeDefinition.Namespace), name);
InitTypeParameters(typeDefinition, td.TypeParameters);
return td;
}
static void InitTypeParameters(TypeDefinition typeDefinition, IList<IUnresolvedTypeParameter> typeParameters)
void InitTypeParameters(TypeDefinition typeDefinition, IList<IUnresolvedTypeParameter> typeParameters)
{
// Type parameters are initialized within the constructor so that the class can be put into the type storage
// before the rest of the initialization runs - this allows it to be available for early binding as soon as possible.
for (int i = 0; i < typeDefinition.GenericParameters.Count; i++) {
if (typeDefinition.GenericParameters[i].Position != i)
var genericParams = typeDefinition.GetGenericParameters();
for (int i = 0; i < genericParams.Count; i++) {
var gp = currentModule.GetGenericParameter(genericParams[i]);
if (gp.Index != i)
throw new InvalidOperationException("g.Position != i");
typeParameters.Add(new DefaultUnresolvedTypeParameter(
SymbolKind.TypeDefinition, i, typeDefinition.GenericParameters[i].Name));
SymbolKind.TypeDefinition, i, currentModule.GetString(gp.Name)));
}
}
void InitTypeParameterConstraints(TypeDefinition typeDefinition, IList<IUnresolvedTypeParameter> typeParameters)
{
var genericParams = typeDefinition.GetGenericParameters();
for (int i = 0; i < typeParameters.Count; i++) {
var tp = (DefaultUnresolvedTypeParameter)typeParameters[i];
AddConstraints(tp, typeDefinition.GenericParameters[i]);
@ -1082,7 +1009,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1082,7 +1009,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
sealed class LazyCecilTypeDefinition : AbstractUnresolvedEntity, IUnresolvedTypeDefinition
{
// loader + cecilTypeDef, used for lazy-loading; and set to null after lazy loading is complete
CecilLoader loader;
MetadataLoader loader;
TypeDefinition cecilTypeDef;
readonly string namespaceName;
@ -1094,7 +1021,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1094,7 +1021,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
IList<IUnresolvedTypeDefinition> nestedTypes;
IList<IUnresolvedMember> members;
public LazyCecilTypeDefinition(CecilLoader loader, TypeDefinition typeDefinition)
public LazyCecilTypeDefinition(MetadataLoader loader, TypeDefinition typeDefinition)
{
this.loader = loader;
this.cecilTypeDef = typeDefinition;
@ -1295,15 +1222,16 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1295,15 +1222,16 @@ namespace ICSharpCode.Decompiler.TypeSystem
#endregion
#region Read Method
public IUnresolvedMethod ReadMethod(MethodDefinition method, IUnresolvedTypeDefinition parentType, SymbolKind methodType = SymbolKind.Method)
public IUnresolvedMethod ReadMethod(MethodDefinitionHandle method, IUnresolvedTypeDefinition parentType, SymbolKind methodType = SymbolKind.Method)
{
return ReadMethod(method, parentType, methodType, null);
}
IUnresolvedMethod ReadMethod(MethodDefinition method, IUnresolvedTypeDefinition parentType, SymbolKind methodType, IUnresolvedMember accessorOwner)
IUnresolvedMethod ReadMethod(MethodDefinitionHandle handle, IUnresolvedTypeDefinition parentType, SymbolKind methodType, IUnresolvedMember accessorOwner)
{
if (method == null)
if (handle.IsNil)
return null;
var method = currentModule.GetMethodDefinition(handle);
DefaultUnresolvedMethod m = new DefaultUnresolvedMethod(parentType, method.Name);
m.SymbolKind = methodType;
m.AccessorOwner = accessorOwner;
@ -1399,42 +1327,43 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1399,42 +1327,43 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
void TranslateModifiers(MethodDefinition method, AbstractUnresolvedMember m)
void TranslateModifiers(MethodDefinitionHandle handle, AbstractUnresolvedMember m)
{
var method = currentModule.GetMethodDefinition(handle);
if (m.DeclaringTypeDefinition.Kind == TypeKind.Interface) {
// interface members don't have modifiers, but we want to handle them as "public abstract"
m.Accessibility = Accessibility.Public;
m.IsAbstract = true;
} else {
m.Accessibility = GetAccessibility(method.Attributes);
if (method.IsAbstract) {
if ((method.Attributes & MethodAttributes.Abstract) == MethodAttributes.Abstract) {
m.IsAbstract = true;
m.IsOverride = !method.IsNewSlot;
} else if (method.IsFinal) {
if (!method.IsNewSlot) {
m.IsOverride = (method.Attributes & MethodAttributes.NewSlot) != MethodAttributes.NewSlot;
} else if ((method.Attributes & MethodAttributes.Final) == MethodAttributes.Final) {
if ((method.Attributes & MethodAttributes.NewSlot) != MethodAttributes.NewSlot) {
m.IsSealed = true;
m.IsOverride = true;
}
} else if (method.IsVirtual) {
if (method.IsNewSlot)
} else if ((method.Attributes & MethodAttributes.Virtual) == MethodAttributes.Virtual) {
if ((method.Attributes & MethodAttributes.NewSlot) == MethodAttributes.NewSlot)
m.IsVirtual = true;
else
m.IsOverride = true;
}
m.IsStatic = method.IsStatic;
m.IsStatic = (method.Attributes & MethodAttributes.Static) == MethodAttributes.Static;
}
}
#endregion
#region Read Parameter
public IUnresolvedParameter ReadParameter(ParameterDefinition parameter)
public IUnresolvedParameter ReadParameter(ParameterHandle handle, ITypeReference type)
{
if (parameter == null)
throw new ArgumentNullException("parameter");
var type = ReadTypeReference(parameter.ParameterType, typeAttributes: parameter);
var p = new DefaultUnresolvedParameter(type, interningProvider.Intern(parameter.Name));
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
var parameter = currentModule.GetParameter(handle);
var p = new DefaultUnresolvedParameter(type, interningProvider.Intern(currentModule.GetString(parameter.Name)));
if (parameter.ParameterType is Mono.Cecil.ByReferenceType) {
if (type is ByReferenceTypeReference) {
if (!parameter.IsIn && parameter.IsOut)
p.IsOut = true;
else
@ -1505,18 +1434,19 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1505,18 +1434,19 @@ namespace ICSharpCode.Decompiler.TypeSystem
return new decimal((int)ctorArgs[4], (int)ctorArgs[3], (int)ctorArgs[2], (byte)ctorArgs[1] != 0, (byte)ctorArgs[0]);
}
public IUnresolvedField ReadField(FieldDefinition field, IUnresolvedTypeDefinition parentType)
public IUnresolvedField ReadField(FieldDefinitionHandle handle, IUnresolvedTypeDefinition parentType)
{
if (field == null)
throw new ArgumentNullException("field");
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
if (parentType == null)
throw new ArgumentNullException("parentType");
DefaultUnresolvedField f = new DefaultUnresolvedField(parentType, field.Name);
throw new ArgumentNullException(nameof(parentType));
var field = currentModule.GetFieldDefinition(handle);
DefaultUnresolvedField f = new DefaultUnresolvedField(parentType, currentModule.GetString(field.Name));
f.Accessibility = GetAccessibility(field.Attributes);
f.IsReadOnly = field.IsInitOnly;
f.IsStatic = field.IsStatic;
f.ReturnType = ReadTypeReference(field.FieldType, typeAttributes: field);
f.IsReadOnly = (field.Attributes & FieldAttributes.InitOnly) == FieldAttributes.InitOnly;
f.IsStatic = (field.Attributes & FieldAttributes.Static) == FieldAttributes.Static;
f.ReturnType = field.DecodeSignature(new TypeReferenceSignatureDecoder(), default(Unit));
if (field.HasConstant) {
f.ConstantValue = CreateSimpleConstantValue(f.ReturnType, field.Constant);
}
@ -1570,14 +1500,13 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1570,14 +1500,13 @@ namespace ICSharpCode.Decompiler.TypeSystem
break;
}
tp.HasReferenceTypeConstraint = g.HasReferenceTypeConstraint;
tp.HasValueTypeConstraint = g.HasNotNullableValueTypeConstraint;
tp.HasDefaultConstructorConstraint = g.HasDefaultConstructorConstraint;
tp.HasReferenceTypeConstraint = (g.Attributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0;
tp.HasValueTypeConstraint = (g.Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0;
tp.HasDefaultConstructorConstraint = (g.Attributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0;
if (g.HasConstraints) {
foreach (TypeReference constraint in g.Constraints) {
tp.Constraints.Add(ReadTypeReference(constraint));
}
foreach (GenericParameterConstraintHandle h in g.GetConstraints()) {
var constraint = currentModule.GetGenericParameterConstraint(h);
tp.Constraints.Add(ReadTypeReference(constraint.Type));
}
}
#endregion
@ -1608,67 +1537,90 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1608,67 +1537,90 @@ namespace ICSharpCode.Decompiler.TypeSystem
return left;
}
public IUnresolvedProperty ReadProperty(PropertyDefinition property, IUnresolvedTypeDefinition parentType, SymbolKind propertyType = SymbolKind.Property)
public IUnresolvedProperty ReadProperty(PropertyDefinitionHandle handle, IUnresolvedTypeDefinition parentType, SymbolKind propertyType = SymbolKind.Property)
{
if (property == null)
throw new ArgumentNullException("property");
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
if (parentType == null)
throw new ArgumentNullException("parentType");
DefaultUnresolvedProperty p = new DefaultUnresolvedProperty(parentType, property.Name);
throw new ArgumentNullException(nameof(parentType));
var property = currentModule.GetPropertyDefinition(handle);
var propertyName = currentModule.GetString(property.Name);
DefaultUnresolvedProperty p = new DefaultUnresolvedProperty(parentType, propertyName);
p.SymbolKind = propertyType;
TranslateModifiers(property.GetMethod ?? property.SetMethod, p);
if (property.GetMethod != null && property.SetMethod != null)
p.Accessibility = MergePropertyAccessibility (GetAccessibility (property.GetMethod.Attributes), GetAccessibility (property.SetMethod.Attributes));
var accessors = property.GetAccessors();
TranslateModifiers(accessors.Getter.IsNil ? accessors.Setter : accessors.Getter, p);
if (!accessors.Getter.IsNil && !accessors.Setter.IsNil)
p.Accessibility = MergePropertyAccessibility(GetAccessibility(currentModule.GetMethodDefinition(accessors.Getter).Attributes), GetAccessibility (currentModule.GetMethodDefinition(accessors.Setter).Attributes));
p.ReturnType = ReadTypeReference(property.PropertyType, typeAttributes: property);
p.Getter = ReadMethod(property.GetMethod, parentType, SymbolKind.Accessor, p);
p.Setter = ReadMethod(property.SetMethod, parentType, SymbolKind.Accessor, p);
var signature = property.DecodeSignature(new TypeReferenceSignatureDecoder(), default(Unit));
p.ReturnType = signature.ReturnType;
if (property.HasParameters) {
foreach (ParameterDefinition par in property.Parameters) {
p.Parameters.Add(ReadParameter(par));
p.Getter = ReadMethod(accessors.Getter, parentType, SymbolKind.Accessor, p);
p.Setter = ReadMethod(accessors.Setter, parentType, SymbolKind.Accessor, p);
ParameterHandleCollection parameterHandles = default(ParameterHandleCollection);
int parameterCount = 0;
if (!accessors.Getter.IsNil) {
var getter = currentModule.GetMethodDefinition(accessors.Getter);
parameterHandles = getter.GetParameters();
parameterCount = parameterHandles.Count;
} else {
if (!accessors.Setter.IsNil) {
var setter = currentModule.GetMethodDefinition(accessors.Setter);
parameterHandles = setter.GetParameters();
parameterCount = parameterHandles.Count - 1;
}
}
int i = 0;
foreach (var par in parameterHandles) {
if (i >= parameterCount) break;
p.Parameters.Add(ReadParameter(par, signature.ParameterTypes[i]));
i++;
}
AddAttributes(property, p);
var accessor = p.Getter ?? p.Setter;
if (accessor != null && accessor.IsExplicitInterfaceImplementation) {
if (ShortenInterfaceImplNames)
p.Name = property.Name.Substring(property.Name.LastIndexOf('.') + 1);
p.Name = propertyName.Substring(propertyName.LastIndexOf('.') + 1);
p.IsExplicitInterfaceImplementation = true;
foreach (var mr in accessor.ExplicitInterfaceImplementations) {
p.ExplicitInterfaceImplementations.Add(new AccessorOwnerMemberReference(mr));
}
}
FinishReadMember(p, property);
FinishReadMember(p, handle);
return p;
}
#endregion
#region Read Event
public IUnresolvedEvent ReadEvent(EventDefinition ev, IUnresolvedTypeDefinition parentType)
public IUnresolvedEvent ReadEvent(EventDefinitionHandle ev, IUnresolvedTypeDefinition parentType)
{
if (ev == null)
throw new ArgumentNullException("ev");
if (ev.IsNil)
throw new ArgumentNullException(nameof(ev));
if (parentType == null)
throw new ArgumentNullException("parentType");
DefaultUnresolvedEvent e = new DefaultUnresolvedEvent(parentType, ev.Name);
TranslateModifiers(ev.AddMethod, e);
e.ReturnType = ReadTypeReference(ev.EventType, typeAttributes: ev);
throw new ArgumentNullException(nameof(parentType));
var ed = currentModule.GetEventDefinition(ev);
var eventName = currentModule.GetString(ed.Name);
DefaultUnresolvedEvent e = new DefaultUnresolvedEvent(parentType, eventName);
var accessors = ed.GetAccessors();
TranslateModifiers(accessors.Adder, e);
e.ReturnType = ReadTypeReference(ed.Type, typeAttributes: ed.GetCustomAttributes());
e.AddAccessor = ReadMethod(ev.AddMethod, parentType, SymbolKind.Accessor, e);
e.RemoveAccessor = ReadMethod(ev.RemoveMethod, parentType, SymbolKind.Accessor, e);
e.InvokeAccessor = ReadMethod(ev.InvokeMethod, parentType, SymbolKind.Accessor, e);
e.AddAccessor = ReadMethod(accessors.Adder, parentType, SymbolKind.Accessor, e);
e.RemoveAccessor = ReadMethod(accessors.Remover, parentType, SymbolKind.Accessor, e);
e.InvokeAccessor = ReadMethod(accessors.Raiser, parentType, SymbolKind.Accessor, e);
AddAttributes(ev, e);
AddAttributes(ed, e);
var accessor = e.AddAccessor ?? e.RemoveAccessor ?? e.InvokeAccessor;
if (accessor != null && accessor.IsExplicitInterfaceImplementation) {
if (ShortenInterfaceImplNames)
e.Name = ev.Name.Substring(ev.Name.LastIndexOf('.') + 1);
e.Name = eventName.Substring(eventName.LastIndexOf('.') + 1);
e.IsExplicitInterfaceImplementation = true;
foreach (var mr in accessor.ExplicitInterfaceImplementations) {
e.ExplicitInterfaceImplementations.Add(new AccessorOwnerMemberReference(mr));
@ -1682,7 +1634,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1682,7 +1634,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
#endregion
#region FinishReadMember / Interning
void FinishReadMember(AbstractUnresolvedMember member, MemberReference cecilDefinition)
void FinishReadMember(AbstractUnresolvedMember member, EntityHandle cecilDefinition)
{
member.ApplyInterningProvider(interningProvider);
member.Freeze();
@ -1691,17 +1643,16 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1691,17 +1643,16 @@ namespace ICSharpCode.Decompiler.TypeSystem
#endregion
#region Type system translation table
readonly Dictionary<object, object> typeSystemTranslationTable;
readonly Dictionary<object, EntityHandle> typeSystemTranslationTable;
void RegisterCecilObject(IUnresolvedEntity typeSystemObject, MemberReference cecilObject)
void RegisterCecilObject(IUnresolvedEntity typeSystemObject, EntityHandle cecilObject)
{
if (OnEntityLoaded != null)
OnEntityLoaded(typeSystemObject, cecilObject);
OnEntityLoaded?.Invoke(typeSystemObject, cecilObject);
AddToTypeSystemTranslationTable(typeSystemObject, cecilObject);
}
void AddToTypeSystemTranslationTable(object typeSystemObject, object cecilObject)
void AddToTypeSystemTranslationTable(object typeSystemObject, EntityHandle cecilObject)
{
if (typeSystemTranslationTable != null) {
// When lazy-loading, the dictionary might be shared between multiple cecil-loaders that are used concurrently
@ -1717,7 +1668,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1717,7 +1668,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
throw new ArgumentNullException ("typeSystemObject");
if (!HasCecilReferences)
throw new NotSupportedException ("This instance contains no cecil references.");
object result;
EntityHandle result;
lock (typeSystemTranslationTable) {
if (!typeSystemTranslationTable.TryGetValue (typeSystemObject, out result))
return null;

4
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -23,7 +23,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -23,7 +23,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// CecilLoader used for converting cecil type references to ITypeReference.
/// May only be accessed within lock(typeReferenceCecilLoader).
/// </summary>
readonly CecilLoader typeReferenceCecilLoader = new CecilLoader();
readonly MetadataLoader typeReferenceCecilLoader = new MetadataLoader();
/// <summary>
/// Dictionary for NRefactory->Cecil lookup.
@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
if (moduleDefinition == null)
throw new ArgumentNullException(nameof(moduleDefinition));
this.moduleDefinition = moduleDefinition;
CecilLoader cecilLoader = new CecilLoader { IncludeInternalMembers = true, LazyLoad = true, OnEntityLoaded = StoreMemberReference, ShortenInterfaceImplNames = false };
MetadataLoader cecilLoader = new MetadataLoader { IncludeInternalMembers = true, LazyLoad = true, OnEntityLoaded = StoreMemberReference, ShortenInterfaceImplNames = false };
typeReferenceCecilLoader.SetCurrentModule(moduleDefinition);
IUnresolvedAssembly mainAssembly = cecilLoader.LoadModule(moduleDefinition);
// Load referenced assemblies and type-forwarder references.

6
ICSharpCode.Decompiler/TypeSystem/IAssembly.cs

@ -35,12 +35,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -35,12 +35,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
string FullAssemblyName { get; }
/// <summary>
/// Gets the path to the assembly location.
/// For projects it is the same as the output path.
/// </summary>
string Location { get; }
/// <summary>
/// Gets the list of all assembly attributes in the project.
/// </summary>

11
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs

@ -98,17 +98,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -98,17 +98,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
fullAssemblyName = value;
}
}
string location;
public string Location {
get {
return location;
}
set {
FreezableHelper.ThrowIfFrozen(this);
location = value;
}
}
public IList<IUnresolvedAttribute> AssemblyAttributes {
get { return assemblyAttributes; }

214
ICSharpCode.Decompiler/TypeSystem/Implementation/TypeSpecification.cs

@ -0,0 +1,214 @@ @@ -0,0 +1,214 @@
// Copyright (c) 2017 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.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{
class SignatureTypeReference : ITypeReference
{
readonly TypeSpecification typeSpecification;
readonly MetadataReader reader;
public SignatureTypeReference(TypeSpecificationHandle handle, MetadataReader reader)
{
this.typeSpecification = reader.GetTypeSpecification(handle);
this.reader = reader;
}
public IType Resolve(ITypeResolveContext context)
{
return typeSpecification.DecodeSignature(new TypeReferenceSignatureDecoder(), default(Unit)).Resolve(context);
}
}
public sealed class PinnedType : TypeWithElementType
{
public PinnedType(IType elementType)
: base(elementType)
{
}
public override string NameSuffix => " pinned";
public override bool? IsReferenceType => elementType.IsReferenceType;
public override TypeKind Kind => TypeKind.Other;
public override ITypeReference ToTypeReference()
{
return new PinnedTypeReference(elementType.ToTypeReference());
}
public override IType VisitChildren(TypeVisitor visitor)
{
var newType = elementType.AcceptVisitor(visitor);
if (newType == elementType)
return this;
return new PinnedType(newType);
}
}
public sealed class PinnedTypeReference : ITypeReference
{
readonly ITypeReference elementType;
public PinnedTypeReference(ITypeReference elementType)
{
this.elementType = elementType;
}
public IType Resolve(ITypeResolveContext context)
{
return new PinnedType(elementType.Resolve(context));
}
}
public struct Unit { }
class TypeReferenceSignatureDecoder : ISignatureTypeProvider<ITypeReference, Unit>
{
public ITypeReference GetArrayType(ITypeReference elementType, ArrayShape shape)
{
return new ArrayTypeReference(elementType, shape.Rank);
}
public ITypeReference GetByReferenceType(ITypeReference elementType)
{
return new ByReferenceTypeReference(elementType);
}
public ITypeReference GetFunctionPointerType(MethodSignature<ITypeReference> signature)
{
return KnownTypeReference.IntPtr;
}
public ITypeReference GetGenericInstantiation(ITypeReference genericType, ImmutableArray<ITypeReference> typeArguments)
{
return new ParameterizedTypeReference(genericType, typeArguments);
}
public ITypeReference GetGenericMethodParameter(Unit genericContext, int index)
{
return new TypeParameterReference(SymbolKind.Method, index);
}
public ITypeReference GetGenericTypeParameter(Unit genericContext, int index)
{
return new TypeParameterReference(SymbolKind.TypeDefinition, index);
}
public ITypeReference GetModifiedType(ITypeReference modifier, ITypeReference unmodifiedType, bool isRequired)
{
return unmodifiedType;
}
public ITypeReference GetPinnedType(ITypeReference elementType)
{
return new PinnedTypeReference(elementType);
}
public ITypeReference GetPointerType(ITypeReference elementType)
{
return new PointerTypeReference(elementType);
}
public ITypeReference GetPrimitiveType(PrimitiveTypeCode typeCode)
{
return KnownTypeReference.Get(typeCode.ToKnownTypeCode());
}
public ITypeReference GetSZArrayType(ITypeReference elementType)
{
return new ArrayTypeReference(elementType);
}
public ITypeReference GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
return new DefaultUnresolvedTypeDefinition(handle.GetFullTypeName(reader).ReflectionName);
}
public ITypeReference GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
var asmref = handle.GetDeclaringAssembly(reader);
if (asmref.IsNil)
return new GetClassTypeReference(handle.GetFullTypeName(reader), DefaultAssemblyReference.CurrentAssembly);
var asm = reader.GetAssemblyReference(asmref);
return new GetClassTypeReference(handle.GetFullTypeName(reader), new DefaultAssemblyReference(reader.GetString(asm.Name)));
}
public ITypeReference GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
{
return new SignatureTypeReference(handle, reader);
}
}
class TypeSystemAttributeTypeProvider : ICustomAttributeTypeProvider<ITypeReference>
{
public ITypeReference GetPrimitiveType(PrimitiveTypeCode typeCode)
{
return KnownTypeReference.Get(typeCode.ToKnownTypeCode());
}
public ITypeReference GetSystemType()
{
return KnownTypeReference.Get(KnownTypeCode.Type);
}
public ITypeReference GetSZArrayType(ITypeReference elementType)
{
return new ArrayTypeReference(elementType);
}
public ITypeReference GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
var type = reader.GetTypeDefinition(handle);
return new DefaultUnresolvedTypeDefinition(type.GetFullTypeName(reader).ToString());
}
public ITypeReference GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
return new DefaultUnresolvedTypeDefinition(handle.GetFullTypeName(reader).ToString());
}
public ITypeReference GetTypeFromSerializedName(string name)
{
return new GetClassTypeReference(new FullTypeName(name));
}
public PrimitiveTypeCode GetUnderlyingEnumType(ITypeReference type)
{
var def = type.GetEnumUnderlyingType().GetDefinition();
if (def == null)
throw new InvalidOperationException();
return def.KnownTypeCode.ToPrimtiveTypeCode();
}
public bool IsSystemType(IType type)
{
return type.IsKnownType(KnownTypeCode.Type);
}
}
}

13
ICSharpCode.Decompiler/TypeSystem/KnownTypeReference.cs

@ -123,6 +123,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -123,6 +123,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
INotifyCompletion,
/// <summary><c>System.Runtime.CompilerServices.ICriticalNotifyCompletion</c></summary>
ICriticalNotifyCompletion,
/// <summary><c>System.TypedReference</c></summary>
TypedReference,
}
/// <summary>
@ -131,8 +133,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -131,8 +133,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
[Serializable]
public sealed class KnownTypeReference : ITypeReference
{
internal const int KnownTypeCodeCount = (int)KnownTypeCode.ICriticalNotifyCompletion + 1;
internal const int KnownTypeCodeCount = (int)KnownTypeCode.TypedReference + 1;
static readonly KnownTypeReference[] knownTypeReferences = new KnownTypeReference[KnownTypeCodeCount] {
null, // None
new KnownTypeReference(KnownTypeCode.Object, "System", "Object", baseType: KnownTypeCode.None),
@ -181,6 +183,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -181,6 +183,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
new KnownTypeReference(KnownTypeCode.IDisposable, "System", "IDisposable"),
new KnownTypeReference(KnownTypeCode.INotifyCompletion, "System.Runtime.CompilerServices", "INotifyCompletion"),
new KnownTypeReference(KnownTypeCode.ICriticalNotifyCompletion, "System.Runtime.CompilerServices", "ICriticalNotifyCompletion"),
new KnownTypeReference(KnownTypeCode.TypedReference, "System", "TypedReference", baseType: KnownTypeCode.ValueType),
};
/// <summary>
@ -411,6 +415,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -411,6 +415,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// Gets a type reference pointing to the <c>System.Runtime.CompilerServices.ICriticalNotifyCompletion</c> type.
/// </summary>
public static readonly KnownTypeReference ICriticalNotifyCompletion = Get(KnownTypeCode.ICriticalNotifyCompletion);
/// <summary>
/// Gets a type reference pointing to the <c>System.TypedReference</c> type.
/// </summary>
public static readonly KnownTypeReference TypedReference = Get(KnownTypeCode.TypedReference);
readonly KnownTypeCode knownTypeCode;
readonly string namespaceName;

199
ICSharpCode.Decompiler/TypeSystem/MetadataExtensions.cs

@ -0,0 +1,199 @@ @@ -0,0 +1,199 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
namespace ICSharpCode.Decompiler.TypeSystem
{
static class MetadataExtensions
{
/// <summary>
/// Gets the type of the attribute.
/// </summary>
/// <returns>Either <see cref="TypeDefinitionHandle"/>, <see cref="TypeReferenceHandle"/>,<see cref="TypeSpecificationHandle".</returns>
public static EntityHandle GetAttributeType(this CustomAttribute attribute, MetadataReader reader)
{
switch (attribute.Constructor.Kind) {
case HandleKind.MethodDefinition:
var md = reader.GetMethodDefinition((MethodDefinitionHandle)attribute.Constructor);
return md.GetDeclaringType();
case HandleKind.MemberReference:
var mr = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor);
return mr.Parent;
default:
throw new NotSupportedException();
}
}
public static FullTypeName GetFullTypeName(this EntityHandle handle, MetadataReader reader)
{
switch (handle.Kind) {
case HandleKind.TypeDefinition:
return ((TypeDefinitionHandle)handle).GetFullTypeName(reader);
case HandleKind.TypeReference:
return ((TypeReferenceHandle)handle).GetFullTypeName(reader);
default:
throw new NotSupportedException();
}
}
public static FullTypeName GetFullTypeName(this TypeReferenceHandle handle, MetadataReader reader)
{
var tr = reader.GetTypeReference(handle);
TypeReferenceHandle declaringTypeHandle;
if ((declaringTypeHandle = tr.GetDeclaringType()).IsNil) {
string @namespace = tr.Namespace.IsNil ? "" : reader.GetString(tr.Namespace);
return new FullTypeName(new TopLevelTypeName(@namespace, reader.GetString(tr.Name)));
} else {
return declaringTypeHandle.GetFullTypeName(reader).NestedType(reader.GetString(tr.Name), 0);
}
}
public static FullTypeName GetFullTypeName(this TypeDefinitionHandle handle, MetadataReader reader)
{
return reader.GetTypeDefinition(handle).GetFullTypeName(reader);
}
public static FullTypeName GetFullTypeName(this TypeDefinition td, MetadataReader reader)
{
TypeDefinitionHandle declaringTypeHandle;
if ((declaringTypeHandle = td.GetDeclaringType()).IsNil) {
string @namespace = td.Namespace.IsNil ? "" : reader.GetString(td.Namespace);
return new FullTypeName(new TopLevelTypeName(@namespace, reader.GetString(td.Name), td.GetGenericParameters().Count));
} else {
return declaringTypeHandle.GetFullTypeName(reader).NestedType(reader.GetString(td.Name), td.GetGenericParameters().Count);
}
}
public static TypeReferenceHandle GetDeclaringType(this TypeReference tr)
{
switch (tr.ResolutionScope.Kind) {
case HandleKind.TypeReference:
return (TypeReferenceHandle)tr.ResolutionScope;
default:
return default(TypeReferenceHandle);
}
}
public static AssemblyReferenceHandle GetDeclaringAssembly(this TypeReferenceHandle handle, MetadataReader reader)
{
var tr = reader.GetTypeReference(handle);
switch (tr.ResolutionScope.Kind) {
case HandleKind.TypeReference:
return ((TypeReferenceHandle)tr.ResolutionScope).GetDeclaringAssembly(reader);
case HandleKind.AssemblyReference:
return (AssemblyReferenceHandle)tr.ResolutionScope;
default:
return default(AssemblyReferenceHandle);
}
}
public static bool IsValueType(this TypeDefinition typeDefinition, MetadataReader reader)
{
if (typeDefinition.BaseType.IsNil)
return false;
var baseType = typeDefinition.BaseType.GetFullTypeName(reader).ToString();
if (baseType == "System.Enum")
return true;
var thisType = typeDefinition.GetFullTypeName(reader).ToString();
return baseType == "System.ValueType" && thisType != "System.Enum";
}
public static bool IsEnum(this TypeDefinition typeDefinition, MetadataReader reader)
{
if (typeDefinition.BaseType.IsNil)
return false;
return typeDefinition.BaseType.GetFullTypeName(reader).ToString() == "System.Enum";
}
public static PrimitiveTypeCode ToPrimtiveTypeCode(this KnownTypeCode typeCode)
{
switch (typeCode) {
case KnownTypeCode.Object:
return PrimitiveTypeCode.Object;
case KnownTypeCode.Boolean:
return PrimitiveTypeCode.Boolean;
case KnownTypeCode.Char:
return PrimitiveTypeCode.Char;
case KnownTypeCode.SByte:
return PrimitiveTypeCode.SByte;
case KnownTypeCode.Byte:
return PrimitiveTypeCode.Byte;
case KnownTypeCode.Int16:
return PrimitiveTypeCode.Int16;
case KnownTypeCode.UInt16:
return PrimitiveTypeCode.UInt16;
case KnownTypeCode.Int32:
return PrimitiveTypeCode.Int32;
case KnownTypeCode.UInt32:
return PrimitiveTypeCode.UInt32;
case KnownTypeCode.Int64:
return PrimitiveTypeCode.Int64;
case KnownTypeCode.UInt64:
return PrimitiveTypeCode.UInt64;
case KnownTypeCode.Single:
return PrimitiveTypeCode.Single;
case KnownTypeCode.Double:
return PrimitiveTypeCode.Double;
case KnownTypeCode.String:
return PrimitiveTypeCode.String;
case KnownTypeCode.Void:
return PrimitiveTypeCode.Void;
case KnownTypeCode.TypedReference:
return PrimitiveTypeCode.TypedReference;
case KnownTypeCode.IntPtr:
return PrimitiveTypeCode.IntPtr;
case KnownTypeCode.UIntPtr:
return PrimitiveTypeCode.UIntPtr;
default:
throw new NotSupportedException();
}
}
public static KnownTypeCode ToKnownTypeCode(this PrimitiveTypeCode typeCode)
{
switch (typeCode) {
case PrimitiveTypeCode.Boolean:
return KnownTypeCode.Boolean;
case PrimitiveTypeCode.Byte:
return KnownTypeCode.Byte;
case PrimitiveTypeCode.SByte:
return KnownTypeCode.SByte;
case PrimitiveTypeCode.Char:
return KnownTypeCode.Byte;
case PrimitiveTypeCode.Int16:
return KnownTypeCode.Byte;
case PrimitiveTypeCode.UInt16:
return KnownTypeCode.Byte;
case PrimitiveTypeCode.Int32:
return KnownTypeCode.Int32;
case PrimitiveTypeCode.UInt32:
return KnownTypeCode.UInt32;
case PrimitiveTypeCode.Int64:
return KnownTypeCode.Int64;
case PrimitiveTypeCode.UInt64:
return KnownTypeCode.UInt64;
case PrimitiveTypeCode.Single:
return KnownTypeCode.Single;
case PrimitiveTypeCode.Double:
return KnownTypeCode.Double;
case PrimitiveTypeCode.IntPtr:
return KnownTypeCode.IntPtr;
case PrimitiveTypeCode.UIntPtr:
return KnownTypeCode.UIntPtr;
case PrimitiveTypeCode.Object:
return KnownTypeCode.Object;
case PrimitiveTypeCode.String:
return KnownTypeCode.String;
case PrimitiveTypeCode.TypedReference:
return KnownTypeCode.TypedReference;
case PrimitiveTypeCode.Void:
return KnownTypeCode.Void;
default:
return KnownTypeCode.None;
}
}
}
}

65
ILSpy/Cecil/CecilExtensions.cs

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
// 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 ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
using Mono.Cecil.Cil;
using ArrayType = Mono.Cecil.ArrayType;
namespace ICSharpCode.ILSpy.Cecil
{
/// <summary>
/// Cecil helper methods.
/// </summary>
public static class CecilExtensions
{
public static HashSet<MethodDefinition> GetAccessorMethods(this TypeDefinition type)
{
HashSet<MethodDefinition> accessorMethods = new HashSet<MethodDefinition>();
foreach (var property in type.Properties) {
accessorMethods.Add(property.GetMethod);
accessorMethods.Add(property.SetMethod);
if (property.HasOtherMethods) {
foreach (var m in property.OtherMethods)
accessorMethods.Add(m);
}
}
foreach (EventDefinition ev in type.Events) {
accessorMethods.Add(ev.AddMethod);
accessorMethods.Add(ev.RemoveMethod);
accessorMethods.Add(ev.InvokeMethod);
if (ev.HasOtherMethods) {
foreach (var m in ev.OtherMethods)
accessorMethods.Add(m);
}
}
return accessorMethods;
}
public static TypeDefinition ResolveWithinSameModule(this TypeReference type)
{
if (type != null && type.GetElementType().Module == type.Module)
return type.Resolve();
else
return null;
}
}
}

2
ICSharpCode.Decompiler/TypeSystem/TypesHierarchyHelpers.cs → ILSpy/Cecil/TypesHierarchyHelpers.cs

@ -22,7 +22,7 @@ using System.Collections.ObjectModel; @@ -22,7 +22,7 @@ using System.Collections.ObjectModel;
using System.Linq;
using Mono.Cecil;
namespace ICSharpCode.Decompiler.TypeSystem
namespace ICSharpCode.ILSpy.Cecil
{
public static class TypesHierarchyHelpers
{

2
ILSpy/ILSpy.csproj

@ -75,6 +75,8 @@ @@ -75,6 +75,8 @@
<Compile Include="AssemblyListManager.cs" />
<Compile Include="AvalonEdit\ITextMarker.cs" />
<Compile Include="AvalonEdit\TextMarkerService.cs" />
<Compile Include="Cecil\CecilExtensions.cs" />
<Compile Include="Cecil\TypesHierarchyHelpers.cs" />
<Compile Include="Commands\CheckForUpdatesCommand.cs" />
<Compile Include="Commands\BrowseBackCommand.cs" />
<Compile Include="Commands\BrowseForwardCommand.cs" />

2
ILSpy/Languages/CSharpILMixedLanguage.cs

@ -21,6 +21,7 @@ using Mono.Cecil.Cil; @@ -21,6 +21,7 @@ using Mono.Cecil.Cil;
namespace ICSharpCode.ILSpy
{
#if false
[Export(typeof(Language))]
class CSharpILMixedLanguage : ILLanguage
{
@ -145,4 +146,5 @@ namespace ICSharpCode.ILSpy @@ -145,4 +146,5 @@ namespace ICSharpCode.ILSpy
}
}
}
#endif
}

2
ILSpy/Languages/ILAstLanguage.cs

@ -77,7 +77,7 @@ namespace ICSharpCode.ILSpy @@ -77,7 +77,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
{
base.DecompileMethod(method, output, options);
new ReflectionDisassembler(output, options.CancellationToken).DisassembleMethodHeader(method);
//new ReflectionDisassembler(output, options.CancellationToken).DisassembleMethodHeader(method);
output.WriteLine();
output.WriteLine();
}

132
ILSpy/Languages/ILLanguage.cs

@ -19,8 +19,12 @@ @@ -19,8 +19,12 @@
using System.Collections.Generic;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using Mono.Cecil;
using System.ComponentModel.Composition;
using System.Reflection.PortableExecutable;
using System.Reflection.Metadata;
using System.IO;
using System.Reflection.Metadata.Ecma335;
using System.Linq;
namespace ICSharpCode.ILSpy
{
@ -44,95 +48,111 @@ namespace ICSharpCode.ILSpy @@ -44,95 +48,111 @@ namespace ICSharpCode.ILSpy
get { return ".il"; }
}
protected virtual ReflectionDisassembler CreateDisassembler(ITextOutput output, DecompilationOptions options)
protected virtual ReflectionDisassembler CreateDisassembler(ITextOutput output, PEReader reader, DecompilationOptions options)
{
return new ReflectionDisassembler(output, options.CancellationToken) {
return new ReflectionDisassembler(output, reader, options.CancellationToken) {
DetectControlStructure = detectControlStructure,
ShowSequencePoints = options.DecompilerSettings.ShowDebugInfo
};
}
public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
public override void DecompileMethod(Mono.Cecil.MethodDefinition method, ITextOutput output, DecompilationOptions options)
{
var dis = CreateDisassembler(output, options);
dis.DisassembleMethod(method);
using (var reader = new PEReader(new FileStream(method.Module.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(method.MetadataToken.ToInt32()));
}
}
public override void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options)
public override void DecompileField(Mono.Cecil.FieldDefinition field, ITextOutput output, DecompilationOptions options)
{
var dis = CreateDisassembler(output, options);
dis.DisassembleField(field);
using (var reader = new PEReader(new FileStream(field.Module.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
dis.DisassembleField(MetadataTokens.FieldDefinitionHandle(field.MetadataToken.ToInt32()));
}
}
public override void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options)
public override void DecompileProperty(Mono.Cecil.PropertyDefinition property, ITextOutput output, DecompilationOptions options)
{
ReflectionDisassembler rd = CreateDisassembler(output, options);
rd.DisassembleProperty(property);
if (property.GetMethod != null) {
output.WriteLine();
rd.DisassembleMethod(property.GetMethod);
}
if (property.SetMethod != null) {
output.WriteLine();
rd.DisassembleMethod(property.SetMethod);
}
foreach (var m in property.OtherMethods) {
output.WriteLine();
rd.DisassembleMethod(m);
using (var reader = new PEReader(new FileStream(property.Module.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
dis.DisassembleProperty(MetadataTokens.PropertyDefinitionHandle(property.MetadataToken.ToInt32()));
if (property.GetMethod != null) {
output.WriteLine();
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(property.GetMethod.MetadataToken.ToInt32()));
}
if (property.SetMethod != null) {
output.WriteLine();
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(property.SetMethod.MetadataToken.ToInt32()));
}
foreach (var m in property.OtherMethods) {
output.WriteLine();
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(m.MetadataToken.ToInt32()));
}
}
}
public override void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options)
public override void DecompileEvent(Mono.Cecil.EventDefinition ev, ITextOutput output, DecompilationOptions options)
{
ReflectionDisassembler rd = CreateDisassembler(output, options);
rd.DisassembleEvent(ev);
if (ev.AddMethod != null) {
output.WriteLine();
rd.DisassembleMethod(ev.AddMethod);
}
if (ev.RemoveMethod != null) {
output.WriteLine();
rd.DisassembleMethod(ev.RemoveMethod);
}
foreach (var m in ev.OtherMethods) {
output.WriteLine();
rd.DisassembleMethod(m);
using (var reader = new PEReader(new FileStream(ev.Module.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
dis.DisassembleEvent(MetadataTokens.EventDefinitionHandle(ev.MetadataToken.ToInt32()));
if (ev.AddMethod != null) {
output.WriteLine();
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(ev.AddMethod.MetadataToken.ToInt32()));
}
if (ev.RemoveMethod != null) {
output.WriteLine();
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(ev.RemoveMethod.MetadataToken.ToInt32()));
}
foreach (var m in ev.OtherMethods) {
output.WriteLine();
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(m.MetadataToken.ToInt32()));
}
}
}
public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options)
public override void DecompileType(Mono.Cecil.TypeDefinition type, ITextOutput output, DecompilationOptions options)
{
var dis = CreateDisassembler(output, options);
dis.DisassembleType(type);
using (var reader = new PEReader(new FileStream(type.Module.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
dis.DisassembleType(MetadataTokens.TypeDefinitionHandle(type.MetadataToken.ToInt32()));
}
}
public override void DecompileNamespace(string nameSpace, IEnumerable<TypeDefinition> types, ITextOutput output, DecompilationOptions options)
public override void DecompileNamespace(string nameSpace, IEnumerable<Mono.Cecil.TypeDefinition> types, ITextOutput output, DecompilationOptions options)
{
var dis = CreateDisassembler(output, options);
dis.DisassembleNamespace(nameSpace, types);
if (!types.Any())
return;
using (var reader = new PEReader(new FileStream(types.First().Module.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
dis.DisassembleNamespace(nameSpace, types.Select(t => MetadataTokens.TypeDefinitionHandle(t.MetadataToken.ToInt32())));
}
}
public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{
output.WriteLine("// " + assembly.FileName);
output.WriteLine();
var dis = CreateDisassembler(output, options);
var module = assembly.GetModuleDefinitionAsync().Result;
if (options.FullDecompilation)
dis.WriteAssemblyReferences(module);
if (module.Assembly != null)
dis.WriteAssemblyHeader(module.Assembly);
output.WriteLine();
dis.WriteModuleHeader(module);
if (options.FullDecompilation) {
output.WriteLine();
using (var reader = new PEReader(new FileStream(assembly.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
var module = assembly.GetModuleDefinitionAsync().Result;
if (options.FullDecompilation)
dis.WriteAssemblyReferences();
if (module.Assembly != null)
dis.WriteAssemblyHeader();
output.WriteLine();
dis.WriteModuleContents(module);
dis.WriteModuleHeader();
if (options.FullDecompilation) {
output.WriteLine();
output.WriteLine();
dis.WriteModuleContents(reader.GetMetadataReader().GetModuleDefinition());
}
}
}
public override string TypeToString(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes = null)
public override string TypeToString(Mono.Cecil.TypeReference type, bool includeNamespace, Mono.Cecil.ICustomAttributeProvider typeAttributes = null)
{
PlainTextOutput output = new PlainTextOutput();
type.WriteTo(output, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName);

5
ILSpy/MainWindow.xaml.cs

@ -633,9 +633,8 @@ namespace ICSharpCode.ILSpy @@ -633,9 +633,8 @@ namespace ICSharpCode.ILSpy
ILSpyTreeNode treeNode = FindTreeNode(reference);
if (treeNode != null) {
SelectNode(treeNode);
} else if (reference is Mono.Cecil.Cil.OpCode) {
string link = "http://msdn.microsoft.com/library/system.reflection.emit.opcodes." + ((Mono.Cecil.Cil.OpCode)reference).Code.ToString().ToLowerInvariant() + ".aspx";
OpenLink(link);
} else if (reference is ICSharpCode.Decompiler.Disassembler.OpCodeInfo opCode) {
OpenLink(opCode.Link);
}
return decompilationTask;
}

11
ILSpy/TextView/DecompilerTextView.cs

@ -194,21 +194,18 @@ namespace ICSharpCode.ILSpy.TextView @@ -194,21 +194,18 @@ namespace ICSharpCode.ILSpy.TextView
object GenerateTooltip(ReferenceSegment segment)
{
if (segment.Reference is Mono.Cecil.Cil.OpCode) {
Mono.Cecil.Cil.OpCode code = (Mono.Cecil.Cil.OpCode)segment.Reference;
string encodedName = code.Code.ToString();
string opCodeHex = code.Size > 1 ? string.Format("0x{0:x2}{1:x2}", code.Op1, code.Op2) : string.Format("0x{0:x2}", code.Op2);
if (segment.Reference is ICSharpCode.Decompiler.Disassembler.OpCodeInfo code) {
XmlDocumentationProvider docProvider = XmlDocLoader.MscorlibDocumentation;
if (docProvider != null){
string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + encodedName);
string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + code.EncodedName);
if (documentation != null) {
XmlDocRenderer renderer = new XmlDocRenderer();
renderer.AppendText(string.Format("{0} ({1}) - ", code.Name, opCodeHex));
renderer.AppendText($"{code.Name} (0x{code.Code:x2}) - ");
renderer.AddXmlDocumentation(documentation);
return renderer.CreateTextBlock();
}
}
return string.Format("{0} ({1})", code.Name, opCodeHex);
return $"{code.Name} (0x{code.Code:x2})";
} else if (segment.Reference is MemberReference) {
MemberReference mr = (MemberReference)segment.Reference;
// if possible, resolve the reference

Loading…
Cancel
Save