1 /* 2 * Copyright (C) 2019 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.google.auto.value.AutoValue; 20 import com.google.common.collect.ImmutableSet; 21 import com.squareup.javapoet.ClassName; 22 import java.util.Optional; 23 24 // TODO(bcorso): Reduce the visibility of this class and return ClassNames instead. 25 // TODO(erichang): Rename this class so it doesn't conflict with 26 // dagger.internal.codegen.ComponentDescriptor 27 /** Represents a single component in the hierarchy. */ 28 @AutoValue 29 public abstract class ComponentDescriptor { builder()30 public static Builder builder() { 31 return new AutoValue_ComponentDescriptor.Builder() 32 .scopes(ImmutableSet.of()); 33 } 34 35 /** Returns the {@link ClassName} for this component descriptor. */ component()36 public abstract ClassName component(); 37 38 /** Returns the {@link ClassName}s for the scopes of this component descriptor. */ scopes()39 public abstract ImmutableSet<ClassName> scopes(); 40 41 /** Returns the {@link ClassName} for the creator interface. if it exists. */ creator()42 public abstract Optional<ClassName> creator(); 43 44 /** Returns the {@link ClassName} for the parent, if it exists. */ parent()45 public abstract Optional<ComponentDescriptor> parent(); 46 47 /** Returns {@code true} if the descriptor represents a root component. */ isRoot()48 public boolean isRoot() { 49 return !parent().isPresent(); 50 } 51 52 /** 53 * Returns {@code true} if the given {@link ComponentDescriptor} represents the same {@link 54 * #component()}. 55 */ 56 // TODO(b/144939893): Remove equals and hashcode once we have unique ComponentDescriptor instances 57 @Override equals(Object obj)58 public final boolean equals(Object obj) { 59 if (obj == this) { 60 return true; 61 } 62 if (!(obj instanceof ComponentDescriptor)) { 63 return false; 64 } 65 ComponentDescriptor that = (ComponentDescriptor) obj; 66 67 // Only check the component name, which should map 1:1 to each component descriptor created 68 // by DefineComponents#componentDescriptor(Element). However, if users are building their own 69 // ComponentDescriptors manually, then this might not be true. We should lock down the builder 70 // method to avoid that. 71 return component().equals(that.component()); 72 } 73 74 @Override hashCode()75 public final int hashCode() { 76 return component().hashCode(); 77 } 78 79 /** Builder for ComponentDescriptor. */ 80 @AutoValue.Builder 81 public interface Builder { component(ClassName component)82 Builder component(ClassName component); 83 scopes(ImmutableSet<ClassName> scopes)84 Builder scopes(ImmutableSet<ClassName> scopes); 85 scopes(ClassName... scopes)86 Builder scopes(ClassName... scopes); 87 creator(ClassName creator)88 Builder creator(ClassName creator); 89 parent(ComponentDescriptor parent)90 Builder parent(ComponentDescriptor parent); 91 92 build()93 ComponentDescriptor build(); 94 } 95 } 96