Skip to content

Commit

Permalink
### Whats added:
Browse files Browse the repository at this point in the history
 * corrected logic fix and warn String Template in Linelength rule
 * added logic fix and warn long Dot Qualified Expression in LineLength rule
 * added logic fix and warn Value Arguments List in LineLength rule
 * added and corrected fix and warn tests in LineLength rule

 ### Issue (#1243)
  • Loading branch information
Arrgentum committed May 24, 2022
1 parent 5e52117 commit 949f78a
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import org.cqfn.diktat.ruleset.rules.DiktatRule
import org.cqfn.diktat.ruleset.utils.*

import com.pinterest.ktlint.core.ast.ElementType.ANDAND
import com.pinterest.ktlint.core.ast.ElementType.ARROW
import com.pinterest.ktlint.core.ast.ElementType.COMMA
import com.pinterest.ktlint.core.ast.ElementType.BINARY_EXPRESSION
import com.pinterest.ktlint.core.ast.ElementType.BOOLEAN_CONSTANT
Expand Down Expand Up @@ -51,13 +52,16 @@ import com.pinterest.ktlint.core.ast.ElementType.RPAR
import com.pinterest.ktlint.core.ast.ElementType.SHORT_STRING_TEMPLATE_ENTRY
import com.pinterest.ktlint.core.ast.ElementType.STRING_TEMPLATE
import com.pinterest.ktlint.core.ast.ElementType.VALUE_ARGUMENT_LIST
import com.pinterest.ktlint.core.ast.ElementType.WHEN_CONDITION_WITH_EXPRESSION
import com.pinterest.ktlint.core.ast.ElementType.WHEN_ENTRY
import com.pinterest.ktlint.core.ast.ElementType.WHITE_SPACE
import com.pinterest.ktlint.core.ast.isWhiteSpace
import com.pinterest.ktlint.core.ast.isWhiteSpaceWithNewline
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl
import org.jetbrains.kotlin.com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.psi.typeReferenceRecursiveVisitor

import java.net.MalformedURLException
import java.net.URL
Expand Down Expand Up @@ -87,6 +91,7 @@ class LineLength(configRules: List<RulesConfig>) : DiktatRule(
checkLength(it, configuration)
}
}
//println(node.prettyPrint())
println(node.text)
}
}
Expand Down Expand Up @@ -129,9 +134,8 @@ class LineLength(configRules: List<RulesConfig>) : DiktatRule(
do {
when (parent.elementType) {
BINARY_EXPRESSION, PARENTHESIZED -> {
parent.findParentNodeWithSpecificType(VALUE_ARGUMENT_LIST) ?. let {
parent = it
} ?: parent.findParentNodeWithSpecificType(FUNCTION_LITERAL) ?. let {
val parentIsValArgListOrFunLitOrWhenEntry = listOf<IElementType>(VALUE_ARGUMENT_LIST, FUNCTION_LITERAL, WHEN_CONDITION_WITH_EXPRESSION)
findParentNodeWithSpecificTypeMany(parent, parentIsValArgListOrFunLitOrWhenEntry) ?. let {
parent = it
} ?: run {
val splitOffset = searchRightSplitAfterType(parent, configuration, OPERATION_REFERENCE)?.second
Expand Down Expand Up @@ -159,20 +163,25 @@ class LineLength(configRules: List<RulesConfig>) : DiktatRule(
VALUE_ARGUMENT_LIST -> {
parent.findParentNodeWithSpecificType(BINARY_EXPRESSION) ?. let {
parent = it
} ?: return checkArgumentList(parent, configuration)
} ?: run {
if (parent.treeParent.treeParent.elementType == WHEN_ENTRY ) {
return WhenEntry(parent.treeParent.treeParent)
}
return ValueArgumentList(parent, configuration)
}
}
WHEN_CONDITION_WITH_EXPRESSION -> return None()
EOL_COMMENT -> return checkComment(parent, configuration)
FUNCTION_LITERAL -> return Lambda(parent)
STRING_TEMPLATE, DOT_QUALIFIED_EXPRESSION -> {
stringOrDot = parent
parent.findParentNodeWithSpecificType(BINARY_EXPRESSION) ?. let {
parent = it
} ?: parent.findParentNodeWithSpecificType(VALUE_ARGUMENT_LIST) ?. let {
val parentIsBinExpOrValArgListOrWhenEntry = listOf<IElementType>(BINARY_EXPRESSION, VALUE_ARGUMENT_LIST, WHEN_CONDITION_WITH_EXPRESSION)
findParentNodeWithSpecificTypeMany(parent, parentIsBinExpOrValArgListOrWhenEntry) ?. let {
parent = it
} ?: run {
val parentFun = parent.findParentNodeWithSpecificType(FUN)
val parentProperty = parent.findParentNodeWithSpecificType(PROPERTY)
val returnElem = checkStringTemplateAndDotQualifiedExpression(parent, configuration, parentProperty ?: parentFun)
val parentIsPropertyOrFun = listOf<IElementType>(PROPERTY, FUN)
val parenPropertyOrFunNode = findParentNodeWithSpecificTypeMany(parent, parentIsPropertyOrFun)
val returnElem = checkStringTemplateAndDotQualifiedExpression(parent, configuration, parenPropertyOrFunNode)
if(returnElem !is None)
return returnElem
parent = parent.treeParent
Expand All @@ -184,13 +193,13 @@ class LineLength(configRules: List<RulesConfig>) : DiktatRule(
return None()
}

/**
* Analyzes the Binary expression and decides to go higher level with the analysis or analyze at this level
*/
private fun isConditionToUpAnalysisBinExpression(parent: ASTNode, offset: Int): Boolean {
val parentIsBiExprOrParenthesized = parent.treeParent.elementType in listOf(BINARY_EXPRESSION, PARENTHESIZED)
val parentIsFunOrProperty = parent.treeParent.elementType in listOf(FUN, PROPERTY)
return (parentIsBiExprOrParenthesized || (parentIsFunOrProperty && offset >= configuration.lineLength))
private fun findParentNodeWithSpecificTypeMany(node: ASTNode, listType : List<IElementType>): ASTNode? {
listType.forEach { type ->
node.findParentNodeWithSpecificType(type) ?. let {
return it
}
}
return null
}

/**
Expand Down Expand Up @@ -291,14 +300,6 @@ class LineLength(configRules: List<RulesConfig>) : DiktatRule(
return None()
}

private fun checkArgumentList(wrongNode: ASTNode, configuration: LineLengthConfiguration) : LongLineFixableCases {
val node = searchRightSplitAfterType(wrongNode, configuration, COMMA)?.first
node ?. let {
return ValueArgumentList(wrongNode, node)
}
return ValueArgumentList(wrongNode)
}

private fun checkFunAndProperty(wrongNode: ASTNode) =
if (wrongNode.hasChildOfType(EQ)) FunAndProperty(wrongNode) else None()

Expand Down Expand Up @@ -349,27 +350,70 @@ class LineLength(configRules: List<RulesConfig>) : DiktatRule(
is DotQualifiedExpression -> fixDotQualifiedExpression(fixableType)
is ValueArgumentList -> fixArgumentList(fixableType)
is Lambda -> fixLambda(fixableType.node)
is WhenEntry -> fixWhenEntry(fixableType)
is None -> return
}
}

private fun fixWhenEntry(wrongWhenEntry : WhenEntry) {
val node = wrongWhenEntry.node
node.getFirstChildWithType(ARROW) ?. let {
node.addChild(PsiWhiteSpaceImpl(" "), it.treeNext)
node.addChild(PsiWhiteSpaceImpl("{"), it.treeNext.treeNext)
node.appendNewlineMergingWhiteSpace(it.treeNext.treeNext.treeNext, it.treeNext.treeNext.treeNext)
}
node.appendNewlineMergingWhiteSpace(node.lastChildNode.treeNext, node.lastChildNode.treeNext)
node.addChild(PsiWhiteSpaceImpl("}"), node.lastChildNode.treeNext)
}

private fun fixDotQualifiedExpression(wrongDotQualifiedExpression: DotQualifiedExpression) {
val node = wrongDotQualifiedExpression.node
val dot = node.getFirstChildWithType(DOT)
node.appendNewlineMergingWhiteSpace(dot,dot)
}
private fun fixArgumentList(wrongArgumentList: ValueArgumentList) {

private fun fixArgumentsListFirstArgument(wrongArgumentList: ValueArgumentList) : Int{
val lineLength = wrongArgumentList.maximumLineLength.lineLength
val node = wrongArgumentList.node
val nodeWithComma = wrongArgumentList.nodeForSplit
val comma = nodeWithComma?.getFirstChildWithType(COMMA)
comma ?. let {
nodeWithComma.appendNewlineMergingWhiteSpace(comma, comma)
} ?: run {
var offset = 0
node.getFirstChildWithType(COMMA) ?. let {
if (positionByOffset(it.startOffset).second > lineLength) {
node.appendNewlineMergingWhiteSpace(node.findChildByType(LPAR)!!.treeNext, node.findChildByType(LPAR)!!.treeNext)
node.appendNewlineMergingWhiteSpace(node.findChildByType(RPAR), node.findChildByType(RPAR))
offset = 50
}
} ?: node.getFirstChildWithType(RPAR) ?. let {
node.appendNewlineMergingWhiteSpace(node.findChildByType(LPAR)!!.treeNext, node.findChildByType(LPAR)!!.treeNext)
node.appendNewlineMergingWhiteSpace(node.findChildByType(RPAR), node.findChildByType(RPAR))
node.getChildren(null).forEach { elem->
if (elem.elementType == COMMA && elem.treeNext.elementType != RPAR)
node.appendNewlineMergingWhiteSpace(elem.treeNext, elem.treeNext)
offset = 50
}
return offset
}

private fun fixArgumentList(wrongArgumentList: ValueArgumentList) {
val lineLength = wrongArgumentList.maximumLineLength.lineLength
val node = wrongArgumentList.node
val offset = fixArgumentsListFirstArgument(wrongArgumentList)
val listComma = node.getAllChildrenWithType(COMMA).map {
it to positionByOffset(it.startOffset - offset).second
}.sortedBy { it.second } //.filter { }
var n = 1
listComma.forEachIndexed { index, pair ->
if (pair.second >= n * lineLength){
n++
val commaSplit = if (index > 0){
listComma[index - 1].first
} else {
pair.first
}
node.appendNewlineMergingWhiteSpace(commaSplit.treeNext, commaSplit.treeNext)
}
}
node.getFirstChildWithType(RPAR) ?. let {
if (positionByOffset(it.treePrev.startOffset).second + it.treePrev.text.length - offset > lineLength * n && listComma.isNotEmpty()) {
listComma.last().first.run {
node.appendNewlineMergingWhiteSpace(this.treeNext, this.treeNext)
}
}
}
}
Expand Down Expand Up @@ -673,7 +717,7 @@ class LineLength(configRules: List<RulesConfig>) : DiktatRule(
private class FunAndProperty(node: ASTNode) : LongLineFixableCases(node)

/**
* Class Lambda show that long line should be split in Comment: in space between two words
* Class Lambda show that long line should be split in Lambda: in space after LBRACE node and before RBRACE node
*/
private class Lambda(node: ASTNode) : LongLineFixableCases(node)

Expand All @@ -687,7 +731,10 @@ class LineLength(configRules: List<RulesConfig>) : DiktatRule(
* If [nodeForSplit] !is null that node should be split after this COMMA
* Else ([nodeForSplit] is null) - node should be split after LPAR, before RPAR and after all COMMA
*/
private class ValueArgumentList(node: ASTNode, val nodeForSplit: ASTNode? = null) : LongLineFixableCases(node)
private class ValueArgumentList(node: ASTNode, val maximumLineLength: LineLengthConfiguration) : LongLineFixableCases(node)

private class WhenEntry(node: ASTNode) : LongLineFixableCases(node)

/**
* val text = "first part" +
* "second part" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,8 @@ class LineLengthFixTest : FixTestBase("test/paragraph3/long_line", ::LineLength)
fixAndCompare("LongDotQualifiedExpressionExpected.kt", "LongDotQualifiedExpressionTest.kt", rulesConfigListLineLength)
}


@Test
fun `fix long value arguments list`() {
fixAndCompare("LongValueArgumentsListExpected.kt", "LongValueArgumentsListTest.kt", rulesConfigListLineLength)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package test.paragraph3.long_line

val A = This.Is.Veeeeryyyyyyy.Loooooong.Dot.Qualified.Expression
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package org.cqfn.diktat.resources.paragraph3.longline
class veryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong {
// looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongggggggggggggggggggggggggg
//looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongggggggggggggggggggggggggg
val s = "d" +
" s d d d d ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
val s =
"d s d d d d ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.cqfn.diktat.resources.paragraph3.longline

class veryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong {
// looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongggggggggggggggggggggggggg
//looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongggggggggggggggggggggggggg
val s =
"d s d d d d ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ fun foo() {
// ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ElementType.IF -> handleIfElse(node)
ElementType.EOL_COMMENT, ElementType.BLOCK_COMMENT -> handleEolAndBlockComments(node, configuration)
ElementType.KDOC -> handleKdocComments(node, configuration)
ElementType.KDOC -> {
handleKdocComments(node, configuration)
}
// ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
else -> {
// this is a generated else block
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,27 @@ package test.paragraph3.long_line

@Query(
value = "select * from test inner join test_execution on test.id = test_execution.test_id and test_execution.st",
nativeQuery = true)
nativeQuery = true
)
fun retrieveBatches(limit: Int, offset: Int, executionId: Long): Some

@Query(value = "select * from test inner join test_execution on test.id = test_execution.test_id and test_execution.status = 'READY' and test_execution.test_suite_execution_id = ?3 limit ?1 offset ?2", nativeQuery = true)
@Query(
value = "select * from test inner join test_execution on test.id = test_execution.test_id and test_execution.status = 'READY' and test_execution.test_suite_execution_id = ?3 limit ?1 offset ?2",
nativeQuery = true
)
fun some(limit: Int, offset: Int, executionId: Long): List<Test>

@Query(value = "select * from test inner joi", nativeQuery = true)
@Query(value = "select * from test inner joi",
nativeQuery = true)
fun test(limit: Int, offset: Int, executionId: Long): List<Test>

@Query(value = "select * from test inner joibbb", nativeQuery = true)
@Query(value = "select * from test inner joibbb",
nativeQuery = true)
fun cornerCase(limit: Int, offset: Int, executionId: Long): List<Test>

@Query(value = "select * from test inner join" +
" test_execution on test.id = test_execution.test_id and test_execution.status = 'READY' and test_execution.test_suite_execution_id = ?3 limit ?1 offset ?2", nativeQuery = true)
@Query(
value = "select * from test inner join test_execution on test.id = test_execution.test_id and test_execution.status = 'READY' and test_execution.test_suite_execution_id = ?3 limit ?1 offset ?2",
nativeQuery = true
)
fun some(limit: Int, offset: Int, executionId: Long) =
println("testtesttesttesttesttesttesttesttesttesttesttest")
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ object Observables {
val someCode = 15
// Some
// looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line
@Deprecated("New type inference algorithm in Kotlin 1.4 makes this method obsolete. Method will be removed in" +
" future RxKotlin release.",
replaceWith = ReplaceWith("Observable.combineLatest(source1, source2, source3, source4, combineFunction)", "io.reactivex.Observable"),
level = DeprecationLevel.WARNING)
@Deprecated(
"New type inference algorithm in Kotlin 1.4 makes this method obsolete. Method will be removed in future RxKotlin release.",
replaceWith = ReplaceWith("Observable.combineLatest(source1, source2, source3, source4, combineFunction)",
"io.reactivex.Observable"),
level = DeprecationLevel.WARNING
)
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
inline fun <T1 : Any, T2 : Any, T3 : Any, T4 : Any, R : Any> combineLatest() {}
Expand All @@ -15,9 +17,12 @@ val someCode = 15
class Foo() {

fun Fuu() {
logger.log("<-- ${response.code} ${ if (response.message.isEmpty()) "skfnvkdjdfvd" else "dfjvndkjnbvif" +
response.message}")
logger.log("<-- ${response.code} ${ if (response.message.isEmpty()) "skfnvsdcsdcscskdjdfvd" else "dfjvndsdcsdcsdcskjnbvif" + response.message}")
logger.log(
"<-- ${response.code} ${ if (response.message.isEmpty()) "skfnvkdjdfvd" else "dfjvndkjnbvif" + response.message}"
)
logger.log(
"<-- ${response.code} ${ if (response.message.isEmpty()) "skfnvsdcsdcscskdjdfvd" else "dfjvndsdcsdcsdcskjnbvif" + response.message}"
)
}

val q = """
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package test.paragraph3.long_line

val firstArgument = 1
val secondArgument = 2
val thirdArgument = 3
val fourthArgument = 4
val fifthArguments = 5
val sixthArguments = 6
val seventhArguments = 7
val eighthArguments = 8

// Many arguments in function
val result1 = ManyParamInFunction(firstArgument,
secondArgument, thirdArgument, fourthArgument,
fifthArguments, sixthArguments, seventhArguments,
eighthArguments)

//
val result2 = veryLongNameFun(firstArgument,
secondArgument)

// first argument cannot to be able to stay in
// the first line
val result3 = veryLongNameInFirstParam(
firstArgument, secondArgument, thirdArgument
)

// first argument cannot to be able to stay in
// the first line
val result4 = veryLongNameInFirstParam(
firstArgument
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package test.paragraph3.long_line

val firstArgument = 1
val secondArgument = 2
val thirdArgument = 3
val fourthArgument = 4
val fifthArguments = 5
val sixthArguments = 6
val seventhArguments = 7
val eighthArguments = 8

// Many arguments in function
val result1 = ManyParamInFunction(firstArgument, secondArgument, thirdArgument, fourthArgument, fifthArguments, sixthArguments, seventhArguments, eighthArguments)

//
val result2 = veryLongNameFun(firstArgument, secondArgument)

// first argument cannot to be able to stay in the first line
val result3 = veryLongNameInFirstParam(firstArgument, secondArgument, thirdArgument)

// first argument cannot to be able to stay in the first line
val result4 = veryLongNameInFirstParam(firstArgument)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package org.cqfn.diktat

val A = This.Is.Veeeeryyyyyyy.Loooooong.Dot.Qualified.Expression
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.cqfn.diktat

/**
* @return
*/
val A = This.Is.Veeeeryyyyyyy.Loooooong.Dot.Qualified.Expression

0 comments on commit 949f78a

Please sign in to comment.