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 fixes for spec compatibility, round 9 #33447

Merged
merged 7 commits into from
May 19, 2023
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 @@ -153,6 +153,9 @@ public class BeanDeployment {

this.excludeTypes = builder.excludeTypes != null ? new ArrayList<>(builder.excludeTypes) : Collections.emptyList();

findScopeAnnotations(DotNames.SCOPE, beanDefiningAnnotations);
findScopeAnnotations(DotNames.NORMAL_SCOPE, beanDefiningAnnotations);

qualifierNonbindingMembers = new HashMap<>();
qualifiers = findQualifiers();
for (QualifierRegistrar registrar : builder.qualifierRegistrars) {
Expand Down Expand Up @@ -721,10 +724,33 @@ private void buildContextPut(String key, Object value) {
}

private boolean isRuntimeAnnotationType(ClassInfo annotationType) {
if (!annotationType.isAnnotation()) {
return false;
}
AnnotationInstance retention = annotationType.declaredAnnotation(Retention.class);
return retention != null && "RUNTIME".equals(retention.value().asEnum());
}

// this method finds and registers custom scope annotations prior to registering custom contexts;
// context registration will later overwrite the corresponding entries in the map, which leaves
// custom scope annotations without a context, and that makes no sense _except_ for the CDI TCK
private void findScopeAnnotations(DotName scopeMetaAnnotation,
Map<DotName, BeanDefiningAnnotation> beanDefiningAnnotations) {
for (AnnotationInstance scope : beanArchiveImmutableIndex.getAnnotations(scopeMetaAnnotation)) {
ClassInfo scopeClass = scope.target().asClass();
if (!isRuntimeAnnotationType(scopeClass)) {
continue;
}
if (isExcluded(scopeClass)) {
continue;
}
DotName scopeName = scopeClass.name();
if (BuiltinScope.from(scopeName) == null && !beanDefiningAnnotations.containsKey(scopeName)) {
beanDefiningAnnotations.put(scopeName, new BeanDefiningAnnotation(scopeName));
}
}
}

private Map<DotName, ClassInfo> findQualifiers() {
Map<DotName, ClassInfo> qualifiers = new HashMap<>();
for (AnnotationInstance qualifier : beanArchiveImmutableIndex.getAnnotations(DotNames.QUALIFIER)) {
Expand Down Expand Up @@ -870,7 +896,7 @@ private Map<DotName, StereotypeInfo> findStereotypes(Map<DotName, ClassInfo> int
return stereotypes;
}

private static ScopeInfo getScope(DotName scopeAnnotationName,
private ScopeInfo getScope(DotName scopeAnnotationName,
Map<ScopeInfo, Function<MethodCreator, ResultHandle>> customContexts) {
BuiltinScope builtin = BuiltinScope.from(scopeAnnotationName);
if (builtin != null) {
Expand All @@ -881,6 +907,19 @@ private static ScopeInfo getScope(DotName scopeAnnotationName,
return customScope;
}
}
if (beanDefiningAnnotations.containsKey(scopeAnnotationName)) {
// custom scope annotations without a registered context make no sense,
// but the CDI TCK uses them
ClassInfo clazz = beanArchiveImmutableIndex.getClassByName(scopeAnnotationName);
if (clazz != null) {
boolean inherited = clazz.hasDeclaredAnnotation(DotNames.INHERITED);
if (clazz.hasDeclaredAnnotation(DotNames.SCOPE)) {
return new ScopeInfo(scopeAnnotationName, false, inherited);
} else if (clazz.hasDeclaredAnnotation(DotNames.NORMAL_SCOPE)) {
return new ScopeInfo(scopeAnnotationName, true, inherited);
}
}
}
return null;
}

Expand Down Expand Up @@ -1197,7 +1236,7 @@ private List<BeanInfo> findBeans(Collection<DotName> beanDefiningAnnotations, Li
Type disposedParamType = unusedDisposer.getDisposedParameterType();
boolean matchingProducerBeanExists = false;
scan: for (BeanInfo bean : beans) {
if (bean.isProducerMethod() || bean.isProducerField()) {
if (bean.isProducer()) {
if (!bean.getDeclaringBean().equals(unusedDisposer.getDeclaringBean())) {
continue;
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static io.quarkus.arc.processor.IndexClassLookupUtils.getClassByName;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -190,6 +191,20 @@ public boolean isProducerField() {
return target.isPresent() && Kind.FIELD.equals(target.get().kind());
}

public boolean isProducer() {
return isProducerMethod() || isProducerField();
}

public boolean isStaticProducer() {
if (isProducerField()) {
return Modifier.isStatic(target.get().asField().flags());
} else if (isProducerMethod()) {
return Modifier.isStatic(target.get().asMethod().flags());
} else {
return false;
}
}

public boolean isSynthetic() {
return !target.isPresent();
}
Expand Down Expand Up @@ -532,7 +547,7 @@ public String getTargetPackageName() {
return targetPackageName;
}
DotName providerTypeName;
if (isProducerMethod() || isProducerField()) {
if (isProducer()) {
providerTypeName = declaringBean.getProviderType().name();
} else {
if (providerType.kind() == org.jboss.jandex.Type.Kind.ARRAY
Expand All @@ -551,7 +566,7 @@ public String getTargetPackageName() {
}

public String getClientProxyPackageName() {
if (isProducerField() || isProducerMethod()) {
if (isProducer()) {
AnnotationTarget target = getTarget().get();
DotName typeName = target.kind() == Kind.FIELD ? target.asField().type().name()
: target.asMethod().returnType().name();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public Optional<BeanInfo> findByIdentifier(String id) {
* @return the new stream of producer beans
*/
public BeanStream producers() {
stream = stream.filter(bean -> bean.isProducerField() || bean.isProducerMethod());
stream = stream.filter(BeanInfo::isProducer);
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ private static ScopeInfo inheritScope(ClassInfo beanClass, BeanDeployment beanDe
}
for (AnnotationInstance annotation : beanDeployment.getAnnotationStore().getAnnotations(classFromIndex)) {
ScopeInfo scopeAnnotation = beanDeployment.getScope(annotation.name());
if (scopeAnnotation != null && scopeAnnotation.declaresInherited()) {
// found some scope, return
return scopeAnnotation;
if (scopeAnnotation != null) {
// found some scope, return it if it's inherited
// if it isn't inherited, it still prevents the bean class
// from inheriting another scope from a further superclass
return scopeAnnotation.declaresInherited() ? scopeAnnotation : null;
}
}
superClassName = classFromIndex.superName();
Expand Down Expand Up @@ -787,7 +789,7 @@ static void validateBean(BeanInfo bean, List<Throwable> errors, Consumer<Bytecod
}
}

} else if (bean.isProducerField() || bean.isProducerMethod()) {
} else if (bean.isProducer()) {
String methodOrField = bean.isProducerMethod() ? "method" : "field";
String classifier = "Producer " + methodOrField + " for a normal scoped bean";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static io.quarkus.arc.processor.IndexClassLookupUtils.getClassByName;

import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;
import java.util.function.BiPredicate;
Expand Down Expand Up @@ -190,17 +189,15 @@ private static boolean cdiAndRawTypeMatches(InjectionPointInfo injectionPoint, D
}

private static void generateInstanceBytecode(GeneratorContext ctx) {
ResultHandle qualifiers = BeanGenerator.collectInjectionPointQualifiers(ctx.classOutput, ctx.clazzCreator,
ResultHandle qualifiers = BeanGenerator.collectInjectionPointQualifiers(
ctx.beanDeployment,
ctx.constructor, ctx.injectionPoint, ctx.annotationLiterals);
ResultHandle parameterizedType = Types.getTypeHandle(ctx.constructor, ctx.injectionPoint.getType());
ResultHandle annotationsHandle = BeanGenerator.collectInjectionPointAnnotations(ctx.classOutput, ctx.clazzCreator,
ResultHandle annotationsHandle = BeanGenerator.collectInjectionPointAnnotations(
ctx.beanDeployment,
ctx.constructor, ctx.injectionPoint, ctx.annotationLiterals, ctx.injectionPointAnnotationsPredicate);
ResultHandle javaMemberHandle = BeanGenerator.getJavaMemberHandle(ctx.constructor, ctx.injectionPoint,
ctx.reflectionRegistration);
boolean isTransient = ctx.injectionPoint.isField()
&& Modifier.isTransient(ctx.injectionPoint.getTarget().asField().flags());
ResultHandle beanHandle;
switch (ctx.targetInfo.kind()) {
case OBSERVER:
Expand All @@ -219,7 +216,7 @@ private static void generateInstanceBytecode(GeneratorContext ctx) {
InjectableBean.class, Set.class, Member.class, int.class, boolean.class),
parameterizedType, qualifiers, beanHandle, annotationsHandle, javaMemberHandle,
ctx.constructor.load(ctx.injectionPoint.getPosition()),
ctx.constructor.load(isTransient));
ctx.constructor.load(ctx.injectionPoint.isTransient()));
ResultHandle instanceProviderSupplier = ctx.constructor.newInstance(
MethodDescriptors.FIXED_VALUE_SUPPLIER_CONSTRUCTOR, instanceProvider);
ctx.constructor.writeInstanceField(
Expand Down Expand Up @@ -248,13 +245,11 @@ private static void generateEventBytecode(GeneratorContext ctx) {
}
}
ResultHandle parameterizedType = Types.getTypeHandle(ctx.constructor, ctx.injectionPoint.getType());
ResultHandle annotations = BeanGenerator.collectInjectionPointAnnotations(ctx.classOutput, ctx.clazzCreator,
ResultHandle annotations = BeanGenerator.collectInjectionPointAnnotations(
ctx.beanDeployment,
ctx.constructor, ctx.injectionPoint, ctx.annotationLiterals, ctx.injectionPointAnnotationsPredicate);
ResultHandle javaMember = BeanGenerator.getJavaMemberHandle(ctx.constructor, ctx.injectionPoint,
ctx.reflectionRegistration);
boolean isTransient = ctx.injectionPoint.isField()
&& Modifier.isTransient(ctx.injectionPoint.getTarget().asField().flags());
ResultHandle bean;
switch (ctx.targetInfo.kind()) {
case OBSERVER:
Expand All @@ -272,7 +267,7 @@ private static void generateEventBytecode(GeneratorContext ctx) {
ResultHandle injectionPoint = ctx.constructor.newInstance(MethodDescriptors.INJECTION_POINT_IMPL_CONSTRUCTOR,
parameterizedType, parameterizedType, qualifiers, bean, annotations, javaMember,
ctx.constructor.load(ctx.injectionPoint.getPosition()),
ctx.constructor.load(isTransient));
ctx.constructor.load(ctx.injectionPoint.isTransient()));

ResultHandle eventProvider = ctx.constructor.newInstance(
MethodDescriptor.ofConstructor(EventProvider.class, java.lang.reflect.Type.class,
Expand Down Expand Up @@ -395,16 +390,14 @@ private static void generateListBytecode(GeneratorContext ctx) {
usesInstanceHandle = mc.load(false);
}

ResultHandle qualifiers = BeanGenerator.collectInjectionPointQualifiers(ctx.classOutput, ctx.clazzCreator,
ResultHandle qualifiers = BeanGenerator.collectInjectionPointQualifiers(
ctx.beanDeployment,
ctx.constructor, ctx.injectionPoint, ctx.annotationLiterals);
ResultHandle annotationsHandle = BeanGenerator.collectInjectionPointAnnotations(ctx.classOutput, ctx.clazzCreator,
ResultHandle annotationsHandle = BeanGenerator.collectInjectionPointAnnotations(
ctx.beanDeployment,
ctx.constructor, ctx.injectionPoint, ctx.annotationLiterals, ctx.injectionPointAnnotationsPredicate);
ResultHandle javaMemberHandle = BeanGenerator.getJavaMemberHandle(ctx.constructor, ctx.injectionPoint,
ctx.reflectionRegistration);
boolean isTransient = ctx.injectionPoint.isField()
&& Modifier.isTransient(ctx.injectionPoint.getTarget().asField().flags());
ResultHandle beanHandle;
switch (ctx.targetInfo.kind()) {
case OBSERVER:
Expand All @@ -424,7 +417,7 @@ private static void generateListBytecode(GeneratorContext ctx) {
InjectableBean.class, Set.class, Member.class, int.class, boolean.class, boolean.class),
requiredType, injectionPointType, qualifiers, beanHandle, annotationsHandle, javaMemberHandle,
ctx.constructor.load(ctx.injectionPoint.getPosition()),
ctx.constructor.load(isTransient), usesInstanceHandle);
ctx.constructor.load(ctx.injectionPoint.isTransient()), usesInstanceHandle);
ResultHandle listProviderSupplier = ctx.constructor.newInstance(
MethodDescriptors.FIXED_VALUE_SUPPLIER_CONSTRUCTOR, listProvider);
ctx.constructor.writeInstanceField(
Expand Down
Loading