[AA] introduce FirReceiverParameter

^KT-54417
This commit is contained in:
Dmitrii Gridin
2022-10-18 08:56:10 +02:00
committed by Space Team
parent be7d282974
commit 37d688ae83
21 changed files with 139 additions and 24 deletions
@@ -0,0 +1,66 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.api.fir.annotations
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.toKtAnnotationApplication
import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClassId
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.resolvedAnnotationClassIds
import org.jetbrains.kotlin.fir.symbols.resolvedAnnotationsWithArguments
import org.jetbrains.kotlin.name.ClassId
internal class KtFirAnnotationListForReceiverParameter private constructor(
private val firCallableSymbol: FirCallableSymbol<*>,
private val receiverParameter: FirAnnotationContainer,
private val useSiteSession: FirSession,
override val token: KtLifetimeToken,
) : KtAnnotationsList() {
override val annotations: List<KtAnnotationApplication>
get() = withValidityAssertion {
receiverParameter.resolvedAnnotationsWithArguments(firCallableSymbol).map { annotation ->
annotation.toKtAnnotationApplication(useSiteSession)
}
}
override fun hasAnnotation(classId: ClassId): Boolean = withValidityAssertion {
classId in receiverParameter.resolvedAnnotationClassIds(firCallableSymbol)
}
override fun annotationsByClassId(classId: ClassId): List<KtAnnotationApplication> = withValidityAssertion {
receiverParameter.resolvedAnnotationsWithArguments(firCallableSymbol).mapNotNull { annotation ->
if (annotation.fullyExpandedClassId(useSiteSession) != classId) return@mapNotNull null
annotation.toKtAnnotationApplication(useSiteSession)
}
}
override val annotationClassIds: Collection<ClassId>
get() = withValidityAssertion {
receiverParameter.resolvedAnnotationClassIds(firCallableSymbol)
}
companion object {
fun create(
firCallableSymbol: FirCallableSymbol<*>,
useSiteSession: FirSession,
token: KtLifetimeToken,
): KtAnnotationsList {
val receiverParameter = firCallableSymbol.receiverParameter
return if (receiverParameter?.annotations?.isEmpty() != false) {
KtEmptyAnnotationsList(token)
} else {
KtFirAnnotationListForReceiverParameter(firCallableSymbol, receiverParameter, useSiteSession, token)
}
}
}
}
@@ -7,7 +7,9 @@ package org.jetbrains.kotlin.analysis.api.fir.symbols
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.analyze import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForReceiverParameter
import org.jetbrains.kotlin.analysis.api.fir.findPsi import org.jetbrains.kotlin.analysis.api.fir.findPsi
import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.KtFirReceiverParameterSymbolPointer import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.KtFirReceiverParameterSymbolPointer
import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.requireOwnerPointer import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.requireOwnerPointer
@@ -46,4 +48,8 @@ internal class KtFirReceiverParameterSymbol(
override fun createPointer(): KtSymbolPointer<KtReceiverParameterSymbol> = withValidityAssertion { override fun createPointer(): KtSymbolPointer<KtReceiverParameterSymbol> = withValidityAssertion {
KtFirReceiverParameterSymbolPointer(owningCallableSymbol.createPointer()) KtFirReceiverParameterSymbolPointer(owningCallableSymbol.createPointer())
} }
override val annotationsList: KtAnnotationsList by cached {
KtFirAnnotationListForReceiverParameter.create(firSymbol, firResolveSession.useSiteFirSession, token)
}
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.resolveSupertypesInTheAir
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
@@ -1,11 +1,12 @@
/* /*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.analysis.api.symbols package org.jetbrains.kotlin.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiversOwner import org.jetbrains.kotlin.analysis.api.base.KtContextReceiversOwner
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtPossibleMemberSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtPossibleMemberSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
@@ -26,7 +27,7 @@ public sealed class KtCallableSymbol : KtSymbolWithKind, KtPossibleMemberSymbol,
* Symbol for a receiver parameter of a function or property. For example, consider code `fun String.foo() {...}`, the declaration of * Symbol for a receiver parameter of a function or property. For example, consider code `fun String.foo() {...}`, the declaration of
* `String` receiver parameter is such a symbol. * `String` receiver parameter is such a symbol.
*/ */
public abstract class KtReceiverParameterSymbol : KtSymbol { public abstract class KtReceiverParameterSymbol : KtAnnotatedSymbol {
public abstract val type: KtType public abstract val type: KtType
/** /**
@@ -4,6 +4,7 @@ KtSuccessCallInfo:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol: partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtImplicitReceiverValue: dispatchReceiver = KtImplicitReceiverValue:
symbol = KtReceiverParameterSymbol: symbol = KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtAnonymousFunctionSymbol(<local>/<no name provided>) owningCallableSymbol: KtAnonymousFunctionSymbol(<local>/<no name provided>)
type: test/Target<kotlin/String> type: test/Target<kotlin/String>
@@ -4,6 +4,7 @@ KtSuccessCallInfo:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol: partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtImplicitReceiverValue: dispatchReceiver = KtImplicitReceiverValue:
symbol = KtReceiverParameterSymbol: symbol = KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtAnonymousFunctionSymbol(<local>/<no name provided>) owningCallableSymbol: KtAnonymousFunctionSymbol(<local>/<no name provided>)
type: test/Target<kotlin/String> type: test/Target<kotlin/String>
@@ -30,4 +31,4 @@ KtSuccessCallInfo:
returnType = T returnType = T
symbol = t: T symbol = t: T
callableIdIfNonLocal = null) callableIdIfNonLocal = null)
} }
@@ -3,6 +3,7 @@ KtSuccessCallInfo:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol: partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtImplicitReceiverValue: dispatchReceiver = KtImplicitReceiverValue:
symbol = KtReceiverParameterSymbol: symbol = KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtFunctionSymbol(/call) owningCallableSymbol: KtFunctionSymbol(/call)
type: JavaClass type: JavaClass
@@ -16,4 +17,4 @@ KtSuccessCallInfo:
callableIdIfNonLocal = /JavaClass.foo callableIdIfNonLocal = /JavaClass.foo
simpleAccess = Read: simpleAccess = Read:
typeArgumentsMapping = {} typeArgumentsMapping = {}
@@ -3,6 +3,7 @@ KtSuccessCallInfo:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol: partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtImplicitReceiverValue: dispatchReceiver = KtImplicitReceiverValue:
symbol = KtReceiverParameterSymbol: symbol = KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtFunctionSymbol(/call) owningCallableSymbol: KtFunctionSymbol(/call)
type: JavaClass type: JavaClass
@@ -16,4 +17,4 @@ KtSuccessCallInfo:
callableIdIfNonLocal = /JavaClass.foo callableIdIfNonLocal = /JavaClass.foo
simpleAccess = Write: simpleAccess = Write:
value = 42 value = 42
typeArgumentsMapping = {} typeArgumentsMapping = {}
@@ -3,6 +3,7 @@ KtSuccessCallInfo:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol: partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtImplicitReceiverValue: dispatchReceiver = KtImplicitReceiverValue:
symbol = KtReceiverParameterSymbol: symbol = KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtFunctionSymbol(/foo) owningCallableSymbol: KtFunctionSymbol(/foo)
type: A type: A
@@ -16,4 +17,4 @@ KtSuccessCallInfo:
callableIdIfNonLocal = /A.i callableIdIfNonLocal = /A.i
simpleAccess = Read: simpleAccess = Read:
typeArgumentsMapping = {} typeArgumentsMapping = {}
@@ -3,6 +3,7 @@ KtSuccessCallInfo:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol: partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtImplicitReceiverValue: dispatchReceiver = KtImplicitReceiverValue:
symbol = KtReceiverParameterSymbol: symbol = KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtFunctionSymbol(/foo) owningCallableSymbol: KtFunctionSymbol(/foo)
type: A type: A
@@ -16,4 +17,4 @@ KtSuccessCallInfo:
callableIdIfNonLocal = /A.i callableIdIfNonLocal = /A.i
simpleAccess = Write: simpleAccess = Write:
value = 1 value = 1
typeArgumentsMapping = {} typeArgumentsMapping = {}
@@ -4,6 +4,7 @@ KtSuccessCallInfo:
dispatchReceiver = KtSmartCastedReceiverValue: dispatchReceiver = KtSmartCastedReceiverValue:
original = KtImplicitReceiverValue: original = KtImplicitReceiverValue:
symbol = KtReceiverParameterSymbol: symbol = KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtFunctionSymbol(/test) owningCallableSymbol: KtFunctionSymbol(/test)
type: kotlin/Any type: kotlin/Any
@@ -18,4 +19,4 @@ KtSuccessCallInfo:
callableIdIfNonLocal = kotlin/String.length callableIdIfNonLocal = kotlin/String.length
simpleAccess = Read: simpleAccess = Read:
typeArgumentsMapping = {} typeArgumentsMapping = {}
@@ -6,6 +6,7 @@ KtSuccessCallInfo:
extensionReceiver = KtSmartCastedReceiverValue: extensionReceiver = KtSmartCastedReceiverValue:
original = KtImplicitReceiverValue: original = KtImplicitReceiverValue:
symbol = KtReceiverParameterSymbol: symbol = KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtFunctionSymbol(/test) owningCallableSymbol: KtFunctionSymbol(/test)
type: kotlin/Any type: kotlin/Any
@@ -18,4 +19,4 @@ KtSuccessCallInfo:
valueParameters = [] valueParameters = []
callableIdIfNonLocal = /foo callableIdIfNonLocal = /foo
typeArgumentsMapping = {} typeArgumentsMapping = {}
argumentMapping = {} argumentMapping = {}
@@ -4,6 +4,7 @@ KtApplicableCallCandidateInfo:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol: partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtImplicitReceiverValue: dispatchReceiver = KtImplicitReceiverValue:
symbol = KtReceiverParameterSymbol: symbol = KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtAnonymousFunctionSymbol(<local>/<no name provided>) owningCallableSymbol: KtAnonymousFunctionSymbol(<local>/<no name provided>)
type: test/Target<kotlin/String> type: test/Target<kotlin/String>
@@ -4,6 +4,7 @@ KtApplicableCallCandidateInfo:
partiallyAppliedSymbol = KtPartiallyAppliedSymbol: partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtImplicitReceiverValue: dispatchReceiver = KtImplicitReceiverValue:
symbol = KtReceiverParameterSymbol: symbol = KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtAnonymousFunctionSymbol(<local>/<no name provided>) owningCallableSymbol: KtAnonymousFunctionSymbol(<local>/<no name provided>)
type: test/Target<kotlin/String> type: test/Target<kotlin/String>
@@ -1,4 +1,8 @@
KtReceiverParameterSymbol: KtReceiverParameterSymbol:
annotationsList: [
ReceiverAnnotation()
psi: KtAnnotationEntry
]
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtFunctionSymbol(/foo) owningCallableSymbol: KtFunctionSymbol(/foo)
type: [ type: [
@@ -1,4 +1,8 @@
KtReceiverParameterSymbol: KtReceiverParameterSymbol:
annotationsList: [
ReceiverAnnotation()
psi: KtAnnotationEntry
]
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtFunctionSymbol(/foo) owningCallableSymbol: KtFunctionSymbol(/foo)
type: [ type: [
@@ -1,4 +1,8 @@
KtReceiverParameterSymbol: KtReceiverParameterSymbol:
annotationsList: [
ReceiverAnnotation()
psi: KtAnnotationEntry
]
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtKotlinPropertySymbol(/prop) owningCallableSymbol: KtKotlinPropertySymbol(/prop)
type: [ type: [
@@ -1,4 +1,8 @@
KtReceiverParameterSymbol: KtReceiverParameterSymbol:
annotationsList: [
ReceiverAnnotation()
psi: KtAnnotationEntry
]
origin: SOURCE origin: SOURCE
owningCallableSymbol: KtKotlinPropertySymbol(/prop) owningCallableSymbol: KtKotlinPropertySymbol(/prop)
type: [ type: [
@@ -125,6 +125,7 @@ object FirNativeObjCNameChecker : FirBasicDeclarationChecker() {
is FirFunctionSymbol<*> -> buildList { is FirFunctionSymbol<*> -> buildList {
add((this@getObjCNames as FirBasedSymbol<*>).getObjCName()) add((this@getObjCNames as FirBasedSymbol<*>).getObjCName())
add(resolvedReceiverTypeRef?.getObjCName()) add(resolvedReceiverTypeRef?.getObjCName())
add(receiverParameter?.getObjCName())
valueParameterSymbols.forEach { add(it.getObjCName()) } valueParameterSymbols.forEach { add(it.getObjCName()) }
} }
@@ -1,11 +1,12 @@
/* /*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.fir.symbols package org.jetbrains.kotlin.fir.symbols
import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
@@ -42,22 +43,28 @@ abstract class FirBasedSymbol<E : FirDeclaration> {
get() = fir.annotations get() = fir.annotations
val resolvedAnnotationsWithArguments: List<FirAnnotation> val resolvedAnnotationsWithArguments: List<FirAnnotation>
get() { get() = fir.resolvedAnnotationsWithArguments(this)
lazyResolveToPhase(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING)
return fir.annotations
}
val resolvedAnnotationsWithClassIds: List<FirAnnotation> val resolvedAnnotationsWithClassIds: List<FirAnnotation>
get() { get() = fir.resolvedAnnotationsWithClassIds(this)
lazyResolveToPhase(FirResolvePhase.TYPES)
return fir.annotations
}
val resolvedAnnotationClassIds: List<ClassId> val resolvedAnnotationClassIds: List<ClassId>
get() { get() = fir.resolvedAnnotationClassIds(this)
lazyResolveToPhase(FirResolvePhase.TYPES) }
return fir.annotations.mapNotNull { (it.annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.classId }
} fun FirAnnotationContainer.resolvedAnnotationsWithArguments(anchorElement: FirBasedSymbol<*>): List<FirAnnotation> {
anchorElement.lazyResolveToPhase(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING)
return annotations
}
fun FirAnnotationContainer.resolvedAnnotationsWithClassIds(anchorElement: FirBasedSymbol<*>): List<FirAnnotation> {
anchorElement.lazyResolveToPhase(FirResolvePhase.TYPES)
return annotations
}
fun FirAnnotationContainer.resolvedAnnotationClassIds(anchorElement: FirBasedSymbol<*>): List<ClassId> {
anchorElement.lazyResolveToPhase(FirResolvePhase.TYPES)
return annotations.mapNotNull { (it.annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.classId }
} }
@RequiresOptIn @RequiresOptIn
@@ -1,11 +1,12 @@
/* /*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.fir.symbols.impl package org.jetbrains.kotlin.fir.symbols.impl
import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
@@ -32,6 +33,12 @@ abstract class FirCallableSymbol<D : FirCallableDeclaration> : FirBasedSymbol<D>
return fir.receiverParameter?.type as FirResolvedTypeRef? return fir.receiverParameter?.type as FirResolvedTypeRef?
} }
val receiverParameter: FirAnnotationContainer?
get() {
ensureType(fir.receiverParameter?.type)
return fir.receiverParameter
}
val resolvedContextReceivers: List<FirContextReceiver> val resolvedContextReceivers: List<FirContextReceiver>
get() { get() {
lazyResolveToPhase(FirResolvePhase.TYPES) lazyResolveToPhase(FirResolvePhase.TYPES)