FIR resolve: introduce draft version of the visibility checker
This commit is contained in:
committed by
Mikhail Glukhikh
parent
adf845b2fd
commit
9169071d60
@@ -5,6 +5,7 @@ plugins {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile(project(":core:descriptors"))
|
compile(project(":core:descriptors"))
|
||||||
|
compile(project(":core:descriptors.jvm"))
|
||||||
compile(project(":core:deserialization"))
|
compile(project(":core:deserialization"))
|
||||||
compile(project(":compiler:fir:cones"))
|
compile(project(":compiler:fir:cones"))
|
||||||
compile(project(":compiler:fir:tree"))
|
compile(project(":compiler:fir:tree"))
|
||||||
|
|||||||
@@ -7,9 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
@@ -40,6 +38,9 @@ class CallInfo(
|
|||||||
val arguments: List<FirExpression>,
|
val arguments: List<FirExpression>,
|
||||||
|
|
||||||
val typeArguments: List<FirTypeProjection>,
|
val typeArguments: List<FirTypeProjection>,
|
||||||
|
val session: FirSession,
|
||||||
|
val containingFile: FirFile,
|
||||||
|
val container: FirDeclaration,
|
||||||
val typeProvider: (FirExpression) -> FirTypeRef?
|
val typeProvider: (FirExpression) -> FirTypeRef?
|
||||||
) {
|
) {
|
||||||
val argumentCount get() = arguments.size
|
val argumentCount get() = arguments.size
|
||||||
|
|||||||
@@ -5,12 +5,22 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.firSafeNullable
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
import org.jetbrains.kotlin.fir.resolve.transformers.firUnsafe
|
||||||
|
import org.jetbrains.kotlin.fir.service
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.ConeSymbol
|
||||||
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.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||||
|
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
|
||||||
import java.lang.IllegalStateException
|
import java.lang.IllegalStateException
|
||||||
@@ -140,14 +150,57 @@ internal object DiscriminateSynthetics : CheckerStage() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal object CheckVisibility : CheckerStage() {
|
||||||
|
|
||||||
|
private fun ConeSymbol.packageFqName(): FqName {
|
||||||
|
return when (this) {
|
||||||
|
is ConeClassLikeSymbol -> classId.packageFqName
|
||||||
|
is ConeCallableSymbol -> callableId.packageName
|
||||||
|
else -> error("No package fq name for ${this}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||||
|
val symbol = candidate.symbol
|
||||||
|
val declaration = symbol.firSafeNullable<FirMemberDeclaration>()
|
||||||
|
if (declaration != null && !declaration.visibility.isPublicAPI) {
|
||||||
|
val visible = when (declaration.visibility) {
|
||||||
|
JavaVisibilities.PACKAGE_VISIBILITY ->
|
||||||
|
symbol.packageFqName() == callInfo.containingFile.packageFqName
|
||||||
|
Visibilities.PRIVATE, Visibilities.PRIVATE_TO_THIS -> {
|
||||||
|
if (declaration.session == callInfo.session) {
|
||||||
|
val provider = callInfo.session.service<FirProvider>()
|
||||||
|
val candidateFile = when (symbol) {
|
||||||
|
is ConeCallableSymbol -> provider.getFirCallableContainerFile(symbol)
|
||||||
|
is ConeClassLikeSymbol -> provider.getFirClassifierContainerFile(symbol.classId)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
candidateFile == callInfo.containingFile
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Visibilities.INTERNAL ->
|
||||||
|
declaration.session == callInfo.session
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!visible) {
|
||||||
|
sink.reportApplicability(CandidateApplicability.HIDDEN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
internal fun functionCallResolutionSequence() = listOf(
|
internal fun functionCallResolutionSequence() = listOf(
|
||||||
MapArguments, CheckExplicitReceiverConsistency, CreateFreshTypeVariableSubstitutorStage,
|
CheckVisibility, MapArguments, CheckExplicitReceiverConsistency, CreateFreshTypeVariableSubstitutorStage,
|
||||||
CheckReceivers.Dispatch, CheckReceivers.Extension, CheckArguments
|
CheckReceivers.Dispatch, CheckReceivers.Extension, CheckArguments
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
internal fun qualifiedAccessResolutionSequence() = listOf(
|
internal fun qualifiedAccessResolutionSequence() = listOf(
|
||||||
|
CheckVisibility,
|
||||||
DiscriminateSynthetics,
|
DiscriminateSynthetics,
|
||||||
CheckExplicitReceiverConsistency,
|
CheckExplicitReceiverConsistency,
|
||||||
CreateFreshTypeVariableSubstitutorStage,
|
CreateFreshTypeVariableSubstitutorStage,
|
||||||
|
|||||||
+13
-2
@@ -48,9 +48,12 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var packageFqName = FqName.ROOT
|
private var packageFqName = FqName.ROOT
|
||||||
|
private lateinit var file: FirFile
|
||||||
|
private var container: FirDeclaration? = null
|
||||||
|
|
||||||
override fun transformFile(file: FirFile, data: Any?): CompositeTransformResult<FirFile> {
|
override fun transformFile(file: FirFile, data: Any?): CompositeTransformResult<FirFile> {
|
||||||
packageFqName = file.packageFqName
|
packageFqName = file.packageFqName
|
||||||
|
this.file = file
|
||||||
return withScopeCleanup(scopes) {
|
return withScopeCleanup(scopes) {
|
||||||
scopes.addImportingScopes(file, session)
|
scopes.addImportingScopes(file, session)
|
||||||
scopes += FirTopLevelDeclaredMemberScope(file, session)
|
scopes += FirTopLevelDeclaredMemberScope(file, session)
|
||||||
@@ -210,7 +213,7 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
|||||||
|
|
||||||
val receiver = qualifiedAccess.explicitReceiver?.transformSingle(this, noExpectedType)
|
val receiver = qualifiedAccess.explicitReceiver?.transformSingle(this, noExpectedType)
|
||||||
|
|
||||||
val info = CallInfo(CallKind.VariableAccess, receiver, emptyList(), emptyList()) { it.resultType }
|
val info = CallInfo(CallKind.VariableAccess, receiver, emptyList(), emptyList(), session, file, container!!) { it.resultType }
|
||||||
val resolver = CallResolver(jump, inferenceComponents)
|
val resolver = CallResolver(jump, inferenceComponents)
|
||||||
resolver.callInfo = info
|
resolver.callInfo = info
|
||||||
resolver.scopes = (scopes + localScopes).asReversed()
|
resolver.scopes = (scopes + localScopes).asReversed()
|
||||||
@@ -320,7 +323,7 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
|||||||
val arguments = functionCall.arguments
|
val arguments = functionCall.arguments
|
||||||
val typeArguments = functionCall.typeArguments
|
val typeArguments = functionCall.typeArguments
|
||||||
|
|
||||||
val info = CallInfo(CallKind.Function, explicitReceiver, arguments, typeArguments) { it.resultType }
|
val info = CallInfo(CallKind.Function, explicitReceiver, arguments, typeArguments, session, file, container!!) { it.resultType }
|
||||||
val resolver = CallResolver(jump, inferenceComponents)
|
val resolver = CallResolver(jump, inferenceComponents)
|
||||||
resolver.callInfo = info
|
resolver.callInfo = info
|
||||||
resolver.scopes = (scopes + localScopes).asReversed()
|
resolver.scopes = (scopes + localScopes).asReversed()
|
||||||
@@ -606,6 +609,14 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun transformDeclaration(declaration: FirDeclaration, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||||
|
val prevContainer = container
|
||||||
|
container = declaration
|
||||||
|
val result = super.transformDeclaration(declaration, data)
|
||||||
|
container = prevContainer
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Any?): CompositeTransformResult<FirDeclaration> {
|
override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Any?): CompositeTransformResult<FirDeclaration> {
|
||||||
if (namedFunction.returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return namedFunction.compose()
|
if (namedFunction.returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return namedFunction.compose()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user