• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Dagger Authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package dagger.internal.codegen.binding;
18 
19 import static androidx.room.compiler.processing.XTypeKt.isArray;
20 import static com.google.common.base.CaseFormat.LOWER_CAMEL;
21 import static com.google.common.base.CaseFormat.UPPER_CAMEL;
22 import static dagger.internal.codegen.binding.SourceFiles.protectAgainstKeywords;
23 import static dagger.internal.codegen.xprocessing.XElements.getSimpleName;
24 import static dagger.internal.codegen.xprocessing.XTypes.isDeclared;
25 import static dagger.internal.codegen.xprocessing.XTypes.isPrimitive;
26 
27 import androidx.room.compiler.processing.XArrayType;
28 import androidx.room.compiler.processing.XType;
29 import androidx.room.compiler.processing.XTypeElement;
30 import com.google.common.collect.ImmutableSet;
31 import dagger.spi.model.DependencyRequest;
32 import dagger.spi.model.Key;
33 import java.util.Iterator;
34 
35 /**
36  * Suggests a variable name for a type based on a {@link Key}. Prefer {@link
37  * DependencyVariableNamer} for cases where a specific {@link DependencyRequest} is present.
38  */
39 public final class KeyVariableNamer {
40   /** Simple names that are very common. Inspired by https://errorprone.info/bugpattern/BadImport */
41   private static final ImmutableSet<String> VERY_SIMPLE_NAMES =
42       ImmutableSet.of(
43           "Builder",
44           "Factory",
45           "Component",
46           "Subcomponent",
47           "Injector");
48 
KeyVariableNamer()49   private KeyVariableNamer() {}
50 
name(Key key)51   public static String name(Key key) {
52     if (key.multibindingContributionIdentifier().isPresent()) {
53       return key.multibindingContributionIdentifier().get().bindingElement();
54     }
55 
56     StringBuilder builder = new StringBuilder();
57 
58     if (key.qualifier().isPresent()) {
59       // TODO(gak): Use a better name for fields with qualifiers with members.
60       builder.append(key.qualifier().get().java().getAnnotationType().asElement().getSimpleName());
61     }
62 
63     typeNamer(key.type().xprocessing(), builder);
64     return protectAgainstKeywords(UPPER_CAMEL.to(LOWER_CAMEL, builder.toString()));
65   }
66 
typeNamer(XType type, StringBuilder builder)67   private static void typeNamer(XType type, StringBuilder builder) {
68     if (isDeclared(type)) {
69       XTypeElement element = type.getTypeElement();
70       if (element.isNested() && VERY_SIMPLE_NAMES.contains(getSimpleName(element))) {
71         builder.append(getSimpleName(element.getEnclosingTypeElement()));
72       }
73 
74       builder.append(getSimpleName(element));
75       Iterator<? extends XType> argumentIterator = type.getTypeArguments().iterator();
76       if (argumentIterator.hasNext()) {
77         builder.append("Of");
78         XType first = argumentIterator.next();
79         typeNamer(first, builder);
80         while (argumentIterator.hasNext()) {
81           builder.append("And");
82           typeNamer(argumentIterator.next(), builder);
83         }
84       }
85     } else if (isPrimitive(type)) {
86       builder.append(LOWER_CAMEL.to(UPPER_CAMEL, type.toString()));
87     } else if (isArray(type)) {
88       typeNamer(((XArrayType) type).getComponentType(), builder);
89       builder.append("Array");
90     }
91   }
92 }
93