xref: /aosp_15_r20/external/kotlinpoet/kotlinpoet/src/commonMain/kotlin/com/squareup/kotlinpoet/LambdaTypeName.kt (revision 3c321d951dd070fb96f8ba59e952ffc3131379a0)
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
17 
18 import kotlin.reflect.KClass
19 
20 @OptIn(ExperimentalKotlinPoetApi::class)
21 public class LambdaTypeName private constructor(
22   public val receiver: TypeName? = null,
23   @property:ExperimentalKotlinPoetApi
24   public val contextReceivers: List<TypeName> = emptyList(),
25   parameters: List<ParameterSpec> = emptyList(),
26   public val returnType: TypeName = UNIT,
27   nullable: Boolean = false,
28   public val isSuspending: Boolean = false,
29   annotations: List<AnnotationSpec> = emptyList(),
30   tags: Map<KClass<*>, Any> = emptyMap(),
31 ) : TypeName(nullable, annotations, TagMap(tags)) {
32   public val parameters: List<ParameterSpec> = parameters.toImmutableList()
33 
34   init {
35     for (param in parameters) {
<lambda>null36       require(param.annotations.isEmpty()) { "Parameters with annotations are not allowed" }
<lambda>null37       require(param.modifiers.isEmpty()) { "Parameters with modifiers are not allowed" }
<lambda>null38       require(param.defaultValue == null) { "Parameters with default values are not allowed" }
39     }
40   }
41 
copynull42   override fun copy(
43     nullable: Boolean,
44     annotations: List<AnnotationSpec>,
45     tags: Map<KClass<*>, Any>,
46   ): LambdaTypeName {
47     return copy(nullable, annotations, this.isSuspending, tags)
48   }
49 
copynull50   public fun copy(
51     nullable: Boolean = this.isNullable,
52     annotations: List<AnnotationSpec> = this.annotations.toList(),
53     suspending: Boolean = this.isSuspending,
54     tags: Map<KClass<*>, Any> = this.tags.toMap(),
55   ): LambdaTypeName {
56     return LambdaTypeName(receiver, contextReceivers, parameters, returnType, nullable, suspending, annotations, tags)
57   }
58 
emitnull59   override fun emit(out: CodeWriter): CodeWriter {
60     if (isNullable) {
61       out.emit("(")
62     }
63 
64     if (isSuspending) {
65       out.emit("suspend·")
66     }
67 
68     out.emitContextReceivers(contextReceivers, suffix = "·")
69 
70     receiver?.let {
71       if (it.isAnnotated) {
72         out.emitCode("(%T).", it)
73       } else {
74         out.emitCode("%T.", it)
75       }
76     }
77 
78     parameters.emit(out)
79     out.emitCode(if (returnType is LambdaTypeName) "·->·(%T)" else "·->·%T", returnType)
80 
81     if (isNullable) {
82       out.emit(")")
83     }
84     return out
85   }
86 
equalsnull87   override fun equals(other: Any?): Boolean {
88     if (this === other) return true
89     if (javaClass != other?.javaClass) return false
90     if (!super.equals(other)) return false
91 
92     other as LambdaTypeName
93 
94     if (receiver != other.receiver) return false
95     if (contextReceivers != other.contextReceivers) return false
96     if (returnType != other.returnType) return false
97     if (isSuspending != other.isSuspending) return false
98     if (parameters != other.parameters) return false
99 
100     return true
101   }
102 
hashCodenull103   override fun hashCode(): Int {
104     var result = super.hashCode()
105     result = 31 * result + (receiver?.hashCode() ?: 0)
106     result = 31 * result + contextReceivers.hashCode()
107     result = 31 * result + returnType.hashCode()
108     result = 31 * result + isSuspending.hashCode()
109     result = 31 * result + parameters.hashCode()
110     return result
111   }
112   public companion object {
113     /** Returns a lambda type with `returnType` and parameters listed in `parameters`. */
114     @ExperimentalKotlinPoetApi @JvmStatic
getnull115     public fun get(
116       receiver: TypeName? = null,
117       parameters: List<ParameterSpec> = emptyList(),
118       returnType: TypeName,
119       contextReceivers: List<TypeName> = emptyList(),
120     ): LambdaTypeName = LambdaTypeName(receiver, contextReceivers, parameters, returnType)
121 
122     /** Returns a lambda type with `returnType` and parameters listed in `parameters`. */
123     @JvmStatic public fun get(
124       receiver: TypeName? = null,
125       parameters: List<ParameterSpec> = emptyList(),
126       returnType: TypeName,
127     ): LambdaTypeName = LambdaTypeName(receiver, emptyList(), parameters, returnType)
128 
129     /** Returns a lambda type with `returnType` and parameters listed in `parameters`. */
130     @JvmStatic public fun get(
131       receiver: TypeName? = null,
132       vararg parameters: TypeName = emptyArray(),
133       returnType: TypeName,
134     ): LambdaTypeName {
135       return LambdaTypeName(
136         receiver,
137         emptyList(),
138         parameters.toList().map { ParameterSpec.unnamed(it) },
139         returnType,
140       )
141     }
142 
143     /** Returns a lambda type with `returnType` and parameters listed in `parameters`. */
getnull144     @JvmStatic public fun get(
145       receiver: TypeName? = null,
146       vararg parameters: ParameterSpec = emptyArray(),
147       returnType: TypeName,
148     ): LambdaTypeName = LambdaTypeName(receiver, emptyList(), parameters.toList(), returnType)
149   }
150 }
151