FIR: Optimize usages of containingClass and its implementation
This commit is contained in:
@@ -12,9 +12,9 @@ import org.jetbrains.kotlin.fir.FirVisibilityChecker
|
||||
import org.jetbrains.kotlin.fir.NoMutableState
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.getOwnerId
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
@NoMutableState
|
||||
object FirJavaVisibilityChecker : FirVisibilityChecker() {
|
||||
@@ -22,7 +22,6 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
|
||||
declarationVisibility: Visibility,
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
useSiteFile: FirFile,
|
||||
ownerId: ClassId?,
|
||||
containingDeclarations: List<FirDeclaration>,
|
||||
candidate: Candidate,
|
||||
session: FirSession
|
||||
@@ -32,6 +31,7 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
|
||||
if (symbol.packageFqName() == useSiteFile.packageFqName) {
|
||||
true
|
||||
} else {
|
||||
val ownerId = symbol.getOwnerId()
|
||||
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, candidate.dispatchReceiverValue, ownerId, session)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
||||
declarationVisibility: Visibility,
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
useSiteFile: FirFile,
|
||||
ownerId: ClassId?,
|
||||
containingDeclarations: List<FirDeclaration>,
|
||||
candidate: Candidate,
|
||||
session: FirSession
|
||||
@@ -55,13 +54,14 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
||||
val containingDeclarations = callInfo.containingDeclarations
|
||||
val session = callInfo.session
|
||||
val provider = session.firProvider
|
||||
val ownerId = symbol.getOwnerId()
|
||||
|
||||
|
||||
return when (declaration.visibility) {
|
||||
Visibilities.Internal -> {
|
||||
declaration.session == callInfo.session
|
||||
}
|
||||
Visibilities.Private, Visibilities.PrivateToThis -> {
|
||||
val ownerId = symbol.getOwnerId()
|
||||
if (declaration.session == callInfo.session) {
|
||||
if (ownerId == null || declaration is FirConstructor && declaration.isFromSealedClass) {
|
||||
val candidateFile = when (symbol) {
|
||||
@@ -81,6 +81,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
||||
}
|
||||
|
||||
Visibilities.Protected -> {
|
||||
val ownerId = symbol.getOwnerId()
|
||||
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, candidate.dispatchReceiverValue, ownerId, session)
|
||||
}
|
||||
|
||||
@@ -88,7 +89,6 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
||||
declaration.visibility,
|
||||
symbol,
|
||||
useSiteFile,
|
||||
ownerId,
|
||||
containingDeclarations,
|
||||
candidate,
|
||||
session
|
||||
@@ -100,7 +100,6 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
||||
declarationVisibility: Visibility,
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
useSiteFile: FirFile,
|
||||
ownerId: ClassId?,
|
||||
containingDeclarations: List<FirDeclaration>,
|
||||
candidate: Candidate,
|
||||
session: FirSession
|
||||
@@ -171,23 +170,6 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
||||
(name == "monitorEnter" || name == "monitorExit")
|
||||
}
|
||||
|
||||
private fun AbstractFirBasedSymbol<*>.getOwnerId(): ClassId? {
|
||||
return when (this) {
|
||||
is FirClassLikeSymbol<*> -> {
|
||||
val ownerId = classId.outerClassId
|
||||
if (classId.isLocal) {
|
||||
ownerId?.asLocal() ?: classId
|
||||
} else {
|
||||
ownerId
|
||||
}
|
||||
}
|
||||
is FirCallableSymbol<*> -> containingClass()?.classId
|
||||
else -> error("Unsupported owner search for ${fir.javaClass}: ${fir.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassId.asLocal(): ClassId = ClassId(packageFqName, relativeClassName, true)
|
||||
|
||||
protected fun canSeeProtectedMemberOf(
|
||||
containingDeclarationOfUseSite: List<FirDeclaration>,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
@@ -214,3 +196,20 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
||||
}
|
||||
|
||||
val FirSession.visibilityChecker: FirVisibilityChecker by FirSession.sessionComponentAccessor()
|
||||
|
||||
fun AbstractFirBasedSymbol<*>.getOwnerId(): ClassId? {
|
||||
return when (this) {
|
||||
is FirClassLikeSymbol<*> -> {
|
||||
val ownerId = classId.outerClassId
|
||||
if (classId.isLocal) {
|
||||
ownerId?.asLocal() ?: classId
|
||||
} else {
|
||||
ownerId
|
||||
}
|
||||
}
|
||||
is FirCallableSymbol<*> -> containingClass()?.classId
|
||||
else -> error("Unsupported owner search for ${fir.javaClass}: ${fir.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassId.asLocal(): ClassId = ClassId(packageFqName, relativeClassName, true)
|
||||
|
||||
+2
-1
@@ -189,7 +189,6 @@ class ScopeTowerLevel(
|
||||
}
|
||||
|
||||
private fun dispatchReceiverValue(candidate: FirCallableSymbol<*>): ReceiverValue? {
|
||||
val lookupTag = candidate.dispatchReceiverClassOrNull()
|
||||
candidate.fir.importedFromObjectClassId?.let { objectClassId ->
|
||||
val symbol = session.firSymbolProvider.getClassLikeSymbolByFqName(objectClassId)
|
||||
if (symbol is FirRegularClassSymbol) {
|
||||
@@ -203,6 +202,8 @@ class ScopeTowerLevel(
|
||||
return ExpressionReceiverValue(resolvedQualifier)
|
||||
}
|
||||
}
|
||||
|
||||
val lookupTag = candidate.dispatchReceiverClassOrNull()
|
||||
return when {
|
||||
candidate !is FirBackingFieldSymbol -> null
|
||||
lookupTag != null -> {
|
||||
|
||||
@@ -19,7 +19,7 @@ fun FirCallableSymbol<*>.dispatchReceiverClassOrNull(): ConeClassLikeLookupTag?
|
||||
|
||||
fun FirCallableDeclaration<*>.dispatchReceiverClassOrNull(): ConeClassLikeLookupTag? {
|
||||
if (this !is FirCallableMemberDeclaration<*>) return null
|
||||
if (symbol.isIntersectionOverride && dispatchReceiverType is ConeIntersectionType) return symbol.overriddenSymbol!!.fir.dispatchReceiverClassOrNull()
|
||||
if (dispatchReceiverType is ConeIntersectionType && symbol.isIntersectionOverride) return symbol.overriddenSymbol!!.fir.dispatchReceiverClassOrNull()
|
||||
|
||||
return (dispatchReceiverType as? ConeClassLikeType)?.lookupTag
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user