SpecificationFunction.cpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Copyright (c) 2023-2024, Dan Klishch <danilklishch@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "Parser/Lexer.h"
  7. #include "Parser/SpecificationParsing.h"
  8. #include "Parser/XMLUtils.h"
  9. namespace JSSpecCompiler {
  10. bool SpecificationFunction::post_initialize(XML::Node const* element)
  11. {
  12. VERIFY(element->as_element().name == tag_emu_clause);
  13. auto& ctx = context();
  14. m_location = ctx.location_from_xml_offset(element->offset);
  15. auto maybe_id = get_attribute_by_name(element, attribute_id);
  16. if (!maybe_id.has_value()) {
  17. ctx.diag().error(m_location,
  18. "no id attribute");
  19. } else {
  20. m_id = maybe_id.value();
  21. }
  22. m_header.header.visit(
  23. [&](AbstractOperationDeclaration const& abstract_operation) {
  24. m_declaration = abstract_operation;
  25. auto abstract_operation_id = get_attribute_by_name(element, attribute_aoid).value();
  26. if (abstract_operation.name != abstract_operation_id) {
  27. ctx.diag().warn(m_location,
  28. "function name in header and <emu-clause>[aoid] do not match");
  29. }
  30. },
  31. [&](OneOf<AccessorDeclaration, MethodDeclaration> auto const& declaration) {
  32. m_declaration = declaration;
  33. },
  34. [&](auto const&) {
  35. VERIFY_NOT_REACHED();
  36. });
  37. Vector<XML::Node const*> algorithm_nodes;
  38. for (auto const& child : element->as_element().children) {
  39. child->content.visit(
  40. [&](XML::Node::Element const& element) {
  41. if (element.name == tag_h1) {
  42. // Processed in SpecificationClause
  43. } else if (element.name == tag_p) {
  44. ctx.diag().warn(ctx.location_from_xml_offset(child->offset),
  45. "prose is ignored");
  46. } else if (element.name == tag_emu_alg) {
  47. algorithm_nodes.append(child);
  48. } else {
  49. ctx.diag().error(ctx.location_from_xml_offset(child->offset),
  50. "<{}> should not be a child of <emu-clause> specifing function"sv, element.name);
  51. }
  52. },
  53. [&](auto const&) {});
  54. }
  55. if (algorithm_nodes.size() != 1) {
  56. ctx.diag().error(m_location,
  57. "<emu-clause> specifing function should have exactly one <emu-alg> child"sv);
  58. return false;
  59. }
  60. auto maybe_algorithm = Algorithm::create(ctx, algorithm_nodes[0]);
  61. if (maybe_algorithm.has_value()) {
  62. m_algorithm = maybe_algorithm.release_value();
  63. return true;
  64. } else {
  65. return false;
  66. }
  67. }
  68. void SpecificationFunction::do_collect(TranslationUnitRef translation_unit)
  69. {
  70. translation_unit->adopt_function(make_ref_counted<FunctionDefinition>(m_declaration.release_value(), m_location, m_algorithm.tree()));
  71. }
  72. }