-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Add require
node(s) to the parse tree
#4210
base: trunk
Are you sure you want to change the base?
Conversation
Added new nodes to the parse tree to handle require declarations `Require` is a new bracketed parse node with the following structure: Require -Impls (New node for `expr impls expr` statement) - AnyExpr - AnyExpr -RequireIntroducer (Bracket node) Two test cases added for the usage in the interfaces.
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.
@josh11b I'm trying to figure out how to review this. Looking at the generics design, I see examples of its use, but I'm having trouble finding what the full syntax is. Is the syntax in the design somewhere that I'm missing? Some of the examples include where
, does this overlap with the where
parsing you've been looking at?
@gysddn FYI, the items on Toolchain tasks are things that are closer to our development focus. I'm going to need some time to figure out what the syntax is intended to be before I can really review, but I've left some comments regarding testing since those are more general comments not specific to this change. It's important to be testing both success cases and failure cases.
toolchain/parse/testdata/generics/interface/require_name.carbon
Outdated
Show resolved
Hide resolved
interface Bar { | ||
require i32 impls 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.
Can you add tests of incorrect syntax? There are a lot of possible typos here, and we should make sure error handling is working.
Just as a few examples:
// Missing components.
require;
require impls Foo;
require i32;
require i32 impls;
// Extra expressions.
require i32 i32 impls Foo;
require i32 impls Foo Foo;
Plus, what happens when there's a missing 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.
It looks like you've added most of these, but is there a test case with a missing semicolon?
e.g.:
interface Foo {
require i32 impls Bar
}
I expect this to work fine, but having tests is important to both catch unexpected results and prevent regressions.
toolchain/parse/testdata/generics/interface/require_name.carbon
Outdated
Show resolved
Hide resolved
The argument to One thing to note, though, that in discussions we've decided that the argument to a |
So to be sure I understand correctly, (if that understanding is correct, probably this change should be reverted since josh11b is already working on |
https://github.com/carbon-language/carbon-lang/blob/trunk/proposals/p2760.md#proposal
Eventually my expectation is that we would accept any kind of |
Yeah, I didn't really realize this while making these changes. |
To be sure we're all on the same page:
|
- Merge tests into one file - Add more cases to cover incorrect syntax
- Make `Require` node to be a fixed children size type (.child_count = 2) instead of bracketed.
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.
Thanks! I think the behavior looks good.
I'm suggesting changes to the state.def comments in order to try and match the file's style better. If I'm misreading something there, please let me know.
toolchain/parse/handle_require.cpp
Outdated
auto state = context.PopState(); | ||
|
||
if (auto impls = context.ConsumeIf(Lex::TokenKind::Impls)) { | ||
// context.AddNode(NodeKind::ImplsTypeAs, *impls, state.has_error); |
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.
// context.AddNode(NodeKind::ImplsTypeAs, *impls, state.has_error); |
Was this leftover from work? Should it be removed?
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.
Oh yeah, sorry about that 😅
toolchain/parse/state.def
Outdated
// require ... | ||
// ^~~~~~~ | ||
// 1. Require | ||
// 2. DeclScopeLoop | ||
// |
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.
Looking at surrounding entries, we're adding them lexically (alias, base, choice, etc). Can you please match that style, placing after package
?
toolchain/parse/state.def
Outdated
// | ||
CARBON_PARSE_STATE(Impls) | ||
|
||
// Finishes impls processing |
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.
// Finishes impls processing | |
// Finishes `impls` processing. | |
// |
As above. Also, fix punctuation.
CARBON_PARSE_STATE(Require) | ||
|
||
// Handles the processing of `impls` in a `require` declaration after the type | ||
// 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.
// expression. | |
// expression. | |
// |
Similar to other comments, let's put a blank line separating comment from example.
toolchain/parse/state.def
Outdated
|
||
CARBON_PARSE_STATE(ImplsFinish) | ||
|
||
// Finishes `require` processing |
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.
// Finishes `require` processing | |
// Finishes `require` processing. | |
// |
As above.
toolchain/parse/state.def
Outdated
// 1. Expr | ||
// 2. Impls | ||
// 3. RequireFinish | ||
// |
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 typically don't put blank lines at the end of a comment block.
toolchain/parse/state.def
Outdated
// impls ... | ||
// ^~~~~ | ||
// | ||
// 1. Expr | ||
// 2. ImplsFinish | ||
// |
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 syntax you're documenting here is for the error case, but you have it for the expression case. Let's document both paths.
Also note this suggestion is fixing extra blank lines.
// impls ... | |
// ^~~~~ | |
// | |
// 1. Expr | |
// 2. ImplsFinish | |
// | |
// expr impls ... | |
// ^~~~~ | |
// 1. Expr | |
// 2. ImplsFinish | |
// | |
// expr ??? | |
// ^ | |
// (state done) |
toolchain/parse/state.def
Outdated
// impls type_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.
// impls type_expression ... | |
// ^ | |
// expr impls expr | |
// ^ |
Let's include the expr
before impls
here.
toolchain/parse/state.def
Outdated
// ^ | ||
// (state done) | ||
// | ||
|
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.
toolchain/parse/state.def
Outdated
// impls type_expression ... | ||
// ^ | ||
// (state done) | ||
// |
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.
// impls type_expression ... | |
// ^ | |
// (state done) | |
// | |
// expr impls expr | |
// ^ | |
// (state done) |
Similar to impls
, I think the syntax example can be more specific. When there is no following syntax handled, we omit the trailing "...". Also, since parsing only checks for an expression, let's only say "expr".
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.
Updated the comments
Added new nodes to the parse tree to handle require declarations
Require
is a new bracketed parse node with the following structure:Require
-Impls (New node for
expr impls expr
statements)- AnyExpr
- AnyExpr
-RequireIntroducer (Bracket node)
Two test cases added for the usage in the interfaces.