8175007: Incorrect error messages for inaccessible classes in visible packages
authorjlahoda
Wed, 15 Feb 2017 11:27:03 +0100
changeset 43866 3195ea126044
parent 43865 532c50fea155
child 43867 9d40b4d77b7f
8175007: Incorrect error messages for inaccessible classes in visible packages Summary: Recovery lookup may be triggered for inaccessible classes in visible packages - providing better errors. Reviewed-by: mcimadamore
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Feb 14 15:45:17 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Feb 15 11:27:03 2017 +0100
@@ -2104,7 +2104,7 @@
 
         for (S sym : candidates) {
             if (validate.test(sym))
-                return new InvisibleSymbolError(env, suppressError, sym);
+                return createInvisibleSymbolError(env, suppressError, sym);
         }
 
         Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules());
@@ -2123,7 +2123,7 @@
                     S sym = load.apply(ms, name);
 
                     if (sym != null && validate.test(sym)) {
-                        return new InvisibleSymbolError(env, suppressError, sym);
+                        return createInvisibleSymbolError(env, suppressError, sym);
                     }
                 }
             }
@@ -2132,6 +2132,21 @@
         return defaultResult;
     }
 
+    private Symbol createInvisibleSymbolError(Env<AttrContext> env, boolean suppressError, Symbol sym) {
+        if (symbolPackageVisible(env, sym)) {
+            return new AccessError(env, null, sym);
+        } else {
+            return new InvisibleSymbolError(env, suppressError, sym);
+        }
+    }
+
+    private boolean symbolPackageVisible(Env<AttrContext> env, Symbol sym) {
+        ModuleSymbol envMod = env.toplevel.modle;
+        PackageSymbol symPack = sym.packge();
+        return envMod == symPack.modle ||
+               envMod.visiblePackages.containsKey(symPack.fullname);
+    }
+
     /**
      * Find a type declared in a scope (not inherited).  Return null
      * if none is found.
@@ -4104,8 +4119,7 @@
                             pos, "not.def.access.package.cant.access",
                         sym, sym.location(), inaccessiblePackageReason(env, sym.packge()));
                 } else if (   sym.packge() != syms.rootPackage
-                           && sym.packge().modle != env.toplevel.modle
-                           && !isAccessible(env, sym.outermostClass())) {
+                           && !symbolPackageVisible(env, sym)) {
                     return diags.create(dkind, log.currentSource(),
                             pos, "not.def.access.class.intf.cant.access.reason",
                             sym, sym.location(), sym.location().packge(),
--- a/langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java	Tue Feb 14 15:45:17 2017 -0800
+++ b/langtools/test/tools/javac/modules/ConvenientAccessErrorsTest.java	Wed Feb 15 11:27:03 2017 +0100
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8169197 8172668 8173117
+ * @bug 8169197 8172668 8173117 8175007
  * @summary Check convenient errors are produced for inaccessible classes.
  * @library /tools/lib
  * @modules jdk.compiler/com.sun.tools.javac.api
@@ -704,4 +704,44 @@
             throw new Exception("Expected names not generated: " + actual);
         }
     }
+
+    @Test
+    public void testInaccessibleInVisible(Path base) throws Exception {
+        Path src = base.resolve("src");
+        Path src_ma = src.resolve("ma");
+        tb.writeJavaFiles(src_ma,
+                          "module ma { exports ma; }",
+                          "package ma; class NotApi { public static class Inner { } }");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        new JavacTask(tb)
+            .outdir(classes)
+            .files(findJavaFiles(src_ma))
+            .run()
+            .writeAll();
+
+        Path src_mb = src.resolve("mb");
+        tb.writeJavaFiles(src_mb,
+                          "module mb { requires ma; }",
+                          "package mb.a; public class Test { ma.NotApi.Inner i1; mb.b.NotApi.Inner i2; }",
+                          "package mb.b; class NotApi { public static class Inner { } }");
+
+        List<String> log = new JavacTask(tb)
+                .options("-XDrawDiagnostics",
+                         "--module-path", classes.toString())
+                .outdir(classes)
+                .files(findJavaFiles(src_mb))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList(
+                "Test.java:1:44: compiler.err.not.def.access.class.intf.cant.access: ma.NotApi.Inner, ma.NotApi",
+                "Test.java:1:66: compiler.err.not.def.access.class.intf.cant.access: mb.b.NotApi.Inner, mb.b.NotApi",
+                "2 errors");
+
+        if (!expected.equals(log))
+            throw new Exception("expected output not found; actual: " + log);
+    }
 }