diff --git a/compiler/src/main/java/autodagger/compiler/SubcomponentComposer.java b/compiler/src/main/java/autodagger/compiler/SubcomponentComposer.java index 2b86f53..af88e1c 100644 --- a/compiler/src/main/java/autodagger/compiler/SubcomponentComposer.java +++ b/compiler/src/main/java/autodagger/compiler/SubcomponentComposer.java @@ -64,6 +64,10 @@ protected JavaFile compose(SubcomponentSpec subcomponentSpec) { builder.addMethod(exposeBuilder.build()); } + if (!subcomponentSpec.getSubcomponentsSpecs().isEmpty()) { + builder.addMethods(subcomponentSpec.getSubcomponentsSpecs()); + } + TypeSpec typeSpec = builder.build(); return JavaFile.builder(subcomponentSpec.getClassName().packageName(), typeSpec).build(); } diff --git a/compiler/src/main/java/autodagger/compiler/SubcomponentExtractor.java b/compiler/src/main/java/autodagger/compiler/SubcomponentExtractor.java index 6796bc4..b9e9575 100644 --- a/compiler/src/main/java/autodagger/compiler/SubcomponentExtractor.java +++ b/compiler/src/main/java/autodagger/compiler/SubcomponentExtractor.java @@ -1,6 +1,7 @@ package autodagger.compiler; import com.google.auto.common.MoreElements; +import com.google.auto.common.MoreTypes; import java.util.ArrayList; import java.util.List; @@ -15,6 +16,7 @@ import autodagger.AutoSubcomponent; import autodagger.compiler.utils.AutoComponentExtractorUtil; +import dagger.Subcomponent; import processorworkflow.AbstractExtractor; import processorworkflow.Errors; import processorworkflow.ExtractorUtils; @@ -26,6 +28,7 @@ public class SubcomponentExtractor extends AbstractExtractor { private List modulesTypeMirrors; private List superinterfacesTypeMirrors; + private List subcomponentsTypeMirrors; private AnnotationMirror scopeAnnotationTypeMirror; public SubcomponentExtractor(Element element, Types types, Elements elements, Errors errors) { @@ -37,6 +40,7 @@ public SubcomponentExtractor(Element element, Types types, Elements elements, Er @Override public void extract() { modulesTypeMirrors = findTypeMirrors(element, AutoComponentExtractorUtil.ANNOTATION_MODULES); + subcomponentsTypeMirrors = findTypeMirrors(element, AutoComponentExtractorUtil.ANNOTATION_SUBCOMPONENTS); if (!MoreElements.isAnnotationPresent(element, AutoSubcomponent.class)) { return; } @@ -46,6 +50,8 @@ public void extract() { } private List findTypeMirrors(Element element, String name) { + boolean addsTo = name.equals(AutoComponentExtractorUtil.ANNOTATION_SUBCOMPONENTS); + List typeMirrors = new ArrayList<>(); List values = ExtractorUtils.getValueFromAnnotation(element, AutoSubcomponent.class, name); if (values != null) { @@ -56,6 +62,13 @@ private List findTypeMirrors(Element element, String name) { try { TypeMirror tm = (TypeMirror) value.getValue(); + if (addsTo) { + Element e = MoreTypes.asElement(tm); + if (!MoreElements.isAnnotationPresent(e, AutoSubcomponent.class) && !MoreElements.isAnnotationPresent(e, Subcomponent.class)) { + errors.addInvalid("@AutoComponent cannot declare a subcomponent that is not annotated with @Subcomponent or @AutoSubcomponent: %s", e.getSimpleName()); + continue; + } + } typeMirrors.add(tm); } catch (Exception e) { errors.addInvalid(e.getMessage()); @@ -104,6 +117,10 @@ public AnnotationMirror getScopeAnnotationTypeMirror() { return scopeAnnotationTypeMirror; } + public List getSubcomponentsTypeMirrors() { + return subcomponentsTypeMirrors; + } + public List getSuperinterfacesTypeMirrors() { return superinterfacesTypeMirrors; } diff --git a/compiler/src/main/java/autodagger/compiler/SubcomponentProcessing.java b/compiler/src/main/java/autodagger/compiler/SubcomponentProcessing.java index 5b7b5c0..ae36965 100644 --- a/compiler/src/main/java/autodagger/compiler/SubcomponentProcessing.java +++ b/compiler/src/main/java/autodagger/compiler/SubcomponentProcessing.java @@ -1,13 +1,24 @@ package autodagger.compiler; +import com.google.auto.common.MoreElements; +import com.google.auto.common.MoreTypes; import com.google.common.collect.ImmutableSet; import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.TypeName; import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; +import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; @@ -108,7 +119,52 @@ protected SubcomponentSpec build() { // injector subcomponentSpec.setInjectorSpecs(ProcessingUtil.getAdditions(extractor.getElement(), state.getInjectorExtractors())); + // subcomponents + subcomponentSpec.setSubcomponentsSpecs(getSubcomponents()); + return subcomponentSpec; } + + private List getSubcomponents() { + if (extractor.getSubcomponentsTypeMirrors().isEmpty()) { + return Collections.emptyList(); + } + + List methodSpecs = new ArrayList<>(extractor.getSubcomponentsTypeMirrors().size()); + for (TypeMirror typeMirror : extractor.getSubcomponentsTypeMirrors()) { + Element e = MoreTypes.asElement(typeMirror); + TypeName typeName; + String name; + if (MoreElements.isAnnotationPresent(e, AutoSubcomponent.class)) { + ClassName cls = AutoComponentClassNameUtil.getComponentClassName(e); + typeName = cls; + name = cls.simpleName(); + } else { + typeName = TypeName.get(typeMirror); + name = e.getSimpleName().toString(); + } + + List modules = state.getSubcomponentModules(typeMirror); + List parameterSpecs; + if(modules != null) { + parameterSpecs = new ArrayList<>(modules.size()); + int count = 0; + for (TypeMirror moduleTypeMirror : modules) { + parameterSpecs.add(ParameterSpec.builder(TypeName.get(moduleTypeMirror), String.format("module%d", ++count)).build()); + } + } else { + parameterSpecs = new ArrayList<>(0); + } + + methodSpecs.add(MethodSpec.methodBuilder("plus" + name) + .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) + .addParameters(parameterSpecs) + .returns(typeName) + .build()); + } + + return methodSpecs; + } } + } \ No newline at end of file diff --git a/compiler/src/main/java/autodagger/compiler/SubcomponentSpec.java b/compiler/src/main/java/autodagger/compiler/SubcomponentSpec.java index b52116f..4917284 100644 --- a/compiler/src/main/java/autodagger/compiler/SubcomponentSpec.java +++ b/compiler/src/main/java/autodagger/compiler/SubcomponentSpec.java @@ -2,6 +2,7 @@ import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.TypeName; import java.util.List; @@ -17,6 +18,7 @@ public class SubcomponentSpec { private List exposeSpecs; private List modulesTypeNames; private List superinterfacesTypeNames; + private List subcomponentsSpecs; public SubcomponentSpec(ClassName className) { this.className = className; @@ -65,4 +67,12 @@ public List getSuperinterfacesTypeNames() { public void setSuperinterfacesTypeNames(List superinterfacesTypeNames) { this.superinterfacesTypeNames = superinterfacesTypeNames; } + + public List getSubcomponentsSpecs() { + return subcomponentsSpecs; + } + + public void setSubcomponentsSpecs(List subcomponentsSpecs) { + this.subcomponentsSpecs = subcomponentsSpecs; + } } \ No newline at end of file diff --git a/example/src/main/java/autodagger/example/FirstActivity.java b/example/src/main/java/autodagger/example/FirstActivity.java index 18adcea..3f6b76d 100644 --- a/example/src/main/java/autodagger/example/FirstActivity.java +++ b/example/src/main/java/autodagger/example/FirstActivity.java @@ -3,6 +3,7 @@ import android.app.Activity; import android.os.Bundle; +import javax.inject.Inject; import javax.inject.Named; import autodagger.AutoComponent; @@ -27,6 +28,7 @@ public class FirstActivity extends Activity { private FirstActivityComponent component; + @Inject MySubObject1 mySubObject1; @Override protected void onCreate(Bundle savedInstanceState) { @@ -38,6 +40,8 @@ protected void onCreate(Bundle savedInstanceState) { .moduleTwo(new ModuleTwo()) .build(); component.inject(this); + + component.plusMySubObject2Component(new MySubObject2.Module(""), new MySubObject2.ModuleTwo()).plusMySubObject1Component().inject(mySubObject1); } @Module @@ -70,6 +74,12 @@ public MyObject4 providesMyObject4Qualifier1() { public MyObject4 providesMyObject4Qualifier2() { return new MyObject4(); } + + @Provides + @DaggerScope(FirstActivity.class) + public MySubObject1 providesMySubObject1() { + return new MySubObject1(); + } } @Module diff --git a/example/src/main/java/autodagger/example/MySubObject1.java b/example/src/main/java/autodagger/example/MySubObject1.java index 765947e..0a91755 100644 --- a/example/src/main/java/autodagger/example/MySubObject1.java +++ b/example/src/main/java/autodagger/example/MySubObject1.java @@ -1,5 +1,6 @@ package autodagger.example; +import autodagger.AutoInjector; import autodagger.AutoSubcomponent; /** @@ -7,6 +8,7 @@ */ @AutoSubcomponent @DaggerScope(MySubObject1.class) +@AutoInjector public class MySubObject1 { } diff --git a/example/src/main/java/autodagger/example/MySubObject2.java b/example/src/main/java/autodagger/example/MySubObject2.java index ae19a84..de6a8eb 100644 --- a/example/src/main/java/autodagger/example/MySubObject2.java +++ b/example/src/main/java/autodagger/example/MySubObject2.java @@ -1,21 +1,28 @@ package autodagger.example; +import autodagger.AutoInjector; import autodagger.AutoSubcomponent; /** * Created by lukasz on 04/12/15. */ -@AutoSubcomponent(modules = {MySubObject2.Module.class, MySubObject2.ModuleTwo.class}, superinterfaces = MySubObject2.MyInterface.class) +@AutoSubcomponent( + modules = {MySubObject2.Module.class, MySubObject2.ModuleTwo.class}, + superinterfaces = MySubObject2.MyInterface.class, + subcomponents = MySubObject1.class +) +@AutoInjector @DaggerScope(MySubObject2.class) public class MySubObject2 { @dagger.Module - public class Module { - + public static class Module { + public Module(String string) { + } } @dagger.Module - public class ModuleTwo { + public static class ModuleTwo { } diff --git a/library/src/main/java/autodagger/AutoSubcomponent.java b/library/src/main/java/autodagger/AutoSubcomponent.java index 5e9006e..a20c78b 100644 --- a/library/src/main/java/autodagger/AutoSubcomponent.java +++ b/library/src/main/java/autodagger/AutoSubcomponent.java @@ -12,4 +12,9 @@ Class[] modules() default {}; Class[] superinterfaces() default {}; + + /** + * Subcomponents to be declared inside this component + */ + Class[] subcomponents() default {}; } \ No newline at end of file