mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:01:08 +01:00
Parsing of designators like .x or .Self (#4254)
These appear in `where` clauses, as in: ``` U:! InterfaceB where .C = Vector(.D) V:! type where Vector(.Self) impls Sortable ``` `.Self` can additionally appear in type expressions in a binding pattern such as `T:! InterfaceA(.Self)`. --------- Co-authored-by: Josh L <josh11b@users.noreply.github.com> Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
co-authored by
Josh L
Jon Ross-Perkins
parent
b9e9e66cee
commit
702d0d8a53
@@ -169,6 +169,44 @@ auto HandleExprInPostfix(Context& context) -> void {
|
||||
context.PushState(state);
|
||||
break;
|
||||
}
|
||||
case Lex::TokenKind::Period: {
|
||||
// For periods, we look at the next token to form a designator like
|
||||
// `.Member` or `.Self`.
|
||||
auto period = context.Consume();
|
||||
if (context.ConsumeAndAddLeafNodeIf(Lex::TokenKind::Identifier,
|
||||
NodeKind::IdentifierName)) {
|
||||
// OK, `.` identifier.
|
||||
} else if (context.ConsumeAndAddLeafNodeIf(
|
||||
Lex::TokenKind::SelfTypeIdentifier,
|
||||
NodeKind::SelfTypeName)) {
|
||||
// OK, `.Self`.
|
||||
} else {
|
||||
CARBON_DIAGNOSTIC(ExpectedIdentifierOrSelfAfterPeriod, Error,
|
||||
"Expected identifier or `Self` after `.`.");
|
||||
context.emitter().Emit(*context.position(),
|
||||
ExpectedIdentifierOrSelfAfterPeriod);
|
||||
// Only consume if it is a number or word.
|
||||
if (context.PositionKind().is_keyword()) {
|
||||
context.AddLeafNode(NodeKind::IdentifierName, context.Consume(),
|
||||
/*has_error=*/true);
|
||||
} else if (context.PositionIs(Lex::TokenKind::IntLiteral)) {
|
||||
context.AddLeafNode(NodeKind::InvalidParse, context.Consume(),
|
||||
/*has_error=*/true);
|
||||
} else {
|
||||
context.AddLeafNode(NodeKind::InvalidParse, *context.position(),
|
||||
/*has_error=*/true);
|
||||
// Indicate the error to the parent state so that it can avoid
|
||||
// producing more errors. We only do this on this path where we don't
|
||||
// consume the token after the period, where we expect further errors
|
||||
// since we likely haven't recovered.
|
||||
context.ReturnErrorOnState();
|
||||
}
|
||||
state.has_error = true;
|
||||
}
|
||||
context.AddNode(NodeKind::DesignatorExpr, period, state.has_error);
|
||||
context.PushState(state);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// Add a node to keep the parse tree balanced.
|
||||
context.AddLeafNode(NodeKind::InvalidParse, *context.position(),
|
||||
|
||||
Reference in New Issue
Block a user