Search in sources :

Example 1 with Linker

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

the class GraphAnalysisProcessor method processCompleteModule.

private Map<String, Binding<?>> processCompleteModule(TypeElement rootModule, boolean ignoreCompletenessErrors) {
    Map<String, TypeElement> allModules = new LinkedHashMap<String, TypeElement>();
    collectIncludesRecursively(rootModule, allModules, new LinkedList<String>());
    ArrayList<GraphAnalysisStaticInjection> staticInjections = new ArrayList<GraphAnalysisStaticInjection>();
    Linker.ErrorHandler errorHandler = ignoreCompletenessErrors ? Linker.ErrorHandler.NULL : new GraphAnalysisErrorHandler(processingEnv, rootModule.getQualifiedName().toString());
    Linker linker = new Linker(null, new GraphAnalysisLoader(processingEnv), errorHandler);
    // to make the linker happy.
    synchronized (linker) {
        BindingsGroup baseBindings = new BindingsGroup() {

            @Override
            public Binding<?> contributeSetBinding(String key, SetBinding<?> value) {
                return super.put(key, value);
            }
        };
        BindingsGroup overrideBindings = new BindingsGroup() {

            @Override
            public Binding<?> contributeSetBinding(String key, SetBinding<?> value) {
                throw new IllegalStateException("Module overrides cannot contribute set bindings.");
            }
        };
        for (TypeElement module : allModules.values()) {
            Map<String, Object> annotation = getAnnotation(Module.class, module);
            boolean overrides = (Boolean) annotation.get("overrides");
            boolean library = (Boolean) annotation.get("library");
            BindingsGroup addTo = overrides ? overrideBindings : baseBindings;
            // Gather the injectable types from the annotation.
            Set<String> injectsProvisionKeys = new LinkedHashSet<String>();
            for (Object injectableTypeObject : (Object[]) annotation.get("injects")) {
                TypeMirror injectableType = (TypeMirror) injectableTypeObject;
                String providerKey = GeneratorKeys.get(injectableType);
                injectsProvisionKeys.add(providerKey);
                String key = isInterface(injectableType) ? providerKey : GeneratorKeys.rawMembersKey(injectableType);
                linker.requestBinding(key, module.getQualifiedName().toString(), getClass().getClassLoader(), false, true);
            }
            // Gather the static injections.
            for (Object staticInjection : (Object[]) annotation.get("staticInjections")) {
                TypeMirror staticInjectionTypeMirror = (TypeMirror) staticInjection;
                Element element = processingEnv.getTypeUtils().asElement(staticInjectionTypeMirror);
                staticInjections.add(new GraphAnalysisStaticInjection(element));
            }
            // Gather the enclosed @Provides methods.
            for (Element enclosed : module.getEnclosedElements()) {
                Provides provides = enclosed.getAnnotation(Provides.class);
                if (provides == null) {
                    continue;
                }
                ExecutableElement providerMethod = (ExecutableElement) enclosed;
                String key = GeneratorKeys.get(providerMethod);
                ProvidesBinding<?> binding = new ProviderMethodBinding(key, providerMethod, library);
                Binding<?> previous = addTo.get(key);
                if (previous != null) {
                    if ((provides.type() == SET || provides.type() == SET_VALUES) && previous instanceof SetBinding) {
                    // No duplicate bindings error if both bindings are set bindings.
                    } else {
                        String message = "Duplicate bindings for " + key;
                        if (overrides) {
                            message += " in override module(s) - cannot override an override";
                        }
                        message += ":\n    " + previous.requiredBy + "\n    " + binding.requiredBy;
                        error(message, providerMethod);
                    }
                }
                switch(provides.type()) {
                    case UNIQUE:
                        if (injectsProvisionKeys.contains(binding.provideKey)) {
                            binding.setDependedOn(true);
                        }
                        try {
                            addTo.contributeProvidesBinding(key, binding);
                        } catch (IllegalStateException ise) {
                            throw new ModuleValidationException(ise.getMessage(), providerMethod);
                        }
                        break;
                    case SET:
                        String setKey = GeneratorKeys.getSetKey(providerMethod);
                        SetBinding.add(addTo, setKey, binding);
                        break;
                    case SET_VALUES:
                        SetBinding.add(addTo, key, binding);
                        break;
                    default:
                        throw new AssertionError("Unknown @Provides type " + provides.type());
                }
            }
        }
        linker.installBindings(baseBindings);
        linker.installBindings(overrideBindings);
        for (GraphAnalysisStaticInjection staticInjection : staticInjections) {
            staticInjection.attach(linker);
        }
        // errors if any dependencies are missing.
        return linker.linkAll();
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) TypeMirror(javax.lang.model.type.TypeMirror) BindingsGroup(dagger.internal.BindingsGroup) TypeElement(javax.lang.model.element.TypeElement) Linker(dagger.internal.Linker) Provides(dagger.Provides) FileObject(javax.tools.FileObject) SetBinding(dagger.internal.SetBinding)

Aggregations

Provides (dagger.Provides)1 BindingsGroup (dagger.internal.BindingsGroup)1 Linker (dagger.internal.Linker)1 SetBinding (dagger.internal.SetBinding)1 ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 Element (javax.lang.model.element.Element)1 ExecutableElement (javax.lang.model.element.ExecutableElement)1 TypeElement (javax.lang.model.element.TypeElement)1 VariableElement (javax.lang.model.element.VariableElement)1 TypeMirror (javax.lang.model.type.TypeMirror)1 FileObject (javax.tools.FileObject)1