Skip to content

Attempts to fix issue #266#317

Open
keyehzy wants to merge 8 commits into
quick-lint:masterfrom
keyehzy:else_fix
Open

Attempts to fix issue #266#317
keyehzy wants to merge 8 commits into
quick-lint:masterfrom
keyehzy:else_fix

Conversation

@keyehzy

@keyehzy keyehzy commented May 18, 2021

Copy link
Copy Markdown
Contributor

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.

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.
Comment thread src/quick-lint-js/error.h Outdated
Comment thread test/test-parse-statement.cpp
Comment thread src/quick-lint-js/parse.h
Comment thread src/quick-lint-js/parse.h
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.

@strager strager left a comment

Copy link
Copy Markdown
Collaborator

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.

Comment thread src/quick-lint-js/parse.h Outdated
Comment thread src/quick-lint-js/parse.h Outdated
Comment thread src/quick-lint-js/parse.h Outdated
Comment thread src/quick-lint-js/parse.h Outdated
Comment thread src/quick-lint-js/parse.h Outdated
Comment thread src/quick-lint-js/parse.h Outdated
Comment thread test/test-parse-statement.cpp Outdated
Comment thread src/quick-lint-js/parse.h
Comment thread test/test-parse-statement.cpp
Comment thread test/test-parse-statement.cpp
This function has been refactored and tested for edge cases.
Comment thread 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))

Copy link
Copy Markdown
Collaborator

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()?

Comment thread test/test-parse-expression.cpp
Comment thread test/test-parse-expression.cpp Outdated
}

{
test_parser p(u8"import foo;"_sv);

Copy link
Copy Markdown
Collaborator

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);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is resolved.

Comment thread test/test-parse-expression.cpp Outdated
Comment thread test/test-parse-expression.cpp
Comment thread test/test-parse-expression.cpp Outdated
Comment thread test/test-parse-expression.cpp Outdated

@strager strager left a comment

Copy link
Copy Markdown
Collaborator

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!

Comment thread 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);

Copy link
Copy Markdown
Collaborator

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.

Comment thread test/test-parse-statement.cpp Outdated
Comment thread 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))

Copy link
Copy Markdown
Collaborator

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()?

Comment thread src/parse.cpp Outdated
Comment thread src/quick-lint-js/parse.h Outdated
break;
}

this->consume_semicolon();

Copy link
Copy Markdown
Collaborator

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed!

Copy link
Copy Markdown
Collaborator

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.

Comment thread test/test-parse-statement.cpp
Comment thread src/parse.cpp
Comment on lines +2124 to +2125
return has_potential_side_effects(*entry.property) ||
has_potential_side_effects(entry.value);

Copy link
Copy Markdown
Collaborator

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.

Comment thread src/quick-lint-js/parse.h Outdated
break;
}

this->consume_semicolon();

Copy link
Copy Markdown
Collaborator

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.

@strager

strager commented Jan 5, 2022

Copy link
Copy Markdown
Collaborator

There are merge conflicts because parser::parse_and_visit_if's body has been moved to src/quick-lint-js/parse-statement-inl.h.

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

Successfully merging this pull request may close these issues.

2 participants