Commit 448239db authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[parser] Parse declarations in the scope that they belong in ParseForStatement

That way we can drop PatternRewriter::scope_ and just use parser_->scope()
instead.

Change-Id: I66137d3ff8e7b805afc7108fd2d55537f69f11e6
Reviewed-on: https://chromium-review.googlesource.com/c/1387500Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58432}
parent 2ebbfc30
...@@ -483,7 +483,6 @@ class ParserBase { ...@@ -483,7 +483,6 @@ class ParserBase {
struct DeclarationDescriptor { struct DeclarationDescriptor {
enum Kind { NORMAL, PARAMETER, FOR_EACH }; enum Kind { NORMAL, PARAMETER, FOR_EACH };
Scope* scope;
VariableMode mode; VariableMode mode;
int declaration_pos; int declaration_pos;
int initialization_pos; int initialization_pos;
...@@ -3522,8 +3521,6 @@ typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseVariableDeclarations( ...@@ -3522,8 +3521,6 @@ typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseVariableDeclarations(
break; break;
} }
parsing_result->descriptor.scope = scope();
int bindings_start = peek_position(); int bindings_start = peek_position();
do { do {
// Parse binding pattern. // Parse binding pattern.
...@@ -5385,15 +5382,23 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement( ...@@ -5385,15 +5382,23 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement(
Expect(Token::SEMICOLON); Expect(Token::SEMICOLON);
StatementT init = impl()->BuildInitializationBlock(&for_info.parsing_result, // Parse the remaining code in the inner block scope since the declaration
&for_info.bound_names); // above was parsed there. We'll finalize the unnecessary outer block scope
// after parsing the rest of the loop.
StatementT result = impl()->NullStatement();
inner_block_scope->set_start_position(scope()->start_position());
{
BlockState inner_state(&scope_, inner_block_scope);
StatementT init = impl()->BuildInitializationBlock(
&for_info.parsing_result, &for_info.bound_names);
Scope* finalized = inner_block_scope->FinalizeBlockScope(); result = ParseStandardForLoopWithLexicalDeclarations(
// No variable declarations will have been created in inner_block_scope. stmt_pos, init, &for_info, labels, own_labels);
}
Scope* finalized = scope()->FinalizeBlockScope();
DCHECK_NULL(finalized); DCHECK_NULL(finalized);
USE(finalized); USE(finalized);
return ParseStandardForLoopWithLexicalDeclarations( return result;
stmt_pos, init, &for_info, labels, own_labels);
} }
StatementT init = impl()->NullStatement(); StatementT init = impl()->NullStatement();
......
...@@ -1574,7 +1574,6 @@ Block* Parser::RewriteCatchPattern(CatchInfo* catch_info) { ...@@ -1574,7 +1574,6 @@ Block* Parser::RewriteCatchPattern(CatchInfo* catch_info) {
DCHECK_NOT_NULL(catch_info->pattern); DCHECK_NOT_NULL(catch_info->pattern);
DeclarationDescriptor descriptor; DeclarationDescriptor descriptor;
descriptor.declaration_kind = DeclarationDescriptor::NORMAL; descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
descriptor.scope = scope();
descriptor.mode = VariableMode::kLet; descriptor.mode = VariableMode::kLet;
descriptor.declaration_pos = catch_info->pattern->position(); descriptor.declaration_pos = catch_info->pattern->position();
descriptor.initialization_pos = catch_info->pattern->position(); descriptor.initialization_pos = catch_info->pattern->position();
...@@ -1885,7 +1884,6 @@ void Parser::DesugarBindingInForEachStatement(ForInfo* for_info, ...@@ -1885,7 +1884,6 @@ void Parser::DesugarBindingInForEachStatement(ForInfo* for_info,
auto descriptor = for_info->parsing_result.descriptor; auto descriptor = for_info->parsing_result.descriptor;
descriptor.declaration_pos = kNoSourcePosition; descriptor.declaration_pos = kNoSourcePosition;
descriptor.initialization_pos = kNoSourcePosition; descriptor.initialization_pos = kNoSourcePosition;
descriptor.scope = scope();
decl.initializer = factory()->NewVariableProxy(temp); decl.initializer = factory()->NewVariableProxy(temp);
bool is_for_var_of = bool is_for_var_of =
...@@ -2819,7 +2817,6 @@ Block* Parser::BuildParameterInitializationBlock( ...@@ -2819,7 +2817,6 @@ Block* Parser::BuildParameterInitializationBlock(
for (auto parameter : parameters.params) { for (auto parameter : parameters.params) {
DeclarationDescriptor descriptor; DeclarationDescriptor descriptor;
descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
descriptor.scope = scope();
descriptor.mode = VariableMode::kLet; descriptor.mode = VariableMode::kLet;
descriptor.declaration_pos = parameter->pattern->position(); descriptor.declaration_pos = parameter->pattern->position();
// The position that will be used by the AssignmentExpression // The position that will be used by the AssignmentExpression
...@@ -2856,9 +2853,6 @@ Block* Parser::BuildParameterInitializationBlock( ...@@ -2856,9 +2853,6 @@ Block* Parser::BuildParameterInitializationBlock(
param_scope->RecordEvalCall(); param_scope->RecordEvalCall();
param_block = factory()->NewBlock(8, true); param_block = factory()->NewBlock(8, true);
param_block->set_scope(param_scope); param_block->set_scope(param_scope);
// Pass the appropriate scope in so that PatternRewriter can appropriately
// rewrite inner initializers of the pattern to param_scope
descriptor.scope = param_scope;
// Rewrite the outer initializer to point to param_scope // Rewrite the outer initializer to point to param_scope
ReparentExpressionScope(stack_limit(), initial_value, param_scope); ReparentExpressionScope(stack_limit(), initial_value, param_scope);
} }
......
...@@ -32,20 +32,18 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> { ...@@ -32,20 +32,18 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> {
ZonePtrList<const AstRawString>* names); ZonePtrList<const AstRawString>* names);
static Expression* RewriteDestructuringAssignment(Parser* parser, static Expression* RewriteDestructuringAssignment(Parser* parser,
Assignment* to_rewrite, Assignment* to_rewrite);
Scope* scope);
private: private:
enum PatternContext : uint8_t { BINDING, ASSIGNMENT }; enum PatternContext : uint8_t { BINDING, ASSIGNMENT };
PatternRewriter(Scope* scope, Parser* parser, PatternContext context, PatternRewriter(Parser* parser, PatternContext context,
const DeclarationDescriptor* descriptor = nullptr, const DeclarationDescriptor* descriptor = nullptr,
ZonePtrList<const AstRawString>* names = nullptr, ZonePtrList<const AstRawString>* names = nullptr,
int initializer_position = kNoSourcePosition, int initializer_position = kNoSourcePosition,
int value_beg_position = kNoSourcePosition, int value_beg_position = kNoSourcePosition,
bool declares_parameter_containing_sloppy_eval = false) bool declares_parameter_containing_sloppy_eval = false)
: scope_(scope), : parser_(parser),
parser_(parser),
block_(nullptr), block_(nullptr),
descriptor_(descriptor), descriptor_(descriptor),
names_(names), names_(names),
...@@ -114,9 +112,8 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> { ...@@ -114,9 +112,8 @@ class PatternRewriter final : public AstVisitor<PatternRewriter> {
std::vector<void*>* pointer_buffer() { return parser_->pointer_buffer(); } std::vector<void*>* pointer_buffer() { return parser_->pointer_buffer(); }
Zone* zone() const { return parser_->zone(); } Zone* zone() const { return parser_->zone(); }
Scope* scope() const { return scope_; } Scope* scope() const { return parser_->scope(); }
Scope* const scope_;
Parser* const parser_; Parser* const parser_;
Block* block_; Block* block_;
const DeclarationDescriptor* descriptor_; const DeclarationDescriptor* descriptor_;
...@@ -143,16 +140,15 @@ void Parser::DeclareAndInitializeVariables( ...@@ -143,16 +140,15 @@ void Parser::DeclareAndInitializeVariables(
void Parser::RewriteDestructuringAssignment(RewritableExpression* to_rewrite) { void Parser::RewriteDestructuringAssignment(RewritableExpression* to_rewrite) {
DCHECK(!to_rewrite->is_rewritten()); DCHECK(!to_rewrite->is_rewritten());
Assignment* assignment = to_rewrite->expression()->AsAssignment(); Assignment* assignment = to_rewrite->expression()->AsAssignment();
Expression* result = PatternRewriter::RewriteDestructuringAssignment( Expression* result =
this, assignment, scope()); PatternRewriter::RewriteDestructuringAssignment(this, assignment);
to_rewrite->Rewrite(result); to_rewrite->Rewrite(result);
} }
Expression* Parser::RewriteDestructuringAssignment(Assignment* assignment) { Expression* Parser::RewriteDestructuringAssignment(Assignment* assignment) {
DCHECK_NOT_NULL(assignment); DCHECK_NOT_NULL(assignment);
DCHECK_EQ(Token::ASSIGN, assignment->op()); DCHECK_EQ(Token::ASSIGN, assignment->op());
return PatternRewriter::RewriteDestructuringAssignment(this, assignment, return PatternRewriter::RewriteDestructuringAssignment(this, assignment);
scope());
} }
void PatternRewriter::DeclareAndInitializeVariables( void PatternRewriter::DeclareAndInitializeVariables(
...@@ -162,13 +158,12 @@ void PatternRewriter::DeclareAndInitializeVariables( ...@@ -162,13 +158,12 @@ void PatternRewriter::DeclareAndInitializeVariables(
ZonePtrList<const AstRawString>* names) { ZonePtrList<const AstRawString>* names) {
DCHECK(block->ignore_completion_value()); DCHECK(block->ignore_completion_value());
Scope* scope = declaration_descriptor->scope; PatternRewriter rewriter(parser, BINDING, declaration_descriptor, names,
PatternRewriter rewriter(scope, parser, BINDING, declaration_descriptor, declaration->initializer_position,
names, declaration->initializer_position,
declaration->value_beg_position, declaration->value_beg_position,
declaration_descriptor->declaration_kind == declaration_descriptor->declaration_kind ==
DeclarationDescriptor::PARAMETER && DeclarationDescriptor::PARAMETER &&
scope->is_block_scope()); parser->scope()->is_block_scope());
rewriter.block_ = block; rewriter.block_ = block;
rewriter.RecurseIntoSubpattern(declaration->pattern, rewriter.RecurseIntoSubpattern(declaration->pattern,
...@@ -176,10 +171,10 @@ void PatternRewriter::DeclareAndInitializeVariables( ...@@ -176,10 +171,10 @@ void PatternRewriter::DeclareAndInitializeVariables(
} }
Expression* PatternRewriter::RewriteDestructuringAssignment( Expression* PatternRewriter::RewriteDestructuringAssignment(
Parser* parser, Assignment* to_rewrite, Scope* scope) { Parser* parser, Assignment* to_rewrite) {
DCHECK(!scope->HasBeenRemoved()); DCHECK(!parser->scope()->HasBeenRemoved());
PatternRewriter rewriter(scope, parser, ASSIGNMENT); PatternRewriter rewriter(parser, ASSIGNMENT);
return rewriter.Rewrite(to_rewrite); return rewriter.Rewrite(to_rewrite);
} }
...@@ -199,16 +194,11 @@ void PatternRewriter::VisitVariableProxy(VariableProxy* proxy) { ...@@ -199,16 +194,11 @@ void PatternRewriter::VisitVariableProxy(VariableProxy* proxy) {
DCHECK_NOT_NULL(block_); DCHECK_NOT_NULL(block_);
DCHECK_NOT_NULL(descriptor_); DCHECK_NOT_NULL(descriptor_);
// scope() isn't guaranteed to be the same as parser_->scope(). scope() is Scope* target_scope = scope();
// where the pattern was parsed, whereas parser_->scope() is where the pattern
// is rewritten into as a declaration.
Scope* target_scope = parser_->scope();
if (declares_parameter_containing_sloppy_eval_) { if (declares_parameter_containing_sloppy_eval_) {
target_scope = scope()->outer_scope(); target_scope = target_scope->outer_scope();
target_scope->DeleteUnresolved(proxy);
} else {
scope()->DeleteUnresolved(proxy);
} }
target_scope->DeleteUnresolved(proxy);
// Declare variable. // Declare variable.
// Note that we *always* must treat the initial value via a separate init // Note that we *always* must treat the initial value via a separate init
...@@ -234,12 +224,11 @@ void PatternRewriter::VisitVariableProxy(VariableProxy* proxy) { ...@@ -234,12 +224,11 @@ void PatternRewriter::VisitVariableProxy(VariableProxy* proxy) {
DCHECK_NE(initializer_position_, kNoSourcePosition); DCHECK_NE(initializer_position_, kNoSourcePosition);
var->set_initializer_position(initializer_position_); var->set_initializer_position(initializer_position_);
Scope* declaration_scope = var->scope(); Scope* declaration_scope = var->scope();
DCHECK_EQ(declaration_scope, DCHECK_EQ(declaration_scope, declares_parameter_containing_sloppy_eval_
declares_parameter_containing_sloppy_eval_ ? scope()->outer_scope()
? scope()->outer_scope() : (IsLexicalVariableMode(descriptor_->mode)
: (IsLexicalVariableMode(descriptor_->mode) ? scope()
? parser_->scope() : scope()->GetDeclarationScope()));
: parser_->scope()->GetDeclarationScope()));
if (declaration_scope->num_var() > kMaxNumFunctionLocals) { if (declaration_scope->num_var() > kMaxNumFunctionLocals) {
parser_->ReportMessage(MessageTemplate::kTooManyVariables); parser_->ReportMessage(MessageTemplate::kTooManyVariables);
return; return;
......
...@@ -434,14 +434,14 @@ void PreParser::DeclareAndInitializeVariables( ...@@ -434,14 +434,14 @@ void PreParser::DeclareAndInitializeVariables(
ZonePtrList<const AstRawString>* names) { ZonePtrList<const AstRawString>* names) {
if (declaration->pattern.variables_ != nullptr) { if (declaration->pattern.variables_ != nullptr) {
for (auto variable : *(declaration->pattern.variables_)) { for (auto variable : *(declaration->pattern.variables_)) {
declaration_descriptor->scope->DeleteUnresolved(variable); scope()->DeleteUnresolved(variable);
Variable* var = scope()->DeclareVariableName( Variable* var = scope()->DeclareVariableName(
variable->raw_name(), declaration_descriptor->mode); variable->raw_name(), declaration_descriptor->mode);
if (var == nullptr) { if (var == nullptr) {
ReportUnidentifiableError(); ReportUnidentifiableError();
return; return;
} }
MarkLoopVariableAsAssigned(declaration_descriptor->scope, var, MarkLoopVariableAsAssigned(scope(), var,
declaration_descriptor->declaration_kind); declaration_descriptor->declaration_kind);
// This is only necessary if there is an initializer, but we don't have // This is only necessary if there is an initializer, but we don't have
// that information here. Consequently, the preparser sometimes says // that information here. Consequently, the preparser sometimes says
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment