8202832: cycle detection depends on ordering of requires directives
authorjlahoda
Tue, 29 May 2018 10:53:55 +0200
changeset 50285 5b6bdc59f8cc
parent 50284 274b2806c34c
child 50286 cbc4fca9171e
8202832: cycle detection depends on ordering of requires directives Summary: Ensuring cyclic dependencies among modules produce a compile-time error. Reviewed-by: vromero
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java
test/langtools/tools/javac/modules/ModuleInfoTest.java
--- 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");
+    }
+}