mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-20 15:25:27 +00:00
8020354: Object literal property initialization is not done in source order
Reviewed-by: sundar, jlaskey
This commit is contained in:
parent
e11a9b1d07
commit
40b8f5d48c
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
43
nashorn/test/script/basic/JDK-8020354.js
Normal file
43
nashorn/test/script/basic/JDK-8020354.js
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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;
|
||||
9
nashorn/test/script/basic/JDK-8020354.js.EXPECTED
Normal file
9
nashorn/test/script/basic/JDK-8020354.js.EXPECTED
Normal file
@ -0,0 +1,9 @@
|
||||
1
|
||||
2
|
||||
3
|
||||
1
|
||||
2
|
||||
3
|
||||
getting x
|
||||
x
|
||||
setting x
|
||||
Loading…
x
Reference in New Issue
Block a user