handle_type.cpp 4.0 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/parse/context.h"
  5. namespace Carbon::Parse {
  6. // Handles processing of a type's introducer.
  7. static auto HandleTypeIntroducer(Context& context, NodeKind introducer_kind,
  8. State after_params_state) -> void {
  9. auto state = context.PopState();
  10. context.AddLeafNode(introducer_kind, context.Consume());
  11. state.state = after_params_state;
  12. context.PushState(state);
  13. context.PushState(State::DeclarationNameAndParamsAsOptional, state.token);
  14. }
  15. auto HandleTypeIntroducerAsClass(Context& context) -> void {
  16. HandleTypeIntroducer(context, NodeKind::ClassIntroducer,
  17. State::TypeAfterParamsAsClass);
  18. }
  19. auto HandleTypeIntroducerAsInterface(Context& context) -> void {
  20. HandleTypeIntroducer(context, NodeKind::InterfaceIntroducer,
  21. State::TypeAfterParamsAsInterface);
  22. }
  23. auto HandleTypeIntroducerAsNamedConstraint(Context& context) -> void {
  24. HandleTypeIntroducer(context, NodeKind::NamedConstraintIntroducer,
  25. State::TypeAfterParamsAsNamedConstraint);
  26. }
  27. // Handles processing after params, deciding whether it's a declaration or
  28. // definition.
  29. static auto HandleTypeAfterParams(Context& context, NodeKind declaration_kind,
  30. NodeKind definition_start_kind,
  31. State definition_finish_state) -> void {
  32. auto state = context.PopState();
  33. if (state.has_error) {
  34. context.RecoverFromDeclarationError(state, declaration_kind,
  35. /*skip_past_likely_end=*/true);
  36. return;
  37. }
  38. if (auto semi = context.ConsumeIf(Lex::TokenKind::Semi)) {
  39. context.AddNode(declaration_kind, *semi, state.subtree_start,
  40. state.has_error);
  41. return;
  42. }
  43. if (!context.PositionIs(Lex::TokenKind::OpenCurlyBrace)) {
  44. context.EmitExpectedDeclarationSemiOrDefinition(
  45. context.tokens().GetKind(state.token));
  46. context.RecoverFromDeclarationError(state, declaration_kind,
  47. /*skip_past_likely_end=*/true);
  48. return;
  49. }
  50. state.state = definition_finish_state;
  51. context.PushState(state);
  52. context.PushState(State::DeclarationScopeLoop);
  53. context.AddNode(definition_start_kind, context.Consume(), state.subtree_start,
  54. state.has_error);
  55. }
  56. auto HandleTypeAfterParamsAsClass(Context& context) -> void {
  57. HandleTypeAfterParams(context, NodeKind::ClassDeclaration,
  58. NodeKind::ClassDefinitionStart,
  59. State::TypeDefinitionFinishAsClass);
  60. }
  61. auto HandleTypeAfterParamsAsInterface(Context& context) -> void {
  62. HandleTypeAfterParams(context, NodeKind::InterfaceDeclaration,
  63. NodeKind::InterfaceDefinitionStart,
  64. State::TypeDefinitionFinishAsInterface);
  65. }
  66. auto HandleTypeAfterParamsAsNamedConstraint(Context& context) -> void {
  67. HandleTypeAfterParams(context, NodeKind::NamedConstraintDeclaration,
  68. NodeKind::NamedConstraintDefinitionStart,
  69. State::TypeDefinitionFinishAsNamedConstraint);
  70. }
  71. // Handles parsing after the declaration scope of a type.
  72. static auto HandleTypeDefinitionFinish(Context& context,
  73. NodeKind definition_kind) -> void {
  74. auto state = context.PopState();
  75. context.AddNode(definition_kind, context.Consume(), state.subtree_start,
  76. state.has_error);
  77. }
  78. auto HandleTypeDefinitionFinishAsClass(Context& context) -> void {
  79. HandleTypeDefinitionFinish(context, NodeKind::ClassDefinition);
  80. }
  81. auto HandleTypeDefinitionFinishAsInterface(Context& context) -> void {
  82. HandleTypeDefinitionFinish(context, NodeKind::InterfaceDefinition);
  83. }
  84. auto HandleTypeDefinitionFinishAsNamedConstraint(Context& context) -> void {
  85. HandleTypeDefinitionFinish(context, NodeKind::NamedConstraintDefinition);
  86. }
  87. } // namespace Carbon::Parse