changeset 4275:d1d80e52e44c

pass-through impl of "exports dynamic [private] default"
author jjg
date Wed, 24 Aug 2016 15:28:40 -0700
parents 1898244b4732
children d218e1f84264
files src/java.compiler/share/classes/javax/lang/model/element/ModuleElement.java src/jdk.compiler/share/classes/com/sun/source/tree/ExportsTree.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java test/tools/javac/diags/examples/DefaultExportsMustBeDynamic/module-info.java test/tools/javac/diags/examples/ExpectedIdentifierOrDefault/module-info.java test/tools/javac/modules/ModuleInfoTest.java
diffstat 14 files changed, 124 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.compiler/share/classes/javax/lang/model/element/ModuleElement.java	Wed Aug 24 23:23:00 2016 +0200
+++ b/src/java.compiler/share/classes/javax/lang/model/element/ModuleElement.java	Wed Aug 24 15:28:40 2016 -0700
@@ -163,7 +163,7 @@
         boolean isPrivate();
 
         /**
-         * Returns the package being exported.
+         * Returns the package being exported, or null if this is a default exports directive.
          * @return the package being exported
          */
         PackageElement getPackage();
--- a/src/jdk.compiler/share/classes/com/sun/source/tree/ExportsTree.java	Wed Aug 24 23:23:00 2016 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/source/tree/ExportsTree.java	Wed Aug 24 15:28:40 2016 -0700
@@ -54,7 +54,7 @@
     boolean isPrivate();
 
     /**
-     * Returns the name of the package to be exported.
+     * Returns the name of the package to be exported, or null if this is a default exports directive.
      * @return  the name of the package to be exported
      */
     ExpressionTree getExportName();
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java	Wed Aug 24 23:23:00 2016 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java	Wed Aug 24 15:28:40 2016 -0700
@@ -99,7 +99,7 @@
      */
     public static class ExportsDirective extends Directive
             implements ModuleElement.ExportsDirective {
-        public final PackageSymbol packge;
+        public final PackageSymbol packge;  // null for default
         public final Set<ExportsFlag> flags;
         public final List<ModuleSymbol> modules;
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Wed Aug 24 23:23:00 2016 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Wed Aug 24 15:28:40 2016 -0700
@@ -633,11 +633,22 @@
 
         @Override
         public void visitExports(JCExports tree) {
-            Name name = TreeInfo.fullName(tree.qualid);
-            PackageSymbol packge = syms.enterPackage(sym, name);
-            attr.setPackageSymbols(tree.qualid, packge);
-            if (!allExports.add(packge)) {
-                log.error(tree.qualid.pos(), Errors.DuplicateExports(packge));
+            PackageSymbol packge;
+
+            if (tree.qualid == null) {
+                if (!tree.isDynamicPhase) {
+                    log.error(tree.pos(), Errors.DefaultExportsMustBeDynamic);
+                }
+                // TODO: more validity checking:
+                // must not conflict with other default exports
+                packge = null;
+            } else {
+                Name name = TreeInfo.fullName(tree.qualid);
+                packge = syms.enterPackage(sym, name);
+                attr.setPackageSymbols(tree.qualid, packge);
+                if (!allExports.add(packge)) {
+                    log.error(tree.qualid.pos(), Errors.DuplicateExports(packge));
+                }
             }
 
             List<ModuleSymbol> toModules = null;
@@ -752,7 +763,7 @@
 
         @Override
         public void visitExports(JCExports tree) {
-            if (tree.directive.packge.members().isEmpty()) {
+            if (tree.directive.packge != null && tree.directive.packge.members().isEmpty()) {
                 log.error(tree.qualid.pos(), Errors.PackageEmptyOrNotFound(tree.directive.packge));
             }
             msym.directives = msym.directives.prepend(tree.directive);
@@ -1097,7 +1108,9 @@
         requiresTransitiveCache.put(msym, requiresTransitive);
         initVisiblePackages(msym, readable);
         for (ExportsDirective d: msym.exports) {
-            d.packge.modle = msym;
+            if (d.packge != null) {
+                d.packge.modle = msym;
+            }
         }
 
     }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Aug 24 23:23:00 2016 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Aug 24 15:28:40 2016 -0700
@@ -966,7 +966,8 @@
         List<ExportsDirective> exports = m.exports;
         databuf.appendChar(exports.size());
         for (ExportsDirective e: exports) {
-            databuf.appendChar(pool.put(names.fromUtf(externalize(e.packge.flatName()))));
+            databuf.appendChar(e.packge == null ? 0 :
+                    pool.put(names.fromUtf(externalize(e.packge.flatName()))));
             databuf.appendChar(ExportsFlag.value(e.flags));
             if (e.modules == null) {
                 databuf.appendChar(0);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Aug 24 23:23:00 2016 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Aug 24 15:28:40 2016 -0700
@@ -3278,7 +3278,19 @@
                     }
                     nextToken();
                 }
-                JCExpression pkgName = qualident(false);
+                JCExpression pkgName;
+                switch (token.kind) {
+                    case DEFAULT:
+                        pkgName = null;
+                        nextToken();
+                        break;
+                    case IDENTIFIER:
+                        pkgName = qualident(false);
+                        break;
+                    default:
+                        reportSyntaxError(token.pos, "expected.identifier.or.default");
+                        pkgName = F.at(token.pos).Erroneous();
+                }
                 List<JCExpression> moduleNames = null;
                 if (token.kind == IDENTIFIER && token.name() == names.to) {
                     nextToken();
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Aug 24 23:23:00 2016 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Aug 24 15:28:40 2016 -0700
@@ -1768,6 +1768,9 @@
     reached end of file while parsing
 
 ## The following are related in form, but do not easily fit the above paradigm.
+compiler.err.expected.identifier.or.default=\
+    expected identifier or ''default''
+
 compiler.err.dot.class.expected=\
     ''.class'' expected
 
@@ -2722,6 +2725,9 @@
 compiler.err.duplicate.uses=\
     duplicate uses: {0}
 
+compiler.err.default.exports.must.be.dynamic=\
+    default exports must also specify ''dynamic''
+
 # 0: symbol
 compiler.err.service.implementation.is.abstract=\
     the service implementation is an abstract class: {0}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Wed Aug 24 23:23:00 2016 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Wed Aug 24 15:28:40 2016 -0700
@@ -2676,7 +2676,7 @@
 
     public static class JCExports extends JCDirective
             implements ExportsTree {
-        public JCExpression qualid;
+        public JCExpression qualid; // null for default
         public boolean isDynamicPhase;
         public boolean isPrivate;
         public List<JCExpression> moduleNames;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java	Wed Aug 24 23:23:00 2016 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java	Wed Aug 24 15:28:40 2016 -0700
@@ -462,6 +462,11 @@
                 print("dynamic ");
             if (tree.isPrivate)
                 print("private ");
+            if (tree.qualid == null) {
+                print("default");
+            } else {
+                print(tree.qualid);
+            }
             printExpr(tree.qualid);
             if (tree.moduleNames != null) {
                 print(" to ");
--- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java	Wed Aug 24 23:23:00 2016 +0200
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java	Wed Aug 24 15:28:40 2016 -0700
@@ -540,7 +540,12 @@
         for (Module_attribute.ExportsEntry e: entries) {
             print("#" + e.exports_index + "," + String.format("%x", e.exports_flags));
             tab();
-            print("// " + constantWriter.stringValue(e.exports_index));
+            print("// ");
+            if (e.exports_index == 0) {
+                print("default");
+            } else {
+                print(constantWriter.stringValue(e.exports_index));
+            }
             if ((e.exports_flags & Module_attribute.ACC_DYNAMIC_PHASE) != 0)
                 print(" ACC_DYNAMIC_PHASE");
             if ((e.exports_flags & Module_attribute.ACC_PRIVATE_REFLECTION) != 0)
--- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java	Wed Aug 24 23:23:00 2016 +0200
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java	Wed Aug 24 15:28:40 2016 -0700
@@ -571,7 +571,11 @@
             if ((entry.exports_flags & Module_attribute.ACC_PRIVATE_REFLECTION) != 0)
                 print(" private");
             print(" ");
-            print(getUTF8Value(entry.exports_index).replace('/', '.'));
+            if (entry.exports_index == 0) {
+                print("default");
+            } else {
+                print(getUTF8Value(entry.exports_index).replace('/', '.'));
+            }
             boolean first = true;
             for (int i: entry.exports_to_index) {
                 String mname;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/DefaultExportsMustBeDynamic/module-info.java	Wed Aug 24 15:28:40 2016 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.default.exports.must.be.dynamic
+
+module m {
+     exports default;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/ExpectedIdentifierOrDefault/module-info.java	Wed Aug 24 15:28:40 2016 -0700
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2010, 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.expected.identifier.or.default
+
+module m {
+    exports *;
+}
--- a/test/tools/javac/modules/ModuleInfoTest.java	Wed Aug 24 23:23:00 2016 +0200
+++ b/test/tools/javac/modules/ModuleInfoTest.java	Wed Aug 24 15:28:40 2016 -0700
@@ -493,7 +493,13 @@
                     .writeAll()
                     .getOutput(Task.OutputKind.DIRECT);
 
-            if (!log.matches("(?s)^module\\-info\\.java:\\d+:\\d+: compiler\\.err\\.expected: token\\.identifier.*"))
+            String expect_prefix = "(?s)^module\\-info\\.java:\\d+:\\d+: ";
+            String expect_message = moduleInfo.contains("exports @")
+                ? "compiler\\.err\\.expected\\.identifier\\.or\\.default"
+                : "compiler\\.err\\.expected: token\\.identifier";
+            String expect_suffix = ".*";
+            String expect = expect_prefix + expect_message + expect_suffix;
+            if (!log.matches(expect))
                 throw new Exception("expected output not found");
         }
     }