blob: e1a8be994527c1e9b72f263a6e7ca2aae26ffef2 [file] [log] [blame]
/*
* Copyright (c) 2013, 2016, 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
* @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;
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;
}
}
public static void main(String... args) throws IOException {
testUninitializedVariable();
testMissingAnnotationValue();
testUnresolvableAnnotationAttribute();
testFinalVariableWithDefaultConstructor();
testFinalVariableWithConstructor();
}
static void testUninitializedVariable() throws IOException {
compile(JavaSource.createJavaSource("Object o = new A().new B(); class A { }",
"B()"));
}
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() { }",
"{}"));
}
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("-Xshouldstop: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");
}
}
}
}
}