[FIR] Add FirVisibilityChecker session component
This is needed because we have different visibility rules for different platform visibilities (e.g. protected and package private on JVM), so we need ability to configure visibility checks for different platforms
This commit is contained in:
@@ -39,6 +39,7 @@ class FirJavaModuleBasedSession private constructor(
|
||||
registerResolveComponents()
|
||||
registerCheckersComponent()
|
||||
registerJvmCallConflictResolverFactory()
|
||||
registerJavaVisibilityChecker()
|
||||
|
||||
val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.java
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirVisibilityChecker
|
||||
import org.jetbrains.kotlin.fir.JavaVisibilities
|
||||
import org.jetbrains.kotlin.fir.Visibility
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
object FirJavaVisibilityChecker : FirVisibilityChecker() {
|
||||
override fun platformVisibilityCheck(
|
||||
declarationVisibility: Visibility,
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
useSiteFile: FirFile,
|
||||
ownerId: ClassId?,
|
||||
containingDeclarations: List<FirDeclaration>,
|
||||
candidate: Candidate,
|
||||
session: FirSession
|
||||
): Boolean {
|
||||
return when (declarationVisibility) {
|
||||
JavaVisibilities.ProtectedAndPackage, JavaVisibilities.ProtectedStaticVisibility -> {
|
||||
if (symbol.packageFqName() == useSiteFile.packageFqName) {
|
||||
true
|
||||
} else {
|
||||
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, candidate.dispatchReceiverValue, ownerId, session)
|
||||
}
|
||||
}
|
||||
|
||||
JavaVisibilities.PackageVisibility -> {
|
||||
symbol.packageFqName() == useSiteFile.packageFqName
|
||||
}
|
||||
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun FirSession.registerJavaVisibilityChecker() {
|
||||
register(FirVisibilityChecker::class, FirJavaVisibilityChecker)
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
abstract class FirVisibilityChecker : FirSessionComponent {
|
||||
object Default : FirVisibilityChecker() {
|
||||
override fun platformVisibilityCheck(
|
||||
declarationVisibility: Visibility,
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
useSiteFile: FirFile,
|
||||
ownerId: ClassId?,
|
||||
containingDeclarations: List<FirDeclaration>,
|
||||
candidate: Candidate,
|
||||
session: FirSession
|
||||
): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
fun isVisible(
|
||||
declaration: FirMemberDeclaration,
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
candidate: Candidate
|
||||
): Boolean {
|
||||
val callInfo = candidate.callInfo
|
||||
val useSiteFile = callInfo.containingFile
|
||||
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 -> {
|
||||
if (declaration.session == callInfo.session) {
|
||||
if (ownerId == null || declaration is FirConstructor && declaration.isFromSealedClass) {
|
||||
val candidateFile = when (symbol) {
|
||||
is FirClassLikeSymbol<*> -> provider.getFirClassifierContainerFileIfAny(symbol)
|
||||
is FirCallableSymbol<*> -> provider.getFirCallableContainerFile(symbol)
|
||||
else -> null
|
||||
}
|
||||
// Top-level: visible in file
|
||||
candidateFile == useSiteFile
|
||||
} else {
|
||||
// Member: visible inside parent class, including all its member classes
|
||||
canSeePrivateMemberOf(containingDeclarations, ownerId, session)
|
||||
}
|
||||
} else {
|
||||
declaration is FirSimpleFunction && declaration.isAllowedToBeAccessedFromOutside()
|
||||
}
|
||||
}
|
||||
|
||||
Visibilities.Protected -> {
|
||||
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, candidate.dispatchReceiverValue, ownerId, session)
|
||||
}
|
||||
|
||||
else -> platformVisibilityCheck(
|
||||
declaration.visibility,
|
||||
symbol,
|
||||
useSiteFile,
|
||||
ownerId,
|
||||
containingDeclarations,
|
||||
candidate,
|
||||
session
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun platformVisibilityCheck(
|
||||
declarationVisibility: Visibility,
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
useSiteFile: FirFile,
|
||||
ownerId: ClassId?,
|
||||
containingDeclarations: List<FirDeclaration>,
|
||||
candidate: Candidate,
|
||||
session: FirSession
|
||||
): Boolean
|
||||
|
||||
private fun canSeePrivateMemberOf(
|
||||
containingDeclarationOfUseSite: List<FirDeclaration>,
|
||||
ownerId: ClassId,
|
||||
session: FirSession
|
||||
): Boolean {
|
||||
ownerId.ownerIfCompanion(session)?.let { companionOwnerClassId ->
|
||||
return canSeePrivateMemberOf(containingDeclarationOfUseSite, companionOwnerClassId, session)
|
||||
}
|
||||
|
||||
for (declaration in containingDeclarationOfUseSite) {
|
||||
if (declaration !is FirClass<*>) continue
|
||||
val boundSymbol = declaration.symbol
|
||||
if (boundSymbol.classId.isSame(ownerId)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 'local' isn't taken into account here
|
||||
private fun ClassId.isSame(other: ClassId): Boolean =
|
||||
packageFqName == other.packageFqName && relativeClassName == other.relativeClassName
|
||||
|
||||
private fun ClassId.ownerIfCompanion(session: FirSession): ClassId? {
|
||||
if (outerClassId == null || isLocal) return null
|
||||
val ownerSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(this) as? FirRegularClassSymbol
|
||||
|
||||
return outerClassId.takeIf { ownerSymbol?.fir?.isCompanion == true }
|
||||
}
|
||||
|
||||
private fun canSeeProtectedMemberOf(
|
||||
containingUseSiteClass: FirClass<*>,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
ownerId: ClassId, session: FirSession
|
||||
): Boolean {
|
||||
dispatchReceiver?.ownerIfCompanion(session)?.let { companionOwnerClassId ->
|
||||
if (containingUseSiteClass.isSubClass(companionOwnerClassId, session)) return true
|
||||
}
|
||||
|
||||
// TODO: Add check for receiver, see org.jetbrains.kotlin.descriptors.Visibility#doesReceiverFitForProtectedVisibility
|
||||
return containingUseSiteClass.isSubClass(ownerId, session)
|
||||
}
|
||||
|
||||
private fun FirClass<*>.isSubClass(ownerId: ClassId, session: FirSession): Boolean {
|
||||
if (classId.isSame(ownerId)) return true
|
||||
|
||||
return lookupSuperTypes(this, lookupInterfaces = true, deep = true, session).any { superType ->
|
||||
(superType as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag?.classId?.isSame(ownerId) == true
|
||||
}
|
||||
}
|
||||
|
||||
private fun ReceiverValue?.ownerIfCompanion(session: FirSession): ClassId? =
|
||||
(this?.type as? ConeClassLikeType)?.lookupTag?.classId?.ownerIfCompanion(session)
|
||||
|
||||
// monitorEnter/monitorExit are the only functions which are accessed "illegally" (see kotlin/util/Synchronized.kt).
|
||||
// Since they are intrinsified in the codegen, FIR should treat it as visible.
|
||||
private fun FirSimpleFunction.isAllowedToBeAccessedFromOutside(): Boolean {
|
||||
if (!isFromLibrary) return false
|
||||
val packageName = symbol.callableId.packageName.asString()
|
||||
val name = name.asString()
|
||||
return packageName == "kotlin.jvm.internal.unsafe" &&
|
||||
(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<*> -> callableId.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?,
|
||||
ownerId: ClassId, session: FirSession
|
||||
): Boolean {
|
||||
if (canSeePrivateMemberOf(containingDeclarationOfUseSite, ownerId, session)) return true
|
||||
|
||||
for (containingDeclaration in containingDeclarationOfUseSite) {
|
||||
if (containingDeclaration !is FirClass<*>) continue
|
||||
val boundSymbol = containingDeclaration.symbol
|
||||
if (canSeeProtectedMemberOf(boundSymbol.fir, dispatchReceiver, ownerId, session)) return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
protected fun AbstractFirBasedSymbol<*>.packageFqName(): FqName {
|
||||
return when (this) {
|
||||
is FirClassLikeSymbol<*> -> classId.packageFqName
|
||||
is FirCallableSymbol<*> -> callableId.packageName
|
||||
else -> error("No package fq name for $this")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val FirSession.visibilityChecker: FirVisibilityChecker by FirSession.sessionComponentAccessor()
|
||||
+7
-158
@@ -5,8 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.Visibilities
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
@@ -14,7 +13,6 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.*
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
@@ -23,7 +21,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
@@ -375,10 +372,11 @@ internal object DiscriminateSynthetics : CheckerStage() {
|
||||
|
||||
internal object CheckVisibility : CheckerStage() {
|
||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||
val visibilityChecker = callInfo.session.visibilityChecker
|
||||
val symbol = candidate.symbol
|
||||
val declaration = symbol.fir
|
||||
if (declaration is FirMemberDeclaration) {
|
||||
if (!checkVisibility(declaration, symbol, sink, candidate)) {
|
||||
if (!checkVisibility(declaration, symbol, sink, candidate, visibilityChecker)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -392,173 +390,24 @@ internal object CheckVisibility : CheckerStage() {
|
||||
if (classSymbol.fir.classKind.isSingleton) {
|
||||
sink.yieldApplicability(CandidateApplicability.HIDDEN)
|
||||
}
|
||||
checkVisibility(classSymbol.fir, classSymbol, sink, candidate)
|
||||
checkVisibility(classSymbol.fir, classSymbol, sink, candidate, visibilityChecker)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun canSeePrivateMemberOf(
|
||||
containingDeclarationOfUseSite: List<FirDeclaration>,
|
||||
ownerId: ClassId,
|
||||
session: FirSession
|
||||
): Boolean {
|
||||
ownerId.ownerIfCompanion(session)?.let { companionOwnerClassId ->
|
||||
return canSeePrivateMemberOf(containingDeclarationOfUseSite, companionOwnerClassId, session)
|
||||
}
|
||||
|
||||
for (declaration in containingDeclarationOfUseSite) {
|
||||
if (declaration !is FirClass<*>) continue
|
||||
val boundSymbol = declaration.symbol
|
||||
if (boundSymbol.classId.isSame(ownerId)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 'local' isn't taken into account here
|
||||
private fun ClassId.isSame(other: ClassId): Boolean =
|
||||
packageFqName == other.packageFqName && relativeClassName == other.relativeClassName
|
||||
|
||||
private fun ClassId.ownerIfCompanion(session: FirSession): ClassId? {
|
||||
if (outerClassId == null || isLocal) return null
|
||||
val ownerSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(this) as? FirRegularClassSymbol
|
||||
|
||||
return outerClassId.takeIf { ownerSymbol?.fir?.isCompanion == true }
|
||||
}
|
||||
|
||||
private fun canSeeProtectedMemberOf(
|
||||
containingUseSiteClass: FirClass<*>,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
ownerId: ClassId, session: FirSession
|
||||
): Boolean {
|
||||
dispatchReceiver?.ownerIfCompanion(session)?.let { companionOwnerClassId ->
|
||||
if (containingUseSiteClass.isSubClass(companionOwnerClassId, session)) return true
|
||||
}
|
||||
|
||||
// TODO: Add check for receiver, see org.jetbrains.kotlin.descriptors.Visibility#doesReceiverFitForProtectedVisibility
|
||||
return containingUseSiteClass.isSubClass(ownerId, session)
|
||||
}
|
||||
|
||||
private fun FirClass<*>.isSubClass(ownerId: ClassId, session: FirSession): Boolean {
|
||||
if (classId.isSame(ownerId)) return true
|
||||
|
||||
return lookupSuperTypes(this, lookupInterfaces = true, deep = true, session).any { superType ->
|
||||
(superType as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag?.classId?.isSame(ownerId) == true
|
||||
}
|
||||
}
|
||||
|
||||
private fun ReceiverValue?.ownerIfCompanion(session: FirSession): ClassId? =
|
||||
(this?.type as? ConeClassLikeType)?.lookupTag?.classId?.ownerIfCompanion(session)
|
||||
|
||||
private suspend fun checkVisibility(
|
||||
declaration: FirMemberDeclaration,
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
sink: CheckerSink,
|
||||
candidate: Candidate
|
||||
candidate: Candidate,
|
||||
visibilityChecker: FirVisibilityChecker
|
||||
): Boolean {
|
||||
val callInfo = candidate.callInfo
|
||||
val useSiteFile = callInfo.containingFile
|
||||
val containingDeclarations = callInfo.containingDeclarations
|
||||
val session = callInfo.session
|
||||
val provider = session.firProvider
|
||||
val ownerId = symbol.getOwnerId()
|
||||
val visible = when (declaration.visibility) {
|
||||
JavaVisibilities.PACKAGE_VISIBILITY -> {
|
||||
symbol.packageFqName() == useSiteFile.packageFqName
|
||||
}
|
||||
Visibilities.Internal -> {
|
||||
declaration.session == callInfo.session
|
||||
}
|
||||
Visibilities.Private, Visibilities.PrivateToThis -> {
|
||||
if (declaration.session == callInfo.session) {
|
||||
if (ownerId == null || declaration is FirConstructor && declaration.isFromSealedClass) {
|
||||
val candidateFile = when (symbol) {
|
||||
is FirClassLikeSymbol<*> -> provider.getFirClassifierContainerFileIfAny(symbol)
|
||||
is FirCallableSymbol<*> -> provider.getFirCallableContainerFile(symbol)
|
||||
else -> null
|
||||
}
|
||||
// Top-level: visible in file
|
||||
candidateFile == useSiteFile
|
||||
} else {
|
||||
// Member: visible inside parent class, including all its member classes
|
||||
canSeePrivateMemberOf(containingDeclarations, ownerId, session)
|
||||
}
|
||||
} else {
|
||||
declaration is FirSimpleFunction && declaration.isAllowedToBeAccessedFromOutside()
|
||||
}
|
||||
}
|
||||
Visibilities.Protected -> {
|
||||
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, candidate.dispatchReceiverValue, ownerId, session)
|
||||
}
|
||||
JavaVisibilities.PROTECTED_AND_PACKAGE, JavaVisibilities.PROTECTED_STATIC_VISIBILITY -> {
|
||||
if (symbol.packageFqName() == useSiteFile.packageFqName) {
|
||||
true
|
||||
} else {
|
||||
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, candidate.dispatchReceiverValue, ownerId, session)
|
||||
}
|
||||
}
|
||||
else -> true
|
||||
}
|
||||
|
||||
if (!visible) {
|
||||
if (!visibilityChecker.isVisible(declaration, symbol, candidate)) {
|
||||
sink.yieldApplicability(CandidateApplicability.HIDDEN)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// monitorEnter/monitorExit are the only functions which are accessed "illegally" (see kotlin/util/Synchronized.kt).
|
||||
// Since they are intrinsified in the codegen, FIR should treat it as visible.
|
||||
private fun FirSimpleFunction.isAllowedToBeAccessedFromOutside(): Boolean {
|
||||
if (!isFromLibrary) return false
|
||||
val packageName = symbol.callableId.packageName.asString()
|
||||
val name = name.asString()
|
||||
return packageName == "kotlin.jvm.internal.unsafe" &&
|
||||
(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<*> -> callableId.classId
|
||||
else -> error("Unsupported owner search for ${fir.javaClass}: ${fir.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassId.asLocal(): ClassId = ClassId(packageFqName, relativeClassName, true)
|
||||
|
||||
private fun canSeeProtectedMemberOf(
|
||||
containingDeclarationOfUseSite: List<FirDeclaration>,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
ownerId: ClassId, session: FirSession
|
||||
): Boolean {
|
||||
if (canSeePrivateMemberOf(containingDeclarationOfUseSite, ownerId, session)) return true
|
||||
|
||||
for (containingDeclaration in containingDeclarationOfUseSite) {
|
||||
if (containingDeclaration !is FirClass<*>) continue
|
||||
val boundSymbol = containingDeclaration.symbol
|
||||
if (canSeeProtectedMemberOf(boundSymbol.fir, dispatchReceiver, ownerId, session)) return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun AbstractFirBasedSymbol<*>.packageFqName(): FqName {
|
||||
return when (this) {
|
||||
is FirClassLikeSymbol<*> -> classId.packageFqName
|
||||
is FirCallableSymbol<*> -> callableId.packageName
|
||||
else -> error("No package fq name for $this")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal object CheckLowPriorityInOverloadResolution : CheckerStage() {
|
||||
|
||||
+2
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.extensions.BunchOfRegisteredExtensions
|
||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||
import org.jetbrains.kotlin.fir.extensions.registerExtensions
|
||||
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.java.registerJavaVisibilityChecker
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.jvm.registerJvmCallConflictResolverFactory
|
||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
@@ -90,6 +91,7 @@ internal class FirIdeJavaModuleBasedSession private constructor(
|
||||
) as FirSymbolProvider
|
||||
)
|
||||
registerJvmCallConflictResolverFactory()
|
||||
registerJavaVisibilityChecker()
|
||||
extensionService.registerExtensions(BunchOfRegisteredExtensions.empty())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user