[cleanup] Split ForOf and ForIn AST nodes apart as they share little

Also make all AstVisitors consistently visit all the relevant parts
of ForOfStatement. PrettyPrinter no longer fares well, but given
how much desugaring happens to ForOf in the parser, any pretty-printed
view of it isn't going to be human readable. AstPrinter, on the other
hand, now gives a realistic view of what's been generated for for-of.

Review-Url: https://codereview.chromium.org/1968753004
Cr-Commit-Position: refs/heads/master@{#36215}
This commit is contained in:
adamk 2016-05-12 09:24:59 -07:00 committed by Commit bot
parent 8f6556bd19
commit 4a7b9b973b
7 changed files with 65 additions and 55 deletions

View File

@ -169,12 +169,10 @@ void AstExpressionRewriter::VisitForInStatement(ForInStatement* node) {
void AstExpressionRewriter::VisitForOfStatement(ForOfStatement* node) {
AST_REWRITE_PROPERTY(Expression, node, each);
AST_REWRITE_PROPERTY(Expression, node, assign_iterator);
AST_REWRITE_PROPERTY(Expression, node, next_result);
AST_REWRITE_PROPERTY(Expression, node, result_done);
AST_REWRITE_PROPERTY(Expression, node, assign_each);
AST_REWRITE_PROPERTY(Expression, node, subject);
AST_REWRITE_PROPERTY(Statement, node, body);
}

View File

@ -170,7 +170,6 @@ void AstExpressionVisitor::VisitForInStatement(ForInStatement* stmt) {
void AstExpressionVisitor::VisitForOfStatement(ForOfStatement* stmt) {
RECURSE(Visit(stmt->iterable()));
RECURSE(Visit(stmt->assign_iterator()));
RECURSE(Visit(stmt->next_result()));
RECURSE(Visit(stmt->result_done()));

View File

@ -790,17 +790,7 @@ class ForEachStatement : public IterationStatement {
ITERATE // for (each of subject) body;
};
void Initialize(Expression* each, Expression* subject, Statement* body) {
IterationStatement::Initialize(body);
each_ = each;
subject_ = subject;
}
Expression* each() const { return each_; }
Expression* subject() const { return subject_; }
void set_each(Expression* e) { each_ = e; }
void set_subject(Expression* e) { subject_ = e; }
using IterationStatement::Initialize;
static const char* VisitModeString(VisitMode mode) {
return mode == ITERATE ? "for-of" : "for-in";
@ -808,11 +798,7 @@ class ForEachStatement : public IterationStatement {
protected:
ForEachStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
: IterationStatement(zone, labels, pos), each_(NULL), subject_(NULL) {}
private:
Expression* each_;
Expression* subject_;
: IterationStatement(zone, labels, pos) {}
};
@ -820,10 +806,22 @@ class ForInStatement final : public ForEachStatement {
public:
DECLARE_NODE_TYPE(ForInStatement)
void Initialize(Expression* each, Expression* subject, Statement* body) {
ForEachStatement::Initialize(body);
each_ = each;
subject_ = subject;
}
Expression* enumerable() const {
return subject();
}
Expression* each() const { return each_; }
Expression* subject() const { return subject_; }
void set_each(Expression* e) { each_ = e; }
void set_subject(Expression* e) { subject_ = e; }
// Type feedback information.
void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) override;
@ -849,12 +847,17 @@ class ForInStatement final : public ForEachStatement {
protected:
ForInStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
: ForEachStatement(zone, labels, pos), for_in_type_(SLOW_FOR_IN) {}
: ForEachStatement(zone, labels, pos),
each_(nullptr),
subject_(nullptr),
for_in_type_(SLOW_FOR_IN) {}
static int parent_num_ids() { return ForEachStatement::num_ids(); }
private:
int local_id(int n) const { return base_id() + parent_num_ids() + n; }
Expression* each_;
Expression* subject_;
ForInType for_in_type_;
FeedbackVectorSlot each_slot_;
FeedbackVectorSlot for_in_feedback_slot_;
@ -865,15 +868,10 @@ class ForOfStatement final : public ForEachStatement {
public:
DECLARE_NODE_TYPE(ForOfStatement)
void Initialize(Expression* each,
Expression* subject,
Statement* body,
Variable* iterator,
Expression* assign_iterator,
Expression* next_result,
Expression* result_done,
Expression* assign_each) {
ForEachStatement::Initialize(each, subject, body);
void Initialize(Statement* body, Variable* iterator,
Expression* assign_iterator, Expression* next_result,
Expression* result_done, Expression* assign_each) {
ForEachStatement::Initialize(body);
iterator_ = iterator;
assign_iterator_ = assign_iterator;
next_result_ = next_result;
@ -881,10 +879,6 @@ class ForOfStatement final : public ForEachStatement {
assign_each_ = assign_each;
}
Expression* iterable() const {
return subject();
}
Variable* iterator() const {
return iterator_;
}

View File

@ -192,10 +192,11 @@ void CallPrinter::VisitForInStatement(ForInStatement* node) {
void CallPrinter::VisitForOfStatement(ForOfStatement* node) {
Find(node->each());
Find(node->assign_iterator());
Find(node->body());
Find(node->next_result());
Find(node->result_done());
Find(node->assign_each());
Find(node->body());
}
@ -675,11 +676,37 @@ void PrettyPrinter::VisitForInStatement(ForInStatement* node) {
void PrettyPrinter::VisitForOfStatement(ForOfStatement* node) {
// TODO(adamk): ForOf is largely desugared as part of parsing,
// so it's hard to display useful stuff here. Should likely
// either bite the bullet and display less or try harder
// to preserve more.
PrintLabels(node->labels());
Print("for (");
Visit(node->each());
Print(" of ");
Visit(node->iterable());
// The <each> is embedded inside a do-expression by the time we get here.
Print("for (<each> of ");
if (node->assign_iterator()->IsAssignment() &&
node->assign_iterator()->AsAssignment()->value()->IsCall() &&
node->assign_iterator()
->AsAssignment()
->value()
->AsCall()
->expression()
->IsProperty() &&
node->assign_iterator()
->AsAssignment()
->value()
->AsCall()
->expression()
->IsProperty()) {
Visit(node->assign_iterator()
->AsAssignment()
->value()
->AsCall()
->expression()
->AsProperty()
->obj());
} else {
Print("<iterable>");
}
Print(") ");
Visit(node->body());
}
@ -1408,13 +1435,11 @@ void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
IndentedScope indent(this, "FOR OF", node->position());
PrintIndented("YIELD COUNT");
Print(" %d\n", node->yield_count());
PrintIndentedVisit("FOR", node->each());
PrintIndentedVisit("OF", node->iterable());
PrintIndentedVisit("BODY", node->body());
PrintIndentedVisit("INIT", node->assign_iterator());
PrintIndentedVisit("NEXT", node->next_result());
PrintIndentedVisit("EACH", node->assign_each());
PrintIndentedVisit("DONE", node->result_done());
PrintIndentedVisit("EACH", node->assign_each());
PrintIndentedVisit("BODY", node->body());
}

View File

@ -265,8 +265,9 @@ void ALAA::VisitForInStatement(ForInStatement* loop) {
void ALAA::VisitForOfStatement(ForOfStatement* loop) {
Visit(loop->assign_iterator());
Enter(loop);
Visit(loop->next_result());
Visit(loop->result_done());
Visit(loop->assign_each());
Visit(loop->subject());
Visit(loop->body());
Exit(loop);
}

View File

@ -304,14 +304,7 @@ void AstTyper::VisitForInStatement(ForInStatement* stmt) {
store_.Forget(); // Control may transfer here via 'break'.
}
void AstTyper::VisitForOfStatement(ForOfStatement* stmt) {
RECURSE(Visit(stmt->iterable()));
store_.Forget(); // Control may transfer here via looping or 'continue'.
RECURSE(Visit(stmt->body()));
store_.Forget(); // Control may transfer here via 'break'.
}
void AstTyper::VisitForOfStatement(ForOfStatement* stmt) {}
void AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) {
Effects try_effects = EnterEffects();

View File

@ -3112,7 +3112,7 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt,
body = block;
each = factory()->NewVariableProxy(temp);
}
stmt->Initialize(each, subject, body);
stmt->AsForInStatement()->Initialize(each, subject, body);
}
}
@ -3169,8 +3169,8 @@ void Parser::InitializeForOfStatement(ForOfStatement* for_of, Expression* each,
}
}
for_of->Initialize(each, iterable, body, iterator, assign_iterator,
next_result, result_done, assign_each);
for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
assign_each);
}
Statement* Parser::DesugarLexicalBindingsInForStatement(