[debugger] step on every assignment in destructuring bind.

R=caitpotter88@gmail.com, littledan@chromium.org

Review URL: https://codereview.chromium.org/1542813003

Cr-Commit-Position: refs/heads/master@{#33009}
This commit is contained in:
yangguo 2015-12-22 05:28:34 -08:00 committed by Commit bot
parent a2cc715bf9
commit b00d9e25bf
3 changed files with 126 additions and 8 deletions

View File

@ -1077,7 +1077,9 @@ class Parser : public ParserBase<ParserTraits> {
void RecurseIntoSubpattern(AstNode* pattern, Expression* value) {
Expression* old_value = current_value_;
current_value_ = value;
recursion_level_++;
pattern->Accept(this);
recursion_level_--;
current_value_ = old_value;
}
@ -1089,6 +1091,7 @@ class Parser : public ParserBase<ParserTraits> {
bool IsAssignmentContext() const { return IsAssignmentContext(context_); }
bool IsAssignmentContext(PatternContext c) const;
bool IsBindingContext(PatternContext c) const;
bool IsSubPattern() const { return recursion_level_ > 1; }
PatternContext SetAssignmentContextIfNeeded(Expression* node);
PatternContext SetInitializerContextIfNeeded(Expression* node);
@ -1110,6 +1113,7 @@ class Parser : public ParserBase<ParserTraits> {
const DeclarationDescriptor* descriptor_;
ZoneList<const AstRawString*>* names_;
Expression* current_value_;
int recursion_level_;
bool* ok_;
};

View File

@ -26,6 +26,7 @@ void Parser::PatternRewriter::DeclareAndInitializeVariables(
rewriter.descriptor_ = declaration_descriptor;
rewriter.names_ = names;
rewriter.ok_ = ok;
rewriter.recursion_level_ = 0;
rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer);
}
@ -46,6 +47,7 @@ void Parser::PatternRewriter::RewriteDestructuringAssignment(
rewriter.descriptor_ = nullptr;
rewriter.names_ = nullptr;
rewriter.ok_ = &ok;
rewriter.recursion_level_ = 0;
rewriter.RecurseIntoSubpattern(rewriter.pattern_, nullptr);
DCHECK(ok);
@ -280,11 +282,12 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
DCHECK_NOT_NULL(proxy);
DCHECK_NOT_NULL(proxy->var());
DCHECK_NOT_NULL(value);
Assignment* assignment = factory()->NewAssignment(
Token::INIT, proxy, value, descriptor_->initialization_pos);
// Add break location for destructured sub-pattern.
int pos = IsSubPattern() ? pattern->position() : RelocInfo::kNoPosition;
Assignment* assignment =
factory()->NewAssignment(Token::INIT, proxy, value, pos);
block_->statements()->Add(
factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
zone());
factory()->NewExpressionStatement(assignment, pos), zone());
value = NULL;
}
@ -296,11 +299,12 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
// if they are inside a 'with' statement - they may change a 'with' object
// property).
VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name);
Assignment* assignment = factory()->NewAssignment(
Token::INIT, proxy, value, descriptor_->initialization_pos);
// Add break location for destructured sub-pattern.
int pos = IsSubPattern() ? pattern->position() : RelocInfo::kNoPosition;
Assignment* assignment =
factory()->NewAssignment(Token::INIT, proxy, value, pos);
block_->statements()->Add(
factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
zone());
factory()->NewExpressionStatement(assignment, pos), zone());
}
}

View File

@ -0,0 +1,110 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-debug-as debug --harmony-destructuring-bind
var exception = null;
var Debug = debug.Debug;
var break_count = 0;
function listener(event, exec_state, event_data, data) {
if (event != Debug.DebugEvent.Break) return;
try {
var source = exec_state.frame(0).sourceLineText();
print(source, break_count);
assertTrue(source.indexOf(`B${break_count++}`) > 0);
if (source.indexOf("assertEquals") > 0) {
exec_state.prepareStep(Debug.StepAction.StepNext);
} else {
exec_state.prepareStep(Debug.StepAction.StepIn);
}
} catch (e) {
exception = e;
print(e);
}
};
Debug.setListener(listener);
var id = x => x; // B9 B10 B36 B37
function test() {
debugger; // B0
function fx1([
a, // B2
b // B3
]) {
assertEquals([1, 2], [a, b]); // B4
} // B5
fx1([1, 2, 3]); // B1
function f2([
a, // B7
b = id(3) // B8
]) {
assertEquals([4, 3], [a, b]); // B11
} // B12
f2([4]); // B6
function f3({
x: a, // B14
y: b // B15
}) {
assertEquals([5, 6], [a, b]); // B16
} // B17
f3({y: 6, x: 5}); // B13
function f4([
a, // B19
{
b, // B20
c, // B21
}
]) {
assertEquals([2, 4, 6], [a, b, c]); // B22
} // B23
f4([2, {c: 6, b: 4}]); // B18
function f5([
{
a, // B25
b = 7 // B26
},
c = 3 // B27
] = [{a:1}]) {
assertEquals([1, 7, 3], [a, b, c]); // B28
} // B29
f5(); // B24
var name = "x"; // B30
function f6({
[id(name)]: a, // B34 B35
b = a // B38
}) {
assertEquals([9, 9], [a, b]); // B39
} // B40
var o6 = {}; // B31
o6[name] = 9; // B32
f6(o6); // B33
try {
throw [3, 4]; // B41
} catch ([
a, // B42
b, // B43
c = 6 // B44
]) {
assertEquals([3, 4, 6], [a, b, c]); // B45
}
var { // B46
x: a, // B47
y: b = 9 // B48
} = { x: 4 };
assertEquals([4, 9], [a, b]); // B49
} // B50
test();
Debug.setListener(null); // B51
assertNull(exception);