[AA] improve symbol pointers for property accessors

Fe10:
* supported default setter
* support default getter
* support parameter from default setter

Fir:
* support java synthetic properties
* support parameter from default setter

^KT-54051
This commit is contained in:
Dmitrii Gridin
2022-11-17 17:09:31 +01:00
committed by Space Team
parent ca12cfb90d
commit edd60cd204
11 changed files with 129 additions and 50 deletions
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased package org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade
@@ -24,11 +25,10 @@ import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.ktSym
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.ktVisibility import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.ktVisibility
import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached
import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList
import org.jetbrains.kotlin.analysis.api.impl.base.symbols.pointers.KtPropertyAccessorSymbolPointer
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertyGetterSymbol import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.KtReceiverParameterSymbol import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
@@ -97,8 +97,12 @@ internal class KtFe10PsiDefaultPropertyGetterSymbol(
descriptor?.let { KtFe10AnnotationsList.create(it.annotations, token) } ?: KtEmptyAnnotationsList(token) descriptor?.let { KtFe10AnnotationsList.create(it.annotations, token) } ?: KtEmptyAnnotationsList(token)
} }
@OptIn(KtAnalysisApiInternals::class)
override fun createPointer(): KtSymbolPointer<KtPropertyGetterSymbol> = withValidityAssertion { override fun createPointer(): KtSymbolPointer<KtPropertyGetterSymbol> = withValidityAssertion {
return KtFe10NeverRestoringSymbolPointer() KtPsiBasedSymbolPointer.createForSymbolFromPsi<KtPropertySymbol>(propertyPsi)?.let {
@Suppress("UNCHECKED_CAST")
KtPropertyAccessorSymbolPointer(it, isGetter = true) as KtSymbolPointer<KtPropertyGetterSymbol>
} ?: KtFe10NeverRestoringSymbolPointer()
} }
override fun equals(other: Any?): Boolean = isEqualTo(other) override fun equals(other: Any?): Boolean = isEqualTo(other)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased package org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade
@@ -24,11 +25,11 @@ import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.ktSym
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.ktVisibility import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.ktVisibility
import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached
import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList
import org.jetbrains.kotlin.analysis.api.impl.base.symbols.pointers.KtPropertyAccessorSymbolPointer
import org.jetbrains.kotlin.analysis.api.impl.base.symbols.pointers.KtValueParameterFromDefaultSetterSymbolPointer
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySetterSymbol import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.KtReceiverParameterSymbol import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
@@ -104,11 +105,14 @@ internal class KtFe10PsiDefaultPropertySetterSymbol(
descriptor?.let { KtFe10AnnotationsList.create(it.annotations, token) } ?: KtEmptyAnnotationsList(token) descriptor?.let { KtFe10AnnotationsList.create(it.annotations, token) } ?: KtEmptyAnnotationsList(token)
} }
@OptIn(KtAnalysisApiInternals::class)
override fun createPointer(): KtSymbolPointer<KtPropertySetterSymbol> = withValidityAssertion { override fun createPointer(): KtSymbolPointer<KtPropertySetterSymbol> = withValidityAssertion {
return KtFe10NeverRestoringSymbolPointer() KtPsiBasedSymbolPointer.createForSymbolFromPsi<KtPropertySymbol>(propertyPsi)?.let {
@Suppress("UNCHECKED_CAST")
KtPropertyAccessorSymbolPointer(it, isGetter = false) as KtSymbolPointer<KtPropertySetterSymbol>
} ?: KtFe10NeverRestoringSymbolPointer()
} }
override fun equals(other: Any?): Boolean = isEqualTo(other) override fun equals(other: Any?): Boolean = isEqualTo(other)
override fun hashCode(): Int = calculateHashCode() override fun hashCode(): Int = calculateHashCode()
@@ -149,8 +153,11 @@ internal class KtFe10PsiDefaultPropertySetterSymbol(
descriptor?.let { KtFe10AnnotationsList.create(it.annotations, token) } ?: KtEmptyAnnotationsList(token) descriptor?.let { KtFe10AnnotationsList.create(it.annotations, token) } ?: KtEmptyAnnotationsList(token)
} }
@OptIn(KtAnalysisApiInternals::class)
override fun createPointer(): KtSymbolPointer<KtValueParameterSymbol> = withValidityAssertion { override fun createPointer(): KtSymbolPointer<KtValueParameterSymbol> = withValidityAssertion {
return KtFe10NeverRestoringSymbolPointer() KtPsiBasedSymbolPointer.createForSymbolFromPsi<KtPropertySymbol>(propertyPsi)?.let {
KtValueParameterFromDefaultSetterSymbolPointer(it)
} ?: KtFe10NeverRestoringSymbolPointer()
} }
override fun equals(other: Any?): Boolean = isEqualTo(other) override fun equals(other: Any?): Boolean = isEqualTo(other)
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2021 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.
*/ */
@@ -18,9 +18,12 @@ import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.creat
import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached
import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList import org.jetbrains.kotlin.analysis.api.impl.base.annotations.KtEmptyAnnotationsList
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySetterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerDelegator
import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -67,10 +70,11 @@ internal class KtFe10PsiDefaultSetterParameterSymbol(
get() = withValidityAssertion { KtEmptyAnnotationsList(token) } get() = withValidityAssertion { KtEmptyAnnotationsList(token) }
override fun createPointer(): KtSymbolPointer<KtValueParameterSymbol> = withValidityAssertion { override fun createPointer(): KtSymbolPointer<KtValueParameterSymbol> = withValidityAssertion {
return KtFe10NeverRestoringSymbolPointer() KtPsiBasedSymbolPointer.createForSymbolFromPsi<KtPropertySetterSymbol>(accessorPsi)?.let { symbolPointer ->
symbolPointerDelegator(symbolPointer) { it.parameter }
} ?: KtFe10NeverRestoringSymbolPointer()
} }
override fun equals(other: Any?): Boolean = isEqualTo(other) override fun equals(other: Any?): Boolean = isEqualTo(other)
override fun hashCode(): Int = calculateHashCode() override fun hashCode(): Int = calculateHashCode()
} }
@@ -88,7 +88,7 @@ internal class KtFirSymbolContainingDeclarationProvider(
KtFakeSourceElementKind.ImplicitConstructor -> return source.psi as KtDeclaration KtFakeSourceElementKind.ImplicitConstructor -> return source.psi as KtDeclaration
KtFakeSourceElementKind.PropertyFromParameter -> return source.psi?.parentOfType<KtPrimaryConstructor>()!! KtFakeSourceElementKind.PropertyFromParameter -> return source.psi?.parentOfType<KtPrimaryConstructor>()!!
KtFakeSourceElementKind.DefaultAccessor -> return source.psi as KtProperty KtFakeSourceElementKind.DefaultAccessor -> return source.psi as KtDeclaration
KtFakeSourceElementKind.ItLambdaParameter -> return source.psi as KtFunctionLiteral KtFakeSourceElementKind.ItLambdaParameter -> return source.psi as KtFunctionLiteral
KtFakeSourceElementKind.EnumInitializer -> return source.psi as KtEnumEntry KtFakeSourceElementKind.EnumInitializer -> return source.psi as KtEnumEntry
KtRealSourceElementKind -> source.psi!! KtRealSourceElementKind -> source.psi!!
@@ -6,12 +6,13 @@
package org.jetbrains.kotlin.analysis.api.fir.symbols package org.jetbrains.kotlin.analysis.api.fir.symbols
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration
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.KtFirPropertyAccessorSymbolPointer
import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.requireOwnerPointer import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.requireOwnerPointer
import org.jetbrains.kotlin.analysis.api.fir.utils.cached import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.impl.base.symbols.pointers.KtPropertyAccessorSymbolPointer
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertyGetterSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtPropertyGetterSymbol
@@ -58,7 +59,13 @@ internal class KtFirPropertyGetterSymbol(
override val returnType: KtType get() = withValidityAssertion { firSymbol.returnType(builder) } override val returnType: KtType get() = withValidityAssertion { firSymbol.returnType(builder) }
override val receiverParameter: KtReceiverParameterSymbol? get() = withValidityAssertion { firSymbol.fir.propertySymbol.receiver(builder) } override val receiverParameter: KtReceiverParameterSymbol? get() = withValidityAssertion { firSymbol.fir.propertySymbol.receiver(builder) }
override val annotationsList by cached { KtFirAnnotationListForDeclaration.create(firSymbol, firResolveSession.useSiteFirSession, token) } override val annotationsList by cached {
KtFirAnnotationListForDeclaration.create(
firSymbol,
firResolveSession.useSiteFirSession,
token,
)
}
/** /**
* Returns [CallableId] of the delegated Java method if the corresponding property of this setter is a synthetic Java property. * Returns [CallableId] of the delegated Java method if the corresponding property of this setter is a synthetic Java property.
@@ -76,11 +83,12 @@ internal class KtFirPropertyGetterSymbol(
override val hasStableParameterNames: Boolean override val hasStableParameterNames: Boolean
get() = withValidityAssertion { true } get() = withValidityAssertion { true }
@OptIn(KtAnalysisApiInternals::class)
override fun createPointer(): KtSymbolPointer<KtPropertyGetterSymbol> = withValidityAssertion { override fun createPointer(): KtSymbolPointer<KtPropertyGetterSymbol> = withValidityAssertion {
KtPsiBasedSymbolPointer.createForSymbolFromSource<KtPropertyGetterSymbol>(this)?.let { return it } KtPsiBasedSymbolPointer.createForSymbolFromSource<KtPropertyGetterSymbol>(this)?.let { return it }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
KtFirPropertyAccessorSymbolPointer(requireOwnerPointer(), isGetter = true) as KtSymbolPointer<KtPropertyGetterSymbol> KtPropertyAccessorSymbolPointer(requireOwnerPointer(), isGetter = true) as KtSymbolPointer<KtPropertyGetterSymbol>
} }
override fun equals(other: Any?): Boolean = symbolEquals(other) override fun equals(other: Any?): Boolean = symbolEquals(other)
@@ -6,12 +6,13 @@
package org.jetbrains.kotlin.analysis.api.fir.symbols package org.jetbrains.kotlin.analysis.api.fir.symbols
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration
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.KtFirPropertyAccessorSymbolPointer
import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.requireOwnerPointer import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.requireOwnerPointer
import org.jetbrains.kotlin.analysis.api.fir.utils.cached import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.impl.base.symbols.pointers.KtPropertyAccessorSymbolPointer
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySetterSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySetterSymbol
@@ -99,11 +100,12 @@ internal class KtFirPropertySetterSymbol(
override val hasStableParameterNames: Boolean override val hasStableParameterNames: Boolean
get() = withValidityAssertion { true } get() = withValidityAssertion { true }
@OptIn(KtAnalysisApiInternals::class)
override fun createPointer(): KtSymbolPointer<KtPropertySetterSymbol> = withValidityAssertion { override fun createPointer(): KtSymbolPointer<KtPropertySetterSymbol> = withValidityAssertion {
KtPsiBasedSymbolPointer.createForSymbolFromSource<KtPropertySetterSymbol>(this)?.let { return it } KtPsiBasedSymbolPointer.createForSymbolFromSource<KtPropertySetterSymbol>(this)?.let { return it }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
KtFirPropertyAccessorSymbolPointer(requireOwnerPointer(), isGetter = false) as KtSymbolPointer<KtPropertySetterSymbol> KtPropertyAccessorSymbolPointer(requireOwnerPointer(), isGetter = false) as KtSymbolPointer<KtPropertySetterSymbol>
} }
override fun equals(other: Any?): Boolean = symbolEquals(other) override fun equals(other: Any?): Boolean = symbolEquals(other)
@@ -46,9 +46,9 @@ internal class KtFirValueParameterSymbol(
firSymbol.source?.kind == KtFakeSourceElementKind.ItLambdaParameter firSymbol.source?.kind == KtFakeSourceElementKind.ItLambdaParameter
} }
override val isCrossinline: Boolean get() = withValidityAssertion { firSymbol.isCrossinline} override val isCrossinline: Boolean get() = withValidityAssertion { firSymbol.isCrossinline }
override val isNoinline: Boolean get() = withValidityAssertion { firSymbol.isNoinline} override val isNoinline: Boolean get() = withValidityAssertion { firSymbol.isNoinline }
override val returnType by cached { override val returnType by cached {
val returnType = firSymbol.resolvedReturnType val returnType = firSymbol.resolvedReturnType
@@ -64,7 +64,13 @@ internal class KtFirValueParameterSymbol(
override val hasDefaultValue: Boolean get() = withValidityAssertion { firSymbol.hasDefaultValue } override val hasDefaultValue: Boolean get() = withValidityAssertion { firSymbol.hasDefaultValue }
override val annotationsList by cached { KtFirAnnotationListForDeclaration.create(firSymbol, firResolveSession.useSiteFirSession, token) } override val annotationsList by cached {
KtFirAnnotationListForDeclaration.create(
firSymbol,
firResolveSession.useSiteFirSession,
token,
)
}
override val generatedPrimaryConstructorProperty: KtKotlinPropertySymbol? by cached { override val generatedPrimaryConstructorProperty: KtKotlinPropertySymbol? by cached {
val propertySymbol = firSymbol.fir.correspondingProperty?.symbol ?: return@cached null val propertySymbol = firSymbol.fir.correspondingProperty?.symbol ?: return@cached null
@@ -72,6 +78,7 @@ internal class KtFirValueParameterSymbol(
check(ktPropertySymbol is KtKotlinPropertySymbol) { check(ktPropertySymbol is KtKotlinPropertySymbol) {
"Unexpected symbol for primary constructor property ${ktPropertySymbol.javaClass} for fir: ${firSymbol.fir.renderWithType()}" "Unexpected symbol for primary constructor property ${ktPropertySymbol.javaClass} for fir: ${firSymbol.fir.renderWithType()}"
} }
ktPropertySymbol ktPropertySymbol
} }
@@ -79,14 +86,16 @@ internal class KtFirValueParameterSymbol(
KtPsiBasedSymbolPointer.createForSymbolFromSource<KtValueParameterSymbol>(this)?.let { return it } KtPsiBasedSymbolPointer.createForSymbolFromSource<KtValueParameterSymbol>(this)?.let { return it }
analyze(firResolveSession.useSiteKtModule) { analyze(firResolveSession.useSiteKtModule) {
val owner = getContainingSymbol() as KtFunctionLikeSymbol when (val owner = getContainingSymbol()) {
val firFunction = owner.firSymbol.fir as FirFunction is KtFunctionLikeSymbol ->
KtFirValueParameterSymbolPointer(
owner.createPointer(),
name,
(owner.firSymbol.fir as FirFunction).valueParameters.indexOf(firSymbol.fir),
)
KtFirValueParameterSymbolPointer( else -> error("${requireNotNull(owner)::class}")
owner.createPointer(), }
name,
firFunction.valueParameters.indexOf(firSymbol.fir),
)
} }
} }
@@ -3,27 +3,25 @@
* 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.fir.symbols.pointers package org.jetbrains.kotlin.analysis.api.impl.base.symbols.pointers
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirKotlinPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertyAccessorSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtPropertyAccessorSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
internal class KtFirPropertyAccessorSymbolPointer( @KtAnalysisApiInternals
private val propertySymbolPointer: KtSymbolPointer<KtKotlinPropertySymbol>, class KtPropertyAccessorSymbolPointer(
private val propertySymbolPointer: KtSymbolPointer<KtPropertySymbol>,
private val isGetter: Boolean, private val isGetter: Boolean,
) : KtSymbolPointer<KtPropertyAccessorSymbol>() { ) : KtSymbolPointer<KtPropertyAccessorSymbol>() {
@Deprecated("Consider using org.jetbrains.kotlin.analysis.api.KtAnalysisSession.restoreSymbol") @Deprecated("Consider using org.jetbrains.kotlin.analysis.api.KtAnalysisSession.restoreSymbol")
override fun restoreSymbol(analysisSession: KtAnalysisSession): KtPropertyAccessorSymbol? { override fun restoreSymbol(analysisSession: KtAnalysisSession): KtPropertyAccessorSymbol? {
require(analysisSession is KtFirAnalysisSession)
val propertySymbol = with(analysisSession) { val propertySymbol = with(analysisSession) {
propertySymbolPointer.restoreSymbol() propertySymbolPointer.restoreSymbol()
} ?: return null } ?: return null
check(propertySymbol is KtFirKotlinPropertySymbol)
return if (isGetter) propertySymbol.getter else propertySymbol.setter return if (isGetter) propertySymbol.getter else propertySymbol.setter
} }
} }
@@ -0,0 +1,25 @@
/*
* 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.symbols.pointers
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
@KtAnalysisApiInternals
class KtValueParameterFromDefaultSetterSymbolPointer(
private val ownerPointer: KtSymbolPointer<KtPropertySymbol>,
) : KtSymbolPointer<KtValueParameterSymbol>() {
@Deprecated("Consider using org.jetbrains.kotlin.analysis.api.KtAnalysisSession.restoreSymbol")
override fun restoreSymbol(analysisSession: KtAnalysisSession): KtValueParameterSymbol? {
val ownerSymbol = with(analysisSession) {
ownerPointer.restoreSymbol()
}
return ownerSymbol?.setter?.parameter
}
}
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.impl.base.test.SymbolByFqName import org.jetbrains.kotlin.analysis.api.impl.base.test.SymbolByFqName
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.AbstractSymbolByFqNameTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.AbstractSymbolByFqNameTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolsData import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolsData
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.TestServices
@@ -85,11 +85,19 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() {
analyseForTest(ktFile) { analyseForTest(ktFile) {
val (symbols, symbolForPrettyRendering) = collectSymbols(ktFile, testServices) val (symbols, symbolForPrettyRendering) = collectSymbols(ktFile, testServices)
val pointerWithRenderedSymbol = symbols.map { symbol -> val pointerWithRenderedSymbol = symbols.flatMap { symbol ->
PointerWithRenderedSymbol( listOf(
symbol.safePointer(), PointerWithRenderedSymbol(
renderSymbolForComparison(symbol), symbol.safePointer(),
) renderSymbolForComparison(symbol),
)
) + symbol.withImplicitSymbols().map { implicitSymbol ->
PointerWithRenderedSymbol(
implicitSymbol.safePointer(),
renderSymbolForComparison(implicitSymbol),
shouldBeRendered = false,
)
}
} }
val pointerWithPrettyRenderedSymbol = symbolForPrettyRendering.map { symbol -> val pointerWithPrettyRenderedSymbol = symbolForPrettyRendering.map { symbol ->
@@ -105,7 +113,7 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() {
is KtReceiverParameterSymbol -> DebugSymbolRenderer().render(symbol) is KtReceiverParameterSymbol -> DebugSymbolRenderer().render(symbol)
else -> error(symbol::class.toString()) else -> error(symbol::class.toString())
} },
) )
} }
@@ -168,7 +176,7 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() {
} }
private fun List<PointerWithRenderedSymbol>.renderDeclarations(): String = private fun List<PointerWithRenderedSymbol>.renderDeclarations(): String =
map { it.rendered }.renderAsDeclarations() mapNotNull { it.rendered.takeIf { _ -> it.shouldBeRendered } }.renderAsDeclarations()
private fun List<String>.renderAsDeclarations(): String = private fun List<String>.renderAsDeclarations(): String =
if (isEmpty()) "NO_SYMBOLS" if (isEmpty()) "NO_SYMBOLS"
@@ -184,10 +192,16 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() {
var failed = false var failed = false
try { try {
val restored = analyseForTest(ktFile) { val restored = analyseForTest(ktFile) {
pointersWithRendered.map { (pointerWrapper, expectedRender) -> pointersWithRendered.mapNotNull { (pointerWrapper, expectedRender, shouldBeRendered) ->
val pointer = pointerWrapper?.let(pointerAccessor) ?: error("Symbol pointer for $expectedRender was not created") val pointer = pointerWrapper?.let(pointerAccessor) ?: error("Symbol pointer for $expectedRender was not created")
val restored = pointer.restoreSymbol() ?: error("Symbol $expectedRender was not restored") val restored = pointer.restoreSymbol() ?: error("Symbol $expectedRender was not restored")
renderSymbolForComparison(restored) val actualRender = renderSymbolForComparison(restored)
if (shouldBeRendered) {
actualRender
} else {
testServices.assertions.assertEquals(expectedRender, actualRender) { "${restored::class}" }
null
}
} }
} }
@@ -259,9 +273,18 @@ private data class SymbolPointersData(
private data class PointerWithRenderedSymbol( private data class PointerWithRenderedSymbol(
val pointer: PointerWrapper?, val pointer: PointerWrapper?,
val rendered: String, val rendered: String,
val shouldBeRendered: Boolean = true,
) )
private data class PointerWrapper( private data class PointerWrapper(
val regularPointer: KtSymbolPointer<*>, val regularPointer: KtSymbolPointer<*>,
val pointerWithoutPsiAnchor: KtSymbolPointer<*>?, val pointerWithoutPsiAnchor: KtSymbolPointer<*>?,
) )
private fun KtSymbol?.withImplicitSymbols(): List<KtSymbol> = when (this) {
null -> emptyList()
is KtPropertySymbol -> listOf(this) + setter.withImplicitSymbols() + getter.withImplicitSymbols()
is KtPropertySetterSymbol -> listOf(this) + parameter
is KtValueParameterSymbol -> listOf(this) + generatedPrimaryConstructorProperty.withImplicitSymbols()
else -> listOf(this)
}