EdgeCases.java revision 3294:9adfb22ff08f
1/* 2 * Copyright (c) 2015, 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 * @summary tests for multi-module mode compilation 27 * @library /tools/lib 28 * @modules 29 * jdk.compiler/com.sun.tools.javac.api 30 * jdk.compiler/com.sun.tools.javac.code 31 * jdk.compiler/com.sun.tools.javac.main 32 * jdk.jdeps/com.sun.tools.javap 33 * @build ToolBox ModuleTestBase 34 * @run main EdgeCases 35 */ 36 37import java.io.Writer; 38import java.nio.file.Files; 39import java.nio.file.Path; 40import java.nio.file.Paths; 41import java.util.Arrays; 42import java.util.HashSet; 43import java.util.List; 44import java.util.Objects; 45import java.util.Set; 46 47import javax.lang.model.element.Element; 48import javax.tools.JavaCompiler; 49import javax.tools.JavaFileObject; 50import javax.tools.StandardJavaFileManager; 51import javax.tools.ToolProvider; 52 53import com.sun.source.tree.CompilationUnitTree; 54import com.sun.source.util.JavacTask; 55import com.sun.tools.javac.api.JavacTaskImpl; 56import com.sun.tools.javac.code.Symbol.ModuleSymbol; 57 58public class EdgeCases extends ModuleTestBase { 59 60 public static void main(String... args) throws Exception { 61 new EdgeCases().runTests(); 62 } 63 64 @Test 65 void testAddExportUndefinedModule(Path base) throws Exception { 66 Path src = base.resolve("src"); 67 tb.writeJavaFiles(src, "package test; import undef.Any; public class Test {}"); 68 Path classes = base.resolve("classes"); 69 tb.createDirectories(classes); 70 71 List<String> log = tb.new JavacTask() 72 .options("-XaddExports:undef/undef=ALL-UNNAMED", "-XDrawDiagnostics") 73 .outdir(classes) 74 .files(findJavaFiles(src)) 75 .run(ToolBox.Expect.FAIL) 76 .writeAll() 77 .getOutputLines(ToolBox.OutputKind.DIRECT); 78 79 List<String> expected = Arrays.asList("- compiler.err.cant.find.module: undef", 80 "Test.java:1:27: compiler.err.doesnt.exist: undef", 81 "2 errors"); 82 83 if (!expected.equals(log)) 84 throw new Exception("expected output not found: " + log); 85 } 86 87 @Test 88 void testModuleSymbolOutterMostClass(Path base) throws Exception { 89 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 90 try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { 91 Path moduleSrc = base.resolve("module-src"); 92 Path m1 = moduleSrc.resolve("m1"); 93 94 tb.writeJavaFiles(m1, "module m1 { }"); 95 96 Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(findJavaFiles(moduleSrc)); 97 JavacTask task = (JavacTask) compiler.getTask(null, fm, null, null, null, files); 98 99 task.analyze(); 100 101 ModuleSymbol msym = (ModuleSymbol) task.getElements().getModuleElement("m1"); 102 103 msym.outermostClass(); 104 } 105 } 106 107 @Test 108 void testParseEnterAnalyze(Path base) throws Exception { 109 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 110 try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) { 111 Path moduleSrc = base.resolve("module-src"); 112 Path m1 = moduleSrc.resolve("m1"); 113 114 tb.writeJavaFiles(m1, "module m1 { }", 115 "package p;", 116 "package p; class T { }"); 117 118 Path classes = base.resolve("classes"); 119 Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(findJavaFiles(moduleSrc)); 120 List<String> options = Arrays.asList("-d", classes.toString(), "-Xpkginfo:always"); 121 JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, fm, null, options, null, files); 122 123 Iterable<? extends CompilationUnitTree> parsed = task.parse(); 124 Iterable<? extends Element> entered = task.enter(parsed); 125 Iterable<? extends Element> analyzed = task.analyze(entered); 126 Iterable<? extends JavaFileObject> generatedFiles = task.generate(analyzed); 127 128 Set<String> generated = new HashSet<>(); 129 130 for (JavaFileObject jfo : generatedFiles) { 131 generated.add(jfo.getName()); 132 } 133 134 Set<String> expected = new HashSet<>( 135 Arrays.asList(Paths.get("testParseEnterAnalyze", "classes", "p", "package-info.class").toString(), 136 Paths.get("testParseEnterAnalyze", "classes", "module-info.class").toString(), 137 Paths.get("testParseEnterAnalyze", "classes", "p", "T.class").toString()) 138 ); 139 140 if (!Objects.equals(expected, generated)) 141 throw new AssertionError("Incorrect generated files: " + generated); 142 } 143 } 144 145 @Test 146 void testModuleImplicitModuleBoundaries(Path base) throws Exception { 147 Path src = base.resolve("src"); 148 Path src_m1 = src.resolve("m1"); 149 tb.writeJavaFiles(src_m1, 150 "module m1 { exports api1; }", 151 "package api1; public class Api1 { public void call() { } }"); 152 Path src_m2 = src.resolve("m2"); 153 tb.writeJavaFiles(src_m2, 154 "module m2 { requires m1; exports api2; }", 155 "package api2; public class Api2 { public static api1.Api1 get() { return null; } }"); 156 Path src_m3 = src.resolve("m3"); 157 tb.writeJavaFiles(src_m3, 158 "module m3 { requires m2; }", 159 "package test; public class Test { { api2.Api2.get().call(); api2.Api2.get().toString(); } }"); 160 Path classes = base.resolve("classes"); 161 tb.createDirectories(classes); 162 163 String log = tb.new JavacTask() 164 .options("-XDrawDiagnostics", 165 "-modulesourcepath", src.toString()) 166 .outdir(classes) 167 .files(findJavaFiles(src)) 168 .run(ToolBox.Expect.FAIL) 169 .writeAll() 170 .getOutput(ToolBox.OutputKind.DIRECT); 171 172 if (!log.contains("Test.java:1:52: compiler.err.not.def.access.class.intf.cant.access: call(), api1.Api1") || 173 !log.contains("Test.java:1:76: compiler.err.not.def.access.class.intf.cant.access: toString(), java.lang.Object")) 174 throw new Exception("expected output not found"); 175 } 176 177 @Test 178 void testAssignClassToAutomaticModule(Path base) throws Exception { 179 //check that if a ClassSymbol belongs to an automatic module, it is properly assigned and not 180 //duplicated when being accessed through a classfile. 181 Path automaticSrc = base.resolve("automaticSrc"); 182 tb.writeJavaFiles(automaticSrc, "package api1; public class Api1 {}"); 183 Path automaticClasses = base.resolve("automaticClasses"); 184 tb.createDirectories(automaticClasses); 185 186 String automaticLog = tb.new JavacTask() 187 .outdir(automaticClasses) 188 .files(findJavaFiles(automaticSrc)) 189 .run() 190 .writeAll() 191 .getOutput(ToolBox.OutputKind.DIRECT); 192 193 if (!automaticLog.isEmpty()) 194 throw new Exception("expected output not found: " + automaticLog); 195 196 Path modulePath = base.resolve("module-path"); 197 198 Files.createDirectories(modulePath); 199 200 Path automaticJar = modulePath.resolve("m1-1.0.jar"); 201 202 tb.new JarTask(automaticJar) 203 .baseDir(automaticClasses) 204 .files("api1/Api1.class") 205 .run(); 206 207 Path src = base.resolve("src"); 208 Path src_m2 = src.resolve("m2"); 209 tb.writeJavaFiles(src_m2, 210 "module m2 { requires m1; exports api2; }", 211 "package api2; public class Api2 { public static api1.Api1 get() { return null; } }"); 212 Path src_m3 = src.resolve("m3"); 213 tb.writeJavaFiles(src_m3, 214 "module m3 { requires m1; requires m2; }", 215 "package test; public class Test { { api2.Api2.get(); api1.Api1 a1; } }"); 216 Path classes = base.resolve("classes"); 217 tb.createDirectories(classes); 218 219 tb.new JavacTask() 220 .options("-modulepath", modulePath.toString(), 221 "-modulesourcepath", src.toString()) 222 .outdir(classes) 223 .files(findJavaFiles(src_m2)) 224 .run() 225 .writeAll(); 226 227 tb.new JavacTask() 228 .options("-modulepath", modulePath.toString(), 229 "-modulesourcepath", src.toString()) 230 .outdir(classes) 231 .files(findJavaFiles(src_m3)) 232 .run() 233 .writeAll(); 234 } 235 236 @Test 237 void testEmptyImplicitModuleInfo(Path base) throws Exception { 238 Path src = base.resolve("src"); 239 Path src_m1 = src.resolve("m1"); 240 Files.createDirectories(src_m1); 241 try (Writer w = Files.newBufferedWriter(src_m1.resolve("module-info.java"))) {} 242 tb.writeJavaFiles(src_m1, 243 "package test; public class Test {}"); 244 Path classes = base.resolve("classes"); 245 tb.createDirectories(classes); 246 247 tb.new JavacTask() 248 .options("-sourcepath", src_m1.toString(), 249 "-XDrawDiagnostics") 250 .outdir(classes) 251 .files(findJavaFiles(src_m1.resolve("test"))) 252 .run(ToolBox.Expect.FAIL) 253 .writeAll(); 254 255 tb.writeJavaFiles(src_m1, 256 "module m1 {}"); 257 258 tb.new JavacTask() 259 .options("-sourcepath", src_m1.toString()) 260 .outdir(classes) 261 .files(findJavaFiles(src_m1.resolve("test"))) 262 .run() 263 .writeAll(); 264 265 } 266 267} 268