Browse Source

Refactor DecompilerTypeSystem.ResolveMethod().

pull/1198/head
Daniel Grunwald 7 years ago
parent
commit
802f6e54fd
  1. 14
      ICSharpCode.Decompiler/CSharp/Resolver/ReducedExtensionMethod.cs
  2. 2
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  3. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  4. 2
      ICSharpCode.Decompiler/Metadata/SignatureBlobComparer.cs
  5. 311
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  6. 12
      ICSharpCode.Decompiler/TypeSystem/IMethod.cs
  7. 9
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedField.cs
  8. 22
      ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedMethod.cs
  9. 166
      ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs
  10. 26
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs
  11. 14
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedField.cs
  12. 23
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs
  13. 10
      ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs

14
ICSharpCode.Decompiler/CSharp/Resolver/ReducedExtensionMethod.cs

@ -177,19 +177,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -177,19 +177,7 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
return baseMethod.IsOperator;
}
}
public bool IsPartial {
get {
return baseMethod.IsPartial;
}
}
public bool IsAsync {
get {
return baseMethod.IsAsync;
}
}
public bool HasBody {
get {
return baseMethod.HasBody;

2
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -1087,8 +1087,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1087,8 +1087,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
MethodDeclaration decl = new MethodDeclaration();
decl.Modifiers = GetMemberModifiers(method);
if (method.IsAsync && ShowModifiers)
decl.Modifiers |= Modifiers.Async;
if (ShowAttributes) {
decl.Attributes.AddRange (method.Attributes.Select ((a) => new AttributeSection (ConvertAttribute (a))));
decl.Attributes.AddRange (method.ReturnTypeAttributes.Select ((a) => new AttributeSection (ConvertAttribute (a)) {

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -339,6 +339,7 @@ @@ -339,6 +339,7 @@
<Compile Include="SRMExtensions.cs" />
<Compile Include="SRMHacks.cs" />
<Compile Include="TypeSystem\ApplyAttributeTypeVisitor.cs" />
<Compile Include="TypeSystem\Implementation\FakeMember.cs" />
<Compile Include="TypeSystem\Implementation\MetadataTypeReference.cs" />
<Compile Include="TypeSystem\Implementation\TypeSpecification.cs" />
<Compile Include="Metadata\MetadataExtensions.cs" />

2
ICSharpCode.Decompiler/Metadata/SignatureBlobComparer.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -31,7 +31,7 @@ namespace ICSharpCode.Decompiler.Metadata
for (; i < totalParameterCount; i++) {
if (!IsSameCompressedInteger(ref a, ref b, out typeCode))
return false;
//
// varargs sentinel
if (typeCode == 65)
break;
if (!TypesAreEqual(ref a, ref b, contextForA, contextForB, typeCode))

311
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -1,4 +1,22 @@ @@ -1,4 +1,22 @@
using System;
// Copyright (c) 2018 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using SRM = System.Reflection.Metadata;
@ -190,23 +208,27 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -190,23 +208,27 @@ namespace ICSharpCode.Decompiler.TypeSystem
if (fieldReference.Kind != SRM.HandleKind.FieldDefinition && fieldReference.Kind != SRM.HandleKind.MemberReference)
throw new ArgumentException("HandleKind must be either FieldDefinition or MemberReference", nameof(fieldReference));
lock (fieldLookupCache) {
IField field;
if (!fieldLookupCache.TryGetValue(fieldReference, out field)) {
if (!fieldLookupCache.TryGetValue(fieldReference, out IField field)) {
var metadata = moduleDefinition.Metadata;
IType declaringType;
ITypeReference returnType;
switch (fieldReference.Kind) {
case SRM.HandleKind.FieldDefinition:
var fieldDefHandle = (SRM.FieldDefinitionHandle)fieldReference;
var fieldDef = metadata.GetFieldDefinition(fieldDefHandle);
declaringType = ResolveDeclaringType(fieldDef.GetDeclaringType());
returnType = new FieldTypeReference(fieldDefHandle, metadata, typeAttributeOptions);
var declaringTypeDefinition = declaringType.GetDefinition();
if (declaringTypeDefinition == null)
field = CreateFakeField(declaringType, metadata.GetString(fieldDef.Name), returnType);
else {
field = declaringTypeDefinition.GetFields(f => f.MetadataToken == fieldReference, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault()
?? CreateFakeField(declaringType, metadata.GetString(fieldDef.Name), returnType);
if (declaringTypeDefinition != null) {
field = declaringTypeDefinition.GetFields(f => f.MetadataToken == fieldReference, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();
} else {
field = null;
}
if (field == null) {
field = new FakeField(compilation) {
DeclaringType = declaringType,
Name = metadata.GetString(fieldDef.Name),
ReturnType = FieldTypeReference.Resolve(fieldDefHandle, metadata, context, typeAttributeOptions),
IsStatic = (fieldDef.Attributes & System.Reflection.FieldAttributes.Static) != 0
};
}
break;
case SRM.HandleKind.MemberReference:
@ -233,38 +255,19 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -233,38 +255,19 @@ namespace ICSharpCode.Decompiler.TypeSystem
var memberRef = metadata.GetMemberReference(memberRefHandle);
string name = metadata.GetString(memberRef.Name);
ITypeDefinition typeDef = declaringType.GetDefinition();
ITypeReference returnType = new FieldTypeReference(memberRefHandle, metadata, typeAttributeOptions);
if (typeDef == null)
return CreateFakeField(declaringType, name, returnType);
foreach (IField field in typeDef.Fields)
if (field.Name == name)
return field;
return CreateFakeField(declaringType, name, returnType);
}
IField CreateFakeField(IType declaringType, string name, ITypeReference returnType)
{
var f = new DefaultUnresolvedField();
f.Name = name;
f.ReturnType = returnType;
return new ResolvedFakeField(f, context.WithCurrentTypeDefinition(declaringType.GetDefinition()), declaringType);
}
class ResolvedFakeField : DefaultResolvedField
{
readonly IType declaringType;
public ResolvedFakeField(DefaultUnresolvedField unresolved, ITypeResolveContext parentContext, IType declaringType)
: base(unresolved, parentContext)
{
this.declaringType = declaringType;
}
public override IType DeclaringType
{
get { return declaringType; }
if (typeDef != null) {
foreach (IField field in typeDef.Fields) {
if (field.Name == name)
return field;
}
}
var returnType = memberRef.DecodeFieldSignature(new TypeProvider(context.CurrentAssembly), context);
return new FakeField(compilation) {
DeclaringType = declaringType,
Name = name,
ReturnType = returnType
};
}
#endregion
@ -276,128 +279,138 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -276,128 +279,138 @@ namespace ICSharpCode.Decompiler.TypeSystem
if (methodReference.Kind != SRM.HandleKind.MethodDefinition && methodReference.Kind != SRM.HandleKind.MemberReference && methodReference.Kind != SRM.HandleKind.MethodSpecification)
throw new ArgumentException("HandleKind must be either a MethodDefinition, MemberReference or MethodSpecification", nameof(methodReference));
lock (methodLookupCache) {
IMethod method;
IType declaringType;
IReadOnlyList<IType> classTypeArguments = null;
IReadOnlyList<IType> methodTypeArguments = null;
SRM.MethodSignature<ITypeReference>? signature = null;
if (!methodLookupCache.TryGetValue(methodReference, out method)) {
if (!methodLookupCache.TryGetValue(methodReference, out IMethod method)) {
var metadata = moduleDefinition.Metadata;
switch (methodReference.Kind) {
case SRM.HandleKind.MethodDefinition:
var methodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)methodReference);
signature = methodDef.DecodeSignature(TypeReferenceSignatureDecoder.Instance, default);
method = FindNonGenericMethod(metadata, methodReference, out declaringType);
method = ResolveMethodDefinition(metadata, (SRM.MethodDefinitionHandle)methodReference);
break;
case SRM.HandleKind.MemberReference:
var memberRef = metadata.GetMemberReference((SRM.MemberReferenceHandle)methodReference);
Debug.Assert(memberRef.GetKind() == SRM.MemberReferenceKind.Method);
signature = memberRef.DecodeMethodSignature(TypeReferenceSignatureDecoder.Instance, default);
var elementMethod = methodReference;
if (memberRef.Parent.Kind == SRM.HandleKind.MethodDefinition) {
elementMethod = (SRM.MethodDefinitionHandle)memberRef.Parent;
}
method = FindNonGenericMethod(metadata, elementMethod, out declaringType);
method = ResolveMethodReference(metadata, (SRM.MemberReferenceHandle)methodReference);
break;
case SRM.HandleKind.MethodSpecification:
var methodSpec = metadata.GetMethodSpecification((SRM.MethodSpecificationHandle)methodReference);
method = FindNonGenericMethod(metadata, methodSpec.Method, out declaringType);
var typeArguments = methodSpec.DecodeSignature(new TypeProvider(context.CurrentAssembly), default);
if (typeArguments.Length > 0) {
methodTypeArguments = typeArguments;
var methodTypeArgs = methodSpec.DecodeSignature(new TypeProvider(context.CurrentAssembly), context);
if (methodSpec.Method.Kind == SRM.HandleKind.MethodDefinition) {
// generic instance of a methoddef (=generic method in non-generic class in current assembly)
method = ResolveMethodDefinition(metadata, (SRM.MethodDefinitionHandle)methodSpec.Method);
method = method.Specialize(new TypeParameterSubstitution(null, methodTypeArgs));
} else {
method = ResolveMethodReference(metadata, (SRM.MemberReferenceHandle)methodSpec.Method, methodTypeArgs);
}
break;
default:
throw new NotSupportedException();
}
if (signature?.Header.CallingConvention == SRM.SignatureCallingConvention.VarArgs) {
method = new VarArgInstanceMethod(method, signature.Value.ParameterTypes.Skip(signature.Value.RequiredParameterCount).Select(p => p.Resolve(context)));
}
if (declaringType.TypeArguments.Count > 0) {
classTypeArguments = declaringType.TypeArguments.ToList();
}
if (classTypeArguments != null || methodTypeArguments != null) {
method = method.Specialize(new TypeParameterSubstitution(classTypeArguments, methodTypeArguments));
}
methodLookupCache.Add(methodReference, method);
}
return method;
}
}
IMethod FindNonGenericMethod(SRM.MetadataReader metadata, SRM.EntityHandle methodReference, out IType declaringType)
IMethod ResolveMethodDefinition(SRM.MetadataReader metadata, SRM.MethodDefinitionHandle methodDefHandle, bool expandVarArgs = true)
{
ITypeDefinition declaringTypeDefinition;
string name;
switch (methodReference.Kind) {
case SRM.HandleKind.MethodDefinition:
var methodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)methodReference);
declaringType = ResolveDeclaringType(methodDef.GetDeclaringType());
declaringTypeDefinition = declaringType.GetDefinition();
if (declaringTypeDefinition == null) {
return CreateFakeMethod(declaringType, metadata.GetString(methodDef.Name), methodDef.DecodeSignature(TypeReferenceSignatureDecoder.Instance, default));
}
name = metadata.GetString(methodDef.Name);
IMethod method;
if (name == ".ctor") {
method = declaringTypeDefinition.GetConstructors(m => m.MetadataToken == methodReference, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();
} else if (name == ".cctor") {
method = declaringTypeDefinition.Methods.FirstOrDefault(m => m.MetadataToken == methodReference);
} else {
method = declaringTypeDefinition.GetMethods(m => m.MetadataToken == methodReference, GetMemberOptions.IgnoreInheritedMembers)
.Concat(declaringTypeDefinition.GetAccessors(m => m.MetadataToken == methodReference, GetMemberOptions.IgnoreInheritedMembers)).FirstOrDefault();
}
return method ?? CreateFakeMethod(declaringType, metadata.GetString(methodDef.Name), methodDef.DecodeSignature(TypeReferenceSignatureDecoder.Instance, default));
case SRM.HandleKind.MemberReference:
var memberRef = metadata.GetMemberReference((SRM.MemberReferenceHandle)methodReference);
Debug.Assert(memberRef.GetKind() == SRM.MemberReferenceKind.Method);
// TODO : Support other handles
switch (memberRef.Parent.Kind) {
case SRM.HandleKind.MethodDefinition:
FindNonGenericMethod(metadata, memberRef.Parent, out declaringType);
break;
default:
declaringType = ResolveDeclaringType(memberRef.Parent);
break;
}
declaringTypeDefinition = declaringType.GetDefinition();
var signature = memberRef.DecodeMethodSignature(TypeReferenceSignatureDecoder.Instance, default);
if (declaringTypeDefinition == null) {
return CreateFakeMethod(declaringType, metadata.GetString(memberRef.Name), signature);
}
var methodDef = metadata.GetMethodDefinition(methodDefHandle);
var declaringType = ResolveDeclaringType(methodDef.GetDeclaringType());
var declaringTypeDefinition = declaringType.GetDefinition();
string name = metadata.GetString(methodDef.Name);
IMethod method;
if (declaringTypeDefinition != null) {
if (name == ".ctor") {
method = declaringTypeDefinition.GetConstructors(m => m.MetadataToken == methodDefHandle, GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();
} else if (name == ".cctor") {
method = declaringTypeDefinition.Methods.FirstOrDefault(m => m.MetadataToken == methodDefHandle);
} else {
method = declaringTypeDefinition.GetMethods(m => m.MetadataToken == methodDefHandle, GetMemberOptions.IgnoreInheritedMembers)
.Concat(declaringTypeDefinition.GetAccessors(m => m.MetadataToken == methodDefHandle, GetMemberOptions.IgnoreInheritedMembers)).FirstOrDefault();
}
} else {
method = null;
}
if (method == null) {
var signature = methodDef.DecodeSignature(new TypeProvider(context.CurrentAssembly),
context.WithCurrentTypeDefinition(declaringTypeDefinition));
method = CreateFakeMethod(declaringType, metadata.GetString(methodDef.Name), signature);
}
if (expandVarArgs && method.Parameters.LastOrDefault()?.Type.Kind == TypeKind.ArgList) {
method = new VarArgInstanceMethod(method, EmptyList<IType>.Instance);
}
return method;
}
/// <summary>
/// Resolves a method reference.
/// </summary>
/// <remarks>
/// Class type arguments are provided by the declaring type stored in the memberRef.
/// Method type arguments are provided by the caller.
/// </remarks>
IMethod ResolveMethodReference(SRM.MetadataReader metadata, SRM.MemberReferenceHandle memberRefHandle, IReadOnlyList<IType> methodTypeArguments = null)
{
var memberRef = metadata.GetMemberReference(memberRefHandle);
Debug.Assert(memberRef.GetKind() == SRM.MemberReferenceKind.Method);
SRM.MethodSignature<IType> signature;
IReadOnlyList<IType> classTypeArguments = null;
IMethod method;
if (memberRef.Parent.Kind == SRM.HandleKind.MethodDefinition) {
method = ResolveMethodDefinition(metadata, (SRM.MethodDefinitionHandle)memberRef.Parent, expandVarArgs: false);
signature = memberRef.DecodeMethodSignature(new TypeProvider(context.CurrentAssembly), context);
} else {
var declaringType = ResolveDeclaringType(memberRef.Parent);
var declaringTypeDefinition = declaringType.GetDefinition();
if (declaringType.TypeArguments.Count > 0) {
classTypeArguments = declaringType.TypeArguments;
}
// Note: declaringType might be parameterized, but the signature is for the original method definition.
// We'll have to search the member directly on declaringTypeDefinition.
string name = metadata.GetString(memberRef.Name);
signature = memberRef.DecodeMethodSignature(new TypeProvider(context.CurrentAssembly),
context.WithCurrentTypeDefinition(declaringTypeDefinition));
if (declaringTypeDefinition != null) {
// Find the set of overloads to search:
IEnumerable<IMethod> methods;
name = metadata.GetString(memberRef.Name);
if (name == ".ctor") {
methods = declaringTypeDefinition.GetConstructors();
} else if (name == ".cctor") {
return declaringTypeDefinition.Methods.FirstOrDefault(m => m.IsConstructor && m.IsStatic);
methods = declaringTypeDefinition.Methods.Where(m => m.IsConstructor && m.IsStatic);
} else {
methods = declaringTypeDefinition.GetMethods(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers)
.Concat(declaringTypeDefinition.GetAccessors(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers));
}
IType[] parameterTypes;
// Determine the expected parameters from the signature:
ImmutableArray<IType> parameterTypes;
if (signature.Header.CallingConvention == SRM.SignatureCallingConvention.VarArgs) {
parameterTypes = signature.ParameterTypes
.Take(signature.RequiredParameterCount)
.Select(p => p.Resolve(context))
.Concat(new[] { SpecialType.ArgList })
.ToArray();
.ToImmutableArray();
} else {
parameterTypes = signature.ParameterTypes.SelectArray(p => p.Resolve(context));
parameterTypes = signature.ParameterTypes;
}
var returnType = signature.ReturnType.Resolve(context);
// Search for the matching method:
method = null;
foreach (var m in methods) {
if (m.TypeParameters.Count != signature.GenericParameterCount)
continue;
if (!CompareSignatures(m.Parameters, parameterTypes) || !CompareTypes(m.ReturnType, returnType))
continue;
return m;
if (CompareSignatures(m.Parameters, parameterTypes) && CompareTypes(m.ReturnType, signature.ReturnType)) {
method = m;
break;
}
}
return CreateFakeMethod(declaringType, metadata.GetString(memberRef.Name), signature);
default:
throw new NotSupportedException();
} else {
method = null;
}
if (method == null) {
method = CreateFakeMethod(declaringType, name, signature);
}
}
if (classTypeArguments != null || methodTypeArguments != null) {
method = method.Specialize(new TypeParameterSubstitution(classTypeArguments, methodTypeArguments));
}
if (signature.Header.CallingConvention == SRM.SignatureCallingConvention.VarArgs) {
method = new VarArgInstanceMethod(method, signature.ParameterTypes.Skip(signature.RequiredParameterCount));
}
return method;
}
static readonly NormalizeTypeVisitor normalizeTypeVisitor = new NormalizeTypeVisitor {
@ -417,7 +430,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -417,7 +430,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
return method.Parameters.Count > 0 && method.Parameters[method.Parameters.Count - 1].Type.Kind == TypeKind.ArgList;
}
static bool CompareSignatures(IReadOnlyList<IParameter> parameters, IType[] parameterTypes)
static bool CompareSignatures(IReadOnlyList<IParameter> parameters, ImmutableArray<IType> parameterTypes)
{
if (parameterTypes.Length != parameters.Count)
return false;
@ -431,40 +444,38 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -431,40 +444,38 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// <summary>
/// Create a dummy IMethod from the specified MethodReference
/// </summary>
IMethod CreateFakeMethod(IType declaringType, string name, SRM.MethodSignature<ITypeReference> signature)
IMethod CreateFakeMethod(IType declaringType, string name, SRM.MethodSignature<IType> signature)
{
var m = new DefaultUnresolvedMethod();
SymbolKind symbolKind = SymbolKind.Method;
if (name == ".ctor" || name == ".cctor")
m.SymbolKind = SymbolKind.Constructor;
symbolKind = SymbolKind.Constructor;
var m = new FakeMethod(compilation, symbolKind);
m.DeclaringType = declaringType;
m.Name = name;
m.MetadataToken = default(SRM.MethodDefinitionHandle);
m.ReturnType = signature.ReturnType;
m.IsStatic = !signature.Header.IsInstance;
var metadata = moduleDefinition.Metadata;
for (int i = 0; i < signature.GenericParameterCount; i++) {
m.TypeParameters.Add(new DefaultUnresolvedTypeParameter(SymbolKind.Method, i, ""));
}
for (int i = 0; i < signature.ParameterTypes.Length; i++) {
m.Parameters.Add(new DefaultUnresolvedParameter(signature.ParameterTypes[i], ""));
}
return new ResolvedFakeMethod(m, context.WithCurrentTypeDefinition(declaringType.GetDefinition()), declaringType);
}
class ResolvedFakeMethod : DefaultResolvedMethod
{
readonly IType declaringType;
public ResolvedFakeMethod(DefaultUnresolvedMethod unresolved, ITypeResolveContext parentContext, IType declaringType)
: base(unresolved, parentContext)
{
this.declaringType = declaringType;
var metadata = moduleDefinition.Metadata;
TypeParameterSubstitution substitution = null;
if (signature.GenericParameterCount > 0) {
var typeParameters = new List<ITypeParameter>();
for (int i = 0; i < signature.GenericParameterCount; i++) {
typeParameters.Add(new DefaultTypeParameter(m, i));
}
m.TypeParameters = typeParameters;
substitution = new TypeParameterSubstitution(null, typeParameters);
}
public override IType DeclaringType
{
get { return declaringType; }
var parameters = new List<IParameter>();
for (int i = 0; i < signature.RequiredParameterCount; i++) {
var type = signature.ParameterTypes[i];
if (substitution != null) {
// replace the dummy method type parameters with the owned instances we just created
type = type.AcceptVisitor(substitution);
}
parameters.Add(new DefaultParameter(type, ""));
}
m.Parameters = parameters;
return m;
}
#endregion

12
ICSharpCode.Decompiler/TypeSystem/IMethod.cs

@ -105,18 +105,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -105,18 +105,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
bool IsDestructor { get; }
bool IsOperator { get; }
/// <summary>
/// Gets whether the method is a C#-style partial method.
/// A call to such a method is ignored by the compiler if the partial method has no body.
/// </summary>
/// <seealso cref="HasBody"/>
bool IsPartial { get; }
/// <summary>
/// Gets whether the method is a C#-style async method.
/// </summary>
bool IsAsync { get; }
/// <summary>
/// Gets whether the method has a body.
/// This property returns <c>false</c> for <c>abstract</c> or <c>extern</c> methods,

9
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedField.cs

@ -72,14 +72,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -72,14 +72,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public override IMember Specialize(TypeParameterSubstitution substitution)
{
if (TypeParameterSubstitution.Identity.Equals(substitution)
|| DeclaringType.TypeParameterCount == 0)
{
return this;
}
if (substitution.MethodTypeArguments != null && substitution.MethodTypeArguments.Count > 0)
substitution = new TypeParameterSubstitution(substitution.ClassTypeArguments, EmptyList<IType>.Instance);
return new SpecializedField(this, substitution);
return SpecializedField.Create(this, substitution);
}
}
}

22
ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedMethod.cs

@ -198,14 +198,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -198,14 +198,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return ((IUnresolvedMethod)unresolved).IsOperator; }
}
public bool IsPartial {
get { return ((IUnresolvedMethod)unresolved).IsPartial; }
}
public bool IsAsync {
get { return ((IUnresolvedMethod)unresolved).IsAsync; }
}
public bool HasBody {
get { return ((IUnresolvedMethod)unresolved).HasBody; }
}
@ -230,22 +222,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -230,22 +222,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public override IMember Specialize(TypeParameterSubstitution substitution)
{
if (TypeParameterSubstitution.Identity.Equals(substitution))
return this;
if (DeclaringType is ArrayType)
return new SpecializedMethod(this, substitution);
if (TypeParameters.Count == 0) {
if (DeclaringType.TypeParameterCount == 0)
return this;
if (substitution.MethodTypeArguments != null && substitution.MethodTypeArguments.Count > 0)
substitution = new TypeParameterSubstitution(substitution.ClassTypeArguments, EmptyList<IType>.Instance);
}
return new SpecializedMethod(this, substitution);
return SpecializedMethod.Create(this, substitution);
}
IMethod IMethod.Specialize(TypeParameterSubstitution substitution)
{
return (IMethod)Specialize(substitution);
return SpecializedMethod.Create(this, substitution);
}
public override string ToString()

166
ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs

@ -0,0 +1,166 @@ @@ -0,0 +1,166 @@
// Copyright (c) 2018 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{
/// <summary>
/// Base class for fake members.
/// </summary>
abstract class FakeMember : IMember
{
readonly ICompilation compilation;
protected FakeMember(ICompilation compilation)
{
this.compilation = compilation ?? throw new ArgumentNullException(nameof(compilation));
}
IMember IMember.MemberDefinition => this;
public IType ReturnType { get; set; } = SpecialType.UnknownType;
IReadOnlyList<IMember> IMember.ImplementedInterfaceMembers => EmptyList<IMember>.Instance;
bool IMember.IsExplicitInterfaceImplementation => false;
bool IMember.IsVirtual => false;
bool IMember.IsOverride => false;
bool IMember.IsOverridable => false;
TypeParameterSubstitution IMember.Substitution => TypeParameterSubstitution.Identity;
EntityHandle IEntity.MetadataToken => default;
public string Name { get; set; }
ITypeDefinition IEntity.DeclaringTypeDefinition => DeclaringType?.GetDefinition();
public IType DeclaringType { get; set; }
IAssembly IEntity.ParentAssembly => DeclaringType?.GetDefinition()?.ParentAssembly;
IReadOnlyList<IAttribute> IEntity.Attributes => EmptyList<IAttribute>.Instance;
Accessibility IEntity.Accessibility => Accessibility.Public;
public bool IsStatic { get; set; }
bool IEntity.IsAbstract => false;
bool IEntity.IsSealed => false;
bool IEntity.IsShadowing => false;
public abstract SymbolKind SymbolKind { get; }
ICompilation ICompilationProvider.Compilation => compilation;
string INamedElement.FullName {
get {
if (DeclaringType != null)
return DeclaringType.FullName + "." + Name;
else
return Name;
}
}
string INamedElement.ReflectionName {
get {
if (DeclaringType != null)
return DeclaringType.ReflectionName + "." + Name;
else
return Name;
}
}
string INamedElement.Namespace => DeclaringType?.Namespace;
bool IMember.Equals(IMember obj, TypeVisitor typeNormalization)
{
return Equals(obj);
}
public abstract IMember Specialize(TypeParameterSubstitution substitution);
}
class FakeField : FakeMember, IField
{
public FakeField(ICompilation compilation) : base(compilation)
{
}
bool IField.IsReadOnly => false;
bool IField.IsVolatile => false;
bool IField.IsFixed => false;
bool IVariable.IsConst => false;
object IVariable.ConstantValue => null;
IType IVariable.Type => ReturnType;
public override SymbolKind SymbolKind => SymbolKind.Field;
public override IMember Specialize(TypeParameterSubstitution substitution)
{
return SpecializedField.Create(this, substitution);
}
}
class FakeMethod : FakeMember, IMethod
{
readonly SymbolKind symbolKind;
public FakeMethod(ICompilation compilation, SymbolKind symbolKind) : base(compilation)
{
this.symbolKind = symbolKind;
}
public override SymbolKind SymbolKind => symbolKind;
IReadOnlyList<IUnresolvedMethod> IMethod.Parts => throw new NotImplementedException();
IReadOnlyList<IAttribute> IMethod.ReturnTypeAttributes => EmptyList<IAttribute>.Instance;
public IReadOnlyList<ITypeParameter> TypeParameters { get; set; } = EmptyList<ITypeParameter>.Instance;
IReadOnlyList<IType> IMethod.TypeArguments => TypeParameters;
bool IMethod.IsExtensionMethod => false;
bool IMethod.IsConstructor => symbolKind == SymbolKind.Constructor;
bool IMethod.IsDestructor => symbolKind == SymbolKind.Destructor;
bool IMethod.IsOperator => symbolKind == SymbolKind.Operator;
bool IMethod.HasBody => false;
bool IMethod.IsAccessor => false;
IMember IMethod.AccessorOwner => null;
IMethod IMethod.ReducedFrom => null;
public IReadOnlyList<IParameter> Parameters { get; set; } = EmptyList<IParameter>.Instance;
public override IMember Specialize(TypeParameterSubstitution substitution)
{
return SpecializedMethod.Create(this, substitution);
}
IMethod IMethod.Specialize(TypeParameterSubstitution substitution)
{
return SpecializedMethod.Create(this, substitution);
}
}
}

26
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs

@ -34,8 +34,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -34,8 +34,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public MetadataTypeReference(SRM.EntityHandle type,
SRM.MetadataReader metadata,
SRM.CustomAttributeHandleCollection? typeAttributes = null,
TypeAttributeOptions attributeOptions = TypeAttributeOptions.Default)
SRM.CustomAttributeHandleCollection? typeAttributes,
TypeAttributeOptions attributeOptions)
{
this.type = type;
this.metadata = metadata;
@ -52,8 +52,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -52,8 +52,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public static IType Resolve(SRM.EntityHandle type,
SRM.MetadataReader metadata,
ITypeResolveContext context,
SRM.CustomAttributeHandleCollection? typeAttributes = null,
TypeAttributeOptions attributeOptions = TypeAttributeOptions.Default)
SRM.CustomAttributeHandleCollection? typeAttributes,
TypeAttributeOptions attributeOptions)
{
if (type.IsNil)
return SpecialType.UnknownType;
@ -89,7 +89,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -89,7 +89,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public FieldTypeReference(SRM.FieldDefinitionHandle fieldHandle,
SRM.MetadataReader metadata,
TypeAttributeOptions attributeOptions = TypeAttributeOptions.Default)
TypeAttributeOptions attributeOptions)
{
this.fieldHandle = fieldHandle;
this.metadata = metadata;
@ -98,7 +98,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -98,7 +98,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public FieldTypeReference(SRM.MemberReferenceHandle fieldReferenceHandle,
SRM.MetadataReader metadata,
TypeAttributeOptions attributeOptions = TypeAttributeOptions.Default)
TypeAttributeOptions attributeOptions)
{
this.fieldHandle = fieldReferenceHandle;
this.metadata = metadata;
@ -121,7 +121,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -121,7 +121,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public static IType Resolve(SRM.FieldDefinitionHandle fieldHandle,
SRM.MetadataReader metadata,
ITypeResolveContext context,
TypeAttributeOptions attributeOptions = TypeAttributeOptions.Default)
TypeAttributeOptions attributeOptions)
{
var fieldDef = metadata.GetFieldDefinition(fieldHandle);
IType ty = fieldDef.DecodeSignature(new TypeProvider(context.CurrentAssembly), context);
@ -141,7 +141,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -141,7 +141,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
readonly TypeAttributeOptions attributeOptions;
public UnresolvedMethodSignature(SRM.MethodDefinitionHandle handle, SRM.MetadataReader metadata,
TypeAttributeOptions attributeOptions = TypeAttributeOptions.Default)
TypeAttributeOptions attributeOptions)
{
this.handle = handle;
this.metadata = metadata;
@ -149,7 +149,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -149,7 +149,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
}
public UnresolvedMethodSignature(SRM.PropertyDefinitionHandle handle, SRM.MetadataReader metadata,
TypeAttributeOptions attributeOptions = TypeAttributeOptions.Default)
TypeAttributeOptions attributeOptions)
{
this.handle = handle;
this.metadata = metadata;
@ -165,12 +165,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -165,12 +165,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
case SRM.HandleKind.MethodDefinition:
return GetSignature(
metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)handle),
metadata, context
metadata, context, attributeOptions
);
case SRM.HandleKind.PropertyDefinition:
return GetSignature(
metadata.GetPropertyDefinition((SRM.PropertyDefinitionHandle)handle),
metadata, context
metadata, context, attributeOptions
);
default:
throw new InvalidOperationException();
@ -181,7 +181,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -181,7 +181,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public static SRM.MethodSignature<IType> GetSignature(SRM.MethodDefinition methodDef,
SRM.MetadataReader metadata, ITypeResolveContext context,
TypeAttributeOptions attributeOptions = TypeAttributeOptions.Default)
TypeAttributeOptions attributeOptions)
{
var typeProvider = new TypeProvider(context.CurrentAssembly);
var signature = methodDef.DecodeSignature(typeProvider, context);
@ -190,7 +190,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -190,7 +190,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public static SRM.MethodSignature<IType> GetSignature(SRM.PropertyDefinition propertyDef,
SRM.MetadataReader metadata, ITypeResolveContext context,
TypeAttributeOptions attributeOptions = TypeAttributeOptions.Default)
TypeAttributeOptions attributeOptions)
{
var typeProvider = new TypeProvider(context.CurrentAssembly);
var signature = propertyDef.DecodeSignature(typeProvider, context);

14
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedField.cs

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{
/// <summary>
@ -23,6 +25,16 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -23,6 +25,16 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
/// </summary>
public class SpecializedField : SpecializedMember, IField
{
internal static IField Create(IField fieldDefinition, TypeParameterSubstitution substitution)
{
if (TypeParameterSubstitution.Identity.Equals(substitution) || fieldDefinition.DeclaringType.TypeParameterCount == 0) {
return fieldDefinition;
}
if (substitution.MethodTypeArguments != null && substitution.MethodTypeArguments.Count > 0)
substitution = new TypeParameterSubstitution(substitution.ClassTypeArguments, EmptyList<IType>.Instance);
return new SpecializedField(fieldDefinition, substitution);
}
readonly IField fieldDefinition;
public SpecializedField(IField fieldDefinition, TypeParameterSubstitution substitution)
@ -31,7 +43,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -31,7 +43,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.fieldDefinition = fieldDefinition;
AddSubstitution(substitution);
}
public bool IsReadOnly {
get { return fieldDefinition.IsReadOnly; }
}

23
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs

@ -29,6 +29,21 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -29,6 +29,21 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
/// </summary>
public class SpecializedMethod : SpecializedParameterizedMember, IMethod
{
internal static IMethod Create(IMethod methodDefinition, TypeParameterSubstitution substitution)
{
if (TypeParameterSubstitution.Identity.Equals(substitution))
return methodDefinition;
if (methodDefinition.DeclaringType is ArrayType)
return new SpecializedMethod(methodDefinition, substitution);
if (methodDefinition.TypeParameters.Count == 0) {
if (methodDefinition.DeclaringType.TypeParameterCount == 0)
return methodDefinition;
if (substitution.MethodTypeArguments != null && substitution.MethodTypeArguments.Count > 0)
substitution = new TypeParameterSubstitution(substitution.ClassTypeArguments, EmptyList<IType>.Instance);
}
return new SpecializedMethod(methodDefinition, substitution);
}
readonly IMethod methodDefinition;
readonly ITypeParameter[] specializedTypeParameters;
readonly bool isParameterized;
@ -108,14 +123,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -108,14 +123,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return methodDefinition.IsOperator; }
}
public bool IsPartial {
get { return methodDefinition.IsPartial; }
}
public bool IsAsync {
get { return methodDefinition.IsAsync; }
}
public bool HasBody {
get { return methodDefinition.HasBody; }
}

10
ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs

@ -143,15 +143,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -143,15 +143,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
public bool IsOperator {
get { return baseMethod.IsOperator; }
}
public bool IsPartial {
get { return baseMethod.IsPartial; }
}
public bool IsAsync {
get { return baseMethod.IsAsync; }
}
public bool HasBody {
get { return baseMethod.HasBody; }
}

Loading…
Cancel
Save