[FIR] Fix resolving of local class reference chain ^KT-47135 Fixed

This commit is contained in:
Ivan Kochurkin
2021-10-06 20:20:30 +03:00
committed by TeamCityServer
parent cbfe0ac073
commit 3dd8ad3599
8 changed files with 78 additions and 8 deletions
@@ -24083,6 +24083,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/regressions/kt9808.kt");
}
@Test
@TestMetadata("LocalClassReferenceChain.kt")
public void testLocalClassReferenceChain() throws Exception {
runTest("compiler/testData/diagnostics/tests/regressions/LocalClassReferenceChain.kt");
}
@Test
@TestMetadata("noThis.kt")
public void testNoThis() throws Exception {
@@ -24083,6 +24083,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/regressions/kt9808.kt");
}
@Test
@TestMetadata("LocalClassReferenceChain.kt")
public void testLocalClassReferenceChain() throws Exception {
runTest("compiler/testData/diagnostics/tests/regressions/LocalClassReferenceChain.kt");
}
@Test
@TestMetadata("noThis.kt")
public void testNoThis() throws Exception {
@@ -24083,6 +24083,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/regressions/kt9808.kt");
}
@Test
@TestMetadata("LocalClassReferenceChain.kt")
public void testLocalClassReferenceChain() throws Exception {
runTest("compiler/testData/diagnostics/tests/regressions/LocalClassReferenceChain.kt");
}
@Test
@TestMetadata("noThis.kt")
public void testNoThis() throws Exception {
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.ConeUnexpectedTypeArgumentsError
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
@@ -68,19 +69,21 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
val qualifierResolver = session.qualifierResolver
var resolvedSymbol: FirBasedSymbol<*>? = null
var substitutor: ConeSubstitutor? = null
scope.processClassifiersByNameWithSubstitution(typeRef.qualifier.first().name) { symbol, substitutorFromScope ->
val qualifier = typeRef.qualifier
scope.processClassifiersByNameWithSubstitution(qualifier.first().name) { symbol, substitutorFromScope ->
if (resolvedSymbol != null) return@processClassifiersByNameWithSubstitution
resolvedSymbol = when (symbol) {
is FirClassLikeSymbol<*> -> {
if (typeRef.qualifier.size == 1) {
if (qualifier.size == 1) {
symbol
} else {
qualifierResolver.resolveSymbolWithPrefix(typeRef.qualifier, symbol.classId)
?: qualifierResolver.resolveEnumEntrySymbol(typeRef.qualifier, symbol.classId)
resolveLocalClassChain(symbol, qualifier)
?: qualifierResolver.resolveSymbolWithPrefix(qualifier, symbol.classId)
?: qualifierResolver.resolveEnumEntrySymbol(qualifier, symbol.classId)
}
}
is FirTypeParameterSymbol -> {
assert(typeRef.qualifier.size == 1)
assert(qualifier.size == 1)
symbol
}
else -> error("!")
@@ -89,7 +92,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
}
// TODO: Imports
val resultSymbol: FirBasedSymbol<*>? = resolvedSymbol ?: qualifierResolver.resolveSymbol(typeRef.qualifier)
val resultSymbol: FirBasedSymbol<*>? = resolvedSymbol ?: qualifierResolver.resolveSymbol(qualifier)
resultSymbol to substitutor
}
@@ -101,6 +104,31 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
}
}
private fun resolveLocalClassChain(symbol: FirClassLikeSymbol<*>, qualifier: List<FirQualifierPart>): FirRegularClassSymbol? {
if (symbol !is FirRegularClassSymbol || !symbol.isLocal) {
return null
}
fun resolveLocalClassChain(classSymbol: FirRegularClassSymbol, qualifierIndex: Int): FirRegularClassSymbol? {
if (qualifierIndex == qualifier.size) {
return classSymbol
}
val qualifierName = qualifier[qualifierIndex].name
for (declarationSymbol in classSymbol.declarationSymbols) {
if (declarationSymbol is FirRegularClassSymbol) {
if (declarationSymbol.toLookupTag().name == qualifierName) {
return resolveLocalClassChain(declarationSymbol, qualifierIndex + 1)
}
}
}
return null
}
return resolveLocalClassChain(symbol, 1)
}
@OptIn(SymbolInternals::class)
private fun FirQualifierResolver.resolveEnumEntrySymbol(
qualifier: List<FirQualifierPart>,
@@ -18,11 +18,11 @@ fun <E> foo(x: Any, y: Any) : Any {
}
// bare type
if (y is <!UNRESOLVED_REFERENCE!>Outer.Inner<!>) {
if (y is <!NO_TYPE_ARGUMENTS_ON_RHS!>Outer.Inner<!>) {
return y
}
y as <!UNRESOLVED_REFERENCE!>Outer<*>.Inner<!>
y as Outer<*>.Inner
return C()
}
@@ -0,0 +1,15 @@
// FIR_IDENTICAL
// KT-47135
fun test2() {
class LocalA {
inner class LocalB {
inner class LocalC {
}
}
}
fun LocalA.LocalB.blah() {
val c: LocalA.LocalB.LocalC = LocalC()
}
}
@@ -0,0 +1,3 @@
package
public fun test2(): kotlin.Unit
@@ -24095,6 +24095,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/regressions/kt9808.kt");
}
@Test
@TestMetadata("LocalClassReferenceChain.kt")
public void testLocalClassReferenceChain() throws Exception {
runTest("compiler/testData/diagnostics/tests/regressions/LocalClassReferenceChain.kt");
}
@Test
@TestMetadata("noThis.kt")
public void testNoThis() throws Exception {