1 /*
2 * Copyright (C) 2019 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.ClassName
19 import kotlin.metadata.KmClass
20 import kotlin.metadata.KmDeclarationContainer
21 import kotlin.metadata.jvm.JvmMethodSignature
22
23 /** A basic interface for looking up JVM information about a given Class. */
24 public interface ClassInspector {
25
26 /**
27 * Indicates if this [ClassInspector] supports [AnnotationRetention.RUNTIME]-retained annotations.
28 * This is used to indicate if manual inference of certain non-RUNTIME-retained annotations should
29 * be done, such as [JvmName].
30 */
31 public val supportsNonRuntimeRetainedAnnotations: Boolean
32
33 /**
34 * Creates a new [ContainerData] instance for a given [declarationContainer].
35 *
36 * @param declarationContainer the source [KmDeclarationContainer] to read from.
37 * @param className the [ClassName] of the target class to to read from.
38 * @param parentClassName the parent [ClassName] name if [declarationContainer] is nested, inner,
39 * or is a companion object.
40 */
containerDatanull41 public fun containerData(
42 declarationContainer: KmDeclarationContainer,
43 className: ClassName,
44 parentClassName: ClassName?,
45 ): ContainerData
46
47 /**
48 * Looks up other declaration containers, such as for nested members. Note that this class would
49 * always be Kotlin, so Metadata can be relied on for this.
50 *
51 * @param className The [ClassName] representation of the class.
52 * @return the read [KmDeclarationContainer] from its metadata. If no class or facade
53 * file was found, this should throw an exception.
54 */
55 public fun declarationContainerFor(className: ClassName): KmDeclarationContainer
56
57 /**
58 * Looks up a class and returns whether or not it is an interface. Note that this class can be
59 * Java or Kotlin, so Metadata should not be relied on for this.
60 *
61 * @param className The [ClassName] representation of the class.
62 * @return whether or not it is an interface.
63 */
64 public fun isInterface(className: ClassName): Boolean
65
66 /**
67 * Looks up the enum entry on a given enum given its member name.
68 *
69 * @param enumClassName The [ClassName] representation of the enum class.
70 * @param memberName The simple member name.
71 * @return the [EnumEntryData]
72 */
73 public fun enumEntry(enumClassName: ClassName, memberName: String): EnumEntryData
74
75 /**
76 * Looks up if a given [methodSignature] within [className] exists.
77 *
78 * @param className The [ClassName] representation of the class.
79 * @param methodSignature The method signature to check.
80 * @return whether or not the method exists.
81 */
82 public fun methodExists(className: ClassName, methodSignature: JvmMethodSignature): Boolean
83 }
84
85 /**
86 * Creates a new [ContainerData] instance for a given [className].
87 *
88 * @param className the [ClassName] of the target class to to read from.
89 * @param parentClassName the parent [ClassName] name if [className] is nested, inner, or is a
90 * companion object.
91 */
92 public fun ClassInspector.containerData(
93 className: ClassName,
94 parentClassName: ClassName?,
95 ): ContainerData {
96 return containerData(declarationContainerFor(className), className, parentClassName)
97 }
98
99 /**
100 * Looks up other classes, such as for nested members. Note that this class would always be
101 * Kotlin, so Metadata can be relied on for this.
102 *
103 * @param className The [ClassName] representation of the class.
104 * @return the read [KmClass] from its metadata. If no class was found, this should throw
105 * an exception.
106 */
classFornull107 public fun ClassInspector.classFor(className: ClassName): KmClass {
108 val container = declarationContainerFor(className)
109 check(container is KmClass) {
110 "Container is not a class! Was ${container.javaClass.simpleName}"
111 }
112 return container
113 }
114