-
Notifications
You must be signed in to change notification settings - Fork 660
fix(rome_js_parser): permisive instantiation expression #3359
fix(rome_js_parser): permisive instantiation expression #3359
Conversation
✅ Deploy Preview for docs-rometools ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
!bench_parser |
Parser Benchmark Results
|
@MichaReiser, Would mind helping with reviewing the code? |
} | ||
} | ||
|
||
/// You could refer to https://github.com/microsoft/TypeScript/blob/42b1049aee8c655631cb4f0065de86ec1023d20a/src/compiler/parser.ts#L4475 |
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 think it makes much sense for us to link to typescript repository inside of the documentation. Instead, we should explain what this method is doing.
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 will add some doc about the implementation , but then add the reference link in Typescrip for people who want to see more details, what do you think?
} | ||
|
||
/// You could refer to https://github.com/microsoft/TypeScript/blob/42b1049aee8c655631cb4f0065de86ec1023d20a/src/compiler/parser.ts#L4475 | ||
fn is_start_of_expr(p: &mut Parser) -> bool { |
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.
How's this method different from is_at_expression
?
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_start_of_expr
has JS_BIG_INT_LITERAL
, but is_at_expression
don't. is_start_of_expr
don't have T![super]
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.
Have we checked if is_at_expression
should have JS_BIG_INT_LITERAL
and T![super]
. Maybe that's a bug.
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_at_expression
, Also is_start_of_expr
need is_binary_operator
for better error recover. I am not sure if we need it too, becuase our error recover maybe different from Typescript
| T![await] | ||
| T![yield] => true, | ||
// TODO: how to represent private identifier | ||
_ => is_binary_operator(p) || is_at_identifier(p), |
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.
What's the reason that this method returns true for binary operators. I'm asking because binary operators don't mark the start of an expression and instead appear in the middle of an expresison.
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 function is just porting from Typescript, I keep the same behavior as Typescript because this will not bring too much maintenance burden when Typescript changes next time.
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.
The issue I see here is that the method tests if it is at the start of an expression which may not be true for a binary operator. It also introduces a lot of duplication with is_at_expression
.
I think it's ok to get inspiration from TypeScript but we should be careful with copying the implementation 1:1. Our parser works similar to TypeScript but isn't an exact rewrite in Rust. Thus, we should only inherit what we explicitly know is necessary.
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 have added the reason why we need to add binary_operator
. We could merge this function but, it may be not good for reuse, what do you think? Other than that, the pattern match is just against JS_SYNTAX_KIND
which should be only u8 under the hood, and it is pretty trivial according to the benchmark.
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.
My issue isn't with performance but with maintainability. As an author, how do I know is I should use is_at_expression
or is_start_of_expr
. So far, is_at_expression
should always return true
for anything that parse_expression
returns Present
which I think is an understandable definition. But I know wouldn't know if I have to use this new method or the old one.
That's why I think it's important to clearly document when to use which method and why. If there's no good reason, then the two should be merged together.
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.
Just chiming in.
The decision here is to whether parse a plain && rhs
to a missing lhs logical expression or not in Rome:
JsLogicalExpression {
left: missing (required),
operator_token: AMP2@2..5 "&&" [] [Whitespace(" ")],
right: ...
}
But regardless of the final decision, it shouldn't be introduced in a feature PR because it needs separate tests.
Also note, almost every kind of expression is a binary expression in TypeScript, so copying exact implementations from TypeScript will end up with a very different outcome.
(I just noticed the other day, assignments and sequence expressions are all binary expressions in TypeScript.)
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.
@MichaReiser What do you think ? Do we need to rewrite the code, make it fixes this test case, and ignore the rest logic in Typescript, fix them one by one when we suffer them?
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 think we need to understand what this logic accomplishes and if we need both is_*_expression
method and if so why, document it and explain when to use which.
My preferred solution would be to only have one (unparametrized) method in the end.
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 think it's necessary to either make a very clear distinction between is_start_of_expr
and is_at_expression
but ideally, only have one.
I think we should also be more explicit in the PR description explaining which new cases this PR handles that the parser currently does not and add positive and negative tests.
This PR is stale because it has been open 14 days with no activity. |
Summary
Test Plan