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 protoMap = registerMap(ProtoMap(PROTO_MAP.storageFile))
|
||||||
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
|
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
|
||||||
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
|
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
|
||||||
private val multifileClassFacadeMap = registerMap(MultifileClassFacadeMap(MULTIFILE_CLASS_FACADES.storageFile))
|
private val multifileFacadeToParts = registerMap(MultifileClassFacadeMap(MULTIFILE_CLASS_FACADES.storageFile))
|
||||||
private val multifileClassPartMap = registerMap(MultifileClassPartMap(MULTIFILE_CLASS_PARTS.storageFile))
|
private val partToMultifileFacade = registerMap(MultifileClassPartMap(MULTIFILE_CLASS_PARTS.storageFile))
|
||||||
private val sourceToClassesMap = registerMap(SourceToClassesMap(SOURCE_TO_CLASSES.storageFile))
|
private val sourceToClassesMap = registerMap(SourceToClassesMap(SOURCE_TO_CLASSES.storageFile))
|
||||||
private val dirtyOutputClassesMap = registerMap(DirtyOutputClassesMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
private val dirtyOutputClassesMap = registerMap(DirtyOutputClassesMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
||||||
private val subtypesMap = registerExperimentalMap(SubtypesMap(SUBTYPES.storageFile))
|
private val subtypesMap = registerExperimentalMap(SubtypesMap(SUBTYPES.storageFile))
|
||||||
@@ -160,7 +160,12 @@ open class IncrementalCacheImpl(
|
|||||||
KotlinClassHeader.Kind.MULTIFILE_CLASS -> {
|
KotlinClassHeader.Kind.MULTIFILE_CLASS -> {
|
||||||
val partNames = kotlinClass.classHeader.data?.toList()
|
val partNames = kotlinClass.classHeader.data?.toList()
|
||||||
?: throw AssertionError("Multifile class has no parts: ${kotlinClass.className}")
|
?: 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)
|
// TODO NO_CHANGES? (delegates only)
|
||||||
constantsMap.process(kotlinClass) +
|
constantsMap.process(kotlinClass) +
|
||||||
@@ -169,7 +174,7 @@ open class IncrementalCacheImpl(
|
|||||||
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
|
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
|
||||||
assert(sourceFiles.size == 1) { "Multifile class part from several source files: $sourceFiles" }
|
assert(sourceFiles.size == 1) { "Multifile class part from several source files: $sourceFiles" }
|
||||||
packagePartMap.addPackagePart(className)
|
packagePartMap.addPackagePart(className)
|
||||||
multifileClassPartMap.add(className.internalName, header.multifileClassName!!)
|
partToMultifileFacade.set(className.internalName, header.multifileClassName!!)
|
||||||
|
|
||||||
protoMap.process(kotlinClass, isPackage = true) +
|
protoMap.process(kotlinClass, isPackage = true) +
|
||||||
constantsMap.process(kotlinClass) +
|
constantsMap.process(kotlinClass) +
|
||||||
@@ -254,11 +259,31 @@ open class IncrementalCacheImpl(
|
|||||||
info + newInfo
|
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 {
|
dirtyClasses.forEach {
|
||||||
protoMap.remove(it)
|
protoMap.remove(it)
|
||||||
packagePartMap.remove(it)
|
packagePartMap.remove(it)
|
||||||
multifileClassFacadeMap.remove(it)
|
multifileFacadeToParts.remove(it)
|
||||||
multifileClassPartMap.remove(it)
|
partToMultifileFacade.remove(it)
|
||||||
constantsMap.remove(it)
|
constantsMap.remove(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,7 +314,7 @@ open class IncrementalCacheImpl(
|
|||||||
override fun getObsoleteMultifileClasses(): Collection<String> {
|
override fun getObsoleteMultifileClasses(): Collection<String> {
|
||||||
val obsoleteMultifileClasses = linkedSetOf<String>()
|
val obsoleteMultifileClasses = linkedSetOf<String>()
|
||||||
for (dirtyClass in dirtyOutputClassesMap.getDirtyOutputClasses()) {
|
for (dirtyClass in dirtyOutputClassesMap.getDirtyOutputClasses()) {
|
||||||
val dirtyFacade = multifileClassPartMap.getFacadeName(dirtyClass) ?: continue
|
val dirtyFacade = partToMultifileFacade.get(dirtyClass) ?: continue
|
||||||
obsoleteMultifileClasses.add(dirtyFacade)
|
obsoleteMultifileClasses.add(dirtyFacade)
|
||||||
}
|
}
|
||||||
KotlinBuilder.LOG.debug("Obsolete multifile class facades: $obsoleteMultifileClasses")
|
KotlinBuilder.LOG.debug("Obsolete multifile class facades: $obsoleteMultifileClasses")
|
||||||
@@ -297,12 +322,12 @@ open class IncrementalCacheImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getStableMultifileFacadeParts(facadeInternalName: String): Collection<String>? {
|
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) }
|
return partNames.filter { !dirtyOutputClassesMap.isDirty(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMultifileFacade(partInternalName: String): String? {
|
override fun getMultifileFacade(partInternalName: String): String? {
|
||||||
return multifileClassPartMap.getFacadeName(partInternalName)
|
return partToMultifileFacade.get(partInternalName)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getModuleMappingData(): ByteArray? {
|
override fun getModuleMappingData(): ByteArray? {
|
||||||
@@ -443,11 +468,11 @@ open class IncrementalCacheImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
|
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
|
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) {
|
fun remove(className: JvmClassName) {
|
||||||
storage.remove(className.internalName)
|
storage.remove(className.internalName)
|
||||||
@@ -457,11 +482,11 @@ open class IncrementalCacheImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private inner class MultifileClassPartMap(storageFile: File) : BasicStringMap<String>(storageFile, EnumeratorStringDescriptor.INSTANCE) {
|
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
|
storage[partName] = facadeName
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFacadeName(partName: String): String? {
|
fun get(partName: String): String? {
|
||||||
return storage.get(partName)
|
return storage.get(partName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
@@ -1069,6 +1069,12 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("classToPackageFacade")
|
||||||
|
public void testClassToPackageFacade() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/classToPackageFacade/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("constructorVisibilityChanged")
|
@TestMetadata("constructorVisibilityChanged")
|
||||||
public void testConstructorVisibilityChanged() throws Exception {
|
public void testConstructorVisibilityChanged() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/constructorVisibilityChanged/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/constructorVisibilityChanged/");
|
||||||
@@ -1153,6 +1159,12 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("packageFacadeToClass")
|
||||||
|
public void testPackageFacadeToClass() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/packageFacadeToClass/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("propertyNullabilityChanged")
|
@TestMetadata("propertyNullabilityChanged")
|
||||||
public void testPropertyNullabilityChanged() throws Exception {
|
public void testPropertyNullabilityChanged() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/propertyNullabilityChanged/");
|
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