diff --git a/ICSharpCode.Decompiler/CSharp/Resolver/ReducedExtensionMethod.cs b/ICSharpCode.Decompiler/CSharp/Resolver/ReducedExtensionMethod.cs
index aac351c75..b0910838e 100644
--- a/ICSharpCode.Decompiler/CSharp/Resolver/ReducedExtensionMethod.cs
+++ b/ICSharpCode.Decompiler/CSharp/Resolver/ReducedExtensionMethod.cs
@@ -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;
diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
index cca707708..0ac002e06 100644
--- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
+++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
@@ -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)) {
diff --git a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
index a66dd3eb2..1bc1d4a49 100644
--- a/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
+++ b/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
@@ -339,6 +339,7 @@
+
diff --git a/ICSharpCode.Decompiler/Metadata/SignatureBlobComparer.cs b/ICSharpCode.Decompiler/Metadata/SignatureBlobComparer.cs
index 317d35383..556839487 100644
--- a/ICSharpCode.Decompiler/Metadata/SignatureBlobComparer.cs
+++ b/ICSharpCode.Decompiler/Metadata/SignatureBlobComparer.cs
@@ -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))
diff --git a/ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs b/ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
index 4db17bf92..21a16d3a4 100644
--- a/ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
@@ -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
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
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
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 classTypeArguments = null;
- IReadOnlyList methodTypeArguments = null;
- SRM.MethodSignature? 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.Instance);
+ }
+ return method;
+ }
+
+ ///
+ /// Resolves a method reference.
+ ///
+ ///
+ /// Class type arguments are provided by the declaring type stored in the memberRef.
+ /// Method type arguments are provided by the caller.
+ ///
+ IMethod ResolveMethodReference(SRM.MetadataReader metadata, SRM.MemberReferenceHandle memberRefHandle, IReadOnlyList methodTypeArguments = null)
+ {
+ var memberRef = metadata.GetMemberReference(memberRefHandle);
+ Debug.Assert(memberRef.GetKind() == SRM.MemberReferenceKind.Method);
+ SRM.MethodSignature signature;
+ IReadOnlyList 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 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 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
return method.Parameters.Count > 0 && method.Parameters[method.Parameters.Count - 1].Type.Kind == TypeKind.ArgList;
}
- static bool CompareSignatures(IReadOnlyList parameters, IType[] parameterTypes)
+ static bool CompareSignatures(IReadOnlyList parameters, ImmutableArray parameterTypes)
{
if (parameterTypes.Length != parameters.Count)
return false;
@@ -431,40 +444,38 @@ namespace ICSharpCode.Decompiler.TypeSystem
///
/// Create a dummy IMethod from the specified MethodReference
///
- IMethod CreateFakeMethod(IType declaringType, string name, SRM.MethodSignature signature)
+ IMethod CreateFakeMethod(IType declaringType, string name, SRM.MethodSignature 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();
+ 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();
+ 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
diff --git a/ICSharpCode.Decompiler/TypeSystem/IMethod.cs b/ICSharpCode.Decompiler/TypeSystem/IMethod.cs
index 38c57d2f6..be826eb32 100644
--- a/ICSharpCode.Decompiler/TypeSystem/IMethod.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/IMethod.cs
@@ -105,18 +105,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
bool IsDestructor { get; }
bool IsOperator { get; }
- ///
- /// 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.
- ///
- ///
- bool IsPartial { get; }
-
- ///
- /// Gets whether the method is a C#-style async method.
- ///
- bool IsAsync { get; }
-
///
/// Gets whether the method has a body.
/// This property returns false for abstract or extern methods,
diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedField.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedField.cs
index f0f8cba79..b76499b56 100644
--- a/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedField.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedField.cs
@@ -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.Instance);
- return new SpecializedField(this, substitution);
+ return SpecializedField.Create(this, substitution);
}
}
}
diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedMethod.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedMethod.cs
index 130356be8..825fc28a9 100644
--- a/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedMethod.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultResolvedMethod.cs
@@ -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
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.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()
diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs
new file mode 100644
index 000000000..a67986d41
--- /dev/null
+++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs
@@ -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
+{
+ ///
+ /// Base class for fake members.
+ ///
+ 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.ImplementedInterfaceMembers => EmptyList.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 IEntity.Attributes => EmptyList.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 IMethod.Parts => throw new NotImplementedException();
+
+ IReadOnlyList IMethod.ReturnTypeAttributes => EmptyList.Instance;
+
+ public IReadOnlyList TypeParameters { get; set; } = EmptyList.Instance;
+
+ IReadOnlyList 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 Parameters { get; set; } = EmptyList.Instance;
+
+ public override IMember Specialize(TypeParameterSubstitution substitution)
+ {
+ return SpecializedMethod.Create(this, substitution);
+ }
+
+ IMethod IMethod.Specialize(TypeParameterSubstitution substitution)
+ {
+ return SpecializedMethod.Create(this, substitution);
+ }
+ }
+}
diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs
index 53489636c..60fb3f19f 100644
--- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs
@@ -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
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
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
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
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
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
}
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
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
public static SRM.MethodSignature 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
public static SRM.MethodSignature 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);
diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedField.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedField.cs
index 762f95117..986757f92 100644
--- a/ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedField.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedField.cs
@@ -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
{
///
@@ -23,6 +25,16 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
///
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.Instance);
+ return new SpecializedField(fieldDefinition, substitution);
+ }
+
readonly IField fieldDefinition;
public SpecializedField(IField fieldDefinition, TypeParameterSubstitution substitution)
@@ -31,7 +43,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.fieldDefinition = fieldDefinition;
AddSubstitution(substitution);
}
-
+
public bool IsReadOnly {
get { return fieldDefinition.IsReadOnly; }
}
diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs
index b5e23c2bc..30689c772 100644
--- a/ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs
@@ -29,6 +29,21 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
///
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.Instance);
+ }
+ return new SpecializedMethod(methodDefinition, substitution);
+ }
+
readonly IMethod methodDefinition;
readonly ITypeParameter[] specializedTypeParameters;
readonly bool isParameterized;
@@ -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; }
}
diff --git a/ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs b/ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs
index 66a766d55..e8eec0c98 100644
--- a/ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs
+++ b/ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs
@@ -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; }
}