Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the behavior of InjectionPointInfo.getRequiredType() #17838

Merged
merged 1 commit into from
Jun 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,19 @@ void analyzeConfigPropertyInjectionPoints(BeanDiscoveryFinishedBuildItem beanDis
}

// Register a custom bean for injection points that are not handled by ConfigProducer
Type requiredType = injectionPoint.getRequiredType();
if (!isHandledByProducers(requiredType)) {
customBeanTypes.add(requiredType);
Type injectedType = injectionPoint.getType();
if (!isHandledByProducers(injectedType)) {
customBeanTypes.add(injectedType);
}

if (DotNames.OPTIONAL.equals(requiredType.name())
|| DotNames.OPTIONAL_INT.equals(requiredType.name())
|| DotNames.OPTIONAL_LONG.equals(requiredType.name())
|| DotNames.OPTIONAL_DOUBLE.equals(requiredType.name())
|| DotNames.PROVIDER.equals(requiredType.name())
|| SUPPLIER_NAME.equals(requiredType.name())
|| CONFIG_VALUE_NAME.equals(requiredType.name())
|| MP_CONFIG_VALUE_NAME.equals(requiredType.name())) {
if (DotNames.OPTIONAL.equals(injectedType.name())
|| DotNames.OPTIONAL_INT.equals(injectedType.name())
|| DotNames.OPTIONAL_LONG.equals(injectedType.name())
|| DotNames.OPTIONAL_DOUBLE.equals(injectedType.name())
|| DotNames.PROVIDER.equals(injectedType.name())
|| SUPPLIER_NAME.equals(injectedType.name())
|| CONFIG_VALUE_NAME.equals(injectedType.name())
|| MP_CONFIG_VALUE_NAME.equals(injectedType.name())) {
// Never validate container objects
continue;
}
Expand All @@ -143,7 +143,7 @@ void analyzeConfigPropertyInjectionPoints(BeanDiscoveryFinishedBuildItem beanDis
propertyDefaultValue = defaultValue.asString();
}

configProperties.produce(new ConfigPropertyBuildItem(propertyName, requiredType, propertyDefaultValue));
configProperties.produce(new ConfigPropertyBuildItem(propertyName, injectedType, propertyDefaultValue));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,6 @@ void discoverInjectedGrpcServices(BeanDiscoveryFinishedBuildItem beanDiscovery,
}

Type injectionType = injectionPoint.getRequiredType();

// Programmatic lookup - take the param type
if (DotNames.INSTANCE.equals(injectionType.name()) || DotNames.INJECTABLE_INSTANCE.equals(injectionType.name())) {
injectionType = injectionType.asParameterizedType().arguments().get(0);
}

if (injectionType.name().equals(GrpcDotNames.CHANNEL)) {
// No need to add the stub class for Channel
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@ void registerOptionalClaimProducer(BeanRegistrationPhaseBuildItem beanRegistrati
continue;
}
AnnotationInstance claimQualifier = injectionPoint.getRequiredQualifier(CLAIM_NAME);
if (claimQualifier != null && injectionPoint.getRequiredType().name().equals(DotNames.PROVIDER)) {
if (claimQualifier != null && injectionPoint.getType().name().equals(DotNames.PROVIDER)) {
// Classes from javax.json are handled specially
Type actualType = injectionPoint.getRequiredType().asParameterizedType().arguments().get(0);
Type actualType = injectionPoint.getRequiredType();
if (actualType.name().equals(DotNames.OPTIONAL) && !actualType.name().toString()
.startsWith("javax.json")) {
additionalTypes.add(actualType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ void init(Consumer<BytecodeTransformer> bytecodeTransformerConsumer,
// Instance<Foo>
for (InjectionPointInfo injectionPoint : instanceInjectionPoints) {
if (Beans.hasQualifiers(bean, injectionPoint.getRequiredQualifiers()) && Beans.matchesType(bean,
injectionPoint.getRequiredType().asParameterizedType().arguments().get(0))) {
injectionPoint.getType().asParameterizedType().arguments().get(0))) {
continue test;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ private ResultHandle newInstanceHandle(BeanInfo bean, ClassCreator beanCreator,

// 1. constructor injection points
for (int i = 0; i < injectionPoints.size(); i++) {
paramTypes.add(injectionPoints.get(i).getRequiredType().name().toString());
paramTypes.add(injectionPoints.get(i).getType().name().toString());
paramHandles.add(providerHandles.get(i));
}
// 2. ctx
Expand Down Expand Up @@ -1038,7 +1038,7 @@ private ResultHandle newInstanceHandle(BeanInfo bean, ClassCreator beanCreator,
ResultHandle argsArray = creator.newArray(Object.class, creator.load(providerHandles.size()));
for (int i = 0; i < injectionPoints.size(); i++) {
creator.writeArrayValue(paramTypesArray, i,
creator.loadClass(injectionPoints.get(i).getRequiredType().name().toString()));
creator.loadClass(injectionPoints.get(i).getType().name().toString()));
creator.writeArrayValue(argsArray, i, providerHandles.get(i));
}
registration.registerMethod(constructor);
Expand All @@ -1050,7 +1050,7 @@ private ResultHandle newInstanceHandle(BeanInfo bean, ClassCreator beanCreator,
String[] paramTypes = new String[injectionPoints.size()];
for (ListIterator<InjectionPointInfo> iterator = injectionPoints.listIterator(); iterator.hasNext();) {
InjectionPointInfo injectionPoint = iterator.next();
paramTypes[iterator.previousIndex()] = DescriptorUtils.typeToString(injectionPoint.getRequiredType());
paramTypes[iterator.previousIndex()] = DescriptorUtils.typeToString(injectionPoint.getType());
}
return creator.newInstance(MethodDescriptor.ofConstructor(providerTypeName, paramTypes),
providerHandles.toArray(new ResultHandle[0]));
Expand Down Expand Up @@ -1350,7 +1350,7 @@ void implementCreateForClassBean(ClassOutput classOutput, ClassCreator beanCreat
if (constructorInjection.isPresent()) {
List<String> paramTypes = new ArrayList<>();
for (InjectionPointInfo injectionPoint : constructorInjection.get().injectionPoints) {
paramTypes.add(injectionPoint.getRequiredType().name().toString());
paramTypes.add(injectionPoint.getType().name().toString());
}
ResultHandle[] paramsHandles = new ResultHandle[2];
paramsHandles[0] = create.loadClass(providerType.className());
Expand Down Expand Up @@ -1794,7 +1794,7 @@ private ResultHandle wrapCurrentInjectionPoint(ClassOutput classOutput, ClassCre
Supplier.class, java.lang.reflect.Type.class,
Set.class, Set.class, Member.class, int.class),
constructor.getThis(), constructor.getMethodParam(paramIdx),
Types.getTypeHandle(constructor, injectionPoint.getRequiredType(), tccl),
Types.getTypeHandle(constructor, injectionPoint.getType(), tccl),
requiredQualifiersHandle, annotationsHandle, javaMemberHandle, constructor.load(injectionPoint.getPosition()));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.arc.processor;

import java.util.Collection;
import org.jboss.jandex.DotName;

/**
Expand Down Expand Up @@ -45,6 +46,10 @@ default <T> BeanConfigurator<T> configure(Class<?> beanClass) {
*/
BeanStream beans();

default Collection<InjectionPointInfo> getInjectionPoints() {
return get(BuildExtension.Key.INJECTION_POINTS);
}
mkouba marked this conversation as resolved.
Show resolved Hide resolved

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ static void resolveInjectionPoint(BeanDeployment deployment, InjectionTargetInfo
errors.add(new DefinitionException("EventMetadata can be only injected into an observer method: "
+ injectionPoint.getTargetInfo()));
} else if (BuiltinBean.INSTANCE == builtinBean
&& injectionPoint.getRequiredType().kind() != Kind.PARAMETERIZED_TYPE) {
&& injectionPoint.getType().kind() != Kind.PARAMETERIZED_TYPE) {
errors.add(
new DefinitionException("An injection point of raw type javax.enterprise.inject.Instance is defined: "
+ injectionPoint.getTargetInfo()));
Expand Down Expand Up @@ -510,7 +510,7 @@ static void resolveInjectionPoint(BeanDeployment deployment, InjectionTargetInfo

private static void addStandardErroneousDependencyMessage(InjectionTargetInfo target, InjectionPointInfo injectionPoint,
StringBuilder message) {
message.append(injectionPoint.getRequiredType());
message.append(injectionPoint.getType());
message.append(" and qualifiers ");
message.append(injectionPoint.getRequiredQualifiers());
message.append("\n\t- java member: ");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ enum BuiltinBean {
ResultHandle qualifiers = BeanGenerator.collectInjectionPointQualifiers(ctx.classOutput, ctx.clazzCreator,
ctx.beanDeployment,
ctx.constructor, ctx.injectionPoint, ctx.annotationLiterals);
ResultHandle parameterizedType = Types.getTypeHandle(ctx.constructor, ctx.injectionPoint.getRequiredType());
ResultHandle parameterizedType = Types.getTypeHandle(ctx.constructor, ctx.injectionPoint.getType());
ResultHandle annotationsHandle = BeanGenerator.collectInjectionPointAnnotations(ctx.classOutput, ctx.clazzCreator,
ctx.beanDeployment,
ctx.constructor, ctx.injectionPoint, ctx.annotationLiterals, ctx.injectionPointAnnotationsPredicate);
Expand Down Expand Up @@ -149,7 +149,7 @@ enum BuiltinBean {
}
}
}
ResultHandle parameterizedType = Types.getTypeHandle(ctx.constructor, ctx.injectionPoint.getRequiredType());
ResultHandle parameterizedType = Types.getTypeHandle(ctx.constructor, ctx.injectionPoint.getType());
ResultHandle eventProvider = ctx.constructor.newInstance(
MethodDescriptor.ofConstructor(EventProvider.class, java.lang.reflect.Type.class,
Set.class),
Expand All @@ -175,7 +175,7 @@ enum BuiltinBean {
Types.getPackageName(ctx.clazzCreator.getClassName())));
}
}
ResultHandle parameterizedType = Types.getTypeHandle(ctx.constructor, ctx.injectionPoint.getRequiredType());
ResultHandle parameterizedType = Types.getTypeHandle(ctx.constructor, ctx.injectionPoint.getType());
ResultHandle resourceProvider = ctx.constructor.newInstance(
MethodDescriptor.ofConstructor(ResourceProvider.class, java.lang.reflect.Type.class,
Set.class),
Expand Down Expand Up @@ -283,7 +283,7 @@ private static boolean isCdiAndRawTypeMatches(InjectionPointInfo injectionPoint,
return false;
}
for (DotName rawTypeDotName : rawTypeDotNames) {
if (rawTypeDotName.equals(injectionPoint.getRequiredType().name())) {
if (rawTypeDotName.equals(injectionPoint.getType().name())) {
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,38 @@ InjectionPointKind getKind() {
return kind;
}

/**
* Note that for programmatic lookup, the required type is the type parameter specified at the injection point. For example,
* the required type for an injection point of type {@code Instance<org.acme.Foo>} is {@code org.acme.Foo}.
*
* @return the required type of this injection point
*/
public Type getRequiredType() {
Type requiredType = typeAndQualifiers.type;
if (isProgrammaticLookup() && requiredType.kind() == org.jboss.jandex.Type.Kind.PARAMETERIZED_TYPE) {
requiredType = requiredType.asParameterizedType().arguments().get(0);
}
return requiredType;
}

/**
* This method always returns the original type declared on the injection point, unlike {@link #getRequiredType()}.
*
* @return the type specified at the injection point
*/
public Type getType() {
return typeAndQualifiers.type;
}

/**
* @return <code>true</code> if this injection represents a dynamically obtained instance, <code>false</code> otherwise
*/
public boolean isProgrammaticLookup() {
DotName requiredTypeName = typeAndQualifiers.type.name();
return DotNames.INSTANCE.equals(requiredTypeName) || DotNames.INJECTABLE_INSTANCE.equals(requiredTypeName)
|| DotNames.PROVIDER.equals(requiredTypeName);
}

public Set<AnnotationInstance> getRequiredQualifiers() {
return typeAndQualifiers.qualifiers;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ protected void createConstructor(ClassOutput classOutput, ClassCreator observerC
Supplier.class, java.lang.reflect.Type.class,
Set.class, Set.class, Member.class, int.class),
constructor.loadNull(), delegateSupplier,
Types.getTypeHandle(constructor, injectionPoint.getRequiredType()),
Types.getTypeHandle(constructor, injectionPoint.getType()),
requiredQualifiersHandle, annotationsHandle, javaMemberHandle,
constructor.load(injectionPoint.getPosition()));
ResultHandle wrapSupplierHandle = constructor.newInstance(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ protected FieldDescriptor createConstructor(ClassOutput classOutput, BeanInfo be
Optional<Injection> constructorInjection = bean.getConstructorInjection();
if (constructorInjection.isPresent()) {
for (InjectionPointInfo injectionPoint : constructorInjection.get().injectionPoints) {
parameterTypes.add(injectionPoint.getRequiredType().name().toString());
parameterTypes.add(injectionPoint.getType().name().toString());
}
}
int superParamsSize = parameterTypes.size();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import io.quarkus.arc.processor.BeanDeploymentValidator;
import io.quarkus.arc.processor.BeanInfo;
import io.quarkus.arc.processor.BeanRegistrar;
import io.quarkus.arc.processor.InjectionPointInfo;
import io.quarkus.arc.processor.ObserverInfo;
import io.quarkus.arc.test.ArcTestContainer;
import java.util.Collection;
Expand All @@ -20,6 +21,7 @@
import javax.enterprise.context.Initialized;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import javax.inject.Named;
import org.jboss.jandex.DotName;
Expand Down Expand Up @@ -56,6 +58,11 @@ static class TestValidator implements BeanDeploymentValidator {

@Override
public void validate(ValidationContext context) {
assertTrue(context.getInjectionPoints().stream().filter(InjectionPointInfo::isProgrammaticLookup)
.filter(ip -> ip.getTarget().kind() == org.jboss.jandex.AnnotationTarget.Kind.FIELD
&& ip.getTarget().asField().name().equals("foo"))
.findFirst().isPresent());

assertFalse(context.removedBeans().withBeanClass(UselessBean.class).isEmpty());

assertFalse(context.beans().classBeans().withBeanClass(Alpha.class).isEmpty());
Expand Down Expand Up @@ -88,6 +95,9 @@ static class Alpha {
@Inject
List<String> strings;

@Inject
Instance<String> foo;

void observeAppContextInit(@Observes @Initialized(ApplicationScoped.class) Object event) {
}

Expand Down