Provide more context when the code of a value cannot be generated
Closes gh-29118
This commit is contained in:
parent
c72c2ffc26
commit
2d4f308cc1
|
|
@ -85,8 +85,31 @@ class BeanDefinitionPropertyValueCodeGenerator {
|
|||
CodeBlock generateCode(@Nullable Object value) {
|
||||
ResolvableType type = (value != null) ? ResolvableType.forInstance(value)
|
||||
: ResolvableType.NONE;
|
||||
try {
|
||||
return generateCode(value, type);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalArgumentException(buildErrorMessage(value, type), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private CodeBlock generateCodeForElement(@Nullable Object value, ResolvableType type) {
|
||||
try {
|
||||
return generateCode(value, type);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalArgumentException(buildErrorMessage(value, type), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static String buildErrorMessage(@Nullable Object value, ResolvableType type) {
|
||||
StringBuilder message = new StringBuilder("Failed to generate code for '");
|
||||
message.append(value).append("'");
|
||||
if (type != ResolvableType.NONE) {
|
||||
message.append(" with type ").append(type);
|
||||
}
|
||||
return message.toString();
|
||||
}
|
||||
|
||||
private CodeBlock generateCode(@Nullable Object value, ResolvableType type) {
|
||||
if (value == null) {
|
||||
|
|
@ -98,8 +121,7 @@ class BeanDefinitionPropertyValueCodeGenerator {
|
|||
return code;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"'type' " + type + " must be supported for instance code generation");
|
||||
throw new IllegalArgumentException("Code generation does not support " + type);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -304,7 +326,7 @@ class BeanDefinitionPropertyValueCodeGenerator {
|
|||
while (iterator.hasNext()) {
|
||||
Object element = iterator.next();
|
||||
code.add("$L", BeanDefinitionPropertyValueCodeGenerator.this
|
||||
.generateCode(element, elementType));
|
||||
.generateCodeForElement(element, elementType));
|
||||
if (iterator.hasNext()) {
|
||||
code.add(", ");
|
||||
}
|
||||
|
|
@ -371,9 +393,9 @@ class BeanDefinitionPropertyValueCodeGenerator {
|
|||
Entry<?, ?> entry = iterator.next();
|
||||
code.add("$T.entry($L,$L)", Map.class,
|
||||
BeanDefinitionPropertyValueCodeGenerator.this
|
||||
.generateCode(entry.getKey(), keyType),
|
||||
.generateCodeForElement(entry.getKey(), keyType),
|
||||
BeanDefinitionPropertyValueCodeGenerator.this
|
||||
.generateCode(entry.getValue(), valueType));
|
||||
.generateCodeForElement(entry.getValue(), valueType));
|
||||
if (iterator.hasNext()) {
|
||||
code.add(", ");
|
||||
}
|
||||
|
|
@ -457,9 +479,9 @@ class BeanDefinitionPropertyValueCodeGenerator {
|
|||
while (iterator.hasNext()) {
|
||||
Entry<K, V> entry = iterator.next();
|
||||
CodeBlock keyCode = BeanDefinitionPropertyValueCodeGenerator.this
|
||||
.generateCode(entry.getKey(), keyType);
|
||||
.generateCodeForElement(entry.getKey(), keyType);
|
||||
CodeBlock valueCode = BeanDefinitionPropertyValueCodeGenerator.this
|
||||
.generateCode(entry.getValue(), valueType);
|
||||
.generateCodeForElement(entry.getValue(), valueType);
|
||||
if (!useOfEntries) {
|
||||
code.add("$L, $L", keyCode, valueCode);
|
||||
}
|
||||
|
|
@ -490,9 +512,9 @@ class BeanDefinitionPropertyValueCodeGenerator {
|
|||
LinkedHashMap.class, map.size());
|
||||
map.forEach((key, value) -> method.addStatement("map.put($L, $L)",
|
||||
BeanDefinitionPropertyValueCodeGenerator.this
|
||||
.generateCode(key, keyType),
|
||||
.generateCodeForElement(key, keyType),
|
||||
BeanDefinitionPropertyValueCodeGenerator.this
|
||||
.generateCode(value, valueType)));
|
||||
.generateCodeForElement(value, valueType)));
|
||||
method.addStatement("return map");
|
||||
});
|
||||
return CodeBlock.of("$L()", generatedMethod.getName());
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import org.springframework.javapoet.MethodSpec;
|
|||
import org.springframework.javapoet.ParameterizedTypeName;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link BeanDefinitionPropertyValueCodeGenerator}.
|
||||
|
|
@ -492,4 +493,48 @@ class BeanDefinitionPropertyValueCodeGeneratorTests {
|
|||
|
||||
}
|
||||
|
||||
@Nested
|
||||
static class ExceptionTests {
|
||||
|
||||
@Test
|
||||
void generateWhenUnsupportedDataTypeThrowsException() {
|
||||
SampleValue sampleValue = new SampleValue("one");
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> generateCode(sampleValue))
|
||||
.withMessageContaining("Failed to generate code for")
|
||||
.withMessageContaining(sampleValue.toString())
|
||||
.withMessageContaining(SampleValue.class.getName())
|
||||
.havingCause()
|
||||
.withMessageContaining("Code generation does not support")
|
||||
.withMessageContaining(SampleValue.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateWhenListOfUnsupportedElement() {
|
||||
SampleValue one = new SampleValue("one");
|
||||
SampleValue two = new SampleValue("two");
|
||||
List<SampleValue> list = List.of(one, two);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> generateCode(list))
|
||||
.withMessageContaining("Failed to generate code for")
|
||||
.withMessageContaining(list.toString())
|
||||
.withMessageContaining(list.getClass().getName())
|
||||
.havingCause()
|
||||
.withMessageContaining("Failed to generate code for")
|
||||
.withMessageContaining(one.toString())
|
||||
.withMessageContaining("?")
|
||||
.havingCause()
|
||||
.withMessageContaining("Code generation does not support ?");
|
||||
}
|
||||
|
||||
private void generateCode(Object value) {
|
||||
TestGenerationContext context = new TestGenerationContext();
|
||||
GeneratedClass generatedClass = context.getGeneratedClasses()
|
||||
.addForFeature("Test", type -> {});
|
||||
new BeanDefinitionPropertyValueCodeGenerator(generatedClass.getMethods())
|
||||
.generateCode(value);
|
||||
}
|
||||
|
||||
record SampleValue(String name) {}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue