1 /* 2 * Copyright (c) 2019, 2020, 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 8071961 27 * @summary Verify expected default constructor warnings are producted or not produced 28 * @library /tools/lib 29 * @modules jdk.compiler/com.sun.tools.javac.api 30 * jdk.compiler/com.sun.tools.javac.main 31 * @build toolbox.ToolBox toolbox.JavacTask toolbox.TestRunner 32 * @run main DefaultCtorWarningToolBox 33 */ 34 35 import java.io.IOException; 36 import java.nio.file.Path; 37 import java.nio.file.Paths; 38 import java.util.Arrays; 39 import java.util.List; 40 41 import java.io.InputStream; 42 import java.nio.file.Files; 43 import java.util.EnumSet; 44 import javax.tools.JavaFileManager; 45 import javax.tools.JavaFileObject; 46 import javax.tools.StandardLocation; 47 import javax.tools.ToolProvider; 48 import toolbox.JavacTask; 49 import toolbox.Task; 50 import toolbox.Task.Expect; 51 import toolbox.TestRunner; 52 import toolbox.ToolBox; 53 54 public class DefaultCtorWarningToolBox extends TestRunner { 55 56 private final ToolBox tb = new ToolBox(); 57 private final String fileSep = System.getProperty("file.separator"); 58 59 public DefaultCtorWarningToolBox() { 60 super(System.err); 61 } 62 63 public static void main(String... args) throws Exception { 64 new DefaultCtorWarningToolBox().runTests(); 65 } 66 67 @Test 68 public void testWithAndWithOutLint(Path base) throws IOException { 69 Path src = base.resolve("src"); 70 71 tb.writeJavaFiles(src, 72 MOD_INFO_SRC, 73 PKG1_BAR_SRC, PKG1_FOO_SRC, 74 PKG2_BAZ_SRC, PKG2_QUUX_SRC, 75 PKG3_CORGE_SRC, PKG3_GRAULT_SRC 76 ); 77 Path classes = base.resolve("classes"); 78 tb.createDirectories(classes); 79 80 List<String> log; 81 List<String> expected = List.of(""); 82 83 // Warning disabled, no messages expected 84 log = new JavacTask(tb) 85 .options("-Xlint:-missing-explicit-ctor", "-Werror") 86 .outdir(classes) 87 .files(tb.findJavaFiles(src)) 88 .run(Expect.SUCCESS) 89 .writeAll() 90 .getOutputLines(Task.OutputKind.DIRECT); 91 92 if (!expected.equals(log)) { 93 throw new AssertionError("Unexpected output: " + log); 94 } 95 96 expected = 97 List.of("Foo.java:4:8: compiler.warn.missing-explicit-ctor: pkg1.Foo, pkg1, mod", 98 "Foo.java:12:12: compiler.warn.missing-explicit-ctor: pkg1.Foo.FooNest, pkg1, mod", 99 "Foo.java:16:19: compiler.warn.missing-explicit-ctor: pkg1.Foo.StaticFooNest, pkg1, mod", 100 "3 warnings"); 101 102 // Warning enable, 103 log = new JavacTask(tb) 104 .options("-Xlint:missing-explicit-ctor", "-XDrawDiagnostics") 105 .outdir(classes) 106 .files(tb.findJavaFiles(src)) 107 .run(Expect.SUCCESS) 108 .writeAll() 109 .getOutputLines(Task.OutputKind.DIRECT); 110 111 if (!expected.equals(log)) { 112 throw new AssertionError("Unexpected output: " + log); 113 } 114 } 115 116 protected void runTests() throws Exception { 117 runTests(m -> new Object[] { Paths.get(m.getName()).toAbsolutePath() }); 118 } 119 120 private static final String MOD_INFO_SRC = 121 """ 122 module mod { 123 exports pkg1; 124 // Do *not* export pkg2. 125 exports pkg3 to java.base; 126 } 127 """; 128 129 private static final String PKG1_BAR_SRC = 130 """ 131 package pkg1; 132 133 // Neither the top-level class nor the nested classes should generate 134 // a warning since Bar is not public. 135 136 // No explicit constructor; use a default. 137 class Bar { 138 139 // No explicit constructor; use a default. 140 public class FooNest { 141 } 142 143 // No explicit constructor; use a default. 144 public static class StaticFooNest { 145 } 146 147 // Package-access classes 148 149 // No explicit constructor; use a default. 150 /*package*/ class PkgFooNest { 151 } 152 153 // No explicit constructor; use a default. 154 /*package*/ static class PkgStaticFooNest { 155 } 156 // Private classes 157 158 // No explicit constructor; use a default. 159 private class PrvFooNest { 160 } 161 162 // No explicit constructor; use a default. 163 private static class PrvStaticFooNest { 164 } 165 } 166 """; 167 168 private static final String PKG1_FOO_SRC = 169 """ 170 package pkg1; 171 172 // No explicit constructor; use a default. 173 public class Foo { 174 175 /* 176 * Of the nexted classes, only FooNest and StaticFooNest should 177 * generate warnings. 178 */ 179 180 // No explicit constructor; use a default. 181 public class FooNest { 182 } 183 184 // No explicit constructor; use a default. 185 public static class StaticFooNest { 186 } 187 188 // No explicit constructor; use a default. 189 @SuppressWarnings("missing-explicit-ctor") 190 public static class SuppressedStaticFooNest { 191 } 192 193 // Package-access classes 194 195 // No explicit constructor; use a default. 196 /*package*/ class PkgFooNest { 197 } 198 199 // No explicit constructor; use a default. 200 /*package*/ static class PkgStaticFooNest { 201 } 202 // Private classes 203 204 // No explicit constructor; use a default. 205 private class PrvFooNest { 206 } 207 208 // No explicit constructor; use a default. 209 private static class PrvStaticFooNest { 210 } 211 } 212 """; 213 214 private static final String PKG2_BAZ_SRC = 215 """ 216 package pkg2; 217 218 // None of these classes should generate warnings since pkg2 is not 219 // exported unconditionally. 220 221 // No explicit constructor; use a default. 222 public class Baz { 223 224 // No explicit constructor; use a default. 225 public class FooNest { 226 } 227 228 // No explicit constructor; use a default. 229 public static class StaticFooNest { 230 } 231 232 // Package-access classes 233 234 // No explicit constructor; use a default. 235 /*package*/ class PkgFooNest { 236 } 237 238 // No explicit constructor; use a default. 239 /*package*/ static class PkgStaticFooNest { 240 } 241 // Private classes 242 243 // No explicit constructor; use a default. 244 private class PrvFooNest { 245 } 246 247 // No explicit constructor; use a default. 248 private static class PrvStaticFooNest { 249 } 250 } 251 """; 252 253 private static final String PKG2_QUUX_SRC = 254 """ 255 package pkg2; 256 257 // Neither the top-level class nor the nested classes should generate 258 // a warning since Bar is not public. 259 260 // No explicit constructor; use a default. 261 class Quux { 262 263 // No explicit constructor; use a default. 264 public class FooNest { 265 } 266 267 // No explicit constructor; use a default. 268 public static class StaticFooNest { 269 } 270 271 // Package-access classes 272 273 // No explicit constructor; use a default. 274 /*package*/ class PkgFooNest { 275 } 276 277 // No explicit constructor; use a default. 278 /*package*/ static class PkgStaticFooNest { 279 } 280 // Private classes 281 282 // No explicit constructor; use a default. 283 private class PrvFooNest { 284 } 285 286 // No explicit constructor; use a default. 287 private static class PrvStaticFooNest { 288 } 289 } 290 """; 291 292 private static final String PKG3_CORGE_SRC = 293 """ 294 package pkg3; 295 296 // None of these classes should generate warnings since pkg3 is not 297 // exported unconditionally. 298 299 // No explicit constructor; use a default. 300 public class Corge { 301 302 // No explicit constructor; use a default. 303 public class FooNest { 304 } 305 306 // No explicit constructor; use a default. 307 public static class StaticFooNest { 308 } 309 310 // Package-access classes 311 312 // No explicit constructor; use a default. 313 /*package*/ class PkgFooNest { 314 } 315 316 // No explicit constructor; use a default. 317 /*package*/ static class PkgStaticFooNest { 318 } 319 // Private classes 320 321 // No explicit constructor; use a default. 322 private class PrvFooNest { 323 } 324 325 // No explicit constructor; use a default. 326 private static class PrvStaticFooNest { 327 } 328 } 329 """; 330 331 private static final String PKG3_GRAULT_SRC = 332 """ 333 package pkg3; 334 335 // None of these classes should generate warnings since pkg3 is not 336 // exported unconditionally. 337 338 // No explicit constructor; use a default. 339 class Grault { 340 341 // No explicit constructor; use a default. 342 public class FooNest { 343 } 344 345 // No explicit constructor; use a default. 346 public static class StaticFooNest { 347 } 348 349 // Package-access classes 350 351 // No explicit constructor; use a default. 352 /*package*/ class PkgFooNest { 353 } 354 355 // No explicit constructor; use a default. 356 /*package*/ static class PkgStaticFooNest { 357 } 358 // Private classes 359 360 // No explicit constructor; use a default. 361 private class PrvFooNest { 362 } 363 364 // No explicit constructor; use a default. 365 private static class PrvStaticFooNest { 366 } 367 } 368 """; 369 }