diff --git a/toolchain/parser/parse_node_kind.cpp b/toolchain/parser/parse_node_kind.cpp index ae0dd8a51c30..f0c85870b289 100644 --- a/toolchain/parser/parse_node_kind.cpp +++ b/toolchain/parser/parse_node_kind.cpp @@ -47,8 +47,7 @@ auto ParseNodeKind::child_count() const -> int32_t { #include "toolchain/parser/parse_node_kind.def" }; auto child_count = ChildCount[static_cast(kind_)]; - // TODO: Allows TodoFixParseNode; see parse_node_kind.def. - CARBON_CHECK(child_count != -1) << *this; + CARBON_CHECK(child_count >= 0) << *this; return child_count; } diff --git a/toolchain/parser/parse_node_kind.def b/toolchain/parser/parse_node_kind.def index 8a9774c95a98..7771e6dbde3f 100644 --- a/toolchain/parser/parse_node_kind.def +++ b/toolchain/parser/parse_node_kind.def @@ -19,11 +19,6 @@ // must be correct even when the node contains errors. // // Macro definitions will be removed at the end of this file to clean up. -// -// TODO: Using CHILD_COUNT(..., TodoFixParseNode) to indicate nodes which need to be fixed, -// sometimes due to inconsistent output in error modes. This is also handled in -// ParseNodeKind::child_count() and ParseTree::Verify(). All of that can be -// cleaned up once remainining nodes are fixed. #if !(defined(CARBON_PARSE_NODE_KIND) || \ (defined(CARBON_PARSE_NODE_KIND_BRACKET) && \ @@ -52,8 +47,8 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(DeclaredName, 0) // `package`: // PackageIntroducer -// (name) -// (library) +// _external_: DeclaredName +// _external_: Literal // PackageLibrary // PackageApi or PackageImpl // PackageDirective @@ -65,24 +60,23 @@ CARBON_PARSE_NODE_KIND_BRACKET(PackageDirective, PackageIntroducer) // A code block: // CodeBlockStart -// (statements) +// _external_: statements // CodeBlock CARBON_PARSE_NODE_KIND_CHILD_COUNT(CodeBlockStart, 0) CARBON_PARSE_NODE_KIND_BRACKET(CodeBlock, CodeBlockStart) - // `fn`: // FunctionIntroducer // DeclaredName -// (parameter list) -// (expression) +// _external_: ParameterList +// _external_: type expression // ReturnType // FunctionDefinitionStart -// (statements) +// _external_: statements // FunctionDefinition // -// Or, for a declaration, FunctionDeclaration will end it where -// FunctionDefinitionStart is for a definition. +// The above is a definition; for a declaration, FunctionDeclaration will end it +// where FunctionDefinitionStart is for a definition. CARBON_PARSE_NODE_KIND_CHILD_COUNT(FunctionIntroducer, 0) CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnType, 1) CARBON_PARSE_NODE_KIND_BRACKET(FunctionDefinitionStart, FunctionIntroducer) @@ -91,22 +85,26 @@ CARBON_PARSE_NODE_KIND_BRACKET(FunctionDeclaration, FunctionIntroducer) // A parameter list: // ParamertListStart -// (expressions separated by ParameterListComma) +// _external_: expression +// ParameterListComma // ParameterList +// +// Expressions and ParameterListComma may repeat with ParameterListComma as a +// separator. CARBON_PARSE_NODE_KIND_CHILD_COUNT(ParameterListStart, 0) CARBON_PARSE_NODE_KIND_CHILD_COUNT(ParameterListComma, 0) CARBON_PARSE_NODE_KIND_BRACKET(ParameterList, ParameterListStart) // A pattern binding, such as `name: Type`: // DeclaredName -// (type expression) +// _external_: type expression // PatternBinding CARBON_PARSE_NODE_KIND_CHILD_COUNT(PatternBinding, 2) // `var`: // VariableIntroducer -// (pattern) -// (expression) +// _external_: PatternBinding +// _external_: expression // optional VariableInitializer // VariableDeclaration CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableIntroducer, 0) @@ -114,98 +112,178 @@ CARBON_PARSE_NODE_KIND_CHILD_COUNT(VariableInitializer, 1) CARBON_PARSE_NODE_KIND_BRACKET(VariableDeclaration, VariableIntroducer) // An expression statement: -// (expression) -// Statement +// _external_: expression +// ExpressionStatement CARBON_PARSE_NODE_KIND_CHILD_COUNT(ExpressionStatement, 1) // `break`: // BreakStatementStart // BreakStatement -CARBON_PARSE_NODE_KIND_CHILD_COUNT(BreakStatement, 1) CARBON_PARSE_NODE_KIND_CHILD_COUNT(BreakStatementStart, 0) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(BreakStatement, 1) // `continue`: // ContinueStatementStart // ContinueStatement -CARBON_PARSE_NODE_KIND_CHILD_COUNT(ContinueStatement, 1) CARBON_PARSE_NODE_KIND_CHILD_COUNT(ContinueStatementStart, 0) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(ContinueStatement, 1) // `return`: // ReturnStatementStart -// (optional expression) +// _external_: expression // ReturnStatement -CARBON_PARSE_NODE_KIND_BRACKET(ReturnStatement, ReturnStatementStart) +// +// The child expression is optional. CARBON_PARSE_NODE_KIND_CHILD_COUNT(ReturnStatementStart, 0) +CARBON_PARSE_NODE_KIND_BRACKET(ReturnStatement, ReturnStatementStart) // `for`: // ForHeaderStart -// (var) -// ForIn (versus a normal `var`, replaces VariableDeclaration) -// (expression) +// VariableIntroducer +// _external_: PatternBinding +// _external_: type expression +// ForIn +// _external_: expression // ForHeader -// CodeBlockStart -// (statements) -// CodeBlock +// _external_: CodeBlock // ForStatement +// +// Versus a normal `var`, ForIn replaces VariableDeclaration. CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForHeaderStart, 0) CARBON_PARSE_NODE_KIND_BRACKET(ForIn, VariableIntroducer) CARBON_PARSE_NODE_KIND_BRACKET(ForHeader, ForHeaderStart) CARBON_PARSE_NODE_KIND_CHILD_COUNT(ForStatement, 2) -// `if`: -// TODO: Still thinking about structure. -// IfConditionStart -// (expression) -// IfCondition +// `if` + `else`: +// IfConditionStart +// _external_: expression +// IfCondition +// _external_: CodeBlock +// IfStatementElse +// _external_: CodeBlock or IfStatement +// IfStatement +// +// IfStatementElse and the following node are optional based on `else` presence. CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfConditionStart, 0) CARBON_PARSE_NODE_KIND_BRACKET(IfCondition, IfConditionStart) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfStatement, TodoFixParseNode) CARBON_PARSE_NODE_KIND_CHILD_COUNT(IfStatementElse, 0) +CARBON_PARSE_NODE_KIND_BRACKET(IfStatement, IfCondition) // `while`: // WhileConditionStart -// (expression) +// _external_: expression // WhileCondition -// CodeBlockStart -// (statements) -// CodeBlock +// _external_: CodeBlock // WhileStatement CARBON_PARSE_NODE_KIND_CHILD_COUNT(WhileConditionStart, 0) CARBON_PARSE_NODE_KIND_BRACKET(WhileCondition, WhileConditionStart) CARBON_PARSE_NODE_KIND_CHILD_COUNT(WhileStatement, 2) -// Expressions. -CARBON_PARSE_NODE_KIND_CHILD_COUNT(Literal, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(TupleLiteral, TodoFixParseNode) +// Parenthesized expressions: +// ParenExpressionOrTupleLiteralStart +// _external_: expression +// ParenExpression + +// Tuples: +// ParenExpressionOrTupleLiteralStart +// _external_: expression +// TupleLiteralComma +// TupleLiteral +// +// Expressions and TupleLiteralComma may repeat with TupleLiteralComma as a +// separator. +CARBON_PARSE_NODE_KIND_CHILD_COUNT(ParenExpressionOrTupleLiteralStart, 0) +CARBON_PARSE_NODE_KIND_BRACKET(ParenExpression, + ParenExpressionOrTupleLiteralStart) CARBON_PARSE_NODE_KIND_CHILD_COUNT(TupleLiteralComma, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(TupleLiteralEnd, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(NameReference, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(ParenExpression, TodoFixParseNode) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(ParenExpressionEnd, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(DesignatorExpression, TodoFixParseNode) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(DesignatedName, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(CallExpression, TodoFixParseNode) +CARBON_PARSE_NODE_KIND_BRACKET(TupleLiteral, ParenExpressionOrTupleLiteralStart) + +// Call expressions, such as `a()`: +// _external_: expression +// CallExpressionStart +// _external_: expression +// CallExpressionComma +// CallExpression +// +// Expressions and CallExpressionComma may repeat with CallExpressionComma as a +// separator. +CARBON_PARSE_NODE_KIND_CHILD_COUNT(CallExpressionStart, 1) CARBON_PARSE_NODE_KIND_CHILD_COUNT(CallExpressionComma, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(CallExpressionEnd, 0) +CARBON_PARSE_NODE_KIND_BRACKET(CallExpression, CallExpressionStart) + +// A designator expression, such as `a.b`: +// _external_: DesignatedName or lhs expression +// _external_: DesignatedName +// DesignatorExpression +CARBON_PARSE_NODE_KIND_CHILD_COUNT(DesignatedName, 0) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(DesignatorExpression, 2) + +// A literal. +CARBON_PARSE_NODE_KIND_CHILD_COUNT(Literal, 0) + +// A reference to an identifier. +CARBON_PARSE_NODE_KIND_CHILD_COUNT(NameReference, 0) + +// A prefix operator: +// _external_: expression +// PrefixOperator CARBON_PARSE_NODE_KIND_CHILD_COUNT(PrefixOperator, 1) + +// An infix operator: +// _external_: lhs expression +// _external_: rhs expression +// InfixOperator CARBON_PARSE_NODE_KIND_CHILD_COUNT(InfixOperator, 2) + +// A postfix operator: +// _external_: expression +// PostfixOperator CARBON_PARSE_NODE_KIND_CHILD_COUNT(PostfixOperator, 1) -// Struct literals. +// Struct literals, such as `{.a = 0}`: +// StructLiteralOrStructTypeLiteralStart +// _external_: DesignatedName +// StructFieldDesignator +// _external_: expression +// StructFieldValue +// StructComma +// StructLiteral +// +// +// Struct type literals, such as `{.a: i32}`: +// _external_: DesignatedName +// StructFieldDesignator +// _external_: type expression +// StructFieldType +// StructComma +// StructTypeLiteral +// +// Elements (StructFieldValue and StructFieldType, respectively) and StructComma +// may repeat with StructComma as a separator. +// +// When a valid StructFieldType or StructFieldValue cannot be formed, elements +// may be replaced by StructFieldUnknown, which may have a preceding sibling +// StructFieldDesignator if one was successfully parsed. +CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructLiteralOrStructTypeLiteralStart, 0) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructFieldDesignator, 1) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructFieldValue, 2) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructFieldType, 2) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructFieldUnknown, 0) +CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructComma, 0) CARBON_PARSE_NODE_KIND_BRACKET(StructLiteral, StructLiteralOrStructTypeLiteralStart) CARBON_PARSE_NODE_KIND_BRACKET(StructTypeLiteral, StructLiteralOrStructTypeLiteralStart) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructLiteralOrStructTypeLiteralStart, 0) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructFieldDesignator, TodoFixParseNode) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructFieldValue, TodoFixParseNode) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructFieldType, TodoFixParseNode) -CARBON_PARSE_NODE_KIND_CHILD_COUNT(StructComma, 0) -// Interfaces -CARBON_PARSE_NODE_KIND_CHILD_COUNT(InterfaceDefinition, TodoFixParseNode) +// `interface`: +// _external_: DeclaredName +// InterfaceBodyStart +// _external_: statements +// InterfaceBodyEnd +// InterfaceDefinition CARBON_PARSE_NODE_KIND_CHILD_COUNT(InterfaceBodyStart, 0) CARBON_PARSE_NODE_KIND_BRACKET(InterfaceBody, InterfaceBodyStart) +CARBON_PARSE_NODE_KIND_BRACKET(InterfaceDefinition, DeclaredName) #undef CARBON_PARSE_NODE_KIND #undef CARBON_PARSE_NODE_KIND_BRACKET diff --git a/toolchain/parser/parse_node_kind.h b/toolchain/parser/parse_node_kind.h index b108f1f646bc..b458d3148db9 100644 --- a/toolchain/parser/parse_node_kind.h +++ b/toolchain/parser/parse_node_kind.h @@ -33,9 +33,6 @@ class ParseNodeKind { }; public: - // TODO: See parse_node_kind.def. - static constexpr int32_t TodoFixParseNode = -2; - // `clang-format` has a bug with spacing around `->` returns in macros. See // https://bugs.llvm.org/show_bug.cgi?id=48320 for details. #define CARBON_PARSE_NODE_KIND(Name) \ diff --git a/toolchain/parser/parse_tree.cpp b/toolchain/parser/parse_tree.cpp index 6e4c1598edc7..bf1c95809f9a 100644 --- a/toolchain/parser/parse_tree.cpp +++ b/toolchain/parser/parse_tree.cpp @@ -26,7 +26,7 @@ auto ParseTree::Parse(TokenizedBuffer& tokens, DiagnosticConsumer& consumer) // Delegate to the parser. auto tree = Parser::Parse(tokens, emitter); auto verify_error = tree.Verify(); - CARBON_CHECK(!verify_error) << *verify_error; + CARBON_CHECK(!verify_error) << tree << *verify_error; return tree; } @@ -215,11 +215,6 @@ auto ParseTree::Verify() const -> llvm::Optional { break; } } - } else if (n_impl.kind.child_count() == ParseNodeKind::TodoFixParseNode) { - while (subtree_size < n_impl.subtree_size && !nodes.empty()) { - auto child_impl = node_impls_[nodes.pop_back_val().index()]; - subtree_size += child_impl.subtree_size; - } } else { for (int i = 0; i < n_impl.kind.child_count(); ++i) { if (nodes.empty()) { diff --git a/toolchain/parser/parser.cpp b/toolchain/parser/parser.cpp index af9934a8548a..9d3c79488a27 100644 --- a/toolchain/parser/parser.cpp +++ b/toolchain/parser/parser.cpp @@ -157,6 +157,12 @@ auto Parser::ConsumeAndAddLeafNodeIf(TokenKind token_kind, return true; } +auto Parser::ConsumeChecked(TokenKind kind) -> TokenizedBuffer::Token { + CARBON_CHECK(PositionIs(kind)) + << "Required " << kind.Name() << ", found " << PositionKind().Name(); + return Consume(); +} + auto Parser::ConsumeIf(TokenKind kind) -> llvm::Optional { if (!PositionIs(kind)) { @@ -598,9 +604,15 @@ auto Parser::HandleBraceExpressionParameterFinish(BraceExpressionKind kind) -> void { auto state = PopState(); - AddNode(kind == BraceExpressionKind::Type ? ParseNodeKind::StructFieldType() - : ParseNodeKind::StructFieldValue(), - state.token, state.subtree_start, state.has_error); + if (state.has_error) { + AddLeafNode(ParseNodeKind::StructFieldUnknown(), state.token, + /*has_error=*/true); + } else { + AddNode(kind == BraceExpressionKind::Type + ? ParseNodeKind::StructFieldType() + : ParseNodeKind::StructFieldValue(), + state.token, state.subtree_start, /*has_error=*/false); + } if (ConsumeListToken(ParseNodeKind::StructComma(), TokenKind::CloseCurlyBrace(), @@ -647,12 +659,11 @@ auto Parser::HandleBraceExpressionFinishAsUnknownState() -> void { auto Parser::HandleCallExpressionState() -> void { auto state = PopState(); - // TODO: When swapping () start/end, this should AddLeafNode the open before - // continuing. state.state = ParserState::CallExpressionFinish(); PushState(state); - // Advance past the open paren. - ++position_; + + AddNode(ParseNodeKind::CallExpressionStart(), Consume(), state.subtree_start, + state.has_error); if (!PositionIs(TokenKind::CloseParen())) { PushState(ParserState::CallExpressionParameterFinish()); PushState(ParserState::Expression()); @@ -677,8 +688,7 @@ auto Parser::HandleCallExpressionParameterFinishState() -> void { auto Parser::HandleCallExpressionFinishState() -> void { auto state = PopState(); - AddLeafNode(ParseNodeKind::CallExpressionEnd(), Consume()); - AddNode(ParseNodeKind::CallExpression(), state.token, state.subtree_start, + AddNode(ParseNodeKind::CallExpression(), Consume(), state.subtree_start, state.has_error); } @@ -744,8 +754,8 @@ auto Parser::HandleDesignator(bool as_struct) -> void { auto state = PopState(); // `.` identifier - auto dot = ConsumeIf(TokenKind::Period()); - CARBON_CHECK(dot); + auto dot = ConsumeChecked(TokenKind::Period()); + if (!ConsumeAndAddLeafNodeIf(TokenKind::Identifier(), ParseNodeKind::DesignatedName())) { CARBON_DIAGNOSTIC(ExpectedIdentifierAfterDot, Error, @@ -757,14 +767,17 @@ auto Parser::HandleDesignator(bool as_struct) -> void { AddLeafNode(ParseNodeKind::DesignatedName(), Consume(), /*has_error=*/true); } else { - state.has_error = true; + AddLeafNode(ParseNodeKind::DesignatedName(), *position_, + /*has_error=*/true); + // Indicate the error to the parent state so that it can avoid producing + // more errors. ReturnErrorOnState(); } } AddNode(as_struct ? ParseNodeKind::StructFieldDesignator() : ParseNodeKind::DesignatorExpression(), - *dot, state.subtree_start, state.has_error); + dot, state.subtree_start, state.has_error); } auto Parser::HandleDesignatorAsExpressionState() -> void { @@ -1044,8 +1057,8 @@ auto Parser::HandleFunctionParameterFinishState() -> void { auto Parser::HandleFunctionParameterListFinishState() -> void { auto state = PopState(); - CARBON_CHECK(PositionIs(TokenKind::CloseParen())) << PositionKind().Name(); - AddNode(ParseNodeKind::ParameterList(), Consume(), state.subtree_start, + AddNode(ParseNodeKind::ParameterList(), + ConsumeChecked(TokenKind::CloseParen()), state.subtree_start, state.has_error); } @@ -1226,12 +1239,10 @@ auto Parser::HandleParenConditionFinishAsWhileState() -> void { auto Parser::HandleParenExpressionState() -> void { auto state = PopState(); - // TODO: When swapping () start/end, this should AddLeafNode the open before - // continuing. - // Advance past the open paren. - CARBON_CHECK(PositionIs(TokenKind::OpenParen())); - ++position_; + AddLeafNode(ParseNodeKind::ParenExpressionOrTupleLiteralStart(), + ConsumeChecked(TokenKind::OpenParen())); + if (PositionIs(TokenKind::CloseParen())) { state.state = ParserState::ParenExpressionFinishAsTuple(); PushState(state); @@ -1284,16 +1295,14 @@ auto Parser::HandleParenExpressionParameterFinishAsTupleState() -> void { auto Parser::HandleParenExpressionFinishState() -> void { auto state = PopState(); - AddLeafNode(ParseNodeKind::ParenExpressionEnd(), Consume()); - AddNode(ParseNodeKind::ParenExpression(), state.token, state.subtree_start, + AddNode(ParseNodeKind::ParenExpression(), Consume(), state.subtree_start, state.has_error); } auto Parser::HandleParenExpressionFinishAsTupleState() -> void { auto state = PopState(); - AddLeafNode(ParseNodeKind::TupleLiteralEnd(), Consume()); - AddNode(ParseNodeKind::TupleLiteral(), state.token, state.subtree_start, + AddNode(ParseNodeKind::TupleLiteral(), Consume(), state.subtree_start, state.has_error); } @@ -1659,6 +1668,12 @@ auto Parser::HandleInterfaceIntroducerState() -> void { "Expected interface name after `interface` keyword."); emitter_->Emit(*position_, ExpectedInterfaceName); state.has_error = true; + + // Add a name node even when it's not present because it's used for subtree + // bracketing on interfaces. + // TODO: Either fix this or normalize it, still deciding on the right + // approach. + AddLeafNode(ParseNodeKind::DeclaredName(), state.token, /*has_error=*/true); } bool parse_body = true; diff --git a/toolchain/parser/parser.h b/toolchain/parser/parser.h index fb06be8696fe..8d2fed1bc8da 100644 --- a/toolchain/parser/parser.h +++ b/toolchain/parser/parser.h @@ -124,6 +124,10 @@ class Parser { auto ConsumeAndAddLeafNodeIf(TokenKind token_kind, ParseNodeKind node_kind) -> bool; + // Returns the current position and moves past it. Requires the token is the + // expected kind. + auto ConsumeChecked(TokenKind kind) -> TokenizedBuffer::Token; + // If the current position's token matches this `Kind`, returns it and // advances to the next position. Otherwise returns an empty optional. auto ConsumeIf(TokenKind kind) -> llvm::Optional; diff --git a/toolchain/parser/testdata/basics/fail_invalid_designators.carbon b/toolchain/parser/testdata/basics/fail_invalid_designators.carbon index 061062fcd56e..34d403c12a71 100644 --- a/toolchain/parser/testdata/basics/fail_invalid_designators.carbon +++ b/toolchain/parser/testdata/basics/fail_invalid_designators.carbon @@ -11,16 +11,18 @@ // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, // CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, -// CHECK:STDOUT: {kind: 'DesignatorExpression', text: '.', has_error: yes, subtree_size: 2}, -// CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'DesignatedName', text: ';', has_error: yes}, +// CHECK:STDOUT: {kind: 'DesignatorExpression', text: '.', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', has_error: yes, subtree_size: 4}, // CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, // CHECK:STDOUT: {kind: 'DesignatedName', text: 'fn', has_error: yes}, // CHECK:STDOUT: {kind: 'DesignatorExpression', text: '.', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 4}, // CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, -// CHECK:STDOUT: {kind: 'DesignatorExpression', text: '.', has_error: yes, subtree_size: 2}, -// CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', has_error: yes, subtree_size: 3}, -// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 16}, +// CHECK:STDOUT: {kind: 'DesignatedName', text: '42', has_error: yes}, +// CHECK:STDOUT: {kind: 'DesignatorExpression', text: '.', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', has_error: yes, subtree_size: 4}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 18}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parser/testdata/basics/fail_paren_match_regression.carbon b/toolchain/parser/testdata/basics/fail_paren_match_regression.carbon index 5181e1e12c93..ea41ed4f2a6a 100644 --- a/toolchain/parser/testdata/basics/fail_paren_match_regression.carbon +++ b/toolchain/parser/testdata/basics/fail_paren_match_regression.carbon @@ -6,9 +6,9 @@ // RUN: %{not} %{carbon-run-parser} // CHECK:STDOUT: [ // CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, +// CHECK:STDOUT: {kind: 'ParenExpressionOrTupleLiteralStart', text: '('}, // CHECK:STDOUT: {kind: 'NameReference', text: 'foo'}, -// CHECK:STDOUT: {kind: 'ParenExpressionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'ParenExpression', text: '(', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'ParenExpression', text: ')', has_error: yes, subtree_size: 3}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 4}, // CHECK:STDOUT: {kind: 'VariableDeclaration', text: 'var', has_error: yes, subtree_size: 6}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, diff --git a/toolchain/parser/testdata/basics/function_call.carbon b/toolchain/parser/testdata/basics/function_call.carbon index 8916b76e5282..5923998894a3 100644 --- a/toolchain/parser/testdata/basics/function_call.carbon +++ b/toolchain/parser/testdata/basics/function_call.carbon @@ -10,24 +10,24 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, -// CHECK:STDOUT: {kind: 'DesignatedName', text: 'b'}, +// CHECK:STDOUT: {kind: 'NameReference', text: 'a'}, +// CHECK:STDOUT: {kind: 'DesignatedName', text: 'b'}, +// CHECK:STDOUT: {kind: 'DesignatorExpression', text: '.', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'DesignatedName', text: 'f'}, +// CHECK:STDOUT: {kind: 'DesignatorExpression', text: '.', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'CallExpressionStart', text: '(', subtree_size: 6}, +// CHECK:STDOUT: {kind: 'NameReference', text: 'c'}, +// CHECK:STDOUT: {kind: 'DesignatedName', text: 'd'}, // CHECK:STDOUT: {kind: 'DesignatorExpression', text: '.', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'DesignatedName', text: 'f'}, -// CHECK:STDOUT: {kind: 'DesignatorExpression', text: '.', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'NameReference', text: 'c'}, -// CHECK:STDOUT: {kind: 'DesignatedName', text: 'd'}, -// CHECK:STDOUT: {kind: 'DesignatorExpression', text: '.', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'CallExpressionComma', text: ','}, -// CHECK:STDOUT: {kind: 'NameReference', text: 'e'}, -// CHECK:STDOUT: {kind: 'ParenExpressionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'ParenExpression', text: '(', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'CallExpressionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'CallExpression', text: '(', subtree_size: 14}, -// CHECK:STDOUT: {kind: 'DesignatedName', text: 'g'}, -// CHECK:STDOUT: {kind: 'DesignatorExpression', text: '.', subtree_size: 16}, -// CHECK:STDOUT: {kind: 'CallExpressionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'CallExpression', text: '(', subtree_size: 18}, +// CHECK:STDOUT: {kind: 'CallExpressionComma', text: ','}, +// CHECK:STDOUT: {kind: 'ParenExpressionOrTupleLiteralStart', text: '('}, +// CHECK:STDOUT: {kind: 'NameReference', text: 'e'}, +// CHECK:STDOUT: {kind: 'ParenExpression', text: ')', subtree_size: 3}, +// CHECK:STDOUT: {kind: 'CallExpression', text: ')', subtree_size: 14}, +// CHECK:STDOUT: {kind: 'DesignatedName', text: 'g'}, +// CHECK:STDOUT: {kind: 'DesignatorExpression', text: '.', subtree_size: 16}, +// CHECK:STDOUT: {kind: 'CallExpressionStart', text: '(', subtree_size: 17}, +// CHECK:STDOUT: {kind: 'CallExpression', text: ')', subtree_size: 18}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 19}, // CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 25}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, diff --git a/toolchain/parser/testdata/basics/tuples.carbon b/toolchain/parser/testdata/basics/tuples.carbon index ec123e4a18a8..7baeb52a263d 100644 --- a/toolchain/parser/testdata/basics/tuples.carbon +++ b/toolchain/parser/testdata/basics/tuples.carbon @@ -7,31 +7,31 @@ // CHECK:STDOUT: [ // CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'x'}, +// CHECK:STDOUT: {kind: 'ParenExpressionOrTupleLiteralStart', text: '('}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, // CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, -// CHECK:STDOUT: {kind: 'TupleLiteralEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'TupleLiteral', text: '(', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 5}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 7}, +// CHECK:STDOUT: {kind: 'ParenExpressionOrTupleLiteralStart', text: '('}, // CHECK:STDOUT: {kind: 'Literal', text: '1'}, // CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','}, // CHECK:STDOUT: {kind: 'Literal', text: '2'}, -// CHECK:STDOUT: {kind: 'TupleLiteralEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'TupleLiteral', text: '(', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 5}, // CHECK:STDOUT: {kind: 'VariableInitializer', text: '=', subtree_size: 6}, // CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 15}, // CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, // CHECK:STDOUT: {kind: 'DeclaredName', text: 'y'}, -// CHECK:STDOUT: {kind: 'TupleLiteralEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'TupleLiteral', text: '(', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ParenExpressionOrTupleLiteralStart', text: '('}, +// CHECK:STDOUT: {kind: 'ParenExpressionOrTupleLiteralStart', text: '('}, +// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','}, -// CHECK:STDOUT: {kind: 'TupleLiteralEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'TupleLiteral', text: '(', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'ParenExpressionOrTupleLiteralStart', text: '('}, +// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'TupleLiteralComma', text: ','}, -// CHECK:STDOUT: {kind: 'TupleLiteralEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'TupleLiteral', text: '(', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'TupleLiteralEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'TupleLiteral', text: '(', subtree_size: 10}, +// CHECK:STDOUT: {kind: 'ParenExpressionOrTupleLiteralStart', text: '('}, +// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 10}, // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 12}, // CHECK:STDOUT: {kind: 'VariableDeclaration', text: ';', subtree_size: 14}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, diff --git a/toolchain/parser/testdata/for/fail_colon_instead_of_in.carbon b/toolchain/parser/testdata/for/fail_colon_instead_of_in.carbon index 19252a5acfeb..bac336b3f49f 100644 --- a/toolchain/parser/testdata/for/fail_colon_instead_of_in.carbon +++ b/toolchain/parser/testdata/for/fail_colon_instead_of_in.carbon @@ -19,10 +19,10 @@ // CHECK:STDOUT: {kind: 'NameReference', text: 'y'}, // CHECK:STDOUT: {kind: 'ForHeader', text: ')', subtree_size: 8}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, -// CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, +// CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, +// CHECK:STDOUT: {kind: 'CallExpressionStart', text: '(', subtree_size: 2}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, -// CHECK:STDOUT: {kind: 'CallExpressionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'CallExpression', text: '(', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'CallExpression', text: ')', subtree_size: 4}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 5}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 7}, // CHECK:STDOUT: {kind: 'ForStatement', text: 'for', subtree_size: 16}, diff --git a/toolchain/parser/testdata/for/fail_missing_in.carbon b/toolchain/parser/testdata/for/fail_missing_in.carbon index 30eb86ebbefd..e54ae4db7bb3 100644 --- a/toolchain/parser/testdata/for/fail_missing_in.carbon +++ b/toolchain/parser/testdata/for/fail_missing_in.carbon @@ -19,10 +19,10 @@ // CHECK:STDOUT: {kind: 'NameReference', text: 'y'}, // CHECK:STDOUT: {kind: 'ForHeader', text: ')', subtree_size: 8}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, -// CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, +// CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, +// CHECK:STDOUT: {kind: 'CallExpressionStart', text: '(', subtree_size: 2}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, -// CHECK:STDOUT: {kind: 'CallExpressionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'CallExpression', text: '(', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'CallExpression', text: ')', subtree_size: 4}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 5}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 7}, // CHECK:STDOUT: {kind: 'ForStatement', text: 'for', subtree_size: 16}, diff --git a/toolchain/parser/testdata/for/fail_missing_var.carbon b/toolchain/parser/testdata/for/fail_missing_var.carbon index d1903b2ec2d5..ac79359728ad 100644 --- a/toolchain/parser/testdata/for/fail_missing_var.carbon +++ b/toolchain/parser/testdata/for/fail_missing_var.carbon @@ -14,10 +14,10 @@ // CHECK:STDOUT: {kind: 'NameReference', text: 'y'}, // CHECK:STDOUT: {kind: 'ForHeader', text: ')', has_error: yes, subtree_size: 3}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, -// CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, +// CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, +// CHECK:STDOUT: {kind: 'CallExpressionStart', text: '(', subtree_size: 2}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, -// CHECK:STDOUT: {kind: 'CallExpressionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'CallExpression', text: '(', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'CallExpression', text: ')', subtree_size: 4}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 5}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 7}, // CHECK:STDOUT: {kind: 'ForStatement', text: 'for', subtree_size: 11}, diff --git a/toolchain/parser/testdata/for/nested.carbon b/toolchain/parser/testdata/for/nested.carbon index 34b4fd2d4dd8..782a44ffb6ce 100644 --- a/toolchain/parser/testdata/for/nested.carbon +++ b/toolchain/parser/testdata/for/nested.carbon @@ -28,10 +28,10 @@ // CHECK:STDOUT: {kind: 'NameReference', text: 'y'}, // CHECK:STDOUT: {kind: 'ForHeader', text: ')', subtree_size: 8}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, -// CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, +// CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, +// CHECK:STDOUT: {kind: 'CallExpressionStart', text: '(', subtree_size: 2}, // CHECK:STDOUT: {kind: 'NameReference', text: 'z'}, -// CHECK:STDOUT: {kind: 'CallExpressionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'CallExpression', text: '(', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'CallExpression', text: ')', subtree_size: 4}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 5}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 7}, // CHECK:STDOUT: {kind: 'ForStatement', text: 'for', subtree_size: 16}, diff --git a/toolchain/parser/testdata/for/simple.carbon b/toolchain/parser/testdata/for/simple.carbon index 4f03fa8b01af..5ed56b3cc663 100644 --- a/toolchain/parser/testdata/for/simple.carbon +++ b/toolchain/parser/testdata/for/simple.carbon @@ -19,10 +19,10 @@ // CHECK:STDOUT: {kind: 'NameReference', text: 'y'}, // CHECK:STDOUT: {kind: 'ForHeader', text: ')', subtree_size: 8}, // CHECK:STDOUT: {kind: 'CodeBlockStart', text: '{'}, -// CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, +// CHECK:STDOUT: {kind: 'NameReference', text: 'Print'}, +// CHECK:STDOUT: {kind: 'CallExpressionStart', text: '(', subtree_size: 2}, // CHECK:STDOUT: {kind: 'NameReference', text: 'x'}, -// CHECK:STDOUT: {kind: 'CallExpressionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'CallExpression', text: '(', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'CallExpression', text: ')', subtree_size: 4}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 5}, // CHECK:STDOUT: {kind: 'CodeBlock', text: '}', subtree_size: 7}, // CHECK:STDOUT: {kind: 'ForStatement', text: 'for', subtree_size: 16}, diff --git a/toolchain/parser/testdata/function/definition/with_params.carbon b/toolchain/parser/testdata/function/definition/with_params.carbon index 4574f4521cc1..564242da729a 100644 --- a/toolchain/parser/testdata/function/definition/with_params.carbon +++ b/toolchain/parser/testdata/function/definition/with_params.carbon @@ -17,14 +17,14 @@ // CHECK:STDOUT: {kind: 'PatternBinding', text: ':', subtree_size: 3}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 9}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 12}, -// CHECK:STDOUT: {kind: 'NameReference', text: 'foo'}, +// CHECK:STDOUT: {kind: 'NameReference', text: 'foo'}, +// CHECK:STDOUT: {kind: 'CallExpressionStart', text: '(', subtree_size: 2}, // CHECK:STDOUT: {kind: 'NameReference', text: 'baz'}, // CHECK:STDOUT: {kind: 'CallExpressionComma', text: ','}, // CHECK:STDOUT: {kind: 'NameReference', text: 'bar'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'baz'}, // CHECK:STDOUT: {kind: 'InfixOperator', text: '+', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'CallExpressionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'CallExpression', text: '(', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'CallExpression', text: ')', subtree_size: 8}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 9}, // CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 22}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, diff --git a/toolchain/parser/testdata/generics/interface/fail_missing_name.carbon b/toolchain/parser/testdata/generics/interface/fail_missing_name.carbon index 4ee53592029d..47bbd050086f 100644 --- a/toolchain/parser/testdata/generics/interface/fail_missing_name.carbon +++ b/toolchain/parser/testdata/generics/interface/fail_missing_name.carbon @@ -5,9 +5,10 @@ // AUTOUPDATE // RUN: %{not} %{carbon-run-parser} // CHECK:STDOUT: [ +// CHECK:STDOUT: {kind: 'DeclaredName', text: 'interface', has_error: yes}, // CHECK:STDOUT: {kind: 'InterfaceBodyStart', text: '{'}, // CHECK:STDOUT: {kind: 'InterfaceBody', text: '}', subtree_size: 2}, -// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: 'interface', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: 'interface', has_error: yes, subtree_size: 4}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''}, // CHECK:STDOUT: ] diff --git a/toolchain/parser/testdata/operators/fixity_in_call.carbon b/toolchain/parser/testdata/operators/fixity_in_call.carbon index 9073e978c439..996514da2f98 100644 --- a/toolchain/parser/testdata/operators/fixity_in_call.carbon +++ b/toolchain/parser/testdata/operators/fixity_in_call.carbon @@ -10,15 +10,15 @@ // CHECK:STDOUT: {kind: 'ParameterListStart', text: '('}, // CHECK:STDOUT: {kind: 'ParameterList', text: ')', subtree_size: 2}, // CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, -// CHECK:STDOUT: {kind: 'NameReference', text: 'G'}, +// CHECK:STDOUT: {kind: 'NameReference', text: 'G'}, +// CHECK:STDOUT: {kind: 'CallExpressionStart', text: '(', subtree_size: 2}, // CHECK:STDOUT: {kind: 'Literal', text: 'i32'}, // CHECK:STDOUT: {kind: 'PostfixOperator', text: '*', subtree_size: 2}, // CHECK:STDOUT: {kind: 'CallExpressionComma', text: ','}, // CHECK:STDOUT: {kind: 'NameReference', text: 'n'}, // CHECK:STDOUT: {kind: 'NameReference', text: 'n'}, // CHECK:STDOUT: {kind: 'InfixOperator', text: '*', subtree_size: 3}, -// CHECK:STDOUT: {kind: 'CallExpressionEnd', text: ')'}, -// CHECK:STDOUT: {kind: 'CallExpression', text: '(', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'CallExpression', text: ')', subtree_size: 9}, // CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 10}, // CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 16}, // CHECK:STDOUT: {kind: 'FileEnd', text: ''},