[destructuring] Support computed property names in patterns.

R=arv@chromium.org,rossberg@chromium.org
BUG=v8:811
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#28487}
This commit is contained in:
dslomov 2015-05-19 09:27:21 -07:00 committed by Commit bot
parent 7bd2d3e32e
commit 3199077791
4 changed files with 110 additions and 8 deletions

View File

@ -224,13 +224,11 @@ Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) {
auto temp = CreateTempVar(current_value_);
if (pattern->properties()->length() == 0) {
block_->AddStatement(descriptor_->parser->BuildAssertIsCoercible(temp),
zone());
}
block_->AddStatement(descriptor_->parser->BuildAssertIsCoercible(temp),
zone());
for (ObjectLiteralProperty* property : *pattern->properties()) {
// TODO(dslomov): computed property names.
RecurseIntoSubpattern(
property->value(),
factory()->NewProperty(factory()->NewVariableProxy(temp),

View File

@ -2555,8 +2555,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
if (allow_harmony_computed_property_names_) {
*is_computed_name = true;
Consume(Token::LBRACK);
ExpressionT expression =
ParseAssignmentExpression(true, classifier, CHECK_OK);
ExpressionClassifier computed_name_classifier;
ExpressionT expression = ParseAssignmentExpression(
true, &computed_name_classifier, CHECK_OK);
classifier->AccumulateReclassifyingAsPattern(computed_name_classifier);
Expect(Token::RBRACK, CHECK_OK);
return expression;
}

View File

@ -6356,6 +6356,7 @@ TEST(StrongModeFreeVariablesNotDeclared) {
TEST(DestructuringPositiveTests) {
i::FLAG_harmony_destructuring = true;
i::FLAG_harmony_computed_property_names = true;
const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
{"var ", " = {};"},
@ -6390,10 +6391,14 @@ TEST(DestructuringPositiveTests) {
"{'hi' : x = 42}",
"{var: x}",
"{var: x = 42}",
"{[x] : z}",
"{[1+1] : z}",
"{[foo()] : z}",
"{}",
NULL};
// clang-format on
static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals,
kAllowHarmonyComputedPropertyNames,
kAllowHarmonyDestructuring};
RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
arraysize(always_flags));
@ -6402,7 +6407,9 @@ TEST(DestructuringPositiveTests) {
TEST(DestructuringNegativeTests) {
i::FLAG_harmony_destructuring = true;
i::FLAG_harmony_computed_property_names = true;
static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals,
kAllowHarmonyComputedPropertyNames,
kAllowHarmonyDestructuring};
{ // All modes.
@ -6459,6 +6466,7 @@ TEST(DestructuringNegativeTests) {
"{x : x = (a+)}",
"{x : x += a}",
"{m() {} = 0}",
"{[1+1]}",
NULL};
// clang-format on
RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --harmony-destructuring
// Flags: --harmony-destructuring --harmony-computed-property-names
(function TestObjectLiteralPattern() {
var { x : x, y : y } = { x : 1, y : 2 };
@ -283,6 +283,100 @@
}());
(function TestComputedNames() {
var x = 1;
var {[x]:y} = {1:2};
assertSame(2, y);
(function(){
'use strict';
let {[x]:y} = {1:2};
assertSame(2, y);
}());
var callCount = 0;
function foo(v) { callCount++; return v; }
(function() {
callCount = 0;
var {[foo("abc")]:x} = {abc:42};
assertSame(42, x);
assertEquals(1, callCount);
}());
(function() {
'use strict';
callCount = 0;
let {[foo("abc")]:x} = {abc:42};
assertSame(42, x);
assertEquals(1, callCount);
}());
(function() {
callCount = 0;
var {[foo("abc")]:x} = {};
assertSame(undefined, x);
assertEquals(1, callCount);
}());
(function() {
'use strict';
callCount = 0;
let {[foo("abc")]:x} = {};
assertSame(undefined, x);
assertEquals(1, callCount);
}());
for (val of [null, undefined]) {
callCount = 0;
assertThrows(function() {
var {[foo()]:x} = val;
}, TypeError);
assertEquals(0, callCount);
callCount = 0;
assertThrows(function() {
'use strict';
let {[foo()]:x} = val;
}, TypeError);
assertEquals(0, callCount);
}
var log = [];
var o = {
get x() { log.push("get x"); return 1; },
get y() { log.push("get y"); return 2; }
}
function f(v) { log.push("f " + v); return v; }
(function() {
log = [];
var { [f('x')]:x, [f('y')]:y } = o;
assertSame(1, x);
assertSame(2, y);
assertArrayEquals(["f x", "get x", "f y", "get y"], log);
}());
(function() {
'use strict';
log = [];
let { [f('x')]:x, [f('y')]:y } = o;
assertSame(1, x);
assertSame(2, y);
assertArrayEquals(["f x", "get x", "f y", "get y"], log);
}());
(function() {
'use strict';
log = [];
const { [f('x')]:x, [f('y')]:y } = o;
assertSame(1, x);
assertSame(2, y);
assertArrayEquals(["f x", "get x", "f y", "get y"], log);
}());
}());
(function TestExceptions() {
for (var val of [null, undefined]) {
assertThrows(function() { var {} = val; }, TypeError);