Skip to content

Commit

Permalink
Apply "instanceof pattern matching" in spring-expression
Browse files Browse the repository at this point in the history
This commit also applies additional clean-up tasks such as the following.

- final fields

This commit also makes use of java.lang.String.repeat(int) in OptMultiply.

This has only been applied to `src/main/java`.
  • Loading branch information
sbrannen committed Oct 14, 2021
1 parent cb17441 commit 4e6ef82
Show file tree
Hide file tree
Showing 23 changed files with 151 additions and 206 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2021 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 Down Expand Up @@ -85,10 +85,9 @@ public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof TypedValue)) {
if (!(other instanceof TypedValue otherTv)) {
return false;
}
TypedValue otherTv = (TypedValue) other;
// Avoid TypeDescriptor initialization if not necessary
return (ObjectUtils.nullSafeEquals(this.value, otherTv.value) &&
((this.typeDescriptor == null && otherTv.typeDescriptor == null) ||
Expand Down
Expand Up @@ -136,8 +136,8 @@ private TypedValue createNewInstance(ExpressionState state) throws EvaluationExc
if (ex.getCause() instanceof InvocationTargetException) {
// User exception was the root cause - exit now
Throwable rootCause = ex.getCause().getCause();
if (rootCause instanceof RuntimeException) {
throw (RuntimeException) rootCause;
if (rootCause instanceof RuntimeException runtimeException) {
throw runtimeException;
}
else {
String typeName = (String) this.children[0].getValueInternal(state).getValue();
Expand All @@ -158,9 +158,9 @@ private TypedValue createNewInstance(ExpressionState state) throws EvaluationExc
executorToUse = findExecutorForConstructor(typeName, argumentTypes, state);
try {
this.cachedExecutor = executorToUse;
if (executorToUse instanceof ReflectiveConstructorExecutor) {
if (executorToUse instanceof ReflectiveConstructorExecutor reflectiveConstructorExecutor) {
this.exitTypeDescriptor = CodeFlow.toDescriptor(
((ReflectiveConstructorExecutor) executorToUse).getConstructor().getDeclaringClass());
reflectiveConstructorExecutor.getConstructor().getDeclaringClass());

}
return executorToUse.execute(state.getEvaluationContext(), arguments);
Expand Down Expand Up @@ -228,14 +228,13 @@ public String toStringAST() {
private TypedValue createArray(ExpressionState state) throws EvaluationException {
// First child gives us the array type which will either be a primitive or reference type
Object intendedArrayType = getChild(0).getValue(state);
if (!(intendedArrayType instanceof String)) {
if (!(intendedArrayType instanceof String type)) {
throw new SpelEvaluationException(getChild(0).getStartPosition(),
SpelMessage.TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION,
FormatHelper.formatClassNameForMessage(
intendedArrayType != null ? intendedArrayType.getClass() : null));
}

String type = (String) intendedArrayType;
Class<?> componentType;
TypeCode arrayTypeCode = TypeCode.forName(type);
if (arrayTypeCode == TypeCode.OBJECT) {
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 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 Down Expand Up @@ -50,6 +50,7 @@
* @author Andy Clement
* @author Phillip Webb
* @author Stephane Nicoll
* @author Sam Brannen
* @since 3.0
*/
// TODO support multidimensional arrays
Expand Down Expand Up @@ -121,8 +122,7 @@ protected ValueRef getValueRef(ExpressionState state) throws EvaluationException
Object index;

// This first part of the if clause prevents a 'double dereference' of the property (SPR-5847)
if (target instanceof Map && (this.children[0] instanceof PropertyOrFieldReference)) {
PropertyOrFieldReference reference = (PropertyOrFieldReference) this.children[0];
if (target instanceof Map && (this.children[0] instanceof PropertyOrFieldReference reference)) {
index = reference.getName();
indexValue = new TypedValue(index);
}
Expand All @@ -148,13 +148,13 @@ protected ValueRef getValueRef(ExpressionState state) throws EvaluationException
Assert.state(targetDescriptor != null, "No type descriptor");

// Indexing into a Map
if (target instanceof Map) {
if (target instanceof Map<?, ?> map) {
Object key = index;
if (targetDescriptor.getMapKeyTypeDescriptor() != null) {
key = state.convertValue(key, targetDescriptor.getMapKeyTypeDescriptor());
}
this.indexedType = IndexedType.MAP;
return new MapIndexingValueRef(state.getTypeConverter(), (Map<?, ?>) target, key, targetDescriptor);
return new MapIndexingValueRef(state.getTypeConverter(), map, key, targetDescriptor);
}

// If the object is something that looks indexable by an integer,
Expand Down Expand Up @@ -275,8 +275,7 @@ else if (this.indexedType == IndexedType.MAP) {
mv.visitTypeInsn(CHECKCAST, "java/util/Map");
// Special case when the key is an unquoted string literal that will be parsed as
// a property/field reference
if ((this.children[0] instanceof PropertyOrFieldReference)) {
PropertyOrFieldReference reference = (PropertyOrFieldReference) this.children[0];
if ((this.children[0] instanceof PropertyOrFieldReference reference)) {
String mapKeyName = reference.getName();
mv.visitLdcInsn(mapKeyName);
}
Expand Down Expand Up @@ -306,9 +305,9 @@ else if (this.indexedType == IndexedType.OBJECT) {
}
}

if (member instanceof Method) {
if (member instanceof Method method) {
mv.visitMethodInsn((isStatic? INVOKESTATIC : INVOKEVIRTUAL), classDesc, member.getName(),
CodeFlow.createSignatureDescriptor((Method) member), false);
CodeFlow.createSignatureDescriptor(method), false);
}
else {
mv.visitFieldInsn((isStatic ? GETSTATIC : GETFIELD), classDesc, member.getName(),
Expand Down Expand Up @@ -572,19 +571,17 @@ public TypedValue getValue() {
targetObjectRuntimeClass, this.evaluationContext.getPropertyAccessors());
for (PropertyAccessor accessor : accessorsToTry) {
if (accessor.canRead(this.evaluationContext, this.targetObject, this.name)) {
if (accessor instanceof ReflectivePropertyAccessor) {
accessor = ((ReflectivePropertyAccessor) accessor).createOptimalAccessor(
if (accessor instanceof ReflectivePropertyAccessor reflectivePropertyAccessor) {
accessor = reflectivePropertyAccessor.createOptimalAccessor(
this.evaluationContext, this.targetObject, this.name);
}
Indexer.this.cachedReadAccessor = accessor;
Indexer.this.cachedReadName = this.name;
Indexer.this.cachedReadTargetType = targetObjectRuntimeClass;
if (accessor instanceof ReflectivePropertyAccessor.OptimalPropertyAccessor) {
ReflectivePropertyAccessor.OptimalPropertyAccessor optimalAccessor =
(ReflectivePropertyAccessor.OptimalPropertyAccessor) accessor;
if (accessor instanceof ReflectivePropertyAccessor.OptimalPropertyAccessor optimalAccessor) {
Member member = optimalAccessor.member;
Indexer.this.exitTypeDescriptor = CodeFlow.toDescriptor(member instanceof Method ?
((Method) member).getReturnType() : ((Field) member).getType());
Indexer.this.exitTypeDescriptor = CodeFlow.toDescriptor(member instanceof Method method ?
method.getReturnType() : ((Field) member).getType());
}
return accessor.read(this.evaluationContext, this.targetObject, this.name);
}
Expand Down Expand Up @@ -665,8 +662,8 @@ public CollectionIndexingValueRef(Collection collection, int index, TypeDescript
@Override
public TypedValue getValue() {
growCollectionIfNecessary();
if (this.collection instanceof List) {
Object o = ((List) this.collection).get(this.index);
if (this.collection instanceof List list) {
Object o = list.get(this.index);
exitTypeDescriptor = CodeFlow.toDescriptor(Object.class);
return new TypedValue(o, this.collectionEntryDescriptor.elementTypeDescriptor(o));
}
Expand All @@ -683,8 +680,7 @@ public TypedValue getValue() {
@Override
public void setValue(@Nullable Object newValue) {
growCollectionIfNecessary();
if (this.collection instanceof List) {
List list = (List) this.collection;
if (this.collection instanceof List list) {
if (this.collectionEntryDescriptor.getElementTypeDescriptor() != null) {
newValue = this.typeConverter.convertValue(newValue, TypeDescriptor.forObject(newValue),
this.collectionEntryDescriptor.getElementTypeDescriptor());
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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 Down Expand Up @@ -34,6 +34,7 @@
* Represent a list in an expression, e.g. '{1,2,3}'
*
* @author Andy Clement
* @author Sam Brannen
* @since 3.0.4
*/
public class InlineList extends SpelNodeImpl {
Expand All @@ -59,8 +60,7 @@ private void checkIfConstant() {
for (int c = 0, max = getChildCount(); c < max; c++) {
SpelNode child = getChild(c);
if (!(child instanceof Literal)) {
if (child instanceof InlineList) {
InlineList inlineList = (InlineList) child;
if (child instanceof InlineList inlineList) {
if (!inlineList.isConstant()) {
isConstant = false;
}
Expand All @@ -75,11 +75,11 @@ private void checkIfConstant() {
int childcount = getChildCount();
for (int c = 0; c < childcount; c++) {
SpelNode child = getChild(c);
if ((child instanceof Literal)) {
constantList.add(((Literal) child).getLiteralValue().getValue());
if (child instanceof Literal literal) {
constantList.add(literal.getLiteralValue().getValue());
}
else if (child instanceof InlineList) {
constantList.add(((InlineList) child).getConstantValue());
else if (child instanceof InlineList inlineList) {
constantList.add(inlineList.getConstantValue());
}
}
this.constant = new TypedValue(Collections.unmodifiableList(constantList));
Expand Down Expand Up @@ -164,8 +164,8 @@ void generateClinitCode(String clazzname, String constantFieldName, MethodVisito
// The children might be further lists if they are not constants. In this
// situation do not call back into generateCode() because it will register another clinit adder.
// Instead, directly build the list here:
if (this.children[c] instanceof InlineList) {
((InlineList)this.children[c]).generateClinitCode(clazzname, constantFieldName, mv, codeflow, true);
if (this.children[c] instanceof InlineList inlineList) {
inlineList.generateClinitCode(clazzname, constantFieldName, mv, codeflow, true);
}
else {
this.children[c].generateCode(mv, codeflow);
Expand Down
Expand Up @@ -31,6 +31,7 @@
* Represent a map in an expression, e.g. '{name:'foo',age:12}'
*
* @author Andy Clement
* @author Sam Brannen
* @since 4.1
*/
public class InlineMap extends SpelNodeImpl {
Expand All @@ -56,15 +57,13 @@ private void checkIfConstant() {
for (int c = 0, max = getChildCount(); c < max; c++) {
SpelNode child = getChild(c);
if (!(child instanceof Literal)) {
if (child instanceof InlineList) {
InlineList inlineList = (InlineList) child;
if (child instanceof InlineList inlineList) {
if (!inlineList.isConstant()) {
isConstant = false;
break;
}
}
else if (child instanceof InlineMap) {
InlineMap inlineMap = (InlineMap) child;
else if (child instanceof InlineMap inlineMap) {
if (!inlineMap.isConstant()) {
isConstant = false;
break;
Expand All @@ -84,23 +83,23 @@ else if (!(c % 2 == 0 && child instanceof PropertyOrFieldReference)) {
SpelNode valueChild = getChild(c);
Object key = null;
Object value = null;
if (keyChild instanceof Literal) {
key = ((Literal) keyChild).getLiteralValue().getValue();
if (keyChild instanceof Literal literal) {
key = literal.getLiteralValue().getValue();
}
else if (keyChild instanceof PropertyOrFieldReference) {
key = ((PropertyOrFieldReference) keyChild).getName();
else if (keyChild instanceof PropertyOrFieldReference propertyOrFieldReference) {
key = propertyOrFieldReference.getName();
}
else {
return;
}
if (valueChild instanceof Literal) {
value = ((Literal) valueChild).getLiteralValue().getValue();
if (valueChild instanceof Literal literal) {
value = literal.getLiteralValue().getValue();
}
else if (valueChild instanceof InlineList) {
value = ((InlineList) valueChild).getConstantValue();
else if (valueChild instanceof InlineList inlineList) {
value = inlineList.getConstantValue();
}
else if (valueChild instanceof InlineMap) {
value = ((InlineMap) valueChild).getConstantValue();
else if (valueChild instanceof InlineMap inlineMap) {
value = inlineMap.getConstantValue();
}
constantMap.put(key, value);
}
Expand All @@ -120,8 +119,7 @@ public TypedValue getValueInternal(ExpressionState expressionState) throws Evalu
// TODO allow for key being PropertyOrFieldReference like Indexer on maps
SpelNode keyChild = getChild(c++);
Object key = null;
if (keyChild instanceof PropertyOrFieldReference) {
PropertyOrFieldReference reference = (PropertyOrFieldReference) keyChild;
if (keyChild instanceof PropertyOrFieldReference reference) {
key = reference.getName();
}
else {
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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 Down Expand Up @@ -34,6 +34,7 @@
* @author Andy Clement
* @author Juergen Hoeller
* @author Giovanni Dall'Oglio Risso
* @author Sam Brannen
* @since 3.2
*/
public class OpDec extends Operator {
Expand All @@ -60,19 +61,18 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
TypedValue returnValue = operandTypedValue;
TypedValue newValue = null;

if (operandValue instanceof Number) {
Number op1 = (Number) operandValue;
if (op1 instanceof BigDecimal) {
newValue = new TypedValue(((BigDecimal) op1).subtract(BigDecimal.ONE), operandTypedValue.getTypeDescriptor());
if (operandValue instanceof Number op1) {
if (op1 instanceof BigDecimal bigDecimal) {
newValue = new TypedValue(bigDecimal.subtract(BigDecimal.ONE), operandTypedValue.getTypeDescriptor());
}
else if (op1 instanceof Double) {
newValue = new TypedValue(op1.doubleValue() - 1.0d, operandTypedValue.getTypeDescriptor());
}
else if (op1 instanceof Float) {
newValue = new TypedValue(op1.floatValue() - 1.0f, operandTypedValue.getTypeDescriptor());
}
else if (op1 instanceof BigInteger) {
newValue = new TypedValue(((BigInteger) op1).subtract(BigInteger.ONE), operandTypedValue.getTypeDescriptor());
else if (op1 instanceof BigInteger bigInteger) {
newValue = new TypedValue(bigInteger.subtract(BigInteger.ONE), operandTypedValue.getTypeDescriptor());
}
else if (op1 instanceof Long) {
newValue = new TypedValue(op1.longValue() - 1L, operandTypedValue.getTypeDescriptor());
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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 Down Expand Up @@ -35,6 +35,7 @@
* @author Andy Clement
* @author Juergen Hoeller
* @author Giovanni Dall'Oglio Risso
* @author Sam Brannen
* @since 3.0
*/
public class OpDivide extends Operator {
Expand All @@ -49,10 +50,7 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
Object leftOperand = getLeftOperand().getValueInternal(state).getValue();
Object rightOperand = getRightOperand().getValueInternal(state).getValue();

if (leftOperand instanceof Number && rightOperand instanceof Number) {
Number leftNumber = (Number) leftOperand;
Number rightNumber = (Number) rightOperand;

if (leftOperand instanceof Number leftNumber && rightOperand instanceof Number rightNumber) {
if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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 Down Expand Up @@ -50,10 +50,7 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati
this.leftActualDescriptor = CodeFlow.toDescriptorFromObject(left);
this.rightActualDescriptor = CodeFlow.toDescriptorFromObject(right);

if (left instanceof Number && right instanceof Number) {
Number leftNumber = (Number) left;
Number rightNumber = (Number) right;

if (left instanceof Number leftNumber && right instanceof Number rightNumber) {
if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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 Down Expand Up @@ -50,10 +50,7 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati
this.leftActualDescriptor = CodeFlow.toDescriptorFromObject(left);
this.rightActualDescriptor = CodeFlow.toDescriptorFromObject(right);

if (left instanceof Number && right instanceof Number) {
Number leftNumber = (Number) left;
Number rightNumber = (Number) right;

if (left instanceof Number leftNumber && right instanceof Number rightNumber) {
if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
Expand Down

0 comments on commit 4e6ef82

Please sign in to comment.