1 /* 2 * Copyright (c) 2013, 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 27 * @summary verify start and end positions 28 * @run main TreeEndPosTest 29 */ 30 31 import java.io.ByteArrayOutputStream; 32 import java.io.File; 33 import java.io.IOException; 34 import java.io.PrintWriter; 35 import java.net.URI; 36 import java.util.ArrayList; 37 import java.util.List; 38 import javax.tools.Diagnostic; 39 import javax.tools.DiagnosticCollector; 40 import javax.tools.JavaCompiler; 41 import javax.tools.JavaFileManager; 42 import javax.tools.JavaFileObject; 43 import javax.tools.SimpleJavaFileObject; 44 import javax.tools.ToolProvider; 45 46 public class TreeEndPosTest { getJavaFileManager(JavaCompiler compiler, DiagnosticCollector dc)47 private static JavaFileManager getJavaFileManager(JavaCompiler compiler, 48 DiagnosticCollector dc) { 49 return compiler.getStandardFileManager(dc, null, null); 50 } 51 52 static class JavaSource extends SimpleJavaFileObject { 53 54 final String source; 55 int startPos; 56 int endPos; 57 JavaSource(String filename, String source)58 private JavaSource(String filename, String source) { 59 super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE); 60 this.source = source; 61 } 62 63 @Override getCharContent(boolean ignoreEncodingErrors)64 public CharSequence getCharContent(boolean ignoreEncodingErrors) { 65 return source; 66 } 67 createJavaSource(String preamble, String body, String postamble, String expected)68 static JavaSource createJavaSource(String preamble, String body, 69 String postamble, String expected) { 70 JavaSource js = createJavaSource(preamble, body, postamble, -1, -1); 71 js.startPos = js.source.indexOf(expected); 72 js.endPos = js.startPos + expected.length(); 73 return js; 74 } 75 createJavaSource(String body, String expected)76 static JavaSource createJavaSource(String body, String expected) { 77 return createJavaSource(null, body, null, expected); 78 } 79 createJavaSource(String preamble, String body, String postamble, int start, int end)80 private static JavaSource createJavaSource(String preamble, String body, 81 String postamble, int start, int end) { 82 final String name = "Bug"; 83 StringBuilder code = new StringBuilder(); 84 if (preamble != null) { 85 code.append(preamble); 86 } 87 code.append("public class " + name + "{"); 88 if (body != null) { 89 code.append(body); 90 } 91 code.append("}"); 92 if (postamble != null) { 93 code.append(postamble); 94 } 95 JavaSource js = new JavaSource(name + ".java", code.toString()); 96 js.startPos = start; 97 js.endPos = end; 98 return js; 99 } 100 } 101 main(String... args)102 public static void main(String... args) throws IOException { 103 testUninitializedVariable(); 104 testMissingAnnotationValue(); 105 testFinalVariableWithDefaultConstructor(); 106 testFinalVariableWithConstructor(); 107 } 108 testUninitializedVariable()109 static void testUninitializedVariable() throws IOException { 110 compile(JavaSource.createJavaSource("Object o = new A().new B(); class A { }", 111 "B()")); 112 } testMissingAnnotationValue()113 static void testMissingAnnotationValue() throws IOException { 114 compile(JavaSource.createJavaSource("@Foo(\"vvvv\")", 115 null, "@interface Foo { }", "\"vvvv\"")); 116 } 117 testFinalVariableWithDefaultConstructor()118 static void testFinalVariableWithDefaultConstructor() throws IOException { 119 compile(JavaSource.createJavaSource("private static final String Foo; public void bar() { }", 120 "private static final String Foo;")); 121 } 122 testFinalVariableWithConstructor()123 static void testFinalVariableWithConstructor() throws IOException { 124 compile(JavaSource.createJavaSource("public Bug (){} private static final String Foo; public void bar() { }", 125 "{}")); 126 } 127 compile(JavaSource src)128 static void compile(JavaSource src) throws IOException { 129 ByteArrayOutputStream ba = new ByteArrayOutputStream(); 130 PrintWriter writer = new PrintWriter(ba); 131 File tempDir = new File("."); 132 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 133 DiagnosticCollector dc = new DiagnosticCollector(); 134 JavaFileManager javaFileManager = getJavaFileManager(compiler, dc); 135 List<String> options = new ArrayList<>(); 136 options.add("-cp"); 137 options.add(tempDir.getPath()); 138 options.add("-d"); 139 options.add(tempDir.getPath()); 140 options.add("-XDshouldStopPolicy=GENERATE"); 141 142 List<JavaFileObject> sources = new ArrayList<>(); 143 sources.add(src); 144 JavaCompiler.CompilationTask task = 145 compiler.getTask(writer, javaFileManager, 146 dc, options, null, 147 sources); 148 task.call(); 149 for (Diagnostic diagnostic : (List<Diagnostic>) dc.getDiagnostics()) { 150 long actualStart = diagnostic.getStartPosition(); 151 long actualEnd = diagnostic.getEndPosition(); 152 System.out.println("Source: " + src.source); 153 System.out.println("Diagnostic: " + diagnostic); 154 System.out.print("Start position: Expected: " + src.startPos); 155 System.out.println(", Actual: " + actualStart); 156 System.out.print("End position: Expected: " + src.endPos); 157 System.out.println(", Actual: " + actualEnd); 158 if (src.startPos != actualStart || src.endPos != actualEnd) { 159 throw new RuntimeException("error: trees don't match"); 160 } 161 } 162 } 163 } 164