1 /* 2 * Copyright (C) 2022 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.writing; 18 19 import static com.squareup.javapoet.MethodSpec.constructorBuilder; 20 import static com.squareup.javapoet.TypeSpec.classBuilder; 21 import static dagger.internal.codegen.writing.ComponentNames.getTopLevelClassName; 22 import static javax.lang.model.element.Modifier.FINAL; 23 import static javax.lang.model.element.Modifier.PRIVATE; 24 import static javax.lang.model.element.Modifier.PUBLIC; 25 26 import com.google.common.collect.ListMultimap; 27 import com.google.common.collect.MultimapBuilder; 28 import com.squareup.javapoet.ClassName; 29 import com.squareup.javapoet.FieldSpec; 30 import com.squareup.javapoet.MethodSpec; 31 import com.squareup.javapoet.TypeSpec; 32 import dagger.internal.codegen.base.UniqueNameSet; 33 import dagger.internal.codegen.binding.BindingGraph; 34 import dagger.internal.codegen.writing.ComponentImplementation.FieldSpecKind; 35 import dagger.internal.codegen.writing.ComponentImplementation.MethodSpecKind; 36 import dagger.internal.codegen.writing.ComponentImplementation.TypeSpecKind; 37 import javax.inject.Inject; 38 39 /** Represents the implementation of the generated holder for the components. */ 40 @PerGeneratedFile 41 public final class ComponentWrapperImplementation implements GeneratedImplementation { 42 private final BindingGraph graph; 43 private final ClassName name; 44 private final UniqueNameSet componentClassNames = new UniqueNameSet(); 45 private final ListMultimap<FieldSpecKind, FieldSpec> fieldSpecsMap = 46 MultimapBuilder.enumKeys(FieldSpecKind.class).arrayListValues().build(); 47 private final ListMultimap<MethodSpecKind, MethodSpec> methodSpecsMap = 48 MultimapBuilder.enumKeys(MethodSpecKind.class).arrayListValues().build(); 49 private final ListMultimap<TypeSpecKind, TypeSpec> typeSpecsMap = 50 MultimapBuilder.enumKeys(TypeSpecKind.class).arrayListValues().build(); 51 52 @Inject ComponentWrapperImplementation(@opLevel BindingGraph graph)53 ComponentWrapperImplementation(@TopLevel BindingGraph graph) { 54 this.graph = graph; 55 this.name = ComponentNames.getTopLevelClassName(graph.componentDescriptor()); 56 } 57 58 @Override name()59 public ClassName name() { 60 return name; 61 } 62 63 @Override getUniqueClassName(String name)64 public String getUniqueClassName(String name) { 65 return componentClassNames.getUniqueName(name); 66 } 67 68 @Override addField(FieldSpecKind fieldKind, FieldSpec fieldSpec)69 public void addField(FieldSpecKind fieldKind, FieldSpec fieldSpec) { 70 fieldSpecsMap.put(fieldKind, fieldSpec); 71 } 72 73 @Override addMethod(MethodSpecKind methodKind, MethodSpec methodSpec)74 public void addMethod(MethodSpecKind methodKind, MethodSpec methodSpec) { 75 methodSpecsMap.put(methodKind, methodSpec); 76 } 77 78 @Override addType(TypeSpecKind typeKind, TypeSpec typeSpec)79 public void addType(TypeSpecKind typeKind, TypeSpec typeSpec) { 80 typeSpecsMap.put(typeKind, typeSpec); 81 } 82 83 @Override generate()84 public TypeSpec generate() { 85 TypeSpec.Builder builder = 86 classBuilder(getTopLevelClassName(graph.componentDescriptor())).addModifiers(FINAL); 87 88 if (graph.componentTypeElement().isPublic()) { 89 builder.addModifiers(PUBLIC); 90 } 91 92 fieldSpecsMap.asMap().values().forEach(builder::addFields); 93 methodSpecsMap.asMap().values().forEach(builder::addMethods); 94 typeSpecsMap.asMap().values().forEach(builder::addTypes); 95 96 return builder.addMethod(constructorBuilder().addModifiers(PRIVATE).build()).build(); 97 } 98 } 99