Skip to content

Commit

Permalink
Prepare for a signature change in TreeMaker.Select (#428)
Browse files Browse the repository at this point in the history
Co-authored-by: Chris Povirk <[email protected]>
  • Loading branch information
wmdietl and cpovirk authored Mar 8, 2023
1 parent 7955983 commit d64da60
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 18 deletions.
2 changes: 1 addition & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Remove the `fastAssemble` task which is subsumed by `assembleForJavac`.

**Closed issues:**

eisop#282, eisop#310, eisop#312.
eisop#282, eisop#310, eisop#312, typetools#5672.


Version 3.32.0 (March 2, 2023)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ private List<MethodInvocationTree> resolveReflectiveMethod(
debugReflection("Resolved non-public method: " + symbol.owner + "." + symbol);
}

JCExpression method = make.Select(receiver, symbol);
JCExpression method = TreeUtils.Select(make, receiver, symbol);
args = getCorrectedArgs(symbol, args);
// Build method invocation tree depending on the number of
// parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import com.sun.tools.javac.tree.JCTree.JCBinary;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCLambda;
import com.sun.tools.javac.tree.JCTree.JCLambda.ParameterKind;
import com.sun.tools.javac.tree.JCTree.JCLiteral;
Expand Down Expand Up @@ -115,6 +116,9 @@ private TreeUtils() {
/** Whether we are running on at least Java 16. */
private static final boolean atLeastJava16;

/** Whether we are running on at least Java 21. */
private static final boolean atLeastJava21;

/** The CaseTree.getExpression method for Java up to 11; null otherwise. */
private static final @Nullable Method CASETREE_GETEXPRESSION;

Expand Down Expand Up @@ -144,6 +148,12 @@ private TreeUtils() {
/** The BindingPatternTree.getVariable method for Java 16 and higher; null otherwise. */
private static final @Nullable Method BINDINGPATTERNTREE_GETVARIABLE;

/**
* The {@code TreeMaker.Select(JCExpression, Symbol)} method. Return type changes for JDK21+.
* Only needs to be used while the code is compiled with JDK below 21.
*/
private static final @Nullable Method TREEMAKER_SELECT;

/** The value of Flags.RECORD which does not exist in Java 9 or 11. */
private static final long Flags_RECORD = 2305843009213693952L;

Expand Down Expand Up @@ -183,6 +193,14 @@ private TreeUtils() {
}
atLeastJava16 = java16 != null && latestSource.ordinal() >= java16.ordinal();

SourceVersion java21;
try {
java21 = SourceVersion.valueOf("RELEASE_21");
} catch (IllegalArgumentException e) {
java21 = null;
}
atLeastJava21 = java21 != null && latestSource.ordinal() >= java21.ordinal();

try {
// TODO: profile and see whether doing all these here has a performance impact.
// If so, move to lazily setting the fields.
Expand Down Expand Up @@ -242,6 +260,12 @@ private TreeUtils() {
INSTANCEOFTREE_GETPATTERN = null;
BINDINGPATTERNTREE_GETVARIABLE = null;
}
if (atLeastJava21) {
TREEMAKER_SELECT =
TreeMaker.class.getMethod("Select", JCExpression.class, Symbol.class);
} else {
TREEMAKER_SELECT = null;
}
} catch (ClassNotFoundException | NoSuchMethodException e) {
Error err = new AssertionError("Unexpected error in TreeUtils static initializer");
err.initCause(e);
Expand Down Expand Up @@ -2545,4 +2569,50 @@ public static Tree.Kind getKindRecordAsClass(Tree tree) {
public static boolean isBinaryComparison(BinaryTree tree) {
return BINARY_COMPARISON_TREE_KINDS.contains(tree.getKind());
}

/**
* Returns the result of {@code treeMaker.Select(base, sym)}.
*
* @param treeMaker the TreeMaker to use
* @param base the expression for the select
* @param sym the symbol to select
* @return the JCFieldAccess tree to select sym in base
*/
public static JCFieldAccess Select(TreeMaker treeMaker, Tree base, Symbol sym) {
if (atLeastJava21) {
try {
assert TREEMAKER_SELECT != null : "@AssumeAssertion(nullness): initialization";
JCFieldAccess jfa = (JCFieldAccess) TREEMAKER_SELECT.invoke(treeMaker, base, sym);
if (jfa != null) {
return jfa;
} else {
throw new BugInCF(
"TreeUtils.Select: TreeMaker.Select returned null for tree: %s", base);
}
} catch (InvocationTargetException | IllegalAccessException e) {
throw new BugInCF("TreeUtils.Select: reflection failed for tree: %s", base, e);
}
} else {
@SuppressWarnings("cast") // Redundant on JDK 21+
JCFieldAccess jfa = (JCFieldAccess) treeMaker.Select((JCExpression) base, sym);
return jfa;
}
}

/**
* Returns the result of {@code treeMaker.Select(base, name)}.
*
* @param treeMaker the TreeMaker to use
* @param base the expression for the select
* @param name the name to select
* @return the JCFieldAccess tree to select sym in base
*/
public static JCFieldAccess Select(
TreeMaker treeMaker, Tree base, com.sun.tools.javac.util.Name name) {
/*
* There's no need for reflection here. The only reason we even declare this method is so that
* callers don't have to remember which overload we provide a wrapper around.
*/
return treeMaker.Select((JCExpression) base, name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,7 @@ public MemberSelectTree buildIteratorMethodAccess(ExpressionTree iterableExpr) {
com.sun.tools.javac.util.List.nil(),
methodClass);

JCTree.JCFieldAccess iteratorAccess =
(JCTree.JCFieldAccess)
maker.Select((JCTree.JCExpression) iterableExpr, iteratorMethod);
JCTree.JCFieldAccess iteratorAccess = TreeUtils.Select(maker, iterableExpr, iteratorMethod);
iteratorAccess.setType(updatedMethodType);

return iteratorAccess;
Expand Down Expand Up @@ -156,11 +154,10 @@ public MemberSelectTree buildHasNextMethodAccess(ExpressionTree iteratorExpr) {
}
}

assert hasNextMethod != null : "no hasNext method declared for expression type";
assert hasNextMethod != null
: "@AssumeAssertion(nullness): no hasNext method declared for expression type";

JCTree.JCFieldAccess hasNextAccess =
(JCTree.JCFieldAccess)
maker.Select((JCTree.JCExpression) iteratorExpr, hasNextMethod);
JCTree.JCFieldAccess hasNextAccess = TreeUtils.Select(maker, iteratorExpr, hasNextMethod);
hasNextAccess.setType(hasNextMethod.asType());

return hasNextAccess;
Expand Down Expand Up @@ -210,8 +207,7 @@ public MemberSelectTree buildNextMethodAccess(ExpressionTree iteratorExpr) {
com.sun.tools.javac.util.List.nil(),
methodClass);

JCTree.JCFieldAccess nextAccess =
(JCTree.JCFieldAccess) maker.Select((JCTree.JCExpression) iteratorExpr, nextMethod);
JCTree.JCFieldAccess nextAccess = TreeUtils.Select(maker, iteratorExpr, nextMethod);
nextAccess.setType(updatedMethodType);

return nextAccess;
Expand All @@ -225,8 +221,7 @@ public MemberSelectTree buildNextMethodAccess(ExpressionTree iteratorExpr) {
*/
public MemberSelectTree buildArrayLengthAccess(ExpressionTree expression) {

return (JCTree.JCFieldAccess)
maker.Select((JCTree.JCExpression) expression, symtab.lengthVar);
return TreeUtils.Select(maker, expression, symtab.lengthVar);
}

/**
Expand Down Expand Up @@ -406,8 +401,7 @@ public MemberSelectTree buildValueOfMethodAccess(Tree expr) {

Type.MethodType methodType = (Type.MethodType) valueOfMethod.asType();

JCTree.JCFieldAccess valueOfAccess =
(JCTree.JCFieldAccess) maker.Select((JCTree.JCExpression) expr, valueOfMethod);
JCTree.JCFieldAccess valueOfAccess = TreeUtils.Select(maker, expr, valueOfMethod);
valueOfAccess.setType(methodType);

return valueOfAccess;
Expand Down Expand Up @@ -467,8 +461,7 @@ public MemberSelectTree buildPrimValueMethodAccess(Tree expr) {

Type.MethodType methodType = (Type.MethodType) primValueMethod.asType();

JCTree.JCFieldAccess primValueAccess =
(JCTree.JCFieldAccess) maker.Select((JCTree.JCExpression) expr, primValueMethod);
JCTree.JCFieldAccess primValueAccess = TreeUtils.Select(maker, expr, primValueMethod);
primValueAccess.setType(methodType);

return primValueAccess;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.sun.tools.javac.util.Names;

import org.checkerframework.javacutil.Pair;
import org.checkerframework.javacutil.TreeUtils;

import java.util.StringTokenizer;

Expand Down Expand Up @@ -119,7 +120,7 @@ private Pair<JCExpression, String> parseExpression(StringTokenizer tokenizer, St
token = delim;
if (".".equals(delim)) {
token = nextToken(tokenizer);
tree = maker.Select(tree, names.fromString(token));
tree = TreeUtils.Select(maker, tree, names.fromString(token));
} else if ("(".equals(delim)) {
token = nextToken(tokenizer);
ListBuffer<JCExpression> args = new ListBuffer<>();
Expand Down

0 comments on commit d64da60

Please sign in to comment.