Merge
authorzmajo
Tue, 29 Mar 2016 13:43:30 +0200
changeset 36997 7214398f8db5
parent 36996 2c3a5307865f (current diff)
parent 36717 66bc9949f8b3 (diff)
child 36998 cb82351c399a
Merge
--- a/langtools/.hgtags	Thu Mar 24 16:21:21 2016 +0100
+++ b/langtools/.hgtags	Tue Mar 29 13:43:30 2016 +0200
@@ -353,3 +353,4 @@
 fd18a155ad22f62e06a9b74850ab8609d415c752 jdk-9+108
 f5991c73ed73b9a355a090b65c8d7fb9a1901f89 jdk-9+109
 9b4c916633f8d61509a3dc6175efdf185b421343 jdk-9+110
+9adfb22ff08f2e82c7801b272607cd685976dbb1 jdk-9+111
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Mar 24 16:21:21 2016 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Mar 29 13:43:30 2016 +0200
@@ -282,7 +282,9 @@
      *  @param env    The current environment.
      */
     void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
-        if ((v.flags() & FINAL) != 0 &&
+        if (v.name == names._this) {
+            log.error(pos, Errors.CantAssignValToThis);
+        } else if ((v.flags() & FINAL) != 0 &&
             ((v.flags() & HASINIT) != 0
              ||
              !((base == null ||
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java	Thu Mar 24 16:21:21 2016 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java	Tue Mar 29 13:43:30 2016 +0200
@@ -356,6 +356,7 @@
         ListBuffer<Type> minUndetVars = new ListBuffer<>();
         for (Type minVar : minVars) {
             UndetVar uv = (UndetVar)asUndetVar(minVar);
+            Assert.check(uv.incorporationActions.size() == 0);
             UndetVar uv2 = new UndetVar((TypeVar)minVar, infer.incorporationEngine(), types);
             for (InferenceBound ib : InferenceBound.values()) {
                 List<Type> newBounds = uv.getBounds(ib).stream()
@@ -403,15 +404,17 @@
         public Void visitUndetVar(UndetVar t, Void _unused) {
             if (min.add(t.qtype)) {
                 Set<Type> deps = minMap.getOrDefault(t.qtype, new HashSet<>(Collections.singleton(t.qtype)));
-                for (Type b : t.getBounds(InferenceBound.values())) {
-                    Type undet = asUndetVar(b);
-                    if (!undet.hasTag(TypeTag.UNDETVAR)) {
-                        visit(undet);
-                    } else if (isEquiv((UndetVar)undet, b)){
-                        deps.add(b);
-                        equiv.add(b);
-                    } else {
-                        visit(undet);
+                for (InferenceBound boundKind : InferenceBound.values()) {
+                    for (Type b : t.getBounds(boundKind)) {
+                        Type undet = asUndetVar(b);
+                        if (!undet.hasTag(TypeTag.UNDETVAR)) {
+                            visit(undet);
+                        } else if (isEquiv(t, b, boundKind)) {
+                            deps.add(b);
+                            equiv.add(b);
+                        } else {
+                            visit(undet);
+                        }
                     }
                 }
                 minMap.put(t.qtype, deps);
@@ -447,11 +450,17 @@
             return null;
         }
 
-        boolean isEquiv(UndetVar from, Type t) {
+        boolean isEquiv(UndetVar from, Type t, InferenceBound boundKind) {
             UndetVar uv = (UndetVar)asUndetVar(t);
             for (InferenceBound ib : InferenceBound.values()) {
-                List<Type> b1 = uv.getBounds(ib);
-                List<Type> b2 = from.getBounds(ib);
+                List<Type> b1 = from.getBounds(ib);
+                if (ib == boundKind) {
+                    b1 = b1.diff(List.of(t));
+                }
+                List<Type> b2 = uv.getBounds(ib);
+                if (ib == boundKind.complement()) {
+                    b2 = b2.diff(List.of(from.qtype));
+                }
                 if (!b1.containsAll(b2) || !b2.containsAll(b1)) {
                     return false;
                 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Mar 24 16:21:21 2016 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Mar 29 13:43:30 2016 +0200
@@ -274,6 +274,9 @@
 compiler.err.cant.assign.val.to.final.var=\
     cannot assign a value to final variable {0}
 
+compiler.err.cant.assign.val.to.this=\
+    cannot assign to ''this''
+
 # 0: symbol, 1: message segment
 compiler.err.cant.ref.non.effectively.final.var=\
     local variables referenced from {1} must be final or effectively final
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java	Thu Mar 24 16:21:21 2016 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java	Tue Mar 29 13:43:30 2016 +0200
@@ -139,7 +139,11 @@
                 String content = typeAndContent[1];
 
                 try {
-                    Log.log(Log.Level.valueOf(type), "[server] " + content);
+                    if (Log.isDebugging()) {
+                        // Distinguish server generated output if debugging.
+                        content = "[sjavac-server] " + content;
+                    }
+                    Log.log(Log.Level.valueOf(type), content);
                     continue;
                 } catch (IllegalArgumentException e) {
                     // Parsing of 'type' as log level failed.
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Thu Mar 24 16:21:21 2016 +0100
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Tue Mar 29 13:43:30 2016 +0200
@@ -48,7 +48,7 @@
 import jdk.internal.jline.NoInterruptUnixTerminal;
 import jdk.internal.jline.Terminal;
 import jdk.internal.jline.TerminalFactory;
-import jdk.internal.jline.UnsupportedTerminal;
+import jdk.internal.jline.TerminalSupport;
 import jdk.internal.jline.WindowsTerminal;
 import jdk.internal.jline.console.ConsoleReader;
 import jdk.internal.jline.console.KeyMap;
@@ -70,7 +70,7 @@
         this.input = new StopDetectingInputStream(() -> repl.state.stop(), ex -> repl.hard("Error on input: %s", ex));
         Terminal term;
         if (System.getProperty("test.jdk") != null) {
-            term = new UnsupportedTerminal();
+            term = new TestTerminal(input);
         } else if (System.getProperty("os.name").toLowerCase(Locale.US).contains(TerminalFactory.WINDOWS)) {
             term = new JShellWindowsTerminal(input);
         } else {
@@ -80,7 +80,7 @@
         in = new ConsoleReader(cmdin, cmdout, term);
         in.setExpandEvents(false);
         in.setHandleUserInterrupt(true);
-        in.setHistory(history = new EditingHistory(JShellTool.PREFS) {
+        in.setHistory(history = new EditingHistory(repl.prefs) {
             @Override protected CompletionInfo analyzeCompletion(String input) {
                 return repl.analysis.analyzeCompletion(input);
             }
@@ -538,4 +538,22 @@
         }
 
     }
+
+    private static final class TestTerminal extends TerminalSupport {
+
+        private final StopDetectingInputStream input;
+
+        public TestTerminal(StopDetectingInputStream input) throws Exception {
+            super(true);
+            setAnsiSupported(false);
+            setEchoEnabled(true);
+            this.input = input;
+        }
+
+        @Override
+        public InputStream wrapInIfNeeded(InputStream in) throws IOException {
+            return input.setInputStream(super.wrapInIfNeeded(in));
+        }
+
+    }
 }
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Thu Mar 24 16:21:21 2016 +0100
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Tue Mar 29 13:43:30 2016 +0200
@@ -121,6 +121,7 @@
     final InputStream userin;
     final PrintStream userout;
     final PrintStream usererr;
+    final Preferences prefs;
 
     final Feedback feedback = new Feedback();
 
@@ -137,7 +138,8 @@
      */
     public JShellTool(InputStream cmdin, PrintStream cmdout, PrintStream cmderr,
             PrintStream console,
-            InputStream userin, PrintStream userout, PrintStream usererr) {
+            InputStream userin, PrintStream userout, PrintStream usererr,
+            Preferences prefs) {
         this.cmdin = cmdin;
         this.cmdout = cmdout;
         this.cmderr = cmderr;
@@ -145,6 +147,7 @@
         this.userin = userin;
         this.userout = userout;
         this.usererr = usererr;
+        this.prefs = prefs;
         initializeFeedbackModes();
     }
 
@@ -230,8 +233,6 @@
     private List<String> replayableHistory;
     private List<String> replayableHistoryPrevious;
 
-    static final Preferences PREFS = Preferences.userRoot().node("tool/JShell");
-
     static final String STARTUP_KEY = "STARTUP";
     static final String REPLAY_RESTORE_KEY = "REPLAY_RESTORE";
 
@@ -387,7 +388,8 @@
      */
     public static void main(String[] args) throws Exception {
         new JShellTool(System.in, System.out, System.err, System.out,
-                 new ByteArrayInputStream(new byte[0]), System.out, System.err)
+                 new ByteArrayInputStream(new byte[0]), System.out, System.err,
+                 Preferences.userRoot().node("tool/JShell"))
                 .start(args);
     }
 
@@ -406,7 +408,7 @@
         resetState(); // Initialize
 
         // Read replay history from last jshell session into previous history
-        String prevReplay = PREFS.get(REPLAY_RESTORE_KEY, null);
+        String prevReplay = prefs.get(REPLAY_RESTORE_KEY, null);
         if (prevReplay != null) {
             replayableHistoryPrevious = Arrays.asList(prevReplay.split(RECORD_SEPARATOR));
         }
@@ -558,10 +560,10 @@
 
         String start;
         if (cmdlineStartup == null) {
-            start = PREFS.get(STARTUP_KEY, "<nada>");
+            start = prefs.get(STARTUP_KEY, "<nada>");
             if (start.equals("<nada>")) {
                 start = DEFAULT_STARTUP;
-                PREFS.put(STARTUP_KEY, DEFAULT_STARTUP);
+                prefs.put(STARTUP_KEY, DEFAULT_STARTUP);
             }
         } else {
             start = cmdlineStartup;
@@ -1198,7 +1200,7 @@
                     try {
                         byte[] encoded = Files.readAllBytes(toPathResolvingUserHome(filename));
                         String init = new String(encoded);
-                        PREFS.put(STARTUP_KEY, init);
+                        prefs.put(STARTUP_KEY, init);
                     } catch (AccessDeniedException e) {
                         hard("File '%s' for /set start is not accessible.", filename);
                         return false;
@@ -1347,7 +1349,7 @@
         regenerateOnDeath = false;
         live = false;
         if (!replayableHistory.isEmpty()) {
-            PREFS.put(REPLAY_RESTORE_KEY, replayableHistory.stream().reduce(
+            prefs.put(REPLAY_RESTORE_KEY, replayableHistory.stream().reduce(
                     (a, b) -> a + RECORD_SEPARATOR + b).get());
         }
         fluff("Goodbye\n");
--- a/langtools/test/jdk/jshell/ReplToolTesting.java	Thu Mar 24 16:21:21 2016 +0100
+++ b/langtools/test/jdk/jshell/ReplToolTesting.java	Tue Mar 29 13:43:30 2016 +0200
@@ -33,6 +33,9 @@
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
+import java.util.prefs.AbstractPreferences;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
@@ -41,6 +44,8 @@
 import jdk.internal.jshell.tool.JShellTool;
 import jdk.jshell.SourceCodeAnalysis.Suggestion;
 
+import org.testng.annotations.BeforeMethod;
+
 import static java.util.stream.Collectors.toList;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -83,6 +88,7 @@
     private Map<String, ClassInfo> classes;
     private Map<String, ImportInfo> imports;
     private boolean isDefaultStartUp = true;
+    private Preferences prefs;
 
     public JShellTool repl = null;
 
@@ -219,6 +225,11 @@
         }
     }
 
+    @BeforeMethod
+    public void setUp() {
+        prefs = new MemoryPreferences();
+    }
+
     public void testRaw(String[] args, ReplTest... tests) {
         cmdin = new WaitingTestingInputStream();
         cmdout = new ByteArrayOutputStream();
@@ -234,7 +245,8 @@
                 new PrintStream(console),
                 userin,
                 new PrintStream(userout),
-                new PrintStream(usererr));
+                new PrintStream(usererr),
+                prefs);
         repl.testPrompt = true;
         try {
             repl.start(args);
@@ -447,7 +459,7 @@
 
     private List<String> computeCompletions(String code, boolean isSmart) {
         JShellTool js = this.repl != null ? this.repl
-                                      : new JShellTool(null, null, null, null, null, null, null);
+                                      : new JShellTool(null, null, null, null, null, null, null, prefs);
         int cursor =  code.indexOf('|');
         code = code.replace("|", "");
         assertTrue(cursor > -1, "'|' not found: " + code);
@@ -762,4 +774,62 @@
             }
         }
     }
+
+    public static final class MemoryPreferences extends AbstractPreferences {
+
+        private final Map<String, String> values = new HashMap<>();
+        private final Map<String, MemoryPreferences> nodes = new HashMap<>();
+
+        public MemoryPreferences() {
+            this(null, "");
+        }
+
+        public MemoryPreferences(MemoryPreferences parent, String name) {
+            super(parent, name);
+        }
+
+        @Override
+        protected void putSpi(String key, String value) {
+            values.put(key, value);
+        }
+
+        @Override
+        protected String getSpi(String key) {
+            return values.get(key);
+        }
+
+        @Override
+        protected void removeSpi(String key) {
+            values.remove(key);
+        }
+
+        @Override
+        protected void removeNodeSpi() throws BackingStoreException {
+            ((MemoryPreferences) parent()).nodes.remove(name());
+        }
+
+        @Override
+        protected String[] keysSpi() throws BackingStoreException {
+            return values.keySet().toArray(new String[0]);
+        }
+
+        @Override
+        protected String[] childrenNamesSpi() throws BackingStoreException {
+            return nodes.keySet().toArray(new String[0]);
+        }
+
+        @Override
+        protected AbstractPreferences childSpi(String name) {
+            return nodes.computeIfAbsent(name, n -> new MemoryPreferences(this, name));
+        }
+
+        @Override
+        protected void syncSpi() throws BackingStoreException {
+        }
+
+        @Override
+        protected void flushSpi() throws BackingStoreException {
+        }
+
+    }
 }
--- a/langtools/test/jdk/jshell/StartOptionTest.java	Thu Mar 24 16:21:21 2016 +0100
+++ b/langtools/test/jdk/jshell/StartOptionTest.java	Tue Mar 29 13:43:30 2016 +0200
@@ -54,7 +54,8 @@
     private ByteArrayOutputStream err;
 
     private JShellTool getShellTool() {
-        return new JShellTool(null, new PrintStream(out), new PrintStream(err), null, null, null, null);
+        return new JShellTool(null, new PrintStream(out), new PrintStream(err), null, null, null,
+                              null, new ReplToolTesting.MemoryPreferences());
     }
 
     private String getOutput() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/CantAssignToThis.java	Tue Mar 29 13:43:30 2016 +0200
@@ -0,0 +1,30 @@
+/*
+ * 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.cant.assign.val.to.this
+
+class CantAssignToThis {
+    void m() {
+        this = null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8152411/T8152411.java	Tue Mar 29 13:43:30 2016 +0200
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8152411
+ * @summary Regression: nested unchecked call does not trigger erasure of return type
+ *
+ * @compile/fail/ref=T8152411.out -XDrawDiagnostics T8152411.java
+ */
+import java.util.List;
+
+class T8152411 {
+        <A2 extends A, A> A m(List<? super A2> a2) { return null; }
+        <B> B g(B b) { return null; }
+
+        void test() {
+                List<Integer> I = null;
+                String s = g(m(I));
+        }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8152411/T8152411.out	Tue Mar 29 13:43:30 2016 +0200
@@ -0,0 +1,2 @@
+T8152411.java:16:29: compiler.err.prob.found.req: (compiler.misc.incompatible.upper.bounds: A2, java.lang.String,B,java.lang.Object,java.lang.Integer,A)
+1 error