Lambdas following a statement can be treated as lambda arguments, breaking syntax
In one of our projects, we have a util named multiCatch which we can tack on to the end of a lambda to more easily follow set logic when catching multiple types of exception.
Here's some simplified example code from our repository:
fun doSearch() {
_results.postValue(Resource.Loading());
{
performSearch(searchParams)
}
.multiCatch(
SocketException::class,
SocketTimeoutException::class,
SSLException::class
) {
// Activity suspended while parsing stream
_results.postValue(Resource.Error(it, null))
}
}
When we run ktfmt on this code, it removes the semicolon from the end of the first statement, and then moves the lambda to the end of that statement, making the Kotlin compiler interpret it as a lambda argument to postValue():
fun doSearch() {
_results
.postValue(Resource.Loading()) { performSearch(searchParams) }
.multiCatch(SocketException::class, SocketTimeoutException::class, SSLException::class) {
// Activity suspended while parsing stream
_results.postValue(Resource.Error(it, null))
}
}
In my opinion, ktfmt should either leave the syntax as-is with a semicolon, or it should wrap the lambda in brackets. It shouldn't change the syntax of the code as part of formatting.
There is code looking for this but it fails when the lambda is part of a larger expression, like a call chain. Usually it wouldn't matter because there would be some other token between the semicolon and the lambda.
The fix is probably to walk up to the statement containing semicolon, then down the left side of the next sibling statement.