6fa25cc134
Reviewed-by: vromero
236 lines
9.3 KiB
Java
236 lines
9.3 KiB
Java
/*
|
|
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 8017216 8019422 8019421 8054956 8205418
|
|
* @summary verify start and end positions
|
|
* @modules java.compiler
|
|
* jdk.compiler
|
|
* @run main TreeEndPosTest
|
|
*/
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.PrintWriter;
|
|
import java.net.URI;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import javax.tools.Diagnostic;
|
|
import javax.tools.DiagnosticCollector;
|
|
import javax.tools.JavaCompiler;
|
|
import javax.tools.JavaFileManager;
|
|
import javax.tools.JavaFileObject;
|
|
import javax.tools.SimpleJavaFileObject;
|
|
import javax.tools.ToolProvider;
|
|
import com.sun.source.tree.CompilationUnitTree;
|
|
import com.sun.source.tree.Tree;
|
|
import com.sun.source.tree.Tree.Kind;
|
|
import com.sun.source.util.JavacTask;
|
|
import com.sun.source.util.SourcePositions;
|
|
import com.sun.source.util.TreeScanner;
|
|
import com.sun.source.util.Trees;
|
|
|
|
public class TreeEndPosTest {
|
|
private static JavaFileManager getJavaFileManager(JavaCompiler compiler,
|
|
DiagnosticCollector dc) {
|
|
return compiler.getStandardFileManager(dc, null, null);
|
|
}
|
|
|
|
static class JavaSource extends SimpleJavaFileObject {
|
|
|
|
final String source;
|
|
int startPos;
|
|
int endPos;
|
|
|
|
private JavaSource(String filename, String source) {
|
|
super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
|
|
this.source = source;
|
|
}
|
|
|
|
@Override
|
|
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
|
return source;
|
|
}
|
|
|
|
static JavaSource createJavaSource(String preamble, String body,
|
|
String postamble, String expected) {
|
|
JavaSource js = createJavaSource(preamble, body, postamble, -1, -1);
|
|
js.startPos = js.source.indexOf(expected);
|
|
js.endPos = js.startPos + expected.length();
|
|
return js;
|
|
}
|
|
|
|
static JavaSource createJavaSource(String body, String expected) {
|
|
return createJavaSource(null, body, null, expected);
|
|
}
|
|
|
|
private static JavaSource createJavaSource(String preamble, String body,
|
|
String postamble, int start, int end) {
|
|
final String name = "Bug";
|
|
StringBuilder code = new StringBuilder();
|
|
if (preamble != null) {
|
|
code.append(preamble);
|
|
}
|
|
code.append("public class " + name + "{");
|
|
if (body != null) {
|
|
code.append(body);
|
|
}
|
|
code.append("}");
|
|
if (postamble != null) {
|
|
code.append(postamble);
|
|
}
|
|
JavaSource js = new JavaSource(name + ".java", code.toString());
|
|
js.startPos = start;
|
|
js.endPos = end;
|
|
return js;
|
|
}
|
|
|
|
static JavaSource createFullJavaSource(String code) {
|
|
final String name = "Bug";
|
|
String[] parts = code.split("\\|", 3);
|
|
JavaSource js = new JavaSource(name + ".java", parts[0] + parts[1] + parts[2]);
|
|
js.startPos = parts[0].length();
|
|
js.endPos = parts[0].length() + parts[1].length();
|
|
return js;
|
|
}
|
|
}
|
|
|
|
public static void main(String... args) throws IOException {
|
|
testUninitializedVariable();
|
|
testMissingAnnotationValue();
|
|
testUnresolvableAnnotationAttribute();
|
|
testFinalVariableWithDefaultConstructor();
|
|
testFinalVariableWithConstructor();
|
|
testWholeTextSpan();
|
|
}
|
|
|
|
static void testUninitializedVariable() throws IOException {
|
|
compile(JavaSource.createJavaSource("Object o = new A().new BT(); class A { }",
|
|
"BT"));
|
|
}
|
|
static void testMissingAnnotationValue() throws IOException {
|
|
compile(JavaSource.createJavaSource("@Foo(\"vvvv\")",
|
|
null, "@interface Foo { }", "\"vvvv\""));
|
|
}
|
|
|
|
static void testUnresolvableAnnotationAttribute() throws IOException {
|
|
compile(JavaSource.createJavaSource("@Foo(value=\"vvvv\")",
|
|
null, "@interface Foo { }", "value"));
|
|
}
|
|
|
|
static void testFinalVariableWithDefaultConstructor() throws IOException {
|
|
compile(JavaSource.createJavaSource("private static final String Foo; public void bar() { }",
|
|
"private static final String Foo;"));
|
|
}
|
|
|
|
static void testFinalVariableWithConstructor() throws IOException {
|
|
compile(JavaSource.createJavaSource("public Bug (){} private static final String Foo; public void bar() { }",
|
|
"private static final String Foo;"));
|
|
}
|
|
|
|
static void testWholeTextSpan() throws IOException {
|
|
treeSpan(JavaSource.createFullJavaSource("|class X |"));
|
|
}
|
|
|
|
static void compile(JavaSource src) throws IOException {
|
|
ByteArrayOutputStream ba = new ByteArrayOutputStream();
|
|
PrintWriter writer = new PrintWriter(ba);
|
|
File tempDir = new File(".");
|
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
|
DiagnosticCollector dc = new DiagnosticCollector();
|
|
try (JavaFileManager javaFileManager = getJavaFileManager(compiler, dc)) {
|
|
List<String> options = new ArrayList<>();
|
|
options.add("-cp");
|
|
options.add(tempDir.getPath());
|
|
options.add("-d");
|
|
options.add(tempDir.getPath());
|
|
options.add("--should-stop=at=GENERATE");
|
|
|
|
List<JavaFileObject> sources = new ArrayList<>();
|
|
sources.add(src);
|
|
JavaCompiler.CompilationTask task =
|
|
compiler.getTask(writer, javaFileManager,
|
|
dc, options, null,
|
|
sources);
|
|
task.call();
|
|
for (Diagnostic diagnostic : (List<Diagnostic>) dc.getDiagnostics()) {
|
|
long actualStart = diagnostic.getStartPosition();
|
|
long actualEnd = diagnostic.getEndPosition();
|
|
System.out.println("Source: " + src.source);
|
|
System.out.println("Diagnostic: " + diagnostic);
|
|
System.out.print("Start position: Expected: " + src.startPos);
|
|
System.out.println(", Actual: " + actualStart);
|
|
System.out.print("End position: Expected: " + src.endPos);
|
|
System.out.println(", Actual: " + actualEnd);
|
|
if (src.startPos != actualStart || src.endPos != actualEnd) {
|
|
throw new RuntimeException("error: trees don't match");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void treeSpan(JavaSource src) throws IOException {
|
|
ByteArrayOutputStream ba = new ByteArrayOutputStream();
|
|
PrintWriter writer = new PrintWriter(ba);
|
|
File tempDir = new File(".");
|
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
|
DiagnosticCollector dc = new DiagnosticCollector();
|
|
try (JavaFileManager javaFileManager = getJavaFileManager(compiler, dc)) {
|
|
List<String> options = new ArrayList<>();
|
|
options.add("-cp");
|
|
options.add(tempDir.getPath());
|
|
options.add("-d");
|
|
options.add(tempDir.getPath());
|
|
options.add("--should-stop=at=GENERATE");
|
|
|
|
List<JavaFileObject> sources = new ArrayList<>();
|
|
sources.add(src);
|
|
JavacTask task = (JavacTask) compiler.getTask(writer, javaFileManager,
|
|
dc, options, null,
|
|
sources);
|
|
SourcePositions sp = Trees.instance(task).getSourcePositions();
|
|
boolean[] found = new boolean[1];
|
|
new TreeScanner<Void, Void>() {
|
|
CompilationUnitTree cut;
|
|
@Override
|
|
public Void scan(Tree tree, Void p) {
|
|
if (tree == null)
|
|
return null;
|
|
if (tree.getKind() == Kind.COMPILATION_UNIT) {
|
|
cut = (CompilationUnitTree) tree;
|
|
}
|
|
found[0] |= (sp.getStartPosition(cut, tree) == src.startPos) &&
|
|
(sp.getEndPosition(cut, tree) == src.endPos);
|
|
return super.scan(tree, p);
|
|
}
|
|
}.scan(task.parse(), null);
|
|
|
|
if (!found[0]) {
|
|
throw new IllegalStateException();
|
|
}
|
|
}
|
|
}
|
|
}
|