| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 1 | /* |
| ronshapiro | 5dde42d | 2016-06-17 09:03:35 -0700 | [diff] [blame] | 2 | * Copyright (C) 2014 The Dagger Authors. |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 3 | * |
| ronshapiro | 3a179ec | 2017-04-14 09:22:17 -0700 | [diff] [blame] | 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 |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| ronshapiro | 3a179ec | 2017-04-14 09:22:17 -0700 | [diff] [blame] | 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. |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 15 | */ |
| dpb | 1b65b6a | 2016-07-11 12:11:24 -0700 | [diff] [blame] | 16 | |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 17 | package dagger.internal.codegen; |
| 18 | |
| gak | 645274e | 2017-01-04 11:34:17 -0800 | [diff] [blame] | 19 | import static com.google.common.base.CaseFormat.LOWER_CAMEL; |
| gak | e55f074 | 2016-07-12 15:36:42 -0700 | [diff] [blame] | 20 | import static com.google.common.base.CaseFormat.UPPER_CAMEL; |
| 21 | import static com.google.common.base.Preconditions.checkArgument; |
| gak | 645274e | 2017-01-04 11:34:17 -0800 | [diff] [blame] | 22 | import static com.google.common.base.Verify.verify; |
| gak | 4d86019 | 2016-10-13 23:41:00 -0700 | [diff] [blame] | 23 | import static dagger.internal.codegen.ContributionBinding.Kind.INJECTION; |
| ronshapiro | 2c9ec49 | 2017-05-26 15:03:38 -0700 | [diff] [blame] | 24 | import static dagger.internal.codegen.ContributionBinding.Kind.SYNTHETIC_MULTIBOUND_SET; |
| dpb | ffd98f6 | 2016-12-20 10:05:16 -0800 | [diff] [blame] | 25 | import static dagger.internal.codegen.Optionals.optionalComparator; |
| gak | e55f074 | 2016-07-12 15:36:42 -0700 | [diff] [blame] | 26 | import static dagger.internal.codegen.TypeNames.DOUBLE_CHECK; |
| ronshapiro | 2c9ec49 | 2017-05-26 15:03:38 -0700 | [diff] [blame] | 27 | import static dagger.internal.codegen.TypeNames.MAP_FACTORY; |
| 28 | import static dagger.internal.codegen.TypeNames.MAP_OF_PRODUCED_PRODUCER; |
| 29 | import static dagger.internal.codegen.TypeNames.MAP_OF_PRODUCER_PRODUCER; |
| 30 | import static dagger.internal.codegen.TypeNames.MAP_PRODUCER; |
| 31 | import static dagger.internal.codegen.TypeNames.MAP_PROVIDER_FACTORY; |
| gak | e55f074 | 2016-07-12 15:36:42 -0700 | [diff] [blame] | 32 | import static dagger.internal.codegen.TypeNames.PROVIDER_OF_LAZY; |
| ronshapiro | 2c9ec49 | 2017-05-26 15:03:38 -0700 | [diff] [blame] | 33 | import static dagger.internal.codegen.TypeNames.SET_FACTORY; |
| 34 | import static dagger.internal.codegen.TypeNames.SET_OF_PRODUCED_PRODUCER; |
| 35 | import static dagger.internal.codegen.TypeNames.SET_PRODUCER; |
| ronshapiro | 0b1bcc6 | 2017-05-26 11:14:20 -0700 | [diff] [blame] | 36 | import static dagger.internal.codegen.Util.toImmutableList; |
| dpb | ffd98f6 | 2016-12-20 10:05:16 -0800 | [diff] [blame] | 37 | import static java.util.Comparator.comparing; |
| gak | 645274e | 2017-01-04 11:34:17 -0800 | [diff] [blame] | 38 | import static javax.lang.model.SourceVersion.isName; |
| gak | e55f074 | 2016-07-12 15:36:42 -0700 | [diff] [blame] | 39 | |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 40 | import com.google.common.base.CaseFormat; |
| ronshapiro | 732e502 | 2016-01-07 12:10:55 -0800 | [diff] [blame] | 41 | import com.google.common.base.Joiner; |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 42 | import com.google.common.collect.FluentIterable; |
| sameb | 0d49be8 | 2015-01-22 17:29:48 -0800 | [diff] [blame] | 43 | import com.google.common.collect.ImmutableList; |
| Christian Edward Gruber | 2a90069 | 2014-07-01 22:28:26 -0700 | [diff] [blame] | 44 | import com.google.common.collect.ImmutableMap; |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 45 | import com.google.common.collect.ImmutableSet; |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 46 | import com.google.common.collect.Iterables; |
| ronshapiro | 6475f47 | 2016-02-02 07:03:10 -0800 | [diff] [blame] | 47 | import com.squareup.javapoet.ClassName; |
| ronshapiro | 732e502 | 2016-01-07 12:10:55 -0800 | [diff] [blame] | 48 | import com.squareup.javapoet.CodeBlock; |
| ronshapiro | 6475f47 | 2016-02-02 07:03:10 -0800 | [diff] [blame] | 49 | import com.squareup.javapoet.ParameterizedTypeName; |
| 50 | import com.squareup.javapoet.TypeName; |
| ronshapiro | 9540fb2 | 2016-01-13 09:46:47 -0800 | [diff] [blame] | 51 | import com.squareup.javapoet.TypeVariableName; |
| ronshapiro | 2c9ec49 | 2017-05-26 15:03:38 -0700 | [diff] [blame] | 52 | import dagger.internal.MapFactory; |
| 53 | import dagger.internal.MapProviderFactory; |
| 54 | import dagger.internal.SetFactory; |
| 55 | import dagger.producers.Produced; |
| 56 | import dagger.producers.internal.MapOfProducerProducer; |
| 57 | import dagger.producers.internal.MapProducer; |
| 58 | import dagger.producers.internal.SetOfProducedProducer; |
| 59 | import dagger.producers.internal.SetProducer; |
| Ron Shapiro | 5f21a80 | 2016-09-21 10:23:55 -0400 | [diff] [blame] | 60 | import java.util.Comparator; |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 61 | import java.util.Iterator; |
| ronshapiro | 0b1bcc6 | 2017-05-26 11:14:20 -0700 | [diff] [blame] | 62 | import java.util.List; |
| gak | 645274e | 2017-01-04 11:34:17 -0800 | [diff] [blame] | 63 | import javax.lang.model.SourceVersion; |
| gak | 6624110 | 2016-09-13 12:23:00 -0700 | [diff] [blame] | 64 | import javax.lang.model.element.Element; |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 65 | import javax.lang.model.element.TypeElement; |
| ronshapiro | 9540fb2 | 2016-01-13 09:46:47 -0800 | [diff] [blame] | 66 | import javax.lang.model.element.TypeParameterElement; |
| Gregory Kick | 03c3c2d | 2014-06-18 17:05:47 -0700 | [diff] [blame] | 67 | |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 68 | /** |
| 69 | * Utilities for generating files. |
| 70 | * |
| 71 | * @author Gregory Kick |
| 72 | * @since 2.0 |
| 73 | */ |
| 74 | class SourceFiles { |
| ronshapiro | 732e502 | 2016-01-07 12:10:55 -0800 | [diff] [blame] | 75 | |
| ronshapiro | 6475f47 | 2016-02-02 07:03:10 -0800 | [diff] [blame] | 76 | private static final Joiner CLASS_FILE_NAME_JOINER = Joiner.on('_'); |
| ronshapiro | 732e502 | 2016-01-07 12:10:55 -0800 | [diff] [blame] | 77 | |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 78 | /** |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 79 | * Sorts {@link DependencyRequest} instances in an order likely to reflect their logical |
| 80 | * importance. |
| 81 | */ |
| Ron Shapiro | 5f21a80 | 2016-09-21 10:23:55 -0400 | [diff] [blame] | 82 | static final Comparator<DependencyRequest> DEPENDENCY_ORDERING = |
| 83 | // put fields before parameters |
| dpb | ffd98f6 | 2016-12-20 10:05:16 -0800 | [diff] [blame] | 84 | comparing( |
| 85 | (DependencyRequest request) -> request.requestElement().map(Element::getKind), |
| Ron Shapiro | 5f21a80 | 2016-09-21 10:23:55 -0400 | [diff] [blame] | 86 | optionalComparator()) |
| 87 | // order by dependency kind |
| 88 | .thenComparing(DependencyRequest::kind) |
| 89 | // then sort by name |
| 90 | .thenComparing( |
| dpb | ffd98f6 | 2016-12-20 10:05:16 -0800 | [diff] [blame] | 91 | request -> |
| 92 | request.requestElement().map(element -> element.getSimpleName().toString()), |
| Ron Shapiro | 5f21a80 | 2016-09-21 10:23:55 -0400 | [diff] [blame] | 93 | optionalComparator()); |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 94 | |
| sameb | 2ea676a | 2015-01-15 10:20:24 -0800 | [diff] [blame] | 95 | /** |
| dpb | 5719880 | 2015-12-17 12:18:15 -0800 | [diff] [blame] | 96 | * Generates names and keys for the factory class fields needed to hold the framework classes for |
| 97 | * all of the dependencies of {@code binding}. It is responsible for choosing a name that |
| 98 | * |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 99 | * <ul> |
| dpb | 5719880 | 2015-12-17 12:18:15 -0800 | [diff] [blame] | 100 | * <li>represents all of the dependency requests for this key |
| 101 | * <li>is <i>probably</i> associated with the type being bound |
| 102 | * <li>is unique within the class |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 103 | * </ul> |
| Ron Shapiro | 5f21a80 | 2016-09-21 10:23:55 -0400 | [diff] [blame] | 104 | * |
| dpb | 5719880 | 2015-12-17 12:18:15 -0800 | [diff] [blame] | 105 | * @param binding must be an unresolved binding (type parameters must match its type element's) |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 106 | */ |
| gak | 59d2c99 | 2015-01-14 14:33:46 -0800 | [diff] [blame] | 107 | static ImmutableMap<BindingKey, FrameworkField> generateBindingFieldsForDependencies( |
| dpb | f6be7d6 | 2016-01-22 11:43:21 -0800 | [diff] [blame] | 108 | Binding binding) { |
| 109 | checkArgument(!binding.unresolved().isPresent(), "binding must be unresolved: %s", binding); |
| 110 | |
| gak | 59d2c99 | 2015-01-14 14:33:46 -0800 | [diff] [blame] | 111 | ImmutableMap.Builder<BindingKey, FrameworkField> bindingFields = ImmutableMap.builder(); |
| gak | 75b9b72 | 2016-09-29 15:48:40 -0700 | [diff] [blame] | 112 | for (Binding.DependencyAssociation dependencyAssociation : binding.dependencyAssociations()) { |
| 113 | FrameworkDependency frameworkDependency = dependencyAssociation.frameworkDependency(); |
| dpb | f6be7d6 | 2016-01-22 11:43:21 -0800 | [diff] [blame] | 114 | bindingFields.put( |
| 115 | frameworkDependency.bindingKey(), |
| dpb | d289ddc | 2016-04-28 13:09:11 -0700 | [diff] [blame] | 116 | FrameworkField.create( |
| 117 | ClassName.get(frameworkDependency.frameworkClass()), |
| 118 | TypeName.get(frameworkDependency.bindingKey().key().type()), |
| gak | 75b9b72 | 2016-09-29 15:48:40 -0700 | [diff] [blame] | 119 | fieldNameForDependency(dependencyAssociation.dependencyRequests()))); |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 120 | } |
| beder | 3e950f3 | 2014-12-19 17:48:47 -0800 | [diff] [blame] | 121 | return bindingFields.build(); |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 122 | } |
| 123 | |
| gak | 75b9b72 | 2016-09-29 15:48:40 -0700 | [diff] [blame] | 124 | private static String fieldNameForDependency(ImmutableSet<DependencyRequest> dependencyRequests) { |
| dpb | f6be7d6 | 2016-01-22 11:43:21 -0800 | [diff] [blame] | 125 | // collect together all of the names that we would want to call the provider |
| 126 | ImmutableSet<String> dependencyNames = |
| gak | 75b9b72 | 2016-09-29 15:48:40 -0700 | [diff] [blame] | 127 | FluentIterable.from(dependencyRequests).transform(new DependencyVariableNamer()).toSet(); |
| dpb | f6be7d6 | 2016-01-22 11:43:21 -0800 | [diff] [blame] | 128 | |
| 129 | if (dependencyNames.size() == 1) { |
| 130 | // if there's only one name, great! use it! |
| 131 | return Iterables.getOnlyElement(dependencyNames); |
| 132 | } else { |
| 133 | // in the event that a field is being used for a bunch of deps with different names, |
| 134 | // add all the names together with "And"s in the middle. E.g.: stringAndS |
| 135 | Iterator<String> namesIterator = dependencyNames.iterator(); |
| 136 | String first = namesIterator.next(); |
| 137 | StringBuilder compositeNameBuilder = new StringBuilder(first); |
| 138 | while (namesIterator.hasNext()) { |
| 139 | compositeNameBuilder |
| 140 | .append("And") |
| 141 | .append(CaseFormat.LOWER_CAMEL.to(UPPER_CAMEL, namesIterator.next())); |
| 142 | } |
| 143 | return compositeNameBuilder.toString(); |
| 144 | } |
| 145 | } |
| 146 | |
| ronshapiro | 732e502 | 2016-01-07 12:10:55 -0800 | [diff] [blame] | 147 | static CodeBlock frameworkTypeUsageStatement( |
| 148 | CodeBlock frameworkTypeMemberSelect, DependencyRequest.Kind dependencyKind) { |
| 149 | switch (dependencyKind) { |
| 150 | case LAZY: |
| ronshapiro | b9158d8 | 2016-04-13 11:00:56 -0700 | [diff] [blame] | 151 | return CodeBlock.of("$T.lazy($L)", DOUBLE_CHECK, frameworkTypeMemberSelect); |
| ronshapiro | 732e502 | 2016-01-07 12:10:55 -0800 | [diff] [blame] | 152 | case INSTANCE: |
| 153 | case FUTURE: |
| ronshapiro | b9158d8 | 2016-04-13 11:00:56 -0700 | [diff] [blame] | 154 | return CodeBlock.of("$L.get()", frameworkTypeMemberSelect); |
| ronshapiro | 732e502 | 2016-01-07 12:10:55 -0800 | [diff] [blame] | 155 | case PROVIDER: |
| 156 | case PRODUCER: |
| 157 | case MEMBERS_INJECTOR: |
| dpb | d8d950a | 2016-08-30 09:24:37 -0700 | [diff] [blame] | 158 | return frameworkTypeMemberSelect; |
| dpb | c9bd6d8 | 2016-04-19 07:25:06 -0700 | [diff] [blame] | 159 | case PROVIDER_OF_LAZY: |
| 160 | return CodeBlock.of("$T.create($L)", PROVIDER_OF_LAZY, frameworkTypeMemberSelect); |
| dpb | d8d950a | 2016-08-30 09:24:37 -0700 | [diff] [blame] | 161 | default: // including PRODUCED |
| 162 | throw new AssertionError(dependencyKind); |
| ronshapiro | 732e502 | 2016-01-07 12:10:55 -0800 | [diff] [blame] | 163 | } |
| 164 | } |
| 165 | |
| dpb | 6bd55de | 2015-09-28 07:58:09 -0700 | [diff] [blame] | 166 | /** |
| 167 | * Returns the generated factory or members injector name for a binding. |
| 168 | */ |
| 169 | static ClassName generatedClassNameForBinding(Binding binding) { |
| 170 | switch (binding.bindingType()) { |
| Christian Edward Gruber | 4aec5ba | 2014-05-20 19:37:11 -0700 | [diff] [blame] | 171 | case PROVISION: |
| dpb | 6bd55de | 2015-09-28 07:58:09 -0700 | [diff] [blame] | 172 | case PRODUCTION: |
| 173 | ContributionBinding contribution = (ContributionBinding) binding; |
| dpb | dd27603 | 2016-07-11 09:34:43 -0700 | [diff] [blame] | 174 | checkArgument(contribution.bindingTypeElement().isPresent()); |
| 175 | ClassName enclosingClassName = ClassName.get(contribution.bindingTypeElement().get()); |
| dpb | 6bd55de | 2015-09-28 07:58:09 -0700 | [diff] [blame] | 176 | switch (contribution.bindingKind()) { |
| 177 | case INJECTION: |
| 178 | case PROVISION: |
| Ron Shapiro | 5f21a80 | 2016-09-21 10:23:55 -0400 | [diff] [blame] | 179 | case PRODUCTION: |
| dpb | 6bd55de | 2015-09-28 07:58:09 -0700 | [diff] [blame] | 180 | return enclosingClassName |
| 181 | .topLevelClassName() |
| ronshapiro | 6475f47 | 2016-02-02 07:03:10 -0800 | [diff] [blame] | 182 | .peerClass( |
| ronshapiro | 23527f6 | 2016-04-20 10:33:08 -0700 | [diff] [blame] | 183 | classFileName(enclosingClassName) |
| dpb | 6bd55de | 2015-09-28 07:58:09 -0700 | [diff] [blame] | 184 | + "_" |
| 185 | + factoryPrefix(contribution) |
| 186 | + "Factory"); |
| 187 | |
| 188 | default: |
| 189 | throw new AssertionError(); |
| 190 | } |
| 191 | |
| 192 | case MEMBERS_INJECTION: |
| dpb | 4955ef9 | 2016-04-29 12:31:14 -0700 | [diff] [blame] | 193 | return membersInjectorNameForType( |
| 194 | ((MembersInjectionBinding) binding).membersInjectedType()); |
| dpb | 6bd55de | 2015-09-28 07:58:09 -0700 | [diff] [blame] | 195 | |
| Christian Edward Gruber | 4aec5ba | 2014-05-20 19:37:11 -0700 | [diff] [blame] | 196 | default: |
| 197 | throw new AssertionError(); |
| 198 | } |
| 199 | } |
| Christian Edward Gruber | 791bd29 | 2014-05-20 19:36:41 -0700 | [diff] [blame] | 200 | |
| gak | 4d86019 | 2016-10-13 23:41:00 -0700 | [diff] [blame] | 201 | static TypeName parameterizedGeneratedTypeNameForBinding(Binding binding) { |
| ronshapiro | 6475f47 | 2016-02-02 07:03:10 -0800 | [diff] [blame] | 202 | ClassName className = generatedClassNameForBinding(binding); |
| gak | 4d86019 | 2016-10-13 23:41:00 -0700 | [diff] [blame] | 203 | ImmutableList<TypeVariableName> typeParameters = bindingTypeElementTypeVariableNames(binding); |
| 204 | return typeParameters.isEmpty() |
| 205 | ? className |
| 206 | : ParameterizedTypeName.get(className, Iterables.toArray(typeParameters, TypeName.class)); |
| Christian Edward Gruber | 10876b0 | 2014-06-01 11:24:55 -0700 | [diff] [blame] | 207 | } |
| 208 | |
| ronshapiro | 6475f47 | 2016-02-02 07:03:10 -0800 | [diff] [blame] | 209 | static ClassName membersInjectorNameForType(TypeElement typeElement) { |
| ronshapiro | a296c10 | 2016-01-14 12:33:42 -0800 | [diff] [blame] | 210 | return siblingClassName(typeElement, "_MembersInjector"); |
| ronshapiro | 732e502 | 2016-01-07 12:10:55 -0800 | [diff] [blame] | 211 | } |
| 212 | |
| ronshapiro | 6475f47 | 2016-02-02 07:03:10 -0800 | [diff] [blame] | 213 | static String classFileName(ClassName className) { |
| ronshapiro | 732e502 | 2016-01-07 12:10:55 -0800 | [diff] [blame] | 214 | return CLASS_FILE_NAME_JOINER.join(className.simpleNames()); |
| 215 | } |
| 216 | |
| ronshapiro | 6475f47 | 2016-02-02 07:03:10 -0800 | [diff] [blame] | 217 | static ClassName generatedMonitoringModuleName( |
| ronshapiro | a296c10 | 2016-01-14 12:33:42 -0800 | [diff] [blame] | 218 | TypeElement componentElement) { |
| 219 | return siblingClassName(componentElement, "_MonitoringModule"); |
| 220 | } |
| 221 | |
| beder | 893f770 | 2016-02-17 05:22:50 -0800 | [diff] [blame] | 222 | static ClassName generatedProductionExecutorModuleName(TypeElement componentElement) { |
| 223 | return siblingClassName(componentElement, "_ProductionExecutorModule"); |
| 224 | } |
| 225 | |
| ronshapiro | 6475f47 | 2016-02-02 07:03:10 -0800 | [diff] [blame] | 226 | // TODO(ronshapiro): when JavaPoet migration is complete, replace the duplicated code |
| 227 | // which could use this. |
| 228 | private static ClassName siblingClassName(TypeElement typeElement, String suffix) { |
| 229 | ClassName className = ClassName.get(typeElement); |
| ronshapiro | 23527f6 | 2016-04-20 10:33:08 -0700 | [diff] [blame] | 230 | return className.topLevelClassName().peerClass(classFileName(className) + suffix); |
| beder | 0e6f248 | 2015-10-23 08:37:55 -0700 | [diff] [blame] | 231 | } |
| 232 | |
| ronshapiro | 2c9ec49 | 2017-05-26 15:03:38 -0700 | [diff] [blame] | 233 | /** |
| 234 | * The {@link java.util.Set} factory class name appropriate for set bindings. |
| 235 | * |
| 236 | * <ul> |
| 237 | * <li>{@link SetFactory} for provision bindings. |
| 238 | * <li>{@link SetProducer} for production bindings for {@code Set<T>}. |
| 239 | * <li>{@link SetOfProducedProducer} for production bindings for {@code Set<Produced<T>>}. |
| 240 | * </ul> |
| 241 | */ |
| 242 | static ClassName setFactoryClassName(ContributionBinding binding) { |
| 243 | checkArgument(binding.bindingKind().equals(SYNTHETIC_MULTIBOUND_SET)); |
| 244 | if (binding.bindingType().equals(BindingType.PROVISION)) { |
| 245 | return SET_FACTORY; |
| 246 | } else { |
| 247 | SetType setType = SetType.from(binding.key()); |
| 248 | return setType.elementsAreTypeOf(Produced.class) ? SET_OF_PRODUCED_PRODUCER : SET_PRODUCER; |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | /** |
| 253 | * The {@link java.util.Map}-of-value factory class name appropriate for map bindings. |
| 254 | * |
| 255 | * <ul> |
| 256 | * <li>{@link MapFactory} for provision bindings. |
| 257 | * <li>{@link MapProducer} for production bindings. |
| 258 | * </ul> |
| 259 | */ |
| 260 | static ClassName mapFactoryClassName(ContributionBinding binding) { |
| 261 | switch (binding.bindingType()) { |
| 262 | case PRODUCTION: |
| 263 | return MapType.from(binding.key()).valuesAreTypeOf(Produced.class) |
| 264 | ? MAP_OF_PRODUCED_PRODUCER : MAP_PRODUCER; |
| 265 | |
| 266 | case PROVISION: |
| 267 | return MAP_FACTORY; |
| 268 | |
| 269 | default: |
| 270 | throw new AssertionError(binding.toString()); |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | /** |
| 275 | * The {@link java.util.Map}-of-framework factory class name appropriate for map bindings. |
| 276 | * |
| 277 | * <ul> |
| 278 | * <li>{@link MapProviderFactory} for provision bindings. |
| 279 | * <li>{@link MapOfProducerProducer} for production bindings. |
| 280 | * </ul> |
| 281 | */ |
| 282 | static ClassName frameworkMapFactoryClassName(BindingType bindingType) { |
| 283 | return bindingType.equals(BindingType.PRODUCTION) |
| 284 | ? MAP_OF_PRODUCER_PRODUCER : MAP_PROVIDER_FACTORY; |
| 285 | } |
| 286 | |
| dpb | 6bd55de | 2015-09-28 07:58:09 -0700 | [diff] [blame] | 287 | private static String factoryPrefix(ContributionBinding binding) { |
| Christian Edward Gruber | 4aec5ba | 2014-05-20 19:37:11 -0700 | [diff] [blame] | 288 | switch (binding.bindingKind()) { |
| 289 | case INJECTION: |
| Christian Edward Gruber | 791bd29 | 2014-05-20 19:36:41 -0700 | [diff] [blame] | 290 | return ""; |
| Christian Edward Gruber | 791bd29 | 2014-05-20 19:36:41 -0700 | [diff] [blame] | 291 | |
| dpb | 6bd55de | 2015-09-28 07:58:09 -0700 | [diff] [blame] | 292 | case PROVISION: |
| Ron Shapiro | 5f21a80 | 2016-09-21 10:23:55 -0400 | [diff] [blame] | 293 | case PRODUCTION: |
| dpb | 6bd55de | 2015-09-28 07:58:09 -0700 | [diff] [blame] | 294 | return CaseFormat.LOWER_CAMEL.to( |
| dpb | dd27603 | 2016-07-11 09:34:43 -0700 | [diff] [blame] | 295 | UPPER_CAMEL, binding.bindingElement().get().getSimpleName().toString()); |
| dpb | 6bd55de | 2015-09-28 07:58:09 -0700 | [diff] [blame] | 296 | |
| beder | 72466bc | 2014-12-08 10:51:05 -0800 | [diff] [blame] | 297 | default: |
| 298 | throw new IllegalArgumentException(); |
| 299 | } |
| 300 | } |
| 301 | |
| ronshapiro | 9540fb2 | 2016-01-13 09:46:47 -0800 | [diff] [blame] | 302 | static ImmutableList<TypeVariableName> bindingTypeElementTypeVariableNames(Binding binding) { |
| gak | 4d86019 | 2016-10-13 23:41:00 -0700 | [diff] [blame] | 303 | if (binding instanceof ContributionBinding) { |
| 304 | ContributionBinding contributionBinding = (ContributionBinding) binding; |
| 305 | if (!contributionBinding.bindingKind().equals(INJECTION) |
| 306 | && !contributionBinding.requiresModuleInstance()) { |
| 307 | return ImmutableList.of(); |
| 308 | } |
| 309 | } |
| ronshapiro | 0b1bcc6 | 2017-05-26 11:14:20 -0700 | [diff] [blame] | 310 | List<? extends TypeParameterElement> typeParameters = |
| 311 | binding.bindingTypeElement().get().getTypeParameters(); |
| 312 | return typeParameters.stream().map(TypeVariableName::get).collect(toImmutableList()); |
| ronshapiro | 9540fb2 | 2016-01-13 09:46:47 -0800 | [diff] [blame] | 313 | } |
| 314 | |
| gak | 645274e | 2017-01-04 11:34:17 -0800 | [diff] [blame] | 315 | /** |
| 316 | * Returns a name to be used for variables of the given {@linkplain TypeElement type}. Prefer |
| 317 | * semantically meaningful variable names, but if none can be derived, this will produce something |
| 318 | * readable. |
| 319 | */ |
| 320 | // TODO(gak): maybe this should be a function of TypeMirrors instead of Elements? |
| 321 | static String simpleVariableName(TypeElement typeElement) { |
| 322 | String candidateName = UPPER_CAMEL.to(LOWER_CAMEL, typeElement.getSimpleName().toString()); |
| 323 | String variableName = protectAgainstKeywords(candidateName); |
| 324 | verify(isName(variableName), "'%s' was expected to be a valid variable name"); |
| 325 | return variableName; |
| 326 | } |
| 327 | |
| 328 | private static String protectAgainstKeywords(String candidateName) { |
| 329 | switch (candidateName) { |
| 330 | case "package": |
| 331 | return "pkg"; |
| 332 | case "boolean": |
| 333 | return "b"; |
| 334 | case "double": |
| 335 | return "d"; |
| 336 | case "byte": |
| 337 | return "b"; |
| 338 | case "int": |
| 339 | return "i"; |
| 340 | case "short": |
| 341 | return "s"; |
| 342 | case "char": |
| 343 | return "c"; |
| 344 | case "void": |
| 345 | return "v"; |
| 346 | case "class": |
| 347 | return "clazz"; |
| 348 | case "float": |
| 349 | return "f"; |
| 350 | case "long": |
| 351 | return "l"; |
| 352 | default: |
| 353 | return SourceVersion.isKeyword(candidateName) ? candidateName + '_' : candidateName; |
| 354 | } |
| 355 | } |
| 356 | |
| Christian Edward Gruber | fbb8e4b | 2014-04-15 14:02:34 -0700 | [diff] [blame] | 357 | private SourceFiles() {} |
| 358 | } |