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