Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
327ef678
D
dragonwell11
项目概览
openanolis
/
dragonwell11
通知
7
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell11
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
327ef678
编写于
5月 23, 2013
作者:
A
attila
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8015267: Allow conversion of JS arrays to Java List/Deque
Reviewed-by: lagergren, sundar
上级
e1cacfed
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
526 addition
and
37 deletion
+526
-37
nashorn/make/build.xml
nashorn/make/build.xml
+1
-15
nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
+26
-19
nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java
nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java
+337
-0
nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java
...src/jdk/nashorn/internal/runtime/linker/InvokeByName.java
+12
-2
nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
...dk/nashorn/internal/runtime/resources/Messages.properties
+1
-1
nashorn/test/script/basic/JDK-8015267.js
nashorn/test/script/basic/JDK-8015267.js
+109
-0
nashorn/test/script/basic/JDK-8015267.js.EXPECTED
nashorn/test/script/basic/JDK-8015267.js.EXPECTED
+40
-0
未找到文件。
nashorn/make/build.xml
浏览文件 @
327ef678
...
...
@@ -42,8 +42,6 @@
<condition
property=
"hg.executable"
value=
"/usr/local/bin/hg"
else=
"hg"
>
<available
file=
"/usr/local/bin/hg"
/>
</condition>
<!-- check if JDK already has ASM classes -->
<available
property=
"asm.available"
classname=
"jdk.internal.org.objectweb.asm.Type"
/>
<!-- check if testng.jar is avaiable -->
<available
property=
"testng.available"
file=
"${file.reference.testng.jar}"
/>
...
...
@@ -80,19 +78,7 @@
<delete
dir=
"${dist.dir}"
/>
</target>
<!-- do it only if ASM is not available -->
<target
name=
"compile-asm"
depends=
"prepare"
unless=
"asm.available"
>
<javac
srcdir=
"${jdk.asm.src.dir}"
destdir=
"${build.classes.dir}"
excludes=
"**/optimizer/* **/xml/* **/attrs/*"
source=
"${javac.source}"
target=
"${javac.target}"
debug=
"${javac.debug}"
encoding=
"${javac.encoding}"
includeantruntime=
"false"
/>
</target>
<target
name=
"compile"
depends=
"compile-asm"
description=
"Compiles nashorn"
>
<target
name=
"compile"
depends=
"prepare"
description=
"Compiles nashorn"
>
<javac
srcdir=
"${src.dir}"
destdir=
"${build.classes.dir}"
classpath=
"${javac.classpath}"
...
...
nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
浏览文件 @
327ef678
...
...
@@ -30,6 +30,8 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
import
java.lang.reflect.Array
;
import
java.util.Collection
;
import
java.util.Deque
;
import
java.util.List
;
import
jdk.internal.dynalink.beans.StaticClass
;
import
jdk.internal.dynalink.support.TypeUtilities
;
import
jdk.nashorn.internal.objects.annotations.Attribute
;
...
...
@@ -37,6 +39,7 @@ import jdk.nashorn.internal.objects.annotations.Function;
import
jdk.nashorn.internal.objects.annotations.ScriptClass
;
import
jdk.nashorn.internal.objects.annotations.Where
;
import
jdk.nashorn.internal.runtime.JSType
;
import
jdk.nashorn.internal.runtime.ListAdapter
;
import
jdk.nashorn.internal.runtime.ScriptObject
;
import
jdk.nashorn.internal.runtime.linker.JavaAdapterFactory
;
...
...
@@ -240,8 +243,8 @@ public final class NativeJava {
}
/**
* Given a script object and a Java type, converts the script object into the desired Java type. Currently it
only
* performs shallow creation of Java arrays,
but might be extended for other types in the future
. Example:
* Given a script object and a Java type, converts the script object into the desired Java type. Currently it
* performs shallow creation of Java arrays,
as well as wrapping of objects in Lists and Dequeues
. Example:
* <pre>
* var anArray = [1, "13", false]
* var javaIntArray = Java.to(anArray, "int[]")
...
...
@@ -250,42 +253,46 @@ public final class NativeJava {
* print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
* </pre>
* @param self not used
* @param obj
Array
the script object. Can be null.
* @param obj the script object. Can be null.
* @param objType either a {@link #type(Object, Object) type object} or a String describing the type of the Java
* object to create. Can not be null. If undefined, a "default" conversion is presumed (allowing the argument to be
* omitted).
* @return a Java object whose value corresponds to the original script object's value. Specifically, for array
* target types, returns a Java array of the same type with contents converted to the array's component type. Does
* not recursively convert for multidimensional arrays.
*
type. Returns null if scriptObject
is null.
* not recursively convert for multidimensional arrays.
For {@link List} or {@link Deque}, returns a live wrapper
*
around the object, see {@link ListAdapter} for details. Returns null if obj
is null.
* @throws ClassNotFoundException if the class described by objType is not found
*/
@Function
(
attributes
=
Attribute
.
NOT_ENUMERABLE
,
where
=
Where
.
CONSTRUCTOR
)
public
static
Object
to
(
final
Object
self
,
final
Object
obj
Array
,
final
Object
objType
)
throws
ClassNotFoundException
{
if
(
obj
Array
==
null
)
{
public
static
Object
to
(
final
Object
self
,
final
Object
obj
,
final
Object
objType
)
throws
ClassNotFoundException
{
if
(
obj
==
null
)
{
return
null
;
}
final
Class
<?>
componentType
;
Global
.
checkObject
(
obj
);
final
Class
<?>
targetClass
;
if
(
objType
==
UNDEFINED
)
{
componentType
=
Object
.
class
;
targetClass
=
Object
[]
.
class
;
}
else
{
final
StaticClass
array
Type
;
final
StaticClass
target
Type
;
if
(
objType
instanceof
StaticClass
)
{
array
Type
=
(
StaticClass
)
objType
;
target
Type
=
(
StaticClass
)
objType
;
}
else
{
arrayType
=
type
(
objType
);
}
final
Class
<?>
arrayClass
=
arrayType
.
getRepresentedClass
();
if
(!
arrayClass
.
isArray
())
{
throw
typeError
(
"to.expects.array.type"
,
arrayClass
.
getName
());
targetType
=
type
(
objType
);
}
componentType
=
arrayClass
.
getComponentType
();
targetClass
=
targetType
.
getRepresentedClass
();
}
Global
.
checkObject
(
objArray
);
if
(
targetClass
.
isArray
())
{
return
((
ScriptObject
)
obj
).
getArray
().
asArrayOfType
(
targetClass
.
getComponentType
());
}
if
(
targetClass
==
List
.
class
||
targetClass
==
Deque
.
class
)
{
return
new
ListAdapter
((
ScriptObject
)
obj
);
}
return
((
ScriptObject
)
objArray
).
getArray
().
asArrayOfType
(
componentType
);
throw
typeError
(
"unsupported.java.to.type"
,
targetClass
.
getName
()
);
}
/**
...
...
nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java
0 → 100644
浏览文件 @
327ef678
package
jdk.nashorn.internal.runtime
;
import
java.util.AbstractList
;
import
java.util.Deque
;
import
java.util.Iterator
;
import
java.util.ListIterator
;
import
java.util.NoSuchElementException
;
import
java.util.RandomAccess
;
import
jdk.nashorn.internal.runtime.linker.InvokeByName
;
/**
* An adapter that can wrap any ECMAScript Array-like object (that adheres to the array rules for the property
* {@code length} and having conforming {@code push}, {@code pop}, {@code shift}, {@code unshift}, and {@code splice}
* methods) and expose it as both a Java list and double-ended queue. While script arrays aren't necessarily efficient
* as dequeues, it's still slightly more efficient to be able to translate dequeue operations into pushes, pops, shifts,
* and unshifts, than to blindly translate all list's add/remove operations into splices. Also, it is conceivable that a
* custom script object that implements an Array-like API can have a background data representation that is optimized
* for dequeue-like access. Note that with ECMAScript arrays, {@code push} and {@pop} operate at the end of the array,
* while in Java {@code Deque} they operate on the front of the queue and as such the Java dequeue {@link #push(Object)}
* and {@link #pop()} operations will translate to {@code unshift} and {@code shift} script operations respectively,
* while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and {@code pop}.
*/
public
class
ListAdapter
extends
AbstractList
<
Object
>
implements
RandomAccess
,
Deque
<
Object
>
{
// These add to the back and front of the list
private
static
final
InvokeByName
PUSH
=
new
InvokeByName
(
"push"
,
ScriptObject
.
class
,
void
.
class
,
Object
.
class
);
private
static
final
InvokeByName
UNSHIFT
=
new
InvokeByName
(
"unshift"
,
ScriptObject
.
class
,
void
.
class
,
Object
.
class
);
// These remove from the back and front of the list
private
static
final
InvokeByName
POP
=
new
InvokeByName
(
"pop"
,
ScriptObject
.
class
,
Object
.
class
);
private
static
final
InvokeByName
SHIFT
=
new
InvokeByName
(
"shift"
,
ScriptObject
.
class
,
Object
.
class
);
// These insert and remove in the middle of the list
private
static
final
InvokeByName
SPLICE_ADD
=
new
InvokeByName
(
"splice"
,
ScriptObject
.
class
,
void
.
class
,
int
.
class
,
int
.
class
,
Object
.
class
);
private
static
final
InvokeByName
SPLICE_REMOVE
=
new
InvokeByName
(
"splice"
,
ScriptObject
.
class
,
void
.
class
,
int
.
class
,
int
.
class
);
private
final
ScriptObject
obj
;
/**
* Creates a new list wrapper for the specified script object.
* @param obj script the object to wrap
*/
public
ListAdapter
(
ScriptObject
obj
)
{
this
.
obj
=
obj
;
}
@Override
public
int
size
()
{
return
JSType
.
toInt32
(
obj
.
getLength
());
}
@Override
public
Object
get
(
int
index
)
{
checkRange
(
index
);
return
obj
.
get
(
index
);
}
@Override
public
Object
set
(
int
index
,
Object
element
)
{
checkRange
(
index
);
final
Object
prevValue
=
get
(
index
);
obj
.
set
(
index
,
element
,
false
);
return
prevValue
;
}
private
void
checkRange
(
int
index
)
{
if
(
index
<
0
||
index
>=
size
())
{
throw
invalidIndex
(
index
);
}
}
@Override
public
void
push
(
Object
e
)
{
addFirst
(
e
);
}
@Override
public
boolean
add
(
Object
e
)
{
addLast
(
e
);
return
true
;
}
@Override
public
void
addFirst
(
Object
e
)
{
try
{
final
Object
fn
=
UNSHIFT
.
getGetter
().
invokeExact
(
obj
);
checkFunction
(
fn
,
UNSHIFT
);
UNSHIFT
.
getInvoker
().
invokeExact
(
fn
,
obj
,
e
);
}
catch
(
RuntimeException
|
Error
ex
)
{
throw
ex
;
}
catch
(
Throwable
t
)
{
throw
new
RuntimeException
(
t
);
}
}
@Override
public
void
addLast
(
Object
e
)
{
try
{
final
Object
fn
=
PUSH
.
getGetter
().
invokeExact
(
obj
);
checkFunction
(
fn
,
PUSH
);
PUSH
.
getInvoker
().
invokeExact
(
fn
,
obj
,
e
);
}
catch
(
RuntimeException
|
Error
ex
)
{
throw
ex
;
}
catch
(
Throwable
t
)
{
throw
new
RuntimeException
(
t
);
}
}
@Override
public
void
add
(
int
index
,
Object
e
)
{
try
{
if
(
index
<
0
)
{
throw
invalidIndex
(
index
);
}
else
if
(
index
==
0
)
{
addFirst
(
e
);
}
else
{
final
int
size
=
size
();
if
(
index
<
size
)
{
final
Object
fn
=
SPLICE_ADD
.
getGetter
().
invokeExact
(
obj
);
checkFunction
(
fn
,
SPLICE_ADD
);
SPLICE_ADD
.
getInvoker
().
invokeExact
(
fn
,
obj
,
index
,
0
,
e
);
}
else
if
(
index
==
size
)
{
addLast
(
e
);
}
else
{
throw
invalidIndex
(
index
);
}
}
}
catch
(
RuntimeException
|
Error
ex
)
{
throw
ex
;
}
catch
(
Throwable
t
)
{
throw
new
RuntimeException
(
t
);
}
}
private
static
void
checkFunction
(
Object
fn
,
InvokeByName
invoke
)
{
if
(!(
fn
instanceof
ScriptFunction
))
{
throw
new
UnsupportedOperationException
(
"The script object doesn't have a function named "
+
invoke
.
getName
());
}
}
private
static
IndexOutOfBoundsException
invalidIndex
(
int
index
)
{
return
new
IndexOutOfBoundsException
(
String
.
valueOf
(
index
));
}
@Override
public
boolean
offer
(
Object
e
)
{
return
offerLast
(
e
);
}
@Override
public
boolean
offerFirst
(
Object
e
)
{
addFirst
(
e
);
return
true
;
}
@Override
public
boolean
offerLast
(
Object
e
)
{
addLast
(
e
);
return
true
;
}
@Override
public
Object
pop
()
{
return
removeFirst
();
}
@Override
public
Object
remove
()
{
return
removeFirst
();
}
@Override
public
Object
removeFirst
()
{
checkNonEmpty
();
return
invokeShift
();
}
@Override
public
Object
removeLast
()
{
checkNonEmpty
();
return
invokePop
();
}
private
void
checkNonEmpty
()
{
if
(
isEmpty
())
{
throw
new
NoSuchElementException
();
}
}
@Override
public
Object
remove
(
int
index
)
{
if
(
index
<
0
)
{
throw
invalidIndex
(
index
);
}
else
if
(
index
==
0
)
{
return
invokeShift
();
}
else
{
final
int
maxIndex
=
size
()
-
1
;
if
(
index
<
maxIndex
)
{
final
Object
prevValue
=
get
(
index
);
invokeSpliceRemove
(
index
,
1
);
return
prevValue
;
}
else
if
(
index
==
maxIndex
)
{
return
invokePop
();
}
else
{
throw
invalidIndex
(
index
);
}
}
}
private
Object
invokeShift
()
{
try
{
final
Object
fn
=
SHIFT
.
getGetter
().
invokeExact
(
obj
);
checkFunction
(
fn
,
SHIFT
);
return
SHIFT
.
getInvoker
().
invokeExact
(
fn
,
obj
);
}
catch
(
RuntimeException
|
Error
ex
)
{
throw
ex
;
}
catch
(
Throwable
t
)
{
throw
new
RuntimeException
(
t
);
}
}
private
Object
invokePop
()
{
try
{
final
Object
fn
=
POP
.
getGetter
().
invokeExact
(
obj
);
checkFunction
(
fn
,
POP
);
return
POP
.
getInvoker
().
invokeExact
(
fn
,
obj
);
}
catch
(
RuntimeException
|
Error
ex
)
{
throw
ex
;
}
catch
(
Throwable
t
)
{
throw
new
RuntimeException
(
t
);
}
}
@Override
protected
void
removeRange
(
int
fromIndex
,
int
toIndex
)
{
invokeSpliceRemove
(
fromIndex
,
toIndex
-
fromIndex
);
}
private
void
invokeSpliceRemove
(
int
fromIndex
,
int
count
)
{
try
{
final
Object
fn
=
SPLICE_REMOVE
.
getGetter
().
invokeExact
(
obj
);
checkFunction
(
fn
,
SPLICE_REMOVE
);
SPLICE_REMOVE
.
getInvoker
().
invokeExact
(
fn
,
obj
,
fromIndex
,
count
);
}
catch
(
RuntimeException
|
Error
ex
)
{
throw
ex
;
}
catch
(
Throwable
t
)
{
throw
new
RuntimeException
(
t
);
}
}
@Override
public
Object
poll
()
{
return
pollFirst
();
}
@Override
public
Object
pollFirst
()
{
return
isEmpty
()
?
null
:
invokeShift
();
}
@Override
public
Object
pollLast
()
{
return
isEmpty
()
?
null
:
invokePop
();
}
@Override
public
Object
peek
()
{
return
peekFirst
();
}
@Override
public
Object
peekFirst
()
{
return
isEmpty
()
?
null
:
get
(
0
);
}
@Override
public
Object
peekLast
()
{
return
isEmpty
()
?
null
:
get
(
size
()
-
1
);
}
@Override
public
Object
element
()
{
return
getFirst
();
}
@Override
public
Object
getFirst
()
{
checkNonEmpty
();
return
get
(
0
);
}
@Override
public
Object
getLast
()
{
checkNonEmpty
();
return
get
(
size
()
-
1
);
}
@Override
public
Iterator
<
Object
>
descendingIterator
()
{
final
ListIterator
<
Object
>
it
=
listIterator
(
size
());
return
new
Iterator
<
Object
>()
{
@Override
public
boolean
hasNext
()
{
return
it
.
hasPrevious
();
}
@Override
public
Object
next
()
{
return
it
.
previous
();
}
@Override
public
void
remove
()
{
it
.
remove
();
}
};
}
@Override
public
boolean
removeFirstOccurrence
(
Object
o
)
{
return
removeOccurrence
(
o
,
iterator
());
}
@Override
public
boolean
removeLastOccurrence
(
Object
o
)
{
return
removeOccurrence
(
o
,
descendingIterator
());
}
private
static
boolean
removeOccurrence
(
Object
o
,
Iterator
<
Object
>
it
)
{
while
(
it
.
hasNext
())
{
final
Object
e
=
it
.
next
();
if
(
o
==
null
?
e
==
null
:
o
.
equals
(
e
))
{
it
.
remove
();
return
true
;
}
}
return
false
;
}
}
nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java
浏览文件 @
327ef678
...
...
@@ -40,7 +40,7 @@ import java.lang.invoke.MethodHandle;
* private static final InvokeByName TO_JSON = new InvokeByName("toJSON", Object.class, Object.class, Object.class);
* ...
* final Object toJSONFn = TO_JSON.getGetter().invokeExact(obj);
* value = TO_JSON.getInvoker().invokeExact(toJSON, obj, key);
* value = TO_JSON.getInvoker().invokeExact(toJSON
Fn
, obj, key);
* </pre>
* In practice, you can have stronger type assumptions if it makes sense for your code, just remember that you must use
* the same parameter types as the formal types of the arguments for {@code invokeExact} to work:
...
...
@@ -50,7 +50,7 @@ import java.lang.invoke.MethodHandle;
* final ScriptObject sobj = (ScriptObject)obj;
* final Object toJSONFn = TO_JSON.getGetter().invokeExact(sobj);
* if(toJSONFn instanceof ScriptFunction) {
* value = TO_JSON.getInvoker().invokeExact(toJSON, sobj, key);
* value = TO_JSON.getInvoker().invokeExact(toJSON
Fn
, sobj, key);
* }
* </pre>
* Note that in general you will not want to reuse a single instance of this class for implementing more than one call
...
...
@@ -59,6 +59,7 @@ import java.lang.invoke.MethodHandle;
* separate instance of this class for every place.
*/
public
class
InvokeByName
{
private
final
String
name
;
private
final
MethodHandle
getter
;
private
final
MethodHandle
invoker
;
...
...
@@ -81,6 +82,7 @@ public class InvokeByName {
* @param ptypes the parameter types of the function.
*/
public
InvokeByName
(
final
String
name
,
final
Class
<?>
targetClass
,
final
Class
<?>
rtype
,
final
Class
<?>...
ptypes
)
{
this
.
name
=
name
;
getter
=
Bootstrap
.
createDynamicInvoker
(
"dyn:getMethod|getProp|getItem:"
+
name
,
Object
.
class
,
targetClass
);
final
Class
<?>[]
finalPtypes
;
...
...
@@ -96,6 +98,14 @@ public class InvokeByName {
invoker
=
Bootstrap
.
createDynamicInvoker
(
"dyn:call"
,
rtype
,
finalPtypes
);
}
/**
* Returns the name of the function retrieved through this invoker.
* @return the name of the function retrieved through this invoker.
*/
public
String
getName
()
{
return
name
;
}
/**
* Returns the property getter that can be invoked on an object to retrieve the function object that will be
* subsequently invoked by the invoker returned by {@link #getInvoker()}.
...
...
nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
浏览文件 @
327ef678
...
...
@@ -125,7 +125,7 @@ type.error.no.constructor.matches.args=Can not construct {0} with the passed arg
type.error.no.method.matches.args
=
Can not invoke method {0} with the passed arguments; they do not match any of its method signatures.
type.error.method.not.constructor
=
Java method {0} can't be used as a constructor.
type.error.env.not.object
=
$ENV must be an Object.
type.error.
to.expects.array.type
=
Java.to() expects an array target type. {0} is not an array type
.
type.error.
unsupported.java.to.type
=
Unsupported Java.to target type {0}
.
range.error.inappropriate.array.length
=
inappropriate array length: {0}
range.error.invalid.fraction.digits
=
fractionDigits argument to {0} must be in [0, 20]
range.error.invalid.precision
=
precision argument toPrecision() must be in [1, 21]
...
...
nashorn/test/script/basic/JDK-8015267.js
0 → 100644
浏览文件 @
327ef678
/*
* 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-8015267: have a List/Deque adapter for JS array-like objects
*
* @test
* @run
*/
var
a
=
[
'
a
'
,
'
b
'
,
'
c
'
,
'
d
'
]
var
l
=
Java
.
to
(
a
,
java
.
util
.
List
)
print
(
l
instanceof
java
.
util
.
List
)
print
(
l
instanceof
java
.
util
.
Deque
)
print
(
l
[
0
])
print
(
l
[
1
])
print
(
l
[
2
])
print
(
l
[
3
])
print
(
l
.
size
())
l
.
push
(
'
x
'
)
print
(
a
)
l
.
addLast
(
'
y
'
)
print
(
a
)
print
(
l
.
pop
())
print
(
l
.
removeLast
())
print
(
a
)
l
.
add
(
'
e
'
)
l
.
add
(
5
,
'
f
'
)
print
(
a
)
l
.
add
(
0
,
'
z
'
)
print
(
a
)
l
.
add
(
2
,
'
x
'
)
print
(
a
)
l
[
7
]
=
'
g
'
print
(
a
)
try
{
l
.
add
(
15
,
''
)
}
catch
(
e
)
{
print
(
e
.
class
)
}
try
{
l
.
remove
(
15
)
}
catch
(
e
)
{
print
(
e
.
class
)
}
try
{
l
.
add
(
-
1
,
''
)
}
catch
(
e
)
{
print
(
e
.
class
)
}
try
{
l
.
remove
(
-
1
)
}
catch
(
e
)
{
print
(
e
.
class
)
}
l
.
remove
(
7
)
l
.
remove
(
2
)
l
.
remove
(
0
)
print
(
a
)
print
(
l
.
peek
())
print
(
l
.
peekFirst
())
print
(
l
.
peekLast
())
print
(
l
.
element
())
print
(
l
.
getFirst
())
print
(
l
.
getLast
())
l
.
offer
(
'
1
'
)
l
.
offerFirst
(
'
2
'
)
l
.
offerLast
(
'
3
'
)
print
(
a
)
a
=
[
'
1
'
,
'
2
'
,
'
x
'
,
'
3
'
,
'
4
'
,
'
x
'
,
'
5
'
,
'
6
'
,
'
x
'
,
'
7
'
,
'
8
'
]
print
(
a
)
var
l
=
Java
.
to
(
a
,
java
.
util
.
List
)
l
.
removeFirstOccurrence
(
'
x
'
)
print
(
a
)
l
.
removeLastOccurrence
(
'
x
'
)
print
(
a
)
var
empty
=
Java
.
to
([],
java
.
util
.
List
)
try
{
empty
.
pop
()
}
catch
(
e
)
{
print
(
e
.
class
)
}
try
{
empty
.
removeFirst
()
}
catch
(
e
)
{
print
(
e
.
class
)
}
try
{
empty
.
removeLast
()
}
catch
(
e
)
{
print
(
e
.
class
)
}
try
{
empty
.
element
()
}
catch
(
e
)
{
print
(
e
.
class
)
}
try
{
empty
.
getFirst
()
}
catch
(
e
)
{
print
(
e
.
class
)
}
try
{
empty
.
getLast
()
}
catch
(
e
)
{
print
(
e
.
class
)
}
print
(
empty
.
peek
())
print
(
empty
.
peekFirst
())
print
(
empty
.
peekLast
())
nashorn/test/script/basic/JDK-8015267.js.EXPECTED
0 → 100644
浏览文件 @
327ef678
true
true
a
b
c
d
4
x,a,b,c,d
x,a,b,c,d,y
x
y
a,b,c,d
a,b,c,d,e,f
z,a,b,c,d,e,f
z,a,x,b,c,d,e,f
z,a,x,b,c,d,e,g
class java.lang.IndexOutOfBoundsException
class java.lang.IndexOutOfBoundsException
class java.lang.IndexOutOfBoundsException
class java.lang.IndexOutOfBoundsException
a,b,c,d,e
a
a
e
a
a
e
2,a,b,c,d,e,1,3
1,2,x,3,4,x,5,6,x,7,8
1,2,3,4,x,5,6,x,7,8
1,2,3,4,x,5,6,7,8
class java.util.NoSuchElementException
class java.util.NoSuchElementException
class java.util.NoSuchElementException
class java.util.NoSuchElementException
class java.util.NoSuchElementException
class java.util.NoSuchElementException
null
null
null
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录