[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:
Dmitriy Novozhilov
2020-08-16 20:21:17 +03:00
parent 18ae593700
commit a02109d857
5 changed files with 264 additions and 158 deletions
@@ -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)
}