mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 14:27:35 +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:
parent
27e0f56c90
commit
e0916dbb35
5 changed files with 106 additions and 107 deletions
|
@ -298,10 +298,8 @@ struct ModuleRequest {
|
||||||
Vector<Assertion> assertions; // [[Assertions]]
|
Vector<Assertion> assertions; // [[Assertions]]
|
||||||
};
|
};
|
||||||
|
|
||||||
class ImportStatement final : public Statement {
|
// ImportEntry Record, https://tc39.es/ecma262/#table-importentry-record-fields
|
||||||
public:
|
struct ImportEntry {
|
||||||
// ImportEntry Record, https://tc39.es/ecma262/#table-importentry-record-fields
|
|
||||||
struct ImportEntry {
|
|
||||||
FlyString import_name; // [[ImportName]] if a String
|
FlyString import_name; // [[ImportName]] if a String
|
||||||
FlyString local_name; // [[LocalName]]
|
FlyString local_name; // [[LocalName]]
|
||||||
bool is_namespace { false }; // [[ImportName]] if `namespace-object`
|
bool is_namespace { false }; // [[ImportName]] if `namespace-object`
|
||||||
|
@ -320,11 +318,13 @@ public:
|
||||||
return *m_module_request;
|
return *m_module_request;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend ImportStatement;
|
friend class ImportStatement;
|
||||||
ModuleRequest* m_module_request; // [[ModuleRequest]]
|
ModuleRequest* m_module_request; // [[ModuleRequest]]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ImportStatement final : public Statement {
|
||||||
|
public:
|
||||||
explicit ImportStatement(SourceRange source_range, ModuleRequest from_module, Vector<ImportEntry> entries = {})
|
explicit ImportStatement(SourceRange source_range, ModuleRequest from_module, Vector<ImportEntry> entries = {})
|
||||||
: Statement(source_range)
|
: Statement(source_range)
|
||||||
, m_module_request(move(from_module))
|
, m_module_request(move(from_module))
|
||||||
|
@ -348,12 +348,8 @@ private:
|
||||||
Vector<ImportEntry> m_entries;
|
Vector<ImportEntry> m_entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExportStatement final : public Statement {
|
// ExportEntry Record, https://tc39.es/ecma262/#table-exportentry-records
|
||||||
public:
|
struct ExportEntry {
|
||||||
static FlyString local_name_for_default;
|
|
||||||
|
|
||||||
// ExportEntry Record, https://tc39.es/ecma262/#table-exportentry-records
|
|
||||||
struct ExportEntry {
|
|
||||||
enum class Kind {
|
enum class Kind {
|
||||||
NamedExport,
|
NamedExport,
|
||||||
ModuleRequestAll,
|
ModuleRequestAll,
|
||||||
|
@ -393,11 +389,11 @@ public:
|
||||||
return *m_module_request;
|
return *m_module_request;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ModuleRequest const* m_module_request { nullptr }; // [[ModuleRequest]]
|
ModuleRequest const* m_module_request { nullptr }; // [[ModuleRequest]]
|
||||||
friend ExportStatement;
|
friend class ExportStatement;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ExportEntry named_export(FlyString export_name, FlyString local_name)
|
static ExportEntry named_export(FlyString export_name, FlyString local_name)
|
||||||
{
|
{
|
||||||
return ExportEntry { Kind::NamedExport, move(export_name), move(local_name) };
|
return ExportEntry { Kind::NamedExport, move(export_name), move(local_name) };
|
||||||
|
@ -417,7 +413,11 @@ public:
|
||||||
{
|
{
|
||||||
return ExportEntry { Kind::EmptyNamedExport, {}, {} };
|
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)
|
ExportStatement(SourceRange source_range, RefPtr<ASTNode> statement, Vector<ExportEntry> entries, bool is_default_export, ModuleRequest module_request)
|
||||||
: Statement(source_range)
|
: Statement(source_range)
|
||||||
|
|
|
@ -163,6 +163,8 @@ class Environment;
|
||||||
class Error;
|
class Error;
|
||||||
class ErrorType;
|
class ErrorType;
|
||||||
struct ExecutionContext;
|
struct ExecutionContext;
|
||||||
|
struct ExportEntry;
|
||||||
|
class ExportStatement;
|
||||||
class Expression;
|
class Expression;
|
||||||
class ForStatement;
|
class ForStatement;
|
||||||
class FunctionEnvironment;
|
class FunctionEnvironment;
|
||||||
|
@ -172,6 +174,8 @@ class GlobalObject;
|
||||||
class HandleImpl;
|
class HandleImpl;
|
||||||
class Heap;
|
class Heap;
|
||||||
class HeapBlock;
|
class HeapBlock;
|
||||||
|
struct ImportEntry;
|
||||||
|
class ImportStatement;
|
||||||
class Interpreter;
|
class Interpreter;
|
||||||
class Intrinsics;
|
class Intrinsics;
|
||||||
class Module;
|
class Module;
|
||||||
|
|
|
@ -556,7 +556,7 @@ void Parser::parse_module(Program& program)
|
||||||
if (export_statement.has_statement())
|
if (export_statement.has_statement())
|
||||||
continue;
|
continue;
|
||||||
for (auto& entry : export_statement.entries()) {
|
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;
|
return;
|
||||||
|
|
||||||
auto const& exported_name = entry.local_or_import_name;
|
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;
|
bool continue_parsing = true;
|
||||||
|
|
||||||
struct ImportWithLocation {
|
struct ImportWithLocation {
|
||||||
ImportStatement::ImportEntry entry;
|
ImportEntry entry;
|
||||||
Position position;
|
Position position;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4203,7 +4203,7 @@ NonnullRefPtr<ImportStatement> Parser::parse_import_statement(Program& program)
|
||||||
if (match_imported_binding()) {
|
if (match_imported_binding()) {
|
||||||
auto namespace_position = position();
|
auto namespace_position = position();
|
||||||
auto namespace_name = consume().value();
|
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 {
|
} else {
|
||||||
syntax_error(String::formatted("Unexpected token: {}", m_state.current_token.name()));
|
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();
|
auto module_request = parse_module_request();
|
||||||
|
|
||||||
Vector<ImportStatement::ImportEntry> entries;
|
Vector<ImportEntry> entries;
|
||||||
entries.ensure_capacity(entries_with_location.size());
|
entries.ensure_capacity(entries_with_location.size());
|
||||||
|
|
||||||
for (auto& entry : entries_with_location) {
|
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)
|
NonnullRefPtr<ExportStatement> Parser::parse_export_statement(Program& program)
|
||||||
{
|
{
|
||||||
using ExportEntry = ExportStatement::ExportEntry;
|
|
||||||
|
|
||||||
// We use the extended syntax which adds:
|
// We use the extended syntax which adds:
|
||||||
// ExportDeclaration:
|
// ExportDeclaration:
|
||||||
// export ExportFromClause FromClause [no LineTerminator here] AssertClause ;
|
// export ExportFromClause FromClause [no LineTerminator here] AssertClause ;
|
||||||
|
@ -4572,7 +4570,7 @@ NonnullRefPtr<ExportStatement> Parser::parse_export_statement(Program& program)
|
||||||
consume_or_insert_semicolon();
|
consume_or_insert_semicolon();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<ExportStatement::ExportEntry> entries;
|
Vector<ExportEntry> entries;
|
||||||
entries.ensure_capacity(entries_with_location.size());
|
entries.ensure_capacity(entries_with_location.size());
|
||||||
|
|
||||||
for (auto& entry : entries_with_location) {
|
for (auto& entry : entries_with_location) {
|
||||||
|
@ -4582,7 +4580,7 @@ NonnullRefPtr<ExportStatement> Parser::parse_export_statement(Program& program)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& new_entry : entries) {
|
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);
|
syntax_error(String::formatted("Duplicate export with name: '{}'", entry.entry.export_name), entry.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,7 @@ Result<NonnullGCPtr<SourceTextModule>, Vector<Parser::Error>> SourceTextModule::
|
||||||
VERIFY(export_statement.has_statement());
|
VERIFY(export_statement.has_statement());
|
||||||
|
|
||||||
auto const& entry = export_statement.entries()[0];
|
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(!entry.is_module_request());
|
||||||
VERIFY(import_entries.find_if(
|
VERIFY(import_entries.find_if(
|
||||||
[&](ImportEntry const& import_entry) {
|
[&](ImportEntry const& import_entry) {
|
||||||
|
@ -182,7 +182,7 @@ Result<NonnullGCPtr<SourceTextModule>, Vector<Parser::Error>> SourceTextModule::
|
||||||
|
|
||||||
// Special case, export {} from "module" should add "module" to
|
// Special case, export {} from "module" should add "module" to
|
||||||
// required_modules but not any import or export so skip here.
|
// 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);
|
VERIFY(export_statement.entries().size() == 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ Result<NonnullGCPtr<SourceTextModule>, Vector<Parser::Error>> SourceTextModule::
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// b. Else if ee.[[ImportName]] is all-but-default, then
|
// 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.
|
// i. Assert: ee.[[ExportName]] is null.
|
||||||
VERIFY(export_entry.export_name.is_null());
|
VERIFY(export_entry.export_name.is_null());
|
||||||
// ii. Append ee to starExportEntries.
|
// 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()));
|
auto imported_module = TRY(vm.host_resolve_imported_module(NonnullGCPtr<Module>(*this), entry.module_request()));
|
||||||
|
|
||||||
// ii. If e.[[ImportName]] is all, then
|
// 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.
|
// 1. Assert: module does not provide the direct binding for this export.
|
||||||
// FIXME: What does this mean? / How do we check this
|
// FIXME: What does this mean? / How do we check this
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,6 @@ class SourceTextModule final : public CyclicModule {
|
||||||
JS_CELL(SourceTextModule, CyclicModule);
|
JS_CELL(SourceTextModule, CyclicModule);
|
||||||
|
|
||||||
public:
|
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);
|
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; }
|
Program const& parse_node() const { return *m_ecmascript_code; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue