Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WRONG_INDENTATION: extendedIndentAfterOperators ignored if lines are wrapped before a binary operator or an infix function #1340

Closed
0x6675636b796f75676974687562 opened this issue Jun 1, 2022 · 1 comment · Fixed by #1401 or #1486
Assignees
Labels
bug Something isn't working
Milestone

Comments

@0x6675636b796f75676974687562
Copy link
Member

0x6675636b796f75676974687562 commented Jun 1, 2022

Consider this fragment (originally from #1312 (comment))

systemUiVisibility = (View.SYSTEM_UI_FLAG_LOW_PROFILE
        or View.SYSTEM_UI_FLAG_FULLSCREEN
        or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)

Here, infix function calls are wrapped before the operator (the infix function), and extendedIndentAfterOperators has no effect (DiKTat always expects a single indent, not a continuation indent).

The workaround (fir version 1.1.0) is to reformat the code as follows (#1312 (comment)):

systemUiVisibility = (View.SYSTEM_UI_FLAG_LOW_PROFILE or
        View.SYSTEM_UI_FLAG_FULLSCREEN or
        View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
        View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)

The expected behaviour is that extendedIndentAfterOperators is honored regardless of whether the code is wrapped before or after a binary operator.

Other examples (the code style assumes extendedIndentAfterOperators is on):

const val FOO = 1

const val BAR = 2

const val BAZ = 4

fun acceptInteger(arg: Int) = Unit

fun main() {
    acceptInteger(FOO or BAR or BAZ or FOO or BAR or BAZ
            or FOO or BAR or BAZ or FOO or BAR or BAZ or FOO or BAR or BAZ
            or FOO or BAR or BAZ)
}
const val TRUE = true

const val FALSE = false

fun acceptBoolean(arg: Boolean) = Unit

fun main() {
    acceptBoolean(TRUE
            || FALSE
            || TRUE)
}
val c = (3
        + 2)
infix fun Int.combineWith(that: Int) = this + that

fun main() {
    val x = (1
            combineWith 2
            combineWith 3
            combineWith 4
            combineWith 5
            combineWith 6)
}

when- and for-statements

The argument of a when-expression:

when (true
        || false) {
    true -> Unit
    else -> Unit
}

The branch condition of a when-expression:

when ("".isEmpty()) {
    (true
            || false) -> Unit
    else -> Unit
}

Infix function calls in a for-loop:

for (i in 6
        downTo 0
        step 2) {
    return
}

Operator function calls in a for-loop:

for (i in 1
        ..42) {
    return
}

More examples

true
        || false

val a = true
        || false

Expressions wrapped in parentheses

Affected by the fix for #1409, see this comment.

(true
        || false)

val a = (true
        || false)

if-conditions (should be controlled by a separate flag)

A slightly modified example from IDEA code style settings (CONTINUATION_INDENT_IN_IF_CONDITIONS is on):

fun foo1(i1: Int, i2: Int, i3: Int): Int {
    if (i2 > 0
            && i3 < 0) {
        return 2
    }
    return 0
}

Minimal repro:

if (true
        || false) {
    return
}

or

while (true
        || false) {
    return
}

Environment information

  • diktat version: 1.1.0
  • build tool (maven/gradle): Maven
  • how is diktat run (CLI, plugin, etc.): mvn diktat:check
  • kotlin version: 1.6.21
  • operating system: Windows 10
@0x6675636b796f75676974687562 0x6675636b796f75676974687562 added the bug Something isn't working label Jun 1, 2022
@0x6675636b796f75676974687562 0x6675636b796f75676974687562 added this to the 1.1.1 milestone Jun 1, 2022
@0x6675636b796f75676974687562 0x6675636b796f75676974687562 changed the title WRONG_INDENTATION: extendedIndentAfterOperators ignored if lines are wrapped *before* a binary operator or an infix function WRONG_INDENTATION: extendedIndentAfterOperators ignored if lines are wrapped _before_ a binary operator or an infix function Jun 1, 2022
@0x6675636b796f75676974687562 0x6675636b796f75676974687562 changed the title WRONG_INDENTATION: extendedIndentAfterOperators ignored if lines are wrapped _before_ a binary operator or an infix function WRONG_INDENTATION: extendedIndentAfterOperators ignored if lines are wrapped before a binary operator or an infix function Jun 1, 2022
0x6675636b796f75676974687562 added a commit that referenced this issue Jun 24, 2022
### What's done:

 * Tests for expressions wrapped on an operator have been added.
 * Both cases (when `extendedIndentAfterOperators` is `true` and `false`) are
   tested.
 * Both binary operators and functions are tested.
 * Related: #1340
0x6675636b796f75676974687562 added a commit that referenced this issue Jun 27, 2022
### What's done:

 * Tests for expressions wrapped on an operator have been added.
 * Both cases (when `extendedIndentAfterOperators` is `true` and `false`) are
   tested.
 * Both binary operators and functions are tested.
 * Related: #1340
0x6675636b796f75676974687562 added a commit that referenced this issue Jun 27, 2022
#1401)

* `WRONG_INDENTATION`: add more tests for `extendedIndentAfterOperators`

### What's done:

 * Tests for expressions wrapped on an operator have been added.
 * Both cases (when `extendedIndentAfterOperators` is `true` and `false`) are
   tested.
 * Both binary operators and functions are tested.
 * Test resources extracted into a separate class so that DeteKT remains quiet.
 * Related: #1340
@0x6675636b796f75676974687562
Copy link
Member Author

0x6675636b796f75676974687562 commented Jun 29, 2022

Note

The fix for #1409 has the following side-effect. Previously (1.2.0), DiKTat would format expressions wrapped before an infix function like this:

fun f() {
    true
    || false
}

— unless those expressions are surrounded with parentheses, requiring an extra indent in this latter case:

fun f() {
    (true
        || false)
}

Once #1409 is fixed, no extra indent is required (i.e. the behaviour is now consistent with and without parentheses):

fun f() {
    (true
    || false)
}

— which is still incorrect and needs to be fixed.

0x6675636b796f75676974687562 added a commit that referenced this issue Jul 29, 2022
### What's done:

 * Now, the indentation in binary expressions wrapped *before* a binary operator
   or an infix function is also controlled with `extendedIndentAfterOperators`.
 * The above is also true for `as` and `as?` operators.
 * The only exclusion is the Elvis operator (`?:`).
 * Fixes #1340.
0x6675636b796f75676974687562 added a commit that referenced this issue Jul 29, 2022
### What's done:

 * Now, the indentation in binary expressions wrapped *before* a binary operator
   or an infix function is also controlled with `extendedIndentAfterOperators`.
 * The above is also true for `as` and `as?` operators.
 * The only exclusion is the Elvis operator (`?:`).
 * Fixes #1340.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
1 participant