Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[jdt-core-dev] Code Instrumentation using ASTVisitor

Hi there,

I have some methods and I want to have some basic instrumentation done to them:
For example:

    public int foobar(){
        int j = 0;
        if (j > 0){
            int i = 2;
            int k =0;
        } else {
            int j =9;
        }
        return 2;
    }

Become.....

    public int foobar(){
        start = System.currentTimeMillis();
        int j = 0;
        stop = System.currentTimeMillis();
        total += stop - start;
        if (j > 0){
            start = System.currentTimeMillis();
            int i = 2;
            int k =0;
            stop = System.currentTimeMillis();
            total += stop - start;
        } else {
            start = System.currentTimeMillis();
            j = 9;
            stop = System.currentTimeMillis();
            total += stop - start;
        }
        int temp = 2;
        return temp;
    }


I thought editing the AST of the method body would be a good way to start.
So, I extended ASTVisitor having a method:

     public boolean visit (MethodDeclaration node){
         Block blk = node.getBody();
         LinkedList temp = parseStatements(node.getBody().statements());
         blk.statements().clear();
         blk.statements().addAll(temp);
         return false;
    }

and parseStatements(), basically is a switch with parseIf()calling parseStatements() recursively for its statement body:

    private LinkedList parseStatements(List statements) {
        LinkedList instrumentedStatements = new LinkedList();
        for (int i = 0; i < statements.size() ; i++){
            Statement state = (Statement)statements.get(i);
            switch(state.getNodeType()){
            case ASTNode.EXPRESSION_STATEMENT:
                               ......
            case ASTNode.VARIABLE_DECLARATION_STATEMENT:
                               ........
            case ASTNode.RETURN_STATEMENT:
                               .........
            case ASTNode.IF_STATEMENT:
                parseIf(instrumentedStatements, (IfStatement)state);
                break;
            default:
                break;
            }
        }
    }

private void parseIf(LinkedList instrumentedStatements, IfStatement statement) {
        List thenStatement =   ((Block)statement.getThenStatement()).statements();
       
        LinkedList thenList = new LinkedList();
        thenList = parseStatements(thenStatement);
       
        thenStatement.clear();
        thenStatement.addAll(thenList);
        ........ //Same for elseStatement

        instrumentedStatements.add(statement);
}

However I am getting exception:

     java.lang.StringIndexOutOfBoundsException: String index out of range: -96

when this is call later when I want to extract the modified AST

      TextEdit edits = cu.rewrite(doc,null);


All I did before my visitor is accepted:

                Document doc = new Document(myCompilationUnit.getSource());
                sourceCode = doc.get().toCharArray();
               
                ASTParser parser = ASTParser.newParser(AST.JLS2);  // handles JDK 1.0, 1.1, 1.2, 1.3, 1.4
                parser.setKind(ASTParser.K_COMPILATION_UNIT);
                parser.setResolveBindings(true);
                parser.setSource(sourceCode);
                parser.setUnitName(myCompilationUnit.getElementName());
                parser.setProject(myProject);
                CompilationUnit cu = (CompilationUnit)     parser.createAST(null);
                cu.recordModifications();



Any idea or help as to how I can add Instrumentation on AST would be very much appreciated. Thanks in advance !


Best Regards

Patrick

Back to the top