FIR IDE: resolve call to property accessors
This commit is contained in:
committed by
Ilya Kirillov
parent
cd4a08cb18
commit
8e242655f9
@@ -381,6 +381,14 @@ fun KtExpression.getAssignmentByLHS(): KtBinaryExpression? {
|
||||
return if (KtPsiUtil.isAssignment(parent) && parent.left == this) parent else null
|
||||
}
|
||||
|
||||
tailrec fun findAssignment(element: PsiElement?): KtBinaryExpression? =
|
||||
when (val parent = element?.parent) {
|
||||
is KtBinaryExpression -> if (parent.left == element && parent.operationToken == KtTokens.EQ) parent else null
|
||||
is KtQualifiedExpression -> findAssignment(element.parent)
|
||||
is KtSimpleNameExpression -> findAssignment(element.parent)
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun KtStringTemplateExpression.getContentRange(): TextRange {
|
||||
val start = node.firstChildNode.textLength
|
||||
val lastChild = node.lastChildNode
|
||||
|
||||
+10
-4
@@ -6,12 +6,10 @@
|
||||
package org.jetbrains.kotlin.idea.frontend.api.components
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.calls.KtCall
|
||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtCallElement
|
||||
import org.jetbrains.kotlin.psi.KtUnaryExpression
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
public abstract class KtCallResolver : KtAnalysisSessionComponent() {
|
||||
public abstract fun resolveAccessorCall(call: KtSimpleNameExpression): KtCall?
|
||||
public abstract fun resolveCall(call: KtCallElement): KtCall?
|
||||
public abstract fun resolveCall(call: KtBinaryExpression): KtCall?
|
||||
public abstract fun resolveCall(call: KtUnaryExpression): KtCall?
|
||||
@@ -19,6 +17,14 @@ public abstract class KtCallResolver : KtAnalysisSessionComponent() {
|
||||
}
|
||||
|
||||
public interface KtCallResolverMixIn : KtAnalysisSessionMixIn {
|
||||
/**
|
||||
* Resolves the given simple name expression to an accessor call if that name refers to a property.
|
||||
*
|
||||
* This spans both Kotlin property and synthetic Java property.
|
||||
*/
|
||||
public fun KtSimpleNameExpression.resolveAccessorCall(): KtCall? =
|
||||
analysisSession.callResolver.resolveAccessorCall(this)
|
||||
|
||||
public fun KtCallElement.resolveCall(): KtCall? =
|
||||
analysisSession.callResolver.resolveCall(this)
|
||||
|
||||
|
||||
+2
-5
@@ -7,18 +7,15 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
|
||||
public sealed class KtPropertyAccessorSymbol : KtCallableSymbol(),
|
||||
public sealed class KtPropertyAccessorSymbol : KtFunctionLikeSymbol(),
|
||||
KtPossibleMemberSymbol,
|
||||
KtSymbolWithModality,
|
||||
KtSymbolWithVisibility,
|
||||
KtAnnotatedSymbol,
|
||||
KtSymbolWithKind {
|
||||
|
||||
final override val callableIdIfNonLocal: CallableId? get() = null
|
||||
final override val isExtension: Boolean get() = false
|
||||
final override val receiverType: KtTypeAndAnnotations? get() = null
|
||||
|
||||
public abstract val isDefault: Boolean
|
||||
public abstract val isInline: Boolean
|
||||
@@ -38,4 +35,4 @@ public abstract class KtPropertySetterSymbol : KtPropertyAccessorSymbol() {
|
||||
public abstract val parameter: KtValueParameterSymbol
|
||||
|
||||
abstract override fun createPointer(): KtSymbolPointer<KtPropertySetterSymbol>
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -200,6 +200,7 @@ internal class KtSymbolByFirBuilder private constructor(
|
||||
}
|
||||
is FirConstructor -> buildConstructorSymbol(fir)
|
||||
is FirAnonymousFunction -> buildAnonymousFunctionSymbol(fir)
|
||||
is FirPropertyAccessor -> buildPropertyAccessorSymbol(fir)
|
||||
else -> throwUnexpectedElementError(fir)
|
||||
}
|
||||
}
|
||||
@@ -224,6 +225,16 @@ internal class KtSymbolByFirBuilder private constructor(
|
||||
check(fir.origin == FirDeclarationOrigin.SamConstructor)
|
||||
return symbolsCache.cache(fir) { KtFirSamConstructorSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder) }
|
||||
}
|
||||
|
||||
fun buildPropertyAccessorSymbol(fir: FirPropertyAccessor): KtFunctionLikeSymbol {
|
||||
return symbolsCache.cache(fir) {
|
||||
if (fir.isGetter) {
|
||||
KtFirPropertyGetterSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder)
|
||||
} else {
|
||||
KtFirPropertySetterSymbol(fir, resolveState, token, this@KtSymbolByFirBuilder)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class VariableLikeSymbolBuilder {
|
||||
|
||||
+34
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirErrorReferenceWithCandidate
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
|
||||
import org.jetbrains.kotlin.fir.types.classId
|
||||
@@ -36,8 +37,10 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithMember
|
||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.withValidityAssertion
|
||||
import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper
|
||||
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.findAssignment
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -47,6 +50,37 @@ internal class KtFirCallResolver(
|
||||
) : KtCallResolver(), KtFirAnalysisSessionComponent {
|
||||
private val diagnosticCache = mutableListOf<FirDiagnostic>()
|
||||
|
||||
override fun resolveAccessorCall(call: KtSimpleNameExpression): KtCall? = withValidityAssertion {
|
||||
when (val fir = call.getOrBuildFir(firResolveState)) {
|
||||
is FirResolvedNamedReference -> {
|
||||
val propertySymbol = fir.resolvedSymbol as? FirPropertySymbol ?: return null
|
||||
val access = call.readWriteAccess(useResolveForReadWrite = false)
|
||||
val setterValue = findAssignment(call)?.right
|
||||
val accessor = when {
|
||||
access.isWrite -> propertySymbol.setterSymbol?.fir
|
||||
access.isRead -> propertySymbol.getterSymbol?.fir
|
||||
else -> null
|
||||
} ?: return null
|
||||
val accessorSymbol = analysisSession.firSymbolBuilder.functionLikeBuilder.buildFunctionLikeSymbol(accessor)
|
||||
val target =
|
||||
if (!access.isWrite || setterValue != null)
|
||||
KtSuccessCallTarget(accessorSymbol)
|
||||
else // access.isWrite && setterValue == null
|
||||
KtErrorCallTarget(
|
||||
listOf(accessorSymbol),
|
||||
KtNonBoundToPsiErrorDiagnostic(factoryName = null, "Setter value is missing", token)
|
||||
)
|
||||
val ktArgumentMapping = LinkedHashMap<KtExpression, KtValueParameterSymbol>()
|
||||
if (access.isWrite && setterValue != null) {
|
||||
val setterParameterSymbol = accessor.valueParameters.single().buildSymbol(firSymbolBuilder) as KtValueParameterSymbol
|
||||
ktArgumentMapping[setterValue] = setterParameterSymbol
|
||||
}
|
||||
return KtFunctionCall(ktArgumentMapping, target)
|
||||
}
|
||||
else -> return null
|
||||
}
|
||||
}
|
||||
|
||||
override fun resolveCall(call: KtBinaryExpression): KtCall? = withValidityAssertion {
|
||||
when (val fir = call.getOrBuildFir(firResolveState)) {
|
||||
is FirFunctionCall -> resolveCall(fir)
|
||||
|
||||
+23
@@ -11,8 +11,10 @@ import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
|
||||
import org.jetbrains.kotlin.fir.resolve.getHasStableParameterNames
|
||||
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
|
||||
@@ -23,12 +25,14 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
|
||||
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.KtValueParameterSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotationCall
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtTypeAndAnnotations
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
|
||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
internal class KtFirPropertyGetterSymbol(
|
||||
@@ -59,10 +63,29 @@ internal class KtFirPropertyGetterSymbol(
|
||||
override fun containsAnnotation(classId: ClassId): Boolean = firRef.containsAnnotation(classId)
|
||||
override val annotationClassIds: Collection<ClassId> by cached { firRef.getAnnotationClassIds() }
|
||||
|
||||
/**
|
||||
* Returns [CallableId] of the delegated Java method if the corresponding property of this getter is a synthetic Java property.
|
||||
* Otherwise, returns `null`
|
||||
*/
|
||||
override val callableIdIfNonLocal: CallableId? by firRef.withFirAndCache { fir ->
|
||||
if (fir is FirSyntheticPropertyAccessor) {
|
||||
fir.delegate.symbol.callableId
|
||||
} else null
|
||||
}
|
||||
|
||||
override val dispatchType: KtType? by cached {
|
||||
firRef.dispatchReceiverTypeAndAnnotations(builder)
|
||||
}
|
||||
|
||||
override val receiverType: KtTypeAndAnnotations? by cached {
|
||||
firRef.receiverTypeAndAnnotations(builder)
|
||||
}
|
||||
|
||||
override val valueParameters: List<KtValueParameterSymbol>
|
||||
get() = emptyList()
|
||||
|
||||
override val hasStableParameterNames: Boolean = firRef.withFir { it.getHasStableParameterNames(it.moduleData.session) }
|
||||
|
||||
override fun createPointer(): KtSymbolPointer<KtPropertyGetterSymbol> {
|
||||
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
|
||||
TODO("Creating pointers for getters from library is not supported yet")
|
||||
|
||||
+21
@@ -11,8 +11,10 @@ import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
|
||||
import org.jetbrains.kotlin.fir.resolve.getHasStableParameterNames
|
||||
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
|
||||
@@ -30,6 +32,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolP
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
|
||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
internal class KtFirPropertySetterSymbol(
|
||||
@@ -58,10 +61,22 @@ internal class KtFirPropertySetterSymbol(
|
||||
override fun containsAnnotation(classId: ClassId): Boolean = firRef.containsAnnotation(classId)
|
||||
override val annotationClassIds: Collection<ClassId> by cached { firRef.getAnnotationClassIds() }
|
||||
|
||||
/**
|
||||
* Returns [CallableId] of the delegated Java method if the corresponding property of this setter is a synthetic Java property.
|
||||
* Otherwise, returns `null`
|
||||
*/
|
||||
override val callableIdIfNonLocal: CallableId? by firRef.withFirAndCache { fir ->
|
||||
if (fir is FirSyntheticPropertyAccessor) {
|
||||
fir.delegate.symbol.callableId
|
||||
} else null
|
||||
}
|
||||
|
||||
override val parameter: KtValueParameterSymbol by firRef.withFirAndCache { fir ->
|
||||
builder.variableLikeBuilder.buildValueParameterSymbol(fir.valueParameters.single())
|
||||
}
|
||||
|
||||
override val valueParameters: List<KtValueParameterSymbol> by cached { listOf(parameter) }
|
||||
|
||||
override val annotatedType: KtTypeAndAnnotations by cached {
|
||||
firRef.returnTypeAndAnnotations(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE, builder)
|
||||
}
|
||||
@@ -70,6 +85,12 @@ internal class KtFirPropertySetterSymbol(
|
||||
firRef.dispatchReceiverTypeAndAnnotations(builder)
|
||||
}
|
||||
|
||||
override val receiverType: KtTypeAndAnnotations? by cached {
|
||||
firRef.receiverTypeAndAnnotations(builder)
|
||||
}
|
||||
|
||||
override val hasStableParameterNames: Boolean = firRef.withFir { it.getHasStableParameterNames(it.moduleData.session) }
|
||||
|
||||
override fun createPointer(): KtSymbolPointer<KtPropertySetterSymbol> {
|
||||
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
|
||||
TODO("Creating pointers for setters from library is not supported yet")
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// FILE: call.kt
|
||||
fun call() {
|
||||
val javaClass = JavaClass()
|
||||
javaClass.<expr>foo</expr>
|
||||
}
|
||||
|
||||
// FILE: JavaClass.java
|
||||
class JavaClass {
|
||||
int getFoo() { return 42; }
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
KtFunctionCall:
|
||||
argumentMapping = { }
|
||||
targetFunction = /JavaClass.getFoo(): kotlin.Int
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// FILE: call.kt
|
||||
fun call() {
|
||||
val javaClass = JavaClass()
|
||||
javaClass.<expr>sub</expr>.foo = 42
|
||||
}
|
||||
|
||||
// FILE: JavaClass.java
|
||||
class JavaClass {
|
||||
private JavaSubClass instance = new JavaSubClass();
|
||||
JavaSubClass getSub() { return instance; }
|
||||
}
|
||||
|
||||
// FILE: JavaSubClass.java
|
||||
class JavaSubClass {
|
||||
private int foo = -1;
|
||||
int getFoo() { return foo; }
|
||||
void setFoo(int v) { foo = v; }
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
KtFunctionCall:
|
||||
argumentMapping = { }
|
||||
targetFunction = /JavaClass.getSub(): ft<JavaSubClass, JavaSubClass?>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// FILE: call.kt
|
||||
fun call() {
|
||||
val javaClass = JavaClass()
|
||||
javaClass.<expr>foo</expr> = 42
|
||||
}
|
||||
|
||||
// FILE: JavaClass.java
|
||||
class JavaClass {
|
||||
private int foo = -1;
|
||||
int getFoo() { return foo; }
|
||||
void setFoo(int v) { foo = v; }
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
KtFunctionCall:
|
||||
argumentMapping = { 42 -> (v: kotlin.Int) }
|
||||
targetFunction = /JavaClass.setFoo(v: kotlin.Int): kotlin.Unit
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
// FILE: call.kt
|
||||
fun call() {
|
||||
val javaClass = JavaClass()
|
||||
// Intentionally incomplete to see if `foo` refers to `setFoo`.
|
||||
javaClass.<expr>foo</expr> =
|
||||
}
|
||||
|
||||
// FILE: JavaClass.java
|
||||
class JavaClass {
|
||||
private int foo = -1;
|
||||
int getFoo() { return foo; }
|
||||
void setFoo(int v) { foo = v; }
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
KtFunctionCall:
|
||||
argumentMapping = { }
|
||||
targetFunction = ERR<Setter value is missing, [/JavaClass.setFoo(v: kotlin.Int): kotlin.Unit]>
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fun call {
|
||||
val ktClass = KtClass()
|
||||
ktClass.<expr>foo</expr>
|
||||
}
|
||||
|
||||
class KtClass {
|
||||
val foo: Int
|
||||
get() = 42
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
KtFunctionCall:
|
||||
argumentMapping = { }
|
||||
targetFunction = <getter>(): kotlin.Int
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
fun call() {
|
||||
val ktClass = KtClass()
|
||||
ktClass.<expr>instance</expr>.foo = 42
|
||||
}
|
||||
|
||||
|
||||
class KtClass {
|
||||
val instance : KtSubClass = KtSubClass()
|
||||
}
|
||||
|
||||
class KtSubClass {
|
||||
var foo : Int = -1
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
KtFunctionCall:
|
||||
argumentMapping = { }
|
||||
targetFunction = <getter>(): KtSubClass
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fun call {
|
||||
val ktClass = KtClass()
|
||||
ktClass.<expr>foo</expr> = 42
|
||||
}
|
||||
|
||||
class KtClass {
|
||||
var foo : Int = -1
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
KtFunctionCall:
|
||||
argumentMapping = { 42 -> (value: kotlin.Int) }
|
||||
targetFunction = <setter>(value: kotlin.Int): kotlin.Unit
|
||||
@@ -39,6 +39,7 @@ KtFirPropertyGetterSymbol:
|
||||
callableIdIfNonLocal: null
|
||||
dispatchType: null
|
||||
hasBody: true
|
||||
hasStableParameterNames: true
|
||||
isDefault: false
|
||||
isExtension: false
|
||||
isInline: false
|
||||
@@ -47,6 +48,7 @@ KtFirPropertyGetterSymbol:
|
||||
origin: SOURCE
|
||||
receiverType: null
|
||||
symbolKind: ACCESSOR
|
||||
valueParameters: []
|
||||
visibility: Public
|
||||
deprecationStatus: null
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ KtFirPropertyGetterSymbol:
|
||||
callableIdIfNonLocal: null
|
||||
dispatchType: null
|
||||
hasBody: true
|
||||
hasStableParameterNames: true
|
||||
isDefault: false
|
||||
isExtension: false
|
||||
isInline: false
|
||||
@@ -57,6 +58,7 @@ KtFirPropertyGetterSymbol:
|
||||
origin: SOURCE
|
||||
receiverType: null
|
||||
symbolKind: ACCESSOR
|
||||
valueParameters: []
|
||||
visibility: Public
|
||||
deprecationStatus: null
|
||||
|
||||
@@ -86,6 +88,7 @@ KtFirPropertySetterSymbol:
|
||||
callableIdIfNonLocal: null
|
||||
dispatchType: null
|
||||
hasBody: true
|
||||
hasStableParameterNames: true
|
||||
isDefault: false
|
||||
isExtension: false
|
||||
isInline: false
|
||||
@@ -95,6 +98,9 @@ KtFirPropertySetterSymbol:
|
||||
parameter: KtFirValueParameterSymbol(value)
|
||||
receiverType: null
|
||||
symbolKind: ACCESSOR
|
||||
valueParameters: [
|
||||
KtFirValueParameterSymbol(value)
|
||||
]
|
||||
visibility: Public
|
||||
deprecationStatus: null
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ KtFirPropertyGetterSymbol:
|
||||
callableIdIfNonLocal: null
|
||||
dispatchType: null
|
||||
hasBody: true
|
||||
hasStableParameterNames: true
|
||||
isDefault: false
|
||||
isExtension: false
|
||||
isInline: false
|
||||
@@ -44,6 +45,7 @@ KtFirPropertyGetterSymbol:
|
||||
origin: SOURCE
|
||||
receiverType: null
|
||||
symbolKind: ACCESSOR
|
||||
valueParameters: []
|
||||
visibility: Public
|
||||
deprecationStatus: null
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ KtFirPropertyGetterSymbol:
|
||||
callableIdIfNonLocal: null
|
||||
dispatchType: null
|
||||
hasBody: true
|
||||
hasStableParameterNames: true
|
||||
isDefault: false
|
||||
isExtension: false
|
||||
isInline: false
|
||||
@@ -44,6 +45,7 @@ KtFirPropertyGetterSymbol:
|
||||
origin: SOURCE
|
||||
receiverType: null
|
||||
symbolKind: ACCESSOR
|
||||
valueParameters: []
|
||||
visibility: Public
|
||||
deprecationStatus: null
|
||||
|
||||
|
||||
+11
-4
@@ -15,9 +15,7 @@ import org.jetbrains.kotlin.idea.frontend.api.calls.KtCall
|
||||
import org.jetbrains.kotlin.idea.frontend.api.calls.KtDelegatedConstructorCallKind
|
||||
import org.jetbrains.kotlin.idea.frontend.api.calls.KtErrorCallTarget
|
||||
import org.jetbrains.kotlin.idea.frontend.api.calls.KtSuccessCallTarget
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtValueParameterSymbol
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
@@ -46,6 +44,7 @@ abstract class AbstractResolveCallTest : AbstractHLApiSingleModuleTest() {
|
||||
is KtBinaryExpression -> element.resolveCall()
|
||||
is KtUnaryExpression -> element.resolveCall()
|
||||
is KtArrayAccessExpression -> element.resolveCall()
|
||||
is KtSimpleNameExpression -> element.resolveAccessorCall()
|
||||
is KtValueArgument -> resolveCall(element.getArgumentExpression()!!)
|
||||
else -> error("Selected element type (${element::class.simpleName}) is not supported for resolveCall()")
|
||||
}
|
||||
@@ -56,7 +55,15 @@ private fun KtCall.stringRepresentation(): String {
|
||||
fun KtType.render() = asStringForDebugging().replace('/', '.')
|
||||
fun Any.stringValue(): String = when (this) {
|
||||
is KtFunctionLikeSymbol -> buildString {
|
||||
append(if (this@stringValue is KtFunctionSymbol) callableIdIfNonLocal ?: name else "<constructor>")
|
||||
append(
|
||||
when (this@stringValue) {
|
||||
is KtFunctionSymbol -> callableIdIfNonLocal ?: name
|
||||
is KtConstructorSymbol -> "<constructor>"
|
||||
is KtPropertyGetterSymbol -> callableIdIfNonLocal ?: "<getter>"
|
||||
is KtPropertySetterSymbol -> callableIdIfNonLocal ?: "<setter>"
|
||||
else -> error("unexpected symbol kind in KtCall: ${this@stringValue::class.java}")
|
||||
}
|
||||
)
|
||||
append("(")
|
||||
(this@stringValue as? KtFunctionSymbol)?.receiverType?.let { receiver ->
|
||||
append("<receiver>: ${receiver.type.render()}")
|
||||
|
||||
+42
@@ -156,6 +156,48 @@ public class ResolveCallTestGenerated extends AbstractResolveCallTest {
|
||||
runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/javaFunctionCall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("javaPropertyGetter.kt")
|
||||
public void testJavaPropertyGetter() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/javaPropertyGetter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("javaPropertyNestedGetter.kt")
|
||||
public void testJavaPropertyNestedGetter() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/javaPropertyNestedGetter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("javaPropertySetter.kt")
|
||||
public void testJavaPropertySetter() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/javaPropertySetter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("javaPropertySetterIncomplete.kt")
|
||||
public void testJavaPropertySetterIncomplete() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/javaPropertySetterIncomplete.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kotlinPropertyGetter.kt")
|
||||
public void testKotlinPropertyGetter() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/kotlinPropertyGetter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kotlinPropertyNestedGetter.kt")
|
||||
public void testKotlinPropertyNestedGetter() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/kotlinPropertyNestedGetter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kotlinPropertySetter.kt")
|
||||
public void testKotlinPropertySetter() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/kotlinPropertySetter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveCallInSuperConstructorParam.kt")
|
||||
public void testResolveCallInSuperConstructorParam() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user