Fix false-positive @Throws error diagnostics in Native
Don't report THROWS_LIST_EMPTY and MISSING_EXCEPTION_IN_THROWS_ON_SUSPEND caused by unresolved arguments.
This commit is contained in:
@@ -37,6 +37,41 @@ fun foo() {}
|
||||
<!THROWS_LIST_EMPTY!>@Throws()<!>
|
||||
fun throwsEmptyParens() {}
|
||||
|
||||
@Throws(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>UnresolvedException<!>::class<!>)
|
||||
fun throwsUnresolved() {}
|
||||
|
||||
@Throws(exceptionClasses = <!ANNOTATION_ARGUMENT_MUST_BE_CONST, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION_ERROR!><!UNRESOLVED_REFERENCE!>UnresolvedException<!>::class<!>)
|
||||
fun throwsNamedUnresolved() {}
|
||||
|
||||
<!THROWS_LIST_EMPTY!>@Throws(exceptionClasses = [])<!>
|
||||
fun throwsNamedEmptyLiteral() {}
|
||||
|
||||
<!THROWS_LIST_EMPTY!>@Throws(exceptionClasses = arrayOf())<!>
|
||||
fun throwsNamedEmptyArrayOf() {}
|
||||
|
||||
<!THROWS_LIST_EMPTY!>@Throws(*[])<!>
|
||||
fun throwsSpreadEmptyLiteral() {}
|
||||
|
||||
<!THROWS_LIST_EMPTY!>@Throws(*arrayOf())<!>
|
||||
fun throwsSpreadEmptyArrayOf() {}
|
||||
|
||||
@Throws(exceptionClasses = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>[<!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>UE<!>::class<!>]<!>)
|
||||
fun throwsNamedLiteralWithUnresolved() {}
|
||||
|
||||
@Throws(exceptionClasses = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>arrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>UE<!>::class<!>)<!>)
|
||||
fun throwsNamedArrayOfUnresolved() {}
|
||||
|
||||
@Throws(*<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>[<!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>UE<!>::class<!>]<!>)
|
||||
fun throwsSpreadLiteralWithUnresolved() {}
|
||||
|
||||
@Throws(*<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>arrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>UE<!>::class<!>)<!>)
|
||||
fun throwsSpreadArrayOfUnresolved() {}
|
||||
|
||||
typealias UEAlias = <!UNRESOLVED_REFERENCE!>UE<!>
|
||||
|
||||
@Throws(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>UEAlias::class<!>)
|
||||
fun throwsTypealiasToUnresolved() {}
|
||||
|
||||
interface Base0 {
|
||||
fun foo()
|
||||
}
|
||||
@@ -244,6 +279,39 @@ suspend fun suspendDoesNotThrowCancellationException1() {}
|
||||
<!MISSING_EXCEPTION_IN_THROWS_ON_SUSPEND!>@Throws(Exception1::class, Exception2::class)<!>
|
||||
suspend fun suspendDoesNotThrowCancellationException2() {}
|
||||
|
||||
@Throws(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>UE<!>::class<!>)
|
||||
suspend fun suspendThrowsUnresolved() {}
|
||||
|
||||
@Throws(exceptionClasses = <!ANNOTATION_ARGUMENT_MUST_BE_CONST, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION_ERROR!><!UNRESOLVED_REFERENCE!>UE<!>::class<!>)
|
||||
suspend fun suspendThrowsNamedUnresolved() {}
|
||||
|
||||
<!THROWS_LIST_EMPTY!>@Throws(exceptionClasses = [])<!>
|
||||
suspend fun suspendThrowsNamedEmptyLiteral() {}
|
||||
|
||||
<!THROWS_LIST_EMPTY!>@Throws(exceptionClasses = arrayOf())<!>
|
||||
suspend fun suspendThrowsNamedEmptyArrayOf() {}
|
||||
|
||||
<!THROWS_LIST_EMPTY!>@Throws(*[])<!>
|
||||
suspend fun suspendThrowsSpreadEmptyLiteral() {}
|
||||
|
||||
<!THROWS_LIST_EMPTY!>@Throws(*arrayOf())<!>
|
||||
suspend fun suspendThrowsSpreadEmptyArrayOf() {}
|
||||
|
||||
@Throws(exceptionClasses = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>[<!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>UE<!>::class<!>]<!>)
|
||||
suspend fun suspendThrowsNamedLiteralWithUnresolved() {}
|
||||
|
||||
@Throws(exceptionClasses = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>arrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>UE<!>::class<!>)<!>)
|
||||
suspend fun suspendThrowsNamedArrayOfUnresolved() {}
|
||||
|
||||
@Throws(*<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>[<!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>UE<!>::class<!>]<!>)
|
||||
suspend fun suspendThrowsSpreadLiteralWithUnresolved() {}
|
||||
|
||||
@Throws(*<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>arrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!><!UNRESOLVED_REFERENCE!>UE<!>::class<!>)<!>)
|
||||
suspend fun suspendThrowsSpreadArrayOfUnresolved() {}
|
||||
|
||||
@Throws(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>UEAlias::class<!>)
|
||||
suspend fun suspendThrowsTypealiasToUnresolved() {}
|
||||
|
||||
@Throws(Exception1::class, CancellationException::class)
|
||||
suspend fun suspendThrowsCancellationException1() {}
|
||||
|
||||
|
||||
@@ -12,15 +12,37 @@ package
|
||||
@kotlin.Throws(exceptionClasses = {kotlin.IllegalStateException::class}) public suspend fun suspendThrowsIllegalStateException1(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {Exception2::class, kotlin.IllegalStateException::class}) public suspend fun suspendThrowsIllegalStateException2(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {kotlin.IllegalStateException::class}) public suspend fun suspendThrowsIllegalStateExceptionTypealias(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public suspend fun suspendThrowsNamedArrayOfUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public suspend fun suspendThrowsNamedEmptyArrayOf(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public suspend fun suspendThrowsNamedEmptyLiteral(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public suspend fun suspendThrowsNamedLiteralWithUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public suspend fun suspendThrowsNamedUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public suspend fun suspendThrowsNothing(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {kotlin.RuntimeException::class}) public suspend fun suspendThrowsRuntimeException1(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {kotlin.RuntimeException::class, Exception3::class}) public suspend fun suspendThrowsRuntimeException2(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {kotlin.RuntimeException::class}) public suspend fun suspendThrowsRuntimeExceptionTypealias(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public suspend fun suspendThrowsSpreadArrayOfUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public suspend fun suspendThrowsSpreadEmptyArrayOf(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public suspend fun suspendThrowsSpreadEmptyLiteral(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public suspend fun suspendThrowsSpreadLiteralWithUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {kotlin.Throwable::class}) public suspend fun suspendThrowsThrowable1(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {kotlin.Throwable::class, Exception2::class}) public suspend fun suspendThrowsThrowable2(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {kotlin.Throwable::class, kotlin.coroutines.cancellation.CancellationException::class}) public suspend fun suspendThrowsThrowable3(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {kotlin.Throwable::class}) public suspend fun suspendThrowsThrowableTypealias(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public suspend fun suspendThrowsTypealiasToUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public suspend fun suspendThrowsUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public fun throwsEmptyParens(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public fun throwsNamedArrayOfUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public fun throwsNamedEmptyArrayOf(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public fun throwsNamedEmptyLiteral(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public fun throwsNamedLiteralWithUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public fun throwsNamedUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public fun throwsSpreadArrayOfUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public fun throwsSpreadEmptyArrayOf(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public fun throwsSpreadEmptyLiteral(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public fun throwsSpreadLiteralWithUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public fun throwsTypealiasToUnresolved(): kotlin.Unit
|
||||
@kotlin.Throws(exceptionClasses = {}) public fun throwsUnresolved(): kotlin.Unit
|
||||
public fun withLocalClass(): kotlin.Unit
|
||||
|
||||
public interface Base0 {
|
||||
@@ -411,6 +433,7 @@ public typealias ExceptionAlias = kotlin.Exception
|
||||
public typealias IllegalStateExceptionAlias = kotlin.IllegalStateException
|
||||
public typealias RuntimeExceptionAlias = kotlin.RuntimeException
|
||||
public typealias ThrowableAlias = kotlin.Throwable
|
||||
public typealias UEAlias = [ERROR : UE]
|
||||
|
||||
package kotlin {
|
||||
|
||||
|
||||
+15
-1
@@ -13,10 +13,15 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.SUSPEND_KEYWORD
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.Call
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.StatementFilter
|
||||
import org.jetbrains.kotlin.resolve.annotations.KOTLIN_THROWS_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.hasUnresolvedArguments
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||
@@ -41,12 +46,16 @@ object NativeThrowsChecker : DeclarationChecker {
|
||||
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
val throwsAnnotation = descriptor.annotations.findAnnotation(throwsFqName)
|
||||
val reportLocation = throwsAnnotation?.let { DescriptorToSourceUtils.getSourceFromAnnotation(it) } ?: declaration
|
||||
val throwsAnnotationEntry = throwsAnnotation?.let { DescriptorToSourceUtils.getSourceFromAnnotation(it) }
|
||||
val reportLocation = throwsAnnotationEntry ?: declaration
|
||||
|
||||
if (!checkInheritance(declaration, descriptor, context, throwsAnnotation, reportLocation)) return
|
||||
|
||||
if (throwsAnnotation == null) return
|
||||
|
||||
val bindingContext = context.trace.bindingContext
|
||||
if (throwsAnnotationEntry?.getCall(bindingContext)?.hasUnresolvedArgumentsRecursive(bindingContext) == true) return
|
||||
|
||||
val classes = throwsAnnotation.getVariadicArguments()
|
||||
if (classes.isEmpty()) {
|
||||
context.trace.report(ErrorsNative.THROWS_LIST_EMPTY.on(reportLocation))
|
||||
@@ -134,3 +143,8 @@ object NativeThrowsChecker : DeclarationChecker {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun Call.hasUnresolvedArgumentsRecursive(context: BindingContext): Boolean {
|
||||
return this.hasUnresolvedArguments(context, StatementFilter.NONE) ||
|
||||
valueArguments.any { it.getArgumentExpression()?.getCall(context)?.hasUnresolvedArgumentsRecursive(context) == true }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user