Browse Source

Support references to specialized methods/fields.

pull/728/head
Daniel Grunwald 11 years ago
parent
commit
0cde213429
  1. 52
      ICSharpCode.Decompiler/DecompilerTypeSystem.cs

52
ICSharpCode.Decompiler/DecompilerTypeSystem.cs

@ -5,6 +5,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.NRefactory.TypeSystem.Implementation;
using Mono.Cecil; using Mono.Cecil;
@ -131,25 +132,18 @@ namespace ICSharpCode.Decompiler
lock (fieldLookupCache) { lock (fieldLookupCache) {
IField field; IField field;
if (!fieldLookupCache.TryGetValue(fieldReference, out field)) { if (!fieldLookupCache.TryGetValue(fieldReference, out field)) {
field = GetNonGenericField(fieldReference); field = FindNonGenericField(fieldReference);
// TODO: specialize the field if necessary if (fieldReference.DeclaringType.IsGenericInstance) {
fieldLookupCache[fieldReference] = field; var git = (GenericInstanceType)fieldReference.DeclaringType;
var typeArguments = git.GenericArguments.SelectArray(GetType);
field = (IField)field.Specialize(new TypeParameterSubstitution(typeArguments, null));
}
fieldLookupCache.Add(fieldReference, field);
} }
return field; return field;
} }
} }
IField GetNonGenericField(FieldReference fieldReference)
{
Debug.Assert(Monitor.IsEntered(fieldLookupCache));
IField field;
if (!fieldLookupCache.TryGetValue(fieldReference, out field)) {
field = FindNonGenericField(fieldReference);
fieldLookupCache.Add(fieldReference, field);
}
return field;
}
IField FindNonGenericField(FieldReference fieldReference) IField FindNonGenericField(FieldReference fieldReference)
{ {
ITypeDefinition typeDef = GetType(fieldReference.DeclaringType).GetDefinition(); ITypeDefinition typeDef = GetType(fieldReference.DeclaringType).GetDefinition();
@ -195,26 +189,26 @@ namespace ICSharpCode.Decompiler
lock (methodLookupCache) { lock (methodLookupCache) {
IMethod method; IMethod method;
if (!methodLookupCache.TryGetValue(methodReference, out method)) { if (!methodLookupCache.TryGetValue(methodReference, out method)) {
method = GetNonGenericMethod(methodReference.GetElementMethod()); method = FindNonGenericMethod(methodReference.GetElementMethod());
// TODO: specialize the method if (methodReference.IsGenericInstance || methodReference.DeclaringType.IsGenericInstance) {
IList<IType> classTypeArguments = null;
methodLookupCache[methodReference] = method; IList<IType> methodTypeArguments = null;
if (methodReference.IsGenericInstance) {
var gim = ((GenericInstanceMethod)methodReference);
methodTypeArguments = gim.GenericArguments.SelectArray(GetType);
}
if (methodReference.DeclaringType.IsGenericInstance) {
var git = (GenericInstanceType)methodReference.DeclaringType;
classTypeArguments = git.GenericArguments.SelectArray(GetType);
}
method = method.Specialize(new TypeParameterSubstitution(classTypeArguments, methodTypeArguments));
}
methodLookupCache.Add(methodReference, method);
} }
return method; return method;
} }
} }
IMethod GetNonGenericMethod(MethodReference methodReference)
{
Debug.Assert(Monitor.IsEntered(methodLookupCache));
IMethod method;
if (!methodLookupCache.TryGetValue(methodReference, out method)) {
method = FindNonGenericMethod(methodReference);
methodLookupCache.Add(methodReference, method);
}
return method;
}
IMethod FindNonGenericMethod(MethodReference methodReference) IMethod FindNonGenericMethod(MethodReference methodReference)
{ {
ITypeDefinition typeDef = GetType(methodReference.DeclaringType).GetDefinition(); ITypeDefinition typeDef = GetType(methodReference.DeclaringType).GetDefinition();

Loading…
Cancel
Save