From e0916dbb359d6181290daf1748fe5dce85015be1 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 23 Nov 2022 12:16:51 +0100 Subject: LibJS: Move {Import,Export}Entry out of {Import,Export}Statement By making these be standalone instead of nested structs, we can forward declare them. This will allow us to stop including AST.h in some places. --- Userland/Libraries/LibJS/AST.h | 170 +++++++++++++------------- Userland/Libraries/LibJS/Forward.h | 4 + Userland/Libraries/LibJS/Parser.cpp | 14 +-- Userland/Libraries/LibJS/SourceTextModule.cpp | 8 +- Userland/Libraries/LibJS/SourceTextModule.h | 3 - 5 files changed, 99 insertions(+), 100 deletions(-) (limited to 'Userland/Libraries') diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index 1ef0d71692..a260478866 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -298,33 +298,33 @@ struct ModuleRequest { Vector assertions; // [[Assertions]] }; -class ImportStatement final : public Statement { -public: - // ImportEntry Record, https://tc39.es/ecma262/#table-importentry-record-fields - struct ImportEntry { - FlyString import_name; // [[ImportName]] if a String - FlyString local_name; // [[LocalName]] - bool is_namespace { false }; // [[ImportName]] if `namespace-object` - - ImportEntry(FlyString import_name_, FlyString local_name_, bool is_namespace_ = false) - : import_name(move(import_name_)) - , local_name(move(local_name_)) - , is_namespace(is_namespace_) - { - VERIFY(!is_namespace || import_name.is_null()); - } +// ImportEntry Record, https://tc39.es/ecma262/#table-importentry-record-fields +struct ImportEntry { + FlyString import_name; // [[ImportName]] if a String + FlyString local_name; // [[LocalName]] + bool is_namespace { false }; // [[ImportName]] if `namespace-object` - ModuleRequest const& module_request() const - { - VERIFY(m_module_request); - return *m_module_request; - } + ImportEntry(FlyString import_name_, FlyString local_name_, bool is_namespace_ = false) + : import_name(move(import_name_)) + , local_name(move(local_name_)) + , is_namespace(is_namespace_) + { + VERIFY(!is_namespace || import_name.is_null()); + } - private: - friend ImportStatement; - ModuleRequest* m_module_request; // [[ModuleRequest]] - }; + ModuleRequest const& module_request() const + { + VERIFY(m_module_request); + return *m_module_request; + } + +private: + friend class ImportStatement; + ModuleRequest* m_module_request; // [[ModuleRequest]] +}; +class ImportStatement final : public Statement { +public: explicit ImportStatement(SourceRange source_range, ModuleRequest from_module, Vector entries = {}) : Statement(source_range) , m_module_request(move(from_module)) @@ -348,76 +348,76 @@ private: Vector m_entries; }; -class ExportStatement final : public Statement { -public: - static FlyString local_name_for_default; +// ExportEntry Record, https://tc39.es/ecma262/#table-exportentry-records +struct ExportEntry { + enum class Kind { + NamedExport, + ModuleRequestAll, + ModuleRequestAllButDefault, + // EmptyNamedExport is a special type for export {} from "module", + // which should import the module without getting any of the exports + // however we don't want give it a fake export name which may get + // duplicates + EmptyNamedExport, + } kind; - // ExportEntry Record, https://tc39.es/ecma262/#table-exportentry-records - struct ExportEntry { - enum class Kind { - NamedExport, - ModuleRequestAll, - ModuleRequestAllButDefault, - // EmptyNamedExport is a special type for export {} from "module", - // which should import the module without getting any of the exports - // however we don't want give it a fake export name which may get - // duplicates - EmptyNamedExport, - } kind; - - FlyString export_name; // [[ExportName]] - FlyString local_or_import_name; // Either [[ImportName]] or [[LocalName]] - - ExportEntry(Kind export_kind, FlyString export_name_, FlyString local_or_import_name_) - : kind(export_kind) - , export_name(move(export_name_)) - , local_or_import_name(move(local_or_import_name_)) - { - } + FlyString export_name; // [[ExportName]] + FlyString local_or_import_name; // Either [[ImportName]] or [[LocalName]] - bool is_module_request() const - { - return m_module_request != nullptr; - } + ExportEntry(Kind export_kind, FlyString export_name_, FlyString local_or_import_name_) + : kind(export_kind) + , export_name(move(export_name_)) + , local_or_import_name(move(local_or_import_name_)) + { + } - static ExportEntry indirect_export_entry(ModuleRequest const& module_request, FlyString export_name, FlyString import_name) - { - ExportEntry entry { Kind::NamedExport, move(export_name), move(import_name) }; - entry.m_module_request = &module_request; - return entry; - } + bool is_module_request() const + { + return m_module_request != nullptr; + } - ModuleRequest const& module_request() const - { - VERIFY(m_module_request); - return *m_module_request; - } + static ExportEntry indirect_export_entry(ModuleRequest const& module_request, FlyString export_name, FlyString import_name) + { + ExportEntry entry { Kind::NamedExport, move(export_name), move(import_name) }; + entry.m_module_request = &module_request; + return entry; + } - private: - ModuleRequest const* m_module_request { nullptr }; // [[ModuleRequest]] - friend ExportStatement; + ModuleRequest const& module_request() const + { + VERIFY(m_module_request); + return *m_module_request; + } - public: - static ExportEntry named_export(FlyString export_name, FlyString local_name) - { - return ExportEntry { Kind::NamedExport, move(export_name), move(local_name) }; - } +private: + ModuleRequest const* m_module_request { nullptr }; // [[ModuleRequest]] + friend class ExportStatement; - static ExportEntry all_but_default_entry() - { - return ExportEntry { Kind::ModuleRequestAllButDefault, {}, {} }; - } +public: + static ExportEntry named_export(FlyString export_name, FlyString local_name) + { + return ExportEntry { Kind::NamedExport, move(export_name), move(local_name) }; + } - static ExportEntry all_module_request(FlyString export_name) - { - return ExportEntry { Kind::ModuleRequestAll, move(export_name), {} }; - } + static ExportEntry all_but_default_entry() + { + return ExportEntry { Kind::ModuleRequestAllButDefault, {}, {} }; + } - static ExportEntry empty_named_export() - { - return ExportEntry { Kind::EmptyNamedExport, {}, {} }; - } - }; + static ExportEntry all_module_request(FlyString export_name) + { + return ExportEntry { Kind::ModuleRequestAll, move(export_name), {} }; + } + + static ExportEntry empty_named_export() + { + return ExportEntry { Kind::EmptyNamedExport, {}, {} }; + } +}; + +class ExportStatement final : public Statement { +public: + static FlyString local_name_for_default; ExportStatement(SourceRange source_range, RefPtr statement, Vector entries, bool is_default_export, ModuleRequest module_request) : Statement(source_range) diff --git a/Userland/Libraries/LibJS/Forward.h b/Userland/Libraries/LibJS/Forward.h index 12cc1cddfe..cb033ecf79 100644 --- a/Userland/Libraries/LibJS/Forward.h +++ b/Userland/Libraries/LibJS/Forward.h @@ -163,6 +163,8 @@ class Environment; class Error; class ErrorType; struct ExecutionContext; +struct ExportEntry; +class ExportStatement; class Expression; class ForStatement; class FunctionEnvironment; @@ -172,6 +174,8 @@ class GlobalObject; class HandleImpl; class Heap; class HeapBlock; +struct ImportEntry; +class ImportStatement; class Interpreter; class Intrinsics; class Module; diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index 58eb7079b3..6610a52d49 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -556,7 +556,7 @@ void Parser::parse_module(Program& program) if (export_statement.has_statement()) continue; for (auto& entry : export_statement.entries()) { - if (entry.is_module_request() || entry.kind == ExportStatement::ExportEntry::Kind::EmptyNamedExport) + if (entry.is_module_request() || entry.kind == ExportEntry::Kind::EmptyNamedExport) return; auto const& exported_name = entry.local_or_import_name; @@ -4162,7 +4162,7 @@ NonnullRefPtr Parser::parse_import_statement(Program& program) bool continue_parsing = true; struct ImportWithLocation { - ImportStatement::ImportEntry entry; + ImportEntry entry; Position position; }; @@ -4203,7 +4203,7 @@ NonnullRefPtr Parser::parse_import_statement(Program& program) if (match_imported_binding()) { auto namespace_position = position(); auto namespace_name = consume().value(); - entries_with_location.append({ ImportStatement::ImportEntry({}, namespace_name, true), namespace_position }); + entries_with_location.append({ ImportEntry({}, namespace_name, true), namespace_position }); } else { syntax_error(String::formatted("Unexpected token: {}", m_state.current_token.name())); } @@ -4271,7 +4271,7 @@ NonnullRefPtr Parser::parse_import_statement(Program& program) auto module_request = parse_module_request(); - Vector entries; + Vector entries; entries.ensure_capacity(entries_with_location.size()); for (auto& entry : entries_with_location) { @@ -4293,8 +4293,6 @@ NonnullRefPtr Parser::parse_import_statement(Program& program) NonnullRefPtr Parser::parse_export_statement(Program& program) { - using ExportEntry = ExportStatement::ExportEntry; - // We use the extended syntax which adds: // ExportDeclaration: // export ExportFromClause FromClause [no LineTerminator here] AssertClause ; @@ -4572,7 +4570,7 @@ NonnullRefPtr Parser::parse_export_statement(Program& program) consume_or_insert_semicolon(); } - Vector entries; + Vector entries; entries.ensure_capacity(entries_with_location.size()); for (auto& entry : entries_with_location) { @@ -4582,7 +4580,7 @@ NonnullRefPtr Parser::parse_export_statement(Program& program) } for (auto& new_entry : entries) { - if (new_entry.kind != ExportStatement::ExportEntry::Kind::EmptyNamedExport && new_entry.export_name == entry.entry.export_name) + if (new_entry.kind != ExportEntry::Kind::EmptyNamedExport && new_entry.export_name == entry.entry.export_name) syntax_error(String::formatted("Duplicate export with name: '{}'", entry.entry.export_name), entry.position); } diff --git a/Userland/Libraries/LibJS/SourceTextModule.cpp b/Userland/Libraries/LibJS/SourceTextModule.cpp index 621c9d48b4..c4dbc17173 100644 --- a/Userland/Libraries/LibJS/SourceTextModule.cpp +++ b/Userland/Libraries/LibJS/SourceTextModule.cpp @@ -168,7 +168,7 @@ Result, Vector> SourceTextModule:: VERIFY(export_statement.has_statement()); auto const& entry = export_statement.entries()[0]; - VERIFY(entry.kind == ExportStatement::ExportEntry::Kind::NamedExport); + VERIFY(entry.kind == ExportEntry::Kind::NamedExport); VERIFY(!entry.is_module_request()); VERIFY(import_entries.find_if( [&](ImportEntry const& import_entry) { @@ -182,7 +182,7 @@ Result, Vector> SourceTextModule:: // Special case, export {} from "module" should add "module" to // required_modules but not any import or export so skip here. - if (export_entry.kind == ExportStatement::ExportEntry::Kind::EmptyNamedExport) { + if (export_entry.kind == ExportEntry::Kind::EmptyNamedExport) { VERIFY(export_statement.entries().size() == 1); break; } @@ -220,7 +220,7 @@ Result, Vector> SourceTextModule:: } } // b. Else if ee.[[ImportName]] is all-but-default, then - else if (export_entry.kind == ExportStatement::ExportEntry::Kind::ModuleRequestAllButDefault) { + else if (export_entry.kind == ExportEntry::Kind::ModuleRequestAllButDefault) { // i. Assert: ee.[[ExportName]] is null. VERIFY(export_entry.export_name.is_null()); // ii. Append ee to starExportEntries. @@ -564,7 +564,7 @@ ThrowCompletionOr SourceTextModule::resolve_export(VM& vm, FlyS auto imported_module = TRY(vm.host_resolve_imported_module(NonnullGCPtr(*this), entry.module_request())); // ii. If e.[[ImportName]] is all, then - if (entry.kind == ExportStatement::ExportEntry::Kind::ModuleRequestAll) { + if (entry.kind == ExportEntry::Kind::ModuleRequestAll) { // 1. Assert: module does not provide the direct binding for this export. // FIXME: What does this mean? / How do we check this diff --git a/Userland/Libraries/LibJS/SourceTextModule.h b/Userland/Libraries/LibJS/SourceTextModule.h index 21531a9252..2761a42b0c 100644 --- a/Userland/Libraries/LibJS/SourceTextModule.h +++ b/Userland/Libraries/LibJS/SourceTextModule.h @@ -20,9 +20,6 @@ class SourceTextModule final : public CyclicModule { JS_CELL(SourceTextModule, CyclicModule); public: - using ImportEntry = ImportStatement::ImportEntry; - using ExportEntry = ExportStatement::ExportEntry; - static Result, Vector> parse(StringView source_text, Realm&, StringView filename = {}, Script::HostDefined* host_defined = nullptr); Program const& parse_node() const { return *m_ecmascript_code; } -- cgit v1.2.3