diff --git a/compiler/fir/resolve/build.gradle.kts b/compiler/fir/resolve/build.gradle.kts index 53eb3af4a66..bd7c2d9e026 100644 --- a/compiler/fir/resolve/build.gradle.kts +++ b/compiler/fir/resolve/build.gradle.kts @@ -5,6 +5,7 @@ plugins { dependencies { compile(project(":core:descriptors")) + compile(project(":core:descriptors.jvm")) compile(project(":core:deserialization")) compile(project(":compiler:fir:cones")) compile(project(":compiler:fir:tree")) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt index 579f961dc26..c0a8ded7278 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallResolver.kt @@ -7,9 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.calls import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration -import org.jetbrains.kotlin.fir.declarations.FirConstructor -import org.jetbrains.kotlin.fir.declarations.FirValueParameter +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.ScopeSession @@ -40,6 +38,9 @@ class CallInfo( val arguments: List, val typeArguments: List, + val session: FirSession, + val containingFile: FirFile, + val container: FirDeclaration, val typeProvider: (FirExpression) -> FirTypeRef? ) { val argumentCount get() = arguments.size diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt index 9da7ccf4dc8..266fe49e9f1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt @@ -5,12 +5,22 @@ 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.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.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.FirFunctionSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType 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 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() + 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() + 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( - MapArguments, CheckExplicitReceiverConsistency, CreateFreshTypeVariableSubstitutorStage, + CheckVisibility, MapArguments, CheckExplicitReceiverConsistency, CreateFreshTypeVariableSubstitutorStage, CheckReceivers.Dispatch, CheckReceivers.Extension, CheckArguments ) internal fun qualifiedAccessResolutionSequence() = listOf( + CheckVisibility, DiscriminateSynthetics, CheckExplicitReceiverConsistency, CreateFreshTypeVariableSubstitutorStage, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt index 865adaff973..2f68f1aac0f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirBodyResolveTransformer.kt @@ -48,9 +48,12 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn } private var packageFqName = FqName.ROOT + private lateinit var file: FirFile + private var container: FirDeclaration? = null override fun transformFile(file: FirFile, data: Any?): CompositeTransformResult { packageFqName = file.packageFqName + this.file = file return withScopeCleanup(scopes) { scopes.addImportingScopes(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 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) resolver.callInfo = info resolver.scopes = (scopes + localScopes).asReversed() @@ -320,7 +323,7 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn val arguments = functionCall.arguments 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) resolver.callInfo = info 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 { + val prevContainer = container + container = declaration + val result = super.transformDeclaration(declaration, data) + container = prevContainer + return result + } + override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Any?): CompositeTransformResult { if (namedFunction.returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly) return namedFunction.compose()