[Analysis API] add info about context receivers to the Analysis API

This commit is contained in:
Ilya Kirillov
2022-06-30 17:52:10 +02:00
parent 2f822ab4d9
commit 8f89f1b368
40 changed files with 481 additions and 16 deletions
@@ -5,8 +5,10 @@
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.KtFe10DescMemberSymbol
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.createContextReceivers
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktHasStableParameterNames
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtType
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.pointers.KtFe10NeverRestoringSymbolPointer
@@ -39,6 +41,9 @@ internal class KtFe10DescAnonymousFunctionSymbol(
override val receiverType: KtType?
get() = withValidityAssertion { descriptor.extensionReceiverParameter?.type?.toKtType(analysisContext) }
override val contextReceivers: List<KtContextReceiver>
get() = withValidityAssertion { descriptor.createContextReceivers(analysisContext) }
override fun createPointer(): KtSymbolPointer<KtAnonymousFunctionSymbol> = withValidityAssertion {
return KtPsiBasedSymbolPointer.createForSymbolFromSource(this) ?: KtFe10NeverRestoringSymbolPointer()
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.*
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.pointers.KtFe10DescFunctionLikeSymbolPointer
@@ -75,6 +76,9 @@ internal class KtFe10DescFunctionSymbol private constructor(
override val receiverType: KtType?
get() = withValidityAssertion { descriptor.extensionReceiverParameter?.type?.toKtType(analysisContext) }
override val contextReceivers: List<KtContextReceiver>
get() = withValidityAssertion { descriptor.createContextReceivers(analysisContext) }
override val isExtension: Boolean
get() = withValidityAssertion { descriptor.isExtension }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased
import org.jetbrains.kotlin.analysis.api.KtInitializerValue
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.*
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.pointers.KtFe10NeverRestoringSymbolPointer
@@ -92,6 +93,9 @@ internal class KtFe10DescKotlinPropertySymbol(
override val receiverType: KtType?
get() = withValidityAssertion { descriptor.extensionReceiverParameter?.type?.toKtType(analysisContext) }
override val contextReceivers: List<KtContextReceiver>
get() = withValidityAssertion { descriptor.createContextReceivers(analysisContext) }
override val typeParameters: List<KtTypeParameterSymbol>
get() = withValidityAssertion { descriptor.typeParameters.map { it.toKtTypeParameter(analysisContext) } }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.*
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.pointers.KtFe10DescNamedClassOrObjectSymbolSymbol
@@ -54,6 +55,9 @@ internal class KtFe10DescNamedClassOrObjectSymbol(
}
}
override val contextReceivers: List<KtContextReceiver>
get() = withValidityAssertion { descriptor.createContextReceivers(analysisContext) }
@OptIn(KtAnalysisApiInternals::class)
override val classKind: KtClassKind
get() = withValidityAssertion {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.*
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.pointers.KtFe10DescSamConstructorSymbolPointer
@@ -48,6 +49,9 @@ internal class KtFe10DescSamConstructorSymbol(
override val receiverType: KtType?
get() = withValidityAssertion { descriptor.extensionReceiverParameter?.type?.toKtType(analysisContext) }
override val contextReceivers: List<KtContextReceiver>
get() = withValidityAssertion { descriptor.createContextReceivers(analysisContext) }
override val isExtension: Boolean
get() = withValidityAssertion { descriptor.isExtension }
@@ -3,11 +3,14 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:OptIn(KtAnalysisApiInternals::class)
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base
import org.jetbrains.kotlin.analysis.api.*
import org.jetbrains.kotlin.analysis.api.annotations.*
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.KtFe10PackageSymbol
@@ -15,6 +18,7 @@ import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.*
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.KtFe10PsiSymbol
import org.jetbrains.kotlin.analysis.api.descriptors.types.*
import org.jetbrains.kotlin.analysis.api.descriptors.utils.KtFe10Renderer
import org.jetbrains.kotlin.analysis.api.impl.base.KtContextReceiverImpl
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.analysis.api.types.KtType
@@ -43,6 +47,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor
import org.jetbrains.kotlin.resolve.sam.SamConstructorDescriptor
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitContextReceiver
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
@@ -263,7 +268,8 @@ internal fun KotlinType.toKtType(analysisContext: Fe10AnalysisContext): KtType {
is FunctionClassDescriptor -> KtFe10FunctionalType(unwrappedType, typeDeclaration, analysisContext)
is ClassDescriptor -> KtFe10UsualClassType(unwrappedType, typeDeclaration, analysisContext)
else -> {
val errorType = ErrorUtils.createErrorType(ErrorTypeKind.UNRESOLVED_CLASS_TYPE, typeConstructor, typeDeclaration.toString())
val errorType =
ErrorUtils.createErrorType(ErrorTypeKind.UNRESOLVED_CLASS_TYPE, typeConstructor, typeDeclaration.toString())
KtFe10ClassErrorType(errorType, analysisContext)
}
}
@@ -563,3 +569,26 @@ internal fun AnnotationDescriptor.getKtNamedAnnotationArguments() =
allValueArguments.map { (name, value) ->
KtNamedAnnotationValue(name, value.toKtAnnotationValue())
}
internal fun CallableDescriptor.createContextReceivers(
analysisContext: Fe10AnalysisContext
): List<KtContextReceiver> {
return contextReceiverParameters.map { createContextReceiver(it, analysisContext) }
}
internal fun ClassDescriptor.createContextReceivers(
analysisContext: Fe10AnalysisContext
): List<KtContextReceiver> {
return contextReceivers.map { createContextReceiver(it, analysisContext) }
}
private fun createContextReceiver(
contextReceiver: ReceiverParameterDescriptor,
analysisContext: Fe10AnalysisContext
): KtContextReceiverImpl {
return KtContextReceiverImpl(
contextReceiver.value.type.toKtType(analysisContext),
(contextReceiver.value as ImplicitContextReceiver).customLabelName,
analysisContext.token
)
}
@@ -5,9 +5,11 @@
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.createContextReceivers
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtType
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.pointers.KtFe10NeverRestoringSymbolPointer
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.KtFe10PsiSymbol
@@ -55,6 +57,9 @@ internal class KtFe10PsiAnonymousFunctionSymbol(
return extensionReceiverParameter.type.toKtType(analysisContext)
}
override val contextReceivers: List<KtContextReceiver>
get() = withValidityAssertion { descriptor?.createContextReceivers(analysisContext) ?: emptyList() }
override val isExtension: Boolean
get() = withValidityAssertion { psi.isExtensionDeclaration() }
@@ -5,8 +5,10 @@
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.createContextReceivers
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktModality
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktVisibility
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtType
@@ -89,6 +91,9 @@ internal class KtFe10PsiFunctionSymbol(
return extensionReceiverParameter.type.toKtType(analysisContext)
}
override val contextReceivers: List<KtContextReceiver>
get() = withValidityAssertion { descriptor?.createContextReceivers(analysisContext) ?: emptyList() }
override val isExtension: Boolean
get() = withValidityAssertion { psi.isExtensionDeclaration() }
@@ -6,8 +6,10 @@
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased
import org.jetbrains.kotlin.analysis.api.KtInitializerValue
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.*
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.createKtInitializerValue
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktModality
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktVisibility
@@ -116,6 +118,9 @@ internal class KtFe10PsiKotlinPropertySymbol(
}
}
override val contextReceivers: List<KtContextReceiver>
get() = withValidityAssertion { descriptor?.createContextReceivers(analysisContext) ?: emptyList() }
override val isExtension: Boolean
get() = withValidityAssertion { psi.isExtensionDeclaration() }
@@ -5,8 +5,10 @@
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.KtFe10DescValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.createContextReceivers
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtType
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.pointers.KtFe10NeverRestoringSymbolPointer
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.KtFe10PsiSymbol
@@ -57,6 +59,10 @@ internal class KtFe10PsiLiteralAnonymousFunctionSymbol(
extensionReceiverParameter.type.toKtType(analysisContext)
}
override val contextReceivers: List<KtContextReceiver>
get() = withValidityAssertion { descriptor?.createContextReceivers(analysisContext) ?: emptyList() }
override val isExtension: Boolean
get() = withValidityAssertion { psi.isExtensionDeclaration() }
@@ -6,8 +6,10 @@
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.*
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.getSupertypesWithAny
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktModality
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktVisibility
@@ -67,6 +69,10 @@ internal class KtFe10PsiNamedClassOrObjectSymbol(
KtFe10PsiNamedClassOrObjectSymbol(companionObject, analysisContext)
}
override val contextReceivers: List<KtContextReceiver>
get() = withValidityAssertion { descriptor?.createContextReceivers(analysisContext) ?: emptyList() }
@OptIn(KtAnalysisApiInternals::class)
override val classKind: KtClassKind
get() = withValidityAssertion {
@@ -243,4 +243,32 @@ public class Fe10IdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated extends A
public void testVarargFunctions() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/varargFunctions.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers")
@TestDataPath("$PROJECT_ROOT")
public class ContextReceivers {
@Test
public void testAllFilesPresentInContextReceivers() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("contextReceiversOnClass.kt")
public void testContextReceiversOnClass() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers/contextReceiversOnClass.kt");
}
@Test
@TestMetadata("contextReceiversOnFunction.kt")
public void testContextReceiversOnFunction() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers/contextReceiversOnFunction.kt");
}
@Test
@TestMetadata("contextReceiversOnProperty.kt")
public void testContextReceiversOnProperty() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers/contextReceiversOnProperty.kt");
}
}
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration
import org.jetbrains.kotlin.analysis.api.fir.findPsi
@@ -40,6 +41,8 @@ internal class KtFirAnonymousFunctionSymbol(
override val returnType: KtType get() = withValidityAssertion { firSymbol.returnType(builder) }
override val receiverType: KtType? get() = withValidityAssertion { firSymbol.receiverType(builder) }
override val contextReceivers: List<KtContextReceiver> by cached { firSymbol.createContextReceivers(builder) }
override val valueParameters: List<KtValueParameterSymbol> by cached { firSymbol.createKtValueParameters(builder) }
override val hasStableParameterNames: Boolean
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.analysis.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration
import org.jetbrains.kotlin.analysis.api.fir.findPsi
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.analysis.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration
import org.jetbrains.kotlin.analysis.api.fir.findPsi
@@ -50,7 +51,8 @@ internal class KtFirFunctionSymbol(
override val returnType: KtType get() = withValidityAssertion { firSymbol.returnType(builder) }
override val receiverType: KtType? get() = withValidityAssertion { firSymbol.receiverType(builder) }
override val contextReceivers: List<KtContextReceiver> by cached { firSymbol.createContextReceivers(builder) }
override val typeParameters by cached { firSymbol.createKtTypeParameters(builder) }
override val valueParameters: List<KtValueParameterSymbol> by cached { firSymbol.createKtValueParameters(builder) }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.analysis.api.KtInitializerValue
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration
import org.jetbrains.kotlin.analysis.api.fir.findPsi
@@ -63,7 +64,8 @@ internal class KtFirKotlinPropertySymbol(
override val returnType: KtType get() = withValidityAssertion { firSymbol.returnType(builder) }
override val receiverType: KtType? get() = withValidityAssertion { firSymbol.receiverType(builder) }
override val contextReceivers: List<KtContextReceiver> by cached { firSymbol.createContextReceivers(builder) }
override val isExtension: Boolean get() = withValidityAssertion { firSymbol.isExtension }
override val initializer: KtInitializerValue? by cached { firSymbol.getKtConstantInitializer() }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration
import org.jetbrains.kotlin.analysis.api.fir.findPsi
@@ -74,6 +75,8 @@ internal class KtFirNamedClassOrObjectSymbol(
override val isFun: Boolean get() = withValidityAssertion { firSymbol.isFun }
override val isExternal: Boolean get() = withValidityAssertion { firSymbol.isExternal }
override val contextReceivers: List<KtContextReceiver> get() = withValidityAssertion { firSymbol.createContextReceivers(builder) }
override val companionObject: KtFirNamedClassOrObjectSymbol? by cached {
firSymbol.companionObjectSymbol?.let {
builder.classifierBuilder.buildNamedClassOrObjectSymbol(it)
@@ -7,18 +7,19 @@ package org.jetbrains.kotlin.analysis.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration
import org.jetbrains.kotlin.analysis.api.fir.findPsi
import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.KtFirSamConstructorSymbolPointer
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtSamConstructorSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
import org.jetbrains.kotlin.fir.resolve.getHasStableParameterNames
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
@@ -44,6 +45,8 @@ internal class KtFirSamConstructorSymbol(
override val returnType: KtType get() = withValidityAssertion { firSymbol.returnType(builder) }
override val contextReceivers: List<KtContextReceiver> by cached { firSymbol.createContextReceivers(builder) }
override val valueParameters: List<KtValueParameterSymbol>
get() = withValidityAssertion {
firSymbol.createKtValueParameters(builder)
@@ -3,19 +3,21 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:OptIn(KtAnalysisApiInternals::class)
package org.jetbrains.kotlin.analysis.api.fir.symbols
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.KtInitializerValue
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.utils.asKtInitializerValue
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.impl.base.KtContextReceiverImpl
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
@@ -23,10 +25,7 @@ import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtDeclaration
@@ -57,6 +56,27 @@ internal fun <D> FirBasedSymbol<D>.createKtTypeParameters(
}
internal fun FirCallableSymbol<*>.createContextReceivers(
builder: KtSymbolByFirBuilder
): List<KtContextReceiver> {
return resolvedContextReceivers.map { createContextReceiver(builder, it) }
}
internal fun FirRegularClassSymbol.createContextReceivers(
builder: KtSymbolByFirBuilder
): List<KtContextReceiver> {
return resolvedContextReceivers.map { createContextReceiver(builder, it) }
}
private fun createContextReceiver(
builder: KtSymbolByFirBuilder,
contextReceiver: FirContextReceiver
) = KtContextReceiverImpl(
builder.typeBuilder.buildKtType(contextReceiver.typeRef),
contextReceiver.customLabelName,
builder.token
)
internal fun FirCallableSymbol<*>.getCallableIdIfNonLocal(): CallableId? =
callableId.takeUnless { it.isLocal }
@@ -243,4 +243,32 @@ public class FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated extends Ab
public void testVarargFunctions() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/varargFunctions.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers")
@TestDataPath("$PROJECT_ROOT")
public class ContextReceivers {
@Test
public void testAllFilesPresentInContextReceivers() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("contextReceiversOnClass.kt")
public void testContextReceiversOnClass() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers/contextReceiversOnClass.kt");
}
@Test
@TestMetadata("contextReceiversOnFunction.kt")
public void testContextReceiversOnFunction() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers/contextReceiversOnFunction.kt");
}
@Test
@TestMetadata("contextReceiversOnProperty.kt")
public void testContextReceiversOnProperty() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers/contextReceiversOnProperty.kt");
}
}
}
@@ -0,0 +1,23 @@
/*
* 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.impl.base
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.name.Name
@KtAnalysisApiInternals
class KtContextReceiverImpl(
private val _type: KtType,
private val _label: Name?,
override val token: KtLifetimeToken
) : KtContextReceiver() {
override val label: Name? get() = withValidityAssertion { _label }
override val type: KtType get() = withValidityAssertion { _type }
}
@@ -243,4 +243,32 @@ public class FirStandaloneNormalAnalysisSourceModuleSymbolByPsiTestGenerated ext
public void testVarargFunctions() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/varargFunctions.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers")
@TestDataPath("$PROJECT_ROOT")
public class ContextReceivers {
@Test
public void testAllFilesPresentInContextReceivers() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("contextReceiversOnClass.kt")
public void testContextReceiversOnClass() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers/contextReceiversOnClass.kt");
}
@Test
@TestMetadata("contextReceiversOnFunction.kt")
public void testContextReceiversOnFunction() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers/contextReceiversOnFunction.kt");
}
@Test
@TestMetadata("contextReceiversOnProperty.kt")
public void testContextReceiversOnProperty() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByPsi/contextReceivers/contextReceiversOnProperty.kt");
}
}
}
@@ -0,0 +1,47 @@
/*
* 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.base
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.name.Name
/**
* A context receiver of function/property type which are directly specified in the code
*
* E.g, for the following code
* ```
* context(a@Int)
* fun foo(){}
* ```
*
* the context receiver is `KtContextReceiver(type=KtClassType(Int), label="a")`
*/
public abstract class KtContextReceiver : KtLifetimeOwner {
/**
* Type of the context receiver
*
* @see KtContextReceiver
*/
public abstract val type: KtType
/**
* Additional label for the context receivers in the format `label@Type`, if label is not present, return `null`
*
* @see KtContextReceiver
*/
public abstract val label: Name?
}
/**
* Something which can have a [KtContextReceiver] declared. This may be a callable symbol or a class symbol
*/
public interface KtContextReceiversOwner : KtLifetimeOwner {
/**
* List of [KtContextReceiver] directly declared in the source code
*/
public val contextReceivers: List<KtContextReceiver>
}
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue
import org.jetbrains.kotlin.analysis.api.KtInitializerValue
import org.jetbrains.kotlin.analysis.api.KtNonConstantInitializerValue
import org.jetbrains.kotlin.analysis.api.annotations.*
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.components.KtSymbolContainingDeclarationProviderMixIn
import org.jetbrains.kotlin.analysis.api.components.KtSymbolInfoProviderMixIn
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol
@@ -203,6 +204,7 @@ public object DebugSymbolRenderer {
is KtAnnotationValue -> renderAnnotationValue(value)
is KtNamedAnnotationValue -> renderNamedConstantValue(value)
is KtInitializerValue -> renderKtInitializerValue(value)
is KtContextReceiver -> rendeContextReceiver(value)
is KtAnnotationApplication -> renderAnnotationApplication(value)
is KtAnnotationsList -> renderAnnotationsList(value)
is KtModule -> renderKtModule(value)
@@ -224,6 +226,16 @@ public object DebugSymbolRenderer {
}
}
private fun PrettyPrinter.rendeContextReceiver(receiver: KtContextReceiver) {
append("ContextReceiver(")
receiver.label?.let { label ->
renderValue(label)
append("@")
}
renderType(receiver.type)
append(")")
}
private fun PrettyPrinter.renderKtModule(ktModule: KtModule) {
val ktModuleClass = ktModule::class.allSuperclasses.filter { it in ktModuleSubclasses }.first()
append("${ktModuleClass.simpleName} \"${ktModule.moduleDescription}\"")
@@ -5,13 +5,14 @@
package org.jetbrains.kotlin.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiversOwner
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.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.name.CallableId
public sealed class KtCallableSymbol : KtSymbolWithKind, KtPossibleMemberSymbol, KtDeclarationSymbol {
public sealed class KtCallableSymbol : KtSymbolWithKind, KtPossibleMemberSymbol, KtDeclarationSymbol, KtContextReceiversOwner {
public abstract val callableIdIfNonLocal: CallableId?
public abstract val returnType: KtType
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiversOwner
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
@@ -74,7 +75,8 @@ public abstract class KtAnonymousObjectSymbol : KtClassOrObjectSymbol() {
public abstract class KtNamedClassOrObjectSymbol : KtClassOrObjectSymbol(),
KtSymbolWithModality,
KtSymbolWithVisibility,
KtNamedSymbol {
KtNamedSymbol,
KtContextReceiversOwner {
public abstract val isInner: Boolean
public abstract val isData: Boolean
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
@@ -74,6 +75,7 @@ public abstract class KtConstructorSymbol : KtFunctionLikeSymbol(),
final override val symbolKind: KtSymbolKind get() = withValidityAssertion { KtSymbolKind.CLASS_MEMBER }
final override val isExtension: Boolean get() = withValidityAssertion { false }
final override val receiverType: KtType? get() = withValidityAssertion { null }
final override val contextReceivers: List<KtContextReceiver> get() = withValidityAssertion { emptyList() }
abstract override fun createPointer(): KtSymbolPointer<KtConstructorSymbol>
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
@@ -20,6 +21,8 @@ public sealed class KtPropertyAccessorSymbol : KtFunctionLikeSymbol(),
final override val typeParameters: List<KtTypeParameterSymbol>
get() = withValidityAssertion { emptyList() }
final override val contextReceivers: List<KtContextReceiver> get() = withValidityAssertion { emptyList() }
public abstract val isDefault: Boolean
public abstract val isInline: Boolean
public abstract val isOverride: Boolean
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.api.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.*
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
@@ -42,6 +43,7 @@ public abstract class KtBackingFieldSymbol : KtVariableLikeSymbol() {
final override val callableIdIfNonLocal: CallableId? get() = withValidityAssertion { null }
final override val isExtension: Boolean get() = withValidityAssertion { false }
final override val receiverType: KtType? get() = withValidityAssertion { null }
final override val contextReceivers: List<KtContextReceiver> get() = withValidityAssertion { emptyList() }
final override val typeParameters: List<KtTypeParameterSymbol>
get() = withValidityAssertion { emptyList() }
@@ -58,6 +60,7 @@ public abstract class KtEnumEntrySymbol : KtVariableLikeSymbol(), KtSymbolWithMe
final override val symbolKind: KtSymbolKind get() = withValidityAssertion { KtSymbolKind.CLASS_MEMBER }
final override val isExtension: Boolean get() = withValidityAssertion { false }
final override val receiverType: KtType? get() = withValidityAssertion { null }
final override val contextReceivers: List<KtContextReceiver> get() = withValidityAssertion { emptyList() }
final override val typeParameters: List<KtTypeParameterSymbol>
get() = withValidityAssertion { emptyList() }
@@ -82,6 +85,7 @@ public abstract class KtJavaFieldSymbol :
final override val symbolKind: KtSymbolKind get() = withValidityAssertion { KtSymbolKind.CLASS_MEMBER }
final override val isExtension: Boolean get() = withValidityAssertion { false }
final override val receiverType: KtType? get() = withValidityAssertion { null }
final override val contextReceivers: List<KtContextReceiver> get() = withValidityAssertion { emptyList() }
final override val typeParameters: List<KtTypeParameterSymbol>
get() = withValidityAssertion { emptyList() }
@@ -137,6 +141,8 @@ public abstract class KtSyntheticJavaPropertySymbol : KtPropertySymbol() {
final override val isDelegatedProperty: Boolean get() = withValidityAssertion { false }
final override val hasGetter: Boolean get() = withValidityAssertion { true }
final override val symbolKind: KtSymbolKind get() = withValidityAssertion { KtSymbolKind.CLASS_MEMBER }
final override val contextReceivers: List<KtContextReceiver> get() = withValidityAssertion { emptyList() }
abstract override val getter: KtPropertyGetterSymbol
@@ -150,6 +156,7 @@ public abstract class KtLocalVariableSymbol : KtVariableSymbol(), KtSymbolWithKi
final override val callableIdIfNonLocal: CallableId? get() = withValidityAssertion { null }
final override val isExtension: Boolean get() = withValidityAssertion { false }
final override val receiverType: KtType? get() = withValidityAssertion { null }
final override val contextReceivers: List<KtContextReceiver> get() = withValidityAssertion { emptyList() }
final override val typeParameters: List<KtTypeParameterSymbol>
get() = withValidityAssertion { emptyList() }
@@ -162,6 +169,7 @@ public abstract class KtValueParameterSymbol : KtVariableLikeSymbol(), KtSymbolW
final override val callableIdIfNonLocal: CallableId? get() = withValidityAssertion { null }
final override val isExtension: Boolean get() = withValidityAssertion { false }
final override val receiverType: KtType? get() = withValidityAssertion { null }
final override val contextReceivers: List<KtContextReceiver> get() = withValidityAssertion { emptyList() }
final override val typeParameters: List<KtTypeParameterSymbol>
get() = withValidityAssertion { emptyList() }
@@ -0,0 +1,4 @@
context(kotlin.Int, s@kotlin.String)
class A {
constructor(int: Int) {}
}
@@ -0,0 +1,3 @@
class A {
constructor(int: kotlin.Int)
}
@@ -0,0 +1,63 @@
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isExtension: false
isImplicitLambdaParameter: false
isVararg: false
name: int
origin: SOURCE
receiverType: null
returnType: kotlin/Int
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
KtConstructorSymbol:
annotationsList: []
callableIdIfNonLocal: null
containingClassIdIfNonLocal: A
contextReceivers: []
hasStableParameterNames: true
isExtension: false
isPrimary: false
origin: SOURCE
receiverType: null
returnType: A
symbolKind: CLASS_MEMBER
typeParameters: []
valueParameters: [
KtValueParameterSymbol(int)
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
KtNamedClassOrObjectSymbol:
annotationsList: []
classIdIfNonLocal: A
classKind: CLASS
companionObject: null
contextReceivers: [
ContextReceiver(kotlin/Int)
ContextReceiver(s@kotlin/String)
]
isData: false
isExternal: false
isFun: false
isInline: false
isInner: false
modality: FINAL
name: A
origin: SOURCE
superTypes: [
kotlin/Any
]
symbolKind: TOP_LEVEL
typeParameters: []
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,2 @@
context(Int, s@String)
fun y(){}
@@ -0,0 +1,28 @@
KtFunctionSymbol:
annotationsList: []
callableIdIfNonLocal: /y
contextReceivers: [
ContextReceiver(kotlin/Int)
ContextReceiver(s@kotlin/String)
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: y
origin: SOURCE
receiverType: null
returnType: kotlin/Unit
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: []
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,2 @@
context(Int, s@String)
val y get() = 10
@@ -0,0 +1,56 @@
KtPropertyGetterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
hasBody: true
hasStableParameterNames: true
isDefault: false
isExtension: false
isInline: false
isOverride: false
modality: FINAL
origin: SOURCE
receiverType: null
returnType: kotlin/Int
symbolKind: ACCESSOR
typeParameters: []
valueParameters: []
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
KtKotlinPropertySymbol:
annotationsList: []
callableIdIfNonLocal: /y
contextReceivers: [
ContextReceiver(kotlin/Int)
ContextReceiver(s@kotlin/String)
]
getter: KtPropertyGetterSymbol(<getter>)
hasBackingField: false
hasGetter: true
hasSetter: false
initializer: null
isConst: false
isDelegatedProperty: false
isExtension: false
isFromPrimaryConstructor: false
isLateInit: false
isOverride: false
isStatic: false
isVal: true
modality: FINAL
name: y
origin: SOURCE
receiverType: null
returnType: kotlin/Int
setter: null
symbolKind: TOP_LEVEL
typeParameters: []
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getY
javaSetterName: null
setterDeprecationStatus: null
@@ -31,6 +31,12 @@ abstract class FirCallableSymbol<D : FirCallableDeclaration> : FirBasedSymbol<D>
return fir.receiverTypeRef as FirResolvedTypeRef?
}
val resolvedContextReceivers: List<FirContextReceiver>
get() {
ensureResolved(FirResolvePhase.TYPES)
return fir.contextReceivers
}
val resolvedStatus: FirResolvedDeclarationStatus
get() {
ensureResolved(FirResolvePhase.STATUS)
@@ -76,6 +76,12 @@ sealed class FirClassSymbol<C : FirClass>(classId: ClassId) : FirClassLikeSymbol
class FirRegularClassSymbol(classId: ClassId) : FirClassSymbol<FirRegularClass>(classId) {
val companionObjectSymbol: FirRegularClassSymbol?
get() = fir.companionObjectSymbol
val resolvedContextReceivers: List<FirContextReceiver>
get() {
ensureResolved(FirResolvePhase.TYPES)
return fir.contextReceivers
}
}
val ANONYMOUS_CLASS_ID = ClassId(FqName.ROOT, FqName.topLevel(SpecialNames.ANONYMOUS), true)