1 /* 2 * Copyright (C) 2020 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.hilt.processor.internal; 18 19 import com.squareup.javapoet.ClassName; 20 import java.util.function.Function; 21 22 /** 23 * Utility class for getting the generated component name. 24 * 25 * <p>This should not be used externally. 26 */ 27 public final class ComponentNames { 28 29 /** 30 * Returns an instance of {@link ComponentNames} that will base all component names off of the 31 * given root. 32 */ withoutRenaming()33 public static ComponentNames withoutRenaming() { 34 return new ComponentNames(Function.identity()); 35 } 36 37 /** 38 * Returns an instance of {@link ComponentNames} that will base all component names off of the 39 * given root after mapping it with {@code rootRenamer}. 40 */ withRenaming(Function<ClassName, ClassName> rootRenamer)41 public static ComponentNames withRenaming(Function<ClassName, ClassName> rootRenamer) { 42 return new ComponentNames(rootRenamer); 43 } 44 45 private final Function<ClassName, ClassName> rootRenamer; 46 ComponentNames(Function<ClassName, ClassName> rootRenamer)47 private ComponentNames(Function<ClassName, ClassName> rootRenamer) { 48 this.rootRenamer = rootRenamer; 49 } 50 generatedComponentTreeDeps(ClassName root)51 public ClassName generatedComponentTreeDeps(ClassName root) { 52 return Processors.append( 53 Processors.getEnclosedClassName(rootRenamer.apply(root)), "_ComponentTreeDeps"); 54 } 55 56 /** Returns the name of the generated component wrapper. */ generatedComponentsWrapper(ClassName root)57 public ClassName generatedComponentsWrapper(ClassName root) { 58 return Processors.append( 59 Processors.getEnclosedClassName(rootRenamer.apply(root)), "_HiltComponents"); 60 } 61 62 /** Returns the name of the generated component. */ generatedComponent(ClassName root, ClassName component)63 public ClassName generatedComponent(ClassName root, ClassName component) { 64 return generatedComponentsWrapper(root).nestedClass(componentName(component)); 65 } 66 67 /** 68 * Returns the shortened component name by replacing the ending "Component" with "C" if it exists. 69 * 70 * <p>This is a hack because nested subcomponents in Dagger generate extremely long class names 71 * that hit the 256 character limit. 72 */ 73 // TODO(bcorso): See if this issue can be fixed in Dagger, e.g. by using static subcomponents. componentName(ClassName component)74 private static String componentName(ClassName component) { 75 // TODO(bcorso): How do we want to handle collisions across packages? Currently, we only handle 76 // collisions across enclosing elements since namespacing by package would likely lead to too 77 // long of class names. 78 // Note: This uses regex matching so we only match if the name ends in "Component" 79 return Processors.getEnclosedName(component).replaceAll("Component$", "C"); 80 } 81 82 } 83