Search in sources :

Example 1 with ModuleAdapter

use of dagger.internal.ModuleAdapter in project dagger by square.

the class ModuleAdapterProcessor method generateModuleAdapter.

/**
   * Write a companion class for {@code type} that implements {@link
   * ModuleAdapter} to expose its provider methods.
   */
private JavaFile generateModuleAdapter(TypeElement type, Map<String, Object> module, List<ExecutableElement> providerMethods) {
    Object[] staticInjections = (Object[]) module.get("staticInjections");
    Object[] injects = (Object[]) module.get("injects");
    Object[] includes = (Object[]) module.get("includes");
    boolean overrides = (Boolean) module.get("overrides");
    boolean complete = (Boolean) module.get("complete");
    boolean library = (Boolean) module.get("library");
    List<Object> duplicateInjects = extractDuplicates(injects);
    if (!duplicateInjects.isEmpty()) {
        error("'injects' list contains duplicate entries: " + duplicateInjects, type);
    }
    List<Object> duplicateIncludes = extractDuplicates(includes);
    if (!duplicateIncludes.isEmpty()) {
        error("'includes' list contains duplicate entries: " + duplicateIncludes, type);
    }
    ClassName moduleClassName = ClassName.get(type);
    ClassName adapterClassName = Util.adapterName(moduleClassName, MODULE_ADAPTER_SUFFIX);
    TypeSpec.Builder adapterBuilder = TypeSpec.classBuilder(adapterClassName.simpleName()).addOriginatingElement(type).addJavadoc(AdapterJavadocs.MODULE_TYPE, Provides.class).superclass(ParameterizedTypeName.get(ClassName.get(ModuleAdapter.class), moduleClassName)).addModifiers(PUBLIC, FINAL);
    adapterBuilder.addField(FieldSpec.builder(String[].class, "INJECTS").addModifiers(PRIVATE, STATIC, FINAL).initializer("$L", injectsInitializer(injects)).build());
    adapterBuilder.addField(FieldSpec.builder(ARRAY_OF_CLASS, "STATIC_INJECTIONS").addModifiers(PRIVATE, STATIC, FINAL).initializer("$L", staticInjectionsInitializer(staticInjections)).build());
    adapterBuilder.addField(FieldSpec.builder(ARRAY_OF_CLASS, "INCLUDES").addModifiers(PRIVATE, STATIC, FINAL).initializer("$L", includesInitializer(type, includes)).build());
    adapterBuilder.addMethod(MethodSpec.constructorBuilder().addModifiers(PUBLIC).addStatement("super($T.class, INJECTS, STATIC_INJECTIONS, $L /*overrides*/, " + "INCLUDES, $L /*complete*/, $L /*library*/)", type.asType(), overrides, complete, library).build());
    ExecutableElement noArgsConstructor = getNoArgsConstructor(type);
    if (noArgsConstructor != null && isCallableConstructor(noArgsConstructor)) {
        adapterBuilder.addMethod(MethodSpec.methodBuilder("newModule").addAnnotation(Override.class).addModifiers(PUBLIC).returns(moduleClassName).addStatement("return new $T()", type.asType()).build());
    }
    // Caches.
    Map<ExecutableElement, ClassName> methodToClassName = new LinkedHashMap<ExecutableElement, ClassName>();
    Map<String, AtomicInteger> methodNameToNextId = new LinkedHashMap<String, AtomicInteger>();
    if (!providerMethods.isEmpty()) {
        MethodSpec.Builder getBindings = MethodSpec.methodBuilder("getBindings").addJavadoc(AdapterJavadocs.GET_DEPENDENCIES_METHOD).addAnnotation(Override.class).addModifiers(PUBLIC).addParameter(BindingsGroup.class, "bindings").addParameter(moduleClassName, "module");
        for (ExecutableElement providerMethod : providerMethods) {
            Provides provides = providerMethod.getAnnotation(Provides.class);
            switch(provides.type()) {
                case UNIQUE:
                    {
                        getBindings.addStatement("bindings.contributeProvidesBinding($S, new $T(module))", GeneratorKeys.get(providerMethod), bindingClassName(adapterClassName, providerMethod, methodToClassName, methodNameToNextId));
                        break;
                    }
                case SET:
                    {
                        getBindings.addStatement("$T.add(bindings, $S, new $T(module))", SetBinding.class, GeneratorKeys.getSetKey(providerMethod), bindingClassName(adapterClassName, providerMethod, methodToClassName, methodNameToNextId));
                        break;
                    }
                case SET_VALUES:
                    {
                        getBindings.addStatement("$T.add(bindings, $S, new $T(module))", SetBinding.class, GeneratorKeys.get(providerMethod), bindingClassName(adapterClassName, providerMethod, methodToClassName, methodNameToNextId));
                        break;
                    }
                default:
                    throw new AssertionError("Unknown @Provides type " + provides.type());
            }
        }
        adapterBuilder.addMethod(getBindings.build());
    }
    for (ExecutableElement providerMethod : providerMethods) {
        adapterBuilder.addType(generateProvidesAdapter(moduleClassName, adapterClassName, providerMethod, methodToClassName, methodNameToNextId, library));
    }
    return JavaFile.builder(adapterClassName.packageName(), adapterBuilder.build()).addFileComment(AdapterJavadocs.GENERATED_BY_DAGGER).build();
}
Also used : MethodSpec(com.squareup.javapoet.MethodSpec) ExecutableElement(javax.lang.model.element.ExecutableElement) Util.typeToString(dagger.internal.codegen.Util.typeToString) Util.elementToString(dagger.internal.codegen.Util.elementToString) Provides(dagger.Provides) LinkedHashMap(java.util.LinkedHashMap) ModuleAdapter(dagger.internal.ModuleAdapter) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ClassName(com.squareup.javapoet.ClassName) BindingsGroup(dagger.internal.BindingsGroup) SetBinding(dagger.internal.SetBinding) TypeSpec(com.squareup.javapoet.TypeSpec)

Aggregations

ClassName (com.squareup.javapoet.ClassName)1 MethodSpec (com.squareup.javapoet.MethodSpec)1 TypeSpec (com.squareup.javapoet.TypeSpec)1 Provides (dagger.Provides)1 BindingsGroup (dagger.internal.BindingsGroup)1 ModuleAdapter (dagger.internal.ModuleAdapter)1 SetBinding (dagger.internal.SetBinding)1 Util.elementToString (dagger.internal.codegen.Util.elementToString)1 Util.typeToString (dagger.internal.codegen.Util.typeToString)1 LinkedHashMap (java.util.LinkedHashMap)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 ExecutableElement (javax.lang.model.element.ExecutableElement)1