FIR IDE: hoist up API to get Java getter/setter name of a property...

and expose API to get the getter and setter symbols for synthetic Java
properties.
This commit is contained in:
Tianyu Geng
2021-08-13 17:17:39 -07:00
committed by Ilya Kirillov
parent bb3f55dec2
commit 14b66872b5
19 changed files with 282 additions and 13 deletions
@@ -131,3 +131,13 @@ fun FirAnnotationCall.getStringArgument(name: Name): String? =
findArgumentByName(name)?.let { expression ->
expression.safeAs<FirConstExpression<*>>()?.value as? String
}
private val jvmNameAnnotationFqName = FqName.fromSegments(listOf("kotlin", "jvm", "JvmName"))
fun FirAnnotationContainer.getJvmNameFromAnnotation(target: AnnotationUseSiteTarget? = null): String? {
val name = Name.identifier("name")
val annotationCalls = getAnnotationsByFqName(jvmNameAnnotationFqName)
return annotationCalls.firstNotNullOfOrNull { call ->
call.getStringArgument(name)?.takeIf { target == null || call.useSiteTarget == target }
}
}
@@ -9,12 +9,16 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.name.Name
public abstract class KtSymbolInfoProvider : KtAnalysisSessionComponent() {
public abstract fun getDeprecation(symbol: KtSymbol): DeprecationInfo?
public abstract fun getDeprecation(symbol: KtSymbol, annotationUseSiteTarget: AnnotationUseSiteTarget?): DeprecationInfo?
public abstract fun getGetterDeprecation(symbol: KtPropertySymbol): DeprecationInfo?
public abstract fun getSetterDeprecation(symbol: KtPropertySymbol): DeprecationInfo?
public abstract fun getJavaGetterName(symbol: KtPropertySymbol): Name
public abstract fun getJavaSetterName(symbol: KtPropertySymbol): Name?
}
public interface KtSymbolInfoProviderMixIn : KtAnalysisSessionMixIn {
@@ -41,4 +45,7 @@ public interface KtSymbolInfoProviderMixIn : KtAnalysisSessionMixIn {
*/
public val KtPropertySymbol.setterDeprecationStatus: DeprecationInfo?
get() = analysisSession.symbolInfoProvider.getSetterDeprecation(this)
public val KtPropertySymbol.javaGetterName: Name get() = analysisSession.symbolInfoProvider.getJavaGetterName(this)
public val KtPropertySymbol.javaSetterName: Name? get() = analysisSession.symbolInfoProvider.getJavaSetterName(this)
}
@@ -115,8 +115,8 @@ public abstract class KtSyntheticJavaPropertySymbol : KtPropertySymbol() {
abstract override val getter: KtPropertyGetterSymbol
public abstract val javaGetterName: Name
public abstract val javaSetterName: Name?
public abstract val javaGetterSymbol: KtFunctionSymbol
public abstract val javaSetterSymbol: KtFunctionSymbol?
abstract override fun createPointer(): KtSymbolPointer<KtSyntheticJavaPropertySymbol>
}
@@ -7,16 +7,21 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.components
import org.jetbrains.kotlin.resolve.deprecation.DeprecationInfo
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.getDeprecationForCallSite
import org.jetbrains.kotlin.fir.declarations.getJvmNameFromAnnotation
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.components.KtSymbolInfoProvider
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirBackingFieldSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirPackageSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSyntheticJavaPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name
internal class KtFirSymbolInfoProvider(
override val analysisSession: KtFirAnalysisSession,
@@ -59,4 +64,32 @@ internal class KtFirSymbolInfoProvider(
it.symbol.getDeprecationForCallSite(AnnotationUseSiteTarget.PROPERTY_SETTER, AnnotationUseSiteTarget.PROPERTY)
}
}
override fun getJavaGetterName(symbol: KtPropertySymbol): Name {
require(symbol is KtFirSymbol<*>)
if (symbol is KtFirSyntheticJavaPropertySymbol) {
return symbol.firRef.withFir { it.getter.delegate.name }
}
val jvmName = symbol.firRef.withFir {
val firProperty = it as? FirProperty ?: return@withFir null
firProperty.getJvmNameFromAnnotation(AnnotationUseSiteTarget.PROPERTY_GETTER) ?: firProperty.getter?.getJvmNameFromAnnotation()
}
return Name.identifier(jvmName ?: JvmAbi.getterName(symbol.name.identifier))
}
override fun getJavaSetterName(symbol: KtPropertySymbol): Name? {
require(symbol is KtFirSymbol<*>)
if (symbol is KtFirSyntheticJavaPropertySymbol) {
symbol.firRef.withFir { it.setter?.delegate?.name }
}
return if (symbol.isVal) null
else {
val jvmName = symbol.firRef.withFir {
val firProperty = it as? FirProperty ?: return@withFir null
firProperty.getJvmNameFromAnnotation(AnnotationUseSiteTarget.PROPERTY_SETTER)
?: firProperty.setter?.getJvmNameFromAnnotation()
}
Name.identifier(jvmName ?: JvmAbi.setterName(symbol.name.identifier))
}
}
}
@@ -10,7 +10,8 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.idea.fir.findPsi
@@ -9,9 +9,9 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
@@ -22,10 +22,7 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.convertConstantExpression
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertyGetterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySetterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSyntheticJavaPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotationCall
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtConstantValue
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtTypeAndAnnotations
@@ -74,14 +71,21 @@ internal class KtFirSyntheticJavaPropertySymbol(
override val getter: KtPropertyGetterSymbol by firRef.withFirAndCache(FirResolvePhase.RAW_FIR) { property ->
property.getter.let { builder.callableBuilder.buildPropertyAccessorSymbol(it) } as KtPropertyGetterSymbol
}
override val javaGetterSymbol: KtFunctionSymbol
get() {
return firRef.withFir { builder.functionLikeBuilder.buildFunctionSymbol(it.getter.delegate) }
}
override val javaSetterSymbol: KtFunctionSymbol?
get() {
return firRef.withFir { fir ->
fir.setter?.delegate?.let { setter -> builder.functionLikeBuilder.buildFunctionSymbol(setter) }
}
}
override val setter: KtPropertySetterSymbol? by firRef.withFirAndCache(FirResolvePhase.RAW_FIR) { property ->
property.setter?.let { builder.callableBuilder.buildPropertyAccessorSymbol(it) } as? KtPropertySetterSymbol
}
override val javaGetterName: Name get() = firRef.withFir { it.getter.delegate.name }
override val javaSetterName: Name? get() = firRef.withFir { it.setter?.delegate?.name }
override val isFromPrimaryConstructor: Boolean get() = false
override val isOverride: Boolean get() = firRef.withFir { it.isOverride }
override val isStatic: Boolean get() = firRef.withFir { it.isStatic }
@@ -61,6 +61,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getTestVal
javaSetterName: null
setterDeprecationStatus: null
CLASSIFIER NAMES:
@@ -561,6 +561,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getSize
javaSetterName: null
setterDeprecationStatus: null
KtFirFunctionSymbol:
@@ -81,8 +81,8 @@ KtFirSyntheticJavaPropertySymbol:
isOverride: false
isStatic: false
isVal: true
javaGetterName: length
javaSetterName: null
javaGetterSymbol: KtFirFunctionSymbol(java/lang/String.length)
javaSetterSymbol: null
modality: OPEN
name: length
origin: JAVA_SYNTHETIC_PROPERTY
@@ -92,6 +92,8 @@ KtFirSyntheticJavaPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: length
javaSetterName: null
setterDeprecationStatus: null
KtFirFunctionSymbol:
@@ -50,6 +50,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getData
javaSetterName: null
setterDeprecationStatus: null
KtFirAnonymousObjectSymbol:
@@ -92,6 +94,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getAnonymousObject
javaSetterName: null
setterDeprecationStatus: null
KtFirNamedClassOrObjectSymbol:
@@ -25,6 +25,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getA
javaSetterName: null
setterDeprecationStatus: null
KtFirFunctionSymbol:
@@ -30,6 +30,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=true, message=don't use i)
getterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=true, message=don't use i)
javaGetterName: getI
javaSetterName: null
setterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=true, message=don't use i)
KtFirKotlinPropertySymbol:
@@ -64,6 +66,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=true, message=don't use getter of i2)
javaGetterName: getI2
javaSetterName: null
setterDeprecationStatus: null
KtFirKotlinPropertySymbol:
@@ -98,6 +102,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getI3
javaSetterName: setI3
setterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=true, message=don't use getter of i3)
KtFirKotlinPropertySymbol:
@@ -135,6 +141,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=true, message=don't use getter of i4)
javaGetterName: getI4
javaSetterName: setI4
setterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=true, message=don't use getter of i4)
KtFirFunctionSymbol:
@@ -226,6 +234,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=true, message=don't use i2)
getterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=true, message=don't use i2)
javaGetterName: getI2
javaSetterName: null
setterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=true, message=don't use i2)
KtFirFunctionSymbol:
@@ -312,6 +322,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: SimpleDeprecationInfo(deprecationLevel=ERROR, propagatesToOverrides=true, message=null)
getterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=ERROR, propagatesToOverrides=true, message=null)
javaGetterName: getJ
javaSetterName: null
setterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=ERROR, propagatesToOverrides=true, message=null)
KtFirKotlinPropertySymbol:
@@ -346,6 +358,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: SimpleDeprecationInfo(deprecationLevel=HIDDEN, propagatesToOverrides=true, message=null)
getterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=HIDDEN, propagatesToOverrides=true, message=null)
javaGetterName: getJ2
javaSetterName: null
setterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=HIDDEN, propagatesToOverrides=true, message=null)
KtFirKotlinPropertySymbol:
@@ -380,4 +394,6 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=false, message=null)
getterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=false, message=null)
javaGetterName: getJ2
javaSetterName: null
setterDeprecationStatus: SimpleDeprecationInfo(deprecationLevel=WARNING, propagatesToOverrides=false, message=null)
@@ -77,6 +77,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getExitAnimation
javaSetterName: null
setterDeprecationStatus: null
KtFirEnumEntrySymbol:
@@ -117,6 +119,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getExitAnimation
javaSetterName: null
setterDeprecationStatus: null
KtFirNamedClassOrObjectSymbol:
@@ -0,0 +1,14 @@
// WITH_STDLIB
class Foo {
@get:JvmName("getMyI")
@set:JvmName("setMyI")
var i: Int
var j: Int
@JvmName("getMyJ")
get() = 1
@JvmName("setMyJ")
set(value) {
}
}
@@ -0,0 +1,152 @@
KtFirKotlinPropertySymbol:
annotatedType: [] kotlin/Int
annotationClassIds: [
kotlin/jvm/JvmName
kotlin/jvm/JvmName
]
annotations: [
kotlin/jvm/JvmName(name = getMyI)
psi: KtAnnotationEntry
kotlin/jvm/JvmName(name = setMyI)
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /Foo.i
dispatchType: Foo
getter: KtFirPropertyGetterSymbol(<getter>)
hasBackingField: true
hasGetter: true
hasSetter: true
initializer: null
isConst: false
isExtension: false
isFromPrimaryConstructor: false
isLateInit: false
isOverride: false
isStatic: false
isVal: false
modality: FINAL
name: i
origin: SOURCE
receiverType: null
setter: KtFirPropertySetterSymbol(<setter>)
symbolKind: MEMBER
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getMyI
javaSetterName: setMyI
setterDeprecationStatus: null
KtFirPropertyGetterSymbol:
annotatedType: [] kotlin/Int
annotationClassIds: [
kotlin/jvm/JvmName
]
annotations: [
kotlin/jvm/JvmName(name = getMyJ)
psi: KtAnnotationEntry
]
callableIdIfNonLocal: null
dispatchType: null
hasBody: true
isDefault: false
isExtension: false
isInline: false
isOverride: false
modality: FINAL
origin: SOURCE
receiverType: null
symbolKind: ACCESSOR
visibility: Public
deprecationStatus: null
KtFirValueParameterSymbol:
annotatedType: [] kotlin/Int
annotationClassIds: []
annotations: []
callableIdIfNonLocal: null
hasDefaultValue: false
isExtension: false
isVararg: false
name: value
origin: SOURCE
receiverType: null
symbolKind: LOCAL
deprecationStatus: null
KtFirPropertySetterSymbol:
annotatedType: [] kotlin/Unit
annotationClassIds: [
kotlin/jvm/JvmName
]
annotations: [
kotlin/jvm/JvmName(name = setMyJ)
psi: KtAnnotationEntry
]
callableIdIfNonLocal: null
dispatchType: null
hasBody: true
isDefault: false
isExtension: false
isInline: false
isOverride: false
modality: FINAL
origin: SOURCE
parameter: KtFirValueParameterSymbol(value)
receiverType: null
symbolKind: ACCESSOR
visibility: Public
deprecationStatus: null
KtFirKotlinPropertySymbol:
annotatedType: [] kotlin/Int
annotationClassIds: []
annotations: []
callableIdIfNonLocal: /Foo.j
dispatchType: Foo
getter: KtFirPropertyGetterSymbol(<getter>)
hasBackingField: false
hasGetter: true
hasSetter: true
initializer: null
isConst: false
isExtension: false
isFromPrimaryConstructor: false
isLateInit: false
isOverride: false
isStatic: false
isVal: false
modality: FINAL
name: j
origin: SOURCE
receiverType: null
setter: KtFirPropertySetterSymbol(<setter>)
symbolKind: MEMBER
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getMyJ
javaSetterName: setMyJ
setterDeprecationStatus: null
KtFirNamedClassOrObjectSymbol:
annotationClassIds: []
annotations: []
classIdIfNonLocal: Foo
classKind: CLASS
companionObject: null
isData: false
isExternal: false
isFun: false
isInline: false
isInner: false
modality: FINAL
name: Foo
origin: SOURCE
superTypes: [
[] kotlin/Any
]
symbolKind: TOP_LEVEL
typeParameters: []
visibility: Public
deprecationStatus: null
@@ -25,6 +25,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getX
javaSetterName: null
setterDeprecationStatus: null
KtFirPropertyGetterSymbol:
@@ -72,6 +74,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getY
javaSetterName: null
setterDeprecationStatus: null
KtFirNamedClassOrObjectSymbol:
@@ -25,6 +25,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getX
javaSetterName: null
setterDeprecationStatus: null
KtFirPropertyGetterSymbol:
@@ -72,4 +74,6 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getY
javaSetterName: null
setterDeprecationStatus: null
@@ -205,6 +205,8 @@ KtFirKotlinPropertySymbol:
visibility: Public
deprecationStatus: null
getterDeprecationStatus: null
javaGetterName: getX
javaSetterName: null
setterDeprecationStatus: null
KtFirNamedClassOrObjectSymbol:
@@ -120,6 +120,12 @@ public class SymbolByPsiTestGenerated extends AbstractSymbolByPsiTest {
runTest("idea/idea-frontend-fir/testData/symbols/symbolByPsi/implicitReturnInLambda.kt");
}
@Test
@TestMetadata("jvmName.kt")
public void testJvmName() throws Exception {
runTest("idea/idea-frontend-fir/testData/symbols/symbolByPsi/jvmName.kt");
}
@Test
@TestMetadata("localDeclarations.kt")
public void testLocalDeclarations() throws Exception {