Skip to content

Commit

Permalink
Merge pull request #20353 from mkouba/arc-immutable-sets
Browse files Browse the repository at this point in the history
ArC - replace Collections.unmodifiableSet() with JDK immutable set
  • Loading branch information
mkouba authored Sep 23, 2021
2 parents 6f5f907 + c802ed3 commit 4ae3d96
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -705,62 +705,60 @@ protected MethodCreator initConstructor(ClassOutput classOutput, ClassCreator be
}

// Bean types
ResultHandle typesHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
ResultHandle typesArray = constructor.newArray(Object.class, bean.getTypes().size());
int typeIndex = 0;
for (org.jboss.jandex.Type type : bean.getTypes()) {
ResultHandle typeHandle;
try {
typeHandle = Types.getTypeHandle(constructor, type, tccl);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("Unable to construct the type handle for " + bean + ": " + e.getMessage());
}
constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, typesHandle, typeHandle);
constructor.writeArrayValue(typesArray, constructor.load(typeIndex++), typeHandle);
}
ResultHandle unmodifiableTypesHandle = constructor.invokeStaticMethod(MethodDescriptors.COLLECTIONS_UNMODIFIABLE_SET,
typesHandle);
constructor.writeInstanceField(
FieldDescriptor.of(beanCreator.getClassName(), FIELD_NAME_BEAN_TYPES, Set.class.getName()),
constructor.getThis(),
unmodifiableTypesHandle);
constructor.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF,
typesArray));

// Qualifiers
if (!bean.getQualifiers().isEmpty() && !bean.hasDefaultQualifiers()) {

ResultHandle qualifiersHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));

ResultHandle qualifiersArray = constructor.newArray(Object.class, bean.getQualifiers().size());
int qualifierIndex = 0;
for (AnnotationInstance qualifierAnnotation : bean.getQualifiers()) {
BuiltinQualifier qualifier = BuiltinQualifier.of(qualifierAnnotation);
if (qualifier != null) {
constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiersHandle,
constructor.writeArrayValue(qualifiersArray, constructor.load(qualifierIndex++),
qualifier.getLiteralInstance(constructor));
} else {
// Create annotation literal first
// Create the annotation literal first
ClassInfo qualifierClass = bean.getDeployment().getQualifier(qualifierAnnotation.name());
constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiersHandle,
constructor.writeArrayValue(qualifiersArray, constructor.load(qualifierIndex++),
annotationLiterals.process(constructor, classOutput,
qualifierClass, qualifierAnnotation, Types.getPackageName(beanCreator.getClassName())));
}
}
ResultHandle unmodifiableQualifiersHandle = constructor
.invokeStaticMethod(MethodDescriptors.COLLECTIONS_UNMODIFIABLE_SET, qualifiersHandle);
constructor.writeInstanceField(
FieldDescriptor.of(beanCreator.getClassName(), FIELD_NAME_QUALIFIERS, Set.class.getName()),
constructor.getThis(),
unmodifiableQualifiersHandle);
constructor.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF,
qualifiersArray));
}

// Stereotypes
if (!bean.getStereotypes().isEmpty()) {
ResultHandle stereotypesHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
ResultHandle stereotypesArray = constructor.newArray(Object.class, bean.getStereotypes().size());
int stereotypesIndex = 0;
for (StereotypeInfo stereotype : bean.getStereotypes()) {
constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, stereotypesHandle,
constructor.writeArrayValue(stereotypesArray, constructor.load(stereotypesIndex++),
constructor.loadClass(stereotype.getTarget().name().toString()));
}
ResultHandle unmodifiableStereotypesHandle = constructor
.invokeStaticMethod(MethodDescriptors.COLLECTIONS_UNMODIFIABLE_SET, stereotypesHandle);
constructor.writeInstanceField(
FieldDescriptor.of(beanCreator.getClassName(), FIELD_NAME_STEREOTYPES, Set.class.getName()),
constructor.getThis(),
unmodifiableStereotypesHandle);
constructor.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF,
stereotypesArray));
}
return constructor;
}
Expand Down Expand Up @@ -1391,18 +1389,20 @@ void implementCreateForClassBean(ClassOutput classOutput, ClassCreator beanCreat
funcBytecode.returnValue(retHandle);

// Interceptor bindings
ResultHandle bindingsHandle = create.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
ResultHandle bindingsArray = create.newArray(Object.class, aroundConstructs.bindings.size());
int bindingsIndex = 0;
for (AnnotationInstance binding : aroundConstructs.bindings) {
// Create annotation literals first
ClassInfo bindingClass = bean.getDeployment().getInterceptorBinding(binding.name());
create.invokeInterfaceMethod(MethodDescriptors.SET_ADD, bindingsHandle,
create.writeArrayValue(bindingsArray, bindingsIndex++,
annotationLiterals.process(create, classOutput, bindingClass, binding,
Types.getPackageName(beanCreator.getClassName())));
}

ResultHandle invocationContextHandle = create.invokeStaticMethod(
MethodDescriptors.INVOCATION_CONTEXTS_AROUND_CONSTRUCT, constructorHandle,
aroundConstructsHandle, func.getInstance(), bindingsHandle);
aroundConstructsHandle, func.getInstance(),
create.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF, bindingsArray));
TryBlock tryCatch = create.tryBlock();
CatchBlockCreator exceptionCatch = tryCatch.addCatch(Exception.class);
// throw new RuntimeException(e)
Expand Down Expand Up @@ -1520,19 +1520,21 @@ void implementCreateForClassBean(ClassOutput classOutput, ClassCreator beanCreat
if (!postConstructs.isEmpty()) {

// Interceptor bindings
ResultHandle bindingsHandle = create.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
ResultHandle bindingsArray = create.newArray(Object.class, postConstructs.bindings.size());
int bindingsIndex = 0;
for (AnnotationInstance binding : postConstructs.bindings) {
// Create annotation literals first
ClassInfo bindingClass = bean.getDeployment().getInterceptorBinding(binding.name());
create.invokeInterfaceMethod(MethodDescriptors.SET_ADD, bindingsHandle,
create.writeArrayValue(bindingsArray, bindingsIndex++,
annotationLiterals.process(create, classOutput, bindingClass, binding,
Types.getPackageName(beanCreator.getClassName())));

}

// InvocationContextImpl.postConstruct(instance,postConstructs).proceed()
ResultHandle invocationContextHandle = create.invokeStaticMethod(
MethodDescriptors.INVOCATION_CONTEXTS_POST_CONSTRUCT, instanceHandle,
postConstructsHandle, bindingsHandle);
postConstructsHandle, create.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF, bindingsArray));

TryBlock tryCatch = create.tryBlock();
CatchBlockCreator exceptionCatch = tryCatch.addCatch(Exception.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ public final class MethodDescriptors {
public static final MethodDescriptor COLLECTIONS_EMPTY_MAP = MethodDescriptor.ofMethod(Collections.class, "emptyMap",
Map.class);

public static final MethodDescriptor SET_OF = MethodDescriptor.ofMethod(Set.class, "of", Set.class, Object[].class);

public static final MethodDescriptor ARC_CONTAINER = MethodDescriptor.ofMethod(Arc.class, "container", ArcContainer.class);

public static final MethodDescriptor ARC_CONTAINER_BEAN = MethodDescriptor.ofMethod(ArcContainer.class, "bean",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -548,29 +547,28 @@ protected void createConstructor(ClassOutput classOutput, ClassCreator observerC
Set<AnnotationInstance> qualifiers = observer.getQualifiers();
if (!qualifiers.isEmpty()) {

ResultHandle qualifiersHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
ResultHandle qualifiersArray = constructor.newArray(Object.class, qualifiers.size());
int qualifiersIndex = 0;

for (AnnotationInstance qualifierAnnotation : qualifiers) {
BuiltinQualifier qualifier = BuiltinQualifier.of(qualifierAnnotation);
if (qualifier != null) {
constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiersHandle,
constructor.writeArrayValue(qualifiersArray, constructor.load(qualifiersIndex++),
qualifier.getLiteralInstance(constructor));
} else {
// Create annotation literal first
ClassInfo qualifierClass = observer.getBeanDeployment()
.getQualifier(qualifierAnnotation.name());
constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, qualifiersHandle,
constructor.writeArrayValue(qualifiersArray, constructor.load(qualifiersIndex++),
annotationLiterals.process(constructor, classOutput,
qualifierClass, qualifierAnnotation, Types.getPackageName(observerCreator.getClassName())));
}
}
ResultHandle unmodifiableQualifiersHandle = constructor
.invokeStaticMethod(MethodDescriptor.ofMethod(Collections.class, "unmodifiableSet", Set.class, Set.class),
qualifiersHandle);
constructor.writeInstanceField(
FieldDescriptor.of(observerCreator.getClassName(), "qualifiers", Set.class.getName()),
constructor.getThis(),
unmodifiableQualifiersHandle);
constructor.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF,
qualifiersArray));
}

if (mockable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,13 @@ public ResultHandle apply(List<BindingKey> keys) {
return constructor.invokeStaticMethod(MethodDescriptors.COLLECTIONS_SINGLETON,
bindingsLiterals.computeIfAbsent(keys.iterator().next(), bindingsLiteralFun));
} else {
ResultHandle bindingsHandle = constructor.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
ResultHandle bindingsArray = constructor.newArray(Object.class, keys.size());
int bindingsIndex = 0;
for (BindingKey binding : keys) {
constructor.invokeInterfaceMethod(MethodDescriptors.SET_ADD, bindingsHandle,
constructor.writeArrayValue(bindingsArray, bindingsIndex++,
bindingsLiterals.computeIfAbsent(binding, bindingsLiteralFun));
}
return bindingsHandle;
return constructor.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF, bindingsArray);
}
}
};
Expand Down Expand Up @@ -790,11 +791,13 @@ protected void createDestroy(ClassOutput classOutput, BeanInfo bean, ClassCreato
ResultHandle predestroysHandle = destroy.readInstanceField(preDestroysField, destroy.getThis());

// Interceptor bindings
ResultHandle bindingsHandle = destroy.newInstance(MethodDescriptor.ofConstructor(HashSet.class));
for (AnnotationInstance binding : bean.getLifecycleInterceptors(InterceptionType.PRE_DESTROY).bindings) {
InterceptionInfo preDestroy = bean.getLifecycleInterceptors(InterceptionType.PRE_DESTROY);
ResultHandle bindingsArray = destroy.newArray(Object.class, preDestroy.bindings.size());
int bindingsIndex = 0;
for (AnnotationInstance binding : preDestroy.bindings) {
// Create annotation literals first
ClassInfo bindingClass = bean.getDeployment().getInterceptorBinding(binding.name());
destroy.invokeInterfaceMethod(MethodDescriptors.SET_ADD, bindingsHandle,
destroy.writeArrayValue(bindingsArray, bindingsIndex++,
annotationLiterals.process(destroy, classOutput, bindingClass, binding,
Types.getPackageName(subclass.getClassName())));
}
Expand All @@ -809,7 +812,7 @@ protected void createDestroy(ClassOutput classOutput, BeanInfo bean, ClassCreato
// InvocationContextImpl.preDestroy(this,predestroys)
ResultHandle invocationContext = tryCatch.invokeStaticMethod(MethodDescriptors.INVOCATION_CONTEXTS_PRE_DESTROY,
tryCatch.getThis(), predestroysHandle,
bindingsHandle);
tryCatch.invokeStaticInterfaceMethod(MethodDescriptors.SET_OF, bindingsArray));

// InvocationContext.proceed()
tryCatch.invokeInterfaceMethod(MethodDescriptors.INVOCATION_CONTEXT_PROCEED, invocationContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -36,7 +35,7 @@ protected AbstractInvocationContext(Object target, Method method,
this.constructor = constructor;
this.parameters = parameters != null ? parameters : EMPTY_PARAMS;
this.contextData = contextData != null ? contextData : new LazyValue<>(this);
this.interceptorBindings = Collections.unmodifiableSet(interceptorBindings);
this.interceptorBindings = interceptorBindings;
this.chain = chain;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.enterprise.inject.Any;
Expand All @@ -17,7 +16,7 @@

public final class Qualifiers {

public static final Set<Annotation> DEFAULT_QUALIFIERS = initDefaultQualifiers();
public static final Set<Annotation> DEFAULT_QUALIFIERS = Set.of(Default.Literal.INSTANCE, Any.Literal.INSTANCE);

public static final Set<Annotation> IP_DEFAULT_QUALIFIERS = Collections.singleton(Default.Literal.INSTANCE);

Expand Down Expand Up @@ -115,13 +114,6 @@ static boolean isSubset(Set<Annotation> observedQualifiers, Set<Annotation> even
return true;
}

private static Set<Annotation> initDefaultQualifiers() {
Set<Annotation> qualifiers = new HashSet<>();
qualifiers.add(Default.Literal.INSTANCE);
qualifiers.add(Any.Literal.INSTANCE);
return Collections.unmodifiableSet(qualifiers);
}

private static Object invoke(Method method, Object instance) {
try {
if (!method.isAccessible()) {
Expand Down

0 comments on commit 4ae3d96

Please sign in to comment.