Parcourir la source

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.
Andreas Kling il y a 2 ans
Parent
commit
e0916dbb35

+ 85 - 85
Userland/Libraries/LibJS/AST.h

@@ -298,33 +298,33 @@ struct ModuleRequest {
     Vector<Assertion> 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<ImportEntry> entries = {})
         : Statement(source_range)
         , m_module_request(move(from_module))
@@ -348,76 +348,76 @@ private:
     Vector<ImportEntry> 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<ASTNode> statement, Vector<ExportEntry> entries, bool is_default_export, ModuleRequest module_request)
         : Statement(source_range)

+ 4 - 0
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;

+ 6 - 8
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<ImportStatement> Parser::parse_import_statement(Program& program)
     bool continue_parsing = true;
 
     struct ImportWithLocation {
-        ImportStatement::ImportEntry entry;
+        ImportEntry entry;
         Position position;
     };
 
@@ -4203,7 +4203,7 @@ NonnullRefPtr<ImportStatement> 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<ImportStatement> Parser::parse_import_statement(Program& program)
 
     auto module_request = parse_module_request();
 
-    Vector<ImportStatement::ImportEntry> entries;
+    Vector<ImportEntry> entries;
     entries.ensure_capacity(entries_with_location.size());
 
     for (auto& entry : entries_with_location) {
@@ -4293,8 +4293,6 @@ NonnullRefPtr<ImportStatement> Parser::parse_import_statement(Program& program)
 
 NonnullRefPtr<ExportStatement> 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<ExportStatement> Parser::parse_export_statement(Program& program)
             consume_or_insert_semicolon();
     }
 
-    Vector<ExportStatement::ExportEntry> entries;
+    Vector<ExportEntry> entries;
     entries.ensure_capacity(entries_with_location.size());
 
     for (auto& entry : entries_with_location) {
@@ -4582,7 +4580,7 @@ NonnullRefPtr<ExportStatement> 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);
         }
 

+ 4 - 4
Userland/Libraries/LibJS/SourceTextModule.cpp

@@ -168,7 +168,7 @@ Result<NonnullGCPtr<SourceTextModule>, Vector<Parser::Error>> 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<NonnullGCPtr<SourceTextModule>, Vector<Parser::Error>> 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<NonnullGCPtr<SourceTextModule>, Vector<Parser::Error>> 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<ResolvedBinding> SourceTextModule::resolve_export(VM& vm, FlyS
         auto imported_module = TRY(vm.host_resolve_imported_module(NonnullGCPtr<Module>(*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
 

+ 0 - 3
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<NonnullGCPtr<SourceTextModule>, Vector<Parser::Error>> parse(StringView source_text, Realm&, StringView filename = {}, Script::HostDefined* host_defined = nullptr);
 
     Program const& parse_node() const { return *m_ecmascript_code; }