Allow Native @Throws on override when the same list is specified
This commit is contained in:
+120
-4
@@ -11,16 +11,36 @@ class Exception3 : Throwable()
|
||||
<!THROWS_LIST_EMPTY!>@Throws<!>
|
||||
fun foo() {}
|
||||
|
||||
interface Base0 {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
class ThrowsOnOverride : Base0 {
|
||||
<!INCOMPATIBLE_THROWS_OVERRIDE!>@Throws(Exception1::class)<!> override fun foo() {}
|
||||
}
|
||||
|
||||
interface Base1 {
|
||||
@Throws(Exception1::class) fun foo()
|
||||
}
|
||||
|
||||
class HasThrowsOnOverride : Base1 {
|
||||
<!THROWS_ON_OVERRIDE!>@Throws(Exception1::class)<!> override fun foo() {}
|
||||
class InheritsThrowsAndNoThrows : Base0, Base1 {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>override fun foo() {}<!>
|
||||
}
|
||||
|
||||
class OverridesThrowsAndNoThrows : Base0, Base1 {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>@Throws(Exception1::class) override fun foo() {}<!>
|
||||
}
|
||||
|
||||
class SameThrowsOnOverride : Base1 {
|
||||
@Throws(Exception1::class) override fun foo() {}
|
||||
}
|
||||
|
||||
class DifferentThrowsOnOverride : Base1 {
|
||||
<!INCOMPATIBLE_THROWS_OVERRIDE!>@Throws(Exception2::class)<!> override fun foo() {}
|
||||
}
|
||||
|
||||
class HasThrowsWithEmptyListOnOverride : Base1 {
|
||||
<!THROWS_ON_OVERRIDE!>@Throws<!> override fun foo() {}
|
||||
<!INCOMPATIBLE_THROWS_OVERRIDE!>@Throws<!> override fun foo() {}
|
||||
}
|
||||
|
||||
interface Base2 {
|
||||
@@ -31,8 +51,28 @@ open class InheritsDifferentThrows1 : Base1, Base2 {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>override fun foo() {}<!>
|
||||
}
|
||||
|
||||
open class OverridesDifferentThrows1_1 : Base1, Base2 {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>@Throws(Exception1::class) override fun foo() {}<!>
|
||||
}
|
||||
|
||||
open class OverridesDifferentThrows1_2 : Base1, Base2 {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>@Throws(Exception2::class) override fun foo() {}<!>
|
||||
}
|
||||
|
||||
open class OverridesDifferentThrows1_3 : Base1, Base2 {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>@Throws(Exception1::class, Exception2::class) override fun foo() {}<!>
|
||||
}
|
||||
|
||||
class InheritsDifferentThrowsThroughSameClass1 : InheritsDifferentThrows1() {
|
||||
override fun foo() {}
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>override fun foo() {}<!>
|
||||
}
|
||||
|
||||
class OverridesDifferentThrowsThroughSameClass1 : InheritsDifferentThrows1() {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>@Throws(Exception1::class) override fun foo() {}<!>
|
||||
}
|
||||
|
||||
class OverridesDifferentThrowsThroughSameClass2 : InheritsDifferentThrows1() {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>@Throws(Exception2::class) override fun foo() {}<!>
|
||||
}
|
||||
|
||||
interface Base3 {
|
||||
@@ -43,6 +83,30 @@ class InheritsDifferentThrows2 : InheritsDifferentThrows1(), Base3 {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>override fun foo() {}<!>
|
||||
}
|
||||
|
||||
class OverridesDifferentThrows2 : InheritsDifferentThrows1(), Base3 {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>@Throws(Exception3::class) override fun foo() {}<!>
|
||||
}
|
||||
|
||||
open class OverridesDifferentThrows3 : Base1, Base2 {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>@Throws(Exception3::class) override fun foo() {}<!>
|
||||
}
|
||||
|
||||
class InheritsDifferentThrows3 : OverridesDifferentThrows3() {
|
||||
override fun foo() {}
|
||||
}
|
||||
|
||||
class OverrideDifferentThrows4 : OverridesDifferentThrows3() {
|
||||
override fun foo() {}
|
||||
}
|
||||
|
||||
class OverrideDifferentThrows5 : OverridesDifferentThrows3() {
|
||||
@Throws(Exception3::class) override fun foo() {}
|
||||
}
|
||||
|
||||
class OverrideDifferentThrows6 : OverridesDifferentThrows3() {
|
||||
<!INCOMPATIBLE_THROWS_OVERRIDE!>@Throws(Exception1::class)<!> override fun foo() {}
|
||||
}
|
||||
|
||||
interface Base4 {
|
||||
@Throws(Exception1::class) fun foo()
|
||||
}
|
||||
@@ -51,6 +115,18 @@ class InheritsSameThrows : Base1, Base4 {
|
||||
override fun foo() {}
|
||||
}
|
||||
|
||||
class OverridesSameThrows : Base1, Base4 {
|
||||
@Throws(Exception1::class) override fun foo() {}
|
||||
}
|
||||
|
||||
class OverrideDifferentThrows7 : Base1, Base4 {
|
||||
<!INCOMPATIBLE_THROWS_OVERRIDE!>@Throws(Exception2::class)<!> override fun foo() {}
|
||||
}
|
||||
|
||||
class OverrideDifferentThrows8 : Base1, Base3 {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>@Throws(Exception2::class) override fun foo() {}<!>
|
||||
}
|
||||
|
||||
interface Base5 {
|
||||
@Throws(Exception1::class, Exception2::class) fun foo()
|
||||
}
|
||||
@@ -63,6 +139,18 @@ class InheritsSameThrowsMultiple : Base5, Base6 {
|
||||
override fun foo() {}
|
||||
}
|
||||
|
||||
class OverridesSameThrowsMultiple1 : Base5, Base6 {
|
||||
@Throws(Exception1::class, Exception2::class) override fun foo() {}
|
||||
}
|
||||
|
||||
class OverridesSameThrowsMultiple2 : Base5, Base6 {
|
||||
@Throws(Exception2::class, Exception1::class) override fun foo() {}
|
||||
}
|
||||
|
||||
class OverridesDifferentThrowsMultiple : Base5, Base6 {
|
||||
<!INCOMPATIBLE_THROWS_OVERRIDE!>@Throws(Exception1::class)<!> override fun foo() {}
|
||||
}
|
||||
|
||||
fun withLocalClass() {
|
||||
class LocalException : Throwable()
|
||||
|
||||
@@ -73,4 +161,32 @@ fun withLocalClass() {
|
||||
class InheritsDifferentThrowsLocal : Base1, Base7() {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>override fun foo() {}<!>
|
||||
}
|
||||
|
||||
class OverridesDifferentThrowsLocal : Base1, Base7() {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>@Throws(Exception1::class, LocalException::class) override fun foo() {}<!>
|
||||
}
|
||||
}
|
||||
|
||||
interface ThrowsOnFakeOverride : Base1
|
||||
|
||||
class InheritThrowsOnFakeOverride : ThrowsOnFakeOverride {
|
||||
override fun foo() {}
|
||||
}
|
||||
|
||||
class OverrideDifferentThrowsOnFakeOverride : ThrowsOnFakeOverride {
|
||||
<!INCOMPATIBLE_THROWS_OVERRIDE!>@Throws(Exception2::class)<!> override fun foo() {}
|
||||
}
|
||||
|
||||
interface IncompatibleThrowsOnFakeOverride : Base1, Base2
|
||||
|
||||
class OverrideIncompatibleThrowsOnFakeOverride1 : IncompatibleThrowsOnFakeOverride {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>@Throws(Exception1::class) override fun foo() {}<!>
|
||||
}
|
||||
|
||||
class OverrideIncompatibleThrowsOnFakeOverride2 : IncompatibleThrowsOnFakeOverride {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>@Throws(Exception2::class) override fun foo() {}<!>
|
||||
}
|
||||
|
||||
class InheritIncompatibleThrowsOnFakeOverride : IncompatibleThrowsOnFakeOverride {
|
||||
<!INCOMPATIBLE_THROWS_INHERITED!>override fun foo() {}<!>
|
||||
}
|
||||
|
||||
+237
-8
@@ -3,6 +3,13 @@ package
|
||||
@kotlin.native.Throws(exceptionClasses = {}) public fun foo(): kotlin.Unit
|
||||
public fun withLocalClass(): kotlin.Unit
|
||||
|
||||
public interface Base0 {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public abstract fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface Base1 {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public abstract fun foo(): kotlin.Unit
|
||||
@@ -45,6 +52,14 @@ public interface Base6 {
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class DifferentThrowsOnOverride : Base1 {
|
||||
public constructor DifferentThrowsOnOverride()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception2::class}) public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class Exception1 : kotlin.Throwable {
|
||||
public constructor Exception1()
|
||||
public open override /*1*/ /*fake_override*/ val cause: kotlin.Throwable?
|
||||
@@ -72,14 +87,6 @@ public final class Exception3 : kotlin.Throwable {
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class HasThrowsOnOverride : Base1 {
|
||||
public constructor HasThrowsOnOverride()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class HasThrowsWithEmptyListOnOverride : Base1 {
|
||||
public constructor HasThrowsWithEmptyListOnOverride()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@@ -88,6 +95,29 @@ public final class HasThrowsWithEmptyListOnOverride : Base1 {
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface IncompatibleThrowsOnFakeOverride : Base1, Base2 {
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public abstract override /*2*/ /*fake_override*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class InheritIncompatibleThrowsOnFakeOverride : IncompatibleThrowsOnFakeOverride {
|
||||
public constructor InheritIncompatibleThrowsOnFakeOverride()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class InheritThrowsOnFakeOverride : ThrowsOnFakeOverride {
|
||||
public constructor InheritThrowsOnFakeOverride()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class InheritsDifferentThrows1 : Base1, Base2 {
|
||||
public constructor InheritsDifferentThrows1()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@@ -104,6 +134,14 @@ public final class InheritsDifferentThrows2 : InheritsDifferentThrows1, Base3 {
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class InheritsDifferentThrows3 : OverridesDifferentThrows3 {
|
||||
public constructor InheritsDifferentThrows3()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class InheritsDifferentThrowsThroughSameClass1 : InheritsDifferentThrows1 {
|
||||
public constructor InheritsDifferentThrowsThroughSameClass1()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@@ -128,6 +166,197 @@ public final class InheritsSameThrowsMultiple : Base5, Base6 {
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class InheritsThrowsAndNoThrows : Base0, Base1 {
|
||||
public constructor InheritsThrowsAndNoThrows()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverrideDifferentThrows4 : OverridesDifferentThrows3 {
|
||||
public constructor OverrideDifferentThrows4()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverrideDifferentThrows5 : OverridesDifferentThrows3 {
|
||||
public constructor OverrideDifferentThrows5()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception3::class}) public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverrideDifferentThrows6 : OverridesDifferentThrows3 {
|
||||
public constructor OverrideDifferentThrows6()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverrideDifferentThrows7 : Base1, Base4 {
|
||||
public constructor OverrideDifferentThrows7()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception2::class}) public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverrideDifferentThrows8 : Base1, Base3 {
|
||||
public constructor OverrideDifferentThrows8()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception2::class}) public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverrideDifferentThrowsOnFakeOverride : ThrowsOnFakeOverride {
|
||||
public constructor OverrideDifferentThrowsOnFakeOverride()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception2::class}) public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverrideIncompatibleThrowsOnFakeOverride1 : IncompatibleThrowsOnFakeOverride {
|
||||
public constructor OverrideIncompatibleThrowsOnFakeOverride1()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverrideIncompatibleThrowsOnFakeOverride2 : IncompatibleThrowsOnFakeOverride {
|
||||
public constructor OverrideIncompatibleThrowsOnFakeOverride2()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception2::class}) public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class OverridesDifferentThrows1_1 : Base1, Base2 {
|
||||
public constructor OverridesDifferentThrows1_1()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class OverridesDifferentThrows1_2 : Base1, Base2 {
|
||||
public constructor OverridesDifferentThrows1_2()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception2::class}) public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class OverridesDifferentThrows1_3 : Base1, Base2 {
|
||||
public constructor OverridesDifferentThrows1_3()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class, Exception2::class}) public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverridesDifferentThrows2 : InheritsDifferentThrows1, Base3 {
|
||||
public constructor OverridesDifferentThrows2()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception3::class}) public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class OverridesDifferentThrows3 : Base1, Base2 {
|
||||
public constructor OverridesDifferentThrows3()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception3::class}) public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverridesDifferentThrowsMultiple : Base5, Base6 {
|
||||
public constructor OverridesDifferentThrowsMultiple()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverridesDifferentThrowsThroughSameClass1 : InheritsDifferentThrows1 {
|
||||
public constructor OverridesDifferentThrowsThroughSameClass1()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverridesDifferentThrowsThroughSameClass2 : InheritsDifferentThrows1 {
|
||||
public constructor OverridesDifferentThrowsThroughSameClass2()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception2::class}) public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverridesSameThrows : Base1, Base4 {
|
||||
public constructor OverridesSameThrows()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverridesSameThrowsMultiple1 : Base5, Base6 {
|
||||
public constructor OverridesSameThrowsMultiple1()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class, Exception2::class}) public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverridesSameThrowsMultiple2 : Base5, Base6 {
|
||||
public constructor OverridesSameThrowsMultiple2()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception2::class, Exception1::class}) public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class OverridesThrowsAndNoThrows : Base0, Base1 {
|
||||
public constructor OverridesThrowsAndNoThrows()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public open override /*2*/ fun foo(): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class SameThrowsOnOverride : Base1 {
|
||||
public constructor SameThrowsOnOverride()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface ThrowsOnFakeOverride : Base1 {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public abstract override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class ThrowsOnOverride : Base0 {
|
||||
public constructor ThrowsOnOverride()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
@kotlin.native.Throws(exceptionClasses = {Exception1::class}) public open override /*1*/ fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
package kotlin {
|
||||
|
||||
package kotlin.native {
|
||||
|
||||
+4
-1
@@ -12,7 +12,10 @@ import org.jetbrains.kotlin.diagnostics.rendering.Renderers
|
||||
private val DIAGNOSTIC_FACTORY_TO_RENDERER by lazy {
|
||||
DiagnosticFactoryToRendererMap("Native").apply {
|
||||
put(ErrorsNative.THROWS_LIST_EMPTY, "@Throws must have non-empty class list")
|
||||
put(ErrorsNative.THROWS_ON_OVERRIDE, "@Throws is prohibited for overridden members")
|
||||
put(
|
||||
ErrorsNative.INCOMPATIBLE_THROWS_OVERRIDE, "Member overrides different @Throws filter from {0}",
|
||||
Renderers.NAME
|
||||
)
|
||||
put(
|
||||
ErrorsNative.INCOMPATIBLE_THROWS_INHERITED, "Member inherits different @Throws filters from {0}",
|
||||
Renderers.commaSeparated(Renderers.NAME)
|
||||
|
||||
@@ -17,7 +17,7 @@ object ErrorsNative {
|
||||
@JvmField
|
||||
val THROWS_LIST_EMPTY = DiagnosticFactory0.create<KtElement>(Severity.ERROR)
|
||||
@JvmField
|
||||
val THROWS_ON_OVERRIDE = DiagnosticFactory0.create<KtElement>(Severity.ERROR)
|
||||
val INCOMPATIBLE_THROWS_OVERRIDE = DiagnosticFactory1.create<KtElement, DeclarationDescriptor>(Severity.ERROR)
|
||||
@JvmField
|
||||
val INCOMPATIBLE_THROWS_INHERITED = DiagnosticFactory1.create<KtDeclaration, Collection<DeclarationDescriptor>>(Severity.ERROR)
|
||||
|
||||
|
||||
+58
-20
@@ -11,48 +11,81 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgument
|
||||
import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
|
||||
object NativeThrowsChecker : DeclarationChecker {
|
||||
private val throwsFqName = FqName("kotlin.native.Throws")
|
||||
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
checkForIncompatibleMultipleInheritance(declaration, descriptor, context)
|
||||
val throwsAnnotation = descriptor.annotations.findAnnotation(throwsFqName)
|
||||
val reportLocation = throwsAnnotation?.let { DescriptorToSourceUtils.getSourceFromAnnotation(it) } ?: declaration
|
||||
|
||||
val throwsAnnotation = descriptor.annotations.findAnnotation(throwsFqName) ?: return
|
||||
val element = DescriptorToSourceUtils.getSourceFromAnnotation(throwsAnnotation) ?: declaration
|
||||
if (!checkInheritance(declaration, descriptor, context, throwsAnnotation, reportLocation)) return
|
||||
|
||||
if (descriptor is CallableMemberDescriptor && descriptor.overriddenDescriptors.isNotEmpty()) {
|
||||
context.trace.report(ErrorsNative.THROWS_ON_OVERRIDE.on(element))
|
||||
return
|
||||
}
|
||||
|
||||
if (throwsAnnotation.getVariadicArguments().isEmpty()) {
|
||||
context.trace.report(ErrorsNative.THROWS_LIST_EMPTY.on(element))
|
||||
if (throwsAnnotation != null && throwsAnnotation.getVariadicArguments().isEmpty()) {
|
||||
context.trace.report(ErrorsNative.THROWS_LIST_EMPTY.on(reportLocation))
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkForIncompatibleMultipleInheritance(
|
||||
private fun checkInheritance(
|
||||
declaration: KtDeclaration,
|
||||
descriptor: DeclarationDescriptor,
|
||||
context: DeclarationCheckerContext
|
||||
) {
|
||||
if (descriptor !is CallableMemberDescriptor) return
|
||||
context: DeclarationCheckerContext,
|
||||
throwsAnnotation: AnnotationDescriptor?,
|
||||
reportLocation: KtElement
|
||||
): Boolean {
|
||||
if (descriptor !is CallableMemberDescriptor || descriptor.overriddenDescriptors.isEmpty()) return true
|
||||
|
||||
if (descriptor.overriddenDescriptors.size < 2) return // No multiple inheritance here.
|
||||
val inherited = findInheritedThrows(descriptor).entries.distinctBy { it.value }
|
||||
|
||||
val incompatible = descriptor.findOriginalTopMostOverriddenDescriptors()
|
||||
.distinctBy { it.annotations.findAnnotation(throwsFqName)?.getVariadicArguments()?.toSet() }
|
||||
if (inherited.size >= 2) {
|
||||
context.trace.report(ErrorsNative.INCOMPATIBLE_THROWS_INHERITED.on(declaration, inherited.map { it.key.containingDeclaration }))
|
||||
return false
|
||||
}
|
||||
|
||||
if (incompatible.size < 2) return
|
||||
if (throwsAnnotation == null) return true
|
||||
|
||||
context.trace.report(ErrorsNative.INCOMPATIBLE_THROWS_INHERITED.on(declaration, incompatible.map { it.containingDeclaration }))
|
||||
val (overriddenMember, overriddenThrows) = inherited.firstOrNull()
|
||||
?: return true // Should not happen though.
|
||||
|
||||
if (decodeThrowsFilter(throwsAnnotation) != overriddenThrows) {
|
||||
context.trace.report(ErrorsNative.INCOMPATIBLE_THROWS_OVERRIDE.on(reportLocation, overriddenMember.containingDeclaration))
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun findInheritedThrows(descriptor: CallableMemberDescriptor): Map<CallableMemberDescriptor, ThrowsFilter> {
|
||||
val result = mutableMapOf<CallableMemberDescriptor, ThrowsFilter>()
|
||||
|
||||
DFS.dfs(
|
||||
descriptor.overriddenDescriptors,
|
||||
{ current -> current.overriddenDescriptors },
|
||||
object : DFS.AbstractNodeHandler<CallableMemberDescriptor, Unit>() {
|
||||
override fun beforeChildren(current: CallableMemberDescriptor): Boolean {
|
||||
val throwsAnnotation = current.annotations.findAnnotation(throwsFqName).takeIf { current.kind.isReal }
|
||||
return if (throwsAnnotation == null && current.overriddenDescriptors.isNotEmpty()) {
|
||||
// Visit overridden members:
|
||||
true
|
||||
} else {
|
||||
// Take current and ignore overridden:
|
||||
result[current.original] = decodeThrowsFilter(throwsAnnotation)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override fun result() {}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun AnnotationDescriptor.getVariadicArguments(): List<ConstantValue<*>> {
|
||||
@@ -60,4 +93,9 @@ object NativeThrowsChecker : DeclarationChecker {
|
||||
return argument.value
|
||||
}
|
||||
|
||||
private fun decodeThrowsFilter(throwsAnnotation: AnnotationDescriptor?) =
|
||||
ThrowsFilter(throwsAnnotation?.getVariadicArguments()?.toSet())
|
||||
|
||||
private data class ThrowsFilter(val classes: Set<ConstantValue<*>>?)
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user