
org.mozilla.javascript.NativeReflect Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rhino Show documentation
Show all versions of rhino Show documentation
Rhino is an open-source implementation of JavaScript written entirely in Java. It is typically
embedded into Java applications to provide scripting to end users.
The newest version!
/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.javascript;
import java.util.ArrayList;
import java.util.List;
/**
* This class implements the Reflect object.
*
* @author Ronald Brill
*/
final class NativeReflect extends ScriptableObject {
private static final long serialVersionUID = 2920773905356325445L;
private static final String REFLECT_TAG = "Reflect";
public static void init(Context cx, Scriptable scope, boolean sealed) {
NativeReflect reflect = new NativeReflect();
reflect.setPrototype(getObjectPrototype(scope));
reflect.setParentScope(scope);
reflect.defineProperty(
scope, "apply", 3, NativeReflect::apply, DONTENUM, DONTENUM | READONLY);
reflect.defineProperty(
scope, "construct", 2, NativeReflect::construct, DONTENUM, DONTENUM | READONLY);
reflect.defineProperty(
scope,
"defineProperty",
3,
NativeReflect::defineProperty,
DONTENUM,
DONTENUM | READONLY);
reflect.defineProperty(
scope,
"deleteProperty",
2,
NativeReflect::deleteProperty,
DONTENUM,
DONTENUM | READONLY);
reflect.defineProperty(scope, "get", 2, NativeReflect::get, DONTENUM, DONTENUM | READONLY);
reflect.defineProperty(
scope,
"getOwnPropertyDescriptor",
2,
NativeReflect::getOwnPropertyDescriptor,
DONTENUM,
DONTENUM | READONLY);
reflect.defineProperty(
scope,
"getPrototypeOf",
1,
NativeReflect::getPrototypeOf,
DONTENUM,
DONTENUM | READONLY);
reflect.defineProperty(scope, "has", 2, NativeReflect::has, DONTENUM, DONTENUM | READONLY);
reflect.defineProperty(
scope,
"isExtensible",
1,
NativeReflect::isExtensible,
DONTENUM,
DONTENUM | READONLY);
reflect.defineProperty(
scope, "ownKeys", 1, NativeReflect::ownKeys, DONTENUM, DONTENUM | READONLY);
reflect.defineProperty(
scope,
"preventExtensions",
1,
NativeReflect::preventExtensions,
DONTENUM,
DONTENUM | READONLY);
reflect.defineProperty(scope, "set", 3, NativeReflect::set, DONTENUM, DONTENUM | READONLY);
reflect.defineProperty(
scope,
"setPrototypeOf",
2,
NativeReflect::setPrototypeOf,
DONTENUM,
DONTENUM | READONLY);
reflect.defineProperty(SymbolKey.TO_STRING_TAG, REFLECT_TAG, DONTENUM | READONLY);
ScriptableObject.defineProperty(scope, REFLECT_TAG, reflect, DONTENUM);
if (sealed) {
reflect.sealObject();
}
}
private NativeReflect() {}
@Override
public String getClassName() {
return "Reflect";
}
private static Object apply(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
if (args.length < 3) {
throw ScriptRuntime.typeErrorById(
"msg.method.missing.parameter",
"Reflect.apply",
"3",
Integer.toString(args.length));
}
Scriptable callable = ScriptableObject.ensureScriptable(args[0]);
if (args[1] instanceof Scriptable) {
thisObj = (Scriptable) args[1];
} else if (ScriptRuntime.isPrimitive(args[1])) {
thisObj = cx.newObject(scope, "Object", new Object[] {args[1]});
}
if (ScriptRuntime.isSymbol(args[2])) {
throw ScriptRuntime.typeErrorById("msg.arg.not.object", ScriptRuntime.typeof(args[2]));
}
ScriptableObject argumentsList = ScriptableObject.ensureScriptableObject(args[2]);
return ScriptRuntime.applyOrCall(
true, cx, scope, callable, new Object[] {thisObj, argumentsList});
}
/** see https://262.ecma-international.org/12.0/#sec-reflect.construct */
private static Scriptable construct(
Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
/*
* 1. If IsConstructor(target) is false, throw a TypeError exception.
* 2. If newTarget is not present, set newTarget to target.
* 3. Else if IsConstructor(newTarget) is false, throw a TypeError exception.
* 4. Let args be ? CreateListFromArrayLike(argumentsList).
* 5. Return ? Construct(target, args, newTarget).
*/
if (args.length < 1) {
throw ScriptRuntime.typeErrorById(
"msg.method.missing.parameter",
"Reflect.construct",
"3",
Integer.toString(args.length));
}
if (!AbstractEcmaObjectOperations.isConstructor(cx, args[0])) {
throw ScriptRuntime.typeErrorById("msg.not.ctor", ScriptRuntime.typeof(args[0]));
}
Constructable ctor = (Constructable) args[0];
if (args.length < 2) {
return ctor.construct(cx, scope, ScriptRuntime.emptyArgs);
}
if (args.length > 2 && !AbstractEcmaObjectOperations.isConstructor(cx, args[2])) {
throw ScriptRuntime.typeErrorById("msg.not.ctor", ScriptRuntime.typeof(args[2]));
}
Object[] callArgs = ScriptRuntime.getApplyArguments(cx, args[1]);
Object newTargetPrototype = null;
if (args.length > 2) {
Scriptable newTarget = ScriptableObject.ensureScriptable(args[2]);
if (newTarget instanceof BaseFunction) {
newTargetPrototype = ((BaseFunction) newTarget).getPrototypeProperty();
} else {
newTargetPrototype = newTarget.get("prototype", newTarget);
}
if (!(newTargetPrototype instanceof Scriptable)
|| ScriptRuntime.isSymbol(newTargetPrototype)
|| Undefined.isUndefined(newTargetPrototype)) {
newTargetPrototype = null;
}
}
// our Constructable interface does not support the newTarget;
// therefore we use a cloned implementation that fixes
// the prototype before executing call(..).
if (ctor instanceof BaseFunction && newTargetPrototype != null) {
BaseFunction ctorBaseFunction = (BaseFunction) ctor;
Scriptable result = ctorBaseFunction.createObject(cx, scope);
if (result != null) {
result.setPrototype((Scriptable) newTargetPrototype);
Object val = ctorBaseFunction.call(cx, scope, result, callArgs);
if (val instanceof Scriptable) {
return (Scriptable) val;
}
return result;
}
}
Scriptable newScriptable = ctor.construct(cx, scope, callArgs);
if (newTargetPrototype != null) {
newScriptable.setPrototype((Scriptable) newTargetPrototype);
}
return newScriptable;
}
private static Object defineProperty(
Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
if (args.length < 3) {
throw ScriptRuntime.typeErrorById(
"msg.method.missing.parameter",
"Reflect.defineProperty",
"3",
Integer.toString(args.length));
}
ScriptableObject target = checkTarget(args);
ScriptableObject desc = ScriptableObject.ensureScriptableObject(args[2]);
try {
return target.defineOwnProperty(cx, args[1], desc);
} catch (EcmaError e) {
return false;
}
}
private static Object deleteProperty(
Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
ScriptableObject target = checkTarget(args);
if (args.length > 1) {
if (ScriptRuntime.isSymbol(args[1])) {
return ScriptableObject.deleteProperty(target, (Symbol) args[1]);
}
return ScriptableObject.deleteProperty(target, ScriptRuntime.toString(args[1]));
}
return false;
}
private static Object get(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
ScriptableObject target = checkTarget(args);
if (args.length > 1) {
if (ScriptRuntime.isSymbol(args[1])) {
Object prop = ScriptableObject.getProperty(target, (Symbol) args[1]);
return prop == Scriptable.NOT_FOUND ? Undefined.SCRIPTABLE_UNDEFINED : prop;
}
if (args[1] instanceof Number) {
Object prop = ScriptableObject.getProperty(target, ScriptRuntime.toIndex(args[1]));
return prop == Scriptable.NOT_FOUND ? Undefined.SCRIPTABLE_UNDEFINED : prop;
}
Object prop = ScriptableObject.getProperty(target, ScriptRuntime.toString(args[1]));
return prop == Scriptable.NOT_FOUND ? Undefined.SCRIPTABLE_UNDEFINED : prop;
}
return Undefined.SCRIPTABLE_UNDEFINED;
}
private static Scriptable getOwnPropertyDescriptor(
Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
ScriptableObject target = checkTarget(args);
if (args.length > 1) {
if (ScriptRuntime.isSymbol(args[1])) {
ScriptableObject desc = target.getOwnPropertyDescriptor(cx, args[1]);
return desc == null ? Undefined.SCRIPTABLE_UNDEFINED : desc;
}
ScriptableObject desc =
target.getOwnPropertyDescriptor(cx, ScriptRuntime.toString(args[1]));
return desc == null ? Undefined.SCRIPTABLE_UNDEFINED : desc;
}
return Undefined.SCRIPTABLE_UNDEFINED;
}
private static Scriptable getPrototypeOf(
Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
ScriptableObject target = checkTarget(args);
return target.getPrototype();
}
private static Object has(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
ScriptableObject target = checkTarget(args);
if (args.length > 1) {
if (ScriptRuntime.isSymbol(args[1])) {
return ScriptableObject.hasProperty(target, (Symbol) args[1]);
}
return ScriptableObject.hasProperty(target, ScriptRuntime.toString(args[1]));
}
return false;
}
private static Object isExtensible(
Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
ScriptableObject target = checkTarget(args);
return target.isExtensible();
}
private static Scriptable ownKeys(
Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
ScriptableObject target = checkTarget(args);
final List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy