/* * 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 androidx.room.compiler.processing.XElementKt.isConstructor; 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.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.PRODUCER; import static dagger.internal.codegen.javapoet.TypeNames.PROVIDER; 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.internal.codegen.model.BindingKind.ASSISTED_INJECTION; import static dagger.internal.codegen.model.BindingKind.INJECTION; import static dagger.internal.codegen.model.BindingKind.MULTIBOUND_MAP; import static dagger.internal.codegen.model.BindingKind.MULTIBOUND_SET; import static dagger.internal.codegen.xprocessing.XElements.asExecutable; import static dagger.internal.codegen.xprocessing.XElements.asTypeElement; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; import static dagger.internal.codegen.xprocessing.XTypeElements.typeVariableNames; import static javax.lang.model.SourceVersion.isName; import androidx.room.compiler.processing.XExecutableElement; import androidx.room.compiler.processing.XFieldElement; import androidx.room.compiler.processing.XTypeElement; 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.codegen.base.MapType; import dagger.internal.codegen.base.SetType; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.RequestKind; import javax.inject.Inject; import javax.lang.model.SourceVersion; /** Utilities for generating files. */ public final class SourceFiles { private static final Joiner CLASS_FILE_NAME_JOINER = Joiner.on('_'); @Inject SourceFiles() {} /** * 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 method is useful during validation before a {@link Binding} can be created. If a * binding already exists for the given element, prefer to call {@link * #generatedClassNameForBinding(Binding)} instead since this method does not validate that the * given element is actually a binding element or not. */ public static ClassName factoryNameForElement(XExecutableElement element) { return elementBasedClassName(element, "Factory"); } /** * Calculates an appropriate {@link ClassName} for a generated class that is based on {@code * element}, appending {@code suffix} at the end. * *
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(XExecutableElement element, String suffix) {
ClassName enclosingClassName = element.getEnclosingElement().getClassName();
String methodName =
isConstructor(element) ? "" : LOWER_CAMEL.to(UPPER_CAMEL, getSimpleName(element));
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(TypeNames.PRODUCED)
? 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) ? MAP_PROVIDER_FACTORY : MAP_FACTORY;
case PRODUCTION:
return mapType.valuesAreFrameworkType()
? mapType.valuesAreTypeOf(PRODUCER)
? MAP_OF_PRODUCER_PRODUCER
: MAP_OF_PRODUCED_PRODUCER
: MAP_PRODUCER;
default:
throw new IllegalArgumentException(binding.bindingType().toString());
}
}
public static ImmutableList