[FIR] Fix redundant calls to firEffectiveVisibility()
This commit is contained in:
@@ -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()
|
||||
|
||||
+54
-20
@@ -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?
|
||||
|
||||
+9
-10
@@ -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>()
|
||||
|
||||
+1
-1
@@ -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() {}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user