[FIR] Support for EXPOSED_TYPE_PARAMETER_BOUND
This commit is contained in:
committed by
Mikhail Glukhikh
parent
bfffcf6b23
commit
02aa11a0a0
+35
@@ -0,0 +1,35 @@
|
||||
private open class A
|
||||
|
||||
internal open class B
|
||||
|
||||
public open class C {
|
||||
protected open class D
|
||||
}
|
||||
|
||||
public open class E
|
||||
|
||||
// invalid, A is private
|
||||
public class Test1<T: <!EXPOSED_TYPE_PARAMETER_BOUND!>A<!>>
|
||||
|
||||
// valid, both type parameters is public
|
||||
public class Test2<T: C, P: E>
|
||||
|
||||
// invalid, D is protected
|
||||
public class Test3<T: E, P: <!EXPOSED_TYPE_PARAMETER_BOUND!>C.D<!>>
|
||||
|
||||
// valid, B is internal
|
||||
internal class Test4<T: B>
|
||||
|
||||
// valid, B is internal
|
||||
private class Test5<T: B>
|
||||
|
||||
public class Container : C {
|
||||
// valid, D is protected in C
|
||||
protected class Test6<T: C.D>
|
||||
|
||||
// invalid, B is internal
|
||||
protected class Test7<T: <!EXPOSED_TYPE_PARAMETER_BOUND!>B<!>>
|
||||
}
|
||||
|
||||
// invalid, A is private, B is internal, D is protected
|
||||
public interface Test8<T: <!EXPOSED_TYPE_PARAMETER_BOUND!>A<!>, P: <!EXPOSED_TYPE_PARAMETER_BOUND!>B<!>, F: C, N: <!EXPOSED_TYPE_PARAMETER_BOUND!>C.D<!>, M: E>
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
FILE: exposedTypeParameters.kt
|
||||
private open class A : R|kotlin/Any| {
|
||||
public[private] constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
internal open class B : R|kotlin/Any| {
|
||||
public[internal] constructor(): R|B| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public open class C : R|kotlin/Any| {
|
||||
public constructor(): R|C| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
protected open class D : R|kotlin/Any| {
|
||||
public[protected] constructor(): R|C.D| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public open class E : R|kotlin/Any| {
|
||||
public constructor(): R|E| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class Test1<T : R|A|> : R|kotlin/Any| {
|
||||
public constructor<T : R|A|>(): R|Test1<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class Test2<T : R|C|, P : R|E|> : R|kotlin/Any| {
|
||||
public constructor<T : R|C|, P : R|E|>(): R|Test2<T, P>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class Test3<T : R|E|, P : R|C.D|> : R|kotlin/Any| {
|
||||
public constructor<T : R|E|, P : R|C.D|>(): R|Test3<T, P>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
internal final class Test4<T : R|B|> : R|kotlin/Any| {
|
||||
public[internal] constructor<T : R|B|>(): R|Test4<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
private final class Test5<T : R|B|> : R|kotlin/Any| {
|
||||
public[private] constructor<T : R|B|>(): R|Test5<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class Container : R|C| {
|
||||
public constructor(): R|Container| {
|
||||
super<R|C|>()
|
||||
}
|
||||
|
||||
protected final class Test6<T : R|C.D|> : R|kotlin/Any| {
|
||||
public[protected] constructor<T : R|C.D|>(): R|Container.Test6<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected final class Test7<T : R|B|> : R|kotlin/Any| {
|
||||
public[protected] constructor<T : R|B|>(): R|Container.Test7<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public abstract interface Test8<T : R|A|, P : R|B|, F : R|C|, N : R|C.D|, M : R|E|> : R|kotlin/Any| {
|
||||
}
|
||||
Generated
+5
@@ -2193,6 +2193,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/visibility/exposedTypeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("exposedTypeParameters.kt")
|
||||
public void testExposedTypeParameters() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/visibility/exposedTypeParameters.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("protectedInCompanion.kt")
|
||||
public void testProtectedInCompanion() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/visibility/protectedInCompanion.kt");
|
||||
|
||||
+5
@@ -2193,6 +2193,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/visibility/exposedTypeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("exposedTypeParameters.kt")
|
||||
public void testExposedTypeParameters() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/visibility/exposedTypeParameters.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("protectedInCompanion.kt")
|
||||
public void testProtectedInCompanion() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/visibility/protectedInCompanion.kt");
|
||||
|
||||
+25
-1
@@ -17,6 +17,7 @@ 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.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
@@ -29,10 +30,15 @@ object FirExposedVisibilityChecker : FirDeclarationChecker<FirMemberDeclaration>
|
||||
is FirTypeAlias -> checkTypeAlias(declaration, reporter)
|
||||
is FirProperty -> checkProperty(declaration, reporter)
|
||||
is FirFunction<*> -> checkFunction(declaration, reporter)
|
||||
is FirRegularClass -> checkSupertypes(declaration, reporter)
|
||||
is FirRegularClass -> checkClass(declaration, reporter)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkClass(declaration: FirRegularClass, reporter: DiagnosticReporter) {
|
||||
checkSupertypes(declaration, reporter)
|
||||
checkParameterBounds(declaration, reporter)
|
||||
}
|
||||
|
||||
private fun checkSupertypes(declaration: FirRegularClass, reporter: DiagnosticReporter) {
|
||||
val classVisibility = declaration.firEffectiveVisibility(declaration.session)
|
||||
val supertypes = declaration.superTypeRefs
|
||||
@@ -57,6 +63,24 @@ object FirExposedVisibilityChecker : FirDeclarationChecker<FirMemberDeclaration>
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkParameterBounds(declaration: FirRegularClass, reporter: DiagnosticReporter) {
|
||||
val classVisibility = declaration.firEffectiveVisibility(declaration.session)
|
||||
for (parameter in declaration.typeParameters) {
|
||||
for (bound in parameter.symbol.fir.bounds) {
|
||||
val restricting = bound.coneTypeSafe<ConeKotlinType>()?.leastPermissiveDescriptor(declaration.session, classVisibility)
|
||||
if (restricting != null) {
|
||||
reporter.reportExposure(
|
||||
FirErrors.EXPOSED_TYPE_PARAMETER_BOUND,
|
||||
restricting,
|
||||
classVisibility,
|
||||
restricting.firEffectiveVisibility(declaration.session),
|
||||
bound.source
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkTypeAlias(declaration: FirTypeAlias, reporter: DiagnosticReporter) {
|
||||
val expandedType = declaration.expandedConeType
|
||||
val typeAliasVisibility = declaration.firEffectiveVisibility(declaration.session)
|
||||
|
||||
+5
-4
@@ -6,17 +6,17 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorWithRelation
|
||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory3
|
||||
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.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.KtSuperTypeListEntry
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
object FirErrors {
|
||||
val UNRESOLVED_REFERENCE by error1<FirSourceElement, PsiElement, String?>()
|
||||
@@ -61,6 +61,7 @@ object FirErrors {
|
||||
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 REPEATED_MODIFIER by error1<FirSourceElement, PsiElement, KtModifierKeywordToken>()
|
||||
val REDUNDANT_MODIFIER by error2<FirSourceElement, PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
||||
|
||||
@@ -6,7 +6,7 @@ public interface Your: <!EXPOSED_SUPER_INTERFACE!>My<!> {
|
||||
fun <T: Base> foo(): T
|
||||
}
|
||||
|
||||
public class Derived<T: My>(<!EXPOSED_PARAMETER_TYPE!>val <!EXPOSED_PROPERTY_TYPE!>x<!>: My<!>): <!EXPOSED_SUPER_CLASS!>Base<!>() {
|
||||
public class Derived<T: <!EXPOSED_TYPE_PARAMETER_BOUND!>My<!>>(<!EXPOSED_PARAMETER_TYPE!>val <!EXPOSED_PROPERTY_TYPE!>x<!>: My<!>): <!EXPOSED_SUPER_CLASS!>Base<!>() {
|
||||
|
||||
constructor(<!EXPOSED_PARAMETER_TYPE!>xx: My?<!>, <!EXPOSED_PARAMETER_TYPE!>x: My<!>): this(xx ?: x)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ abstract class Your {
|
||||
interface His: <!EXPOSED_SUPER_INTERFACE!>List<My><!>
|
||||
|
||||
// invalid, My is internal
|
||||
interface Generic<E: My>
|
||||
interface Generic<E: <!EXPOSED_TYPE_PARAMETER_BOUND!>My<!>>
|
||||
|
||||
interface Our {
|
||||
// invalid, Generic<My> is effectively internal
|
||||
|
||||
Reference in New Issue
Block a user