1 /*
<lambda>null2 * Copyright 2020 Google LLC
3 * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package com.google.devtools.ksp.symbol.impl.binary
19
20 import com.google.devtools.ksp.*
21 import com.google.devtools.ksp.processing.impl.ResolverImpl
22 import com.google.devtools.ksp.symbol.*
23 import com.google.devtools.ksp.symbol.impl.*
24 import com.google.devtools.ksp.symbol.impl.java.KSFunctionDeclarationJavaImpl
25 import com.google.devtools.ksp.symbol.impl.java.KSPropertyDeclarationJavaImpl
26 import com.google.devtools.ksp.symbol.impl.kotlin.*
27 import com.google.devtools.ksp.symbol.impl.replaceTypeArguments
28 import com.intellij.psi.PsiField
29 import com.intellij.psi.PsiMethod
30 import org.jetbrains.kotlin.builtins.StandardNames
31 import org.jetbrains.kotlin.descriptors.*
32 import org.jetbrains.kotlin.psi.KtClassOrObject
33 import org.jetbrains.kotlin.psi.KtFunction
34 import org.jetbrains.kotlin.psi.KtParameter
35 import org.jetbrains.kotlin.psi.KtProperty
36 import org.jetbrains.kotlin.resolve.calls.tower.isSynthesized
37 import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
38 import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
39 import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
40 import org.jetbrains.kotlin.descriptors.ClassKind as KtClassKind
41
42 class KSClassDeclarationDescriptorImpl private constructor(val descriptor: ClassDescriptor) :
43 KSClassDeclaration,
44 KSDeclarationDescriptorImpl(descriptor),
45 KSExpectActual by KSExpectActualDescriptorImpl(descriptor) {
46 companion object : KSObjectCache<ClassDescriptor, KSClassDeclarationDescriptorImpl>() {
47 fun getCached(descriptor: ClassDescriptor) = cache.getOrPut(descriptor) {
48 KSClassDeclarationDescriptorImpl(descriptor)
49 }
50 }
51
52 override val classKind: ClassKind by lazy {
53 when (descriptor.kind) {
54 KtClassKind.INTERFACE -> ClassKind.INTERFACE
55 KtClassKind.CLASS -> ClassKind.CLASS
56 KtClassKind.OBJECT -> ClassKind.OBJECT
57 KtClassKind.ENUM_CLASS -> ClassKind.ENUM_CLASS
58 KtClassKind.ENUM_ENTRY -> ClassKind.ENUM_ENTRY
59 KtClassKind.ANNOTATION_CLASS -> ClassKind.ANNOTATION_CLASS
60 }
61 }
62
63 override val isCompanionObject by lazy {
64 descriptor.isCompanionObject
65 }
66
67 override fun getSealedSubclasses(): Sequence<KSClassDeclaration> {
68 return descriptor.sealedSubclassesSequence()
69 }
70
71 override fun getAllFunctions(): Sequence<KSFunctionDeclaration> = descriptor.getAllFunctions()
72
73 override fun getAllProperties(): Sequence<KSPropertyDeclaration> = descriptor.getAllProperties()
74
75 override val primaryConstructor: KSFunctionDeclaration? by lazy {
76 descriptor.unsubstitutedPrimaryConstructor?.let { KSFunctionDeclarationDescriptorImpl.getCached(it) }
77 }
78
79 // Workaround for https://github.com/google/ksp/issues/195
80 private val mockSerializableType = ResolverImpl.instance!!.mockSerializableType
81 private val javaSerializableType = ResolverImpl.instance!!.javaSerializableType
82
83 override val superTypes: Sequence<KSTypeReference> by lazy {
84
85 descriptor.defaultType.constructor.supertypes.asSequence().map { kotlinType ->
86 KSTypeReferenceDescriptorImpl.getCached(
87 javaSerializableType?.let { if (kotlinType === mockSerializableType) it else kotlinType }
88 ?: kotlinType,
89 origin,
90 this
91 )
92 }.memoized()
93 }
94
95 override val typeParameters: List<KSTypeParameter> by lazy {
96 descriptor.declaredTypeParameters.map { KSTypeParameterDescriptorImpl.getCached(it) }
97 }
98
99 override val declarations: Sequence<KSDeclaration> by lazy {
100 sequenceOf(
101 descriptor.unsubstitutedMemberScope.getDescriptorsFiltered(),
102 // FIXME: Support static, synthetic `entries` for enums when the language feature is enabled.
103 descriptor.staticScope.getDescriptorsFiltered().filterNot {
104 descriptor.kind == KtClassKind.ENUM_CLASS &&
105 it is CallableDescriptor &&
106 it.isSynthesized &&
107 it.name == StandardNames.ENUM_ENTRIES
108 },
109 descriptor.constructors
110 ).flatten()
111 .filter {
112 it is MemberDescriptor &&
113 it.visibility != DescriptorVisibilities.INHERITED &&
114 it.visibility != DescriptorVisibilities.INVISIBLE_FAKE &&
115 (it !is CallableMemberDescriptor || it.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
116 }
117 .map {
118 when (it) {
119 is PropertyDescriptor -> KSPropertyDeclarationDescriptorImpl.getCached(it)
120 is FunctionDescriptor -> KSFunctionDeclarationDescriptorImpl.getCached(it)
121 is ClassDescriptor -> getCached(it)
122 else -> throw IllegalStateException("Unexpected descriptor type ${it.javaClass}, $ExceptionMessage")
123 }
124 }.memoized()
125 }
126
127 override val modifiers: Set<Modifier> by lazy {
128 val modifiers = mutableSetOf<Modifier>()
129 modifiers.addAll(descriptor.toKSModifiers())
130 if (descriptor.isData) {
131 modifiers.add(Modifier.DATA)
132 }
133 if (descriptor.isInline) {
134 modifiers.add(Modifier.INLINE)
135 }
136 if (descriptor.kind == KtClassKind.ANNOTATION_CLASS) {
137 modifiers.add(Modifier.ANNOTATION)
138 }
139 if (descriptor.isInner) {
140 modifiers.add(Modifier.INNER)
141 }
142 if (descriptor.isFun) {
143 modifiers.add(Modifier.FUN)
144 }
145 if (descriptor.isValue) {
146 modifiers.add(Modifier.VALUE)
147 }
148 modifiers
149 }
150
151 override fun asType(typeArguments: List<KSTypeArgument>): KSType =
152 descriptor.defaultType.replaceTypeArguments(typeArguments)?.let {
153 getKSTypeCached(it, typeArguments)
154 } ?: KSErrorType
155
156 override fun asStarProjectedType(): KSType {
157 return getKSTypeCached(descriptor.defaultType.replaceArgumentsWithStarProjections())
158 }
159
160 override fun <D, R> accept(visitor: KSVisitor<D, R>, data: D): R {
161 return visitor.visitClassDeclaration(this, data)
162 }
163 }
164
getAllFunctionsnull165 internal fun ClassDescriptor.getAllFunctions(): Sequence<KSFunctionDeclaration> {
166 ResolverImpl.instance!!.incrementalContext.recordLookupForGetAllFunctions(this)
167 val functionDescriptors = unsubstitutedMemberScope.getDescriptorsFiltered(DescriptorKindFilter.FUNCTIONS)
168 .asSequence()
169 .filter { (it as FunctionDescriptor).visibility != DescriptorVisibilities.INVISIBLE_FAKE }
170 return functionDescriptors.plus(constructors).map {
171 when (val psi = it.findPsi()) {
172 is KtFunction -> KSFunctionDeclarationImpl.getCached(psi)
173 is PsiMethod -> KSFunctionDeclarationJavaImpl.getCached(psi)
174 else -> KSFunctionDeclarationDescriptorImpl.getCached(it as FunctionDescriptor)
175 }
176 }
177 }
178
getAllPropertiesnull179 internal fun ClassDescriptor.getAllProperties(): Sequence<KSPropertyDeclaration> {
180 ResolverImpl.instance!!.incrementalContext.recordLookupForGetAllProperties(this)
181 return unsubstitutedMemberScope.getDescriptorsFiltered(DescriptorKindFilter.VARIABLES).asSequence()
182 .filter { (it as PropertyDescriptor).visibility != DescriptorVisibilities.INVISIBLE_FAKE }
183 .map {
184 when (val psi = it.findPsi()) {
185 is KtParameter -> KSPropertyDeclarationParameterImpl.getCached(psi)
186 is KtProperty -> KSPropertyDeclarationImpl.getCached(psi)
187 is PsiField -> KSPropertyDeclarationJavaImpl.getCached(psi)
188 else -> KSPropertyDeclarationDescriptorImpl.getCached(it as PropertyDescriptor)
189 }
190 }
191 }
192
sealedSubclassesSequencenull193 internal fun ClassDescriptor.sealedSubclassesSequence(): Sequence<KSClassDeclaration> {
194 // TODO record incremental subclass lookups in Kotlin 1.5.x?
195 return sealedSubclasses
196 .asSequence()
197 .map { sealedSubClass ->
198 when (val psi = sealedSubClass.findPsi()) {
199 is KtClassOrObject -> KSClassDeclarationImpl.getCached(psi)
200 else -> KSClassDeclarationDescriptorImpl.getCached(sealedSubClass)
201 }
202 }
203 }
204