Browse Source

implement proper fix for #179 + add unit test

pull/172/merge
Siegfried Pammer 14 years ago
parent
commit
439de223bf
  1. 11
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 28
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  3. 4
      ICSharpCode.Decompiler/Tests/Generics.cs

11
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -427,17 +427,6 @@ namespace ICSharpCode.Decompiler.Ast
astType = new MemberType { Target = nsType, MemberName = name }; astType = new MemberType { Target = nsType, MemberName = name };
} else { } else {
astType = new SimpleType(name); astType = new SimpleType(name);
// Look for generic type parameters defined in TypeDefinition
// allows us to display angle brackets in unbound type names
// e.g. typeof(List<>)
TypeDefinition resolvedType = type.Resolve();
if (!type.HasGenericParameters && resolvedType != null) {
for (int i = 0; i < resolvedType.GenericParameters.Count; i++) {
((SimpleType)astType).TypeArguments.Add(new SimpleType(""));
}
}
} }
astType.AddAnnotation(type); astType.AddAnnotation(type);

28
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -601,7 +601,7 @@ namespace ICSharpCode.Decompiler.Ast
case ILCode.Ldstr: return new Ast.PrimitiveExpression(operand); case ILCode.Ldstr: return new Ast.PrimitiveExpression(operand);
case ILCode.Ldtoken: case ILCode.Ldtoken:
if (operand is Cecil.TypeReference) { if (operand is Cecil.TypeReference) {
return new Ast.TypeOfExpression { Type = operandAsTypeRef }.Member("TypeHandle"); return new Ast.TypeOfExpression { Type = AddEmptyTypeArgumentsForUnboundGenerics(operandAsTypeRef) }.Member("TypeHandle");
} else { } else {
return InlineAssembly(byteCode, args); return InlineAssembly(byteCode, args);
} }
@ -749,6 +749,32 @@ namespace ICSharpCode.Decompiler.Ast
} }
} }
AstType AddEmptyTypeArgumentsForUnboundGenerics(AstType type)
{
TypeDefinition typeDef = type.Annotation<TypeReference>().Resolve();
if (typeDef == null || !typeDef.HasGenericParameters)
return type;
SimpleType sType = type as SimpleType;
MemberType mType = type as MemberType;
if (sType != null) {
while (typeDef.GenericParameters.Count > sType.TypeArguments.Count) {
sType.TypeArguments.Add(new SimpleType(""));
}
}
if (mType != null) {
AddEmptyTypeArgumentsForUnboundGenerics(mType.Target);
int outerTypeParamCount = typeDef.DeclaringType == null ? 0 : typeDef.DeclaringType.GenericParameters.Count;
while (typeDef.GenericParameters.Count - outerTypeParamCount > mType.TypeArguments.Count) {
mType.TypeArguments.Add(new SimpleType(""));
}
}
return type;
}
static readonly AstNode objectInitializerPattern = new AssignmentExpression( static readonly AstNode objectInitializerPattern = new AssignmentExpression(
new MemberReferenceExpression { new MemberReferenceExpression {
Target = new InitializedObjectExpression() Target = new InitializedObjectExpression()

4
ICSharpCode.Decompiler/Tests/Generics.cs

@ -60,6 +60,10 @@ public static class Generics
} }
} }
private static Type type1 = typeof(List<>);
private static Type type2 = typeof(Generics.MyArray<>);
private static Type type3 = typeof(List<>.Enumerator);
public static void MethodWithConstraint<T, S>() where T : class, S where S : ICloneable, new() public static void MethodWithConstraint<T, S>() where T : class, S where S : ICloneable, new()
{ {
} }

Loading…
Cancel
Save