From a2142d58f17e5fa882864a7ad30579aed13274a3 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Wed, 4 May 2022 16:49:42 +0200 Subject: [PATCH] ArC - resolve type variables for inherited observer methods - resolves #25364 --- .../quarkus/arc/processor/ObserverInfo.java | 15 +++- .../ObserverInheritanceTypeVariableTest.java | 85 +++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/observers/inheritance/typevariable/ObserverInheritanceTypeVariableTest.java diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverInfo.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverInfo.java index 781377bafa4d4..6374e4c0b80c1 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverInfo.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/ObserverInfo.java @@ -8,9 +8,11 @@ import io.quarkus.arc.processor.ObserverTransformer.TransformationContext; import io.quarkus.gizmo.MethodCreator; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.ListIterator; +import java.util.Map; import java.util.Set; import java.util.function.Consumer; import javax.enterprise.event.Reception; @@ -25,6 +27,7 @@ import org.jboss.jandex.MethodInfo; import org.jboss.jandex.MethodParameterInfo; import org.jboss.jandex.Type; +import org.jboss.jandex.TypeVariable; import org.jboss.logging.Logger; /** @@ -48,10 +51,20 @@ static ObserverInfo create(BeanInfo declaringBean, MethodInfo observerMethod, In } else { priority = ObserverMethod.DEFAULT_PRIORITY; } + + Type observedType = observerMethod.parameters().get(eventParameter.position()); + if (Types.containsTypeVariable(observedType)) { + Map resolvedTypeVariables = Types + .resolvedTypeVariables(declaringBean.getImplClazz(), declaringBean.getDeployment()) + .getOrDefault(observerMethod.declaringClass(), Collections.emptyMap()); + observedType = Types.resolveTypeParam(observedType, resolvedTypeVariables, + declaringBean.getDeployment().getBeanArchiveIndex()); + } + return create(null, declaringBean.getDeployment(), declaringBean.getTarget().get().asClass().name(), declaringBean, observerMethod, injection, eventParameter, - observerMethod.parameters().get(eventParameter.position()), + observedType, initQualifiers(declaringBean.getDeployment(), observerMethod, eventParameter), initReception(isAsync, declaringBean.getDeployment(), observerMethod), initTransactionPhase(isAsync, declaringBean.getDeployment(), observerMethod), isAsync, priority, transformers, diff --git a/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/observers/inheritance/typevariable/ObserverInheritanceTypeVariableTest.java b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/observers/inheritance/typevariable/ObserverInheritanceTypeVariableTest.java new file mode 100644 index 0000000000000..42151cdc53ea2 --- /dev/null +++ b/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/observers/inheritance/typevariable/ObserverInheritanceTypeVariableTest.java @@ -0,0 +1,85 @@ +package io.quarkus.arc.test.observers.inheritance.typevariable; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +import io.quarkus.arc.Arc; +import io.quarkus.arc.Unremovable; +import io.quarkus.arc.test.ArcTestContainer; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.Dependent; +import javax.enterprise.event.Event; +import javax.enterprise.event.Observes; +import javax.inject.Inject; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +/** + * https://github.com/quarkusio/quarkus/issues/25364 + */ +public class ObserverInheritanceTypeVariableTest { + + @RegisterExtension + public ArcTestContainer container = new ArcTestContainer(MyEvent.class, MyAEvent.class, MyBEvent.class, MyAService.class, + MyBService.class, EventSource.class); + + @Test + public void testNotification() { + Arc.container().instance(EventSource.class).get().sendA(); + assertNotNull(MyAService.event); + assertNull(MyBService.event); + } + + static class MyEvent { + } + + static class MyAEvent extends MyEvent { + } + + static class MyBEvent extends MyEvent { + } + + static abstract class AbstractService { + + void onEvent(@Observes E myEvent) { + doSomething(myEvent); + } + + abstract void doSomething(E myEvent); + } + + @ApplicationScoped + static class MyAService extends AbstractService { + + static volatile MyAEvent event; + + @Override + protected void doSomething(MyAEvent myEvent) { + MyAService.event = myEvent; + } + } + + @ApplicationScoped + static class MyBService extends AbstractService { + + static volatile MyBEvent event; + + @Override + void doSomething(MyBEvent myEvent) { + MyBService.event = myEvent; + } + } + + @Unremovable + @Dependent + static class EventSource { + + @Inject + Event event; + + void sendA() { + event.fire(new MyAEvent()); + } + } + +}