1 /* 2 * 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.java 19 20 import com.google.devtools.ksp.KSObjectCache 21 import com.google.devtools.ksp.isConstructor 22 import com.google.devtools.ksp.memoized 23 import com.google.devtools.ksp.processing.impl.KSNameImpl 24 import com.google.devtools.ksp.processing.impl.ResolverImpl 25 import com.google.devtools.ksp.processing.impl.workaroundForNested 26 import com.google.devtools.ksp.symbol.* 27 import com.google.devtools.ksp.symbol.impl.* 28 import com.google.devtools.ksp.symbol.impl.binary.getAllFunctions 29 import com.google.devtools.ksp.symbol.impl.binary.getAllProperties 30 import com.google.devtools.ksp.symbol.impl.kotlin.KSErrorType 31 import com.google.devtools.ksp.symbol.impl.kotlin.KSExpectActualNoImpl 32 import com.google.devtools.ksp.symbol.impl.kotlin.getKSTypeCached 33 import com.google.devtools.ksp.symbol.impl.replaceTypeArguments 34 import com.google.devtools.ksp.symbol.impl.synthetic.KSConstructorSyntheticImpl 35 import com.google.devtools.ksp.toKSModifiers 36 import com.intellij.psi.PsiClass 37 import com.intellij.psi.PsiEnumConstant 38 import com.intellij.psi.PsiJavaFile 39 import org.jetbrains.kotlin.descriptors.ClassDescriptor 40 import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl 41 import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections 42 43 class KSClassDeclarationJavaImpl private constructor(val psi: PsiClass) : 44 KSClassDeclaration, 45 KSDeclarationJavaImpl(psi), 46 KSExpectActual by KSExpectActualNoImpl() { 47 companion object : KSObjectCache<PsiClass, KSClassDeclarationJavaImpl>() { <lambda>null48 fun getCached(psi: PsiClass) = cache.getOrPut(psi) { KSClassDeclarationJavaImpl(psi) } 49 } 50 51 override val origin = Origin.JAVA 52 <lambda>null53 override val location: Location by lazy { 54 psi.toLocation() 55 } 56 <lambda>null57 override val annotations: Sequence<KSAnnotation> by lazy { 58 psi.annotations.asSequence().map { KSAnnotationJavaImpl.getCached(it) }.memoized() 59 } 60 <lambda>null61 override val classKind: ClassKind by lazy { 62 when { 63 psi.isAnnotationType -> ClassKind.ANNOTATION_CLASS 64 psi.isInterface -> ClassKind.INTERFACE 65 psi.isEnum -> ClassKind.ENUM_CLASS 66 else -> ClassKind.CLASS 67 } 68 } 69 <lambda>null70 override val containingFile: KSFile? by lazy { 71 KSFileJavaImpl.getCached(psi.containingFile as PsiJavaFile) 72 } 73 74 override val isCompanionObject = false 75 76 // Could the resolution ever fail? <lambda>null77 private val descriptor: ClassDescriptor? by lazy { 78 ResolverImpl.instance!!.moduleClassResolver.resolveClass(JavaClassImpl(psi).apply { workaroundForNested() }) 79 } 80 81 // TODO in 1.5 + jvmTarget 15, will we return Java permitted types? getSealedSubclassesnull82 override fun getSealedSubclasses(): Sequence<KSClassDeclaration> = emptySequence() 83 84 override fun getAllFunctions(): Sequence<KSFunctionDeclaration> = 85 descriptor?.getAllFunctions() ?: emptySequence() 86 87 override fun getAllProperties(): Sequence<KSPropertyDeclaration> = 88 descriptor?.getAllProperties() ?: emptySequence() 89 90 override val declarations: Sequence<KSDeclaration> by lazy { 91 val allDeclarations = ( 92 psi.fields.asSequence().map { 93 when (it) { 94 is PsiEnumConstant -> KSClassDeclarationJavaEnumEntryImpl.getCached(it) 95 else -> KSPropertyDeclarationJavaImpl.getCached(it) 96 } 97 } + 98 psi.innerClasses.map { KSClassDeclarationJavaImpl.getCached(it) } + 99 psi.constructors.map { KSFunctionDeclarationJavaImpl.getCached(it) } + 100 psi.methods.map { KSFunctionDeclarationJavaImpl.getCached(it) } 101 ) 102 .distinct() 103 // java annotation classes are interface. they get a constructor in .class 104 // hence they should get one here. 105 if (classKind == ClassKind.ANNOTATION_CLASS || !psi.isInterface) { 106 val hasConstructor = allDeclarations.any { 107 it is KSFunctionDeclaration && it.isConstructor() 108 } 109 if (hasConstructor) { 110 allDeclarations.memoized() 111 } else { 112 (allDeclarations + KSConstructorSyntheticImpl.getCached(this)).memoized() 113 } 114 } else { 115 allDeclarations.memoized() 116 } 117 } 118 <lambda>null119 override val modifiers: Set<Modifier> by lazy { 120 val modifiers = mutableSetOf<Modifier>() 121 modifiers.addAll(psi.toKSModifiers()) 122 if (psi.isAnnotationType) { 123 modifiers.add(Modifier.ANNOTATION) 124 } 125 if (psi.isEnum) { 126 modifiers.add(Modifier.ENUM) 127 } 128 modifiers 129 } 130 131 override val primaryConstructor: KSFunctionDeclaration? = null 132 <lambda>null133 override val qualifiedName: KSName by lazy { 134 KSNameImpl.getCached(psi.qualifiedName!!) 135 } 136 <lambda>null137 override val simpleName: KSName by lazy { 138 KSNameImpl.getCached(psi.name!!) 139 } 140 <lambda>null141 override val superTypes: Sequence<KSTypeReference> by lazy { 142 val adjusted = if (!psi.isInterface && psi.superTypes.size > 1) { 143 psi.superTypes.filterNot { 144 it.className == "Object" && it.canonicalText == "java.lang.Object" 145 } 146 } else { 147 psi.superTypes.toList() 148 } 149 adjusted.asSequence().map { KSTypeReferenceJavaImpl.getCached(it, this) }.memoized() 150 } 151 <lambda>null152 override val typeParameters: List<KSTypeParameter> by lazy { 153 psi.typeParameters.map { KSTypeParameterJavaImpl.getCached(it) } 154 } 155 asTypenull156 override fun asType(typeArguments: List<KSTypeArgument>): KSType { 157 return descriptor?.let { 158 it.defaultType.replaceTypeArguments(typeArguments)?.let { 159 getKSTypeCached(it, typeArguments) 160 } 161 } ?: KSErrorType 162 } 163 asStarProjectedTypenull164 override fun asStarProjectedType(): KSType { 165 return descriptor?.let { 166 getKSTypeCached(it.defaultType.replaceArgumentsWithStarProjections()) 167 } ?: KSErrorType 168 } 169 acceptnull170 override fun <D, R> accept(visitor: KSVisitor<D, R>, data: D): R { 171 return visitor.visitClassDeclaration(this, data) 172 } 173 } 174