提交 aed588de 编写于 作者: H hannesw

8020354: Object literal property initialization is not done in source order

Reviewed-by: sundar, jlaskey
上级 6d47b7d7
......@@ -55,9 +55,9 @@ import static jdk.nashorn.internal.parser.TokenType.WHILE;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import jdk.nashorn.internal.codegen.CompilerConstants;
......@@ -1946,14 +1946,14 @@ loop:
// Object context.
// Prepare to accumulate elements.
// final List<Node> elements = new ArrayList<>();
final Map<String, PropertyNode> map = new LinkedHashMap<>();
final List<PropertyNode> elements = new ArrayList<>();
final Map<String, Integer> map = new HashMap<>();
// Create a block for the object literal.
boolean commaSeen = true;
boolean commaSeen = true;
loop:
while (true) {
switch (type) {
while (true) {
switch (type) {
case RBRACE:
next();
break loop;
......@@ -1975,14 +1975,16 @@ loop:
// Get and add the next property.
final PropertyNode property = propertyAssignment();
final String key = property.getKeyName();
final PropertyNode existingProperty = map.get(key);
final Integer existing = map.get(key);
if (existingProperty == null) {
map.put(key, property);
// elements.add(property);
if (existing == null) {
map.put(key, elements.size());
elements.add(property);
break;
}
final PropertyNode existingProperty = elements.get(existing);
// ECMA section 11.1.5 Object Initialiser
// point # 4 on property assignment production
final Expression value = property.getValue();
......@@ -1993,12 +1995,9 @@ loop:
final FunctionNode prevGetter = existingProperty.getGetter();
final FunctionNode prevSetter = existingProperty.getSetter();
boolean redefinitionOk = true;
// ECMA 11.1.5 strict mode restrictions
if (isStrictMode) {
if (value != null && prevValue != null) {
redefinitionOk = false;
}
if (isStrictMode && value != null && prevValue != null) {
throw error(AbstractParser.message("property.redefinition", key), property.getToken());
}
final boolean isPrevAccessor = prevGetter != null || prevSetter != null;
......@@ -2006,49 +2005,33 @@ loop:
// data property redefined as accessor property
if (prevValue != null && isAccessor) {
redefinitionOk = false;
throw error(AbstractParser.message("property.redefinition", key), property.getToken());
}
// accessor property redefined as data
if (isPrevAccessor && value != null) {
redefinitionOk = false;
throw error(AbstractParser.message("property.redefinition", key), property.getToken());
}
if (isAccessor && isPrevAccessor) {
if (getter != null && prevGetter != null ||
setter != null && prevSetter != null) {
redefinitionOk = false;
setter != null && prevSetter != null) {
throw error(AbstractParser.message("property.redefinition", key), property.getToken());
}
}
if (!redefinitionOk) {
throw error(AbstractParser.message("property.redefinition", key), property.getToken());
}
PropertyNode newProperty = existingProperty;
if (value != null) {
if (prevValue == null) {
map.put(key, newProperty = newProperty.setValue(value));
} else {
final long propertyToken = Token.recast(newProperty.getToken(), COMMARIGHT);
map.put(key, newProperty = newProperty.setValue(new BinaryNode(propertyToken, prevValue, value)));
}
map.put(key, newProperty = newProperty.setGetter(null).setSetter(null));
}
if (getter != null) {
map.put(key, newProperty = newProperty.setGetter(getter));
}
if (setter != null) {
map.put(key, newProperty = newProperty.setSetter(setter));
elements.add(property);
} else if (getter != null) {
elements.set(existing, existingProperty.setGetter(getter));
} else if (setter != null) {
elements.set(existing, existingProperty.setSetter(setter));
}
break;
}
}
return new ObjectNode(objectToken, finish, new ArrayList<>(map.values()));
return new ObjectNode(objectToken, finish, elements);
}
/**
......
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8020354: Object literal property initialization is not done in source order
*
* @test
* @run
*/
var obj = ({a: print(1), b: print(2), a: print(3)});
var obj = ({
a: print(1),
get x() { print("getting x"); return "x" },
set x(v) { print("setting x"); },
b: print(2),
a: print(3)
});
print(obj.x);
obj.x = 4;
1
2
3
1
2
3
getting x
x
setting x
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册