Fix FIR incremental compilation failure with inlines and lambdas

#KT-51546 fixed
This commit is contained in:
Ilya Chernikov
2022-03-05 18:27:25 +01:00
committed by teamcity
parent 8f1a2f4612
commit aa0386276d
13 changed files with 134 additions and 12 deletions
@@ -166,7 +166,10 @@ abstract class AbstractFirDeserializedSymbolProvider(
return getPackageParts(callableId.packageName).flatMap { part ->
val functionIds = part.topLevelFunctionNameIndex[callableId.callableName] ?: return@flatMap emptyList()
functionIds.map {
part.context.memberDeserializer.loadFunction(part.proto.getFunction(it)).symbol
part.context.memberDeserializer.loadFunction(
part.proto.getFunction(it),
deserializationOrigin = defaultDeserializationOrigin
).symbol
}
}
}
@@ -428,7 +428,9 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
fun loadFunction(
proto: ProtoBuf.Function,
classProto: ProtoBuf.Class? = null,
classSymbol: FirClassSymbol<*>? = null
classSymbol: FirClassSymbol<*>? = null,
// TODO: introduce the similar changes for the other deserialized entities
deserializationOrigin: FirDeclarationOrigin = FirDeclarationOrigin.Library
): FirSimpleFunction {
val flags = if (proto.hasFlags()) proto.flags else loadOldFlags(proto.oldFlags)
@@ -447,7 +449,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
val simpleFunction = buildSimpleFunction {
moduleData = c.moduleData
origin = FirDeclarationOrigin.Library
origin = deserializationOrigin
returnTypeRef = proto.returnType(local.typeTable).toTypeRef(local)
receiverTypeRef = proto.receiverType(local.typeTable)?.toTypeRef(local).apply {
annotations += receiverAnnotations
@@ -483,7 +483,7 @@ class Fir2IrClassifierStorage(
val classId = firClassSymbol.classId
val parentId = classId.outerClassId
val parentClass = parentId?.let { session.symbolProvider.getClassLikeSymbolByClassId(it) }
val irParent = declarationStorage.findIrParent(classId.packageFqName, parentClass?.toLookupTag(), firClassSymbol)!!
val irParent = declarationStorage.findIrParent(classId.packageFqName, parentClass?.toLookupTag(), firClassSymbol, firClass.origin)!!
val symbol = Fir2IrClassSymbol(signature)
val irClass = firClass.convertWithOffsets { startOffset, endOffset ->
symbolTable.declareClass(signature, { symbol }) {
@@ -210,9 +210,9 @@ class Fir2IrDeclarationStorage(
private fun ConeKotlinType.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType =
with(typeConverter) { toIrType(typeContext) }
private fun getIrExternalOrBuiltInsPackageFragment(fqName: FqName): IrExternalPackageFragment {
private fun getIrExternalOrBuiltInsPackageFragment(fqName: FqName, firOrigin: FirDeclarationOrigin): IrExternalPackageFragment {
val isBuiltIn = fqName in BUILT_INS_PACKAGE_FQ_NAMES
return if (isBuiltIn) getIrBuiltInsPackageFragment(fqName) else getIrExternalPackageFragment(fqName)
return if (isBuiltIn) getIrBuiltInsPackageFragment(fqName) else getIrExternalPackageFragment(fqName, firOrigin)
}
private fun getIrBuiltInsPackageFragment(fqName: FqName): IrExternalPackageFragment {
@@ -221,11 +221,17 @@ class Fir2IrDeclarationStorage(
}
}
fun getIrExternalPackageFragment(fqName: FqName): IrExternalPackageFragment {
fun getIrExternalPackageFragment(
fqName: FqName,
firOrigin: FirDeclarationOrigin = FirDeclarationOrigin.Library
): IrExternalPackageFragment {
return fragmentCache.getOrPut(fqName) {
// Make sure that external package fragments have a different module descriptor. The module descriptors are compared
// to determine if objects need regeneration because they are from different modules.
val externalFragmentModuleDescriptor = FirModuleDescriptor(session)
// But keep original module descriptor for the fragments coming from parts compiled on the previous incremental step
val externalFragmentModuleDescriptor =
if (firOrigin == FirDeclarationOrigin.Precompiled) moduleDescriptor
else FirModuleDescriptor(session)
return symbolTable.declareExternalPackageFragment(FirPackageFragmentDescriptor(fqName, externalFragmentModuleDescriptor))
}
}
@@ -245,7 +251,8 @@ class Fir2IrDeclarationStorage(
internal fun findIrParent(
packageFqName: FqName,
parentLookupTag: ConeClassLikeLookupTag?,
firBasedSymbol: FirBasedSymbol<*>
firBasedSymbol: FirBasedSymbol<*>,
firOrigin: FirDeclarationOrigin
): IrDeclarationParent? {
return if (parentLookupTag != null) {
findIrClass(parentLookupTag)
@@ -258,10 +265,10 @@ class Fir2IrDeclarationStorage(
when {
containerFile != null -> fileCache[containerFile]
firBasedSymbol is FirCallableSymbol -> getIrExternalPackageFragment(packageFqName)
firBasedSymbol is FirCallableSymbol -> getIrExternalPackageFragment(packageFqName, firOrigin)
// TODO: All classes from BUILT_INS_PACKAGE_FQ_NAMES are considered built-ins now,
// which is not exact and can lead to some problems
else -> getIrExternalOrBuiltInsPackageFragment(packageFqName)
else -> getIrExternalOrBuiltInsPackageFragment(packageFqName, firOrigin)
}
}
}
@@ -269,7 +276,8 @@ class Fir2IrDeclarationStorage(
internal fun findIrParent(callableDeclaration: FirCallableDeclaration): IrDeclarationParent? {
val firBasedSymbol = callableDeclaration.symbol
val callableId = firBasedSymbol.callableId
return findIrParent(callableId.packageName, callableDeclaration.containingClass(), firBasedSymbol)
val callableOrigin = callableDeclaration.origin
return findIrParent(callableId.packageName, callableDeclaration.containingClass(), firBasedSymbol, callableOrigin)
}
private fun IrDeclaration.setAndModifyParent(irParent: IrDeclarationParent?) {
@@ -923,6 +923,11 @@ public class IncrementalFirJvmCompilerRunnerTestGenerated extends AbstractIncrem
runTest("jps/jps-plugin/testData/incremental/inlineFunCallSite/function/");
}
@TestMetadata("functionIndirect")
public void testFunctionIndirect() throws Exception {
runTest("jps/jps-plugin/testData/incremental/inlineFunCallSite/functionIndirect/");
}
@TestMetadata("getter")
public void testGetter() throws Exception {
runTest("jps/jps-plugin/testData/incremental/inlineFunCallSite/getter/");
@@ -1025,6 +1030,19 @@ public class IncrementalFirJvmCompilerRunnerTestGenerated extends AbstractIncrem
}
}
@TestMetadata("jps/jps-plugin/testData/incremental/inlineFunCallSite/functionIndirect")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionIndirect extends AbstractIncrementalFirJvmCompilerRunnerTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
}
public void testAllFilesPresentInFunctionIndirect() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps/jps-plugin/testData/incremental/inlineFunCallSite/functionIndirect"), Pattern.compile("^([^\\.]+)$"), null, TargetBackend.JVM_IR, true);
}
}
@TestMetadata("jps/jps-plugin/testData/incremental/inlineFunCallSite/getter")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -923,6 +923,11 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
runTest("jps/jps-plugin/testData/incremental/inlineFunCallSite/function/");
}
@TestMetadata("functionIndirect")
public void testFunctionIndirect() throws Exception {
runTest("jps/jps-plugin/testData/incremental/inlineFunCallSite/functionIndirect/");
}
@TestMetadata("getter")
public void testGetter() throws Exception {
runTest("jps/jps-plugin/testData/incremental/inlineFunCallSite/getter/");
@@ -1025,6 +1030,19 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
}
}
@TestMetadata("jps/jps-plugin/testData/incremental/inlineFunCallSite/functionIndirect")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionIndirect extends AbstractIncrementalJvmCompilerRunnerTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
}
public void testAllFilesPresentInFunctionIndirect() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps/jps-plugin/testData/incremental/inlineFunCallSite/functionIndirect"), Pattern.compile("^([^\\.]+)$"), null, TargetBackend.JVM_IR, true);
}
}
@TestMetadata("jps/jps-plugin/testData/incremental/inlineFunCallSite/getter")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -923,6 +923,11 @@ public class IncrementalJvmOldBackendCompilerRunnerTestGenerated extends Abstrac
runTest("jps/jps-plugin/testData/incremental/inlineFunCallSite/function/");
}
@TestMetadata("functionIndirect")
public void testFunctionIndirect() throws Exception {
runTest("jps/jps-plugin/testData/incremental/inlineFunCallSite/functionIndirect/");
}
@TestMetadata("getter")
public void testGetter() throws Exception {
runTest("jps/jps-plugin/testData/incremental/inlineFunCallSite/getter/");
@@ -1025,6 +1030,19 @@ public class IncrementalJvmOldBackendCompilerRunnerTestGenerated extends Abstrac
}
}
@TestMetadata("jps/jps-plugin/testData/incremental/inlineFunCallSite/functionIndirect")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionIndirect extends AbstractIncrementalJvmOldBackendCompilerRunnerTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInFunctionIndirect() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps/jps-plugin/testData/incremental/inlineFunCallSite/functionIndirect"), Pattern.compile("^([^\\.]+)$"), null, TargetBackend.JVM, true);
}
}
@TestMetadata("jps/jps-plugin/testData/incremental/inlineFunCallSite/getter")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -2802,6 +2802,11 @@ public class IncrementalJvmJpsTestGenerated extends AbstractIncrementalJvmJpsTes
runTest("jps/jps-plugin/testData/incremental/inlineFunCallSite/function/");
}
@TestMetadata("functionIndirect")
public void testFunctionIndirect() throws Exception {
runTest("jps/jps-plugin/testData/incremental/inlineFunCallSite/functionIndirect/");
}
@TestMetadata("getter")
public void testGetter() throws Exception {
runTest("jps/jps-plugin/testData/incremental/inlineFunCallSite/getter/");
@@ -2904,6 +2909,19 @@ public class IncrementalJvmJpsTestGenerated extends AbstractIncrementalJvmJpsTes
}
}
@TestMetadata("jps/jps-plugin/testData/incremental/inlineFunCallSite/functionIndirect")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionIndirect extends AbstractIncrementalJvmJpsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
}
public void testAllFilesPresentInFunctionIndirect() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps/jps-plugin/testData/incremental/inlineFunCallSite/functionIndirect"), Pattern.compile("^([^\\.]+)$"), null, TargetBackend.JVM_IR, true);
}
}
@TestMetadata("jps/jps-plugin/testData/incremental/inlineFunCallSite/getter")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -0,0 +1,11 @@
================ Step #1 =================
Cleaning output files:
out/production/module/META-INF/module.kotlin_module
out/production/module/usage/Usage.class
End of files
Compiling files:
src/usage.kt
End of files
Exit code: OK
------------------------------------------
@@ -0,0 +1,9 @@
package inline
private inline fun ps(): () -> String { val z = "Outer"; return { "OK" } }
internal inline fun test(s: () -> () -> String = ::ps) =
s()
val same = test()
@@ -0,0 +1,3 @@
package usage
fun other() {}
@@ -0,0 +1,7 @@
package usage
internal class Usage {
val inlined = inline.test()
val check = inline.same::class.java == inlined::class.java
}
@@ -0,0 +1,7 @@
package usage
internal class Usage {
private val inlined = inline.test()
private val check = inline.same::class.java == inlined::class.java
}