Skip to content

Commit

Permalink
Extract value code generation to make it reusable
Browse files Browse the repository at this point in the history
This commit introduces ValueCodeGenerator and its Delegate interface
as a way to generate the code for a particular value. Implementations
in spring-core provides support for common value types such a String,
primitives, Collections, etc.

Additional implementations are provided for code generation of bean
definition property values.

Closes gh-28999
  • Loading branch information
snicoll committed Dec 13, 2023
1 parent 75da9c3 commit 3c2c9ca
Show file tree
Hide file tree
Showing 14 changed files with 1,479 additions and 833 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
import java.util.function.Predicate;

import org.springframework.aot.generate.GeneratedMethods;
import org.springframework.aot.generate.ValueCodeGenerator;
import org.springframework.aot.generate.ValueCodeGenerator.Delegate;
import org.springframework.aot.generate.ValueCodeGeneratorDelegates;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
Expand Down Expand Up @@ -89,7 +92,7 @@ class BeanDefinitionPropertiesCodeGenerator {

private final Predicate<String> attributeFilter;

private final BeanDefinitionPropertyValueCodeGenerator valueCodeGenerator;
private final ValueCodeGenerator valueCodeGenerator;


BeanDefinitionPropertiesCodeGenerator(RuntimeHints hints,
Expand All @@ -98,8 +101,11 @@ class BeanDefinitionPropertiesCodeGenerator {

this.hints = hints;
this.attributeFilter = attributeFilter;
this.valueCodeGenerator = new BeanDefinitionPropertyValueCodeGenerator(generatedMethods,
(object, type) -> customValueCodeGenerator.apply(PropertyNamesStack.peek(), object));
this.valueCodeGenerator = ValueCodeGenerator
.with(new ValueCodeGeneratorDelegateAdapter(customValueCodeGenerator))
.add(BeanDefinitionPropertyValueCodeGeneratorDelegates.INSTANCES)
.add(ValueCodeGeneratorDelegates.INSTANCES)
.scoped(generatedMethods);
}


Expand Down Expand Up @@ -366,6 +372,22 @@ private CodeBlock castIfNecessary(boolean castNecessary, Class<?> castType, Code
return (castNecessary ? CodeBlock.of("($T) $L", castType, valueCode) : valueCode);
}


static class ValueCodeGeneratorDelegateAdapter implements Delegate {

private final BiFunction<String, Object, CodeBlock> customValueCodeGenerator;

ValueCodeGeneratorDelegateAdapter(BiFunction<String, Object, CodeBlock> customValueCodeGenerator) {
this.customValueCodeGenerator = customValueCodeGenerator;
}

@Override
public CodeBlock generateCode(ValueCodeGenerator valueCodeGenerator, Object value) {
return this.customValueCodeGenerator.apply(PropertyNamesStack.peek(), value);
}
}


static class PropertyNamesStack {

private static final ThreadLocal<ArrayDeque<String>> threadLocal = ThreadLocal.withInitial(ArrayDeque::new);
Expand All @@ -384,7 +406,6 @@ static String peek() {
String value = threadLocal.get().peek();
return ("".equals(value) ? null : value);
}

}

}

0 comments on commit 3c2c9ca

Please sign in to comment.