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