FIR: Add FirVisibilityQualifierChecker

This commit is contained in:
Denis.Zharkov
2021-09-07 13:10:37 +03:00
committed by teamcityserver
parent 9575d4d242
commit 9ca96ebbd2
7 changed files with 69 additions and 10 deletions
@@ -135,6 +135,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
FirStandaloneQualifierChecker,
FirOptInUsageQualifierChecker,
FirDeprecatedQualifierChecker,
FirVisibilityQualifierChecker,
)
override val equalityOperatorCallCheckers: Set<FirEqualityOperatorCallChecker>
@@ -0,0 +1,58 @@
/*
* Copyright 2010-2021 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.analysis.checkers.expression
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.getOwnerLookupTag
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.types.toSymbol
import org.jetbrains.kotlin.fir.visibilityChecker
object FirVisibilityQualifierChecker : FirResolvedQualifierChecker() {
override fun check(expression: FirResolvedQualifier, context: CheckerContext, reporter: DiagnosticReporter) {
checkClassLikeSymbol(expression.symbol ?: return, expression, context, reporter)
}
@OptIn(SymbolInternals::class)
private fun checkClassLikeSymbol(
symbol: FirClassLikeSymbol<*>,
expression: FirResolvedQualifier,
context: CheckerContext,
reporter: DiagnosticReporter
) {
val firFile = context.containingDeclarations.firstOrNull() as? FirFile ?: return
val firClassLikeDeclaration = symbol.fir
if (firClassLikeDeclaration !is FirMemberDeclaration) return
if (!context.session.visibilityChecker.isVisible(
firClassLikeDeclaration, context.session, firFile, context.containingDeclarations,
dispatchReceiver = null,
)) {
reporter.reportOn(expression.source, FirErrors.INVISIBLE_REFERENCE, symbol, context)
return
}
if (firClassLikeDeclaration is FirTypeAlias) {
(firClassLikeDeclaration.expandedConeType?.toSymbol(context.session) as? FirClassLikeSymbol)?.let {
checkClassLikeSymbol(it, expression, context, reporter)
}
}
symbol.getOwnerLookupTag()?.toSymbol(context.session)?.let {
checkClassLikeSymbol(it, expression, context, reporter)
}
}
}
@@ -10,6 +10,6 @@ class A {
}
}
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>f1<!>() = A.Companion.B.C
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>f1<!>() = A.Companion.B.<!INVISIBLE_REFERENCE!>C<!>
fun f2() = A.Companion.B.C.foo()
fun f2() = A.Companion.B.<!INVISIBLE_REFERENCE!>C<!>.foo()
@@ -21,6 +21,6 @@ import A.Nested.*
import B.JC.JC1
fun test() {
O1
<!INVISIBLE_REFERENCE!>O1<!>
JC1()
}
}
@@ -28,5 +28,5 @@ fun testAccess() {
E1
NestedEntry
A1()
A2
}
<!INVISIBLE_REFERENCE!>A2<!>
}
@@ -14,5 +14,5 @@ public class Foo {
// FILE: 1.kt
fun main() {
javaPackage.Foo.Bar.doSmth()
}
javaPackage.Foo.<!INVISIBLE_REFERENCE!>Bar<!>.doSmth()
}
@@ -7,10 +7,10 @@ private class C {
private typealias TA = C
private val test1: C = <!INVISIBLE_REFERENCE!>C<!>()
private val test1co: C.Companion = <!INITIALIZER_TYPE_MISMATCH, NO_COMPANION_OBJECT!>C<!>
private val test1co: C.Companion = <!INITIALIZER_TYPE_MISMATCH, INVISIBLE_REFERENCE, NO_COMPANION_OBJECT!>C<!>
private val test2: TA = <!INITIALIZER_TYPE_MISMATCH!>TA(<!NO_VALUE_FOR_PARAMETER!>)<!><!>
private val test2co = TA
private val test2co = <!INVISIBLE_REFERENCE!>TA<!>
// FILE: file2.kt
private val test1: C = C()