FIR LL: fix resolving proerties in library

Property can be overloaded with different extension receiver type.
This commit is contained in:
Tianyu Geng
2021-10-15 16:31:22 -07:00
committed by Ilya Kirillov
parent b03c9b6fc6
commit 5a1680ca3b
2 changed files with 20 additions and 19 deletions
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.builder.BodyBuildingMode import org.jetbrains.kotlin.fir.builder.BodyBuildingMode
import org.jetbrains.kotlin.fir.builder.PsiHandlingMode import org.jetbrains.kotlin.fir.builder.PsiHandlingMode
import org.jetbrains.kotlin.fir.builder.RawFirBuilder import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.ScopeSession
@@ -20,13 +21,14 @@ import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtTypeReference import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
// TODO replace with structural type comparison? // TODO replace with structural type comparison?
object KtDeclarationAndFirDeclarationEqualityChecker { object KtDeclarationAndFirDeclarationEqualityChecker {
fun representsTheSameDeclaration(psi: KtFunction, fir: FirFunction): Boolean { fun representsTheSameDeclaration(psi: KtCallableDeclaration, fir: FirCallableDeclaration): Boolean {
if ((fir.receiverTypeRef != null) != (psi.receiverTypeReference != null)) return false if ((fir.receiverTypeRef != null) != (psi.receiverTypeReference != null)) return false
if (fir.receiverTypeRef != null if (fir.receiverTypeRef != null
&& !isTheSameTypes( && !isTheSameTypes(
@@ -37,18 +39,20 @@ object KtDeclarationAndFirDeclarationEqualityChecker {
) { ) {
return false return false
} }
if (fir.valueParameters.size != psi.valueParameters.size) return false if (fir is FirFunction) {
fir.valueParameters.zip(psi.valueParameters) { expectedParameter, candidateParameter -> if (fir.valueParameters.size != psi.valueParameters.size) return false
if (expectedParameter.name.toString() != candidateParameter.name) return false fir.valueParameters.zip(psi.valueParameters) { expectedParameter, candidateParameter ->
if (expectedParameter.isVararg != candidateParameter.isVarArg) return false if (expectedParameter.name.toString() != candidateParameter.name) return false
val candidateParameterType = candidateParameter.typeReference ?: return false if (expectedParameter.isVararg != candidateParameter.isVarArg) return false
if (!isTheSameTypes( val candidateParameterType = candidateParameter.typeReference ?: return false
candidateParameterType, if (!isTheSameTypes(
expectedParameter.returnTypeRef, candidateParameterType,
isVararg = expectedParameter.isVararg expectedParameter.returnTypeRef,
) isVararg = expectedParameter.isVararg
) { )
return false ) {
return false
}
} }
} }
return true return true
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.util package org.jetbrains.kotlin.analysis.low.level.api.fir.util
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.KtDeclarationAndFirDeclarationEqualityChecker
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirFunction
@@ -16,7 +17,6 @@ import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.KtDeclarationAndFirDeclarationEqualityChecker
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
@@ -56,7 +56,7 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
val functionCandidate = val functionCandidate =
symbolProvider.findFunctionCandidates(declaration) symbolProvider.findFunctionCandidates(declaration)
.singleOrNull { representSameFunction(declaration, it.fir) } .singleOrNull { KtDeclarationAndFirDeclarationEqualityChecker.representsTheSameDeclaration(declaration, it.fir) }
?: error("We should be able to find a symbol for function ${declaration.name}: ${declaration.getElementTextInContext()}") ?: error("We should be able to find a symbol for function ${declaration.name}: ${declaration.getElementTextInContext()}")
return functionCandidate.fir return functionCandidate.fir
@@ -67,7 +67,7 @@ internal class FirDeclarationForCompiledElementSearcher(private val symbolProvid
val propertyCandidate = val propertyCandidate =
symbolProvider.findPropertyCandidates(declaration) symbolProvider.findPropertyCandidates(declaration)
.singleOrNull() .singleOrNull { KtDeclarationAndFirDeclarationEqualityChecker.representsTheSameDeclaration(declaration, it.fir) }
?: error("We should be able to find a symbol for property ${declaration.name}: ${declaration.getElementTextInContext()}") ?: error("We should be able to find a symbol for property ${declaration.name}: ${declaration.getElementTextInContext()}")
return propertyCandidate.fir return propertyCandidate.fir
@@ -96,9 +96,6 @@ private fun FirSymbolProvider.findCallableCandidates(
getClassDeclaredPropertySymbols(containerClassId, declaration.nameAsSafeName) getClassDeclaredPropertySymbols(containerClassId, declaration.nameAsSafeName)
} }
private fun representSameFunction(psiFunction: KtNamedFunction, it: FirFunction): Boolean =
KtDeclarationAndFirDeclarationEqualityChecker.representsTheSameDeclaration(psiFunction, it)
private fun representSameConstructor(psiConstructor: KtConstructor<*>, firConstructor: FirConstructor): Boolean { private fun representSameConstructor(psiConstructor: KtConstructor<*>, firConstructor: FirConstructor): Boolean {
if ((firConstructor.isPrimary) != (psiConstructor is KtPrimaryConstructor)) { if ((firConstructor.isPrimary) != (psiConstructor is KtPrimaryConstructor)) {
return false return false