Thu, 24 Nov 2011 13:38:40 +0000
7115049: Add AST node for method references
Summary: Add tree nodes for representing method/constructor references and update relevant visitors interfaces
Reviewed-by: jjg
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/source/tree/MemberReferenceTree.java Thu Nov 24 13:38:40 2011 +0000 1.3 @@ -0,0 +1,58 @@ 1.4 +/* 1.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.source.tree; 1.30 + 1.31 +import java.util.List; 1.32 + 1.33 +import javax.lang.model.element.Name; 1.34 + 1.35 +/** 1.36 + * A tree node for a member reference expression. 1.37 + * 1.38 + * For example: 1.39 + * <pre> 1.40 + * <em>expression</em> # <em>[ identifier | new ]</em> 1.41 + * </pre> 1.42 + * 1.43 + * @see JSR 292 1.44 + */ 1.45 +public interface MemberReferenceTree extends ExpressionTree { 1.46 + 1.47 + /** 1.48 + * There are two kinds of member references: (i) method references and 1.49 + * (ii) constructor references 1.50 + */ 1.51 + public enum ReferenceMode { 1.52 + /** enum constant for method references */ 1.53 + INVOKE, 1.54 + /** enum constant for constructor references */ 1.55 + NEW 1.56 + } 1.57 + ReferenceMode getMode(); 1.58 + ExpressionTree getQualifierExpression(); 1.59 + Name getName(); 1.60 + List<? extends ExpressionTree> getTypeArguments(); 1.61 +}
2.1 --- a/src/share/classes/com/sun/source/tree/Tree.java Thu Nov 24 13:36:20 2011 +0000 2.2 +++ b/src/share/classes/com/sun/source/tree/Tree.java Thu Nov 24 13:38:40 2011 +0000 2.3 @@ -132,6 +132,11 @@ 2.4 MEMBER_SELECT(MemberSelectTree.class), 2.5 2.6 /** 2.7 + * Used for instances of {@link MemberReferenceTree}. 2.8 + */ 2.9 + MEMBER_REFERENCE(MemberReferenceTree.class), 2.10 + 2.11 + /** 2.12 * Used for instances of {@link ForLoopTree}. 2.13 */ 2.14 FOR_LOOP(ForLoopTree.class),
3.1 --- a/src/share/classes/com/sun/source/tree/TreeVisitor.java Thu Nov 24 13:36:20 2011 +0000 3.2 +++ b/src/share/classes/com/sun/source/tree/TreeVisitor.java Thu Nov 24 13:38:40 2011 +0000 3.3 @@ -89,6 +89,7 @@ 3.4 R visitParenthesized(ParenthesizedTree node, P p); 3.5 R visitReturn(ReturnTree node, P p); 3.6 R visitMemberSelect(MemberSelectTree node, P p); 3.7 + R visitMemberReference(MemberReferenceTree node, P p); 3.8 R visitEmptyStatement(EmptyStatementTree node, P p); 3.9 R visitSwitch(SwitchTree node, P p); 3.10 R visitSynchronized(SynchronizedTree node, P p);
4.1 --- a/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Thu Nov 24 13:36:20 2011 +0000 4.2 +++ b/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Thu Nov 24 13:38:40 2011 +0000 4.3 @@ -212,6 +212,10 @@ 4.4 return defaultAction(node, p); 4.5 } 4.6 4.7 + public R visitMemberReference(MemberReferenceTree node, P p) { 4.8 + return defaultAction(node, p); 4.9 + } 4.10 + 4.11 public R visitIdentifier(IdentifierTree node, P p) { 4.12 return defaultAction(node, p); 4.13 }
5.1 --- a/src/share/classes/com/sun/source/util/TreeScanner.java Thu Nov 24 13:36:20 2011 +0000 5.2 +++ b/src/share/classes/com/sun/source/util/TreeScanner.java Thu Nov 24 13:38:40 2011 +0000 5.3 @@ -339,6 +339,12 @@ 5.4 return scan(node.getExpression(), p); 5.5 } 5.6 5.7 + public R visitMemberReference(MemberReferenceTree node, P p) { 5.8 + R r = scan(node.getQualifierExpression(), p); 5.9 + r = scanAndReduce(node.getTypeArguments(), p, r); 5.10 + return r; 5.11 + } 5.12 + 5.13 public R visitIdentifier(IdentifierTree node, P p) { 5.14 return null; 5.15 }
6.1 --- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java Thu Nov 24 13:36:20 2011 +0000 6.2 +++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java Thu Nov 24 13:38:40 2011 +0000 6.3 @@ -42,6 +42,7 @@ 6.4 import com.sun.tools.javac.parser.EndPosTable; 6.5 import com.sun.source.tree.*; 6.6 import com.sun.source.tree.LambdaExpressionTree.BodyKind; 6.7 +import com.sun.source.tree.MemberReferenceTree.ReferenceMode; 6.8 6.9 import static com.sun.tools.javac.code.BoundKind.*; 6.10 import static com.sun.tools.javac.tree.JCTree.Tag.*; 6.11 @@ -227,6 +228,10 @@ 6.12 */ 6.13 SELECT, 6.14 6.15 + /** Member references, of type Reference. 6.16 + */ 6.17 + REFERENCE, 6.18 + 6.19 /** Simple identifiers, of type Ident. 6.20 */ 6.21 IDENT, 6.22 @@ -1802,6 +1807,46 @@ 6.23 } 6.24 6.25 /** 6.26 + * Selects a member expression. 6.27 + */ 6.28 + public static class JCMemberReference extends JCExpression implements MemberReferenceTree { 6.29 + public ReferenceMode mode; 6.30 + public Name name; 6.31 + public JCExpression expr; 6.32 + public List<JCExpression> typeargs; 6.33 + public Type targetType; 6.34 + public Symbol sym; 6.35 + 6.36 + protected JCMemberReference(ReferenceMode mode, Name name, JCExpression expr, List<JCExpression> typeargs) { 6.37 + this.mode = mode; 6.38 + this.name = name; 6.39 + this.expr = expr; 6.40 + this.typeargs = typeargs; 6.41 + } 6.42 + @Override 6.43 + public void accept(Visitor v) { v.visitReference(this); } 6.44 + 6.45 + public Kind getKind() { return Kind.MEMBER_REFERENCE; } 6.46 + @Override 6.47 + public ReferenceMode getMode() { return mode; } 6.48 + @Override 6.49 + public JCExpression getQualifierExpression() { return expr; } 6.50 + @Override 6.51 + public Name getName() { return name; } 6.52 + @Override 6.53 + public List<JCExpression> getTypeArguments() { return typeargs; } 6.54 + 6.55 + @Override 6.56 + public <R,D> R accept(TreeVisitor<R,D> v, D d) { 6.57 + return v.visitMemberReference(this, d); 6.58 + } 6.59 + @Override 6.60 + public Tag getTag() { 6.61 + return REFERENCE; 6.62 + } 6.63 + } 6.64 + 6.65 + /** 6.66 * An identifier 6.67 * @param idname the name 6.68 * @param sym the symbol 6.69 @@ -2336,6 +2381,7 @@ 6.70 public void visitTypeTest(JCInstanceOf that) { visitTree(that); } 6.71 public void visitIndexed(JCArrayAccess that) { visitTree(that); } 6.72 public void visitSelect(JCFieldAccess that) { visitTree(that); } 6.73 + public void visitReference(JCMemberReference that) { visitTree(that); } 6.74 public void visitIdent(JCIdent that) { visitTree(that); } 6.75 public void visitLiteral(JCLiteral that) { visitTree(that); } 6.76 public void visitTypeIdent(JCPrimitiveTypeTree that) { visitTree(that); }
7.1 --- a/src/share/classes/com/sun/tools/javac/tree/Pretty.java Thu Nov 24 13:36:20 2011 +0000 7.2 +++ b/src/share/classes/com/sun/tools/javac/tree/Pretty.java Thu Nov 24 13:38:40 2011 +0000 7.3 @@ -28,6 +28,8 @@ 7.4 import java.io.*; 7.5 import java.util.*; 7.6 7.7 +import com.sun.source.tree.MemberReferenceTree.ReferenceMode; 7.8 + 7.9 import com.sun.tools.javac.util.*; 7.10 import com.sun.tools.javac.util.List; 7.11 import com.sun.tools.javac.code.*; 7.12 @@ -1063,6 +1065,21 @@ 7.13 } 7.14 } 7.15 7.16 + public void visitReference(JCMemberReference tree) { 7.17 + try { 7.18 + printExpr(tree.expr); 7.19 + print("#"); 7.20 + if (tree.typeargs != null) { 7.21 + print("<"); 7.22 + printExprs(tree.typeargs); 7.23 + print(">"); 7.24 + } 7.25 + print(tree.getMode() == ReferenceMode.INVOKE ? tree.name : "new"); 7.26 + } catch (IOException e) { 7.27 + throw new UncheckedIOException(e); 7.28 + } 7.29 + } 7.30 + 7.31 public void visitIdent(JCIdent tree) { 7.32 try { 7.33 print(tree.name);
8.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Thu Nov 24 13:36:20 2011 +0000 8.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Thu Nov 24 13:38:40 2011 +0000 8.3 @@ -296,6 +296,13 @@ 8.4 return M.at(t.pos).Select(selected, t.name); 8.5 } 8.6 8.7 + public JCTree visitMemberReference(MemberReferenceTree node, P p) { 8.8 + JCMemberReference t = (JCMemberReference) node; 8.9 + JCExpression expr = copy(t.expr, p); 8.10 + List<JCExpression> typeargs = copy(t.typeargs, p); 8.11 + return M.at(t.pos).Reference(t.mode, t.name, expr, typeargs); 8.12 + } 8.13 + 8.14 public JCTree visitEmptyStatement(EmptyStatementTree node, P p) { 8.15 JCSkip t = (JCSkip) node; 8.16 return M.at(t.pos).Skip();
9.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Thu Nov 24 13:36:20 2011 +0000 9.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Thu Nov 24 13:38:40 2011 +0000 9.3 @@ -227,6 +227,34 @@ 9.4 } 9.5 } 9.6 9.7 + /** 9.8 + * Return true if the AST corresponds to a static select of the kind A.B 9.9 + */ 9.10 + public static boolean isStaticSelector(JCTree base, Names names) { 9.11 + if (base == null) 9.12 + return false; 9.13 + switch (base.getTag()) { 9.14 + case IDENT: 9.15 + JCIdent id = (JCIdent)base; 9.16 + return id.name != names._this && 9.17 + id.name != names._super && 9.18 + isStaticSym(base); 9.19 + case SELECT: 9.20 + return isStaticSym(base) && 9.21 + isStaticSelector(((JCFieldAccess)base).selected, names); 9.22 + case TYPEAPPLY: 9.23 + return true; 9.24 + default: 9.25 + return false; 9.26 + } 9.27 + } 9.28 + //where 9.29 + private static boolean isStaticSym(JCTree tree) { 9.30 + Symbol sym = symbol(tree); 9.31 + return (sym.kind == Kinds.TYP || 9.32 + sym.kind == Kinds.PCK); 9.33 + } 9.34 + 9.35 /** Return true if a tree represents the null literal. */ 9.36 public static boolean isNull(JCTree tree) { 9.37 if (!tree.hasTag(LITERAL))
10.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Thu Nov 24 13:36:20 2011 +0000 10.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Thu Nov 24 13:38:40 2011 +0000 10.3 @@ -413,6 +413,13 @@ 10.4 return tree; 10.5 } 10.6 10.7 + public JCMemberReference Reference(JCMemberReference.ReferenceMode mode, Name name, 10.8 + JCExpression expr, List<JCExpression> typeargs) { 10.9 + JCMemberReference tree = new JCMemberReference(mode, name, expr, typeargs); 10.10 + tree.pos = pos; 10.11 + return tree; 10.12 + } 10.13 + 10.14 public JCIdent Ident(Name name) { 10.15 JCIdent tree = new JCIdent(name, null); 10.16 tree.pos = pos;
11.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Thu Nov 24 13:36:20 2011 +0000 11.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Thu Nov 24 13:38:40 2011 +0000 11.3 @@ -259,6 +259,11 @@ 11.4 scan(tree.selected); 11.5 } 11.6 11.7 + public void visitReference(JCMemberReference tree) { 11.8 + scan(tree.expr); 11.9 + scan(tree.typeargs); 11.10 + } 11.11 + 11.12 public void visitIdent(JCIdent tree) { 11.13 } 11.14
12.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Thu Nov 24 13:36:20 2011 +0000 12.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Thu Nov 24 13:38:40 2011 +0000 12.3 @@ -346,6 +346,11 @@ 12.4 result = tree; 12.5 } 12.6 12.7 + public void visitReference(JCMemberReference tree) { 12.8 + tree.expr = translate(tree.expr); 12.9 + result = tree; 12.10 + } 12.11 + 12.12 public void visitIdent(JCIdent tree) { 12.13 result = tree; 12.14 }