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:
Svyatoslav Scherbina
2020-05-25 16:30:22 +03:00
parent 242d0aa26e
commit fa152593ef
3 changed files with 106 additions and 1 deletions
@@ -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 }
}