Getting the list of classes used within a Method

78 views
Skip to first unread message

Koush

unread,
Jan 13, 2010, 2:11:56 AM1/13/10
to mono-cecil
Suppose I have the following method:

public Thing MyMethod
{
Cat cat = new Cat();
Dog dog = new Dog();
return new Thing();
}

How would I get the list of classes that this method body uses? Ie...
Cat, Dog, and Thing.

Koush

Jb Evain

unread,
Jan 13, 2010, 2:45:26 AM1/13/10
to mono-...@googlegroups.com
Hey,

On 1/13/10, Koush <kou...@gmail.com> wrote:
> public Thing MyMethod
> {
> Cat cat = new Cat();
> Dog dog = new Dog();
> return new Thing();
> }
>
> How would I get the list of classes that this method body uses? Ie...
> Cat, Dog, and Thing.

Just iterate over the instructions in the body of MyMethod. Switch on
the opcode of the instruction, if its OperandType is InlineType, the
operand of the Instruction will be a TypeReference.

A InlineToken operand may also be a TypeReference (but it can be a
FieldReference or a MethodReference as well).

--
Jb Evain <j...@nurv.fr>

Dinis Cruz

unread,
Jan 18, 2010, 8:39:30 AM1/18/10
to mono-...@googlegroups.com
Koush, I think that if you look at CecilUtils.cs you will find the code you need (Question to MonoCecil guys, is this the right way to do this?)

public static List<MethodCalled> getMethodsCalledInsideAssembly(String assemblyToLoad)
        {
            try
            {
                var methodsCalled = new List<MethodCalled>();
                foreach (MethodDefinition methodDefinition in getMethods(assemblyToLoad))
                    methodsCalled.AddRange(getMethodsCalledInsideMethod(methodDefinition));
                return methodsCalled;
            }
            catch (Exception ex)
            {
                DI.log.ex(ex, "in CecilUtils.getMethodsCalledInsideAssembly");
                return null;
            }
        }

        public static List<MethodCalled> getMethodsCalledInsideMethod(MethodDefinition methodDefinition)
        {
            try
            {
                var methodsCalled = new List<MethodCalled>();
                if (methodDefinition.Body != null)
                {
                    SequencePoint currentSequencePoint = null;
                    foreach (Instruction instruction in methodDefinition.Body.Instructions)
                    {
                        currentSequencePoint = instruction.SequencePoint ?? currentSequencePoint;
                        if (instruction.Operand != null)
                        {
                            switch (instruction.Operand.GetType().Name)
                            {
                                case "MethodReference":
                                case "MethodDefinition":
                                    methodsCalled.Add(new MethodCalled((IMemberReference)instruction.Operand, currentSequencePoint));
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                }
                return methodsCalled;
            }
            catch (Exception ex)
            {
                DI.log.ex(ex, "in CecilUtils.getMethodsCalledInsideMethod");
                return null;
            }
        }

The code above will return a list of all methods called inside a method (or an assembly if you want the big list). The data returned is a list of type MethodCalled.cs which is basically a pointer to the IMemberReference and SequencePoint which if available will give you the source code location of that method call

public class MethodCalled
    {
        public IMemberReference memberReference { get; set;}
        public SequencePoint sequencePoint { get; set; }

        public MethodCalled(IMemberReference _memberReference, SequencePoint _sequencePoint)
        {
            memberReference = _memberReference;
            sequencePoint = _sequencePoint;
        }
    }

Hope this helps

Dinis Cruz

2010/1/13 Jb Evain <j...@nurv.fr>
--
--
mono-cecil

Reply all
Reply to author
Forward
0 new messages