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

NPE in NewlinesRule: #1050

Merged
merged 8 commits into from
Sep 22, 2021
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.cqfn.diktat.ruleset.utils.isSingleLineIfElse
import org.cqfn.diktat.ruleset.utils.leaveOnlyOneNewLine

import com.pinterest.ktlint.core.ast.ElementType.ANDAND
import com.pinterest.ktlint.core.ast.ElementType.ARRAY_ACCESS_EXPRESSION
import com.pinterest.ktlint.core.ast.ElementType.ARROW
import com.pinterest.ktlint.core.ast.ElementType.BINARY_EXPRESSION
import com.pinterest.ktlint.core.ast.ElementType.BLOCK
Expand Down Expand Up @@ -461,7 +462,7 @@ class NewlinesRule(configRules: List<RulesConfig>) : DiktatRule(

if (psi.children.isNotEmpty() && !psi.isFirstChildElementType(DOT_QUALIFIED_EXPRESSION) &&
!psi.isFirstChildElementType(SAFE_ACCESS_EXPRESSION)) {
val firstChild = psi.firstChild
val firstChild = if (psi.isFirstChildElementType(ARRAY_ACCESS_EXPRESSION)) psi.firstChild.firstChild else psi.firstChild
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that just workaround?

I looked at this bug before and think, that the main problem is in these lines:

https://github.com/cqfn/diKTat/blob/37b2478924f69d9f4be205bc46a2a12bbed89fb8/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/NewlinesRule.kt#L469-L471

For now I didn't catch the logic of this if statement - in which cases do we need this, even more it doesn't covered by any test.
Probably, we should modify it or get rid of it at all.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I deleted this piece and. everything continued to work

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it should work, however did you understand the reason, why did we need this before, for which cases?

I can't imagine any other examples for now, which will satisfy this condition, instead of it.responseBody!![0].name, for which it doesn't work

Copy link
Member

@orchestr7 orchestr7 Sep 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't get how it should fix anything?

If we had an NPE on the further manipulations val firstChild or psi.firstChild, you should do null-checks and create special logic for it. Not simply hardcode ARRAY_ACCESS_EXPRESSION

if (firstChild.isFirstChildElementType(DOT_QUALIFIED_EXPRESSION) ||
firstChild.isFirstChildElementType(SAFE_ACCESS_EXPRESSION)) {
getOrderedCallExpressions(firstChild.firstChild, result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,18 @@ class NewlinesRuleWarnTest : LintTestBase(::NewlinesRule) {
)
}

@Test
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create fixer tests (where WRONG_NEWLINES is fixing the code in such case) to prove that you are right

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cheshiriks where are tests for fixers?

@Tag(WarningNames.WRONG_NEWLINES)
fun `should warn for array access expression`() {
lintMethod(
"""
|fun bar(): String {
| val a = it.responseBody!!.name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code basically didn't trigger an NPE before

Suggested change
| val a = it.responseBody!!.name
| val a = it.responseBody!![0].name

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I removed this for a test and forgot to return

|}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add positive scenarios (that will trigger warnings)

""".trimMargin()
)
}

@Test
@Tag(WarningNames.WRONG_NEWLINES)
fun `long argument list should be split into several lines - positive example`() {
Expand Down