Polishing

This commit is contained in:
Sam Brannen 2023-04-03 14:42:38 +02:00
parent 98f1287f3a
commit 4eed2ced74
4 changed files with 38 additions and 43 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2018 the original author or authors. * Copyright 2002-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,9 +24,10 @@ import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
/** /**
* Utility methods (formatters etc) used during parsing and evaluation. * Utility methods (formatters, etc) used during parsing and evaluation.
* *
* @author Andy Clement * @author Andy Clement
* @author Sam Brannen
*/ */
abstract class FormatHelper { abstract class FormatHelper {
@ -34,19 +35,15 @@ abstract class FormatHelper {
* Produce a readable representation for a given method name with specified arguments. * Produce a readable representation for a given method name with specified arguments.
* @param name the name of the method * @param name the name of the method
* @param argumentTypes the types of the arguments to the method * @param argumentTypes the types of the arguments to the method
* @return a nicely formatted representation, e.g. {@code foo(String,int)} * @return a nicely formatted representation — for example, {@code foo(java.lang.String,int)}
*/ */
public static String formatMethodForMessage(String name, List<TypeDescriptor> argumentTypes) { static String formatMethodForMessage(String name, List<TypeDescriptor> argumentTypes) {
StringJoiner sj = new StringJoiner(",", "(", ")"); StringJoiner sj = new StringJoiner(",", "(", ")");
for (TypeDescriptor typeDescriptor : argumentTypes) { for (TypeDescriptor typeDescriptor : argumentTypes) {
if (typeDescriptor != null) { String className = (typeDescriptor != null ? formatClassNameForMessage(typeDescriptor.getType()) : "null");
sj.add(formatClassNameForMessage(typeDescriptor.getType())); sj.add(className);
}
else {
sj.add(formatClassNameForMessage(null));
}
} }
return name + sj.toString(); return name + sj;
} }
/** /**
@ -56,7 +53,7 @@ abstract class FormatHelper {
* @return a formatted String suitable for message inclusion * @return a formatted String suitable for message inclusion
* @see ClassUtils#getQualifiedName(Class) * @see ClassUtils#getQualifiedName(Class)
*/ */
public static String formatClassNameForMessage(@Nullable Class<?> clazz) { static String formatClassNameForMessage(@Nullable Class<?> clazz) {
return (clazz != null ? ClassUtils.getQualifiedName(clazz) : "null"); return (clazz != null ? ClassUtils.getQualifiedName(clazz) : "null");
} }

View File

@ -231,8 +231,8 @@ public class MethodReference extends SpelNodeImpl {
* if the cause was a RuntimeException, throw the RuntimeException directly. * if the cause was a RuntimeException, throw the RuntimeException directly.
*/ */
private void throwSimpleExceptionIfPossible(Object value, AccessException ex) { private void throwSimpleExceptionIfPossible(Object value, AccessException ex) {
if (ex.getCause() instanceof InvocationTargetException) { if (ex.getCause() instanceof InvocationTargetException cause) {
Throwable rootCause = ex.getCause().getCause(); Throwable rootCause = cause.getCause();
if (rootCause instanceof RuntimeException runtimeException) { if (rootCause instanceof RuntimeException runtimeException) {
throw runtimeException; throw runtimeException;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2021 the original author or authors. * Copyright 2002-2023 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -28,10 +28,11 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* Represents a reference to a type, for example * Represents a reference to a type, for example {@code "T(String)"} or
* {@code "T(String)" or "T(com.somewhere.Foo)"}. * {@code "T(com.example.Foo)"}.
* *
* @author Andy Clement * @author Andy Clement
* @author Sam Brannen
*/ */
public class TypeReference extends SpelNodeImpl { public class TypeReference extends SpelNodeImpl {
@ -74,22 +75,19 @@ public class TypeReference extends SpelNodeImpl {
} }
private Class<?> makeArrayIfNecessary(Class<?> clazz) { private Class<?> makeArrayIfNecessary(Class<?> clazz) {
if (this.dimensions != 0) { if (this.dimensions < 1) {
for (int i = 0; i < this.dimensions; i++) { return clazz;
Object array = Array.newInstance(clazz, 0);
clazz = array.getClass();
}
} }
return clazz; int[] dims = new int[this.dimensions];
Object array = Array.newInstance(clazz, dims);
return array.getClass();
} }
@Override @Override
public String toStringAST() { public String toStringAST() {
StringBuilder sb = new StringBuilder("T("); StringBuilder sb = new StringBuilder("T(");
sb.append(getChild(0).toStringAST()); sb.append(getChild(0).toStringAST());
for (int d = 0; d < this.dimensions; d++) { sb.append("[]".repeat(this.dimensions));
sb.append("[]");
}
sb.append(')'); sb.append(')');
return sb.toString(); return sb.toString();
} }

View File

@ -869,7 +869,7 @@ class SpelReproTests extends AbstractExpressionTests {
Expression expression = parser.parseExpression("parseInt('-FF', 16)"); Expression expression = parser.parseExpression("parseInt('-FF', 16)");
Integer result = expression.getValue(context, "", Integer.class); Integer result = expression.getValue(context, "", Integer.class);
assertThat(result.intValue()).isEqualTo(-255); assertThat(result).isEqualTo(-255);
} }
@Test @Test
@ -880,25 +880,25 @@ class SpelReproTests extends AbstractExpressionTests {
Object result = null; Object result = null;
expression = parser.parseExpression("new java.lang.Long[0].class"); expression = parser.parseExpression("new java.lang.Long[0].class");
result = expression.getValue(context, ""); result = expression.getValue(context);
assertThat(result.toString()).as("Equal assertion failed: ").isEqualTo("class [Ljava.lang.Long;"); assertThat(result).asString().isEqualTo("class [Ljava.lang.Long;");
expression = parser.parseExpression("T(java.lang.Long[])"); expression = parser.parseExpression("T(java.lang.Long[])");
result = expression.getValue(context, ""); result = expression.getValue(context);
assertThat(result.toString()).as("Equal assertion failed: ").isEqualTo("class [Ljava.lang.Long;"); assertThat(result).asString().isEqualTo("class [Ljava.lang.Long;");
expression = parser.parseExpression("T(java.lang.String[][][])"); expression = parser.parseExpression("T(java.lang.String[][][])");
result = expression.getValue(context, ""); result = expression.getValue(context);
assertThat(result.toString()).as("Equal assertion failed: ").isEqualTo("class [[[Ljava.lang.String;"); assertThat(result).asString().isEqualTo("class [[[Ljava.lang.String;");
assertThat(((SpelExpression) expression).toStringAST()).isEqualTo("T(java.lang.String[][][])"); assertThat(((SpelExpression) expression).toStringAST()).isEqualTo("T(java.lang.String[][][])");
expression = parser.parseExpression("new int[0].class"); expression = parser.parseExpression("new int[0].class");
result = expression.getValue(context, ""); result = expression.getValue(context);
assertThat(result.toString()).as("Equal assertion failed: ").isEqualTo("class [I"); assertThat(result).asString().isEqualTo("class [I");
expression = parser.parseExpression("T(int[][])"); expression = parser.parseExpression("T(int[][])");
result = expression.getValue(context, ""); result = expression.getValue(context);
assertThat(result.toString()).isEqualTo("class [[I"); assertThat(result).asString().isEqualTo("class [[I");
} }
@Test @Test
@ -1587,12 +1587,12 @@ class SpelReproTests extends AbstractExpressionTests {
// #this should be the element from list1 // #this should be the element from list1
Expression ex = parser.parseExpression("#list1.?[#list2.contains(#this)]"); Expression ex = parser.parseExpression("#list1.?[#list2.contains(#this)]");
Object result = ex.getValue(context); Object result = ex.getValue(context);
assertThat(result.toString()).isEqualTo("[x]"); assertThat(result).asString().isEqualTo("[x]");
// toString() should be called on the element from list1 // toString() should be called on the element from list1
ex = parser.parseExpression("#list1.?[#list2.contains(toString())]"); ex = parser.parseExpression("#list1.?[#list2.contains(toString())]");
result = ex.getValue(context); result = ex.getValue(context);
assertThat(result.toString()).isEqualTo("[x]"); assertThat(result).asString().isEqualTo("[x]");
List list3 = new ArrayList(); List list3 = new ArrayList();
list3.add(1); list3.add(1);
@ -1604,11 +1604,11 @@ class SpelReproTests extends AbstractExpressionTests {
context.setVariable("list3", list3); context.setVariable("list3", list3);
ex = parser.parseExpression("#list3.?[#this > 2]"); ex = parser.parseExpression("#list3.?[#this > 2]");
result = ex.getValue(context); result = ex.getValue(context);
assertThat(result.toString()).isEqualTo("[3, 4]"); assertThat(result).asString().isEqualTo("[3, 4]");
ex = parser.parseExpression("#list3.?[#this >= T(java.lang.Math).abs(T(java.lang.Math).abs(#this))]"); ex = parser.parseExpression("#list3.?[#this >= T(java.lang.Math).abs(T(java.lang.Math).abs(#this))]");
result = ex.getValue(context); result = ex.getValue(context);
assertThat(result.toString()).isEqualTo("[1, 2, 3, 4]"); assertThat(result).asString().isEqualTo("[1, 2, 3, 4]");
} }
@Test @Test
@ -1628,11 +1628,11 @@ class SpelReproTests extends AbstractExpressionTests {
// #this should be the element from list1 // #this should be the element from list1
Expression ex = parser.parseExpression("#map1.?[#map2.containsKey(#this.getKey())]"); Expression ex = parser.parseExpression("#map1.?[#map2.containsKey(#this.getKey())]");
Object result = ex.getValue(context); Object result = ex.getValue(context);
assertThat(result.toString()).isEqualTo("{X=66}"); assertThat(result).asString().isEqualTo("{X=66}");
ex = parser.parseExpression("#map1.?[#map2.containsKey(key)]"); ex = parser.parseExpression("#map1.?[#map2.containsKey(key)]");
result = ex.getValue(context); result = ex.getValue(context);
assertThat(result.toString()).isEqualTo("{X=66}"); assertThat(result).asString().isEqualTo("{X=66}");
} }
@Test @Test