162 lines
6.6 KiB
Java
162 lines
6.6 KiB
Java
/*
|
|
* Copyright (C) 2014 The Dagger Authors.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package dagger.internal.codegen;
|
|
|
|
import static com.google.auto.common.MoreElements.asType;
|
|
import static com.google.common.collect.Sets.union;
|
|
import static dagger.internal.codegen.base.ComponentAnnotation.allComponentAnnotations;
|
|
import static dagger.internal.codegen.base.ComponentAnnotation.rootComponentAnnotations;
|
|
import static dagger.internal.codegen.base.ComponentAnnotation.subcomponentAnnotations;
|
|
import static dagger.internal.codegen.binding.ComponentCreatorAnnotation.allCreatorAnnotations;
|
|
import static java.util.Collections.disjoint;
|
|
|
|
import com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
|
|
import com.google.auto.common.MoreElements;
|
|
import com.google.common.collect.ImmutableSet;
|
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
|
import dagger.internal.codegen.base.SourceFileGenerator;
|
|
import dagger.internal.codegen.binding.BindingGraph;
|
|
import dagger.internal.codegen.binding.BindingGraphFactory;
|
|
import dagger.internal.codegen.binding.ComponentDescriptor;
|
|
import dagger.internal.codegen.binding.ComponentDescriptorFactory;
|
|
import dagger.internal.codegen.validation.BindingGraphValidator;
|
|
import dagger.internal.codegen.validation.ComponentCreatorValidator;
|
|
import dagger.internal.codegen.validation.ComponentDescriptorValidator;
|
|
import dagger.internal.codegen.validation.ComponentValidator;
|
|
import dagger.internal.codegen.validation.TypeCheckingProcessingStep;
|
|
import dagger.internal.codegen.validation.ValidationReport;
|
|
import java.lang.annotation.Annotation;
|
|
import java.util.Set;
|
|
import javax.annotation.processing.Messager;
|
|
import javax.inject.Inject;
|
|
import javax.lang.model.element.Element;
|
|
import javax.lang.model.element.TypeElement;
|
|
|
|
/**
|
|
* A {@link ProcessingStep} that is responsible for dealing with a component or production component
|
|
* as part of the {@link ComponentProcessor}.
|
|
*/
|
|
final class ComponentProcessingStep extends TypeCheckingProcessingStep<TypeElement> {
|
|
private final Messager messager;
|
|
private final ComponentValidator componentValidator;
|
|
private final ComponentCreatorValidator creatorValidator;
|
|
private final ComponentDescriptorValidator componentDescriptorValidator;
|
|
private final ComponentDescriptorFactory componentDescriptorFactory;
|
|
private final BindingGraphFactory bindingGraphFactory;
|
|
private final SourceFileGenerator<BindingGraph> componentGenerator;
|
|
private final BindingGraphValidator bindingGraphValidator;
|
|
|
|
@Inject
|
|
ComponentProcessingStep(
|
|
Messager messager,
|
|
ComponentValidator componentValidator,
|
|
ComponentCreatorValidator creatorValidator,
|
|
ComponentDescriptorValidator componentDescriptorValidator,
|
|
ComponentDescriptorFactory componentDescriptorFactory,
|
|
BindingGraphFactory bindingGraphFactory,
|
|
SourceFileGenerator<BindingGraph> componentGenerator,
|
|
BindingGraphValidator bindingGraphValidator) {
|
|
super(MoreElements::asType);
|
|
this.messager = messager;
|
|
this.componentValidator = componentValidator;
|
|
this.creatorValidator = creatorValidator;
|
|
this.componentDescriptorValidator = componentDescriptorValidator;
|
|
this.componentDescriptorFactory = componentDescriptorFactory;
|
|
this.bindingGraphFactory = bindingGraphFactory;
|
|
this.componentGenerator = componentGenerator;
|
|
this.bindingGraphValidator = bindingGraphValidator;
|
|
}
|
|
|
|
@Override
|
|
public Set<Class<? extends Annotation>> annotations() {
|
|
return union(allComponentAnnotations(), allCreatorAnnotations());
|
|
}
|
|
|
|
@Override
|
|
protected void process(
|
|
TypeElement element, ImmutableSet<Class<? extends Annotation>> annotations) {
|
|
if (!disjoint(annotations, rootComponentAnnotations())) {
|
|
processRootComponent(element);
|
|
}
|
|
if (!disjoint(annotations, subcomponentAnnotations())) {
|
|
processSubcomponent(element);
|
|
}
|
|
if (!disjoint(annotations, allCreatorAnnotations())) {
|
|
processCreator(element);
|
|
}
|
|
}
|
|
|
|
private void processRootComponent(TypeElement component) {
|
|
if (!isComponentValid(component)) {
|
|
return;
|
|
}
|
|
ComponentDescriptor componentDescriptor =
|
|
componentDescriptorFactory.rootComponentDescriptor(component);
|
|
if (!isValid(componentDescriptor)) {
|
|
return;
|
|
}
|
|
if (!validateFullBindingGraph(componentDescriptor)) {
|
|
return;
|
|
}
|
|
BindingGraph bindingGraph = bindingGraphFactory.create(componentDescriptor, false);
|
|
if (bindingGraphValidator.isValid(bindingGraph.topLevelBindingGraph())) {
|
|
generateComponent(bindingGraph);
|
|
}
|
|
}
|
|
|
|
private void processSubcomponent(TypeElement subcomponent) {
|
|
if (!isComponentValid(subcomponent)) {
|
|
return;
|
|
}
|
|
ComponentDescriptor subcomponentDescriptor =
|
|
componentDescriptorFactory.subcomponentDescriptor(subcomponent);
|
|
// TODO(dpb): ComponentDescriptorValidator for subcomponents, as we do for root components.
|
|
validateFullBindingGraph(subcomponentDescriptor);
|
|
}
|
|
|
|
private void generateComponent(BindingGraph bindingGraph) {
|
|
componentGenerator.generate(bindingGraph, messager);
|
|
}
|
|
|
|
private void processCreator(Element creator) {
|
|
creatorValidator.validate(MoreElements.asType(creator)).printMessagesTo(messager);
|
|
}
|
|
|
|
private boolean isComponentValid(Element component) {
|
|
ValidationReport<?> report = componentValidator.validate(asType(component));
|
|
report.printMessagesTo(messager);
|
|
return report.isClean();
|
|
}
|
|
|
|
@CanIgnoreReturnValue
|
|
private boolean validateFullBindingGraph(ComponentDescriptor componentDescriptor) {
|
|
TypeElement component = componentDescriptor.typeElement();
|
|
if (!bindingGraphValidator.shouldDoFullBindingGraphValidation(component)) {
|
|
return true;
|
|
}
|
|
BindingGraph fullBindingGraph = bindingGraphFactory.create(componentDescriptor, true);
|
|
return bindingGraphValidator.isValid(fullBindingGraph.topLevelBindingGraph());
|
|
}
|
|
|
|
private boolean isValid(ComponentDescriptor componentDescriptor) {
|
|
ValidationReport<TypeElement> componentDescriptorReport =
|
|
componentDescriptorValidator.validate(componentDescriptor);
|
|
componentDescriptorReport.printMessagesTo(messager);
|
|
return componentDescriptorReport.isClean();
|
|
}
|
|
}
|