1 /* 2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8017216 8019422 8019421 8054956 27 * @summary verify start and end positions 28 * @modules java.compiler 29 * jdk.compiler 30 * @run main TreeEndPosTest 31 */ 32 33 import java.io.ByteArrayOutputStream; 34 import java.io.File; 35 import java.io.IOException; 36 import java.io.PrintWriter; 37 import java.net.URI; 38 import java.util.ArrayList; 39 import java.util.List; 40 import javax.tools.Diagnostic; 41 import javax.tools.DiagnosticCollector; 42 import javax.tools.JavaCompiler; 43 import javax.tools.JavaFileManager; 44 import javax.tools.JavaFileObject; 45 import javax.tools.SimpleJavaFileObject; 46 import javax.tools.ToolProvider; 47 48 public class TreeEndPosTest { getJavaFileManager(JavaCompiler compiler, DiagnosticCollector dc)49 private static JavaFileManager getJavaFileManager(JavaCompiler compiler, 50 DiagnosticCollector dc) { 51 return compiler.getStandardFileManager(dc, null, null); 52 } 53 54 static class JavaSource extends SimpleJavaFileObject { 55 56 final String source; 57 int startPos; 58 int endPos; 59 JavaSource(String filename, String source)60 private JavaSource(String filename, String source) { 61 super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE); 62 this.source = source; 63 } 64 65 @Override getCharContent(boolean ignoreEncodingErrors)66 public CharSequence getCharContent(boolean ignoreEncodingErrors) { 67 return source; 68 } 69 createJavaSource(String preamble, String body, String postamble, String expected)70 static JavaSource createJavaSource(String preamble, String body, 71 String postamble, String expected) { 72 JavaSource js = createJavaSource(preamble, body, postamble, -1, -1); 73 js.startPos = js.source.indexOf(expected); 74 js.endPos = js.startPos + expected.length(); 75 return js; 76 } 77 createJavaSource(String body, String expected)78 static JavaSource createJavaSource(String body, String expected) { 79 return createJavaSource(null, body, null, expected); 80 } 81 createJavaSource(String preamble, String body, String postamble, int start, int end)82 private static JavaSource createJavaSource(String preamble, String body, 83 String postamble, int start, int end) { 84 final String name = "Bug"; 85 StringBuilder code = new StringBuilder(); 86 if (preamble != null) { 87 code.append(preamble); 88 } 89 code.append("public class " + name + "{"); 90 if (body != null) { 91 code.append(body); 92 } 93 code.append("}"); 94 if (postamble != null) { 95 code.append(postamble); 96 } 97 JavaSource js = new JavaSource(name + ".java", code.toString()); 98 js.startPos = start; 99 js.endPos = end; 100 return js; 101 } 102 } 103 main(String... args)104 public static void main(String... args) throws IOException { 105 testUninitializedVariable(); 106 testMissingAnnotationValue(); 107 testUnresolvableAnnotationAttribute(); 108 testFinalVariableWithDefaultConstructor(); 109 testFinalVariableWithConstructor(); 110 } 111 testUninitializedVariable()112 static void testUninitializedVariable() throws IOException { 113 compile(JavaSource.createJavaSource("Object o = new A().new B(); class A { }", 114 "B()")); 115 } testMissingAnnotationValue()116 static void testMissingAnnotationValue() throws IOException { 117 compile(JavaSource.createJavaSource("@Foo(\"vvvv\")", 118 null, "@interface Foo { }", "\"vvvv\"")); 119 } 120 testUnresolvableAnnotationAttribute()121 static void testUnresolvableAnnotationAttribute() throws IOException { 122 compile(JavaSource.createJavaSource("@Foo(value=\"vvvv\")", 123 null, "@interface Foo { }", "value")); 124 } 125 testFinalVariableWithDefaultConstructor()126 static void testFinalVariableWithDefaultConstructor() throws IOException { 127 compile(JavaSource.createJavaSource("private static final String Foo; public void bar() { }", 128 "private static final String Foo;")); 129 } 130 testFinalVariableWithConstructor()131 static void testFinalVariableWithConstructor() throws IOException { 132 compile(JavaSource.createJavaSource("public Bug (){} private static final String Foo; public void bar() { }", 133 "{}")); 134 } 135 compile(JavaSource src)136 static void compile(JavaSource src) throws IOException { 137 ByteArrayOutputStream ba = new ByteArrayOutputStream(); 138 PrintWriter writer = new PrintWriter(ba); 139 File tempDir = new File("."); 140 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 141 DiagnosticCollector dc = new DiagnosticCollector(); 142 try (JavaFileManager javaFileManager = getJavaFileManager(compiler, dc)) { 143 List<String> options = new ArrayList<>(); 144 options.add("-cp"); 145 options.add(tempDir.getPath()); 146 options.add("-d"); 147 options.add(tempDir.getPath()); 148 options.add("--should-stop=at=GENERATE"); 149 150 List<JavaFileObject> sources = new ArrayList<>(); 151 sources.add(src); 152 JavaCompiler.CompilationTask task = 153 compiler.getTask(writer, javaFileManager, 154 dc, options, null, 155 sources); 156 task.call(); 157 for (Diagnostic diagnostic : (List<Diagnostic>) dc.getDiagnostics()) { 158 long actualStart = diagnostic.getStartPosition(); 159 long actualEnd = diagnostic.getEndPosition(); 160 System.out.println("Source: " + src.source); 161 System.out.println("Diagnostic: " + diagnostic); 162 System.out.print("Start position: Expected: " + src.startPos); 163 System.out.println(", Actual: " + actualStart); 164 System.out.print("End position: Expected: " + src.endPos); 165 System.out.println(", Actual: " + actualEnd); 166 if (src.startPos != actualStart || src.endPos != actualEnd) { 167 throw new RuntimeException("error: trees don't match"); 168 } 169 } 170 } 171 } 172 } 173