Recompile all sealed class usages when new derived class is added
This commit is contained in:
@@ -177,6 +177,7 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
|
|||||||
override fun difference(): Difference {
|
override fun difference(): Difference {
|
||||||
var isClassSignatureChanged = false
|
var isClassSignatureChanged = false
|
||||||
val names = hashSetOf<String>()
|
val names = hashSetOf<String>()
|
||||||
|
val classIsSealed = newProto.isSealed && oldProto.isSealed
|
||||||
|
|
||||||
fun Int.oldToNames() = names.add(oldNameResolver.getString(this))
|
fun Int.oldToNames() = names.add(oldNameResolver.getString(this))
|
||||||
fun Int.newToNames() = names.add(newNameResolver.getString(this))
|
fun Int.newToNames() = names.add(newNameResolver.getString(this))
|
||||||
@@ -193,8 +194,15 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
|
|||||||
if (oldProto.hasCompanionObjectName()) oldProto.companionObjectName.oldToNames()
|
if (oldProto.hasCompanionObjectName()) oldProto.companionObjectName.oldToNames()
|
||||||
if (newProto.hasCompanionObjectName()) newProto.companionObjectName.newToNames()
|
if (newProto.hasCompanionObjectName()) newProto.companionObjectName.newToNames()
|
||||||
}
|
}
|
||||||
ProtoBufClassKind.NESTED_CLASS_NAME_LIST ->
|
ProtoBufClassKind.NESTED_CLASS_NAME_LIST -> {
|
||||||
|
if (classIsSealed) {
|
||||||
|
// when class is sealed, adding an implementation can break exhaustive when expressions
|
||||||
|
// the workaround is to recompile all class usages
|
||||||
|
isClassSignatureChanged = true
|
||||||
|
}
|
||||||
|
|
||||||
names.addAll(calcDifferenceForNames(oldProto.nestedClassNameList, newProto.nestedClassNameList))
|
names.addAll(calcDifferenceForNames(oldProto.nestedClassNameList, newProto.nestedClassNameList))
|
||||||
|
}
|
||||||
ProtoBufClassKind.CONSTRUCTOR_LIST ->
|
ProtoBufClassKind.CONSTRUCTOR_LIST ->
|
||||||
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getConstructorList))
|
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getConstructorList))
|
||||||
ProtoBufClassKind.FUNCTION_LIST ->
|
ProtoBufClassKind.FUNCTION_LIST ->
|
||||||
@@ -255,3 +263,6 @@ private class DifferenceCalculatorForPackageFacade(oldData: ProtoMapValue, newDa
|
|||||||
return Difference(isClassSignatureChanged = false, changedMembersNames = names)
|
return Difference(isClassSignatureChanged = false, changedMembersNames = names)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val ProtoBuf.Class.isSealed: Boolean
|
||||||
|
get() = ProtoBuf.Modality.SEALED == Flags.MODALITY.get(flags)
|
||||||
|
|||||||
+6
@@ -1159,6 +1159,12 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("sealedClassImplAdded")
|
||||||
|
public void testSealedClassImplAdded() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/sealedClassImplAdded/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("starProjectionUpperBoundChanged")
|
@TestMetadata("starProjectionUpperBoundChanged")
|
||||||
public void testStarProjectionUpperBoundChanged() throws Exception {
|
public void testStarProjectionUpperBoundChanged() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/starProjectionUpperBoundChanged/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/starProjectionUpperBoundChanged/");
|
||||||
|
|||||||
@@ -159,6 +159,12 @@ public class ProtoComparisonTestGenerated extends AbstractProtoComparisonTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("sealedClassImplAdded")
|
||||||
|
public void testSealedClassImplAdded() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/sealedClassImplAdded/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers")
|
@TestMetadata("jps-plugin/testData/comparison/packageMembers")
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
sealed class Base {
|
||||||
|
class A : Base()
|
||||||
|
class B : Base()
|
||||||
|
class C : Base()
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
sealed class Base {
|
||||||
|
class A : Base()
|
||||||
|
class B : Base()
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
ADDED: class Base$C.class
|
||||||
|
changes in test/Base.A: NONE
|
||||||
|
changes in test/Base.B: NONE
|
||||||
|
changes in test/Base: CLASS_SIGNATURE, MEMBERS
|
||||||
|
[C]
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
sealed class Base {
|
||||||
|
class A : Base()
|
||||||
|
class B : Base()
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
sealed class Base {
|
||||||
|
class A : Base()
|
||||||
|
class B : Base()
|
||||||
|
class C : Base()
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
Cleaning output files:
|
||||||
|
out/production/module/Base$A.class
|
||||||
|
out/production/module/Base$B.class
|
||||||
|
out/production/module/Base.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/Base.kt
|
||||||
|
End of files
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/UseKt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/use.kt
|
||||||
|
End of files
|
||||||
|
COMPILATION FAILED
|
||||||
|
'when' expression must be exhaustive or contain an 'else' branch
|
||||||
|
|
||||||
|
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/Base$A.class
|
||||||
|
out/production/module/Base$B.class
|
||||||
|
out/production/module/Base$C.class
|
||||||
|
out/production/module/Base.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/Base.kt
|
||||||
|
src/use.kt
|
||||||
|
End of files
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
import Base.*
|
||||||
|
|
||||||
|
fun use(x: Base): String =
|
||||||
|
when (x) {
|
||||||
|
is A -> "A"
|
||||||
|
is B -> "B"
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
import Base.*
|
||||||
|
|
||||||
|
fun use(x: Base): String =
|
||||||
|
when (x) {
|
||||||
|
is A -> "A"
|
||||||
|
is B -> "B"
|
||||||
|
is C -> "C"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user