-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
initial revision of reachability checks #4788
Conversation
fancy 😎 |
return false; | ||
} | ||
|
||
switch(n.kind) { |
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.
Space after switch
* Returns true if node and its subnodes were successfully traversed. | ||
* Returning false means that node was not examined and caller needs to dive into the node himself. | ||
*/ | ||
function bindReachableStatement(n: Node): boolean { |
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.
use the parameter name 'node' instead
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.
ok
const hasDefault = forEach(n.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause); | ||
|
||
// post switch state is unreachable if switch is exaustive (has a default case ) and does not have fallthrough from the last case | ||
const postSwitchState = hasDefault && currentReachabilityState !== Reachability.Reachable ? Reachability.Unreachable : preSwitchState; |
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 don't understand reachability of switch-statement. Why being exhaustive prevent post switch to be reachable?
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.
discussed offline
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.
🍪 🍰
🍺 is it enabled by default? impact on performance? |
@ahejlsberg I've addressed your comments, can you please take another look to see if everything looks good from your perspective? |
@vladima function foo(x: number) {
if (x < 0) return 42;
} |
@DanielRosenwasser function foo(x: number): number {
if (x < 0) return 42;
}
|
@vladima yes, I wasn't sure if that was intentional or not. I think that's a little too subtle. I would assume you are more likely to forget a type annotation as you are an explicit return, and the switch is "no implicit returns". |
currently implemented behavior is aligned with our existing approach to report errors on missing |
This is fantastic! We love preventing bugs. I'm curious if the team has discussed how to classify which static analysis will be included in the compiler, vs. what would be in something like tslint.
in Google's code, and this is very easily prevented by disallowing "empty" if statements with no then/else blocks. Do you imagine adding many more compilerOptions like the new |
@ahejlsberg can you please check if your time measurements got better with last commit? |
} | ||
|
||
function popImplicitLabel(implicitLabelIndex: number, outerState: Reachability): void { | ||
Debug.assert(labelStack.length === implicitLabelIndex + 1, `Label stack: ${labelStack.length}, index:${implicitLabelIndex}`); |
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.
Since we don't remove Debug.assert
calls in retail code, this will always perform expensive number-to-string and string allocation/concatenation operations.
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.
makes sense, will fix it
@vladima Just ran my RWC Monaco tests. With the latest changes we're now consistently a little bit faster than 1.6 even with reachability checks. Good stuff. |
👍 |
initial revision of reachability checks
…eScript#4788 (reachability checks)
What about the tsconfig.json schema? Shouldn't it be updated? |
this PR supersedes #1287.
Checking unreachable code in the compiler uncovered 2 bugs, both of the same origin:
Currently reachability checks are placed in binder but ultimately I'd like to be separate actions that are executed on the same pass - split walking and processing logic