dagger.internal.codegen.BindingGraphPlugins.java Source code

Java tutorial

Introduction

Here is the source code for dagger.internal.codegen.BindingGraphPlugins.java

Source

/*
 * Copyright (C) 2018 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.common.base.Preconditions.checkNotNull;
import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static javax.tools.Diagnostic.Kind.ERROR;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import dagger.internal.codegen.DiagnosticReporterFactory.DiagnosticReporterImpl;
import dagger.model.BindingGraph;
import dagger.spi.BindingGraphPlugin;
import dagger.spi.DiagnosticReporter;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.Map;
import java.util.Set;
import javax.annotation.processing.Filer;
import javax.inject.Qualifier;
import javax.inject.Singleton;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;

/** The set of SPI and validation plugins. */
@Singleton
final class BindingGraphPlugins {

    @Qualifier
    @Retention(RUNTIME)
    @Target({ FIELD, PARAMETER, METHOD })
    @interface TestingPlugins {
    }

    private final ImmutableSet<BindingGraphPlugin> plugins;
    private final Filer filer;
    private final Types types;
    private final Elements elements;
    private final Map<String, String> processingOptions;
    private final DiagnosticReporterFactory diagnosticReporterFactory;

    BindingGraphPlugins(Iterable<BindingGraphPlugin> plugins, Filer filer, Types types, Elements elements,
            Map<String, String> processingOptions, DiagnosticReporterFactory diagnosticReporterFactory) {
        this.plugins = ImmutableSet.copyOf(plugins);
        this.filer = checkNotNull(filer);
        this.types = checkNotNull(types);
        this.elements = checkNotNull(elements);
        this.processingOptions = checkNotNull(processingOptions);
        this.diagnosticReporterFactory = checkNotNull(diagnosticReporterFactory);
    }

    /** Returns {@link BindingGraphPlugin#supportedOptions()} from all the plugins. */
    ImmutableSet<String> allSupportedOptions() {
        return plugins.stream().flatMap(plugin -> plugin.supportedOptions().stream()).collect(toImmutableSet());
    }

    /** Initializes the plugins. */
    void initializePlugins() {
        plugins.forEach(this::initializePlugin);
    }

    private void initializePlugin(BindingGraphPlugin plugin) {
        plugin.initFiler(filer);
        plugin.initTypes(types);
        plugin.initElements(elements);
        Set<String> supportedOptions = plugin.supportedOptions();
        if (!supportedOptions.isEmpty()) {
            plugin.initOptions(Maps.filterKeys(processingOptions, supportedOptions::contains));
        }
    }

    /**
     * Calls {@link BindingGraphPlugin#visitGraph(BindingGraph, DiagnosticReporter)} on each of the
     * SPI plugins
     *
     * @return the kinds of diagnostics that were reported
     */
    // TODO(ronshapiro): Should we validate the uniqueness of plugin names?
    ImmutableSet<Diagnostic.Kind> visitGraph(BindingGraph graph) {
        ImmutableSet.Builder<Diagnostic.Kind> diagnosticKinds = ImmutableSet.builder();
        for (BindingGraphPlugin plugin : plugins) {
            DiagnosticReporterImpl reporter = diagnosticReporterFactory.reporter(graph, plugin);
            plugin.visitGraph(graph, reporter);
            diagnosticKinds.addAll(reporter.reportedDiagnosticKinds());
        }
        return diagnosticKinds.build();
    }

    /** Returns {@code true} if any errors are reported by any of the plugins for {@code graph}. */
    boolean pluginsReportErrors(BindingGraph graph) {
        return visitGraph(graph).contains(ERROR);
    }
}