You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
4.7 KiB
109 lines
4.7 KiB
/*
|
|
* Copyright (C) 2017 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.rootComponentAnnotations;
|
|
import static dagger.internal.codegen.binding.ComponentCreatorAnnotation.rootComponentCreatorAnnotations;
|
|
import static java.util.Collections.disjoint;
|
|
|
|
import com.google.auto.common.MoreElements;
|
|
import com.google.common.collect.ImmutableSet;
|
|
import dagger.internal.codegen.base.SourceFileGenerator;
|
|
import dagger.internal.codegen.binding.BindingGraph;
|
|
import dagger.internal.codegen.binding.ComponentDescriptor;
|
|
import dagger.internal.codegen.binding.ComponentDescriptorFactory;
|
|
import dagger.internal.codegen.validation.ComponentCreatorValidator;
|
|
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.TypeElement;
|
|
|
|
/**
|
|
* A processing step that emits the API of a generated component, without any actual implementation.
|
|
*
|
|
* <p>When compiling a header jar (hjar), Bazel needs to run annotation processors that generate
|
|
* API, like Dagger, to see what code they might output. Full {@link BindingGraph} analysis is
|
|
* costly and unnecessary from the perspective of the header compiler; it's sole goal is to pass
|
|
* along a slimmed down version of what will be the jar for a particular compilation, whether or not
|
|
* that compilation succeeds. If it does not, the compilation pipeline will fail, even if header
|
|
* compilation succeeded.
|
|
*
|
|
* <p>The components emitted by this processing step include all of the API elements exposed by the
|
|
* normal step. Method bodies are omitted as Turbine ignores them entirely.
|
|
*/
|
|
final class ComponentHjarProcessingStep extends TypeCheckingProcessingStep<TypeElement> {
|
|
private final Messager messager;
|
|
private final ComponentValidator componentValidator;
|
|
private final ComponentCreatorValidator creatorValidator;
|
|
private final ComponentDescriptorFactory componentDescriptorFactory;
|
|
private final SourceFileGenerator<ComponentDescriptor> componentGenerator;
|
|
|
|
@Inject
|
|
ComponentHjarProcessingStep(
|
|
Messager messager,
|
|
ComponentValidator componentValidator,
|
|
ComponentCreatorValidator creatorValidator,
|
|
ComponentDescriptorFactory componentDescriptorFactory,
|
|
SourceFileGenerator<ComponentDescriptor> componentGenerator) {
|
|
super(MoreElements::asType);
|
|
this.messager = messager;
|
|
this.componentValidator = componentValidator;
|
|
this.creatorValidator = creatorValidator;
|
|
this.componentDescriptorFactory = componentDescriptorFactory;
|
|
this.componentGenerator = componentGenerator;
|
|
}
|
|
|
|
@Override
|
|
public Set<Class<? extends Annotation>> annotations() {
|
|
return union(rootComponentAnnotations(), rootComponentCreatorAnnotations());
|
|
}
|
|
|
|
// TODO(ronshapiro): Validation might not even be necessary. We should measure it and figure out
|
|
// if it's worth seeing if removing it will still work. We could potentially add a new catch
|
|
// clause for any exception that's not TypeNotPresentException and ignore the component entirely
|
|
// in that case.
|
|
@Override
|
|
protected void process(
|
|
TypeElement element, ImmutableSet<Class<? extends Annotation>> annotations) {
|
|
if (!disjoint(annotations, rootComponentAnnotations())) {
|
|
processRootComponent(element);
|
|
}
|
|
if (!disjoint(annotations, rootComponentCreatorAnnotations())) {
|
|
processRootCreator(element);
|
|
}
|
|
}
|
|
|
|
private void processRootComponent(TypeElement element) {
|
|
ValidationReport<TypeElement> validationReport = componentValidator.validate(element);
|
|
validationReport.printMessagesTo(messager);
|
|
if (validationReport.isClean()) {
|
|
componentGenerator.generate(
|
|
componentDescriptorFactory.rootComponentDescriptor(element), messager);
|
|
}
|
|
}
|
|
|
|
private void processRootCreator(TypeElement creator) {
|
|
creatorValidator.validate(asType(creator)).printMessagesTo(messager);
|
|
}
|
|
}
|