In the following demo, the EMPTY_STATEMENT tree is given an end position that is smaller than its start position.
The end positions were correct prior to JDK 21, I wonder if this was affected by the changes for https://bugs.openjdk.org/browse/JDK-8305671
```
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.JavacTask;
import com.sun.source.util.TreeScanner;
import com.sun.tools.javac.tree.EndPosTable;
import com.sun.tools.javac.tree.JCTree;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
public class EndPos {
public static void main(String[] args) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
var source =
new SimpleJavaFileObject(URI.create("file://T.java"), JavaFileObject.Kind.SOURCE) {
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return """
package errorpronecrash;
;
public class ReproFile {}
""";
}
};
JavaCompiler.CompilationTask task =
compiler.getTask(null, null, null, List.of(), List.of(), List.of(source));
Iterable<? extends CompilationUnitTree> units = ((JavacTask) task).parse();
JCTree.JCCompilationUnit unit = (JCTree.JCCompilationUnit) units.iterator().next();
unit.accept(
new TreeScanner<Void, Void>() {
@Override
public Void scan(Tree tree, Void aVoid) {
if (tree != null) {
int start = ((JCTree) tree).getStartPosition();
int end = ((JCTree) tree).getEndPosition(unit.endPositions);
System.err.printf("[%d, %d] %s %s\n", start, end, tree.getKind(), tree);
}
return super.scan(tree, aVoid);
}
},
null);
}
}
```
$ javac --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED EndPos.java -d .
$ java --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED EndPos
[0, 24] PACKAGE package errorpronecrash;
[8, 23] IDENTIFIER errorpronecrash
[25, 24] EMPTY_STATEMENT ;
[27, 52] CLASS
public class ReproFile {
}
[27, 33] MODIFIERS public
The end positions were correct prior to JDK 21, I wonder if this was affected by the changes for https://bugs.openjdk.org/browse/JDK-8305671
```
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.Tree;
import com.sun.source.util.JavacTask;
import com.sun.source.util.TreeScanner;
import com.sun.tools.javac.tree.EndPosTable;
import com.sun.tools.javac.tree.JCTree;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
public class EndPos {
public static void main(String[] args) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
var source =
new SimpleJavaFileObject(URI.create("file://T.java"), JavaFileObject.Kind.SOURCE) {
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return """
package errorpronecrash;
;
public class ReproFile {}
""";
}
};
JavaCompiler.CompilationTask task =
compiler.getTask(null, null, null, List.of(), List.of(), List.of(source));
Iterable<? extends CompilationUnitTree> units = ((JavacTask) task).parse();
JCTree.JCCompilationUnit unit = (JCTree.JCCompilationUnit) units.iterator().next();
unit.accept(
new TreeScanner<Void, Void>() {
@Override
public Void scan(Tree tree, Void aVoid) {
if (tree != null) {
int start = ((JCTree) tree).getStartPosition();
int end = ((JCTree) tree).getEndPosition(unit.endPositions);
System.err.printf("[%d, %d] %s %s\n", start, end, tree.getKind(), tree);
}
return super.scan(tree, aVoid);
}
},
null);
}
}
```
$ javac --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED EndPos.java -d .
$ java --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED EndPos
[0, 24] PACKAGE package errorpronecrash;
[8, 23] IDENTIFIER errorpronecrash
[25, 24] EMPTY_STATEMENT ;
[27, 52] CLASS
public class ReproFile {
}
[27, 33] MODIFIERS public