Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New rule: RedundantExplicitOperatorCall #7034

Open
osipxd opened this issue Mar 9, 2024 · 0 comments
Open

New rule: RedundantExplicitOperatorCall #7034

osipxd opened this issue Mar 9, 2024 · 0 comments

Comments

@osipxd
Copy link
Contributor

osipxd commented Mar 9, 2024

This issue is continue of discussion started in #7019 (comment)

Expected Behavior of the rule

The rule should report explicit call of operator fun where it is possible to use its operator form.

Config:

RedundantExplicitOperatorCall:
    enabled: true
    # This is just an example, list of default operators is not defined yet
    operators:
      - get
      - set
      - not

Examples:

val featureFlags: Map<String, Boolean> = ...

// Noncompliant
val isMyFeatureEnabled = featureFlags.get("myFeature")
if (isMyFeatureEnabled.not()) { ... }

// Compliant
val isMyFeatureEnabled = featureFlags["myFeature"]
if (!isMyFeatureEnabled) { ... }

Exceptions to the rule

  • With nullable types. Explicit call with nullable type should not be reported, as operators couldn't be called on nullable types (unless it is extension operator for nullable types):
    val featureFlags: Map<String, Boolean>? = ...
    
    featureFlags?.get("myFeature") // OK
    
    // but if we have an extension-function for nullable type
    operator fun Map<String, Boolean>?.get(key: String) = this?.get(key) ?: false
    
    featureFlags.get("myFeature") // Not OK
  • Call on implicit receiver. The only possible way to use operators with implicit receiver is to use this explicitly, so maybe such cases shouldn't be reported:
    with(featureFlags) {
        if (get("myFeature1")) println("OK")
        if (this["myFeature2"]) println("Also OK")
    }
  • Call chain. It may be not appreciated to use operator in a code written in functional style.
    sequenceOf(1, 2, 3)
        .filter { it % 2 == 0 }
        .plus(42) // It is an operator but it is OK to use it in call chain
        .forEach(::println)
    
    // With operator call it could be
    (sequenceOf(1, 2, 3)
        .filter { it % 2 == 0 }
        + 42)
        .forEach(::println)
  • Operator-specific exceptions. Specific restrictions for operators should also be handled. For example False positive on ExplicitCollectionElementAccessMethod with spread operator #5640

Context

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants