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.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.isEffectDescriptor(): Boolean = equalsDslDescriptor(EFFECT)
fun DeclarationDescriptor.isCallsInPlaceEffectDescriptor(): Boolean = equalsDslDescriptor(CALLS_IN_PLACE) 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.ReturnsEffectDeclaration
import org.jetbrains.kotlin.contracts.description.expressions.ConstantReference import org.jetbrains.kotlin.contracts.description.expressions.ConstantReference
import org.jetbrains.kotlin.contracts.parsing.* import org.jetbrains.kotlin.contracts.parsing.*
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
internal class PsiReturnsEffectParser( internal class PsiReturnsEffectParser(
@@ -34,25 +32,20 @@ internal class PsiReturnsEffectParser(
val resolvedCall = expression.getResolvedCall(callContext.bindingContext) ?: return null val resolvedCall = expression.getResolvedCall(callContext.bindingContext) ?: return null
val descriptor = resolvedCall.resultingDescriptor val descriptor = resolvedCall.resultingDescriptor
if (descriptor.isReturnsNotNullDescriptor()) if (descriptor.isReturnsNotNullDescriptor()) return ReturnsEffectDeclaration(ConstantReference.NOT_NULL)
return ReturnsEffectDeclaration(ConstantReference.NOT_NULL) if (descriptor.isReturnsWildcardDescriptor()) return ReturnsEffectDeclaration(ConstantReference.WILDCARD)
if (!descriptor.isReturnsEffectDescriptor()) return null if (!descriptor.isReturnsEffectDescriptor()) return null
val argumentExpression = resolvedCall.firstArgumentAsExpressionOrNull() val argumentExpression = resolvedCall.firstArgumentAsExpressionOrNull()
val constantValue = if (argumentExpression == null) { val constantValue = if (argumentExpression != null) contractParserDispatcher.parseConstant(argumentExpression) else null
ConstantReference.WILDCARD
} else { if (constantValue == null) {
// Note that we distinguish absence of an argument and unparsed argument collector.badDescription(
val constant = contractParserDispatcher.parseConstant(argumentExpression) "only true/false/null constants in Returns-effect are currently supported",
if (constant == null) { argumentExpression ?: expression
collector.badDescription( )
"only true/false/null constants in Returns-effect are currently supported", return null
argumentExpression
)
return null
}
constant
} }
return ReturnsEffectDeclaration(constantValue) return ReturnsEffectDeclaration(constantValue)