changeset 43262:61eeb6ee2289

Merge
author henryjen
date Thu, 19 Jan 2017 07:02:34 -0800
parents d377e97291d8 f5b52e571607
children ca999fb7b46d
files
diffstat 13 files changed, 560 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/AnnotationValueVisitor.java	Tue Jul 12 14:41:14 2016 -0700
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/AnnotationValueVisitor.java	Thu Jan 19 07:02:34 2017 -0800
@@ -68,8 +68,8 @@
  * javax.lang.model.*} packages bundled in Java SE 8 were required to
  * also be runnable on Java SE 7.  Therefore, default methods
  * were <em>not</em> used when extending {@code javax.lang.model.*}
- * to cover Java SE 8 language features.  However, default methods may
- * be used in subsequent revisions of the {@code javax.lang.model.*}
+ * to cover Java SE 8 language features.  However, default methods
+ * are used in subsequent revisions of the {@code javax.lang.model.*}
  * packages that are only required to run on Java SE 8 and higher
  * platform versions.
  *
@@ -90,11 +90,16 @@
     R visit(AnnotationValue av, P p);
 
     /**
-     * A convenience method equivalent to {@code v.visit(av, null)}.
+     * A convenience method equivalent to {@code visit(av, null)}.
+     *
+     * @implSpec The default implementation is {@code visit(av, null)}.
+     *
      * @param av the value to visit
      * @return  a visitor-specified result
      */
-    R visit(AnnotationValue av);
+    default R visit(AnnotationValue av) {
+        return visit(av, null);
+    }
 
     /**
      * Visits a {@code boolean} value in an annotation.
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/ElementVisitor.java	Tue Jul 12 14:41:14 2016 -0700
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/ElementVisitor.java	Thu Jan 19 07:02:34 2017 -0800
@@ -59,8 +59,8 @@
  * javax.lang.model.*} packages bundled in Java SE 8 were required to
  * also be runnable on Java SE 7.  Therefore, default methods
  * were <em>not</em> used when extending {@code javax.lang.model.*}
- * to cover Java SE 8 language features.  However, default methods may
- * be used in subsequent revisions of the {@code javax.lang.model.*}
+ * to cover Java SE 8 language features.  However, default methods
+ * are used in subsequent revisions of the {@code javax.lang.model.*}
  * packages that are only required to run on Java SE 8 and higher
  * platform versions.
  *
@@ -85,11 +85,16 @@
     R visit(Element e, P p);
 
     /**
-     * A convenience method equivalent to {@code v.visit(e, null)}.
+     * A convenience method equivalent to {@code visit(e, null)}.
+     *
+     * @implSpec The default implementation is {@code visit(e, null)}.
+     *
      * @param e  the element to visit
      * @return a visitor-specified result
      */
-    R visit(Element e);
+    default R visit(Element e) {
+        return visit(e, null);
+    }
 
     /**
      * Visits a package element.
@@ -146,10 +151,16 @@
 
     /**
      * Visits a module element.
+     *
+     * @implSpec Visits a {@code ModuleElement} by calling {@code
+     * visitUnknown(e, p)}.
+     *
      * @param e  the element to visit
      * @param p  a visitor-specified parameter
      * @return a visitor-specified result
      * @since 9
      */
-    R visitModule(ModuleElement e, P p);
+    default R visitModule(ModuleElement e, P p) {
+        return visitUnknown(e, p);
+    }
 }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeVisitor.java	Tue Jul 12 14:41:14 2016 -0700
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeVisitor.java	Thu Jan 19 07:02:34 2017 -0800
@@ -59,8 +59,8 @@
  * javax.lang.model.*} packages bundled in Java SE 8 were required to
  * also be runnable on Java SE 7.  Therefore, default methods
  * were <em>not</em> used when extending {@code javax.lang.model.*}
- * to cover Java SE 8 language features.  However, default methods may
- * be used in subsequent revisions of the {@code javax.lang.model.*}
+ * to cover Java SE 8 language features.  However, default methods
+ * are used in subsequent revisions of the {@code javax.lang.model.*}
  * packages that are only required to run on Java SE 8 and higher
  * platform versions.
  *
@@ -85,11 +85,16 @@
     R visit(TypeMirror t, P p);
 
     /**
-     * A convenience method equivalent to {@code v.visit(t, null)}.
+     * A convenience method equivalent to {@code visit(t, null)}.
+     *
+     * @implSpec The default implementation is {@code visit(t, null)}.
+     *
      * @param t the element to visit
      * @return  a visitor-specified result
      */
-    R visit(TypeMirror t);
+    default R visit(TypeMirror t) {
+        return visit(t, null);
+    }
 
     /**
      * Visits a primitive type.
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java	Tue Jul 12 14:41:14 2016 -0700
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java	Thu Jan 19 07:02:34 2017 -0800
@@ -139,6 +139,7 @@
      */
     @Override
     public R visitModule(ModuleElement e, P p) {
-        return visitUnknown(e, p);
+        // Use implementation from interface default method
+        return ElementVisitor.super.visitModule(e, p);
     }
 }
--- a/langtools/test/TEST.ROOT	Tue Jul 12 14:41:14 2016 -0700
+++ b/langtools/test/TEST.ROOT	Thu Jan 19 07:02:34 2017 -0800
@@ -14,8 +14,8 @@
 # Group definitions
 groups=TEST.groups
 
-# Tests using jtreg 4.2 b04 features
-requiredVersion=4.2 b04
+# Tests using jtreg 4.2 b05 features
+requiredVersion=4.2 b05
 
 # Use new module options
 useNewOptions=true
--- a/langtools/test/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java	Tue Jul 12 14:41:14 2016 -0700
+++ b/langtools/test/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java	Thu Jan 19 07:02:34 2017 -0800
@@ -143,6 +143,7 @@
                     Arrays.asList(new File(System.getProperty("test.src"),
                     this.getClass().getName() + ".java")));
             java.util.List<String> options = Arrays.asList(
+                "--add-modules", "jdk.jdeps",
                 "--add-exports", "jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED",
                 "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
                 "--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
--- a/langtools/test/tools/javac/classfiles/attributes/Module/ModuleTest.java	Tue Jul 12 14:41:14 2016 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/Module/ModuleTest.java	Thu Jan 19 07:02:34 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -24,7 +24,7 @@
 /*
  * @test
  * @summary Module attribute tests
- * @bug 8080878 8161906 8162713
+ * @bug 8080878 8161906 8162713 8170250
  * @modules java.compiler
  *          jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -53,6 +53,28 @@
     }
 
     @Test
+    public void testOpenEmptyModule(Path base) throws Exception {
+        ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m", ModuleFlag.OPEN)
+                .write(base);
+        compile(base);
+        testModuleAttribute(base, moduleDescriptor);
+    }
+
+    @Test
+    public void testModuleName(Path base) throws Exception {
+        testName("module.name", base.resolve("dot"));
+        testName("module.exports.component.subcomponent.more.dots", base.resolve("dots"));
+        testName("moduleName", base.resolve("noDots"));
+    }
+
+    private void testName(String name, Path path) throws Exception{
+        ModuleDescriptor moduleDescriptor = new ModuleDescriptor(name)
+                .write(path);
+        compile(path);
+        testModuleAttribute(path, moduleDescriptor);
+    }
+
+    @Test
     public void testExports(Path base) throws Exception {
         ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
                 .exports("pack")
@@ -92,16 +114,6 @@
     }
 
     @Test
-    public void testQualifiedDynamicExports(Path base) throws Exception {
-        ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
-                .exportsTo("pack", "jdk.compiler")
-                .write(base);
-        tb.writeJavaFiles(base, "package pack; public class A { }");
-        compile(base);
-        testModuleAttribute(base, moduleDescriptor);
-    }
-
-    @Test
     public void testSeveralQualifiedExports(Path base) throws Exception {
         ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
                 .exportsTo("pack", "jdk.compiler, jdk.jdeps")
@@ -121,6 +133,47 @@
     }
 
     @Test
+    public void testOpens(Path base) throws Exception {
+        ModuleDescriptor moduleDescriptor = new ModuleDescriptor("module.name")
+                .opens("pack")
+                .write(base);
+        tb.writeJavaFiles(base, "package pack; public class C extends java.util.ArrayList{ }");
+        compile(base);
+        testModuleAttribute(base, moduleDescriptor);
+    }
+
+    @Test
+    public void testQualifiedOpens(Path base) throws Exception {
+        ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
+                .opensTo("pack", "jdk.compiler")
+                .write(base);
+        tb.writeJavaFiles(base, "package pack; public class A { }");
+        compile(base);
+        testModuleAttribute(base, moduleDescriptor);
+    }
+
+    @Test
+    public void testSeveralOpens(Path base) throws Exception {
+        ModuleDescriptor moduleDescriptor = new ModuleDescriptor("module.m1.name")
+                .opensTo("pack", "jdk.compiler, jdk.jdeps")
+                .opensTo("pack2", "jdk.jdeps")
+                .opensTo("pack3", "jdk.compiler")
+                .opensTo("pack4", "jdk.compiler, jdk.jdeps")
+                .opensTo("pack5", "jdk.compiler")
+                .opens("pack6")
+                .write(base);
+        tb.writeJavaFiles(base,
+                "package pack; public class A {}",
+                "package pack2; public class B {}",
+                "package pack3; public class C {}",
+                "package pack4; public class C {}",
+                "package pack5; public class C {}",
+                "package pack6; public class C {}");
+        compile(base);
+        testModuleAttribute(base, moduleDescriptor);
+    }
+
+    @Test
     public void testRequires(Path base) throws Exception {
         ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
                 .requires("jdk.compiler")
@@ -182,10 +235,12 @@
                 .provides("java.util.Collection", "pack2.D")
                 .provides("java.util.List", "pack2.D")
                 .requires("jdk.compiler")
+                .provides("javax.tools.FileObject", "pack2.E")
                 .provides("com.sun.tools.javac.Main", "pack2.C")
                 .write(base);
         tb.writeJavaFiles(base, "package pack2; public class D extends java.util.ArrayList{ }",
-                "package pack2; public class C extends com.sun.tools.javac.Main{ }");
+                "package pack2; public class C extends com.sun.tools.javac.Main{ }",
+                "package pack2; public class E extends javax.tools.SimpleJavaFileObject{ public E(){ super(null,null); } }");
         compile(base);
         testModuleAttribute(base, moduleDescriptor);
     }
@@ -203,9 +258,10 @@
     public void testSeveralUses(Path base) throws Exception {
         ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m")
                 .uses("java.util.List")
-                .uses("java.util.Collection")
+                .uses("java.util.Collection") // from java.base
                 .requires("jdk.compiler")
-                .uses("javax.tools.JavaCompiler")
+                .uses("javax.tools.JavaCompiler") // from java.compiler
+                .uses("com.sun.tools.javac.Main") // from jdk.compiler
                 .write(base);
         compile(base);
         testModuleAttribute(base, moduleDescriptor);
@@ -216,9 +272,10 @@
         Path m1 = base.resolve("m1x");
         ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m1x")
                 .exports("pack1")
-                .exports("pack3")
+                .opens("pack3")
                 .exportsTo("packTo1", "m2x")
-                .exportsTo("packTo3", "m3x")
+                .opensTo("packTo1", "m2x") // the same as exportsTo
+                .opensTo("packTo3", "m3x")
                 .requires("jdk.compiler")
                 .requires("m2x", RequiresFlag.TRANSITIVE)
                 .requires("m3x", RequiresFlag.STATIC)
@@ -230,9 +287,49 @@
                 .requires("m5x", RequiresFlag.STATIC)
                 .requires("m6x", RequiresFlag.TRANSITIVE)
                 .requires("java.compiler")
-                .exportsTo("packTo4", "java.compiler")
+                .opensTo("packTo4", "java.compiler")
                 .exportsTo("packTo2", "java.compiler")
-                .exports("pack4")
+                .opens("pack2") // same as exports
+                .opens("pack4")
+                .exports("pack2")
+                .write(m1);
+        tb.writeJavaFiles(m1, "package pack1; public class C extends java.util.ArrayList{ }",
+                "package pack2; public class D extends java.util.ArrayList{ }",
+                "package pack3; public class D extends java.util.ArrayList{ }",
+                "package pack4; public class D extends java.util.ArrayList{ }");
+        tb.writeJavaFiles(m1,
+                "package packTo1; public class T1 {}",
+                "package packTo2; public class T2 {}",
+                "package packTo3; public class T3 {}",
+                "package packTo4; public class T4 {}");
+        tb.writeJavaFiles(base.resolve("m2x"), "module m2x { }");
+        tb.writeJavaFiles(base.resolve("m3x"), "module m3x { }");
+        tb.writeJavaFiles(base.resolve("m4x"), "module m4x { }");
+        tb.writeJavaFiles(base.resolve("m5x"), "module m5x { }");
+        tb.writeJavaFiles(base.resolve("m6x"), "module m6x { }");
+        compile(base, "--module-source-path", base.toString(),
+                "-d", base.toString());
+        testModuleAttribute(m1, moduleDescriptor);
+    }
+
+    @Test
+    public void testOpenComplexModule(Path base) throws Exception {
+        Path m1 = base.resolve("m1x");
+        ModuleDescriptor moduleDescriptor = new ModuleDescriptor("m1x", ModuleFlag.OPEN)
+                .exports("pack1")
+                .exportsTo("packTo1", "m2x")
+                .requires("jdk.compiler")
+                .requires("m2x", RequiresFlag.TRANSITIVE)
+                .requires("m3x", RequiresFlag.STATIC)
+                .requires("m4x", RequiresFlag.TRANSITIVE, RequiresFlag.STATIC)
+                .provides("java.util.List", "pack1.C", "pack2.D")
+                .uses("java.util.List")
+                .uses("java.nio.file.Path")
+                .requires("jdk.jdeps", RequiresFlag.STATIC, RequiresFlag.TRANSITIVE)
+                .requires("m5x", RequiresFlag.STATIC)
+                .requires("m6x", RequiresFlag.TRANSITIVE)
+                .requires("java.compiler")
+                .exportsTo("packTo2", "java.compiler")
                 .exports("pack2")
                 .write(m1);
         tb.writeJavaFiles(m1, "package pack1; public class C extends java.util.ArrayList{ }",
--- a/langtools/test/tools/javac/classfiles/attributes/Module/ModuleTestBase.java	Tue Jul 12 14:41:14 2016 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/Module/ModuleTestBase.java	Thu Jan 19 07:02:34 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -25,7 +25,6 @@
 import com.sun.tools.classfile.ConstantPool;
 import com.sun.tools.classfile.ConstantPoolException;
 import com.sun.tools.classfile.Module_attribute;
-import com.sun.tools.javac.util.Pair;
 
 import java.io.IOException;
 import java.lang.annotation.Retention;
@@ -36,11 +35,11 @@
 import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
@@ -74,20 +73,30 @@
         ClassFile classFile = ClassFile.read(modulePath.resolve("module-info.class"));
         Module_attribute moduleAttribute = (Module_attribute) classFile.getAttribute("Module");
         ConstantPool constantPool = classFile.constant_pool;
-
+        testModuleName(moduleDescriptor, moduleAttribute, constantPool);
+        testModuleFlags(moduleDescriptor, moduleAttribute);
         testRequires(moduleDescriptor, moduleAttribute, constantPool);
         testExports(moduleDescriptor, moduleAttribute, constantPool);
+        testOpens(moduleDescriptor, moduleAttribute, constantPool);
         testProvides(moduleDescriptor, moduleAttribute, constantPool);
         testUses(moduleDescriptor, moduleAttribute, constantPool);
     }
 
+    private void testModuleName(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
+        tr.checkEquals(constantPool.getModuleInfo(module.module_name).getName(), moduleDescriptor.name, "Unexpected module name");
+    }
+
+    private void testModuleFlags(ModuleDescriptor moduleDescriptor, Module_attribute module) {
+        tr.checkEquals(module.module_flags, moduleDescriptor.flags, "Unexpected module flags");
+    }
+
     private void testRequires(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
         tr.checkEquals(module.requires_count, moduleDescriptor.requires.size(), "Wrong amount of requires.");
 
-        List<Pair<String, Integer>> actualRequires = new ArrayList<>();
+        List<Requires> actualRequires = new ArrayList<>();
         for (Module_attribute.RequiresEntry require : module.requires) {
-            actualRequires.add(Pair.of(
-                    require.getRequires(constantPool).replace('/', '.'),
+            actualRequires.add(new Requires(
+                    require.getRequires(constantPool),
                     require.requires_flags));
         }
         tr.checkContains(actualRequires, moduleDescriptor.requires, "Lists of requires don't match");
@@ -104,18 +113,36 @@
                 tr.checkEquals(export.exports_to_count, expectedTo.size(), "Wrong amount of exports to");
                 List<String> actualTo = new ArrayList<>();
                 for (int toIdx : export.exports_to_index) {
-                    actualTo.add(constantPool.getModuleInfo(toIdx).getName().replace('/', '.'));
+                    actualTo.add(constantPool.getModuleInfo(toIdx).getName());
                 }
                 tr.checkContains(actualTo, expectedTo, "Lists of \"exports to\" don't match.");
             }
         }
     }
 
+    private void testOpens(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
+        tr.checkEquals(module.opens_count, moduleDescriptor.opens.size(), "Wrong amount of opens.");
+        for (Module_attribute.OpensEntry open : module.opens) {
+            String pkg = constantPool.getPackageInfo(open.opens_index).getName();
+            if (tr.checkTrue(moduleDescriptor.opens.containsKey(pkg), "Unexpected open " + pkg)) {
+                Open expectedOpen = moduleDescriptor.opens.get(pkg);
+                tr.checkEquals(expectedOpen.mask, open.opens_flags, "Wrong open flags");
+                List<String> expectedTo = expectedOpen.to;
+                tr.checkEquals(open.opens_to_count, expectedTo.size(), "Wrong amount of opens to");
+                List<String> actualTo = new ArrayList<>();
+                for (int toIdx : open.opens_to_index) {
+                    actualTo.add(constantPool.getModuleInfo(toIdx).getName());
+                }
+                tr.checkContains(actualTo, expectedTo, "Lists of \"opens to\" don't match.");
+            }
+        }
+    }
+
     private void testUses(ModuleDescriptor moduleDescriptor, Module_attribute module, ConstantPool constantPool) throws ConstantPoolException {
         tr.checkEquals(module.uses_count, moduleDescriptor.uses.size(), "Wrong amount of uses.");
         List<String> actualUses = new ArrayList<>();
         for (int usesIdx : module.uses_index) {
-            String uses = constantPool.getClassInfo(usesIdx).getBaseName().replace('/', '.');
+            String uses = constantPool.getClassInfo(usesIdx).getBaseName();
             actualUses.add(uses);
         }
         tr.checkContains(actualUses, moduleDescriptor.uses, "Lists of uses don't match");
@@ -131,10 +158,10 @@
         tr.checkEquals(moduleProvidesCount, moduleDescriptorProvidesCount, "Wrong amount of provides.");
         Map<String, List<String>> actualProvides = new HashMap<>();
         for (Module_attribute.ProvidesEntry provide : module.provides) {
-            String provides = constantPool.getClassInfo(provide.provides_index).getBaseName().replace('/', '.');
+            String provides = constantPool.getClassInfo(provide.provides_index).getBaseName();
             List<String> impls = new ArrayList<>();
             for (int i = 0; i < provide.with_count; i++) {
-                String with = constantPool.getClassInfo(provide.with_index[i]).getBaseName().replace('/', '.');
+                String with = constantPool.getClassInfo(provide.with_index[i]).getBaseName();
                 impls.add(with);
             }
             actualProvides.put(provides, impls);
@@ -163,9 +190,27 @@
         int getMask();
     }
 
+    public enum ModuleFlag implements Mask {
+        OPEN("open", Module_attribute.ACC_OPEN);
+
+        private final String token;
+        private final int mask;
+
+        ModuleFlag(String token, int mask) {
+            this.token = token;
+            this.mask = mask;
+        }
+
+        @Override
+        public int getMask() {
+            return mask;
+        }
+    }
+
     public enum RequiresFlag implements Mask {
         TRANSITIVE("transitive", Module_attribute.ACC_TRANSITIVE),
-        STATIC("static", Module_attribute.ACC_STATIC_PHASE);
+        STATIC("static", Module_attribute.ACC_STATIC_PHASE),
+        MANDATED("", Module_attribute.ACC_MANDATED);
 
         private final String token;
         private final int mask;
@@ -181,13 +226,30 @@
         }
     }
 
-    public enum ExportFlag implements Mask {
+    public enum ExportsFlag implements Mask {
         SYNTHETIC("", Module_attribute.ACC_SYNTHETIC);
 
         private final String token;
         private final int mask;
 
-        ExportFlag(String token, int mask) {
+        ExportsFlag(String token, int mask) {
+            this.token = token;
+            this.mask = mask;
+        }
+
+        @Override
+        public int getMask() {
+            return mask;
+        }
+    }
+
+    public enum OpensFlag implements Mask {
+        SYNTHETIC("", Module_attribute.ACC_SYNTHETIC);
+
+        private final String token;
+        private final int mask;
+
+        OpensFlag(String token, int mask) {
             this.token = token;
             this.mask = mask;
         }
@@ -199,27 +261,64 @@
     }
 
     private class Export {
-        String pkg;
-        int mask;
-        List<String> to = new ArrayList<>();
+        private final String pkg;
+        private final int mask;
+        private final List<String> to = new ArrayList<>();
 
-        public Export(String pkg, int mask) {
+        Export(String pkg, int mask) {
             this.pkg = pkg;
             this.mask = mask;
         }
     }
 
+    private class Open {
+        private final String pkg;
+        private final int mask;
+        private final List<String> to = new ArrayList<>();
+
+        Open(String pkg, int mask) {
+            this.pkg = pkg;
+            this.mask = mask;
+        }
+    }
+
+    private class Requires {
+        private final String module;
+        private final int mask;
+
+        Requires(String module, int mask) {
+            this.module = module;
+            this.mask = mask;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            Requires requires = (Requires) o;
+            return mask == requires.mask &&
+                    Objects.equals(module, requires.module);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(module, mask);
+        }
+    }
+
     protected class ModuleDescriptor {
 
         private final String name;
-        //pair is name of module and flag(public,mandated,synthetic)
-        private final List<Pair<String, Integer>> requires = new ArrayList<>();
+        private final int flags;
+
+        private final List<Requires> requires = new ArrayList<>();
 
         {
-            requires.add(new Pair<>("java.base", Module_attribute.ACC_MANDATED));
+            requires.add(new Requires("java.base", computeMask(RequiresFlag.MANDATED)));
         }
 
         private final Map<String, Export> exports = new HashMap<>();
+        private final Map<String, Open> opens = new HashMap<>();
 
         //List of service and implementation
         private final Map<String, List<String>> provides = new LinkedHashMap<>();
@@ -227,22 +326,26 @@
 
         private static final String LINE_END = ";\n";
 
-        StringBuilder content = new StringBuilder("module ");
+        StringBuilder content = new StringBuilder("");
 
-        public ModuleDescriptor(String moduleName) {
+        public ModuleDescriptor(String moduleName, ModuleFlag... flags) {
             this.name = moduleName;
-            content.append(name).append('{').append('\n');
+            this.flags = computeMask(flags);
+            for (ModuleFlag flag : flags) {
+                content.append(flag.token).append(" ");
+            }
+            content.append("module ").append(moduleName).append('{').append('\n');
         }
 
         public ModuleDescriptor requires(String module) {
-            this.requires.add(Pair.of(module, 0));
+            this.requires.add(new Requires(module, 0));
             content.append("    requires ").append(module).append(LINE_END);
 
             return this;
         }
 
         public ModuleDescriptor requires(String module, RequiresFlag... flags) {
-            this.requires.add(new Pair<>(module, computeMask(flags)));
+            this.requires.add(new Requires(module, computeMask(flags)));
 
             content.append("    requires ");
             for (RequiresFlag flag : flags) {
@@ -253,26 +356,52 @@
             return this;
         }
 
-        public ModuleDescriptor exports(String pkg, ExportFlag... flags) {
-            this.exports.putIfAbsent(pkg, new Export(pkg, computeMask(flags)));
+        public ModuleDescriptor exports(String pkg, ExportsFlag... flags) {
+            this.exports.put(toInternalForm(pkg), new Export(toInternalForm(pkg), computeMask(flags)));
             content.append("    exports ");
-            for (ExportFlag flag : flags) {
+            for (ExportsFlag flag : flags) {
                 content.append(flag.token).append(" ");
             }
             content.append(pkg).append(LINE_END);
             return this;
         }
 
-        public ModuleDescriptor exportsTo(String pkg, String to, ExportFlag... flags) {
+        public ModuleDescriptor exportsTo(String pkg, String to, ExportsFlag... flags) {
             List<String> tos = Pattern.compile(",")
                     .splitAsStream(to)
                     .map(String::trim)
                     .collect(Collectors.toList());
-            this.exports.computeIfAbsent(pkg, k -> new Export(pkg, computeMask(flags)))
+            this.exports.compute(toInternalForm(pkg), (k,v) -> new Export(k, computeMask(flags)))
                     .to.addAll(tos);
 
             content.append("    exports ");
-            for (ExportFlag flag : flags) {
+            for (ExportsFlag flag : flags) {
+                content.append(flag.token).append(" ");
+            }
+            content.append(pkg).append(" to ").append(to).append(LINE_END);
+            return this;
+        }
+
+        public ModuleDescriptor opens(String pkg, OpensFlag... flags) {
+            this.opens.put(toInternalForm(pkg), new Open(toInternalForm(pkg), computeMask(flags)));
+            content.append("    opens ");
+            for (OpensFlag flag : flags) {
+                content.append(flag.token).append(" ");
+            }
+            content.append(pkg).append(LINE_END);
+            return this;
+        }
+
+        public ModuleDescriptor opensTo(String pkg, String to, OpensFlag... flags) {
+            List<String> tos = Pattern.compile(",")
+                    .splitAsStream(to)
+                    .map(String::trim)
+                    .collect(Collectors.toList());
+            this.opens.compute(toInternalForm(pkg), (k,v) -> new Open(toInternalForm(k), computeMask(flags)))
+                    .to.addAll(tos);
+
+            content.append("    opens ");
+            for (OpensFlag flag : flags) {
                 content.append(flag.token).append(" ");
             }
             content.append(pkg).append(" to ").append(to).append(LINE_END);
@@ -280,7 +409,10 @@
         }
 
         public ModuleDescriptor provides(String provides, String... with) {
-            this.provides.put(provides, Arrays.asList(with));
+            List<String> impls = Arrays.stream(with)
+                    .map(this::toInternalForm)
+                    .collect(Collectors.toList());
+            this.provides.put(toInternalForm(provides), impls);
             content.append("    provides ")
                     .append(provides)
                     .append(" with ")
@@ -290,8 +422,8 @@
         }
 
         public ModuleDescriptor uses(String... uses) {
-            Collections.addAll(this.uses, uses);
             for (String use : uses) {
+                this.uses.add(toInternalForm(use));
                 content.append("    uses ").append(use).append(LINE_END);
             }
             return this;
@@ -305,7 +437,11 @@
             return this;
         }
 
-        private int computeMask(Mask[] masks) {
+        private String toInternalForm(String name) {
+            return name.replace('.', '/');
+        }
+
+        private int computeMask(Mask... masks) {
             return Arrays.stream(masks)
                     .map(Mask::getMask)
                     .reduce((a, b) -> a | b)
--- a/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java	Tue Jul 12 14:41:14 2016 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java	Thu Jan 19 07:02:34 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -82,7 +82,8 @@
         Set<?> copy = new HashSet<>(expected);
         copy.removeAll(found);
         if (!found.containsAll(expected)) {
-            return checkTrue(false, message + " FAIL : not found elements : " + copy);
+            return checkTrue(false, message + " FAIL : not found elements : " + copy + "\n" +
+                    "Actual: " + found);
         } else {
             return checkTrue(true, message + " PASS : all elements found");
         }
--- a/langtools/test/tools/javac/diags/Example.java	Tue Jul 12 14:41:14 2016 -0700
+++ b/langtools/test/tools/javac/diags/Example.java	Thu Jan 19 07:02:34 2017 -0800
@@ -236,6 +236,7 @@
             // source for import statements or a magic comment
             for (File pf: procFiles) {
                 if (pf.getName().equals("CreateBadClassFile.java")) {
+                    pOpts.add("--add-modules=jdk.jdeps");
                     pOpts.add("--add-exports=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED");
                 }
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/TestVisitorDefaults.java	Thu Jan 19 07:02:34 2017 -0800
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/*
+ * @test
+ * @bug 8172910
+ * @summary Test behavior of default methods on visitors.
+ * @modules java.compiler
+ */
+
+import java.util.List;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+import javax.lang.model.util.*;
+
+/**
+ * Verify expected behavior of default methods on visitors.
+ */
+public class TestVisitorDefaults {
+    public static void main(String... args) {
+        DirectElementVisitorChild dvc = new DirectElementVisitorChild();
+        if (!"visitUnknown".equals(dvc.visitModule(null, null))) {
+            throw new RuntimeException("Problem with DirectElementVisitorChild");
+        }
+        if (!"visit".equals(dvc.visit(null))) {
+            throw new RuntimeException("Problem with DirectElementVisitorChild");
+        }
+
+        IndirectElementVisitorChild ivc = new IndirectElementVisitorChild();
+        if (!"visitUnknown".equals(ivc.visitModule(null, null))) {
+            throw new RuntimeException("Problem with IndirectElementVisitorChild");
+        }
+
+        DirectTypeVisitorChild dtvc = new DirectTypeVisitorChild();
+        if (!"visit".equals(dtvc.visit(null))) {
+            throw new RuntimeException("Problem with DirectTypeVisitorChild");
+        }
+
+        DirectAnnotationVisitorChild davc = new DirectAnnotationVisitorChild();
+        if (!"visit".equals(davc.visit(null))) {
+            throw new RuntimeException("Problem with DirectAnnotationVisitorChild");
+        }
+    }
+
+    private static class DirectElementVisitorChild
+        implements ElementVisitor<String, Object> {
+
+        public DirectElementVisitorChild() {
+            super();
+        }
+
+        @Override
+        public String visitModule(ModuleElement e, Object o) {
+            return ElementVisitor.super.visitModule(e, null);
+        }
+
+        @Override
+        public String visitUnknown(Element e, Object o) {
+            return "visitUnknown";
+        }
+
+        @Override
+        public String visit(Element e) {
+            return ElementVisitor.super.visit(e);
+        }
+
+        @Override
+        public String visit(Element e, Object o) {
+            return "visit";
+        }
+
+        @Override
+        public String visitExecutable(ExecutableElement e, Object o)       { return throwUOE(); }
+        @Override
+        public String visitPackage(PackageElement e, Object o)             { return throwUOE(); }
+        @Override
+        public String visitType(TypeElement e, Object o)                   { return throwUOE(); }
+        @Override
+        public String visitTypeParameter(TypeParameterElement e, Object o) { return throwUOE(); }
+        @Override
+        public String visitVariable(VariableElement e, Object o)           { return throwUOE(); }
+    }
+
+    private static class IndirectElementVisitorChild
+        extends AbstractElementVisitor6<String, Object> {
+
+        public IndirectElementVisitorChild() {
+            super();
+        }
+
+        @Override
+        public String visitModule(ModuleElement e, Object o) {
+            return super.visitModule(e, o);
+        }
+
+
+        @Override
+        public String visitUnknown(Element e, Object o) {
+            return "visitUnknown";
+        }
+
+        @Override
+        public String visitExecutable(ExecutableElement e, Object o)       { return throwUOE(); }
+        @Override
+        public String visitPackage(PackageElement e, Object o)             { return throwUOE(); }
+        @Override
+        public String visitType(TypeElement e, Object o)                   { return throwUOE(); }
+        @Override
+        public String visitTypeParameter(TypeParameterElement e, Object o) { return throwUOE(); }
+        @Override
+        public String visitVariable(VariableElement e, Object o)           { return throwUOE(); }
+    }
+
+
+    private static class DirectTypeVisitorChild
+        implements TypeVisitor<String, Object> {
+
+        public DirectTypeVisitorChild() {
+            super();
+        }
+
+        @Override
+        public String visit(TypeMirror t) {
+            return TypeVisitor.super.visit(t);
+        }
+
+        @Override
+        public String visit(TypeMirror t, Object o) {
+            return "visit";
+        }
+
+        @Override
+        public String visitUnknown(TypeMirror t, Object o)            { return throwUOE(); }
+        @Override
+        public String visitArray(ArrayType t, Object o)               { return throwUOE(); }
+        @Override
+        public String visitDeclared(DeclaredType t, Object o)         { return throwUOE(); }
+        @Override
+        public String visitError(ErrorType t, Object o)               { return throwUOE(); }
+        @Override
+        public String visitExecutable(ExecutableType t, Object o)     { return throwUOE(); }
+        @Override
+        public String visitIntersection(IntersectionType t, Object o) { return throwUOE(); }
+        @Override
+        public String visitNoType(NoType t, Object o)                 { return throwUOE(); }
+        @Override
+        public String visitNull(NullType t, Object o)                 { return throwUOE(); }
+        @Override
+        public String visitPrimitive(PrimitiveType t, Object o)       { return throwUOE(); }
+        @Override
+        public String visitTypeVariable(TypeVariable t, Object o)     { return throwUOE(); }
+        @Override
+        public String visitUnion(UnionType t, Object o)               { return throwUOE(); }
+        @Override
+        public String visitWildcard(WildcardType t, Object o)         { return throwUOE(); }
+    }
+
+    private static class DirectAnnotationVisitorChild
+        implements AnnotationValueVisitor<String, Object> {
+
+        @Override
+        public String visit(AnnotationValue av) {
+            return AnnotationValueVisitor.super.visit(av);
+        }
+
+        @Override
+        public String visit(AnnotationValue av, Object o) {
+            return "visit";
+        }
+
+        @Override
+        public String visitAnnotation(AnnotationMirror a, Object o)    { return throwUOE(); }
+        @Override
+        public String visitArray(List<? extends AnnotationValue> vals,
+                                   Object o)                           { return throwUOE(); }
+        @Override
+        public String visitBoolean(boolean b, Object o)                { return throwUOE(); }
+        @Override
+        public String visitByte(byte b, Object o)                      { return throwUOE(); }
+        @Override
+        public String visitChar(char c, Object o)                      { return throwUOE(); }
+        @Override
+        public String visitDouble(double d, Object o)                  { return throwUOE(); }
+        @Override
+        public String visitEnumConstant(VariableElement c, Object o)   { return throwUOE(); }
+        @Override
+        public String visitFloat(float f, Object o)                    { return throwUOE(); }
+        @Override
+        public String visitInt(int i, Object o)                        { return throwUOE(); }
+        @Override
+        public String visitLong(long i, Object o)                      { return throwUOE(); }
+        @Override
+        public String visitShort(short s, Object o)                    { return throwUOE(); }
+        @Override
+        public String visitString(String s, Object o)                  { return throwUOE(); }
+        @Override
+        public String visitType(TypeMirror t, Object o)                { return throwUOE(); }
+        @Override
+        public String visitUnknown(AnnotationValue av, Object o)       { return throwUOE(); }
+    }
+
+    private static String throwUOE() {
+        throw new UnsupportedOperationException();
+    }
+}
--- a/langtools/test/tools/javap/T7004698.java	Tue Jul 12 14:41:14 2016 -0700
+++ b/langtools/test/tools/javap/T7004698.java	Thu Jan 19 07:02:34 2017 -0800
@@ -42,6 +42,7 @@
         File srcFile = new File(srcDir, T7004698.class.getSimpleName() + ".java");
         File classesDir = new File(".");
         compile("-Xjcov",
+                "--add-modules", "jdk.jdeps",
                 "--add-exports", "jdk.jdeps/com.sun.tools.javap=ALL-UNNAMED",
                 "-d", classesDir.getPath(),
                 srcFile.getPath());
--- a/langtools/test/tools/jdeps/APIDeps.java	Tue Jul 12 14:41:14 2016 -0700
+++ b/langtools/test/tools/jdeps/APIDeps.java	Thu Jan 19 07:02:34 2017 -0800
@@ -60,6 +60,9 @@
         Path testsrc = Paths.get(System.getProperty("test.src"));
         List<String> options = new ArrayList<>();
 
+        // jdk.jdeps is a service provider module so needs to be explicitly included
+        options.add("--add-modules=jdk.jdeps");
+
         // add --add-exports
         String testModules = System.getProperty("test.modules", "");
         List<String> addExports = new ArrayList<>();