Harmonize use of generate
This commit harmonizes the use of the "generate" keyword for anything related to code generation. Previously, there was a mix of "generate" and "write." See gh-28047
This commit is contained in:
parent
ea19b92deb
commit
97986b368a
|
|
@ -838,7 +838,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
||||||
boolean isRequired = isRequired(element);
|
boolean isRequired = isRequired(element);
|
||||||
Member member = element.getMember();
|
Member member = element.getMember();
|
||||||
analyzeMember(contribution, member);
|
analyzeMember(contribution, member);
|
||||||
contribution.statements().addStatement(this.generator.writeInjection(member, isRequired));
|
contribution.statements().addStatement(this.generator.generateInjection(member, isRequired));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support for writing parameters.
|
* Support for generating parameters.
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
|
|
@ -52,16 +52,16 @@ public final class BeanParameterGenerator {
|
||||||
|
|
||||||
private final ResolvableTypeGenerator typeGenerator = new ResolvableTypeGenerator();
|
private final ResolvableTypeGenerator typeGenerator = new ResolvableTypeGenerator();
|
||||||
|
|
||||||
private final BiConsumer<BeanDefinition, Builder> innerBeanDefinitionWriter;
|
private final BiConsumer<BeanDefinition, Builder> innerBeanDefinitionGenerator;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an instance with the callback to use to write an inner bean
|
* Create an instance with the callback to use to generate an inner bean
|
||||||
* definition.
|
* definition.
|
||||||
* @param innerBeanDefinitionWriter the inner bean definition writer
|
* @param innerBeanDefinitionGenerator the inner bean definition generator
|
||||||
*/
|
*/
|
||||||
public BeanParameterGenerator(BiConsumer<BeanDefinition, Builder> innerBeanDefinitionWriter) {
|
public BeanParameterGenerator(BiConsumer<BeanDefinition, Builder> innerBeanDefinitionGenerator) {
|
||||||
this.innerBeanDefinitionWriter = innerBeanDefinitionWriter;
|
this.innerBeanDefinitionGenerator = innerBeanDefinitionGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -75,39 +75,39 @@ public final class BeanParameterGenerator {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the specified parameter {@code value}.
|
* Generate the specified parameter {@code value}.
|
||||||
* @param value the value of the parameter
|
* @param value the value of the parameter
|
||||||
* @return the value of the parameter
|
* @return the value of the parameter
|
||||||
*/
|
*/
|
||||||
public CodeBlock writeParameterValue(@Nullable Object value) {
|
public CodeBlock generateParameterValue(@Nullable Object value) {
|
||||||
return writeParameterValue(value, () -> ResolvableType.forInstance(value));
|
return generateParameterValue(value, () -> ResolvableType.forInstance(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the specified parameter {@code value}.
|
* Generate the specified parameter {@code value}.
|
||||||
* @param value the value of the parameter
|
* @param value the value of the parameter
|
||||||
* @param parameterType the type of the parameter
|
* @param parameterType the type of the parameter
|
||||||
* @return the value of the parameter
|
* @return the value of the parameter
|
||||||
*/
|
*/
|
||||||
public CodeBlock writeParameterValue(@Nullable Object value, Supplier<ResolvableType> parameterType) {
|
public CodeBlock generateParameterValue(@Nullable Object value, Supplier<ResolvableType> parameterType) {
|
||||||
Builder code = CodeBlock.builder();
|
Builder code = CodeBlock.builder();
|
||||||
writeParameterValue(code, value, parameterType);
|
generateParameterValue(code, value, parameterType);
|
||||||
return code.build();
|
return code.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the parameter types of the specified {@link Executable}.
|
* Generate the parameter types of the specified {@link Executable}.
|
||||||
* @param executable the executable
|
* @param executable the executable
|
||||||
* @return the parameter types of the executable as a comma separated list
|
* @return the parameter types of the executable as a comma separated list
|
||||||
*/
|
*/
|
||||||
public CodeBlock writeExecutableParameterTypes(Executable executable) {
|
public CodeBlock generateExecutableParameterTypes(Executable executable) {
|
||||||
Class<?>[] parameterTypes = Arrays.stream(executable.getParameters())
|
Class<?>[] parameterTypes = Arrays.stream(executable.getParameters())
|
||||||
.map(Parameter::getType).toArray(Class<?>[]::new);
|
.map(Parameter::getType).toArray(Class<?>[]::new);
|
||||||
return CodeBlock.of(Arrays.stream(parameterTypes).map(d -> "$T.class")
|
return CodeBlock.of(Arrays.stream(parameterTypes).map(d -> "$T.class")
|
||||||
.collect(Collectors.joining(", ")), (Object[]) parameterTypes);
|
.collect(Collectors.joining(", ")), (Object[]) parameterTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeParameterValue(Builder code, @Nullable Object value, Supplier<ResolvableType> parameterTypeSupplier) {
|
private void generateParameterValue(Builder code, @Nullable Object value, Supplier<ResolvableType> parameterTypeSupplier) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
code.add("null");
|
code.add("null");
|
||||||
return;
|
return;
|
||||||
|
|
@ -115,7 +115,7 @@ public final class BeanParameterGenerator {
|
||||||
ResolvableType parameterType = parameterTypeSupplier.get();
|
ResolvableType parameterType = parameterTypeSupplier.get();
|
||||||
if (parameterType.isArray()) {
|
if (parameterType.isArray()) {
|
||||||
code.add("new $T { ", parameterType.toClass());
|
code.add("new $T { ", parameterType.toClass());
|
||||||
code.add(writeAll(Arrays.asList(ObjectUtils.toObjectArray(value)),
|
code.add(generateAll(Arrays.asList(ObjectUtils.toObjectArray(value)),
|
||||||
item -> parameterType.getComponentType()));
|
item -> parameterType.getComponentType()));
|
||||||
code.add(" }");
|
code.add(" }");
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +127,7 @@ public final class BeanParameterGenerator {
|
||||||
Class<?> listType = (value instanceof ManagedList ? ManagedList.class : List.class);
|
Class<?> listType = (value instanceof ManagedList ? ManagedList.class : List.class);
|
||||||
code.add("$T.of(", listType);
|
code.add("$T.of(", listType);
|
||||||
ResolvableType collectionType = parameterType.as(List.class).getGenerics()[0];
|
ResolvableType collectionType = parameterType.as(List.class).getGenerics()[0];
|
||||||
code.add(writeAll(list, item -> collectionType));
|
code.add(generateAll(list, item -> collectionType));
|
||||||
code.add(")");
|
code.add(")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -139,7 +139,7 @@ public final class BeanParameterGenerator {
|
||||||
Class<?> setType = (value instanceof ManagedSet ? ManagedSet.class : Set.class);
|
Class<?> setType = (value instanceof ManagedSet ? ManagedSet.class : Set.class);
|
||||||
code.add("$T.of(", setType);
|
code.add("$T.of(", setType);
|
||||||
ResolvableType collectionType = parameterType.as(Set.class).getGenerics()[0];
|
ResolvableType collectionType = parameterType.as(Set.class).getGenerics()[0];
|
||||||
code.add(writeAll(set, item -> collectionType));
|
code.add(generateAll(set, item -> collectionType));
|
||||||
code.add(")");
|
code.add(")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -151,7 +151,7 @@ public final class BeanParameterGenerator {
|
||||||
parameters.add(mapKey);
|
parameters.add(mapKey);
|
||||||
parameters.add(mapValue);
|
parameters.add(mapValue);
|
||||||
});
|
});
|
||||||
code.add(writeAll(parameters, ResolvableType::forInstance));
|
code.add(generateAll(parameters, ResolvableType::forInstance));
|
||||||
code.add(")");
|
code.add(")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +175,7 @@ public final class BeanParameterGenerator {
|
||||||
code.add(this.typeGenerator.generateTypeFor((ResolvableType) value));
|
code.add(this.typeGenerator.generateTypeFor((ResolvableType) value));
|
||||||
}
|
}
|
||||||
else if (value instanceof BeanDefinition) {
|
else if (value instanceof BeanDefinition) {
|
||||||
this.innerBeanDefinitionWriter.accept((BeanDefinition) value, code);
|
this.innerBeanDefinitionGenerator.accept((BeanDefinition) value, code);
|
||||||
}
|
}
|
||||||
else if (value instanceof BeanReference) {
|
else if (value instanceof BeanReference) {
|
||||||
code.add("new $T($S)", RuntimeBeanReference.class, ((BeanReference) value).getBeanName());
|
code.add("new $T($S)", RuntimeBeanReference.class, ((BeanReference) value).getBeanName());
|
||||||
|
|
@ -185,10 +185,10 @@ public final class BeanParameterGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> CodeBlock writeAll(Iterable<T> items, Function<T, ResolvableType> elementType) {
|
private <T> CodeBlock generateAll(Iterable<T> items, Function<T, ResolvableType> elementType) {
|
||||||
MultiCodeBlock multi = new MultiCodeBlock();
|
MultiCodeBlock multi = new MultiCodeBlock();
|
||||||
items.forEach(item -> multi.add(code ->
|
items.forEach(item -> multi.add(code ->
|
||||||
writeParameterValue(code, item, () -> elementType.apply(item))));
|
generateParameterValue(code, item, () -> elementType.apply(item))));
|
||||||
return multi.join(", ");
|
return multi.join(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import org.springframework.javapoet.CodeBlock;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the necessary statements to instantiate a bean.
|
* Generate the necessary statements to instantiate a bean.
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @see BeanInstantiationContribution
|
* @see BeanInstantiationContribution
|
||||||
|
|
@ -64,18 +64,18 @@ class DefaultBeanInstantiationGenerator {
|
||||||
* @return a code contribution that provides an initialized bean instance
|
* @return a code contribution that provides an initialized bean instance
|
||||||
*/
|
*/
|
||||||
public CodeContribution generateBeanInstantiation(RuntimeHints runtimeHints) {
|
public CodeContribution generateBeanInstantiation(RuntimeHints runtimeHints) {
|
||||||
DefaultCodeContribution contribution = new DefaultCodeContribution(runtimeHints);
|
DefaultCodeContribution codeContribution = new DefaultCodeContribution(runtimeHints);
|
||||||
contribution.protectedAccess().analyze(this.instanceCreator, this.beanInstanceOptions);
|
codeContribution.protectedAccess().analyze(this.instanceCreator, this.beanInstanceOptions);
|
||||||
if (this.instanceCreator instanceof Constructor<?> constructor) {
|
if (this.instanceCreator instanceof Constructor<?> constructor) {
|
||||||
writeBeanInstantiation(contribution, constructor);
|
generateBeanInstantiation(codeContribution, constructor);
|
||||||
}
|
}
|
||||||
else if (this.instanceCreator instanceof Method method) {
|
else if (this.instanceCreator instanceof Method method) {
|
||||||
writeBeanInstantiation(contribution, method);
|
generateBeanInstantiation(codeContribution, method);
|
||||||
}
|
}
|
||||||
return contribution;
|
return codeContribution;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeBeanInstantiation(CodeContribution contribution, Constructor<?> constructor) {
|
private void generateBeanInstantiation(CodeContribution codeContribution, Constructor<?> constructor) {
|
||||||
Class<?> declaringType = ClassUtils.getUserClass(constructor.getDeclaringClass());
|
Class<?> declaringType = ClassUtils.getUserClass(constructor.getDeclaringClass());
|
||||||
boolean innerClass = isInnerClass(declaringType);
|
boolean innerClass = isInnerClass(declaringType);
|
||||||
boolean multiStatements = !this.contributions.isEmpty();
|
boolean multiStatements = !this.contributions.isEmpty();
|
||||||
|
|
@ -96,24 +96,24 @@ class DefaultBeanInstantiationGenerator {
|
||||||
code.add("$T::new", declaringType);
|
code.add("$T::new", declaringType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
contribution.statements().addStatement(code.build());
|
codeContribution.statements().addStatement(code.build());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
contribution.runtimeHints().reflection().registerConstructor(constructor,
|
codeContribution.runtimeHints().reflection().registerConstructor(constructor,
|
||||||
hint -> hint.withMode(ExecutableMode.INTROSPECT));
|
hint -> hint.withMode(ExecutableMode.INTROSPECT));
|
||||||
code.add("(instanceContext) ->");
|
code.add("(instanceContext) ->");
|
||||||
branch(multiStatements, () -> code.beginControlFlow(""), () -> code.add(" "));
|
branch(multiStatements, () -> code.beginControlFlow(""), () -> code.add(" "));
|
||||||
if (multiStatements) {
|
if (multiStatements) {
|
||||||
code.add("$T bean = ", declaringType);
|
code.add("$T bean = ", declaringType);
|
||||||
}
|
}
|
||||||
code.add(this.injectionGenerator.writeInstantiation(constructor));
|
code.add(this.injectionGenerator.generateInstantiation(constructor));
|
||||||
contribution.statements().addStatement(code.build());
|
codeContribution.statements().addStatement(code.build());
|
||||||
|
|
||||||
if (multiStatements) {
|
if (multiStatements) {
|
||||||
for (BeanInstantiationContribution contributor : this.contributions) {
|
for (BeanInstantiationContribution contribution : this.contributions) {
|
||||||
contributor.applyTo(contribution);
|
contribution.applyTo(codeContribution);
|
||||||
}
|
}
|
||||||
contribution.statements().addStatement("return bean")
|
codeContribution.statements().addStatement("return bean")
|
||||||
.add(codeBlock -> codeBlock.unindent().add("}"));
|
.add(codeBlock -> codeBlock.unindent().add("}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -122,9 +122,9 @@ class DefaultBeanInstantiationGenerator {
|
||||||
return type.isMemberClass() && !Modifier.isStatic(type.getModifiers());
|
return type.isMemberClass() && !Modifier.isStatic(type.getModifiers());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeBeanInstantiation(CodeContribution contribution, Method method) {
|
private void generateBeanInstantiation(CodeContribution codeContribution, Method method) {
|
||||||
// Factory method can be introspected
|
// Factory method can be introspected
|
||||||
contribution.runtimeHints().reflection().registerMethod(method,
|
codeContribution.runtimeHints().reflection().registerMethod(method,
|
||||||
hint -> hint.withMode(ExecutableMode.INTROSPECT));
|
hint -> hint.withMode(ExecutableMode.INTROSPECT));
|
||||||
List<Class<?>> parameterTypes = new ArrayList<>(Arrays.asList(method.getParameterTypes()));
|
List<Class<?>> parameterTypes = new ArrayList<>(Arrays.asList(method.getParameterTypes()));
|
||||||
boolean multiStatements = !this.contributions.isEmpty();
|
boolean multiStatements = !this.contributions.isEmpty();
|
||||||
|
|
@ -137,7 +137,7 @@ class DefaultBeanInstantiationGenerator {
|
||||||
() -> code.add("$T", declaringType),
|
() -> code.add("$T", declaringType),
|
||||||
() -> code.add("beanFactory.getBean($T.class)", declaringType));
|
() -> code.add("beanFactory.getBean($T.class)", declaringType));
|
||||||
code.add(".$L()", method.getName());
|
code.add(".$L()", method.getName());
|
||||||
contribution.statements().addStatement(code.build());
|
codeContribution.statements().addStatement(code.build());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
code.add("(instanceContext) ->");
|
code.add("(instanceContext) ->");
|
||||||
|
|
@ -145,13 +145,13 @@ class DefaultBeanInstantiationGenerator {
|
||||||
if (multiStatements) {
|
if (multiStatements) {
|
||||||
code.add("$T bean = ", method.getReturnType());
|
code.add("$T bean = ", method.getReturnType());
|
||||||
}
|
}
|
||||||
code.add(this.injectionGenerator.writeInstantiation(method));
|
code.add(this.injectionGenerator.generateInstantiation(method));
|
||||||
contribution.statements().addStatement(code.build());
|
codeContribution.statements().addStatement(code.build());
|
||||||
if (multiStatements) {
|
if (multiStatements) {
|
||||||
for (BeanInstantiationContribution contributor : this.contributions) {
|
for (BeanInstantiationContribution contribution : this.contributions) {
|
||||||
contributor.applyTo(contribution);
|
contribution.applyTo(codeContribution);
|
||||||
}
|
}
|
||||||
contribution.statements().addStatement("return bean")
|
codeContribution.statements().addStatement("return bean")
|
||||||
.add(codeBlock -> codeBlock.unindent().add("}"));
|
.add(codeBlock -> codeBlock.unindent().add("}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@ import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the necessary code to {@link #writeInstantiation(Executable)
|
* Generate the necessary code to {@link #generateInstantiation(Executable)
|
||||||
* create a bean instance} or {@link #writeInjection(Member, boolean)
|
* create a bean instance} or {@link #generateInjection(Member, boolean)
|
||||||
* inject dependencies}.
|
* inject dependencies}.
|
||||||
* <p/>
|
* <p/>
|
||||||
* The generator assumes a number of variables to be accessible:
|
* The generator assumes a number of variables to be accessible:
|
||||||
|
|
@ -63,37 +63,37 @@ public class InjectionGenerator {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the necessary code to instantiate an object using the specified
|
* Generate the necessary code to instantiate an object using the specified
|
||||||
* {@link Executable}. The code is suitable to be assigned to a variable
|
* {@link Executable}. The code is suitable to be assigned to a variable
|
||||||
* or used as a {@literal return} statement.
|
* or used as a {@literal return} statement.
|
||||||
* @param creator the executable to invoke to create an instance of the
|
* @param creator the executable to invoke to create an instance of the
|
||||||
* requested object
|
* requested object
|
||||||
* @return the code to instantiate an object using the specified executable
|
* @return the code to instantiate an object using the specified executable
|
||||||
*/
|
*/
|
||||||
public CodeBlock writeInstantiation(Executable creator) {
|
public CodeBlock generateInstantiation(Executable creator) {
|
||||||
if (creator instanceof Constructor<?> constructor) {
|
if (creator instanceof Constructor<?> constructor) {
|
||||||
return write(constructor);
|
return generateConstructorInstantiation(constructor);
|
||||||
}
|
}
|
||||||
if (creator instanceof Method method) {
|
if (creator instanceof Method method) {
|
||||||
return writeMethodInstantiation(method);
|
return generateMethodInstantiation(method);
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("Could not handle creator " + creator);
|
throw new IllegalArgumentException("Could not handle creator " + creator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the code to inject a value resolved by {@link BeanInstanceContext}
|
* Generate the code to inject a value resolved by {@link BeanInstanceContext}
|
||||||
* in the specified {@link Member}.
|
* in the specified {@link Member}.
|
||||||
* @param member the field or method to inject
|
* @param member the field or method to inject
|
||||||
* @param required whether the value is required
|
* @param required whether the value is required
|
||||||
* @return a statement that injects a value to the specified member
|
* @return a statement that injects a value to the specified member
|
||||||
* @see #getProtectedAccessInjectionOptions(Member)
|
* @see #getProtectedAccessInjectionOptions(Member)
|
||||||
*/
|
*/
|
||||||
public CodeBlock writeInjection(Member member, boolean required) {
|
public CodeBlock generateInjection(Member member, boolean required) {
|
||||||
if (member instanceof Method method) {
|
if (member instanceof Method method) {
|
||||||
return writeMethodInjection(method, required);
|
return generateMethodInjection(method, required);
|
||||||
}
|
}
|
||||||
if (member instanceof Field field) {
|
if (member instanceof Field field) {
|
||||||
return writeFieldInjection(field, required);
|
return generateFieldInjection(field, required);
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("Could not handle member " + member);
|
throw new IllegalArgumentException("Could not handle member " + member);
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +115,7 @@ public class InjectionGenerator {
|
||||||
throw new IllegalArgumentException("Could not handle member " + member);
|
throw new IllegalArgumentException("Could not handle member " + member);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeBlock write(Constructor<?> creator) {
|
private CodeBlock generateConstructorInstantiation(Constructor<?> creator) {
|
||||||
Builder code = CodeBlock.builder();
|
Builder code = CodeBlock.builder();
|
||||||
Class<?> declaringType = ClassUtils.getUserClass(creator.getDeclaringClass());
|
Class<?> declaringType = ClassUtils.getUserClass(creator.getDeclaringClass());
|
||||||
boolean innerClass = isInnerClass(declaringType);
|
boolean innerClass = isInnerClass(declaringType);
|
||||||
|
|
@ -162,7 +162,7 @@ public class InjectionGenerator {
|
||||||
return type.isMemberClass() && !Modifier.isStatic(type.getModifiers());
|
return type.isMemberClass() && !Modifier.isStatic(type.getModifiers());
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeBlock writeMethodInstantiation(Method injectionPoint) {
|
private CodeBlock generateMethodInstantiation(Method injectionPoint) {
|
||||||
if (injectionPoint.getParameterCount() == 0) {
|
if (injectionPoint.getParameterCount() == 0) {
|
||||||
Builder code = CodeBlock.builder();
|
Builder code = CodeBlock.builder();
|
||||||
Class<?> declaringType = injectionPoint.getDeclaringClass();
|
Class<?> declaringType = injectionPoint.getDeclaringClass();
|
||||||
|
|
@ -175,10 +175,10 @@ public class InjectionGenerator {
|
||||||
code.add(".$L()", injectionPoint.getName());
|
code.add(".$L()", injectionPoint.getName());
|
||||||
return code.build();
|
return code.build();
|
||||||
}
|
}
|
||||||
return write(injectionPoint, code -> code.add(".create(beanFactory, (attributes) ->"), true);
|
return generateMethodInvocation(injectionPoint, code -> code.add(".create(beanFactory, (attributes) ->"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeBlock writeMethodInjection(Method injectionPoint, boolean required) {
|
private CodeBlock generateMethodInjection(Method injectionPoint, boolean required) {
|
||||||
Consumer<Builder> attributesResolver = code -> {
|
Consumer<Builder> attributesResolver = code -> {
|
||||||
if (required) {
|
if (required) {
|
||||||
code.add(".invoke(beanFactory, (attributes) ->");
|
code.add(".invoke(beanFactory, (attributes) ->");
|
||||||
|
|
@ -187,15 +187,15 @@ public class InjectionGenerator {
|
||||||
code.add(".resolve(beanFactory, false).ifResolved((attributes) ->");
|
code.add(".resolve(beanFactory, false).ifResolved((attributes) ->");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return write(injectionPoint, attributesResolver, false);
|
return generateMethodInvocation(injectionPoint, attributesResolver, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeBlock write(Method injectionPoint, Consumer<Builder> attributesResolver, boolean instantiation) {
|
private CodeBlock generateMethodInvocation(Method injectionPoint, Consumer<Builder> attributesResolver, boolean instantiation) {
|
||||||
Builder code = CodeBlock.builder();
|
Builder code = CodeBlock.builder();
|
||||||
code.add("instanceContext");
|
code.add("instanceContext");
|
||||||
if (!instantiation) {
|
if (!instantiation) {
|
||||||
code.add(".method($S, ", injectionPoint.getName());
|
code.add(".method($S, ", injectionPoint.getName());
|
||||||
code.add(this.parameterGenerator.writeExecutableParameterTypes(injectionPoint));
|
code.add(this.parameterGenerator.generateExecutableParameterTypes(injectionPoint));
|
||||||
code.add(")\n").indent().indent();
|
code.add(")\n").indent().indent();
|
||||||
}
|
}
|
||||||
attributesResolver.accept(code);
|
attributesResolver.accept(code);
|
||||||
|
|
@ -222,7 +222,7 @@ public class InjectionGenerator {
|
||||||
return code.build();
|
return code.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeBlock writeFieldInjection(Field injectionPoint, boolean required) {
|
CodeBlock generateFieldInjection(Field injectionPoint, boolean required) {
|
||||||
Builder code = CodeBlock.builder();
|
Builder code = CodeBlock.builder();
|
||||||
code.add("instanceContext.field($S, $T.class", injectionPoint.getName(), injectionPoint.getType());
|
code.add("instanceContext.field($S, $T.class", injectionPoint.getName(), injectionPoint.getType());
|
||||||
code.add(")\n").indent().indent();
|
code.add(")\n").indent().indent();
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
import org.springframework.core.io.ResourceLoader;
|
import org.springframework.core.io.ResourceLoader;
|
||||||
import org.springframework.javapoet.support.CodeSnippet;
|
import org.springframework.javapoet.support.CodeSnippet;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
@ -59,21 +60,21 @@ class BeanParameterGeneratorTests {
|
||||||
private final BeanParameterGenerator generator = new BeanParameterGenerator();
|
private final BeanParameterGenerator generator = new BeanParameterGenerator();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeCharArray() {
|
void generateCharArray() {
|
||||||
char[] value = new char[] { 'v', 'a', 'l', 'u', 'e' };
|
char[] value = new char[] { 'v', 'a', 'l', 'u', 'e' };
|
||||||
assertThat(write(value, ResolvableType.forArrayComponent(ResolvableType.forClass(char.class))))
|
assertThat(generate(value, ResolvableType.forArrayComponent(ResolvableType.forClass(char.class))))
|
||||||
.isEqualTo("new char[] { 'v', 'a', 'l', 'u', 'e' }");
|
.isEqualTo("new char[] { 'v', 'a', 'l', 'u', 'e' }");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeStringArray() {
|
void generateStringArray() {
|
||||||
String[] value = new String[] { "a", "test" };
|
String[] value = new String[] { "a", "test" };
|
||||||
assertThat(write(value, ResolvableType.forArrayComponent(ResolvableType.forClass(String.class))))
|
assertThat(generate(value, ResolvableType.forArrayComponent(ResolvableType.forClass(String.class))))
|
||||||
.isEqualTo("new String[] { \"a\", \"test\" }");
|
.isEqualTo("new String[] { \"a\", \"test\" }");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeStringList() {
|
void generateStringList() {
|
||||||
List<String> value = List.of("a", "test");
|
List<String> value = List.of("a", "test");
|
||||||
CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(List.class, String.class));
|
CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(List.class, String.class));
|
||||||
assertThat(code.getSnippet()).isEqualTo(
|
assertThat(code.getSnippet()).isEqualTo(
|
||||||
|
|
@ -82,7 +83,7 @@ class BeanParameterGeneratorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeStringManagedList() {
|
void generateStringManagedList() {
|
||||||
ManagedList<String> value = ManagedList.of("a", "test");
|
ManagedList<String> value = ManagedList.of("a", "test");
|
||||||
CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(List.class, String.class));
|
CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(List.class, String.class));
|
||||||
assertThat(code.getSnippet()).isEqualTo(
|
assertThat(code.getSnippet()).isEqualTo(
|
||||||
|
|
@ -91,7 +92,7 @@ class BeanParameterGeneratorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeEmptyList() {
|
void generateEmptyList() {
|
||||||
List<String> value = List.of();
|
List<String> value = List.of();
|
||||||
CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(List.class, String.class));
|
CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(List.class, String.class));
|
||||||
assertThat(code.getSnippet()).isEqualTo("Collections.emptyList()");
|
assertThat(code.getSnippet()).isEqualTo("Collections.emptyList()");
|
||||||
|
|
@ -99,7 +100,7 @@ class BeanParameterGeneratorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeStringSet() {
|
void generateStringSet() {
|
||||||
Set<String> value = Set.of("a", "test");
|
Set<String> value = Set.of("a", "test");
|
||||||
CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(Set.class, String.class));
|
CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(Set.class, String.class));
|
||||||
assertThat(code.getSnippet()).startsWith("Set.of(").contains("a").contains("test");
|
assertThat(code.getSnippet()).startsWith("Set.of(").contains("a").contains("test");
|
||||||
|
|
@ -107,7 +108,7 @@ class BeanParameterGeneratorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeStringManagedSet() {
|
void generateStringManagedSet() {
|
||||||
Set<String> value = ManagedSet.of("a", "test");
|
Set<String> value = ManagedSet.of("a", "test");
|
||||||
CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(Set.class, String.class));
|
CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(Set.class, String.class));
|
||||||
assertThat(code.getSnippet()).isEqualTo(
|
assertThat(code.getSnippet()).isEqualTo(
|
||||||
|
|
@ -116,7 +117,7 @@ class BeanParameterGeneratorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeEmptySet() {
|
void generateEmptySet() {
|
||||||
Set<String> value = Set.of();
|
Set<String> value = Set.of();
|
||||||
CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(Set.class, String.class));
|
CodeSnippet code = codeSnippet(value, ResolvableType.forClassWithGenerics(Set.class, String.class));
|
||||||
assertThat(code.getSnippet()).isEqualTo("Collections.emptySet()");
|
assertThat(code.getSnippet()).isEqualTo("Collections.emptySet()");
|
||||||
|
|
@ -124,39 +125,39 @@ class BeanParameterGeneratorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeMap() {
|
void generateMap() {
|
||||||
Map<String, Object> value = new LinkedHashMap<>();
|
Map<String, Object> value = new LinkedHashMap<>();
|
||||||
value.put("name", "Hello");
|
value.put("name", "Hello");
|
||||||
value.put("counter", 42);
|
value.put("counter", 42);
|
||||||
assertThat(write(value)).isEqualTo("Map.of(\"name\", \"Hello\", \"counter\", 42)");
|
assertThat(generate(value)).isEqualTo("Map.of(\"name\", \"Hello\", \"counter\", 42)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeMapWithEnum() {
|
void generateMapWithEnum() {
|
||||||
Map<String, Object> value = new HashMap<>();
|
Map<String, Object> value = new HashMap<>();
|
||||||
value.put("unit", ChronoUnit.DAYS);
|
value.put("unit", ChronoUnit.DAYS);
|
||||||
assertThat(write(value)).isEqualTo("Map.of(\"unit\", ChronoUnit.DAYS)");
|
assertThat(generate(value)).isEqualTo("Map.of(\"unit\", ChronoUnit.DAYS)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeEmptyMap() {
|
void generateEmptyMap() {
|
||||||
assertThat(write(Map.of())).isEqualTo("Map.of()");
|
assertThat(generate(Map.of())).isEqualTo("Map.of()");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeString() {
|
void generateString() {
|
||||||
assertThat(write("test", ResolvableType.forClass(String.class))).isEqualTo("\"test\"");
|
assertThat(generate("test", ResolvableType.forClass(String.class))).isEqualTo("\"test\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeCharEscapeBackslash() {
|
void generateCharEscapeBackslash() {
|
||||||
assertThat(write('\\', ResolvableType.forType(char.class))).isEqualTo("'\\\\'");
|
assertThat(generate('\\', ResolvableType.forType(char.class))).isEqualTo("'\\\\'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("primitiveValues")
|
@MethodSource("primitiveValues")
|
||||||
void writePrimitiveValue(Object value, String parameter) {
|
void generatePrimitiveValue(Object value, String parameter) {
|
||||||
assertThat(write(value, ResolvableType.forClass(value.getClass()))).isEqualTo(parameter);
|
assertThat(generate(value, ResolvableType.forClass(value.getClass()))).isEqualTo(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Stream<Arguments> primitiveValues() {
|
private static Stream<Arguments> primitiveValues() {
|
||||||
|
|
@ -166,87 +167,88 @@ class BeanParameterGeneratorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeEnum() {
|
void generateEnum() {
|
||||||
assertThat(write(ChronoUnit.DAYS, ResolvableType.forClass(ChronoUnit.class)))
|
assertThat(generate(ChronoUnit.DAYS, ResolvableType.forClass(ChronoUnit.class)))
|
||||||
.isEqualTo("ChronoUnit.DAYS");
|
.isEqualTo("ChronoUnit.DAYS");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeClass() {
|
void generateClass() {
|
||||||
assertThat(write(Integer.class, ResolvableType.forClass(Class.class)))
|
assertThat(generate(Integer.class, ResolvableType.forClass(Class.class)))
|
||||||
.isEqualTo("Integer.class");
|
.isEqualTo("Integer.class");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeResolvableType() {
|
void generateResolvableType() {
|
||||||
ResolvableType type = ResolvableType.forClassWithGenerics(Consumer.class, Integer.class);
|
ResolvableType type = ResolvableType.forClassWithGenerics(Consumer.class, Integer.class);
|
||||||
assertThat(write(type, type))
|
assertThat(generate(type, type))
|
||||||
.isEqualTo("ResolvableType.forClassWithGenerics(Consumer.class, Integer.class)");
|
.isEqualTo("ResolvableType.forClassWithGenerics(Consumer.class, Integer.class)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeExecutableParameterTypesWithConstructor() {
|
void generateExecutableParameterTypesWithConstructor() {
|
||||||
Constructor<?> constructor = TestSample.class.getDeclaredConstructors()[0];
|
Constructor<?> constructor = TestSample.class.getDeclaredConstructors()[0];
|
||||||
assertThat(CodeSnippet.process(this.generator.writeExecutableParameterTypes(constructor)))
|
assertThat(CodeSnippet.process(this.generator.generateExecutableParameterTypes(constructor)))
|
||||||
.isEqualTo("String.class, ResourceLoader.class");
|
.isEqualTo("String.class, ResourceLoader.class");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeExecutableParameterTypesWithNoArgConstructor() {
|
void generateExecutableParameterTypesWithNoArgConstructor() {
|
||||||
Constructor<?> constructor = BeanParameterGeneratorTests.class.getDeclaredConstructors()[0];
|
Constructor<?> constructor = BeanParameterGeneratorTests.class.getDeclaredConstructors()[0];
|
||||||
assertThat(CodeSnippet.process(this.generator.writeExecutableParameterTypes(constructor)))
|
assertThat(CodeSnippet.process(this.generator.generateExecutableParameterTypes(constructor)))
|
||||||
.isEmpty();
|
.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeExecutableParameterTypesWithMethod() {
|
void generateExecutableParameterTypesWithMethod() {
|
||||||
Method method = ReflectionUtils.findMethod(TestSample.class, "createBean", String.class, Integer.class);
|
Method method = ReflectionUtils.findMethod(TestSample.class, "createBean", String.class, Integer.class);
|
||||||
assertThat(CodeSnippet.process(this.generator.writeExecutableParameterTypes(method)))
|
assertThat(CodeSnippet.process(this.generator.generateExecutableParameterTypes(method)))
|
||||||
.isEqualTo("String.class, Integer.class");
|
.isEqualTo("String.class, Integer.class");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeNull() {
|
void generateNull() {
|
||||||
assertThat(write(null)).isEqualTo("null");
|
assertThat(generate(null)).isEqualTo("null");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeBeanReference() {
|
void generateBeanReference() {
|
||||||
BeanReference beanReference = mock(BeanReference.class);
|
BeanReference beanReference = mock(BeanReference.class);
|
||||||
given(beanReference.getBeanName()).willReturn("testBean");
|
given(beanReference.getBeanName()).willReturn("testBean");
|
||||||
assertThat(write(beanReference)).isEqualTo("new RuntimeBeanReference(\"testBean\")");
|
assertThat(generate(beanReference)).isEqualTo("new RuntimeBeanReference(\"testBean\")");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeBeanDefinitionCallsConsumer() {
|
void generateBeanDefinitionCallsConsumer() {
|
||||||
BeanParameterGenerator customGenerator = new BeanParameterGenerator(
|
BeanParameterGenerator customGenerator = new BeanParameterGenerator(
|
||||||
((beanDefinition, builder) -> builder.add("test")));
|
((beanDefinition, builder) -> builder.add("test")));
|
||||||
assertThat(CodeSnippet.process(customGenerator.writeParameterValue(new RootBeanDefinition()))).isEqualTo("test");
|
assertThat(CodeSnippet.process(customGenerator.generateParameterValue(
|
||||||
|
new RootBeanDefinition()))).isEqualTo("test");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeBeanDefinitionWithoutConsumerFails() {
|
void generateBeanDefinitionWithoutConsumerFails() {
|
||||||
BeanParameterGenerator customGenerator = new BeanParameterGenerator();
|
BeanParameterGenerator customGenerator = new BeanParameterGenerator();
|
||||||
assertThatIllegalStateException().isThrownBy(() -> customGenerator
|
assertThatIllegalStateException().isThrownBy(() -> customGenerator
|
||||||
.writeParameterValue(new RootBeanDefinition()));
|
.generateParameterValue(new RootBeanDefinition()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeUnsupportedParameter() {
|
void generateUnsupportedParameter() {
|
||||||
assertThatIllegalArgumentException().isThrownBy(() -> write(new StringWriter()))
|
assertThatIllegalArgumentException().isThrownBy(() -> generate(new StringWriter()))
|
||||||
.withMessageContaining(StringWriter.class.getName());
|
.withMessageContaining(StringWriter.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String write(Object value) {
|
private String generate(@Nullable Object value) {
|
||||||
return CodeSnippet.process(this.generator.writeParameterValue(value));
|
return CodeSnippet.process(this.generator.generateParameterValue(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String write(Object value, ResolvableType resolvableType) {
|
private String generate(Object value, ResolvableType resolvableType) {
|
||||||
return codeSnippet(value, resolvableType).getSnippet();
|
return codeSnippet(value, resolvableType).getSnippet();
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeSnippet codeSnippet(Object value, ResolvableType resolvableType) {
|
private CodeSnippet codeSnippet(Object value, ResolvableType resolvableType) {
|
||||||
return CodeSnippet.of(this.generator.writeParameterValue(value, () -> resolvableType));
|
return CodeSnippet.of(this.generator.generateParameterValue(value, () -> resolvableType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,119 +45,119 @@ class InjectionGeneratorTests {
|
||||||
private final ProtectedAccess protectedAccess = new ProtectedAccess();
|
private final ProtectedAccess protectedAccess = new ProtectedAccess();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInstantiationForConstructorWithNoArgUseShortcut() {
|
void generateInstantiationForConstructorWithNoArgUseShortcut() {
|
||||||
Constructor<?> constructor = SimpleBean.class.getDeclaredConstructors()[0];
|
Constructor<?> constructor = SimpleBean.class.getDeclaredConstructors()[0];
|
||||||
assertThat(writeInstantiation(constructor).lines())
|
assertThat(generateInstantiation(constructor).lines())
|
||||||
.containsExactly("new InjectionGeneratorTests.SimpleBean()");
|
.containsExactly("new InjectionGeneratorTests.SimpleBean()");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInstantiationForConstructorWithNonGenericParameter() {
|
void generateInstantiationForConstructorWithNonGenericParameter() {
|
||||||
Constructor<?> constructor = SimpleConstructorBean.class.getDeclaredConstructors()[0];
|
Constructor<?> constructor = SimpleConstructorBean.class.getDeclaredConstructors()[0];
|
||||||
assertThat(writeInstantiation(constructor).lines()).containsExactly(
|
assertThat(generateInstantiation(constructor).lines()).containsExactly(
|
||||||
"instanceContext.create(beanFactory, (attributes) -> new InjectionGeneratorTests.SimpleConstructorBean(attributes.get(0), attributes.get(1)))");
|
"instanceContext.create(beanFactory, (attributes) -> new InjectionGeneratorTests.SimpleConstructorBean(attributes.get(0), attributes.get(1)))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInstantiationForConstructorWithGenericParameter() {
|
void generateInstantiationForConstructorWithGenericParameter() {
|
||||||
Constructor<?> constructor = GenericConstructorBean.class.getDeclaredConstructors()[0];
|
Constructor<?> constructor = GenericConstructorBean.class.getDeclaredConstructors()[0];
|
||||||
assertThat(writeInstantiation(constructor).lines()).containsExactly(
|
assertThat(generateInstantiation(constructor).lines()).containsExactly(
|
||||||
"instanceContext.create(beanFactory, (attributes) -> new InjectionGeneratorTests.GenericConstructorBean(attributes.get(0)))");
|
"instanceContext.create(beanFactory, (attributes) -> new InjectionGeneratorTests.GenericConstructorBean(attributes.get(0)))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInstantiationForAmbiguousConstructor() throws Exception {
|
void generateInstantiationForAmbiguousConstructor() throws Exception {
|
||||||
Constructor<?> constructor = AmbiguousConstructorBean.class.getDeclaredConstructor(String.class, Number.class);
|
Constructor<?> constructor = AmbiguousConstructorBean.class.getDeclaredConstructor(String.class, Number.class);
|
||||||
assertThat(writeInstantiation(constructor).lines()).containsExactly(
|
assertThat(generateInstantiation(constructor).lines()).containsExactly(
|
||||||
"instanceContext.create(beanFactory, (attributes) -> new InjectionGeneratorTests.AmbiguousConstructorBean(attributes.get(0, String.class), attributes.get(1, Number.class)))");
|
"instanceContext.create(beanFactory, (attributes) -> new InjectionGeneratorTests.AmbiguousConstructorBean(attributes.get(0, String.class), attributes.get(1, Number.class)))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInstantiationForConstructorInInnerClass() {
|
void generateInstantiationForConstructorInInnerClass() {
|
||||||
Constructor<?> constructor = InnerClass.class.getDeclaredConstructors()[0];
|
Constructor<?> constructor = InnerClass.class.getDeclaredConstructors()[0];
|
||||||
assertThat(writeInstantiation(constructor).lines()).containsExactly(
|
assertThat(generateInstantiation(constructor).lines()).containsExactly(
|
||||||
"beanFactory.getBean(InjectionGeneratorTests.SimpleConstructorBean.class).new InnerClass()");
|
"beanFactory.getBean(InjectionGeneratorTests.SimpleConstructorBean.class).new InnerClass()");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInstantiationForMethodWithNoArgUseShortcut() {
|
void generateInstantiationForMethodWithNoArgUseShortcut() {
|
||||||
assertThat(writeInstantiation(method(SimpleBean.class, "name")).lines()).containsExactly(
|
assertThat(generateInstantiation(method(SimpleBean.class, "name")).lines()).containsExactly(
|
||||||
"beanFactory.getBean(InjectionGeneratorTests.SimpleBean.class).name()");
|
"beanFactory.getBean(InjectionGeneratorTests.SimpleBean.class).name()");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInstantiationForStaticMethodWithNoArgUseShortcut() {
|
void generateInstantiationForStaticMethodWithNoArgUseShortcut() {
|
||||||
assertThat(writeInstantiation(method(SimpleBean.class, "number")).lines()).containsExactly(
|
assertThat(generateInstantiation(method(SimpleBean.class, "number")).lines()).containsExactly(
|
||||||
"InjectionGeneratorTests.SimpleBean.number()");
|
"InjectionGeneratorTests.SimpleBean.number()");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInstantiationForMethodWithNonGenericParameter() {
|
void generateInstantiationForMethodWithNonGenericParameter() {
|
||||||
assertThat(writeInstantiation(method(SampleBean.class, "source", Integer.class)).lines()).containsExactly(
|
assertThat(generateInstantiation(method(SampleBean.class, "source", Integer.class)).lines()).containsExactly(
|
||||||
"instanceContext.create(beanFactory, (attributes) -> beanFactory.getBean(InjectionGeneratorTests.SampleBean.class).source(attributes.get(0)))");
|
"instanceContext.create(beanFactory, (attributes) -> beanFactory.getBean(InjectionGeneratorTests.SampleBean.class).source(attributes.get(0)))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInstantiationForStaticMethodWithNonGenericParameter() {
|
void generateInstantiationForStaticMethodWithNonGenericParameter() {
|
||||||
assertThat(writeInstantiation(method(SampleBean.class, "staticSource", Integer.class)).lines()).containsExactly(
|
assertThat(generateInstantiation(method(SampleBean.class, "staticSource", Integer.class)).lines()).containsExactly(
|
||||||
"instanceContext.create(beanFactory, (attributes) -> InjectionGeneratorTests.SampleBean.staticSource(attributes.get(0)))");
|
"instanceContext.create(beanFactory, (attributes) -> InjectionGeneratorTests.SampleBean.staticSource(attributes.get(0)))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInstantiationForMethodWithGenericParameters() {
|
void generateInstantiationForMethodWithGenericParameters() {
|
||||||
assertThat(writeInstantiation(method(SampleBean.class, "source", ObjectProvider.class)).lines()).containsExactly(
|
assertThat(generateInstantiation(method(SampleBean.class, "source", ObjectProvider.class)).lines()).containsExactly(
|
||||||
"instanceContext.create(beanFactory, (attributes) -> beanFactory.getBean(InjectionGeneratorTests.SampleBean.class).source(attributes.get(0)))");
|
"instanceContext.create(beanFactory, (attributes) -> beanFactory.getBean(InjectionGeneratorTests.SampleBean.class).source(attributes.get(0)))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInjectionForUnsupportedMember() {
|
void generateInjectionForUnsupportedMember() {
|
||||||
assertThatIllegalArgumentException().isThrownBy(() -> writeInjection(mock(Member.class), false));
|
assertThatIllegalArgumentException().isThrownBy(() -> generateInjection(mock(Member.class), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInjectionForNonRequiredMethodWithNonGenericParameters() {
|
void generateInjectionForNonRequiredMethodWithNonGenericParameters() {
|
||||||
Method method = method(SampleBean.class, "sourceAndCounter", String.class, Integer.class);
|
Method method = method(SampleBean.class, "sourceAndCounter", String.class, Integer.class);
|
||||||
assertThat(writeInjection(method, false)).isEqualTo("""
|
assertThat(generateInjection(method, false)).isEqualTo("""
|
||||||
instanceContext.method("sourceAndCounter", String.class, Integer.class)
|
instanceContext.method("sourceAndCounter", String.class, Integer.class)
|
||||||
.resolve(beanFactory, false).ifResolved((attributes) -> bean.sourceAndCounter(attributes.get(0), attributes.get(1)))""");
|
.resolve(beanFactory, false).ifResolved((attributes) -> bean.sourceAndCounter(attributes.get(0), attributes.get(1)))""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInjectionForRequiredMethodWithGenericParameter() {
|
void generateInjectionForRequiredMethodWithGenericParameter() {
|
||||||
Method method = method(SampleBean.class, "nameAndCounter", String.class, ObjectProvider.class);
|
Method method = method(SampleBean.class, "nameAndCounter", String.class, ObjectProvider.class);
|
||||||
assertThat(writeInjection(method, true)).isEqualTo("""
|
assertThat(generateInjection(method, true)).isEqualTo("""
|
||||||
instanceContext.method("nameAndCounter", String.class, ObjectProvider.class)
|
instanceContext.method("nameAndCounter", String.class, ObjectProvider.class)
|
||||||
.invoke(beanFactory, (attributes) -> bean.nameAndCounter(attributes.get(0), attributes.get(1)))""");
|
.invoke(beanFactory, (attributes) -> bean.nameAndCounter(attributes.get(0), attributes.get(1)))""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInjectionForNonRequiredMethodWithGenericParameter() {
|
void generateInjectionForNonRequiredMethodWithGenericParameter() {
|
||||||
Method method = method(SampleBean.class, "nameAndCounter", String.class, ObjectProvider.class);
|
Method method = method(SampleBean.class, "nameAndCounter", String.class, ObjectProvider.class);
|
||||||
assertThat(writeInjection(method, false)).isEqualTo("""
|
assertThat(generateInjection(method, false)).isEqualTo("""
|
||||||
instanceContext.method("nameAndCounter", String.class, ObjectProvider.class)
|
instanceContext.method("nameAndCounter", String.class, ObjectProvider.class)
|
||||||
.resolve(beanFactory, false).ifResolved((attributes) -> bean.nameAndCounter(attributes.get(0), attributes.get(1)))""");
|
.resolve(beanFactory, false).ifResolved((attributes) -> bean.nameAndCounter(attributes.get(0), attributes.get(1)))""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInjectionForRequiredField() {
|
void generateInjectionForRequiredField() {
|
||||||
Field field = field(SampleBean.class, "counter");
|
Field field = field(SampleBean.class, "counter");
|
||||||
assertThat(writeInjection(field, true)).isEqualTo("""
|
assertThat(generateInjection(field, true)).isEqualTo("""
|
||||||
instanceContext.field("counter", Integer.class)
|
instanceContext.field("counter", Integer.class)
|
||||||
.invoke(beanFactory, (attributes) -> bean.counter = attributes.get(0))""");
|
.invoke(beanFactory, (attributes) -> bean.counter = attributes.get(0))""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInjectionForNonRequiredField() {
|
void generateInjectionForNonRequiredField() {
|
||||||
Field field = field(SampleBean.class, "counter");
|
Field field = field(SampleBean.class, "counter");
|
||||||
assertThat(writeInjection(field, false)).isEqualTo("""
|
assertThat(generateInjection(field, false)).isEqualTo("""
|
||||||
instanceContext.field("counter", Integer.class)
|
instanceContext.field("counter", Integer.class)
|
||||||
.resolve(beanFactory, false).ifResolved((attributes) -> bean.counter = attributes.get(0))""");
|
.resolve(beanFactory, false).ifResolved((attributes) -> bean.counter = attributes.get(0))""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void writeInjectionForRequiredPrivateField() {
|
void generateInjectionForRequiredPrivateField() {
|
||||||
Field field = field(SampleBean.class, "source");
|
Field field = field(SampleBean.class, "source");
|
||||||
assertThat(writeInjection(field, true)).isEqualTo("""
|
assertThat(generateInjection(field, true)).isEqualTo("""
|
||||||
instanceContext.field("source", String.class)
|
instanceContext.field("source", String.class)
|
||||||
.invoke(beanFactory, (attributes) -> {
|
.invoke(beanFactory, (attributes) -> {
|
||||||
Field sourceField = ReflectionUtils.findField(InjectionGeneratorTests.SampleBean.class, "source", String.class);
|
Field sourceField = ReflectionUtils.findField(InjectionGeneratorTests.SampleBean.class, "source", String.class);
|
||||||
|
|
@ -215,12 +215,12 @@ class InjectionGeneratorTests {
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String writeInstantiation(Executable creator) {
|
private String generateInstantiation(Executable creator) {
|
||||||
return CodeSnippet.process(code -> code.add(new InjectionGenerator().writeInstantiation(creator)));
|
return CodeSnippet.process(code -> code.add(new InjectionGenerator().generateInstantiation(creator)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String writeInjection(Member member, boolean required) {
|
private String generateInjection(Member member, boolean required) {
|
||||||
return CodeSnippet.process(code -> code.add(new InjectionGenerator().writeInjection(member, required)));
|
return CodeSnippet.process(code -> code.add(new InjectionGenerator().generateInjection(member, required)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void analyzeProtectedAccess(Member member) {
|
private void analyzeProtectedAccess(Member member) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue