changeset 56937:de5b82868cdd amber-demo-II

manual merge with patterns-stage-1
author vromero
date Mon, 15 Jul 2019 13:34:21 -0400
parents f02972e89dec cba20f435610
children c0338134a40b
files src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java test/langtools/tools/javac/lib/DPrinter.java
diffstat 27 files changed, 361 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/source/tree/BindingPatternTree.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/source/tree/BindingPatternTree.java	Mon Jul 15 13:34:21 2019 -0400
@@ -40,7 +40,7 @@
 
     /**
      * A binding variable name.
-     * @return something
+     * @return the name of the binding variable
      */
     Name getBinding();
 
--- a/src/jdk.compiler/share/classes/com/sun/source/tree/PatternTree.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/source/tree/PatternTree.java	Mon Jul 15 13:34:21 2019 -0400
@@ -25,11 +25,8 @@
 
 package com.sun.source.tree;
 
-import javax.lang.model.element.Name;
-
 /**
- * A super-type for all the patterns.
+ * A tree node used as the base class for the different kinds of
+ * statements.
  */
-public interface PatternTree extends Tree {
-
-}
+public interface PatternTree extends Tree {}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java	Mon Jul 15 13:34:21 2019 -0400
@@ -353,19 +353,19 @@
     /** Modifier masks.
      */
     public static final int
-        AccessFlags                 = PUBLIC | PROTECTED | PRIVATE,
-        LocalClassFlags             = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC,
+        AccessFlags           = PUBLIC | PROTECTED | PRIVATE,
+        LocalClassFlags       = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC,
         LocalRecordFlags            = LocalClassFlags | STATIC,
-        MemberClassFlags            = LocalClassFlags | INTERFACE | AccessFlags,
+        MemberClassFlags      = LocalClassFlags | INTERFACE | AccessFlags,
         MemberRecordClassFlags      = MemberClassFlags | STATIC,
-        ClassFlags                  = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION,
-        InterfaceVarFlags           = FINAL | STATIC | PUBLIC,
-        VarFlags                    = AccessFlags | FINAL | STATIC |
-                                      VOLATILE | TRANSIENT | ENUM,
-        ConstructorFlags            = AccessFlags,
-        InterfaceMethodFlags        = ABSTRACT | PUBLIC,
-        MethodFlags                 = AccessFlags | ABSTRACT | STATIC | NATIVE |
-                                      SYNCHRONIZED | FINAL | STRICTFP;
+        ClassFlags            = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION,
+        InterfaceVarFlags     = FINAL | STATIC | PUBLIC,
+        VarFlags              = AccessFlags | FINAL | STATIC |
+                                VOLATILE | TRANSIENT | ENUM,
+        ConstructorFlags      = AccessFlags,
+        InterfaceMethodFlags  = ABSTRACT | PUBLIC,
+        MethodFlags           = AccessFlags | ABSTRACT | STATIC | NATIVE |
+                                SYNCHRONIZED | FINAL | STRICTFP;
     public static final long
         ExtendedStandardFlags            = (long)StandardFlags | DEFAULT | SEALED | NON_SEALED,
         ExtendedLocalClassFlags          = (long)LocalClassFlags | SEALED | NON_SEALED,
@@ -476,6 +476,8 @@
         POTENTIALLY_AMBIGUOUS(Flags.POTENTIALLY_AMBIGUOUS),
         ANONCONSTR_BASED(Flags.ANONCONSTR_BASED),
         NAME_FILLED(Flags.NAME_FILLED),
+        MATCH_BINDING(Flags.MATCH_BINDING),
+        MATCH_BINDING_TO_OUTER(Flags.MATCH_BINDING_TO_OUTER),
         SEALED(Flags.SEALED),
         NON_SEALED(Flags.NON_SEALED),
         RECORD(Flags.RECORD);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Mon Jul 15 13:34:21 2019 -0400
@@ -1067,6 +1067,13 @@
                                         outer_type_index, location);
                 }
 
+                case BINDING_PATTERN: {
+                    final List<JCTree> newPath = path.tail;
+                    return resolveFrame(newPath.head, newPath.tail.head,
+                                        newPath, currentLambda,
+                                        outer_type_index, location);
+                }
+
                 default:
                     throw new AssertionError("Unresolved frame: " + frame +
                                              " of kind: " + frame.getKind() +
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Jul 15 13:34:21 2019 -0400
@@ -123,6 +123,7 @@
     final Dependencies dependencies;
     final Annotate annotate;
     final ArgumentAttr argumentAttr;
+    final MatchBindingsComputer matchBindingsComputer;
 
     public static Attr instance(Context context) {
         Attr instance = context.get(attrKey);
@@ -158,6 +159,7 @@
         typeEnvs = TypeEnvs.instance(context);
         dependencies = Dependencies.instance(context);
         argumentAttr = ArgumentAttr.instance(context);
+        matchBindingsComputer = MatchBindingsComputer.instance(context);
 
         Options options = Options.instance(context);
 
@@ -1326,7 +1328,7 @@
         attribStat(tree.body, env.dup(tree));
         attribExpr(tree.cond, env, syms.booleanType);
         if (!breaksOutOf(tree, tree.body)) {
-            List<BindingSymbol> bindings = getMatchBindings(types, log, tree.cond, false);
+            List<BindingSymbol> bindings = matchBindingsComputer.getMatchBindings(tree.cond, false);
 
             bindings.forEach(env.info.scope::enter);
             bindings.forEach(BindingSymbol::preserveBinding);
@@ -1337,14 +1339,14 @@
     public void visitWhileLoop(JCWhileLoop tree) {
         attribExpr(tree.cond, env, syms.booleanType);
         // include x.T in while's body
-        Env<AttrContext> whileEnv = bindingEnv(env, getMatchBindings(types, log, tree.cond, true));
+        Env<AttrContext> whileEnv = bindingEnv(env, matchBindingsComputer.getMatchBindings(tree.cond, true));
         try {
             attribStat(tree.body, whileEnv.dup(tree));
         } finally {
             whileEnv.info.scope.leave();
         }
         if (!breaksOutOf(tree, tree.body)) {
-            List<BindingSymbol> bindings = getMatchBindings(types, log, tree.cond, false);
+            List<BindingSymbol> bindings = matchBindingsComputer.getMatchBindings(tree.cond, false);
 
             bindings.forEach(env.info.scope::enter);
             bindings.forEach(BindingSymbol::preserveBinding);
@@ -1366,7 +1368,7 @@
             if (tree.cond != null) {
                 attribExpr(tree.cond, loopEnv, syms.booleanType);
                 // include x.T in the evaluation scopes of body & step.
-                matchBindings = getMatchBindings(types, log, tree.cond, true);
+                matchBindings = matchBindingsComputer.getMatchBindings(tree.cond, true);
             }
             Env<AttrContext> bodyEnv = bindingEnv(loopEnv, matchBindings);
             try {
@@ -1382,7 +1384,7 @@
             loopEnv.info.scope.leave(); // all injected match bindings vanish here.
         }
         if (!breaksOutOf(tree, tree.body)) {
-            List<BindingSymbol> bindings = getMatchBindings(types, log, tree.cond, false);
+            List<BindingSymbol> bindings = matchBindingsComputer.getMatchBindings(tree.cond, false);
 
             bindings.forEach(env.info.scope::enter);
             bindings.forEach(BindingSymbol::preserveBinding);
@@ -1743,7 +1745,7 @@
         */
 
         Type truetype;
-        Env<AttrContext> trueEnv = bindingEnv(env, getMatchBindings(types, log, tree.cond, true));
+        Env<AttrContext> trueEnv = bindingEnv(env, matchBindingsComputer.getMatchBindings(tree.cond, true));
         try {
             truetype = attribTree(tree.truepart, trueEnv, condInfo);
         } finally {
@@ -1751,7 +1753,7 @@
         }
 
         Type falsetype;
-        Env<AttrContext> falseEnv = bindingEnv(env, getMatchBindings(types, log, tree.cond, false));
+        Env<AttrContext> falseEnv = bindingEnv(env, matchBindingsComputer.getMatchBindings(tree.cond, false));
         try {
             falsetype = attribTree(tree.falsepart, falseEnv, condInfo);
         } finally {
@@ -1922,7 +1924,7 @@
 
         // if (x) { y } [ else z ] include x.T in y; include x.F in z
 
-        List<BindingSymbol> thenBindings = getMatchBindings(types, log, tree.cond, true);
+        List<BindingSymbol> thenBindings = matchBindingsComputer.getMatchBindings(tree.cond, true);
         Env<AttrContext> thenEnv = bindingEnv(env, thenBindings);
 
         try {
@@ -1934,7 +1936,7 @@
         preFlow(tree.thenpart);
         boolean aliveAfterThen = flow.aliveAfter(env, tree.thenpart, make);
         boolean aliveAfterElse;
-        List<BindingSymbol> elseBindings = getMatchBindings(types, log, tree.cond, false);
+        List<BindingSymbol> elseBindings = matchBindingsComputer.getMatchBindings(tree.cond, false);
 
         if (tree.elsepart != null) {
             Env<AttrContext> elseEnv = bindingEnv(env, elseBindings);
@@ -3669,10 +3671,10 @@
         List<BindingSymbol> matchBindings;
         switch (tree.getTag()) {
             case AND:
-                matchBindings = getMatchBindings(types, log, tree.lhs, true);
+                matchBindings = matchBindingsComputer.getMatchBindings(tree.lhs, true);
                 break;
             case OR:
-                matchBindings = getMatchBindings(types, log, tree.lhs, false);
+                matchBindings = matchBindingsComputer.getMatchBindings(tree.lhs, false);
                 break;
             default:
                 matchBindings = List.nil();
@@ -3756,7 +3758,8 @@
             attribTree(tree.pattern, env, unknownExprInfo);
             clazztype = tree.pattern.type;
             if (!clazztype.hasTag(TYPEVAR)) {
-                clazztype = chk.checkClassOrArrayType(tree.pattern.pos(), clazztype);
+                JCBindingPattern pattern = (JCBindingPattern) tree.pattern;
+                clazztype = chk.checkClassOrArrayType(pattern.vartype.pos(), clazztype);
             }
         } else {
             clazztype = attribType(tree.pattern, env);
@@ -5516,12 +5519,4 @@
         }.scan(pid);
     }
 
-
-    public static List<BindingSymbol> getMatchBindings(Types types, Log log, JCTree expression, boolean whenTrue) {
-        return getMatchBindings(types, log, expression, whenTrue, null);
-    }
-
-    public static List<BindingSymbol> getMatchBindings(Types types, Log log, JCTree expression, boolean whenTrue, List<BindingSymbol> intersectWith) {
-        return new MatchBindingsComputer(types, log, expression, whenTrue).getBindings(intersectWith);
-    }
 }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Mon Jul 15 13:34:21 2019 -0400
@@ -3523,6 +3523,11 @@
                     duplicateErasureError(pos, sym, byName);
                     sym.flags_field |= CLASH;
                     return true;
+                } else if ((sym.flags() & MATCH_BINDING) != 0 &&
+                           (byName.flags() & MATCH_BINDING) != 0 &&
+                           (byName.flags() & MATCH_BINDING_TO_OUTER) == 0) {
+                    //this error will be reported separatelly in MatchBindingsComputer
+                    return false;
                 } else {
                     duplicateError(pos, byName);
                     return false;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/CompileStates.java	Mon Jul 15 13:34:21 2019 -0400
@@ -59,8 +59,8 @@
         ATTR(4),
         FLOW(5),
         TRANSTYPES(6),
-        UNLAMBDA(7),
-        TRANSPATTERNS(8),
+        TRANSPATTERNS(7),
+        UNLAMBDA(8),
         LOWER(9),
         GENERATE(10);
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java	Mon Jul 15 13:34:21 2019 -0400
@@ -258,7 +258,7 @@
 
     public boolean aliveAfter(Env<AttrContext> env, JCTree that, TreeMaker make) {
         //we need to disable diagnostics temporarily; the problem is that if
-        //a lambda expression contains e.g. an unreachable statement, an error
+        //"that" contains e.g. an unreachable statement, an error
         //message will be reported and will cause compilation to skip the flow analyis
         //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
         //related errors, which will allow for more errors to be detected
@@ -275,7 +275,7 @@
 
     public boolean breaksOutOf(Env<AttrContext> env, JCTree loop, JCTree body, TreeMaker make) {
         //we need to disable diagnostics temporarily; the problem is that if
-        //a lambda expression contains e.g. an unreachable statement, an error
+        //"that" contains e.g. an unreachable statement, an error
         //message will be reported and will cause compilation to skip the flow analyis
         //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
         //related errors, which will allow for more errors to be detected
@@ -1717,7 +1717,7 @@
          */
         protected boolean trackable(VarSymbol sym) {
             return
-                sym.pos >= startPos && ((sym.flags() & MATCH_BINDING) == 0) &&
+                sym.pos >= startPos &&
                 ((sym.owner.kind == MTH || sym.owner.kind == VAR ||
                 isFinalUninitializedField(sym)));
         }
@@ -2694,11 +2694,6 @@
             // Do nothing for modules
         }
 
-        // TODO: 2017-02-02 JUST TO ALLOW THINGS TO CONTINUE
-        public void visitTypeTestPattern(JCBindingPattern tree) {
-            // Do nothing
-        }
-
     /**************************************************************************
      * main method
      *************************************************************************/
@@ -2898,11 +2893,6 @@
             // Do nothing for modules
         }
 
-        // TODO: 2017-02-02 JUST TO ALLOW THINGS TO CONTINUE
-        public void visitTypeTestPattern(JCBindingPattern tree) {
-            // Do nothing
-        }
-
     /**************************************************************************
      * main method
      *************************************************************************/
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MatchBindingsComputer.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MatchBindingsComputer.java	Mon Jul 15 13:34:21 2019 -0400
@@ -37,24 +37,37 @@
 import com.sun.tools.javac.tree.JCTree.JCUnary;
 import com.sun.tools.javac.tree.JCTree.JCBindingPattern;
 import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Name;
 
 
 public class MatchBindingsComputer extends TreeScanner {
+    protected static final Context.Key<MatchBindingsComputer> matchBindingsComputerKey = new Context.Key<>();
 
-    private final JCTree tree;
     private final Log log;
     private final Types types;
     boolean whenTrue;
     List<BindingSymbol> bindings;
 
-    public MatchBindingsComputer(Types types, Log log, JCTree tree, boolean whenTrue) {
-        this.tree = tree;
+    public static MatchBindingsComputer instance(Context context) {
+        MatchBindingsComputer instance = context.get(matchBindingsComputerKey);
+        if (instance == null)
+            instance = new MatchBindingsComputer(context);
+        return instance;
+    }
+
+    protected MatchBindingsComputer(Context context) {
+        this.log = Log.instance(context);
+        this.types = Types.instance(context);
+    }
+
+    public List<BindingSymbol> getMatchBindings(JCTree expression, boolean whenTrue) {
         this.whenTrue = whenTrue;
-        this.log = log;
-        this.types = types;
+        this.bindings = List.nil();
+        scan(expression);
+        return bindings;
     }
 
     @Override
@@ -180,14 +193,6 @@
         super.scan(tree);
     }
 
-    public List<BindingSymbol> getBindings(List<BindingSymbol> intersectWith) {
-        scan(tree);
-        if (intersectWith != null) {
-            bindings = intersection(tree, intersectWith, bindings);
-        }
-        return bindings;
-    }
-
     public static class BindingSymbol extends VarSymbol {
 
         public BindingSymbol(Name name, Type type, Symbol owner) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java	Mon Jul 15 13:34:21 2019 -0400
@@ -65,6 +65,7 @@
 import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
 import static com.sun.tools.javac.code.TypeTag.BOT;
 import com.sun.tools.javac.comp.MatchBindingsComputer.BindingSymbol;
+import com.sun.tools.javac.jvm.Target;
 import com.sun.tools.javac.tree.JCTree.JCBlock;
 import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop;
 import com.sun.tools.javac.tree.JCTree.JCStatement;
@@ -84,13 +85,15 @@
         return instance;
     }
 
-    private Symtab syms;
+    private final Symtab syms;
+    private final Types types;
+    private final Operators operators;
+    private final Log log;
+    private final ConstFold constFold;
+    private final Names names;
+    private final Target target;
+    private final MatchBindingsComputer matchBindingsComputer;
     private TreeMaker make;
-    private Types types;
-    private Operators operators;
-    private Log log;
-    private ConstFold constFold;
-    private Names names;
 
     BindingContext bindingContext = new BindingContext() {
         @Override
@@ -135,6 +138,8 @@
         log = Log.instance(context);
         constFold = ConstFold.instance(context);
         names = Names.instance(context);
+        target = Target.instance(context);
+        matchBindingsComputer = MatchBindingsComputer.instance(context);
         debugTransPatterns = Options.instance(context).isSet("debug.patterns");
     }
 
@@ -146,8 +151,8 @@
             Type tempType = tree.expr.type.hasTag(BOT) ?
                     syms.objectType
                     : tree.expr.type;
-            VarSymbol temp = new VarSymbol(pattSym.flags(),
-                    pattSym.name.append(names.fromString("$temp")),
+            VarSymbol temp = new VarSymbol(pattSym.flags() | Flags.SYNTHETIC,
+                    names.fromString(pattSym.name.toString() + target.syntheticNameChar() + "temp"),
                     tempType,
                     patt.symbol.owner);
             JCExpression translatedExpr = translate(tree.expr);
@@ -176,10 +181,10 @@
         List<BindingSymbol> matchBindings;
         switch (tree.getTag()) {
             case AND:
-                matchBindings = Attr.getMatchBindings(types, log, tree.lhs, true);
+                matchBindings = matchBindingsComputer.getMatchBindings(tree.lhs, true);
                 break;
             case OR:
-                matchBindings = Attr.getMatchBindings(types, log, tree.lhs, false);
+                matchBindings = matchBindingsComputer.getMatchBindings(tree.lhs, false);
                 break;
             default:
                 matchBindings = List.nil();
@@ -198,8 +203,8 @@
     @Override
     public void visitConditional(JCConditional tree) {
         bindingContext = new BasicBindingContext(
-                Attr.getMatchBindings(types, log, tree.cond, true)
-                        .appendList(Attr.getMatchBindings(types, log, tree.cond, false)));
+                matchBindingsComputer.getMatchBindings(tree.cond, true)
+                        .appendList(matchBindingsComputer.getMatchBindings(tree.cond, false)));
         try {
             super.visitConditional(tree);
             result = bindingContext.decorateExpression(tree);
@@ -382,8 +387,8 @@
     }
 
     private List<BindingSymbol> getMatchBindings(JCExpression cond) {
-        return Attr.getMatchBindings(types, log, cond, true)
-                        .appendList(Attr.getMatchBindings(types, log, cond, false));
+        return matchBindingsComputer.getMatchBindings(cond, true)
+                        .appendList(matchBindingsComputer.getMatchBindings(cond, false));
     }
     abstract class BindingContext {
         abstract VarSymbol getBindingFor(BindingSymbol varSymbol);
@@ -403,7 +408,7 @@
             this.parent = bindingContext;
             this.hoistedVarMap = matchBindings.stream()
                     .filter(v -> parent.getBindingFor(v) == null)
-                    .collect(Collectors.toMap(v -> v, v -> new VarSymbol(v.flags(), v.name.append(names.fromString("$binding")), v.type, v.owner)));
+                    .collect(Collectors.toMap(v -> v, v -> new VarSymbol(v.flags(), v.name, v.type, v.owner)));
         }
 
         @Override
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Jul 15 13:34:21 2019 -0400
@@ -1558,6 +1558,12 @@
             env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
             compileStates.put(env, CompileState.TRANSTYPES);
 
+            if (shouldStop(CompileState.TRANSPATTERNS))
+                return;
+
+            env.tree = TransPatterns.instance(context).translateTopLevelClass(env, env.tree, localMake);
+            compileStates.put(env, CompileState.TRANSPATTERNS);
+
             if (Feature.LAMBDA.allowedInSource(source) && scanner.hasLambdas) {
                 if (shouldStop(CompileState.UNLAMBDA))
                     return;
@@ -1566,12 +1572,6 @@
                 compileStates.put(env, CompileState.UNLAMBDA);
             }
 
-            if (shouldStop(CompileState.TRANSPATTERNS))
-                return;
-
-            env.tree = TransPatterns.instance(context).translateTopLevelClass(env, env.tree, localMake);
-            compileStates.put(env, CompileState.TRANSPATTERNS);
-
             if (shouldStop(CompileState.LOWER))
                 return;
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Mon Jul 15 13:34:21 2019 -0400
@@ -922,10 +922,9 @@
             if (token.kind == INSTANCEOF) {
                 int pos = token.pos;
                 nextToken();
-                int patternPos = token.pos;
                 JCTree pattern = parseType();
                 if (token.kind == IDENTIFIER) {
-                    pattern = toP(F.at(patternPos).BindingPattern(ident(), pattern));
+                    pattern = toP(F.at(token.pos).BindingPattern(ident(), pattern));
                 }
                 odStack[top] = F.at(pos).TypeTest(odStack[top], pattern);
             } else {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java	Mon Jul 15 13:34:21 2019 -0400
@@ -243,15 +243,6 @@
         printExpr(tree);
     }
 
-    public <T extends JCTree> void printPatterns(List<T> trees) throws IOException {
-        if (trees.nonEmpty()) {
-            printPattern(trees.head);
-            for (List<T> l = trees.tail; l.nonEmpty(); l = l.tail) {
-                print(", ");
-                printPattern(l.head);
-            }
-        }
-    }
     /** Derived visitor method: print list of statements, each on a separate line.
      */
     public void printStats(List<? extends JCTree> trees) throws IOException {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Mon Jul 15 13:34:21 2019 -0400
@@ -526,6 +526,10 @@
                     return getStartPos(node.vartype);
                 }
             }
+            case BINDINGPATTERN: {
+                JCBindingPattern node = (JCBindingPattern)tree;
+                return getStartPos(node.vartype);
+            }
             case ERRONEOUS: {
                 JCErroneous node = (JCErroneous)tree;
                 if (node.errs != null && node.errs.nonEmpty())
--- a/test/langtools/tools/javac/api/TestGetElementReferenceData.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/test/langtools/tools/javac/api/TestGetElementReferenceData.java	Mon Jul 15 13:34:21 2019 -0400
@@ -35,8 +35,8 @@
         java.util.List< /*getElement:INTERFACE:java.util.List*/ String> l;
         utility/*getElement:METHOD:test.TestGetElementReferenceData.Base.utility()*/();
         target(TestGetElementReferenceData :: test/*getElement:METHOD:test.TestGetElementReferenceData.test()*/);
-        Object o = null;
-        if (o instanceof String/*getElement:CLASS:java.lang.String*/ str/*getElement:LOCAL_VARIABLE:str*/) ;
+        Object/*getElement:CLASS:java.lang.Object*/ o = null;
+        if (o/*getElement:LOCAL_VARIABLE:o*/ instanceof String/*getElement:CLASS:java.lang.String*/ str/*getElement:LOCAL_VARIABLE:str*/) ;
     }
     private static void target(Runnable r) { r.run(); }
     public static class Base {
--- a/test/langtools/tools/javac/diags/examples/MatchBindingExists.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/test/langtools/tools/javac/diags/examples/MatchBindingExists.java	Mon Jul 15 13:34:21 2019 -0400
@@ -22,17 +22,9 @@
  */
 
 // key: compiler.err.match.binding.exists
-// key: compiler.err.match.binding.exists.with.different.type
-//TODO: the following error is extraneous?
-// key: compiler.err.already.defined
 
-class X {
-    public static void main(String [] args) {
-        String s = "Hello";
-        Integer i = 42;
-        Object o1 = s, o2 = i;
-
+class MatchBindingExists {
+    public void test(Object o1, Object o2) {
         if (o1 instanceof String k && o2 instanceof Integer k) {}
-        if (o1 instanceof String k || o2 instanceof Integer k) {}
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/MatchBindingExistsWithDifferentType.java	Mon Jul 15 13:34:21 2019 -0400
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.match.binding.exists.with.different.type
+
+class MatchBindingExistsWithDifferentType {
+    public static void main(Object o1, Object o2) {
+        if (o1 instanceof String k || o2 instanceof Integer k) {}
+    }
+}
--- a/test/langtools/tools/javac/lib/DPrinter.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/test/langtools/tools/javac/lib/DPrinter.java	Mon Jul 15 13:34:21 2019 -0400
@@ -879,7 +879,7 @@
         @Override
         public void visitTypeTest(JCInstanceOf tree) {
             printTree("expr", tree.expr);
-            printTree("clazz", tree.clazz);
+            printTree("pattern", tree.pattern);
         }
 
         @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/patterns/BindingsExistTest.java	Mon Jul 15 13:34:21 2019 -0400
@@ -0,0 +1,29 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Clashing bindings are reported correctly
+ * @compile/fail/ref=BindingsExistTest.out -XDrawDiagnostics BindingsExistTest.java
+ */
+public class BindingsExistTest {
+    public void t(Object o1, Object o2) {
+        if (o1 instanceof String k && o2 instanceof Integer k) {}
+
+        if (o1 instanceof String k || o2 instanceof Integer k) {}
+
+        if (!(o1 instanceof String k)) {
+            return ;
+        }
+        if (o1 instanceof Integer k) {}
+
+        String s2 = "";
+        if (o1 instanceof String s2) {}
+
+        if (o1 instanceof String s3) {
+            String s3 = "";
+        }
+
+        if (!(o1 instanceof String s4)) {
+            return ;
+        }
+        String s4 = "";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/patterns/BindingsExistTest.out	Mon Jul 15 13:34:21 2019 -0400
@@ -0,0 +1,7 @@
+BindingsExistTest.java:8:36: compiler.err.match.binding.exists
+BindingsExistTest.java:10:36: compiler.err.match.binding.exists.with.different.type
+BindingsExistTest.java:15:35: compiler.err.already.defined: kindname.variable, k, kindname.method, t(java.lang.Object,java.lang.Object)
+BindingsExistTest.java:18:34: compiler.err.already.defined: kindname.variable, s2, kindname.method, t(java.lang.Object,java.lang.Object)
+BindingsExistTest.java:21:20: compiler.err.already.defined: kindname.variable, s3, kindname.method, t(java.lang.Object,java.lang.Object)
+BindingsExistTest.java:27:16: compiler.err.already.defined: kindname.variable, s4, kindname.method, t(java.lang.Object,java.lang.Object)
+6 errors
--- a/test/langtools/tools/javac/patterns/BindingsTest1.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/test/langtools/tools/javac/patterns/BindingsTest1.java	Mon Jul 15 13:34:21 2019 -0400
@@ -175,6 +175,21 @@
             s.length();
         }
 
+        if (o1 instanceof String s) {
+            Runnable r1 = new Runnable() {
+                @Override
+                public void run() {
+                    s.length();
+                }
+            };
+            r1.run();
+            Runnable r2 = () -> {
+                s.length();
+            };
+            r2.run();
+            String s2 = s;
+        }
+
         System.out.println("BindingsTest1 complete");
     }
 }
--- a/test/langtools/tools/javac/patterns/DuplicateBindingTest.out	Fri Jul 12 20:50:33 2019 +0000
+++ b/test/langtools/tools/javac/patterns/DuplicateBindingTest.out	Mon Jul 15 13:34:21 2019 -0400
@@ -1,2 +1,2 @@
-DuplicateBindingTest.java:15:36: compiler.err.already.defined: kindname.variable, s, kindname.method, main(java.lang.String[])
+DuplicateBindingTest.java:15:43: compiler.err.already.defined: kindname.variable, s, kindname.method, main(java.lang.String[])
 1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/patterns/LocalVariableTable.java	Mon Jul 15 13:34:21 2019 -0400
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2013, 2015, 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
+ * @summary Ensure the LV table entries are generated for bindings
+ * @modules jdk.jdeps/com.sun.tools.classfile
+ * @compile -g LocalVariableTable.java
+ * @run main LocalVariableTable
+ */
+
+import java.io.*;
+import java.lang.annotation.*;
+import java.util.*;
+import com.sun.tools.classfile.*;
+
+/*
+ * The test checks that a LocalVariableTable attribute is generated for the
+ * method bodies containing patterns, and checks that the expected
+ * set of entries is found in the attribute.
+ *
+ * The test looks for test cases represented by nested classes whose
+ * name begins with "Pattern".  Each such class contains a method
+ * with patterns, and because the test is compiled
+ * with -g, these methods should have a LocalVariableTable.  The set of
+ * expected names in the LVT is provided in an annotation on the class for
+ * the test case.
+ */
+//Copied from: test/langtools/tools/javac/lambda/LocalVariableTable.java
+public class LocalVariableTable {
+    public static void main(String... args) throws Exception {
+        new LocalVariableTable().run();
+    }
+
+    void run() throws Exception {
+        // the declared classes are returned in an unspecified order,
+        // so for neatness, sort them by name before processing them
+        Class<?>[] classes = getClass().getDeclaredClasses();
+        Arrays.sort(classes, (c1, c2) -> c1.getName().compareTo(c2.getName()));
+
+        for (Class<?> c : classes) {
+            if (c.getSimpleName().startsWith("Pattern"))
+                check(c);
+        }
+        if (errors > 0)
+            throw new Exception(errors + " errors found");
+    }
+
+    /** Check an individual test case. */
+    void check(Class<?> c) throws Exception {
+        System.err.println("Checking " + c.getSimpleName());
+
+        Expect expect = c.getAnnotation(Expect.class);
+        if (expect == null) {
+            error("@Expect not found for class " + c.getSimpleName());
+            return;
+        }
+
+        ClassFile cf = ClassFile.read(getClass().getResource(c.getName() + ".class").openStream());
+        Method m = getMethodByName(cf, c.getSimpleName().contains("Lambda") ? "lambda$" : "test");
+        if (m == null) {
+            error("test method not found");
+            return;
+        }
+
+        Code_attribute code = (Code_attribute) m.attributes.get(Attribute.Code);
+        if (code == null) {
+            error("Code attribute not found");
+            return;
+        }
+
+        LocalVariableTable_attribute lvt =
+                (LocalVariableTable_attribute) code.attributes.get(Attribute.LocalVariableTable);
+        if (lvt == null) {
+            error("LocalVariableTable attribute not found");
+            return;
+        }
+
+        Set<String> foundNames = new LinkedHashSet<>();
+        for (LocalVariableTable_attribute.Entry e: lvt.local_variable_table) {
+            foundNames.add(cf.constant_pool.getUTF8Value(e.name_index));
+        }
+
+        Set<String> expectNames = new LinkedHashSet<>(Arrays.asList(expect.value()));
+        if (!foundNames.equals(expectNames)) {
+            Set<String> foundOnly = new LinkedHashSet<>(foundNames);
+            foundOnly.removeAll(expectNames);
+            for (String s: foundOnly)
+                error("Unexpected name found: " + s);
+            Set<String> expectOnly = new LinkedHashSet<>(expectNames);
+            expectOnly.removeAll(foundNames);
+            for (String s: expectOnly)
+                error("Expected name not found: " + s);
+        }
+    }
+
+    Method getMethodByName(ClassFile cf, String name) throws ConstantPoolException {
+        for (Method m: cf.methods) {
+            if (m.getName(cf.constant_pool).startsWith(name))
+                return m;
+        }
+        return null;
+    }
+
+    /** Report an error. */
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+
+    /**
+     * Annotation used to provide the set of names expected in the LVT attribute.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface Expect {
+        String[] value();
+    }
+
+    /*
+     * ---------- Test cases ---------------------------------------------------
+     */
+
+    @Expect({ "o", "s" })
+    static class Pattern_Simple {
+        public static void test(Object o) {
+            if (o instanceof String s) {}
+        }
+    }
+
+    @Expect({ "s" })
+    static class Pattern_Lambda {
+        public static void test(Object o) {
+            if (o instanceof String s) {
+                Runnable r = () -> {
+                    s.length();
+                };
+            }
+        }
+    }
+
+}
+
--- a/test/langtools/tools/javac/patterns/MatchBindingScopeTest.out	Fri Jul 12 20:50:33 2019 +0000
+++ b/test/langtools/tools/javac/patterns/MatchBindingScopeTest.out	Mon Jul 15 13:34:21 2019 -0400
@@ -1,5 +1,4 @@
 MatchBindingScopeTest.java:18:32: compiler.err.cant.resolve.location: kindname.variable, j, , , (compiler.misc.location: kindname.class, MatchBindingScopeTest, null)
-MatchBindingScopeTest.java:22:53: compiler.err.already.defined: kindname.variable, j, kindname.method, main(java.lang.String[])
 MatchBindingScopeTest.java:22:36: compiler.err.match.binding.exists
 MatchBindingScopeTest.java:29:32: compiler.err.cant.resolve.location: kindname.variable, j, , , (compiler.misc.location: kindname.class, MatchBindingScopeTest, null)
 MatchBindingScopeTest.java:30:32: compiler.err.cant.resolve.location: kindname.variable, k, , , (compiler.misc.location: kindname.class, MatchBindingScopeTest, null)
@@ -13,4 +12,4 @@
 MatchBindingScopeTest.java:56:32: compiler.err.cant.resolve.location: kindname.variable, j, , , (compiler.misc.location: kindname.class, MatchBindingScopeTest, null)
 MatchBindingScopeTest.java:61:23: compiler.err.cant.resolve.location: kindname.variable, j, , , (compiler.misc.location: kindname.class, MatchBindingScopeTest, null)
 MatchBindingScopeTest.java:64:23: compiler.err.cant.resolve.location: kindname.variable, j, , , (compiler.misc.location: kindname.class, MatchBindingScopeTest, null)
-15 errors
+14 errors
--- a/test/langtools/tools/javac/patterns/PatternMatchPosTest.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/test/langtools/tools/javac/patterns/PatternMatchPosTest.java	Mon Jul 15 13:34:21 2019 -0400
@@ -105,5 +105,6 @@
 class PatternMatchPosTestData {
     void data(Object o) {
         if (o instanceof String s) { }
+        if (o instanceof java.lang.String s) { }
     }
 }
--- a/test/langtools/tools/javac/patterns/PatternMatchPosTest.out	Fri Jul 12 20:50:33 2019 +0000
+++ b/test/langtools/tools/javac/patterns/PatternMatchPosTest.out	Mon Jul 15 13:34:21 2019 -0400
@@ -3,3 +3,10 @@
 o
 String s
 String
+(o instanceof java.lang.String s)
+o instanceof java.lang.String s
+o
+java.lang.String s
+java.lang.String
+java.lang
+java
--- a/test/langtools/tools/javac/patterns/scope/ScopeTest.java	Fri Jul 12 20:50:33 2019 +0000
+++ b/test/langtools/tools/javac/patterns/scope/ScopeTest.java	Mon Jul 15 13:34:21 2019 -0400
@@ -110,8 +110,10 @@
     }
 
     private void assertFail(String expectedDiag, String block) {
+        String sourceVersion = Integer.toString(Runtime.version().feature());
+
         reset();
-        addCompileOptions("--enable-preview", "-source", "12");
+        addCompileOptions("--enable-preview", "-source", sourceVersion);
         program(block);
         try {
             compile();