Make infix modifier diagnostic message more informative (KT-12589)
(cherry picked from commit 2744309)
This commit is contained in:
+1
-1
@@ -87,7 +87,7 @@ public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implement
|
||||
SimpleFunctionDescriptorImpl descriptor = super.initialize(
|
||||
receiverParameterType, dispatchReceiverParameter, typeParameters, unsubstitutedValueParameters,
|
||||
unsubstitutedReturnType, modality, visibility);
|
||||
setOperator(OperatorChecks.INSTANCE.checkOperator(descriptor).isSuccess());
|
||||
setOperator(OperatorChecks.INSTANCE.check(descriptor).isSuccess());
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
|
||||
+34
-16
@@ -68,11 +68,11 @@ interface Check {
|
||||
}
|
||||
|
||||
sealed class MemberKindCheck(override val description: String) : Check {
|
||||
object MemberOrExtension : MemberKindCheck("must be a member or an extension") {
|
||||
object MemberOrExtension : MemberKindCheck("must be a member or an extension function") {
|
||||
override fun check(functionDescriptor: FunctionDescriptor) =
|
||||
functionDescriptor.isExtension || functionDescriptor.containingDeclaration is ClassDescriptor
|
||||
}
|
||||
object Member : MemberKindCheck("must be a member") {
|
||||
object Member : MemberKindCheck("must be a member function") {
|
||||
override fun check(functionDescriptor: FunctionDescriptor) = functionDescriptor.containingDeclaration is ClassDescriptor
|
||||
}
|
||||
}
|
||||
@@ -92,6 +92,13 @@ sealed class ValueParameterCountCheck(override val description: String) : Check
|
||||
}
|
||||
}
|
||||
|
||||
private object HasDispatchOrExtensionReceiverParameter : Check {
|
||||
override val description = "must be a member of an extension function"
|
||||
override fun check(functionDescriptor: FunctionDescriptor): Boolean {
|
||||
return functionDescriptor.dispatchReceiverParameter != null || functionDescriptor.extensionReceiverParameter != null
|
||||
}
|
||||
}
|
||||
|
||||
private object NoDefaultAndVarargsCheck : Check {
|
||||
override val description = "should not have varargs or parameters with default values"
|
||||
override fun check(functionDescriptor: FunctionDescriptor) =
|
||||
@@ -120,7 +127,7 @@ sealed class ReturnsCheck(val name: String, val type: KotlinBuiltIns.() -> Kotli
|
||||
object ReturnsUnit : ReturnsCheck("Unit", { unitType })
|
||||
}
|
||||
|
||||
private class Checks private constructor(
|
||||
internal class Checks private constructor(
|
||||
val name: Name?,
|
||||
val regex: Regex?,
|
||||
val nameList: Collection<Name>?,
|
||||
@@ -150,6 +157,8 @@ private class Checks private constructor(
|
||||
return CheckResult.SuccessCheck
|
||||
}
|
||||
|
||||
constructor(vararg checks: Check, additionalChecks: FunctionDescriptor.() -> String? = { null })
|
||||
: this(null, null, null, additionalChecks, *checks)
|
||||
constructor(name: Name, vararg checks: Check, additionalChecks: FunctionDescriptor.() -> String? = { null })
|
||||
: this(name, null, null, additionalChecks, *checks)
|
||||
constructor(regex: Regex, vararg checks: Check, additionalChecks: FunctionDescriptor.() -> String? = { null })
|
||||
@@ -158,10 +167,23 @@ private class Checks private constructor(
|
||||
: this(null, null, nameList, additionalChecks, *checks)
|
||||
}
|
||||
|
||||
object OperatorChecks {
|
||||
private inline fun ensure(cond: Boolean, msg: () -> String) = if (!cond) msg() else null
|
||||
abstract class AbstractModifierChecks {
|
||||
abstract internal val checks: List<Checks>
|
||||
|
||||
inline fun ensure(cond: Boolean, msg: () -> String) = if (!cond) msg() else null
|
||||
|
||||
private val CHECKS = listOf(
|
||||
fun check(functionDescriptor: FunctionDescriptor): CheckResult {
|
||||
for (check in checks) {
|
||||
if (!check.isApplicable(functionDescriptor)) continue
|
||||
return check.checkAll(functionDescriptor)
|
||||
}
|
||||
|
||||
return CheckResult.IllegalFunctionName
|
||||
}
|
||||
}
|
||||
|
||||
object OperatorChecks : AbstractModifierChecks() {
|
||||
override val checks = listOf(
|
||||
Checks(GET, MemberOrExtension, ValueParameterCountCheck.AtLeast(1)),
|
||||
Checks(SET, MemberOrExtension, ValueParameterCountCheck.AtLeast(2)) {
|
||||
val lastIsOk = valueParameters.lastOrNull()?.let { !it.hasDefaultValue() && it.varargElementType == null } ?: false
|
||||
@@ -212,15 +234,11 @@ object OperatorChecks {
|
||||
"Second parameter should be Continuation<Nothing>"
|
||||
}
|
||||
}
|
||||
|
||||
fun checkOperator(functionDescriptor: FunctionDescriptor): CheckResult {
|
||||
for (check in CHECKS) {
|
||||
if (!check.isApplicable(functionDescriptor)) continue
|
||||
return check.checkAll(functionDescriptor)
|
||||
}
|
||||
|
||||
return CheckResult.IllegalFunctionName
|
||||
}
|
||||
}
|
||||
|
||||
fun FunctionDescriptor.isValidOperator() = isOperator && OperatorChecks.checkOperator(this).isSuccess
|
||||
object InfixChecks : AbstractModifierChecks() {
|
||||
override val checks = listOf(
|
||||
Checks(HasDispatchOrExtensionReceiverParameter, SingleValueParameter, NoDefaultAndVarargsCheck))
|
||||
}
|
||||
|
||||
fun FunctionDescriptor.isValidOperator() = isOperator && OperatorChecks.check(this).isSuccess
|
||||
Reference in New Issue
Block a user