ES6: Duplicate properties are no longer an error
This removes the duplicate property checker and updates the tests. BUG=v8:3498 LOG=Y R=marja@chromium.org Review URL: https://codereview.chromium.org/459463002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23239 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
930e5ccc3e
commit
cfdfbb885e
@ -496,60 +496,6 @@ class ParserBase : public Traits {
|
||||
ExpressionT expression,
|
||||
Scanner::Location location, const char* message, bool* ok);
|
||||
|
||||
// Used to detect duplicates in object literals. Each of the values
|
||||
// kGetterProperty, kSetterProperty and kValueProperty represents
|
||||
// a type of object literal property. When parsing a property, its
|
||||
// type value is stored in the DuplicateFinder for the property name.
|
||||
// Values are chosen so that having intersection bits means the there is
|
||||
// an incompatibility.
|
||||
// I.e., you can add a getter to a property that already has a setter, since
|
||||
// kGetterProperty and kSetterProperty doesn't intersect, but not if it
|
||||
// already has a getter or a value. Adding the getter to an existing
|
||||
// setter will store the value (kGetterProperty | kSetterProperty), which
|
||||
// is incompatible with adding any further properties.
|
||||
enum PropertyKind {
|
||||
kNone = 0,
|
||||
// Bit patterns representing different object literal property types.
|
||||
kGetterProperty = 1,
|
||||
kSetterProperty = 2,
|
||||
kValueProperty = 7,
|
||||
// Helper constants.
|
||||
kValueFlag = 4
|
||||
};
|
||||
|
||||
// Validation per ECMA 262 - 11.1.5 "Object Initialiser".
|
||||
class ObjectLiteralChecker {
|
||||
public:
|
||||
ObjectLiteralChecker(ParserBase* parser, StrictMode strict_mode)
|
||||
: parser_(parser),
|
||||
finder_(scanner()->unicode_cache()),
|
||||
strict_mode_(strict_mode) { }
|
||||
|
||||
void CheckProperty(Token::Value property, PropertyKind type, bool* ok);
|
||||
|
||||
private:
|
||||
ParserBase* parser() const { return parser_; }
|
||||
Scanner* scanner() const { return parser_->scanner(); }
|
||||
|
||||
// Checks the type of conflict based on values coming from PropertyType.
|
||||
bool HasConflict(PropertyKind type1, PropertyKind type2) {
|
||||
return (type1 & type2) != 0;
|
||||
}
|
||||
bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) {
|
||||
return ((type1 & type2) & kValueFlag) != 0;
|
||||
}
|
||||
bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) {
|
||||
return ((type1 ^ type2) & kValueFlag) != 0;
|
||||
}
|
||||
bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) {
|
||||
return ((type1 | type2) & kValueFlag) == 0;
|
||||
}
|
||||
|
||||
ParserBase* parser_;
|
||||
DuplicateFinder finder_;
|
||||
StrictMode strict_mode_;
|
||||
};
|
||||
|
||||
// If true, the next (and immediately following) function literal is
|
||||
// preceded by a parenthesis.
|
||||
// Heuristically that means that the function will be called immediately,
|
||||
@ -1863,8 +1809,6 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
|
||||
int number_of_boilerplate_properties = 0;
|
||||
bool has_function = false;
|
||||
|
||||
ObjectLiteralChecker checker(this, strict_mode());
|
||||
|
||||
Expect(Token::LBRACE, CHECK_OK);
|
||||
|
||||
while (peek() != Token::RBRACE) {
|
||||
@ -1903,9 +1847,6 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
|
||||
*ok = false;
|
||||
return this->EmptyLiteral();
|
||||
}
|
||||
// Validate the property.
|
||||
PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
|
||||
checker.CheckProperty(next, type, CHECK_OK);
|
||||
IdentifierT name = this->GetSymbol(scanner_);
|
||||
typename Traits::Type::FunctionLiteral value =
|
||||
this->ParseFunctionLiteral(
|
||||
@ -1969,9 +1910,6 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the property
|
||||
checker.CheckProperty(next, kValueProperty, CHECK_OK);
|
||||
|
||||
Expect(Token::COLON, CHECK_OK);
|
||||
ExpressionT value = this->ParseAssignmentExpression(true, CHECK_OK);
|
||||
|
||||
@ -2660,36 +2598,6 @@ ParserBase<Traits>::CheckAndRewriteReferenceExpression(
|
||||
#undef CHECK_OK_CUSTOM
|
||||
|
||||
|
||||
template <typename Traits>
|
||||
void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
|
||||
Token::Value property,
|
||||
PropertyKind type,
|
||||
bool* ok) {
|
||||
int old;
|
||||
if (property == Token::NUMBER) {
|
||||
old = scanner()->FindNumber(&finder_, type);
|
||||
} else {
|
||||
old = scanner()->FindSymbol(&finder_, type);
|
||||
}
|
||||
PropertyKind old_type = static_cast<PropertyKind>(old);
|
||||
if (HasConflict(old_type, type)) {
|
||||
if (IsDataDataConflict(old_type, type)) {
|
||||
// Both are data properties.
|
||||
if (strict_mode_ == SLOPPY) return;
|
||||
parser()->ReportMessage("strict_duplicate_property");
|
||||
} else if (IsDataAccessorConflict(old_type, type)) {
|
||||
// Both a data and an accessor property with the same name.
|
||||
parser()->ReportMessage("accessor_data_property");
|
||||
} else {
|
||||
DCHECK(IsAccessorAccessorConflict(old_type, type));
|
||||
// Both accessors of the same type.
|
||||
parser()->ReportMessage("accessor_get_set");
|
||||
}
|
||||
*ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} } // v8::internal
|
||||
|
||||
#endif // V8_PREPARSER_H
|
||||
|
@ -2486,7 +2486,7 @@ TEST(StrictObjectLiteralChecking) {
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
// These are only errors in strict mode.
|
||||
// ES6 allows duplicate properties even in strict mode.
|
||||
const char* statement_data[] = {
|
||||
"foo: 1, foo: 2",
|
||||
"\"foo\": 1, \"foo\": 2",
|
||||
@ -2499,7 +2499,7 @@ TEST(StrictObjectLiteralChecking) {
|
||||
};
|
||||
|
||||
RunParserSyncTest(non_strict_context_data, statement_data, kSuccess);
|
||||
RunParserSyncTest(strict_context_data, statement_data, kError);
|
||||
RunParserSyncTest(strict_context_data, statement_data, kSuccess);
|
||||
}
|
||||
|
||||
|
||||
@ -2512,23 +2512,6 @@ TEST(ErrorsObjectLiteralChecking) {
|
||||
|
||||
const char* statement_data[] = {
|
||||
",",
|
||||
"foo: 1, get foo() {}",
|
||||
"foo: 1, set foo(v) {}",
|
||||
"\"foo\": 1, get \"foo\"() {}",
|
||||
"\"foo\": 1, set \"foo\"(v) {}",
|
||||
"1: 1, get 1() {}",
|
||||
"1: 1, set 1() {}",
|
||||
// It's counter-intuitive, but these collide too (even in classic
|
||||
// mode). Note that we can have "foo" and foo as properties in classic mode,
|
||||
// but we cannot have "foo" and get foo, or foo and get "foo".
|
||||
"foo: 1, get \"foo\"() {}",
|
||||
"foo: 1, set \"foo\"(v) {}",
|
||||
"\"foo\": 1, get foo() {}",
|
||||
"\"foo\": 1, set foo(v) {}",
|
||||
"1: 1, get \"1\"() {}",
|
||||
"1: 1, set \"1\"() {}",
|
||||
"\"1\": 1, get 1() {}"
|
||||
"\"1\": 1, set 1(v) {}"
|
||||
// Wrong number of parameters
|
||||
"get bar(x) {}",
|
||||
"get bar(x, y) {}",
|
||||
@ -2582,6 +2565,24 @@ TEST(NoErrorsObjectLiteralChecking) {
|
||||
"super: 6",
|
||||
"eval: 7",
|
||||
"arguments: 8",
|
||||
// Duplicate property names are allowed in ES6.
|
||||
"foo: 1, get foo() {}",
|
||||
"foo: 1, set foo(v) {}",
|
||||
"\"foo\": 1, get \"foo\"() {}",
|
||||
"\"foo\": 1, set \"foo\"(v) {}",
|
||||
"1: 1, get 1() {}",
|
||||
"1: 1, set 1(v) {}",
|
||||
// It's counter-intuitive, but these collide too (even in classic
|
||||
// mode). Note that we can have "foo" and foo as properties in classic mode,
|
||||
// but we cannot have "foo" and get foo, or foo and get "foo".
|
||||
"foo: 1, get \"foo\"() {}",
|
||||
"foo: 1, set \"foo\"(v) {}",
|
||||
"\"foo\": 1, get foo() {}",
|
||||
"\"foo\": 1, set foo(v) {}",
|
||||
"1: 1, get \"1\"() {}",
|
||||
"1: 1, set \"1\"(v) {}",
|
||||
"\"1\": 1, get 1() {}",
|
||||
"\"1\": 1, set 1(v) {}",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
33
test/mjsunit/number-literal.js
Normal file
33
test/mjsunit/number-literal.js
Normal file
@ -0,0 +1,33 @@
|
||||
// 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.
|
||||
|
||||
function test(message, a, b, skipStrictMode) {
|
||||
assertSame(eval(a), eval(b), message);
|
||||
if (!skipStrictMode) {
|
||||
(function() {
|
||||
'use strict';
|
||||
assertSame(eval(a), eval(b), message);
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
test('hex-int', '0x20', '32');
|
||||
test('oct-int', '040', '32', true); // Octals disallowed in strict mode.
|
||||
test('dec-int', '32.00', '32');
|
||||
test('dec-underflow-int', '32.00000000000000000000000000000000000000001', '32');
|
||||
test('exp-int', '3.2e1', '32');
|
||||
test('exp-int', '3200e-2', '32');
|
||||
test('overflow-inf', '1e2000', 'Infinity');
|
||||
test('overflow-inf-exact', '1.797693134862315808e+308', 'Infinity');
|
||||
test('non-overflow-inf-exact', '1.797693134862315807e+308',
|
||||
'1.7976931348623157e+308');
|
||||
test('underflow-0', '1e-2000', '0');
|
||||
test('underflow-0-exact', '2.4703282292062E-324', '0');
|
||||
test('non-underflow-0-exact', '2.4703282292063E-324', '5e-324');
|
||||
test('precission-loss-high', '9007199254740992', '9007199254740993');
|
||||
test('precission-loss-low', '1.9999999999999998', '1.9999999999999997');
|
||||
test('non-canonical-literal-int', '1.0', '1');
|
||||
test('non-canonical-literal-frac', '1.50', '1.5');
|
||||
test('rounding-down', '1.12512512512512452', '1.1251251251251244');
|
||||
test('rounding-up', '1.12512512512512453', '1.1251251251251246');
|
@ -166,17 +166,6 @@ assertThrows('\
|
||||
"use strict";\
|
||||
}', SyntaxError);
|
||||
|
||||
// Duplicate data properties.
|
||||
CheckStrictMode("var x = { dupe : 1, nondupe: 3, dupe : 2 };", SyntaxError);
|
||||
CheckStrictMode("var x = { '1234' : 1, '2345' : 2, '1234' : 3 };", SyntaxError);
|
||||
CheckStrictMode("var x = { '1234' : 1, '2345' : 2, 1234 : 3 };", SyntaxError);
|
||||
CheckStrictMode("var x = { 3.14 : 1, 2.71 : 2, 3.14 : 3 };", SyntaxError);
|
||||
CheckStrictMode("var x = { 3.14 : 1, '3.14' : 2 };", SyntaxError);
|
||||
CheckStrictMode("var x = { \
|
||||
123: 1, \
|
||||
123.00000000000000000000000000000000000000000000000000000000000000000001: 2 \
|
||||
}", SyntaxError);
|
||||
|
||||
// Non-conflicting data properties.
|
||||
(function StrictModeNonDuplicate() {
|
||||
"use strict";
|
||||
@ -188,37 +177,52 @@ CheckStrictMode("var x = { \
|
||||
};
|
||||
})();
|
||||
|
||||
// Two getters (non-strict)
|
||||
assertThrows("var x = { get foo() { }, get foo() { } };", SyntaxError);
|
||||
assertThrows("var x = { get foo(){}, get 'foo'(){}};", SyntaxError);
|
||||
assertThrows("var x = { get 12(){}, get '12'(){}};", SyntaxError);
|
||||
// Duplicate properties are no longer errors in ES6.
|
||||
(function Duplicates() {
|
||||
"use strict";
|
||||
|
||||
// Two setters (non-strict)
|
||||
assertThrows("var x = { set foo(v) { }, set foo(v) { } };", SyntaxError);
|
||||
assertThrows("var x = { set foo(v) { }, set 'foo'(v) { } };", SyntaxError);
|
||||
assertThrows("var x = { set 13(v) { }, set '13'(v) { } };", SyntaxError);
|
||||
({ dupe : 1, nondupe: 3, dupe : 2 });
|
||||
({ '1234' : 1, '2345' : 2, '1234' : 3 });
|
||||
({ '1234' : 1, '2345' : 2, 1234 : 3 });
|
||||
({ 3.14 : 1, 2.71 : 2, 3.14 : 3 });
|
||||
({ 3.14 : 1, '3.14' : 2 });
|
||||
({
|
||||
123: 1,
|
||||
123.00000000000000000000000000000000000000000000000000000000000000000001: 2
|
||||
});
|
||||
|
||||
// Setter and data (non-strict)
|
||||
assertThrows("var x = { foo: 'data', set foo(v) { } };", SyntaxError);
|
||||
assertThrows("var x = { set foo(v) { }, foo: 'data' };", SyntaxError);
|
||||
assertThrows("var x = { foo: 'data', set 'foo'(v) { } };", SyntaxError);
|
||||
assertThrows("var x = { set foo(v) { }, 'foo': 'data' };", SyntaxError);
|
||||
assertThrows("var x = { 'foo': 'data', set foo(v) { } };", SyntaxError);
|
||||
assertThrows("var x = { set 'foo'(v) { }, foo: 'data' };", SyntaxError);
|
||||
assertThrows("var x = { 'foo': 'data', set 'foo'(v) { } };", SyntaxError);
|
||||
assertThrows("var x = { set 'foo'(v) { }, 'foo': 'data' };", SyntaxError);
|
||||
assertThrows("var x = { 12: 1, set '12'(v){}};", SyntaxError);
|
||||
assertThrows("var x = { 12: 1, set 12(v){}};", SyntaxError);
|
||||
assertThrows("var x = { '12': 1, set '12'(v){}};", SyntaxError);
|
||||
assertThrows("var x = { '12': 1, set 12(v){}};", SyntaxError);
|
||||
// Two getters
|
||||
({ get foo() { }, get foo() { } });
|
||||
({ get foo(){}, get 'foo'(){}});
|
||||
({ get 12(){}, get '12'(){}});
|
||||
|
||||
// Getter and data (non-strict)
|
||||
assertThrows("var x = { foo: 'data', get foo() { } };", SyntaxError);
|
||||
assertThrows("var x = { get foo() { }, foo: 'data' };", SyntaxError);
|
||||
assertThrows("var x = { 'foo': 'data', get foo() { } };", SyntaxError);
|
||||
assertThrows("var x = { get 'foo'() { }, 'foo': 'data' };", SyntaxError);
|
||||
assertThrows("var x = { '12': 1, get '12'(){}};", SyntaxError);
|
||||
assertThrows("var x = { '12': 1, get 12(){}};", SyntaxError);
|
||||
// Two setters
|
||||
({ set foo(v) { }, set foo(v) { } });
|
||||
({ set foo(v) { }, set 'foo'(v) { } });
|
||||
({ set 13(v) { }, set '13'(v) { } });
|
||||
|
||||
// Setter and data
|
||||
({ foo: 'data', set foo(v) { } });
|
||||
({ set foo(v) { }, foo: 'data' });
|
||||
({ foo: 'data', set 'foo'(v) { } });
|
||||
({ set foo(v) { }, 'foo': 'data' });
|
||||
({ 'foo': 'data', set foo(v) { } });
|
||||
({ set 'foo'(v) { }, foo: 'data' });
|
||||
({ 'foo': 'data', set 'foo'(v) { } });
|
||||
({ set 'foo'(v) { }, 'foo': 'data' });
|
||||
({ 12: 1, set '12'(v){}});
|
||||
({ 12: 1, set 12(v){}});
|
||||
({ '12': 1, set '12'(v){}});
|
||||
({ '12': 1, set 12(v){}});
|
||||
|
||||
// Getter and data
|
||||
({ foo: 'data', get foo() { } });
|
||||
({ get foo() { }, foo: 'data' });
|
||||
({ 'foo': 'data', get foo() { } });
|
||||
({ get 'foo'() { }, 'foo': 'data' });
|
||||
({ '12': 1, get '12'(){}});
|
||||
({ '12': 1, get 12(){}});
|
||||
})();
|
||||
|
||||
// Assignment to eval or arguments
|
||||
CheckStrictMode("function strict() { eval = undefined; }", SyntaxError);
|
||||
|
@ -1,162 +0,0 @@
|
||||
# Copyright 2011 the V8 project authors. All rights reserved.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Tests of duplicate properties in object literals.
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Utility functions to generate a number of tests for each property
|
||||
# name pair.
|
||||
|
||||
def PropertyTest(name, propa, propb, allow_strict = True):
|
||||
replacement = {"id1": propa, "id2": propb, "name": name}
|
||||
|
||||
# Tests same test in both strict and non-strict context.
|
||||
def StrictTest(name, source, replacement, expectation):
|
||||
if (allow_strict):
|
||||
Template("strict-" + name,
|
||||
"\"use strict\";\n" + source)(replacement, expectation)
|
||||
Template(name, source)(replacement, expectation)
|
||||
|
||||
# This one only fails in non-strict context.
|
||||
if (allow_strict):
|
||||
Template("strict-$name-data-data", """
|
||||
"use strict";
|
||||
var o = {$id1: 42, $id2: 42};
|
||||
""")(replacement, "strict_duplicate_property")
|
||||
|
||||
Template("$name-data-data", """
|
||||
var o = {$id1: 42, $id2: 42};
|
||||
""")(replacement, None)
|
||||
|
||||
StrictTest("$name-data-get", """
|
||||
var o = {$id1: 42, get $id2(){}};
|
||||
""", replacement, "accessor_data_property")
|
||||
|
||||
StrictTest("$name-data-set", """
|
||||
var o = {$id1: 42, set $id2(v){}};
|
||||
""", replacement, "accessor_data_property")
|
||||
|
||||
StrictTest("$name-get-data", """
|
||||
var o = {get $id1(){}, $id2: 42};
|
||||
""", replacement, "accessor_data_property")
|
||||
|
||||
StrictTest("$name-set-data", """
|
||||
var o = {set $id1(v){}, $id2: 42};
|
||||
""", replacement, "accessor_data_property")
|
||||
|
||||
StrictTest("$name-get-get", """
|
||||
var o = {get $id1(){}, get $id2(){}};
|
||||
""", replacement, "accessor_get_set")
|
||||
|
||||
StrictTest("$name-set-set", """
|
||||
var o = {set $id1(v){}, set $id2(v){}};
|
||||
""", replacement, "accessor_get_set")
|
||||
|
||||
StrictTest("$name-nested-get", """
|
||||
var o = {get $id1(){}, o: {get $id2(){} } };
|
||||
""", replacement, None)
|
||||
|
||||
StrictTest("$name-nested-set", """
|
||||
var o = {set $id1(v){}, o: {set $id2(v){} } };
|
||||
""", replacement, None)
|
||||
|
||||
|
||||
def TestBothWays(name, propa, propb, allow_strict = True):
|
||||
PropertyTest(name + "-1", propa, propb, allow_strict)
|
||||
PropertyTest(name + "-2", propb, propa, allow_strict)
|
||||
|
||||
def TestSame(name, prop, allow_strict = True):
|
||||
PropertyTest(name, prop, prop, allow_strict)
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
# Simple identifier property
|
||||
TestSame("a", "a")
|
||||
|
||||
# Get/set identifiers
|
||||
TestSame("get-id", "get")
|
||||
TestSame("set-id", "set")
|
||||
|
||||
# Number properties
|
||||
TestSame("0", "0")
|
||||
TestSame("0.1", "0.1")
|
||||
TestSame("1.0", "1.0")
|
||||
TestSame("42.33", "42.33")
|
||||
TestSame("2^32-2", "4294967294")
|
||||
TestSame("2^32", "4294967296")
|
||||
TestSame("2^53", "9007199254740992")
|
||||
TestSame("Hex20", "0x20")
|
||||
TestSame("exp10", "1e10")
|
||||
TestSame("exp20", "1e20")
|
||||
TestSame("Oct40", "040", False);
|
||||
|
||||
|
||||
# String properties
|
||||
TestSame("str-a", '"a"')
|
||||
TestSame("str-0", '"0"')
|
||||
TestSame("str-42", '"42"')
|
||||
TestSame("str-empty", '""')
|
||||
|
||||
# Keywords
|
||||
TestSame("if", "if")
|
||||
TestSame("case", "case")
|
||||
|
||||
# Future reserved keywords
|
||||
TestSame("public", "public")
|
||||
TestSame("class", "class")
|
||||
|
||||
|
||||
# Test that numbers are converted to string correctly.
|
||||
|
||||
TestBothWays("hex-int", "0x20", "32")
|
||||
TestBothWays("oct-int", "040", "32", False) # Octals disallowed in strict mode.
|
||||
TestBothWays("dec-int", "32.00", "32")
|
||||
TestBothWays("dec-underflow-int",
|
||||
"32.00000000000000000000000000000000000000001", "32")
|
||||
TestBothWays("exp-int", "3.2e1", "32")
|
||||
TestBothWays("exp-int", "3200e-2", "32")
|
||||
TestBothWays("overflow-inf", "1e2000", "Infinity")
|
||||
TestBothWays("overflow-inf-exact", "1.797693134862315808e+308", "Infinity")
|
||||
TestBothWays("non-overflow-inf-exact", "1.797693134862315807e+308",
|
||||
"1.7976931348623157e+308")
|
||||
TestBothWays("underflow-0", "1e-2000", "0")
|
||||
TestBothWays("underflow-0-exact", "2.4703282292062E-324", "0")
|
||||
TestBothWays("non-underflow-0-exact", "2.4703282292063E-324", "5e-324")
|
||||
TestBothWays("precission-loss-high", "9007199254740992", "9007199254740993")
|
||||
TestBothWays("precission-loss-low", "1.9999999999999998", "1.9999999999999997")
|
||||
TestBothWays("non-canonical-literal-int", "1.0", "1")
|
||||
TestBothWays("non-canonical-literal-frac", "1.50", "1.5")
|
||||
TestBothWays("rounding-down", "1.12512512512512452", "1.1251251251251244")
|
||||
TestBothWays("rounding-up", "1.12512512512512453", "1.1251251251251246")
|
||||
|
||||
TestBothWays("hex-int-str", "0x20", '"32"')
|
||||
TestBothWays("dec-int-str", "32.00", '"32"')
|
||||
TestBothWays("exp-int-str", "3.2e1", '"32"')
|
||||
TestBothWays("overflow-inf-str", "1e2000", '"Infinity"')
|
||||
TestBothWays("underflow-0-str", "1e-2000", '"0"')
|
||||
TestBothWays("non-canonical-literal-int-str", "1.0", '"1"')
|
||||
TestBothWays("non-canonical-literal-frac-str", "1.50", '"1.5"')
|
@ -26,20 +26,20 @@ Make sure that we correctly identify parse errors in object literals
|
||||
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
|
||||
|
||||
|
||||
PASS ({a:1, get a(){}}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
|
||||
PASS ({a:1, set a(v){}}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
|
||||
PASS ({get a(){}, a:1}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
|
||||
PASS ({set a(v){}, a:1}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
|
||||
PASS ({get a(){}, get a(){}}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
|
||||
PASS ({set a(v){}, set a(v){}}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
|
||||
PASS ({set a(v){}, get a(){}, set a(v){}}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
|
||||
PASS (function(){({a:1, get a(){}})}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
|
||||
PASS (function(){({a:1, set a(v){}})}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
|
||||
PASS (function(){({get a(){}, a:1})}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
|
||||
PASS (function(){({set a(v){}, a:1})}) threw exception SyntaxError: Object literal may not have data and accessor property with the same name.
|
||||
PASS (function(){({get a(){}, get a(){}})}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
|
||||
PASS (function(){({set a(v){}, set a(v){}})}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
|
||||
PASS (function(){({set a(v){}, get a(){}, set a(v){}})}) threw exception SyntaxError: Object literal may not have multiple get/set accessors with the same name.
|
||||
PASS ({a:1, get a(){}}), true is true
|
||||
PASS ({a:1, set a(v){}}), true is true
|
||||
PASS ({get a(){}, a:1}), true is true
|
||||
PASS ({set a(v){}, a:1}), true is true
|
||||
PASS ({get a(){}, get a(){}}), true is true
|
||||
PASS ({set a(v){}, set a(v){}}), true is true
|
||||
PASS ({set a(v){}, get a(){}, set a(v){}}), true is true
|
||||
PASS (function(){({a:1, get a(){}})}), true is true
|
||||
PASS (function(){({a:1, set a(v){}})}), true is true
|
||||
PASS (function(){({get a(){}, a:1})}), true is true
|
||||
PASS (function(){({set a(v){}, a:1})}), true is true
|
||||
PASS (function(){({get a(){}, get a(){}})}), true is true
|
||||
PASS (function(){({set a(v){}, set a(v){}})}), true is true
|
||||
PASS (function(){({set a(v){}, get a(){}, set a(v){}})}), true is true
|
||||
PASS ({a:1, a:1, a:1}), true is true
|
||||
PASS ({get a(){}, set a(v){}}), true is true
|
||||
PASS ({set a(v){}, get a(){}}), true is true
|
||||
@ -48,5 +48,6 @@ PASS (function(){({get a(){}, set a(v){}})}), true is true
|
||||
PASS (function(){({set a(v){}, get a(){}})}), true is true
|
||||
PASS successfullyParsed is true
|
||||
|
||||
|
||||
TEST COMPLETE
|
||||
|
||||
|
@ -23,20 +23,20 @@
|
||||
|
||||
description("Make sure that we correctly identify parse errors in object literals");
|
||||
|
||||
shouldThrow("({a:1, get a(){}})");
|
||||
shouldThrow("({a:1, set a(v){}})");
|
||||
shouldThrow("({get a(){}, a:1})");
|
||||
shouldThrow("({set a(v){}, a:1})");
|
||||
shouldThrow("({get a(){}, get a(){}})");
|
||||
shouldThrow("({set a(v){}, set a(v){}})");
|
||||
shouldThrow("({set a(v){}, get a(){}, set a(v){}})");
|
||||
shouldThrow("(function(){({a:1, get a(){}})})");
|
||||
shouldThrow("(function(){({a:1, set a(v){}})})");
|
||||
shouldThrow("(function(){({get a(){}, a:1})})");
|
||||
shouldThrow("(function(){({set a(v){}, a:1})})");
|
||||
shouldThrow("(function(){({get a(){}, get a(){}})})");
|
||||
shouldThrow("(function(){({set a(v){}, set a(v){}})})");
|
||||
shouldThrow("(function(){({set a(v){}, get a(){}, set a(v){}})})");
|
||||
shouldBeTrue("({a:1, get a(){}}), true");
|
||||
shouldBeTrue("({a:1, set a(v){}}), true");
|
||||
shouldBeTrue("({get a(){}, a:1}), true");
|
||||
shouldBeTrue("({set a(v){}, a:1}), true");
|
||||
shouldBeTrue("({get a(){}, get a(){}}), true");
|
||||
shouldBeTrue("({set a(v){}, set a(v){}}), true");
|
||||
shouldBeTrue("({set a(v){}, get a(){}, set a(v){}}), true");
|
||||
shouldBeTrue("(function(){({a:1, get a(){}})}), true");
|
||||
shouldBeTrue("(function(){({a:1, set a(v){}})}), true");
|
||||
shouldBeTrue("(function(){({get a(){}, a:1})}), true");
|
||||
shouldBeTrue("(function(){({set a(v){}, a:1})}), true");
|
||||
shouldBeTrue("(function(){({get a(){}, get a(){}})}), true");
|
||||
shouldBeTrue("(function(){({set a(v){}, set a(v){}})}), true");
|
||||
shouldBeTrue("(function(){({set a(v){}, get a(){}, set a(v){}})}), true");
|
||||
shouldBeTrue("({a:1, a:1, a:1}), true");
|
||||
shouldBeTrue("({get a(){}, set a(v){}}), true");
|
||||
shouldBeTrue("({set a(v){}, get a(){}}), true");
|
||||
|
Loading…
Reference in New Issue
Block a user