mirror of
https://github.com/icsharpcode/ILSpy.git
synced 2026-10-12 02:15:58 +00:00
Finished port of UI (Analyzers still excluded) and Disassembler
This commit is contained in:
@@ -36,7 +36,6 @@ using ICSharpCode.Decompiler.TypeSystem;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CSharp;
|
||||
using Mono.Cecil;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace ICSharpCode.Decompiler.Tests.Helpers
|
||||
@@ -114,7 +113,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
|
||||
using (var writer = new StreamWriter(outputFile)) {
|
||||
//module.Name = Path.GetFileNameWithoutExtension(outputFile);
|
||||
var output = new PlainTextOutput(writer);
|
||||
ReflectionDisassembler rd = new ReflectionDisassembler(output, module.GetMetadataReader(), CancellationToken.None);
|
||||
ReflectionDisassembler rd = new ReflectionDisassembler(output, CancellationToken.None);
|
||||
rd.DetectControlStructure = false;
|
||||
//rd.WriteAssemblyReferences(module);
|
||||
/*if (module.Assembly != null)
|
||||
|
||||
@@ -178,7 +178,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
||||
}
|
||||
|
||||
public CSharpDecompiler(string fileName, DecompilerSettings settings)
|
||||
: this(UniversalAssemblyResolver.LoadMainModule(fileName, settings.ThrowOnAssemblyResolveErrors, settings.LoadInMemory), settings)
|
||||
//: this(UniversalAssemblyResolver.LoadMainModule(fileName, settings.ThrowOnAssemblyResolveErrors, settings.LoadInMemory), settings)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1158,7 +1158,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
||||
///
|
||||
/// This only works correctly when the nodes in the syntax tree have line/column information.
|
||||
/// </summary>
|
||||
public Dictionary<ILFunction, List<SequencePoint>> CreateSequencePoints(SyntaxTree syntaxTree)
|
||||
public Dictionary<ILFunction, List<Dom.SequencePoint>> CreateSequencePoints(SyntaxTree syntaxTree)
|
||||
{
|
||||
SequencePointBuilder spb = new SequencePointBuilder();
|
||||
syntaxTree.AcceptVisitor(spb);
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
||||
}
|
||||
}
|
||||
|
||||
readonly List<(ILFunction, SequencePoint)> sequencePoints = new List<(ILFunction, SequencePoint)>();
|
||||
readonly List<(ILFunction, Dom.SequencePoint)> sequencePoints = new List<(ILFunction, Dom.SequencePoint)>();
|
||||
readonly HashSet<ILInstruction> mappedInstructions = new HashSet<ILInstruction>();
|
||||
|
||||
// Stack holding information for outer statements.
|
||||
@@ -219,7 +219,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
||||
// use LongSet to deduplicate and merge the intervals
|
||||
var longSet = new LongSet(current.Intervals.Select(i => new LongInterval(i.Start, i.End)));
|
||||
Debug.Assert(!longSet.IsEmpty);
|
||||
sequencePoints.Add((current.Function, new SequencePoint {
|
||||
sequencePoints.Add((current.Function, new Dom.SequencePoint {
|
||||
Offset = (int)longSet.Intervals[0].Start,
|
||||
EndOffset = (int)longSet.Intervals[0].End,
|
||||
StartLine = startLocation.Line,
|
||||
@@ -277,18 +277,18 @@ namespace ICSharpCode.Decompiler.CSharp
|
||||
/// <summary>
|
||||
/// Called after the visitor is done to return the results.
|
||||
/// </summary>
|
||||
internal Dictionary<ILFunction, List<SequencePoint>> GetSequencePoints()
|
||||
internal Dictionary<ILFunction, List<Dom.SequencePoint>> GetSequencePoints()
|
||||
{
|
||||
var dict = new Dictionary<ILFunction, List<SequencePoint>>();
|
||||
var dict = new Dictionary<ILFunction, List<Dom.SequencePoint>>();
|
||||
foreach (var (function, sequencePoint) in this.sequencePoints) {
|
||||
if (!dict.TryGetValue(function, out var list)) {
|
||||
dict.Add(function, list = new List<SequencePoint>());
|
||||
dict.Add(function, list = new List<Dom.SequencePoint>());
|
||||
}
|
||||
list.Add(sequencePoint);
|
||||
}
|
||||
foreach (var (function, list) in dict.ToList()) {
|
||||
// For each function, sort sequence points and fix overlaps+gaps
|
||||
var newList = new List<SequencePoint>();
|
||||
var newList = new List<Dom.SequencePoint>();
|
||||
int pos = 0;
|
||||
foreach (var sequencePoint in list.OrderBy(sp => sp.Offset).ThenBy(sp => sp.EndOffset)) {
|
||||
if (sequencePoint.Offset < pos) {
|
||||
@@ -305,7 +305,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
||||
}
|
||||
} else if (sequencePoint.Offset > pos) {
|
||||
// insert hidden sequence point in the gap.
|
||||
var hidden = new SequencePoint();
|
||||
var hidden = new Dom.SequencePoint();
|
||||
hidden.Offset = pos;
|
||||
hidden.EndOffset = sequencePoint.Offset;
|
||||
hidden.SetHidden();
|
||||
@@ -315,7 +315,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
||||
pos = sequencePoint.EndOffset;
|
||||
}
|
||||
if (pos < function.CecilMethod.Body.CodeSize) {
|
||||
var hidden = new SequencePoint();
|
||||
var hidden = new Dom.SequencePoint();
|
||||
hidden.Offset = pos;
|
||||
hidden.EndOffset = function.CecilMethod.Body.CodeSize;
|
||||
hidden.SetHidden();
|
||||
|
||||
@@ -25,6 +25,7 @@ using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
|
||||
using ICSharpCode.Decompiler.CSharp.TypeSystem;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using ICSharpCode.Decompiler.Semantics;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.Decompiler.CSharp.Transforms
|
||||
{
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
// 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 ICSharpCode.Decompiler.Semantics;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using ICSharpCode.Decompiler.TypeSystem.Implementation;
|
||||
using SRM = System.Reflection.Metadata;
|
||||
|
||||
namespace ICSharpCode.Decompiler.Disassembler
|
||||
{
|
||||
sealed class BlobDecoder
|
||||
{
|
||||
SRM.BlobReader blob;
|
||||
static readonly ITypeResolveContext context = new SimpleTypeResolveContext(MinimalCorlib.Instance.CreateCompilation());
|
||||
|
||||
public BlobDecoder(SRM.BlobReader blob)
|
||||
{
|
||||
this.blob = blob;
|
||||
}
|
||||
|
||||
public int Offset => blob.Offset;
|
||||
|
||||
public ResolveResult ReadFixedArg(IType argType)
|
||||
{
|
||||
if (argType.Kind == TypeKind.Array) {
|
||||
if (((ArrayType)argType).Dimensions != 1) {
|
||||
// Only single-dimensional arrays are supported
|
||||
return ErrorResolveResult.UnknownError;
|
||||
}
|
||||
IType elementType = ((ArrayType)argType).ElementType;
|
||||
uint numElem = blob.ReadUInt32();
|
||||
if (numElem == 0xffffffff) {
|
||||
// null reference
|
||||
return new ConstantResolveResult(argType, null);
|
||||
} else {
|
||||
ResolveResult[] elements = new ResolveResult[numElem];
|
||||
for (int i = 0; i < elements.Length; i++) {
|
||||
elements[i] = ReadElem(elementType);
|
||||
// Stop decoding when encountering an error:
|
||||
if (elements[i].IsError)
|
||||
return ErrorResolveResult.UnknownError;
|
||||
}
|
||||
IType int32 = context.Compilation.FindType(KnownTypeCode.Int32);
|
||||
ResolveResult[] sizeArgs = { new ConstantResolveResult(int32, elements.Length) };
|
||||
return new ArrayCreateResolveResult(argType, sizeArgs, elements);
|
||||
}
|
||||
} else {
|
||||
return ReadElem(argType);
|
||||
}
|
||||
}
|
||||
|
||||
public ResolveResult ReadElem(IType elementType)
|
||||
{
|
||||
ITypeDefinition underlyingType;
|
||||
if (elementType.Kind == TypeKind.Enum) {
|
||||
underlyingType = elementType.GetDefinition().EnumUnderlyingType.GetDefinition();
|
||||
} else {
|
||||
underlyingType = elementType.GetDefinition();
|
||||
}
|
||||
if (underlyingType == null)
|
||||
return ErrorResolveResult.UnknownError;
|
||||
KnownTypeCode typeCode = underlyingType.KnownTypeCode;
|
||||
if (typeCode == KnownTypeCode.Object) {
|
||||
// boxed value type
|
||||
IType boxedTyped = ReadCustomAttributeFieldOrPropType();
|
||||
ResolveResult elem = ReadFixedArg(boxedTyped);
|
||||
if (elem.IsCompileTimeConstant && elem.ConstantValue == null)
|
||||
return new ConstantResolveResult(elementType, null);
|
||||
else
|
||||
return new ConversionResolveResult(elementType, elem, Conversion.BoxingConversion);
|
||||
} else if (typeCode == KnownTypeCode.Type) {
|
||||
var type = ReadType();
|
||||
if (type != null) {
|
||||
return new TypeOfResolveResult(underlyingType, type);
|
||||
} else {
|
||||
return new ConstantResolveResult(underlyingType, null);
|
||||
}
|
||||
} else {
|
||||
return new ConstantResolveResult(elementType, ReadElemValue(typeCode));
|
||||
}
|
||||
}
|
||||
|
||||
object ReadElemValue(KnownTypeCode typeCode)
|
||||
{
|
||||
switch (typeCode) {
|
||||
case KnownTypeCode.Boolean:
|
||||
return blob.ReadBoolean();
|
||||
case KnownTypeCode.Char:
|
||||
return blob.ReadChar();
|
||||
case KnownTypeCode.SByte:
|
||||
return blob.ReadSByte();
|
||||
case KnownTypeCode.Byte:
|
||||
return blob.ReadByte();
|
||||
case KnownTypeCode.Int16:
|
||||
return blob.ReadInt16();
|
||||
case KnownTypeCode.UInt16:
|
||||
return blob.ReadUInt16();
|
||||
case KnownTypeCode.Int32:
|
||||
return blob.ReadInt32();
|
||||
case KnownTypeCode.UInt32:
|
||||
return blob.ReadUInt32();
|
||||
case KnownTypeCode.Int64:
|
||||
return blob.ReadInt64();
|
||||
case KnownTypeCode.UInt64:
|
||||
return blob.ReadUInt64();
|
||||
case KnownTypeCode.Single:
|
||||
return blob.ReadSingle();
|
||||
case KnownTypeCode.Double:
|
||||
return blob.ReadDouble();
|
||||
case KnownTypeCode.String:
|
||||
return blob.ReadSerializedString();
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public KeyValuePair<string, ResolveResult> ReadNamedArg()
|
||||
{
|
||||
SymbolKind memberType;
|
||||
var b = blob.ReadByte();
|
||||
switch (b) {
|
||||
case 0x53:
|
||||
memberType = SymbolKind.Field;
|
||||
break;
|
||||
case 0x54:
|
||||
memberType = SymbolKind.Property;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException(string.Format("Custom member type 0x{0:x} is not supported.", b));
|
||||
}
|
||||
IType type = ReadCustomAttributeFieldOrPropType();
|
||||
string name = blob.ReadSerializedString();
|
||||
ResolveResult val = ReadFixedArg(type);
|
||||
return new KeyValuePair<string, ResolveResult>(name, val);
|
||||
}
|
||||
|
||||
IType ReadCustomAttributeFieldOrPropType()
|
||||
{
|
||||
ICompilation compilation = context.Compilation;
|
||||
var b = blob.ReadByte();
|
||||
switch (b) {
|
||||
case 0x02:
|
||||
return compilation.FindType(KnownTypeCode.Boolean);
|
||||
case 0x03:
|
||||
return compilation.FindType(KnownTypeCode.Char);
|
||||
case 0x04:
|
||||
return compilation.FindType(KnownTypeCode.SByte);
|
||||
case 0x05:
|
||||
return compilation.FindType(KnownTypeCode.Byte);
|
||||
case 0x06:
|
||||
return compilation.FindType(KnownTypeCode.Int16);
|
||||
case 0x07:
|
||||
return compilation.FindType(KnownTypeCode.UInt16);
|
||||
case 0x08:
|
||||
return compilation.FindType(KnownTypeCode.Int32);
|
||||
case 0x09:
|
||||
return compilation.FindType(KnownTypeCode.UInt32);
|
||||
case 0x0a:
|
||||
return compilation.FindType(KnownTypeCode.Int64);
|
||||
case 0x0b:
|
||||
return compilation.FindType(KnownTypeCode.UInt64);
|
||||
case 0x0c:
|
||||
return compilation.FindType(KnownTypeCode.Single);
|
||||
case 0x0d:
|
||||
return compilation.FindType(KnownTypeCode.Double);
|
||||
case 0x0e:
|
||||
return compilation.FindType(KnownTypeCode.String);
|
||||
case 0x1d:
|
||||
return new ArrayType(compilation, ReadCustomAttributeFieldOrPropType());
|
||||
case 0x50:
|
||||
return compilation.FindType(KnownTypeCode.Type);
|
||||
case 0x51: // boxed value type
|
||||
return compilation.FindType(KnownTypeCode.Object);
|
||||
case 0x55: // enum
|
||||
var type = ReadType();
|
||||
if (type == null) {
|
||||
throw new NotSupportedException("Enum type should not be null.");
|
||||
}
|
||||
return type;
|
||||
default:
|
||||
throw new NotSupportedException(string.Format("Custom attribute type 0x{0:x} is not supported.", b));
|
||||
}
|
||||
}
|
||||
|
||||
IType ReadType()
|
||||
{
|
||||
string typeName = blob.ReadSerializedString();
|
||||
if (typeName == null) {
|
||||
return null;
|
||||
}
|
||||
ITypeReference typeReference = ReflectionHelper.ParseReflectionName(typeName);
|
||||
IType typeInCurrentAssembly = typeReference.Resolve(context);
|
||||
if (typeInCurrentAssembly.Kind != TypeKind.Unknown)
|
||||
return typeInCurrentAssembly;
|
||||
|
||||
// look for the type in mscorlib
|
||||
ITypeDefinition systemObject = context.Compilation.FindType(KnownTypeCode.Object).GetDefinition();
|
||||
if (systemObject != null) {
|
||||
return typeReference.Resolve(new SimpleTypeResolveContext(systemObject.ParentAssembly));
|
||||
} else {
|
||||
// couldn't find corlib - return the unknown IType for the current assembly
|
||||
return typeInCurrentAssembly;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,9 +18,11 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Text;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
using SRM = System.Reflection.Metadata;
|
||||
|
||||
namespace ICSharpCode.Decompiler.Disassembler
|
||||
@@ -57,62 +59,35 @@ namespace ICSharpCode.Decompiler.Disassembler
|
||||
return string.Format("IL_{0:x4}", offset);
|
||||
}
|
||||
|
||||
public static void WriteOffsetReference(ITextOutput writer, Instruction instruction)
|
||||
public static void WriteOffsetReference(ITextOutput writer, int? offset)
|
||||
{
|
||||
if (instruction == null)
|
||||
if (offset == null)
|
||||
writer.Write("null");
|
||||
else
|
||||
writer.WriteReference(OffsetToString(instruction.Offset), instruction);
|
||||
writer.WriteReference(OffsetToString(offset.Value), offset);
|
||||
}
|
||||
|
||||
public static void WriteTo(this ExceptionHandler exceptionHandler, ITextOutput writer)
|
||||
public static void WriteTo(this SRM.ExceptionRegion exceptionHandler, Dom.MethodDefinition method, ITextOutput writer)
|
||||
{
|
||||
writer.Write(".try ");
|
||||
WriteOffsetReference(writer, exceptionHandler.TryStart);
|
||||
WriteOffsetReference(writer, exceptionHandler.TryOffset);
|
||||
writer.Write('-');
|
||||
WriteOffsetReference(writer, exceptionHandler.TryEnd);
|
||||
WriteOffsetReference(writer, exceptionHandler.TryOffset + exceptionHandler.TryLength);
|
||||
writer.Write(' ');
|
||||
writer.Write(exceptionHandler.HandlerType.ToString().ToLowerInvariant());
|
||||
if (exceptionHandler.FilterStart != null) {
|
||||
writer.Write(exceptionHandler.Kind.ToString().ToLowerInvariant());
|
||||
if (exceptionHandler.FilterOffset != -1) {
|
||||
writer.Write(' ');
|
||||
WriteOffsetReference(writer, exceptionHandler.FilterStart);
|
||||
WriteOffsetReference(writer, exceptionHandler.FilterOffset);
|
||||
writer.Write(" handler ");
|
||||
}
|
||||
if (exceptionHandler.CatchType != null) {
|
||||
if (!exceptionHandler.CatchType.IsNil) {
|
||||
writer.Write(' ');
|
||||
exceptionHandler.CatchType.WriteTo(writer);
|
||||
exceptionHandler.CatchType.CoerceTypeReference(method.Module).WriteTo(writer, new GenericContext(method));
|
||||
}
|
||||
writer.Write(' ');
|
||||
WriteOffsetReference(writer, exceptionHandler.HandlerStart);
|
||||
WriteOffsetReference(writer, exceptionHandler.HandlerOffset);
|
||||
writer.Write('-');
|
||||
WriteOffsetReference(writer, exceptionHandler.HandlerEnd);
|
||||
}
|
||||
|
||||
public static void WriteTo(this Instruction instruction, ITextOutput writer)
|
||||
{
|
||||
writer.WriteDefinition(OffsetToString(instruction.Offset), instruction);
|
||||
writer.Write(": ");
|
||||
writer.WriteReference(instruction.OpCode.Name, instruction.OpCode);
|
||||
if (instruction.Operand != null) {
|
||||
writer.Write(' ');
|
||||
if (instruction.OpCode == OpCodes.Ldtoken) {
|
||||
if (instruction.Operand is MethodReference)
|
||||
writer.Write("method ");
|
||||
else if (instruction.Operand is FieldReference)
|
||||
writer.Write("field ");
|
||||
}
|
||||
WriteOperand(writer, instruction.Operand);
|
||||
}
|
||||
}
|
||||
|
||||
static void WriteLabelList(ITextOutput writer, Instruction[] instructions)
|
||||
{
|
||||
writer.Write("(");
|
||||
for (int i = 0; i < instructions.Length; i++) {
|
||||
if (i != 0) writer.Write(", ");
|
||||
WriteOffsetReference(writer, instructions[i]);
|
||||
}
|
||||
writer.Write(")");
|
||||
WriteOffsetReference(writer, exceptionHandler.HandlerOffset + exceptionHandler.HandlerLength);
|
||||
}
|
||||
|
||||
static string ToInvariantCultureString(object value)
|
||||
@@ -123,57 +98,6 @@ namespace ICSharpCode.Decompiler.Disassembler
|
||||
: value.ToString();
|
||||
}
|
||||
|
||||
public static void WriteTo(this MethodReference method, ITextOutput writer)
|
||||
{
|
||||
if (method.ExplicitThis) {
|
||||
writer.Write("instance explicit ");
|
||||
} else if (method.HasThis) {
|
||||
writer.Write("instance ");
|
||||
}
|
||||
if (method.CallingConvention == MethodCallingConvention.VarArg) {
|
||||
writer.Write("vararg ");
|
||||
}
|
||||
method.ReturnType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
writer.Write(' ');
|
||||
if (method.DeclaringType != null) {
|
||||
method.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
|
||||
writer.Write("::");
|
||||
}
|
||||
MethodDefinition md = method as MethodDefinition;
|
||||
if (md != null && md.IsCompilerControlled) {
|
||||
writer.WriteReference(Escape(method.Name + "$PST" + method.MetadataToken.ToInt32().ToString("X8")), method);
|
||||
} else {
|
||||
writer.WriteReference(Escape(method.Name), method);
|
||||
}
|
||||
GenericInstanceMethod gim = method as GenericInstanceMethod;
|
||||
if (gim != null) {
|
||||
writer.Write('<');
|
||||
for (int i = 0; i < gim.GenericArguments.Count; i++) {
|
||||
if (i > 0)
|
||||
writer.Write(", ");
|
||||
gim.GenericArguments[i].WriteTo(writer);
|
||||
}
|
||||
writer.Write('>');
|
||||
}
|
||||
writer.Write("(");
|
||||
var parameters = method.Parameters;
|
||||
for (int i = 0; i < parameters.Count; ++i) {
|
||||
if (i > 0)
|
||||
writer.Write(", ");
|
||||
parameters[i].ParameterType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
}
|
||||
writer.Write(")");
|
||||
}
|
||||
|
||||
static void WriteTo(this FieldReference field, ITextOutput writer)
|
||||
{
|
||||
field.FieldType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
writer.Write(' ');
|
||||
field.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
|
||||
writer.Write("::");
|
||||
writer.WriteReference(Escape(field.Name), field);
|
||||
}
|
||||
|
||||
static bool IsValidIdentifierCharacter(char c)
|
||||
{
|
||||
return c == '_' || c == '$' || c == '@' || c == '?' || c == '`';
|
||||
@@ -194,48 +118,9 @@ namespace ICSharpCode.Decompiler.Disassembler
|
||||
return true;
|
||||
}
|
||||
|
||||
static readonly HashSet<string> ilKeywords = BuildKeywordList(
|
||||
"abstract", "algorithm", "alignment", "ansi", "any", "arglist",
|
||||
"array", "as", "assembly", "assert", "at", "auto", "autochar", "beforefieldinit",
|
||||
"blob", "blob_object", "bool", "brnull", "brnull.s", "brzero", "brzero.s", "bstr",
|
||||
"bytearray", "byvalstr", "callmostderived", "carray", "catch", "cdecl", "cf",
|
||||
"char", "cil", "class", "clsid", "const", "currency", "custom", "date", "decimal",
|
||||
"default", "demand", "deny", "endmac", "enum", "error", "explicit", "extends", "extern",
|
||||
"false", "famandassem", "family", "famorassem", "fastcall", "fault", "field", "filetime",
|
||||
"filter", "final", "finally", "fixed", "float", "float32", "float64", "forwardref",
|
||||
"fromunmanaged", "handler", "hidebysig", "hresult", "idispatch", "il", "illegal",
|
||||
"implements", "implicitcom", "implicitres", "import", "in", "inheritcheck", "init",
|
||||
"initonly", "instance", "int", "int16", "int32", "int64", "int8", "interface", "internalcall",
|
||||
"iunknown", "lasterr", "lcid", "linkcheck", "literal", "localloc", "lpstr", "lpstruct", "lptstr",
|
||||
"lpvoid", "lpwstr", "managed", "marshal", "method", "modopt", "modreq", "native", "nested",
|
||||
"newslot", "noappdomain", "noinlining", "nomachine", "nomangle", "nometadata", "noncasdemand",
|
||||
"noncasinheritance", "noncaslinkdemand", "noprocess", "not", "not_in_gc_heap", "notremotable",
|
||||
"notserialized", "null", "nullref", "object", "objectref", "opt", "optil", "out",
|
||||
"permitonly", "pinned", "pinvokeimpl", "prefix1", "prefix2", "prefix3", "prefix4", "prefix5", "prefix6",
|
||||
"prefix7", "prefixref", "prejitdeny", "prejitgrant", "preservesig", "private", "privatescope", "protected",
|
||||
"public", "record", "refany", "reqmin", "reqopt", "reqrefuse", "reqsecobj", "request", "retval",
|
||||
"rtspecialname", "runtime", "safearray", "sealed", "sequential", "serializable", "special", "specialname",
|
||||
"static", "stdcall", "storage", "stored_object", "stream", "streamed_object", "string", "struct",
|
||||
"synchronized", "syschar", "sysstring", "tbstr", "thiscall", "tls", "to", "true", "typedref",
|
||||
"unicode", "unmanaged", "unmanagedexp", "unsigned", "unused", "userdefined", "value", "valuetype",
|
||||
"vararg", "variant", "vector", "virtual", "void", "wchar", "winapi", "with", "wrapper",
|
||||
|
||||
// These are not listed as keywords in spec, but ILAsm treats them as such
|
||||
"property", "type", "flags", "callconv", "strict"
|
||||
);
|
||||
|
||||
static HashSet<string> BuildKeywordList(params string[] keywords)
|
||||
{
|
||||
HashSet<string> s = new HashSet<string>(keywords);
|
||||
foreach (var field in typeof(OpCodes).GetFields()) {
|
||||
s.Add(((OpCode)field.GetValue(null)).Name);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public static string Escape(string identifier)
|
||||
{
|
||||
if (IsValidIdentifier(identifier) && !ilKeywords.Contains(identifier)) {
|
||||
if (IsValidIdentifier(identifier) && !IL.ILOpCodeExtensions.ILKeywords.Contains(identifier)) {
|
||||
return identifier;
|
||||
} else {
|
||||
// The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence,
|
||||
@@ -244,112 +129,34 @@ namespace ICSharpCode.Decompiler.Disassembler
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteTo(this TypeReference type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature)
|
||||
public static void WriteParameterReference(ITextOutput writer, Dom.MethodDefinition method, int sequence)
|
||||
{
|
||||
ILNameSyntax syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature;
|
||||
if (type is PinnedType) {
|
||||
((PinnedType)type).ElementType.WriteTo(writer, syntaxForElementTypes);
|
||||
writer.Write(" pinned");
|
||||
} else if (type is ArrayType) {
|
||||
ArrayType at = (ArrayType)type;
|
||||
at.ElementType.WriteTo(writer, syntaxForElementTypes);
|
||||
writer.Write('[');
|
||||
writer.Write(string.Join(", ", at.Dimensions));
|
||||
writer.Write(']');
|
||||
} else if (type is GenericParameter) {
|
||||
writer.Write('!');
|
||||
if (((GenericParameter)type).Owner.GenericParameterType == GenericParameterType.Method)
|
||||
writer.Write('!');
|
||||
if (string.IsNullOrEmpty(type.Name) || type.Name[0] == '!' || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
|
||||
writer.Write(((GenericParameter)type).Position.ToString());
|
||||
else
|
||||
writer.Write(Escape(type.Name));
|
||||
} else if (type is ByReferenceType) {
|
||||
((ByReferenceType)type).ElementType.WriteTo(writer, syntaxForElementTypes);
|
||||
writer.Write('&');
|
||||
} else if (type is PointerType) {
|
||||
((PointerType)type).ElementType.WriteTo(writer, syntaxForElementTypes);
|
||||
writer.Write('*');
|
||||
} else if (type is GenericInstanceType) {
|
||||
type.GetElementType().WriteTo(writer, syntaxForElementTypes);
|
||||
writer.Write('<');
|
||||
var arguments = ((GenericInstanceType)type).GenericArguments;
|
||||
for (int i = 0; i < arguments.Count; i++) {
|
||||
if (i > 0)
|
||||
writer.Write(", ");
|
||||
arguments[i].WriteTo(writer, syntaxForElementTypes);
|
||||
}
|
||||
writer.Write('>');
|
||||
} else if (type is OptionalModifierType) {
|
||||
((OptionalModifierType)type).ElementType.WriteTo(writer, syntax);
|
||||
writer.Write(" modopt(");
|
||||
((OptionalModifierType)type).ModifierType.WriteTo(writer, ILNameSyntax.TypeName);
|
||||
writer.Write(") ");
|
||||
} else if (type is RequiredModifierType) {
|
||||
((RequiredModifierType)type).ElementType.WriteTo(writer, syntax);
|
||||
writer.Write(" modreq(");
|
||||
((RequiredModifierType)type).ModifierType.WriteTo(writer, ILNameSyntax.TypeName);
|
||||
writer.Write(") ");
|
||||
} else if (type is FunctionPointerType fpt) {
|
||||
writer.Write("method ");
|
||||
fpt.ReturnType.WriteTo(writer, syntax);
|
||||
writer.Write(" *(");
|
||||
bool first = true;
|
||||
foreach (var p in fpt.Parameters) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
writer.Write(", ");
|
||||
p.ParameterType.WriteTo(writer, syntax);
|
||||
}
|
||||
writer.Write(')');
|
||||
} else if (type is SentinelType) {
|
||||
writer.Write("..., ");
|
||||
((SentinelType)type).ElementType.WriteTo(writer, syntax);
|
||||
var metadata = method.Module.GetMetadataReader();
|
||||
var signatureHeader = method.DecodeSignature(new FullTypeNameSignatureDecoder(metadata), default(Unit)).Header;
|
||||
int index = signatureHeader.IsInstance && !signatureHeader.HasExplicitThis ? sequence - 1 : sequence;
|
||||
if (index < 0 || index >= method.Parameters.Count) {
|
||||
writer.Write(sequence.ToString());
|
||||
} else {
|
||||
string name = PrimitiveTypeName(type.FullName);
|
||||
if (syntax == ILNameSyntax.ShortTypeName) {
|
||||
if (name != null)
|
||||
writer.Write(name);
|
||||
else
|
||||
writer.WriteReference(Escape(type.Name), type);
|
||||
} else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null) {
|
||||
writer.Write(name);
|
||||
var param = metadata.GetParameter(method.Parameters.ElementAt(index));
|
||||
if (param.Name.IsNil) {
|
||||
writer.Write(sequence.ToString());
|
||||
} else {
|
||||
if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
|
||||
writer.Write(type.IsValueType ? "valuetype " : "class ");
|
||||
|
||||
if (type.DeclaringType != null) {
|
||||
type.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
|
||||
writer.Write('/');
|
||||
writer.WriteReference(Escape(type.Name), type);
|
||||
} else {
|
||||
if (!type.IsDefinition && type.Scope != null && !(type is TypeSpecification))
|
||||
writer.Write("[{0}]", Escape(type.Scope.Name));
|
||||
writer.WriteReference(Escape(type.FullName), type);
|
||||
}
|
||||
writer.Write(Escape(metadata.GetString(param.Name)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteVariableReference(ITextOutput writer, Dom.MethodDefinition method, int index)
|
||||
{
|
||||
writer.Write(index.ToString());
|
||||
}
|
||||
|
||||
public static void WriteOperand(ITextOutput writer, object operand)
|
||||
{
|
||||
if (operand == null)
|
||||
throw new ArgumentNullException(nameof(operand));
|
||||
|
||||
Instruction targetInstruction = operand as Instruction;
|
||||
if (targetInstruction != null) {
|
||||
WriteOffsetReference(writer, targetInstruction);
|
||||
return;
|
||||
}
|
||||
|
||||
Instruction[] targetInstructions = operand as Instruction[];
|
||||
if (targetInstructions != null) {
|
||||
WriteLabelList(writer, targetInstructions);
|
||||
return;
|
||||
}
|
||||
|
||||
VariableReference variableRef = operand as VariableReference;
|
||||
/*VariableReference variableRef = operand as VariableReference;
|
||||
if (variableRef != null) {
|
||||
writer.WriteReference(variableRef.Index.ToString(), variableRef);
|
||||
return;
|
||||
@@ -363,25 +170,7 @@ namespace ICSharpCode.Decompiler.Disassembler
|
||||
} else
|
||||
writer.WriteReference(Escape(paramRef.Name), paramRef);
|
||||
return;
|
||||
}
|
||||
|
||||
MethodReference methodRef = operand as MethodReference;
|
||||
if (methodRef != null) {
|
||||
methodRef.WriteTo(writer);
|
||||
return;
|
||||
}
|
||||
|
||||
TypeReference typeRef = operand as TypeReference;
|
||||
if (typeRef != null) {
|
||||
typeRef.WriteTo(writer, ILNameSyntax.TypeName);
|
||||
return;
|
||||
}
|
||||
|
||||
FieldReference fieldRef = operand as FieldReference;
|
||||
if (fieldRef != null) {
|
||||
fieldRef.WriteTo(writer);
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
string s = operand as string;
|
||||
if (s != null) {
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
// 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.Immutable;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
|
||||
namespace ICSharpCode.Decompiler.Disassembler
|
||||
{
|
||||
public static class DomExtensions
|
||||
{
|
||||
public static void WriteTo(this Dom.FieldDefinition field, ITextOutput output)
|
||||
{
|
||||
var signature = field.DecodeSignature(new DisassemblerSignatureProvider(field.Module, output), new GenericContext(field.DeclaringType));
|
||||
signature(ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
output.Write(' ');
|
||||
field.DeclaringType.WriteTo(output, ILNameSyntax.TypeName);
|
||||
output.Write("::");
|
||||
output.Write(DisassemblerHelpers.Escape(field.Name));
|
||||
}
|
||||
|
||||
public static void WriteTo(this IMemberReference member, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
|
||||
{
|
||||
void WriteParent(EntityHandle parentHandle)
|
||||
{
|
||||
var metadata = member.Module.GetMetadataReader();
|
||||
switch (parentHandle.Kind) {
|
||||
case HandleKind.MethodDefinition:
|
||||
new Dom.MethodDefinition(member.Module, (MethodDefinitionHandle)parentHandle).WriteTo(output, genericContext, syntax);
|
||||
break;
|
||||
case HandleKind.ModuleReference:
|
||||
output.Write('[');
|
||||
var moduleRef = metadata.GetModuleReference((ModuleReferenceHandle)parentHandle);
|
||||
output.Write(metadata.GetString(moduleRef.Name));
|
||||
output.Write(']');
|
||||
break;
|
||||
case HandleKind.TypeDefinition:
|
||||
new Dom.TypeDefinition(member.Module, (TypeDefinitionHandle)parentHandle).WriteTo(output, syntax);
|
||||
break;
|
||||
case HandleKind.TypeReference:
|
||||
new Dom.TypeReference(member.Module, (TypeReferenceHandle)parentHandle).WriteTo(output, syntax);
|
||||
break;
|
||||
case HandleKind.TypeSpecification:
|
||||
new Dom.TypeSpecification(member.Module, (TypeSpecificationHandle)parentHandle).WriteTo(output, genericContext, syntax);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MethodSignature<Action<ILNameSyntax>> signature;
|
||||
switch (member) {
|
||||
case Dom.MethodDefinition md:
|
||||
md.WriteTo(output);
|
||||
break;
|
||||
case Dom.MemberReference mr:
|
||||
switch (mr.Kind) {
|
||||
case MemberReferenceKind.Method:
|
||||
signature = mr.DecodeMethodSignature(new DisassemblerSignatureProvider(member.Module, output), genericContext);
|
||||
if (signature.Header.HasExplicitThis) {
|
||||
output.Write("instance explicit ");
|
||||
} else if (signature.Header.IsInstance) {
|
||||
output.Write("instance ");
|
||||
}
|
||||
if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
|
||||
output.Write("vararg ");
|
||||
}
|
||||
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
output.Write(' ');
|
||||
WriteParent(mr.Parent);
|
||||
output.Write("::");
|
||||
output.Write(DisassemblerHelpers.Escape(mr.Name));
|
||||
output.Write("(");
|
||||
for (int i = 0; i < signature.ParameterTypes.Length; ++i) {
|
||||
if (i > 0)
|
||||
output.Write(", ");
|
||||
signature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
}
|
||||
output.Write(")");
|
||||
break;
|
||||
case MemberReferenceKind.Field:
|
||||
var fieldSignature = mr.DecodeFieldSignature(new DisassemblerSignatureProvider(member.Module, output), genericContext);
|
||||
fieldSignature(ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
output.Write(' ');
|
||||
WriteParent(mr.Parent);
|
||||
output.Write("::");
|
||||
output.Write(DisassemblerHelpers.Escape(mr.Name));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Dom.MethodSpecification ms:
|
||||
var substitution = ms.DecodeSignature(new DisassemblerSignatureProvider(ms.Module, output), genericContext);
|
||||
switch (ms.Method) {
|
||||
case Dom.MethodDefinition method:
|
||||
var metadata = method.Module.GetMetadataReader();
|
||||
signature = method.DecodeSignature(new DisassemblerSignatureProvider(method.Module, output), new GenericContext(method));
|
||||
if (signature.Header.HasExplicitThis) {
|
||||
output.Write("instance explicit ");
|
||||
} else if (signature.Header.IsInstance) {
|
||||
output.Write("instance ");
|
||||
}
|
||||
if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
|
||||
output.Write("vararg ");
|
||||
}
|
||||
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
output.Write(' ');
|
||||
if (!method.DeclaringType.IsNil) {
|
||||
method.DeclaringType.WriteTo(output, ILNameSyntax.TypeName);
|
||||
output.Write("::");
|
||||
}
|
||||
bool isCompilerControlled = (method.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;
|
||||
if (isCompilerControlled) {
|
||||
output.Write(DisassemblerHelpers.Escape(method.Name + "$PST" + MetadataTokens.GetToken(method.Handle).ToString("X8")));
|
||||
} else {
|
||||
output.Write(DisassemblerHelpers.Escape(method.Name));
|
||||
}
|
||||
output.Write('<');
|
||||
for (int i = 0; i < substitution.Length; i++) {
|
||||
if (i > 0)
|
||||
output.Write(", ");
|
||||
substitution[i](syntax);
|
||||
}
|
||||
output.Write('>');
|
||||
output.Write("(");
|
||||
for (int i = 0; i < signature.ParameterTypes.Length; ++i) {
|
||||
if (i > 0)
|
||||
output.Write(", ");
|
||||
signature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
}
|
||||
output.Write(")");
|
||||
break;
|
||||
case Dom.MemberReference mr:
|
||||
signature = mr.DecodeMethodSignature(new DisassemblerSignatureProvider(member.Module, output), genericContext);
|
||||
if (signature.Header.HasExplicitThis) {
|
||||
output.Write("instance explicit ");
|
||||
} else if (signature.Header.IsInstance) {
|
||||
output.Write("instance ");
|
||||
}
|
||||
if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
|
||||
output.Write("vararg ");
|
||||
}
|
||||
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
output.Write(' ');
|
||||
WriteParent(mr.Parent);
|
||||
output.Write("::");
|
||||
output.Write(DisassemblerHelpers.Escape(mr.Name));
|
||||
output.Write('<');
|
||||
for (int i = 0; i < substitution.Length; i++) {
|
||||
if (i > 0)
|
||||
output.Write(", ");
|
||||
substitution[i](syntax);
|
||||
}
|
||||
output.Write('>');
|
||||
output.Write("(");
|
||||
for (int i = 0; i < signature.ParameterTypes.Length; ++i) {
|
||||
if (i > 0)
|
||||
output.Write(", ");
|
||||
signature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
}
|
||||
output.Write(")");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteTo(this Dom.TypeReference typeRef, ITextOutput output, ILNameSyntax syntax = ILNameSyntax.Signature)
|
||||
{
|
||||
var metadata = typeRef.Module.GetMetadataReader();
|
||||
if (!typeRef.ResolutionScope.IsNil) {
|
||||
output.Write("[");
|
||||
var currentTypeRef = typeRef;
|
||||
while (currentTypeRef.ResolutionScope.Kind == HandleKind.TypeReference) {
|
||||
currentTypeRef = new Dom.TypeReference(currentTypeRef.Module, (TypeReferenceHandle)currentTypeRef.ResolutionScope);
|
||||
}
|
||||
switch (currentTypeRef.ResolutionScope.Kind) {
|
||||
case HandleKind.ModuleReference:
|
||||
break;
|
||||
case HandleKind.AssemblyReference:
|
||||
var asmRef = metadata.GetAssemblyReference((AssemblyReferenceHandle)currentTypeRef.ResolutionScope);
|
||||
output.Write(DisassemblerHelpers.Escape(metadata.GetString(asmRef.Name)));
|
||||
break;
|
||||
}
|
||||
output.Write("]");
|
||||
}
|
||||
output.WriteReference(typeRef.FullName.ToILNameString(), typeRef);
|
||||
}
|
||||
|
||||
public static void WriteTo(this Dom.TypeDefinition typeDefinition, ITextOutput output, ILNameSyntax syntax = ILNameSyntax.Signature)
|
||||
{
|
||||
output.WriteReference(typeDefinition.FullName.ToILNameString(), typeDefinition);
|
||||
}
|
||||
|
||||
public static void WriteTo(this Dom.TypeSpecification typeSpecification, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
|
||||
{
|
||||
var signature = typeSpecification.DecodeSignature(new DisassemblerSignatureProvider(typeSpecification.Module, output), genericContext);
|
||||
signature(syntax);
|
||||
}
|
||||
|
||||
public static void WriteTo(this ITypeReference type, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
|
||||
{
|
||||
switch (type) {
|
||||
case Dom.TypeDefinition td:
|
||||
td.WriteTo(output, syntax);
|
||||
break;
|
||||
case Dom.TypeReference tr:
|
||||
tr.WriteTo(output, syntax);
|
||||
break;
|
||||
case Dom.TypeSpecification ts:
|
||||
ts.WriteTo(output, genericContext, syntax);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteTo(this Dom.MethodDefinition method, ITextOutput output)
|
||||
{
|
||||
var metadata = method.Module.GetMetadataReader();
|
||||
var signature = method.DecodeSignature(new DisassemblerSignatureProvider(method.Module, output), new GenericContext(method));
|
||||
if (signature.Header.HasExplicitThis) {
|
||||
output.Write("instance explicit ");
|
||||
} else if (signature.Header.IsInstance) {
|
||||
output.Write("instance ");
|
||||
}
|
||||
if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
|
||||
output.Write("vararg ");
|
||||
}
|
||||
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
output.Write(' ');
|
||||
if (!method.DeclaringType.IsNil) {
|
||||
method.DeclaringType.WriteTo(output, ILNameSyntax.TypeName);
|
||||
output.Write("::");
|
||||
}
|
||||
bool isCompilerControlled = (method.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;
|
||||
if (isCompilerControlled) {
|
||||
output.Write(DisassemblerHelpers.Escape(method.Name + "$PST" + MetadataTokens.GetToken(method.Handle).ToString("X8")));
|
||||
} else {
|
||||
output.Write(DisassemblerHelpers.Escape(method.Name));
|
||||
}
|
||||
var genericParameters = method.GenericParameters;
|
||||
if (genericParameters.Count > 0) {
|
||||
output.Write('<');
|
||||
for (int i = 0; i < genericParameters.Count; i++) {
|
||||
if (i > 0)
|
||||
output.Write(", ");
|
||||
var gp = metadata.GetGenericParameter(genericParameters[i]);
|
||||
if ((gp.Attributes & GenericParameterAttributes.ReferenceTypeConstraint) == GenericParameterAttributes.ReferenceTypeConstraint) {
|
||||
output.Write("class ");
|
||||
} else if ((gp.Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == GenericParameterAttributes.NotNullableValueTypeConstraint) {
|
||||
output.Write("valuetype ");
|
||||
}
|
||||
if ((gp.Attributes & GenericParameterAttributes.DefaultConstructorConstraint) == GenericParameterAttributes.DefaultConstructorConstraint) {
|
||||
output.Write(".ctor ");
|
||||
}
|
||||
var constraints = gp.GetConstraints();
|
||||
if (constraints.Count > 0) {
|
||||
output.Write('(');
|
||||
for (int j = 0; j < constraints.Count; j++) {
|
||||
if (j > 0)
|
||||
output.Write(", ");
|
||||
var constraint = metadata.GetGenericParameterConstraint(constraints[j]);
|
||||
constraint.Type.CoerceTypeReference(method.Module).WriteTo(output, new GenericContext(method), ILNameSyntax.TypeName);
|
||||
}
|
||||
output.Write(") ");
|
||||
}
|
||||
if ((gp.Attributes & GenericParameterAttributes.Contravariant) == GenericParameterAttributes.Contravariant) {
|
||||
output.Write('-');
|
||||
} else if ((gp.Attributes & GenericParameterAttributes.Covariant) == GenericParameterAttributes.Covariant) {
|
||||
output.Write('+');
|
||||
}
|
||||
output.Write(DisassemblerHelpers.Escape(metadata.GetString(gp.Name)));
|
||||
}
|
||||
output.Write('>');
|
||||
}
|
||||
output.Write("(");
|
||||
for (int i = 0; i < signature.ParameterTypes.Length; ++i) {
|
||||
if (i > 0)
|
||||
output.Write(", ");
|
||||
signature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
|
||||
}
|
||||
output.Write(")");
|
||||
}
|
||||
|
||||
public static bool IsBaseTypeOf(this ITypeReference baseType, ITypeReference derivedType)
|
||||
{
|
||||
var derivedTypeDefinition = derivedType.GetDefinition();
|
||||
while (!derivedTypeDefinition.IsNil) {
|
||||
if (derivedTypeDefinition.FullName == baseType.FullName)
|
||||
return true;
|
||||
derivedTypeDefinition = derivedTypeDefinition.BaseType.GetDefinition();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class TypeUsedInSignature : ISignatureTypeProvider<bool, Unit>
|
||||
{
|
||||
readonly PEFile module;
|
||||
readonly Dom.TypeDefinition type;
|
||||
|
||||
public TypeUsedInSignature(ITypeReference type)
|
||||
{
|
||||
this.module = type.Module;
|
||||
this.type = type.GetDefinition();
|
||||
}
|
||||
|
||||
public bool GetArrayType(bool elementType, ArrayShape shape) => elementType;
|
||||
|
||||
public bool GetByReferenceType(bool elementType) => elementType;
|
||||
|
||||
public bool GetFunctionPointerType(MethodSignature<bool> signature)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool GetGenericInstantiation(bool genericType, ImmutableArray<bool> typeArguments)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool GetGenericMethodParameter(Unit genericContext, int index) => false;
|
||||
|
||||
public bool GetGenericTypeParameter(Unit genericContext, int index) => false;
|
||||
|
||||
public bool GetModifiedType(bool modifier, bool unmodifiedType, bool isRequired)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool GetPinnedType(bool elementType) => elementType;
|
||||
|
||||
public bool GetPointerType(bool elementType) => elementType;
|
||||
|
||||
public bool GetPrimitiveType(PrimitiveTypeCode typeCode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool GetSZArrayType(bool elementType) => elementType;
|
||||
|
||||
public bool GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
|
||||
{
|
||||
return module == type.Module && handle == type.Handle;
|
||||
}
|
||||
|
||||
public bool GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
|
||||
{
|
||||
return new Dom.TypeReference(module, handle).GetDefinition() == type;
|
||||
}
|
||||
|
||||
public bool GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
|
||||
{
|
||||
return new Dom.TypeSpecification(module, handle).GetDefinition() == type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Mono.Cecil.Cil;
|
||||
using System.Reflection.Metadata;
|
||||
using ICSharpCode.Decompiler.IL;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
|
||||
namespace ICSharpCode.Decompiler.Disassembler
|
||||
{
|
||||
@@ -55,6 +57,7 @@ namespace ICSharpCode.Decompiler.Disassembler
|
||||
/// </summary>
|
||||
public class ILStructure
|
||||
{
|
||||
public readonly Dom.MethodDefinition Method;
|
||||
public readonly ILStructureType Type;
|
||||
|
||||
/// <summary>
|
||||
@@ -70,82 +73,83 @@ namespace ICSharpCode.Decompiler.Disassembler
|
||||
/// <summary>
|
||||
/// The exception handler associated with the Try, Filter or Handler block.
|
||||
/// </summary>
|
||||
public readonly ExceptionHandler ExceptionHandler;
|
||||
public readonly ExceptionRegion ExceptionHandler;
|
||||
|
||||
/// <summary>
|
||||
/// The loop's entry point.
|
||||
/// </summary>
|
||||
public readonly Instruction LoopEntryPoint;
|
||||
public readonly int LoopEntryPointOffset;
|
||||
|
||||
/// <summary>
|
||||
/// The list of child structures.
|
||||
/// </summary>
|
||||
public readonly List<ILStructure> Children = new List<ILStructure>();
|
||||
|
||||
public ILStructure(MethodBody body)
|
||||
: this(ILStructureType.Root, 0, body.CodeSize)
|
||||
public ILStructure(Dom.MethodDefinition method, MethodBodyBlock body)
|
||||
: this(method, ILStructureType.Root, 0, body.GetILReader().Length)
|
||||
{
|
||||
// Build the tree of exception structures:
|
||||
for (int i = 0; i < body.ExceptionHandlers.Count; i++) {
|
||||
ExceptionHandler eh = body.ExceptionHandlers[i];
|
||||
if (!body.ExceptionHandlers.Take(i).Any(oldEh => oldEh.TryStart == eh.TryStart && oldEh.TryEnd == eh.TryEnd))
|
||||
AddNestedStructure(new ILStructure(ILStructureType.Try, eh.TryStart.Offset, eh.TryEnd.Offset, eh));
|
||||
if (eh.HandlerType == ExceptionHandlerType.Filter)
|
||||
AddNestedStructure(new ILStructure(ILStructureType.Filter, eh.FilterStart.Offset, eh.HandlerStart.Offset, eh));
|
||||
AddNestedStructure(new ILStructure(ILStructureType.Handler, eh.HandlerStart.Offset, eh.HandlerEnd == null ? body.CodeSize : eh.HandlerEnd.Offset, eh));
|
||||
for (int i = 0; i < body.ExceptionRegions.Length; i++) {
|
||||
ExceptionRegion eh = body.ExceptionRegions[i];
|
||||
if (!body.ExceptionRegions.Take(i).Any(oldEh => oldEh.TryOffset == eh.TryOffset && oldEh.TryLength == eh.TryLength))
|
||||
AddNestedStructure(new ILStructure(method, ILStructureType.Try, eh.TryOffset, eh.TryOffset + eh.TryLength, eh));
|
||||
if (eh.Kind == ExceptionRegionKind.Filter)
|
||||
AddNestedStructure(new ILStructure(method, ILStructureType.Filter, eh.FilterOffset, eh.HandlerOffset, eh));
|
||||
AddNestedStructure(new ILStructure(method, ILStructureType.Handler, eh.HandlerOffset, eh.HandlerOffset + eh.HandlerLength, eh));
|
||||
}
|
||||
// Very simple loop detection: look for backward branches
|
||||
List<KeyValuePair<Instruction, Instruction>> allBranches = FindAllBranches(body);
|
||||
(var allBranches, var isAfterConditionalBranch) = FindAllBranches(body.GetILReader());
|
||||
// We go through the branches in reverse so that we find the biggest possible loop boundary first (think loops with "continue;")
|
||||
for (int i = allBranches.Count - 1; i >= 0; i--) {
|
||||
int loopEnd = allBranches[i].Key.GetEndOffset();
|
||||
int loopStart = allBranches[i].Value.Offset;
|
||||
int loopEnd = allBranches[i].Source.End;
|
||||
int loopStart = allBranches[i].Target;
|
||||
if (loopStart < loopEnd) {
|
||||
// We found a backward branch. This is a potential loop.
|
||||
// Check that is has only one entry point:
|
||||
Instruction entryPoint = null;
|
||||
int entryPoint = -1;
|
||||
|
||||
// entry point is first instruction in loop if prev inst isn't an unconditional branch
|
||||
Instruction prev = allBranches[i].Value.Previous;
|
||||
if (prev != null && !prev.OpCode.IsUnconditionalBranch())
|
||||
entryPoint = allBranches[i].Value;
|
||||
if (!isAfterConditionalBranch[loopStart])
|
||||
entryPoint = allBranches[i].Target;
|
||||
|
||||
bool multipleEntryPoints = false;
|
||||
foreach (var pair in allBranches) {
|
||||
if (pair.Key.Offset < loopStart || pair.Key.Offset >= loopEnd) {
|
||||
if (loopStart <= pair.Value.Offset && pair.Value.Offset < loopEnd) {
|
||||
foreach (var branch in allBranches) {
|
||||
if (branch.Source.Start < loopStart || branch.Source.Start >= loopEnd) {
|
||||
if (loopStart <= branch.Target && branch.Target < loopEnd) {
|
||||
// jump from outside the loop into the loop
|
||||
if (entryPoint == null)
|
||||
entryPoint = pair.Value;
|
||||
else if (pair.Value != entryPoint)
|
||||
if (entryPoint < 0)
|
||||
entryPoint = branch.Target;
|
||||
else if (branch.Target != entryPoint)
|
||||
multipleEntryPoints = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!multipleEntryPoints) {
|
||||
AddNestedStructure(new ILStructure(ILStructureType.Loop, loopStart, loopEnd, entryPoint));
|
||||
AddNestedStructure(new ILStructure(method, ILStructureType.Loop, loopStart, loopEnd, entryPoint));
|
||||
}
|
||||
}
|
||||
}
|
||||
SortChildren();
|
||||
}
|
||||
|
||||
public ILStructure(ILStructureType type, int startOffset, int endOffset, ExceptionHandler handler = null)
|
||||
public ILStructure(Dom.MethodDefinition method, ILStructureType type, int startOffset, int endOffset, ExceptionRegion handler = default(ExceptionRegion))
|
||||
{
|
||||
Debug.Assert(startOffset < endOffset);
|
||||
this.Method = method;
|
||||
this.Type = type;
|
||||
this.StartOffset = startOffset;
|
||||
this.EndOffset = endOffset;
|
||||
this.ExceptionHandler = handler;
|
||||
}
|
||||
|
||||
public ILStructure(ILStructureType type, int startOffset, int endOffset, Instruction loopEntryPoint)
|
||||
public ILStructure(Dom.MethodDefinition method, ILStructureType type, int startOffset, int endOffset, int loopEntryPoint)
|
||||
{
|
||||
Debug.Assert(startOffset < endOffset);
|
||||
this.Method = method;
|
||||
this.Type = type;
|
||||
this.StartOffset = startOffset;
|
||||
this.EndOffset = endOffset;
|
||||
this.LoopEntryPoint = loopEntryPoint;
|
||||
this.LoopEntryPointOffset = loopEntryPoint;
|
||||
}
|
||||
|
||||
bool AddNestedStructure(ILStructure newStructure)
|
||||
@@ -180,29 +184,68 @@ namespace ICSharpCode.Decompiler.Disassembler
|
||||
return true;
|
||||
}
|
||||
|
||||
struct Branch
|
||||
{
|
||||
public Interval Source;
|
||||
public int Target;
|
||||
|
||||
public Branch(int start, int end, int target)
|
||||
{
|
||||
this.Source = new Interval(start, end);
|
||||
this.Target = target;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[Branch Source={Source}, Target={Target}]";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds all branches. Returns list of source offset->target offset mapping.
|
||||
/// Multiple entries for the same source offset are possible (switch statements).
|
||||
/// The result is sorted by source offset.
|
||||
/// </summary>
|
||||
List<KeyValuePair<Instruction, Instruction>> FindAllBranches(MethodBody body)
|
||||
(List<Branch> Branches, BitSet IsAfterUnconditionalBranch) FindAllBranches(BlobReader body)
|
||||
{
|
||||
var result = new List<KeyValuePair<Instruction, Instruction>>();
|
||||
foreach (Instruction inst in body.Instructions) {
|
||||
switch (inst.OpCode.OperandType) {
|
||||
case OperandType.InlineBrTarget:
|
||||
case OperandType.ShortInlineBrTarget:
|
||||
result.Add(new KeyValuePair<Instruction, Instruction>(inst, (Instruction)inst.Operand));
|
||||
var result = new List<Branch>();
|
||||
var bitset = new BitSet(body.Length);
|
||||
body.Reset();
|
||||
int target;
|
||||
while (body.RemainingBytes > 0) {
|
||||
var offset = body.Offset;
|
||||
int endOffset;
|
||||
var thisOpCode = ILParser.DecodeOpCode(ref body);
|
||||
switch (thisOpCode.GetOperandType()) {
|
||||
case OperandType.BrTarget:
|
||||
case OperandType.ShortBrTarget:
|
||||
endOffset = body.Offset + thisOpCode.GetBranchOperandSize();
|
||||
target = ILParser.DecodeBranchTarget(ref body, thisOpCode);
|
||||
result.Add(new Branch(offset, endOffset, target));
|
||||
bitset[endOffset] = IsUnconditionalBranch(thisOpCode);
|
||||
break;
|
||||
case OperandType.InlineSwitch:
|
||||
foreach (Instruction target in (Instruction[])inst.Operand)
|
||||
result.Add(new KeyValuePair<Instruction, Instruction>(inst, target));
|
||||
case OperandType.Switch:
|
||||
var targets = ILParser.DecodeSwitchTargets(ref body);
|
||||
foreach (int t in targets)
|
||||
result.Add(new Branch(offset, offset + 4 * (targets.Length + 1), t));
|
||||
break;
|
||||
default:
|
||||
ILParser.SkipOperand(ref body, thisOpCode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ignore the branches where Cecil doesn't decode the target
|
||||
result.RemoveAll(x => x.Value == null);
|
||||
return result;
|
||||
return (result, bitset);
|
||||
}
|
||||
|
||||
static bool IsUnconditionalBranch(ILOpCode opCode)
|
||||
{
|
||||
switch (opCode) {
|
||||
case ILOpCode.Br:
|
||||
case ILOpCode.Br_s:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SortChildren()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,22 +19,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ICSharpCode.Decompiler.IL;
|
||||
|
||||
namespace ICSharpCode.Decompiler.Disassembler
|
||||
{
|
||||
public struct OpCodeInfo : IEquatable<OpCodeInfo>
|
||||
{
|
||||
public readonly int Code;
|
||||
public readonly ILOpCode Code;
|
||||
public readonly string Name;
|
||||
|
||||
string encodedName;
|
||||
|
||||
public OpCodeInfo(int code, string name)
|
||||
public OpCodeInfo(ILOpCode code, string name)
|
||||
{
|
||||
this.Code = code;
|
||||
this.Name = name;
|
||||
this.Name = name ?? "";
|
||||
this.encodedName = null;
|
||||
}
|
||||
|
||||
@@ -46,6 +49,18 @@ namespace ICSharpCode.Decompiler.Disassembler
|
||||
public static bool operator ==(OpCodeInfo lhs, OpCodeInfo rhs) => lhs.Equals(rhs);
|
||||
public static bool operator !=(OpCodeInfo lhs, OpCodeInfo rhs) => !(lhs == rhs);
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is OpCodeInfo opCode)
|
||||
return Equals(opCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return unchecked(982451629 * Code.GetHashCode() + 982451653 * Name.GetHashCode());
|
||||
}
|
||||
|
||||
public string Link => "http://msdn.microsoft.com/library/system.reflection.emit.opcodes." + EncodedName.ToLowerInvariant() + ".aspx";
|
||||
public string EncodedName {
|
||||
get {
|
||||
@@ -89,4 +104,98 @@ namespace ICSharpCode.Decompiler.Disassembler
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ILParser
|
||||
{
|
||||
public static ILOpCode DecodeOpCode(ref BlobReader blob)
|
||||
{
|
||||
byte opCodeByte = blob.ReadByte();
|
||||
return (ILOpCode)(opCodeByte == 0xFE ? 0xFE00 + blob.ReadByte() : opCodeByte);
|
||||
}
|
||||
|
||||
public static void SkipOperand(ref BlobReader blob, ILOpCode opCode)
|
||||
{
|
||||
switch (opCode.GetOperandType()) {
|
||||
// 64-bit
|
||||
case OperandType.I8:
|
||||
case OperandType.R:
|
||||
blob.Offset += 8;
|
||||
break;
|
||||
// 32-bit
|
||||
case OperandType.BrTarget:
|
||||
case OperandType.Field:
|
||||
case OperandType.Method:
|
||||
case OperandType.I:
|
||||
case OperandType.Sig:
|
||||
case OperandType.String:
|
||||
case OperandType.Tok:
|
||||
case OperandType.Type:
|
||||
case OperandType.ShortR:
|
||||
blob.Offset += 4;
|
||||
break;
|
||||
// (n + 1) * 32-bit
|
||||
case OperandType.Switch:
|
||||
uint n = blob.ReadUInt32();
|
||||
blob.Offset += (int)(n * 4);
|
||||
break;
|
||||
// 16-bit
|
||||
case OperandType.Variable:
|
||||
blob.Offset += 2;
|
||||
break;
|
||||
// 8-bit
|
||||
case OperandType.ShortVariable:
|
||||
case OperandType.ShortBrTarget:
|
||||
case OperandType.ShortI:
|
||||
blob.Offset++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static int DecodeBranchTarget(ref BlobReader blob, ILOpCode opCode)
|
||||
{
|
||||
return (opCode.GetBranchOperandSize() == 4 ? blob.ReadInt32() : blob.ReadSByte()) + blob.Offset;
|
||||
}
|
||||
|
||||
public static int[] DecodeSwitchTargets(ref BlobReader blob)
|
||||
{
|
||||
int[] targets = new int[blob.ReadUInt32()];
|
||||
int offset = blob.Offset + 4 * targets.Length;
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
targets[i] = blob.ReadInt32() + offset;
|
||||
return targets;
|
||||
}
|
||||
|
||||
public static string DecodeUserString(ref BlobReader blob, Dom.PEFile module)
|
||||
{
|
||||
return module.GetMetadataReader().GetUserString(MetadataTokens.UserStringHandle(blob.ReadInt32()));
|
||||
}
|
||||
|
||||
public static Dom.IMemberReference DecodeMemberToken(ref BlobReader blob, Dom.PEFile module)
|
||||
{
|
||||
var handle = MetadataTokens.EntityHandle(blob.ReadInt32());
|
||||
switch (handle.Kind) {
|
||||
case HandleKind.TypeDefinition:
|
||||
return new Dom.TypeDefinition(module, (TypeDefinitionHandle)handle);
|
||||
case HandleKind.TypeReference:
|
||||
return new Dom.TypeReference(module, (TypeReferenceHandle)handle);
|
||||
case HandleKind.TypeSpecification:
|
||||
return new Dom.TypeSpecification(module, (TypeSpecificationHandle)handle);
|
||||
case HandleKind.MethodDefinition:
|
||||
return new Dom.MethodDefinition(module, (MethodDefinitionHandle)handle);
|
||||
case HandleKind.MethodSpecification:
|
||||
return new Dom.MethodSpecification(module, (MethodSpecificationHandle)handle);
|
||||
case HandleKind.FieldDefinition:
|
||||
return new Dom.FieldDefinition(module, (FieldDefinitionHandle)handle);
|
||||
case HandleKind.MemberReference:
|
||||
return new Dom.MemberReference(module, (MemberReferenceHandle)handle);
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsReturn(this ILOpCode opCode)
|
||||
{
|
||||
return opCode == ILOpCode.Ret || opCode == ILOpCode.Endfilter || opCode == ILOpCode.Endfinally;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+215
-24
@@ -1,17 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using ICSharpCode.Decompiler.TypeSystem.Implementation;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
|
||||
namespace ICSharpCode.Decompiler.TypeSystem
|
||||
namespace ICSharpCode.Decompiler
|
||||
{
|
||||
static class MetadataExtensions
|
||||
public static class MetadataExtensions
|
||||
{
|
||||
public static Dom.ITypeReference CoerceTypeReference(this EntityHandle handle, Dom.PEFile module)
|
||||
{
|
||||
if (handle.IsNil)
|
||||
return null;
|
||||
switch (handle.Kind) {
|
||||
case HandleKind.TypeDefinition:
|
||||
return new Dom.TypeDefinition(module, (TypeDefinitionHandle)handle);
|
||||
case HandleKind.TypeReference:
|
||||
return new Dom.TypeReference(module, (TypeReferenceHandle)handle);
|
||||
case HandleKind.TypeSpecification:
|
||||
return new Dom.TypeSpecification(module, (TypeSpecificationHandle)handle);
|
||||
default:
|
||||
throw new ArgumentException("must be either TypeDef, TypeRef or TypeSpec!", nameof(handle));
|
||||
}
|
||||
}
|
||||
|
||||
public static Dom.IMemberReference CoerceMemberReference(this EntityHandle handle, Dom.PEFile module)
|
||||
{
|
||||
if (handle.IsNil)
|
||||
return null;
|
||||
switch (handle.Kind) {
|
||||
case HandleKind.MemberReference:
|
||||
return new Dom.MemberReference(module, (MemberReferenceHandle)handle);
|
||||
case HandleKind.MethodDefinition:
|
||||
return new Dom.MethodDefinition(module, (MethodDefinitionHandle)handle);
|
||||
default:
|
||||
throw new ArgumentException("must be either MethodDef or MemberRef!", nameof(handle));
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsNil(this Dom.IAssemblyReference reference)
|
||||
{
|
||||
return reference == null || (reference is Dom.AssemblyReference ar && ar.IsNil);
|
||||
}
|
||||
|
||||
public static string GetFullAssemblyName(this MetadataReader reader)
|
||||
{
|
||||
if (!reader.IsAssembly)
|
||||
@@ -26,6 +66,20 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
return $"{reader.GetString(asm.Name)}, Version={asm.Version}, Culture={reader.GetString(asm.Culture)}, PublicKeyToken={publicKey}";
|
||||
}
|
||||
|
||||
public static string GetFullAssemblyName(this AssemblyReference reference, MetadataReader reader)
|
||||
{
|
||||
string publicKey = "null";
|
||||
if (!reference.PublicKeyOrToken.IsNil && (reference.Flags & AssemblyFlags.PublicKey) != 0) {
|
||||
SHA1 sha1 = SHA1.Create();
|
||||
var publicKeyTokenBytes = sha1.ComputeHash(reader.GetBlobBytes(reference.PublicKeyOrToken)).Skip(12).ToArray();
|
||||
publicKey = publicKeyTokenBytes.ToHexString();
|
||||
}
|
||||
string properties = "";
|
||||
if ((reference.Flags & AssemblyFlags.Retargetable) != 0)
|
||||
properties = ", Retargetable=true";
|
||||
return $"{reader.GetString(reference.Name)}, Version={reference.Version}, Culture={reader.GetString(reference.Culture)}, PublicKeyToken={publicKey}{properties}";
|
||||
}
|
||||
|
||||
static string ToHexString(this byte[] bytes)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(bytes.Length * 2);
|
||||
@@ -37,7 +91,24 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
/// <summary>
|
||||
/// Gets the type of the attribute.
|
||||
/// </summary>
|
||||
/// <returns>Either <see cref="TypeDefinitionHandle"/>, <see cref="TypeReferenceHandle"/>,<see cref="TypeSpecificationHandle".</returns>
|
||||
public static Dom.ITypeReference GetAttributeType(this CustomAttribute attribute, Dom.PEFile module)
|
||||
{
|
||||
var reader = module.GetMetadataReader();
|
||||
switch (attribute.Constructor.Kind) {
|
||||
case HandleKind.MethodDefinition:
|
||||
var md = reader.GetMethodDefinition((MethodDefinitionHandle)attribute.Constructor);
|
||||
return new Dom.TypeDefinition(module, md.GetDeclaringType());
|
||||
case HandleKind.MemberReference:
|
||||
var mr = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor);
|
||||
return mr.Parent.CoerceTypeReference(module);
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the attribute.
|
||||
/// </summary>
|
||||
public static EntityHandle GetAttributeType(this CustomAttribute attribute, MetadataReader reader)
|
||||
{
|
||||
switch (attribute.Constructor.Kind) {
|
||||
@@ -52,32 +123,61 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<TypeDefinitionHandle> GetTopLevelTypeDefinitions(this MetadataReader reader)
|
||||
{
|
||||
var queue = new Queue<NamespaceDefinition>();
|
||||
queue.Enqueue(reader.GetNamespaceDefinitionRoot());
|
||||
while (queue.Count > 0) {
|
||||
var ns = queue.Dequeue();
|
||||
foreach (var td in ns.TypeDefinitions)
|
||||
yield return td;
|
||||
foreach (var nestedNS in ns.NamespaceDefinitions)
|
||||
queue.Enqueue(reader.GetNamespaceDefinition(nestedNS));
|
||||
}
|
||||
}
|
||||
|
||||
public static FullTypeName GetFullTypeName(this EntityHandle handle, MetadataReader reader)
|
||||
{
|
||||
if (handle.IsNil)
|
||||
throw new ArgumentNullException(nameof(handle));
|
||||
switch (handle.Kind) {
|
||||
case HandleKind.TypeDefinition:
|
||||
return ((TypeDefinitionHandle)handle).GetFullTypeName(reader);
|
||||
case HandleKind.TypeReference:
|
||||
return ((TypeReferenceHandle)handle).GetFullTypeName(reader);
|
||||
case HandleKind.TypeSpecification:
|
||||
return ((TypeSpecificationHandle)handle).GetFullTypeName(reader);
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public static FullTypeName GetFullTypeName(this TypeReferenceHandle handle, MetadataReader reader)
|
||||
public static FullTypeName GetFullTypeName(this TypeSpecificationHandle handle, MetadataReader reader, bool omitGenericParamCount = false)
|
||||
{
|
||||
if (handle.IsNil)
|
||||
throw new ArgumentNullException(nameof(handle));
|
||||
var ts = reader.GetTypeSpecification(handle);
|
||||
return ts.DecodeSignature(new Dom.FullTypeNameSignatureDecoder(reader), default(Unit));
|
||||
}
|
||||
|
||||
public static FullTypeName GetFullTypeName(this TypeReferenceHandle handle, MetadataReader reader, bool omitGenericParamCount = false)
|
||||
{
|
||||
if (handle.IsNil)
|
||||
throw new ArgumentNullException(nameof(handle));
|
||||
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);
|
||||
return declaringTypeHandle.GetFullTypeName(reader, omitGenericParamCount).NestedType(reader.GetString(tr.Name), 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static FullTypeName GetFullTypeName(this TypeDefinitionHandle handle, MetadataReader reader)
|
||||
{
|
||||
if (handle.IsNil)
|
||||
throw new ArgumentNullException(nameof(handle));
|
||||
return reader.GetTypeDefinition(handle).GetFullTypeName(reader);
|
||||
}
|
||||
|
||||
@@ -86,9 +186,21 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
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));
|
||||
return new FullTypeName(new TopLevelTypeName(@namespace, reader.GetString(td.Name)));
|
||||
} else {
|
||||
return declaringTypeHandle.GetFullTypeName(reader).NestedType(reader.GetString(td.Name), td.GetGenericParameters().Count);
|
||||
return declaringTypeHandle.GetFullTypeName(reader).NestedType(reader.GetString(td.Name), 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static string ToILNameString(this FullTypeName typeName)
|
||||
{
|
||||
var escapedName = Disassembler.DisassemblerHelpers.Escape(typeName.Name);
|
||||
if (typeName.IsNested) {
|
||||
return $"{typeName.GetDeclaringType().ToILNameString()}/{escapedName}";
|
||||
} else if (!string.IsNullOrEmpty(typeName.TopLevelTypeName.Namespace)) {
|
||||
return $"{typeName.TopLevelTypeName.Namespace}.{escapedName}";
|
||||
} else {
|
||||
return $"{escapedName}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,23 +227,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe static MethodSemanticsAttributes GetMethodSemanticsAttributes(this MethodDefinitionHandle handle, MetadataReader reader)
|
||||
{
|
||||
byte* startPointer = reader.MetadataPointer;
|
||||
int offset = reader.GetTableMetadataOffset(TableIndex.MethodSemantics);
|
||||
int rowSize = reader.GetTableRowSize(TableIndex.MethodSemantics);
|
||||
int rowCount = reader.GetTableRowCount(TableIndex.MethodSemantics);
|
||||
int token = reader.GetToken(handle);
|
||||
for (int row = rowCount - 1; row >= 0; row--) {
|
||||
byte* ptr = startPointer + offset + rowSize * row;
|
||||
ushort methodToken = *(ptr + 2);
|
||||
if (token == methodToken) {
|
||||
return (MethodSemanticsAttributes)(*ptr);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static bool IsValueType(this TypeDefinition typeDefinition, MetadataReader reader)
|
||||
{
|
||||
if (typeDefinition.BaseType.IsNil)
|
||||
@@ -157,6 +252,32 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
return typeDefinition.BaseType.GetFullTypeName(reader).ToString() == "System.Enum";
|
||||
}
|
||||
|
||||
public static string GetDefaultMemberName(this TypeDefinitionHandle type, MetadataReader reader)
|
||||
{
|
||||
return type.GetDefaultMemberName(reader, out var attr);
|
||||
}
|
||||
|
||||
static readonly ITypeResolveContext minimalCorlibContext = new SimpleTypeResolveContext(MinimalCorlib.Instance.CreateCompilation());
|
||||
|
||||
public static string GetDefaultMemberName(this TypeDefinitionHandle type, MetadataReader reader, out CustomAttributeHandle defaultMemberAttribute)
|
||||
{
|
||||
var td = reader.GetTypeDefinition(type);
|
||||
|
||||
foreach (var h in td.GetCustomAttributes()) {
|
||||
var ca = reader.GetCustomAttribute(h);
|
||||
if (ca.GetAttributeType(reader).ToString() == "System.Reflection.DefaultMemberAttribute") {
|
||||
var decodedValues = ca.DecodeValue(new TypeSystemAttributeTypeProvider(minimalCorlibContext));
|
||||
if (decodedValues.FixedArguments.Length == 1 && decodedValues.FixedArguments[0].Value is string value) {
|
||||
defaultMemberAttribute = h;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultMemberAttribute = default(CustomAttributeHandle);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool HasOverrides(this MethodDefinitionHandle handle, MetadataReader reader)
|
||||
{
|
||||
for (int row = 1; row <= reader.GetTableRowCount(TableIndex.MethodImpl); row++) {
|
||||
@@ -267,5 +388,75 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
return KnownTypeCode.None;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsSmallReference(this MetadataReader reader, TableIndex table)
|
||||
{
|
||||
// TODO detect whether #JTD is present (EnC)
|
||||
return reader.GetTableRowCount(table) <= ushort.MaxValue;
|
||||
}
|
||||
|
||||
public static int GetReferenceSize(this MetadataReader reader, TableIndex table)
|
||||
{
|
||||
return IsSmallReference(reader, table) ? 2 : 4;
|
||||
}
|
||||
|
||||
public static unsafe (int startRow, int endRow) BinarySearchRange(this MetadataReader reader, TableIndex table, int valueOffset, uint referenceValue, bool small)
|
||||
{
|
||||
int offset = reader.GetTableMetadataOffset(table);
|
||||
int rowSize = reader.GetTableRowSize(table);
|
||||
int rowCount = reader.GetTableRowCount(table);
|
||||
int tableLength = rowSize * rowCount;
|
||||
byte* startPointer = reader.MetadataPointer;
|
||||
|
||||
int result = BinarySearch();
|
||||
if (result == -1)
|
||||
return (-1, -1);
|
||||
|
||||
int start = result;
|
||||
|
||||
while (start > 0 && GetValue(start - 1) == referenceValue)
|
||||
start--;
|
||||
|
||||
int end = result;
|
||||
|
||||
while (end + 1 < tableLength && GetValue(end + 1) == referenceValue)
|
||||
end++;
|
||||
|
||||
return (start, end);
|
||||
|
||||
uint GetValue(int row)
|
||||
{
|
||||
if (small)
|
||||
return *(ushort*)(startPointer + offset + row * rowSize + valueOffset);
|
||||
else
|
||||
return *(uint*)(startPointer + offset + row * rowSize + valueOffset);
|
||||
}
|
||||
|
||||
int BinarySearch()
|
||||
{
|
||||
int startRow = 0;
|
||||
int endRow = rowCount - 1;
|
||||
while (startRow <= endRow) {
|
||||
int row = (startRow + endRow) / 2;
|
||||
uint currentValue = GetValue(row);
|
||||
if (referenceValue > currentValue) {
|
||||
startRow = row + 1;
|
||||
} else if (referenceValue < currentValue) {
|
||||
endRow = row - 1;
|
||||
} else {
|
||||
return row;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static AssemblyDefinition? GetAssemblyDefinition(this PEReader reader)
|
||||
{
|
||||
var metadata = reader.GetMetadataReader();
|
||||
if (metadata.IsAssembly)
|
||||
return metadata.GetAssemblyDefinition();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
|
||||
namespace ICSharpCode.Decompiler.Dom
|
||||
{
|
||||
public interface IMetadataResolveContext
|
||||
{
|
||||
PEFile CurrentModule { get; }
|
||||
PEFile ResolveAssembly(IAssemblyReference reference);
|
||||
}
|
||||
|
||||
public class SimpleMetadataResolveContext : IMetadataResolveContext
|
||||
{
|
||||
readonly PEFile mainModule;
|
||||
readonly IAssemblyResolver assemblyResolver;
|
||||
readonly Dictionary<IAssemblyReference, PEFile> loadedModules = new Dictionary<IAssemblyReference, PEFile>();
|
||||
|
||||
public SimpleMetadataResolveContext(PEFile mainModule)
|
||||
{
|
||||
this.mainModule = mainModule;
|
||||
this.assemblyResolver = mainModule.AssemblyResolver;
|
||||
}
|
||||
|
||||
public PEFile CurrentModule => mainModule;
|
||||
|
||||
public PEFile ResolveAssembly(IAssemblyReference reference)
|
||||
{
|
||||
if (loadedModules.TryGetValue(reference, out var module))
|
||||
return module;
|
||||
var resolved = assemblyResolver.Resolve(reference);
|
||||
loadedModules.Add(reference, resolved);
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MetadataResolver
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements resolving of TypeReferences to TypeDefinitions as decribed in II.7.3 of ECMA-335 6th edition.
|
||||
/// </summary>
|
||||
public static TypeDefinition Resolve(TypeReferenceHandle handle, IMetadataResolveContext context)
|
||||
{
|
||||
var metadata = context.CurrentModule.GetMetadataReader();
|
||||
var tr = metadata.GetTypeReference(handle);
|
||||
if (tr.ResolutionScope.IsNil) {
|
||||
foreach (var h in metadata.ExportedTypes) {
|
||||
var exportedType = metadata.GetExportedType(h);
|
||||
if (exportedType.Name == tr.Name && exportedType.Namespace == tr.Namespace) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (tr.ResolutionScope.Kind) {
|
||||
case HandleKind.TypeReference:
|
||||
//return Resolve((TypeReferenceHandle)tr.ResolutionScope, context).GetNestedType(new );
|
||||
break;
|
||||
case HandleKind.ModuleReference:
|
||||
break;
|
||||
case HandleKind.AssemblyReference:
|
||||
var module = context.ResolveAssembly(new AssemblyReference(context.CurrentModule, (AssemblyReferenceHandle)tr.ResolutionScope));
|
||||
var moduleMetadata = module.GetMetadataReader();
|
||||
var @namespace = ResolveNamespace(moduleMetadata, metadata.GetString(tr.Namespace).Split('.'));
|
||||
if (@namespace == null)
|
||||
throw new NotSupportedException();
|
||||
var type = FindTypeInNamespace(moduleMetadata, @namespace.Value, metadata.GetString(tr.Name));
|
||||
if (type.IsNil)
|
||||
throw new NotSupportedException();
|
||||
return new TypeDefinition(module, type);
|
||||
}
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
static NamespaceDefinition? ResolveNamespace(MetadataReader metadata, string[] namespaceParts)
|
||||
{
|
||||
var currentNamespace = metadata.GetNamespaceDefinitionRoot();
|
||||
for (int i = 0; i < namespaceParts.Length; i++) {
|
||||
string identifier = namespaceParts[i];
|
||||
var next = currentNamespace.NamespaceDefinitions.FirstOrDefault(ns => metadata.GetString(metadata.GetNamespaceDefinition(ns).Name) == identifier);
|
||||
if (next.IsNil)
|
||||
return null;
|
||||
currentNamespace = metadata.GetNamespaceDefinition(next);
|
||||
}
|
||||
return currentNamespace;
|
||||
}
|
||||
|
||||
static TypeDefinitionHandle FindTypeInNamespace(MetadataReader metadata, NamespaceDefinition @namespace, string name)
|
||||
{
|
||||
foreach (var type in @namespace.TypeDefinitions) {
|
||||
var typeName = metadata.GetString(metadata.GetTypeDefinition(type).Name);
|
||||
if (name == typeName)
|
||||
return type;
|
||||
}
|
||||
return default(TypeDefinitionHandle);
|
||||
}
|
||||
|
||||
public static IMemberDefinition Resolve(MemberReferenceHandle handle, IMetadataResolveContext context)
|
||||
{
|
||||
var metadata = context.CurrentModule.GetMetadataReader();
|
||||
var mr = metadata.GetMemberReference(handle);
|
||||
TypeDefinition declaringType;
|
||||
switch (mr.Parent.Kind) {
|
||||
case HandleKind.TypeDefinition:
|
||||
declaringType = new TypeDefinition(context.CurrentModule, (TypeDefinitionHandle)mr.Parent);
|
||||
break;
|
||||
case HandleKind.TypeReference:
|
||||
declaringType = Resolve((TypeReferenceHandle)mr.Parent, context);
|
||||
break;
|
||||
case HandleKind.TypeSpecification:
|
||||
case HandleKind.MethodDefinition:
|
||||
case HandleKind.ModuleReference:
|
||||
throw new NotImplementedException();
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
var name = metadata.GetString(mr.Name);
|
||||
switch (mr.GetKind()) {
|
||||
case MemberReferenceKind.Field:
|
||||
return declaringType.Fields.FirstOrDefault(fd => fd.Name == name);
|
||||
case MemberReferenceKind.Method:
|
||||
var signature = mr.DecodeMethodSignature(new TypeSystem.Implementation.TypeReferenceSignatureDecoder(), default(Unit));
|
||||
return declaringType.Methods.SingleOrDefault(md => MatchMethodDefinition(name, signature, md));
|
||||
}
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
static bool MatchMethodDefinition(string name, MethodSignature<TypeSystem.ITypeReference> signature, MethodDefinition md)
|
||||
{
|
||||
if (name != md.Name || md.GenericParameters.Count != signature.GenericParameterCount || signature.RequiredParameterCount != md.Parameters.Count)
|
||||
return false;
|
||||
// TODO overload resolution... OMG
|
||||
return true;
|
||||
}
|
||||
|
||||
public static TypeDefinition Resolve(TypeSpecificationHandle handle, IMetadataResolveContext context)
|
||||
{
|
||||
var metadata = context.CurrentModule.GetMetadataReader();
|
||||
var ts = metadata.GetTypeSpecification(handle);
|
||||
var unspecialized = ts.DecodeSignature(new Unspecializer(), default(Unit));
|
||||
switch (unspecialized.Kind) {
|
||||
case HandleKind.TypeDefinition:
|
||||
return new TypeDefinition(context.CurrentModule, (TypeDefinitionHandle)unspecialized);
|
||||
case HandleKind.TypeReference:
|
||||
return Resolve((TypeReferenceHandle)unspecialized, context);
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
class Unspecializer : ISignatureTypeProvider<EntityHandle, Unit>
|
||||
{
|
||||
public EntityHandle GetArrayType(EntityHandle elementType, ArrayShape shape)
|
||||
{
|
||||
return elementType;
|
||||
}
|
||||
|
||||
public EntityHandle GetByReferenceType(EntityHandle elementType)
|
||||
{
|
||||
return elementType;
|
||||
}
|
||||
|
||||
public EntityHandle GetFunctionPointerType(MethodSignature<EntityHandle> signature)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public EntityHandle GetGenericInstantiation(EntityHandle genericType, ImmutableArray<EntityHandle> typeArguments)
|
||||
{
|
||||
return genericType;
|
||||
}
|
||||
|
||||
public EntityHandle GetGenericMethodParameter(Unit genericContext, int index)
|
||||
{
|
||||
return MetadataTokens.EntityHandle(0);
|
||||
}
|
||||
|
||||
public EntityHandle GetGenericTypeParameter(Unit genericContext, int index)
|
||||
{
|
||||
return MetadataTokens.EntityHandle(0);
|
||||
}
|
||||
|
||||
public EntityHandle GetModifiedType(EntityHandle modifier, EntityHandle unmodifiedType, bool isRequired)
|
||||
{
|
||||
return unmodifiedType;
|
||||
}
|
||||
|
||||
public EntityHandle GetPinnedType(EntityHandle elementType)
|
||||
{
|
||||
return elementType;
|
||||
}
|
||||
|
||||
public EntityHandle GetPointerType(EntityHandle elementType)
|
||||
{
|
||||
return elementType;
|
||||
}
|
||||
|
||||
public EntityHandle GetPrimitiveType(PrimitiveTypeCode typeCode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public EntityHandle GetSZArrayType(EntityHandle elementType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public EntityHandle GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
|
||||
public EntityHandle GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
|
||||
public EntityHandle GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
|
||||
{
|
||||
return reader.GetTypeSpecification(handle).DecodeSignature(this, genericContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Text;
|
||||
|
||||
namespace ICSharpCode.Decompiler.Dom
|
||||
{
|
||||
using SRMDocument = System.Reflection.Metadata.Document;
|
||||
|
||||
/// <summary>
|
||||
/// A sequence point read from a PDB file or produced by the decompiler.
|
||||
/// </summary>
|
||||
public struct SequencePoint
|
||||
{
|
||||
/// <summary>
|
||||
/// IL start offset.
|
||||
/// </summary>
|
||||
public int Offset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IL end offset.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This does not get stored in debug information;
|
||||
/// it is used internally to create hidden sequence points
|
||||
/// for the IL fragments not covered by any sequence point.
|
||||
/// </remarks>
|
||||
public int EndOffset { get; set; }
|
||||
|
||||
public int StartLine { get; set; }
|
||||
public int StartColumn { get; set; }
|
||||
public int EndLine { get; set; }
|
||||
public int EndColumn { get; set; }
|
||||
|
||||
public bool IsHidden {
|
||||
get { return StartLine == 0xfeefee && StartLine == EndLine; }
|
||||
}
|
||||
|
||||
public Document Document { get; set; }
|
||||
|
||||
internal void SetHidden()
|
||||
{
|
||||
StartLine = EndLine = 0xfeefee;
|
||||
}
|
||||
}
|
||||
|
||||
public struct Document : IEquatable<Document>
|
||||
{
|
||||
public PEFile Module { get; }
|
||||
public DocumentHandle Handle { get; }
|
||||
public bool IsNil => Handle.IsNil;
|
||||
|
||||
public Document(PEFile module, DocumentHandle handle) : this()
|
||||
{
|
||||
this.Module = module ?? throw new ArgumentNullException(nameof(module));
|
||||
this.Handle = handle;
|
||||
}
|
||||
|
||||
SRMDocument This() => Module.GetMetadataReader().GetDocument(Handle);
|
||||
|
||||
public bool Equals(Document other)
|
||||
{
|
||||
return Module == other.Module && Handle == other.Handle;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is Document md)
|
||||
return Equals(md);
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return unchecked(982451629 * Module.GetHashCode() + 982451653 * MetadataTokens.GetToken(Handle));
|
||||
}
|
||||
|
||||
public static bool operator ==(Document lhs, Document rhs) => lhs.Equals(rhs);
|
||||
public static bool operator !=(Document lhs, Document rhs) => !lhs.Equals(rhs);
|
||||
|
||||
public string Url {
|
||||
get {
|
||||
if (Handle.IsNil)
|
||||
return null;
|
||||
var h = This().Name;
|
||||
if (h.IsNil) return null;
|
||||
return Module.GetMetadataReader().GetString(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,8 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using LightJson.Serialization;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.Decompiler
|
||||
{
|
||||
@@ -70,7 +70,7 @@ namespace ICSharpCode.Decompiler
|
||||
}
|
||||
}
|
||||
|
||||
public string TryResolveDotNetCore(AssemblyNameReference name)
|
||||
public string TryResolveDotNetCore(IAssemblyReference name)
|
||||
{
|
||||
foreach (var basePath in packageBasePaths) {
|
||||
if (File.Exists(Path.Combine(basePath, name.Name + ".dll"))) {
|
||||
@@ -106,7 +106,7 @@ namespace ICSharpCode.Decompiler
|
||||
}
|
||||
}
|
||||
|
||||
string FallbackToDotNetSharedDirectory(AssemblyNameReference name, Version version)
|
||||
string FallbackToDotNetSharedDirectory(IAssemblyReference name, Version version)
|
||||
{
|
||||
if (dotnetBasePath == null) return null;
|
||||
var basePath = Path.Combine(dotnetBasePath, "shared", "Microsoft.NETCore.App");
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ICSharpCode.Decompiler.TypeSystem.Implementation;
|
||||
using Mono.Cecil;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.PortableExecutable;
|
||||
|
||||
namespace ICSharpCode.Decompiler
|
||||
{
|
||||
public static class DotNetCorePathFinderExtensions
|
||||
{
|
||||
public static string DetectTargetFrameworkId(this AssemblyDefinition assembly)
|
||||
public static string DetectTargetFrameworkId(this PEReader assembly)
|
||||
{
|
||||
if (assembly == null)
|
||||
throw new ArgumentNullException(nameof(assembly));
|
||||
|
||||
const string TargetFrameworkAttributeName = "System.Runtime.Versioning.TargetFrameworkAttribute";
|
||||
var reader = assembly.GetMetadataReader();
|
||||
|
||||
foreach (var attribute in assembly.CustomAttributes) {
|
||||
if (attribute.AttributeType.FullName != TargetFrameworkAttributeName)
|
||||
foreach (var h in reader.GetCustomAttributes(Handle.AssemblyDefinition)) {
|
||||
var attribute = reader.GetCustomAttribute(h);
|
||||
if (attribute.GetAttributeType(reader).ToString() != TargetFrameworkAttributeName)
|
||||
continue;
|
||||
var blobReader = new BlobReader(attribute.GetBlob(), null);
|
||||
var blobReader = reader.GetBlobReader(attribute.Value);
|
||||
if (blobReader.ReadUInt16() == 0x0001) {
|
||||
return blobReader.ReadSerString();
|
||||
return blobReader.ReadSerializedString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Text;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.Decompiler
|
||||
{
|
||||
@@ -58,26 +59,18 @@ namespace ICSharpCode.Decompiler
|
||||
AddSearchDirectory(baseDirectory);
|
||||
}
|
||||
|
||||
public static ModuleDefinition LoadMainModule(string mainAssemblyFileName, bool throwOnError = true, bool inMemory = false)
|
||||
public static PEFile LoadMainModule(string mainAssemblyFileName, bool throwOnError = true, bool inMemory = false)
|
||||
{
|
||||
var resolver = new UniversalAssemblyResolver(mainAssemblyFileName, throwOnError);
|
||||
|
||||
var module = ModuleDefinition.ReadModule(mainAssemblyFileName, new ReaderParameters {
|
||||
AssemblyResolver = resolver,
|
||||
InMemory = inMemory
|
||||
});
|
||||
var module = new PEReader(new FileStream(mainAssemblyFileName, FileMode.Open));
|
||||
|
||||
resolver.TargetFramework = module.Assembly.DetectTargetFrameworkId();
|
||||
resolver.TargetFramework = module.DetectTargetFrameworkId();
|
||||
|
||||
return module;
|
||||
return new PEFile(mainAssemblyFileName, module, resolver);
|
||||
}
|
||||
|
||||
public AssemblyDefinition Resolve(AssemblyNameReference name)
|
||||
{
|
||||
return Resolve(name, new ReaderParameters());
|
||||
}
|
||||
|
||||
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
|
||||
public PEFile Resolve(IAssemblyReference name)
|
||||
{
|
||||
var file = FindAssemblyFile(name);
|
||||
if (file == null) {
|
||||
@@ -85,10 +78,10 @@ namespace ICSharpCode.Decompiler
|
||||
throw new AssemblyResolutionException(name);
|
||||
return null;
|
||||
}
|
||||
return GetAssembly(file, parameters);
|
||||
return new PEFile(file, GetAssembly(file), this);
|
||||
}
|
||||
|
||||
public string FindAssemblyFile(AssemblyNameReference name)
|
||||
public string FindAssemblyFile(IAssemblyReference name)
|
||||
{
|
||||
var targetFramework = TargetFramework.Split(new[] { ",Version=v" }, StringSplitOptions.None);
|
||||
string file = null;
|
||||
@@ -110,28 +103,21 @@ namespace ICSharpCode.Decompiler
|
||||
}
|
||||
}
|
||||
|
||||
string ResolveInternal(AssemblyNameReference name)
|
||||
string ResolveInternal(IAssemblyReference name)
|
||||
{
|
||||
if (name == null)
|
||||
if (name.IsNil())
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
|
||||
var assembly = SearchDirectory(name, directories);
|
||||
if (assembly != null)
|
||||
return assembly;
|
||||
|
||||
if (name.IsRetargetable) {
|
||||
// if the reference is retargetable, zero it
|
||||
name = new AssemblyNameReference(name.Name, ZeroVersion) {
|
||||
PublicKeyToken = Empty<byte>.Array,
|
||||
};
|
||||
}
|
||||
|
||||
var framework_dir = Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName);
|
||||
var framework_dirs = DetectMono()
|
||||
? new[] { framework_dir, Path.Combine(framework_dir, "Facades") }
|
||||
: new[] { framework_dir };
|
||||
|
||||
if (IsZero(name.Version)) {
|
||||
if (IsZeroVersionOrRetargetable(name)) {
|
||||
assembly = SearchDirectory(name, framework_dirs);
|
||||
if (assembly != null)
|
||||
return assembly;
|
||||
@@ -157,7 +143,7 @@ namespace ICSharpCode.Decompiler
|
||||
}
|
||||
|
||||
#region .NET / mono GAC handling
|
||||
string SearchDirectory(AssemblyNameReference name, IEnumerable<string> directories)
|
||||
string SearchDirectory(IAssemblyReference name, IEnumerable<string> directories)
|
||||
{
|
||||
var extensions = name.IsWindowsRuntime ? new[] { ".winmd", ".dll" } : new[] { ".exe", ".dll" };
|
||||
foreach (var directory in directories) {
|
||||
@@ -176,19 +162,22 @@ namespace ICSharpCode.Decompiler
|
||||
return null;
|
||||
}
|
||||
|
||||
static bool IsZeroVersionOrRetargetable(IAssemblyReference reference)
|
||||
{
|
||||
return IsZero(reference.Version) || reference.IsRetargetable;
|
||||
}
|
||||
|
||||
static bool IsZero(Version version)
|
||||
{
|
||||
return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0;
|
||||
}
|
||||
|
||||
static Version ZeroVersion = new Version(0, 0, 0, 0);
|
||||
|
||||
string GetCorlib(AssemblyNameReference reference)
|
||||
string GetCorlib(IAssemblyReference reference)
|
||||
{
|
||||
var version = reference.Version;
|
||||
var corlib = typeof(object).Assembly.GetName();
|
||||
|
||||
if (corlib.Version == version || IsZero(version))
|
||||
if (corlib.Version == version || IsZeroVersionOrRetargetable(reference))
|
||||
return typeof(object).Module.FullyQualifiedName;
|
||||
|
||||
var path = Directory.GetParent(
|
||||
@@ -286,15 +275,12 @@ namespace ICSharpCode.Decompiler
|
||||
"gac");
|
||||
}
|
||||
|
||||
AssemblyDefinition GetAssembly(string file, ReaderParameters parameters)
|
||||
PEReader GetAssembly(string file)
|
||||
{
|
||||
if (parameters.AssemblyResolver == null)
|
||||
parameters.AssemblyResolver = this;
|
||||
|
||||
return ModuleDefinition.ReadModule(file, parameters).Assembly;
|
||||
return new PEReader(new FileStream(file, FileMode.Open));
|
||||
}
|
||||
|
||||
string GetAssemblyInGac(AssemblyNameReference reference)
|
||||
string GetAssemblyInGac(IAssemblyReference reference)
|
||||
{
|
||||
if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)
|
||||
return null;
|
||||
@@ -305,7 +291,7 @@ namespace ICSharpCode.Decompiler
|
||||
return GetAssemblyInNetGac(reference);
|
||||
}
|
||||
|
||||
string GetAssemblyInMonoGac(AssemblyNameReference reference)
|
||||
string GetAssemblyInMonoGac(IAssemblyReference reference)
|
||||
{
|
||||
for (int i = 0; i < gac_paths.Count; i++) {
|
||||
var gac_path = gac_paths[i];
|
||||
@@ -317,7 +303,7 @@ namespace ICSharpCode.Decompiler
|
||||
return null;
|
||||
}
|
||||
|
||||
string GetAssemblyInNetGac(AssemblyNameReference reference)
|
||||
string GetAssemblyInNetGac(IAssemblyReference reference)
|
||||
{
|
||||
var gacs = new[] { "GAC_MSIL", "GAC_32", "GAC_64", "GAC" };
|
||||
var prefixes = new[] { string.Empty, "v4.0_" };
|
||||
@@ -334,7 +320,7 @@ namespace ICSharpCode.Decompiler
|
||||
return null;
|
||||
}
|
||||
|
||||
static string GetAssemblyFile(AssemblyNameReference reference, string prefix, string gac)
|
||||
static string GetAssemblyFile(IAssemblyReference reference, string prefix, string gac)
|
||||
{
|
||||
var gac_folder = new StringBuilder()
|
||||
.Append(prefix)
|
||||
|
||||
@@ -268,6 +268,8 @@
|
||||
<Compile Include="CSharp\Transforms\ReplaceMethodCallsWithOperators.cs" />
|
||||
<Compile Include="CSharp\WholeProjectDecompiler.cs" />
|
||||
<Compile Include="CSharp\Transforms\AddXmlDocumentationTransform.cs" />
|
||||
<Compile Include="Disassembler\BlobDecoder.cs" />
|
||||
<Compile Include="Disassembler\DomExtensions.cs" />
|
||||
<Compile Include="Disassembler\OpCodeInfo.cs" />
|
||||
<Compile Include="Documentation\GetPotentiallyNestedClassTypeReference.cs" />
|
||||
<Compile Include="Documentation\IdStringMemberReference.cs" />
|
||||
@@ -275,6 +277,8 @@
|
||||
<Compile Include="Documentation\XmlDocKeyProvider.cs" />
|
||||
<Compile Include="Documentation\XmlDocLoader.cs" />
|
||||
<Compile Include="Documentation\XmlDocumentationProvider.cs" />
|
||||
<Compile Include="Dom\Dom.cs" />
|
||||
<Compile Include="Dom\MetadataResolver.cs" />
|
||||
<Compile Include="DotNetCore\DotNetCorePathFinder.cs" />
|
||||
<Compile Include="DotNetCore\DotNetCorePathFinderExtensions.cs" />
|
||||
<Compile Include="DotNetCore\LightJson\JsonArray.cs" />
|
||||
@@ -292,7 +296,7 @@
|
||||
<Compile Include="IL\ILAstWritingOptions.cs" />
|
||||
<Compile Include="IL\Instructions\LdFlda.cs" />
|
||||
<Compile Include="IL\Instructions\StLoc.cs" />
|
||||
<Compile Include="IL\SequencePoint.cs" />
|
||||
<Compile Include="Dom\SequencePoint.cs" />
|
||||
<Compile Include="IL\Instructions\CallIndirect.cs" />
|
||||
<Compile Include="IL\Instructions\DefaultValue.cs" />
|
||||
<Compile Include="IL\Transforms\EarlyExpressionTransforms.cs" />
|
||||
@@ -326,7 +330,7 @@
|
||||
<Compile Include="IL\Transforms\TransformCollectionAndObjectInitializers.cs" />
|
||||
<Compile Include="Output\TextTokenWriter.cs" />
|
||||
<Compile Include="TypeSystem\Implementation\TypeSpecification.cs" />
|
||||
<Compile Include="TypeSystem\MetadataExtensions.cs" />
|
||||
<Compile Include="Dom\MetadataExtensions.cs" />
|
||||
<Compile Include="Util\GraphVizGraph.cs" />
|
||||
<Compile Include="Util\KeyComparer.cs" />
|
||||
<Compile Include="Util\LongDict.cs" />
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -21,40 +21,148 @@
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ import namespace="System.Reflection.Metadata" #>
|
||||
<#@ import namespace="System.Reflection.Emit" #>
|
||||
<#@ output extension=".cs" #>
|
||||
using System;
|
||||
using System.Reflection.Emit;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.Metadata;
|
||||
<#
|
||||
var operandTypes = new OperandType[0x11f];
|
||||
|
||||
var operandTypes = Enumerable.Repeat((OperandType)0xff, 0x11f).ToArray();
|
||||
var operandNames = new string[0x11f];
|
||||
#>
|
||||
namespace ICSharpCode.Decompiler.IL
|
||||
{
|
||||
enum ILOpCode : ushort
|
||||
/// <summary>Describes the operand type of Microsoft intermediate language (MSIL) instruction.</summary>
|
||||
public enum OperandType
|
||||
{
|
||||
<# foreach (var field in typeof(OpCodes).GetFields()) {
|
||||
var opCode = (OpCode)field.GetValue(null);
|
||||
ushort val = (ushort)(((opCode.Value & 0x200) >> 1) | (opCode.Value & 0xff));
|
||||
operandTypes[val] = opCode.OperandType;
|
||||
#>
|
||||
<#=field.Name#> = 0x<#=val.ToString("x2")#>,
|
||||
<# } // end foreach #>
|
||||
/// <summary>The operand is a 32-bit integer branch target.</summary>
|
||||
BrTarget,
|
||||
/// <summary>The operand is a 32-bit metadata token.</summary>
|
||||
Field,
|
||||
/// <summary>The operand is a 32-bit integer.</summary>
|
||||
I,
|
||||
/// <summary>The operand is a 64-bit integer.</summary>
|
||||
I8,
|
||||
/// <summary>The operand is a 32-bit metadata token.</summary>
|
||||
Method,
|
||||
/// <summary>No operand.</summary>
|
||||
None,
|
||||
/// <summary>The operand is reserved and should not be used.</summary>
|
||||
[Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
|
||||
Phi,
|
||||
/// <summary>The operand is a 64-bit IEEE floating point number.</summary>
|
||||
R,
|
||||
/// <summary>The operand is a 32-bit metadata signature token.</summary>
|
||||
Sig = 9,
|
||||
/// <summary>The operand is a 32-bit metadata string token.</summary>
|
||||
String,
|
||||
/// <summary>The operand is the 32-bit integer argument to a switch instruction.</summary>
|
||||
Switch,
|
||||
/// <summary>The operand is a <see langword="FieldRef" />, <see langword="MethodRef" />, or <see langword="TypeRef" /> token.</summary>
|
||||
Tok,
|
||||
/// <summary>The operand is a 32-bit metadata token.</summary>
|
||||
Type,
|
||||
/// <summary>The operand is 16-bit integer containing the ordinal of a local variable or an argument.</summary>
|
||||
Variable,
|
||||
/// <summary>The operand is an 8-bit integer branch target.</summary>
|
||||
ShortBrTarget,
|
||||
/// <summary>The operand is an 8-bit integer.</summary>
|
||||
ShortI,
|
||||
/// <summary>The operand is a 32-bit IEEE floating point number.</summary>
|
||||
ShortR,
|
||||
/// <summary>The operand is an 8-bit integer containing the ordinal of a local variable or an argumenta.</summary>
|
||||
ShortVariable
|
||||
}
|
||||
|
||||
<#
|
||||
foreach (var field in typeof(OpCodes).GetFields()) {
|
||||
var opCode = (OpCode)field.GetValue(null);
|
||||
ushort index = (ushort)(((opCode.Value & 0x200) >> 1) | (opCode.Value & 0xff));
|
||||
operandTypes[index] = opCode.OperandType;
|
||||
operandNames[index] = opCode.Name;
|
||||
} #>
|
||||
|
||||
static class ILOpCodeExtensions
|
||||
{
|
||||
// We use a byte array instead of an enum array because it can be initialized more efficiently
|
||||
static readonly byte[] operandTypes = { <#
|
||||
foreach (var operandType in operandTypes) {
|
||||
string operandTypeName = operandType.ToString().Replace("Inline", "").Replace("Var", "Variable");
|
||||
Write("(byte)OperandType." + operandTypeName + ", ");
|
||||
if ((byte)operandType == 255) {
|
||||
Write("255, ");
|
||||
} else {
|
||||
string operandTypeName = operandType.ToString().Replace("Inline", "").Replace("Var", "Variable");
|
||||
Write("(byte)OperandType." + operandTypeName + ", ");
|
||||
}
|
||||
}
|
||||
#> };
|
||||
|
||||
static readonly string[] operandNames = { <#
|
||||
foreach (var operandName in operandNames) {
|
||||
Write("\"" + operandName + "\", ");
|
||||
}
|
||||
#> };
|
||||
|
||||
public static OperandType GetOperandType(this ILOpCode opCode)
|
||||
{
|
||||
return (OperandType)operandTypes[(ushort)opCode];
|
||||
ushort index = (ushort)((((int)opCode & 0x200) >> 1) | ((int)opCode & 0xff));
|
||||
if (index >= operandTypes.Length)
|
||||
return (OperandType)255;
|
||||
return (OperandType)operandTypes[index];
|
||||
}
|
||||
|
||||
public static string GetDisplayName(this ILOpCode opCode)
|
||||
{
|
||||
ushort index = (ushort)((((int)opCode & 0x200) >> 1) | ((int)opCode & 0xff));
|
||||
if (index >= operandNames.Length)
|
||||
return "";
|
||||
return operandNames[index];
|
||||
}
|
||||
|
||||
public static bool IsDefined(this ILOpCode opCode)
|
||||
{
|
||||
return !string.IsNullOrEmpty(GetDisplayName(opCode));
|
||||
}
|
||||
|
||||
public static readonly HashSet<string> ILKeywords = BuildKeywordList(
|
||||
"abstract", "algorithm", "alignment", "ansi", "any", "arglist",
|
||||
"array", "as", "assembly", "assert", "at", "auto", "autochar", "beforefieldinit",
|
||||
"blob", "blob_object", "bool", "brnull", "brnull.s", "brzero", "brzero.s", "bstr",
|
||||
"bytearray", "byvalstr", "callmostderived", "carray", "catch", "cdecl", "cf",
|
||||
"char", "cil", "class", "clsid", "const", "currency", "custom", "date", "decimal",
|
||||
"default", "demand", "deny", "endmac", "enum", "error", "explicit", "extends", "extern",
|
||||
"false", "famandassem", "family", "famorassem", "fastcall", "fault", "field", "filetime",
|
||||
"filter", "final", "finally", "fixed", "float", "float32", "float64", "forwardref",
|
||||
"fromunmanaged", "handler", "hidebysig", "hresult", "idispatch", "il", "illegal",
|
||||
"implements", "implicitcom", "implicitres", "import", "in", "inheritcheck", "init",
|
||||
"initonly", "instance", "int", "int16", "int32", "int64", "int8", "interface", "internalcall",
|
||||
"iunknown", "lasterr", "lcid", "linkcheck", "literal", "localloc", "lpstr", "lpstruct", "lptstr",
|
||||
"lpvoid", "lpwstr", "managed", "marshal", "method", "modopt", "modreq", "native", "nested",
|
||||
"newslot", "noappdomain", "noinlining", "nomachine", "nomangle", "nometadata", "noncasdemand",
|
||||
"noncasinheritance", "noncaslinkdemand", "noprocess", "not", "not_in_gc_heap", "notremotable",
|
||||
"notserialized", "null", "nullref", "object", "objectref", "opt", "optil", "out",
|
||||
"permitonly", "pinned", "pinvokeimpl", "prefix1", "prefix2", "prefix3", "prefix4", "prefix5", "prefix6",
|
||||
"prefix7", "prefixref", "prejitdeny", "prejitgrant", "preservesig", "private", "privatescope", "protected",
|
||||
"public", "record", "refany", "reqmin", "reqopt", "reqrefuse", "reqsecobj", "request", "retval",
|
||||
"rtspecialname", "runtime", "safearray", "sealed", "sequential", "serializable", "special", "specialname",
|
||||
"static", "stdcall", "storage", "stored_object", "stream", "streamed_object", "string", "struct",
|
||||
"synchronized", "syschar", "sysstring", "tbstr", "thiscall", "tls", "to", "true", "typedref",
|
||||
"unicode", "unmanaged", "unmanagedexp", "unsigned", "unused", "userdefined", "value", "valuetype",
|
||||
"vararg", "variant", "vector", "virtual", "void", "wchar", "winapi", "with", "wrapper",
|
||||
|
||||
// These are not listed as keywords in spec, but ILAsm treats them as such
|
||||
"property", "type", "flags", "callconv", "strict"
|
||||
);
|
||||
|
||||
static HashSet<string> BuildKeywordList(params string[] keywords)
|
||||
{
|
||||
HashSet<string> s = new HashSet<string>(keywords);
|
||||
foreach (var inst in operandNames) {
|
||||
if (string.IsNullOrEmpty(inst))
|
||||
continue;
|
||||
s.Add(inst);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ICSharpCode.Decompiler.IL
|
||||
{
|
||||
/// <summary>
|
||||
/// A sequence point produced by the decompiler.
|
||||
/// </summary>
|
||||
public struct SequencePoint
|
||||
{
|
||||
/// <summary>
|
||||
/// IL start offset.
|
||||
/// </summary>
|
||||
public int Offset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IL end offset.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This does not get stored in debug information;
|
||||
/// it is used internally to create hidden sequence points
|
||||
/// for the IL fragments not covered by any sequence point.
|
||||
/// </remarks>
|
||||
public int EndOffset { get; set; }
|
||||
|
||||
public int StartLine { get; set; }
|
||||
public int StartColumn { get; set; }
|
||||
public int EndLine { get; set; }
|
||||
public int EndColumn { get; set; }
|
||||
|
||||
public bool IsHidden {
|
||||
get { return StartLine == 0xfeefee && StartLine == EndLine; }
|
||||
}
|
||||
|
||||
internal void SetHidden()
|
||||
{
|
||||
StartLine = EndLine = 0xfeefee;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,7 +227,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
InitTypeDefinition(cecilTypeDefs[i], typeDefs[i]);
|
||||
}
|
||||
|
||||
AddToTypeSystemTranslationTable(this.currentAssembly, assemblyDefinition);
|
||||
//AddToTypeSystemTranslationTable(this.currentAssembly, assemblyDefinition);
|
||||
// Freezing the assembly here is important:
|
||||
// otherwise it will be frozen when a compilation is first created
|
||||
// from it. But freezing has the effect of changing some collection instances
|
||||
@@ -911,7 +911,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
{
|
||||
foreach (MethodDefinitionHandle h in typeDefinition.GetMethods()) {
|
||||
var method = currentModule.GetMethodDefinition(h);
|
||||
if (IsVisible(method.Attributes) && !IsAccessor(h.GetMethodSemanticsAttributes(currentModule))) {
|
||||
/*if (IsVisible(method.Attributes) && !IsAccessor(h.GetMethodSemanticsAttributes(currentModule))) {
|
||||
SymbolKind type = SymbolKind.Method;
|
||||
if ((method.Attributes & MethodAttributes.SpecialName) != 0) {
|
||||
if (method.IsConstructor(currentModule))
|
||||
@@ -920,7 +920,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
type = SymbolKind.Operator;
|
||||
}
|
||||
members.Add(ReadMethod(h, td, type));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
foreach (FieldDefinitionHandle h in typeDefinition.GetFields()) {
|
||||
var field = currentModule.GetFieldDefinition(h);
|
||||
@@ -1714,39 +1714,45 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
|
||||
public AssemblyDefinition GetCecilObject (IUnresolvedAssembly content)
|
||||
{
|
||||
return InternalGetCecilObject<AssemblyDefinition> (content);
|
||||
throw new NotImplementedException();
|
||||
//return InternalGetCecilObject<AssemblyDefinition> (content);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TypeDefinition GetCecilObject (IUnresolvedTypeDefinition type)
|
||||
{
|
||||
if (type == null)
|
||||
throw new ArgumentNullException ("type");
|
||||
return InternalGetCecilObject<TypeDefinition> (type);
|
||||
throw new NotImplementedException();
|
||||
//return InternalGetCecilObject<TypeDefinition> (type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public MethodDefinition GetCecilObject (IUnresolvedMethod method)
|
||||
{
|
||||
return InternalGetCecilObject<MethodDefinition> (method);
|
||||
throw new NotImplementedException();
|
||||
//return InternalGetCecilObject<MethodDefinition> (method);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public FieldDefinition GetCecilObject (IUnresolvedField field)
|
||||
{
|
||||
return InternalGetCecilObject<FieldDefinition> (field);
|
||||
throw new NotImplementedException();
|
||||
//return InternalGetCecilObject<FieldDefinition> (field);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public EventDefinition GetCecilObject (IUnresolvedEvent evt)
|
||||
{
|
||||
return InternalGetCecilObject<EventDefinition> (evt);
|
||||
throw new NotImplementedException();
|
||||
//return InternalGetCecilObject<EventDefinition> (evt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public PropertyDefinition GetCecilObject (IUnresolvedProperty property)
|
||||
{
|
||||
return InternalGetCecilObject<PropertyDefinition> (property);
|
||||
throw new NotImplementedException();
|
||||
//return InternalGetCecilObject<PropertyDefinition> (property);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
if (moduleDefinition == null)
|
||||
throw new ArgumentNullException(nameof(moduleDefinition));
|
||||
this.moduleDefinition = moduleDefinition;
|
||||
MetadataLoader cecilLoader = new MetadataLoader { 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.
|
||||
@@ -69,7 +69,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
referencedAssemblies.Add(MinimalCorlib.Instance);
|
||||
compilation = new SimpleCompilation(mainAssembly, referencedAssemblies);
|
||||
}
|
||||
context = new SimpleTypeResolveContext(compilation.MainAssembly);
|
||||
context = new SimpleTypeResolveContext(compilation.MainAssembly);*/
|
||||
}
|
||||
|
||||
public ICompilation Compilation {
|
||||
@@ -130,6 +130,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
#region Resolve Type
|
||||
public IType Resolve(TypeReference typeReference)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
#if false
|
||||
if (typeReference == null)
|
||||
return SpecialType.UnknownType;
|
||||
// We need to skip SentinelType and PinnedType.
|
||||
@@ -137,15 +139,16 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
while (typeReference is OptionalModifierType || typeReference is RequiredModifierType) {
|
||||
typeReference = ((TypeSpecification)typeReference).ElementType;
|
||||
}
|
||||
if (typeReference is SentinelType || typeReference is PinnedType) {
|
||||
if (typeReference is SentinelType || typeReference is Mono.Cecil.PinnedType) {
|
||||
typeReference = ((TypeSpecification)typeReference).ElementType;
|
||||
}
|
||||
ITypeReference typeRef;
|
||||
lock (typeReferenceCecilLoader)
|
||||
typeRef = typeReferenceCecilLoader.ReadTypeReference(typeReference);
|
||||
return typeRef.Resolve(context);
|
||||
#endif
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Resolve Field
|
||||
public IField Resolve(FieldReference fieldReference)
|
||||
@@ -180,6 +183,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
|
||||
IField CreateFakeField(FieldReference fieldReference)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
#if false
|
||||
var declaringType = Resolve(fieldReference.DeclaringType);
|
||||
var f = new DefaultUnresolvedField();
|
||||
f.Name = fieldReference.Name;
|
||||
@@ -187,6 +192,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
f.ReturnType = typeReferenceCecilLoader.ReadTypeReference(fieldReference.FieldType);
|
||||
}
|
||||
return new ResolvedFakeField(f, context.WithCurrentTypeDefinition(declaringType.GetDefinition()), declaringType);
|
||||
#endif
|
||||
}
|
||||
|
||||
class ResolvedFakeField : DefaultResolvedField
|
||||
@@ -204,7 +210,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
get { return declaringType; }
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Resolve Method
|
||||
public IMethod Resolve(MethodReference methodReference)
|
||||
@@ -306,6 +312,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
/// </summary>
|
||||
IMethod CreateFakeMethod(MethodReference methodReference)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
#if false
|
||||
var m = new DefaultUnresolvedMethod();
|
||||
ITypeReference declaringTypeReference;
|
||||
lock (typeReferenceCecilLoader) {
|
||||
@@ -324,6 +332,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
}
|
||||
var type = declaringTypeReference.Resolve(context);
|
||||
return new ResolvedFakeMethod(m, context.WithCurrentTypeDefinition(type.GetDefinition()), type);
|
||||
#endif
|
||||
}
|
||||
|
||||
class ResolvedFakeMethod : DefaultResolvedMethod
|
||||
@@ -343,7 +352,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Resolve Property
|
||||
#region Resolve Property
|
||||
public IProperty Resolve(PropertyReference propertyReference)
|
||||
{
|
||||
if (propertyReference == null)
|
||||
@@ -378,9 +387,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
}
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Resolve Event
|
||||
#region Resolve Event
|
||||
public IEvent Resolve(EventReference eventReference)
|
||||
{
|
||||
if (eventReference == null)
|
||||
@@ -412,6 +421,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
|
||||
}
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,8 +105,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
|
||||
}
|
||||
}
|
||||
|
||||
public struct Unit { }
|
||||
|
||||
class TypeReferenceSignatureDecoder : ISignatureTypeProvider<ITypeReference, Unit>
|
||||
{
|
||||
public ITypeReference GetArrayType(ITypeReference elementType, ArrayShape shape)
|
||||
@@ -184,10 +182,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
|
||||
}
|
||||
}
|
||||
|
||||
class TypeSystemAttributeTypeProvider : ICustomAttributeTypeProvider<IType>
|
||||
public class TypeSystemAttributeTypeProvider : ICustomAttributeTypeProvider<IType>
|
||||
{
|
||||
readonly ITypeResolveContext context;
|
||||
|
||||
public static TypeSystemAttributeTypeProvider CreateDefault() => new TypeSystemAttributeTypeProvider(new SimpleTypeResolveContext(MinimalCorlib.Instance.CreateCompilation()));
|
||||
|
||||
public TypeSystemAttributeTypeProvider(ITypeResolveContext context)
|
||||
{
|
||||
this.context = context;
|
||||
|
||||
@@ -116,4 +116,6 @@ namespace ICSharpCode.Decompiler.Util
|
||||
{
|
||||
public static readonly T[] Array = new T[0];
|
||||
}
|
||||
|
||||
public struct Unit { }
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj" />
|
||||
<ProjectReference Include="..\ILSpy.BamlDecompiler\ILSpy.BamlDecompiler.csproj" />
|
||||
<ProjectReference Include="..\ILSpy\ILSpy.csproj" />
|
||||
<ProjectReference Include="..\SharpTreeView\ICSharpCode.TreeView.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
<ProjectReference Include="..\ICSharpCode.Decompiler.Tests\ICSharpCode.Decompiler.Tests.csproj" />
|
||||
<ProjectReference Include="..\ILSpy\ILSpy.csproj" />
|
||||
<ProjectReference Include="..\SharpTreeView\ICSharpCode.TreeView.csproj" />
|
||||
<ProjectReference Include="..\ILSpy.BamlDecompiler\ILSpy.BamlDecompiler.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -10,11 +10,11 @@ using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
|
||||
using ICSharpCode.AvalonEdit.Highlighting;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
using ICSharpCode.ILSpy;
|
||||
using ICSharpCode.ILSpy.TextView;
|
||||
using ICSharpCode.ILSpy.TreeNodes;
|
||||
using Mono.Cecil;
|
||||
using Ricciolo.StylesExplorer.MarkupReflection;
|
||||
|
||||
namespace ILSpy.BamlDecompiler
|
||||
@@ -50,16 +50,16 @@ namespace ILSpy.BamlDecompiler
|
||||
{
|
||||
var asm = this.Ancestors().OfType<AssemblyTreeNode>().FirstOrDefault().LoadedAssembly;
|
||||
Data.Position = 0;
|
||||
XDocument xamlDocument = LoadIntoDocument(asm.GetAssemblyResolver(), asm.GetAssemblyDefinitionAsync().Result, Data, cancellationToken);
|
||||
XDocument xamlDocument = LoadIntoDocument(asm.GetAssemblyResolver(), asm.GetPEFileOrNull(), Data, cancellationToken);
|
||||
output.Write(xamlDocument.ToString());
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static XDocument LoadIntoDocument(IAssemblyResolver resolver, AssemblyDefinition asm, Stream stream, CancellationToken cancellationToken)
|
||||
internal static XDocument LoadIntoDocument(PEFile module, Stream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
XDocument xamlDocument;
|
||||
using (XmlBamlReader reader = new XmlBamlReader(stream, new CecilTypeResolver(resolver, asm))) {
|
||||
using (XmlBamlReader reader = new XmlBamlReader(stream, new NRTypeResolver(resolver, asm))) {
|
||||
xamlDocument = XDocument.Load(reader);
|
||||
ConvertConnectionIds(xamlDocument, asm, cancellationToken);
|
||||
ConvertToEmptyElements(xamlDocument.Root);
|
||||
|
||||
@@ -7,13 +7,14 @@ using System.IO;
|
||||
|
||||
using ICSharpCode.ILSpy.TreeNodes;
|
||||
using ICSharpCode.ILSpy;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ILSpy.BamlDecompiler
|
||||
{
|
||||
[Export(typeof(IResourceNodeFactory))]
|
||||
public sealed class BamlResourceNodeFactory : IResourceNodeFactory
|
||||
{
|
||||
public ILSpyTreeNode CreateNode(Mono.Cecil.Resource resource)
|
||||
public ILSpyTreeNode CreateNode(Resource resource)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -35,7 +36,7 @@ namespace ILSpy.BamlDecompiler
|
||||
|
||||
public string WriteResourceToFile(LoadedAssembly assembly, string fileName, Stream stream, DecompilationOptions options)
|
||||
{
|
||||
var document = BamlResourceEntryNode.LoadIntoDocument(assembly.GetAssemblyResolver(), assembly.GetAssemblyDefinitionAsync().Result, stream, options.CancellationToken);
|
||||
var document = BamlResourceEntryNode.LoadIntoDocument(assembly.GetAssemblyResolver(), assembly.GetPEFileOrNull(), stream, options.CancellationToken);
|
||||
fileName = Path.ChangeExtension(fileName, ".xaml");
|
||||
document.Save(Path.Combine(options.SaveAsProjectDirectory, fileName));
|
||||
return fileName;
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
|
||||
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Mono.Cecil;
|
||||
using Ricciolo.StylesExplorer.MarkupReflection;
|
||||
|
||||
namespace ILSpy.BamlDecompiler
|
||||
{
|
||||
public class CecilDependencyPropertyDescriptor : IDependencyPropertyDescriptor
|
||||
{
|
||||
string member;
|
||||
TypeDefinition type;
|
||||
|
||||
public CecilDependencyPropertyDescriptor(string member, TypeDefinition type)
|
||||
{
|
||||
if (type == null)
|
||||
throw new ArgumentNullException("type");
|
||||
this.member = member;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public bool IsAttached {
|
||||
get {
|
||||
return type.Methods.Any(m => m.Name == "Get" + member);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("[CecilDependencyPropertyDescriptor Member={0}, Type={1}]", member, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,68 +2,49 @@
|
||||
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using Mono.Cecil;
|
||||
using Ricciolo.StylesExplorer.MarkupReflection;
|
||||
|
||||
namespace ILSpy.BamlDecompiler
|
||||
{
|
||||
public class CecilType : IType
|
||||
public class NRType : IDotNetType
|
||||
{
|
||||
internal readonly TypeDefinition type;
|
||||
readonly ITypeDefinition type;
|
||||
|
||||
public ITypeDefinition Type => type;
|
||||
|
||||
public CecilType(TypeDefinition type)
|
||||
public NRType(ITypeDefinition type)
|
||||
{
|
||||
if (type == null)
|
||||
throw new ArgumentNullException("type");
|
||||
this.type = type;
|
||||
this.type = type ?? throw new ArgumentNullException(nameof(type));
|
||||
}
|
||||
|
||||
public string AssemblyQualifiedName {
|
||||
get {
|
||||
return type.FullName +
|
||||
", " + type.Module.Assembly.FullName;
|
||||
", " + type.ParentAssembly.FullAssemblyName;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSubclassOf(IType type)
|
||||
public bool IsSubclassOf(IDotNetType type)
|
||||
{
|
||||
if (type == null)
|
||||
throw new ArgumentNullException("type");
|
||||
if (!(type is CecilType))
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
if (!(type is NRType baseType))
|
||||
return false;
|
||||
|
||||
CecilType ct = (CecilType)type;
|
||||
|
||||
var t = this.type;
|
||||
|
||||
if (t == ct.type)
|
||||
return false;
|
||||
|
||||
while (t != null) {
|
||||
if (t == ct.type)
|
||||
return true;
|
||||
foreach (var @interface in t.Interfaces) {
|
||||
var resolved = @interface.InterfaceType.Resolve();
|
||||
if (resolved == ct.type)
|
||||
return true;
|
||||
}
|
||||
if (t.BaseType == null)
|
||||
break;
|
||||
|
||||
t = t.BaseType.Resolve();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
return this.type.GetAllBaseTypeDefinitions().Any(t => t.Equals(baseType.type));
|
||||
}
|
||||
|
||||
public bool Equals(IType type)
|
||||
public bool Equals(IDotNetType type)
|
||||
{
|
||||
if (type == null)
|
||||
throw new ArgumentNullException("type");
|
||||
if (!(type is CecilType))
|
||||
if (!(type is NRType))
|
||||
return false;
|
||||
|
||||
return this.type == ((CecilType)type).type;
|
||||
return this.type.Equals(((NRType)type).type);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@@ -71,13 +52,14 @@ namespace ILSpy.BamlDecompiler
|
||||
return string.Format("[CecilType Type={0}]", type);
|
||||
}
|
||||
|
||||
public IType BaseType {
|
||||
public IDotNetType BaseType {
|
||||
get {
|
||||
TypeDefinition td = type.BaseType.Resolve();
|
||||
var t = type.DirectBaseTypes.First();
|
||||
var td = t.GetDefinition();
|
||||
if (td == null)
|
||||
throw new Exception("could not resolve '" + type.BaseType.FullName + "'!");
|
||||
throw new Exception($"Could not resolve '{t.FullName}'!");
|
||||
|
||||
return new CecilType(td);
|
||||
return new NRType(td);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
|
||||
|
||||
using System;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using Mono.Cecil;
|
||||
using Ricciolo.StylesExplorer.MarkupReflection;
|
||||
|
||||
@@ -10,20 +11,18 @@ namespace ILSpy.BamlDecompiler
|
||||
/// <summary>
|
||||
/// Description of CecilTypeResolver.
|
||||
/// </summary>
|
||||
public class CecilTypeResolver : ITypeResolver
|
||||
public class NRTypeResolver : IDotNetTypeResolver
|
||||
{
|
||||
IAssemblyResolver resolver;
|
||||
AssemblyDefinition thisAssembly;
|
||||
|
||||
public CecilTypeResolver(IAssemblyResolver resolver, AssemblyDefinition asm)
|
||||
readonly ICompilation compilation;
|
||||
|
||||
public NRTypeResolver(ICompilation compilation)
|
||||
{
|
||||
this.resolver = resolver;
|
||||
this.thisAssembly = asm;
|
||||
this.compilation = compilation;
|
||||
}
|
||||
|
||||
public bool IsLocalAssembly(string name)
|
||||
{
|
||||
return MakeShort(name) == this.thisAssembly.Name.Name;
|
||||
return MakeShort(name) == compilation.MainAssembly.AssemblyName;
|
||||
}
|
||||
|
||||
string MakeShort(string name)
|
||||
@@ -35,7 +34,7 @@ namespace ILSpy.BamlDecompiler
|
||||
return name.Substring(0, endOffset);
|
||||
}
|
||||
|
||||
public IType GetTypeByAssemblyQualifiedName(string name)
|
||||
public IDotNetType GetTypeByAssemblyQualifiedName(string name)
|
||||
{
|
||||
int bracket = name.LastIndexOf(']');
|
||||
int comma = bracket > -1 ? name.IndexOf(',', bracket) : name.IndexOf(',');
|
||||
@@ -45,48 +44,22 @@ namespace ILSpy.BamlDecompiler
|
||||
|
||||
string fullName = bracket > -1 ? name.Substring(0, name.IndexOf('[')) : name.Substring(0, comma);
|
||||
string assemblyName = name.Substring(comma + 1).Trim();
|
||||
|
||||
var type = thisAssembly.MainModule.GetType(fullName);
|
||||
|
||||
if (type == null) {
|
||||
type = TryFindInExportedTypes(fullName, thisAssembly);
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
var otherAssembly = resolver.Resolve(AssemblyNameReference.Parse(assemblyName));
|
||||
if (otherAssembly == null)
|
||||
return new UnresolvableType(name);
|
||||
type = otherAssembly.MainModule.GetType(fullName.Replace('+', '/'));
|
||||
|
||||
if (type == null) {
|
||||
type = TryFindInExportedTypes(fullName, otherAssembly);
|
||||
}
|
||||
}
|
||||
|
||||
var type = compilation.FindType(new FullTypeName(fullName)).GetDefinition();
|
||||
|
||||
if (type == null)
|
||||
return new UnresolvableType(name);
|
||||
|
||||
return new CecilType(type);
|
||||
}
|
||||
|
||||
TypeDefinition TryFindInExportedTypes(string fullName, AssemblyDefinition asm)
|
||||
{
|
||||
foreach (var exportedType in asm.MainModule.ExportedTypes) {
|
||||
if (exportedType.IsForwarder && exportedType.FullName == fullName) {
|
||||
return exportedType.Resolve();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return new NRType(type);
|
||||
}
|
||||
|
||||
public IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType)
|
||||
public IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IDotNetType ownerType, IDotNetType targetType)
|
||||
{
|
||||
if (ownerType == null)
|
||||
throw new ArgumentNullException("ownerType");
|
||||
|
||||
if (ownerType is CecilType)
|
||||
return new CecilDependencyPropertyDescriptor(name, ((CecilType)ownerType).type);
|
||||
if (ownerType is NRType)
|
||||
return new NRTypeDependencyPropertyDescriptor(((NRType)ownerType).Type, name);
|
||||
if (ownerType is UnresolvableType)
|
||||
return new UnresolvableDependencyPropertyDescriptor();
|
||||
|
||||
@@ -95,7 +68,8 @@ namespace ILSpy.BamlDecompiler
|
||||
|
||||
public string RuntimeVersion {
|
||||
get {
|
||||
return thisAssembly.MainModule.Runtime.ToString();
|
||||
throw new NotImplementedException();
|
||||
//return thisAssembly.MainModule.Runtime.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="BamlResourceNodeFactory.cs" />
|
||||
<Compile Include="BamlResourceEntryNode.cs" />
|
||||
<Compile Include="CecilDependencyPropertyDescriptor.cs" />
|
||||
<Compile Include="SRMDependencyPropertyDescriptor.cs" />
|
||||
<Compile Include="CecilType.cs" />
|
||||
<Compile Include="CecilTypeResolver.cs" />
|
||||
<Compile Include="ConnectMethodDecompiler.cs" />
|
||||
|
||||
@@ -7,41 +7,31 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
|
||||
/// <summary>
|
||||
/// Interface representing a DotNet type
|
||||
/// </summary>
|
||||
public interface IType
|
||||
public interface IDotNetType
|
||||
{
|
||||
IType BaseType { get; }
|
||||
IDotNetType BaseType { get; }
|
||||
string AssemblyQualifiedName { get; }
|
||||
bool IsSubclassOf(IType type);
|
||||
bool Equals(IType type);
|
||||
bool IsSubclassOf(IDotNetType type);
|
||||
bool Equals(IDotNetType type);
|
||||
}
|
||||
|
||||
public class UnresolvableType : IType
|
||||
|
||||
public class UnresolvableType : IDotNetType
|
||||
{
|
||||
string assemblyQualifiedName;
|
||||
|
||||
public UnresolvableType(string assemblyQualifiedName)
|
||||
{
|
||||
this.assemblyQualifiedName = assemblyQualifiedName;
|
||||
this.AssemblyQualifiedName = assemblyQualifiedName;
|
||||
}
|
||||
|
||||
public IType BaseType {
|
||||
get {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string AssemblyQualifiedName {
|
||||
get {
|
||||
return assemblyQualifiedName;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSubclassOf(IType type)
|
||||
|
||||
public IDotNetType BaseType => null;
|
||||
|
||||
public string AssemblyQualifiedName { get; }
|
||||
|
||||
public bool IsSubclassOf(IDotNetType type)
|
||||
{
|
||||
return Equals(type);
|
||||
}
|
||||
|
||||
public bool Equals(IType type)
|
||||
|
||||
public bool Equals(IDotNetType type)
|
||||
{
|
||||
return type is UnresolvableType && type.AssemblyQualifiedName == AssemblyQualifiedName;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
namespace Ricciolo.StylesExplorer.MarkupReflection
|
||||
{
|
||||
public interface ITypeResolver
|
||||
public interface IDotNetTypeResolver
|
||||
{
|
||||
string RuntimeVersion { get; }
|
||||
bool IsLocalAssembly(string name);
|
||||
IType GetTypeByAssemblyQualifiedName(string name);
|
||||
IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType);
|
||||
IDotNetType GetTypeByAssemblyQualifiedName(string name);
|
||||
IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IDotNetType ownerType, IDotNetType targetType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
|
||||
{
|
||||
}
|
||||
|
||||
public KnownInfo(ITypeResolver resolver)
|
||||
public KnownInfo(IDotNetTypeResolver resolver)
|
||||
{
|
||||
switch (resolver.RuntimeVersion) {
|
||||
case "Net_2_0":
|
||||
|
||||
@@ -9,33 +9,33 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
|
||||
{
|
||||
readonly XmlBamlReader reader;
|
||||
readonly bool _isExtension;
|
||||
IType _type;
|
||||
IDotNetType _type;
|
||||
bool _typeLoaded;
|
||||
readonly ITypeResolver resolver;
|
||||
readonly IDotNetTypeResolver resolver;
|
||||
|
||||
protected TypeDeclaration(ITypeResolver resolver)
|
||||
protected TypeDeclaration(IDotNetTypeResolver resolver)
|
||||
{
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public TypeDeclaration(ITypeResolver resolver, string name, string namespaceName, short assemblyId)
|
||||
public TypeDeclaration(IDotNetTypeResolver resolver, string name, string namespaceName, short assemblyId)
|
||||
: this(null, resolver, name, namespaceName, assemblyId)
|
||||
{
|
||||
}
|
||||
|
||||
public TypeDeclaration(ITypeResolver resolver, string name, string enclosingTypeName, string namespaceName, short assemblyId)
|
||||
public TypeDeclaration(IDotNetTypeResolver resolver, string name, string enclosingTypeName, string namespaceName, short assemblyId)
|
||||
: this(null, resolver, name, namespaceName, assemblyId)
|
||||
{
|
||||
this.EnclosingTypeName = enclosingTypeName;
|
||||
}
|
||||
|
||||
public TypeDeclaration(ITypeResolver resolver, string name, string namespaceName, short assemblyId, bool isExtension)
|
||||
public TypeDeclaration(IDotNetTypeResolver resolver, string name, string namespaceName, short assemblyId, bool isExtension)
|
||||
: this(null, resolver, name, namespaceName, assemblyId)
|
||||
{
|
||||
_isExtension = isExtension;
|
||||
}
|
||||
|
||||
public TypeDeclaration(XmlBamlReader reader, ITypeResolver resolver, string name, string namespaceName, short assemblyId)
|
||||
public TypeDeclaration(XmlBamlReader reader, IDotNetTypeResolver resolver, string name, string namespaceName, short assemblyId)
|
||||
{
|
||||
this.reader = reader;
|
||||
this.resolver = resolver;
|
||||
@@ -73,7 +73,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
|
||||
|
||||
public virtual string Name { get; protected set; }
|
||||
|
||||
public IType Type {
|
||||
public IDotNetType Type {
|
||||
get {
|
||||
if (!_typeLoaded) {
|
||||
if (this.Name.Length > 0)
|
||||
@@ -119,7 +119,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
|
||||
protected set { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
public ResolverTypeDeclaration(ITypeResolver resolver, string assemblyQualifiedName)
|
||||
public ResolverTypeDeclaration(IDotNetTypeResolver resolver, string assemblyQualifiedName)
|
||||
: base(resolver)
|
||||
{
|
||||
string name, @namespace, assembly;
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
|
||||
Dictionary<short, TypeDeclaration> typeTable = new Dictionary<short, TypeDeclaration>();
|
||||
Dictionary<short, PropertyDeclaration> propertyTable = new Dictionary<short, PropertyDeclaration>();
|
||||
|
||||
readonly ITypeResolver _resolver;
|
||||
readonly IDotNetTypeResolver _resolver;
|
||||
|
||||
BamlRecordType currentType;
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
|
||||
|
||||
public ISet<XmlNamespace> XmlnsDefinitions { get; } = new HashSet<XmlNamespace>();
|
||||
|
||||
public XmlBamlReader(Stream stream, ITypeResolver resolver)
|
||||
public XmlBamlReader(Stream stream, IDotNetTypeResolver resolver)
|
||||
{
|
||||
if (stream == null)
|
||||
throw new ArgumentNullException(nameof(stream));
|
||||
@@ -1626,7 +1626,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
|
||||
/// <summary>
|
||||
/// Returns object used to resolve types
|
||||
/// </summary>
|
||||
public ITypeResolver Resolver
|
||||
public IDotNetTypeResolver Resolver
|
||||
{
|
||||
get { return _resolver; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
|
||||
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using Ricciolo.StylesExplorer.MarkupReflection;
|
||||
|
||||
namespace ILSpy.BamlDecompiler
|
||||
{
|
||||
public class NRTypeDependencyPropertyDescriptor : IDependencyPropertyDescriptor
|
||||
{
|
||||
readonly ITypeDefinition typeDefinition;
|
||||
readonly string member;
|
||||
|
||||
public NRTypeDependencyPropertyDescriptor(ITypeDefinition type, string name)
|
||||
{
|
||||
this.typeDefinition = type;
|
||||
this.member = name;
|
||||
}
|
||||
|
||||
public bool IsAttached {
|
||||
get {
|
||||
return typeDefinition.GetMethods(m => m.Name == "Get" + member, GetMemberOptions.IgnoreInheritedMembers).Any();
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("[CecilDependencyPropertyDescriptor Member={0}, Type={1}]", member, typeDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.12
|
||||
VisualStudioVersion = 15.0.27130.2026
|
||||
MinimumVisualStudioVersion = 15.0
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{F45DB999-7E72-4000-B5AD-3A7B485A0896}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
@@ -24,10 +24,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestPlugin", "TestPlugin\Te
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Pdb", "cecil\symbols\pdb\Mono.Cecil.Pdb.csproj", "{63E6915C-7EA4-4D76-AB28-0D7191EEA626}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.BamlDecompiler", "ILSpy.BamlDecompiler\ILSpy.BamlDecompiler.csproj", "{A6BAD2BA-76BA-461C-8B6D-418607591247}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.BamlDecompiler.Tests", "ILSpy.BamlDecompiler.Tests\ILSpy.BamlDecompiler.Tests.csproj", "{1169E6D1-1899-43D4-A500-07CE4235B388}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.AddIn", "ILSpy.AddIn\ILSpy.AddIn.csproj", "{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0A344E19-D1FC-4F4C-8883-0844AC669113}"
|
||||
@@ -69,14 +65,6 @@ Global
|
||||
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|Any CPU.Build.0 = net_4_0_Debug|Any CPU
|
||||
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
|
||||
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|Any CPU.Build.0 = net_4_0_Release|Any CPU
|
||||
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
||||
@@ -119,4 +119,4 @@ namespace ICSharpCode.ILSpy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#if DEBUG
|
||||
#if false && DEBUG
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace ICSharpCode.ILSpy
|
||||
|
||||
public static ILAstWritingOptions Options => writingOptions;
|
||||
|
||||
#if DEBUG
|
||||
#if false && DEBUG
|
||||
ILAstLanguage language;
|
||||
#endif
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace ICSharpCode.ILSpy
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
#if DEBUG
|
||||
#if false && DEBUG
|
||||
MainWindow.Instance.SessionSettings.FilterSettings.PropertyChanged += FilterSettings_PropertyChanged;
|
||||
MainWindow.Instance.SelectionChanged += SelectionChanged;
|
||||
writingOptions.PropertyChanged += WritingOptions_PropertyChanged;
|
||||
@@ -56,7 +56,7 @@ namespace ICSharpCode.ILSpy
|
||||
|
||||
private void FilterSettings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
#if DEBUG
|
||||
#if false && DEBUG
|
||||
if (e.PropertyName == "Language") {
|
||||
if (language != null) {
|
||||
language.StepperUpdated -= ILAstStepperUpdated;
|
||||
@@ -72,7 +72,7 @@ namespace ICSharpCode.ILSpy
|
||||
|
||||
private void ILAstStepperUpdated(object sender, EventArgs e)
|
||||
{
|
||||
#if DEBUG
|
||||
#if false && DEBUG
|
||||
if (language == null) return;
|
||||
Dispatcher.Invoke(() => {
|
||||
tree.ItemsSource = language.Stepper.Steps;
|
||||
@@ -88,7 +88,7 @@ namespace ICSharpCode.ILSpy
|
||||
|
||||
void IPane.Closed()
|
||||
{
|
||||
#if DEBUG
|
||||
#if false && DEBUG
|
||||
MainWindow.Instance.SessionSettings.FilterSettings.PropertyChanged -= FilterSettings_PropertyChanged;
|
||||
MainWindow.Instance.SelectionChanged -= SelectionChanged;
|
||||
writingOptions.PropertyChanged -= WritingOptions_PropertyChanged;
|
||||
|
||||
@@ -101,13 +101,45 @@ namespace ICSharpCode.ILSpy
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string ToSuffixString(this MetadataToken token)
|
||||
|
||||
public static string ToSuffixString(this System.Reflection.Metadata.MethodDefinitionHandle token)
|
||||
{
|
||||
if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)
|
||||
return string.Empty;
|
||||
|
||||
return " @" + token.ToInt32().ToString("x8");
|
||||
|
||||
return " @" + System.Reflection.Metadata.Ecma335.MetadataTokens.GetToken(token).ToString("x8");
|
||||
}
|
||||
|
||||
public static string ToSuffixString(this System.Reflection.Metadata.PropertyDefinitionHandle token)
|
||||
{
|
||||
if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)
|
||||
return string.Empty;
|
||||
|
||||
return " @" + System.Reflection.Metadata.Ecma335.MetadataTokens.GetToken(token).ToString("x8");
|
||||
}
|
||||
|
||||
public static string ToSuffixString(this System.Reflection.Metadata.EventDefinitionHandle token)
|
||||
{
|
||||
if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)
|
||||
return string.Empty;
|
||||
|
||||
return " @" + System.Reflection.Metadata.Ecma335.MetadataTokens.GetToken(token).ToString("x8");
|
||||
}
|
||||
|
||||
public static string ToSuffixString(this System.Reflection.Metadata.FieldDefinitionHandle token)
|
||||
{
|
||||
if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)
|
||||
return string.Empty;
|
||||
|
||||
return " @" + System.Reflection.Metadata.Ecma335.MetadataTokens.GetToken(token).ToString("x8");
|
||||
}
|
||||
|
||||
public static string ToSuffixString(this System.Reflection.Metadata.TypeDefinitionHandle token)
|
||||
{
|
||||
if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)
|
||||
return string.Empty;
|
||||
|
||||
return " @" + System.Reflection.Metadata.Ecma335.MetadataTokens.GetToken(token).ToString("x8");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
+5
-34
@@ -76,7 +76,6 @@
|
||||
<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" />
|
||||
@@ -127,6 +126,7 @@
|
||||
<Compile Include="Images\Images.cs" />
|
||||
<Compile Include="Languages\ILLanguage.cs" />
|
||||
<Compile Include="Languages\IResourceFileHandler.cs" />
|
||||
<Compile Include="Languages\ITypeProvider.cs" />
|
||||
<Compile Include="Languages\Language.cs" />
|
||||
<Compile Include="Languages\Languages.cs" />
|
||||
<Compile Include="LoadedAssembly.cs" />
|
||||
@@ -181,28 +181,8 @@
|
||||
<Compile Include="TextView\EditorCommands.cs" />
|
||||
<Compile Include="TextView\FoldingCommands.cs" />
|
||||
<Compile Include="TextView\XmlDocRenderer.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzeContextMenuEntry.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedAssemblyTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedAttributeAppliedToTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedEventOverridesTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedEventTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedInterfacePropertyImplementedByTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedInterfaceMethodImplementedByTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedInterfaceEventImplementedByTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedEventFiredByTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedPropertyAccessorTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeExposedByTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeExtensionMethodsTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeInstantiationsTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedEventAccessorTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeUsedByTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedVirtualMethodUsedByTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzerEntityTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzerSearchTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\RemoveAnalyzeContextMenuEntry.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\Helpers.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\ScopedWhereUsedAnalyzer.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzerTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\BaseTypesEntryNode.cs" />
|
||||
<Compile Include="TreeNodes\CopyFullyQualifiedNameContextMenuEntry.cs" />
|
||||
<Compile Include="TreeNodes\DerivedTypesEntryNode.cs" />
|
||||
@@ -213,12 +193,12 @@
|
||||
<Compile Include="TreeNodes\ResourceNodes\IconResourceEntryNode.cs" />
|
||||
<Compile Include="TreeNodes\ResourceNodes\ImageListResourceEntryNode.cs" />
|
||||
<Compile Include="TreeNodes\ResourceNodes\ImageResourceEntryNode.cs" />
|
||||
<Compile Include="TreeNodes\ResourceNodes\XmlResourceNode.cs" />
|
||||
<Compile Include="TreeNodes\ResourceNodes\IResourceNodeFactory.cs" />
|
||||
<Compile Include="TreeNodes\ResourceNodes\ResourceEntryNode.cs" />
|
||||
<Compile Include="TreeNodes\ResourceNodes\ResourcesFileTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\ResourceNodes\ResourceTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\ResourceNodes\XamlResourceNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedPropertyOverridesTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedPropertyTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\ResourceNodes\XmlResourceNode.cs" />
|
||||
<Compile Include="TreeNodes\SearchMsdnContextMenuEntry.cs" />
|
||||
<EmbeddedResource Include="..\doc\LGPL.txt">
|
||||
<Link>LGPL.txt</Link>
|
||||
@@ -264,13 +244,6 @@
|
||||
<Compile Include="TextView\ReferenceElementGenerator.cs" />
|
||||
<Compile Include="TextView\AvalonEditTextOutput.cs" />
|
||||
<Compile Include="TextView\UIElementGenerator.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedFieldAccessTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedFieldTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodUsedByTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodUsesTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzerTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodOverridesTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\AssemblyListTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\AssemblyReferenceTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\AssemblyTreeNode.cs" />
|
||||
@@ -284,9 +257,7 @@
|
||||
<Compile Include="TreeNodes\NamespaceTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\PropertyTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\ReferenceFolderTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\ResourceNodes\ResourceEntryNode.cs" />
|
||||
<Compile Include="TreeNodes\ResourceListTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\ResourceNodes\ResourceTreeNode.cs" />
|
||||
<Compile Include="TreeNodes\ThreadingSupport.cs" />
|
||||
<Compile Include="TreeNodes\TypeTreeNode.cs" />
|
||||
<EmbeddedResource Include="README.txt" />
|
||||
|
||||
@@ -23,23 +23,21 @@ using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Resources;
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using ICSharpCode.Decompiler;
|
||||
using ICSharpCode.ILSpy.Options;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.CSharp;
|
||||
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
|
||||
using ICSharpCode.Decompiler.CSharp.Syntax;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using ICSharpCode.ILSpy.TreeNodes;
|
||||
using ICSharpCode.Decompiler.CSharp.Transforms;
|
||||
using ICSharpCode.AvalonEdit.Highlighting;
|
||||
using System.Windows.Media;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using ICSharpCode.ILSpy.Options;
|
||||
using ICSharpCode.ILSpy.TreeNodes;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.ILSpy
|
||||
{
|
||||
#if false
|
||||
/// <summary>
|
||||
/// C# decompiler integration into ILSpy.
|
||||
/// Note: if you're interested in using the decompiler without the ILSpy UI,
|
||||
@@ -252,40 +250,6 @@ namespace ICSharpCode.ILSpy
|
||||
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(type), decompiler.TypeSystem);
|
||||
}
|
||||
|
||||
public static string GetPlatformDisplayName(ModuleDefinition module)
|
||||
{
|
||||
switch (module.Architecture) {
|
||||
case TargetArchitecture.I386:
|
||||
if ((module.Attributes & ModuleAttributes.Preferred32Bit) == ModuleAttributes.Preferred32Bit)
|
||||
return "AnyCPU (32-bit preferred)";
|
||||
else if ((module.Attributes & ModuleAttributes.Required32Bit) == ModuleAttributes.Required32Bit)
|
||||
return "x86";
|
||||
else
|
||||
return "AnyCPU (64-bit preferred)";
|
||||
case TargetArchitecture.AMD64:
|
||||
return "x64";
|
||||
case TargetArchitecture.IA64:
|
||||
return "Itanium";
|
||||
default:
|
||||
return module.Architecture.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetRuntimeDisplayName(ModuleDefinition module)
|
||||
{
|
||||
switch (module.Runtime) {
|
||||
case TargetRuntime.Net_1_0:
|
||||
return ".NET 1.0";
|
||||
case TargetRuntime.Net_1_1:
|
||||
return ".NET 1.1";
|
||||
case TargetRuntime.Net_2_0:
|
||||
return ".NET 2.0";
|
||||
case TargetRuntime.Net_4_0:
|
||||
return ".NET 4.0";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void AddReferenceWarningMessage(AssemblyDefinition assembly, ITextOutput output)
|
||||
{
|
||||
var loadedAssembly = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().FirstOrDefault(la => la.GetAssemblyDefinitionOrNull() == assembly);
|
||||
@@ -519,4 +483,5 @@ namespace ICSharpCode.ILSpy
|
||||
return new CSharpAmbience() { ConversionFlags = flags }.ConvertSymbol(symbol);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@ using System.Linq;
|
||||
using ICSharpCode.Decompiler;
|
||||
using ICSharpCode.Decompiler.CSharp;
|
||||
using ICSharpCode.Decompiler.Disassembler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.Decompiler.IL;
|
||||
using ICSharpCode.Decompiler.IL.Transforms;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.ILSpy
|
||||
{
|
||||
#if DEBUG
|
||||
#if false && DEBUG
|
||||
/// <summary>
|
||||
/// Represents the ILAst "language" used for debugging purposes.
|
||||
/// </summary>
|
||||
|
||||
@@ -25,6 +25,7 @@ using System.Reflection.Metadata;
|
||||
using System.IO;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Linq;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy
|
||||
{
|
||||
@@ -48,114 +49,99 @@ namespace ICSharpCode.ILSpy
|
||||
get { return ".il"; }
|
||||
}
|
||||
|
||||
protected virtual ReflectionDisassembler CreateDisassembler(ITextOutput output, PEReader reader, DecompilationOptions options)
|
||||
protected virtual ReflectionDisassembler CreateDisassembler(ITextOutput output, DecompilationOptions options)
|
||||
{
|
||||
return new ReflectionDisassembler(output, reader, options.CancellationToken) {
|
||||
return new ReflectionDisassembler(output, options.CancellationToken) {
|
||||
DetectControlStructure = detectControlStructure,
|
||||
ShowSequencePoints = options.DecompilerSettings.ShowDebugInfo
|
||||
};
|
||||
}
|
||||
|
||||
public override void DecompileMethod(Mono.Cecil.MethodDefinition method, ITextOutput output, DecompilationOptions options)
|
||||
public override void DecompileMethod(Decompiler.Dom.MethodDefinition method, ITextOutput output, DecompilationOptions options)
|
||||
{
|
||||
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()));
|
||||
}
|
||||
var dis = CreateDisassembler(output, options);
|
||||
dis.DisassembleMethod(method);
|
||||
}
|
||||
|
||||
public override void DecompileField(Mono.Cecil.FieldDefinition field, ITextOutput output, DecompilationOptions options)
|
||||
public override void DecompileField(Decompiler.Dom.FieldDefinition field, ITextOutput output, DecompilationOptions options)
|
||||
{
|
||||
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()));
|
||||
}
|
||||
var dis = CreateDisassembler(output, options);
|
||||
dis.DisassembleField(field);
|
||||
}
|
||||
|
||||
public override void DecompileProperty(Mono.Cecil.PropertyDefinition property, ITextOutput output, DecompilationOptions options)
|
||||
public override void DecompileProperty(Decompiler.Dom.PropertyDefinition property, ITextOutput output, DecompilationOptions options)
|
||||
{
|
||||
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()));
|
||||
var dis = CreateDisassembler(output, options);
|
||||
dis.DisassembleProperty(property);
|
||||
|
||||
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()));
|
||||
}
|
||||
if (!property.GetMethod.IsNil) {
|
||||
output.WriteLine();
|
||||
dis.DisassembleMethod(property.GetMethod);
|
||||
}
|
||||
if (!property.SetMethod.IsNil) {
|
||||
output.WriteLine();
|
||||
dis.DisassembleMethod(property.SetMethod);
|
||||
}
|
||||
foreach (var m in property.OtherMethods) {
|
||||
output.WriteLine();
|
||||
dis.DisassembleMethod(m);
|
||||
}
|
||||
}
|
||||
|
||||
public override void DecompileEvent(Mono.Cecil.EventDefinition ev, ITextOutput output, DecompilationOptions options)
|
||||
public override void DecompileEvent(Decompiler.Dom.EventDefinition ev, ITextOutput output, DecompilationOptions options)
|
||||
{
|
||||
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()));
|
||||
}
|
||||
var dis = CreateDisassembler(output, options);
|
||||
dis.DisassembleEvent(ev);
|
||||
if (!ev.AddMethod.IsNil) {
|
||||
output.WriteLine();
|
||||
dis.DisassembleMethod(ev.AddMethod);
|
||||
}
|
||||
if (!ev.RemoveMethod.IsNil) {
|
||||
output.WriteLine();
|
||||
dis.DisassembleMethod(ev.RemoveMethod);
|
||||
}
|
||||
foreach (var m in ev.OtherMethods) {
|
||||
output.WriteLine();
|
||||
dis.DisassembleMethod(m);
|
||||
}
|
||||
}
|
||||
|
||||
public override void DecompileType(Mono.Cecil.TypeDefinition type, ITextOutput output, DecompilationOptions options)
|
||||
public override void DecompileType(Decompiler.Dom.TypeDefinition type, ITextOutput output, DecompilationOptions options)
|
||||
{
|
||||
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()));
|
||||
}
|
||||
var dis = CreateDisassembler(output, options);
|
||||
dis.DisassembleType(type);
|
||||
}
|
||||
|
||||
public override void DecompileNamespace(string nameSpace, IEnumerable<Mono.Cecil.TypeDefinition> types, ITextOutput output, DecompilationOptions options)
|
||||
public override void DecompileNamespace(string nameSpace, IEnumerable<Decompiler.Dom.TypeDefinition> types, ITextOutput output, DecompilationOptions options)
|
||||
{
|
||||
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())));
|
||||
}
|
||||
var dis = CreateDisassembler(output, options);
|
||||
dis.DisassembleNamespace(nameSpace, types);
|
||||
}
|
||||
|
||||
public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
|
||||
{
|
||||
output.WriteLine("// " + assembly.FileName);
|
||||
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();
|
||||
var module = assembly.GetPEFileOrNull();
|
||||
var metadata = module.GetMetadataReader();
|
||||
var dis = CreateDisassembler(output, options);
|
||||
if (options.FullDecompilation)
|
||||
dis.WriteAssemblyReferences(module);
|
||||
if (metadata.IsAssembly)
|
||||
dis.WriteAssemblyHeader(module);
|
||||
output.WriteLine();
|
||||
dis.WriteModuleHeader(module);
|
||||
if (options.FullDecompilation) {
|
||||
output.WriteLine();
|
||||
dis.WriteModuleHeader();
|
||||
if (options.FullDecompilation) {
|
||||
output.WriteLine();
|
||||
output.WriteLine();
|
||||
dis.WriteModuleContents(reader.GetMetadataReader().GetModuleDefinition());
|
||||
}
|
||||
output.WriteLine();
|
||||
dis.WriteModuleContents(module);
|
||||
}
|
||||
}
|
||||
|
||||
public override string TypeToString(Mono.Cecil.TypeReference type, bool includeNamespace, Mono.Cecil.ICustomAttributeProvider typeAttributes = null)
|
||||
public override string TypeToString(Decompiler.Dom.ITypeReference type, bool includeNamespace, Decompiler.Dom.ICustomAttributeProvider typeAttributes = null)
|
||||
{
|
||||
PlainTextOutput output = new PlainTextOutput();
|
||||
type.WriteTo(output, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName);
|
||||
type.WriteTo(output, GenericContext.Empty, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName);
|
||||
return output.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy
|
||||
{
|
||||
|
||||
|
||||
public sealed class CSharpSignatureTypeProvider : ISignatureTypeProvider<string, GenericContext>
|
||||
{
|
||||
public string GetArrayType(string elementType, ArrayShape shape)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetByReferenceType(string elementType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetFunctionPointerType(MethodSignature<string> signature)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetGenericInstantiation(string genericType, ImmutableArray<string> typeArguments)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetGenericMethodParameter(GenericContext genericContext, int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetGenericTypeParameter(GenericContext genericContext, int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetModifiedType(string modifier, string unmodifiedType, bool isRequired)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetPinnedType(string elementType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetPointerType(string elementType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetPrimitiveType(PrimitiveTypeCode typeCode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetSZArrayType(string elementType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetTypeFromSpecification(MetadataReader reader, GenericContext genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
+221
-21
@@ -18,8 +18,13 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using ICSharpCode.Decompiler;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
using static System.Reflection.Metadata.PEReaderExtensions;
|
||||
using SRM = System.Reflection.Metadata;
|
||||
|
||||
namespace ICSharpCode.ILSpy
|
||||
{
|
||||
@@ -87,16 +92,18 @@ namespace ICSharpCode.ILSpy
|
||||
public virtual void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
|
||||
{
|
||||
WriteCommentLine(output, assembly.FileName);
|
||||
var asm = assembly.GetAssemblyDefinitionOrNull();
|
||||
if (asm != null) {
|
||||
var name = asm.Name;
|
||||
if (name.IsWindowsRuntime) {
|
||||
var asm = assembly.GetPEFileOrNull();
|
||||
if (asm == null) return;
|
||||
var reader = asm.GetMetadataReader();
|
||||
if (reader.IsAssembly) {
|
||||
var name = reader.GetAssemblyDefinition();
|
||||
if ((name.Flags & System.Reflection.AssemblyFlags.WindowsRuntime) != 0) {
|
||||
WriteCommentLine(output, name.Name + " [WinRT]");
|
||||
} else {
|
||||
WriteCommentLine(output, name.FullName);
|
||||
WriteCommentLine(output, reader.GetFullAssemblyName());
|
||||
}
|
||||
} else {
|
||||
WriteCommentLine(output, assembly.GetModuleDefinitionAsync().Result.Name);
|
||||
WriteCommentLine(output, reader.GetString(reader.GetModuleDefinition().Name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,57 +115,69 @@ namespace ICSharpCode.ILSpy
|
||||
/// <summary>
|
||||
/// Converts a type reference into a string. This method is used by the member tree node for parameter and return types.
|
||||
/// </summary>
|
||||
public virtual string TypeToString(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes = null)
|
||||
public virtual string TypeToString(ITypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes = null)
|
||||
{
|
||||
if (includeNamespace)
|
||||
return type.FullName;
|
||||
return type.FullName.ToString();
|
||||
else
|
||||
return type.Name;
|
||||
}
|
||||
|
||||
public virtual SRM.ISignatureTypeProvider<string, GenericContext> CreateSignatureTypeProvider(bool includeNamespace)
|
||||
{
|
||||
return new ILSignatureProvider(includeNamespace);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a member signature to a string.
|
||||
/// This is used for displaying the tooltip on a member reference.
|
||||
/// </summary>
|
||||
public virtual string GetTooltip(MemberReference member)
|
||||
public virtual string GetTooltip(IMemberReference member)
|
||||
{
|
||||
if (member is TypeReference)
|
||||
return TypeToString((TypeReference)member, true);
|
||||
else
|
||||
return member.ToString();
|
||||
return member.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a member signature to a string.
|
||||
/// This is used for displaying the tooltip on a member reference.
|
||||
/// </summary>
|
||||
public virtual string GetTooltip(ITypeReference type)
|
||||
{
|
||||
return TypeToString(type, true);
|
||||
}
|
||||
|
||||
|
||||
public virtual string FormatFieldName(FieldDefinition field)
|
||||
{
|
||||
if (field == null)
|
||||
if (field.Handle.IsNil)
|
||||
throw new ArgumentNullException(nameof(field));
|
||||
return field.Name;
|
||||
}
|
||||
|
||||
public virtual string FormatPropertyName(PropertyDefinition property, bool? isIndexer = null)
|
||||
{
|
||||
if (property == null)
|
||||
if (property.Handle.IsNil)
|
||||
throw new ArgumentNullException(nameof(property));
|
||||
return property.Name;
|
||||
}
|
||||
|
||||
public virtual string FormatMethodName(MethodDefinition method)
|
||||
{
|
||||
if (method == null)
|
||||
if (method.Handle.IsNil)
|
||||
throw new ArgumentNullException(nameof(method));
|
||||
return method.Name;
|
||||
}
|
||||
|
||||
public virtual string FormatEventName(EventDefinition @event)
|
||||
{
|
||||
if (@event == null)
|
||||
if (@event.Handle.IsNil)
|
||||
throw new ArgumentNullException(nameof(@event));
|
||||
return @event.Name;
|
||||
}
|
||||
|
||||
public virtual string FormatTypeName(TypeDefinition type)
|
||||
{
|
||||
if (type == null)
|
||||
if (type.Handle.IsNil)
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
return type.Name;
|
||||
}
|
||||
@@ -171,7 +190,7 @@ namespace ICSharpCode.ILSpy
|
||||
return Name;
|
||||
}
|
||||
|
||||
public virtual bool ShowMember(MemberReference member)
|
||||
public virtual bool ShowMember(IMemberReference member)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -179,9 +198,190 @@ namespace ICSharpCode.ILSpy
|
||||
/// <summary>
|
||||
/// Used by the analyzer to map compiler generated code back to the original code's location
|
||||
/// </summary>
|
||||
public virtual MemberReference GetOriginalCodeLocation(MemberReference member)
|
||||
public virtual IMemberReference GetOriginalCodeLocation(IMemberReference member)
|
||||
{
|
||||
return member;
|
||||
}
|
||||
|
||||
public static string GetPlatformDisplayName(PEFile module)
|
||||
{
|
||||
var architecture = module.Reader.PEHeaders.CoffHeader.Machine;
|
||||
var flags = module.Reader.PEHeaders.CorHeader.Flags;
|
||||
switch (architecture) {
|
||||
case Machine.I386:
|
||||
if ((flags & CorFlags.Prefers32Bit) != 0)
|
||||
return "AnyCPU (32-bit preferred)";
|
||||
else if ((flags & CorFlags.Requires32Bit) != 0)
|
||||
return "x86";
|
||||
else
|
||||
return "AnyCPU (64-bit preferred)";
|
||||
case Machine.Amd64:
|
||||
return "x64";
|
||||
case Machine.IA64:
|
||||
return "Itanium";
|
||||
default:
|
||||
return architecture.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetRuntimeDisplayName(PEFile module)
|
||||
{
|
||||
string version = module.GetMetadataReader().MetadataVersion;
|
||||
switch (version[1]) {
|
||||
case '1':
|
||||
if (version[3] == 1)
|
||||
return ".NET 1.1";
|
||||
else
|
||||
return ".NET 1.0";
|
||||
case '2':
|
||||
return ".NET 2.0";
|
||||
case '4':
|
||||
return ".NET 4.0";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class ILSignatureProvider : SRM.ISignatureTypeProvider<string, GenericContext>
|
||||
{
|
||||
bool includeNamespace;
|
||||
|
||||
public ILSignatureProvider(bool includeNamespace)
|
||||
{
|
||||
this.includeNamespace = includeNamespace;
|
||||
}
|
||||
|
||||
public string GetArrayType(string elementType, SRM.ArrayShape shape)
|
||||
{
|
||||
string printedShape = "";
|
||||
for (int i = 0; i < shape.Rank; i++) {
|
||||
if (i > 0)
|
||||
printedShape += ", ";
|
||||
if (i < shape.LowerBounds.Length || i < shape.Sizes.Length) {
|
||||
int lower = 0;
|
||||
if (i < shape.LowerBounds.Length) {
|
||||
lower = shape.LowerBounds[i];
|
||||
printedShape += lower.ToString();
|
||||
}
|
||||
printedShape += "...";
|
||||
if (i < shape.Sizes.Length)
|
||||
printedShape += (lower + shape.Sizes[i] - 1).ToString();
|
||||
}
|
||||
}
|
||||
return $"{elementType}[{printedShape}]";
|
||||
}
|
||||
|
||||
public string GetByReferenceType(string elementType)
|
||||
{
|
||||
return elementType + "&";
|
||||
}
|
||||
|
||||
public string GetFunctionPointerType(SRM.MethodSignature<string> signature)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetGenericInstantiation(string genericType, ImmutableArray<string> typeArguments)
|
||||
{
|
||||
return genericType + "<" + string.Join(", ", typeArguments) + ">";
|
||||
}
|
||||
|
||||
public string GetGenericMethodParameter(GenericContext genericContext, int index)
|
||||
{
|
||||
return "!!" + genericContext.GetGenericMethodTypeParameterName(index);
|
||||
}
|
||||
|
||||
public string GetGenericTypeParameter(GenericContext genericContext, int index)
|
||||
{
|
||||
return "!" + genericContext.GetGenericTypeParameterName(index);
|
||||
}
|
||||
|
||||
public string GetModifiedType(string modifier, string unmodifiedType, bool isRequired)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetPinnedType(string elementType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetPointerType(string elementType)
|
||||
{
|
||||
return elementType + "*";
|
||||
}
|
||||
|
||||
public string GetPrimitiveType(SRM.PrimitiveTypeCode typeCode)
|
||||
{
|
||||
switch (typeCode) {
|
||||
case SRM.PrimitiveTypeCode.Boolean:
|
||||
return "bool";
|
||||
case SRM.PrimitiveTypeCode.Byte:
|
||||
return "uint8";
|
||||
case SRM.PrimitiveTypeCode.SByte:
|
||||
return "int8";
|
||||
case SRM.PrimitiveTypeCode.Char:
|
||||
return "char";
|
||||
case SRM.PrimitiveTypeCode.Int16:
|
||||
return "int16";
|
||||
case SRM.PrimitiveTypeCode.UInt16:
|
||||
return "uint16";
|
||||
case SRM.PrimitiveTypeCode.Int32:
|
||||
return "int32";
|
||||
case SRM.PrimitiveTypeCode.UInt32:
|
||||
return "uint32";
|
||||
case SRM.PrimitiveTypeCode.Int64:
|
||||
return "int64";
|
||||
case SRM.PrimitiveTypeCode.UInt64:
|
||||
return "uint64";
|
||||
case SRM.PrimitiveTypeCode.Single:
|
||||
return "float32";
|
||||
case SRM.PrimitiveTypeCode.Double:
|
||||
return "float64";
|
||||
case SRM.PrimitiveTypeCode.IntPtr:
|
||||
return "native int";
|
||||
case SRM.PrimitiveTypeCode.UIntPtr:
|
||||
break;
|
||||
case SRM.PrimitiveTypeCode.Object:
|
||||
return "object";
|
||||
case SRM.PrimitiveTypeCode.String:
|
||||
return "string";
|
||||
case SRM.PrimitiveTypeCode.TypedReference:
|
||||
break;
|
||||
case SRM.PrimitiveTypeCode.Void:
|
||||
return "void";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetSZArrayType(string elementType)
|
||||
{
|
||||
return elementType + "[]";
|
||||
}
|
||||
|
||||
public string GetTypeFromDefinition(SRM.MetadataReader reader, SRM.TypeDefinitionHandle handle, byte rawTypeKind)
|
||||
{
|
||||
if (!includeNamespace) {
|
||||
return Decompiler.Disassembler.DisassemblerHelpers.Escape(handle.GetFullTypeName(reader).Name);
|
||||
}
|
||||
|
||||
return handle.GetFullTypeName(reader).ToILNameString();
|
||||
}
|
||||
|
||||
public string GetTypeFromReference(SRM.MetadataReader reader, SRM.TypeReferenceHandle handle, byte rawTypeKind)
|
||||
{
|
||||
if (!includeNamespace) {
|
||||
return Decompiler.Disassembler.DisassemblerHelpers.Escape(handle.GetFullTypeName(reader).Name);
|
||||
}
|
||||
|
||||
return handle.GetFullTypeName(reader).ToILNameString();
|
||||
}
|
||||
|
||||
public string GetTypeFromSpecification(SRM.MetadataReader reader, GenericContext genericContext, SRM.TypeSpecificationHandle handle, byte rawTypeKind)
|
||||
{
|
||||
return reader.GetTypeSpecification(handle).DecodeSignature(this, genericContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ namespace ICSharpCode.ILSpy
|
||||
languages.AddRange(composition.GetExportedValues<Language>());
|
||||
languages.Sort((a, b) => a.Name.CompareTo(b.Name));
|
||||
#if DEBUG
|
||||
languages.AddRange(ILAstLanguage.GetDebugLanguages());
|
||||
languages.AddRange(CSharpLanguage.GetDebugLanguages());
|
||||
//languages.AddRange(ILAstLanguage.GetDebugLanguages());
|
||||
//languages.AddRange(CSharpLanguage.GetDebugLanguages());
|
||||
#endif
|
||||
allLanguages = languages.AsReadOnly();
|
||||
}
|
||||
|
||||
+44
-72
@@ -19,13 +19,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Threading;
|
||||
using ICSharpCode.Decompiler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.ILSpy.Options;
|
||||
using Mono.Cecil;
|
||||
|
||||
using static System.Reflection.Metadata.PEReaderExtensions;
|
||||
|
||||
namespace ICSharpCode.ILSpy
|
||||
{
|
||||
@@ -34,21 +35,17 @@ namespace ICSharpCode.ILSpy
|
||||
/// </summary>
|
||||
public sealed class LoadedAssembly
|
||||
{
|
||||
readonly Task<ModuleDefinition> assemblyTask;
|
||||
readonly Task<PEFile> assemblyTask;
|
||||
readonly AssemblyList assemblyList;
|
||||
readonly string fileName;
|
||||
readonly string shortName;
|
||||
|
||||
public LoadedAssembly(AssemblyList assemblyList, string fileName, Stream stream = null)
|
||||
{
|
||||
if (assemblyList == null)
|
||||
throw new ArgumentNullException(nameof(assemblyList));
|
||||
if (fileName == null)
|
||||
throw new ArgumentNullException(nameof(fileName));
|
||||
this.assemblyList = assemblyList;
|
||||
this.fileName = fileName;
|
||||
this.assemblyList = assemblyList ?? throw new ArgumentNullException(nameof(assemblyList));
|
||||
this.fileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
|
||||
|
||||
this.assemblyTask = Task.Factory.StartNew<ModuleDefinition>(LoadAssembly, stream); // requires that this.fileName is set
|
||||
this.assemblyTask = Task.Factory.StartNew(LoadAssembly, stream); // requires that this.fileName is set
|
||||
this.shortName = Path.GetFileNameWithoutExtension(fileName);
|
||||
}
|
||||
|
||||
@@ -58,8 +55,8 @@ namespace ICSharpCode.ILSpy
|
||||
/// </summary>
|
||||
public async Task<string> GetTargetFrameworkIdAsync()
|
||||
{
|
||||
var assembly = await GetAssemblyDefinitionAsync().ConfigureAwait(false);
|
||||
return assembly?.DetectTargetFrameworkId() ?? string.Empty;
|
||||
var assembly = await GetPEFileAsync().ConfigureAwait(false);
|
||||
return assembly.Reader.DetectTargetFrameworkId() ?? string.Empty;
|
||||
}
|
||||
|
||||
public ReferenceLoadInfo LoadedAssemblyReferencesInfo { get; } = new ReferenceLoadInfo();
|
||||
@@ -67,7 +64,7 @@ namespace ICSharpCode.ILSpy
|
||||
/// <summary>
|
||||
/// Gets the Cecil ModuleDefinition.
|
||||
/// </summary>
|
||||
public Task<ModuleDefinition> GetModuleDefinitionAsync()
|
||||
public Task<PEFile> GetPEFileAsync()
|
||||
{
|
||||
return assemblyTask;
|
||||
}
|
||||
@@ -76,33 +73,10 @@ namespace ICSharpCode.ILSpy
|
||||
/// Gets the Cecil ModuleDefinition.
|
||||
/// Returns null in case of load errors.
|
||||
/// </summary>
|
||||
public ModuleDefinition GetModuleDefinitionOrNull()
|
||||
public PEFile GetPEFileOrNull()
|
||||
{
|
||||
try {
|
||||
return GetModuleDefinitionAsync().Result;
|
||||
} catch (Exception ex) {
|
||||
System.Diagnostics.Trace.TraceError(ex.ToString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Cecil AssemblyDefinition.
|
||||
/// </summary>
|
||||
public async Task<AssemblyDefinition> GetAssemblyDefinitionAsync()
|
||||
{
|
||||
var module = await assemblyTask.ConfigureAwait(false);
|
||||
return module != null ? module.Assembly : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Cecil AssemblyDefinition.
|
||||
/// Returns null when there was a load error; or when opening a netmodule.
|
||||
/// </summary>
|
||||
public AssemblyDefinition GetAssemblyDefinitionOrNull()
|
||||
{
|
||||
try {
|
||||
return GetAssemblyDefinitionAsync().Result;
|
||||
return GetPEFileAsync().Result;
|
||||
} catch (Exception ex) {
|
||||
System.Diagnostics.Trace.TraceError(ex.ToString());
|
||||
return null;
|
||||
@@ -118,7 +92,7 @@ namespace ICSharpCode.ILSpy
|
||||
public string Text {
|
||||
get {
|
||||
if (IsLoaded && !HasLoadError) {
|
||||
string version = GetAssemblyDefinitionOrNull()?.Name.Version.ToString();
|
||||
string version = GetPEFileOrNull()?.Reader.GetAssemblyDefinition()?.Version.ToString();
|
||||
if (version == null)
|
||||
return ShortName;
|
||||
return String.Format("{0} ({1})", ShortName, version);
|
||||
@@ -134,25 +108,26 @@ namespace ICSharpCode.ILSpy
|
||||
|
||||
public bool IsAutoLoaded { get; set; }
|
||||
|
||||
ModuleDefinition LoadAssembly(object state)
|
||||
PEFile LoadAssembly(object state)
|
||||
{
|
||||
var stream = state as Stream;
|
||||
ModuleDefinition module;
|
||||
PEReader module;
|
||||
|
||||
// runs on background thread
|
||||
ReaderParameters p = new ReaderParameters();
|
||||
p.AssemblyResolver = new MyAssemblyResolver(this);
|
||||
p.InMemory = true;
|
||||
|
||||
if (stream != null)
|
||||
{
|
||||
// Read the module from a precrafted stream
|
||||
module = ModuleDefinition.ReadModule(stream, p);
|
||||
module = new PEReader(stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read the module from disk (by default)
|
||||
module = ModuleDefinition.ReadModule(fileName, p);
|
||||
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
|
||||
var ms = new MemoryStream();
|
||||
fs.CopyTo(ms);
|
||||
ms.Position = 0;
|
||||
module = new PEReader(ms, PEStreamOptions.PrefetchEntireImage);
|
||||
}
|
||||
}
|
||||
|
||||
if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) {
|
||||
@@ -164,17 +139,18 @@ namespace ICSharpCode.ILSpy
|
||||
// ignore any errors during symbol loading
|
||||
}
|
||||
}
|
||||
return module;
|
||||
return new PEFile(fileName, module, new MyAssemblyResolver(this));
|
||||
}
|
||||
|
||||
private void LoadSymbols(ModuleDefinition module)
|
||||
private void LoadSymbols(PEReader reader)
|
||||
{
|
||||
if (!module.HasDebugHeader) {
|
||||
/*string pdbDirectory = Path.GetDirectoryName(fileName);
|
||||
if (!reader.TryOpenAssociatedPortablePdb(pdbDirectory, OpenStream, out var provider, out var pdbFileName) {
|
||||
return;
|
||||
}
|
||||
|
||||
// search for pdb in same directory as dll
|
||||
string pdbName = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".pdb");
|
||||
string pdbName = Path.Combine(, Path.GetFileNameWithoutExtension(fileName) + ".pdb");
|
||||
if (File.Exists(pdbName)) {
|
||||
using (Stream s = File.OpenRead(pdbName)) {
|
||||
module.ReadSymbols(new Mono.Cecil.Pdb.PdbReaderProvider().GetSymbolReader(module, s));
|
||||
@@ -183,6 +159,11 @@ namespace ICSharpCode.ILSpy
|
||||
}
|
||||
|
||||
// TODO: use symbol cache, get symbols from microsoft
|
||||
|
||||
Stream OpenStream(string pdbFileName)
|
||||
{
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
[ThreadStatic]
|
||||
@@ -218,18 +199,9 @@ namespace ICSharpCode.ILSpy
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public AssemblyDefinition Resolve(AssemblyNameReference name)
|
||||
{
|
||||
return parent.LookupReferencedAssembly(name)?.GetAssemblyDefinitionOrNull();
|
||||
}
|
||||
|
||||
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
|
||||
{
|
||||
return parent.LookupReferencedAssembly(name)?.GetAssemblyDefinitionOrNull();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public PEFile Resolve(IAssemblyReference reference)
|
||||
{
|
||||
return parent.LookupReferencedAssembly(reference)?.GetPEFileOrNull();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,14 +210,12 @@ namespace ICSharpCode.ILSpy
|
||||
return new MyAssemblyResolver(this);
|
||||
}
|
||||
|
||||
public LoadedAssembly LookupReferencedAssembly(AssemblyNameReference name)
|
||||
public LoadedAssembly LookupReferencedAssembly(IAssemblyReference reference)
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
if (name.IsWindowsRuntime) {
|
||||
return assemblyList.assemblyLookupCache.GetOrAdd((name.Name, true), LookupReferencedAssemblyInternal);
|
||||
if (reference.IsWindowsRuntime) {
|
||||
return assemblyList.assemblyLookupCache.GetOrAdd((reference.Name, true), LookupReferencedAssemblyInternal);
|
||||
} else {
|
||||
return assemblyList.assemblyLookupCache.GetOrAdd((name.FullName, false), LookupReferencedAssemblyInternal);
|
||||
return assemblyList.assemblyLookupCache.GetOrAdd((reference.FullName, false), LookupReferencedAssemblyInternal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,8 +235,10 @@ namespace ICSharpCode.ILSpy
|
||||
LoadedAssembly asm;
|
||||
lock (loadingAssemblies) {
|
||||
foreach (LoadedAssembly loaded in assemblyList.GetAssemblies()) {
|
||||
var asmDef = loaded.GetAssemblyDefinitionOrNull();
|
||||
if (asmDef != null && data.fullName.Equals(data.isWinRT ? asmDef.Name.Name : asmDef.FullName, StringComparison.OrdinalIgnoreCase)) {
|
||||
var reader = loaded.GetPEFileOrNull()?.GetMetadataReader();
|
||||
if (reader == null || !reader.IsAssembly) continue;
|
||||
var asmDef = reader.GetAssemblyDefinition();
|
||||
if (data.fullName.Equals(data.isWinRT ? reader.GetString(asmDef.Name) : reader.GetFullAssemblyName(), StringComparison.OrdinalIgnoreCase)) {
|
||||
LoadedAssemblyReferencesInfo.AddMessageOnce(data.fullName, MessageKind.Info, "Success - Found in Assembly List");
|
||||
return loaded;
|
||||
}
|
||||
@@ -312,7 +284,7 @@ namespace ICSharpCode.ILSpy
|
||||
return asm;
|
||||
}
|
||||
|
||||
public Task ContinueWhenLoaded(Action<Task<ModuleDefinition>> onAssemblyLoaded, TaskScheduler taskScheduler)
|
||||
public Task ContinueWhenLoaded(Action<Task<PEFile>> onAssemblyLoaded, TaskScheduler taskScheduler)
|
||||
{
|
||||
return this.assemblyTask.ContinueWith(onAssemblyLoaded, default(CancellationToken), TaskContinuationOptions.RunContinuationsAsynchronously, taskScheduler);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ using ICSharpCode.ILSpy.TextView;
|
||||
using ICSharpCode.ILSpy.TreeNodes;
|
||||
using ICSharpCode.TreeView;
|
||||
using Microsoft.Win32;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.ILSpy
|
||||
{
|
||||
@@ -273,14 +272,14 @@ namespace ICSharpCode.ILSpy
|
||||
}
|
||||
} else {
|
||||
foreach (LoadedAssembly asm in commandLineLoadedAssemblies) {
|
||||
ModuleDefinition def = asm.GetModuleDefinitionOrNull();
|
||||
var def = asm.GetPEFileOrNull();
|
||||
if (def != null) {
|
||||
MemberReference mr = XmlDocKeyProvider.FindMemberByKey(def, args.NavigateTo);
|
||||
/*MemberReference mr = XmlDocKeyProvider.FindMemberByKey(def, args.NavigateTo);
|
||||
if (mr != null) {
|
||||
found = true;
|
||||
JumpToReference(mr);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,7 +291,7 @@ namespace ICSharpCode.ILSpy
|
||||
} else if (commandLineLoadedAssemblies.Count == 1) {
|
||||
// NavigateTo == null and an assembly was given on the command-line:
|
||||
// Select the newly loaded assembly
|
||||
JumpToReference(commandLineLoadedAssemblies[0].GetModuleDefinitionOrNull());
|
||||
JumpToReference(commandLineLoadedAssemblies[0].GetPEFileOrNull());
|
||||
}
|
||||
if (args.Search != null)
|
||||
{
|
||||
@@ -577,7 +576,7 @@ namespace ICSharpCode.ILSpy
|
||||
|
||||
public ILSpyTreeNode FindTreeNode(object reference)
|
||||
{
|
||||
if (reference is TypeReference)
|
||||
/*if (reference is TypeReference)
|
||||
{
|
||||
return assemblyListTreeNode.FindTypeNode(((TypeReference)reference).Resolve());
|
||||
}
|
||||
@@ -597,7 +596,7 @@ namespace ICSharpCode.ILSpy
|
||||
{
|
||||
return assemblyListTreeNode.FindEventNode(((EventReference)reference).Resolve());
|
||||
}
|
||||
else if (reference is AssemblyDefinition)
|
||||
else if (reference is PEFile)
|
||||
{
|
||||
return assemblyListTreeNode.FindAssemblyNode((AssemblyDefinition)reference);
|
||||
}
|
||||
@@ -607,12 +606,14 @@ namespace ICSharpCode.ILSpy
|
||||
}
|
||||
else if (reference is Resource)
|
||||
{
|
||||
return assemblyListTreeNode.FindResourceNode((Resource)reference);
|
||||
return null;
|
||||
//return assemblyListTreeNode.FindResourceNode((Resource)reference);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}*/
|
||||
return null;
|
||||
}
|
||||
|
||||
public void JumpToReference(object reference)
|
||||
|
||||
+4
-4
@@ -26,7 +26,7 @@ using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.ILSpy.TreeNodes;
|
||||
using Mono.Cecil;
|
||||
|
||||
@@ -216,12 +216,12 @@ namespace ICSharpCode.ILSpy
|
||||
try {
|
||||
var searcher = GetSearchStrategy(searchMode, searchTerm);
|
||||
foreach (var loadedAssembly in assemblies) {
|
||||
ModuleDefinition module = loadedAssembly.GetModuleDefinitionOrNull();
|
||||
var module = loadedAssembly.GetPEFileOrNull();
|
||||
if (module == null)
|
||||
continue;
|
||||
CancellationToken cancellationToken = cts.Token;
|
||||
|
||||
foreach (TypeDefinition type in module.Types) {
|
||||
foreach (var type in module.TypeDefinitions) {
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
searcher.Search(type, language, AddResult);
|
||||
}
|
||||
@@ -333,7 +333,7 @@ namespace ICSharpCode.ILSpy
|
||||
|
||||
public static readonly System.Collections.Generic.IComparer<SearchResult> Comparer = new SearchResultComparer();
|
||||
|
||||
public MemberReference Member { get; set; }
|
||||
public IMemberReference Member { get; set; }
|
||||
public float Fitness { get; set; }
|
||||
|
||||
public string Location { get; set; }
|
||||
|
||||
+114
-89
@@ -3,11 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Media;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
using ICSharpCode.ILSpy.TreeNodes;
|
||||
using Mono.Cecil;
|
||||
using Code = Mono.Cecil.Cil.Code;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using System.Reflection;
|
||||
using ICSharpCode.Decompiler.Disassembler;
|
||||
using ILOpCode = System.Reflection.Metadata.ILOpCode;
|
||||
|
||||
namespace ICSharpCode.ILSpy
|
||||
{
|
||||
@@ -37,7 +38,7 @@ namespace ICSharpCode.ILSpy
|
||||
searchTerm = terms;
|
||||
}
|
||||
|
||||
protected float CalculateFitness(MemberReference member)
|
||||
protected float CalculateFitness(IMemberReference member)
|
||||
{
|
||||
string text = member.Name;
|
||||
|
||||
@@ -49,11 +50,11 @@ namespace ICSharpCode.ILSpy
|
||||
// Constructors always have the same name in IL:
|
||||
// Use type name instead
|
||||
if (text == ".cctor" || text == ".ctor") {
|
||||
text = member.DeclaringType.Name;
|
||||
//text = member.DeclaringType.Name;
|
||||
}
|
||||
|
||||
// Ignore generic arguments, it not possible to search based on them either
|
||||
text = ReflectionHelper.SplitTypeParameterCountFromReflectionName(text);
|
||||
text = Decompiler.TypeSystem.ReflectionHelper.SplitTypeParameterCountFromReflectionName(text);
|
||||
|
||||
return 1.0f / text.Length;
|
||||
}
|
||||
@@ -139,7 +140,7 @@ namespace ICSharpCode.ILSpy
|
||||
}
|
||||
}
|
||||
|
||||
void Add<T>(IEnumerable<T> items, TypeDefinition type, Language language, Action<SearchResult> addResult, Func<T, Language, bool> matcher, Func<T, ImageSource> image) where T : MemberReference
|
||||
void Add<T>(IEnumerable<T> items, TypeDefinition type, Language language, Action<SearchResult> addResult, Func<T, Language, bool> matcher, Func<T, ImageSource> image) where T : IMemberReference
|
||||
{
|
||||
foreach (var item in items) {
|
||||
if (matcher(item, language)) {
|
||||
@@ -170,12 +171,12 @@ namespace ICSharpCode.ILSpy
|
||||
|
||||
bool NotSpecialMethod(MethodDefinition arg)
|
||||
{
|
||||
return (arg.SemanticsAttributes & (
|
||||
return (arg.GetMethodSemanticsAttributes() & (
|
||||
MethodSemanticsAttributes.Setter
|
||||
| MethodSemanticsAttributes.Getter
|
||||
| MethodSemanticsAttributes.AddOn
|
||||
| MethodSemanticsAttributes.RemoveOn
|
||||
| MethodSemanticsAttributes.Fire)) == 0;
|
||||
| MethodSemanticsAttributes.Adder
|
||||
| MethodSemanticsAttributes.Remover
|
||||
| MethodSemanticsAttributes.Raiser)) == 0;
|
||||
}
|
||||
|
||||
Regex SafeNewRegex(string unsafePattern)
|
||||
@@ -227,7 +228,7 @@ namespace ICSharpCode.ILSpy
|
||||
|
||||
protected override bool IsMatch(FieldDefinition field, Language language)
|
||||
{
|
||||
return IsLiteralMatch(field.Constant);
|
||||
return IsLiteralMatch(field.DecodeConstant());
|
||||
}
|
||||
|
||||
protected override bool IsMatch(PropertyDefinition property, Language language)
|
||||
@@ -268,91 +269,115 @@ namespace ICSharpCode.ILSpy
|
||||
|
||||
bool MethodIsLiteralMatch(MethodDefinition m)
|
||||
{
|
||||
if (m == null)
|
||||
return false;
|
||||
var body = m.Body;
|
||||
if (body == null)
|
||||
if (m == null || !m.HasBody)
|
||||
return false;
|
||||
var blob = m.Body.GetILReader();
|
||||
if (searchTermLiteralType == TypeCode.Int64) {
|
||||
long val = (long)searchTermLiteralValue;
|
||||
foreach (var inst in body.Instructions) {
|
||||
switch (inst.OpCode.Code) {
|
||||
case Code.Ldc_I8:
|
||||
if (val == (long)inst.Operand)
|
||||
return true;
|
||||
break;
|
||||
case Code.Ldc_I4:
|
||||
if (val == (int)inst.Operand)
|
||||
return true;
|
||||
break;
|
||||
case Code.Ldc_I4_S:
|
||||
if (val == (sbyte)inst.Operand)
|
||||
return true;
|
||||
break;
|
||||
case Code.Ldc_I4_M1:
|
||||
if (val == -1)
|
||||
return true;
|
||||
break;
|
||||
case Code.Ldc_I4_0:
|
||||
if (val == 0)
|
||||
return true;
|
||||
break;
|
||||
case Code.Ldc_I4_1:
|
||||
if (val == 1)
|
||||
return true;
|
||||
break;
|
||||
case Code.Ldc_I4_2:
|
||||
if (val == 2)
|
||||
return true;
|
||||
break;
|
||||
case Code.Ldc_I4_3:
|
||||
if (val == 3)
|
||||
return true;
|
||||
break;
|
||||
case Code.Ldc_I4_4:
|
||||
if (val == 4)
|
||||
return true;
|
||||
break;
|
||||
case Code.Ldc_I4_5:
|
||||
if (val == 5)
|
||||
return true;
|
||||
break;
|
||||
case Code.Ldc_I4_6:
|
||||
if (val == 6)
|
||||
return true;
|
||||
break;
|
||||
case Code.Ldc_I4_7:
|
||||
if (val == 7)
|
||||
return true;
|
||||
break;
|
||||
case Code.Ldc_I4_8:
|
||||
if (val == 8)
|
||||
return true;
|
||||
break;
|
||||
while (blob.RemainingBytes > 0) {
|
||||
ILOpCode code;
|
||||
switch (code = ILParser.DecodeOpCode(ref blob)) {
|
||||
case ILOpCode.Ldc_i8:
|
||||
if (val == blob.ReadInt64())
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_i4:
|
||||
if (val == blob.ReadInt32())
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_i4_s:
|
||||
if (val == blob.ReadSByte())
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_i4_m1:
|
||||
if (val == -1)
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_i4_0:
|
||||
if (val == 0)
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_i4_1:
|
||||
if (val == 1)
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_i4_2:
|
||||
if (val == 2)
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_i4_3:
|
||||
if (val == 3)
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_i4_4:
|
||||
if (val == 4)
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_i4_5:
|
||||
if (val == 5)
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_i4_6:
|
||||
if (val == 6)
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_i4_7:
|
||||
if (val == 7)
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_i4_8:
|
||||
if (val == 8)
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
ILParser.SkipOperand(ref blob, code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (searchTermLiteralType != TypeCode.Empty) {
|
||||
Code expectedCode;
|
||||
ILOpCode expectedCode;
|
||||
switch (searchTermLiteralType) {
|
||||
case TypeCode.Single:
|
||||
expectedCode = Code.Ldc_R4;
|
||||
break;
|
||||
case TypeCode.Double:
|
||||
expectedCode = Code.Ldc_R8;
|
||||
break;
|
||||
case TypeCode.String:
|
||||
expectedCode = Code.Ldstr;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
case TypeCode.Single:
|
||||
expectedCode = ILOpCode.Ldc_r4;
|
||||
break;
|
||||
case TypeCode.Double:
|
||||
expectedCode = ILOpCode.Ldc_r8;
|
||||
break;
|
||||
case TypeCode.String:
|
||||
expectedCode = ILOpCode.Ldstr;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
foreach (var inst in body.Instructions) {
|
||||
if (inst.OpCode.Code == expectedCode && searchTermLiteralValue.Equals(inst.Operand))
|
||||
return true;
|
||||
while (blob.RemainingBytes > 0) {
|
||||
var code = ILParser.DecodeOpCode(ref blob);
|
||||
if (code != expectedCode) {
|
||||
ILParser.SkipOperand(ref blob, code);
|
||||
continue;
|
||||
}
|
||||
switch (code) {
|
||||
case ILOpCode.Ldc_r4:
|
||||
if ((float)searchTermLiteralValue == blob.ReadSingle())
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldc_r8:
|
||||
if ((double)searchTermLiteralValue == blob.ReadDouble())
|
||||
return true;
|
||||
break;
|
||||
case ILOpCode.Ldstr:
|
||||
if ((string)searchTermLiteralValue == ILParser.DecodeUserString(ref blob, m.Module))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach (var inst in body.Instructions) {
|
||||
if (inst.OpCode.Code == Code.Ldstr && IsMatch(t => (string)inst.Operand))
|
||||
while (blob.RemainingBytes > 0) {
|
||||
var code = ILParser.DecodeOpCode(ref blob);
|
||||
if (code != ILOpCode.Ldstr) {
|
||||
ILParser.SkipOperand(ref blob, code);
|
||||
continue;
|
||||
}
|
||||
if (IsMatch(t => ILParser.DecodeUserString(ref blob, m.Module)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -450,8 +475,8 @@ namespace ICSharpCode.ILSpy
|
||||
Image = TypeTreeNode.GetIcon(type),
|
||||
Fitness = CalculateFitness(type),
|
||||
Name = name,
|
||||
LocationImage = type.DeclaringType != null ? TypeTreeNode.GetIcon(type.DeclaringType) : Images.Namespace,
|
||||
Location = type.DeclaringType != null ? language.TypeToString(type.DeclaringType, includeNamespace: true) : type.Namespace
|
||||
LocationImage = !type.DeclaringType.IsNil ? TypeTreeNode.GetIcon(type.DeclaringType) : Images.Namespace,
|
||||
Location = !type.DeclaringType.IsNil ? language.TypeToString(type.DeclaringType, includeNamespace: true) : type.Namespace
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -200,12 +200,12 @@ namespace ICSharpCode.ILSpy.TextView
|
||||
string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + code.EncodedName);
|
||||
if (documentation != null) {
|
||||
XmlDocRenderer renderer = new XmlDocRenderer();
|
||||
renderer.AppendText($"{code.Name} (0x{code.Code:x2}) - ");
|
||||
renderer.AppendText($"{code.Name} (0x{code.Code:x}) - ");
|
||||
renderer.AddXmlDocumentation(documentation);
|
||||
return renderer.CreateTextBlock();
|
||||
}
|
||||
}
|
||||
return $"{code.Name} (0x{code.Code:x2})";
|
||||
return $"{code.Name} (0x{code.Code:x})";
|
||||
} else if (segment.Reference is MemberReference) {
|
||||
MemberReference mr = (MemberReference)segment.Reference;
|
||||
// if possible, resolve the reference
|
||||
@@ -215,7 +215,7 @@ namespace ICSharpCode.ILSpy.TextView
|
||||
mr = ((MethodReference)mr).Resolve() ?? mr;
|
||||
}
|
||||
XmlDocRenderer renderer = new XmlDocRenderer();
|
||||
renderer.AppendText(MainWindow.Instance.CurrentLanguage.GetTooltip(mr));
|
||||
//renderer.AppendText(MainWindow.Instance.CurrentLanguage.GetTooltip(mr));
|
||||
try {
|
||||
XmlDocumentationProvider docProvider = XmlDocLoader.LoadDocumentation(mr.Module);
|
||||
if (docProvider != null) {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Linq;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -62,32 +62,31 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
}
|
||||
}
|
||||
|
||||
public static void Analyze(MemberReference member)
|
||||
public static void Analyze(IMemberReference member)
|
||||
{
|
||||
if (member is TypeReference) {
|
||||
TypeDefinition type = ((TypeReference)member).Resolve();
|
||||
if (type != null)
|
||||
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedTypeTreeNode(type));
|
||||
}
|
||||
else if (member is FieldReference) {
|
||||
FieldDefinition field = ((FieldReference)member).Resolve();
|
||||
if (field != null)
|
||||
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedFieldTreeNode(field));
|
||||
}
|
||||
else if (member is MethodReference) {
|
||||
MethodDefinition method = ((MethodReference)member).Resolve();
|
||||
if (method != null)
|
||||
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedMethodTreeNode(method));
|
||||
}
|
||||
else if (member is PropertyReference) {
|
||||
PropertyDefinition property = ((PropertyReference)member).Resolve();
|
||||
if (property != null)
|
||||
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedPropertyTreeNode(property));
|
||||
}
|
||||
else if (member is EventReference) {
|
||||
EventDefinition @event = ((EventReference)member).Resolve();
|
||||
if (@event != null)
|
||||
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedEventTreeNode(@event));
|
||||
var definition = member.GetDefinition();
|
||||
if (definition == null) return;
|
||||
switch (definition) {
|
||||
case TypeDefinition td:
|
||||
if (!td.IsNil)
|
||||
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedTypeTreeNode(td));
|
||||
break;
|
||||
case FieldDefinition fd:
|
||||
if (!fd.IsNil)
|
||||
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedFieldTreeNode(fd));
|
||||
break;
|
||||
case MethodDefinition md:
|
||||
if (!md.IsNil)
|
||||
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedMethodTreeNode(md));
|
||||
break;
|
||||
case PropertyDefinition pd:
|
||||
if (!pd.IsNil)
|
||||
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedPropertyTreeNode(pd));
|
||||
break;
|
||||
case EventDefinition ed:
|
||||
if (!ed.IsNil)
|
||||
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedEventTreeNode(ed));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,15 +17,15 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
internal class AnalyzedAssemblyTreeNode : AnalyzerEntityTreeNode
|
||||
{
|
||||
private readonly ModuleDefinition analyzedAssembly;
|
||||
private readonly PEFile analyzedAssembly;
|
||||
|
||||
public AnalyzedAssemblyTreeNode(ModuleDefinition analyzedAssembly)
|
||||
public AnalyzedAssemblyTreeNode(PEFile analyzedAssembly)
|
||||
{
|
||||
if (analyzedAssembly == null)
|
||||
throw new ArgumentNullException(nameof(analyzedAssembly));
|
||||
@@ -33,27 +33,15 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
//this.LazyLoading = true;
|
||||
}
|
||||
|
||||
public override object Icon
|
||||
{
|
||||
get { return Images.Assembly; }
|
||||
}
|
||||
public override object Icon => Images.Assembly;
|
||||
|
||||
public override object Text
|
||||
{
|
||||
get
|
||||
{
|
||||
return analyzedAssembly.Name;
|
||||
}
|
||||
}
|
||||
public override object Text => analyzedAssembly.Name;
|
||||
|
||||
protected override void LoadChildren()
|
||||
{
|
||||
//this.Children.Add(new AnalyzedAssemblyReferencedByTreeNode(analyzedAssembly));
|
||||
}
|
||||
|
||||
public override MemberReference Member
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
public override IMemberReference Member => null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Mono.Cecil;
|
||||
using System.Collections.Concurrent;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -43,7 +43,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public AnalyzedAttributeAppliedToTreeNode(TypeDefinition analyzedType)
|
||||
{
|
||||
if (analyzedType == null)
|
||||
if (analyzedType.IsNil)
|
||||
throw new ArgumentNullException(nameof(analyzedType));
|
||||
|
||||
this.analyzedType = analyzedType;
|
||||
@@ -103,7 +103,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
#region standard custom attributes
|
||||
|
||||
private IEnumerable<AnalyzerTreeNode> FindReferencesInAssembly(ModuleDefinition module, TypeReference tr, CancellationToken ct)
|
||||
private IEnumerable<AnalyzerTreeNode> FindReferencesInAssembly(PEFile module, TypeReference tr, CancellationToken ct)
|
||||
{
|
||||
//since we do not display modules as separate entities, coalesce the assembly and module searches
|
||||
bool foundInAssyOrModule = false;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
|
||||
@@ -19,9 +19,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Disassembler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -31,7 +32,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public AnalyzedEventOverridesTreeNode(EventDefinition analyzedEvent)
|
||||
{
|
||||
if (analyzedEvent == null)
|
||||
if (analyzedEvent.IsNil)
|
||||
throw new ArgumentNullException(nameof(analyzedEvent));
|
||||
|
||||
this.analyzedEvent = analyzedEvent;
|
||||
@@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
private IEnumerable<AnalyzerTreeNode> FindReferencesInType(TypeDefinition type)
|
||||
{
|
||||
if (!TypesHierarchyHelpers.IsBaseType(analyzedEvent.DeclaringType, type, resolveTypeArguments: false))
|
||||
if (!analyzedEvent.DeclaringType.IsBaseTypeOf(type))
|
||||
yield break;
|
||||
|
||||
foreach (EventDefinition eventDef in type.Events) {
|
||||
@@ -66,8 +67,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public static bool CanShow(EventDefinition property)
|
||||
{
|
||||
var accessor = property.AddMethod ?? property.RemoveMethod;
|
||||
return accessor.IsVirtual && !accessor.IsFinal && !accessor.DeclaringType.IsInterface;
|
||||
var accessor = property.GetAccessors().First().Method;
|
||||
return accessor.HasFlag(MethodAttributes.Virtual) && !accessor.HasFlag(MethodAttributes.Final) && !accessor.DeclaringType.IsInterface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using Mono.Cecil;
|
||||
using System.Linq;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -35,9 +36,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
this.LazyLoading = true;
|
||||
}
|
||||
|
||||
public override MemberReference Member {
|
||||
get { return analyzedEvent; }
|
||||
}
|
||||
public override IMemberReference Member => analyzedEvent;
|
||||
|
||||
public override object Icon
|
||||
{
|
||||
@@ -82,13 +81,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool CanShow(MemberReference member)
|
||||
public static bool CanShow(IMemberReference member)
|
||||
{
|
||||
var eventDef = member as EventDefinition;
|
||||
if (eventDef == null)
|
||||
if (!(member is EventDefinition eventDef))
|
||||
return false;
|
||||
|
||||
return !MainWindow.Instance.CurrentLanguage.ShowMember(eventDef.AddMethod ?? eventDef.RemoveMethod)
|
||||
return !MainWindow.Instance.CurrentLanguage.ShowMember(eventDef.GetAccessors().First().Method)
|
||||
|| AnalyzedEventOverridesTreeNode.CanShow(eventDef);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,10 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using ICSharpCode.Decompiler.Disassembler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
using ILOpCode = System.Reflection.Metadata.ILOpCode;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -35,7 +37,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public AnalyzedFieldAccessTreeNode(FieldDefinition analyzedField, bool showWrites)
|
||||
{
|
||||
if (analyzedField == null)
|
||||
if (analyzedField.IsNil)
|
||||
throw new ArgumentNullException(nameof(analyzedField));
|
||||
|
||||
this.analyzedField = analyzedField;
|
||||
@@ -67,24 +69,27 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
bool found = false;
|
||||
if (!method.HasBody)
|
||||
continue;
|
||||
foreach (Instruction instr in method.Body.Instructions) {
|
||||
if (CanBeReference(instr.OpCode.Code)) {
|
||||
FieldReference fr = instr.Operand as FieldReference;
|
||||
if (fr != null && fr.Name == name &&
|
||||
Helpers.IsReferencedBy(analyzedField.DeclaringType, fr.DeclaringType) &&
|
||||
fr.Resolve() == analyzedField) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
var blob = method.Body.GetILReader();
|
||||
while (blob.RemainingBytes > 0) {
|
||||
var opCode = ILParser.DecodeOpCode(ref blob);
|
||||
if (!CanBeReference(opCode)) {
|
||||
ILParser.SkipOperand(ref blob, opCode);
|
||||
continue;
|
||||
}
|
||||
var field = ILParser.DecodeMemberToken(ref blob, method.Module);
|
||||
if (field == null || field.Name != name)
|
||||
continue;
|
||||
var definition = field.GetDefinition() as FieldDefinition?;
|
||||
if (definition?.DeclaringType.FullName != analyzedField.DeclaringType.FullName)
|
||||
continue;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
method.Body = null;
|
||||
|
||||
if (found) {
|
||||
MethodDefinition codeLocation = this.Language.GetOriginalCodeLocation(method) as MethodDefinition;
|
||||
if (codeLocation != null && !HasAlreadyBeenFound(codeLocation)) {
|
||||
var node = new AnalyzedMethodTreeNode(codeLocation);
|
||||
MethodDefinition? codeLocation = this.Language.GetOriginalCodeLocation(method) as MethodDefinition?;
|
||||
if (codeLocation != null && !HasAlreadyBeenFound(codeLocation.Value)) {
|
||||
var node = new AnalyzedMethodTreeNode(codeLocation.Value);
|
||||
node.Language = this.Language;
|
||||
yield return node;
|
||||
}
|
||||
@@ -92,17 +97,17 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
}
|
||||
}
|
||||
|
||||
private bool CanBeReference(Code code)
|
||||
private bool CanBeReference(ILOpCode code)
|
||||
{
|
||||
switch (code) {
|
||||
case Code.Ldfld:
|
||||
case Code.Ldsfld:
|
||||
case ILOpCode.Ldfld:
|
||||
case ILOpCode.Ldsfld:
|
||||
return !showWrites;
|
||||
case Code.Stfld:
|
||||
case Code.Stsfld:
|
||||
case ILOpCode.Stfld:
|
||||
case ILOpCode.Stsfld:
|
||||
return showWrites;
|
||||
case Code.Ldflda:
|
||||
case Code.Ldsflda:
|
||||
case ILOpCode.Ldflda:
|
||||
case ILOpCode.Ldsflda:
|
||||
return true; // always show address-loading
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -27,16 +27,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public AnalyzedFieldTreeNode(FieldDefinition analyzedField)
|
||||
{
|
||||
if (analyzedField == null)
|
||||
if (analyzedField.IsNil)
|
||||
throw new ArgumentNullException(nameof(analyzedField));
|
||||
this.analyzedField = analyzedField;
|
||||
this.LazyLoading = true;
|
||||
}
|
||||
|
||||
public override object Icon
|
||||
{
|
||||
get { return FieldTreeNode.GetIcon(analyzedField); }
|
||||
}
|
||||
public override object Icon => FieldTreeNode.GetIcon(analyzedField);
|
||||
|
||||
public override object Text
|
||||
{
|
||||
@@ -54,8 +51,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
this.Children.Add(new AnalyzedFieldAccessTreeNode(analyzedField, true));
|
||||
}
|
||||
|
||||
public override MemberReference Member {
|
||||
get { return analyzedField; }
|
||||
}
|
||||
public override IMemberReference Member => analyzedField;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using Mono.Cecil;
|
||||
using System.Reflection;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -28,7 +29,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public AnalyzedMethodTreeNode(MethodDefinition analyzedMethod, string prefix = "")
|
||||
{
|
||||
if (analyzedMethod == null)
|
||||
if (analyzedMethod.IsNil)
|
||||
throw new ArgumentNullException(nameof(analyzedMethod));
|
||||
this.analyzedMethod = analyzedMethod;
|
||||
this.prefix = prefix;
|
||||
@@ -53,7 +54,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
if (analyzedMethod.HasBody)
|
||||
this.Children.Add(new AnalyzedMethodUsesTreeNode(analyzedMethod));
|
||||
|
||||
if (analyzedMethod.IsVirtual && !(analyzedMethod.IsNewSlot && analyzedMethod.IsFinal))
|
||||
if (analyzedMethod.HasFlag(MethodAttributes.Virtual) && !(analyzedMethod.HasFlag(MethodAttributes.NewSlot) && analyzedMethod.HasFlag(MethodAttributes.Final)))
|
||||
this.Children.Add(new AnalyzedVirtualMethodUsedByTreeNode(analyzedMethod));
|
||||
else
|
||||
this.Children.Add(new AnalyzedMethodUsedByTreeNode(analyzedMethod));
|
||||
@@ -65,8 +66,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
this.Children.Add(new AnalyzedInterfaceMethodImplementedByTreeNode(analyzedMethod));
|
||||
}
|
||||
|
||||
public override MemberReference Member {
|
||||
get { return analyzedMethod; }
|
||||
}
|
||||
public override IMemberReference Member => analyzedMethod;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
foreach (Instruction instr in method.Body.Instructions) {
|
||||
MethodReference mr = instr.Operand as MethodReference;
|
||||
if (mr != null && mr.Name == name &&
|
||||
Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) &&
|
||||
Helpers.IsSameType(analyzedMethod.DeclaringType, mr.DeclaringType) &&
|
||||
mr.Resolve() == analyzedMethod) {
|
||||
found = true;
|
||||
break;
|
||||
|
||||
@@ -20,8 +20,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using ICSharpCode.Decompiler.Disassembler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.Decompiler.IL;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -34,7 +35,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public AnalyzedMethodUsesTreeNode(MethodDefinition analyzedMethod)
|
||||
{
|
||||
if (analyzedMethod == null)
|
||||
if (analyzedMethod.IsNil)
|
||||
throw new ArgumentNullException(nameof(analyzedMethod));
|
||||
|
||||
this.analyzedMethod = analyzedMethod;
|
||||
@@ -61,24 +62,42 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
private IEnumerable<MethodDefinition> GetUsedMethods()
|
||||
{
|
||||
foreach (Instruction instr in analyzedMethod.Body.Instructions) {
|
||||
MethodReference mr = instr.Operand as MethodReference;
|
||||
if (mr != null) {
|
||||
MethodDefinition def = mr.Resolve();
|
||||
if (def != null)
|
||||
yield return def;
|
||||
if (!analyzedMethod.HasBody) yield break;
|
||||
var blob = analyzedMethod.Body.GetILReader();
|
||||
while (blob.RemainingBytes > 0) {
|
||||
var opCode = ILParser.DecodeOpCode(ref blob);
|
||||
switch (opCode.GetOperandType()) {
|
||||
case OperandType.Method:
|
||||
case OperandType.Sig:
|
||||
case OperandType.Tok:
|
||||
var member = ILParser.DecodeMemberToken(ref blob, analyzedMethod.Module).GetDefinition();
|
||||
if (member is MethodDefinition md)
|
||||
yield return md;
|
||||
break;
|
||||
default:
|
||||
ILParser.SkipOperand(ref blob, opCode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<FieldDefinition> GetUsedFields()
|
||||
IEnumerable<FieldDefinition> GetUsedFields()
|
||||
{
|
||||
foreach (Instruction instr in analyzedMethod.Body.Instructions) {
|
||||
FieldReference fr = instr.Operand as FieldReference;
|
||||
if (fr != null) {
|
||||
FieldDefinition def = fr.Resolve();
|
||||
if (def != null)
|
||||
yield return def;
|
||||
if (!analyzedMethod.HasBody) yield break;
|
||||
var blob = analyzedMethod.Body.GetILReader();
|
||||
while (blob.RemainingBytes > 0) {
|
||||
var opCode = ILParser.DecodeOpCode(ref blob);
|
||||
switch (opCode.GetOperandType()) {
|
||||
case OperandType.Field:
|
||||
case OperandType.Sig:
|
||||
case OperandType.Tok:
|
||||
var member = ILParser.DecodeMemberToken(ref blob, analyzedMethod.Module).GetDefinition();
|
||||
if (member is FieldDefinition fd)
|
||||
yield return fd;
|
||||
break;
|
||||
default:
|
||||
ILParser.SkipOperand(ref blob, opCode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
|
||||
@@ -19,9 +19,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Disassembler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -50,11 +51,11 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
private IEnumerable<AnalyzerTreeNode> FindReferencesInType(TypeDefinition type)
|
||||
{
|
||||
if (!TypesHierarchyHelpers.IsBaseType(analyzedProperty.DeclaringType, type, resolveTypeArguments: false))
|
||||
if (!analyzedProperty.DeclaringType.IsBaseTypeOf(type))
|
||||
yield break;
|
||||
|
||||
foreach (PropertyDefinition property in type.Properties) {
|
||||
|
||||
analyzedProperty.
|
||||
if (TypesHierarchyHelpers.IsBaseProperty(analyzedProperty, property)) {
|
||||
MethodDefinition anyAccessor = property.GetMethod ?? property.SetMethod;
|
||||
bool hidesParent = !anyAccessor.IsVirtual ^ anyAccessor.IsNewSlot;
|
||||
@@ -67,8 +68,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public static bool CanShow(PropertyDefinition property)
|
||||
{
|
||||
var accessor = property.GetMethod ?? property.SetMethod;
|
||||
return accessor.IsVirtual && !accessor.IsFinal && !accessor.DeclaringType.IsInterface;
|
||||
var accessor = property.GetAccessors().First().Method;
|
||||
return accessor.HasFlag(MethodAttributes.Virtual) && !accessor.HasFlag(MethodAttributes.Final) && !accessor.DeclaringType.IsInterface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
using System;
|
||||
using ICSharpCode.Decompiler;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -32,7 +32,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
if (analyzedProperty == null)
|
||||
throw new ArgumentNullException(nameof(analyzedProperty));
|
||||
this.isIndexer = analyzedProperty.IsIndexer();
|
||||
this.isIndexer = analyzedProperty.IsIndexer;
|
||||
this.analyzedProperty = analyzedProperty;
|
||||
this.prefix = prefix;
|
||||
this.LazyLoading = true;
|
||||
@@ -54,9 +54,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
protected override void LoadChildren()
|
||||
{
|
||||
if (analyzedProperty.GetMethod != null)
|
||||
if (!analyzedProperty.GetMethod.IsNil)
|
||||
this.Children.Add(new AnalyzedPropertyAccessorTreeNode(analyzedProperty.GetMethod, "get"));
|
||||
if (analyzedProperty.SetMethod != null)
|
||||
if (!analyzedProperty.SetMethod.IsNil)
|
||||
this.Children.Add(new AnalyzedPropertyAccessorTreeNode(analyzedProperty.SetMethod, "set"));
|
||||
foreach (var accessor in analyzedProperty.OtherMethods)
|
||||
this.Children.Add(new AnalyzedPropertyAccessorTreeNode(accessor, null));
|
||||
@@ -67,26 +67,23 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
this.Children.Add(new AnalyzedInterfacePropertyImplementedByTreeNode(analyzedProperty));
|
||||
}
|
||||
|
||||
public static AnalyzerTreeNode TryCreateAnalyzer(MemberReference member)
|
||||
public static AnalyzerTreeNode TryCreateAnalyzer(IMemberReference member)
|
||||
{
|
||||
if (CanShow(member))
|
||||
return new AnalyzedPropertyTreeNode(member as PropertyDefinition);
|
||||
return new AnalyzedPropertyTreeNode((PropertyDefinition)member);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool CanShow(MemberReference member)
|
||||
public static bool CanShow(IMemberReference member)
|
||||
{
|
||||
var property = member as PropertyDefinition;
|
||||
if (property == null)
|
||||
if (!(member is PropertyDefinition property))
|
||||
return false;
|
||||
|
||||
return !MainWindow.Instance.CurrentLanguage.ShowMember(property.GetMethod ?? property.SetMethod)
|
||||
return !MainWindow.Instance.CurrentLanguage.ShowMember(property.GetMethod.IsNil ? property.SetMethod : property.GetMethod)
|
||||
|| AnalyzedPropertyOverridesTreeNode.CanShow(property);
|
||||
}
|
||||
|
||||
public override MemberReference Member {
|
||||
get { return analyzedProperty; }
|
||||
}
|
||||
|
||||
public override IMemberReference Member => analyzedProperty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -30,7 +31,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public AnalyzedTypeExposedByTreeNode(TypeDefinition analyzedType)
|
||||
{
|
||||
if (analyzedType == null)
|
||||
if (analyzedType.IsNil)
|
||||
throw new ArgumentNullException(nameof(analyzedType));
|
||||
|
||||
this.analyzedType = analyzedType;
|
||||
@@ -135,7 +136,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
// exclude methods with 'semantics'. for example, property getters & setters.
|
||||
// HACK: this is a potentially fragile implementation, as the MethodSemantics may be extended to other uses at a later date.
|
||||
if (method.SemanticsAttributes != MethodSemanticsAttributes.None)
|
||||
if (method.GetMethodSemanticsAttributes() != 0)
|
||||
return false;
|
||||
|
||||
if (method.ReturnType.Resolve() == analyzedType)
|
||||
@@ -153,8 +154,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
private static bool IsPrivate(PropertyDefinition property)
|
||||
{
|
||||
bool isGetterPublic = (property.GetMethod != null && !property.GetMethod.IsPrivate);
|
||||
bool isSetterPublic = (property.SetMethod != null && !property.SetMethod.IsPrivate);
|
||||
bool isGetterPublic = (!property.GetMethod.IsNil && !property.GetMethod.IsPrivate);
|
||||
bool isSetterPublic = (!property.SetMethod.IsNil && !property.SetMethod.IsPrivate);
|
||||
return !(isGetterPublic || isSetterPublic);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using ICSharpCode.Decompiler.TypeSystem;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using ICSharpCode.Decompiler.Disassembler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.Decompiler.IL;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -33,12 +34,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public AnalyzedTypeInstantiationsTreeNode(TypeDefinition analyzedType)
|
||||
{
|
||||
if (analyzedType == null)
|
||||
if (analyzedType.IsNil)
|
||||
throw new ArgumentNullException(nameof(analyzedType));
|
||||
|
||||
this.analyzedType = analyzedType;
|
||||
|
||||
this.isSystemObject = (analyzedType.FullName == "System.Object");
|
||||
this.isSystemObject = (analyzedType.FullName.ToString() == "System.Object");
|
||||
}
|
||||
|
||||
public override object Text
|
||||
@@ -61,22 +62,30 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
// ignore chained constructors
|
||||
// (since object is the root of everything, we can short circuit the test in this case)
|
||||
if (method.Name == ".ctor" &&
|
||||
(isSystemObject || analyzedType == type || TypesHierarchyHelpers.IsBaseType(analyzedType, type, false)))
|
||||
if (method.IsConstructor && (isSystemObject || analyzedType == type || analyzedType.IsBaseTypeOf(type)))
|
||||
continue;
|
||||
|
||||
foreach (Instruction instr in method.Body.Instructions) {
|
||||
MethodReference mr = instr.Operand as MethodReference;
|
||||
if (mr != null && mr.Name == ".ctor") {
|
||||
if (Helpers.IsReferencedBy(analyzedType, mr.DeclaringType)) {
|
||||
found = true;
|
||||
var blob = method.Body.GetILReader();
|
||||
|
||||
while (!found && blob.RemainingBytes > 0) {
|
||||
var opCode = ILParser.DecodeOpCode(ref blob);
|
||||
switch (opCode.GetOperandType()) {
|
||||
case OperandType.Method:
|
||||
case OperandType.Sig:
|
||||
case OperandType.Tok:
|
||||
var member = ILParser.DecodeMemberToken(ref blob, method.Module);
|
||||
if (member.Name == ".ctor") {
|
||||
if (member.DeclaringType.FullName == analyzedType.FullName) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ILParser.SkipOperand(ref blob, opCode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
method.Body = null;
|
||||
|
||||
if (found) {
|
||||
var node = new AnalyzedMethodTreeNode(method);
|
||||
node.Language = this.Language;
|
||||
@@ -87,7 +96,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public static bool CanShow(TypeDefinition type)
|
||||
{
|
||||
return (type.IsClass && !(type.IsAbstract && type.IsSealed) && !type.IsEnum);
|
||||
return (type.IsClass && !(type.HasFlag(TypeAttributes.Abstract) && type.HasFlag(TypeAttributes.Sealed)) && !type.IsEnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -27,7 +27,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public AnalyzedTypeTreeNode(TypeDefinition analyzedType)
|
||||
{
|
||||
if (analyzedType == null)
|
||||
if (analyzedType.IsNil)
|
||||
throw new ArgumentNullException(nameof(analyzedType));
|
||||
this.analyzedType = analyzedType;
|
||||
this.LazyLoading = true;
|
||||
@@ -64,8 +64,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
this.Children.Add(new AnalyzedTypeExtensionMethodsTreeNode(analyzedType));
|
||||
}
|
||||
|
||||
public override MemberReference Member {
|
||||
get { return analyzedType; }
|
||||
}
|
||||
public override IMemberReference Member => analyzedType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Disassembler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -30,7 +32,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
public AnalyzedTypeUsedByTreeNode(TypeDefinition analyzedType)
|
||||
{
|
||||
if (analyzedType == null)
|
||||
if (analyzedType.IsNil)
|
||||
throw new ArgumentNullException(nameof(analyzedType));
|
||||
|
||||
this.analyzedType = analyzedType;
|
||||
@@ -46,7 +48,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
var analyzer = new ScopedWhereUsedAnalyzer<AnalyzerTreeNode>(analyzedType, FindTypeUsage);
|
||||
return analyzer.PerformAnalysis(ct)
|
||||
.Cast<AnalyzerEntityTreeNode>()
|
||||
.Where(n => n.Member.DeclaringType != analyzedType)
|
||||
.Where(n => n.Member.DeclaringType.FullName != analyzedType.FullName)
|
||||
.Distinct(new AnalyzerEntityTreeNodeComparer())
|
||||
.OrderBy(n => n.Text);
|
||||
}
|
||||
@@ -59,7 +61,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
if (IsUsedInTypeDefinition(type))
|
||||
yield return new AnalyzedTypeTreeNode(type) { Language = Language };
|
||||
|
||||
foreach (var field in type.Fields.Where(IsUsedInFieldReference))
|
||||
foreach (var field in type.Fields.Where(IsUsedInField))
|
||||
yield return new AnalyzedFieldTreeNode(field) { Language = Language };
|
||||
|
||||
foreach (var method in type.Methods.Where(IsUsedInMethodDefinition))
|
||||
@@ -80,7 +82,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
return types.Any(IsUsedInTypeReference);
|
||||
}
|
||||
|
||||
private bool IsUsedInTypeReference(TypeReference type)
|
||||
private bool IsUsedInTypeReference(ITypeReference type)
|
||||
{
|
||||
if (type == null)
|
||||
return false;
|
||||
@@ -96,16 +98,14 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|| IsUsedInTypeReferences(type.Interfaces.Select(i => i.InterfaceType));
|
||||
}
|
||||
|
||||
private bool IsUsedInFieldReference(FieldReference field)
|
||||
private bool IsUsedInField(FieldDefinition field)
|
||||
{
|
||||
if (field == null)
|
||||
return false;
|
||||
if (field.IsNil) return false;
|
||||
|
||||
return TypeMatches(field.DeclaringType)
|
||||
|| TypeMatches(field.FieldType);
|
||||
return TypeMatches(field.DeclaringType) || field.DecodeSignature(new TypeUsedInSignature(analyzedType), default(Unit));
|
||||
}
|
||||
|
||||
private bool IsUsedInMethodReference(MethodReference method)
|
||||
private bool IsUsedInMethod(MethodDefinition method)
|
||||
{
|
||||
if (method == null)
|
||||
return false;
|
||||
@@ -161,10 +161,10 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
return TypeMatches(parameter.ParameterType);
|
||||
}
|
||||
|
||||
private bool TypeMatches(TypeReference tref)
|
||||
private bool TypeMatches(ITypeReference tref)
|
||||
{
|
||||
if (tref != null && tref.Name == analyzedType.Name) {
|
||||
var tdef = tref.Resolve();
|
||||
var tdef = tref.GetDefinition();
|
||||
if (tdef != null) {
|
||||
return (tdef == analyzedType);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
if (mr != null && mr.Name == name) {
|
||||
// explicit call to the requested method
|
||||
if (instr.OpCode.Code == Code.Call
|
||||
&& Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType)
|
||||
&& Helpers.IsSameType(analyzedMethod.DeclaringType, mr.DeclaringType)
|
||||
&& mr.Resolve() == analyzedMethod) {
|
||||
found = true;
|
||||
prefix = "(as base) ";
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.TreeView;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -27,7 +27,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
/// </summary>
|
||||
public abstract class AnalyzerEntityTreeNode : AnalyzerTreeNode, IMemberTreeNode
|
||||
{
|
||||
public abstract MemberReference Member { get; }
|
||||
public abstract IMemberReference Member { get; }
|
||||
|
||||
public override void ActivateItem(System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
@@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
public override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies)
|
||||
{
|
||||
foreach (LoadedAssembly asm in removedAssemblies) {
|
||||
if (this.Member.Module == asm.GetModuleDefinitionOrNull())
|
||||
if (this.Member.Module == asm.GetPEFileOrNull())
|
||||
return false; // remove this node
|
||||
}
|
||||
this.Children.RemoveAll(
|
||||
|
||||
@@ -16,8 +16,12 @@
|
||||
// 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.Reflection.Metadata;
|
||||
using System.Threading;
|
||||
using ICSharpCode.Decompiler.Disassembler;
|
||||
using Dom = ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
internal static class Helpers
|
||||
{
|
||||
public static bool IsReferencedBy(TypeDefinition type, TypeReference typeRef)
|
||||
public static bool IsSameType(TypeDefinition type, TypeReference typeRef)
|
||||
{
|
||||
// TODO: move it to a better place after adding support for more cases.
|
||||
if (type == null)
|
||||
@@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
if (type.DeclaringType != null || typeRef.DeclaringType != null) {
|
||||
if (type.DeclaringType == null || typeRef.DeclaringType == null)
|
||||
return false;
|
||||
if (!IsReferencedBy(type.DeclaringType, typeRef.DeclaringType))
|
||||
if (!IsSameType(type.DeclaringType, typeRef.DeclaringType))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
foreach (Instruction instr in method.Body.Instructions) {
|
||||
MethodReference mr = instr.Operand as MethodReference;
|
||||
if (mr != null && mr.Name == name &&
|
||||
IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) &&
|
||||
IsSameType(analyzedMethod.DeclaringType, mr.DeclaringType) &&
|
||||
mr.Resolve() == analyzedMethod) {
|
||||
found = true;
|
||||
break;
|
||||
|
||||
@@ -19,9 +19,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using ICSharpCode.Decompiler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.Decompiler.TypeSystem.Implementation;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
{
|
||||
@@ -30,8 +33,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
/// </summary>
|
||||
internal class ScopedWhereUsedAnalyzer<T>
|
||||
{
|
||||
private readonly AssemblyDefinition assemblyScope;
|
||||
private readonly PEFile assemblyScope;
|
||||
private TypeDefinition typeScope;
|
||||
private static readonly TypeSystemAttributeTypeProvider typeProvider = TypeSystemAttributeTypeProvider.CreateDefault();
|
||||
|
||||
private readonly Accessibility memberAccessibility = Accessibility.Public;
|
||||
private Accessibility typeAccessibility = Accessibility.Public;
|
||||
@@ -40,7 +44,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
public ScopedWhereUsedAnalyzer(TypeDefinition type, Func<TypeDefinition, IEnumerable<T>> typeAnalysisFunction)
|
||||
{
|
||||
this.typeScope = type;
|
||||
this.assemblyScope = type.Module.Assembly;
|
||||
this.assemblyScope = type.Module;
|
||||
this.typeAnalysisFunction = typeAnalysisFunction;
|
||||
}
|
||||
|
||||
@@ -53,8 +57,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
public ScopedWhereUsedAnalyzer(PropertyDefinition property, Func<TypeDefinition, IEnumerable<T>> typeAnalysisFunction)
|
||||
: this(property.DeclaringType, typeAnalysisFunction)
|
||||
{
|
||||
Accessibility getterAccessibility = (property.GetMethod == null) ? Accessibility.Private : GetMethodAccessibility(property.GetMethod);
|
||||
Accessibility setterAccessibility = (property.SetMethod == null) ? Accessibility.Private : GetMethodAccessibility(property.SetMethod);
|
||||
Accessibility getterAccessibility = (property.GetMethod.IsNil) ? Accessibility.Private : GetMethodAccessibility(property.GetMethod);
|
||||
Accessibility setterAccessibility = (property.SetMethod.IsNil) ? Accessibility.Private : GetMethodAccessibility(property.SetMethod);
|
||||
this.memberAccessibility = (Accessibility)Math.Max((int)getterAccessibility, (int)setterAccessibility);
|
||||
}
|
||||
|
||||
@@ -142,7 +146,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
|
||||
private void DetermineTypeAccessibility()
|
||||
{
|
||||
while (typeScope.IsNested) {
|
||||
while (!typeScope.DeclaringType.IsNil) {
|
||||
Accessibility accessibility = GetNestedTypeAccessibility(typeScope);
|
||||
if ((int)typeAccessibility > (int)accessibility) {
|
||||
typeAccessibility = accessibility;
|
||||
@@ -215,9 +219,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
return assemblies.AsParallel().WithCancellation(ct).SelectMany(asm => FindReferencesInAssembly(asm, ct));
|
||||
}
|
||||
|
||||
private IEnumerable<T> FindReferencesInAssembly(AssemblyDefinition asm, CancellationToken ct)
|
||||
private IEnumerable<T> FindReferencesInAssembly(PEFile asm, CancellationToken ct)
|
||||
{
|
||||
foreach (TypeDefinition type in TreeTraversal.PreOrder(asm.MainModule.Types, t => t.NestedTypes)) {
|
||||
foreach (TypeDefinition type in TreeTraversal.PreOrder(asm.TypeDefinitions, t => t.NestedTypes)) {
|
||||
ct.ThrowIfCancellationRequested();
|
||||
foreach (var result in typeAnalysisFunction(type)) {
|
||||
ct.ThrowIfCancellationRequested();
|
||||
@@ -248,67 +252,66 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<AssemblyDefinition> GetReferencingAssemblies(AssemblyDefinition asm, CancellationToken ct)
|
||||
private IEnumerable<PEFile> GetReferencingAssemblies(PEFile asm, CancellationToken ct)
|
||||
{
|
||||
yield return asm;
|
||||
|
||||
string requiredAssemblyFullName = asm.FullName;
|
||||
|
||||
IEnumerable<LoadedAssembly> assemblies = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().Where(assy => assy.GetAssemblyDefinitionOrNull() != null);
|
||||
IEnumerable<LoadedAssembly> assemblies = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().Where(assy => assy.GetPEFileOrNull()?.IsAssembly == true);
|
||||
|
||||
foreach (var assembly in assemblies) {
|
||||
ct.ThrowIfCancellationRequested();
|
||||
bool found = false;
|
||||
var module = assembly.GetModuleDefinitionOrNull();
|
||||
var module = assembly.GetPEFileOrNull();
|
||||
if (module == null)
|
||||
continue;
|
||||
var metadata = module.GetMetadataReader();
|
||||
foreach (var reference in module.AssemblyReferences) {
|
||||
if (requiredAssemblyFullName == reference.FullName) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found && AssemblyReferencesScopeType(module.Assembly))
|
||||
yield return module.Assembly;
|
||||
if (found && AssemblyReferencesScopeType(module))
|
||||
yield return module;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<AssemblyDefinition> GetAssemblyAndAnyFriends(AssemblyDefinition asm, CancellationToken ct)
|
||||
private IEnumerable<PEFile> GetAssemblyAndAnyFriends(PEFile asm, CancellationToken ct)
|
||||
{
|
||||
yield return asm;
|
||||
var reader = asm.GetMetadataReader();
|
||||
|
||||
if (asm.HasCustomAttributes) {
|
||||
var attributes = asm.CustomAttributes
|
||||
.Where(attr => attr.AttributeType.FullName == "System.Runtime.CompilerServices.InternalsVisibleToAttribute");
|
||||
var friendAssemblies = new HashSet<string>();
|
||||
foreach (var attribute in attributes) {
|
||||
string assemblyName = attribute.ConstructorArguments[0].Value as string;
|
||||
assemblyName = assemblyName.Split(',')[0]; // strip off any public key info
|
||||
friendAssemblies.Add(assemblyName);
|
||||
}
|
||||
var attributes = reader.CustomAttributes.Select(h => reader.GetCustomAttribute(h)).Where(ca => ca.GetAttributeType(asm).FullName.ToString() == "System.Runtime.CompilerServices.InternalsVisibleToAttribute");
|
||||
var friendAssemblies = new HashSet<string>();
|
||||
foreach (var attribute in attributes) {
|
||||
string assemblyName = attribute.DecodeValue(typeProvider).FixedArguments[0].Value as string;
|
||||
assemblyName = assemblyName.Split(',')[0]; // strip off any public key info
|
||||
friendAssemblies.Add(assemblyName);
|
||||
}
|
||||
|
||||
if (friendAssemblies.Count > 0) {
|
||||
IEnumerable<LoadedAssembly> assemblies = MainWindow.Instance.CurrentAssemblyList.GetAssemblies();
|
||||
if (friendAssemblies.Count > 0) {
|
||||
IEnumerable<LoadedAssembly> assemblies = MainWindow.Instance.CurrentAssemblyList.GetAssemblies();
|
||||
|
||||
foreach (var assembly in assemblies) {
|
||||
ct.ThrowIfCancellationRequested();
|
||||
if (friendAssemblies.Contains(assembly.ShortName)) {
|
||||
var module = assembly.GetModuleDefinitionOrNull();
|
||||
if (module == null)
|
||||
continue;
|
||||
if (AssemblyReferencesScopeType(module.Assembly))
|
||||
yield return module.Assembly;
|
||||
}
|
||||
foreach (var assembly in assemblies) {
|
||||
ct.ThrowIfCancellationRequested();
|
||||
if (friendAssemblies.Contains(assembly.ShortName)) {
|
||||
var module = assembly.GetPEFileOrNull();
|
||||
if (module == null)
|
||||
continue;
|
||||
if (AssemblyReferencesScopeType(module))
|
||||
yield return module;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool AssemblyReferencesScopeType(AssemblyDefinition asm)
|
||||
private bool AssemblyReferencesScopeType(PEFile asm)
|
||||
{
|
||||
bool hasRef = false;
|
||||
foreach (var typeref in asm.MainModule.GetTypeReferences()) {
|
||||
if (typeref.Name == typeScope.Name && typeref.Namespace == typeScope.Namespace) {
|
||||
foreach (var typeRef in asm.TypeReferences) {
|
||||
if (typeRef.Name == typeScope.Name && typeRef.Namespace == typeScope.Namespace) {
|
||||
hasRef = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -22,10 +22,11 @@ using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Windows;
|
||||
using ICSharpCode.Decompiler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.TreeView;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -153,7 +154,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
}
|
||||
|
||||
#region Find*Node
|
||||
|
||||
/*
|
||||
public ILSpyTreeNode FindResourceNode(Resource resource)
|
||||
{
|
||||
if (resource == null)
|
||||
@@ -177,27 +178,15 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
}
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public AssemblyTreeNode FindAssemblyNode(ModuleDefinition module)
|
||||
public AssemblyTreeNode FindAssemblyNode(PEFile module)
|
||||
{
|
||||
if (module == null)
|
||||
return null;
|
||||
App.Current.Dispatcher.VerifyAccess();
|
||||
foreach (AssemblyTreeNode node in this.Children) {
|
||||
if (node.LoadedAssembly.IsLoaded && node.LoadedAssembly.GetModuleDefinitionOrNull() == module)
|
||||
return node;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public AssemblyTreeNode FindAssemblyNode(AssemblyDefinition asm)
|
||||
{
|
||||
if (asm == null)
|
||||
return null;
|
||||
App.Current.Dispatcher.VerifyAccess();
|
||||
foreach (AssemblyTreeNode node in this.Children) {
|
||||
if (node.LoadedAssembly.IsLoaded && node.LoadedAssembly.GetAssemblyDefinitionOrNull() == asm)
|
||||
if (node.LoadedAssembly.IsLoaded && node.LoadedAssembly.GetPEFileOrNull() == module)
|
||||
return node;
|
||||
}
|
||||
return null;
|
||||
@@ -221,16 +210,14 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
/// </summary>
|
||||
public TypeTreeNode FindTypeNode(TypeDefinition def)
|
||||
{
|
||||
if (def == null)
|
||||
return null;
|
||||
if (def.DeclaringType != null) {
|
||||
if (!def.DeclaringType.IsNil) {
|
||||
TypeTreeNode decl = FindTypeNode(def.DeclaringType);
|
||||
if (decl != null) {
|
||||
decl.EnsureLazyChildren();
|
||||
return decl.Children.OfType<TypeTreeNode>().FirstOrDefault(t => t.TypeDefinition == def && !t.IsHidden);
|
||||
}
|
||||
} else {
|
||||
AssemblyTreeNode asm = FindAssemblyNode(def.Module.Assembly);
|
||||
AssemblyTreeNode asm = FindAssemblyNode(def.Module);
|
||||
if (asm != null) {
|
||||
return asm.FindTypeNode(def);
|
||||
}
|
||||
@@ -244,8 +231,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
/// </summary>
|
||||
public ILSpyTreeNode FindMethodNode(MethodDefinition def)
|
||||
{
|
||||
if (def == null)
|
||||
return null;
|
||||
TypeTreeNode typeNode = FindTypeNode(def.DeclaringType);
|
||||
if (typeNode == null)
|
||||
return null;
|
||||
@@ -281,8 +266,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
/// </summary>
|
||||
public FieldTreeNode FindFieldNode(FieldDefinition def)
|
||||
{
|
||||
if (def == null)
|
||||
return null;
|
||||
TypeTreeNode typeNode = FindTypeNode(def.DeclaringType);
|
||||
if (typeNode == null)
|
||||
return null;
|
||||
@@ -296,8 +279,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
/// </summary>
|
||||
public PropertyTreeNode FindPropertyNode(PropertyDefinition def)
|
||||
{
|
||||
if (def == null)
|
||||
return null;
|
||||
TypeTreeNode typeNode = FindTypeNode(def.DeclaringType);
|
||||
if (typeNode == null)
|
||||
return null;
|
||||
@@ -311,8 +292,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
/// </summary>
|
||||
public EventTreeNode FindEventNode(EventDefinition def)
|
||||
{
|
||||
if (def == null)
|
||||
return null;
|
||||
TypeTreeNode typeNode = FindTypeNode(def.DeclaringType);
|
||||
if (typeNode == null)
|
||||
return null;
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
/// <summary>
|
||||
/// Node within assembly reference list.
|
||||
/// </summary>
|
||||
public sealed class AssemblyReferenceTreeNode : ILSpyTreeNode
|
||||
/*public sealed class AssemblyReferenceTreeNode : ILSpyTreeNode
|
||||
{
|
||||
readonly AssemblyNameReference r;
|
||||
readonly AssemblyTreeNode parentAssembly;
|
||||
@@ -77,7 +77,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
if (assemblyListNode != null) {
|
||||
var refNode = assemblyListNode.FindAssemblyNode(parentAssembly.LoadedAssembly.LookupReferencedAssembly(r));
|
||||
if (refNode != null) {
|
||||
ModuleDefinition module = refNode.LoadedAssembly.GetModuleDefinitionOrNull();
|
||||
ModuleDefinition module = refNode.LoadedAssembly.GetPEFileOrNull();
|
||||
if (module != null) {
|
||||
foreach (var childRef in module.AssemblyReferences)
|
||||
this.Children.Add(new AssemblyReferenceTreeNode(childRef, refNode));
|
||||
@@ -106,5 +106,5 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
output.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -20,15 +20,19 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using ICSharpCode.Decompiler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.ILSpy.TextView;
|
||||
using ICSharpCode.TreeView;
|
||||
using Microsoft.Win32;
|
||||
using Mono.Cecil;
|
||||
|
||||
using SRM = System.Reflection.Metadata;
|
||||
using static System.Reflection.Metadata.PEReaderExtensions;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -97,18 +101,19 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
|
||||
if (tooltip == null && assembly.IsLoaded) {
|
||||
tooltip = new TextBlock();
|
||||
var module = assembly.GetModuleDefinitionOrNull();
|
||||
if (module.Assembly != null) {
|
||||
var module = assembly.GetPEFileOrNull();
|
||||
var metadata = module?.GetMetadataReader();
|
||||
if (metadata?.IsAssembly == true) {
|
||||
tooltip.Inlines.Add(new Bold(new Run("Name: ")));
|
||||
tooltip.Inlines.Add(new Run(module.Assembly.FullName));
|
||||
tooltip.Inlines.Add(new Run(metadata.GetFullAssemblyName()));
|
||||
tooltip.Inlines.Add(new LineBreak());
|
||||
}
|
||||
tooltip.Inlines.Add(new Bold(new Run("Location: ")));
|
||||
tooltip.Inlines.Add(new Run(assembly.FileName));
|
||||
tooltip.Inlines.Add(new LineBreak());
|
||||
tooltip.Inlines.Add(new Bold(new Run("Architecture: ")));
|
||||
tooltip.Inlines.Add(new Run(CSharpLanguage.GetPlatformDisplayName(module)));
|
||||
string runtimeName = CSharpLanguage.GetRuntimeDisplayName(module);
|
||||
tooltip.Inlines.Add(new Run(Language.GetPlatformDisplayName(module)));
|
||||
string runtimeName = Language.GetRuntimeDisplayName(module);
|
||||
if (runtimeName != null) {
|
||||
tooltip.Inlines.Add(new LineBreak());
|
||||
tooltip.Inlines.Add(new Bold(new Run("Runtime: ")));
|
||||
@@ -125,7 +130,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
get { return !assembly.HasLoadError; }
|
||||
}
|
||||
|
||||
void OnAssemblyLoaded(Task<ModuleDefinition> moduleTask)
|
||||
void OnAssemblyLoaded(Task<PEFile> moduleTask)
|
||||
{
|
||||
// change from "Loading" icon to final icon
|
||||
RaisePropertyChanged("Icon");
|
||||
@@ -145,19 +150,20 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
|
||||
protected override void LoadChildren()
|
||||
{
|
||||
ModuleDefinition moduleDefinition = assembly.GetModuleDefinitionOrNull();
|
||||
if (moduleDefinition == null) {
|
||||
var module = assembly.GetPEFileOrNull();
|
||||
if (module == null) {
|
||||
// if we crashed on loading, then we don't have any children
|
||||
return;
|
||||
}
|
||||
var metadata = module.GetMetadataReader();
|
||||
|
||||
this.Children.Add(new ReferenceFolderTreeNode(moduleDefinition, this));
|
||||
if (moduleDefinition.HasResources)
|
||||
this.Children.Add(new ResourceListTreeNode(moduleDefinition));
|
||||
this.Children.Add(new ReferenceFolderTreeNode(metadata, this));
|
||||
if (module.Resources.Any())
|
||||
this.Children.Add(new ResourceListTreeNode(module));
|
||||
foreach (NamespaceTreeNode ns in namespaces.Values) {
|
||||
ns.Children.Clear();
|
||||
}
|
||||
foreach (TypeDefinition type in moduleDefinition.Types.OrderBy(t => t.FullName, NaturalStringComparer.Instance)) {
|
||||
foreach (TypeDefinition type in metadata.GetTopLevelTypeDefinitions().Select(td => new TypeDefinition(module, td)).OrderBy(t => t.FullName.ToString(), NaturalStringComparer.Instance)) {
|
||||
NamespaceTreeNode ns;
|
||||
if (!namespaces.TryGetValue(type.Namespace, out ns)) {
|
||||
ns = new NamespaceTreeNode(type.Namespace);
|
||||
@@ -172,10 +178,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
this.Children.Add(ns);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanExpandRecursively {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanExpandRecursively => true;
|
||||
|
||||
/// <summary>
|
||||
/// Finds the node for a top-level type.
|
||||
@@ -396,10 +400,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
return;
|
||||
foreach (var node in context.SelectedTreeNodes) {
|
||||
var la = ((AssemblyTreeNode)node).LoadedAssembly;
|
||||
var module = la.GetModuleDefinitionOrNull();
|
||||
var module = la.GetPEFileOrNull();
|
||||
if (module != null) {
|
||||
foreach (var assyRef in module.AssemblyReferences) {
|
||||
la.LookupReferencedAssembly(assyRef);
|
||||
var metadata = module.GetMetadataReader();
|
||||
foreach (var assyRef in metadata.AssemblyReferences) {
|
||||
la.LookupReferencedAssembly(new AssemblyReference(module, assyRef));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,35 +19,33 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using ICSharpCode.Decompiler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.TreeView;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
sealed class BaseTypesEntryNode : ILSpyTreeNode, IMemberTreeNode
|
||||
{
|
||||
private readonly TypeReference tr;
|
||||
private readonly ITypeReference tr;
|
||||
private TypeDefinition def;
|
||||
private readonly bool isInterface;
|
||||
|
||||
public BaseTypesEntryNode(TypeReference tr, bool isInterface)
|
||||
public BaseTypesEntryNode(ITypeReference tr, bool isInterface)
|
||||
{
|
||||
if (tr == null)
|
||||
throw new ArgumentNullException(nameof(tr));
|
||||
this.tr = tr;
|
||||
this.def = tr.Resolve();
|
||||
this.tr = tr ?? throw new ArgumentNullException(nameof(tr));
|
||||
this.def = tr.GetDefinition();
|
||||
this.isInterface = isInterface;
|
||||
this.LazyLoading = true;
|
||||
}
|
||||
|
||||
public override bool ShowExpander
|
||||
{
|
||||
get { return def != null && (def.BaseType != null || def.HasInterfaces); }
|
||||
get { return !def.IsNil && (def.BaseType != null || def.HasInterfaces); }
|
||||
}
|
||||
|
||||
public override object Text
|
||||
{
|
||||
get { return this.Language.TypeToString(tr, true) + tr.MetadataToken.ToSuffixString(); }
|
||||
get { return def.FullName + def.Handle.ToSuffixString(); }
|
||||
}
|
||||
|
||||
public override object Icon
|
||||
@@ -71,7 +69,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
// on item activation, try to resolve once again (maybe the user loaded the assembly in the meantime)
|
||||
if (def == null) {
|
||||
def = tr.Resolve();
|
||||
def = tr.GetDefinition();
|
||||
if (def != null)
|
||||
this.LazyLoading = true;
|
||||
// re-load children
|
||||
@@ -96,9 +94,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
language.WriteCommentLine(output, language.TypeToString(tr, true));
|
||||
}
|
||||
|
||||
MemberReference IMemberTreeNode.Member
|
||||
{
|
||||
get { return tr; }
|
||||
}
|
||||
IMemberReference IMemberTreeNode.Member => tr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
using System;
|
||||
using System.Windows.Threading;
|
||||
using ICSharpCode.Decompiler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.TreeView;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -37,15 +37,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
this.LazyLoading = true;
|
||||
}
|
||||
|
||||
public override object Text
|
||||
{
|
||||
get { return "Base Types"; }
|
||||
}
|
||||
public override object Text => "Base Types";
|
||||
|
||||
public override object Icon
|
||||
{
|
||||
get { return Images.SuperTypes; }
|
||||
}
|
||||
public override object Icon => Images.SuperTypes;
|
||||
|
||||
protected override void LoadChildren()
|
||||
{
|
||||
@@ -57,7 +51,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
if (type.BaseType != null)
|
||||
children.Add(new BaseTypesEntryNode(type.BaseType, false));
|
||||
foreach (var i in type.Interfaces) {
|
||||
children.Add(new BaseTypesEntryNode(i.InterfaceType, true));
|
||||
children.Add(new BaseTypesEntryNode(i, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
|
||||
public void Execute(TextViewContext context)
|
||||
{
|
||||
var member = GetMemberNodeFromContext(context)?.Member;
|
||||
/*var member = GetMemberNodeFromContext(context)?.Member;
|
||||
if (member == null) return;
|
||||
Clipboard.SetText(GetFullyQualifiedName(member));
|
||||
Clipboard.SetText(GetFullyQualifiedName(member));*/
|
||||
}
|
||||
|
||||
private IMemberTreeNode GetMemberNodeFromContext(TextViewContext context)
|
||||
|
||||
@@ -17,19 +17,21 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Threading;
|
||||
using ICSharpCode.Decompiler;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
class DerivedTypesEntryNode : ILSpyTreeNode, IMemberTreeNode
|
||||
{
|
||||
private readonly TypeDefinition type;
|
||||
private readonly ModuleDefinition[] assemblies;
|
||||
private readonly PEFile[] assemblies;
|
||||
private readonly ThreadingSupport threading;
|
||||
|
||||
public DerivedTypesEntryNode(TypeDefinition type, ModuleDefinition[] assemblies)
|
||||
public DerivedTypesEntryNode(TypeDefinition type, PEFile[] assemblies)
|
||||
{
|
||||
this.type = type;
|
||||
this.assemblies = assemblies;
|
||||
@@ -39,12 +41,12 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
|
||||
public override bool ShowExpander
|
||||
{
|
||||
get { return !type.IsSealed && base.ShowExpander; }
|
||||
get { return !type.HasFlag(TypeAttributes.Sealed) && base.ShowExpander; }
|
||||
}
|
||||
|
||||
public override object Text
|
||||
{
|
||||
get { return this.Language.TypeToString(type, true) + type.MetadataToken.ToSuffixString(); }
|
||||
get { return type.FullName + type.Handle.ToSuffixString(); }
|
||||
}
|
||||
|
||||
public override object Icon
|
||||
@@ -57,7 +59,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
if (!settings.ShowInternalApi && !IsPublicAPI)
|
||||
return FilterResult.Hidden;
|
||||
if (settings.SearchTermMatches(type.Name)) {
|
||||
if (type.IsNested && !settings.Language.ShowMember(type))
|
||||
if (!type.DeclaringType.IsNil && !settings.Language.ShowMember(type))
|
||||
return FilterResult.Hidden;
|
||||
else
|
||||
return FilterResult.Match;
|
||||
@@ -100,6 +102,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
language.WriteCommentLine(output, language.TypeToString(type, true));
|
||||
}
|
||||
|
||||
MemberReference IMemberTreeNode.Member => type;
|
||||
IMemberReference IMemberTreeNode.Member => type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,13 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Threading;
|
||||
using ICSharpCode.Decompiler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.Decompiler.Util;
|
||||
using Mono.Cecil;
|
||||
|
||||
using static System.Reflection.Metadata.PEReaderExtensions;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -60,18 +63,20 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
IEnumerable<ILSpyTreeNode> FetchChildren(CancellationToken cancellationToken)
|
||||
{
|
||||
// FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread
|
||||
var assemblies = list.GetAssemblies().Select(node => node.GetModuleDefinitionOrNull()).Where(asm => asm != null).ToArray();
|
||||
var assemblies = list.GetAssemblies().Select(node => node.GetPEFileOrNull()).Where(asm => asm != null).ToArray();
|
||||
return FindDerivedTypes(type, assemblies, cancellationToken);
|
||||
}
|
||||
|
||||
internal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(TypeDefinition type, ModuleDefinition[] assemblies, CancellationToken cancellationToken)
|
||||
internal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(TypeDefinition type, PEFile[] assemblies, CancellationToken cancellationToken)
|
||||
{
|
||||
foreach (ModuleDefinition module in assemblies) {
|
||||
foreach (TypeDefinition td in TreeTraversal.PreOrder(module.Types, t => t.NestedTypes)) {
|
||||
foreach (var module in assemblies) {
|
||||
var reader = module.GetMetadataReader();
|
||||
foreach (var h in TreeTraversal.PreOrder(reader.GetTopLevelTypeDefinitions(), t => reader.GetTypeDefinition(t).GetNestedTypes())) {
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var td = new TypeDefinition(module, h);
|
||||
if (type.IsInterface && td.HasInterfaces) {
|
||||
foreach (var iface in td.Interfaces) {
|
||||
if (IsSameType(iface.InterfaceType, type))
|
||||
if (IsSameType(iface, type))
|
||||
yield return new DerivedTypesEntryNode(td, assemblies);
|
||||
}
|
||||
} else if (!type.IsInterface && td.BaseType != null && IsSameType(td.BaseType, type)) {
|
||||
@@ -79,22 +84,13 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
}
|
||||
}
|
||||
}
|
||||
yield break;
|
||||
}
|
||||
|
||||
static bool IsSameType(TypeReference typeRef, TypeDefinition type)
|
||||
|
||||
static bool IsSameType(ITypeReference typeRef, TypeDefinition type)
|
||||
{
|
||||
if (typeRef.FullName == type.FullName)
|
||||
return true;
|
||||
if (typeRef.Name != type.Name || type.Namespace != typeRef.Namespace)
|
||||
return false;
|
||||
if (typeRef.IsNested || type.IsNested)
|
||||
if (!typeRef.IsNested || !type.IsNested || !IsSameType(typeRef.DeclaringType, type.DeclaringType))
|
||||
return false;
|
||||
var gTypeRef = typeRef as GenericInstanceType;
|
||||
if (gTypeRef != null || type.HasGenericParameters)
|
||||
if (gTypeRef == null || !type.HasGenericParameters || gTypeRef.GenericArguments.Count != type.GenericParameters.Count)
|
||||
return false;
|
||||
return true;
|
||||
// FullName contains only namespace, name and type parameter count, therefore this should suffice.
|
||||
return typeRef.FullName == type.FullName;
|
||||
}
|
||||
|
||||
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows.Media;
|
||||
using ICSharpCode.Decompiler;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -28,41 +30,39 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
/// </summary>
|
||||
public sealed class EventTreeNode : ILSpyTreeNode, IMemberTreeNode
|
||||
{
|
||||
|
||||
public EventTreeNode(EventDefinition ev)
|
||||
{
|
||||
if (ev == null)
|
||||
if (ev.IsNil)
|
||||
throw new ArgumentNullException(nameof(ev));
|
||||
this.EventDefinition = ev;
|
||||
|
||||
if (ev.AddMethod != null)
|
||||
if (!ev.AddMethod.IsNil)
|
||||
this.Children.Add(new MethodTreeNode(ev.AddMethod));
|
||||
if (ev.RemoveMethod != null)
|
||||
if (!ev.RemoveMethod.IsNil)
|
||||
this.Children.Add(new MethodTreeNode(ev.RemoveMethod));
|
||||
if (ev.InvokeMethod != null)
|
||||
if (!ev.InvokeMethod.IsNil)
|
||||
this.Children.Add(new MethodTreeNode(ev.InvokeMethod));
|
||||
if (ev.HasOtherMethods) {
|
||||
foreach (var m in ev.OtherMethods)
|
||||
this.Children.Add(new MethodTreeNode(m));
|
||||
}
|
||||
foreach (var m in ev.OtherMethods)
|
||||
this.Children.Add(new MethodTreeNode(m));
|
||||
}
|
||||
|
||||
public EventDefinition EventDefinition { get; }
|
||||
|
||||
public override object Text => GetText(EventDefinition, this.Language) + EventDefinition.MetadataToken.ToSuffixString();
|
||||
public override object Text => GetText(EventDefinition, this.Language) + EventDefinition.Handle.ToSuffixString();
|
||||
|
||||
public static object GetText(EventDefinition eventDef, Language language)
|
||||
{
|
||||
return HighlightSearchMatch(eventDef.Name, " : " + language.TypeToString(eventDef.EventType, false, eventDef));
|
||||
var eventType = eventDef.DecodeSignature(language.CreateSignatureTypeProvider(false), new GenericContext(eventDef.DeclaringType));
|
||||
return HighlightSearchMatch(eventDef.Name, " : " + eventType);
|
||||
}
|
||||
|
||||
public override object Icon => GetIcon(EventDefinition);
|
||||
|
||||
public static ImageSource GetIcon(EventDefinition eventDef)
|
||||
{
|
||||
MethodDefinition accessor = eventDef.AddMethod ?? eventDef.RemoveMethod;
|
||||
if (accessor != null)
|
||||
return Images.GetIcon(MemberIcon.Event, GetOverlayIcon(eventDef.AddMethod.Attributes), eventDef.AddMethod.IsStatic);
|
||||
MethodDefinition accessor = eventDef.GetAccessors().FirstOrDefault().Method;
|
||||
if (!accessor.IsNil)
|
||||
return Images.GetIcon(MemberIcon.Event, GetOverlayIcon(accessor.Attributes), accessor.HasFlag(MethodAttributes.Static));
|
||||
else
|
||||
return Images.GetIcon(MemberIcon.Event, AccessOverlayIcon.Public, false);
|
||||
}
|
||||
@@ -82,7 +82,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
return AccessOverlayIcon.ProtectedInternal;
|
||||
case MethodAttributes.Private:
|
||||
return AccessOverlayIcon.Private;
|
||||
case MethodAttributes.CompilerControlled:
|
||||
case 0:
|
||||
return AccessOverlayIcon.CompilerControlled;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
@@ -104,14 +104,21 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
language.DecompileEvent(EventDefinition, output, options);
|
||||
}
|
||||
|
||||
|
||||
public override bool IsPublicAPI {
|
||||
get {
|
||||
MethodDefinition accessor = EventDefinition.AddMethod ?? EventDefinition.RemoveMethod;
|
||||
return accessor != null && (accessor.IsPublic || accessor.IsFamilyOrAssembly || accessor.IsFamily);
|
||||
MethodDefinition accessor = EventDefinition.GetAccessors().FirstOrDefault().Method;
|
||||
if (accessor.IsNil) return false;
|
||||
switch (accessor.Attributes & MethodAttributes.MemberAccessMask) {
|
||||
case MethodAttributes.Public:
|
||||
case MethodAttributes.FamORAssem:
|
||||
case MethodAttributes.Family:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MemberReference IMemberTreeNode.Member => EventDefinition;
|
||||
IMemberReference IMemberTreeNode.Member => EventDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Windows.Media;
|
||||
using ICSharpCode.Decompiler;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -37,37 +38,35 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
this.FieldDefinition = field;
|
||||
}
|
||||
|
||||
public override object Text
|
||||
public override object Text => GetText(FieldDefinition, Language) + FieldDefinition.Handle.ToSuffixString();
|
||||
|
||||
public static object GetText(FieldDefinition field, Language language)
|
||||
{
|
||||
get {
|
||||
return HighlightSearchMatch(
|
||||
FieldDefinition.Name,
|
||||
" : " + this.Language.TypeToString(FieldDefinition.FieldType, false, FieldDefinition) + FieldDefinition.MetadataToken.ToSuffixString()
|
||||
);
|
||||
}
|
||||
string fieldType = field.DecodeSignature(language.CreateSignatureTypeProvider(false), new GenericContext(field.DeclaringType));
|
||||
return HighlightSearchMatch(field.Name, " : " + fieldType);
|
||||
}
|
||||
|
||||
public override object Icon => GetIcon(FieldDefinition);
|
||||
|
||||
public static ImageSource GetIcon(FieldDefinition field)
|
||||
{
|
||||
if (field.DeclaringType.IsEnum && !field.Attributes.HasFlag(FieldAttributes.SpecialName))
|
||||
if (field.DeclaringType.IsEnum && !field.HasFlag(FieldAttributes.SpecialName))
|
||||
return Images.GetIcon(MemberIcon.EnumValue, GetOverlayIcon(field.Attributes), false);
|
||||
|
||||
if (field.IsLiteral)
|
||||
if (field.HasFlag(FieldAttributes.Literal))
|
||||
return Images.GetIcon(MemberIcon.Literal, GetOverlayIcon(field.Attributes), false);
|
||||
else if (field.IsInitOnly) {
|
||||
else if (field.HasFlag(FieldAttributes.InitOnly)) {
|
||||
if (IsDecimalConstant(field))
|
||||
return Images.GetIcon(MemberIcon.Literal, GetOverlayIcon(field.Attributes), false);
|
||||
else
|
||||
return Images.GetIcon(MemberIcon.FieldReadOnly, GetOverlayIcon(field.Attributes), field.IsStatic);
|
||||
return Images.GetIcon(MemberIcon.FieldReadOnly, GetOverlayIcon(field.Attributes), field.HasFlag(FieldAttributes.Static));
|
||||
} else
|
||||
return Images.GetIcon(MemberIcon.Field, GetOverlayIcon(field.Attributes), field.IsStatic);
|
||||
return Images.GetIcon(MemberIcon.Field, GetOverlayIcon(field.Attributes), field.HasFlag(FieldAttributes.Static));
|
||||
}
|
||||
|
||||
private static bool IsDecimalConstant(FieldDefinition field)
|
||||
{
|
||||
var fieldType = field.FieldType;
|
||||
/*var fieldType = field.FieldType;
|
||||
if (fieldType.Name == "Decimal" && fieldType.Namespace == "System") {
|
||||
if (field.HasCustomAttributes) {
|
||||
var attrs = field.CustomAttributes;
|
||||
@@ -77,7 +76,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -96,7 +95,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
return AccessOverlayIcon.ProtectedInternal;
|
||||
case FieldAttributes.Private:
|
||||
return AccessOverlayIcon.Private;
|
||||
case FieldAttributes.CompilerControlled:
|
||||
case 0:
|
||||
return AccessOverlayIcon.CompilerControlled;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
@@ -120,10 +119,17 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
|
||||
public override bool IsPublicAPI {
|
||||
get {
|
||||
return FieldDefinition.IsPublic || FieldDefinition.IsFamily || FieldDefinition.IsFamilyOrAssembly;
|
||||
switch (FieldDefinition.Attributes & FieldAttributes.FieldAccessMask) {
|
||||
case FieldAttributes.Public:
|
||||
case FieldAttributes.FamORAssem:
|
||||
case FieldAttributes.Family:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MemberReference IMemberTreeNode.Member => FieldDefinition;
|
||||
IMemberReference IMemberTreeNode.Member => FieldDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -27,6 +27,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
/// </summary>
|
||||
public interface IMemberTreeNode
|
||||
{
|
||||
MemberReference Member { get; }
|
||||
IMemberReference Member { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,13 +17,15 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
using ICSharpCode.Decompiler;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using SRM = System.Reflection.Metadata;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -36,24 +38,27 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
|
||||
public MethodTreeNode(MethodDefinition method)
|
||||
{
|
||||
if (method == null)
|
||||
if (method.IsNil)
|
||||
throw new ArgumentNullException(nameof(method));
|
||||
this.MethodDefinition = method;
|
||||
}
|
||||
|
||||
public override object Text => GetText(MethodDefinition, Language) + MethodDefinition.MetadataToken.ToSuffixString();
|
||||
public override object Text => GetText(MethodDefinition, Language) + MethodDefinition.Handle.ToSuffixString();
|
||||
|
||||
public static object GetText(MethodDefinition method, Language language)
|
||||
{
|
||||
StringBuilder b = new StringBuilder();
|
||||
var b = new StringBuilder();
|
||||
var signatureProvider = language.CreateSignatureTypeProvider(false);
|
||||
var signature = method.DecodeSignature(signatureProvider, new GenericContext(method));
|
||||
|
||||
b.Append('(');
|
||||
for (int i = 0; i < method.Parameters.Count; i++) {
|
||||
for (int i = 0; i < signature.ParameterTypes.Length; i++) {
|
||||
if (i > 0)
|
||||
b.Append(", ");
|
||||
b.Append(language.TypeToString(method.Parameters[i].ParameterType, false, method.Parameters[i]));
|
||||
b.Append(signature.ParameterTypes[i]);
|
||||
}
|
||||
if (method.CallingConvention == MethodCallingConvention.VarArg) {
|
||||
if (method.HasParameters)
|
||||
if (signature.Header.CallingConvention == SRM.SignatureCallingConvention.VarArgs) {
|
||||
if (signature.ParameterTypes.Length > 0)
|
||||
b.Append(", ");
|
||||
b.Append("...");
|
||||
}
|
||||
@@ -61,7 +66,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
b.Append(')');
|
||||
} else {
|
||||
b.Append(") : ");
|
||||
b.Append(language.TypeToString(method.ReturnType, false, method.MethodReturnType));
|
||||
b.Append(signature.ReturnType);
|
||||
}
|
||||
return HighlightSearchMatch(language.FormatMethodName(method), b.ToString());
|
||||
}
|
||||
@@ -70,32 +75,28 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
|
||||
public static ImageSource GetIcon(MethodDefinition method)
|
||||
{
|
||||
if (method.IsSpecialName && method.Name.StartsWith("op_", StringComparison.Ordinal)) {
|
||||
if (method.HasFlag(MethodAttributes.SpecialName) && method.Name.StartsWith("op_", StringComparison.Ordinal)) {
|
||||
return Images.GetIcon(MemberIcon.Operator, GetOverlayIcon(method.Attributes), false);
|
||||
}
|
||||
|
||||
if (method.IsStatic && method.HasCustomAttributes) {
|
||||
foreach (var ca in method.CustomAttributes) {
|
||||
if (ca.AttributeType.FullName == "System.Runtime.CompilerServices.ExtensionAttribute") {
|
||||
return Images.GetIcon(MemberIcon.ExtensionMethod, GetOverlayIcon(method.Attributes), false);
|
||||
}
|
||||
}
|
||||
if (method.IsExtensionMethod) {
|
||||
return Images.GetIcon(MemberIcon.ExtensionMethod, GetOverlayIcon(method.Attributes), false);
|
||||
}
|
||||
|
||||
if (method.IsSpecialName &&
|
||||
if (method.HasFlag(MethodAttributes.SpecialName) &&
|
||||
(method.Name == ".ctor" || method.Name == ".cctor")) {
|
||||
return Images.GetIcon(MemberIcon.Constructor, GetOverlayIcon(method.Attributes), method.IsStatic);
|
||||
return Images.GetIcon(MemberIcon.Constructor, GetOverlayIcon(method.Attributes), method.HasFlag(MethodAttributes.Static));
|
||||
}
|
||||
|
||||
if (method.HasPInvokeInfo)
|
||||
return Images.GetIcon(MemberIcon.PInvokeMethod, GetOverlayIcon(method.Attributes), true);
|
||||
|
||||
bool showAsVirtual = method.IsVirtual && !(method.IsNewSlot && method.IsFinal) && !method.DeclaringType.IsInterface;
|
||||
bool showAsVirtual = method.HasFlag(MethodAttributes.Virtual) && !(method.HasFlag(MethodAttributes.NewSlot) && method.HasFlag(MethodAttributes.Final)) && !method.DeclaringType.IsInterface;
|
||||
|
||||
return Images.GetIcon(
|
||||
showAsVirtual ? MemberIcon.VirtualMethod : MemberIcon.Method,
|
||||
GetOverlayIcon(method.Attributes),
|
||||
method.IsStatic);
|
||||
method.HasFlag(MethodAttributes.Static));
|
||||
}
|
||||
|
||||
private static AccessOverlayIcon GetOverlayIcon(MethodAttributes methodAttributes)
|
||||
@@ -113,7 +114,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
return AccessOverlayIcon.ProtectedInternal;
|
||||
case MethodAttributes.Private:
|
||||
return AccessOverlayIcon.Private;
|
||||
case MethodAttributes.CompilerControlled:
|
||||
case 0:
|
||||
return AccessOverlayIcon.CompilerControlled;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
@@ -137,10 +138,17 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
|
||||
public override bool IsPublicAPI {
|
||||
get {
|
||||
return MethodDefinition.IsPublic || MethodDefinition.IsFamily || MethodDefinition.IsFamilyOrAssembly;
|
||||
switch (MethodDefinition.Attributes & MethodAttributes.MemberAccessMask) {
|
||||
case MethodAttributes.Public:
|
||||
case MethodAttributes.Family:
|
||||
case MethodAttributes.FamORAssem:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MemberReference IMemberTreeNode.Member => MethodDefinition;
|
||||
IMemberReference IMemberTreeNode.Member => MethodDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
/// <summary>
|
||||
/// Module reference in ReferenceFolderTreeNode.
|
||||
/// </summary>
|
||||
sealed class ModuleReferenceTreeNode : ILSpyTreeNode
|
||||
/*sealed class ModuleReferenceTreeNode : ILSpyTreeNode
|
||||
{
|
||||
readonly ModuleReference r;
|
||||
|
||||
@@ -48,5 +48,5 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
language.WriteCommentLine(output, r.Name);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Windows.Media;
|
||||
using ICSharpCode.Decompiler;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
using SRM = System.Reflection.Metadata;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -36,39 +39,37 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
throw new ArgumentNullException(nameof(property));
|
||||
this.PropertyDefinition = property;
|
||||
using (LoadedAssembly.DisableAssemblyLoad()) {
|
||||
this.isIndexer = property.IsIndexer();
|
||||
this.isIndexer = property.IsIndexer;
|
||||
}
|
||||
|
||||
if (property.GetMethod != null)
|
||||
if (!property.GetMethod.IsNil)
|
||||
this.Children.Add(new MethodTreeNode(property.GetMethod));
|
||||
if (property.SetMethod != null)
|
||||
if (!property.SetMethod.IsNil)
|
||||
this.Children.Add(new MethodTreeNode(property.SetMethod));
|
||||
if (property.HasOtherMethods) {
|
||||
foreach (var m in property.OtherMethods)
|
||||
this.Children.Add(new MethodTreeNode(m));
|
||||
}
|
||||
foreach (var m in property.OtherMethods)
|
||||
this.Children.Add(new MethodTreeNode(m));
|
||||
}
|
||||
|
||||
public PropertyDefinition PropertyDefinition { get; }
|
||||
|
||||
public override object Text => GetText(PropertyDefinition, Language, isIndexer) + PropertyDefinition.MetadataToken.ToSuffixString();
|
||||
public override object Text => GetText(PropertyDefinition, Language, isIndexer) + PropertyDefinition.Handle.ToSuffixString();
|
||||
|
||||
public static object GetText(PropertyDefinition property, Language language, bool? isIndexer = null)
|
||||
{
|
||||
string name = language.FormatPropertyName(property, isIndexer);
|
||||
var signature = property.DecodeSignature(language.CreateSignatureTypeProvider(false), new GenericContext(property.DeclaringType));
|
||||
|
||||
var b = new System.Text.StringBuilder();
|
||||
if (property.HasParameters)
|
||||
{
|
||||
b.Append('(');
|
||||
for (int i = 0; i < property.Parameters.Count; i++)
|
||||
for (int i = 0; i < signature.ParameterTypes.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
b.Append(", ");
|
||||
b.Append(language.TypeToString(property.Parameters[i].ParameterType, false, property.Parameters[i]));
|
||||
b.Append(signature.ParameterTypes[i]);
|
||||
}
|
||||
var method = property.GetMethod ?? property.SetMethod;
|
||||
if (method.CallingConvention == MethodCallingConvention.VarArg)
|
||||
if (signature.Header.CallingConvention == SRM.SignatureCallingConvention.VarArgs)
|
||||
{
|
||||
if (property.HasParameters)
|
||||
b.Append(", ");
|
||||
@@ -80,7 +81,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
b.Append(" : ");
|
||||
}
|
||||
b.Append(language.TypeToString(property.PropertyType, false, property));
|
||||
b.Append(signature.ReturnType);
|
||||
|
||||
return HighlightSearchMatch(name, b.ToString());
|
||||
}
|
||||
@@ -110,7 +111,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
return AccessOverlayIcon.ProtectedInternal;
|
||||
case MethodAttributes.Private:
|
||||
return AccessOverlayIcon.Private;
|
||||
case MethodAttributes.CompilerControlled:
|
||||
case 0:
|
||||
return AccessOverlayIcon.CompilerControlled;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
@@ -128,7 +129,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
// in numeric order, so we can do an integer comparison of the masked attribute
|
||||
int accessLevel = 0;
|
||||
|
||||
if (property.GetMethod != null) {
|
||||
if (!property.GetMethod.IsNil) {
|
||||
int methodAccessLevel = (int)(property.GetMethod.Attributes & MethodAttributes.MemberAccessMask);
|
||||
if (accessLevel < methodAccessLevel) {
|
||||
accessLevel = methodAccessLevel;
|
||||
@@ -136,7 +137,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
}
|
||||
}
|
||||
|
||||
if (property.SetMethod != null) {
|
||||
if (!property.SetMethod.IsNil) {
|
||||
int methodAccessLevel = (int)(property.SetMethod.Attributes & MethodAttributes.MemberAccessMask);
|
||||
if (accessLevel < methodAccessLevel) {
|
||||
accessLevel = methodAccessLevel;
|
||||
@@ -144,13 +145,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
}
|
||||
}
|
||||
|
||||
if (property.HasOtherMethods) {
|
||||
foreach (var m in property.OtherMethods) {
|
||||
int methodAccessLevel = (int)(m.Attributes & MethodAttributes.MemberAccessMask);
|
||||
if (accessLevel < methodAccessLevel) {
|
||||
accessLevel = methodAccessLevel;
|
||||
result = m.Attributes;
|
||||
}
|
||||
foreach (var m in property.OtherMethods) {
|
||||
int methodAccessLevel = (int)(m.Attributes & MethodAttributes.MemberAccessMask);
|
||||
if (accessLevel < methodAccessLevel) {
|
||||
accessLevel = methodAccessLevel;
|
||||
result = m.Attributes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,6 +184,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
}
|
||||
}
|
||||
|
||||
MemberReference IMemberTreeNode.Member => PropertyDefinition;
|
||||
IMemberReference IMemberTreeNode.Member => PropertyDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,10 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Windows.Threading;
|
||||
using ICSharpCode.Decompiler;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -29,10 +30,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
/// </summary>
|
||||
sealed class ReferenceFolderTreeNode : ILSpyTreeNode
|
||||
{
|
||||
readonly ModuleDefinition module;
|
||||
readonly MetadataReader module;
|
||||
readonly AssemblyTreeNode parentAssembly;
|
||||
|
||||
public ReferenceFolderTreeNode(ModuleDefinition module, AssemblyTreeNode parentAssembly)
|
||||
public ReferenceFolderTreeNode(MetadataReader module, AssemblyTreeNode parentAssembly)
|
||||
{
|
||||
this.module = module;
|
||||
this.parentAssembly = parentAssembly;
|
||||
@@ -53,10 +54,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
|
||||
protected override void LoadChildren()
|
||||
{
|
||||
foreach (var r in module.AssemblyReferences.OrderBy(r => r.Name))
|
||||
this.Children.Add(new AssemblyReferenceTreeNode(r, parentAssembly));
|
||||
foreach (var r in module.ModuleReferences.OrderBy(r => r.Name))
|
||||
this.Children.Add(new ModuleReferenceTreeNode(r));
|
||||
//foreach (var r in module.AssemblyReferences.OrderBy(r => r.Name))
|
||||
// this.Children.Add(new AssemblyReferenceTreeNode(r, parentAssembly));
|
||||
//foreach (var r in module.ModuleReferences.OrderBy(r => r.Name))
|
||||
// this.Children.Add(new ModuleReferenceTreeNode(r));
|
||||
}
|
||||
|
||||
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
|
||||
@@ -66,10 +67,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
output.WriteLine();
|
||||
language.WriteCommentLine(output, "Referenced assemblies (in metadata order):");
|
||||
// Show metadata order of references
|
||||
foreach (var r in module.AssemblyReferences)
|
||||
/*foreach (var r in module.AssemblyReferences)
|
||||
new AssemblyReferenceTreeNode(r, parentAssembly).Decompile(language, output, options);
|
||||
foreach (var r in module.ModuleReferences)
|
||||
language.WriteCommentLine(output, r.Name);
|
||||
language.WriteCommentLine(output, r.Name);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Threading;
|
||||
using ICSharpCode.Decompiler;
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -29,9 +29,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
/// </summary>
|
||||
sealed class ResourceListTreeNode : ILSpyTreeNode
|
||||
{
|
||||
readonly ModuleDefinition module;
|
||||
readonly PEFile module;
|
||||
|
||||
public ResourceListTreeNode(ModuleDefinition module)
|
||||
public ResourceListTreeNode(PEFile module)
|
||||
{
|
||||
this.LazyLoading = true;
|
||||
this.module = module;
|
||||
|
||||
@@ -21,8 +21,8 @@ using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media.Imaging;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.ILSpy.TextView;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -33,11 +33,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
|
||||
public ILSpyTreeNode CreateNode(Resource resource)
|
||||
{
|
||||
EmbeddedResource er = resource as EmbeddedResource;
|
||||
if (er != null) {
|
||||
return CreateNode(er.Name, er.GetResourceStream());
|
||||
}
|
||||
return null;
|
||||
Stream stream = resource.TryOpenStream();
|
||||
if (stream == null)
|
||||
return null;
|
||||
return CreateNode(resource.Name, stream);
|
||||
}
|
||||
|
||||
public ILSpyTreeNode CreateNode(string key, object data)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using Mono.Cecil;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
|
||||
@@ -21,8 +21,8 @@ using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media.Imaging;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
using ICSharpCode.ILSpy.TextView;
|
||||
using Mono.Cecil;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
@@ -31,11 +31,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
public ILSpyTreeNode CreateNode(Resource resource)
|
||||
{
|
||||
EmbeddedResource er = resource as EmbeddedResource;
|
||||
if (er != null) {
|
||||
return CreateNode(er.Name, er.GetResourceStream());
|
||||
}
|
||||
return null;
|
||||
Stream stream = resource.TryOpenStream();
|
||||
if (stream == null)
|
||||
return null;
|
||||
return CreateNode(resource.Name, stream);
|
||||
}
|
||||
|
||||
public ILSpyTreeNode CreateNode(string key, object data)
|
||||
|
||||
@@ -20,15 +20,14 @@ using System.ComponentModel.Composition;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using ICSharpCode.Decompiler;
|
||||
using ICSharpCode.Decompiler.Dom;
|
||||
|
||||
namespace ICSharpCode.ILSpy.TreeNodes
|
||||
{
|
||||
[Export(typeof(IResourceNodeFactory))]
|
||||
sealed class ImageListResourceEntryNodeFactory : IResourceNodeFactory
|
||||
{
|
||||
#region IResourceNodeFactory Members
|
||||
|
||||
public ILSpyTreeNode CreateNode(Mono.Cecil.Resource resource)
|
||||
public ILSpyTreeNode CreateNode(Resource resource)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -39,8 +38,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
|
||||
return new ImageListResourceEntryNode(key, (ImageListStreamer)data);
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
sealed class ImageListResourceEntryNode : ILSpyTreeNode
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user