JPS: Fix JvmMultifileClass processing for IR backend
#KT-44644 Fixed
This commit is contained in:
@@ -94,6 +94,10 @@ open class IncrementalJvmCache(
|
||||
fun sourcesByInternalName(internalName: String): Collection<File> =
|
||||
internalNameToSource[internalName]
|
||||
|
||||
fun getAllPartsOfMultifileFacade(facade: JvmClassName): Collection<String>? {
|
||||
return multifileFacadeToParts[facade]
|
||||
}
|
||||
|
||||
fun isMultifileFacade(className: JvmClassName): Boolean =
|
||||
className in multifileFacadeToParts
|
||||
|
||||
|
||||
Generated
+5
@@ -2261,6 +2261,11 @@ public class IncrementalJvmJpsTestGenerated extends AbstractIncrementalJvmJpsTes
|
||||
runTest("jps-plugin/testData/incremental/withJava/other/multifilePartsWithProperties/");
|
||||
}
|
||||
|
||||
@TestMetadata("multifileDependantUsage")
|
||||
public void testMultifileDependantUsage() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/withJava/other/multifileDependantUsage/");
|
||||
}
|
||||
|
||||
@TestMetadata("optionalParameter")
|
||||
public void testOptionalParameter() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/withJava/other/optionalParameter/");
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.*
|
||||
import org.jetbrains.jps.incremental.java.JavaBuilder
|
||||
import org.jetbrains.jps.model.JpsProject
|
||||
import org.jetbrains.kotlin.build.GeneratedFile
|
||||
import org.jetbrains.kotlin.build.GeneratedJvmClass
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
@@ -48,6 +49,7 @@ import org.jetbrains.kotlin.jps.incremental.JpsLookupStorageManager
|
||||
import org.jetbrains.kotlin.jps.model.kotlinKind
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinJvmModuleBuildTarget
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.preloading.ClassCondition
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
@@ -439,6 +441,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
}
|
||||
|
||||
val generatedFiles = getGeneratedFiles(context, chunk, environment.outputItemsCollector)
|
||||
|
||||
markDirtyComplementaryMultifileClasses(generatedFiles, kotlinContext, incrementalCaches, fsOperations)
|
||||
|
||||
val kotlinTargets = kotlinContext.targetsBinding
|
||||
for ((target, outputItems) in generatedFiles) {
|
||||
val kotlinTarget = kotlinTargets[target] ?: error("Could not find Kotlin target for JPS target $target")
|
||||
@@ -526,14 +531,23 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
for (target in kotlinChunk.targets) {
|
||||
val cache = incrementalCaches[target]
|
||||
val jpsTarget = target.jpsModuleBuildTarget
|
||||
|
||||
val targetDirtyFiles = dirtyFilesHolder.byTarget[jpsTarget]
|
||||
|
||||
if (cache != null && targetDirtyFiles != null) {
|
||||
val complementaryFiles = cache.getComplementaryFilesRecursive(
|
||||
targetDirtyFiles.dirty.keys + targetDirtyFiles.removed
|
||||
)
|
||||
val dirtyFiles = targetDirtyFiles.dirty.keys + targetDirtyFiles.removed
|
||||
val complementaryFiles = cache.getComplementaryFilesRecursive(dirtyFiles)
|
||||
|
||||
fsOperations.markFilesForCurrentRound(jpsTarget, complementaryFiles)
|
||||
// Get all parts of @JvmMultifileClass file for simultaneous rebuild
|
||||
var dirtyMultifileClassFiles: Collection<File> = emptyList()
|
||||
if (cache is IncrementalJvmCache) {
|
||||
dirtyMultifileClassFiles = cache.classesBySources(dirtyFiles)
|
||||
.filter { cache.isMultifileFacade(it) }
|
||||
.flatMap { cache.getAllPartsOfMultifileFacade(it).orEmpty() }
|
||||
.flatMap { cache.sourcesByInternalName(it) }
|
||||
.distinct()
|
||||
.filter { !dirtyFiles.contains(it) }
|
||||
}
|
||||
fsOperations.markFilesForCurrentRound(jpsTarget, complementaryFiles + dirtyMultifileClassFiles)
|
||||
|
||||
cache.markDirty(targetDirtyFiles.dirty.keys + targetDirtyFiles.removed)
|
||||
}
|
||||
@@ -666,6 +680,28 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
lookupStorage.addAll(lookupTracker.lookups, lookupTracker.pathInterner.values)
|
||||
}
|
||||
}
|
||||
|
||||
private fun markDirtyComplementaryMultifileClasses(
|
||||
generatedFiles: Map<ModuleBuildTarget, List<GeneratedFile>>,
|
||||
kotlinContext: KotlinCompileContext,
|
||||
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>,
|
||||
fsOperations: FSOperationsHelper
|
||||
) {
|
||||
for ((target, files) in generatedFiles) {
|
||||
val kotlinModuleBuilderTarget = kotlinContext.targetsBinding[target] ?: continue
|
||||
val cache = incrementalCaches[kotlinModuleBuilderTarget] as? IncrementalJvmCache ?: continue
|
||||
val generated = files.filterIsInstance<GeneratedJvmClass>()
|
||||
val multifileClasses = generated.filter { it.outputClass.classHeader.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS }
|
||||
val expectedAllParts = multifileClasses.flatMap { cache.getAllPartsOfMultifileFacade(it.outputClass.className).orEmpty() }
|
||||
if (multifileClasses.isEmpty()) continue
|
||||
val actualParts = generated.filter { it.outputClass.classHeader.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS_PART }
|
||||
.map { it.outputClass.className.toString() }
|
||||
if (!actualParts.containsAll(expectedAllParts)) {
|
||||
fsOperations.markFiles(expectedAllParts.flatMap { cache.sourcesByInternalName(it) }
|
||||
+ multifileClasses.flatMap { it.sourceFiles })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class JpsICReporter : ICReporterBase() {
|
||||
|
||||
Vendored
+4
-3
@@ -5,7 +5,11 @@ Cleaning output files:
|
||||
out/production/module/test/Test.class
|
||||
out/production/module/test/Test__BKt.class
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/test/Test__AKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/a.kt
|
||||
src/b.kt
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
@@ -14,12 +18,9 @@ Exit code: ADDITIONAL_PASS_REQUIRED
|
||||
------------------------------------------
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/test/Test.class
|
||||
out/production/module/test/Test__AKt.class
|
||||
out/production/module/usage/UsageKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/a.kt
|
||||
src/usage.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
|
||||
+16
-1
@@ -3,5 +3,20 @@
|
||||
Compiling files:
|
||||
src/b.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
Marked as dirty by Kotlin:
|
||||
src/a.kt
|
||||
src/b.kt
|
||||
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||
------------------------------------------
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/test/Test.class
|
||||
out/production/module/test/Test__AKt.class
|
||||
out/production/module/test/Test__BKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/a.kt
|
||||
src/b.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
------------------------------------------
|
||||
+5
-1
@@ -5,8 +5,12 @@ Cleaning output files:
|
||||
out/production/module/test/Test.class
|
||||
out/production/module/test/Test__BKt.class
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/test/Test__AKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/a.kt
|
||||
src/b.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
------------------------------------------
|
||||
------------------------------------------
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
================ Step #1 =================
|
||||
|
||||
Marked as dirty by Kotlin:
|
||||
src/partB.kt
|
||||
src/usagePartB.kt
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/OuterClass$InnerClass.class
|
||||
out/production/module/OuterClass.class
|
||||
out/production/module/UsagePartBKt.class
|
||||
out/production/module/Utils.class
|
||||
out/production/module/Utils__PartBKt.class
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/Utils__PartAKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/partA.kt
|
||||
src/partB.kt
|
||||
src/usagePartB.kt
|
||||
End of files
|
||||
Exit code: ABORT
|
||||
------------------------------------------
|
||||
COMPILATION FAILED
|
||||
Unresolved reference: OuterClass
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
@file:JvmName("Utils")
|
||||
@file:JvmMultifileClass
|
||||
|
||||
val aVal: Int get() = 0
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
@file:JvmName("Utils")
|
||||
@file:JvmMultifileClass
|
||||
|
||||
val bVal: Int get() = 0
|
||||
|
||||
class OuterClass{
|
||||
inner class InnerClass {
|
||||
val getZero: Int get() = 0
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
@file:JvmName("Utils")
|
||||
@file:JvmMultifileClass
|
||||
|
||||
val bVal: Int get() = 0
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun zero() = OuterClass().InnerClass().getZero
|
||||
+7
-7
@@ -5,11 +5,16 @@ Cleaning output files:
|
||||
out/production/module/Utils.class
|
||||
out/production/module/Utils__PartBKt.class
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/Utils__PartAKt.class
|
||||
out/production/module/Utils__PartCKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/partA.kt
|
||||
src/partB.kt
|
||||
src/partC.kt
|
||||
End of files
|
||||
Marked as dirty by Kotlin:
|
||||
src/partA.kt
|
||||
src/useFooF.kt
|
||||
src/useFooG.kt
|
||||
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||
@@ -18,15 +23,10 @@ Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/UseFooFKt.class
|
||||
out/production/module/UseFooGKt.class
|
||||
out/production/module/Utils.class
|
||||
out/production/module/Utils__PartAKt.class
|
||||
out/production/module/Utils__PartCKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/partA.kt
|
||||
src/partC.kt
|
||||
src/useFooF.kt
|
||||
src/useFooG.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
------------------------------------------
|
||||
------------------------------------------
|
||||
+1
-7
@@ -5,18 +5,12 @@ Cleaning output files:
|
||||
out/production/module/Utils.class
|
||||
out/production/module/Utils__PartBKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/partB.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
------------------------------------------
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/Utils.class
|
||||
out/production/module/Utils__PartAKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/partA.kt
|
||||
src/partB.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
------------------------------------------
|
||||
@@ -86,11 +86,6 @@ org.jetbrains.kotlin.jps.build.IncrementalJvmJpsTestGenerated.Jvm.testCircularDe
|
||||
org.jetbrains.kotlin.jps.build.IncrementalJvmJpsTestGenerated.Jvm.testCircularDependencySamePackageUnchanged, Temporary muted due to problems with IC and JVM IR backend,,
|
||||
org.jetbrains.kotlin.jps.build.IncrementalJvmJpsTestGenerated.Jvm.testCircularDependencyTopLevelFunctions, Temporary muted due to problems with IC and JVM IR backend,,
|
||||
org.jetbrains.kotlin.jps.build.IncrementalJvmJpsTestGenerated.Jvm.testCircularDependencyWithAccessToInternal, Temporary muted due to problems with IC and JVM IR backend,,
|
||||
org.jetbrains.kotlin.jps.build.IncrementalJvmJpsTestGenerated.WithJava.Other.testMultifileClassAddTopLevelFunWithDefault, Temporary muted due to problems with IC and JVM IR backend,,
|
||||
org.jetbrains.kotlin.jps.build.IncrementalJvmJpsTestGenerated.WithJava.Other.testMultifileClassFileAdded, Temporary muted due to problems with IC and JVM IR backend,,
|
||||
org.jetbrains.kotlin.jps.build.IncrementalJvmJpsTestGenerated.WithJava.Other.testMultifileClassFileChanged, Temporary muted due to problems with IC and JVM IR backend,,
|
||||
org.jetbrains.kotlin.jps.build.IncrementalJvmJpsTestGenerated.WithJava.Other.testMultifilePackagePartMethodAdded, Temporary muted due to problems with IC and JVM IR backend,,
|
||||
org.jetbrains.kotlin.jps.build.IncrementalJvmJpsTestGenerated.WithJava.Other.testMultifilePartsWithProperties, Temporary muted due to problems with IC and JVM IR backend,,
|
||||
org.jetbrains.kotlin.jps.build.KotlinJpsBuildTest.testCircularDependenciesDifferentPackages, Temporary muted due to problems with IC and JVM IR backend,,
|
||||
org.jetbrains.kotlin.jps.build.KotlinJpsBuildTest.testCircularDependenciesSamePackage, Temporary muted due to problems with IC and JVM IR backend,,
|
||||
org.jetbrains.kotlin.jps.build.KotlinJpsBuildTest.testCircularDependenciesSamePackageWithTests, Temporary muted due to problems with IC and JVM IR backend,,
|
||||
|
||||
|
Reference in New Issue
Block a user