From 70dc6ef0f70f7caca50430160a8241ceecc6caa3 Mon Sep 17 00:00:00 2001 From: Dmitry Savvinov Date: Mon, 20 Aug 2018 14:15:50 +0300 Subject: [PATCH] Minor: detect 'returns()' more accurately Before, we've assumed that if call has no expression arguments, then it's a 'returns()' call. Now we check that we've resolved to overload of 'returns' from ContractsDsl with zero parameters. --- .../contracts/parsing/PsiContractsUtils.kt | 4 +++ .../parsing/effects/PsiReturnsEffectParser.kt | 27 +++++++------------ 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/PsiContractsUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/PsiContractsUtils.kt index 9556a42364b..b4f187da8ad 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/PsiContractsUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/PsiContractsUtils.kt @@ -76,6 +76,10 @@ fun DeclarationDescriptor.isReturnsEffectDescriptor(): Boolean = equalsDslDescri fun DeclarationDescriptor.isReturnsNotNullDescriptor(): Boolean = equalsDslDescriptor(RETURNS_NOT_NULL) +fun DeclarationDescriptor.isReturnsWildcardDescriptor(): Boolean = equalsDslDescriptor(RETURNS) && + this is FunctionDescriptor && + valueParameters.isEmpty() + fun DeclarationDescriptor.isEffectDescriptor(): Boolean = equalsDslDescriptor(EFFECT) fun DeclarationDescriptor.isCallsInPlaceEffectDescriptor(): Boolean = equalsDslDescriptor(CALLS_IN_PLACE) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/effects/PsiReturnsEffectParser.kt b/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/effects/PsiReturnsEffectParser.kt index 30ff759c51b..a5ebd27079a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/effects/PsiReturnsEffectParser.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/effects/PsiReturnsEffectParser.kt @@ -20,9 +20,7 @@ import org.jetbrains.kotlin.contracts.description.EffectDeclaration import org.jetbrains.kotlin.contracts.description.ReturnsEffectDeclaration import org.jetbrains.kotlin.contracts.description.expressions.ConstantReference import org.jetbrains.kotlin.contracts.parsing.* -import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.psi.KtExpression -import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall internal class PsiReturnsEffectParser( @@ -34,25 +32,20 @@ internal class PsiReturnsEffectParser( val resolvedCall = expression.getResolvedCall(callContext.bindingContext) ?: return null val descriptor = resolvedCall.resultingDescriptor - if (descriptor.isReturnsNotNullDescriptor()) - return ReturnsEffectDeclaration(ConstantReference.NOT_NULL) + if (descriptor.isReturnsNotNullDescriptor()) return ReturnsEffectDeclaration(ConstantReference.NOT_NULL) + if (descriptor.isReturnsWildcardDescriptor()) return ReturnsEffectDeclaration(ConstantReference.WILDCARD) if (!descriptor.isReturnsEffectDescriptor()) return null val argumentExpression = resolvedCall.firstArgumentAsExpressionOrNull() - val constantValue = if (argumentExpression == null) { - ConstantReference.WILDCARD - } else { - // Note that we distinguish absence of an argument and unparsed argument - val constant = contractParserDispatcher.parseConstant(argumentExpression) - if (constant == null) { - collector.badDescription( - "only true/false/null constants in Returns-effect are currently supported", - argumentExpression - ) - return null - } - constant + val constantValue = if (argumentExpression != null) contractParserDispatcher.parseConstant(argumentExpression) else null + + if (constantValue == null) { + collector.badDescription( + "only true/false/null constants in Returns-effect are currently supported", + argumentExpression ?: expression + ) + return null } return ReturnsEffectDeclaration(constantValue)