• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.kotlin
19 
20 import com.google.devtools.ksp.KSObjectCache
21 import com.google.devtools.ksp.getClassType
22 import com.google.devtools.ksp.isConstructor
23 import com.google.devtools.ksp.memoized
24 import com.google.devtools.ksp.processing.impl.ResolverImpl
25 import com.google.devtools.ksp.symbol.*
26 import com.google.devtools.ksp.symbol.impl.*
27 import com.google.devtools.ksp.symbol.impl.binary.getAllFunctions
28 import com.google.devtools.ksp.symbol.impl.binary.getAllProperties
29 import com.google.devtools.ksp.symbol.impl.binary.sealedSubclassesSequence
30 import com.google.devtools.ksp.symbol.impl.synthetic.KSConstructorSyntheticImpl
31 import com.google.devtools.ksp.symbol.impl.synthetic.KSTypeReferenceSyntheticImpl
32 import org.jetbrains.kotlin.descriptors.ClassDescriptor
33 import org.jetbrains.kotlin.psi.KtClassOrObject
34 import org.jetbrains.kotlin.psi.KtObjectDeclaration
35 import org.jetbrains.kotlin.psi.KtSecondaryConstructor
36 import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
37 
38 class KSClassDeclarationImpl private constructor(val ktClassOrObject: KtClassOrObject) :
39     KSClassDeclaration,
40     KSDeclarationImpl(ktClassOrObject),
41     KSExpectActual by KSExpectActualImpl(ktClassOrObject) {
42     companion object : KSObjectCache<KtClassOrObject, KSClassDeclarationImpl>() {
43         fun getCached(ktClassOrObject: KtClassOrObject) =
44             cache.getOrPut(ktClassOrObject) { KSClassDeclarationImpl(ktClassOrObject) }
45     }
46 
47     override val classKind: ClassKind by lazy {
48         ktClassOrObject.getClassType()
49     }
50 
51     override val isCompanionObject by lazy {
52         (ktClassOrObject is KtObjectDeclaration) && (ktClassOrObject.isCompanion())
53     }
54 
55     override fun getSealedSubclasses(): Sequence<KSClassDeclaration> {
56         return if (Modifier.SEALED in modifiers) {
57             ResolverImpl.instance!!.incrementalContext.recordGetSealedSubclasses(this)
58             descriptor.sealedSubclassesSequence()
59         } else {
60             emptySequence()
61         }
62     }
63 
64     override fun getAllFunctions(): Sequence<KSFunctionDeclaration> = descriptor.getAllFunctions()
65 
66     override fun getAllProperties(): Sequence<KSPropertyDeclaration> = descriptor.getAllProperties()
67 
68     override val declarations: Sequence<KSDeclaration> by lazy {
69         val propertiesFromConstructor = primaryConstructor?.parameters
70             ?.asSequence()
71             ?.filter { it.isVar || it.isVal }
72             ?.map { KSPropertyDeclarationParameterImpl.getCached((it as KSValueParameterImpl).ktParameter) }
73             ?: emptySequence()
74         var result = propertiesFromConstructor.plus(ktClassOrObject.declarations.asSequence().getKSDeclarations())
75         primaryConstructor?.let { primaryConstructor: KSFunctionDeclaration ->
76             // if primary constructor is from source, it won't show up in declarations
77             // hence add it as well.
78             if (primaryConstructor.origin == Origin.KOTLIN) {
79                 result = sequenceOf(primaryConstructor).plus(result)
80             }
81         }
82         if (classKind != ClassKind.INTERFACE) {
83             // check if we need to add a synthetic constructor
84             val hasConstructor = result.any {
85                 it is KSFunctionDeclaration && it.isConstructor()
86             }
87             if (hasConstructor) {
88                 result.memoized()
89             } else {
90                 (result + KSConstructorSyntheticImpl.getCached(this)).memoized()
91             }
92         } else {
93             result.memoized()
94         }
95     }
96 
97     override val primaryConstructor: KSFunctionDeclaration? by lazy {
98         ktClassOrObject.primaryConstructor?.let { KSFunctionDeclarationImpl.getCached(it) }
99             ?: if ((classKind == ClassKind.CLASS || classKind == ClassKind.ENUM_CLASS) &&
100                 ktClassOrObject.declarations.none { it is KtSecondaryConstructor }
101             )
102                 KSConstructorSyntheticImpl.getCached(this) else null
103     }
104 
105     override val superTypes: Sequence<KSTypeReference> by lazy {
106         val resolver = ResolverImpl.instance!!
107         ktClassOrObject.superTypeListEntries
108             .asSequence()
109             .map { KSTypeReferenceImpl.getCached(it.typeReference!!) }
110             .ifEmpty {
111                 sequenceOf(
112                     KSTypeReferenceSyntheticImpl.getCached(
113                         resolver.builtIns.anyType,
114                         this
115                     )
116                 )
117             }
118             .memoized()
119     }
120 
121     private val descriptor: ClassDescriptor by lazy {
122         (ResolverImpl.instance!!.resolveDeclaration(ktClassOrObject) as ClassDescriptor)
123     }
124 
125     override fun asType(typeArguments: List<KSTypeArgument>): KSType {
126         return descriptor.defaultType.replaceTypeArguments(typeArguments)?.let {
127             getKSTypeCached(it, typeArguments)
128         } ?: KSErrorType
129     }
130 
131     override fun asStarProjectedType(): KSType {
132         return getKSTypeCached(descriptor.defaultType.replaceArgumentsWithStarProjections())
133     }
134 
135     override fun <D, R> accept(visitor: KSVisitor<D, R>, data: D): R {
136         return visitor.visitClassDeclaration(this, data)
137     }
138 }
139