зеркало из https://github.com/mozilla/gecko-dev.git
Add new Context method "toType" to convert to a specified Java type
This commit is contained in:
Родитель
797571ad23
Коммит
9cdc547eaa
|
@ -175,7 +175,7 @@ public class Context {
|
|||
Thread old = cx.currentThread;
|
||||
if (old != null && old != t) {
|
||||
throw new RuntimeException
|
||||
("Can not enter on Context active on another thread");
|
||||
("Cannot enter Context active on another thread");
|
||||
}
|
||||
if (Context.check && old == t && cx != current)
|
||||
Context.codeBug();
|
||||
|
@ -1227,6 +1227,23 @@ public class Context {
|
|||
return ScriptRuntime.toObject(scope, value, staticType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a JavaScript value into the desired type.
|
||||
* Uses the semantics defined with LiveConnect3 and throws an
|
||||
* Illegal argument exception if the conversion cannot be performed.
|
||||
* @param value the JavaScript value to convert
|
||||
* @param desired type the Java type to convert to. Primitive Java
|
||||
* types are represented using the TYPE fields in the corresponding
|
||||
* wrapper class in java.lang.
|
||||
* @return the converted value
|
||||
* @throws IllegalArgumentException if the conversion cannot be performed
|
||||
*/
|
||||
public static Object toType(Object value, Class desiredType)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
return NativeJavaObject.coerceType(desiredType, value, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether debug information is being generated.
|
||||
* @since 1.3
|
||||
|
|
|
@ -66,7 +66,7 @@ public class JavaAdapter extends ScriptableObject {
|
|||
// Avoid an error for an undefined value; return null instead.
|
||||
return null;
|
||||
}
|
||||
return NativeJavaObject.coerceType(c, result);
|
||||
return NativeJavaObject.coerceType(c, result, true);
|
||||
}
|
||||
|
||||
public static Scriptable setAdapterProto(Scriptable obj, Object adapter) {
|
||||
|
|
|
@ -215,8 +215,9 @@ class JavaMembers {
|
|||
if (method == null)
|
||||
throw reportMemberNotFound(name);
|
||||
Class[] types = method.getParameterTypes();
|
||||
Object[] params = { NativeJavaObject.coerceType(types[0], value) };
|
||||
method.invoke(javaObject, params);
|
||||
Object[] args = { NativeJavaObject.coerceType(types[0], value,
|
||||
true) };
|
||||
method.invoke(javaObject, args);
|
||||
} catch (IllegalAccessException accessEx) {
|
||||
throw new RuntimeException("unexpected IllegalAccessException " +
|
||||
"accessing Java field");
|
||||
|
@ -234,7 +235,8 @@ class JavaMembers {
|
|||
"msg.java.internal.private", name);
|
||||
}
|
||||
field.set(javaObject,
|
||||
NativeJavaObject.coerceType(field.getType(), value));
|
||||
NativeJavaObject.coerceType(field.getType(), value,
|
||||
true));
|
||||
} catch (ClassCastException e) {
|
||||
throw Context.reportRuntimeError1(
|
||||
"msg.java.method.assign", name);
|
||||
|
|
|
@ -110,7 +110,8 @@ public class NativeJavaArray extends NativeJavaObject {
|
|||
|
||||
public void put(int index, Scriptable start, Object value) {
|
||||
if (0 <= index && index < length) {
|
||||
Array.set(array, index, NativeJavaObject.coerceType(cls, value));
|
||||
Array.set(array, index, NativeJavaObject.coerceType(cls, value,
|
||||
true));
|
||||
return;
|
||||
}
|
||||
super.put(index, start, value);
|
||||
|
|
|
@ -218,7 +218,7 @@ public class NativeJavaClass extends NativeJavaObject implements Function {
|
|||
|
||||
Class[] paramTypes = ctor.getParameterTypes();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
args[i] = NativeJavaObject.coerceType(paramTypes[i], args[i]);
|
||||
args[i] = NativeJavaObject.coerceType(paramTypes[i], args[i], true);
|
||||
}
|
||||
try {
|
||||
// we need to force this to be wrapped, because construct _has_
|
||||
|
|
|
@ -204,7 +204,7 @@ public class NativeJavaMethod extends NativeFunction implements Function {
|
|||
|
||||
// First, we marshall the args.
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
args[i] = NativeJavaObject.coerceType(paramTypes[i], args[i]);
|
||||
args[i] = NativeJavaObject.coerceType(paramTypes[i], args[i], true);
|
||||
}
|
||||
Object javaObject;
|
||||
if (Modifier.isStatic(meth.getModifiers())) {
|
||||
|
|
|
@ -506,7 +506,9 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
* Type-munging for field setting and method invocation.
|
||||
* Conforms to LC3 specification
|
||||
*/
|
||||
public static Object coerceType(Class type, Object value) {
|
||||
public static Object coerceType(Class type, Object value,
|
||||
boolean useErrorHandler)
|
||||
{
|
||||
if (value != null && value.getClass() == type) {
|
||||
return value;
|
||||
}
|
||||
|
@ -516,7 +518,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
case JSTYPE_NULL:
|
||||
// raise error if type.isPrimitive()
|
||||
if (type.isPrimitive()) {
|
||||
reportConversionError(value, type);
|
||||
reportConversionError(value, type, !useErrorHandler);
|
||||
}
|
||||
return null;
|
||||
|
||||
|
@ -526,7 +528,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
return "undefined";
|
||||
}
|
||||
else {
|
||||
reportConversionError("undefined", type);
|
||||
reportConversionError("undefined", type, !useErrorHandler);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -541,7 +543,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
return value.toString();
|
||||
}
|
||||
else {
|
||||
reportConversionError(value, type);
|
||||
reportConversionError(value, type, !useErrorHandler);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -550,14 +552,14 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
return ScriptRuntime.toString(value);
|
||||
}
|
||||
else if (type == ScriptRuntime.ObjectClass) {
|
||||
return coerceToNumber(Double.TYPE, value);
|
||||
return coerceToNumber(Double.TYPE, value, useErrorHandler);
|
||||
}
|
||||
else if ((type.isPrimitive() && type != Boolean.TYPE) ||
|
||||
ScriptRuntime.NumberClass.isAssignableFrom(type)) {
|
||||
return coerceToNumber(type, value);
|
||||
return coerceToNumber(type, value, useErrorHandler);
|
||||
}
|
||||
else {
|
||||
reportConversionError(value, type);
|
||||
reportConversionError(value, type, !useErrorHandler);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -576,15 +578,15 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
return new Character(((String)value).charAt(0));
|
||||
}
|
||||
else {
|
||||
return coerceToNumber(type, value);
|
||||
return coerceToNumber(type, value, useErrorHandler);
|
||||
}
|
||||
}
|
||||
else if ((type.isPrimitive() && type != Boolean.TYPE) ||
|
||||
ScriptRuntime.NumberClass.isAssignableFrom(type)) {
|
||||
return coerceToNumber(type, value);
|
||||
return coerceToNumber(type, value, useErrorHandler);
|
||||
}
|
||||
else {
|
||||
reportConversionError(value, type);
|
||||
reportConversionError(value, type, !useErrorHandler);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -607,7 +609,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
return value.toString();
|
||||
}
|
||||
else {
|
||||
reportConversionError(value, type);
|
||||
reportConversionError(value, type, !useErrorHandler);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -616,9 +618,9 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
case JSTYPE_JAVA_ARRAY:
|
||||
if (type.isPrimitive()) {
|
||||
if (type == Boolean.TYPE) {
|
||||
reportConversionError(value, type);
|
||||
reportConversionError(value, type, !useErrorHandler);
|
||||
}
|
||||
return coerceToNumber(type, value);
|
||||
return coerceToNumber(type, value, useErrorHandler);
|
||||
}
|
||||
else {
|
||||
if (value instanceof Wrapper) {
|
||||
|
@ -632,7 +634,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
return value;
|
||||
}
|
||||
else {
|
||||
reportConversionError(value, type);
|
||||
reportConversionError(value, type, !useErrorHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -649,9 +651,9 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
}
|
||||
else if (type.isPrimitive()) {
|
||||
if (type == Boolean.TYPE) {
|
||||
reportConversionError(value, type);
|
||||
reportConversionError(value, type, !useErrorHandler);
|
||||
}
|
||||
return coerceToNumber(type, value);
|
||||
return coerceToNumber(type, value, useErrorHandler);
|
||||
}
|
||||
else if (type.isInstance(value)) {
|
||||
return value;
|
||||
|
@ -666,10 +668,11 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
for (int i = 0 ; i < length ; ++i) {
|
||||
try {
|
||||
Array.set(Result, i, coerceType(arrayType,
|
||||
array.get(i, array)));
|
||||
array.get(i, array),
|
||||
useErrorHandler));
|
||||
}
|
||||
catch (EvaluatorException ee) {
|
||||
reportConversionError(value, type);
|
||||
reportConversionError(value, type, !useErrorHandler);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -679,10 +682,10 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
value = ((Wrapper)value).unwrap();
|
||||
if (type.isInstance(value))
|
||||
return value;
|
||||
reportConversionError(value, type);
|
||||
reportConversionError(value, type, !useErrorHandler);
|
||||
}
|
||||
else {
|
||||
reportConversionError(value, type);
|
||||
reportConversionError(value, type, !useErrorHandler);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -712,7 +715,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
}
|
||||
}
|
||||
|
||||
static Object coerceToNumber(Class type, Object value) {
|
||||
static Object coerceToNumber(Class type, Object value, boolean useErrorHandler) {
|
||||
Class valueClass = value.getClass();
|
||||
|
||||
// Character
|
||||
|
@ -723,7 +726,8 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
return new Character((char)toInteger(value,
|
||||
ScriptRuntime.CharacterClass,
|
||||
(double)Character.MIN_VALUE,
|
||||
(double)Character.MAX_VALUE));
|
||||
(double)Character.MAX_VALUE,
|
||||
useErrorHandler));
|
||||
}
|
||||
|
||||
// Double, Float
|
||||
|
@ -731,7 +735,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
type == ScriptRuntime.DoubleClass || type == Double.TYPE) {
|
||||
return valueClass == ScriptRuntime.DoubleClass
|
||||
? value
|
||||
: new Double(toDouble(value));
|
||||
: new Double(toDouble(value, useErrorHandler));
|
||||
}
|
||||
|
||||
if (type == ScriptRuntime.FloatClass || type == Float.TYPE) {
|
||||
|
@ -739,7 +743,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
return value;
|
||||
}
|
||||
else {
|
||||
double number = toDouble(value);
|
||||
double number = toDouble(value, useErrorHandler);
|
||||
if (Double.isInfinite(number) || Double.isNaN(number)
|
||||
|| number == 0.0) {
|
||||
return new Float((float)number);
|
||||
|
@ -770,7 +774,8 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
return new Integer((int)toInteger(value,
|
||||
ScriptRuntime.IntegerClass,
|
||||
(double)Integer.MIN_VALUE,
|
||||
(double)Integer.MAX_VALUE));
|
||||
(double)Integer.MAX_VALUE,
|
||||
useErrorHandler));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -791,7 +796,8 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
return new Long(toInteger(value,
|
||||
ScriptRuntime.LongClass,
|
||||
min,
|
||||
max));
|
||||
max,
|
||||
useErrorHandler));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -803,7 +809,8 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
return new Short((short)toInteger(value,
|
||||
ScriptRuntime.ShortClass,
|
||||
(double)Short.MIN_VALUE,
|
||||
(double)Short.MAX_VALUE));
|
||||
(double)Short.MAX_VALUE,
|
||||
useErrorHandler));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -815,15 +822,16 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
return new Byte((byte)toInteger(value,
|
||||
ScriptRuntime.ByteClass,
|
||||
(double)Byte.MIN_VALUE,
|
||||
(double)Byte.MAX_VALUE));
|
||||
(double)Byte.MAX_VALUE,
|
||||
useErrorHandler));
|
||||
}
|
||||
}
|
||||
|
||||
return new Double(toDouble(value));
|
||||
return new Double(toDouble(value, useErrorHandler));
|
||||
}
|
||||
|
||||
|
||||
static double toDouble(Object value) {
|
||||
static double toDouble(Object value, boolean useErrorHandler) {
|
||||
if (value instanceof Number) {
|
||||
return ((Number)value).doubleValue();
|
||||
}
|
||||
|
@ -833,7 +841,7 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
else if (value instanceof Scriptable) {
|
||||
if (value instanceof Wrapper) {
|
||||
// XXX: optimize tail-recursion?
|
||||
return toDouble(((Wrapper)value).unwrap());
|
||||
return toDouble(((Wrapper)value).unwrap(), useErrorHandler);
|
||||
}
|
||||
else {
|
||||
return ScriptRuntime.toNumber(value);
|
||||
|
@ -856,23 +864,26 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
}
|
||||
catch (IllegalAccessException e) {
|
||||
// XXX: ignore, or error message?
|
||||
reportConversionError(value, Double.TYPE);
|
||||
reportConversionError(value, Double.TYPE, !useErrorHandler);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
// XXX: ignore, or error message?
|
||||
reportConversionError(value, Double.TYPE);
|
||||
reportConversionError(value, Double.TYPE, !useErrorHandler);
|
||||
}
|
||||
}
|
||||
return ScriptRuntime.toNumber(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
static long toInteger(Object value, Class type, double min, double max) {
|
||||
double d = toDouble(value);
|
||||
static long toInteger(Object value, Class type, double min, double max,
|
||||
boolean useErrorHandler)
|
||||
{
|
||||
double d = toDouble(value, useErrorHandler);
|
||||
|
||||
if (Double.isInfinite(d) || Double.isNaN(d)) {
|
||||
// Convert to string first, for more readable message
|
||||
reportConversionError(ScriptRuntime.toString(value), type);
|
||||
reportConversionError(ScriptRuntime.toString(value), type,
|
||||
!useErrorHandler);
|
||||
}
|
||||
|
||||
if (d > 0.0) {
|
||||
|
@ -884,12 +895,19 @@ public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
|
|||
|
||||
if (d < min || d > max) {
|
||||
// Convert to string first, for more readable message
|
||||
reportConversionError(ScriptRuntime.toString(value), type);
|
||||
reportConversionError(ScriptRuntime.toString(value), type,
|
||||
!useErrorHandler);
|
||||
}
|
||||
return (long)d;
|
||||
}
|
||||
|
||||
static void reportConversionError(Object value, Class type) {
|
||||
static void reportConversionError(Object value, Class type,
|
||||
boolean throwIllegalArg)
|
||||
{
|
||||
if (throwIllegalArg) {
|
||||
throw new IllegalArgumentException("Cannot convert " + value +
|
||||
" to type " + type);
|
||||
}
|
||||
throw Context.reportRuntimeError2
|
||||
("msg.conversion.not.allowed",
|
||||
value.toString(), NativeJavaMethod.javaSignature(type));
|
||||
|
|
Загрузка…
Ссылка в новой задаче