Repository: analysis-dev/diktat (kotlin)

Issue:
LAMBDA_IS_NOT_LAST_PARAMETER: incorrectly treats argument with nullable functional type as not functional
## Describe the bug
```kotlin
fun foo(lambda1: () -> Unit,
             lambda2: (() -> Unit)?
) {}
```
emits warning `LAMBDA_IS_NOT_LAST_PARAMETER`, but if `lambda2` is non-nullable, there is no warning:
```kotlin
fun foo(lambda1: () -> Unit,
             lambda2: (() -> Unit)
) {}
```

## Environment information
* diktat version: 1.0.0-rc.2

Pull request:
### What's done:
- Fixed bug
- Closes #992

Patch:
diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileSize.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileSize.kt
index d140e553e2..d556473ffe 100644
--- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileSize.kt
+++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter3/files/FileSize.kt
@@ -5,14 +5,9 @@ import org.cqfn.diktat.common.config.rules.RulesConfig
 import org.cqfn.diktat.common.config.rules.getRuleConfig
 import org.cqfn.diktat.ruleset.constants.Warnings.FILE_IS_TOO_LONG
 import org.cqfn.diktat.ruleset.rules.DiktatRule
-import org.cqfn.diktat.ruleset.utils.SRC_DIRECTORY_NAME
-import org.cqfn.diktat.ruleset.utils.getFilePath
-import org.cqfn.diktat.ruleset.utils.isGradleScript
-import org.cqfn.diktat.ruleset.utils.splitPathToDirs
 
 import com.pinterest.ktlint.core.ast.ElementType
 import org.jetbrains.kotlin.com.intellij.lang.ASTNode
-import org.slf4j.LoggerFactory
 
 /**
  * Rule that checks number of lines in a file
diff --git a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaParameterOrder.kt b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaParameterOrder.kt
index efa7d4fae2..6cef205889 100644
--- a/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaParameterOrder.kt
+++ b/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/chapter5/LambdaParameterOrder.kt
@@ -8,6 +8,7 @@ import org.cqfn.diktat.ruleset.utils.hasChildOfType
 import com.pinterest.ktlint.core.ast.ElementType
 import com.pinterest.ktlint.core.ast.ElementType.FUNCTION_TYPE
 import com.pinterest.ktlint.core.ast.ElementType.IDENTIFIER
+import com.pinterest.ktlint.core.ast.ElementType.NULLABLE_TYPE
 import org.jetbrains.kotlin.com.intellij.lang.ASTNode
 import org.jetbrains.kotlin.psi.KtFunction
 import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
@@ -28,7 +29,14 @@ class LambdaParameterOrder(configRules: List<RulesConfig>) : DiktatRule(
     @Suppress("UnsafeCallOnNullableType")
     private fun checkArguments(node: ASTNode) {
         val funArguments = (node.psi as KtFunction).valueParameters
-        val sortArguments = funArguments.sortedBy { it.typeReference?.node?.hasChildOfType(FUNCTION_TYPE) }
+        val sortArguments = funArguments
+            .sortedBy { valueParam ->
+                valueParam
+                    .typeReference
+                    ?.node
+                    ?.let { it.findChildByType(NULLABLE_TYPE) ?: it }
+                    ?.hasChildOfType(FUNCTION_TYPE)
+            }
         funArguments.filterIndexed { index, ktParameter -> ktParameter != sortArguments[index] }.ifNotEmpty {
             LAMBDA_IS_NOT_LAST_PARAMETER.warn(configRules, emitWarn, isFixMode, node.findChildByType(IDENTIFIER)!!.text,
                 first().node.startOffset, node)


Test patch:
diff --git a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/LambdaParameterOrderWarnTest.kt b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/LambdaParameterOrderWarnTest.kt
index 12def37611..9b6216fef8 100644
--- a/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/LambdaParameterOrderWarnTest.kt
+++ b/diktat-rules/src/test/kotlin/org/cqfn/diktat/ruleset/chapter5/LambdaParameterOrderWarnTest.kt
@@ -28,6 +28,8 @@ class LambdaParameterOrderWarnTest : LintTestBase(::LambdaParameterOrder) {
                     |fun foo(a: Int, myLambdab: () -> Unit, myLambda: () -> Unit)
                     |
                     |fun foo(a: Int? = null, myLambdab: () -> Unit, myLambda: () -> Unit)
+                    |
+                    |fun foo(lambda1: () -> Unit, lambda2: (() -> Unit)?) {}
                 """.trimMargin(),
             LintError(1, 17, ruleId, "${LAMBDA_IS_NOT_LAST_PARAMETER.warnText()} foo", false)
         )