You r rite, i forgot about array types. Regarding fields (and other class members) i m not worried for my purpose since im only dealing with generic params within method scope. I agree, some kind of visitor or walker would be nice for this sort of thing
Sent from my HTC ----- Reply message ----- From: "Daniel Grunwald" <[email protected]> To: <[email protected]> Subject: [mono-cecil] Re: Locating all generic references Date: Mon, May 2, 2011 8:44 pm What about array types? You also need to replace the T in "T[]". In fact, you'd have to handle all the type specifications. For example, a field "volatile T member;" will require replacement of the GenericParameter within the OptionalModifierType when one wants to move the field to another class. I think replacing types is something that belongs directly into Cecil -- so far, all of my projects using Cecil have required something like this, even if its just for determining the parameter types of a generic method call. The visitor pattern works quite well for this - take a look at how System.Linq.Expressions.ExpressionVisitor can be used for replacing nodes within an expression tree. And it's useful for more than just replacements. For example, here are two type visitors I use in the NRefactory type system, where I've already implemented this idea: sealed class Substitution : TypeVisitor { readonly IType[] typeArguments; public Substitution(IType[] typeArguments) { this.typeArguments = typeArguments; } public override IType VisitTypeParameter(ITypeParameter type) { int index = type.Index; if (type.OwnerType == EntityType.TypeDefinition) { if (index >= 0 && index < typeArguments.Length) return typeArguments[index]; else return SharedTypes.UnknownType; } else { return type.VisitChildren(this); } } } // Usage: IType result = type.AcceptVisitor(new Substitution(typeArguments)); sealed class TypeClassificationVisitor : TypeVisitor { internal bool isOpen; public override IType VisitTypeParameter(ITypeParameter type) { isOpen = true; return type.VisitChildren(this); } } So TypeReference would have two methods: AcceptVisitor() is the regular visitor pattern and just calls the appropriate Visit-Method on the visitor. VisitChildren() will call AcceptVisitor() for all child types, and then reconstruct the type around the return values of those child calls. For non-TypeSpecifications, VisitChildren() simply is "return this;" For TypeSpecifications, it would look similar to this: public override IType VisitChildren(TypeVisitor visitor) // in ArrayType { IType e = elementType.AcceptVisitor(visitor); if (e == elementType) return this; else return new ArrayType(e, dimensions); } Daniel On 5/2/2011 10:44, Alex Corrado wrote: Hi, As far as I know, there is no easy way to do this, though I would love if someone proved me wrong. I'm working on an async method transformation that extracts method bodies into Cecil-generated nested classes. I wrote a couple of extension methods to fix up the generic type tokens. Basically, you will need to inspect every instruction that emits a type or method reference in the IL and replace any generic type tokens with the correct ones from the new method you created. You can use the methods I wrote to do that replacement if you'd like: .... -- -- mono-cecil
