Finding all USES of a class or function .... at runtime.

Say you have a class

static class teste
	{
	function test( s:String ) { Debug.Log("called with "+s); }
	}

Of course, anywhere at all in the project there could be calls such as:

teste.say("abc");
teste.say("def");
teste.say("mno");

What I would like to be able to do …

while the project is running on a device, find all the places where “teste.test()” is called. (Of course, some calls may not be constants, adding a further complication.)

Perhaps this is impossible and only really possible at editor-script time? (Like using Doxygen, say.)

Any experts in .Net / reflection / etc have any thoughts on this?

An interesting question. I would approach this problem by first modifying the speak method such, that it has an argument of who called it.

Then I would create,say class CallerList that contains a list of MonoBehaviours with a static function AddCaller(message:string, caller:MonoBehvaiour), and at each call to teste.speak I would add the caller to that list. The calling would be teste.speak("the message",this)

This way, you will have all calls to the stored in the list, which could be printed out or whatever you need to do with them. And the final result would be something like

function speak( s:String, caller:MonoBehaviour ){ voc.deutsche(phonemes(prosidics((s))); CallerList.AddCaller(s,caller); }

presudocode:
` class CallerList{
private static List monoBehaviourList
private static List messageList

static method AddCaller(string message, MonoBehaviour caller){
monoBehviourList.Add(caller)
messageList.Add(message)}
}`

I’ve seen the question a few days ago, but had no time to answer it.

AFAIK there’s no built-in way to do something like this because:

  • Reflection only works on types / classes / instances / members.
  • You need to find references in plain code which can’t be reflected, but only decompiled / disassembled.
  • Even when you have a disassembler / decompiler at runtime Unity doesn’t make the job very easy since you can use SendMessage / Invoke / or reflection to call a method or to change a value.

The only practical way would be to disassemble the code (not at runtime but after building it) and do a plain text search through the code. This is far from being automated, is not very reliable and still requires user interaction / knowledge to comprehend the findings.

At edit time, so before compilation, you can use MonoDevelop and it’s refactoring features and tools. However since i figured out that the “find references” feature could fail miserably, i don’t use it anymore. If i really need a more or less reliable list, i open the project in Visual Studio and search there :wink:

The funny thing is starting VisualStudio, open the project, search for references and switching back to Mono is faster than waiting for the “find references” in MonoDevelop…

Mono Cecil is supposed to enable injecting code into compiled assemblies, but the documentation is abysmal and I have never used myself. So I can’t offer any specifics on usage. But in theory you should be able to load a .NET DLL or EXE, find a method, modify its implementation, and then save out the results.