[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:
parent
7bd2d3e32e
commit
3199077791
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user