Skip to content

Commit

Permalink
Merge pull request quarkusio#8866 from stuartwdouglas/arc-generation
Browse files Browse the repository at this point in the history
Don't generate ArC beans for platform beans that have already been de…
  • Loading branch information
mkouba authored Apr 28, 2020
2 parents f669f89 + 758e823 commit 78405ae
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import io.quarkus.deployment.builditem.GeneratedClassBuildItem;
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.builditem.LiveReloadBuildItem;
import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
import io.quarkus.deployment.builditem.TestClassPredicateBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
Expand Down Expand Up @@ -371,6 +372,7 @@ public BeanContainerBuildItem generateResources(ArcRecorder recorder, ShutdownCo
BuildProducer<ReflectiveMethodBuildItem> reflectiveMethods,
BuildProducer<ReflectiveFieldBuildItem> reflectiveFields,
BuildProducer<GeneratedClassBuildItem> generatedClass,
LiveReloadBuildItem liveReloadBuildItem,
BuildProducer<GeneratedResourceBuildItem> generatedResource) throws Exception {

for (ValidationErrorBuildItem validationError : validationErrors) {
Expand All @@ -381,6 +383,11 @@ public BeanContainerBuildItem generateResources(ArcRecorder recorder, ShutdownCo

BeanProcessor beanProcessor = validationPhase.getBeanProcessor();
beanProcessor.processValidationErrors(validationPhase.getContext());
ExistingClasses existingClasses = liveReloadBuildItem.getContextObject(ExistingClasses.class);
if (existingClasses == null) {
existingClasses = new ExistingClasses();
liveReloadBuildItem.setContextObject(ExistingClasses.class, existingClasses);
}

long start = System.currentTimeMillis();
List<ResourceOutput.Resource> resources = beanProcessor.generateResources(new ReflectionRegistration() {
Expand All @@ -393,14 +400,17 @@ public void registerMethod(MethodInfo methodInfo) {
public void registerField(FieldInfo fieldInfo) {
reflectiveFields.produce(new ReflectiveFieldBuildItem(fieldInfo));
}
});
}, existingClasses.existingClasses);
for (ResourceOutput.Resource resource : resources) {
switch (resource.getType()) {
case JAVA_CLASS:
LOGGER.debugf("Add %s class: %s", (resource.isApplicationClass() ? "APP" : "FWK"),
resource.getFullyQualifiedName());
generatedClass.produce(new GeneratedClassBuildItem(resource.isApplicationClass(), resource.getName(),
resource.getData(), resource.getSource()));
if (!resource.isApplicationClass()) {
existingClasses.existingClasses.add(resource.getName());
}
break;
case SERVICE_PROVIDER:
generatedResource.produce(
Expand Down Expand Up @@ -548,4 +558,12 @@ public boolean test(T t) {
return false;
}
}

/**
* This tracks beans etc from the platform that have already been generated. There is no need to spend time
* generating them again on a hot reload
*/
static class ExistingClasses {
Set<String> existingClasses = new HashSet<>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.enterprise.util.AnnotationLiteral;
Expand Down Expand Up @@ -55,26 +56,30 @@ public class AnnotationLiteralGenerator extends AbstractGenerator {

/**
*
* @param beanDeployment
* @param annotationLiterals
* @param beanDeployment
* @param existingClasses
* @return a collection of resources
*/
Collection<Resource> generate(String name, BeanDeployment beanDeployment,
ComputingCache<Key, Literal> annotationLiteralsCache) {
ComputingCache<Key, Literal> annotationLiteralsCache, Set<String> existingClasses) {
List<Resource> resources = new ArrayList<>();
annotationLiteralsCache.forEachEntry((key, literal) -> {
ResourceClassOutput classOutput = new ResourceClassOutput(literal.isApplicationClass, generateSources);
createSharedAnnotationLiteral(classOutput, key, literal);
createSharedAnnotationLiteral(classOutput, key, literal, existingClasses);
resources.addAll(classOutput.getResources());
});
return resources;
}

static void createSharedAnnotationLiteral(ClassOutput classOutput, Key key, Literal literal) {
static void createSharedAnnotationLiteral(ClassOutput classOutput, Key key, Literal literal, Set<String> existingClasses) {
// Ljavax/enterprise/util/AnnotationLiteral<Lcom/foo/MyQualifier;>;Lcom/foo/MyQualifier;
String signature = String.format("Ljavax/enterprise/util/AnnotationLiteral<L%1$s;>;L%1$s;",
key.annotationName.toString().replace('.', '/'));
String generatedName = literal.className.replace('.', '/');
if (existingClasses.contains(generatedName)) {
return;
}

ClassCreator annotationLiteral = ClassCreator.builder().classOutput(classOutput).className(generatedName)
.superClass(AnnotationLiteral.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,40 +84,48 @@ public class BeanGenerator extends AbstractGenerator {
protected final AnnotationLiteralProcessor annotationLiterals;
protected final Predicate<DotName> applicationClassPredicate;
protected final PrivateMembersCollector privateMembers;
protected final ReflectionRegistration reflectionRegistration;
protected final Set<String> existingClasses;
protected final Map<BeanInfo, String> beanToGeneratedName;

public BeanGenerator(AnnotationLiteralProcessor annotationLiterals, Predicate<DotName> applicationClassPredicate,
PrivateMembersCollector privateMembers, boolean generateSources) {
PrivateMembersCollector privateMembers, boolean generateSources, ReflectionRegistration reflectionRegistration,
Set<String> existingClasses,
Map<BeanInfo, String> beanToGeneratedName) {
super(generateSources);
this.annotationLiterals = annotationLiterals;
this.applicationClassPredicate = applicationClassPredicate;
this.privateMembers = privateMembers;
this.reflectionRegistration = reflectionRegistration;
this.existingClasses = existingClasses;
this.beanToGeneratedName = beanToGeneratedName;
}

/**
*
* @param bean
* @return a collection of resources
*/
Collection<Resource> generate(BeanInfo bean, ReflectionRegistration reflectionRegistration) {
Collection<Resource> generate(BeanInfo bean) {
if (bean.getTarget().isPresent()) {
AnnotationTarget target = bean.getTarget().get();
switch (target.kind()) {
case CLASS:
return generateClassBean(bean, target.asClass(), reflectionRegistration);
return generateClassBean(bean, target.asClass());
case METHOD:
return generateProducerMethodBean(bean, target.asMethod(), reflectionRegistration);
return generateProducerMethodBean(bean, target.asMethod());
case FIELD:
return generateProducerFieldBean(bean, target.asField(), reflectionRegistration);
return generateProducerFieldBean(bean, target.asField());
default:
throw new IllegalArgumentException("Unsupported bean type");
}
} else {
// Synthetic beans
return generateSyntheticBean(bean, reflectionRegistration);
return generateSyntheticBean(bean);
}
}

Collection<Resource> generateSyntheticBean(BeanInfo bean, ReflectionRegistration reflectionRegistration) {
Collection<Resource> generateSyntheticBean(BeanInfo bean) {

StringBuilder baseNameBuilder = new StringBuilder();
if (bean.getImplClazz().enclosingClass() != null) {
Expand All @@ -136,6 +144,10 @@ Collection<Resource> generateSyntheticBean(BeanInfo bean, ReflectionRegistration
String providerTypeName = providerType.name().toString();
String targetPackage = getPackageName(bean);
String generatedName = generatedNameFromTarget(targetPackage, baseName, BEAN_SUFFIX);
beanToGeneratedName.put(bean, generatedName);
if (existingClasses.contains(generatedName)) {
return Collections.emptyList();
}

boolean isApplicationClass = applicationClassPredicate.test(bean.getImplClazz().name());
ResourceClassOutput classOutput = new ResourceClassOutput(isApplicationClass,
Expand Down Expand Up @@ -234,7 +246,7 @@ Collection<Resource> generateSyntheticBean(BeanInfo bean, ReflectionRegistration
return classOutput.getResources();
}

Collection<Resource> generateClassBean(BeanInfo bean, ClassInfo beanClass, ReflectionRegistration reflectionRegistration) {
Collection<Resource> generateClassBean(BeanInfo bean, ClassInfo beanClass) {

String baseName;
if (beanClass.enclosingClass() != null) {
Expand All @@ -246,6 +258,10 @@ Collection<Resource> generateClassBean(BeanInfo bean, ClassInfo beanClass, Refle
String providerTypeName = providerType.name().toString();
String targetPackage = DotNames.packageName(providerType.name());
String generatedName = generatedNameFromTarget(targetPackage, baseName, BEAN_SUFFIX);
beanToGeneratedName.put(bean, generatedName);
if (existingClasses.contains(generatedName)) {
return Collections.emptyList();
}

boolean isApplicationClass = applicationClassPredicate.test(beanClass.name());
ResourceClassOutput classOutput = new ResourceClassOutput(isApplicationClass,
Expand Down Expand Up @@ -314,8 +330,7 @@ Collection<Resource> generateClassBean(BeanInfo bean, ClassInfo beanClass, Refle
return classOutput.getResources();
}

Collection<Resource> generateProducerMethodBean(BeanInfo bean, MethodInfo producerMethod,
ReflectionRegistration reflectionRegistration) {
Collection<Resource> generateProducerMethodBean(BeanInfo bean, MethodInfo producerMethod) {

ClassInfo declaringClass = producerMethod.declaringClass();
String declaringClassBase;
Expand All @@ -341,6 +356,10 @@ Collection<Resource> generateProducerMethodBean(BeanInfo bean, MethodInfo produc
String providerTypeName = providerType.name().toString();
String targetPackage = DotNames.packageName(declaringClass.name());
String generatedName = generatedNameFromTarget(targetPackage, baseName, BEAN_SUFFIX);
beanToGeneratedName.put(bean, generatedName);
if (existingClasses.contains(generatedName)) {
return Collections.emptyList();
}

boolean isApplicationClass = applicationClassPredicate.test(declaringClass.name());
ResourceClassOutput classOutput = new ResourceClassOutput(isApplicationClass,
Expand Down Expand Up @@ -409,8 +428,7 @@ Collection<Resource> generateProducerMethodBean(BeanInfo bean, MethodInfo produc
return classOutput.getResources();
}

Collection<Resource> generateProducerFieldBean(BeanInfo bean, FieldInfo producerField,
ReflectionRegistration reflectionRegistration) {
Collection<Resource> generateProducerFieldBean(BeanInfo bean, FieldInfo producerField) {

ClassInfo declaringClass = producerField.declaringClass();
String declaringClassBase;
Expand All @@ -426,6 +444,10 @@ Collection<Resource> generateProducerFieldBean(BeanInfo bean, FieldInfo producer
String providerTypeName = providerType.name().toString();
String targetPackage = DotNames.packageName(declaringClass.name());
String generatedName = generatedNameFromTarget(targetPackage, baseName, BEAN_SUFFIX);
beanToGeneratedName.put(bean, generatedName);
if (existingClasses.contains(generatedName)) {
return Collections.emptyList();
}

boolean isApplicationClass = applicationClassPredicate.test(declaringClass.name());
ResourceClassOutput classOutput = new ResourceClassOutput(isApplicationClass,
Expand Down Expand Up @@ -564,7 +586,7 @@ protected MethodCreator initConstructor(ClassOutput classOutput, ClassCreator be
// Invoke super()
constructor.invokeSpecialMethod(MethodDescriptors.OBJECT_CONSTRUCTOR, constructor.getThis());

// Get the TCCL - we will use it later
// Get the TCCL - we will use it later
ResultHandle currentThread = constructor
.invokeStaticMethod(MethodDescriptors.THREAD_CURRENT_THREAD);
ResultHandle tccl = constructor.invokeVirtualMethod(MethodDescriptors.THREAD_GET_TCCL, currentThread);
Expand Down
Loading

0 comments on commit 78405ae

Please sign in to comment.