package autodagger.compiler; import com.google.common.collect.ImmutableSet; import com.squareup.javapoet.AnnotationSpec; import java.lang.annotation.Annotation; import java.util.HashSet; import java.util.Set; import javax.lang.model.element.Element; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import autodagger.AutoSubcomponent; import autodagger.compiler.utils.AutoComponentClassNameUtil; import dagger.Subcomponent; import processorworkflow.AbstractComposer; import processorworkflow.AbstractProcessing; import processorworkflow.Errors; import processorworkflow.ProcessingBuilder; /** * @author Lukasz Piliszczuk - lukasz.pili@gmail.com */ public class SubcomponentProcessing extends AbstractProcessing<SubcomponentSpec, State> { /** * Build all extractors first, then build all builders, because * we want to gather all addsTo that can be related to other annoted auto subcomponents */ private final Set<SubcomponentExtractor> extractors = new HashSet<>(); public SubcomponentProcessing(Elements elements, Types types, Errors errors, State state) { super(elements, types, errors, state); } @Override public Set<Class<? extends Annotation>> supportedAnnotations() { Set set = ImmutableSet.of(AutoSubcomponent.class, Subcomponent.class); return set; } @Override protected void processElements(Set<? extends Element> annotationElements) { super.processElements(annotationElements); if (errors.hasErrors()) { return; } processExtractors(); } @Override public boolean processElement(Element element, Errors.ElementErrors elementErrors) { SubcomponentExtractor extractor = new SubcomponentExtractor(element, types, elements, errors); if (errors.hasErrors()) { return false; } extractors.add(extractor); if (!extractor.getModulesTypeMirrors().isEmpty()) { state.addSubcomponentModule(element.asType(), extractor.getModulesTypeMirrors()); } return true; } private void processExtractors() { for (SubcomponentExtractor extractor : extractors) { SubcomponentSpec spec = new Builder(extractor, errors).build(); if (errors.hasErrors()) { return; } specs.add(spec); } } @Override public AbstractComposer<SubcomponentSpec> createComposer() { return new SubcomponentComposer(specs); } private class Builder extends ProcessingBuilder<SubcomponentExtractor, SubcomponentSpec> { public Builder(SubcomponentExtractor extractor, Errors errors) { super(extractor, errors); } @Override protected SubcomponentSpec build() { SubcomponentSpec subcomponentSpec = new SubcomponentSpec(AutoComponentClassNameUtil.getComponentClassName(extractor.getElement())); if (extractor.getScopeAnnotationTypeMirror() != null) { subcomponentSpec.setScopeAnnotationSpec(AnnotationSpec.get(extractor.getScopeAnnotationTypeMirror())); } // modules subcomponentSpec.setModulesTypeNames(ProcessingUtil.getTypeNames(extractor.getModulesTypeMirrors())); // superinterfaces subcomponentSpec.setSuperinterfacesTypeNames(ProcessingUtil.getTypeNames(extractor.getSuperinterfacesTypeMirrors())); // exposed subcomponentSpec.setExposeSpecs(ProcessingUtil.getAdditions(extractor.getElement(), state.getExposeExtractors())); // injector subcomponentSpec.setInjectorSpecs(ProcessingUtil.getAdditions(extractor.getElement(), state.getInjectorExtractors())); return subcomponentSpec; } } }