• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.internal.codegen.kotlin;
18 
19 import static com.google.common.base.Preconditions.checkState;
20 import static dagger.internal.codegen.extension.DaggerStreams.toImmutableMap;
21 import static dagger.internal.codegen.xprocessing.XElements.closestEnclosingTypeElement;
22 
23 import androidx.room.compiler.processing.XAnnotation;
24 import androidx.room.compiler.processing.XElement;
25 import androidx.room.compiler.processing.XFieldElement;
26 import androidx.room.compiler.processing.XMethodElement;
27 import androidx.room.compiler.processing.XTypeElement;
28 import com.google.common.collect.ImmutableMap;
29 import com.google.common.collect.ImmutableSet;
30 import com.squareup.javapoet.ClassName;
31 import dagger.internal.codegen.javapoet.TypeNames;
32 import java.util.Optional;
33 import javax.inject.Inject;
34 
35 /** Utility class for interacting with Kotlin Metadata. */
36 public final class KotlinMetadataUtil {
37   private final KotlinMetadataFactory metadataFactory;
38 
39   @Inject
KotlinMetadataUtil(KotlinMetadataFactory metadataFactory)40   KotlinMetadataUtil(KotlinMetadataFactory metadataFactory) {
41     this.metadataFactory = metadataFactory;
42   }
43 
44   /**
45    * Returns {@code true} if this element has the Kotlin Metadata annotation or if it is enclosed in
46    * an element that does.
47    */
hasMetadata(XElement element)48   public boolean hasMetadata(XElement element) {
49     return closestEnclosingTypeElement(element).hasAnnotation(TypeNames.KOTLIN_METADATA);
50   }
51 
52   /**
53    * Returns the synthetic annotations of a Kotlin property.
54    *
55    * <p>Note that this method only looks for additional annotations in the synthetic property
56    * method, if any, of a Kotlin property and not for annotations in its backing field.
57    */
getSyntheticPropertyAnnotations( XFieldElement fieldElement, ClassName annotationType)58   public ImmutableSet<XAnnotation> getSyntheticPropertyAnnotations(
59       XFieldElement fieldElement, ClassName annotationType) {
60     return metadataFactory
61         .create(fieldElement)
62         .getSyntheticAnnotationMethod(fieldElement)
63         .map(methodElement -> methodElement.getAnnotationsAnnotatedWith(annotationType))
64         .map(ImmutableSet::copyOf)
65         .orElse(ImmutableSet.of());
66   }
67 
68   /**
69    * Returns {@code true} if the synthetic method for annotations is missing. This can occur when
70    * the Kotlin metadata of the property reports that it contains a synthetic method for annotations
71    * but such method is not found since it is synthetic and ignored by the processor.
72    */
isMissingSyntheticPropertyForAnnotations(XFieldElement fieldElement)73   public boolean isMissingSyntheticPropertyForAnnotations(XFieldElement fieldElement) {
74     return metadataFactory.create(fieldElement).isMissingSyntheticAnnotationMethod(fieldElement);
75   }
76 
getPropertyGetter(XFieldElement fieldElement)77   public Optional<XMethodElement> getPropertyGetter(XFieldElement fieldElement) {
78     return metadataFactory.create(fieldElement).getPropertyGetter(fieldElement);
79   }
80 
81   /**
82    * Returns a map mapping all method signatures within the given class element, including methods
83    * that it inherits from its ancestors, to their method names.
84    */
getAllMethodNamesBySignature(XTypeElement element)85   public ImmutableMap<String, String> getAllMethodNamesBySignature(XTypeElement element) {
86     checkState(
87         hasMetadata(element), "Can not call getAllMethodNamesBySignature for non-Kotlin class");
88     return metadataFactory.create(element)
89         .classMetadata()
90         .getFunctionsBySignature().values().stream()
91         .collect(
92             toImmutableMap(
93                 FunctionMetadata::getSignature,
94                 FunctionMetadata::getName)); // SUPPRESS_GET_NAME_CHECK
95   }
96 }
97