8202832: cycle detection depends on ordering of requires directives
Summary: Ensuring cyclic dependencies among modules produce a compile-time error.
Reviewed-by: vromero
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Mon May 28 12:11:50 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Tue May 29 10:53:55 2018 +0200
@@ -673,7 +673,6 @@
msym.requires = List.nil();
msym.uses = List.nil();
msym.directives = directives.toList();
- msym.flags_field |= Flags.ACYCLIC;
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
@@ -1739,7 +1738,7 @@
if (!nonSyntheticDeps.add(current))
continue;
current.complete();
- if ((current.flags() & Flags.ACYCLIC) != 0)
+ if ((current.flags() & Flags.AUTOMATIC_MODULE) != 0)
continue;
Assert.checkNonNull(current.requires, current::toString);
for (RequiresDirective dep : current.requires) {
@@ -1750,7 +1749,6 @@
if (nonSyntheticDeps.contains(mod.sym)) {
log.error(rd.moduleName.pos(), Errors.CyclicRequires(rd.directive.module));
}
- mod.sym.flags_field |= Flags.ACYCLIC;
}
}
--- a/test/langtools/tools/javac/modules/ModuleInfoTest.java Mon May 28 12:11:50 2018 +0200
+++ b/test/langtools/tools/javac/modules/ModuleInfoTest.java Tue May 29 10:53:55 2018 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8158123 8161906 8162713
+ * @bug 8158123 8161906 8162713 8202832
* @summary tests for module declarations
* @library /tools/lib
* @modules
@@ -37,6 +37,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
+import java.util.List;
import toolbox.JavacTask;
import toolbox.Task;
@@ -740,4 +741,61 @@
if (!log.contains("module-info.java:1:11: compiler.err.expected: '}'"))
throw new Exception("expected output not found");
}
-}
\ No newline at end of file
+
+ @Test
+ public void testJDK8202832(Path base) throws Exception {
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src.resolve("m1a"),
+ "module m1a {\n" +
+ " requires m2a;\n" +
+ " requires m2b;\n" +
+ "}");
+ tb.writeJavaFiles(src.resolve("m1b"),
+ "module m1b {\n" +
+ " requires m2b;\n" +
+ " requires m2a;\n" +
+ "}");
+ tb.writeJavaFiles(src.resolve("m2a"),
+ "module m2a {\n" +
+ " requires m3;\n" +
+ " requires m1a;\n" +
+ " requires m1b;\n" +
+ "}");
+ tb.writeJavaFiles(src.resolve("m2b"),
+ "module m2b {\n" +
+ " requires m3;\n" +
+ " requires m1a;\n" +
+ " requires m1b;\n" +
+ "}");
+ tb.writeJavaFiles(src.resolve("m3"),
+ "module m3 { }");
+
+ Path classes = base.resolve("classes");
+ Files.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--module-source-path", src.toString())
+ .outdir(classes)
+ .files(src.resolve("m1a").resolve("module-info.java"),
+ src.resolve("m1b").resolve("module-info.java"),
+ src.resolve("m2a").resolve("module-info.java"),
+ src.resolve("m2b").resolve("module-info.java"),
+ src.resolve("m3").resolve("module-info.java"))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = List.of("module-info.java:2:14: compiler.err.cyclic.requires: m2b",
+ "module-info.java:3:14: compiler.err.cyclic.requires: m2a",
+ "module-info.java:3:14: compiler.err.cyclic.requires: m1a",
+ "module-info.java:4:14: compiler.err.cyclic.requires: m1b",
+ "module-info.java:2:14: compiler.err.cyclic.requires: m2a",
+ "module-info.java:3:14: compiler.err.cyclic.requires: m2b",
+ "module-info.java:3:14: compiler.err.cyclic.requires: m1a",
+ "module-info.java:4:14: compiler.err.cyclic.requires: m1b",
+ "8 errors");
+ if (!expected.equals(log))
+ throw new Exception("expected output not found");
+ }
+}