mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:27:45 +00:00
LibJS: Implement destructuring assignments and function parameters
This commit is contained in:
parent
1123af361d
commit
7a00d6d9c8
9 changed files with 533 additions and 83 deletions
|
@ -10,8 +10,10 @@
|
|||
#include <AK/FlyString.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/NonnullRefPtrVector.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Runtime/PropertyName.h>
|
||||
|
@ -22,6 +24,7 @@ namespace JS {
|
|||
|
||||
class VariableDeclaration;
|
||||
class FunctionDeclaration;
|
||||
class Identifier;
|
||||
|
||||
template<class T, class... Args>
|
||||
static inline NonnullRefPtr<T>
|
||||
|
@ -185,10 +188,32 @@ public:
|
|||
Value execute(Interpreter&, GlobalObject&) const override { return {}; }
|
||||
};
|
||||
|
||||
struct BindingPattern : RefCounted<BindingPattern> {
|
||||
struct BindingProperty {
|
||||
RefPtr<Identifier> name;
|
||||
RefPtr<Identifier> alias;
|
||||
RefPtr<BindingPattern> pattern;
|
||||
RefPtr<Expression> initializer;
|
||||
bool is_rest { false };
|
||||
};
|
||||
|
||||
enum class Kind {
|
||||
Array,
|
||||
Object,
|
||||
};
|
||||
|
||||
void dump(int indent) const;
|
||||
template<typename C>
|
||||
void for_each_assigned_name(C&& callback) const;
|
||||
|
||||
Vector<BindingProperty> properties;
|
||||
Kind kind { Kind::Object };
|
||||
};
|
||||
|
||||
class FunctionNode {
|
||||
public:
|
||||
struct Parameter {
|
||||
FlyString name;
|
||||
Variant<FlyString, NonnullRefPtr<BindingPattern>> binding;
|
||||
RefPtr<Expression> default_value;
|
||||
bool is_rest { false };
|
||||
};
|
||||
|
@ -907,25 +932,32 @@ class VariableDeclarator final : public ASTNode {
|
|||
public:
|
||||
VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier> id)
|
||||
: ASTNode(move(source_range))
|
||||
, m_id(move(id))
|
||||
, m_target(move(id))
|
||||
{
|
||||
}
|
||||
|
||||
VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier> id, RefPtr<Expression> init)
|
||||
VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier> target, RefPtr<Expression> init)
|
||||
: ASTNode(move(source_range))
|
||||
, m_id(move(id))
|
||||
, m_target(move(target))
|
||||
, m_init(move(init))
|
||||
{
|
||||
}
|
||||
|
||||
const Identifier& id() const { return m_id; }
|
||||
VariableDeclarator(SourceRange source_range, Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>> target, RefPtr<Expression> init)
|
||||
: ASTNode(move(source_range))
|
||||
, m_target(move(target))
|
||||
, m_init(move(init))
|
||||
{
|
||||
}
|
||||
|
||||
auto& target() const { return m_target; }
|
||||
const Expression* init() const { return m_init; }
|
||||
|
||||
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
||||
virtual void dump(int indent) const override;
|
||||
|
||||
private:
|
||||
NonnullRefPtr<Identifier> m_id;
|
||||
Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>> m_target;
|
||||
RefPtr<Expression> m_init;
|
||||
};
|
||||
|
||||
|
@ -1269,4 +1301,16 @@ public:
|
|||
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
||||
};
|
||||
|
||||
template<typename C>
|
||||
void BindingPattern::for_each_assigned_name(C&& callback) const
|
||||
{
|
||||
for (auto& property : properties) {
|
||||
if (property.name) {
|
||||
callback(property.name->string());
|
||||
continue;
|
||||
}
|
||||
property.pattern->template for_each_assigned_name(forward<C>(callback));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue