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.NoMutableState
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
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.resolve.calls.Candidate
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
|
||||||
|
|
||||||
@NoMutableState
|
@NoMutableState
|
||||||
object FirJavaVisibilityChecker : FirVisibilityChecker() {
|
object FirJavaVisibilityChecker : FirVisibilityChecker() {
|
||||||
@@ -22,7 +22,6 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
|
|||||||
declarationVisibility: Visibility,
|
declarationVisibility: Visibility,
|
||||||
symbol: AbstractFirBasedSymbol<*>,
|
symbol: AbstractFirBasedSymbol<*>,
|
||||||
useSiteFile: FirFile,
|
useSiteFile: FirFile,
|
||||||
ownerId: ClassId?,
|
|
||||||
containingDeclarations: List<FirDeclaration>,
|
containingDeclarations: List<FirDeclaration>,
|
||||||
candidate: Candidate,
|
candidate: Candidate,
|
||||||
session: FirSession
|
session: FirSession
|
||||||
@@ -32,6 +31,7 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
|
|||||||
if (symbol.packageFqName() == useSiteFile.packageFqName) {
|
if (symbol.packageFqName() == useSiteFile.packageFqName) {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
val ownerId = symbol.getOwnerId()
|
||||||
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, candidate.dispatchReceiverValue, ownerId, session)
|
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, candidate.dispatchReceiverValue, ownerId, session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
declarationVisibility: Visibility,
|
declarationVisibility: Visibility,
|
||||||
symbol: AbstractFirBasedSymbol<*>,
|
symbol: AbstractFirBasedSymbol<*>,
|
||||||
useSiteFile: FirFile,
|
useSiteFile: FirFile,
|
||||||
ownerId: ClassId?,
|
|
||||||
containingDeclarations: List<FirDeclaration>,
|
containingDeclarations: List<FirDeclaration>,
|
||||||
candidate: Candidate,
|
candidate: Candidate,
|
||||||
session: FirSession
|
session: FirSession
|
||||||
@@ -55,13 +54,14 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
val containingDeclarations = callInfo.containingDeclarations
|
val containingDeclarations = callInfo.containingDeclarations
|
||||||
val session = callInfo.session
|
val session = callInfo.session
|
||||||
val provider = session.firProvider
|
val provider = session.firProvider
|
||||||
val ownerId = symbol.getOwnerId()
|
|
||||||
|
|
||||||
return when (declaration.visibility) {
|
return when (declaration.visibility) {
|
||||||
Visibilities.Internal -> {
|
Visibilities.Internal -> {
|
||||||
declaration.session == callInfo.session
|
declaration.session == callInfo.session
|
||||||
}
|
}
|
||||||
Visibilities.Private, Visibilities.PrivateToThis -> {
|
Visibilities.Private, Visibilities.PrivateToThis -> {
|
||||||
|
val ownerId = symbol.getOwnerId()
|
||||||
if (declaration.session == callInfo.session) {
|
if (declaration.session == callInfo.session) {
|
||||||
if (ownerId == null || declaration is FirConstructor && declaration.isFromSealedClass) {
|
if (ownerId == null || declaration is FirConstructor && declaration.isFromSealedClass) {
|
||||||
val candidateFile = when (symbol) {
|
val candidateFile = when (symbol) {
|
||||||
@@ -81,6 +81,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Visibilities.Protected -> {
|
Visibilities.Protected -> {
|
||||||
|
val ownerId = symbol.getOwnerId()
|
||||||
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, candidate.dispatchReceiverValue, ownerId, session)
|
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, candidate.dispatchReceiverValue, ownerId, session)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +89,6 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
declaration.visibility,
|
declaration.visibility,
|
||||||
symbol,
|
symbol,
|
||||||
useSiteFile,
|
useSiteFile,
|
||||||
ownerId,
|
|
||||||
containingDeclarations,
|
containingDeclarations,
|
||||||
candidate,
|
candidate,
|
||||||
session
|
session
|
||||||
@@ -100,7 +100,6 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
declarationVisibility: Visibility,
|
declarationVisibility: Visibility,
|
||||||
symbol: AbstractFirBasedSymbol<*>,
|
symbol: AbstractFirBasedSymbol<*>,
|
||||||
useSiteFile: FirFile,
|
useSiteFile: FirFile,
|
||||||
ownerId: ClassId?,
|
|
||||||
containingDeclarations: List<FirDeclaration>,
|
containingDeclarations: List<FirDeclaration>,
|
||||||
candidate: Candidate,
|
candidate: Candidate,
|
||||||
session: FirSession
|
session: FirSession
|
||||||
@@ -171,23 +170,6 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
(name == "monitorEnter" || name == "monitorExit")
|
(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(
|
protected fun canSeeProtectedMemberOf(
|
||||||
containingDeclarationOfUseSite: List<FirDeclaration>,
|
containingDeclarationOfUseSite: List<FirDeclaration>,
|
||||||
dispatchReceiver: ReceiverValue?,
|
dispatchReceiver: ReceiverValue?,
|
||||||
@@ -214,3 +196,20 @@ abstract class FirVisibilityChecker : FirSessionComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val FirSession.visibilityChecker: FirVisibilityChecker by FirSession.sessionComponentAccessor()
|
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? {
|
private fun dispatchReceiverValue(candidate: FirCallableSymbol<*>): ReceiverValue? {
|
||||||
val lookupTag = candidate.dispatchReceiverClassOrNull()
|
|
||||||
candidate.fir.importedFromObjectClassId?.let { objectClassId ->
|
candidate.fir.importedFromObjectClassId?.let { objectClassId ->
|
||||||
val symbol = session.firSymbolProvider.getClassLikeSymbolByFqName(objectClassId)
|
val symbol = session.firSymbolProvider.getClassLikeSymbolByFqName(objectClassId)
|
||||||
if (symbol is FirRegularClassSymbol) {
|
if (symbol is FirRegularClassSymbol) {
|
||||||
@@ -203,6 +202,8 @@ class ScopeTowerLevel(
|
|||||||
return ExpressionReceiverValue(resolvedQualifier)
|
return ExpressionReceiverValue(resolvedQualifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val lookupTag = candidate.dispatchReceiverClassOrNull()
|
||||||
return when {
|
return when {
|
||||||
candidate !is FirBackingFieldSymbol -> null
|
candidate !is FirBackingFieldSymbol -> null
|
||||||
lookupTag != null -> {
|
lookupTag != null -> {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ fun FirCallableSymbol<*>.dispatchReceiverClassOrNull(): ConeClassLikeLookupTag?
|
|||||||
|
|
||||||
fun FirCallableDeclaration<*>.dispatchReceiverClassOrNull(): ConeClassLikeLookupTag? {
|
fun FirCallableDeclaration<*>.dispatchReceiverClassOrNull(): ConeClassLikeLookupTag? {
|
||||||
if (this !is FirCallableMemberDeclaration<*>) return null
|
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
|
return (dispatchReceiverType as? ConeClassLikeType)?.lookupTag
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user