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.
This commit is contained in:
Dmitry Savvinov
2018-08-20 14:15:50 +03:00
committed by Ilya Gorbunov
parent 1300a475db
commit 70dc6ef0f7
2 changed files with 14 additions and 17 deletions
@@ -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)
@@ -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)