Skip to content

Commit

Permalink
Refactor instanceof expressions to use new Java 21 name syntax.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 696532159
Change-Id: Iabd92b1f7015b79254a071efc9c623a6e58583db
  • Loading branch information
katre authored and copybara-github committed Nov 14, 2024
1 parent 1ddb323 commit 12dc0b9
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 67 deletions.
86 changes: 35 additions & 51 deletions src/main/java/net/starlark/java/eval/Eval.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,22 +89,21 @@ private static TokenKind execStatements(
// We enable it only for statements outside any function (isToplevelFunction)
// and outside any if- or for- statements (!indented).
if (isToplevelFunction && !indented && fr.thread.postAssignHook != null) {
if (stmt instanceof AssignmentStatement) {
AssignmentStatement assign = (AssignmentStatement) stmt;
if (stmt instanceof AssignmentStatement assign) {
for (Identifier id : Identifier.boundIdentifiers(assign.getLHS())) {
Object value = fn(fr).getGlobal(id.getBinding().getIndex());
// TODO(bazel-team): Instead of special casing StarlarkFunction, make it implement
// StarlarkExportable.
if (value instanceof StarlarkFunction) {
if (value instanceof StarlarkFunction func) {
// Optimization: The id token of a StarlarkFunction should be based on its global
// identifier when available. This enables an name-based lookup on deserialization.
((StarlarkFunction) value).export(fr.thread, id.getName());
func.export(fr.thread, id.getName());
} else {
fr.thread.postAssignHook.assign(id.getName(), value);
}
}
} else if (stmt instanceof DefStatement) {
Identifier id = ((DefStatement) stmt).getIdentifier();
} else if (stmt instanceof DefStatement def) {
Identifier id = def.getIdentifier();
((StarlarkFunction) fn(fr).getGlobal(id.getBinding().getIndex()))
.export(fr.thread, id.getName());
}
Expand Down Expand Up @@ -314,24 +313,22 @@ private static TokenKind exec(StarlarkThread.Frame fr, Statement st)
*/
private static void assign(StarlarkThread.Frame fr, Expression lhs, Object value)
throws EvalException, InterruptedException {
if (lhs instanceof Identifier) {
if (lhs instanceof Identifier ident) {
// x = ...
assignIdentifier(fr, (Identifier) lhs, value);
assignIdentifier(fr, ident, value);

} else if (lhs instanceof IndexExpression) {
} else if (lhs instanceof IndexExpression index) {
// x[i] = ...
Object object = eval(fr, ((IndexExpression) lhs).getObject());
Object key = eval(fr, ((IndexExpression) lhs).getKey());
Object object = eval(fr, index.getObject());
Object key = eval(fr, index.getKey());
EvalUtils.setIndex(object, key, value);

} else if (lhs instanceof ListExpression) {
} else if (lhs instanceof ListExpression list) {
// a, b, c = ...
ListExpression list = (ListExpression) lhs;
assignSequence(fr, list.getElements(), value);

} else if (lhs instanceof DotExpression) {
} else if (lhs instanceof DotExpression dot) {
// x.f = ...
DotExpression dot = (DotExpression) lhs;
Object object = eval(fr, dot.getObject());
String field = dot.getField().getName();
try {
Expand Down Expand Up @@ -398,7 +395,7 @@ private static void execAugmentedAssignment(StarlarkThread.Frame fr, AssignmentS
TokenKind op = stmt.getOperator();
Expression rhs = stmt.getRHS();

if (lhs instanceof Identifier) {
if (lhs instanceof Identifier ident) {
// x op= y (lhs must be evaluated only once)
Object x = eval(fr, lhs);
Object y = eval(fr, rhs);
Expand All @@ -409,12 +406,11 @@ private static void execAugmentedAssignment(StarlarkThread.Frame fr, AssignmentS
fr.setErrorLocation(stmt.getOperatorLocation());
throw ex;
}
assignIdentifier(fr, (Identifier) lhs, z);
assignIdentifier(fr, ident, z);

} else if (lhs instanceof IndexExpression) {
} else if (lhs instanceof IndexExpression index) {
// object[index] op= y
// The object and key should be evaluated only once, so we don't use lhs.eval().
IndexExpression index = (IndexExpression) lhs;
Object object = eval(fr, index.getObject());
Object key = eval(fr, index.getKey());
Object x = EvalUtils.index(fr.thread, object, key);
Expand All @@ -434,9 +430,8 @@ private static void execAugmentedAssignment(StarlarkThread.Frame fr, AssignmentS
throw ex;
}

} else if (lhs instanceof DotExpression) {
} else if (lhs instanceof DotExpression dot) {
// object.field op= y (lhs must be evaluated only once)
DotExpression dot = (DotExpression) lhs;
Object object = eval(fr, dot.getObject());
String field = dot.getField().getName();
try {
Expand Down Expand Up @@ -474,10 +469,9 @@ private static Object inplaceBinaryOp(StarlarkThread.Frame fr, TokenKind op, Obj
case PLUS:
// list += iterable behaves like list.extend(iterable)
// TODO(b/141263526): following Python, allow list+=iterable (but not list+iterable).
if (x instanceof StarlarkList && y instanceof StarlarkList) {
StarlarkList<?> list = (StarlarkList) x;
list.extend(y);
return list;
if (x instanceof StarlarkList<?> xList && y instanceof StarlarkList<?> yList) {
xList.extend(yList);
return xList;
}
break;

Expand All @@ -490,41 +484,33 @@ private static Object inplaceBinaryOp(StarlarkThread.Frame fr, TokenKind op, Obj
Map<Object, Object> yMap = (Map<Object, Object>) y;
xDict.putEntries(yMap);
return xDict;
} else if (x instanceof StarlarkSet && y instanceof Set) {
} else if (x instanceof StarlarkSet<?> xSet && y instanceof Set<?> ySet) {
// set |= set merges the contents of the second operand into the first.
@SuppressWarnings("unchecked")
StarlarkSet<Object> xSet = (StarlarkSet<Object>) x;
xSet.update(Tuple.of(y));
xSet.update(Tuple.of(ySet));
return xSet;
}
break;

case AMPERSAND:
if (x instanceof StarlarkSet && y instanceof Set) {
if (x instanceof StarlarkSet<?> xSet && y instanceof Set<?> ySet) {
// set &= set replaces the first set with the intersection of the two sets.
@SuppressWarnings("unchecked")
StarlarkSet<Object> xSet = (StarlarkSet<Object>) x;
xSet.intersectionUpdate(Tuple.of(y));
xSet.intersectionUpdate(Tuple.of(ySet));
return xSet;
}
break;

case CARET:
if (x instanceof StarlarkSet && y instanceof Set) {
if (x instanceof StarlarkSet<?> xSet && y instanceof Set<?> ySet) {
// set ^= set replaces the first set with the symmetric difference of the two sets.
@SuppressWarnings("unchecked")
StarlarkSet<Object> xSet = (StarlarkSet<Object>) x;
xSet.symmetricDifferenceUpdate(y);
xSet.symmetricDifferenceUpdate(ySet);
return xSet;
}
break;

case MINUS:
if (x instanceof StarlarkSet && y instanceof Set) {
if (x instanceof StarlarkSet<?> xSet && y instanceof Set<?> ySet) {
// set -= set removes all elements of the second set from the first set.
@SuppressWarnings("unchecked")
StarlarkSet<Object> xSet = (StarlarkSet<Object>) x;
xSet.differenceUpdate(Tuple.of(y));
xSet.differenceUpdate(Tuple.of(ySet));
return xSet;
}
break;
Expand Down Expand Up @@ -568,10 +554,10 @@ private static Object eval(StarlarkThread.Frame fr, Expression expr)
// the StarlarkInt in the IntLiteral (a temporary hack
// until we use a compiled representation).
Number n = ((IntLiteral) expr).getValue();
if (n instanceof Integer) {
return StarlarkInt.of((Integer) n);
} else if (n instanceof Long) {
return StarlarkInt.of((Long) n);
if (n instanceof Integer nInt) {
return StarlarkInt.of(nInt);
} else if (n instanceof Long nLong) {
return StarlarkInt.of(nLong);
} else {
return StarlarkInt.of((BigInteger) n);
}
Expand Down Expand Up @@ -707,14 +693,14 @@ private static Object evalCall(StarlarkThread.Frame fr, CallExpression call)
// f(*args) -- varargs
if (star != null) {
Object value = eval(fr, star.getValue());
if (!(value instanceof StarlarkIterable)) {
if (!(value instanceof StarlarkIterable<?> iter)) {
fr.setErrorLocation(star.getStartLocation());
throw Starlark.errorf("argument after * must be an iterable, not %s", Starlark.type(value));
}
// TODO(adonovan): opt: if value.size is known, preallocate (and skip if empty).
ArrayList<Object> list = new ArrayList<>();
Collections.addAll(list, positional);
Iterables.addAll(list, ((Iterable<?>) value));
Iterables.addAll(list, iter);
positional = list.toArray();
}

Expand All @@ -723,11 +709,10 @@ private static Object evalCall(StarlarkThread.Frame fr, CallExpression call)
Object value = eval(fr, starstar.getValue());
// Unlike *args, we don't have a Starlark-specific mapping interface to check for in **kwargs,
// so check for Java's Map instead.
if (!(value instanceof Map)) {
if (!(value instanceof Map<?, ?> kwargs)) {
fr.setErrorLocation(starstar.getStartLocation());
throw Starlark.errorf("argument after ** must be a dict, not %s", Starlark.type(value));
}
Map<?, ?> kwargs = (Map<?, ?>) value;
int j = named.length;
named = Arrays.copyOf(named, j + 2 * kwargs.size());
for (Map.Entry<?, ?> e : kwargs.entrySet()) {
Expand Down Expand Up @@ -847,8 +832,7 @@ void execClauses(int index) throws EvalException, InterruptedException {
// recursive case: one or more clauses
if (index < comp.getClauses().size()) {
Comprehension.Clause clause = comp.getClauses().get(index);
if (clause instanceof Comprehension.For) {
Comprehension.For forClause = (Comprehension.For) clause;
if (clause instanceof Comprehension.For forClause) {

Iterable<?> seq = evalAsIterable(fr, forClause.getIterable());
EvalUtils.addIterator(seq);
Expand Down
9 changes: 3 additions & 6 deletions src/main/java/net/starlark/java/eval/EvalUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,7 @@ static Object binaryOp(TokenKind op, Object x, Object y, StarlarkThread starlark
break;

case STAR:
if (x instanceof StarlarkInt) {
StarlarkInt xi = (StarlarkInt) x;
if (x instanceof StarlarkInt xi) {
if (y instanceof StarlarkInt) {
// int * int
return StarlarkInt.multiply(xi, (StarlarkInt) y);
Expand Down Expand Up @@ -327,9 +326,8 @@ static Object binaryOp(TokenKind op, Object x, Object y, StarlarkThread starlark
return StarlarkFloat.mod(xf, yf);
}

} else if (x instanceof String) {
} else if (x instanceof String xs) {
// string % any
String xs = (String) x;
try {
if (y instanceof Tuple) {
return Starlark.formatWithList(semantics, xs, (Tuple) y);
Expand Down Expand Up @@ -487,8 +485,7 @@ static Object index(StarlarkThread starlarkThread, Object object, Object key)
// it should go in the implementations of StarlarkIndexable#getIndex that produce non-Starlark
// values.
return result == null ? null : Starlark.fromJava(result, mu);
} else if (object instanceof String) {
String string = (String) object;
} else if (object instanceof String string) {
int index = Starlark.toInt(key, "string index");
index = getSequenceIndex(index, string.length());
return StringModule.memoizedCharToString(string.charAt(index));
Expand Down
6 changes: 2 additions & 4 deletions src/main/java/net/starlark/java/eval/MethodLibrary.java
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,7 @@ private static final class KeyCallException extends RuntimeException {
doc = "A number (int or float)")
})
public Object abs(Object x) throws EvalException {
if (x instanceof StarlarkInt) {
StarlarkInt starlarkInt = (StarlarkInt) x;
if (x instanceof StarlarkInt starlarkInt) {
if (starlarkInt.signum() < 0) {
return StarlarkInt.uminus(starlarkInt);
}
Expand Down Expand Up @@ -474,8 +473,7 @@ public boolean bool(Object x) throws EvalException {
@Param(name = "x", doc = "The value to convert.", defaultValue = "unbound"),
})
public StarlarkFloat floatForStarlark(Object x) throws EvalException {
if (x instanceof String) {
String s = (String) x;
if (x instanceof String s) {
if (s.isEmpty()) {
throw Starlark.errorf("empty string");
}
Expand Down
6 changes: 2 additions & 4 deletions src/main/java/net/starlark/java/eval/MutableStarlarkList.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,13 @@ public void addElementAt(int index, E element) throws EvalException {
@Override
public void addElements(Iterable<? extends E> elements) throws EvalException {
Starlark.checkMutable(this);
if (elements instanceof MutableStarlarkList) {
MutableStarlarkList<?> that = (MutableStarlarkList) elements;
if (elements instanceof MutableStarlarkList<?> that) {
// (safe even if this == that)
growAdditional(that.size);
System.arraycopy(that.elems, 0, this.elems, this.size, that.size);
this.size += that.size;
} else if (elements instanceof Collection) {
} else if (elements instanceof Collection<?> that) {
// collection of known size
Collection<?> that = (Collection) elements;
growAdditional(that.size());
for (Object x : that) {
elems[size++] = x;
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/net/starlark/java/eval/Starlark.java
Original file line number Diff line number Diff line change
Expand Up @@ -901,8 +901,7 @@ public static Object getattr(
}

// user-defined field?
if (x instanceof Structure) {
Structure struct = (Structure) x;
if (x instanceof Structure struct) {

This comment has been minimized.

Copy link
@fmeum

fmeum Nov 14, 2024

Collaborator

@katre Does this mean that we can start to use Java 21 API and language features in src/main/java/net/starlark? Jon said that this wasn't possible due to other projects depending on it that only support Java 11.

This comment has been minimized.

Copy link
@katre

katre Nov 14, 2024

Author Member

It should be possible to use Java 21 APIs more widely, now.

Object field = struct.getValue(semantics, name);
if (field != null) {
return Starlark.checkValid(field);
Expand Down

0 comments on commit 12dc0b9

Please sign in to comment.