1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:08:11 +00:00

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.
This commit is contained in:
Andreas Kling 2022-11-23 12:16:51 +01:00 committed by Linus Groh
parent 27e0f56c90
commit e0916dbb35
5 changed files with 106 additions and 107 deletions

View file

@ -298,10 +298,8 @@ struct ModuleRequest {
Vector<Assertion> assertions; // [[Assertions]]
};
class ImportStatement final : public Statement {
public:
// ImportEntry Record, https://tc39.es/ecma262/#table-importentry-record-fields
struct ImportEntry {
// 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`
@ -320,11 +318,13 @@ public:
return *m_module_request;
}
private:
friend ImportStatement;
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,12 +348,8 @@ 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 {
// ExportEntry Record, https://tc39.es/ecma262/#table-exportentry-records
struct ExportEntry {
enum class Kind {
NamedExport,
ModuleRequestAll,
@ -393,11 +389,11 @@ public:
return *m_module_request;
}
private:
private:
ModuleRequest const* m_module_request { nullptr }; // [[ModuleRequest]]
friend ExportStatement;
friend class ExportStatement;
public:
public:
static ExportEntry named_export(FlyString export_name, FlyString local_name)
{
return ExportEntry { Kind::NamedExport, move(export_name), move(local_name) };
@ -417,7 +413,11 @@ public:
{
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)

View file

@ -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;

View file

@ -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);
}

View file

@ -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

View file

@ -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; }