FIR: introduce synthetic property symbol hierarchy

This commit is contained in:
Mikhail Glukhikh
2021-10-21 17:40:13 +03:00
committed by TeamCityServer
parent c673c4cc91
commit 79b98f9173
17 changed files with 92 additions and 39 deletions
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.buildSymbol
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirPackageSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
@@ -89,7 +89,7 @@ internal object FirReferenceResolveHelper {
}
is FirResolvedNamedReference -> {
val fir = when (val symbol = resolvedSymbol) {
is FirAccessorSymbol -> {
is FirSyntheticPropertySymbol -> {
val syntheticProperty = symbol.fir as FirSyntheticProperty
if (syntheticProperty.getter.delegate.symbol.callableId == symbol.getterId) {
syntheticProperty.getter.delegate
@@ -75,7 +75,7 @@ internal class FirIdeProvider(
symbol.fir.originalForSubstitutionOverride?.symbol?.let {
return getFirCallableContainerFile(it)
}
if (symbol is FirAccessorSymbol) {
if (symbol is FirSyntheticPropertySymbol) {
val fir = symbol.fir
if (fir is FirSyntheticProperty) {
return getFirCallableContainerFile(fir.getter.delegate.symbol)
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.FirThisReference
import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
@@ -188,7 +188,7 @@ fun FirReference.toSymbolForCall(
private fun FirCallableSymbol<*>.toSymbolForCall(declarationStorage: Fir2IrDeclarationStorage, preferGetter: Boolean): IrSymbol? =
when (this) {
is FirFunctionSymbol<*> -> declarationStorage.getIrFunctionSymbol(this)
is FirSyntheticPropertySymbol -> {
is FirSimpleSyntheticPropertySymbol -> {
(fir as? FirSyntheticProperty)?.let { syntheticProperty ->
val delegateSymbol = if (preferGetter) {
syntheticProperty.getter.delegate.symbol
@@ -451,7 +451,7 @@ internal fun FirReference.statementOrigin(): IrStatementOrigin? {
return when (this) {
is FirPropertyFromParameterResolvedNamedReference -> IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
is FirResolvedNamedReference -> when (val symbol = resolvedSymbol) {
is FirAccessorSymbol -> IrStatementOrigin.GET_PROPERTY
is FirSyntheticPropertySymbol -> IrStatementOrigin.GET_PROPERTY
is FirNamedFunctionSymbol -> when {
symbol.callableId.isInvoke() ->
IrStatementOrigin.INVOKE
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
@@ -45,7 +45,7 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
) return true
// FE1.0 allows calling public setters with property assignment syntax if the getter is protected.
if (!isCallToPropertySetter || symbol !is FirSyntheticPropertySymbol) return false
if (!isCallToPropertySetter || symbol !is FirSimpleSyntheticPropertySymbol) return false
symbol.setterSymbol?.visibility == Visibilities.Public
}
}
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.java.FirJavaTypeConversionMode
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
import org.jetbrains.kotlin.fir.java.declarations.*
import org.jetbrains.kotlin.fir.java.resolveIfJavaType
import org.jetbrains.kotlin.fir.java.symbols.FirJavaOverriddenSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeProbablyFlexible
import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptor
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
@@ -154,7 +155,7 @@ class FirSignatureEnhancement(
return buildSyntheticProperty {
moduleData = this@FirSignatureEnhancement.moduleData
this.name = name
symbol = FirAccessorSymbol(accessorSymbol.callableId, accessorSymbol.getterId)
symbol = FirJavaOverriddenSyntheticPropertySymbol(accessorSymbol.callableId, accessorSymbol.getterId)
delegateGetter = enhancedGetterSymbol.fir as FirSimpleFunction
delegateSetter = enhancedSetterSymbol?.fir as FirSimpleFunction?
status = firElement.status
@@ -162,7 +163,7 @@ class FirSignatureEnhancement(
}.symbol
}
else -> {
if (original is FirPropertySymbol || original is FirAccessorSymbol) return original
if (original is FirPropertySymbol || original is FirSyntheticPropertySymbol) return original
error("Can't make enhancement for $original: `${firElement.render()}`")
}
}
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.fir.copy
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.java.symbols.FirJavaOverriddenSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.nullableModuleData
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
@@ -45,7 +45,7 @@ class JavaAnnotationSyntheticPropertiesScope(
val function = functionSymbol.fir
val symbol = syntheticPropertiesCache.getOrPut(functionSymbol) {
val callableId = CallableId(classId, name)
FirAccessorSymbol(callableId, callableId).also {
FirJavaOverriddenSyntheticPropertySymbol(callableId, callableId).also {
val accessor = FirSyntheticPropertyAccessor(function, isGetter = true)
FirSyntheticProperty(
session.nullableModuleData ?: function.moduleData,
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
import org.jetbrains.kotlin.fir.java.declarations.buildJavaMethodCopy
import org.jetbrains.kotlin.fir.java.declarations.buildJavaValueParameterCopy
import org.jetbrains.kotlin.fir.java.symbols.FirJavaOverriddenSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.java.toConeKotlinTypeProbablyFlexible
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.*
@@ -50,7 +51,7 @@ class JavaClassUseSiteMemberScope(
) {
private val typeParameterStack = klass.javaTypeParameterStack
private val specialFunctions = hashMapOf<Name, Collection<FirNamedFunctionSymbol>>()
private val accessorByNameMap = hashMapOf<Name, FirAccessorSymbol>()
private val accessorByNameMap = hashMapOf<Name, FirSyntheticPropertySymbol>()
private val canUseSpecialGetters: Boolean by lazy { !klass.hasKotlinSuper(session) }
@@ -69,12 +70,12 @@ class JavaClassUseSiteMemberScope(
setterSymbol: FirNamedFunctionSymbol?,
property: FirProperty,
takeModalityFromGetter: Boolean,
): FirAccessorSymbol {
): FirSyntheticPropertySymbol {
return accessorByNameMap.getOrPut(property.name) {
buildSyntheticProperty {
moduleData = session.moduleData
name = property.name
symbol = FirAccessorSymbol(
symbol = FirJavaOverriddenSyntheticPropertySymbol(
getterId = getterSymbol.callableId,
propertyId = CallableId(getterSymbol.callableId.packageName, getterSymbol.callableId.className, property.name)
)
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2021 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.fir.java.symbols
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.name.CallableId
/**
* This is a synthetic property symbol created for Java getter overriding Kotlin property.
*
* Frontend IR creates such kind a symbol when a Java class is asked for a property which
* exists in one of its base Kotlin classes, and the Java class itself contains the bound getter.
*
* The typical example:
*
* ```
* abstract class SomeKotlinClass {
* abstract val foo: Int
* }
*
* public class SomeJavaClass extends SomeKotlinClass {
* @Override
* public int getFoo() { return 42; }
* }
* ```
*/
class FirJavaOverriddenSyntheticPropertySymbol(
propertyId: CallableId,
getterId: CallableId
) : FirSyntheticPropertySymbol(propertyId, getterId) {
override fun copy(): FirSyntheticPropertySymbol = FirJavaOverriddenSyntheticPropertySymbol(callableId, getterId)
}
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
@@ -27,10 +27,18 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.AbstractTypeChecker
class FirSyntheticPropertySymbol(
/**
* This symbol is bound to a synthetic property based on Java getter/setter call
*
* See details about such properties here: https://kotlinlang.org/docs/java-interop.html#getters-and-setters).
* Frontend IR creates this kind of symbol each time when x.foo should be resolved to x.getFoo() or x.setFoo().
*/
class FirSimpleSyntheticPropertySymbol(
propertyId: CallableId,
getterId: CallableId
) : FirAccessorSymbol(propertyId, getterId), SyntheticSymbol
) : FirSyntheticPropertySymbol(propertyId, getterId), SyntheticSymbol {
override fun copy(): FirSyntheticPropertySymbol = FirSimpleSyntheticPropertySymbol(callableId, getterId)
}
class FirSyntheticFunctionSymbol(
callableId: CallableId
@@ -113,7 +121,7 @@ class FirSyntheticPropertiesScope(
val property = buildSyntheticProperty {
moduleData = session.moduleData
name = propertyName
symbol = FirSyntheticPropertySymbol(
symbol = FirSimpleSyntheticPropertySymbol(
getterId = getterSymbol.callableId,
propertyId = CallableId(packageName, className, propertyName)
)
@@ -43,7 +43,7 @@ class FirClassSubstitutionScope(
get() = when (this) {
is FirPropertySymbol,
is FirFieldSymbol,
is FirAccessorSymbol -> true
is FirSyntheticPropertySymbol -> true
else -> false
}
}
@@ -294,7 +294,7 @@ class FirClassSubstitutionScope(
return FirFakeOverrideGenerator.createSubstitutionOverrideField(session, member, original, newReturnType, newOwnerClassId)
}
fun createSubstitutionOverrideAccessor(original: FirAccessorSymbol): FirAccessorSymbol {
fun createSubstitutionOverrideSyntheticProperty(original: FirSyntheticPropertySymbol): FirSyntheticPropertySymbol {
if (substitutor == ConeSubstitutor.Empty) return original
val member = original.fir as FirSyntheticProperty
if (skipPrivateMembers && member.visibility == Visibilities.Private) return original
@@ -319,7 +319,7 @@ class FirClassSubstitutionScope(
return original
}
return FirFakeOverrideGenerator.createSubstitutionOverrideAccessor(
return FirFakeOverrideGenerator.createSubstitutionOverrideSyntheticProperty(
session,
member,
original,
@@ -363,7 +363,7 @@ class FirSubstitutionOverrideStorage(val session: FirSession) : FirSessionCompon
when (original) {
is FirPropertySymbol -> scope.createSubstitutionOverrideProperty(original)
is FirFieldSymbol -> scope.createSubstitutionOverrideField(original)
is FirAccessorSymbol -> scope.createSubstitutionOverrideAccessor(original)
is FirSyntheticPropertySymbol -> scope.createSubstitutionOverrideSyntheticProperty(original)
else -> error("symbol $original is not overridable")
}
}
@@ -425,16 +425,16 @@ object FirFakeOverrideGenerator {
return symbol
}
fun createSubstitutionOverrideAccessor(
fun createSubstitutionOverrideSyntheticProperty(
session: FirSession,
baseProperty: FirSyntheticProperty,
baseSymbol: FirAccessorSymbol,
baseSymbol: FirSyntheticPropertySymbol,
newDispatchReceiverType: ConeKotlinType?,
newReturnType: ConeKotlinType?,
newGetterParameterTypes: List<ConeKotlinType?>?,
newSetterParameterTypes: List<ConeKotlinType?>?,
fakeOverrideSubstitution: FakeOverrideSubstitution?
): FirAccessorSymbol {
): FirSyntheticPropertySymbol {
val getterSymbol = FirNamedFunctionSymbol(baseSymbol.getterId)
val getter = createSubstitutionOverrideFunction(
getterSymbol,
@@ -463,7 +463,7 @@ object FirFakeOverrideGenerator {
return buildSyntheticProperty {
moduleData = session.moduleData
name = baseProperty.name
symbol = FirAccessorSymbol(baseSymbol.callableId, baseSymbol.getterId)
symbol = baseSymbol.copy()
delegateGetter = getter
delegateSetter = setter
status = baseProperty.status
@@ -29,7 +29,7 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: FirKotli
if (symbol is FirBackingFieldSymbol) {
return getFirCallableContainerFile(symbol.fir.propertySymbol)
}
if (symbol is FirAccessorSymbol) {
if (symbol is FirSyntheticPropertySymbol) {
val fir = symbol.fir
if (fir is FirSyntheticProperty) {
return getFirCallableContainerFile(fir.getter.delegate.symbol)
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
import org.jetbrains.kotlin.fir.resolve.transformers.TransformImplicitType
import org.jetbrains.kotlin.fir.resolve.transformers.contracts.runContractResolveForLocalClass
import org.jetbrains.kotlin.fir.scopes.fakeOverrideSubstitution
import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
@@ -332,7 +332,7 @@ class ImplicitBodyResolveComputationSession {
private val implicitBodyResolveStatusMap = hashMapOf<FirCallableSymbol<*>, ImplicitBodyResolveComputationStatus>()
internal fun getStatus(symbol: FirCallableSymbol<*>): ImplicitBodyResolveComputationStatus {
if (symbol is FirAccessorSymbol) {
if (symbol is FirSyntheticPropertySymbol) {
val fir = symbol.fir
if (fir is FirSyntheticProperty) {
return getStatus(fir.getter.delegate.symbol)
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.FirThisReference
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -102,7 +102,7 @@ val FirElement.symbol: FirBasedSymbol<*>?
else -> null
}?.takeIf {
(this as? FirExpression)?.unwrapSmartcastExpression() is FirThisReceiverExpression ||
(it !is FirFunctionSymbol<*> && it !is FirAccessorSymbol)
(it !is FirFunctionSymbol<*> && it !is FirSyntheticPropertySymbol)
}
@DfaInternals
@@ -11,8 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirDelegateFieldSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirTypeRef
@@ -25,7 +24,7 @@ class FirSyntheticProperty(
override val moduleData: FirModuleData,
override val name: Name,
override val isVar: Boolean,
override val symbol: FirAccessorSymbol,
override val symbol: FirSyntheticPropertySymbol,
override val status: FirDeclarationStatus,
override var resolvePhase: FirResolvePhase,
override val getter: FirSyntheticPropertyAccessor,
@@ -9,13 +9,13 @@ import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.declarations.DeprecationsPerUseSite
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.name.Name
class FirSyntheticPropertyBuilder {
lateinit var moduleData: FirModuleData
lateinit var name: Name
lateinit var symbol: FirAccessorSymbol
lateinit var symbol: FirSyntheticPropertySymbol
lateinit var delegateGetter: FirSimpleFunction
lateinit var deprecation: DeprecationsPerUseSite
@@ -80,10 +80,19 @@ class FirConstructorSymbol(
get() = fir.delegatedConstructor?.isSuper ?: false
}
open class FirAccessorSymbol(
/**
* This is a property symbol which is always bound to FirSyntheticProperty.
*
* Synthetic property symbol is effectively a combination of
* a property (which never exists in sources) and
* a getter which exists in sources and is either from Java or overrides another getter from Java.
*/
abstract class FirSyntheticPropertySymbol(
propertyId: CallableId,
val getterId: CallableId
) : FirPropertySymbol(propertyId)
) : FirPropertySymbol(propertyId) {
abstract fun copy(): FirSyntheticPropertySymbol
}
// ------------------------ unnamed ------------------------