Merge
authorddehaven
Mon, 05 Dec 2016 08:36:16 -0800
changeset 42834 832c63c0692f
parent 42416 1cfad0990b99 (diff)
parent 42833 9c19d5018da1 (current diff)
child 42835 1dc3889eb057
Merge
--- a/langtools/.hgtags	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/.hgtags	Mon Dec 05 08:36:16 2016 -0800
@@ -389,3 +389,4 @@
 47871e348144bafddea0ede3a44299461e254a2d jdk-9+144
 cb9e896265ef45295fdd09986dee76624e4d41e4 jdk-9+145
 26f972dc2d174a75bc32131c29661c78568586b0 jdk-9+146
+76389430a13e82a9321cdc085216f6bff526e316 jdk-9+147
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java	Mon Dec 05 08:36:16 2016 -0800
@@ -1869,6 +1869,12 @@
      */
     public static class UndetVar extends DelegatedType {
 
+        enum Kind {
+            NORMAL,
+            CAPTURED,
+            THROWS;
+        }
+
         /** Inference variable change listener. The listener method is called
          *  whenever a change to the inference variable's bounds occurs
          */
@@ -1929,6 +1935,8 @@
         /** inference variable's change listener */
         public UndetVarListener listener = null;
 
+        Kind kind;
+
         @Override
         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
             return v.visitUndetVar(this, s);
@@ -1937,6 +1945,9 @@
         public UndetVar(TypeVar origin, UndetVarListener listener, Types types) {
             // This is a synthesized internal type, so we cannot annotate it.
             super(UNDETVAR, origin);
+            this.kind = origin.isCaptured() ?
+                    Kind.CAPTURED :
+                    Kind.NORMAL;
             this.listener = listener;
             bounds = new EnumMap<>(InferenceBound.class);
             List<Type> declaredBounds = types.getBounds(origin);
@@ -1948,6 +1959,10 @@
                 //add bound works in reverse order
                 addBound(InferenceBound.UPPER, t, types, true);
             }
+            if (origin.isCaptured() && !origin.lower.hasTag(BOT)) {
+                //add lower bound if needed
+                addBound(InferenceBound.LOWER, origin.lower, types, true);
+            }
         }
 
         @DefinedBy(Api.LANGUAGE_MODEL)
@@ -1977,6 +1992,14 @@
             return result;
         }
 
+        public void setThrow() {
+            if (this.kind == Kind.CAPTURED) {
+                //invalid state transition
+                throw new IllegalStateException();
+            }
+            this.kind = Kind.THROWS;
+        }
+
         /**
          * Returns a new copy of this undet var.
          */
@@ -2062,17 +2085,29 @@
             addBound(ib, bound, types, false);
         }
 
-        protected void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
-            Type bound2 = bound.map(toTypeVarMap).baseType();
-            List<Type> prevBounds = bounds.get(ib);
-            if (bound == qtype) return;
-            for (Type b : prevBounds) {
-                //check for redundancy - use strict version of isSameType on tvars
-                //(as the standard version will lead to false positives w.r.t. clones ivars)
-                if (types.isSameType(b, bound2, true)) return;
+        @SuppressWarnings("fallthrough")
+        private void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
+            if (kind == Kind.CAPTURED && !update) {
+                //Captured inference variables bounds must not be updated during incorporation,
+                //except when some inference variable (beta) has been instantiated in the
+                //right-hand-side of a 'C<alpha> = capture(C<? extends/super beta>) constraint.
+                if (bound.hasTag(UNDETVAR) && !((UndetVar)bound).isCaptured()) {
+                    //If the new incoming bound is itself a (regular) inference variable,
+                    //then we are allowed to propagate this inference variable bounds to it.
+                    ((UndetVar)bound).addBound(ib.complement(), this, types, false);
+                }
+            } else {
+                Type bound2 = bound.map(toTypeVarMap).baseType();
+                List<Type> prevBounds = bounds.get(ib);
+                if (bound == qtype) return;
+                for (Type b : prevBounds) {
+                    //check for redundancy - use strict version of isSameType on tvars
+                    //(as the standard version will lead to false positives w.r.t. clones ivars)
+                    if (types.isSameType(b, bound2, true)) return;
+                }
+                bounds.put(ib, prevBounds.prepend(bound2));
+                notifyBoundChange(ib, bound2, false);
             }
-            bounds.put(ib, prevBounds.prepend(bound2));
-            notifyBoundChange(ib, bound2, false);
         }
         //where
             TypeMapping<Void> toTypeVarMap = new TypeMapping<Void>() {
@@ -2128,46 +2163,12 @@
             }
         }
 
-        public boolean isCaptured() {
-            return false;
-        }
-    }
-
-    /**
-     * This class is used to represent synthetic captured inference variables
-     * that can be generated during nested generic method calls. The only difference
-     * between these inference variables and ordinary ones is that captured inference
-     * variables cannot get new bounds through incorporation.
-     */
-    public static class CapturedUndetVar extends UndetVar {
-
-        public CapturedUndetVar(CapturedType origin, UndetVarListener listener, Types types) {
-            super(origin, listener, types);
-            if (!origin.lower.hasTag(BOT)) {
-                addBound(InferenceBound.LOWER, origin.lower, types, true);
-            }
+        public final boolean isCaptured() {
+            return kind == Kind.CAPTURED;
         }
 
-        @Override
-        public void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
-            if (update) {
-                //only change bounds if request comes from substBounds
-                super.addBound(ib, bound, types, update);
-            }
-            else if (bound.hasTag(UNDETVAR) && !((UndetVar) bound).isCaptured()) {
-                ((UndetVar) bound).addBound(ib.complement(), this, types, false);
-            }
-        }
-
-        @Override
-        public boolean isCaptured() {
-            return true;
-        }
-
-        public UndetVar dup(Types types) {
-            UndetVar uv2 = new CapturedUndetVar((CapturedType)qtype, listener, types);
-            dupTo(uv2, types);
-            return uv2;
+        public final boolean isThrows() {
+            return kind == Kind.THROWS;
         }
     }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Dec 05 08:36:16 2016 -0800
@@ -2494,6 +2494,11 @@
                     List<Type> thrownTypes = resultInfo.checkContext.inferenceContext().asUndetVars(lambdaType.getThrownTypes());
 
                     chk.unhandled(inferredThrownTypes, thrownTypes);
+
+                    //18.2.5: "In addition, for all j (1 <= j <= n), the constraint reduces to the bound throws Ej"
+                    thrownTypes.stream()
+                            .filter(t -> t.hasTag(UNDETVAR))
+                            .forEach(t -> ((UndetVar)t).setThrow());
                 }
 
                 checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, currentTarget);
@@ -3074,6 +3079,10 @@
             if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) {
                 log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes());
             }
+            //18.2.5: "In addition, for all j (1 <= j <= n), the constraint reduces to the bound throws Ej"
+            thrownTypes.stream()
+                    .filter(t -> t.hasTag(UNDETVAR))
+                    .forEach(t -> ((UndetVar)t).setThrow());
         }
     }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java	Mon Dec 05 08:36:16 2016 -0800
@@ -412,6 +412,17 @@
             if (owner.kind == TYP) {
                 // We are seeing a member class.
                 c = syms.enterClass(env.toplevel.modle, tree.name, (TypeSymbol)owner);
+                if (c.owner != owner) {
+                    //anonymous class loaded from a classfile may be recreated from source (see below)
+                    //if this class is a member of such an anonymous class, fix the owner:
+                    Assert.check(owner.owner.kind != TYP, () -> owner.toString());
+                    Assert.check(c.owner.kind == TYP, () -> c.owner.toString());
+                    ClassSymbol cowner = (ClassSymbol) c.owner;
+                    if (cowner.members_field != null) {
+                        cowner.members_field.remove(c);
+                    }
+                    c.owner = owner;
+                }
                 if ((owner.flags_field & INTERFACE) != 0) {
                     tree.mods.flags |= PUBLIC | STATIC;
                 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Dec 05 08:36:16 2016 -0800
@@ -627,12 +627,11 @@
     TypeMapping<Void> fromTypeVarFun = new TypeMapping<Void>() {
         @Override
         public Type visitTypeVar(TypeVar tv, Void aVoid) {
-            return new UndetVar(tv, incorporationEngine(), types);
-        }
-
-        @Override
-        public Type visitCapturedType(CapturedType t, Void aVoid) {
-            return new CapturedUndetVar(t, incorporationEngine(), types);
+            UndetVar uv = new UndetVar(tv, incorporationEngine(), types);
+            if ((tv.tsym.flags() & Flags.THROWS) != 0) {
+                uv.setThrow();
+            }
+            return uv;
         }
     };
 
@@ -1463,7 +1462,7 @@
         THROWS(InferenceBound.UPPER) {
             @Override
             public boolean accepts(UndetVar t, InferenceContext inferenceContext) {
-                if ((t.qtype.tsym.flags() & Flags.THROWS) == 0) {
+                if (!t.isThrows()) {
                     //not a throws undet var
                     return false;
                 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Mon Dec 05 08:36:16 2016 -0800
@@ -890,6 +890,8 @@
      * like UPGRADE_MODULE_PATH and MODULE_PATH.
      */
     private class ModulePathLocationHandler extends SimpleLocationHandler {
+        private Map<String, ModuleLocationHandler> pathModules;
+
         ModulePathLocationHandler(Location location, Option... options) {
             super(location, options);
         }
@@ -904,6 +906,12 @@
         }
 
         @Override
+        public Location getLocationForModule(String moduleName) {
+            initPathModules();
+            return pathModules.get(moduleName);
+        }
+
+        @Override
         Iterable<Set<Location>> listLocationsForModules() {
             if (searchPath == null)
                 return Collections.emptyList();
@@ -921,6 +929,23 @@
             super.setPaths(paths);
         }
 
+        private void initPathModules() {
+            if (pathModules != null) {
+                return;
+            }
+
+            pathModules = new LinkedHashMap<>();
+
+            for (Set<Location> set : listLocationsForModules()) {
+                for (Location locn : set) {
+                    if (locn instanceof ModuleLocationHandler) {
+                        ModuleLocationHandler h = (ModuleLocationHandler) locn;
+                        pathModules.put(h.moduleName, h);
+                    }
+                }
+            }
+        }
+
         private void checkValidModulePathEntry(Path p) {
             if (Files.isDirectory(p)) {
                 // either an exploded module or a directory of modules
@@ -1158,7 +1183,6 @@
         private Map<String, Location> moduleLocations;
         private Map<Path, Location> pathLocations;
 
-
         ModuleSourcePathLocationHandler() {
             super(StandardLocation.MODULE_SOURCE_PATH,
                     Option.MODULE_SOURCE_PATH);
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Mon Dec 05 08:36:16 2016 -0800
@@ -279,7 +279,7 @@
      */
     @Override
     public void hard(String format, Object... args) {
-        rawout(feedback.getPre() + format + feedback.getPost(), args);
+        rawout(prefix(format), args);
     }
 
     /**
@@ -289,7 +289,7 @@
      * @param args printf args
      */
     void error(String format, Object... args) {
-        rawout(feedback.getErrorPre() + format + feedback.getErrorPost(), args);
+        rawout(prefixError(format), args);
     }
 
     /**
@@ -315,18 +315,6 @@
     }
 
     /**
-     * Optional output -- with embedded per- and post-fix
-     *
-     * @param format printf format
-     * @param args printf args
-     */
-    void fluffRaw(String format, Object... args) {
-        if (showFluff()) {
-            rawout(format, args);
-        }
-    }
-
-    /**
      * Resource bundle look-up
      *
      * @param key the resource key
@@ -351,28 +339,42 @@
     }
 
     /**
-     * Add prefixing to embedded newlines in a string, leading with the normal
-     * prefix
+     * Add normal prefixing/postfixing to embedded newlines in a string,
+     * bracketing with normal prefix/postfix
      *
      * @param s the string to prefix
+     * @return the pre/post-fixed and bracketed string
      */
     String prefix(String s) {
-        return prefix(s, feedback.getPre());
+         return prefix(s, feedback.getPre(), feedback.getPost());
     }
 
     /**
-     * Add prefixing to embedded newlines in a string
+     * Add error prefixing/postfixing to embedded newlines in a string,
+     * bracketing with error prefix/postfix
      *
      * @param s the string to prefix
-     * @param leading the string to prepend
+     * @return the pre/post-fixed and bracketed string
      */
-    String prefix(String s, String leading) {
-        if (s == null || s.isEmpty()) {
+    String prefixError(String s) {
+         return prefix(s, feedback.getErrorPre(), feedback.getErrorPost());
+    }
+
+    /**
+     * Add prefixing/postfixing to embedded newlines in a string,
+     * bracketing with prefix/postfix
+     *
+     * @param s the string to prefix
+     * @param pre the string to prepend to each line
+     * @param post the string to append to each line (replacing newline)
+     * @return the pre/post-fixed and bracketed string
+     */
+    String prefix(String s, String pre, String post) {
+        if (s == null) {
             return "";
         }
-        return leading
-                + s.substring(0, s.length() - 1).replaceAll("\\R", System.getProperty("line.separator") + feedback.getPre())
-                + s.substring(s.length() - 1, s.length());
+        String pp = s.replaceAll("\\R", post + pre);
+        return pre + pp + post;
     }
 
     /**
@@ -381,8 +383,7 @@
      * @param key the resource key
      */
     void hardrb(String key) {
-        String s = prefix(getResourceString(key));
-        cmdout.println(s);
+        hard(getResourceString(key));
     }
 
     /**
@@ -405,7 +406,7 @@
      */
     @Override
     public void hardmsg(String key, Object... args) {
-        cmdout.println(prefix(messageFormat(key, args)));
+        hard(messageFormat(key, args));
     }
 
     /**
@@ -418,7 +419,7 @@
     @Override
     public void errormsg(String key, Object... args) {
         if (isRunningInteractive()) {
-            cmdout.println(prefix(messageFormat(key, args), feedback.getErrorPre()));
+            rawout(prefixError(messageFormat(key, args)));
         } else {
             startmsg(key, args);
         }
@@ -431,7 +432,7 @@
      * @param args
      */
     void startmsg(String key, Object... args) {
-        cmderr.println(prefix(messageFormat(key, args), ""));
+        cmderr.println(messageFormat(key, args));
     }
 
     /**
@@ -452,15 +453,9 @@
         Map<String, String> a2b = stream.collect(toMap(a, b,
                 (m1, m2) -> m1,
                 () -> new LinkedHashMap<>()));
-        int aLen = 0;
-        for (String av : a2b.keySet()) {
-            aLen = Math.max(aLen, av.length());
-        }
-        String format = "   %-" + aLen + "s -- %s";
-        String indentedNewLine = LINE_SEP + feedback.getPre()
-                + String.format("   %-" + (aLen + 4) + "s", "");
         for (Entry<String, String> e : a2b.entrySet()) {
-            hard(format, e.getKey(), e.getValue().replaceAll("\n", indentedNewLine));
+            hard("%s", e.getKey());
+            rawout(prefix(e.getValue(), feedback.getPre() + "\t", feedback.getPost()));
         }
     }
 
@@ -1096,6 +1091,7 @@
             }
             if (path.isEmpty()) {
                 StreamSupport.stream(FileSystems.getDefault().getRootDirectories().spliterator(), false)
+                             .filter(root -> Files.exists(root))
                              .filter(root -> accept.test(root) && root.toString().startsWith(prefix))
                              .map(root -> new ArgSuggestion(root.toString()))
                              .forEach(result::add);
@@ -1697,7 +1693,7 @@
         } else if (start.isEmpty()) {
             stset = cmd + "-none";
         } else {
-            stset = prefix("startup.jsh:\n" + start + "\n" + cmd + "startup.jsh", "");
+            stset = "startup.jsh:\n" + start + "\n" + cmd + "startup.jsh";
         }
         hard(stset);
     }
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties	Mon Dec 05 08:36:16 2016 -0800
@@ -25,7 +25,7 @@
 
 jshell.msg.welcome =\
 Welcome to JShell -- Version {0}\n\
-For an introduction type: /help intro\n
+For an introduction type: /help intro
 jshell.err.opt.arg = Argument to {0} missing.
 jshell.err.opt.invalid = Invalid options: {0}.
 jshell.err.opt.one = Only one {0} option may be used.
@@ -94,7 +94,8 @@
 Type a Java language expression, statement, or declaration.\n\
 Or type one of the following commands:\n
 jshell.msg.help.subject =\n\
-For more information type ''/help'' followed by the name of command or a subject.\n\
+For more information type ''/help'' followed by the name of a\n\
+command or a subject.\n\
 For example ''/help /list'' or ''/help intro''.  Subjects:\n
 
 jshell.err.drop.arg =\
@@ -674,7 +675,7 @@
 \n\
 Where <mode> is the name of a previously defined feedback mode.\n\
 Where <prompt> and <continuation-prompt> are quoted strings printed as input prompts;\n\
-Both may optionally contain '%s' which will be substituted with the next snippet id --\n\
+Both may optionally contain '%%s' which will be substituted with the next snippet id --\n\
 note that what is entered may not be assigned that id, for example it may be an error or command.\n\
 The continuation-prompt is used on the second and subsequent lines of a multi-line snippet.\n\
 \n\
--- a/langtools/src/jdk.jshell/share/classes/module-info.java	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/src/jdk.jshell/share/classes/module-info.java	Mon Dec 05 08:36:16 2016 -0800
@@ -30,12 +30,12 @@
  */
 module jdk.jshell {
     requires transitive java.compiler;
+    requires transitive jdk.jdi;
     requires java.prefs;
     requires jdk.compiler;
     requires jdk.internal.le;
     requires jdk.internal.ed;
     requires jdk.internal.opt;
-    requires jdk.jdi;
 
     exports jdk.jshell;
     exports jdk.jshell.spi;
--- a/langtools/test/jdk/jshell/CommandCompletionTest.java	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/test/jdk/jshell/CommandCompletionTest.java	Mon Dec 05 08:36:16 2016 -0800
@@ -46,6 +46,7 @@
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 
 import org.testng.annotations.Test;
 
@@ -144,7 +145,7 @@
         Compiler compiler = new Compiler();
         assertCompletion("/o|", false, "/open ");
         List<String> p1 = listFiles(Paths.get(""));
-        FileSystems.getDefault().getRootDirectories().forEach(s -> p1.add(s.toString()));
+        getRootDirectories().forEach(s -> p1.add(s.toString()));
         Collections.sort(p1);
         assertCompletion("/open |", false, p1.toArray(new String[p1.size()]));
         Path classDir = compiler.getClassDir();
@@ -157,7 +158,7 @@
         assertCompletion("/s|", false, "/save ", "/set ");
         List<String> p1 = listFiles(Paths.get(""));
         Collections.addAll(p1, "-all ", "-history ", "-start ");
-        FileSystems.getDefault().getRootDirectories().forEach(s -> p1.add(s.toString()));
+        getRootDirectories().forEach(s -> p1.add(s.toString()));
         Collections.sort(p1);
         assertCompletion("/save |", false, p1.toArray(new String[p1.size()]));
         Path classDir = compiler.getClassDir();
@@ -198,7 +199,7 @@
 
     public void testSet() throws IOException {
         List<String> p1 = listFiles(Paths.get(""));
-        FileSystems.getDefault().getRootDirectories().forEach(s -> p1.add(s.toString()));
+        getRootDirectories().forEach(s -> p1.add(s.toString()));
         Collections.sort(p1);
 
         String[] modes = {"concise ", "normal ", "silent ", "verbose "};
@@ -267,4 +268,13 @@
                     (Files.isDirectory(file) ||
                      file.getFileName().toString().endsWith(".jar") ||
                      file.getFileName().toString().endsWith(".zip"));
+
+    private static Iterable<? extends Path> getRootDirectories() {
+        return StreamSupport.stream(FileSystems.getDefault()
+                                               .getRootDirectories()
+                                               .spliterator(),
+                                    false)
+                            .filter(p -> Files.exists(p))
+                            .collect(Collectors.toList());
+    }
 }
--- a/langtools/test/jdk/jshell/EditorTestBase.java	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/test/jdk/jshell/EditorTestBase.java	Mon Dec 05 08:36:16 2016 -0800
@@ -253,7 +253,11 @@
                 a -> assertEditOutput(a, "/ed", "b ==> 10", () -> {
                     writeSource(getSource() + "\nint b = 10");
                     exit();
-                })
+                }),
+
+                //TODO: this is a work-around to JDK-8170369
+                a -> assertCommand(a, "1234",
+                        null, "", null, null, "")
         );
     }
 
--- a/langtools/test/jdk/jshell/ExternalEditorTest.java	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/test/jdk/jshell/ExternalEditorTest.java	Mon Dec 05 08:36:16 2016 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @summary Testing external editor.
- * @bug 8143955 8080843 8163816 8143006
+ * @bug 8143955 8080843 8163816 8143006 8169828
  * @modules jdk.jshell/jdk.internal.jshell.tool
  * @build ReplToolTesting CustomEditor EditorTestBase
  * @run testng ExternalEditorTest
--- a/langtools/test/jdk/jshell/ToolCommandOptionTest.java	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/test/jdk/jshell/ToolCommandOptionTest.java	Mon Dec 05 08:36:16 2016 -0800
@@ -23,12 +23,16 @@
 
  /*
  * @test
- * @bug 8157395 8157393 8157517 8158738 8167128 8163840 8167637
+ * @bug 8157395 8157393 8157517 8158738 8167128 8163840 8167637 8170368
  * @summary Tests of jshell comand options, and undoing operations
  * @modules jdk.jshell/jdk.internal.jshell.tool
+ *          jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.main
+ * @library /tools/lib
  * @build ToolCommandOptionTest ReplToolTesting
  * @run testng ToolCommandOptionTest
  */
+import java.nio.file.Path;
 import org.testng.annotations.Test;
 import static org.testng.Assert.assertFalse;
 
@@ -240,6 +244,9 @@
     }
 
     public void setStartTest() {
+        Compiler compiler = new Compiler();
+        Path startup = compiler.getPath("StartTest/startup.txt");
+        compiler.writeToFile(startup, "int iAmHere = 1234;");
         test(
                 (a) -> assertCommand(a, "/set start -furball",
                         "|  Unknown option: -furball -- /set start -furball"),
@@ -257,6 +264,13 @@
                         ""),
                 (a) -> assertCommand(a, "/set start",
                         "|  /set start -default"),
+                (a) -> assertCommand(a, "/set start " + startup.toString(),
+                        ""),
+                (a) -> assertCommand(a, "/set start",
+                        "|  startup.jsh:\n" +
+                        "|  int iAmHere = 1234;\n" +
+                        "|  \n" +
+                        "|  /set start startup.jsh"),
                 (a) -> assertCommand(a, "/se sta -no",
                         ""),
                 (a) -> assertCommand(a, "/set start",
@@ -265,6 +279,9 @@
     }
 
     public void retainStartTest() {
+        Compiler compiler = new Compiler();
+        Path startup = compiler.getPath("StartTest/startup.txt");
+        compiler.writeToFile(startup, "int iAmHere = 1234;");
         test(
                 (a) -> assertCommand(a, "/set start -retain -furball",
                         "|  Unknown option: -furball -- /set start -retain -furball"),
@@ -292,7 +309,14 @@
                 (a) -> assertCommand(a, "/se st -ret",
                         ""),
                 (a) -> assertCommand(a, "/se sta",
-                        "|  /set start -retain -none")
+                        "|  /set start -retain -none"),
+                (a) -> assertCommand(a, "/set start -retain " + startup.toString(),
+                        ""),
+                (a) -> assertCommand(a, "/set start",
+                        "|  startup.jsh:\n" +
+                        "|  int iAmHere = 1234;\n" +
+                        "|  \n" +
+                        "|  /set start -retain startup.jsh")
         );
     }
 
--- a/langtools/test/jdk/jshell/ToolSimpleTest.java	Thu Dec 01 10:34:29 2016 -0800
+++ b/langtools/test/jdk/jshell/ToolSimpleTest.java	Mon Dec 05 08:36:16 2016 -0800
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513
+ * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368
  * @summary Simple jshell tool tests
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -280,6 +280,16 @@
         );
     }
 
+    public void testApplicationOfPost() {
+        test(
+                (a) -> assertCommand(a, "/set mode t normal -command", "|  Created new feedback mode: t"),
+                (a) -> assertCommand(a, "/set feedback t", "|  Feedback mode: t"),
+                (a) -> assertCommand(a, "/set format t post \"$%n\"", ""),
+                (a) -> assertCommand(a, "/set prompt t \"+\" \"-\"", ""),
+                (a) -> assertCommand(a, "/set prompt t", "|  /set prompt t \"+\" \"-\"$")
+        );
+    }
+
     public void testHelpLength() {
         Consumer<String> testOutput = (s) -> {
             List<String> ss = Stream.of(s.split("\n"))
@@ -300,14 +310,35 @@
                 (a) -> assertHelp(a, "/help", "/list", "/help", "/exit", "intro"),
                 (a) -> assertHelp(a, "/help short", "shortcuts", "<tab>"),
                 (a) -> assertHelp(a, "/? /li", "/list -all", "snippets"),
+                (a) -> assertHelp(a, "/help /set prompt", "optionally contain '%s'", "quoted"),
                 (a) -> assertHelp(a, "/help /help", "/help <command>")
         );
     }
 
+    public void testHelpFormat() {
+        test(
+                (a) -> assertCommandCheckOutput(a, "/help", s -> {
+                    String[] lines = s.split("\\R");
+                    assertTrue(lines.length > 20,
+                            "Too few lines of /help output: " + lines.length
+                          + "\n" + s);
+                    for (int i = 0; i < lines.length; ++i) {
+                        String l = lines[i];
+                        assertTrue(l.startsWith("| "),
+                                "Expected /help line to start with | :\n" + l);
+                        assertTrue(l.length() <= 80,
+                                "/help line too long: " + l.length() + "\n" + l);
+                    }
+                 })
+        );
+    }
+
     private void assertHelp(boolean a, String command, String... find) {
         assertCommandCheckOutput(a, command, s -> {
             for (String f : find) {
-                assertTrue(s.contains(f), "Expected output of " + command + " to contain: " + f);
+                assertTrue(s.contains(f),
+                        "Expected output of " + command + " to contain: " + f
+                      + "\n" + s);
             }
         });
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8170410/T8170410.java	Mon Dec 05 08:36:16 2016 -0800
@@ -0,0 +1,23 @@
+/*
+ * @test
+ * @bug 8170410
+ * @summary inference: javac doesn't implement 18.2.5 correctly
+ * @compile T8170410.java
+ */
+
+class T8170410 {
+    interface CheckedSupplier<T extends Throwable, R> {
+        R get() throws T;
+    }
+
+    static <T extends Throwable, R> CheckedSupplier<T, R> checked(CheckedSupplier<T, R> checkedSupplier) {
+        return checkedSupplier;
+    }
+
+    static void test() {
+        checked(() -> null).get();
+        checked(T8170410::m).get();
+    }
+
+    static String m() { return ""; }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/GetLocationForModuleTest.java	Mon Dec 05 08:36:16 2016 -0800
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8162712
+ * @summary StandardJavaFileManager.getModuleLocation() can't find a module
+ * @library /tools/lib
+ * @modules
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.JavacTask toolbox.ToolBox
+ * @run main GetLocationForModuleTest
+ */
+
+import java.io.IOException;
+import java.nio.file.*;
+import java.util.*;
+import javax.tools.*;
+import toolbox.JavacTask;
+import toolbox.ToolBox;
+
+public class GetLocationForModuleTest extends ModuleTestBase {
+    public static void main(String... args) throws Exception {
+        new GetLocationForModuleTest().run(Paths.get("."));
+    }
+
+    public void run(Path base) throws Exception {
+        // Set up some trivial modules
+        Path moduleSrc = base.resolve("module-src");
+        Path m1 = moduleSrc.resolve("m1");
+        tb.writeJavaFiles(m1, "module m1 { }");
+        Path m2 = moduleSrc.resolve("m2");
+        tb.writeJavaFiles(m2, "module m2 { }");
+
+        Path modulePath = base.resolve("module-path");
+        Files.createDirectories(modulePath);
+        new JavacTask(tb)
+                .options("--module-source-path", moduleSrc.toString())
+                .outdir(modulePath)
+                .files(findJavaFiles(moduleSrc))
+                .run()
+                .writeAll();
+
+        // Init file manager
+        StandardJavaFileManager fm =
+                ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null);
+        fm.setLocationFromPaths(StandardLocation.MODULE_PATH, Arrays.asList(modulePath));
+
+        // Test
+        test(fm, StandardLocation.SYSTEM_MODULES, "java.base", "java.compiler");
+        test(fm, StandardLocation.MODULE_PATH, "m1", "m2");
+    }
+
+    void test(JavaFileManager fm, JavaFileManager.Location locn, String... mods) throws IOException {
+        for (String mod : mods) {
+            JavaFileManager.Location modLocn = fm.getLocationForModule(locn, mod);
+            if (modLocn == null) {
+                error(locn.getName() + ": can't find " + mod);
+            } else {
+                System.err.println(locn.getName() + ": found " + mod + ": " + modLocn.getName());
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/LocalInAnonymous.java	Mon Dec 05 08:36:16 2016 -0800
@@ -0,0 +1,267 @@
+/*
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 8166628
+ * @summary Verify that loading a classfile for a local class that is a member of an anonymous class
+ *          won't break compilation.
+ * @modules jdk.compiler
+ */
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticListener;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+import com.sun.source.tree.BlockTree;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskEvent.Kind;
+import com.sun.source.util.TaskListener;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.Trees;
+
+public class LocalInAnonymous {
+
+    public static void main(String[] args) throws Exception {
+        Path base = Paths.get(".").toAbsolutePath();
+        Path classes = base.resolve("classes");
+        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+        DiagnosticListener<JavaFileObject> noErrors = d -> {
+            if (d.getKind() == Diagnostic.Kind.ERROR) {
+                throw new AssertionError(d.getMessage(null));
+            }
+        };
+        List<TJFO> files = Arrays.asList(new TJFO("Test", CODE));
+        List<String> options = Arrays.asList("-d", classes.toString());
+        StringWriter out = new StringWriter();
+        JavacTask task = (JavacTask) compiler.getTask(out, null, noErrors, options, null, files);
+        task.call();
+        if (!out.toString().isEmpty()) {
+            throw new AssertionError("Unexpected output: " + out);
+        }
+        options = Arrays.asList("-classpath", classes.toString(), "-d", classes.toString());
+        JavacTask task2 = (JavacTask) compiler.getTask(out, null, noErrors, options, null, files);
+        task2.addTaskListener(new TaskListener() {
+            @Override
+            public void started(TaskEvent te) {
+            }
+            @Override
+            public void finished(TaskEvent te) {
+                if (te.getKind() == Kind.ENTER) {
+                    Element pack = task2.getElements().getTypeElement("Test").getEnclosingElement();
+                    System.err.println(pack.getEnclosedElements());
+                }
+                if (te.getKind() == Kind.ANALYZE) {
+                    PackageElement pack = task2.getElements().getPackageOf(te.getTypeElement());
+                    new OwnerCheck(Trees.instance(task2), pack).scan(te.getCompilationUnit(), null);
+                }
+            }
+        });
+        task2.call();
+        if (!out.toString().isEmpty()) {
+            throw new AssertionError("Unexpected output: " + out);
+        }
+        options = Arrays.asList("-classpath", classes.toString(),
+                                "-d", classes.toString(),
+                                "-processorpath", System.getProperty("test.classes"),
+                                "-processor", Processor.class.getName());
+        JavacTask task3 = (JavacTask) compiler.getTask(out, null, noErrors, options, null, files);
+        task3.call();
+        if (!out.toString().isEmpty()) {
+            throw new AssertionError("Unexpected output: " + out);
+        }
+    }
+
+    private static final class TJFO extends SimpleJavaFileObject {
+
+        private final String code;
+
+        public TJFO(String name, String code) throws URISyntaxException {
+            super(new URI("mem:///" + name + ".java"), Kind.SOURCE);
+            this.code = code;
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+            return code;
+        }
+
+    }
+
+    @SupportedAnnotationTypes("*")
+    public static final class Processor extends AbstractProcessor {
+
+        @Override
+        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+            Trees trees = Trees.instance(processingEnv);
+            Elements elements = processingEnv.getElementUtils();
+            Element pack = elements.getTypeElement("Test").getEnclosingElement();
+            for (Element root : pack.getEnclosedElements()) {
+                TreePath tp = trees.getPath(root);
+                new OwnerCheck(trees, pack).scan(tp.getCompilationUnit(), null);
+
+            }
+            return false;
+        }
+
+    }
+
+    private static final class OwnerCheck extends TreePathScanner<Void, Void> {
+        private final Trees trees;
+        private Element currentOwner;
+
+        public OwnerCheck(Trees trees, Element pack) {
+            this.trees = trees;
+            this.currentOwner = pack;
+        }
+
+        @Override
+        public Void visitClass(ClassTree node, Void p) {
+            Element prevOwner = currentOwner;
+            try {
+                Element currentElement = trees.getElement(getCurrentPath());
+                if (currentOwner != null && currentElement.getEnclosingElement() != currentOwner) {
+                    throw new AssertionError("Unexpected owner!");
+                }
+                currentOwner = currentElement;
+                return super.visitClass(node, p);
+            } finally {
+                currentOwner = prevOwner;
+            }
+        }
+
+        @Override
+        public Void visitMethod(MethodTree node, Void p) {
+            Element prevOwner = currentOwner;
+            try {
+                Element currentElement = trees.getElement(getCurrentPath());
+                if (currentElement.getEnclosingElement() != currentOwner) {
+                    throw new AssertionError("Unexpected owner!");
+                }
+                currentOwner = currentElement;
+                return super.visitMethod(node, p);
+            } finally {
+                currentOwner = prevOwner;
+            }
+        }
+
+        @Override
+        public Void visitVariable(VariableTree node, Void p) {
+            Element currentElement = trees.getElement(getCurrentPath());
+            if (!currentElement.getKind().isField()) {
+                return super.visitVariable(node, p);
+            }
+            Element prevOwner = currentOwner;
+            try {
+                if (currentElement.getEnclosingElement() != currentOwner) {
+                    throw new AssertionError("Unexpected owner!");
+                }
+                currentOwner = currentElement;
+                return super.visitVariable(node, p);
+            } finally {
+                currentOwner = prevOwner;
+            }
+        }
+
+        @Override
+        public Void visitBlock(BlockTree node, Void p) {
+            if (getCurrentPath().getParentPath().getLeaf().getKind() != Tree.Kind.CLASS) {
+                return super.visitBlock(node, p);
+            }
+            Element prevOwner = currentOwner;
+            try {
+                currentOwner = null;
+                return super.visitBlock(node, p);
+            } finally {
+                currentOwner = prevOwner;
+            }
+        }
+
+    }
+
+    private static final String CODE =
+            "public class Test {\n" +
+            "   void test() {\n" +
+            "       Object o = new Object() {\n" +
+            "           class IC {}\n" +
+            "           public Object get() {\n" +
+            "               return new IC();\n" +
+            "           }\n" +
+            "       };\n" +
+            "   }\n" +
+            "   {\n" +
+            "       Object o = new Object() {\n" +
+            "           class IC {}\n" +
+            "           public Object get() {\n" +
+            "               return new IC();\n" +
+            "           }\n" +
+            "       };\n" +
+            "   }\n" +
+            "   static {\n" +
+            "       Object o = new Object() {\n" +
+            "           class IC {}\n" +
+            "           public Object get() {\n" +
+            "               return new IC();\n" +
+            "           }\n" +
+            "       };\n" +
+            "   }\n" +
+            "   Object o1 = new Object() {\n" +
+            "       class IC {}\n" +
+            "       public Object get() {\n" +
+            "          return new IC();\n" +
+            "       }\n" +
+            "   };\n" +
+            "   static Object o2 = new Object() {\n" +
+            "       class IC {}\n" +
+            "       public Object get() {\n" +
+            "          return new IC();\n" +
+            "       }\n" +
+            "   };\n" +
+            "}";
+}