mirror of https://github.com/icsharpcode/ILSpy.git
109 changed files with 4581 additions and 3306 deletions
@ -0,0 +1,223 @@
@@ -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; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,373 @@
@@ -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; |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,230 @@
@@ -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 @@
@@ -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); |
||||
} |
||||
} |
||||
} |
||||
} |
File diff suppressed because one or more lines are too long
@ -1,41 +0,0 @@
@@ -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; |
||||
} |
||||
} |
||||
} |
@ -1,35 +0,0 @@
@@ -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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,33 @@
@@ -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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,86 @@
@@ -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(); |
||||
} |
||||
} |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue