changeset 4279:c7f21d1d8965

initial support for weak modules; improved conflict checking for exports; some cleanup
author jjg
date Tue, 30 Aug 2016 20:43:58 -0700
parents c68bd6a4e207
children 3097254e5c8a
files src/jdk.compiler/share/classes/com/sun/source/tree/ModuleTree.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/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.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java test/tools/javac/diags/examples/ConflictingDefaultExports/module-info.java test/tools/javac/diags/examples/ConflictingExports/exported/Class.java test/tools/javac/diags/examples/ConflictingExports/module-info.java test/tools/javac/diags/examples/ConflictingExportsToModule/exported/Class.java test/tools/javac/diags/examples/ConflictingExportsToModule/module-info.java test/tools/javac/diags/examples/DuplicateExports/exported/Class.java test/tools/javac/diags/examples/DuplicateExports/module-info.java test/tools/javac/diags/examples/ExpectedModule.java test/tools/javac/modules/ModuleInfoTest.java test/tools/javac/parser/JavacParserTest.java
diffstat 21 files changed, 348 insertions(+), 111 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/source/tree/ModuleTree.java	Sat Aug 27 19:27:11 2016 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/source/tree/ModuleTree.java	Tue Aug 30 20:43:58 2016 -0700
@@ -33,7 +33,8 @@
  *
  * For example:
  * <pre>
- *    module <em>module-name</em> {
+ *    <em>annotations</em>
+ *    [weak] module <em>module-name</em> {
  *        <em>directives</em>
  *    }
  * </pre>
@@ -48,6 +49,12 @@
     List<? extends AnnotationTree> getAnnotations();
 
     /**
+     * Returns true if this is a "weak" module.
+     * @return true if this is a "weak" module
+     */
+    boolean isWeak();
+
+    /**
      * Returns the name of the module.
      * @return the name of the module
      */
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java	Sat Aug 27 19:27:11 2016 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java	Tue Aug 30 20:43:58 2016 -0700
@@ -77,7 +77,9 @@
     /** Flags for ExportsDirective. */
     public enum ExportsFlag {
         DYNAMIC_PHASE(0x0040),
-        PRIVATE_REFLECTION(0x0080);
+        PRIVATE_REFLECTION(0x0080),
+        SYNTHETIC(0x1000),
+        MANDATED(0x8000);
 
         // overkill? move to ClassWriter?
         public static int value(Set<ExportsFlag> s) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Sat Aug 27 19:27:11 2016 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Tue Aug 30 20:43:58 2016 -0700
@@ -109,7 +109,6 @@
 
 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;
 
 /**
  *  TODO: fill in
@@ -597,7 +596,7 @@
     class ModuleVisitor extends JCTree.Visitor {
         private ModuleSymbol sym;
         private final Set<ModuleSymbol> allRequires = new HashSet<>();
-        private final Set<PackageSymbol> allExports = new HashSet<>();
+        private final Map<PackageSymbol,List<ExportsDirective>> allExports = new HashMap<>();
 
         @Override
         public void visitModuleDef(JCModuleDecl tree) {
@@ -609,6 +608,9 @@
             sym.requires = sym.requires.reverse();
             sym.exports = sym.exports.reverse();
             ensureJavaBase();
+            if (tree.weak) {
+                ensureExportsDynamicPrivateDefault();
+            }
         }
 
         @Override
@@ -646,9 +648,11 @@
                 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<ExportsDirective> exportsForPackage = allExports.computeIfAbsent(packge, p -> List.nil());
+            for (ExportsDirective d : allExports.computeIfAbsent(packge, p -> List.nil())) {
+                checkDuplicateExports(tree, packge, d);
             }
 
             List<ModuleSymbol> toModules = null;
@@ -658,8 +662,13 @@
                     ModuleSymbol msym = lookupModule(n);
                     if (msym.kind != MDL) {
                         log.error(n.pos(), Errors.ModuleNotFound(msym));
-                    } else if (!to.add(msym)) {
-                        log.error(n.pos(), Errors.DuplicateExports(msym));
+                    } else {
+                        for (ExportsDirective d : exportsForPackage) {
+                            checkDuplicateExportsToModule(n, msym, d);
+                        }
+                        if (!to.add(msym)) {
+                            reportExportConflictToModule(n, msym);
+                        }
                     }
                 }
                 toModules = List.from(to);
@@ -676,9 +685,71 @@
                 ExportsDirective d = new ExportsDirective(packge, toModules, flags);
                 tree.directive = d;
                 sym.exports = sym.exports.prepend(d);
+
+                allExports.put(packge, exportsForPackage.prepend(d));
             }
         }
 
+        /**
+         * Check if an exports tree conflicts with an earlier exports, represented by an exports directive
+         * @param tree the tree to check
+         * @param packge the package being exported, or null for exports default
+         * @param d the directive to compare against
+         */
+        private void checkDuplicateExports(JCExports tree, PackageSymbol packge, ExportsDirective d) {
+            if (tree.moduleNames == null) {
+                if (d.modules == null) {
+                    // both are unqualified: error
+                    reportExportConflict(tree, packge);
+                } else {
+                    // tree unqualified, directive qualified:
+                    // error if directive (i.e. qualified) does not remove dynamic or add private
+                    if (!(tree.isDynamicPhase && !d.isDynamic()
+                            || !tree.isPrivate && d.isPrivate())) {
+                        reportExportConflict(tree, packge);
+                    }
+                }
+            } else {
+                if (d.modules == null) {
+                    // tree qualified, directive unqualified:
+                    // error if tree (i.e. qualified) does not remove dynamic or add private
+                    if (!(d.isDynamic() && !tree.isDynamicPhase
+                            || !d.isPrivate() && tree.isPrivate)) {
+                        reportExportConflict(tree, packge);
+                    }
+                } else {
+                    // both are qualified: error if dynamic and private match
+                    if (tree.isDynamicPhase && d.isDynamic()
+                            && tree.isPrivate && d.isPrivate()) {
+                        reportExportConflict(tree, packge);
+                    }
+                }
+            }
+        }
+
+        private void reportExportConflict(JCExports tree, PackageSymbol packge) {
+            if (tree.qualid == null) {
+                log.error(tree.pos(), Errors.ConflictingDefaultExports);
+            } else {
+                log.error(tree.qualid.pos(), Errors.ConflictingExports(packge));
+            }
+        }
+
+        private void checkDuplicateExportsToModule(JCExpression name, ModuleSymbol msym,
+                ExportsDirective d) {
+            if (d.modules != null) {
+                for (ModuleSymbol other : d.modules) {
+                    if (msym == other) {
+                        reportExportConflictToModule(name, msym);
+                    }
+                }
+            }
+        }
+
+        private void reportExportConflictToModule(JCExpression name, ModuleSymbol msym) {
+            log.error(name.pos(), Errors.ConflictingExportsToModule(msym));
+        }
+
         @Override
         public void visitProvides(JCProvides tree) { }
 
@@ -701,16 +772,23 @@
             sym.requires = sym.requires.prepend(d);
         }
 
+        private void ensureExportsDynamicPrivateDefault() {
+            for (ExportsDirective d : sym.exports) {
+                if (d.isDynamic() && d.isPrivate() && d.packge == null) {
+                    return;
+                }
+            }
+            Directive.ExportsDirective d =
+                    new Directive.ExportsDirective(null, null,
+                            EnumSet.of(ExportsFlag.DYNAMIC_PHASE, ExportsFlag.PRIVATE_REFLECTION, ExportsFlag.MANDATED));
+            sym.exports = sym.exports.prepend(d);
+        }
+
         private ModuleSymbol lookupModule(JCExpression moduleName) {
-            try {
             Name name = TreeInfo.fullName(moduleName);
             ModuleSymbol msym = moduleFinder.findModule(name);
             TreeInfo.setSymbol(moduleName, msym);
             return msym;
-            } catch (Throwable t) {
-                System.err.println("Module " + sym + "; lookup export " + moduleName);
-                throw t;
-            }
         }
     }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Sat Aug 27 19:27:11 2016 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Tue Aug 30 20:43:58 2016 -0700
@@ -51,7 +51,6 @@
 import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
 import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
-import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
 
 /** The parser maps a token sequence into an abstract syntax
  *  tree. It operates by recursive descent, with code derived
@@ -3150,16 +3149,25 @@
                 }
                 if (mods != null || token.kind != SEMI)
                     mods = modifiersOpt(mods);
-                if (token.kind == IDENTIFIER && token.name() == names.module && firstTypeDecl) {
-                    List<JCAnnotation> annotations = List.nil();
-                    if (mods != null) {
-                        checkNoMods(mods.flags);
-                        annotations = mods.annotations;
-                        mods = null;
+                if (firstTypeDecl && token.kind == IDENTIFIER) {
+                    boolean weak = false;
+                    if (token.name() == names.weak) {
+                        weak = true;
+                        nextToken();
                     }
-                    defs.append(moduleDecl(annotations, docComment));
-                    consumedToplevelDoc = true;
-                    break;
+                    if (token.kind == IDENTIFIER && token.name() == names.module) {
+                        List<JCAnnotation> annotations = List.nil();
+                        if (mods != null) {
+                            checkNoMods(mods.flags);
+                            annotations = mods.annotations;
+                            mods = null;
+                        }
+                        defs.append(moduleDecl(annotations, weak, docComment));
+                        consumedToplevelDoc = true;
+                        break;
+                    } else if (weak) {
+                        reportSyntaxError(token.pos, "expected.module");
+                    }
                 }
                 JCTree def = typeDeclaration(mods, docComment);
                 if (def instanceof JCExpressionStatement)
@@ -3185,7 +3193,7 @@
         return toplevel;
     }
 
-    JCModuleDecl moduleDecl(List<JCAnnotation> annotations, Comment dc) {
+    JCModuleDecl moduleDecl(List<JCAnnotation> annotations, boolean weak, Comment dc) {
         int pos = token.pos;
         if (!allowModules) {
             log.error(pos, Errors.ModulesNotSupportedInSource(source.name));
@@ -3201,7 +3209,7 @@
         accept(RBRACE);
         accept(EOF);
 
-        JCModuleDecl result = toP(F.at(pos).ModuleDef(annotations, name, directives));
+        JCModuleDecl result = toP(F.at(pos).ModuleDef(annotations, weak, name, directives));
         attach(result, dc);
         return result;
     }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Sat Aug 27 19:27:11 2016 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Aug 30 20:43:58 2016 -0700
@@ -1778,6 +1778,9 @@
 compiler.err.expected.identifier.or.default=\
     expected identifier or ''default''
 
+compiler.err.expected.module=\
+    ''module'' expected
+
 compiler.err.dot.class.expected=\
     ''.class'' expected
 
@@ -2725,8 +2728,15 @@
     duplicate requires: {0}
 
 # 0: symbol
-compiler.err.duplicate.exports=\
-    duplicate export: {0}
+compiler.err.conflicting.exports=\
+    duplicate or conflicting exports: {0}
+
+compiler.err.conflicting.default.exports=\
+    duplicate or conflicting ''exports default''
+
+# 0: symbol
+compiler.err.conflicting.exports.to.module=\
+    duplicate or conflicting exports to module: {0}
 
 # 0: symbol, 1: symbol
 compiler.err.duplicate.provides=\
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Sat Aug 27 19:27:11 2016 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Tue Aug 30 20:43:58 2016 -0700
@@ -2630,12 +2630,15 @@
 
     public static class JCModuleDecl extends JCTree implements ModuleTree {
         public List<JCAnnotation> annotations;
+        public boolean weak;
         public JCExpression qualId;
         public List<JCDirective> directives;
         public ModuleSymbol sym;
 
-        protected JCModuleDecl(List<JCAnnotation> annotations, JCExpression qualId, List<JCDirective> directives) {
+        protected JCModuleDecl(List<JCAnnotation> annotations, boolean weak,
+                JCExpression qualId, List<JCDirective> directives) {
             this.annotations = annotations;
+            this.weak = weak;
             this.qualId = qualId;
             this.directives = directives;
         }
@@ -2654,6 +2657,11 @@
         }
 
         @Override @DefinedBy(Api.COMPILER_TREE)
+        public boolean isWeak() {
+            return weak;
+        }
+
+        @Override @DefinedBy(Api.COMPILER_TREE)
         public JCExpression getName() {
             return qualId;
         }
@@ -2984,7 +2992,7 @@
         JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args);
         JCModifiers Modifiers(long flags, List<JCAnnotation> annotations);
         JCErroneous Erroneous(List<? extends JCTree> errs);
-        JCModuleDecl ModuleDef(List<JCAnnotation> annotations, JCExpression qualId, List<JCDirective> directives);
+        JCModuleDecl ModuleDef(List<JCAnnotation> annotations, boolean weak, JCExpression qualId, List<JCDirective> directives);
         JCExports Exports(JCExpression qualId, boolean isDynamicPhase, boolean isPrivate, List<JCExpression> moduleNames);
         JCProvides Provides(JCExpression serviceName, JCExpression implName);
         JCRequires Requires(boolean isTransitive, boolean isStaticPhase, JCExpression qualId);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java	Sat Aug 27 19:27:11 2016 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java	Tue Aug 30 20:43:58 2016 -0700
@@ -441,6 +441,10 @@
     @Override
     public void visitModuleDef(JCModuleDecl tree) {
         try {
+            printAnnotations(tree.annotations);
+            if (tree.isWeak()) {
+                print("weak ");
+            }
             print("module ");
             printExpr(tree.qualId);
             if (tree.directives == null) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Sat Aug 27 19:27:11 2016 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Tue Aug 30 20:43:58 2016 -0700
@@ -511,7 +511,7 @@
         List<JCAnnotation> annotations = copy(t.annotations, p);
         JCExpression qualId = copy(t.qualId);
         List<JCDirective> directives = copy(t.directives);
-        return M.at(t.pos).ModuleDef(annotations, qualId, directives);
+        return M.at(t.pos).ModuleDef(annotations, t.weak, qualId, directives);
     }
 
     @Override @DefinedBy(Api.COMPILER_TREE)
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Sat Aug 27 19:27:11 2016 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Tue Aug 30 20:43:58 2016 -0700
@@ -538,8 +538,9 @@
     }
 
     @Override
-    public JCModuleDecl ModuleDef(List<JCAnnotation> annotations, JCExpression qualid, List<JCDirective> directives) {
-        JCModuleDecl tree = new JCModuleDecl(annotations, qualid, directives);
+    public JCModuleDecl ModuleDef(List<JCAnnotation> annotations, boolean weak,
+            JCExpression qualid, List<JCDirective> directives) {
+        JCModuleDecl tree = new JCModuleDecl(annotations, weak, qualid, directives);
         tree.pos = pos;
         return tree;
     }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java	Sat Aug 27 19:27:11 2016 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java	Tue Aug 30 20:43:58 2016 -0700
@@ -71,6 +71,7 @@
     public final Name to;
     public final Name transitive;
     public final Name uses;
+    public final Name weak;
     public final Name with;
 
     // field and method names
@@ -229,6 +230,7 @@
         to = fromString("to");
         transitive = fromString("transitive");
         uses = fromString("uses");
+        weak = fromString("weak");
         with = fromString("with");
 
         // field and method names
--- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java	Sat Aug 27 19:27:11 2016 -0700
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java	Tue Aug 30 20:43:58 2016 -0700
@@ -546,6 +546,10 @@
             } else {
                 print(constantWriter.stringValue(e.exports_index));
             }
+            if ((e.exports_flags & Module_attribute.ACC_MANDATED) != 0)
+                print(" ACC_MANDATED");
+            if ((e.exports_flags & Module_attribute.ACC_SYNTHETIC) != 0)
+                print(" ACC_SYNTHETIC");
             if ((e.exports_flags & Module_attribute.ACC_DYNAMIC_PHASE) != 0)
                 print(" ACC_DYNAMIC_PHASE");
             if ((e.exports_flags & Module_attribute.ACC_PRIVATE_REFLECTION) != 0)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/ConflictingDefaultExports/module-info.java	Tue Aug 30 20:43:58 2016 -0700
@@ -0,0 +1,29 @@
+/*
+ * 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.conflicting.default.exports
+
+module ConflictingDefaultExports {
+    exports dynamic default;
+    exports dynamic private default;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/ConflictingExports/exported/Class.java	Tue Aug 30 20:43:58 2016 -0700
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package exported;
+
+public class Class {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/ConflictingExports/module-info.java	Tue Aug 30 20:43:58 2016 -0700
@@ -0,0 +1,29 @@
+/*
+ * 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.conflicting.exports
+
+module ConflictingExports {
+     exports exported;
+     exports exported;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/ConflictingExportsToModule/exported/Class.java	Tue Aug 30 20:43:58 2016 -0700
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package exported;
+
+public class Class {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/ConflictingExportsToModule/module-info.java	Tue Aug 30 20:43:58 2016 -0700
@@ -0,0 +1,29 @@
+/*
+ * 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.conflicting.exports.to.module
+
+module ConflictingExports {
+     exports exported to java.base;
+     exports private exported to java.base;
+}
--- a/test/tools/javac/diags/examples/DuplicateExports/exported/Class.java	Sat Aug 27 19:27:11 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-
-package exported;
-
-public class Class {
-}
--- a/test/tools/javac/diags/examples/DuplicateExports/module-info.java	Sat Aug 27 19:27:11 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * 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.duplicate.exports
-
-module DuplicateExports {
-     exports exported;
-     exports exported;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/diags/examples/ExpectedModule.java	Tue Aug 30 20:43:58 2016 -0700
@@ -0,0 +1,26 @@
+/*
+ * 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.expected.module
+
+weak class ExpectedModule { }
--- a/test/tools/javac/modules/ModuleInfoTest.java	Sat Aug 27 19:27:11 2016 -0700
+++ b/test/tools/javac/modules/ModuleInfoTest.java	Tue Aug 30 20:43:58 2016 -0700
@@ -314,7 +314,7 @@
      * Verify that duplicate exported packages are detected.
      */
     @Test
-    public void testDuplicateExports_packages(Path base) throws Exception {
+    public void testConflictingExports_packages(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module m1 { exports p; exports p; }");
 
@@ -329,7 +329,7 @@
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
-        if (!log.contains("module-info.java:1:32: compiler.err.duplicate.exports: p"))
+        if (!log.contains("module-info.java:1:32: compiler.err.conflicting.exports: p"))
             throw new Exception("expected output not found");
     }
 
@@ -337,7 +337,7 @@
      * Verify that duplicate exported packages are detected.
      */
     @Test
-    public void testDuplicateDynamicExports_packages(Path base) throws Exception {
+    public void testConflictingDynamicExports_packages(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src, "module m1 { exports p; exports dynamic p; }");
 
@@ -352,7 +352,7 @@
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
-        if (!log.contains("module-info.java:1:40: compiler.err.duplicate.exports: p"))
+        if (!log.contains("module-info.java:1:40: compiler.err.conflicting.exports: p"))
             throw new Exception("expected output not found");
     }
 
@@ -360,7 +360,7 @@
      * Verify that duplicate exported packages are detected.
      */
     @Test
-    public void testDuplicateExports_packages2(Path base) throws Exception {
+    public void testConflictingExports_packages2(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"), "module m1 { exports p; exports p to m2; }");
         tb.writeJavaFiles(src.resolve("m2"), "module m2 { }");
@@ -376,7 +376,7 @@
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
-        if (!log.contains("module-info.java:1:32: compiler.err.duplicate.exports: p"))
+        if (!log.contains("module-info.java:1:32: compiler.err.conflicting.exports: p"))
             throw new Exception("expected output not found");
     }
 
@@ -384,7 +384,7 @@
      * Verify that duplicate exported packages are detected.
      */
     @Test
-    public void testDuplicateDynamicExports_packages2(Path base) throws Exception {
+    public void testConflictingDynamicExports_packages2(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src.resolve("m1"), "module m1 { exports p; exports dynamic p to m2; }");
         tb.writeJavaFiles(src.resolve("m2"), "module m2 { }");
@@ -400,7 +400,7 @@
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
-        if (!log.contains("module-info.java:1:40: compiler.err.duplicate.exports: p"))
+        if (!log.contains("module-info.java:1:40: compiler.err.conflicting.exports: p"))
             throw new Exception("expected output not found");
     }
 
@@ -408,7 +408,7 @@
      * Verify that duplicate exported packages are detected.
      */
     @Test
-    public void testDuplicateExports_modules(Path base) throws Exception {
+    public void testConflictingExports_modules(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeFile(src_m1.resolve("module-info.java"), "module m1 { }");
@@ -426,7 +426,7 @@
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
-        if (!log.contains("module-info.java:1:30: compiler.err.duplicate.exports: m1"))
+        if (!log.contains("module-info.java:1:30: compiler.err.conflicting.exports.to.module: m1"))
             throw new Exception("expected output not found");
     }
 
@@ -434,12 +434,14 @@
      * Verify that duplicate exported packages are detected.
      */
     @Test
-    public void testDuplicateDynamicExports_modules(Path base) throws Exception {
+    public void testConflictingDynamicExports_modules(Path base) throws Exception {
         Path src = base.resolve("src");
         Path src_m1 = src.resolve("m1");
         tb.writeFile(src_m1.resolve("module-info.java"), "module m1 { }");
         Path src_m2 = src.resolve("m2");
-        tb.writeFile(src_m2.resolve("module-info.java"), "module m2 { exports dynamic p to m1, m1; }");
+        tb.writeJavaFiles(src_m2,
+                "module m2 { exports dynamic p to m1, m1; }",
+                "package p; public class C { }");
 
         Path classes = base.resolve("classes");
         Files.createDirectories(classes);
@@ -452,7 +454,7 @@
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
 
-        if (!log.contains("module-info.java:1:38: compiler.err.duplicate.exports: m1"))
+        if (!log.contains("module-info.java:1:38: compiler.err.conflicting.exports.to.module: m1"))
             throw new Exception("expected output not found");
     }
 
--- a/test/tools/javac/parser/JavacParserTest.java	Sat Aug 27 19:27:11 2016 -0700
+++ b/test/tools/javac/parser/JavacParserTest.java	Tue Aug 30 20:43:58 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -370,7 +370,7 @@
     }
 
     @Test
-    void testCorrectWilcardPositions1() throws IOException {
+    void testCorrectWildcardPositions1() throws IOException {
         performWildcardPositionsTest("package test; import java.util.List; " +
                 "class Test { private void method() { List<? extends List<? extends String>> l; } }",
 
@@ -385,7 +385,7 @@
     }
 
     @Test
-    void testCorrectWilcardPositions2() throws IOException {
+    void testCorrectWildcardPositions2() throws IOException {
         performWildcardPositionsTest("package test; import java.util.List; "
                 + "class Test { private void method() { List<? super List<? super String>> l; } }",
                 Arrays.asList("List<? super List<? super String>> l;",
@@ -399,7 +399,7 @@
     }
 
     @Test
-    void testCorrectWilcardPositions3() throws IOException {
+    void testCorrectWildcardPositions3() throws IOException {
         performWildcardPositionsTest("package test; import java.util.List; " +
                 "class Test { private void method() { List<? super List<?>> l; } }",
 
@@ -413,7 +413,7 @@
     }
 
     @Test
-    void testCorrectWilcardPositions4() throws IOException {
+    void testCorrectWildcardPositions4() throws IOException {
         performWildcardPositionsTest("package test; import java.util.List; " +
                 "class Test { private void method() { " +
                 "List<? extends List<? extends List<? extends String>>> l; } }",
@@ -432,7 +432,7 @@
     }
 
     @Test
-    void testCorrectWilcardPositions5() throws IOException {
+    void testCorrectWildcardPositions5() throws IOException {
         performWildcardPositionsTest("package test; import java.util.List; " +
                 "class Test { private void method() { " +
                 "List<? extends List<? extends List<? extends String   >>> l; } }",
@@ -701,7 +701,7 @@
             }
         }.scan(cut, null);
 
-        assertEquals("testSwitchError: The Erroneous tree "
+        assertEquals("testOperatorMissingError: The Erroneous tree "
                 + "error values: " + values
                 + " do not match expected error values: "
                 + expectedValues, values, expectedValues);
@@ -726,7 +726,7 @@
             }
         }.scan(cut, null);
 
-        assertEquals("testSwitchError: The Erroneous tree "
+        assertEquals("testMissingParenthesisError: The Erroneous tree "
                 + "error values: " + values
                 + " do not match expected error values: "
                 + expectedValues, values, expectedValues);
@@ -751,7 +751,7 @@
             }
         }.scan(cut, null);
 
-        assertEquals("testSwitchError: The Erroneous tree "
+        assertEquals("testMissingClassError: The Erroneous tree "
                 + "error values: " + values
                 + " do not match expected error values: "
                 + expectedValues, values, expectedValues);