[FIR] Only inherit class type parameters if inner class
Nested classes which are not inner class should not be able to access type parameters of the outer class. Make sure access is not available when resolving super types. #KT-54748 Fixed
This commit is contained in:
+6
@@ -19418,6 +19418,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/inner/nestedClassNotAllowed_before.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedClassTypeParameterNameCollision.kt")
|
||||
public void testNestedClassTypeParameterNameCollision() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inner/nestedClassTypeParameterNameCollision.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedObject.kt")
|
||||
public void testNestedObject() throws Exception {
|
||||
|
||||
+6
@@ -19418,6 +19418,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/inner/nestedClassNotAllowed_before.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedClassTypeParameterNameCollision.kt")
|
||||
public void testNestedClassTypeParameterNameCollision() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inner/nestedClassTypeParameterNameCollision.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedObject.kt")
|
||||
public void testNestedObject() throws Exception {
|
||||
|
||||
+6
@@ -19418,6 +19418,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/inner/nestedClassNotAllowed_before.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedClassTypeParameterNameCollision.kt")
|
||||
public void testNestedClassTypeParameterNameCollision() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inner/nestedClassTypeParameterNameCollision.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedObject.kt")
|
||||
public void testNestedObject() throws Exception {
|
||||
|
||||
+6
@@ -19424,6 +19424,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/inner/nestedClassNotAllowed_before.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedClassTypeParameterNameCollision.kt")
|
||||
public void testNestedClassTypeParameterNameCollision() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inner/nestedClassTypeParameterNameCollision.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedObject.kt")
|
||||
public void testNestedObject() throws Exception {
|
||||
|
||||
+27
-10
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInner
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||
@@ -286,24 +287,31 @@ open class FirSupertypeResolverVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun prepareScopeForNestedClasses(klass: FirClass): ScopePersistentList {
|
||||
return supertypeComputationSession.getOrPutScopeForNestedClasses(klass) {
|
||||
calculateScopes(klass, true)
|
||||
private fun prepareScopeForNestedClasses(klass: FirClass, forStaticNestedClass: Boolean): ScopePersistentList {
|
||||
return if (forStaticNestedClass) {
|
||||
supertypeComputationSession.getOrPutScopeForStaticNestedClasses(klass) {
|
||||
calculateScopes(klass, withCompanionScopes = true, forStaticNestedClass = true)
|
||||
}
|
||||
} else {
|
||||
supertypeComputationSession.getOrPutScopeForNestedClasses(klass) {
|
||||
calculateScopes(klass, withCompanionScopes = true, forStaticNestedClass = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun prepareScopeForCompanion(klass: FirClass): ScopePersistentList {
|
||||
return supertypeComputationSession.getOrPutScopeForCompanion(klass) {
|
||||
calculateScopes(klass, false)
|
||||
calculateScopes(klass, withCompanionScopes = false, forStaticNestedClass = true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateScopes(
|
||||
outerClass: FirClass,
|
||||
withCompanionScopes: Boolean,
|
||||
forStaticNestedClass: Boolean,
|
||||
): PersistentList<FirScope> {
|
||||
resolveAllSupertypesForOuterClass(outerClass)
|
||||
return prepareScopes(outerClass).pushAll(
|
||||
return prepareScopes(outerClass, forStaticNestedClass).pushAll(
|
||||
createOtherScopesForNestedClassesOrCompanion(
|
||||
klass = outerClass,
|
||||
session = session,
|
||||
@@ -338,7 +346,7 @@ open class FirSupertypeResolverVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun prepareScopes(classLikeDeclaration: FirClassLikeDeclaration): PersistentList<FirScope> {
|
||||
private fun prepareScopes(classLikeDeclaration: FirClassLikeDeclaration, forStaticNestedClass: Boolean): PersistentList<FirScope> {
|
||||
val classId = classLikeDeclaration.symbol.classId
|
||||
val classModuleSession = classLikeDeclaration.moduleData.session
|
||||
|
||||
@@ -351,7 +359,7 @@ open class FirSupertypeResolverVisitor(
|
||||
val parent = localClassesNavigationInfo.parentForClass[classLikeDeclaration]
|
||||
|
||||
when {
|
||||
parent != null && parent is FirClass -> prepareScopeForNestedClasses(parent)
|
||||
parent != null && parent is FirClass -> prepareScopeForNestedClasses(parent, forStaticNestedClass)
|
||||
else -> scopeForLocalClass ?: return persistentListOf()
|
||||
}
|
||||
}
|
||||
@@ -361,12 +369,17 @@ open class FirSupertypeResolverVisitor(
|
||||
}
|
||||
classId.isNestedClass -> {
|
||||
val outerClassFir = classId.outerClassId?.let { getFirClassifierByFqName(classModuleSession, it) } as? FirRegularClass
|
||||
prepareScopeForNestedClasses(outerClassFir ?: return persistentListOf())
|
||||
// TypeAliases are treated as inner classes even though they are technically not allowed
|
||||
val isStatic = !classLikeDeclaration.isInner && classLikeDeclaration !is FirTypeAlias
|
||||
prepareScopeForNestedClasses(outerClassFir ?: return persistentListOf(), isStatic || forStaticNestedClass)
|
||||
}
|
||||
else -> getFirClassifierContainerFileIfAny(classLikeDeclaration.symbol)?.let(::prepareFileScopes) ?: persistentListOf()
|
||||
}
|
||||
|
||||
return result.pushIfNotNull(classLikeDeclaration.typeParametersScope())
|
||||
return when {
|
||||
forStaticNestedClass -> result
|
||||
else -> result.pushIfNotNull(classLikeDeclaration.typeParametersScope())
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveSpecificClassLikeSupertypes(
|
||||
@@ -386,7 +399,7 @@ open class FirSupertypeResolverVisitor(
|
||||
}
|
||||
|
||||
supertypeComputationSession.startComputingSupertypes(classLikeDeclaration)
|
||||
val scopes = prepareScopes(classLikeDeclaration)
|
||||
val scopes = prepareScopes(classLikeDeclaration, forStaticNestedClass = false)
|
||||
|
||||
val transformer = FirSpecificTypeResolverTransformer(session, supertypeSupplier = supertypeComputationSession.supertypesSupplier)
|
||||
|
||||
@@ -559,6 +572,7 @@ private fun createErrorTypeRef(fir: FirElement, message: String, kind: Diagnosti
|
||||
open class SupertypeComputationSession {
|
||||
private val fileScopesMap = hashMapOf<FirFile, ScopePersistentList>()
|
||||
private val scopesForNestedClassesMap = hashMapOf<FirClass, ScopePersistentList>()
|
||||
private val scopesForStaticNestedClassesMap = hashMapOf<FirClass, ScopePersistentList>()
|
||||
private val scopesForCompanionMap = hashMapOf<FirClass, ScopePersistentList>()
|
||||
private val supertypeStatusMap = linkedMapOf<FirClassLikeDeclaration, SupertypeComputationStatus>()
|
||||
|
||||
@@ -586,6 +600,9 @@ open class SupertypeComputationSession {
|
||||
fun getOrPutScopeForNestedClasses(klass: FirClass, scope: () -> ScopePersistentList): ScopePersistentList =
|
||||
scopesForNestedClassesMap.getOrPut(klass) { scope() }
|
||||
|
||||
fun getOrPutScopeForStaticNestedClasses(klass: FirClass, scope: () -> ScopePersistentList): ScopePersistentList =
|
||||
scopesForStaticNestedClassesMap.getOrPut(klass) { scope() }
|
||||
|
||||
fun getOrPutScopeForCompanion(klass: FirClass, scope: () -> ScopePersistentList): ScopePersistentList =
|
||||
scopesForCompanionMap.getOrPut(klass) { scope() }
|
||||
|
||||
|
||||
+4
@@ -56,6 +56,10 @@ private class NavigationInfoVisitor : FirDefaultVisitor<Unit, Any?>() {
|
||||
visitClass(anonymousObject, null)
|
||||
}
|
||||
|
||||
override fun visitTypeAlias(typeAlias: FirTypeAlias, data: Any?) {
|
||||
parentForClass[typeAlias] = currentPath.lastOrNull()
|
||||
}
|
||||
|
||||
override fun visitClass(klass: FirClass, data: Any?) {
|
||||
parentForClass[klass] = currentPath.lastOrNull()
|
||||
currentPath.add(klass)
|
||||
|
||||
@@ -4,6 +4,6 @@ open class ToResolve<SomeClass>(f : (Int) -> Int)
|
||||
fun testFun(a : Int) = 12
|
||||
|
||||
class TestSome<P> {
|
||||
companion object : ToResolve<P>({testFun(it)}) {
|
||||
companion object : ToResolve<<!UNRESOLVED_REFERENCE!>P<!>>(<!ARGUMENT_TYPE_MISMATCH!>{testFun(it)}<!>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ private fun <E> foobar() = {
|
||||
fun a() = A<E, X, Y, Z>()
|
||||
}
|
||||
|
||||
typealias LocalAlias<W> = A<E, <!UNRESOLVED_REFERENCE!>X<!>, <!UNRESOLVED_REFERENCE!>Y<!>, W>
|
||||
typealias LocalAlias<W> = A<E, X, Y, W>
|
||||
}
|
||||
|
||||
class Derived : LocalOuter<Double, Short>() {
|
||||
@@ -26,7 +26,7 @@ private fun noParameters() = {
|
||||
fun a() = A<Any, X, Y, Z>()
|
||||
}
|
||||
|
||||
typealias LocalAlias2<W> = A<Any, <!UNRESOLVED_REFERENCE!>X<!>, <!UNRESOLVED_REFERENCE!>Y<!>, W>
|
||||
typealias LocalAlias2<W> = A<Any, X, Y, W>
|
||||
}
|
||||
|
||||
class Derived2 : LocalOuter2<Double, Short>() {
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ class Outer<T> {
|
||||
fun a() = A<T, F, E, X, Y, Z>()
|
||||
}
|
||||
|
||||
typealias LocalAlias<W> = A<T, F, E, <!UNRESOLVED_REFERENCE!>X<!>, <!UNRESOLVED_REFERENCE!>Y<!>, W>
|
||||
typealias LocalAlias<W> = A<T, F, E, X, Y, W>
|
||||
}
|
||||
|
||||
class Derived : LocalOuter<Double, Short>() {
|
||||
@@ -28,7 +28,7 @@ class Outer<T> {
|
||||
fun a() = A<T, F, Any, X, Y, Z>()
|
||||
}
|
||||
|
||||
typealias LocalAlias2<W> = A<T, F, Any, <!UNRESOLVED_REFERENCE!>X<!>, <!UNRESOLVED_REFERENCE!>Y<!>, W>
|
||||
typealias LocalAlias2<W> = A<T, F, Any, X, Y, W>
|
||||
}
|
||||
|
||||
class Derived2 : LocalOuter2<Double, Short>() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
open class SomeClass<T>
|
||||
class TestSome<P> {
|
||||
companion object : SomeClass<P>() {
|
||||
companion object : SomeClass<<!UNRESOLVED_REFERENCE!>P<!>>() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
open class SomeClass<T>
|
||||
class TestSome<P> {
|
||||
object Some : SomeClass<P>() {
|
||||
object Some : SomeClass<<!UNRESOLVED_REFERENCE!>P<!>>() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// FIR_IDENTICAL
|
||||
// KT-54748
|
||||
|
||||
sealed class Result<String> {
|
||||
data class Success(val value: String) : Result<String>()
|
||||
class Failure(val cause: Throwable) : Result<String>()
|
||||
}
|
||||
|
||||
fun foo(): Result<String> = Result.Success("...")
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -TOPLEVEL_TYPEALIASES_ONLY
|
||||
|
||||
class Outer<TO> {
|
||||
typealias LTO = List<TO>
|
||||
|
||||
class Nested<TN> {
|
||||
typealias LTO = List<TO>
|
||||
typealias LTN = List<TN>
|
||||
|
||||
inner class Inner<TI> {
|
||||
typealias LTO = List<TO>
|
||||
typealias LTN = List<TN>
|
||||
typealias LTI = List<TI>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <TF> foo() {
|
||||
class Local<TL> {
|
||||
typealias LTF = List<TF>
|
||||
typealias LTL = List<<!UNRESOLVED_REFERENCE!>TL<!>>
|
||||
}
|
||||
|
||||
fun <TLF> localfun() =
|
||||
object {
|
||||
typealias LTF = List<TF>
|
||||
typealias LTLF = List<TLF>
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -TOPLEVEL_TYPEALIASES_ONLY
|
||||
|
||||
class Outer<TO> {
|
||||
|
||||
Generated
+6
@@ -19424,6 +19424,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/inner/nestedClassNotAllowed_before.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedClassTypeParameterNameCollision.kt")
|
||||
public void testNestedClassTypeParameterNameCollision() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inner/nestedClassTypeParameterNameCollision.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedObject.kt")
|
||||
public void testNestedObject() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user