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

Consider disallowing default cases in switch statements #480

Closed
pkoenig10 opened this issue Nov 30, 2018 · 7 comments
Closed

Consider disallowing default cases in switch statements #480

pkoenig10 opened this issue Nov 30, 2018 · 7 comments

Comments

@pkoenig10
Copy link
Member

What happened?

If a switch statement has a default case, then the MissingCasesInEnumSwitch check is ineffective. This makes is easy to accidentally not handle new enum variants.

For example, suppose we have:

enum Colors {
    RED,
    GREEN
}

boolean isRedOrBlue(Color color) {
    switch (color) {
        case RED:
            return true;
        case GREEN:
            return false;
        default:
            throw new RuntimeException("Unknown color");
    }
}

And then a BLUE variant is added to the enum:

enum Colors {
    RED,
    GREEN,
    BLUE
}

There will not be a warning that the switch statement does not explicitly handle the BLUE case and that the method is now incorrect.

What did you want to happen?

Each enum variant should be explicitly handled to ensure that we get a warning when new variants are added. To ensure the MissingCasesInEnumSwitch check always checks for missing cases, default cases should be disallowed.

The initial example would change to:

boolean isRedOrBlue(Color color) {
    switch (color) {
        case RED:
            return true;
        case GREEN:
            return false;
    }

    throw new RuntimeException("Unknown color");
}
bulldozer-bot bot pushed a commit that referenced this issue Dec 4, 2018
Fixes #480

A severity of `WARNING` is probably too strong for this check.
@iamdanfox
Copy link
Contributor

Closed by #481

@whickman
Copy link

whickman commented Mar 12, 2019

hey @iamdanfox @pkoenig10 , why did we do this? there's also this http://errorprone.info/bugpattern/MissingDefault which requires default.

also the docs you linked say "To avoid this ambiguity, the Google Java Style Guide requires each switch statement on an enum type to either handle all values of the enum, or have a default statement group," so it seems like having default is fine.

cc @bwaldrep

@pkoenig10
Copy link
Member Author

pkoenig10 commented Mar 12, 2019

The error prone docs also state:

A switch statement for an enum type may omit the default statement group, if it includes explicit cases covering all possible values of that type.

This check enforces our preference for using this strategy to handle enum values. The issue with using a default is that you will not be warned when a new enum variant is added that you may want to handle differently that the current default behavior.

This was primarily motivated by the desire to enforce proper handling of enums returned from API endpoints, which may return values the client does not know about. There are certainly cases where this check is more of a hindrance than a help and in those cases you should feel free to suppress the warning. But having the warning forces you to consider the tradeoff you are making by doing so.

@whickman
Copy link

I understand the argument. My concerns: this is a pretty big break for our codebase in a minor version and the preference for enumerating all options doesn't really seem like it was discussed, nor does it appear standard elsewhere.

Would like to have this sort of thing called out in the release notes at a minimum. Breaks like this make excavator changes very painful.

@iamdanfox
Copy link
Contributor

iamdanfox commented Mar 12, 2019

@whickman I think this is actually only a warning? We intentionally only promote things to error when we have high confidence that they should be applied everywhere, and I think this was still in the 'rollout' phase?

EDIT it's actually even lower, SUGGESTION really should not block PRs merging

@bwaldrep
Copy link

@iamdanfox You are correct, this is not actually blocking the merge. I got confused by the gradle output with -Werror as to which warnings were blocking and which were just advisory.

@whickman
Copy link

Aha, sorry @pkoenig10 and @iamdanfox for all this, then. fine with this being a suggestion

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

No branches or pull requests

4 participants