7115049: Add AST node for method references
authormcimadamore
Thu, 24 Nov 2011 13:38:40 +0000
changeset 11142 45d0ec1e7463
parent 11141 7d112a1ecd0f
child 11143 9dbe313bfb74
7115049: Add AST node for method references Summary: Add tree nodes for representing method/constructor references and update relevant visitors interfaces Reviewed-by: jjg
langtools/src/share/classes/com/sun/source/tree/MemberReferenceTree.java
langtools/src/share/classes/com/sun/source/tree/Tree.java
langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java
langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java
langtools/src/share/classes/com/sun/source/util/TreeScanner.java
langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java
langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java
langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/tree/MemberReferenceTree.java	Thu Nov 24 13:38:40 2011 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.source.tree;
+
+import java.util.List;
+
+import javax.lang.model.element.Name;
+
+/**
+ * A tree node for a member reference expression.
+ *
+ * For example:
+ * <pre>
+ *   <em>expression</em> # <em>[ identifier | new ]</em>
+ * </pre>
+ *
+ * @see JSR 292
+ */
+public interface MemberReferenceTree extends ExpressionTree {
+
+    /**
+     * There are two kinds of member references: (i) method references and
+     * (ii) constructor references
+     */
+    public enum ReferenceMode {
+        /** enum constant for method references */
+        INVOKE,
+        /** enum constant for constructor references */
+        NEW
+    }
+    ReferenceMode getMode();
+    ExpressionTree getQualifierExpression();
+    Name getName();
+    List<? extends ExpressionTree> getTypeArguments();
+}
--- a/langtools/src/share/classes/com/sun/source/tree/Tree.java	Thu Nov 24 13:36:20 2011 +0000
+++ b/langtools/src/share/classes/com/sun/source/tree/Tree.java	Thu Nov 24 13:38:40 2011 +0000
@@ -132,6 +132,11 @@
         MEMBER_SELECT(MemberSelectTree.class),
 
         /**
+         * Used for instances of {@link MemberReferenceTree}.
+         */
+        MEMBER_REFERENCE(MemberReferenceTree.class),
+
+        /**
          * Used for instances of {@link ForLoopTree}.
          */
         FOR_LOOP(ForLoopTree.class),
--- a/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java	Thu Nov 24 13:36:20 2011 +0000
+++ b/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java	Thu Nov 24 13:38:40 2011 +0000
@@ -89,6 +89,7 @@
     R visitParenthesized(ParenthesizedTree node, P p);
     R visitReturn(ReturnTree node, P p);
     R visitMemberSelect(MemberSelectTree node, P p);
+    R visitMemberReference(MemberReferenceTree node, P p);
     R visitEmptyStatement(EmptyStatementTree node, P p);
     R visitSwitch(SwitchTree node, P p);
     R visitSynchronized(SynchronizedTree node, P p);
--- a/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java	Thu Nov 24 13:36:20 2011 +0000
+++ b/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java	Thu Nov 24 13:38:40 2011 +0000
@@ -212,6 +212,10 @@
         return defaultAction(node, p);
     }
 
+    public R visitMemberReference(MemberReferenceTree node, P p) {
+        return defaultAction(node, p);
+    }
+
     public R visitIdentifier(IdentifierTree node, P p) {
         return defaultAction(node, p);
     }
--- a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java	Thu Nov 24 13:36:20 2011 +0000
+++ b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java	Thu Nov 24 13:38:40 2011 +0000
@@ -339,6 +339,12 @@
         return scan(node.getExpression(), p);
     }
 
+    public R visitMemberReference(MemberReferenceTree node, P p) {
+        R r = scan(node.getQualifierExpression(), p);
+        r = scanAndReduce(node.getTypeArguments(), p, r);
+        return r;
+    }
+
     public R visitIdentifier(IdentifierTree node, P p) {
         return null;
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Nov 24 13:36:20 2011 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Nov 24 13:38:40 2011 +0000
@@ -42,6 +42,7 @@
 import com.sun.tools.javac.parser.EndPosTable;
 import com.sun.source.tree.*;
 import com.sun.source.tree.LambdaExpressionTree.BodyKind;
+import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
 
 import static com.sun.tools.javac.code.BoundKind.*;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
@@ -227,6 +228,10 @@
          */
         SELECT,
 
+        /** Member references, of type Reference.
+         */
+        REFERENCE,
+
         /** Simple identifiers, of type Ident.
          */
         IDENT,
@@ -1802,6 +1807,46 @@
     }
 
     /**
+     * Selects a member expression.
+     */
+    public static class JCMemberReference extends JCExpression implements MemberReferenceTree {
+        public ReferenceMode mode;
+        public Name name;
+        public JCExpression expr;
+        public List<JCExpression> typeargs;
+        public Type targetType;
+        public Symbol sym;
+
+        protected JCMemberReference(ReferenceMode mode, Name name, JCExpression expr, List<JCExpression> typeargs) {
+            this.mode = mode;
+            this.name = name;
+            this.expr = expr;
+            this.typeargs = typeargs;
+        }
+        @Override
+        public void accept(Visitor v) { v.visitReference(this); }
+
+        public Kind getKind() { return Kind.MEMBER_REFERENCE; }
+        @Override
+        public ReferenceMode getMode() { return mode; }
+        @Override
+        public JCExpression getQualifierExpression() { return expr; }
+        @Override
+        public Name getName() { return name; }
+        @Override
+        public List<JCExpression> getTypeArguments() { return typeargs; }
+
+        @Override
+        public <R,D> R accept(TreeVisitor<R,D> v, D d) {
+            return v.visitMemberReference(this, d);
+        }
+        @Override
+        public Tag getTag() {
+            return REFERENCE;
+        }
+    }
+
+    /**
      * An identifier
      * @param idname the name
      * @param sym the symbol
@@ -2336,6 +2381,7 @@
         public void visitTypeTest(JCInstanceOf that)         { visitTree(that); }
         public void visitIndexed(JCArrayAccess that)         { visitTree(that); }
         public void visitSelect(JCFieldAccess that)          { visitTree(that); }
+        public void visitReference(JCMemberReference that)   { visitTree(that); }
         public void visitIdent(JCIdent that)                 { visitTree(that); }
         public void visitLiteral(JCLiteral that)             { visitTree(that); }
         public void visitTypeIdent(JCPrimitiveTypeTree that) { visitTree(that); }
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Thu Nov 24 13:36:20 2011 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Thu Nov 24 13:38:40 2011 +0000
@@ -28,6 +28,8 @@
 import java.io.*;
 import java.util.*;
 
+import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
+
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.code.*;
@@ -1063,6 +1065,21 @@
         }
     }
 
+    public void visitReference(JCMemberReference tree) {
+        try {
+            printExpr(tree.expr);
+            print("#");
+            if (tree.typeargs != null) {
+                print("<");
+                printExprs(tree.typeargs);
+                print(">");
+            }
+            print(tree.getMode() == ReferenceMode.INVOKE ? tree.name : "new");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
     public void visitIdent(JCIdent tree) {
         try {
             print(tree.name);
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Thu Nov 24 13:36:20 2011 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Thu Nov 24 13:38:40 2011 +0000
@@ -296,6 +296,13 @@
         return M.at(t.pos).Select(selected, t.name);
     }
 
+    public JCTree visitMemberReference(MemberReferenceTree node, P p) {
+        JCMemberReference t = (JCMemberReference) node;
+        JCExpression expr = copy(t.expr, p);
+        List<JCExpression> typeargs = copy(t.typeargs, p);
+        return M.at(t.pos).Reference(t.mode, t.name, expr, typeargs);
+    }
+
     public JCTree visitEmptyStatement(EmptyStatementTree node, P p) {
         JCSkip t = (JCSkip) node;
         return M.at(t.pos).Skip();
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Thu Nov 24 13:36:20 2011 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Thu Nov 24 13:38:40 2011 +0000
@@ -227,6 +227,34 @@
         }
     }
 
+    /**
+     * Return true if the AST corresponds to a static select of the kind A.B
+     */
+    public static boolean isStaticSelector(JCTree base, Names names) {
+        if (base == null)
+            return false;
+        switch (base.getTag()) {
+            case IDENT:
+                JCIdent id = (JCIdent)base;
+                return id.name != names._this &&
+                        id.name != names._super &&
+                        isStaticSym(base);
+            case SELECT:
+                return isStaticSym(base) &&
+                    isStaticSelector(((JCFieldAccess)base).selected, names);
+            case TYPEAPPLY:
+                return true;
+            default:
+                return false;
+        }
+    }
+    //where
+        private static boolean isStaticSym(JCTree tree) {
+            Symbol sym = symbol(tree);
+            return (sym.kind == Kinds.TYP ||
+                    sym.kind == Kinds.PCK);
+        }
+
     /** Return true if a tree represents the null literal. */
     public static boolean isNull(JCTree tree) {
         if (!tree.hasTag(LITERAL))
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Thu Nov 24 13:36:20 2011 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Thu Nov 24 13:38:40 2011 +0000
@@ -413,6 +413,13 @@
         return tree;
     }
 
+    public JCMemberReference Reference(JCMemberReference.ReferenceMode mode, Name name,
+            JCExpression expr, List<JCExpression> typeargs) {
+        JCMemberReference tree = new JCMemberReference(mode, name, expr, typeargs);
+        tree.pos = pos;
+        return tree;
+    }
+
     public JCIdent Ident(Name name) {
         JCIdent tree = new JCIdent(name, null);
         tree.pos = pos;
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Thu Nov 24 13:36:20 2011 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Thu Nov 24 13:38:40 2011 +0000
@@ -259,6 +259,11 @@
         scan(tree.selected);
     }
 
+    public void visitReference(JCMemberReference tree) {
+        scan(tree.expr);
+        scan(tree.typeargs);
+    }
+
     public void visitIdent(JCIdent tree) {
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java	Thu Nov 24 13:36:20 2011 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java	Thu Nov 24 13:38:40 2011 +0000
@@ -346,6 +346,11 @@
         result = tree;
     }
 
+    public void visitReference(JCMemberReference tree) {
+        tree.expr = translate(tree.expr);
+        result = tree;
+    }
+
     public void visitIdent(JCIdent tree) {
         result = tree;
     }