SwiftLint icon indicating copy to clipboard operation
SwiftLint copied to clipboard

Custom Rule shows warning message on incorrect line number

Open prabindatta opened this issue 1 year ago • 1 comments

New Issue Checklist

Bug Description

I have added a custom rule to check if developer has used booleanVariable == true or booleanVariable == false except when we have optional chain like optionalVariable?.booleanVariable == true or optionalVariable?.booleanVariable == false Rules are working and I can see warning message is shown to developers except it always appear couple of lines above the actual expected line of code.

// This triggers a violation:
func checkBooleanValues() {
        // Check isUserLoggedIn
        if isUserLoggedIn == true { // This line should have the warning message
            print("User is logged in")
            handleLoggedInUser()
        } else {
            print("User is not logged in")
            handleLoggedOutUser()
        }
}

Mention the command or other SwiftLint integration method that caused the issue. Include stack traces or command output.

# Type a script or drag a script file from your workspace to insert its path.
SWIFTLINT=${PODS_ROOT}/SwiftLint/swiftlint

if [ -f $SWIFTLINT ];
then
    "$SWIFTLINT"
else
    echo "warning: `swiftlint` command not found - See https://github.com/realm/SwiftLint#installation for installation instructions."
fi

Environment

SwiftLint version: 0.56.1 Xcode version: Xcode 15 (unrelated, replicable in CLI) Installation method: Homebrew and Cocoapod (both have same behaviour)

  • Configuration file:
custom_rules:
  already_false:
    regex: '^(?:(?!\?).)* == false'
    message: "Don't compare to false, just use !value."

  already_true:
    regex: '^(?:(?!\?).)* == true'
    message: "Don't compare to true, just use the bool value."

prabindatta avatar Aug 22 '24 05:08 prabindatta

This is mentioned in the README:

It is important to note that the regular expression pattern is used with the flags s and m enabled, that is . matches newlines and ^/$ match the start and end of lines, respectively. If you do not want to have . match newlines, for example, the regex can be prepended by (?-s).

Your regex matches up to as many lines before as it can. Since the position where it triggers is the beginning of the match be default, you see the warning "somewhere". Prepending the regex with (?-s) at least makes the rule trigger in the line where the violation actually appears.

SimplyDanny avatar Aug 22 '24 13:08 SimplyDanny