[FIR] Add session parameter to all "element --> reference" utilities
`FirDeserializedEnumAccessExpression` requires session to build proper reference, so it's important to have it in all utilities, which may pass this element as input ^KT-64975
This commit is contained in:
committed by
Space Team
parent
bd9cb2b7e0
commit
150ff1172e
@@ -6,36 +6,106 @@
|
||||
package org.jetbrains.kotlin.fir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.references.FirReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.resolved
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
|
||||
fun FirElement.toReference(): FirReference? {
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
|
||||
annotation class UnsafeExpressionUtility
|
||||
|
||||
/**
|
||||
* Returns the [FirReference] of this [FirElement], if available.
|
||||
* The reference is resolved in the context of a use-site [session], which may be required to find a symbol for an ID-based expression.
|
||||
*/
|
||||
fun FirElement.toReference(session: FirSession): FirReference? {
|
||||
return when (this) {
|
||||
is FirExpression -> toReference()
|
||||
is FirExpression -> toReferenceImpl(session)
|
||||
is FirVariableAssignment -> calleeReference
|
||||
is FirResolvable -> calleeReference
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun FirExpression.toReference(): FirReference? {
|
||||
/**
|
||||
* Returns the [FirReference] of this [FirExpression], if available.
|
||||
* The reference is resolved in the context of a use-site [session], which may be required to find a symbol for an ID-based expression.
|
||||
*/
|
||||
fun FirExpression.toReference(session: FirSession): FirReference? {
|
||||
return toReferenceImpl(session)
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility won't return proper reference for `FirEnumEntryDeserializedAccessExpression`,
|
||||
* so use only if you are really sure that it be never called on this node
|
||||
*
|
||||
* In most cases it's better to use safe [toReference] methods with session parameter.
|
||||
*/
|
||||
@UnsafeExpressionUtility
|
||||
fun FirExpression.toReferenceUnsafe(): FirReference? {
|
||||
return toReferenceImpl(session = null)
|
||||
}
|
||||
|
||||
private fun FirExpression.toReferenceImpl(session: FirSession?): FirReference? {
|
||||
return when (this) {
|
||||
is FirWrappedArgumentExpression -> expression.toResolvedCallableReference()
|
||||
is FirSmartCastExpression -> originalExpression.toReference()
|
||||
is FirDesugaredAssignmentValueReferenceExpression -> expressionRef.value.toReference()
|
||||
is FirWrappedArgumentExpression -> expression.toResolvedCallableReferenceImpl(session)
|
||||
is FirSmartCastExpression -> originalExpression.toReferenceImpl(session)
|
||||
is FirDesugaredAssignmentValueReferenceExpression -> expressionRef.value.toReferenceImpl(session)
|
||||
is FirResolvable -> calleeReference
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
val FirVariableAssignment.calleeReference: FirReference? get() = lValue.toReference()
|
||||
val FirVariableAssignment.calleeReference: FirReference?
|
||||
get() {
|
||||
// non-nullable session for `toReferenceImpl` is needed only for `FirEnumEntryDeserializedAccessExpression` value,
|
||||
// which never can appear in the lhs of variable assignment
|
||||
return lValue.toReferenceImpl(session = null)
|
||||
}
|
||||
|
||||
fun FirExpression.toResolvedCallableReference(): FirResolvedNamedReference? {
|
||||
return toReference()?.resolved
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
|
||||
fun FirExpression.toResolvedCallableReference(session: FirSession): FirResolvedNamedReference? {
|
||||
return toResolvedCallableReferenceImpl(session)
|
||||
}
|
||||
|
||||
fun FirExpression.toResolvedCallableSymbol(): FirCallableSymbol<*>? {
|
||||
return toResolvedCallableReference()?.resolvedSymbol as? FirCallableSymbol<*>?
|
||||
fun FirResolvable.toResolvedCallableReference(): FirResolvedNamedReference? {
|
||||
return calleeReference.resolved
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility won't return proper reference for `FirEnumEntryDeserializedAccessExpression`,
|
||||
* so use only if you are really sure that it be never called on this node
|
||||
*
|
||||
* In most cases it's better to use safe [toResolvedCallableReference] methods with session parameter
|
||||
*/
|
||||
@UnsafeExpressionUtility
|
||||
fun FirExpression.toResolvedCallableReferenceUnsafe(): FirResolvedNamedReference? {
|
||||
return toResolvedCallableReferenceImpl(session = null)
|
||||
}
|
||||
|
||||
fun FirExpression.toResolvedCallableReferenceImpl(session: FirSession?): FirResolvedNamedReference? {
|
||||
return toReferenceImpl(session)?.resolved
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------
|
||||
|
||||
fun FirExpression.toResolvedCallableSymbol(session: FirSession): FirCallableSymbol<*>? {
|
||||
return toResolvedCallableReference(session)?.resolvedSymbol as? FirCallableSymbol<*>?
|
||||
}
|
||||
|
||||
fun FirResolvable.toResolvedCallableSymbol(): FirCallableSymbol<*>? {
|
||||
return toResolvedCallableReference()?.resolvedSymbol as? FirCallableSymbol<*>
|
||||
}
|
||||
|
||||
/**
|
||||
* This utility won't return proper reference for `FirEnumEntryDeserializedAccessExpression`,
|
||||
* so use only if you are really sure that it be never called on this node
|
||||
*
|
||||
* In most cases it's better to use safe [toResolvedCallableSymbol] methods with session parameter
|
||||
*/
|
||||
@UnsafeExpressionUtility
|
||||
fun FirExpression.toResolvedCallableSymbolUnsafe(): FirCallableSymbol<*>? {
|
||||
return toResolvedCallableReferenceUnsafe()?.resolvedSymbol as? FirCallableSymbol<*>?
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user