Required parameters after optional ones
REQUIRED_PARAMETER_AFTER_OPTIONAL reports required parameters of public functions and
constructors declared after an optional (defaulted or vararg) parameter.
| Diagnostic | REQUIRED_PARAMETER_AFTER_OPTIONAL |
| Default severity | Error |
| Gradle property | requiredParameterAfterOptional |
| Exemption | @IntentionallyRequiredParameterAfterOptional |
What it reports
Every required parameter (one that doesn't have a default value) that comes after the first optional one - defaulted
or vararg - in the parameter list of a public function or constructor:
@file:JvmName("Requests")/** Sends a request to [host]. */@JvmOverloadspublic fun request(retries: Int = 3, host: String) { }
All required parameters behind the first optional one are reported, not just the first:
@file:JvmName("Configuration")/** Configures a connection. */@JvmOverloadspublic fun configure(timeout: Long = 0L,host: String,port: Int,) { }
Rationale
A required parameter behind an optional one can't be passed positionally, which pushes callers toward named arguments for a parameter that should have been more trivial to supply. See the Kotlin library authors' guide on parameter order, naming, and usage: essential inputs first, optional inputs last.
Don't
@file:JvmName("Connections")/** Connects to [host]. */@JvmOverloadspublic fun connect(retries: Int = 3, host: String) { }
Do
@file:JvmName("Connections")/** Connects to [host]. */@JvmOverloadspublic fun connect(host: String, retries: Int = 3) { }
Don't
/** A server at [host]. */public class Server@JvmOverloadsconstructor(port: Int = 80, host: String)
Do
/** A server at [host]. */public class Server@JvmOverloadsconstructor(host: String, port: Int = 80)
Notes
@PublishedApi internalfunctions and constructors are not reported because library users cannot call them in source.- A
varargparameter counts as optional too: callers can omit it entirely, so a required parameter after it is still reported. - A required function-type or
fun interfaceparameter in the last position is not reported: keeping it last is what makes trailing-lambda call syntax available, and the standard library itself places such parameters after defaulted ones (joinToString(separator = ..., transform)). The same required function-type parameter is still reported when it is not last, since there is no trailing-lambda syntax to preserve there. - Overrides are not reported: they can't declare default values, and their parameter order is fixed by the overridden declaration, which is reported instead.
Exemption
Apply @IntentionallyRequiredParameterAfterOptional to the function or constructor when the order
is a deliberate, stable part of the contract, for example an old parameter list kept for source
compatibility:
@file:JvmName("Connections")/** Connects through the legacy parameter order. */@IntentionallyRequiredParameterAfterOptional(reason = ExemptionReason.FOR_BACKWARDS_COMPATIBILITY,)@IntentionallyWithoutJvmOverloads(reason = ExemptionReason.FOR_BACKWARDS_COMPATIBILITY,)public fun connect(retries: Int = 3, host: String) { }
Configuration
apiWatchdog {requiredParameterAfterOptional = WatchdogSeverity.WARNING}
With direct compiler invocation:
-P plugin:org.jetbrains.kotlin.library.api.watchdog:diagnosticSeverity=REQUIRED_PARAMETER_AFTER_OPTIONAL:warning
See also
- Preserve parameter order, naming, and usage
- Inconsistent parameter order in overloads, a sibling check on parameter order across overloads
- Exemptions and internal API