[LL FIR] fix lazy resolution of member-property statuses for local classes
Previously, statuses of superclass which are not local was not ignored Sometimes it worked in the IDE by calling lazyResolveToPhase which is a violation of the lazy resolution contract ^KT-54890
This commit is contained in:
+1
-1
@@ -26,7 +26,7 @@ internal class LLFirDesignatedStatusResolveTransformer(
|
||||
private val scopeSession: ScopeSession,
|
||||
) : LLFirLazyTransformer {
|
||||
private inner class FirDesignatedStatusResolveTransformerForIDE :
|
||||
FirStatusResolveTransformer(session, scopeSession, StatusComputationSession.Regular()) {
|
||||
FirStatusResolveTransformer(session, scopeSession, StatusComputationSession()) {
|
||||
|
||||
val designationTransformer = LLFirDeclarationTransformer(designation)
|
||||
|
||||
|
||||
+6
@@ -3163,6 +3163,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/implicitInLocalClasses.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("overrideInLocal.kt")
|
||||
public void testOverrideInLocal() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/overrideInLocal.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typesFromSuperClasses.kt")
|
||||
public void testTypesFromSuperClasses() throws Exception {
|
||||
|
||||
+5
@@ -2783,6 +2783,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/implicitInLocalClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overrideInLocal.kt")
|
||||
public void testOverrideInLocal() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/overrideInLocal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typesFromSuperClasses.kt")
|
||||
public void testTypesFromSuperClasses() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/typesFromSuperClasses.kt");
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
FILE: a.kt
|
||||
public final fun main(): R|kotlin/Unit| {
|
||||
local final class Local : R|B| {
|
||||
public constructor(): R|Local| {
|
||||
super<R|B|>()
|
||||
}
|
||||
|
||||
protected final override val message: R|kotlin/String| = String(expression expected)
|
||||
protected get(): R|kotlin/String|
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
FILE: b.kt
|
||||
public abstract class B : R|kotlin/Any| {
|
||||
public constructor(): R|B| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
protected abstract val message: R|kotlin/String|
|
||||
protected get(): R|kotlin/String|
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// FILE: a.kt
|
||||
fun main() {
|
||||
class Local : B() {
|
||||
override val message = "expression expected"
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: b.kt
|
||||
abstract class B {
|
||||
protected abstract val message: String
|
||||
}
|
||||
+6
@@ -3163,6 +3163,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/implicitInLocalClasses.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("overrideInLocal.kt")
|
||||
public void testOverrideInLocal() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/overrideInLocal.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typesFromSuperClasses.kt")
|
||||
public void testTypesFromSuperClasses() throws Exception {
|
||||
|
||||
+6
@@ -3163,6 +3163,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/implicitInLocalClasses.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("overrideInLocal.kt")
|
||||
public void testOverrideInLocal() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/overrideInLocal.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("typesFromSuperClasses.kt")
|
||||
public void testTypesFromSuperClasses() throws Exception {
|
||||
|
||||
+21
-50
@@ -37,7 +37,7 @@ class FirStatusResolveProcessor(
|
||||
scopeSession: ScopeSession
|
||||
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
|
||||
override val transformer = run {
|
||||
val statusComputationSession = StatusComputationSession.Regular()
|
||||
val statusComputationSession = StatusComputationSession()
|
||||
FirStatusResolveTransformer(
|
||||
session,
|
||||
scopeSession,
|
||||
@@ -52,7 +52,7 @@ fun <F : FirClassLikeDeclaration> F.runStatusResolveForLocalClass(
|
||||
scopesForLocalClass: List<FirScope>,
|
||||
localClassesNavigationInfo: LocalClassesNavigationInfo
|
||||
): F {
|
||||
val statusComputationSession = StatusComputationSession.ForLocalClassResolution(localClassesNavigationInfo.parentForClass.keys)
|
||||
val statusComputationSession = StatusComputationSession()
|
||||
val transformer = FirStatusResolveTransformer(
|
||||
session,
|
||||
scopeSession,
|
||||
@@ -174,12 +174,26 @@ open class FirDesignatedStatusResolveTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
sealed class StatusComputationSession {
|
||||
abstract operator fun get(klass: FirClass): StatusComputationStatus
|
||||
class StatusComputationSession {
|
||||
private val statusMap = mutableMapOf<FirClass, StatusComputationStatus>()
|
||||
.withDefault { StatusComputationStatus.NotComputed }
|
||||
|
||||
abstract fun startComputing(klass: FirClass): StatusComputationStatus
|
||||
abstract fun endComputing(klass: FirClass)
|
||||
abstract fun computeOnlyClassStatus(klass: FirClass)
|
||||
operator fun get(klass: FirClass): StatusComputationStatus = statusMap.getValue(klass)
|
||||
|
||||
fun startComputing(klass: FirClass): StatusComputationStatus {
|
||||
return statusMap.getOrPut(klass) { StatusComputationStatus.Computing }
|
||||
}
|
||||
|
||||
fun endComputing(klass: FirClass) {
|
||||
statusMap[klass] = StatusComputationStatus.Computed
|
||||
}
|
||||
|
||||
fun computeOnlyClassStatus(klass: FirClass) {
|
||||
val existedStatus = statusMap.getValue(klass)
|
||||
if (existedStatus < StatusComputationStatus.ComputedOnlyClassStatus) {
|
||||
statusMap[klass] = StatusComputationStatus.ComputedOnlyClassStatus
|
||||
}
|
||||
}
|
||||
|
||||
enum class StatusComputationStatus(val requiresComputation: Boolean) {
|
||||
NotComputed(true),
|
||||
@@ -187,49 +201,6 @@ sealed class StatusComputationSession {
|
||||
ComputedOnlyClassStatus(true),
|
||||
Computed(false)
|
||||
}
|
||||
|
||||
class Regular : StatusComputationSession() {
|
||||
private val statusMap = mutableMapOf<FirClass, StatusComputationStatus>()
|
||||
.withDefault { StatusComputationStatus.NotComputed }
|
||||
|
||||
override fun get(klass: FirClass): StatusComputationStatus = statusMap.getValue(klass)
|
||||
|
||||
override fun startComputing(klass: FirClass): StatusComputationStatus {
|
||||
return statusMap.getOrPut(klass) { StatusComputationStatus.Computing }
|
||||
}
|
||||
|
||||
override fun endComputing(klass: FirClass) {
|
||||
statusMap[klass] = StatusComputationStatus.Computed
|
||||
}
|
||||
|
||||
override fun computeOnlyClassStatus(klass: FirClass) {
|
||||
val existedStatus = statusMap.getValue(klass)
|
||||
if (existedStatus < StatusComputationStatus.ComputedOnlyClassStatus) {
|
||||
statusMap[klass] = StatusComputationStatus.ComputedOnlyClassStatus
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ForLocalClassResolution(private val localClasses: Set<FirClassLikeDeclaration>) : StatusComputationSession() {
|
||||
private val delegate = Regular()
|
||||
|
||||
override fun get(klass: FirClass): StatusComputationStatus {
|
||||
if (klass !in localClasses) return StatusComputationStatus.Computed
|
||||
return delegate[klass]
|
||||
}
|
||||
|
||||
override fun startComputing(klass: FirClass): StatusComputationStatus {
|
||||
return delegate.startComputing(klass)
|
||||
}
|
||||
|
||||
override fun endComputing(klass: FirClass) {
|
||||
delegate.endComputing(klass)
|
||||
}
|
||||
|
||||
override fun computeOnlyClassStatus(klass: FirClass) {
|
||||
delegate.computeOnlyClassStatus(klass)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractFirStatusResolveTransformer(
|
||||
|
||||
Reference in New Issue
Block a user