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

Arc - improve injection point transformation API #40841

Merged
merged 3 commits into from
Jun 6, 2024
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 @@ -14,7 +14,7 @@
import static org.jboss.jandex.AnnotationInstance.create;
import static org.jboss.jandex.AnnotationTarget.Kind.CLASS;
import static org.jboss.jandex.AnnotationTarget.Kind.FIELD;
import static org.jboss.jandex.AnnotationTarget.Kind.METHOD;
import static org.jboss.jandex.AnnotationTarget.Kind.METHOD_PARAMETER;
import static org.jboss.jandex.AnnotationValue.createStringValue;

import java.util.ArrayList;
Expand Down Expand Up @@ -42,6 +42,7 @@
import org.jboss.jandex.DotName;
import org.jboss.jandex.FieldInfo;
import org.jboss.jandex.MethodInfo;
import org.jboss.jandex.MethodParameterInfo;
import org.jboss.jandex.Type;
import org.jboss.jandex.Type.Kind;

Expand Down Expand Up @@ -174,12 +175,12 @@ void configPropertyInjectionPoints(
} else {
// org.acme.Foo.config
if (injectionPoint.isField()) {
FieldInfo field = injectionPoint.getTarget().asField();
FieldInfo field = injectionPoint.getAnnotationTarget().asField();
propertyName = getPropertyName(field.name(), field.declaringClass());
} else if (injectionPoint.isParam()) {
MethodInfo method = injectionPoint.getTarget().asMethod();
propertyName = getPropertyName(method.parameterName(injectionPoint.getPosition()),
method.declaringClass());
MethodParameterInfo methodParameterInfo = injectionPoint.getAnnotationTarget().asMethodParameter();
propertyName = getPropertyName(methodParameterInfo.name(),
methodParameterInfo.method().declaringClass());
} else {
throw new IllegalStateException("Unsupported injection point target: " + injectionPoint);
}
Expand All @@ -205,8 +206,8 @@ void configPropertyInjectionPoints(
propertyDefaultValue = defaultValue.asString();
}

if (injectionPoint.getTarget().kind().equals(METHOD)
&& observerMethods.contains(injectionPoint.getTarget().asMethod())) {
if (injectionPoint.getAnnotationTarget().kind().equals(METHOD_PARAMETER)
&& observerMethods.contains(injectionPoint.getAnnotationTarget().asMethodParameter().method())) {
configProperties
.produce(ConfigPropertyBuildItem.staticInit(propertyName, injectedType, propertyDefaultValue));
}
Expand Down Expand Up @@ -405,19 +406,17 @@ void validateConfigMappingsInjectionPoints(
Type type = Type.create(injectionPoint.getRequiredType().name(), Type.Kind.CLASS);
ConfigClassBuildItem configClass = configMappingTypes.get(type);
if (configClass != null) {
AnnotationTarget target = injectionPoint.getTarget();
AnnotationTarget target = injectionPoint.getAnnotationTarget();
AnnotationInstance mapping = null;
if (target.kind().equals(FIELD)) {
mapping = target.asField().annotation(CONFIG_MAPPING_NAME);
} else if (target.kind().equals(METHOD)) {
List<Type> parameters = target.asMethod().parameterTypes();
for (int i = 0; i < parameters.size(); i++) {
Type parameter = parameters.get(i);
if (parameter.name().equals(type.name())) {
Set<AnnotationInstance> parameterAnnotations = getParameterAnnotations(
validationPhase.getBeanProcessor().getBeanDeployment(), target.asMethod(), i);
mapping = Annotations.find(parameterAnnotations, CONFIG_MAPPING_NAME);
}
} else if (target.kind().equals(METHOD_PARAMETER)) {
MethodParameterInfo methodParameterInfo = target.asMethodParameter();
if (methodParameterInfo.type().name().equals(type.name())) {
Set<AnnotationInstance> parameterAnnotations = getParameterAnnotations(
validationPhase.getBeanProcessor().getBeanDeployment(),
target.asMethodParameter().method(), methodParameterInfo.position());
mapping = Annotations.find(parameterAnnotations, CONFIG_MAPPING_NAME);
}
}

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

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Function;

Expand All @@ -27,19 +28,27 @@ public final class TransformedAnnotationsBuildItem extends SimpleBuildItem
}

public Collection<AnnotationInstance> getAnnotations(AnnotationTarget target) {
return beanDeployment.getAnnotations(target);
return queryAndConditionallyFilter(target);
}

public AnnotationInstance getAnnotation(AnnotationTarget target, DotName annotationName) {
return beanDeployment.getAnnotation(target, annotationName);
if (target.kind().equals(AnnotationTarget.Kind.METHOD_PARAMETER)) {
return queryForMethodParam(target, annotationName);
} else {
return beanDeployment.getAnnotation(target, annotationName);
}
}

public AnnotationInstance getAnnotation(AnnotationTarget target, Class<? extends Annotation> annotationClass) {
return getAnnotation(target, DotName.createSimple(annotationClass));
}

public boolean hasAnnotation(AnnotationTarget target, DotName annotationName) {
return beanDeployment.hasAnnotation(target, annotationName);
if (target.kind().equals(AnnotationTarget.Kind.METHOD_PARAMETER)) {
return queryForMethodParam(target, annotationName) != null;
} else {
return beanDeployment.hasAnnotation(target, annotationName);
}
}

public boolean hasAnnotation(AnnotationTarget target, Class<? extends Annotation> annotationClass) {
Expand All @@ -48,7 +57,40 @@ public boolean hasAnnotation(AnnotationTarget target, Class<? extends Annotation

@Override
public Collection<AnnotationInstance> apply(AnnotationTarget target) {
return beanDeployment.getAnnotations(target);
return queryAndConditionallyFilter(target);
}

private Collection<AnnotationInstance> queryAndConditionallyFilter(AnnotationTarget target) {
if (target.kind().equals(AnnotationTarget.Kind.METHOD_PARAMETER)) {
// We cannot query Jandex for method param. annotation target, so we operate on the whole method
// and filter results accordingly
Collection<AnnotationInstance> result = new ArrayList<>();
for (AnnotationInstance instance : beanDeployment.getAnnotations(target.asMethodParameter().method())) {
if (instance.target().kind().equals(AnnotationTarget.Kind.METHOD_PARAMETER)
&& instance.target().asMethodParameter().position() == target.asMethodParameter().position()) {
result.add(instance);
}
}
return result;
} else {
return beanDeployment.getAnnotations(target);
}
}

private AnnotationInstance queryForMethodParam(AnnotationTarget target, DotName annotationName) {
if (!target.kind().equals(AnnotationTarget.Kind.METHOD_PARAMETER)) {
throw new IllegalArgumentException(
"TransformedAnnotationsBuildItem#queryForMethodParam needs to operate on METHOD_PARAMETER AnnotationTarget");
}
// We cannot query Jandex for method param. annotation target, so we operate on the whole method
// and filter results accordingly
for (AnnotationInstance instance : beanDeployment.getAnnotations(target.asMethodParameter().method())) {
if (instance.name().equals(annotationName)
&& instance.target().kind().equals(AnnotationTarget.Kind.METHOD_PARAMETER)
&& instance.target().asMethodParameter().position() == target.asMethodParameter().position()) {
return instance;
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -346,21 +346,17 @@ public void transform(TransformationContext ctx) {
AnnotationInstance clientAnnotation = Annotations.find(ctx.getQualifiers(), GrpcDotNames.GRPC_CLIENT);
if (clientAnnotation != null && clientAnnotation.value() == null) {
String clientName = null;
AnnotationTarget annotationTarget = ctx.getTarget();
if (ctx.getTarget().kind() == Kind.FIELD) {
AnnotationTarget annotationTarget = ctx.getAnnotationTarget();
if (ctx.getAnnotationTarget().kind() == Kind.FIELD) {
clientName = clientAnnotation.target().asField().name();
} else if (ctx.getTarget().kind() == Kind.METHOD
&& clientAnnotation.target().kind().equals(Kind.METHOD_PARAMETER)) {
} else if (annotationTarget.kind() == Kind.METHOD_PARAMETER) {
MethodParameterInfo param = clientAnnotation.target().asMethodParameter();
annotationTarget = param;
// We don't need to check if parameter names are recorded - that's validated elsewhere
clientName = param.method().parameterName(param.position());
}
if (clientName != null) {
ctx.transform().remove(GrpcDotNames::isGrpcClient)
.add(AnnotationInstance.builder(GrpcDotNames.GRPC_CLIENT)
.value(clientName)
.buildWithTarget(annotationTarget))
.add(AnnotationInstance.builder(GrpcDotNames.GRPC_CLIENT).value(clientName).build())
.done();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3341,10 +3341,10 @@ static void collectNamespaceExpressions(Expression expression, Set<Expression> n

public static String getName(InjectionPointInfo injectionPoint) {
if (injectionPoint.isField()) {
return injectionPoint.getTarget().asField().name();
return injectionPoint.getAnnotationTarget().asField().name();
} else if (injectionPoint.isParam()) {
String name = injectionPoint.getTarget().asMethod().parameterName(injectionPoint.getPosition());
return name == null ? injectionPoint.getTarget().asMethod().name() : name;
String name = injectionPoint.getAnnotationTarget().asMethodParameter().name();
return name == null ? injectionPoint.getAnnotationTarget().asMethodParameter().method().name() : name;
}
throw new IllegalArgumentException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ public boolean appliesTo(Type requiredType) {
}

public void transform(TransformationContext context) {
if (context.getTarget().kind() == AnnotationTarget.Kind.FIELD) {
var declaringClassName = context.getTarget().asField().declaringClass().name();
if (context.getAnnotationTarget().kind() == AnnotationTarget.Kind.FIELD) {
var declaringClassName = context.getAnnotationTarget().asField().declaringClass().name();
if (JPA_IDENTITY_PROVIDER_NAME.equals(declaringClassName)
|| JPA_TRUSTED_IDENTITY_PROVIDER_NAME.equals(declaringClassName)) {
context.transform()
Expand Down
Loading
Loading