xref: /aosp_15_r20/external/kotlinpoet/kotlinpoet/src/commonMain/kotlin/com/squareup/kotlinpoet/TypeAliasSpec.kt (revision 3c321d951dd070fb96f8ba59e952ffc3131379a0)
1 /*
2  * Copyright (C) 2017 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
17 
18 import com.squareup.kotlinpoet.KModifier.ACTUAL
19 import com.squareup.kotlinpoet.KModifier.INTERNAL
20 import com.squareup.kotlinpoet.KModifier.PRIVATE
21 import com.squareup.kotlinpoet.KModifier.PUBLIC
22 import java.lang.reflect.Type
23 import kotlin.reflect.KClass
24 
25 /** A generated typealias declaration */
26 public class TypeAliasSpec private constructor(
27   builder: Builder,
28   private val tagMap: TagMap = builder.buildTagMap(),
29 ) : Taggable by tagMap, Annotatable, Documentable {
30   public val name: String = builder.name
31   public val type: TypeName = builder.type
32   public val modifiers: Set<KModifier> = builder.modifiers.toImmutableSet()
33   public val typeVariables: List<TypeVariableName> = builder.typeVariables.toImmutableList()
34   override val kdoc: CodeBlock = builder.kdoc.build()
35   override val annotations: List<AnnotationSpec> = builder.annotations.toImmutableList()
36 
emitnull37   internal fun emit(codeWriter: CodeWriter) {
38     codeWriter.emitKdoc(kdoc.ensureEndsWithNewLine())
39     codeWriter.emitAnnotations(annotations, false)
40     codeWriter.emitModifiers(modifiers, setOf(PUBLIC))
41     codeWriter.emitCode("typealias %N", name)
42     codeWriter.emitTypeVariables(typeVariables)
43     codeWriter.emitCode(" = %T", type)
44     codeWriter.emit("\n")
45   }
46 
equalsnull47   override fun equals(other: Any?): Boolean {
48     if (this === other) return true
49     if (other == null) return false
50     if (javaClass != other.javaClass) return false
51     return toString() == other.toString()
52   }
53 
hashCodenull54   override fun hashCode(): Int = toString().hashCode()
55 
56   override fun toString(): String = buildCodeString { emit(this) }
57 
58   @JvmOverloads
toBuildernull59   public fun toBuilder(name: String = this.name, type: TypeName = this.type): Builder {
60     val builder = Builder(name, type)
61     builder.modifiers += modifiers
62     builder.typeVariables += typeVariables
63     builder.kdoc.add(kdoc)
64     builder.annotations += annotations
65     builder.tags += tagMap.tags
66     return builder
67   }
68 
69   public class Builder internal constructor(
70     internal val name: String,
71     internal val type: TypeName,
72   ) : Taggable.Builder<Builder>, Annotatable.Builder<Builder>, Documentable.Builder<Builder> {
73     public val modifiers: MutableSet<KModifier> = mutableSetOf()
74     public val typeVariables: MutableSet<TypeVariableName> = mutableSetOf()
75     override val tags: MutableMap<KClass<*>, Any> = mutableMapOf()
76     override val kdoc: CodeBlock.Builder = CodeBlock.builder()
77     override val annotations: MutableList<AnnotationSpec> = mutableListOf()
78 
<lambda>null79     public fun addModifiers(vararg modifiers: KModifier): Builder = apply {
80       modifiers.forEach(this::addModifier)
81     }
82 
<lambda>null83     public fun addModifiers(modifiers: Iterable<KModifier>): Builder = apply {
84       modifiers.forEach(this::addModifier)
85     }
86 
addModifiernull87     private fun addModifier(modifier: KModifier) {
88       this.modifiers.add(modifier)
89     }
90 
<lambda>null91     public fun addTypeVariables(typeVariables: Iterable<TypeVariableName>): Builder = apply {
92       this.typeVariables += typeVariables
93     }
94 
addTypeVariablenull95     public fun addTypeVariable(typeVariable: TypeVariableName): Builder = apply {
96       typeVariables += typeVariable
97     }
98 
99     //region Overrides for binary compatibility
100     @Suppress("RedundantOverride")
addAnnotationnull101     override fun addAnnotation(annotationSpec: AnnotationSpec): Builder = super.addAnnotation(annotationSpec)
102 
103     @Suppress("RedundantOverride")
104     override fun addAnnotations(annotationSpecs: Iterable<AnnotationSpec>): Builder =
105       super.addAnnotations(annotationSpecs)
106 
107     @Suppress("RedundantOverride")
108     override fun addAnnotation(annotation: ClassName): Builder = super.addAnnotation(annotation)
109 
110     @DelicateKotlinPoetApi(
111       message = "Java reflection APIs don't give complete information on Kotlin types. Consider " +
112         "using the kotlinpoet-metadata APIs instead.",
113     )
114     override fun addAnnotation(annotation: Class<*>): Builder = super.addAnnotation(annotation)
115 
116     @Suppress("RedundantOverride")
117     override fun addAnnotation(annotation: KClass<*>): Builder = super.addAnnotation(annotation)
118 
119     @Suppress("RedundantOverride")
120     override fun addKdoc(format: String, vararg args: Any): Builder = super.addKdoc(format, *args)
121 
122     @Suppress("RedundantOverride")
123     override fun addKdoc(block: CodeBlock): Builder = super.addKdoc(block)
124     //endregion
125 
126     public fun build(): TypeAliasSpec {
127       for (it in modifiers) {
128         require(it in ALLOWABLE_MODIFIERS) {
129           "unexpected typealias modifier $it"
130         }
131       }
132       return TypeAliasSpec(this)
133     }
134 
135     private companion object {
136       private val ALLOWABLE_MODIFIERS = setOf(PUBLIC, INTERNAL, PRIVATE, ACTUAL)
137     }
138   }
139 
140   public companion object {
buildernull141     @JvmStatic public fun builder(name: String, type: TypeName): Builder = Builder(name, type)
142 
143     @DelicateKotlinPoetApi(
144       message = "Java reflection APIs don't give complete information on Kotlin types. Consider " +
145         "using the kotlinpoet-metadata APIs instead.",
146     )
147     @JvmStatic
148     public fun builder(name: String, type: Type): Builder =
149       builder(name, type.asTypeName())
150 
151     @JvmStatic public fun builder(name: String, type: KClass<*>): Builder =
152       builder(name, type.asTypeName())
153   }
154 }
155