summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-11-23 12:16:51 +0100
committerLinus Groh <mail@linusgroh.de>2022-11-23 16:05:59 +0000
commite0916dbb359d6181290daf1748fe5dce85015be1 (patch)
tree45cac63ee225ba0cc807be3474e275fb0b09c03e
parent27e0f56c90e52c552a9fce543084ea83917035ef (diff)
downloadserenity-e0916dbb359d6181290daf1748fe5dce85015be1.zip
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.
-rw-r--r--Userland/Libraries/LibJS/AST.h170
-rw-r--r--Userland/Libraries/LibJS/Forward.h4
-rw-r--r--Userland/Libraries/LibJS/Parser.cpp14
-rw-r--r--Userland/Libraries/LibJS/SourceTextModule.cpp8
-rw-r--r--Userland/Libraries/LibJS/SourceTextModule.h3
5 files changed, 99 insertions, 100 deletions
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<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)
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<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);
}
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<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
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<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; }