xref: /aosp_15_r20/external/ksp/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt (revision af87fb4bb8e3042070d2a054e912924f599b22b7)
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.processing.impl
19 
20 import com.google.devtools.ksp.*
21 import com.google.devtools.ksp.processing.KSBuiltIns
22 import com.google.devtools.ksp.processing.Resolver
23 import com.google.devtools.ksp.processing.SymbolProcessor
24 import com.google.devtools.ksp.symbol.*
25 import com.google.devtools.ksp.symbol.ClassKind
26 import com.google.devtools.ksp.symbol.Variance
27 import com.google.devtools.ksp.symbol.impl.binary.*
28 import com.google.devtools.ksp.symbol.impl.declarationsInSourceOrder
29 import com.google.devtools.ksp.symbol.impl.findParentAnnotated
30 import com.google.devtools.ksp.symbol.impl.findPsi
31 import com.google.devtools.ksp.symbol.impl.getInstanceForCurrentRound
32 import com.google.devtools.ksp.symbol.impl.java.*
33 import com.google.devtools.ksp.symbol.impl.jvmAccessFlag
34 import com.google.devtools.ksp.symbol.impl.kotlin.*
35 import com.google.devtools.ksp.symbol.impl.resolveContainingClass
36 import com.google.devtools.ksp.symbol.impl.synthetic.*
37 import com.google.devtools.ksp.visitor.CollectAnnotatedSymbolsVisitor
38 import com.intellij.openapi.project.Project
39 import com.intellij.psi.*
40 import com.intellij.psi.impl.source.PsiClassReferenceType
41 import org.jetbrains.kotlin.builtins.KotlinBuiltIns
42 import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
43 import org.jetbrains.kotlin.codegen.ClassBuilderMode
44 import org.jetbrains.kotlin.codegen.OwnerKind
45 import org.jetbrains.kotlin.codegen.state.JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME
46 import org.jetbrains.kotlin.codegen.state.JVM_WILDCARD_ANNOTATION_FQ_NAME
47 import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
48 import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
49 import org.jetbrains.kotlin.container.ComponentProvider
50 import org.jetbrains.kotlin.container.get
51 import org.jetbrains.kotlin.container.tryGetService
52 import org.jetbrains.kotlin.descriptors.*
53 import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
54 import org.jetbrains.kotlin.descriptors.annotations.Annotations
55 import org.jetbrains.kotlin.incremental.components.NoLookupLocation
56 import org.jetbrains.kotlin.load.java.components.TypeUsage
57 import org.jetbrains.kotlin.load.java.descriptors.JavaForKotlinOverridePropertyDescriptor
58 import org.jetbrains.kotlin.load.java.lazy.JavaResolverComponents
59 import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
60 import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver
61 import org.jetbrains.kotlin.load.java.lazy.TypeParameterResolver
62 import org.jetbrains.kotlin.load.java.lazy.childForClassOrPackage
63 import org.jetbrains.kotlin.load.java.lazy.childForMethod
64 import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor
65 import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver
66 import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
67 import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
68 import org.jetbrains.kotlin.load.java.structure.JavaClass
69 import org.jetbrains.kotlin.load.java.structure.classId
70 import org.jetbrains.kotlin.load.java.structure.impl.JavaArrayTypeImpl
71 import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
72 import org.jetbrains.kotlin.load.java.structure.impl.JavaConstructorImpl
73 import org.jetbrains.kotlin.load.java.structure.impl.JavaFieldImpl
74 import org.jetbrains.kotlin.load.java.structure.impl.JavaMethodImpl
75 import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeImpl
76 import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeParameterImpl
77 import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass
78 import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaMethod
79 import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaMethodBase
80 import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
81 import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass
82 import org.jetbrains.kotlin.load.kotlin.getContainingKotlinJvmBinaryClass
83 import org.jetbrains.kotlin.load.kotlin.getOptimalModeForReturnType
84 import org.jetbrains.kotlin.load.kotlin.getOptimalModeForValueParameter
85 import org.jetbrains.kotlin.name.FqName
86 import org.jetbrains.kotlin.name.FqNameUnsafe
87 import org.jetbrains.kotlin.name.Name
88 import org.jetbrains.kotlin.psi.*
89 import org.jetbrains.kotlin.resolve.*
90 import org.jetbrains.kotlin.resolve.annotations.argumentValue
91 import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
92 import org.jetbrains.kotlin.resolve.calls.inference.components.composeWith
93 import org.jetbrains.kotlin.resolve.calls.inference.substitute
94 import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
95 import org.jetbrains.kotlin.resolve.constants.*
96 import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
97 import org.jetbrains.kotlin.resolve.descriptorUtil.classId
98 import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperClassifiers
99 import org.jetbrains.kotlin.resolve.descriptorUtil.module
100 import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor
101 import org.jetbrains.kotlin.resolve.lazy.DeclarationScopeProvider
102 import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
103 import org.jetbrains.kotlin.resolve.lazy.ResolveSession
104 import org.jetbrains.kotlin.resolve.multiplatform.findActuals
105 import org.jetbrains.kotlin.resolve.multiplatform.findExpects
106 import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
107 import org.jetbrains.kotlin.resolve.scopes.LexicalScope
108 import org.jetbrains.kotlin.resolve.scopes.MemberScope
109 import org.jetbrains.kotlin.types.*
110 import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext
111 import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
112 import org.jetbrains.kotlin.types.typeUtil.substitute
113 import org.jetbrains.kotlin.types.typeUtil.supertypes
114 import org.jetbrains.kotlin.util.containingNonLocalDeclaration
115 import org.jetbrains.org.objectweb.asm.ClassReader
116 import org.jetbrains.org.objectweb.asm.ClassVisitor
117 import org.jetbrains.org.objectweb.asm.MethodVisitor
118 import org.jetbrains.org.objectweb.asm.Opcodes
119 import org.jetbrains.org.objectweb.asm.Opcodes.API_VERSION
120 import java.io.File
121 import java.util.Stack
122 
123 class ResolverImpl(
124     val module: ModuleDescriptor,
125     val allKSFiles: Collection<KSFile>,
126     val newKSFiles: Collection<KSFile>,
127     private val deferredSymbols: Map<SymbolProcessor, List<KSAnnotated>>,
128     val bindingTrace: BindingTrace,
129     val project: Project,
130     componentProvider: ComponentProvider,
131     val incrementalContext: IncrementalContext,
132     val options: KspOptions,
133 ) : Resolver {
134     val psiDocumentManager = PsiDocumentManager.getInstance(project)
135     private val nameToKSMap: MutableMap<KSName, KSClassDeclaration>
136     private val javaTypeParameterMap: MutableMap<LazyJavaTypeParameterDescriptor, PsiTypeParameter> = mutableMapOf()
137 
138     /**
139      * Checking as member of is an expensive operation, hence we cache result values in this map.
140      */
141     private val functionAsMemberOfCache: MutableMap<Pair<KSFunctionDeclaration, KSType>, KSFunction>
142     private val propertyAsMemberOfCache: MutableMap<Pair<KSPropertyDeclaration, KSType>, KSType>
143 
144     private val typeMapper = KotlinTypeMapper(
145         BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES,
146         module.name.getNonSpecialIdentifier(),
147         KotlinTypeMapper.LANGUAGE_VERSION_SETTINGS_DEFAULT, // TODO use proper LanguageVersionSettings
148         true
149     )
150     private val qualifiedExpressionResolver = QualifiedExpressionResolver(LanguageVersionSettingsImpl.DEFAULT)
151 
152     private val aliasingFqNs: MutableMap<String, KSTypeAlias> = mutableMapOf()
153     private val aliasingNames: MutableSet<String> = mutableSetOf()
154     private val topDownAnalysisContext by lazy {
155         TopDownAnalysisContext(TopDownAnalysisMode.TopLevelDeclarations, DataFlowInfo.EMPTY, declarationScopeProvider)
156     }
157 
158     companion object {
159         var instance: ResolverImpl? = null
160     }
161 
162     var resolveSession: ResolveSession
163     var bodyResolver: BodyResolver
164     var constantExpressionEvaluator: ConstantExpressionEvaluator
165     var declarationScopeProvider: DeclarationScopeProvider
166 
167     lateinit var moduleClassResolver: ModuleClassResolver
168     lateinit var javaTypeResolver: JavaTypeResolver
169     lateinit var lazyJavaResolverContext: LazyJavaResolverContext
170 
171     init {
172         resolveSession = componentProvider.get()
173         bodyResolver = componentProvider.get()
174         declarationScopeProvider = componentProvider.get()
175         constantExpressionEvaluator = componentProvider.get()
176 
177         componentProvider.tryGetService(JavaResolverComponents::class.java)?.let {
178             lazyJavaResolverContext = LazyJavaResolverContext(it, TypeParameterResolver.EMPTY) { null }
179             javaTypeResolver = lazyJavaResolverContext.typeResolver
180             moduleClassResolver = lazyJavaResolverContext.components.moduleClassResolver
181         }
182         instance = this
183 
184         nameToKSMap = mutableMapOf()
185         functionAsMemberOfCache = mutableMapOf()
186         propertyAsMemberOfCache = mutableMapOf()
187 
188         val visitor = object : KSVisitorVoid() {
189             override fun visitFile(file: KSFile, data: Unit) {
190                 file.declarations.forEach { it.accept(this, data) }
191 
192                 // TODO: evaluate with benchmarks: cost of getContainingFile v.s. name collision
193                 // Import aliases are file-scoped. `aliasingNamesByFile` could be faster
194                 (file as? KSFileImpl)?.file?.importDirectives?.forEach {
195                     it.aliasName?.let { aliasingNames.add(it) }
196                 }
197             }
198 
199             override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {
200                 val qualifiedName = classDeclaration.qualifiedName
201                 if (qualifiedName != null) {
202                     nameToKSMap[qualifiedName] = classDeclaration
203                 }
204                 classDeclaration.declarations.forEach { it.accept(this, data) }
205             }
206 
207             override fun visitTypeAlias(typeAlias: KSTypeAlias, data: Unit) {
208                 typeAlias.qualifiedName?.asString()?.let { fqn ->
209                     aliasingFqNs[fqn] = typeAlias
210                     aliasingNames.add(fqn.substringAfterLast('.'))
211                 }
212             }
213         }
214 
215         // FIXME: reuse results from previous rounds and only loop through newKSFiles.
216         allKSFiles.forEach { it.accept(visitor, Unit) }
217     }
218 
219     // Mitigation for processors with memory leaks
220     // https://github.com/google/ksp/issues/1063
221     fun tearDown() {
222         instance = null
223     }
224 
225     override fun getNewFiles(): Sequence<KSFile> {
226         return newKSFiles.asSequence()
227     }
228 
229     override fun getAllFiles(): Sequence<KSFile> {
230         return allKSFiles.asSequence()
231     }
232 
233     override fun getClassDeclarationByName(name: KSName): KSClassDeclaration? {
234         nameToKSMap[name]?.let { return it }
235 
236         return module.resolveClassByFqName(FqName(name.asString()), NoLookupLocation.WHEN_FIND_BY_FQNAME)
237             ?.let {
238                 val psi = it.findPsi()
239                 if (psi != null) {
240                     when (psi) {
241                         is KtClassOrObject -> KSClassDeclarationImpl.getCached(psi)
242                         is PsiClass -> KSClassDeclarationJavaImpl.getCached(psi)
243                         else -> throw IllegalStateException("unexpected psi: ${psi.javaClass}")
244                     }
245                 } else {
246                     KSClassDeclarationDescriptorImpl.getCached(it)
247                 }
248             }
249     }
250 
251     override fun getFunctionDeclarationsByName(
252         name: KSName,
253         includeTopLevel: Boolean,
254     ): Sequence<KSFunctionDeclaration> {
255         val qualifier = name.getQualifier()
256         val functionName = name.getShortName()
257         val nonTopLevelResult = this.getClassDeclarationByName(qualifier)?.getDeclaredFunctions()
258             ?.filter { it.simpleName.asString() == functionName }?.asSequence() ?: emptySequence()
259         return if (!includeTopLevel) nonTopLevelResult else {
260             nonTopLevelResult.plus(
261                 module.getPackage(FqName(qualifier))
262                     .memberScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS) {
263                         it.asString() == functionName
264                     }
265                     .filterIsInstance<MemberDescriptor>().mapNotNull { it.toKSDeclaration() as? KSFunctionDeclaration }
266             )
267         }
268     }
269 
270     override fun getPropertyDeclarationByName(name: KSName, includeTopLevel: Boolean): KSPropertyDeclaration? {
271         val qualifier = name.getQualifier()
272         val propertyName = name.getShortName()
273         val nonTopLevelResult = this.getClassDeclarationByName(qualifier)?.getDeclaredProperties()
274             ?.singleOrNull { it.simpleName.asString() == propertyName }
275         return if (!includeTopLevel) nonTopLevelResult else {
276             val topLevelResult = (
277                 module.getPackage(FqName(qualifier))
278                     .memberScope.getContributedDescriptors(DescriptorKindFilter.VARIABLES) {
279                         it.asString() == propertyName
280                     }
281                     .also {
282                         if (it.size > 1) {
283                             throw IllegalStateException("Found multiple properties with same qualified name")
284                         }
285                     }
286                     .singleOrNull() as? MemberDescriptor
287                 )?.toKSDeclaration() as? KSPropertyDeclaration
288             if (topLevelResult != null && nonTopLevelResult != null) {
289                 throw IllegalStateException("Found multiple properties with same qualified name")
290             }
291             nonTopLevelResult ?: topLevelResult
292         }
293     }
294 
295     internal fun checkAnnotation(annotation: KSAnnotation, ksName: KSName, shortName: String): Boolean {
296         val annotationType = annotation.annotationType
297         val referencedName = (annotationType.element as? KSClassifierReference)?.referencedName()
298         val simpleName = referencedName?.substringAfterLast('.')
299         return (simpleName == shortName || simpleName in aliasingNames) &&
300             annotationType.resolveToUnderlying().declaration.qualifiedName == ksName
301     }
302 
303     override fun getSymbolsWithAnnotation(annotationName: String, inDepth: Boolean): Sequence<KSAnnotated> {
304         // If annotationName is a typealias, resolve to underlying type.
305         val realAnnotationName =
306             aliasingFqNs[annotationName]?.type?.resolveToUnderlying()?.declaration?.qualifiedName?.asString()
307                 ?: annotationName
308 
309         val ksName = KSNameImpl.getCached(realAnnotationName)
310         val shortName = ksName.getShortName()
311 
312         fun checkAnnotated(annotated: KSAnnotated): Boolean {
313             return annotated.annotations.any {
314                 checkAnnotation(it, ksName, shortName)
315             }
316         }
317 
318         val allAnnotated = if (inDepth) newAnnotatedSymbolsWithLocals else newAnnotatedSymbols
319         return allAnnotated.asSequence().filter(::checkAnnotated)
320     }
321 
322     private fun collectAnnotatedSymbols(inDepth: Boolean): Collection<KSAnnotated> {
323         val visitor = CollectAnnotatedSymbolsVisitor(inDepth)
324 
325         for (file in newKSFiles) {
326             file.accept(visitor, Unit)
327         }
328 
329         return visitor.symbols
330     }
331 
332     private val deferredSymbolsUpdated: Collection<KSAnnotated> by lazy {
333         deferredSymbols.values.flatten().mapNotNull { it.getInstanceForCurrentRound() }
334     }
335 
336     private val newAnnotatedSymbols: Collection<KSAnnotated> by lazy {
337         collectAnnotatedSymbols(false) + deferredSymbolsUpdated
338     }
339 
340     private val newAnnotatedSymbolsWithLocals: Collection<KSAnnotated> by lazy {
341         collectAnnotatedSymbols(true) + deferredSymbolsUpdated
342     }
343 
344     override fun getKSNameFromString(name: String): KSName {
345         return KSNameImpl.getCached(name)
346     }
347 
348     override fun createKSTypeReferenceFromKSType(type: KSType): KSTypeReference {
349         return KSTypeReferenceSyntheticImpl.getCached(type, null)
350     }
351 
352     @KspExperimental
353     override fun mapToJvmSignature(declaration: KSDeclaration): String? = mapToJvmSignatureInternal(declaration)
354 
355     internal fun mapToJvmSignatureInternal(declaration: KSDeclaration): String? = when (declaration) {
356         is KSClassDeclaration -> resolveClassDeclaration(declaration)?.let { typeMapper.mapType(it).descriptor }
357         is KSFunctionDeclaration -> resolveFunctionDeclaration(declaration)?.let {
358             when (it) {
359                 is FunctionDescriptor -> typeMapper.mapAsmMethod(it).descriptor
360                 is PropertyDescriptor -> typeMapper.mapFieldSignature(it.type, it) ?: typeMapper.mapType(it).descriptor
361                 else -> throw IllegalStateException("Unexpected descriptor type for declaration: $declaration")
362             }
363         }
364         is KSPropertyDeclaration -> resolvePropertyDeclaration(declaration)?.let {
365             typeMapper.mapFieldSignature(it.type, it) ?: typeMapper.mapType(it).descriptor
366         }
367         else -> null
368     }
369 
370     override fun overrides(overrider: KSDeclaration, overridee: KSDeclaration): Boolean {
371         fun resolveForOverride(declaration: KSDeclaration): DeclarationDescriptor? {
372             return when (declaration) {
373                 is KSPropertyDeclaration -> resolvePropertyDeclaration(declaration)
374                 is KSFunctionDeclarationJavaImpl -> resolveJavaDeclaration(declaration.psi)
375                 is KSFunctionDeclaration -> resolveFunctionDeclaration(declaration)
376                 else -> null
377             }
378         }
379 
380         if (!overridee.isOpen())
381             return false
382         if (!overridee.isVisibleFrom(overrider))
383             return false
384         if (!(
385             overridee is KSFunctionDeclaration || overrider is KSFunctionDeclaration ||
386                 (overridee is KSPropertyDeclaration && overrider is KSPropertyDeclaration)
387             )
388         )
389             return false
390 
391         if (overrider is KSPropertyDeclarationJavaImpl)
392             return false
393 
394         val superDescriptor = resolveForOverride(overridee) as? CallableMemberDescriptor ?: return false
395         val subDescriptor = resolveForOverride(overrider) as? CallableMemberDescriptor ?: return false
396         val subClassDescriptor = overrider.closestClassDeclaration()?.let {
397             resolveClassDeclaration(it)
398         } ?: return false
399         val superClassDescriptor = overridee.closestClassDeclaration()?.let {
400             resolveClassDeclaration(it)
401         } ?: return false
402 
403         incrementalContext.recordLookupWithSupertypes(subClassDescriptor.defaultType)
404 
405         val typeOverride = subClassDescriptor.getAllSuperClassifiers()
406             .filter { it != subClassDescriptor } // exclude subclass itself as it cannot override its own methods
407             .any {
408                 it == superClassDescriptor
409             }
410         if (!typeOverride) return false
411 
412         incrementalContext.recordLookupForDeclaration(overrider)
413         incrementalContext.recordLookupForDeclaration(overridee)
414 
415         return OverridingUtil.overrides(subDescriptor, superDescriptor, true, true)
416     }
417 
418     // check if the candidate is overridden from the original declaration.
419     private fun isOriginal(original: KSDeclaration, candidate: KSDeclaration): Boolean {
420         incrementalContext.recordLookupForDeclaration(original)
421         incrementalContext.recordLookupForDeclaration(candidate)
422         val originalDescriptor = when (original) {
423             is KSPropertyDeclaration -> resolvePropertyDeclaration(original)
424             is KSFunctionDeclaration ->
425                 (resolveFunctionDeclaration(original) as? FunctionDescriptor)?.propertyIfAccessor
426             else -> return false
427         }
428 
429         val candidateDescriptors = when (candidate) {
430             is KSPropertyDeclaration -> resolvePropertyDeclaration(candidate)?.overriddenDescriptors
431             is KSFunctionDeclaration -> resolveFunctionDeclaration(candidate)?.overriddenDescriptors
432             else -> return false
433         }
434         return candidateDescriptors?.any { it == originalDescriptor } ?: false
435     }
436 
437     override fun overrides(
438         overrider: KSDeclaration,
439         overridee: KSDeclaration,
440         containingClass: KSClassDeclaration
441     ): Boolean {
442         incrementalContext.recordLookupForDeclaration(containingClass)
443         return when (overrider) {
444             is KSPropertyDeclaration -> containingClass.getAllProperties().singleOrNull {
445                 it.simpleName.asString() == overrider.simpleName.asString() && isOriginal(overrider, it)
446             }?.let { overrides(it, overridee) } ?: false
447             is KSFunctionDeclaration -> {
448                 val candidates = containingClass.getAllFunctions().filter {
449                     it.simpleName.asString() == overridee.simpleName.asString()
450                 }
451                 if (overrider.simpleName.asString().startsWith("get") ||
452                     overrider.simpleName.asString().startsWith("set")
453                 ) {
454                     candidates.plus(
455                         containingClass.getAllProperties().filter {
456                             val overriderName = overrider.simpleName.asString().substring(3)
457                                 .replaceFirstChar { it.lowercase() }
458                             it.simpleName.asString() == overriderName ||
459                                 it.simpleName.asString().replaceFirstChar { it.lowercase() } == overriderName
460                         }
461                         // TODO: It is currently not possible to do the overridden descriptor optimization for java overrides.
462                     ).any { overrides(it, overridee) }
463                 } else {
464                     candidates.singleOrNull { isOriginal(overrider, it) }?.let { overrides(it, overridee) } ?: false
465                 }
466             }
467             else -> false
468         }
469     }
470 
471     fun evaluateConstant(expression: KtExpression?, expectedType: KotlinType): ConstantValue<*>? {
472         return expression?.let {
473             if (it is KtClassLiteralExpression && it.receiverExpression != null) {
474                 val parent = KtStubbedPsiUtil.getPsiOrStubParent(it, KtPrimaryConstructor::class.java, false)
475                 val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(parent!!)
476                 val result = qualifiedExpressionResolver
477                     .resolveDescriptorForDoubleColonLHS(it.receiverExpression!!, scope, bindingTrace, false)
478                 val classifier = result.classifierDescriptor ?: return null
479                 val typeResolutionContext = TypeResolutionContext(scope, bindingTrace, true, true, false)
480                 val possiblyBareType = resolveSession.typeResolver
481                     .resolveTypeForClassifier(typeResolutionContext, classifier, result, it, Annotations.EMPTY)
482                 var actualType = if (possiblyBareType.isBare)
483                     possiblyBareType.bareTypeConstructor.declarationDescriptor!!.defaultType
484                 else possiblyBareType.actualType
485                 var arrayDimension = 0
486                 while (KotlinBuiltIns.isArray(actualType)) {
487                     actualType = actualType.arguments.single().type
488                     arrayDimension += 1
489                 }
490                 KClassValue(actualType.constructor.declarationDescriptor.classId!!, arrayDimension)
491             } else {
492                 constantExpressionEvaluator.evaluateExpression(it, bindingTrace)?.toConstantValue(expectedType) ?: run {
493                     val parent = KtStubbedPsiUtil
494                         .getPsiOrStubParent(expression, KtPrimaryConstructor::class.java, false)
495                     val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(parent!!)
496                     qualifiedExpressionResolver
497                         .resolvePackageHeader(expression.containingKtFile.packageDirective!!, module, bindingTrace)
498                     bodyResolver.resolveConstructorParameterDefaultValues(
499                         topDownAnalysisContext.outerDataFlowInfo, bindingTrace,
500                         parent, (scope.ownerDescriptor as ClassDescriptor).constructors.first(), scope,
501                         resolveSession.inferenceSession
502                     )
503                     constantExpressionEvaluator.evaluateExpression(it, bindingTrace)?.toConstantValue(expectedType)
504                 }
505             }
506         }
507     }
508 
509     fun resolveDeclaration(declaration: KtDeclaration): DeclarationDescriptor? {
510         return if (KtPsiUtil.isLocal(declaration)) {
511             resolveDeclarationForLocal(declaration)
512             bindingTrace.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
513         } else {
514             resolveSession.resolveToDescriptor(declaration)
515         }
516     }
517 
518     // TODO: Resolve Java variables is not supported by this function. Not needed currently.
519     fun resolveJavaDeclaration(psi: PsiElement): DeclarationDescriptor? {
520         return when (psi) {
521             is PsiClass -> moduleClassResolver.resolveClass(
522                 JavaClassImpl(psi).apply { workaroundForNested(lazyJavaResolverContext) }
523             )
524             is PsiMethod -> {
525                 // TODO: get rid of hardcoded check if possible.
526                 val property = if (psi.name.startsWith("set") || psi.name.startsWith("get")) {
527                     moduleClassResolver
528                         .resolveContainingClass(psi)
529                         ?.findEnclosedDescriptor(
530                             kindFilter = DescriptorKindFilter.CALLABLES
531                         ) {
532                             (it as? PropertyDescriptor)?.getter?.findPsi() == psi ||
533                                 (it as? PropertyDescriptor)?.setter?.findPsi() == psi
534                         }
535                 } else null
536                 property ?: moduleClassResolver
537                     .resolveContainingClass(psi)?.let { containingClass ->
538                         val filter = if (psi is SyntheticElement) {
539                             { declaration: DeclarationDescriptor -> declaration.name.asString() == psi.name }
540                         } else {
541                             { declaration: DeclarationDescriptor -> declaration.findPsi() == psi }
542                         }
543                         containingClass.findEnclosedDescriptor(
544                             kindFilter = DescriptorKindFilter.FUNCTIONS,
545                             filter = filter
546                         )
547                     }
548             }
549             is PsiField -> {
550                 moduleClassResolver
551                     .resolveClass(
552                         JavaFieldImpl(psi).containingClass.apply { workaroundForNested(lazyJavaResolverContext) }
553                     )
554                     ?.findEnclosedDescriptor(
555                         kindFilter = DescriptorKindFilter.VARIABLES,
556                         filter = { it.findPsi() == psi }
557                     )
558             }
559             else -> throw IllegalStateException("unhandled psi element kind: ${psi.javaClass}")
560         }
561     }
562 
563     fun resolveClassDeclaration(classDeclaration: KSClassDeclaration): ClassDescriptor? {
564         return when (classDeclaration) {
565             is KSClassDeclarationImpl -> resolveDeclaration(classDeclaration.ktClassOrObject)
566             is KSClassDeclarationDescriptorImpl -> classDeclaration.descriptor
567             is KSClassDeclarationJavaImpl -> resolveJavaDeclaration(classDeclaration.psi)
568             else -> throw IllegalStateException("unexpected class: ${classDeclaration.javaClass}")
569         } as ClassDescriptor?
570     }
571 
572     fun resolveFunctionDeclaration(function: KSFunctionDeclaration): CallableDescriptor? {
573         return when (function) {
574             is KSFunctionDeclarationImpl -> resolveDeclaration(function.ktFunction)
575             is KSFunctionDeclarationDescriptorImpl -> function.descriptor
576             is KSFunctionDeclarationJavaImpl -> {
577                 val descriptor = resolveJavaDeclaration(function.psi)
578                 if (descriptor is JavaForKotlinOverridePropertyDescriptor) {
579                     if (function.simpleName.asString().startsWith("set")) {
580                         descriptor.setter
581                     } else {
582                         descriptor.getter
583                     }
584                 } else {
585                     descriptor
586                 }
587             }
588             is KSConstructorSyntheticImpl -> {
589                 // we might create synthetic constructor when it is not declared in code
590                 // it is either for kotlin, where we can use primary constructor, or for java
591                 // where we can use the only available constructor
592                 val resolved = resolveClassDeclaration(function.ksClassDeclaration)
593                 resolved?.unsubstitutedPrimaryConstructor ?: resolved?.constructors?.singleOrNull()
594             }
595             else -> throw IllegalStateException("unexpected class: ${function.javaClass}")
596         } as? CallableDescriptor
597     }
598 
599     fun resolvePropertyDeclaration(property: KSPropertyDeclaration): PropertyDescriptor? {
600         return when (property) {
601             is KSPropertyDeclarationImpl -> resolveDeclaration(property.ktProperty)
602             is KSPropertyDeclarationParameterImpl -> resolveDeclaration(property.ktParameter)
603             is KSPropertyDeclarationDescriptorImpl -> property.descriptor
604             is KSPropertyDeclarationJavaImpl -> resolveJavaDeclaration(property.psi)
605             else -> throw IllegalStateException("unexpected class: ${property.javaClass}")
606         } as PropertyDescriptor?
607     }
608 
609     fun resolvePropertyAccessorDeclaration(accessor: KSPropertyAccessor): PropertyAccessorDescriptor? {
610         return when (accessor) {
611             is KSPropertyAccessorDescriptorImpl -> accessor.descriptor
612             is KSPropertyAccessorImpl -> resolveDeclaration(accessor.ktPropertyAccessor)
613             is KSPropertySetterSyntheticImpl -> resolvePropertyDeclaration(accessor.receiver)?.setter
614             is KSPropertyGetterSyntheticImpl -> resolvePropertyDeclaration(accessor.receiver)?.getter
615             else -> throw IllegalStateException("unexpected class: ${accessor.javaClass}")
616         } as PropertyAccessorDescriptor?
617     }
618 
619     fun resolveJavaType(psi: PsiType, parentTypeReference: KSTypeReference? = null): KotlinType {
620         incrementalContext.recordLookup(psi)
621         val javaType = JavaTypeImpl.create(psi)
622 
623         var parent: KSNode? = parentTypeReference
624 
625         val stack = Stack<KSNode>()
626         while (parent != null) {
627             if (parent is KSFunctionDeclarationJavaImpl || parent is KSClassDeclarationJavaImpl) {
628                 stack.push(parent)
629             }
630             parent = parent.parent
631         }
632         // Construct resolver context for the PsiType
633         var resolverContext = lazyJavaResolverContext
634 
635         for (e in stack) {
636             when (e) {
637                 is KSFunctionDeclarationJavaImpl -> {
638                     // Non-physical methods have no interesting scope and may have no containing class
639                     if (!e.psi.isPhysical || e.psi.containingClass == null)
640                         continue
641                     resolverContext = resolverContext
642                         .childForMethod(
643                             resolveJavaDeclaration(e.psi)!!,
644                             if (e.psi.isConstructor) JavaConstructorImpl(e.psi) else JavaMethodImpl(e.psi)
645                         )
646                 }
647                 is KSClassDeclarationJavaImpl -> {
648                     resolverContext = resolverContext
649                         .childForClassOrPackage(resolveJavaDeclaration(e.psi) as ClassDescriptor, JavaClassImpl(e.psi))
650                 }
651             }
652         }
653         return if (javaType is JavaArrayTypeImpl)
654             resolverContext
655                 .typeResolver.transformArrayType(javaType, TypeUsage.COMMON.toAttributes(), psi is PsiEllipsisType)
656         else
657             resolverContext.typeResolver.transformJavaType(javaType, TypeUsage.COMMON.toAttributes())
658     }
659 
660     /*
661      * Don't map Java types in annotation parameters
662      *
663      * Users may specify Java types explicitly by instances of `Class<T>`.
664      * The situation is similar to `getClassDeclarationByName` where we have
665      * decided to keep those Java types not mapped.
666      *
667      * It would be troublesome if users try to use reflection on types that
668      * were mapped to Kotlin builtins, becuase some of those builtins don't
669      * even exist in classpath.
670      *
671      * Therefore, ResolverImpl.resolveJavaType cannot be used.
672      */
673     fun resolveJavaTypeInAnnotations(psiType: PsiType): KSType = if (options.mapAnnotationArgumentsInJava) {
674         getKSTypeCached(resolveJavaType(psiType))
675     } else {
676         when (psiType) {
677             is PsiPrimitiveType -> {
678                 getClassDeclarationByName(psiType.boxedTypeName!!)!!.asStarProjectedType()
679             }
680             is PsiArrayType -> {
681                 val componentType = resolveJavaTypeInAnnotations(psiType.componentType)
682                 val componentTypeRef = createKSTypeReferenceFromKSType(componentType)
683                 val typeArgs = listOf(getTypeArgument(componentTypeRef, Variance.INVARIANT))
684                 builtIns.arrayType.replace(typeArgs)
685             }
686             else -> {
687                 getClassDeclarationByName(psiType.canonicalText)?.asStarProjectedType() ?: KSErrorType
688             }
689         }
690     }
691 
692     fun KotlinType.expandNonRecursively(): KotlinType =
693         (constructor.declarationDescriptor as? TypeAliasDescriptor)?.expandedType?.withAbbreviation(this as SimpleType)
694             ?: this
695 
696     fun TypeProjection.expand(): TypeProjection {
697         val expandedType = type.expand()
698         return if (expandedType == type) this else substitute { expandedType }
699     }
700 
701     // TODO: Is this the most efficient way?
702     fun KotlinType.expand(): KotlinType =
703         replace(arguments.map { it.expand() }).expandNonRecursively()
704 
705     fun KtTypeReference.lookup(): KotlinType? =
706         bindingTrace.get(BindingContext.ABBREVIATED_TYPE, this)?.expand() ?: bindingTrace.get(BindingContext.TYPE, this)
707 
708     fun resolveUserType(type: KSTypeReference): KSType {
709         when (type) {
710             is KSTypeReferenceImpl -> {
711                 val typeReference = type.ktTypeReference
712                 typeReference.lookup()?.let {
713                     return getKSTypeCached(it, type.element.typeArguments, type.annotations)
714                 }
715                 KtStubbedPsiUtil.getContainingDeclaration(typeReference)?.let { containingDeclaration ->
716                     resolveDeclaration(containingDeclaration)?.let {
717                         // TODO: only resolve relevant branch.
718                         ForceResolveUtil.forceResolveAllContents(it)
719                     }
720                     // TODO: Fix resolution look up to avoid fallback to file scope.
721                     typeReference.lookup()?.let {
722                         return getKSTypeCached(it, type.element.typeArguments, type.annotations)
723                     }
724                 }
725                 val scope = resolveSession.fileScopeProvider.getFileResolutionScope(typeReference.containingKtFile)
726                 return resolveSession.typeResolver.resolveType(scope, typeReference, bindingTrace, false).let {
727                     getKSTypeCached(it, type.element.typeArguments, type.annotations)
728                 }
729             }
730             is KSTypeReferenceDescriptorImpl -> {
731                 return getKSTypeCached(type.kotlinType)
732             }
733             is KSTypeReferenceJavaImpl -> {
734                 val psi = (type.psi as? PsiClassReferenceType)?.resolve()
735                 if (psi is PsiTypeParameter) {
736                     (type.psi as PsiClassReferenceType).typeArguments().forEach {
737                         if (it is PsiType) {
738                             incrementalContext.recordLookup(it)
739                         }
740                     }
741                     val containingDeclaration = if (psi.owner is PsiClass) {
742                         moduleClassResolver.resolveClass(
743                             JavaClassImpl(psi.owner as PsiClass).apply { workaroundForNested(lazyJavaResolverContext) }
744                         )
745                     } else {
746                         val owner = psi.owner
747                         check(owner is PsiMethod) {
748                             "unexpected owner type: $owner / ${owner?.javaClass}"
749                         }
750                         moduleClassResolver.resolveContainingClass(owner)
751                             ?.findEnclosedDescriptor(
752                                 kindFilter = DescriptorKindFilter.FUNCTIONS,
753                                 filter = { it.findPsi() == owner }
754                             ) as FunctionDescriptor
755                     } as DeclarationDescriptor
756                     val typeParameterDescriptor = LazyJavaTypeParameterDescriptor(
757                         lazyJavaResolverContext,
758                         JavaTypeParameterImpl(psi),
759                         psi.index,
760                         containingDeclaration
761                     )
762                     javaTypeParameterMap[typeParameterDescriptor] = psi
763                 }
764                 return getKSTypeCached(resolveJavaType(type.psi, type), type.element.typeArguments, type.annotations)
765             }
766             else -> throw IllegalStateException("Unable to resolve type for $type, $ExceptionMessage")
767         }
768     }
769 
770     fun findDeclaration(kotlinType: KotlinType): KSDeclaration {
771         val descriptor = kotlinType.constructor.declarationDescriptor
772         val psi = descriptor?.findPsi()
773         return if (psi != null) {
774             when (psi) {
775                 is KtClassOrObject -> KSClassDeclarationImpl.getCached(psi)
776                 is PsiClass -> KSClassDeclarationJavaImpl.getCached(psi)
777                 is KtTypeAlias -> KSTypeAliasImpl.getCached(psi)
778                 is KtTypeParameter -> KSTypeParameterImpl.getCached(psi)
779                 is PsiEnumConstant -> KSClassDeclarationJavaEnumEntryImpl.getCached(psi)
780                 else -> throw IllegalStateException("Unexpected psi type: ${psi.javaClass}, $ExceptionMessage")
781             }
782         } else {
783             when (descriptor) {
784                 is ClassDescriptor -> KSClassDeclarationDescriptorImpl.getCached(descriptor)
785                 // LazyJavaTypeParameterDescriptor has `source` overridden to `NO_SOURCE`, therefore
786                 // need to look up psi within KSP.
787                 is TypeParameterDescriptor -> if (descriptor in javaTypeParameterMap) {
788                     KSTypeParameterJavaImpl.getCached(javaTypeParameterMap[descriptor]!!)
789                 } else {
790                     KSTypeParameterDescriptorImpl.getCached(descriptor)
791                 }
792                 is TypeAliasDescriptor -> KSTypeAliasDescriptorImpl.getCached(descriptor)
793                 null -> throw IllegalStateException("Failed to resolve descriptor for $kotlinType")
794                 else -> throw IllegalStateException(
795                     "Unexpected descriptor type: ${descriptor.javaClass}, $ExceptionMessage"
796                 )
797             }
798         }
799     }
800 
801     // Finds closest non-local scope.
802     fun KtElement.findLexicalScope(): LexicalScope {
803         return containingNonLocalDeclaration()?.let {
804             resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(it)
805         } ?: resolveSession.fileScopeProvider.getFileResolutionScope(this.containingKtFile)
806     }
807 
808     fun resolveAnnotationEntry(ktAnnotationEntry: KtAnnotationEntry): AnnotationDescriptor? {
809         bindingTrace.get(BindingContext.ANNOTATION, ktAnnotationEntry)?.let { return it }
810         KtStubbedPsiUtil.getContainingDeclaration(ktAnnotationEntry)?.let { containingDeclaration ->
811             if (KtPsiUtil.isLocal(containingDeclaration)) {
812                 resolveDeclarationForLocal(containingDeclaration)
813             } else {
814                 resolveSession.resolveToDescriptor(containingDeclaration).annotations.forEach {}
815             }
816         } ?: ktAnnotationEntry.containingKtFile.let {
817             resolveSession.getFileAnnotations(it).forEach {}
818         }
819         return bindingTrace.get(BindingContext.ANNOTATION, ktAnnotationEntry)
820     }
821 
822     fun resolveDeclarationForLocal(localDeclaration: KtDeclaration) {
823         var declaration = KtStubbedPsiUtil.getContainingDeclaration(localDeclaration) ?: return
824         while (KtPsiUtil.isLocal(declaration))
825             declaration = KtStubbedPsiUtil.getContainingDeclaration(declaration)!!
826 
827         val containingFD = resolveSession.resolveToDescriptor(declaration).also {
828             ForceResolveUtil.forceResolveAllContents(it)
829         }
830 
831         if (declaration is KtNamedFunction) {
832             val dataFlowInfo = DataFlowInfo.EMPTY
833             val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(declaration)
834             bodyResolver.resolveFunctionBody(
835                 dataFlowInfo,
836                 bindingTrace,
837                 declaration,
838                 containingFD as FunctionDescriptor,
839                 scope,
840                 null
841             )
842         }
843     }
844 
845     @KspExperimental
846     override fun getJvmName(accessor: KSPropertyAccessor): String? {
847         val descriptor = resolvePropertyAccessorDeclaration(accessor)
848 
849         return descriptor?.let {
850             // KotlinTypeMapper.mapSignature always uses OwnerKind.IMPLEMENTATION
851             typeMapper.mapFunctionName(descriptor, OwnerKind.IMPLEMENTATION)
852         }
853     }
854 
855     @KspExperimental
856     override fun getJvmName(declaration: KSFunctionDeclaration): String? {
857         // function names might be mangled if they receive inline class parameters or they are internal
858         val descriptor = resolveFunctionDeclaration(declaration)
859         return (descriptor as? FunctionDescriptor)?.let {
860             // KotlinTypeMapper.mapSignature always uses OwnerKind.IMPLEMENTATION
861             typeMapper.mapFunctionName(it, OwnerKind.IMPLEMENTATION)
862         }
863     }
864 
865     @KspExperimental
866     override fun getOwnerJvmClassName(declaration: KSPropertyDeclaration): String? {
867         val descriptor = resolvePropertyDeclaration(declaration) ?: return null
868         return getJvmOwnerQualifiedName(descriptor)
869     }
870 
871     @KspExperimental
872     override fun getOwnerJvmClassName(declaration: KSFunctionDeclaration): String? {
873         val descriptor = resolveFunctionDeclaration(declaration) ?: return null
874         return getJvmOwnerQualifiedName(descriptor)
875     }
876 
877     private fun getJvmOwnerQualifiedName(descriptor: DeclarationDescriptor): String? {
878         return try {
879             typeMapper.mapImplementationOwner(descriptor).className
880         } catch (unsupported: UnsupportedOperationException) {
881             null
882         }
883     }
884 
885     private fun extractThrowsFromClassFile(
886         virtualFileContent: ByteArray,
887         jvmDesc: String?,
888         simpleName: String?
889     ): Sequence<KSType> {
890         val exceptionNames = mutableListOf<String>()
891         ClassReader(virtualFileContent).accept(
892             object : ClassVisitor(API_VERSION) {
893                 override fun visitMethod(
894                     access: Int,
895                     name: String?,
896                     descriptor: String?,
897                     signature: String?,
898                     exceptions: Array<out String>?,
899                 ): MethodVisitor {
900                     if (name == simpleName && jvmDesc == descriptor) {
901                         exceptions?.toList()?.let { exceptionNames.addAll(it) }
902                     }
903                     return object : MethodVisitor(API_VERSION) {
904                     }
905                 }
906             },
907             ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES
908         )
909         return exceptionNames.mapNotNull {
910             this@ResolverImpl.getClassDeclarationByName(it.replace("/", "."))?.asStarProjectedType()
911         }.asSequence()
912     }
913 
914     @SuppressWarnings("UNCHECKED_CAST")
915     private fun extractThrowsAnnotation(annotated: KSAnnotated): Sequence<KSType> {
916         return annotated.annotations
917             .singleOrNull {
918                 it.shortName.asString() == "Throws" &&
919                     it.annotationType.resolve().declaration.qualifiedName?.asString() == "kotlin.Throws"
920             }?.arguments
921             ?.singleOrNull()
922             ?.let { it.value as? ArrayList<KSType> }
923             ?.asSequence() ?: emptySequence()
924     }
925 
926     // TODO: refactor and reuse BinaryClassInfoCache
927     @KspExperimental
928     override fun getJvmCheckedException(function: KSFunctionDeclaration): Sequence<KSType> {
929         return when (function.origin) {
930             Origin.JAVA -> {
931                 val psi = (function as KSFunctionDeclarationJavaImpl).psi
932                 psi.throwsList.referencedTypes.asSequence().map { getKSTypeCached(resolveJavaType(it)) }
933             }
934             Origin.KOTLIN -> {
935                 extractThrowsAnnotation(function)
936             }
937             Origin.KOTLIN_LIB, Origin.JAVA_LIB -> {
938                 val descriptor = (function as KSFunctionDeclarationDescriptorImpl).descriptor
939                 val jvmDesc = this.mapToJvmSignature(function)
940                 val virtualFileContent = if (function.origin == Origin.KOTLIN_LIB) {
941                     (descriptor.getContainingKotlinJvmBinaryClass() as? VirtualFileKotlinClass)?.file
942                         ?.contentsToByteArray()
943                 } else {
944                     (
945                         ((descriptor.source as? JavaSourceElement)?.javaElement as? BinaryJavaMethodBase)
946                             ?.containingClass as? BinaryJavaClass
947                         )?.virtualFile?.contentsToByteArray()
948                 }
949                 if (virtualFileContent == null) {
950                     return emptySequence()
951                 }
952                 extractThrowsFromClassFile(virtualFileContent, jvmDesc, function.simpleName.asString())
953             }
954             else -> emptySequence()
955         }
956     }
957 
958     @KspExperimental
959     override fun getJvmCheckedException(accessor: KSPropertyAccessor): Sequence<KSType> {
960         return when (accessor.origin) {
961             Origin.KOTLIN, Origin.SYNTHETIC -> {
962                 extractThrowsAnnotation(accessor)
963             }
964             Origin.KOTLIN_LIB -> {
965                 val descriptor = (accessor as KSPropertyAccessorDescriptorImpl).descriptor
966                 val jvmDesc = typeMapper.mapAsmMethod(descriptor).descriptor
967                 val virtualFileContent = if (accessor.origin == Origin.KOTLIN_LIB) {
968                     (descriptor.correspondingProperty.getContainingKotlinJvmBinaryClass() as? VirtualFileKotlinClass)
969                         ?.file?.contentsToByteArray()
970                 } else {
971                     (
972                         ((descriptor.source as? JavaSourceElement)?.javaElement as? BinaryJavaMethod)?.containingClass
973                             as? BinaryJavaClass
974                         )?.virtualFile?.contentsToByteArray()
975                 }
976                 if (virtualFileContent == null) {
977                     return emptySequence()
978                 }
979                 extractThrowsFromClassFile(virtualFileContent, jvmDesc, getJvmName(accessor))
980             }
981             else -> emptySequence()
982         }
983     }
984 
985     private val javaPackageToClassMap: Map<String, List<KSDeclaration>> by lazy {
986         val packageToClassMapping = mutableMapOf<String, List<KSDeclaration>>()
987         allKSFiles
988             .filter { file ->
989                 file.origin == Origin.JAVA &&
990                     options.javaSourceRoots.any { root ->
991                         file.filePath.startsWith(root.absolutePath) &&
992                             file.filePath.substringAfter(root.absolutePath)
993                             .dropLastWhile { c -> c != File.separatorChar }.dropLast(1).drop(1)
994                             .replace(File.separatorChar, '.') == file.packageName.asString()
995                     }
996             }
997             .forEach {
998                 packageToClassMapping.put(
999                     it.packageName.asString(),
1000                     packageToClassMapping.getOrDefault(it.packageName.asString(), emptyList())
1001                         .plus(
1002                             it.declarations.filterNot {
1003                                 it.containingFile?.fileName?.split(".")?.first() == it.simpleName.asString()
1004                             }
1005                         )
1006                 )
1007             }
1008         packageToClassMapping
1009     }
1010 
1011     @KspExperimental
1012     override fun getDeclarationsFromPackage(packageName: String): Sequence<KSDeclaration> {
1013         val noPackageFilter = DescriptorKindFilter.ALL.withoutKinds(DescriptorKindFilter.PACKAGES_MASK)
1014         return module.getPackage(FqName(packageName))
1015             .memberScope.getContributedDescriptors(noPackageFilter)
1016             .asSequence()
1017             .mapNotNull { (it as? MemberDescriptor)?.toKSDeclaration() }
1018             .plus(javaPackageToClassMap.getOrDefault(packageName, emptyList()).asSequence())
1019     }
1020 
1021     override fun getTypeArgument(typeRef: KSTypeReference, variance: Variance): KSTypeArgument {
1022         return KSTypeArgumentLiteImpl.getCached(typeRef, variance)
1023     }
1024 
1025     internal fun asMemberOf(
1026         property: KSPropertyDeclaration,
1027         containing: KSType,
1028     ): KSType {
1029         val key = property to containing
1030         return propertyAsMemberOfCache.getOrPut(key) {
1031             computeAsMemberOf(property, containing)
1032         }
1033     }
1034 
1035     private fun computeAsMemberOf(
1036         property: KSPropertyDeclaration,
1037         containing: KSType,
1038     ): KSType {
1039         val propertyDeclaredIn = property.closestClassDeclaration()
1040             ?: throw IllegalArgumentException(
1041                 "Cannot call asMemberOf with a property that is " +
1042                     "not declared in a class or an interface"
1043             )
1044         val declaration = resolvePropertyDeclaration(property)
1045         if (declaration != null && containing is KSTypeImpl && !containing.isError) {
1046             incrementalContext.recordLookupWithSupertypes(containing.kotlinType)
1047             incrementalContext.recordLookupForDeclaration(property)
1048             if (!containing.kotlinType.isSubtypeOf(propertyDeclaredIn)) {
1049                 throw IllegalArgumentException(
1050                     "$containing is not a sub type of the class/interface that contains `$property` " +
1051                         "($propertyDeclaredIn)"
1052                 )
1053             }
1054             val typeSubstitutor = containing.kotlinType.createTypeSubstitutor()
1055             val substituted = declaration.substitute(typeSubstitutor) as? ValueDescriptor
1056             substituted?.let {
1057                 return getKSTypeCached(substituted.type)
1058             }
1059         }
1060         // if substitution fails, fallback to the type from the property
1061         return KSErrorType
1062     }
1063 
1064     internal fun asMemberOf(
1065         function: KSFunctionDeclaration,
1066         containing: KSType,
1067     ): KSFunction {
1068         val key = function to containing
1069         return functionAsMemberOfCache.getOrPut(key) {
1070             computeAsMemberOf(function, containing)
1071         }
1072     }
1073 
1074     private fun computeAsMemberOf(
1075         function: KSFunctionDeclaration,
1076         containing: KSType,
1077     ): KSFunction {
1078         val functionDeclaredIn = function.closestClassDeclaration()
1079             ?: throw IllegalArgumentException(
1080                 "Cannot call asMemberOf with a function that is " +
1081                     "not declared in a class or an interface"
1082             )
1083         val declaration = resolveFunctionDeclaration(function)
1084         if (declaration != null && containing is KSTypeImpl && !containing.isError) {
1085             incrementalContext.recordLookupWithSupertypes(containing.kotlinType)
1086             incrementalContext.recordLookupForDeclaration(function)
1087             if (!containing.kotlinType.isSubtypeOf(functionDeclaredIn)) {
1088                 throw IllegalArgumentException(
1089                     "$containing is not a sub type of the class/interface that contains " +
1090                         "`$function` ($functionDeclaredIn)"
1091                 )
1092             }
1093             val typeSubstitutor = containing.kotlinType.createTypeSubstitutor()
1094             if (declaration is PropertyAccessorDescriptor) {
1095                 val substitutedProperty = (declaration.correspondingProperty).substitute(typeSubstitutor)
1096                 // TODO: Fix in upstream for property accessors: https://github.com/JetBrains/kotlin/blob/master/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyAccessorDescriptorImpl.java#L122
1097                 return KSFunctionImpl(
1098                     (substitutedProperty as PropertyDescriptor).accessors.single {
1099                         it.name == declaration.name
1100                     }
1101                 )
1102             }
1103             val substituted = declaration.substitute(typeSubstitutor)
1104             return KSFunctionImpl(substituted)
1105         }
1106         // if substitution fails, return an error function that resembles the original declaration
1107         return KSFunctionErrorImpl(function)
1108     }
1109 
1110     private fun KotlinType.isSubtypeOf(declaration: KSClassDeclaration): Boolean {
1111         val classDeclaration = resolveClassDeclaration(declaration)
1112         if (classDeclaration == null) {
1113             throw IllegalArgumentException(
1114                 "Cannot find the declaration for class $classDeclaration"
1115             )
1116         }
1117         return constructor
1118             .declarationDescriptor
1119             ?.getAllSuperClassifiers()
1120             ?.any { it == classDeclaration } == true
1121     }
1122 
1123     override val builtIns: KSBuiltIns by lazy {
1124         val builtIns = module.builtIns
1125         object : KSBuiltIns {
1126             override val anyType: KSType by lazy { getKSTypeCached(builtIns.anyType) }
1127             override val nothingType by lazy { getKSTypeCached(builtIns.nothingType) }
1128             override val unitType: KSType by lazy { getKSTypeCached(builtIns.unitType) }
1129             override val numberType: KSType by lazy { getKSTypeCached(builtIns.numberType) }
1130             override val byteType: KSType by lazy { getKSTypeCached(builtIns.byteType) }
1131             override val shortType: KSType by lazy { getKSTypeCached(builtIns.shortType) }
1132             override val intType: KSType by lazy { getKSTypeCached(builtIns.intType) }
1133             override val longType: KSType by lazy { getKSTypeCached(builtIns.longType) }
1134             override val floatType: KSType by lazy { getKSTypeCached(builtIns.floatType) }
1135             override val doubleType: KSType by lazy { getKSTypeCached(builtIns.doubleType) }
1136             override val charType: KSType by lazy { getKSTypeCached(builtIns.charType) }
1137             override val booleanType: KSType by lazy { getKSTypeCached(builtIns.booleanType) }
1138             override val stringType: KSType by lazy { getKSTypeCached(builtIns.stringType) }
1139             override val iterableType: KSType by lazy {
1140                 getKSTypeCached(builtIns.iterableType.replaceArgumentsWithStarProjections())
1141             }
1142             override val annotationType: KSType by lazy { getKSTypeCached(builtIns.annotationType) }
1143             override val arrayType: KSType by lazy {
1144                 getKSTypeCached(builtIns.array.defaultType.replaceArgumentsWithStarProjections())
1145             }
1146         }
1147     }
1148 
1149     internal val mockSerializableType = module.builtIns.numberType.supertypes().singleOrNull {
1150         it.constructor.declarationDescriptor?.name?.asString() == "Serializable"
1151     }
1152 
1153     internal val javaSerializableType = module.resolveClassByFqName(
1154         FqName("java.io.Serializable"), NoLookupLocation.WHEN_FIND_BY_FQNAME
1155     )?.defaultType
1156 
1157     @KspExperimental
1158     override fun mapJavaNameToKotlin(javaName: KSName): KSName? =
1159         JavaToKotlinClassMap.mapJavaToKotlin(FqName(javaName.asString()))?.toKSName()
1160 
1161     @KspExperimental
1162     override fun mapKotlinNameToJava(kotlinName: KSName): KSName? =
1163         JavaToKotlinClassMap.mapKotlinToJava(FqNameUnsafe(kotlinName.asString()))?.toKSName()
1164 
1165     @KspExperimental
1166     internal fun mapToJvmSignature(accessor: KSPropertyAccessor): String {
1167         return resolvePropertyAccessorDeclaration(accessor)?.let {
1168             typeMapper.mapAsmMethod(it).descriptor
1169         } ?: ""
1170     }
1171 
1172     @KspExperimental
1173     override fun getDeclarationsInSourceOrder(container: KSDeclarationContainer): Sequence<KSDeclaration> {
1174         return container.declarationsInSourceOrder
1175     }
1176 
1177     @KspExperimental
1178     override fun effectiveJavaModifiers(declaration: KSDeclaration): Set<Modifier> {
1179         val modifiers = HashSet<Modifier>(declaration.modifiers.filter { it in javaModifiers })
1180 
1181         // This is only needed by sources.
1182         // PUBLIC, PRIVATE, PROTECTED are already handled in descriptor based impls.
1183         fun addVisibilityModifiers() {
1184             when {
1185                 declaration.isPublic() -> modifiers.add(Modifier.PUBLIC)
1186                 declaration.isPrivate() -> modifiers.add(Modifier.PRIVATE)
1187                 declaration.isProtected() -> modifiers.add(Modifier.PROTECTED)
1188             }
1189         }
1190 
1191         when (declaration.origin) {
1192             Origin.JAVA -> {
1193                 addVisibilityModifiers()
1194                 if (declaration is KSClassDeclaration && declaration.classKind == ClassKind.INTERFACE)
1195                     modifiers.add(Modifier.ABSTRACT)
1196             }
1197             Origin.KOTLIN -> {
1198                 addVisibilityModifiers()
1199                 if (!declaration.isOpen())
1200                     modifiers.add(Modifier.FINAL)
1201                 if (declaration.hasAnnotation(JVM_STATIC_ANNOTATION_FQN))
1202                     modifiers.add(Modifier.JAVA_STATIC)
1203                 if (declaration.hasAnnotation(JVM_DEFAULT_ANNOTATION_FQN))
1204                     modifiers.add(Modifier.JAVA_DEFAULT)
1205                 if (declaration.hasAnnotation(JVM_DEFAULT_WITHOUT_COMPATIBILITY_ANNOTATION_FQN))
1206                     modifiers.add(Modifier.JAVA_DEFAULT)
1207                 if (declaration.hasAnnotation(JVM_STRICTFP_ANNOTATION_FQN))
1208                     modifiers.add(Modifier.JAVA_STRICT)
1209                 if (declaration.hasAnnotation(JVM_SYNCHRONIZED_ANNOTATION_FQN))
1210                     modifiers.add(Modifier.JAVA_SYNCHRONIZED)
1211                 if (declaration.hasAnnotation(JVM_TRANSIENT_ANNOTATION_FQN))
1212                     modifiers.add(Modifier.JAVA_TRANSIENT)
1213                 if (declaration.hasAnnotation(JVM_VOLATILE_ANNOTATION_FQN))
1214                     modifiers.add(Modifier.JAVA_VOLATILE)
1215                 when (declaration) {
1216                     is KSClassDeclaration -> {
1217                         if (declaration.isCompanionObject)
1218                             modifiers.add(Modifier.JAVA_STATIC)
1219                         if (declaration.classKind == ClassKind.INTERFACE)
1220                             modifiers.add(Modifier.ABSTRACT)
1221                     }
1222                     is KSPropertyDeclaration -> {
1223                         if (declaration.isAbstract())
1224                             modifiers.add(Modifier.ABSTRACT)
1225                     }
1226                     is KSFunctionDeclaration -> {
1227                         if (declaration.isAbstract)
1228                             modifiers.add(Modifier.ABSTRACT)
1229                     }
1230                 }
1231             }
1232             Origin.KOTLIN_LIB, Origin.JAVA_LIB -> {
1233                 when (declaration) {
1234                     is KSPropertyDeclaration -> {
1235                         if (declaration.jvmAccessFlag and Opcodes.ACC_TRANSIENT != 0)
1236                             modifiers.add(Modifier.JAVA_TRANSIENT)
1237                         if (declaration.jvmAccessFlag and Opcodes.ACC_VOLATILE != 0)
1238                             modifiers.add(Modifier.JAVA_VOLATILE)
1239                     }
1240                     is KSFunctionDeclaration -> {
1241                         if (declaration.jvmAccessFlag and Opcodes.ACC_STRICT != 0)
1242                             modifiers.add(Modifier.JAVA_STRICT)
1243                         if (declaration.jvmAccessFlag and Opcodes.ACC_SYNCHRONIZED != 0)
1244                             modifiers.add(Modifier.JAVA_SYNCHRONIZED)
1245                     }
1246                 }
1247             }
1248             else -> Unit
1249         }
1250         return modifiers
1251     }
1252 
1253     private enum class RefPosition {
1254         PARAMETER_TYPE,
1255         RETURN_TYPE,
1256         SUPER_TYPE
1257     }
1258 
1259     // Search in self and parents for the first type reference that is not part of a type argument.
1260     private fun KSTypeReference.findOuterMostRef(): Pair<KSTypeReference, List<Int>> {
1261         fun KSNode.findParentRef(): KSTypeReference? {
1262             var parent = parent
1263             while (parent != null && parent !is KSTypeReference)
1264                 parent = parent.parent
1265             return parent as? KSTypeReference
1266         }
1267 
1268         val fallback = Pair<KSTypeReference, List<Int>>(this, emptyList())
1269         val indexes = mutableListOf<Int>()
1270         var candidate: KSTypeReference = this
1271         // KSTypeArgument's parent can be either KSReferenceElement or KSType.
1272         while (candidate.parent is KSTypeArgument) {
1273             // If the parent is a KSType, it's a synthetic reference.
1274             // Do nothing and reply on the fallback behavior.
1275             val referenceElement = (candidate.parent!!.parent as? KSReferenceElement) ?: return fallback
1276             indexes.add(referenceElement.typeArguments.indexOf(candidate.parent))
1277             // In case the program isn't properly structured, fallback.
1278             candidate = referenceElement.findParentRef() ?: return fallback
1279         }
1280         return Pair(candidate, indexes)
1281     }
1282 
1283     // TODO: Strict mode for catching unhandled cases.
1284     private fun findRefPosition(ref: KSTypeReference): RefPosition = when (val parent = ref.parent) {
1285         is KSCallableReference -> when (ref) {
1286             parent.returnType -> RefPosition.RETURN_TYPE
1287             else -> RefPosition.PARAMETER_TYPE
1288         }
1289         is KSFunctionDeclaration -> when (ref) {
1290             parent.returnType -> RefPosition.RETURN_TYPE
1291             else -> RefPosition.PARAMETER_TYPE
1292         }
1293         is KSPropertyGetter -> RefPosition.RETURN_TYPE
1294         is KSPropertyDeclaration -> when (ref) {
1295             parent.type -> RefPosition.RETURN_TYPE
1296             else -> RefPosition.PARAMETER_TYPE
1297         }
1298         is KSClassDeclaration -> RefPosition.SUPER_TYPE
1299         // is KSTypeArgument -> RefPosition.PARAMETER_TYPE
1300         // is KSAnnotation -> RefPosition.PARAMETER_TYPE
1301         // is KSTypeAlias -> RefPosition.PARAMETER_TYPE
1302         // is KSValueParameter -> RefPosition.PARAMETER_TYPE
1303         // is KSTypeParameter -> RefPosition.PARAMETER_TYPE
1304         else -> RefPosition.PARAMETER_TYPE
1305     }
1306 
1307     private fun KSTypeReference.isReturnTypeOfAnnotationMethod(): Boolean {
1308         var candidate = this.parent
1309         while (candidate !is KSClassDeclaration && candidate != null)
1310             candidate = candidate.parent
1311         return (candidate as? KSClassDeclaration)?.classKind == ClassKind.ANNOTATION_CLASS
1312     }
1313 
1314     // Convert type arguments for Java wildcard, recursively.
1315     private fun KotlinType.toWildcard(mode: TypeMappingMode): KotlinType? {
1316         val parameters = constructor.parameters
1317         val arguments = arguments
1318 
1319         val wildcardArguments = parameters.zip(arguments).map { (parameter, argument) ->
1320             if (!argument.isStarProjection &&
1321                 parameter.variance != argument.projectionKind &&
1322                 parameter.variance != org.jetbrains.kotlin.types.Variance.INVARIANT &&
1323                 argument.projectionKind != org.jetbrains.kotlin.types.Variance.INVARIANT
1324             ) {
1325                 // conflicting variances
1326                 // TODO: error message
1327                 return null
1328             }
1329 
1330             val argMode = mode.updateFromAnnotations(argument.type)
1331             val variance = KotlinTypeMapper.getVarianceForWildcard(parameter, argument, argMode)
1332             val genericMode = argMode.toGenericArgumentMode(
1333                 getEffectiveVariance(parameter.variance, argument.projectionKind)
1334             )
1335             TypeProjectionImpl(variance, argument.type.toWildcard(genericMode) ?: return null)
1336         }
1337 
1338         return replace(wildcardArguments)
1339     }
1340 
1341     private val JVM_SUPPRESS_WILDCARDS_NAME = KSNameImpl.getCached("kotlin.jvm.JvmSuppressWildcards")
1342     private val JVM_SUPPRESS_WILDCARDS_SHORT = "JvmSuppressWildcards"
1343     private fun KSTypeReference.findJvmSuppressWildcards(): Boolean? {
1344         var candidate: KSNode? = this
1345 
1346         while (candidate != null) {
1347             if ((candidate is KSTypeReference || candidate is KSDeclaration)) {
1348                 (
1349                     (candidate as KSAnnotated).annotations.firstOrNull {
1350                         checkAnnotation(it, JVM_SUPPRESS_WILDCARDS_NAME, JVM_SUPPRESS_WILDCARDS_SHORT)
1351                     }?.arguments?.firstOrNull()?.value as? Boolean
1352                     )?.let {
1353                     // KSAnnotated.getAnnotationsByType is handy but it uses reflection.
1354                     return it
1355                 }
1356             }
1357             candidate = candidate.parent
1358         }
1359 
1360         return null
1361     }
1362 
1363     private fun TypeMappingMode.updateFromAnnotations(
1364         type: KotlinType
1365     ): TypeMappingMode {
1366         (
1367             type.annotations.findAnnotation(JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME)
1368                 ?.argumentValue("suppress")?.value as? Boolean
1369             )?.let {
1370             return this.suppressJvmWildcards(it)
1371         }
1372 
1373         if (type.annotations.hasAnnotation(JVM_WILDCARD_ANNOTATION_FQ_NAME)) {
1374             return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
1375                 skipDeclarationSiteWildcards = false,
1376                 isForAnnotationParameter = isForAnnotationParameter,
1377                 fallbackMode = this,
1378                 needInlineClassWrapping = needInlineClassWrapping,
1379                 mapTypeAliases = mapTypeAliases
1380             )
1381         }
1382 
1383         return this
1384     }
1385 
1386     private fun TypeMappingMode.suppressJvmWildcards(
1387         suppress: Boolean
1388     ): TypeMappingMode {
1389         return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
1390             skipDeclarationSiteWildcards = suppress,
1391             isForAnnotationParameter = isForAnnotationParameter,
1392             needInlineClassWrapping = needInlineClassWrapping,
1393             mapTypeAliases = mapTypeAliases
1394         )
1395     }
1396 
1397     private fun TypeMappingMode.updateFromParents(
1398         ref: KSTypeReference
1399     ): TypeMappingMode {
1400         ref.findJvmSuppressWildcards()?.let {
1401             return this.suppressJvmWildcards(it)
1402         }
1403 
1404         return this
1405     }
1406 
1407     // Type arguments need to be resolved recursively in a top-down manner. So we find and resolve the outer most
1408     // reference that contains this argument. Then locate and return the argument.
1409     @KspExperimental
1410     override fun getJavaWildcard(reference: KSTypeReference): KSTypeReference {
1411         // If the outer-most reference cannot be found, e.g., when this reference is nested in KSType.arguments,
1412         // fallback to PARAMETER_TYPE effectively.
1413         val (ref, indexes) = reference.findOuterMostRef()
1414 
1415         val type = ref.resolve()
1416         if (type.isError)
1417             return reference
1418 
1419         val position = findRefPosition(ref)
1420         val kotlinType = (type as KSTypeImpl).kotlinType
1421 
1422         val typeSystem = SimpleClassicTypeSystemContext
1423         val typeMappingMode = when (position) {
1424             RefPosition.PARAMETER_TYPE -> typeSystem.getOptimalModeForValueParameter(kotlinType)
1425             RefPosition.RETURN_TYPE ->
1426                 typeSystem.getOptimalModeForReturnType(kotlinType, ref.isReturnTypeOfAnnotationMethod())
1427             RefPosition.SUPER_TYPE -> TypeMappingMode.SUPER_TYPE
1428         }.updateFromParents(ref)
1429 
1430         val parameters = kotlinType.constructor.parameters
1431         val arguments = kotlinType.arguments
1432 
1433         parameters.zip(arguments).forEach { (parameter, argument) ->
1434             if (position == RefPosition.SUPER_TYPE &&
1435                 argument.projectionKind != org.jetbrains.kotlin.types.Variance.INVARIANT
1436             ) {
1437                 // Type projection isn't allowed in immediate arguments to supertypes.
1438                 // TODO: error message
1439                 return KSTypeReferenceSyntheticImpl.getCached(KSErrorType, null)
1440             }
1441         }
1442 
1443         val wildcardType = kotlinType.toWildcard(typeMappingMode)?.let {
1444             var candidate: KotlinType = it
1445             for (i in indexes.reversed()) {
1446                 candidate = candidate.arguments[i].type
1447             }
1448             getKSTypeCached(candidate)
1449         } ?: KSErrorType
1450 
1451         return KSTypeReferenceSyntheticImpl.getCached(wildcardType, null)
1452     }
1453 
1454     @KspExperimental
1455     override fun isJavaRawType(type: KSType): Boolean {
1456         return type is KSTypeImpl && type.kotlinType.unwrap() is RawType
1457     }
1458 
1459     private val psiJavaFiles = allKSFiles.filterIsInstance<KSFileJavaImpl>().map {
1460         Pair(it.psi.virtualFile.path, it.psi)
1461     }.toMap()
1462 
1463     internal fun findPsiJavaFile(path: String): PsiFile? = psiJavaFiles.get(path)
1464 }
1465 
1466 // TODO: cross module resolution
findExpectsInKSDeclarationnull1467 fun DeclarationDescriptor.findExpectsInKSDeclaration(): Sequence<KSDeclaration> =
1468     findExpects().asSequence().map {
1469         it.toKSDeclaration()
1470     }
1471 
1472 // TODO: cross module resolution
findActualsInKSDeclarationnull1473 fun DeclarationDescriptor.findActualsInKSDeclaration(): Sequence<KSDeclaration> =
1474     findActuals(this.module).asSequence().map {
1475         it.toKSDeclaration()
1476     }
1477 
toKSDeclarationnull1478 fun MemberDescriptor.toKSDeclaration(): KSDeclaration =
1479     when (val psi = findPsi()) {
1480         is KtClassOrObject -> KSClassDeclarationImpl.getCached(psi)
1481         is KtFunction -> KSFunctionDeclarationImpl.getCached(psi)
1482         is KtProperty -> KSPropertyDeclarationImpl.getCached((psi))
1483         is KtTypeAlias -> KSTypeAliasImpl.getCached(psi)
1484         is PsiClass -> KSClassDeclarationJavaImpl.getCached(psi)
1485         is PsiMethod -> KSFunctionDeclarationJavaImpl.getCached(psi)
1486         is PsiField -> KSPropertyDeclarationJavaImpl.getCached(psi)
1487         else -> when (this) {
1488             is ClassDescriptor -> KSClassDeclarationDescriptorImpl.getCached(this)
1489             is FunctionDescriptor -> KSFunctionDeclarationDescriptorImpl.getCached(this)
1490             is PropertyDescriptor -> KSPropertyDeclarationDescriptorImpl.getCached(this)
1491             else -> throw IllegalStateException("Unknown expect/actual implementation")
1492         }
1493     }
1494 
1495 /**
1496  * [NewTypeSubstitutor] handles variance better than [TypeSubstitutor] so we use it when subtituting
1497  * types in [ResolverImpl.asMemberOf] implementations.
1498  */
TypeSubstitutornull1499 private fun TypeSubstitutor.toNewSubstitutor() = composeWith(
1500     org.jetbrains.kotlin.resolve.calls.inference.components.EmptySubstitutor
1501 )
1502 
1503 private fun KotlinType.createTypeSubstitutor(): NewTypeSubstitutor {
1504     return SubstitutionUtils.buildDeepSubstitutor(this).toNewSubstitutor()
1505 }
1506 
1507 /**
1508  * Extracts the identifier from a module Name.
1509  *
1510  * One caveat here is that kotlin passes a special name into the plugin which cannot be used as an identifier.
1511  * On the other hand, to construct the correct TypeMapper, we need a non-special name.
1512  * This function extracts the non-special name from a given name if it is special.
1513  *
1514  * @see: https://github.com/JetBrains/kotlin/blob/master/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt#L305
1515  */
getNonSpecialIdentifiernull1516 private fun Name.getNonSpecialIdentifier(): String {
1517     // the analyzer might pass down a special name which will break type mapper name computations.
1518     // If it is a special name, we turn it back to an id
1519     if (!isSpecial || asString().isBlank()) {
1520         return asString()
1521     }
1522     // special names starts with a `<` and usually end with `>`
1523     return if (asString().last() == '>') {
1524         asString().substring(1, asString().length - 1)
1525     } else {
1526         asString().substring(1)
1527     }
1528 }
1529 
findEnclosedDescriptornull1530 private inline fun MemberScope.findEnclosedDescriptor(
1531     kindFilter: DescriptorKindFilter,
1532     crossinline filter: (DeclarationDescriptor) -> Boolean,
1533 ): DeclarationDescriptor? {
1534     return getContributedDescriptors(
1535         kindFilter = kindFilter
1536     ).firstOrNull(filter)
1537 }
1538 
findEnclosedDescriptornull1539 private inline fun ClassDescriptor.findEnclosedDescriptor(
1540     kindFilter: DescriptorKindFilter,
1541     crossinline filter: (DeclarationDescriptor) -> Boolean,
1542 ): DeclarationDescriptor? {
1543     return this.unsubstitutedMemberScope.findEnclosedDescriptor(
1544         kindFilter = kindFilter,
1545         filter = filter
1546     ) ?: this.staticScope.findEnclosedDescriptor(
1547         kindFilter = kindFilter,
1548         filter = filter
1549     ) ?: constructors.firstOrNull {
1550         kindFilter.accepts(it) && filter(it)
1551     }
1552 }
1553 
findAnnotationFromUseSiteTargetnull1554 internal fun KSAnnotated.findAnnotationFromUseSiteTarget(): Sequence<KSAnnotation> {
1555     return when (this) {
1556         is KSPropertyGetter -> (this.receiver as? KSDeclarationImpl)?.let {
1557             it.originalAnnotations.asSequence().filter { it.useSiteTarget == AnnotationUseSiteTarget.GET }
1558         }
1559         is KSPropertySetter -> (this.receiver as? KSDeclarationImpl)?.let {
1560             it.originalAnnotations.asSequence().filter { it.useSiteTarget == AnnotationUseSiteTarget.SET }
1561         }
1562         is KSValueParameter -> {
1563             var parent = when (this) {
1564                 is KSValueParameterSyntheticImpl -> this.owner
1565                 is KSValueParameterImpl -> this.ktParameter.findParentAnnotated()
1566                 else -> null
1567             }
1568             // TODO: eliminate annotationsFromParents to make this fully sequence.
1569             val annotationsFromParents = mutableListOf<KSAnnotation>()
1570             (parent as? KSPropertyAccessorImpl)?.let {
1571                 annotationsFromParents.addAll(
1572                     it.originalAnnotations.asSequence()
1573                         .filter { it.useSiteTarget == AnnotationUseSiteTarget.SETPARAM }
1574                 )
1575                 parent = (parent as KSPropertyAccessorImpl).receiver
1576             }
1577             (parent as? KSPropertyDeclarationImpl)?.let {
1578                 annotationsFromParents.addAll(
1579                     it.originalAnnotations.asSequence()
1580                         .filter { it.useSiteTarget == AnnotationUseSiteTarget.SETPARAM }
1581                 )
1582             }
1583             annotationsFromParents.asSequence()
1584         }
1585         else -> emptySequence()
1586     } ?: emptySequence()
1587 }
1588 
1589 // Resolve to underlying type.
1590 // Only slightly slower than resolving a plain type, because everything is resolved and cached in the first resolve().
1591 // FIXME: add a resolution mode in resolveUserType() to resolve to underlying type directly.
resolveToUnderlyingnull1592 internal fun KSTypeReference.resolveToUnderlying(): KSType {
1593     var candidate = resolve()
1594     var declaration = candidate.declaration
1595     while (declaration is KSTypeAlias) {
1596         candidate = declaration.type.resolve()
1597         declaration = candidate.declaration
1598     }
1599     return candidate
1600 }
1601 
1602 // TODO: Remove this after upgrading to Kotlin 1.8.20.
1603 // Temporary work around for https://github.com/google/ksp/issues/1034
1604 // Force resolve outer most class for Java nested classes.
workaroundForNestednull1605 internal fun JavaClass.workaroundForNested(
1606     lazyJavaResolverContext: LazyJavaResolverContext = ResolverImpl.instance!!.lazyJavaResolverContext
1607 ) {
1608     var outerMost = outerClass
1609     while (outerMost?.outerClass != null) {
1610         outerMost = outerMost.outerClass
1611     }
1612     outerMost?.classId?.let { lazyJavaResolverContext.components.finder.findClass(it) }
1613 }
1614