mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-12 14:39:49 +00:00
8176045: No compile error when a package is not declared
Fixing handling of otherwise empty files with package clauses and empty files without package clauses. Reviewed-by: jjg
This commit is contained in:
parent
d60b98466f
commit
308a2b9f90
@ -89,7 +89,6 @@ import com.sun.tools.javac.tree.JCTree.JCExports;
|
||||
import com.sun.tools.javac.tree.JCTree.JCExpression;
|
||||
import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCOpens;
|
||||
import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCProvides;
|
||||
import com.sun.tools.javac.tree.JCTree.JCRequires;
|
||||
import com.sun.tools.javac.tree.JCTree.JCUses;
|
||||
@ -112,6 +111,7 @@ import static com.sun.tools.javac.code.Flags.ABSTRACT;
|
||||
import static com.sun.tools.javac.code.Flags.ENUM;
|
||||
import static com.sun.tools.javac.code.Flags.PUBLIC;
|
||||
import static com.sun.tools.javac.code.Flags.UNATTRIBUTED;
|
||||
import com.sun.tools.javac.code.Kinds;
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.ERR;
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.MDL;
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.MTH;
|
||||
@ -167,6 +167,8 @@ public class Modules extends JCTree.Visitor {
|
||||
private Set<ModuleSymbol> rootModules = null;
|
||||
private final Set<ModuleSymbol> warnedMissing = new HashSet<>();
|
||||
|
||||
public PackageNameFinder findPackageInFile;
|
||||
|
||||
public static Modules instance(Context context) {
|
||||
Modules instance = context.get(Modules.class);
|
||||
if (instance == null)
|
||||
@ -956,7 +958,30 @@ public class Modules extends JCTree.Visitor {
|
||||
|
||||
@Override
|
||||
public void visitExports(JCExports tree) {
|
||||
if (tree.directive.packge.members().isEmpty()) {
|
||||
Iterable<Symbol> packageContent = tree.directive.packge.members().getSymbols();
|
||||
List<JavaFileObject> filesToCheck = List.nil();
|
||||
boolean packageNotEmpty = false;
|
||||
for (Symbol sym : packageContent) {
|
||||
if (sym.kind != Kinds.Kind.TYP)
|
||||
continue;
|
||||
ClassSymbol csym = (ClassSymbol) sym;
|
||||
if (sym.completer.isTerminal() ||
|
||||
csym.classfile.getKind() == Kind.CLASS) {
|
||||
packageNotEmpty = true;
|
||||
filesToCheck = List.nil();
|
||||
break;
|
||||
}
|
||||
if (csym.classfile.getKind() == Kind.SOURCE) {
|
||||
filesToCheck = filesToCheck.prepend(csym.classfile);
|
||||
}
|
||||
}
|
||||
for (JavaFileObject jfo : filesToCheck) {
|
||||
if (findPackageInFile.findPackageNameOf(jfo) == tree.directive.packge.fullname) {
|
||||
packageNotEmpty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!packageNotEmpty) {
|
||||
log.error(tree.qualid.pos(), Errors.PackageEmptyOrNotFound(tree.directive.packge));
|
||||
}
|
||||
msym.directives = msym.directives.prepend(tree.directive);
|
||||
@ -1676,4 +1701,8 @@ public class Modules extends JCTree.Visitor {
|
||||
rootModules = null;
|
||||
warnedMissing.clear();
|
||||
}
|
||||
|
||||
public interface PackageNameFinder {
|
||||
public Name findPackageNameOf(JavaFileObject jfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -412,6 +412,7 @@ public class JavaCompiler {
|
||||
diags = Factory.instance(context);
|
||||
|
||||
finder.sourceCompleter = sourceCompleter;
|
||||
modules.findPackageInFile = this::findPackageInFile;
|
||||
moduleFinder.moduleNameFromSourceReader = this::readModuleName;
|
||||
|
||||
options = Options.instance(context);
|
||||
@ -1737,6 +1738,11 @@ public class JavaCompiler {
|
||||
});
|
||||
}
|
||||
|
||||
private Name findPackageInFile(JavaFileObject fo) {
|
||||
return parseAndGetName(fo, t -> t.getPackage() != null ?
|
||||
TreeInfo.fullName(t.getPackage().getPackageName()) : null);
|
||||
}
|
||||
|
||||
private Name parseAndGetName(JavaFileObject fo,
|
||||
Function<JCTree.JCCompilationUnit, Name> tree2Name) {
|
||||
DiagnosticHandler dh = new DiscardDiagnosticHandler(log);
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8154283 8167320 8171098 8172809 8173068 8173117
|
||||
* @bug 8154283 8167320 8171098 8172809 8173068 8173117 8176045
|
||||
* @summary tests for multi-module mode compilation
|
||||
* @library /tools/lib
|
||||
* @modules
|
||||
@ -36,6 +36,7 @@
|
||||
* @run main EdgeCases
|
||||
*/
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -67,10 +68,7 @@ import com.sun.source.tree.CompilationUnitTree;
|
||||
//import com.sun.source.util.JavacTask; // conflicts with toolbox.JavacTask
|
||||
import com.sun.tools.javac.api.JavacTaskImpl;
|
||||
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.PackageSymbol;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
|
||||
import toolbox.JarTask;
|
||||
import toolbox.JavacTask;
|
||||
@ -821,4 +819,143 @@ public class EdgeCases extends ModuleTestBase {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyInExportedPackage(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
Path m = src.resolve("m");
|
||||
tb.writeJavaFiles(m,
|
||||
"module m { exports api; }");
|
||||
Path apiFile = m.resolve("api").resolve("Api.java");
|
||||
Files.createDirectories(apiFile.getParent());
|
||||
try (BufferedWriter w = Files.newBufferedWriter(apiFile)) {
|
||||
w.write("//no package decl");
|
||||
}
|
||||
Path classes = base.resolve("classes");
|
||||
tb.createDirectories(classes);
|
||||
|
||||
List<String> log;
|
||||
List<String> expected =
|
||||
Arrays.asList("module-info.java:1:20: compiler.err.package.empty.or.not.found: api",
|
||||
"1 error");
|
||||
|
||||
System.err.println("file explicitly specified:");
|
||||
|
||||
log = new JavacTask(tb)
|
||||
.options("-XDrawDiagnostics",
|
||||
"--module-source-path", src.toString())
|
||||
.outdir(classes)
|
||||
.files(findJavaFiles(src))
|
||||
.run(Task.Expect.FAIL)
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
|
||||
if (!expected.equals(log))
|
||||
throw new Exception("expected output not found: " + log);
|
||||
|
||||
System.err.println("file not specified:");
|
||||
|
||||
tb.cleanDirectory(classes);
|
||||
|
||||
log = new JavacTask(tb)
|
||||
.options("-XDrawDiagnostics",
|
||||
"--module-source-path", src.toString())
|
||||
.outdir(classes)
|
||||
.files(findJavaFiles(m.resolve("module-info.java")))
|
||||
.run(Task.Expect.FAIL)
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
|
||||
if (!expected.equals(log))
|
||||
throw new Exception("expected output not found: " + log);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJustPackageInExportedPackage(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
Path m = src.resolve("m");
|
||||
tb.writeJavaFiles(m,
|
||||
"module m { exports api; }");
|
||||
Path apiFile = m.resolve("api").resolve("Api.java");
|
||||
Files.createDirectories(apiFile.getParent());
|
||||
try (BufferedWriter w = Files.newBufferedWriter(apiFile)) {
|
||||
w.write("package api;");
|
||||
}
|
||||
Path classes = base.resolve("classes");
|
||||
tb.createDirectories(classes);
|
||||
|
||||
System.err.println("file explicitly specified:");
|
||||
|
||||
new JavacTask(tb)
|
||||
.options("-XDrawDiagnostics",
|
||||
"--module-source-path", src.toString())
|
||||
.outdir(classes)
|
||||
.files(findJavaFiles(src))
|
||||
.run()
|
||||
.writeAll();
|
||||
|
||||
System.err.println("file not specified:");
|
||||
|
||||
tb.cleanDirectory(classes);
|
||||
|
||||
new JavacTask(tb)
|
||||
.options("-XDrawDiagnostics",
|
||||
"--module-source-path", src.toString())
|
||||
.outdir(classes)
|
||||
.files(findJavaFiles(m.resolve("module-info.java")))
|
||||
.run()
|
||||
.writeAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongPackageInExportedPackage(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
Path m = src.resolve("m");
|
||||
tb.writeJavaFiles(m,
|
||||
"module m { exports api; }");
|
||||
Path apiFile = m.resolve("api").resolve("Api.java");
|
||||
Files.createDirectories(apiFile.getParent());
|
||||
try (BufferedWriter w = Files.newBufferedWriter(apiFile)) {
|
||||
w.write("package impl; public class Api { }");
|
||||
}
|
||||
Path classes = base.resolve("classes");
|
||||
tb.createDirectories(classes);
|
||||
|
||||
List<String> log;
|
||||
|
||||
List<String> expected =
|
||||
Arrays.asList("module-info.java:1:20: compiler.err.package.empty.or.not.found: api",
|
||||
"1 error");
|
||||
|
||||
System.err.println("file explicitly specified:");
|
||||
|
||||
log = new JavacTask(tb)
|
||||
.options("-XDrawDiagnostics",
|
||||
"--module-source-path", src.toString())
|
||||
.outdir(classes)
|
||||
.files(findJavaFiles(src))
|
||||
.run(Task.Expect.FAIL)
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
|
||||
if (!expected.equals(log))
|
||||
throw new Exception("expected output not found: " + log);
|
||||
|
||||
System.err.println("file not specified:");
|
||||
|
||||
tb.cleanDirectory(classes);
|
||||
|
||||
log = new JavacTask(tb)
|
||||
.options("-XDrawDiagnostics",
|
||||
"--module-source-path", src.toString())
|
||||
.outdir(classes)
|
||||
.files(findJavaFiles(m.resolve("module-info.java")))
|
||||
.run(Task.Expect.FAIL)
|
||||
.writeAll()
|
||||
.getOutputLines(Task.OutputKind.DIRECT);
|
||||
|
||||
if (!expected.equals(log))
|
||||
throw new Exception("expected output not found: " + log);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user