/* * Copyright (C) 2014 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.binding; import static com.google.common.base.CaseFormat.LOWER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_CAMEL; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Verify.verify; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.javapoet.TypeNames.DOUBLE_CHECK; import static dagger.internal.codegen.javapoet.TypeNames.MAP_FACTORY; import static dagger.internal.codegen.javapoet.TypeNames.MAP_OF_PRODUCED_PRODUCER; import static dagger.internal.codegen.javapoet.TypeNames.MAP_OF_PRODUCER_PRODUCER; import static dagger.internal.codegen.javapoet.TypeNames.MAP_PRODUCER; import static dagger.internal.codegen.javapoet.TypeNames.MAP_PROVIDER_FACTORY; import static dagger.internal.codegen.javapoet.TypeNames.PROVIDER_OF_LAZY; import static dagger.internal.codegen.javapoet.TypeNames.SET_FACTORY; import static dagger.internal.codegen.javapoet.TypeNames.SET_OF_PRODUCED_PRODUCER; import static dagger.internal.codegen.javapoet.TypeNames.SET_PRODUCER; import static dagger.model.BindingKind.ASSISTED_INJECTION; import static dagger.model.BindingKind.INJECTION; import static dagger.model.BindingKind.MULTIBOUND_MAP; import static dagger.model.BindingKind.MULTIBOUND_SET; import static javax.lang.model.SourceVersion.isName; import com.google.auto.common.MoreElements; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeVariableName; import dagger.internal.SetFactory; import dagger.internal.codegen.base.MapType; import dagger.internal.codegen.base.SetType; import dagger.model.DependencyRequest; import dagger.model.RequestKind; import dagger.producers.Produced; import dagger.producers.Producer; import dagger.producers.internal.SetOfProducedProducer; import dagger.producers.internal.SetProducer; import java.util.List; import javax.inject.Provider; import javax.lang.model.SourceVersion; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeParameterElement; import javax.lang.model.element.VariableElement; /** Utilities for generating files. */ public class SourceFiles { private static final Joiner CLASS_FILE_NAME_JOINER = Joiner.on('_'); /** * Generates names and keys for the factory class fields needed to hold the framework classes for * all of the dependencies of {@code binding}. It is responsible for choosing a name that * *
This will always return a {@linkplain ClassName#topLevelClassName() top level class name},
* even if {@code element}'s enclosing class is a nested type.
*/
public static ClassName elementBasedClassName(ExecutableElement element, String suffix) {
ClassName enclosingClassName =
ClassName.get(MoreElements.asType(element.getEnclosingElement()));
String methodName =
element.getKind().equals(ElementKind.CONSTRUCTOR)
? ""
: LOWER_CAMEL.to(UPPER_CAMEL, element.getSimpleName().toString());
return ClassName.get(
enclosingClassName.packageName(),
classFileName(enclosingClassName) + "_" + methodName + suffix);
}
public static TypeName parameterizedGeneratedTypeNameForBinding(Binding binding) {
ClassName className = generatedClassNameForBinding(binding);
ImmutableList
*
*/
public static ClassName setFactoryClassName(ContributionBinding binding) {
checkArgument(binding.kind().equals(MULTIBOUND_SET));
if (binding.bindingType().equals(BindingType.PROVISION)) {
return SET_FACTORY;
} else {
SetType setType = SetType.from(binding.key());
return setType.elementsAreTypeOf(Produced.class) ? SET_OF_PRODUCED_PRODUCER : SET_PRODUCER;
}
}
/** The {@link java.util.Map} factory class name appropriate for map bindings. */
public static ClassName mapFactoryClassName(ContributionBinding binding) {
checkState(binding.kind().equals(MULTIBOUND_MAP), binding.kind());
MapType mapType = MapType.from(binding.key());
switch (binding.bindingType()) {
case PROVISION:
return mapType.valuesAreTypeOf(Provider.class) ? MAP_PROVIDER_FACTORY : MAP_FACTORY;
case PRODUCTION:
return mapType.valuesAreFrameworkType()
? mapType.valuesAreTypeOf(Producer.class)
? MAP_OF_PRODUCER_PRODUCER
: MAP_OF_PRODUCED_PRODUCER
: MAP_PRODUCER;
default:
throw new IllegalArgumentException(binding.bindingType().toString());
}
}
public static ImmutableList