diff --git a/src/preparser.h b/src/preparser.h index 78f6a269f0..b34b04e152 100644 --- a/src/preparser.h +++ b/src/preparser.h @@ -2027,6 +2027,12 @@ typename ParserBase::ObjectLiteralPropertyT ParserBase< CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); return factory()->NewObjectLiteralProperty(is_get, value, next_pos, is_static); + + } else if (!in_class && allow_harmony_object_literals_ && + Token::IsIdentifier(name_token, strict_mode(), + this->is_generator())) { + value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory()); + } else { Token::Value next = Next(); ReportUnexpectedToken(next); diff --git a/src/token.h b/src/token.h index 9c719b827e..bab925acce 100644 --- a/src/token.h +++ b/src/token.h @@ -6,6 +6,7 @@ #define V8_TOKEN_H_ #include "src/base/logging.h" +#include "src/globals.h" namespace v8 { namespace internal { @@ -187,6 +188,24 @@ class Token { return token_type[tok] == 'K'; } + static bool IsIdentifier(Value tok, StrictMode strict_mode, + bool is_generator) { + switch (tok) { + case IDENTIFIER: + return true; + case FUTURE_STRICT_RESERVED_WORD: + case LET: + case STATIC: + return strict_mode == SLOPPY; + case YIELD: + return !is_generator && strict_mode == SLOPPY; + default: + return false; + } + UNREACHABLE(); + return false; + } + static bool IsAssignmentOp(Value tok) { return INIT_VAR <= tok && tok <= ASSIGN_MOD; } diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index 72f2298042..3556c649f1 100644 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -3969,3 +3969,121 @@ TEST(ClassesAreStrictErrors) { RunParserSyncTest(context_data, class_body_data, kError, NULL, 0, always_flags, arraysize(always_flags)); } + + +TEST(ObjectLiteralPropertyShorthandKeywordsError) { + const char* context_data[][2] = {{"({", "});"}, + {"'use strict'; ({", "});"}, + {NULL, NULL}}; + + const char* name_data[] = { + "break", + "case", + "catch", + "class", + "const", + "continue", + "debugger", + "default", + "delete", + "do", + "else", + "enum", + "export", + "extends", + "false", + "finally", + "for", + "function", + "if", + "import", + "in", + "instanceof", + "new", + "null", + "return", + "super", + "switch", + "this", + "throw", + "true", + "try", + "typeof", + "var", + "void", + "while", + "with", + NULL + }; + + static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals}; + RunParserSyncTest(context_data, name_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); +} + + +TEST(ObjectLiteralPropertyShorthandStrictKeywords) { + const char* context_data[][2] = {{"({", "});"}, + {NULL, NULL}}; + + const char* name_data[] = { + "implements", + "interface", + "let", + "package", + "private", + "protected", + "public", + "static", + "yield", + NULL + }; + + static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals}; + RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0, + always_flags, arraysize(always_flags)); + + const char* context_strict_data[][2] = {{"'use strict'; ({", "});"}, + {NULL, NULL}}; + RunParserSyncTest(context_strict_data, name_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); +} + + +TEST(ObjectLiteralPropertyShorthandError) { + const char* context_data[][2] = {{"({", "});"}, + {"'use strict'; ({", "});"}, + {NULL, NULL}}; + + const char* name_data[] = { + "1", + "1.2", + "0", + "0.1", + "1.0", + "1e1", + "0x1", + "\"s\"", + "'s'", + NULL + }; + + static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals}; + RunParserSyncTest(context_data, name_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); +} + + +TEST(ObjectLiteralPropertyShorthandYieldInGeneratorError) { + const char* context_data[][2] = {{"", ""}, + {NULL, NULL}}; + + const char* name_data[] = { + "function* g() { ({yield}); }", + NULL + }; + + static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals}; + RunParserSyncTest(context_data, name_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); +} diff --git a/test/mjsunit/harmony/object-literals-property-shorthand.js b/test/mjsunit/harmony/object-literals-property-shorthand.js new file mode 100644 index 0000000000..2921495d89 --- /dev/null +++ b/test/mjsunit/harmony/object-literals-property-shorthand.js @@ -0,0 +1,51 @@ +// Copyright 2014 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: --harmony-object-literals + + +(function TestBasics() { + var x = 1; + var object = {x}; + assertEquals(1, object.x); +})(); + + +(function TestDescriptor() { + var x = 1; + var object = {x}; + var descr = Object.getOwnPropertyDescriptor(object, 'x'); + assertEquals(1, descr.value); + assertTrue(descr.enumerable); + assertTrue(descr.writable); + assertTrue(descr.configurable); +})(); + + +(function TestNotDefined() { + 'use strict'; + assertThrows(function() { + return {notDefined}; + }, ReferenceError); +})(); + + +(function TestLet() { + var let = 1; + var object = {let}; + assertEquals(1, object.let); +})(); + + +(function TestYieldInFunction() { + var yield = 1; + var object = {yield}; + assertEquals(1, object.yield); +})(); + + +(function TestToString() { + function f(x) { return {x}; } + assertEquals('function f(x) { return {x}; }', f.toString()); +})();