views:

213

answers:

9

I am looking to write a static analyser for a university class. To provide more power for the tool I would like to be able to look up the call hierarchy (as Ctrl+Alt+H does in Eclipse). This would also have to be a fast operation, so the lookup would probably have to be done against an index rather than bytecode scanning.

However, writing an Eclipse plugin would be too ambitious I expect. Instead I would rather decouple the parts of Eclipse which create the code index, and use a library to do lookups. The interface to the user would be on the command line, to simplify implementation.

I read that Eclipse uses Lucene to do the indexing[1], however, there must be a significant amount of work atop Lucene for the capabilities Eclipse allows.

The question is, is it possible to decouple the indexing capabilities of Eclipse for reuse? If not, are there other, readily available libraries available that could do the kind of processing I've discussed?

[1] Lucene In Action (IIRC)


EDIT

I think there's been some misunderstanding. I'm not looking to inspect the class hierarchy, I want to inspect the call hierarchy. That's why searching and indexing (of some kind, though maybe that's not the right term) comes into the discussion. Inspecting the class hierarchy is probably a lot less expensive than inspecting the call hierarchy.

As for writing an Eclipse plugin, yes I'd love to, but given this assignment is on a very short timescale it's probably unlikely I'll manage it. But it's useful information that some of you feel this is not as tough as I think it will be.

Perhaps I have put too much emphasis on Eclipse, it occurred to me I'm really looking for any tool that provides an API for inspecting a call graph through the bytecode.

Thanks for your answers so far!

A: 

Have you looked at ecj? It's the compiler portion of eclipse, factored out into a separate project.

Or you can use the JDT portion of eclipse: http://www.eclipse.org/jdt/core/index.php

Michael Donohue
+1  A: 

The operation you are looking for is not exactly indexing. Indexing is done to provide full text search. Finding the super-class of a given class is hardly text search.

You want to write an Eclipse plugin (rather simple, may be just a couple of classes) which uses JDT. You will need to write an AST (Abstract Syntax Tree) Visitor which will be used to analyze your code. You will then be able to resolve types and easily traverse the class hierarchy using the JDT facilities.

Check out my answer to this question.

zvikico
Please see my edit. I'm not looking to resolve the superclass, but call graphs for a particular method. Cheers.
Grundlefleck
Suppose you are now inspecting method foo, are you looking for all the methods invoked by foo or invoking foo? There's a great difference.
zvikico
Invoking foo. Invoking a constructor specifically.
Grundlefleck
A: 

Eclipse plugins really aren't that hard; they take a little getting used to, but not too long.

Think about adding whatever functionality you want to the eclipse IDE. You can leverage other plugin functionality (such as JDT, which includes the search functionality you're looking for).

You can then provide your plugins for all eclipse users to use, rather than develop another standalone tool.

Scott Stanchfield
A: 

I would go for a solution based on ASM, it will do the hard work, resolving hierarchy. Here is a simple analyser, that println the call hierarchy of Class given :

public class Analyzer {
    public static void main(String[] args) throws IOException {
     ClassReader classReader;
     ClassNode classNode;
     String fullyQualifiedClassName = args[0];
     String callHierarchy = "";
     while (null != fullyQualifiedClassName) {
      callHierarchy = " > " + fullyQualifiedClassName + callHierarchy;
      classReader = new ClassReader(fullyQualifiedClassName);
      classNode = new ClassNode();
      classReader.accept(classNode, 0);
      if (null != classNode.superName) {
       fullyQualifiedClassName = classNode.superName.replace('/', '.');
      } else {
       fullyQualifiedClassName = null;
      }
     }
     System.out.println(callHierarchy);
    }
}

Given java.util.TreeMap as argument, it prints

> java.lang.Object > java.util.AbstractMap > java.util.TreeMap

I know this is bytecode analysis, but to be honest, ASM is lightning fast and if all you need is Call Hierarchy, scanning won't take much time (nothing noticeable imo).

Hope this help :)

Olivier
Your example demonstrates the "Type hierarchy", I'm looking for the "Call Hierarchy". As in, if method A calls method B, and I look up the call hierarchy of B, it shows method A. This is more complicated than type hierarchy, and I think requires scanning the entire codebase. That's why I was looking for an indexed solution. Unless I've misunderstood something...
Grundlefleck
+3  A: 

Walking the byte code is not hard at all and is not slow either. We have performed static analysis of large Java code projects at interactive speeds. Since, you are short on time I would suggest that you modify something like a call graph viewer plugin[1] in eclipse. Also, Eclipse code is hard to comprehend, you are better off writing your own plugin that uses as much of Eclipse's undocumented API's as possible.

[1] http://www.eclipseplugincentral.com/Web%5FLinks-index-req-viewlink-cid-1326.html

mansu
+1 the link provides something interesting to explore.
Grundlefleck
I love this proposal: "use as much of Eclipse's undocumented APIs as possible". Are you serious?
Ira Baxter
I did it. It is time consuming but with persistence you can do it.
mansu
A: 

Have a look at IBM's WALA framework. Among other things, you can generate the Call Graph (CG) for your code base. In fact, pretty much everything in WALA starts with building the CG. You can modify their examples and replace the test data with your own.

mshomrat
A: 

I would ignore Eclipse entirely: it's just going to distract you.

If you're performing static analysis, you'll almost certainly want to analyze bytecode. To find the call hierarchy, you look for the invokeinstance, invokestatic, and invokespecial bytecodes (see the JVM spec). These reference a fully qualified class/methodname, and you can build your call hierarchy using a Map<FuncRef,Set<FuncRef>>, where FuncRef is a class you define to hold the method call information.

BCEL can help you with bytecode scanning.

However, you're going to have to do more work than that, particularly with invokeinstance, since you don't know what the real instance might be. Sometimes you can look backwards in the code to find an assignment, but more likely you're going to be guessing -- this is the Achilles heal of static analysis.

kdgregory
A: 

This is a GUI plugin to Eclipse that gives a visual representation of the call hierarchy. It's not a list, but it's a help.

http://www.certiv.net/projects/callgraph.html

Mike Capito
A: 

I suspect you will find that it's easier to write the plugin - for which Eclipse is designed and documented - than to extract the bits that are meant to be internal and build something else out of them.

Carl Manaster