From 4d8f74c1493fee3a73fefd1d00e0928f87356fc6 Mon Sep 17 00:00:00 2001 From: Dan Klishch Date: Sun, 21 Jan 2024 15:26:17 -0500 Subject: [PATCH] JSSpecCompiler: Parse method headers --- .../JSSpecCompiler/Parser/SpecParser.cpp | 12 +++++-- .../JSSpecCompiler/Parser/SpecParser.h | 1 + .../JSSpecCompiler/Parser/TextParser.cpp | 35 ++++++++++++++----- .../JSSpecCompiler/Parser/TextParser.h | 15 ++++++-- .../JSSpecCompiler/Tests/spec-headers.xml | 17 +++++++++ .../Tests/spec-headers.xml.expectation | 16 +++++++++ Tests/JSSpecCompiler/test-runner.cpp | 1 + 7 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-headers.xml create mode 100644 Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-headers.xml.expectation diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/SpecParser.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/SpecParser.cpp index 5fc673f493..beae11f696 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/SpecParser.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/SpecParser.cpp @@ -239,7 +239,7 @@ NonnullOwnPtr SpecificationClause::create(SpecificationPars [&](AK::Empty const&) { result = make(move(specification_clause)); }, - [&](OneOf auto const&) { + [&](OneOf auto const&) { result = make(move(specification_clause)); }); @@ -269,7 +269,7 @@ Optional SpecificationClause::parse_header(XML::Node auto const& tokens = maybe_tokens.release_value(); TextParser parser(ctx, tokens, element); - auto parse_result = parser.parse_clause_header(); + auto parse_result = parser.parse_clause_header(m_clause_has_aoid_attribute); if (parse_result.is_error()) { // Still try to at least scavenge section number. if (tokens.size() && tokens[0].type == TokenType::SectionNumber) @@ -291,6 +291,10 @@ void SpecificationClause::parse(XML::Node const* element) bool node_ignored_warning_issued = false; Optional header_parse_error; + m_clause_has_aoid_attribute = element->as_element().attributes.get("aoid").has_value() + ? TextParser::ClauseHasAoidAttribute::Yes + : TextParser::ClauseHasAoidAttribute::No; + for (auto const& child : element->as_element().children) { child->content.visit( [&](XML::Node::Element const& element) { @@ -363,6 +367,10 @@ bool SpecFunction::post_initialize(XML::Node const* element) [&](ClauseHeader::Accessor const& accessor) { m_name = MUST(String::formatted("%get {}%", MUST(String::join("."sv, accessor.qualified_name)))); }, + [&](ClauseHeader::Method const& method) { + m_name = MUST(String::formatted("%{}%", MUST(String::join("."sv, method.qualified_name)))); + m_arguments = method.arguments; + }, [&](auto const&) { VERIFY_NOT_REACHED(); }); diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/SpecParser.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/SpecParser.h index cc471c2aef..8dd8da7a1c 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/SpecParser.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/SpecParser.h @@ -116,6 +116,7 @@ private: Optional parse_header(XML::Node const* element); void parse(XML::Node const* element); + TextParser::ClauseHasAoidAttribute m_clause_has_aoid_attribute; SpecificationParsingContext* m_ctx_pointer; Vector> m_subclauses; }; diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp index 845cad052a..b336b92543 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp @@ -722,23 +722,42 @@ TextParseErrorOr TextParser::parse_accessor_declaration( return accessor; } +TextParseErrorOr TextParser::parse_method_declaration() +{ + auto rollback = rollback_point(); + + ClauseHeader::Method method; + method.qualified_name = TRY(parse_qualified_name()); + method.arguments = TRY(parse_function_arguments_in_declaration()); + TRY(expect_eof()); + + rollback.disarm(); + return method; +} + // :== | -TextParseErrorOr TextParser::parse_clause_header() +TextParseErrorOr TextParser::parse_clause_header(ClauseHasAoidAttribute clause_has_aoid_attribute) { ClauseHeader result; auto section_number_token = TRY(consume_token_with_type(TokenType::SectionNumber)); result.section_number = section_number_token.data; - if (auto ao_declaration = parse_abstract_operation_declaration(); !ao_declaration.is_error()) { - result.header = ao_declaration.release_value(); - } else if (auto accessor = parse_accessor_declaration(); !accessor.is_error()) { - result.header = accessor.release_value(); + if (clause_has_aoid_attribute == ClauseHasAoidAttribute::Yes) { + if (auto ao_declaration = parse_abstract_operation_declaration(); !ao_declaration.is_error()) { + result.header = ao_declaration.release_value(); + return result; + } } else { - return TextParseError {}; + if (auto accessor = parse_accessor_declaration(); !accessor.is_error()) { + result.header = accessor.release_value(); + return result; + } else if (auto method = parse_method_declaration(); !method.is_error()) { + result.header = method.release_value(); + return result; + } } - - return result; + return TextParseError {}; } FailedTextParseDiagnostic TextParser::get_diagnostic() const diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.h index 8d7d1190bf..d71942c7cc 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.h @@ -22,8 +22,13 @@ struct ClauseHeader { Vector qualified_name; }; + struct Method { + Vector qualified_name; + Vector arguments; + }; + StringView section_number; - Variant header; + Variant header; }; struct TextParseError { }; @@ -38,6 +43,11 @@ using TextParseErrorOr = ErrorOr; class TextParser { public: + enum class ClauseHasAoidAttribute { + No, + Yes, + }; + TextParser(SpecificationParsingContext& ctx, Vector const& tokens, XML::Node const* node) : m_ctx(ctx) , m_tokens(tokens) @@ -45,7 +55,7 @@ public: { } - TextParseErrorOr parse_clause_header(); + TextParseErrorOr parse_clause_header(ClauseHasAoidAttribute clause_has_aoid_attribute); TextParseErrorOr parse_step_without_substeps(); TextParseErrorOr parse_step_with_substeps(Tree substeps); @@ -95,6 +105,7 @@ private: TextParseErrorOr> parse_qualified_name(); TextParseErrorOr> parse_function_arguments_in_declaration(); TextParseErrorOr parse_abstract_operation_declaration(); + TextParseErrorOr parse_method_declaration(); TextParseErrorOr parse_accessor_declaration(); SpecificationParsingContext& m_ctx; diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-headers.xml b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-headers.xml new file mode 100644 index 0000000000..f68524d651 --- /dev/null +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-headers.xml @@ -0,0 +1,17 @@ +]> + + +

1 get Foo.Bar.baz

+
  1. Return unused.
+
+ + +

2 TestAbstractOperation ( a )

+
  1. Return unused.
+
+ + +

3 Foo.Bar.foo ( a )

+
  1. Return unused.
+
+
diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-headers.xml.expectation b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-headers.xml.expectation new file mode 100644 index 0000000000..836837fd80 --- /dev/null +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Tests/spec-headers.xml.expectation @@ -0,0 +1,16 @@ +===== AST after reference-resolving ===== +%get Foo.Bar.baz%(): +TreeList + ReturnNode + Enumerator unused + +TestAbstractOperation(a): +TreeList + ReturnNode + Enumerator unused + +%Foo.Bar.foo%(a): +TreeList + ReturnNode + Enumerator unused + diff --git a/Tests/JSSpecCompiler/test-runner.cpp b/Tests/JSSpecCompiler/test-runner.cpp index e4fb58e790..86afb46392 100644 --- a/Tests/JSSpecCompiler/test-runner.cpp +++ b/Tests/JSSpecCompiler/test-runner.cpp @@ -49,6 +49,7 @@ const Array regression_tests = { }, TestDescription { .sources = { + "spec-headers.xml"sv, "spec-no-new-line-after-dot.xml"sv, "spec-optional-arguments.xml"sv, "spec-parsing.xml"sv,