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

Reply via email to