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<!>
|
<!THROWS_LIST_EMPTY!>@Throws<!>
|
||||||
fun foo() {}
|
fun foo() {}
|
||||||
|
|
||||||
|
interface Base0 {
|
||||||
|
fun foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThrowsOnOverride : Base0 {
|
||||||
|
<!INCOMPATIBLE_THROWS_OVERRIDE!>@Throws(Exception1::class)<!> override fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
interface Base1 {
|
interface Base1 {
|
||||||
@Throws(Exception1::class) fun foo()
|
@Throws(Exception1::class) fun foo()
|
||||||
}
|
}
|
||||||
|
|
||||||
class HasThrowsOnOverride : Base1 {
|
class InheritsThrowsAndNoThrows : Base0, Base1 {
|
||||||
<!THROWS_ON_OVERRIDE!>@Throws(Exception1::class)<!> override fun foo() {}
|
<!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 {
|
class HasThrowsWithEmptyListOnOverride : Base1 {
|
||||||
<!THROWS_ON_OVERRIDE!>@Throws<!> override fun foo() {}
|
<!INCOMPATIBLE_THROWS_OVERRIDE!>@Throws<!> override fun foo() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Base2 {
|
interface Base2 {
|
||||||
@@ -31,8 +51,28 @@ open class InheritsDifferentThrows1 : Base1, Base2 {
|
|||||||
<!INCOMPATIBLE_THROWS_INHERITED!>override fun foo() {}<!>
|
<!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() {
|
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 {
|
interface Base3 {
|
||||||
@@ -43,6 +83,30 @@ class InheritsDifferentThrows2 : InheritsDifferentThrows1(), Base3 {
|
|||||||
<!INCOMPATIBLE_THROWS_INHERITED!>override fun foo() {}<!>
|
<!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 {
|
interface Base4 {
|
||||||
@Throws(Exception1::class) fun foo()
|
@Throws(Exception1::class) fun foo()
|
||||||
}
|
}
|
||||||
@@ -51,6 +115,18 @@ class InheritsSameThrows : Base1, Base4 {
|
|||||||
override fun foo() {}
|
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 {
|
interface Base5 {
|
||||||
@Throws(Exception1::class, Exception2::class) fun foo()
|
@Throws(Exception1::class, Exception2::class) fun foo()
|
||||||
}
|
}
|
||||||
@@ -63,6 +139,18 @@ class InheritsSameThrowsMultiple : Base5, Base6 {
|
|||||||
override fun foo() {}
|
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() {
|
fun withLocalClass() {
|
||||||
class LocalException : Throwable()
|
class LocalException : Throwable()
|
||||||
|
|
||||||
@@ -73,4 +161,32 @@ fun withLocalClass() {
|
|||||||
class InheritsDifferentThrowsLocal : Base1, Base7() {
|
class InheritsDifferentThrowsLocal : Base1, Base7() {
|
||||||
<!INCOMPATIBLE_THROWS_INHERITED!>override fun foo() {}<!>
|
<!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
|
@kotlin.native.Throws(exceptionClasses = {}) public fun foo(): kotlin.Unit
|
||||||
public fun withLocalClass(): 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 interface Base1 {
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
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
|
@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 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 final class Exception1 : kotlin.Throwable {
|
||||||
public constructor Exception1()
|
public constructor Exception1()
|
||||||
public open override /*1*/ /*fake_override*/ val cause: kotlin.Throwable?
|
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 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 final class HasThrowsWithEmptyListOnOverride : Base1 {
|
||||||
public constructor HasThrowsWithEmptyListOnOverride()
|
public constructor HasThrowsWithEmptyListOnOverride()
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
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 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 open class InheritsDifferentThrows1 : Base1, Base2 {
|
||||||
public constructor InheritsDifferentThrows1()
|
public constructor InheritsDifferentThrows1()
|
||||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
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 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 final class InheritsDifferentThrowsThroughSameClass1 : InheritsDifferentThrows1 {
|
||||||
public constructor InheritsDifferentThrowsThroughSameClass1()
|
public constructor InheritsDifferentThrowsThroughSameClass1()
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
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 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 {
|
||||||
|
|
||||||
package kotlin.native {
|
package kotlin.native {
|
||||||
|
|||||||
+4
-1
@@ -12,7 +12,10 @@ import org.jetbrains.kotlin.diagnostics.rendering.Renderers
|
|||||||
private val DIAGNOSTIC_FACTORY_TO_RENDERER by lazy {
|
private val DIAGNOSTIC_FACTORY_TO_RENDERER by lazy {
|
||||||
DiagnosticFactoryToRendererMap("Native").apply {
|
DiagnosticFactoryToRendererMap("Native").apply {
|
||||||
put(ErrorsNative.THROWS_LIST_EMPTY, "@Throws must have non-empty class list")
|
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(
|
put(
|
||||||
ErrorsNative.INCOMPATIBLE_THROWS_INHERITED, "Member inherits different @Throws filters from {0}",
|
ErrorsNative.INCOMPATIBLE_THROWS_INHERITED, "Member inherits different @Throws filters from {0}",
|
||||||
Renderers.commaSeparated(Renderers.NAME)
|
Renderers.commaSeparated(Renderers.NAME)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ object ErrorsNative {
|
|||||||
@JvmField
|
@JvmField
|
||||||
val THROWS_LIST_EMPTY = DiagnosticFactory0.create<KtElement>(Severity.ERROR)
|
val THROWS_LIST_EMPTY = DiagnosticFactory0.create<KtElement>(Severity.ERROR)
|
||||||
@JvmField
|
@JvmField
|
||||||
val THROWS_ON_OVERRIDE = DiagnosticFactory0.create<KtElement>(Severity.ERROR)
|
val INCOMPATIBLE_THROWS_OVERRIDE = DiagnosticFactory1.create<KtElement, DeclarationDescriptor>(Severity.ERROR)
|
||||||
@JvmField
|
@JvmField
|
||||||
val INCOMPATIBLE_THROWS_INHERITED = DiagnosticFactory1.create<KtDeclaration, Collection<DeclarationDescriptor>>(Severity.ERROR)
|
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.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgument
|
import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgument
|
||||||
import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors
|
import org.jetbrains.kotlin.utils.DFS
|
||||||
|
|
||||||
object NativeThrowsChecker : DeclarationChecker {
|
object NativeThrowsChecker : DeclarationChecker {
|
||||||
private val throwsFqName = FqName("kotlin.native.Throws")
|
private val throwsFqName = FqName("kotlin.native.Throws")
|
||||||
|
|
||||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
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
|
if (!checkInheritance(declaration, descriptor, context, throwsAnnotation, reportLocation)) return
|
||||||
val element = DescriptorToSourceUtils.getSourceFromAnnotation(throwsAnnotation) ?: declaration
|
|
||||||
|
|
||||||
if (descriptor is CallableMemberDescriptor && descriptor.overriddenDescriptors.isNotEmpty()) {
|
if (throwsAnnotation != null && throwsAnnotation.getVariadicArguments().isEmpty()) {
|
||||||
context.trace.report(ErrorsNative.THROWS_ON_OVERRIDE.on(element))
|
context.trace.report(ErrorsNative.THROWS_LIST_EMPTY.on(reportLocation))
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (throwsAnnotation.getVariadicArguments().isEmpty()) {
|
|
||||||
context.trace.report(ErrorsNative.THROWS_LIST_EMPTY.on(element))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkForIncompatibleMultipleInheritance(
|
private fun checkInheritance(
|
||||||
declaration: KtDeclaration,
|
declaration: KtDeclaration,
|
||||||
descriptor: DeclarationDescriptor,
|
descriptor: DeclarationDescriptor,
|
||||||
context: DeclarationCheckerContext
|
context: DeclarationCheckerContext,
|
||||||
) {
|
throwsAnnotation: AnnotationDescriptor?,
|
||||||
if (descriptor !is CallableMemberDescriptor) return
|
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()
|
if (inherited.size >= 2) {
|
||||||
.distinctBy { it.annotations.findAnnotation(throwsFqName)?.getVariadicArguments()?.toSet() }
|
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<*>> {
|
private fun AnnotationDescriptor.getVariadicArguments(): List<ConstantValue<*>> {
|
||||||
@@ -60,4 +93,9 @@ object NativeThrowsChecker : DeclarationChecker {
|
|||||||
return argument.value
|
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