Switch modifiers to use distinct parse nodes. (#3461)

This is supporting a direction that all parse nodes should correspond to
a single token, allowing for reduced tokenized buffer access during
checking (it's still necessary for diagnostics, and some literals).

One of the justifications for a unified parse node was implementation
LOC: note this is slightly smaller, using macros to reduce some
duplication. While this does add more switching in HandleDeclScopeLoop,
that's offset by less explicit switching in the check handlers. Also, I
think the duplication in HandleDeclScopeLoop can be reduced by shifting
the flow there, which I'll do in a separate PR.
This commit is contained in:
Jon Ross-Perkins
2023-12-06 22:14:53 +00:00
committed by GitHub
parent a970b1e587
commit d73729179a
11 changed files with 116 additions and 152 deletions
+26 -19
View File
@@ -120,15 +120,32 @@ auto HandleDeclScopeLoop(Context& context) -> void {
bool saw_modifier = false;
while (true) {
switch (context.PositionKind()) {
// If we see a access modifier keyword token, add it as a leaf node
// and repeat with the next token.
// If we see a modifier keyword token, add it as a leaf node and loop to
// the next token.
case Lex::TokenKind::Abstract:
context.AddLeafNode(NodeKind::AbstractModifier, context.Consume());
saw_modifier = true;
break;
case Lex::TokenKind::Default:
context.AddLeafNode(NodeKind::DefaultModifier, context.Consume());
saw_modifier = true;
break;
case Lex::TokenKind::Final:
context.AddLeafNode(NodeKind::FinalModifier, context.Consume());
saw_modifier = true;
break;
case Lex::TokenKind::Private:
case Lex::TokenKind::Protected: {
auto modifier_token = context.Consume();
context.AddLeafNode(NodeKind::AccessModifierKeyword, modifier_token);
context.AddLeafNode(NodeKind::PrivateModifier, context.Consume());
saw_modifier = true;
break;
case Lex::TokenKind::Protected:
context.AddLeafNode(NodeKind::ProtectedModifier, context.Consume());
saw_modifier = true;
break;
case Lex::TokenKind::Virtual:
context.AddLeafNode(NodeKind::VirtualModifier, context.Consume());
saw_modifier = true;
break;
}
case Lex::TokenKind::Base:
// `base` may be followed by:
@@ -160,26 +177,16 @@ auto HandleDeclScopeLoop(Context& context) -> void {
OutputInvalidParseSubtree(context, state.subtree_start);
return;
}
[[fallthrough]];
// If we see a declaration modifier keyword token, add it as a leaf node
// and repeat with the next token.
case Lex::TokenKind::Abstract:
case Lex::TokenKind::Default:
case Lex::TokenKind::Final:
case Lex::TokenKind::Virtual: {
auto modifier_token = context.Consume();
context.AddLeafNode(NodeKind::DeclModifierKeyword, modifier_token);
context.AddLeafNode(NodeKind::BaseModifier, context.Consume());
saw_modifier = true;
break;
}
case Lex::TokenKind::Impl: {
// `impl` is considered a declaration modifier if it is followed by
// another modifier or an introducer.
if (TokenIsModifierOrIntroducer(
context.PositionKind(Lookahead::NextToken))) {
context.AddLeafNode(NodeKind::DeclModifierKeyword, context.Consume());
context.AddLeafNode(NodeKind::ImplModifier, context.Consume());
saw_modifier = true;
} else {
// TODO: Treat this `impl` token as a declaration introducer
@@ -194,7 +201,7 @@ auto HandleDeclScopeLoop(Context& context) -> void {
// another modifier or an introducer.
if (TokenIsModifierOrIntroducer(
context.PositionKind(Lookahead::NextToken))) {
context.AddLeafNode(NodeKind::DeclModifierKeyword, context.Consume());
context.AddLeafNode(NodeKind::ExtendModifier, context.Consume());
saw_modifier = true;
} else {
// TODO: Treat this `extend` token as a declaration introducer