Test incremental facade to class conversion and vice versa
This commit is contained in:
@@ -84,8 +84,8 @@ open class IncrementalCacheImpl(
|
||||
private val protoMap = registerMap(ProtoMap(PROTO_MAP.storageFile))
|
||||
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
|
||||
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
|
||||
private val multifileClassFacadeMap = registerMap(MultifileClassFacadeMap(MULTIFILE_CLASS_FACADES.storageFile))
|
||||
private val multifileClassPartMap = registerMap(MultifileClassPartMap(MULTIFILE_CLASS_PARTS.storageFile))
|
||||
private val multifileFacadeToParts = registerMap(MultifileClassFacadeMap(MULTIFILE_CLASS_FACADES.storageFile))
|
||||
private val partToMultifileFacade = registerMap(MultifileClassPartMap(MULTIFILE_CLASS_PARTS.storageFile))
|
||||
private val sourceToClassesMap = registerMap(SourceToClassesMap(SOURCE_TO_CLASSES.storageFile))
|
||||
private val dirtyOutputClassesMap = registerMap(DirtyOutputClassesMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
||||
private val subtypesMap = registerExperimentalMap(SubtypesMap(SUBTYPES.storageFile))
|
||||
@@ -160,7 +160,12 @@ open class IncrementalCacheImpl(
|
||||
KotlinClassHeader.Kind.MULTIFILE_CLASS -> {
|
||||
val partNames = kotlinClass.classHeader.data?.toList()
|
||||
?: throw AssertionError("Multifile class has no parts: ${kotlinClass.className}")
|
||||
multifileClassFacadeMap.add(className, partNames)
|
||||
multifileFacadeToParts[className] = partNames
|
||||
// When a class is replaced with a facade with the same name,
|
||||
// the class' proto wouldn't ever be deleted,
|
||||
// because we don't write proto for multifile facades.
|
||||
// As a workaround we can remove proto values for multifile facades.
|
||||
protoMap.remove(className)
|
||||
|
||||
// TODO NO_CHANGES? (delegates only)
|
||||
constantsMap.process(kotlinClass) +
|
||||
@@ -169,7 +174,7 @@ open class IncrementalCacheImpl(
|
||||
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
|
||||
assert(sourceFiles.size == 1) { "Multifile class part from several source files: $sourceFiles" }
|
||||
packagePartMap.addPackagePart(className)
|
||||
multifileClassPartMap.add(className.internalName, header.multifileClassName!!)
|
||||
partToMultifileFacade.set(className.internalName, header.multifileClassName!!)
|
||||
|
||||
protoMap.process(kotlinClass, isPackage = true) +
|
||||
constantsMap.process(kotlinClass) +
|
||||
@@ -254,11 +259,31 @@ open class IncrementalCacheImpl(
|
||||
info + newInfo
|
||||
}
|
||||
|
||||
val facadesWithRemovedParts = hashMapOf<JvmClassName, MutableSet<String>>()
|
||||
for (dirtyClass in dirtyClasses) {
|
||||
val facade = partToMultifileFacade.get(dirtyClass.internalName) ?: continue
|
||||
val facadeClassName = JvmClassName.byInternalName(facade)
|
||||
val removedParts = facadesWithRemovedParts.getOrPut(facadeClassName) { hashSetOf() }
|
||||
removedParts.add(dirtyClass.internalName)
|
||||
}
|
||||
|
||||
for ((facade, removedParts) in facadesWithRemovedParts.entries) {
|
||||
val allParts = multifileFacadeToParts[facade.internalName] ?: continue
|
||||
val notRemovedParts = allParts.filter { it !in removedParts }
|
||||
|
||||
if (notRemovedParts.isEmpty()) {
|
||||
multifileFacadeToParts.remove(facade)
|
||||
}
|
||||
else {
|
||||
multifileFacadeToParts[facade] = notRemovedParts
|
||||
}
|
||||
}
|
||||
|
||||
dirtyClasses.forEach {
|
||||
protoMap.remove(it)
|
||||
packagePartMap.remove(it)
|
||||
multifileClassFacadeMap.remove(it)
|
||||
multifileClassPartMap.remove(it)
|
||||
multifileFacadeToParts.remove(it)
|
||||
partToMultifileFacade.remove(it)
|
||||
constantsMap.remove(it)
|
||||
}
|
||||
|
||||
@@ -289,7 +314,7 @@ open class IncrementalCacheImpl(
|
||||
override fun getObsoleteMultifileClasses(): Collection<String> {
|
||||
val obsoleteMultifileClasses = linkedSetOf<String>()
|
||||
for (dirtyClass in dirtyOutputClassesMap.getDirtyOutputClasses()) {
|
||||
val dirtyFacade = multifileClassPartMap.getFacadeName(dirtyClass) ?: continue
|
||||
val dirtyFacade = partToMultifileFacade.get(dirtyClass) ?: continue
|
||||
obsoleteMultifileClasses.add(dirtyFacade)
|
||||
}
|
||||
KotlinBuilder.LOG.debug("Obsolete multifile class facades: $obsoleteMultifileClasses")
|
||||
@@ -297,12 +322,12 @@ open class IncrementalCacheImpl(
|
||||
}
|
||||
|
||||
override fun getStableMultifileFacadeParts(facadeInternalName: String): Collection<String>? {
|
||||
val partNames = multifileClassFacadeMap.getMultifileClassParts(facadeInternalName) ?: return null
|
||||
val partNames = multifileFacadeToParts.get(facadeInternalName) ?: return null
|
||||
return partNames.filter { !dirtyOutputClassesMap.isDirty(it) }
|
||||
}
|
||||
|
||||
override fun getMultifileFacade(partInternalName: String): String? {
|
||||
return multifileClassPartMap.getFacadeName(partInternalName)
|
||||
return partToMultifileFacade.get(partInternalName)
|
||||
}
|
||||
|
||||
override fun getModuleMappingData(): ByteArray? {
|
||||
@@ -443,11 +468,11 @@ open class IncrementalCacheImpl(
|
||||
}
|
||||
|
||||
private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
|
||||
fun add(facadeName: JvmClassName, partNames: Collection<String>) {
|
||||
operator fun set(facadeName: JvmClassName, partNames: Collection<String>) {
|
||||
storage[facadeName.internalName] = partNames
|
||||
}
|
||||
|
||||
fun getMultifileClassParts(facadeName: String): Collection<String>? = storage[facadeName]
|
||||
operator fun get(facadeName: String): Collection<String>? = storage[facadeName]
|
||||
|
||||
fun remove(className: JvmClassName) {
|
||||
storage.remove(className.internalName)
|
||||
@@ -457,11 +482,11 @@ open class IncrementalCacheImpl(
|
||||
}
|
||||
|
||||
private inner class MultifileClassPartMap(storageFile: File) : BasicStringMap<String>(storageFile, EnumeratorStringDescriptor.INSTANCE) {
|
||||
fun add(partName: String, facadeName: String) {
|
||||
fun set(partName: String, facadeName: String) {
|
||||
storage[partName] = facadeName
|
||||
}
|
||||
|
||||
fun getFacadeName(partName: String): String? {
|
||||
fun get(partName: String): String? {
|
||||
return storage.get(partName)
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -1069,6 +1069,12 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classToPackageFacade")
|
||||
public void testClassToPackageFacade() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/classToPackageFacade/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("constructorVisibilityChanged")
|
||||
public void testConstructorVisibilityChanged() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/constructorVisibilityChanged/");
|
||||
@@ -1153,6 +1159,12 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("packageFacadeToClass")
|
||||
public void testPackageFacadeToClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/packageFacadeToClass/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("propertyNullabilityChanged")
|
||||
public void testPropertyNullabilityChanged() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/propertyNullabilityChanged/");
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
open class A {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun f() {}
|
||||
|
||||
@JvmStatic
|
||||
fun g() {}
|
||||
}
|
||||
|
||||
fun h() {}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class AChild : A() {
|
||||
fun j() {}
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
class AChild {
|
||||
fun j() {}
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
@file:JvmName("A")
|
||||
@file:JvmMultifileClass
|
||||
|
||||
fun f() {}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
@file:JvmName("A")
|
||||
@file:JvmMultifileClass
|
||||
|
||||
fun g() {}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
Cleaning output files:
|
||||
out/production/module/A$Companion.class
|
||||
out/production/module/A.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/APartF.kt
|
||||
src/APartG.kt
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/AChild.class
|
||||
out/production/module/GetAKt.class
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/UseFKt.class
|
||||
out/production/module/UseGKt.class
|
||||
out/production/module/UseHKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/AChild.kt
|
||||
src/getA.kt
|
||||
src/useF.kt
|
||||
src/useG.kt
|
||||
src/useH.kt
|
||||
End of files
|
||||
COMPILATION FAILED
|
||||
Unresolved reference: A
|
||||
Unresolved reference: A
|
||||
Unresolved reference: A
|
||||
Unresolved reference: A
|
||||
|
||||
|
||||
Cleaning output files:
|
||||
out/production/module/A.class
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/A__APartFKt.class
|
||||
out/production/module/A__APartGKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/AChild.kt
|
||||
src/APartF.kt
|
||||
src/APartG.kt
|
||||
src/useF.kt
|
||||
src/useG.kt
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/GetAChildKt.class
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/UseJKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/getAChild.kt
|
||||
src/useJ.kt
|
||||
End of files
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun getA() = A()
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
fun getAChild() = AChild()
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun useF() {
|
||||
A.f()
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun useF() {
|
||||
f()
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun useG() {
|
||||
A.g()
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun useG() {
|
||||
g()
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun useH() {
|
||||
getA().h()
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
fun useJ() {
|
||||
getAChild().j()
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun f() {}
|
||||
|
||||
@JvmStatic
|
||||
fun g() {}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class AA {
|
||||
companion object {
|
||||
fun f() {}
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
@file:JvmName("A")
|
||||
@file:JvmMultifileClass
|
||||
|
||||
fun f() {}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
@file:JvmName("A")
|
||||
@file:JvmMultifileClass
|
||||
|
||||
fun g() {}
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun f() {}
|
||||
|
||||
@JvmStatic
|
||||
fun g() {}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class UseFJava {
|
||||
void doUse() {
|
||||
A.f();
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
Cleaning output files:
|
||||
out/production/module/A.class
|
||||
out/production/module/A__APartFKt.class
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/A__APartGKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.kt
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/META-INF/module.kotlin_module
|
||||
out/production/module/UseFJava.class
|
||||
out/production/module/UseFKt.class
|
||||
out/production/module/UseGKt.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/useF.kt
|
||||
src/useG.kt
|
||||
End of files
|
||||
COMPILATION FAILED
|
||||
Unresolved reference: f
|
||||
Unresolved reference: g
|
||||
|
||||
|
||||
Cleaning output files:
|
||||
out/production/module/A.class
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/A$Companion.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.kt
|
||||
src/useF.kt
|
||||
src/useG.kt
|
||||
End of files
|
||||
Compiling files:
|
||||
src/UseFJava.java
|
||||
End of files
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun useAA() {
|
||||
AA.f()
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun useF() {
|
||||
f()
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun useF() {
|
||||
A.f()
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun useG() {
|
||||
g()
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun useG() {
|
||||
A.g()
|
||||
}
|
||||
Reference in New Issue
Block a user