-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Don't include already-covered cases in switch completions #51790
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
Conversation
if (caseClause && (isCaseKeyword(contextToken!) || isNodeDescendantOf(contextToken!, caseClause.expression))) { | ||
const tracker = newCaseClauseTracker(checker, caseClause.parent.clauses); | ||
literals = literals.filter(literal => !tracker.hasValue(literal)); | ||
symbols.forEach((symbol, i) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't filter the symbols
array because the index of a symbol in this array is tied to the information in symbolToOriginInfoMap
. I didn't want to create an abstraction on top of these two arrays and refactor everything, so I added an "ignore" flag to the origin info, but I'm open to suggestions on other ways to achieve this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are overdue to make a nice abstraction over a similar data structure to what we have so it’s easier to work with without sacrificing (and probably improving on) the reasonably efficient allocations we have going. This seems fine for now.
const tracker = newCaseClauseTracker(checker, caseClause.parent.clauses); | ||
literals = literals.filter(literal => !tracker.hasValue(literal)); | ||
symbols.forEach((symbol, i) => { | ||
if (symbol.valueDeclaration && isEnumMember(symbol.valueDeclaration)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the filtering won't work if someone is using e.g. an object literal as an enum, because checker.constantValue
only works for enum members. But I'm hoping that filtering out literals and enum members already covers a lot of the cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like something that can be expanded to readonly
members with literal types if there’s demand for it 👍
Oh yes! Thank you ❤️ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your comment on the reason for marking symbols as ignored might be worth putting in the code as well.
if (caseClause && (isCaseKeyword(contextToken!) || isNodeDescendantOf(contextToken!, caseClause.expression))) { | ||
const tracker = newCaseClauseTracker(checker, caseClause.parent.clauses); | ||
literals = literals.filter(literal => !tracker.hasValue(literal)); | ||
symbols.forEach((symbol, i) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are overdue to make a nice abstraction over a similar data structure to what we have so it’s easier to work with without sacrificing (and probably improving on) the reasonably efficient allocations we have going. This seems fine for now.
// filter literals & enum symbols whose values are already present in existing case clauses. | ||
const caseClause = findAncestor(contextToken, isCaseClause); | ||
if (caseClause && (isCaseKeyword(contextToken!) || isNodeDescendantOf(contextToken!, caseClause.expression))) { | ||
const tracker = newCaseClauseTracker(checker, caseClause.parent.clauses); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool that this abstraction came in handy in an additional place 🎉
const tracker = newCaseClauseTracker(checker, caseClause.parent.clauses); | ||
literals = literals.filter(literal => !tracker.hasValue(literal)); | ||
symbols.forEach((symbol, i) => { | ||
if (symbol.valueDeclaration && isEnumMember(symbol.valueDeclaration)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like something that can be expanded to readonly
members with literal types if there’s demand for it 👍
Fixes #13711.