-
-
Notifications
You must be signed in to change notification settings - Fork 192
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
Attempts to fix issue #266 #317
base: master
Are you sure you want to change the base?
Conversation
We do this by treating `else (` separately. If `else` is followed by a (conditional + block) pattern, maybe the intention was to use an `else if` instead and a warning is emitted.
Included function to check if the expression is side-effect-free, although I have to check more carefully if the cases are done correctly. The cases that explicitly not side-effect-free are: dot, index, function and named_functions. From testing I found that arrow functions invalidate placing an `if`, even if their children are side-effect-free. This case is treated seperately. Maybe there are more cases where this happens and I must think it through.
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.
Hmm, this issue is more complicated than I thought! Lots of edge cases.
This function has been refactored and tested for edge cases.
src/parse.cpp
Outdated
auto entry = ast->object_entry(i); | ||
if (entry.property.has_value()) { | ||
if (this->has_potential_side_effects(*entry.property) || | ||
this->has_potential_side_effects(entry.value)) |
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.
Shouldn't we check entry.value
regardless of entry.property.has_value()
?
test/test-parse-expression.cpp
Outdated
} | ||
|
||
{ | ||
test_parser p(u8"import foo;"_sv); |
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.
Blocking: This has syntax errors. I think you meant this:
import(foo);
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.
This one is resolved.
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.
Blocking: if (a) { b; } else (c) { d; }
is still an issue (false negative).
Other than that, this commit looks bueno!
test/test-parse-statement.cpp
Outdated
TEST(test_parse, else_with_implicit_if) { | ||
{ | ||
spy_visitor v; | ||
padded_string code(u8"if (a) { b; } else (c)\n{ d; }"_sv); |
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 should check v.visits
so we know we recovered from the error correctly.
src/parse.cpp
Outdated
auto entry = ast->object_entry(i); | ||
if (entry.property.has_value()) { | ||
if (has_potential_side_effects(*entry.property) || | ||
has_potential_side_effects(entry.value)) |
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.
Shouldn't we check entry.value
regardless of entry.property.has_value()
?
src/quick-lint-js/parse.h
Outdated
break; | ||
} | ||
|
||
this->consume_semicolon(); |
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.
Blocking: This looks like it's in the wrong spot. Won't skipping a semicolon here cause the following code to have the error_else_with_conditional_missing_if warning?
if (a) { b; } else (c);
{ d; }
I think we need to consume a semicolon after the check on line 2546.
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.
Agreed!
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.
Please add a test for this example.
return has_potential_side_effects(*entry.property) || | ||
has_potential_side_effects(entry.value); |
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.
Blocking: You're only checking the first entry which has a value! We should check all entries.
src/quick-lint-js/parse.h
Outdated
break; | ||
} | ||
|
||
this->consume_semicolon(); |
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.
Please add a test for this example.
There are merge conflicts because |
We do this by treating
else (
separately. Ifelse
is followed bya (conditional + block) pattern, maybe the intention was to use an
else if
instead and a warning is emitted.