• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(),
<lambda>null29 ) : Taggable by tagMap {
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   public val kdoc: CodeBlock = builder.kdoc.build()
35   public val annotations: List<AnnotationSpec> = builder.annotations.toImmutableList()
36 
37   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 
47   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 
54   override fun hashCode(): Int = toString().hashCode()
55 
56   override fun toString(): String = buildCodeString { emit(this) }
57 
58   @JvmOverloads
59   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> {
73     internal val kdoc = CodeBlock.builder()
74 
75     public val modifiers: MutableSet<KModifier> = mutableSetOf()
76     public val typeVariables: MutableSet<TypeVariableName> = mutableSetOf()
77     public val annotations: MutableList<AnnotationSpec> = mutableListOf()
78     override val tags: MutableMap<KClass<*>, Any> = mutableMapOf()
79 
80     public fun addModifiers(vararg modifiers: KModifier): Builder = apply {
81       modifiers.forEach(this::addModifier)
82     }
83 
84     public fun addModifiers(modifiers: Iterable<KModifier>): Builder = apply {
85       modifiers.forEach(this::addModifier)
86     }
87 
88     private fun addModifier(modifier: KModifier) {
89       this.modifiers.add(modifier)
90     }
91 
92     public fun addTypeVariables(typeVariables: Iterable<TypeVariableName>): Builder = apply {
93       this.typeVariables += typeVariables
94     }
95 
96     public fun addTypeVariable(typeVariable: TypeVariableName): Builder = apply {
97       typeVariables += typeVariable
98     }
99 
100     public fun addKdoc(format: String, vararg args: Any): Builder = apply {
101       kdoc.add(format, *args)
102     }
103 
104     public fun addKdoc(block: CodeBlock): Builder = apply {
105       kdoc.add(block)
106     }
107 
108     public fun addAnnotations(annotationSpecs: Iterable<AnnotationSpec>): Builder = apply {
109       this.annotations += annotationSpecs
110     }
111 
112     public fun addAnnotation(annotationSpec: AnnotationSpec): Builder = apply {
113       annotations += annotationSpec
114     }
115 
116     public fun addAnnotation(annotation: ClassName): Builder = apply {
117       annotations += AnnotationSpec.builder(annotation).build()
118     }
119 
120     @DelicateKotlinPoetApi(
121       message = "Java reflection APIs don't give complete information on Kotlin types. Consider " +
122         "using the kotlinpoet-metadata APIs instead.",
123     )
124     public fun addAnnotation(annotation: Class<*>): Builder =
125       addAnnotation(annotation.asClassName())
126 
127     public fun addAnnotation(annotation: KClass<*>): Builder =
128       addAnnotation(annotation.asClassName())
129 
130     public fun build(): TypeAliasSpec {
131       for (it in modifiers) {
132         require(it in ALLOWABLE_MODIFIERS) {
133           "unexpected typealias modifier $it"
134         }
135       }
136       return TypeAliasSpec(this)
137     }
138 
139     private companion object {
140       private val ALLOWABLE_MODIFIERS = setOf(PUBLIC, INTERNAL, PRIVATE, ACTUAL)
141     }
142   }
143 
144   public companion object {
145     @JvmStatic public fun builder(name: String, type: TypeName): Builder = Builder(name, type)
146 
147     @DelicateKotlinPoetApi(
148       message = "Java reflection APIs don't give complete information on Kotlin types. Consider " +
149         "using the kotlinpoet-metadata APIs instead.",
150     )
151     @JvmStatic
152     public fun builder(name: String, type: Type): Builder =
153       builder(name, type.asTypeName())
154 
155     @JvmStatic public fun builder(name: String, type: KClass<*>): Builder =
156       builder(name, type.asTypeName())
157   }
158 }
159