Skip to content

☂️ [wildcards] new and updated diagnostics / lints #56595

@pq

Description

@pq

Accommodating wildcards implies changes to a number of existing diagnostics and lints. In a number of places we're already supporting a kind of simulation of wildcards (ignoring unused catch parameters for example and ignoring unused identifiers with just underscores and special casing underscores in naming lints) and it's tempting to see this as an opportunity to fix the approximations now that we have actual wildcards and moreover nudge people towards using them appropriately. Unfortunately, this is complicated by interrelationships between the existing lints and diagnostics.

This issue will attempt to tease out these relationships, explore diagnostics we want to report and give us a place to discuss a plan forward.

Lints (current)

  • non_constant_identifier_names (core lint)

    • allows parameters with just underscores
    • allows variables and members named _ (but not __... – except constructors where __+ is ok)
  • no_leading_underscores_for_local_identifiers (recommended lint)

    • allows variables with just underscores
  • no_wildcard_variable_uses (core lint)

    • disallows the use of any identifier that is just underscores
  • empty_catches (core lint)

    • allows a catch with an empty body if the parameter is named _
    • requires a body or a comment for all other identifiers

Annotations (current)

  • @useResult
    • assignment to any identifier is considered a legitimate “use”

Question: should wildcards be special-cased?

Diagnostics (current)

TODO

Wildcard Uses (future)

With wildcards we can improve some current Dart idioms.

For example:

Unused catch clause parameters.

An idiom for catching and ignoring all thrown exceptions is to write this:

try {

} catch(e) {

}

Since the identifier cannot be omitted we do not report it as unused. (Nor did we choose to require it to be an underscore.)

With wildcards, we might consider flagging all bound parameters (e.g., non-wildcards) and encourage the use of a wildcard. With such a fix, the above code would become:

try {

} catch(_) {

}

Proposal: new lint: use_catch_parameters

See also #5571 which proposes that such cases be treated as warnings (UNUSED_LOCAL_VARIABLE or a new UNUSED_CATCH_PARAMETER diagnostic).

Reasons for a lint over a warning:

  1. feels like a style concern which is more the province of lints
  2. a warning could be very disruptive (Google3 migration could be onerous)

Unnecessary underscores.

With _ binding, developers have adopted an idiom of using multiple underscores for parameters that they intend to be unused.

For example:

f(int _, int __) { }

With wildcards, we might consider flagging unnecessary (multiple) underscores and encourage the use of a proper wildcard. With such a fix, the above code would become:

f(int _, int _) { }

Proposal: new lint: unnecessary_underscores

Unused parameters.

Unused parameters are not currently reported (except by avoid_unused_constructor_parameters for constructors). In some cases the unused parameters might signal a programming error.

int f(int x, int y, int z) => x + y;

With wildcards, we might consider flagging unused parameters and encourage the use a wildcard variable (or removal of the parameter). With such a fix, the above code would become:

int f(int x, int y, int _) => x + y;

or:

int f(int x, int y) => x + y;

Complications:

  • its common practice for parameters in overriding methods to match the name in the overridden method; would we skip those cases?
  • for similar reasons, we would not want to recommend an unused parameter in an overridden method be converted to a wildcard but here it's trickier since we can't know if there are any overrides
  • and what about augmentations? 😬

Proposal: do nothing.

(It'd be great to get more feedback here.)

EDIT see related discussion and proposal in #59475 (similar conclusion)

Implementation

New lints

I've proposed 2 new lints to ease adoption and Google3 migration. (Alternatively, we might consider a super use_wildcard_variables lint that enforces both proposals but this could limit adoption. Open question!)

If we introduce new lints, existing ones can remain largely unchanged.

Existing lints

  • non_constant_identifier_names : unchanged
  • no_leading_underscores_for_local_identifiers: unchanged
  • no_wildcard_variable_uses: update to be a no-op with wildcards enabled
  • empty_catches:
    • do we want to start reporting on non-wildcard parameters?
    • maybe only when use_catch_parameters is enabled?

While this is still a bit rough and not complete, feedback is welcome!

/cc @bwilkerson @kallentu

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2A bug or feature request we're likely to work onarea-devexpFor issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages.devexp-warningIssues with the analyzer's Warning codesfeature-wildcard-variablesImplementation of the wildcard variables featuretype-enhancementA request for a change that isn't a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions