Prohibit declaring multiple callsInPlace contract on same lambda.
#KT-26150 fixed
This commit is contained in:
+17
-2
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.contracts.parsing
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.contracts.description.BooleanExpression
|
||||
import org.jetbrains.kotlin.contracts.description.CallsEffectDeclaration
|
||||
import org.jetbrains.kotlin.contracts.description.ContractDescription
|
||||
import org.jetbrains.kotlin.contracts.description.EffectDeclaration
|
||||
import org.jetbrains.kotlin.contracts.description.expressions.BooleanVariableReference
|
||||
@@ -69,8 +70,9 @@ internal class PsiContractParserDispatcher(
|
||||
return null
|
||||
}
|
||||
|
||||
val effects = lambda.bodyExpression?.statements?.mapNotNull { parseEffect(it) } ?: return null
|
||||
|
||||
val effectsWithExpression = lambda.bodyExpression?.statements?.map { parseEffect(it) to it } ?: return null
|
||||
checkDuplicatedCallsEffectsAndReport(effectsWithExpression)
|
||||
val effects = effectsWithExpression.mapNotNull { it.first }
|
||||
if (effects.isEmpty()) return null
|
||||
|
||||
return ContractDescription(effects, callContext.functionDescriptor, storageManager)
|
||||
@@ -92,6 +94,19 @@ internal class PsiContractParserDispatcher(
|
||||
return parser.tryParseEffect(expression)
|
||||
}
|
||||
|
||||
private fun checkDuplicatedCallsEffectsAndReport(effects: List<Pair<EffectDeclaration?, KtExpression>>) {
|
||||
val descriptorsWithCallsEffect = mutableSetOf<ParameterDescriptor>()
|
||||
for ((effect, expression) in effects) {
|
||||
if (effect !is CallsEffectDeclaration) continue
|
||||
val descriptor = effect.variableReference.descriptor
|
||||
if (descriptor in descriptorsWithCallsEffect) {
|
||||
collector.badDescription("Duplicated contract for ${descriptor.name}. Only one `callsInPlace` contract per parameter is allowed.", expression)
|
||||
} else {
|
||||
descriptorsWithCallsEffect.add(descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isValidEffectDeclaration(expression: KtExpression): Boolean {
|
||||
if (expression !is KtCallExpression && expression !is KtBinaryExpression) {
|
||||
collector.badDescription("unexpected construction in contract description", expression)
|
||||
|
||||
Reference in New Issue
Block a user