diff --git a/java/dagger/internal/codegen/binding/MapKeys.java b/java/dagger/internal/codegen/binding/MapKeys.java index a53fa1bf00a..0537c4cb653 100644 --- a/java/dagger/internal/codegen/binding/MapKeys.java +++ b/java/dagger/internal/codegen/binding/MapKeys.java @@ -219,6 +219,12 @@ public static boolean useLazyClassKey(Binding binding, BindingGraph graph) { return false; } + public static CodeBlock getLazyClassMapKeyExpression(ContributionBinding contributionBinding) { + ClassName proxyClassName = + lazyClassKeyProxyClassName(XElements.asMethod(contributionBinding.bindingElement().get())); + return CodeBlock.of("$T.$N", proxyClassName, LAZY_CLASS_KEY_NAME_FIELD); + } + public static ClassName lazyClassKeyProxyClassName(XMethodElement methodElement) { return elementBasedClassName(methodElement, "_LazyMapKey"); } diff --git a/java/dagger/internal/codegen/writing/LazyClassKeyProviders.java b/java/dagger/internal/codegen/writing/LazyClassKeyProviders.java deleted file mode 100644 index b1a216b8e1b..00000000000 --- a/java/dagger/internal/codegen/writing/LazyClassKeyProviders.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2024 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.writing; - -import static dagger.internal.codegen.base.MapKeyAccessibility.isMapKeyAccessibleFrom; -import static javax.lang.model.element.Modifier.FINAL; -import static javax.lang.model.element.Modifier.PRIVATE; -import static javax.lang.model.element.Modifier.STATIC; - -import androidx.room.compiler.processing.XAnnotation; -import com.google.common.base.Preconditions; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.CodeBlock; -import com.squareup.javapoet.FieldSpec; -import com.squareup.javapoet.TypeSpec; -import dagger.internal.codegen.base.UniqueNameSet; -import dagger.internal.codegen.javapoet.TypeNames; -import dagger.internal.codegen.model.Key; -import java.util.LinkedHashMap; -import java.util.Map; -import javax.inject.Inject; - -/** - * Keeps track of all providers for DaggerMap keys. - * - *

Generated class looks like below: - * - *

{@code
- *  @IdentifierNameString
- *  static final class  LazyClassKeyProvider {
- *    static final String com_google_foo_Bar = "com.google.foo.Bar";
- *    @KeepFieldType static final com.google.foo.Bar com_google_foo_Bar2;
- * }
- * }
- */ -public final class LazyClassKeyProviders { - @PerGeneratedFile - static final class LazyClassKeyProviderCache { - // Map key to its corresponding the field reference expression from LazyClassKeyProvider. - final Map mapKeyToProvider = new LinkedHashMap<>(); - private final Map entries = new LinkedHashMap<>(); - private final Map keepClassNamesFields = new LinkedHashMap<>(); - private final UniqueNameSet uniqueFieldNames = new UniqueNameSet(); - private ClassName mapKeyProviderType; - - @Inject - LazyClassKeyProviderCache() {} - - private CodeBlock getMapKeyExpression(Key key) { - Preconditions.checkArgument( - key.multibindingContributionIdentifier().isPresent() - && key.multibindingContributionIdentifier() - .get() - .bindingMethod() - .xprocessing() - .hasAnnotation(TypeNames.LAZY_CLASS_KEY)); - XAnnotation lazyClassKeyAnnotation = getLazyClassKeyAnnotation(key); - ClassName lazyClassKey = getLazyClassKey(lazyClassKeyAnnotation); - if (mapKeyToProvider.containsKey(lazyClassKey)) { - return mapKeyToProvider.get(lazyClassKey); - } - addField(lazyClassKey, lazyClassKeyAnnotation, mapKeyProviderType.packageName()); - mapKeyToProvider.put( - lazyClassKey, CodeBlock.of("$T.$N", mapKeyProviderType, entries.get(lazyClassKey))); - return mapKeyToProvider.get(lazyClassKey); - } - - private ClassName getLazyClassKey(XAnnotation lazyClassKeyAnnotation) { - return lazyClassKeyAnnotation.getAsType("value").getTypeElement().getClassName(); - } - - private XAnnotation getLazyClassKeyAnnotation(Key key) { - return key.multibindingContributionIdentifier() - .get() - .bindingMethod() - .xprocessing() - .getAnnotation(TypeNames.LAZY_CLASS_KEY); - } - - private void addField( - ClassName lazyClassKey, XAnnotation lazyClassKeyAnnotation, String accessingPackage) { - entries.put( - lazyClassKey, - FieldSpec.builder( - TypeNames.STRING, - uniqueFieldNames.getUniqueName(lazyClassKey.canonicalName().replace('.', '_'))) - // TODO(b/217435141): Leave the field as non-final. We will apply - // @IdentifierNameString on the field, which doesn't work well with static final - // fields. - .addModifiers(STATIC) - .initializer("$S", lazyClassKey.reflectionName()) - .build()); - // To be able to apply -includedescriptorclasses rule to keep the class names referenced by - // LazyClassKey, we need to generate fields that uses those classes as type in - // LazyClassKeyProvider. For types that are not accessible from the generated component, we - // generate fields in the proxy class. - // Note: the generated field should not be initialized to avoid class loading. - if (isMapKeyAccessibleFrom(lazyClassKeyAnnotation, accessingPackage)) { - keepClassNamesFields.put( - lazyClassKey, - FieldSpec.builder( - lazyClassKey, - uniqueFieldNames.getUniqueName(lazyClassKey.canonicalName().replace('.', '_'))) - .addAnnotation(TypeNames.KEEP_FIELD_TYPE) - .build()); - } - } - - private TypeSpec build() { - return TypeSpec.classBuilder(mapKeyProviderType) - .addAnnotation(TypeNames.IDENTIFIER_NAME_STRING) - .addModifiers(PRIVATE, STATIC, FINAL) - .addFields(entries.values()) - .addFields(keepClassNamesFields.values()) - .build(); - } - } - - public static final String MAP_KEY_PROVIDER_NAME = "LazyClassKeyProvider"; - private final GeneratedImplementation topLevelImplementation; - private final LazyClassKeyProviderCache cache; - - @Inject - LazyClassKeyProviders( - @TopLevel GeneratedImplementation topLevelImplementation, LazyClassKeyProviderCache cache) { - this.topLevelImplementation = topLevelImplementation; - this.cache = cache; - } - - /** Returns a reference to a field in LazyClassKeyProvider that corresponds to this binding. */ - CodeBlock getMapKeyExpression(Key key) { - // This is for avoid generating empty LazyClassKeyProvider. - if (cache.entries.isEmpty()) { - String name = topLevelImplementation.getUniqueClassName(MAP_KEY_PROVIDER_NAME); - cache.mapKeyProviderType = topLevelImplementation.name().nestedClass(name); - topLevelImplementation.addTypeSupplier(this::build); - } - return cache.getMapKeyExpression(key); - } - - private TypeSpec build() { - return cache.build(); - } -} diff --git a/java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java b/java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java index 1e186b5cd24..892eba963aa 100644 --- a/java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java +++ b/java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java @@ -17,6 +17,7 @@ package dagger.internal.codegen.writing; import static com.google.common.base.Preconditions.checkNotNull; +import static dagger.internal.codegen.binding.MapKeys.getLazyClassMapKeyExpression; import static dagger.internal.codegen.binding.MapKeys.getMapKeyExpression; import static dagger.internal.codegen.binding.SourceFiles.mapFactoryClassName; @@ -43,12 +44,10 @@ final class MapFactoryCreationExpression extends MultibindingFactoryCreationExpr private final BindingGraph graph; private final MultiboundMapBinding binding; private final boolean useLazyClassKey; - private final LazyClassKeyProviders lazyClassKeyProviders; @AssistedInject MapFactoryCreationExpression( @Assisted MultiboundMapBinding binding, - LazyClassKeyProviders lazyClassKeyProviders, XProcessingEnv processingEnv, ComponentImplementation componentImplementation, ComponentRequestRepresentations componentRequestRepresentations, @@ -59,7 +58,6 @@ final class MapFactoryCreationExpression extends MultibindingFactoryCreationExpr this.componentImplementation = componentImplementation; this.graph = graph; this.useLazyClassKey = MapKeys.useLazyClassKey(binding, graph); - this.lazyClassKeyProviders = lazyClassKeyProviders; } @Override @@ -83,7 +81,7 @@ public CodeBlock creationExpression() { builder.add( ".put($L, $L)", useLazyClassKey - ? lazyClassKeyProviders.getMapKeyExpression(dependency.key()) + ? getLazyClassMapKeyExpression(graph.contributionBinding(dependency.key())) : getMapKeyExpression( contributionBinding, componentImplementation.name(), processingEnv), multibindingDependencyExpression(dependency)); diff --git a/java/dagger/internal/codegen/writing/MapRequestRepresentation.java b/java/dagger/internal/codegen/writing/MapRequestRepresentation.java index ae11ea8c279..a870f669f0a 100644 --- a/java/dagger/internal/codegen/writing/MapRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/MapRequestRepresentation.java @@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.internal.codegen.binding.BindingRequest.bindingRequest; +import static dagger.internal.codegen.binding.MapKeys.getLazyClassMapKeyExpression; import static dagger.internal.codegen.binding.MapKeys.getMapKeyExpression; import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock; import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom; @@ -56,12 +57,10 @@ final class MapRequestRepresentation extends RequestRepresentation { private final ImmutableMap dependencies; private final ComponentRequestRepresentations componentRequestRepresentations; private final boolean useLazyClassKey; - private final LazyClassKeyProviders lazyClassKeyProviders; @AssistedInject MapRequestRepresentation( @Assisted MultiboundMapBinding binding, - LazyClassKeyProviders lazyClassKeyProviders, XProcessingEnv processingEnv, BindingGraph graph, ComponentImplementation componentImplementation, @@ -74,7 +73,6 @@ final class MapRequestRepresentation extends RequestRepresentation { this.dependencies = Maps.toMap(binding.dependencies(), dep -> graph.contributionBinding(dep.key())); this.useLazyClassKey = MapKeys.useLazyClassKey(binding, graph); - this.lazyClassKeyProviders = lazyClassKeyProviders; } @Override @@ -153,7 +151,7 @@ private CodeBlock keyAndValueExpression(DependencyRequest dependency, ClassName return CodeBlock.of( "$L, $L", useLazyClassKey - ? lazyClassKeyProviders.getMapKeyExpression(dependency.key()) + ? getLazyClassMapKeyExpression(dependencies.get(dependency)) : getMapKeyExpression(dependencies.get(dependency), requestingClass, processingEnv), componentRequestRepresentations .getDependencyExpression(bindingRequest(dependency), requestingClass) diff --git a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_DEFAULT_MODE_test.DaggerTestComponent index 2d8e6fec35b..a3faffc55c7 100644 --- a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_DEFAULT_MODE_test.DaggerTestComponent @@ -2,8 +2,6 @@ package test; import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; -import dagger.internal.IdentifierNameString; -import dagger.internal.KeepFieldType; import dagger.internal.LazyClassKeyMap; import java.util.Map; import javax.annotation.processing.Generated; @@ -52,21 +50,8 @@ final class DaggerTestComponent { @Override public Map, Integer> classKey() { - return LazyClassKeyMap.of(ImmutableMap.of(LazyClassKeyProvider.test_Foo_Bar, MapKeyBindingsModule.classKey(), LazyClassKeyProvider.test_Foo_Bar3, MapKeyBindingsModule.classKey2())); + return LazyClassKeyMap.of(ImmutableMap.of(MapKeyBindingsModule_ClassKey_LazyMapKey.lazyClassKeyName, MapKeyBindingsModule.classKey(), MapKeyBindingsModule_ClassKey2_LazyMapKey.lazyClassKeyName, MapKeyBindingsModule.classKey2())); } } - - @IdentifierNameString - private static final class LazyClassKeyProvider { - static String test_Foo_Bar = "test.Foo_Bar"; - - static String test_Foo_Bar3 = "test.Foo$Bar"; - - @KeepFieldType - Foo_Bar test_Foo_Bar2; - - @KeepFieldType - Foo.Bar test_Foo_Bar4; - } } diff --git a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_FAST_INIT_MODE_test.DaggerTestComponent index 2d8e6fec35b..a3faffc55c7 100644 --- a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,8 +2,6 @@ package test; import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; -import dagger.internal.IdentifierNameString; -import dagger.internal.KeepFieldType; import dagger.internal.LazyClassKeyMap; import java.util.Map; import javax.annotation.processing.Generated; @@ -52,21 +50,8 @@ final class DaggerTestComponent { @Override public Map, Integer> classKey() { - return LazyClassKeyMap.of(ImmutableMap.of(LazyClassKeyProvider.test_Foo_Bar, MapKeyBindingsModule.classKey(), LazyClassKeyProvider.test_Foo_Bar3, MapKeyBindingsModule.classKey2())); + return LazyClassKeyMap.of(ImmutableMap.of(MapKeyBindingsModule_ClassKey_LazyMapKey.lazyClassKeyName, MapKeyBindingsModule.classKey(), MapKeyBindingsModule_ClassKey2_LazyMapKey.lazyClassKeyName, MapKeyBindingsModule.classKey2())); } } - - @IdentifierNameString - private static final class LazyClassKeyProvider { - static String test_Foo_Bar = "test.Foo_Bar"; - - static String test_Foo_Bar3 = "test.Foo$Bar"; - - @KeepFieldType - Foo_Bar test_Foo_Bar2; - - @KeepFieldType - Foo.Bar test_Foo_Bar4; - } } diff --git a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent index a1b4bfe4a1f..77e0a95c7ce 100644 --- a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent @@ -2,7 +2,6 @@ package test; import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; -import dagger.internal.IdentifierNameString; import dagger.internal.LazyClassKeyMap; import dagger.internal.MapFactory; import dagger.internal.Provider; @@ -11,6 +10,7 @@ import javax.annotation.processing.Generated; import mapkeys.MapKeys; import mapkeys.MapModule; import mapkeys.MapModule_ClassKeyFactory; +import mapkeys.MapModule_ClassKey_LazyMapKey; import mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueFactory; import mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey; import mapkeys.MapModule_ComplexKeyWithInaccessibleArrayValueFactory; @@ -67,13 +67,13 @@ final class DaggerTestComponent { @SuppressWarnings("unchecked") private void initialize() { - this.mapOfClassOfAndIntegerProvider = LazyClassKeyMap.MapFactory.of(MapFactory.builder(1).put(LazyClassKeyProvider.mapkeys_MapKeys_Inaccessible, MapModule_ClassKeyFactory.create()).build()); + this.mapOfClassOfAndIntegerProvider = LazyClassKeyMap.MapFactory.of(MapFactory.builder(1).put(MapModule_ClassKey_LazyMapKey.lazyClassKeyName, MapModule_ClassKeyFactory.create()).build()); this.mapOfComplexKeyAndIntegerProvider = MapFactory.builder(3).put(MapModule_ComplexKeyWithInaccessibleValueMapKey.create(), MapModule_ComplexKeyWithInaccessibleValueFactory.create()).put(MapModule_ComplexKeyWithInaccessibleArrayValueMapKey.create(), MapModule_ComplexKeyWithInaccessibleArrayValueFactory.create()).put(MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey.create(), MapModule_ComplexKeyWithInaccessibleAnnotationValueFactory.create()).build(); } @Override public Map, Integer> classKey() { - return LazyClassKeyMap.of(ImmutableMap.of(LazyClassKeyProvider.mapkeys_MapKeys_Inaccessible, MapModule.classKey())); + return LazyClassKeyMap.of(ImmutableMap.of(MapModule_ClassKey_LazyMapKey.lazyClassKeyName, MapModule.classKey())); } @Override @@ -91,10 +91,5 @@ final class DaggerTestComponent { return mapOfComplexKeyAndIntegerProvider; } } - - @IdentifierNameString - private static final class LazyClassKeyProvider { - static String mapkeys_MapKeys_Inaccessible = "mapkeys.MapKeys$Inaccessible"; - } } diff --git a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_test.DaggerTestComponent index b3c32b90939..71da9b92d62 100644 --- a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_FAST_INIT_MODE_test.DaggerTestComponent @@ -2,13 +2,13 @@ package test; import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; -import dagger.internal.IdentifierNameString; import dagger.internal.LazyClassKeyMap; import dagger.internal.Provider; import java.util.Map; import javax.annotation.processing.Generated; import mapkeys.MapKeys; import mapkeys.MapModule; +import mapkeys.MapModule_ClassKey_LazyMapKey; import mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey; import mapkeys.MapModule_ComplexKeyWithInaccessibleArrayValueMapKey; import mapkeys.MapModule_ComplexKeyWithInaccessibleValueMapKey; @@ -101,7 +101,7 @@ final class DaggerTestComponent { public T get() { switch (id) { case 0: // java.util.Map,java.lang.Integer> - return (T) LazyClassKeyMap.of(ImmutableMap.of(LazyClassKeyProvider.mapkeys_MapKeys_Inaccessible, MapModule.classKey())); + return (T) LazyClassKeyMap.of(ImmutableMap.of(MapModule_ClassKey_LazyMapKey.lazyClassKeyName, MapModule.classKey())); case 1: // java.util.Map return (T) ImmutableMap.of(MapModule_ComplexKeyWithInaccessibleValueMapKey.create(), MapModule.complexKeyWithInaccessibleValue(), MapModule_ComplexKeyWithInaccessibleArrayValueMapKey.create(), MapModule.complexKeyWithInaccessibleArrayValue(), MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey.create(), MapModule.complexKeyWithInaccessibleAnnotationValue()); @@ -111,10 +111,5 @@ final class DaggerTestComponent { } } } - - @IdentifierNameString - private static final class LazyClassKeyProvider { - static String mapkeys_MapKeys_Inaccessible = "mapkeys.MapKeys$Inaccessible"; - } }