Search code examples
parsingabstract-syntax-treeeclipse-jdt

accept method of CompilationUnit


I have used Standalone ASTParser to read the variable names, but it only shows the first declared variable. It is probably because of the addition of bw.close() but I can't get where else to put it. Moreover, I can't understand how accept method of CompilationUnit can print all declared variables when ASTParser constructor is called only once.

final CompilationUnit cu = (CompilationUnit) parser.createAST(null);

    cu.accept(new ASTVisitor() {

        Set names = new HashSet();
        BufferedWriter bw = new BufferedWriter(fw);
        public boolean visit(VariableDeclarationFragment node) {
            SimpleName name = node.getName();
            this.names.add(name.getIdentifier());
            try {
                bw.write("writin");
                bw.write("Declaration of '"+name+"' at line"+cu.getLineNumber(name.getStartPosition()));
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return false; // do not continue to avoid usage info
        }
    });

Solution

  • Without seeing your whole code, I can only guess...

    From what you said, I believe, you are calling bw.close() somewhere during your visit method? You should change that, so the BufferedWriter is only closed (and flushed), after the visiting is finished. To do this, declare a final BufferedWriter bw variable outside of the visitor scope and then close() it in a finally block.

    Here is a complete example:

    public static void parse(String fileContent) {
    
        ASTParser parser = ASTParser.newParser(AST.JLS8);
        parser.setKind(ASTParser.K_COMPILATION_UNIT);       
        parser.setSource(fileContent.toCharArray());
    
        final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
        final StringWriter writer = new StringWriter();
        final BufferedWriter bw = new BufferedWriter(writer);
    
        try{
            cu.accept(new ASTVisitor() {
                public boolean visit(VariableDeclarationFragment node) {
                    SimpleName name = node.getName();
                    try {
                        bw.write("writing ");
                        bw.write("Declaration of '"+name+"' at line "+cu.getLineNumber(name.getStartPosition()));
                        bw.write("\n");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return false; // do not continue to avoid usage info
                }
            });
        } finally{
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println(writer.getBuffer());
    }
    

    If you use the following class as (text) input,

    class TestClass{
        private Object field1;
        private Object field2;
    }
    

    you should see a similar output to this:

    writing Declaration of 'field1' at line 4
    writing Declaration of 'field2' at line 5