Skip to content

Commit

Permalink
Merge branch '6.1.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
sbrannen committed Mar 22, 2024
2 parents cf4ac96 + f941754 commit b695dbc
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -24,7 +24,6 @@
import org.springframework.expression.spel.CodeFlow;
import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.expression.spel.SpelNode;

/**
* Represents a DOT separated expression sequence, such as
Expand Down Expand Up @@ -120,14 +119,13 @@ public String toStringAST() {
for (int i = 0; i < getChildCount(); i++) {
sb.append(getChild(i).toStringAST());
if (i < getChildCount() - 1) {
SpelNode nextChild = getChild(i + 1);
SpelNodeImpl nextChild = this.children[i + 1];
if (nextChild.isNullSafe()) {
sb.append("?.");
}
// Don't append a '.' if the next child is an Indexer.
// For example, we want 'myVar[0]' instead of 'myVar.[0]'.
if (!(nextChild instanceof Indexer)) {
if ((nextChild instanceof MethodReference methodRef && methodRef.isNullSafe()) ||
(nextChild instanceof PropertyOrFieldReference pofRef && pofRef.isNullSafe())) {
sb.append('?');
}
else if (!(nextChild instanceof Indexer)) {
sb.append('.');
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public MethodReference(boolean nullSafe, String methodName, int startPos, int en
* Does this node represent a null-safe method reference?
* @since 6.0.13
*/
@Override
public final boolean isNullSafe() {
return this.nullSafe;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public PropertyOrFieldReference(boolean nullSafe, String propertyOrFieldName, in
/**
* Does this node represent a null-safe property or field reference?
*/
@Override
public boolean isNullSafe() {
return this.nullSafe;
}
Expand Down Expand Up @@ -181,7 +182,7 @@ private TypedValue readProperty(TypedValue contextObject, EvaluationContext eval
throws EvaluationException {

Object targetObject = contextObject.getValue();
if (targetObject == null && this.nullSafe) {
if (targetObject == null && isNullSafe()) {
return TypedValue.NULL;
}

Expand Down Expand Up @@ -233,7 +234,7 @@ private void writeProperty(
TypedValue contextObject, EvaluationContext evalContext, String name, @Nullable Object newValue)
throws EvaluationException {

if (contextObject.getValue() == null && this.nullSafe) {
if (contextObject.getValue() == null && isNullSafe()) {
return;
}
if (contextObject.getValue() == null) {
Expand Down Expand Up @@ -353,7 +354,7 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) {
}

Label skipIfNull = null;
if (this.nullSafe) {
if (isNullSafe()) {
mv.visitInsn(DUP);
skipIfNull = new Label();
Label continueLabel = new Label();
Expand Down Expand Up @@ -381,7 +382,7 @@ void setExitTypeDescriptor(String descriptor) {
// If this property or field access would return a primitive - and yet
// it is also marked null safe - then the exit type descriptor must be
// promoted to the box type to allow a null value to be passed on
if (this.nullSafe && CodeFlow.isPrimitive(descriptor)) {
if (isNullSafe() && CodeFlow.isPrimitive(descriptor)) {
this.originalPrimitiveExitTypeDescriptor = descriptor;
this.exitTypeDescriptor = CodeFlow.toBoxedDescriptor(descriptor);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,16 @@ public int getEndPosition() {
return this.endPos;
}

/**
* Determine if this node is the target of a null-safe navigation operation.
* <p>The default implementation returns {@code false}.
* @return {@code true} if this node is the target of a null-safe operation
* @since 6.1.6
*/
public boolean isNullSafe() {
return false;
}

/**
* Check whether a node can be compiled to bytecode. The reasoning in each node may
* be different but will typically involve checking whether the exit type descriptor
Expand Down

0 comments on commit b695dbc

Please sign in to comment.