1 /*
2  * Copyright (C) 2021 Square, Inc.
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  * https://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 package com.squareup.kotlinpoet.metadata.specs
17 
18 import com.squareup.kotlinpoet.AnnotationSpec
19 import com.squareup.kotlinpoet.AnnotationSpec.UseSiteTarget
20 import com.squareup.kotlinpoet.TypeName
21 import com.squareup.kotlinpoet.metadata.classinspectors.ClassInspectorUtil
22 
23 /**
24  * Represents relevant information on a method used for [ClassInspector]. Should only be
25  * associated with methods of a [ClassData] or [PropertyData].
26  *
27  * @param annotations declared annotations on this method.
28  * @property parameterAnnotations a mapping of parameter indices to annotations on them.
29  * @property isSynthetic indicates if this method is synthetic or not.
30  * @property jvmModifiers set of [JvmMethodModifiers][JvmMethodModifier] on this method.
31  * @property isOverride indicates if this method overrides one in a supertype.
32  * @property exceptions list of exceptions thrown by this method.
33  */
34 public data class MethodData(
35   private val annotations: List<AnnotationSpec>,
36   val parameterAnnotations: Map<Int, Collection<AnnotationSpec>>,
37   val isSynthetic: Boolean,
38   val jvmModifiers: Set<JvmMethodModifier>,
39   val isOverride: Boolean,
40   val exceptions: List<TypeName>,
41 ) {
42 
43   /**
44    * A collection of all annotations on this method, including any derived from [jvmModifiers],
45    * [isSynthetic], and [exceptions].
46    *
47    * @param useSiteTarget an optional [UseSiteTarget] that all annotations on this method should
48    *        use.
49    * @param containsReifiedTypeParameter an optional boolean indicating if any type parameters on
50    *        this function are `reified`, which are implicitly synthetic.
51    */
allAnnotationsnull52   public fun allAnnotations(
53     useSiteTarget: UseSiteTarget? = null,
54     containsReifiedTypeParameter: Boolean = false,
55   ): Collection<AnnotationSpec> {
56     return ClassInspectorUtil.createAnnotations(
57       useSiteTarget,
58     ) {
59       addAll(annotations)
60       if (isSynthetic && !containsReifiedTypeParameter) {
61         add(ClassInspectorUtil.JVM_SYNTHETIC_SPEC)
62       }
63       addAll(jvmModifiers.mapNotNull(JvmMethodModifier::annotationSpec))
64       exceptions.takeIf { it.isNotEmpty() }
65         ?.let {
66           add(ClassInspectorUtil.createThrowsSpec(it, useSiteTarget))
67         }
68     }
69   }
70 
71   public companion object {
72     public val SYNTHETIC: MethodData = MethodData(
73       annotations = emptyList(),
74       parameterAnnotations = emptyMap(),
75       isSynthetic = true,
76       jvmModifiers = emptySet(),
77       isOverride = false,
78       exceptions = emptyList(),
79     )
80     public val EMPTY: MethodData = MethodData(
81       annotations = emptyList(),
82       parameterAnnotations = emptyMap(),
83       isSynthetic = false,
84       jvmModifiers = emptySet(),
85       isOverride = false,
86       exceptions = emptyList(),
87     )
88   }
89 }
90