realm / SwiftLint

A tool to enforce Swift style and conventions.
https://realm.github.io/SwiftLint
MIT License
18.58k stars 2.22k forks source link

Custom Rule shows warning message on incorrect line number #5766

Open prabindatta opened 3 weeks ago

prabindatta commented 3 weeks ago

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)

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."
SimplyDanny commented 3 weeks ago

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.