handle_type.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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 declaration or definition after its introducer.
  7. static auto HandleTypeAfterIntroducer(Context& context,
  8. State after_params_state) -> void {
  9. auto state = context.PopState();
  10. context.PushState(state, after_params_state);
  11. context.PushState(State::DeclNameAndParamsAsOptional, state.token);
  12. }
  13. auto HandleTypeAfterIntroducerAsClass(Context& context) -> void {
  14. HandleTypeAfterIntroducer(context, State::TypeAfterParamsAsClass);
  15. }
  16. auto HandleTypeAfterIntroducerAsInterface(Context& context) -> void {
  17. HandleTypeAfterIntroducer(context, State::TypeAfterParamsAsInterface);
  18. }
  19. auto HandleTypeAfterIntroducerAsNamedConstraint(Context& context) -> void {
  20. HandleTypeAfterIntroducer(context, State::TypeAfterParamsAsNamedConstraint);
  21. }
  22. // Handles processing after params, deciding whether it's a declaration or
  23. // definition.
  24. static auto HandleTypeAfterParams(Context& context, NodeKind decl_kind,
  25. NodeKind definition_start_kind,
  26. State definition_finish_state) -> void {
  27. auto state = context.PopState();
  28. if (state.has_error) {
  29. context.RecoverFromDeclError(state, decl_kind,
  30. /*skip_past_likely_end=*/true);
  31. return;
  32. }
  33. if (auto semi = context.ConsumeIf(Lex::TokenKind::Semi)) {
  34. context.AddNode(decl_kind, *semi, state.subtree_start, state.has_error);
  35. return;
  36. }
  37. if (!context.PositionIs(Lex::TokenKind::OpenCurlyBrace)) {
  38. context.EmitExpectedDeclSemiOrDefinition(
  39. context.tokens().GetKind(state.token));
  40. context.RecoverFromDeclError(state, decl_kind,
  41. /*skip_past_likely_end=*/true);
  42. return;
  43. }
  44. context.PushState(state, definition_finish_state);
  45. context.PushState(State::DeclScopeLoop);
  46. context.AddNode(definition_start_kind, context.Consume(), state.subtree_start,
  47. state.has_error);
  48. }
  49. auto HandleTypeAfterParamsAsClass(Context& context) -> void {
  50. HandleTypeAfterParams(context, NodeKind::ClassDecl,
  51. NodeKind::ClassDefinitionStart,
  52. State::TypeDefinitionFinishAsClass);
  53. }
  54. auto HandleTypeAfterParamsAsInterface(Context& context) -> void {
  55. HandleTypeAfterParams(context, NodeKind::InterfaceDecl,
  56. NodeKind::InterfaceDefinitionStart,
  57. State::TypeDefinitionFinishAsInterface);
  58. }
  59. auto HandleTypeAfterParamsAsNamedConstraint(Context& context) -> void {
  60. HandleTypeAfterParams(context, NodeKind::NamedConstraintDecl,
  61. NodeKind::NamedConstraintDefinitionStart,
  62. State::TypeDefinitionFinishAsNamedConstraint);
  63. }
  64. // Handles parsing after the declaration scope of a type.
  65. static auto HandleTypeDefinitionFinish(Context& context,
  66. NodeKind definition_kind) -> void {
  67. auto state = context.PopState();
  68. context.AddNode(definition_kind, context.Consume(), state.subtree_start,
  69. state.has_error);
  70. }
  71. auto HandleTypeDefinitionFinishAsClass(Context& context) -> void {
  72. HandleTypeDefinitionFinish(context, NodeKind::ClassDefinition);
  73. }
  74. auto HandleTypeDefinitionFinishAsInterface(Context& context) -> void {
  75. HandleTypeDefinitionFinish(context, NodeKind::InterfaceDefinition);
  76. }
  77. auto HandleTypeDefinitionFinishAsNamedConstraint(Context& context) -> void {
  78. HandleTypeDefinitionFinish(context, NodeKind::NamedConstraintDefinition);
  79. }
  80. } // namespace Carbon::Parse