[FIR] Fix redundant calls to firEffectiveVisibility()

This commit is contained in:
Nick
2020-07-10 15:19:02 +03:00
parent 5340cf5567
commit 67e58ff152
11 changed files with 73 additions and 55 deletions
@@ -15,7 +15,7 @@ fun test(e: MyException, stream: PrintStream) {
val result = e.getLocalizedMessage()
}
fun test(<!EXPOSED_PARAMETER_TYPE!>e: YourException<!>, stream: PrintStream) {
fun test(e: YourException, stream: PrintStream) {
e.printStackTrace()
e.printStackTrace(stream)
val result = e.getLocalizedMessage()
@@ -10,6 +10,7 @@ import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.RelationToType
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass
@@ -17,8 +18,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory3
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
// TODO: check why coneTypeSafe is necessary at some points inside
object FirExposedVisibilityChecker : FirMemberDeclarationChecker() {
@@ -37,7 +40,7 @@ object FirExposedVisibilityChecker : FirMemberDeclarationChecker() {
}
private fun checkSupertypes(declaration: FirRegularClass, reporter: DiagnosticReporter) {
val classVisibility = declaration.firEffectiveVisibility(declaration.session)
val classVisibility = declaration.effectiveVisibility
val supertypes = declaration.superTypeRefs
val isInterface = declaration.classKind == ClassKind.INTERFACE
for (supertypeRef in supertypes) {
@@ -47,13 +50,13 @@ object FirExposedVisibilityChecker : FirMemberDeclarationChecker() {
if (superIsInterface != isInterface) {
continue
}
val restricting = supertype.leastPermissiveDescriptor(declaration.session, classVisibility)
val restricting = supertype.findVisibilityExposure(declaration.session, classVisibility)
if (restricting != null) {
reporter.reportExposure(
if (isInterface) FirErrors.EXPOSED_SUPER_INTERFACE else FirErrors.EXPOSED_SUPER_CLASS,
restricting,
classVisibility,
restricting.firEffectiveVisibility(declaration.session),
restricting.effectiveVisibility,
supertypeRef.source ?: declaration.source
)
}
@@ -61,16 +64,16 @@ object FirExposedVisibilityChecker : FirMemberDeclarationChecker() {
}
private fun checkParameterBounds(declaration: FirRegularClass, reporter: DiagnosticReporter) {
val classVisibility = declaration.firEffectiveVisibility(declaration.session)
val classVisibility = declaration.effectiveVisibility
for (parameter in declaration.typeParameters) {
for (bound in parameter.symbol.fir.bounds) {
val restricting = bound.coneType.leastPermissiveDescriptor(declaration.session, classVisibility)
val restricting = bound.coneType.findVisibilityExposure(declaration.session, classVisibility)
if (restricting != null) {
reporter.reportExposure(
FirErrors.EXPOSED_TYPE_PARAMETER_BOUND,
restricting,
classVisibility,
restricting.firEffectiveVisibility(declaration.session),
restricting.effectiveVisibility,
bound.source
)
}
@@ -81,13 +84,13 @@ object FirExposedVisibilityChecker : FirMemberDeclarationChecker() {
private fun checkTypeAlias(declaration: FirTypeAlias, reporter: DiagnosticReporter) {
val expandedType = declaration.expandedConeType
val typeAliasVisibility = declaration.firEffectiveVisibility(declaration.session)
val restricting = expandedType?.leastPermissiveDescriptor(declaration.session, typeAliasVisibility)
val restricting = expandedType?.findVisibilityExposure(declaration.session, typeAliasVisibility)
if (restricting != null) {
reporter.reportExposure(
FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE,
restricting,
typeAliasVisibility,
restricting.firEffectiveVisibility(declaration.session),
restricting.effectiveVisibility,
declaration.source?.getIdentifierSource() ?: declaration.source
)
}
@@ -97,13 +100,13 @@ object FirExposedVisibilityChecker : FirMemberDeclarationChecker() {
val functionVisibility = (declaration as FirMemberDeclaration).effectiveVisibility
if (declaration !is FirConstructor) {
val restricting = declaration.returnTypeRef.coneTypeSafe<ConeKotlinType>()
?.leastPermissiveDescriptor(declaration.session, functionVisibility)
?.findVisibilityExposure(declaration.session, functionVisibility)
if (restricting != null) {
reporter.reportExposure(
FirErrors.EXPOSED_FUNCTION_RETURN_TYPE,
restricting,
functionVisibility,
restricting.firEffectiveVisibility(declaration.session),
restricting.effectiveVisibility,
declaration.source?.getIdentifierSource() ?: declaration.source
)
}
@@ -112,13 +115,13 @@ object FirExposedVisibilityChecker : FirMemberDeclarationChecker() {
if (i < declaration.valueParameters.size) {
val restricting =
valueParameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()
?.leastPermissiveDescriptor(declaration.session, functionVisibility)
?.findVisibilityExposure(declaration.session, functionVisibility)
if (restricting != null) {
reporter.reportExposure(
FirErrors.EXPOSED_PARAMETER_TYPE,
restricting,
functionVisibility,
restricting.firEffectiveVisibility(declaration.session),
restricting.effectiveVisibility,
valueParameter.source
)
}
@@ -128,15 +131,16 @@ object FirExposedVisibilityChecker : FirMemberDeclarationChecker() {
}
private fun checkProperty(declaration: FirProperty, reporter: DiagnosticReporter) {
val propertyVisibility = declaration.firEffectiveVisibility(declaration.session)
val propertyVisibility = declaration.effectiveVisibility
val restricting =
declaration.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.leastPermissiveDescriptor(declaration.session, propertyVisibility)
declaration.returnTypeRef.coneTypeSafe<ConeKotlinType>()
?.findVisibilityExposure(declaration.session, propertyVisibility)
if (restricting != null) {
reporter.reportExposure(
FirErrors.EXPOSED_PROPERTY_TYPE,
restricting,
propertyVisibility,
restricting.firEffectiveVisibility(declaration.session),
restricting.effectiveVisibility,
declaration.source?.getIdentifierSource() ?: declaration.source
)
}
@@ -149,22 +153,52 @@ object FirExposedVisibilityChecker : FirMemberDeclarationChecker() {
) {
if (typeRef == null || memberDeclaration == null) return
val receiverParameterType = typeRef.coneType
val memberVisibility = memberDeclaration.firEffectiveVisibility(memberDeclaration.session)
val restricting = receiverParameterType.leastPermissiveDescriptor(memberDeclaration.session, memberVisibility)
val memberVisibility = memberDeclaration.effectiveVisibility
val restricting = receiverParameterType.findVisibilityExposure(memberDeclaration.session, memberVisibility)
if (restricting != null) {
reporter.reportExposure(
FirErrors.EXPOSED_RECEIVER_TYPE,
restricting,
memberVisibility,
restricting.firEffectiveVisibility(memberDeclaration.session),
restricting.effectiveVisibility,
typeRef.source
)
}
}
private fun ConeKotlinType.findVisibilityExposure(session: FirSession, base: FirEffectiveVisibility): FirMemberDeclaration? {
val type = this as? ConeClassLikeType
?: return null
val fir = type.lookupTag.toSymbol(session)
?.fir
?: return null
if (
fir is FirMemberDeclaration &&
fir.effectiveVisibility != FirEffectiveVisibility.Default // because abstract interface List<out T> returns it here
) {
when (fir.effectiveVisibility.relation(base)) {
FirEffectiveVisibility.Permissiveness.LESS,
FirEffectiveVisibility.Permissiveness.UNKNOWN -> {
return fir
}
else -> {
}
}
}
for (it in type.typeArguments) {
it.safeAs<ConeClassLikeType>()?.findVisibilityExposure(session, base)?.let {
return it
}
}
return null
}
private inline fun <reified E : FirSourceElement, P : PsiElement> DiagnosticReporter.reportExposure(
error: FirDiagnosticFactory3<E, P, FirEffectiveVisibility, DeclarationWithRelation, FirEffectiveVisibility>,
restrictingDeclaration: DeclarationWithRelation,
error: FirDiagnosticFactory3<E, P, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>,
restrictingDeclaration: FirMemberDeclaration,
elementVisibility: FirEffectiveVisibility,
restrictingVisibility: FirEffectiveVisibility,
source: FirSourceElement?
@@ -7,10 +7,9 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.fir.DeclarationWithRelation
import org.jetbrains.kotlin.fir.FirEffectiveVisibility
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -62,14 +61,14 @@ object FirErrors {
val VAR_ANNOTATION_PARAMETER by existing<FirSourceElement, KtParameter>(Errors.VAR_ANNOTATION_PARAMETER)
// Exposed visibility group
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<FirSourceElement, PsiElement, FirEffectiveVisibility, DeclarationWithRelation, FirEffectiveVisibility>()
val EXPOSED_FUNCTION_RETURN_TYPE by error3<FirSourceElement, PsiElement, FirEffectiveVisibility, DeclarationWithRelation, FirEffectiveVisibility>()
val EXPOSED_RECEIVER_TYPE by error3<FirSourceElement, KtTypeReference, FirEffectiveVisibility, DeclarationWithRelation, FirEffectiveVisibility>()
val EXPOSED_PROPERTY_TYPE by error3<FirSourceElement, PsiElement, FirEffectiveVisibility, DeclarationWithRelation, FirEffectiveVisibility>()
val EXPOSED_PARAMETER_TYPE by error3<FirSourceElement, KtParameter, FirEffectiveVisibility, DeclarationWithRelation, FirEffectiveVisibility>()
val EXPOSED_SUPER_INTERFACE by error3<FirSourceElement, KtSuperTypeListEntry, FirEffectiveVisibility, DeclarationWithRelation, FirEffectiveVisibility>()
val EXPOSED_SUPER_CLASS by error3<FirSourceElement, KtSuperTypeListEntry, FirEffectiveVisibility, DeclarationWithRelation, FirEffectiveVisibility>()
val EXPOSED_TYPE_PARAMETER_BOUND by error3<FirSourceElement, KtTypeParameter, FirEffectiveVisibility, DeclarationWithRelation, FirEffectiveVisibility>()
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<FirSourceElement, PsiElement, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_FUNCTION_RETURN_TYPE by error3<FirSourceElement, PsiElement, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_RECEIVER_TYPE by error3<FirSourceElement, KtTypeReference, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_PROPERTY_TYPE by error3<FirSourceElement, PsiElement, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_PARAMETER_TYPE by error3<FirSourceElement, KtParameter, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_SUPER_INTERFACE by error3<FirSourceElement, KtSuperTypeListEntry, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_SUPER_CLASS by error3<FirSourceElement, KtSuperTypeListEntry, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_TYPE_PARAMETER_BOUND by error3<FirSourceElement, KtTypeParameter, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val REPEATED_MODIFIER by error1<FirSourceElement, PsiElement, KtModifierKeywordToken>()
val REDUNDANT_MODIFIER by error2<FirSourceElement, PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
@@ -6,7 +6,7 @@ interface A extends C {
// FILE: B.kt
interface B : <!EXPOSED_SUPER_INTERFACE!>A<!> {
interface B : A {
fun bar()
}
@@ -6,6 +6,6 @@ class J extends K {
// FILE: K.kt
class K : <!EXPOSED_SUPER_CLASS!>J<!>() {
class K : J() {
fun bar() {}
}
@@ -12,6 +12,6 @@ class J extends I {
// FILE: K.kt
open class K : <!EXPOSED_SUPER_CLASS!>J<!>() {
open class K : J() {
fun baz() {}
}
@@ -1,6 +1,6 @@
// FILE: ExceptionTracker.kt
interface ExceptionTracker : <!EXPOSED_SUPER_INTERFACE!>LockBasedStorageManager.ExceptionHandlingStrategy<!> {
interface ExceptionTracker : LockBasedStorageManager.ExceptionHandlingStrategy {
}
// FILE: StorageManager.kt
@@ -1,16 +0,0 @@
// FILE: Outer.java
public abstract class Outer {
protected static class My {}
protected static class Your extends My {}
abstract protected Your foo(My my);
}
// FILE: OuterDerived.kt
class OuterDerived: Outer() {
// valid, My has better visibility
protected class His: Outer.My()
// valid, My and Your have better visibility
override fun <!EXPOSED_FUNCTION_RETURN_TYPE!>foo<!>(<!EXPOSED_PARAMETER_TYPE!>my: Outer.My<!>) = Outer.Your()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: Outer.java
public abstract class Outer {
@@ -16,10 +16,10 @@ class MyJavaClass {
//FILE:a.kt
package a
val <!EXPOSED_PROPERTY_TYPE!>mc<!> = MyJavaClass()
val mc = MyJavaClass()
val x = MyJavaClass.staticMethod()
val y = MyJavaClass.NestedClass.staticMethodOfNested()
val <!EXPOSED_PROPERTY_TYPE!>z<!> = MyJavaClass.NestedClass()
val z = MyJavaClass.NestedClass()
//FILE: b.kt
package b
@@ -10,6 +10,6 @@ package kotlin.sequences
import p.*
interface I {
val <!EXPOSED_PROPERTY_TYPE!>v1<!>: FilteringSequence
val <!EXPOSED_PROPERTY_TYPE!>v2<!>: IndexingSequence<String>
val v1: FilteringSequence
val v2: IndexingSequence<String>
}