Treat SEALED_SUBCLASS_FQ_NAME_LIST change as a class signature change

#KT-19580
This commit is contained in:
Alexey Tsvetkov
2017-08-09 22:15:38 +03:00
parent 856276328e
commit 6354d9d54f
39 changed files with 440 additions and 18 deletions
@@ -236,7 +236,15 @@ private class DifferenceCalculatorForClass(
isClassAffected = true
}
ProtoBufClassKind.SEALED_SUBCLASS_FQ_NAME_LIST -> {
// TODO
isClassAffected = true
// Subclasses are considered to be affected to fix the case where
// an implementation is added to an nth-level (n > 1) sealed class.
// In case of the following hierarchy:
// Base <- Intermediate <- Impl
// the change of the SEALED_SUBCLASS_FQ_NAME_LIST will be detected in the Intermediate,
// but there can be usages, that should be rebuilt, without direct references to the Intermediate:
// when (x as Base) { is Impl -> ... }
areSubclassesAffected = true
}
ProtoBufClassKind.TYPE_TABLE -> {
// TODO
@@ -1580,6 +1580,18 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
doTest(fileName);
}
@TestMetadata("sealedClassIndirectImplAdded")
public void testSealedClassIndirectImplAdded() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/sealedClassIndirectImplAdded/");
doTest(fileName);
}
@TestMetadata("sealedClassNestedImplAdded")
public void testSealedClassNestedImplAdded() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/sealedClassNestedImplAdded/");
doTest(fileName);
}
@TestMetadata("secondaryConstructorAdded")
public void testSecondaryConstructorAdded() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/classHierarchyAffected/secondaryConstructorAdded/");
@@ -67,6 +67,42 @@ public class JsProtoComparisonTestGenerated extends AbstractJsProtoComparisonTes
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/classWithSuperTypeListChanged/");
doTest(fileName);
}
@TestMetadata("nestedClassSignatureChanged")
public void testNestedClassSignatureChanged() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/nestedClassSignatureChanged/");
doTest(fileName);
}
@TestMetadata("sealedClassImplAdded")
public void testSealedClassImplAdded() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplAdded/");
doTest(fileName);
}
@TestMetadata("sealedClassImplRemoved")
public void testSealedClassImplRemoved() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplRemoved/");
doTest(fileName);
}
@TestMetadata("sealedClassNestedImplAdded")
public void testSealedClassNestedImplAdded() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAdded/");
doTest(fileName);
}
@TestMetadata("sealedClassNestedImplAddedDeep")
public void testSealedClassNestedImplAddedDeep() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAddedDeep/");
doTest(fileName);
}
@TestMetadata("sealedClassNestedImplRemoved")
public void testSealedClassNestedImplRemoved() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplRemoved/");
doTest(fileName);
}
}
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange")
@@ -158,6 +194,12 @@ public class JsProtoComparisonTestGenerated extends AbstractJsProtoComparisonTes
doTest(fileName);
}
@TestMetadata("nestedClassMembersChanged")
public void testNestedClassMembersChanged() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/nestedClassMembersChanged/");
doTest(fileName);
}
@TestMetadata("sealedClassImplAdded")
public void testSealedClassImplAdded() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/sealedClassImplAdded/");
@@ -67,6 +67,42 @@ public class JvmProtoComparisonTestGenerated extends AbstractJvmProtoComparisonT
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/classWithSuperTypeListChanged/");
doTest(fileName);
}
@TestMetadata("nestedClassSignatureChanged")
public void testNestedClassSignatureChanged() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/nestedClassSignatureChanged/");
doTest(fileName);
}
@TestMetadata("sealedClassImplAdded")
public void testSealedClassImplAdded() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplAdded/");
doTest(fileName);
}
@TestMetadata("sealedClassImplRemoved")
public void testSealedClassImplRemoved() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplRemoved/");
doTest(fileName);
}
@TestMetadata("sealedClassNestedImplAdded")
public void testSealedClassNestedImplAdded() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAdded/");
doTest(fileName);
}
@TestMetadata("sealedClassNestedImplAddedDeep")
public void testSealedClassNestedImplAddedDeep() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAddedDeep/");
doTest(fileName);
}
@TestMetadata("sealedClassNestedImplRemoved")
public void testSealedClassNestedImplRemoved() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplRemoved/");
doTest(fileName);
}
}
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange")
@@ -158,6 +194,12 @@ public class JvmProtoComparisonTestGenerated extends AbstractJvmProtoComparisonT
doTest(fileName);
}
@TestMetadata("nestedClassMembersChanged")
public void testNestedClassMembersChanged() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/nestedClassMembersChanged/");
doTest(fileName);
}
@TestMetadata("sealedClassImplAdded")
public void testSealedClassImplAdded() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/sealedClassImplAdded/");
@@ -0,0 +1,9 @@
package test
class Base {
class Nested1 {
class Nested2 {
fun added() {}
}
}
}
@@ -0,0 +1,9 @@
package test
class Base {
class Nested1 {
class Nested2 {
fun removed() {}
}
}
}
@@ -0,0 +1,3 @@
PROTO DIFFERENCE in test/Base.Nested1.Nested2: FUNCTION_LIST
CHANGES in test/Base.Nested1.Nested2: MEMBERS
[added, removed]
@@ -0,0 +1,7 @@
package test
open class Base {
class Nested1 {
class Nested2
}
}
@@ -0,0 +1,7 @@
package test
open class Base {
class Nested1 {
class Nested2 : Base()
}
}
@@ -0,0 +1,2 @@
PROTO DIFFERENCE in test/Base.Nested1.Nested2: SUPERTYPE_LIST
CHANGES in test/Base.Nested1.Nested2: CLASS_SIGNATURE
@@ -0,0 +1,9 @@
package test
sealed class Base1
class Impl1 : Base1()
class Impl11 : Base1()
sealed class Base2
class Impl2 : Base2()
class Impl22 : Base2()
@@ -0,0 +1,8 @@
package test
sealed class Base1
class Impl1 : Base1()
sealed class Base2
class Impl2 : Base2()
class Impl22
@@ -0,0 +1,7 @@
ADDED test/Impl11
PROTO DIFFERENCE in test/Base1: SEALED_SUBCLASS_FQ_NAME_LIST
CHANGES in test/Base1: CLASS_SIGNATURE
PROTO DIFFERENCE in test/Base2: SEALED_SUBCLASS_FQ_NAME_LIST
CHANGES in test/Base2: CLASS_SIGNATURE
PROTO DIFFERENCE in test/Impl22: SUPERTYPE_LIST
CHANGES in test/Impl22: CLASS_SIGNATURE
@@ -0,0 +1,8 @@
package test
sealed class Base1
class Impl1 : Base1()
sealed class Base2
class Impl2 : Base2()
class Impl22
@@ -0,0 +1,9 @@
package test
sealed class Base1
class Impl1 : Base1()
class Impl11 : Base1()
sealed class Base2
class Impl2 : Base2()
class Impl22 : Base2()
@@ -0,0 +1,7 @@
REMOVED test/Impl11
PROTO DIFFERENCE in test/Base1: SEALED_SUBCLASS_FQ_NAME_LIST
CHANGES in test/Base1: CLASS_SIGNATURE
PROTO DIFFERENCE in test/Base2: SEALED_SUBCLASS_FQ_NAME_LIST
CHANGES in test/Base2: CLASS_SIGNATURE
PROTO DIFFERENCE in test/Impl22: SUPERTYPE_LIST
CHANGES in test/Impl22: CLASS_SIGNATURE
@@ -0,0 +1,12 @@
package test
sealed class Base1 {
class Nested1 : Base1()
class Nested2 : Base1()
}
sealed class Base2 {
class Nested1 : Base2()
class Nested2 : Base2()
}
@@ -0,0 +1,11 @@
package test
sealed class Base1 {
class Nested1 : Base1()
}
sealed class Base2 {
class Nested1 : Base2()
class Nested2
}
@@ -0,0 +1,8 @@
ADDED test/Base1.Nested2
PROTO DIFFERENCE in test/Base1: NESTED_CLASS_NAME_LIST, SEALED_SUBCLASS_FQ_NAME_LIST
CHANGES in test/Base1: CLASS_SIGNATURE, MEMBERS
[Nested2]
PROTO DIFFERENCE in test/Base2: SEALED_SUBCLASS_FQ_NAME_LIST
CHANGES in test/Base2: CLASS_SIGNATURE
PROTO DIFFERENCE in test/Base2.Nested2: SUPERTYPE_LIST
CHANGES in test/Base2.Nested2: CLASS_SIGNATURE
@@ -0,0 +1,22 @@
package test
sealed class Base1 {
sealed class Nested1 : Base1() {
sealed class Nested2 : Nested1() {
class Nested3 : Nested2()
}
}
}
sealed class Base2 {
sealed class Nested1 : Base2() {
class Nested2 : Nested1()
class Nested3 : Nested1()
}
}
sealed class Base3 {
sealed class Nested1 : Base3() {
class Nested2 : Nested1()
}
}
@@ -0,0 +1,19 @@
package test
sealed class Base1 {
sealed class Nested1 : Base1() {
sealed class Nested2 : Nested1()
}
}
sealed class Base2 {
sealed class Nested1 : Base2() {
class Nested2 : Nested1()
}
}
sealed class Base3 {
sealed class Nested1 : Base3() {
class Nested2
}
}
@@ -0,0 +1,12 @@
ADDED test/Base1.Nested1.Nested2.Nested3
ADDED test/Base2.Nested1.Nested3
PROTO DIFFERENCE in test/Base1.Nested1.Nested2: NESTED_CLASS_NAME_LIST, SEALED_SUBCLASS_FQ_NAME_LIST
CHANGES in test/Base1.Nested1.Nested2: CLASS_SIGNATURE, MEMBERS
[Nested3]
PROTO DIFFERENCE in test/Base2.Nested1: NESTED_CLASS_NAME_LIST, SEALED_SUBCLASS_FQ_NAME_LIST
CHANGES in test/Base2.Nested1: CLASS_SIGNATURE, MEMBERS
[Nested3]
PROTO DIFFERENCE in test/Base3.Nested1: SEALED_SUBCLASS_FQ_NAME_LIST
CHANGES in test/Base3.Nested1: CLASS_SIGNATURE
PROTO DIFFERENCE in test/Base3.Nested1.Nested2: SUPERTYPE_LIST
CHANGES in test/Base3.Nested1.Nested2: CLASS_SIGNATURE
@@ -0,0 +1,11 @@
package test
sealed class Base1 {
class Nested1 : Base1()
}
sealed class Base2 {
class Nested1 : Base2()
class Nested2
}
@@ -0,0 +1,12 @@
package test
sealed class Base1 {
class Nested1 : Base1()
class Nested2 : Base1()
}
sealed class Base2 {
class Nested1 : Base2()
class Nested2 : Base2()
}
@@ -0,0 +1,8 @@
REMOVED test/Base1.Nested2
PROTO DIFFERENCE in test/Base1: NESTED_CLASS_NAME_LIST, SEALED_SUBCLASS_FQ_NAME_LIST
CHANGES in test/Base1: CLASS_SIGNATURE, MEMBERS
[Nested2]
PROTO DIFFERENCE in test/Base2: SEALED_SUBCLASS_FQ_NAME_LIST
CHANGES in test/Base2: CLASS_SIGNATURE
PROTO DIFFERENCE in test/Base2.Nested2: SUPERTYPE_LIST
CHANGES in test/Base2.Nested2: CLASS_SIGNATURE
@@ -1,4 +1,4 @@
sealed class Base {
class A : Base()
class B : Base()
}
sealed class Base
class A : Base()
class B : Base()
@@ -1,5 +1,5 @@
sealed class Base {
class A : Base()
class B : Base()
class C : Base()
}
sealed class Base
class A : Base()
class B : Base()
class C : Base()
@@ -1,8 +1,8 @@
================ Step #1 =================
Cleaning output files:
out/production/module/Base$A.class
out/production/module/Base$B.class
out/production/module/A.class
out/production/module/B.class
out/production/module/Base.class
End of files
Compiling files:
@@ -27,14 +27,14 @@ COMPILATION FAILED
================ Step #2 =================
Cleaning output files:
out/production/module/Base$A.class
out/production/module/Base$B.class
out/production/module/Base$C.class
out/production/module/A.class
out/production/module/B.class
out/production/module/Base.class
out/production/module/C.class
End of files
Compiling files:
src/Base.kt
src/use.kt
End of files
Exit code: OK
------------------------------------------
------------------------------------------
@@ -1,5 +1,3 @@
import Base.*
fun use(x: Base): String =
when (x) {
is A -> "A"
@@ -0,0 +1,3 @@
sealed class Base
sealed class Intermediate : Base()
class Impl1 : Intermediate()
@@ -0,0 +1,4 @@
sealed class Base
sealed class Intermediate : Base()
class Impl1 : Intermediate()
class Impl2 : Intermediate()
@@ -0,0 +1,40 @@
================ Step #1 =================
Cleaning output files:
out/production/module/Base.class
out/production/module/Impl1.class
out/production/module/Intermediate.class
End of files
Compiling files:
src/Base.kt
End of files
Marked as dirty by Kotlin:
src/use.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
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
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
'when' expression must be exhaustive, add necessary 'is Impl2' branch or 'else' branch instead
================ Step #2 =================
Cleaning output files:
out/production/module/Base.class
out/production/module/Impl1.class
out/production/module/Impl2.class
out/production/module/Intermediate.class
End of files
Compiling files:
src/Base.kt
src/use.kt
End of files
Exit code: OK
------------------------------------------
@@ -0,0 +1,4 @@
fun use(x: Base): Int =
when (x) {
is Impl1 -> 1
}
@@ -0,0 +1,5 @@
fun use(x: Base): Int =
when (x) {
is Impl1 -> 1
is Impl2 -> 2
}
@@ -0,0 +1,4 @@
sealed class Base {
class A : Base()
class B : Base()
}
@@ -0,0 +1,5 @@
sealed class Base {
class A : Base()
class B : Base()
class C : Base()
}
@@ -0,0 +1,40 @@
================ Step #1 =================
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
Marked as dirty by Kotlin:
src/use.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
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
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
'when' expression must be exhaustive, add necessary 'is C' branch or 'else' branch instead
================ Step #2 =================
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
Exit code: OK
------------------------------------------
@@ -0,0 +1,7 @@
import Base.*
fun use(x: Base): String =
when (x) {
is A -> "A"
is B -> "B"
}
@@ -0,0 +1,8 @@
import Base.*
fun use(x: Base): String =
when (x) {
is A -> "A"
is B -> "B"
is C -> "C"
}