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> =
|
fun sourcesByInternalName(internalName: String): Collection<File> =
|
||||||
internalNameToSource[internalName]
|
internalNameToSource[internalName]
|
||||||
|
|
||||||
|
fun getAllPartsOfMultifileFacade(facade: JvmClassName): Collection<String>? {
|
||||||
|
return multifileFacadeToParts[facade]
|
||||||
|
}
|
||||||
|
|
||||||
fun isMultifileFacade(className: JvmClassName): Boolean =
|
fun isMultifileFacade(className: JvmClassName): Boolean =
|
||||||
className in multifileFacadeToParts
|
className in multifileFacadeToParts
|
||||||
|
|
||||||
|
|||||||
Generated
+5
@@ -2261,6 +2261,11 @@ public class IncrementalJvmJpsTestGenerated extends AbstractIncrementalJvmJpsTes
|
|||||||
runTest("jps-plugin/testData/incremental/withJava/other/multifilePartsWithProperties/");
|
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")
|
@TestMetadata("optionalParameter")
|
||||||
public void testOptionalParameter() throws Exception {
|
public void testOptionalParameter() throws Exception {
|
||||||
runTest("jps-plugin/testData/incremental/withJava/other/optionalParameter/");
|
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.incremental.java.JavaBuilder
|
||||||
import org.jetbrains.jps.model.JpsProject
|
import org.jetbrains.jps.model.JpsProject
|
||||||
import org.jetbrains.kotlin.build.GeneratedFile
|
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.ExitCode
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
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.model.kotlinKind
|
||||||
import org.jetbrains.kotlin.jps.targets.KotlinJvmModuleBuildTarget
|
import org.jetbrains.kotlin.jps.targets.KotlinJvmModuleBuildTarget
|
||||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
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.name.FqName
|
||||||
import org.jetbrains.kotlin.preloading.ClassCondition
|
import org.jetbrains.kotlin.preloading.ClassCondition
|
||||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||||
@@ -439,6 +441,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val generatedFiles = getGeneratedFiles(context, chunk, environment.outputItemsCollector)
|
val generatedFiles = getGeneratedFiles(context, chunk, environment.outputItemsCollector)
|
||||||
|
|
||||||
|
markDirtyComplementaryMultifileClasses(generatedFiles, kotlinContext, incrementalCaches, fsOperations)
|
||||||
|
|
||||||
val kotlinTargets = kotlinContext.targetsBinding
|
val kotlinTargets = kotlinContext.targetsBinding
|
||||||
for ((target, outputItems) in generatedFiles) {
|
for ((target, outputItems) in generatedFiles) {
|
||||||
val kotlinTarget = kotlinTargets[target] ?: error("Could not find Kotlin target for JPS target $target")
|
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) {
|
for (target in kotlinChunk.targets) {
|
||||||
val cache = incrementalCaches[target]
|
val cache = incrementalCaches[target]
|
||||||
val jpsTarget = target.jpsModuleBuildTarget
|
val jpsTarget = target.jpsModuleBuildTarget
|
||||||
|
|
||||||
val targetDirtyFiles = dirtyFilesHolder.byTarget[jpsTarget]
|
val targetDirtyFiles = dirtyFilesHolder.byTarget[jpsTarget]
|
||||||
|
|
||||||
if (cache != null && targetDirtyFiles != null) {
|
if (cache != null && targetDirtyFiles != null) {
|
||||||
val complementaryFiles = cache.getComplementaryFilesRecursive(
|
val dirtyFiles = targetDirtyFiles.dirty.keys + targetDirtyFiles.removed
|
||||||
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)
|
cache.markDirty(targetDirtyFiles.dirty.keys + targetDirtyFiles.removed)
|
||||||
}
|
}
|
||||||
@@ -666,6 +680,28 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
|||||||
lookupStorage.addAll(lookupTracker.lookups, lookupTracker.pathInterner.values)
|
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() {
|
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.class
|
||||||
out/production/module/test/Test__BKt.class
|
out/production/module/test/Test__BKt.class
|
||||||
End of files
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/test/Test__AKt.class
|
||||||
|
End of files
|
||||||
Compiling files:
|
Compiling files:
|
||||||
|
src/a.kt
|
||||||
src/b.kt
|
src/b.kt
|
||||||
End of files
|
End of files
|
||||||
Marked as dirty by Kotlin:
|
Marked as dirty by Kotlin:
|
||||||
@@ -14,12 +18,9 @@ Exit code: ADDITIONAL_PASS_REQUIRED
|
|||||||
------------------------------------------
|
------------------------------------------
|
||||||
Cleaning output files:
|
Cleaning output files:
|
||||||
out/production/module/META-INF/module.kotlin_module
|
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
|
out/production/module/usage/UsageKt.class
|
||||||
End of files
|
End of files
|
||||||
Compiling files:
|
Compiling files:
|
||||||
src/a.kt
|
|
||||||
src/usage.kt
|
src/usage.kt
|
||||||
End of files
|
End of files
|
||||||
Exit code: OK
|
Exit code: OK
|
||||||
|
|||||||
+16
-1
@@ -3,5 +3,20 @@
|
|||||||
Compiling files:
|
Compiling files:
|
||||||
src/b.kt
|
src/b.kt
|
||||||
End of files
|
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.class
|
||||||
out/production/module/test/Test__BKt.class
|
out/production/module/test/Test__BKt.class
|
||||||
End of files
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/test/Test__AKt.class
|
||||||
|
End of files
|
||||||
Compiling files:
|
Compiling files:
|
||||||
|
src/a.kt
|
||||||
src/b.kt
|
src/b.kt
|
||||||
End of files
|
End of files
|
||||||
Exit code: OK
|
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.class
|
||||||
out/production/module/Utils__PartBKt.class
|
out/production/module/Utils__PartBKt.class
|
||||||
End of files
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/Utils__PartAKt.class
|
||||||
|
out/production/module/Utils__PartCKt.class
|
||||||
|
End of files
|
||||||
Compiling files:
|
Compiling files:
|
||||||
|
src/partA.kt
|
||||||
src/partB.kt
|
src/partB.kt
|
||||||
|
src/partC.kt
|
||||||
End of files
|
End of files
|
||||||
Marked as dirty by Kotlin:
|
Marked as dirty by Kotlin:
|
||||||
src/partA.kt
|
|
||||||
src/useFooF.kt
|
src/useFooF.kt
|
||||||
src/useFooG.kt
|
src/useFooG.kt
|
||||||
Exit code: ADDITIONAL_PASS_REQUIRED
|
Exit code: ADDITIONAL_PASS_REQUIRED
|
||||||
@@ -18,15 +23,10 @@ Cleaning output files:
|
|||||||
out/production/module/META-INF/module.kotlin_module
|
out/production/module/META-INF/module.kotlin_module
|
||||||
out/production/module/UseFooFKt.class
|
out/production/module/UseFooFKt.class
|
||||||
out/production/module/UseFooGKt.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
|
End of files
|
||||||
Compiling files:
|
Compiling files:
|
||||||
src/partA.kt
|
|
||||||
src/partC.kt
|
|
||||||
src/useFooF.kt
|
src/useFooF.kt
|
||||||
src/useFooG.kt
|
src/useFooG.kt
|
||||||
End of files
|
End of files
|
||||||
Exit code: OK
|
Exit code: OK
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
+1
-7
@@ -5,18 +5,12 @@ Cleaning output files:
|
|||||||
out/production/module/Utils.class
|
out/production/module/Utils.class
|
||||||
out/production/module/Utils__PartBKt.class
|
out/production/module/Utils__PartBKt.class
|
||||||
End of files
|
End of files
|
||||||
Compiling files:
|
|
||||||
src/partB.kt
|
|
||||||
End of files
|
|
||||||
Exit code: OK
|
|
||||||
------------------------------------------
|
|
||||||
Cleaning output files:
|
Cleaning output files:
|
||||||
out/production/module/META-INF/module.kotlin_module
|
|
||||||
out/production/module/Utils.class
|
|
||||||
out/production/module/Utils__PartAKt.class
|
out/production/module/Utils__PartAKt.class
|
||||||
End of files
|
End of files
|
||||||
Compiling files:
|
Compiling files:
|
||||||
src/partA.kt
|
src/partA.kt
|
||||||
|
src/partB.kt
|
||||||
End of files
|
End of files
|
||||||
Exit code: OK
|
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.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.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.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.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.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,,
|
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