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