United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6472751 SourcePositions.getStartPos returns incorrect value for enum constants
JDK-6472751 : SourcePositions.getStartPos returns incorrect value for enum constants

Details
Type:
Bug
Submit Date:
2006-09-20
Status:
Closed
Updated Date:
2012-01-13
Project Name:
JDK
Resolved Date:
2012-01-13
Component:
tools
OS:
generic
Sub-Component:
javac
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports
Relates:
Relates:

Sub Tasks

Description
SourcePositions.getStartPos() incorrectly returns -1 for enum constants. TreeInfo.java line 288 has:

	case(JCTree.VARDEF): {
	    JCVariableDecl node = (JCVariableDecl)tree;
	    if (node.mods.pos != Position.NOPOS) {
		return node.mods.pos;
	    } else {
		return getStartPos(node.vartype);
	    }

and you can see why it doesn't work for enum constants.
I'm lazy, so let me try to explain the problem one more time. If you still think you need a test case, I'll consider writing one.

The problem happens when I'm looking at the tree of enum constant declaration, like "ABC" of:

  enum E { ABC, DEF; }

Javac creates JCTree.JCVariableDecl node for 'ABC' (and 'DEF') Unlike other 'ordinary' field declarations or local variable declarations, this JCVariableDecl doesn't have the JCVariableDecl#vartype set. So when I try to access the start position of this JCVariableDecl, the following code runs:

	case(JCTree.VARDEF): {
	    JCVariableDecl node = (JCVariableDecl)tree;
	    if (node.mods.pos != Position.NOPOS) {
		return node.mods.pos;
	    } else {
		return getStartPos(node.vartype);
	    }

and I get NOPOS. The correct code should be: 

	case(JCTree.VARDEF): {
	    JCVariableDecl node = (JCVariableDecl)tree;
	    if (node.mods.pos != Position.NOPOS) {
		return node.mods.pos;
	    }
            if(node.vartype!=null) {
		return getStartPos(node.vartype);
	    }
            return node.sym.pos;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.JavacTask;
import com.sun.source.util.SourcePositions;
import com.sun.source.util.TreeScanner;
import com.sun.source.util.Trees;
import com.sun.tools.javac.util.List;
import java.io.IOException;
import java.net.URI;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;

public class T6472751 {
    static class MyFileObject extends SimpleJavaFileObject {
        public MyFileObject() {
            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
        }
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return "public enum Test { ABC, DEF; }";
        }
    }
    static Trees trees;
    static SourcePositions positions;
    public static void main(String[] args) throws IOException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        JavacTask task = (JavacTask) compiler.getTask(null, null, null, null, null, List.of(new MyFileObject()));
        trees = Trees.instance(task);
        positions = trees.getSourcePositions();
        Iterable<? extends CompilationUnitTree> asts = task.parse();
        for (CompilationUnitTree ast : asts) {
            new MyVisitor().scan(ast, null);
        }
    }
    
    static class MyVisitor extends TreeScanner<Void,Void> {
        @Override
        public Void scan(Tree node, Void ignored) {
            if (node == null)
                return null;
            System.out.format("%s: %s%n", node.getKind(), positions.getStartPosition(null,node));
            return super.scan(node, ignored);
        }

    }
}

                                    

Comments
EVALUATION

The synopsis is valid, but the reasoning in the Description is incorrect. The vartype is set in the JCVariableDecl but the position of the vartype is incorrectly set to NOPOS. See 6567414. Fixing that fixes this problem.
                                     
2010-01-14



Hardware and Software, Engineered to Work Together