7115049: Add AST node for method references
Add tree nodes for representing method/constructor references and update relevant visitors interfaces Reviewed-by: jjg
This commit is contained in:
parent
41a3a6c5d3
commit
86e6e6be73
@ -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();
|
||||||
|
}
|
@ -131,6 +131,11 @@ public interface Tree {
|
|||||||
*/
|
*/
|
||||||
MEMBER_SELECT(MemberSelectTree.class),
|
MEMBER_SELECT(MemberSelectTree.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for instances of {@link MemberReferenceTree}.
|
||||||
|
*/
|
||||||
|
MEMBER_REFERENCE(MemberReferenceTree.class),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for instances of {@link ForLoopTree}.
|
* Used for instances of {@link ForLoopTree}.
|
||||||
*/
|
*/
|
||||||
|
@ -89,6 +89,7 @@ public interface TreeVisitor<R,P> {
|
|||||||
R visitParenthesized(ParenthesizedTree node, P p);
|
R visitParenthesized(ParenthesizedTree node, P p);
|
||||||
R visitReturn(ReturnTree node, P p);
|
R visitReturn(ReturnTree node, P p);
|
||||||
R visitMemberSelect(MemberSelectTree node, P p);
|
R visitMemberSelect(MemberSelectTree node, P p);
|
||||||
|
R visitMemberReference(MemberReferenceTree node, P p);
|
||||||
R visitEmptyStatement(EmptyStatementTree node, P p);
|
R visitEmptyStatement(EmptyStatementTree node, P p);
|
||||||
R visitSwitch(SwitchTree node, P p);
|
R visitSwitch(SwitchTree node, P p);
|
||||||
R visitSynchronized(SynchronizedTree node, P p);
|
R visitSynchronized(SynchronizedTree node, P p);
|
||||||
|
@ -212,6 +212,10 @@ public class SimpleTreeVisitor <R,P> implements TreeVisitor<R,P> {
|
|||||||
return defaultAction(node, p);
|
return defaultAction(node, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public R visitMemberReference(MemberReferenceTree node, P p) {
|
||||||
|
return defaultAction(node, p);
|
||||||
|
}
|
||||||
|
|
||||||
public R visitIdentifier(IdentifierTree node, P p) {
|
public R visitIdentifier(IdentifierTree node, P p) {
|
||||||
return defaultAction(node, p);
|
return defaultAction(node, p);
|
||||||
}
|
}
|
||||||
|
@ -339,6 +339,12 @@ public class TreeScanner<R,P> implements TreeVisitor<R,P> {
|
|||||||
return scan(node.getExpression(), p);
|
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) {
|
public R visitIdentifier(IdentifierTree node, P p) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ import com.sun.tools.javac.code.Symbol.*;
|
|||||||
import com.sun.tools.javac.parser.EndPosTable;
|
import com.sun.tools.javac.parser.EndPosTable;
|
||||||
import com.sun.source.tree.*;
|
import com.sun.source.tree.*;
|
||||||
import com.sun.source.tree.LambdaExpressionTree.BodyKind;
|
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.code.BoundKind.*;
|
||||||
import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
||||||
@ -227,6 +228,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||||||
*/
|
*/
|
||||||
SELECT,
|
SELECT,
|
||||||
|
|
||||||
|
/** Member references, of type Reference.
|
||||||
|
*/
|
||||||
|
REFERENCE,
|
||||||
|
|
||||||
/** Simple identifiers, of type Ident.
|
/** Simple identifiers, of type Ident.
|
||||||
*/
|
*/
|
||||||
IDENT,
|
IDENT,
|
||||||
@ -1801,6 +1806,46 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* An identifier
|
||||||
* @param idname the name
|
* @param idname the name
|
||||||
@ -2336,6 +2381,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
|||||||
public void visitTypeTest(JCInstanceOf that) { visitTree(that); }
|
public void visitTypeTest(JCInstanceOf that) { visitTree(that); }
|
||||||
public void visitIndexed(JCArrayAccess that) { visitTree(that); }
|
public void visitIndexed(JCArrayAccess that) { visitTree(that); }
|
||||||
public void visitSelect(JCFieldAccess 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 visitIdent(JCIdent that) { visitTree(that); }
|
||||||
public void visitLiteral(JCLiteral that) { visitTree(that); }
|
public void visitLiteral(JCLiteral that) { visitTree(that); }
|
||||||
public void visitTypeIdent(JCPrimitiveTypeTree that) { visitTree(that); }
|
public void visitTypeIdent(JCPrimitiveTypeTree that) { visitTree(that); }
|
||||||
|
@ -28,6 +28,8 @@ package com.sun.tools.javac.tree;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
|
||||||
|
|
||||||
import com.sun.tools.javac.util.*;
|
import com.sun.tools.javac.util.*;
|
||||||
import com.sun.tools.javac.util.List;
|
import com.sun.tools.javac.util.List;
|
||||||
import com.sun.tools.javac.code.*;
|
import com.sun.tools.javac.code.*;
|
||||||
@ -1063,6 +1065,21 @@ public class Pretty extends JCTree.Visitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
public void visitIdent(JCIdent tree) {
|
||||||
try {
|
try {
|
||||||
print(tree.name);
|
print(tree.name);
|
||||||
|
@ -296,6 +296,13 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
|
|||||||
return M.at(t.pos).Select(selected, t.name);
|
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) {
|
public JCTree visitEmptyStatement(EmptyStatementTree node, P p) {
|
||||||
JCSkip t = (JCSkip) node;
|
JCSkip t = (JCSkip) node;
|
||||||
return M.at(t.pos).Skip();
|
return M.at(t.pos).Skip();
|
||||||
|
@ -227,6 +227,34 @@ public class TreeInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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. */
|
/** Return true if a tree represents the null literal. */
|
||||||
public static boolean isNull(JCTree tree) {
|
public static boolean isNull(JCTree tree) {
|
||||||
if (!tree.hasTag(LITERAL))
|
if (!tree.hasTag(LITERAL))
|
||||||
|
@ -413,6 +413,13 @@ public class TreeMaker implements JCTree.Factory {
|
|||||||
return tree;
|
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) {
|
public JCIdent Ident(Name name) {
|
||||||
JCIdent tree = new JCIdent(name, null);
|
JCIdent tree = new JCIdent(name, null);
|
||||||
tree.pos = pos;
|
tree.pos = pos;
|
||||||
|
@ -259,6 +259,11 @@ public class TreeScanner extends Visitor {
|
|||||||
scan(tree.selected);
|
scan(tree.selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void visitReference(JCMemberReference tree) {
|
||||||
|
scan(tree.expr);
|
||||||
|
scan(tree.typeargs);
|
||||||
|
}
|
||||||
|
|
||||||
public void visitIdent(JCIdent tree) {
|
public void visitIdent(JCIdent tree) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,6 +346,11 @@ public class TreeTranslator extends JCTree.Visitor {
|
|||||||
result = tree;
|
result = tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void visitReference(JCMemberReference tree) {
|
||||||
|
tree.expr = translate(tree.expr);
|
||||||
|
result = tree;
|
||||||
|
}
|
||||||
|
|
||||||
public void visitIdent(JCIdent tree) {
|
public void visitIdent(JCIdent tree) {
|
||||||
result = tree;
|
result = tree;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user