pinterest / ktlint

An anti-bikeshedding Kotlin linter with built-in formatter
https://pinterest.github.io/ktlint/
MIT License
6.07k stars 504 forks source link

Internal Error (rule 'standard:binary-expression-wrapping') #2601

Closed Kolyall closed 3 months ago

Kolyall commented 3 months ago

Error: Version 1.2.1 ./ktlint -F /path/*/.kt

Internal Error (rule 'standard:binary-expression-wrapping') in MyViewModel.kt at position '0:0. Please create a ticket at https://github.com/pinterest/ktlint/issues and provide the source code that triggered an error.
com.pinterest.ktlint.rule.engine.api.KtLintRuleException: Rule 'standard:binary-expression-wrapping' throws exception in file 'MarketplaceDeliveryViewModel.kt' at position (0:0)
   Rule maintainer: KtLint
   Issue tracker  : https://github.com/pinterest/ktlint/issues
   Repository     : https://github.com/pinterest/ktlint
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRule(RuleExecutionContext.kt:65)
        at com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine$format$3.invoke(KtLintRuleEngine.kt:146)
        at com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine$format$3.invoke(KtLintRuleEngine.kt:145)
        at com.pinterest.ktlint.rule.engine.internal.VisitorProvider$visitor$3.invoke(VisitorProvider.kt:46)
        at com.pinterest.ktlint.rule.engine.internal.VisitorProvider$visitor$3.invoke(VisitorProvider.kt:44)
        at com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine.format(KtLintRuleEngine.kt:145)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine.format(KtlintCommandLine.kt:476)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine.process(KtlintCommandLine.kt:462)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine.access$process(KtlintCommandLine.kt:68)
        at com.pinterest.ktlint.cli.internal.KtlintCommandLine$lintFiles$3.invoke$lambda$0(KtlintCommandLine.kt:402)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.IllegalArgumentException: First node in non-empty sequence must be a whitespace containing a newline
        at com.pinterest.ktlint.rule.engine.core.api.ASTNodeExtensionKt.lineLengthWithoutNewlinePrefix(ASTNodeExtension.kt:505)
        at com.pinterest.ktlint.ruleset.standard.rules.BinaryExpressionWrappingRule.causesMaxLineLengthToBeExceeded(BinaryExpressionWrappingRule.kt:257)
        at com.pinterest.ktlint.ruleset.standard.rules.BinaryExpressionWrappingRule.visitBinaryExpression(BinaryExpressionWrappingRule.kt:152)
        at com.pinterest.ktlint.ruleset.standard.rules.BinaryExpressionWrappingRule.beforeVisitChildNodes(BinaryExpressionWrappingRule.kt:82)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$1.invoke(RuleExecutionContext.kt:125)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$1.invoke(RuleExecutionContext.kt:124)
        at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:124)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.access$executeRuleOnNodeRecursively(RuleExecutionContext.kt:30)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:132)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext$executeRuleOnNodeRecursively$2$1.invoke(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.SuppressHandler.handle(SuppressHandler.kt:28)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:131)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRuleOnNodeRecursively(RuleExecutionContext.kt:93)
        at com.pinterest.ktlint.rule.engine.internal.RuleExecutionContext.executeRule(RuleExecutionContext.kt:62)
        ... 13 more
 ()
paul-dingemans commented 3 months ago

Please include code sample that reproduces the problem. Also specify editorconfig and klont version

Kolyall commented 3 months ago

@paul-dingemans

ktlint version 1.2.1

File kt example:

class MyViewModel(
) : BaseViewModel(),
    GeoListener,
    GeoListener {

    private fun checkReady() {
        when (deliveryType) {
            MyEnum.FIRST -> {
                isReady = expressInfo.address?.let {
                    /*it.city.isNotEmpty() && */it.street.isNotEmpty()
                } ?: false
            }

            else -> {
                isReady = /*expressInfo.address?.city?.isNotEmpty() ?: false
                        &&*/ expressInfo.address?.street?.isNotEmpty() ?: false &&
                        expressInfo.deliveryTime?.date?.isNotEmpty() ?: false &&
                        expressInfo.deliveryTime?.timeFrameCode?.isNotEmpty() ?: false
            }
        }
    }

}

Rules:

[{*.gradle.kts,*.kt,*.kts,*.main.kts}]
ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL
ij_kotlin_align_multiline_parameters = true
ij_kotlin_align_multiline_parameters_in_calls = true
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true
ij_kotlin_block_comment_add_space = true
ij_kotlin_call_parameters_new_line_after_left_paren = true
ij_kotlin_call_parameters_right_paren_on_new_line = true
ij_kotlin_call_parameters_wrap = split_into_lines
ij_kotlin_catch_on_new_line = false
ij_kotlin_class_annotation_wrap = split_into_lines
ij_kotlin_else_on_new_line = false
ij_kotlin_enum_constants_wrap = split_into_lines
ij_kotlin_extends_list_wrap = split_into_lines
ij_kotlin_field_annotation_wrap = split_into_lines
ij_kotlin_finally_on_new_line = false
ij_kotlin_if_rparen_on_new_line = false
ij_kotlin_import_nested_classes = false
ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
ij_kotlin_keep_blank_lines_in_code = 1
ij_kotlin_keep_blank_lines_in_declarations = 1
ij_kotlin_lbrace_on_next_line = false
ij_kotlin_line_comment_add_space = true
ij_kotlin_line_comment_add_space_on_reformat = true
ij_kotlin_method_annotation_wrap = split_into_lines
ij_kotlin_method_parameters_new_line_after_left_paren = true
ij_kotlin_method_parameters_right_paren_on_new_line = true
ij_kotlin_method_parameters_wrap = split_into_lines
ij_kotlin_name_count_to_use_star_import = 2147483647
ij_kotlin_name_count_to_use_star_import_for_members = 2147483647
ij_kotlin_packages_to_use_import_on_demand = kotlinx.android.synthetic.**
ij_kotlin_parameter_annotation_wrap = split_into_lines
ij_kotlin_space_after_comma = true
ij_kotlin_space_after_extend_colon = true
ij_kotlin_space_after_type_colon = true
ij_kotlin_space_before_catch_parentheses = true
ij_kotlin_space_before_comma = false
ij_kotlin_space_before_extend_colon = true
ij_kotlin_space_before_for_parentheses = true
ij_kotlin_space_before_if_parentheses = true
ij_kotlin_space_before_lambda_arrow = true
ij_kotlin_space_before_type_colon = false
ij_kotlin_space_before_when_parentheses = true
ij_kotlin_space_before_while_parentheses = true
ij_kotlin_spaces_around_additive_operators = true
ij_kotlin_spaces_around_assignment_operators = true
ij_kotlin_spaces_around_equality_operators = true
ij_kotlin_spaces_around_function_type_arrow = true
ij_kotlin_spaces_around_logical_operators = true
ij_kotlin_spaces_around_multiplicative_operators = true
ij_kotlin_spaces_around_range = false
ij_kotlin_spaces_around_relational_operators = true
ij_kotlin_spaces_around_unary_operator = false
ij_kotlin_spaces_around_when_arrow = true
ij_kotlin_use_custom_formatting_for_modifiers = true

# KtLint configuration
ktlint_code_style = ktlint_official
ktlint_experimental = enabled
ktlint_standard_package-name = disabled
ktlint_standard_function-expression-body = disabled
ktlint_standard_max-line-length = disabled
ktlint_standard_backing-property-naming = disabled
ktlint_standard_property-naming = disabled
ktlint_standard_no-consecutive-comments = disabled
ktlint_standard_kdoc = disabled
ktlint_standard_no-wildcard-imports = disabled
ktlint_standard_filename = disabled
ktlint_standard_comment-wrapping = disabled
ktlint_standard_if-else-wrapping = disabled
ktlint_standard_enum-entry-name-case = disabled
ktlint_standard_no-empty-file = disabled
ktlint_standard_value-parameter-comment = disabled
ktlint_standard_class-naming = disabled
ktlint_standard_value-argument-comment = disabled
ktlint_standard_function-naming = disabled

ktlint_function_signature_body_expression_wrapping = default
ktlint_standard_function-signature = enabled
ktlint_standard_if-else-bracing = enabled
ktlint_standard_import-ordering = enabled
# ktlint_standard_binary-expression-wrapping = disabled
ktlint_standard_no-empty-first-line-in-class-body = disabled
ktlint_standard_no-single-line-block-comment = disabled
ktlint_standard_multiline-if-else = enabled
ktlint_standard_no-blank-line-before-rbrace = enabled
ktlint_standard_no-blank-lines-in-chained-method-calls = enabled
ktlint_standard_no-consecutive-blank-lines = enabled
ktlint_standard_no-empty-class-body = enabled
ktlint_standard_no-empty-first-line-in-method-block = disabled
ktlint_standard_no-line-break-after-else = enabled
ktlint_standard_no-line-break-before-assignment = enabled
ktlint_standard_no-multi-spaces = enabled
ktlint_standard_no-semi = enabled
ktlint_standard_no-unit-return = enabled
ktlint_standard_no-unused-imports = enabled
ktlint_standard_spacing-around-angle-brackets = enabled
ktlint_standard_annotation-spacing = enabled
ktlint_standard_spacing-between-declarations-with-annotations = enabled
ktlint_standard_spacing-between-declarations-with-comments = enabled
ktlint_standard_colon-spacing = enabled
ktlint_standard_comma-spacing = enabled
ktlint_standard_comment-spacing = enabled
ktlint_standard_curly-spacing = enabled
ktlint_standard_dot-spacing = enabled
ktlint_standard_double-colon-spacing = enabled
ktlint_standard_function-return-type-spacing = enabled
ktlint_standard_function-start-of-body-spacing = enabled
ktlint_standard_function-type-reference-spacing = enabled
ktlint_standard_fun-keyword-spacing = enabled
ktlint_standard_kdoc-wrapping = enabled
ktlint_standard_keyword-spacing = enabled
ktlint_standard_modifier-list-spacing = enabled
ktlint_standard_nullable-type-spacing = enabled
ktlint_standard_op-spacing = enabled
ktlint_standard_parameter-list-spacing = enabled
ktlint_standard_paren-spacing = enabled
ktlint_standard_range-spacing = enabled
ktlint_standard_spacing-between-function-name-and-opening-parenthesis = enabled
ktlint_standard_try-catch-finally-spacing = enabled
ktlint_standard_type-argument-list-spacing = enabled
ktlint_standard_type-parameter-list-spacing = enabled
ktlint_standard_unary-op-spacing = enabled
ktlint_standard_string-template = disabled
ktlint_standard_string-template-indent = disabled
# ktlint_standard_trailing-comma-on-call-site = enabled
ktlint_standard_trailing-comma-on-call-site = disabled
# ktlint_standard_trailing-comma-on-declaration-site = enabled
ktlint_standard_trailing-comma-on-declaration-site = disabled
ktlint_standard_type-argument-comment = enabled
ktlint_standard_type-parameter-comment = enabled
ktlint_standard_unnecessary-parentheses-before-trailing-lambda = enabled
ktlint_standard_value-argument-comment = enabled
ktlint_standard_value-parameter-comment = enabled
ktlint_standard_argument-list-wrapping = enabled
ktlint_argument_list_wrapping_ignore_when_parameter_count_greater_or_equal_than = 1
# ktlint_standard_chain-wrapping = enabled
ktlint_standard_chain-wrapping = disabled
ktlint_standard_comment-wrapping = enabled
ktlint_standard_context-receiver-wrapping = enabled
ktlint_standard_enum-wrapping = enabled
ktlint_standard_if-else-wrapping = enabled
ktlint_standard_multiline-expression-wrapping = disabled
ktlint_standard_parameter-list-wrapping = disabled
ktlint_standard_parameter-wrapping = disabled
ktlint_standard_property-wrapping = disabled
ktlint_standard_statement-wrapping = enabled
ktlint_standard_wrapping = disabled
ij_kotlin_wrap_first_method_in_call_chain = false
paul-dingemans commented 3 months ago

Tnx for reporting. I can reproduce the problem. It is caused by the newline character in the last block comment. You can prevent this problem by writing the code like:

class MyViewModel :
    BaseViewModel(),
    GeoListener,
    GeoListener {
    private fun checkReady() {
        when (deliveryType) {
            MyEnum.FIRST -> {
                isReady = expressInfo.address?.let {
                    /* it.city.isNotEmpty() &&*/it.street.isNotEmpty()
                } ?: false
            }

            else -> {
                isReady = /*expressInfo.address?.city?.isNotEmpty() ?: false &&*/
                    expressInfo.address?.street?.isNotEmpty() ?: false &&
                    expressInfo.deliveryTime?.date?.isNotEmpty() ?: false &&
                    expressInfo.deliveryTime?.timeFrameCode?.isNotEmpty() ?: false
            }
        }
    }
}

But of course not exception should have thrown.