[IR] Forcefully collect mapping of f/o for all source classes

```kotlin
// FILE: AB.kt
interface A {
    val x: Int = 1
}

interface B : A {
    // f/o val x: Int
    //    overrides: A.x
}

// FILE: C.java
public interface C extends B {
    // f/o val x: Int
    //    overrides: (B, A.x)
}

// FILE: D.java
public interface D extends C {
    // f/o val x: Int
    //    overrides: (C, A.x)
}

// FILE: usage.kt
fun test(d: D) {
    d.x
}
```

In such test backend will ask for overriddens of lazy property C.x only
  after property lowering, which removes property `B.x` and replaces it
  with getter `B.<get-x>`. That fact that there is no property anymore
  really confuses `SpecialFakeOverrideSymbolsResolver` during computation
  of overriddens of `C.x`.
So, to prevent this situation, we can process all source kotlin classes
  beforehand, so when any lazy function/property will start computation
  of its overriddens, there won't be the need to calculate mapping of
  f/o for classes

This problem was found during work on KT-66341, after total signature
  computation removal from fir2ir. Previously those fake-overrides just
  matched by signature in symbol table
This commit is contained in:
Dmitriy Novozhilov
2024-03-05 13:10:56 +02:00
committed by Space Team
parent e8f8399af4
commit b43f69364b
2 changed files with 24 additions and 2 deletions
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.ir.util.KotlinMangler
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.utils.addToStdlib.runIf
data class FirResult(val outputs: List<ModuleCompilerAnalyzedOutput>)
@@ -123,14 +124,18 @@ fun FirResult.convertToIrAndActualize(
components.fakeOverrideBuilder.buildForAll(allIrModules, temporaryResolver)
}
val expectActualMap = irActualizer?.actualizeCallablesAndMergeModules() ?: emptyMap()
if (!components.configuration.useFirBasedFakeOverrideGenerator) {
val fakeOverrideResolver = runIf(!components.configuration.useFirBasedFakeOverrideGenerator) {
val fakeOverrideResolver = SpecialFakeOverrideSymbolsResolver(expectActualMap)
irModuleFragment.acceptVoid(SpecialFakeOverrideSymbolsResolverVisitor(fakeOverrideResolver))
@OptIn(Fir2IrSymbolsMappingForLazyClasses.SymbolRemapperInternals::class)
components.symbolsMappingForLazyClasses.initializeSymbolMap(fakeOverrideResolver)
fakeOverrideResolver
}
Fir2IrConverter.evaluateConstants(irModuleFragment, components)
val actualizationResult = irActualizer?.runChecksAndFinalize(expectActualMap)
fakeOverrideResolver?.cacheFakeOverridesOfAllClasses(irModuleFragment)
pluginContext.applyIrGenerationExtensions(irModuleFragment, irGeneratorExtensions)
return Fir2IrActualizedResult(irModuleFragment, components, pluginContext, actualizationResult)
}
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.ir.util.SymbolRemapper
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
/**
* This class provides utility to resolve [org.jetbrains.kotlin.ir.symbols.impl.IrFunctionFakeOverrideSymbol]
@@ -112,6 +111,24 @@ class SpecialFakeOverrideSymbolsResolver(private val expectActualMap: Map<IrSymb
}
}
}
fun cacheFakeOverridesOfAllClasses(irModuleFragment: IrModuleFragment) {
val visitor = object : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {}
override fun visitFile(declaration: IrFile) {
declaration.acceptChildrenVoid(this)
}
override fun visitClass(declaration: IrClass) {
if (!declaration.isExpect) {
processClass(declaration)
}
declaration.acceptChildrenVoid(this)
}
}
irModuleFragment.acceptChildrenVoid(visitor)
}
}