KT-60957 [Analysis API] Visit FirPropertyAccessExpressions instead of FirResolvedNamedReferences
It's much easier to analyze complex cases like invoke operator calls using dedicated `FirPropertyAccessExpression`
This commit is contained in:
+17
-25
@@ -404,18 +404,18 @@ private class ElementsToShortenCollector(
|
|||||||
processTypeQualifier(errorResolvedQualifier)
|
processTypeQualifier(errorResolvedQualifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitResolvedNamedReference(resolvedNamedReference: FirResolvedNamedReference) {
|
|
||||||
super.visitResolvedNamedReference(resolvedNamedReference)
|
|
||||||
|
|
||||||
processPropertyReference(resolvedNamedReference)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunctionCall(functionCall: FirFunctionCall) {
|
override fun visitFunctionCall(functionCall: FirFunctionCall) {
|
||||||
super.visitFunctionCall(functionCall)
|
super.visitFunctionCall(functionCall)
|
||||||
|
|
||||||
processFunctionCall(functionCall)
|
processFunctionCall(functionCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitPropertyAccessExpression(propertyAccessExpression: FirPropertyAccessExpression) {
|
||||||
|
super.visitPropertyAccessExpression(propertyAccessExpression)
|
||||||
|
|
||||||
|
processPropertyAccess(propertyAccessExpression)
|
||||||
|
}
|
||||||
|
|
||||||
private fun processTypeRef(resolvedTypeRef: FirResolvedTypeRef) {
|
private fun processTypeRef(resolvedTypeRef: FirResolvedTypeRef) {
|
||||||
val typeElement = resolvedTypeRef.correspondingTypePsi ?: return
|
val typeElement = resolvedTypeRef.correspondingTypePsi ?: return
|
||||||
if (typeElement.referenceExpression?.textRange?.intersects(selection) != true) return
|
if (typeElement.referenceExpression?.textRange?.intersects(selection) != true) return
|
||||||
@@ -984,46 +984,38 @@ private class ElementsToShortenCollector(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processPropertyReference(resolvedNamedReference: FirResolvedNamedReference) {
|
private fun processPropertyAccess(firPropertyAccess: FirPropertyAccessExpression) {
|
||||||
val referenceExpression = resolvedNamedReference.psi as? KtNameReferenceExpression ?: return
|
val propertyReferenceExpression = (firPropertyAccess.psi as? KtDotQualifiedExpression)?.selectorExpression as? KtNameReferenceExpression ?: return
|
||||||
if (!referenceExpression.textRange.intersects(selection)) return
|
if (!propertyReferenceExpression.textRange.intersects(selection)) return
|
||||||
val qualifiedProperty = referenceExpression.getDotQualifiedExpressionForSelector() ?: return
|
|
||||||
|
|
||||||
val callableSymbol = resolvedNamedReference.resolvedSymbol as? FirCallableSymbol<*> ?: return
|
val qualifiedProperty = propertyReferenceExpression.getQualifiedElement() as? KtDotQualifiedExpression ?: return
|
||||||
|
val propertySymbol = firPropertyAccess.referencedSymbol ?: return
|
||||||
|
|
||||||
val option = callableShortenOption(callableSymbol)
|
val option = callableShortenOption(propertySymbol)
|
||||||
if (option == ShortenOption.DO_NOT_SHORTEN) return
|
if (option == ShortenOption.DO_NOT_SHORTEN) return
|
||||||
|
|
||||||
val scopes = shorteningContext.findScopesAtPosition(qualifiedProperty, getNamesToImport(), towerContextProvider) ?: return
|
val scopes = shorteningContext.findScopesAtPosition(qualifiedProperty, getNamesToImport(), towerContextProvider) ?: return
|
||||||
val availableCallables = shorteningContext.findPropertiesInScopes(scopes, callableSymbol.name)
|
val availableCallables = shorteningContext.findPropertiesInScopes(scopes, propertySymbol.name)
|
||||||
|
|
||||||
val firPropertyAccess = qualifiedProperty.getCorrespondingPropertyAccessExpression() ?: return
|
|
||||||
|
|
||||||
// if explicit receiver is a property access or a function call, we cannot shorten it
|
// if explicit receiver is a property access or a function call, we cannot shorten it
|
||||||
if (firPropertyAccess.explicitReceiver !is FirResolvedQualifier) return
|
if (firPropertyAccess.explicitReceiver !is FirResolvedQualifier) return
|
||||||
|
|
||||||
if (availableCallables.isNotEmpty() && shortenIfAlreadyImported(firPropertyAccess, callableSymbol, referenceExpression)) {
|
if (availableCallables.isNotEmpty() && shortenIfAlreadyImported(firPropertyAccess, propertySymbol, qualifiedProperty)) {
|
||||||
addElementToShorten(ShortenQualifier(qualifiedProperty))
|
addElementToShorten(ShortenQualifier(qualifiedProperty))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (option == ShortenOption.SHORTEN_IF_ALREADY_IMPORTED) return
|
if (option == ShortenOption.SHORTEN_IF_ALREADY_IMPORTED) return
|
||||||
|
|
||||||
processCallableQualifiedAccess(
|
processCallableQualifiedAccess(
|
||||||
callableSymbol,
|
propertySymbol,
|
||||||
option,
|
option,
|
||||||
qualifiedProperty,
|
qualifiedProperty,
|
||||||
availableCallables,
|
availableCallables,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtDotQualifiedExpression.getCorrespondingPropertyAccessExpression(): FirPropertyAccessExpression? {
|
private val FirPropertyAccessExpression.referencedSymbol: FirVariableSymbol<*>?
|
||||||
val accessExpression = when (val fir = getOrBuildFir(firResolveSession)) {
|
get() = (calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirVariableSymbol<*>
|
||||||
is FirVariableAssignment -> fir.unwrapLValue()
|
|
||||||
else -> fir
|
|
||||||
}
|
|
||||||
|
|
||||||
return accessExpression as? FirPropertyAccessExpression
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun processFunctionCall(functionCall: FirFunctionCall) {
|
private fun processFunctionCall(functionCall: FirFunctionCall) {
|
||||||
if (!canBePossibleToDropReceiver(functionCall)) return
|
if (!canBePossibleToDropReceiver(functionCall)) return
|
||||||
|
|||||||
Reference in New Issue
Block a user