What your trying to do is called static code analysis - specifically data flow analysis, but with a twist...you didn't show you are looking at source code, but at compiled code...if you want to do it at runtime, where you're having to deal with compiled (bytecode) code instead of source. So, you're looking for a library capable of bytecode data-flow analysis. There are quite a few libraries out there to help (now that you know what to search for, you can find alternatives to my recommendation if you would like).
OK, not getting to an example...I like javassist - I find it to be as clear as a bytecode library can be with great examples and documentation online. javassit has some higher-level bytecode analysis API, so you might not even have to dig down too deep, depending on what you need to do.
To print output for your Foo/Bar example above, use the following code:
public static void main (String... args) throws Exception {
Analyzer a = new Analyzer();
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("test.Foo");
for (CtMethod cm : cc.getDeclaredMethods()) {
Frame[] frames = a.analyze(cm);
for (Frame f : frames) {
System.out.println(f);
}
}
}
will print:
locals = [test.Foo, int, test.Bar] stack = []
locals = [test.Foo, int, test.Bar] stack = [int]
locals = [test.Foo, int, test.Bar] stack = [int, int]
null
null
locals = [test.Foo, int, test.Bar] stack = []
locals = [test.Foo, int, test.Bar] stack = [test.Bar]
null
null
locals = [test.Foo, int, test.Bar] stack = []
If you need more detail, you'll need to actually read the bytecode, and have the JVM specification handy:
public static void main (String... args) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("test.Foo");
for (CtMethod cm : cc.getDeclaredMethods()) {
MethodInfo mi = cm.getMethodInfo();
CodeAttribute ca = mi.getCodeAttribute();
CodeIterator ci = ca.iterator();
while (ci.hasNext()) {
int index = ci.next();
int op = ci.byteAt(index);
switch (op) {
case Opcode.INVOKEVIRTUAL:
System.out.println("virutal");
//lookup in the JVM spec how to extract the actual method
//call info here
break;
}
}
}
}
I hope this helps get you started =)