handle_decl_name_and_params.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/lex/token_index.h"
  5. #include "toolchain/parse/context.h"
  6. #include "toolchain/parse/handle.h"
  7. namespace Carbon::Parse {
  8. // Adds a leaf node for the name, and updates the state stack for parameter
  9. // handling.
  10. static auto HandleName(Context& context, Context::State state,
  11. Lex::TokenIndex name_token,
  12. NodeKind not_before_params_kind,
  13. NodeKind not_before_params_qualifier_kind,
  14. NodeKind before_params_kind) -> void {
  15. switch (context.PositionKind()) {
  16. case Lex::TokenKind::Period:
  17. context.AddLeafNode(not_before_params_kind, name_token);
  18. context.AddNode(not_before_params_qualifier_kind,
  19. context.ConsumeChecked(Lex::TokenKind::Period),
  20. state.has_error);
  21. context.PushState(StateKind::DeclNameAndParams);
  22. break;
  23. case Lex::TokenKind::OpenSquareBracket:
  24. context.AddLeafNode(before_params_kind, name_token);
  25. state.kind = StateKind::DeclNameAndParamsAfterImplicit;
  26. context.PushState(state);
  27. context.PushState(StateKind::PatternListAsImplicit);
  28. break;
  29. case Lex::TokenKind::OpenParen:
  30. context.AddLeafNode(before_params_kind, name_token);
  31. state.kind = StateKind::DeclNameAndParamsAfterParams;
  32. context.PushState(state);
  33. context.PushState(StateKind::PatternListAsExplicit);
  34. break;
  35. case Lex::TokenKind::MinusGreater:
  36. case Lex::TokenKind::MinusGreaterQuestion:
  37. context.AddLeafNode(before_params_kind, name_token);
  38. break;
  39. default:
  40. context.AddLeafNode(not_before_params_kind, name_token);
  41. break;
  42. }
  43. }
  44. auto HandleDeclNameAndParams(Context& context) -> void {
  45. auto state = context.PopState();
  46. if (auto identifier = context.ConsumeIf(Lex::TokenKind::Identifier)) {
  47. HandleName(context, state, *identifier,
  48. NodeKind::IdentifierNameNotBeforeSignature,
  49. NodeKind::IdentifierNameQualifierWithoutParams,
  50. NodeKind::IdentifierNameMaybeBeforeSignature);
  51. return;
  52. }
  53. Lex::TokenIndex token = *context.position();
  54. if (context.tokens().GetKind(token) == Lex::TokenKind::FileEnd) {
  55. // The end of file is an unhelpful diagnostic location. Instead, use the
  56. // introducer token.
  57. token = state.token;
  58. }
  59. if (state.token == *context.position()) {
  60. CARBON_DIAGNOSTIC(ExpectedDeclNameAfterPeriod, Error,
  61. "`.` should be followed by a name");
  62. context.emitter().Emit(token, ExpectedDeclNameAfterPeriod);
  63. } else {
  64. CARBON_DIAGNOSTIC(ExpectedDeclName, Error,
  65. "`{0}` introducer should be followed by a name",
  66. Lex::TokenKind);
  67. context.emitter().Emit(token, ExpectedDeclName,
  68. context.tokens().GetKind(state.token));
  69. }
  70. context.ReturnErrorOnState();
  71. context.AddInvalidParse(*context.position());
  72. }
  73. auto HandleDeclNameAndParamsAfterImplicit(Context& context) -> void {
  74. auto state = context.PopState();
  75. state.kind = StateKind::DeclNameAndParamsAfterParams;
  76. context.PushState(state);
  77. if (!context.PositionIs(Lex::TokenKind::OpenParen)) {
  78. return;
  79. }
  80. context.PushState(StateKind::PatternListAsExplicit);
  81. }
  82. auto HandleDeclNameAndParamsAfterParams(Context& context) -> void {
  83. auto state = context.PopState();
  84. if (auto period = context.ConsumeIf(Lex::TokenKind::Period)) {
  85. CARBON_CHECK(context.tree().node_kind(NodeId(state.subtree_start)) ==
  86. NodeKind::IdentifierNameMaybeBeforeSignature);
  87. context.AddNode(NodeKind::IdentifierNameQualifierWithParams, *period,
  88. state.has_error);
  89. context.PushState(StateKind::DeclNameAndParams);
  90. }
  91. }
  92. } // namespace Carbon::Parse