+ class DeconstructionPatternNode : public RefCounted<DeconstructionPatternNode> {
+ WTF_MAKE_NONCOPYABLE(DeconstructionPatternNode);
+ WTF_MAKE_FAST_ALLOCATED;
+
+ public:
+ virtual void collectBoundIdentifiers(Vector<Identifier>&) const = 0;
+ virtual void bindValue(BytecodeGenerator&, RegisterID* source) const = 0;
+ virtual void toString(StringBuilder&) const = 0;
+
+ virtual bool isBindingNode() const { return false; }
+ virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID*, ExpressionNode*) { return 0; }
+
+ virtual ~DeconstructionPatternNode() = 0;
+
+ protected:
+ DeconstructionPatternNode(VM*);
+ };
+
+ class ArrayPatternNode : public DeconstructionPatternNode {
+ public:
+ static PassRefPtr<ArrayPatternNode> create(VM*);
+ void appendIndex(const JSTokenLocation&, DeconstructionPatternNode* node)
+ {
+ m_targetPatterns.append(node);
+ }
+
+ private:
+ ArrayPatternNode(VM*);
+ virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
+ virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
+ virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID* dst, ExpressionNode*) override;
+ virtual void toString(StringBuilder&) const override;
+
+ Vector<RefPtr<DeconstructionPatternNode>> m_targetPatterns;
+ };
+
+ class ObjectPatternNode : public DeconstructionPatternNode {
+ public:
+ static PassRefPtr<ObjectPatternNode> create(VM*);
+ void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DeconstructionPatternNode* pattern)
+ {
+ m_targetPatterns.append(Entry(identifier, wasString, pattern));
+ }
+
+ private:
+ ObjectPatternNode(VM*);
+ virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
+ virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
+ virtual void toString(StringBuilder&) const override;
+ struct Entry {
+ Entry(const Identifier& propertyName, bool wasString, DeconstructionPatternNode* pattern)
+ : propertyName(propertyName)
+ , wasString(wasString)
+ , pattern(pattern)
+ {
+ }
+ Identifier propertyName;
+ bool wasString;
+ RefPtr<DeconstructionPatternNode> pattern;
+ };
+ Vector<Entry> m_targetPatterns;
+ };
+
+ class BindingNode : public DeconstructionPatternNode {
+ public:
+ static PassRefPtr<BindingNode> create(VM*, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
+ const Identifier& boundProperty() const { return m_boundProperty; }
+
+ const JSTextPosition& divotStart() const { return m_divotStart; }
+ const JSTextPosition& divotEnd() const { return m_divotEnd; }
+
+ private:
+ BindingNode(VM*, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
+
+ virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
+ virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
+ virtual void toString(StringBuilder&) const override;
+
+ virtual bool isBindingNode() const override { return true; }
+
+ JSTextPosition m_divotStart;
+ JSTextPosition m_divotEnd;
+ Identifier m_boundProperty;
+ };
+
+ class DeconstructingAssignmentNode : public ExpressionNode, public ParserArenaDeletable {
+ public:
+ DeconstructingAssignmentNode(const JSTokenLocation&, PassRefPtr<DeconstructionPatternNode>, ExpressionNode*);
+ DeconstructionPatternNode* bindings() { return m_bindings.get(); }
+
+ using ParserArenaDeletable::operator new;
+
+ private:
+ virtual bool isAssignmentLocation() const override { return true; }
+ virtual bool isDeconstructionNode() const override { return true; }
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+ RefPtr<DeconstructionPatternNode> m_bindings;
+ ExpressionNode* m_initializer;
+ };
+