mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add deleteProperty API (#52911)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/52911 Add a new `deleteProperty` API to JSI. As the name implies, allows users to delete properties from Objects through JSI. The default implementation uses `Reflect.deleteProperty.` For the `PropNameID` overload, convert the propNameID to a String and pass into the `deleteProperty` function. Changelog: [Internal] Reviewed By: dannysu Differential Revision: D79120814 fbshipit-source-id: e30f383247d94bb5971e4909f004c75e8165adda
This commit is contained in:
committed by
Facebook GitHub Bot
parent
da9136f587
commit
646945c2f2
@@ -328,6 +328,18 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation {
|
||||
plain_.setPropertyValue(o, name, value);
|
||||
};
|
||||
|
||||
void deleteProperty(const Object& object, const PropNameID& name) override {
|
||||
plain_.deleteProperty(object, name);
|
||||
}
|
||||
|
||||
void deleteProperty(const Object& object, const String& name) override {
|
||||
plain_.deleteProperty(object, name);
|
||||
}
|
||||
|
||||
void deleteProperty(const Object& object, const Value& name) override {
|
||||
plain_.deleteProperty(object, name);
|
||||
}
|
||||
|
||||
bool isArray(const Object& o) const override {
|
||||
return plain_.isArray(o);
|
||||
};
|
||||
@@ -852,6 +864,21 @@ class WithRuntimeDecorator : public RuntimeDecorator<Plain, Base> {
|
||||
RD::setPropertyValue(o, name, value);
|
||||
};
|
||||
|
||||
void deleteProperty(const Object& object, const PropNameID& name) override {
|
||||
Around around{with_};
|
||||
RD::deleteProperty(object, name);
|
||||
}
|
||||
|
||||
void deleteProperty(const Object& object, const String& name) override {
|
||||
Around around{with_};
|
||||
RD::deleteProperty(object, name);
|
||||
}
|
||||
|
||||
void deleteProperty(const Object& object, const Value& name) override {
|
||||
Around around{with_};
|
||||
RD::deleteProperty(object, name);
|
||||
}
|
||||
|
||||
bool isArray(const Object& o) const override {
|
||||
Around around{with_};
|
||||
return RD::isArray(o);
|
||||
|
||||
@@ -148,6 +148,23 @@ void Object::setProperty(Runtime& runtime, const PropNameID& name, T&& value)
|
||||
runtime, name, detail::toValue(runtime, std::forward<T>(value)));
|
||||
}
|
||||
|
||||
inline void Object::deleteProperty(Runtime& runtime, const char* name) const {
|
||||
deleteProperty(runtime, String::createFromAscii(runtime, name));
|
||||
}
|
||||
|
||||
inline void Object::deleteProperty(Runtime& runtime, const String& name) const {
|
||||
runtime.deleteProperty(*this, name);
|
||||
}
|
||||
|
||||
inline void Object::deleteProperty(Runtime& runtime, const PropNameID& name)
|
||||
const {
|
||||
runtime.deleteProperty(*this, name);
|
||||
}
|
||||
|
||||
inline void Object::deleteProperty(Runtime& runtime, const Value& name) const {
|
||||
runtime.deleteProperty(*this, name);
|
||||
}
|
||||
|
||||
inline Array Object::getArray(Runtime& runtime) const& {
|
||||
assert(runtime.isArray(*this));
|
||||
(void)runtime; // when assert is disabled we need to mark this as used
|
||||
|
||||
@@ -416,6 +416,37 @@ Object Runtime::createObjectWithPrototype(const Value& prototype) {
|
||||
return createFn.call(*this, prototype).asObject(*this);
|
||||
}
|
||||
|
||||
void Runtime::deleteProperty(const Object& object, const PropNameID& name) {
|
||||
auto nameStr = String::createFromUtf16(*this, name.utf16(*this));
|
||||
auto deleteFn = global()
|
||||
.getPropertyAsObject(*this, "Reflect")
|
||||
.getPropertyAsFunction(*this, "deleteProperty");
|
||||
auto res = deleteFn.call(*this, object, nameStr).getBool();
|
||||
if (!res) {
|
||||
throw JSError(*this, "Failed to delete property");
|
||||
}
|
||||
}
|
||||
|
||||
void Runtime::deleteProperty(const Object& object, const String& name) {
|
||||
auto deleteFn = global()
|
||||
.getPropertyAsObject(*this, "Reflect")
|
||||
.getPropertyAsFunction(*this, "deleteProperty");
|
||||
auto res = deleteFn.call(*this, object, name).getBool();
|
||||
if (!res) {
|
||||
throw JSError(*this, "Failed to delete property");
|
||||
}
|
||||
}
|
||||
|
||||
void Runtime::deleteProperty(const Object& object, const Value& name) {
|
||||
auto deleteFn = global()
|
||||
.getPropertyAsObject(*this, "Reflect")
|
||||
.getPropertyAsFunction(*this, "deleteProperty");
|
||||
auto res = deleteFn.call(*this, object, name).getBool();
|
||||
if (!res) {
|
||||
throw JSError(*this, "Failed to delete property");
|
||||
}
|
||||
}
|
||||
|
||||
void Runtime::setRuntimeDataImpl(
|
||||
const UUID& uuid,
|
||||
const void* data,
|
||||
|
||||
@@ -486,6 +486,10 @@ class JSI_EXPORT Runtime : public ICast {
|
||||
virtual void
|
||||
setPropertyValue(const Object&, const String& name, const Value& value) = 0;
|
||||
|
||||
virtual void deleteProperty(const Object&, const PropNameID& name);
|
||||
virtual void deleteProperty(const Object&, const String& name);
|
||||
virtual void deleteProperty(const Object&, const Value& name);
|
||||
|
||||
virtual bool isArray(const Object&) const = 0;
|
||||
virtual bool isArrayBuffer(const Object&) const = 0;
|
||||
virtual bool isFunction(const Object&) const = 0;
|
||||
@@ -984,6 +988,22 @@ class JSI_EXPORT Object : public Pointer {
|
||||
template <typename T>
|
||||
void setProperty(Runtime& runtime, const PropNameID& name, T&& value) const;
|
||||
|
||||
/// Delete the property with the given ascii name. Throws if the deletion
|
||||
/// failed.
|
||||
void deleteProperty(Runtime& runtime, const char* name) const;
|
||||
|
||||
/// Delete the property with the given String name. Throws if the deletion
|
||||
/// failed.
|
||||
void deleteProperty(Runtime& runtime, const String& name) const;
|
||||
|
||||
/// Delete the property with the given PropNameID name. Throws if the deletion
|
||||
/// failed.
|
||||
void deleteProperty(Runtime& runtime, const PropNameID& name) const;
|
||||
|
||||
/// Delete the property with the given Value name. Throws if the deletion
|
||||
/// failed.
|
||||
void deleteProperty(Runtime& runtime, const Value& name) const;
|
||||
|
||||
/// \return true iff JS \c Array.isArray() would return \c true. If
|
||||
/// so, then \c getArray() will succeed.
|
||||
bool isArray(Runtime& runtime) const {
|
||||
|
||||
@@ -1882,6 +1882,65 @@ TEST_P(JSITest, CastInterface) {
|
||||
EXPECT_TRUE(ptr == nullptr);
|
||||
}
|
||||
|
||||
TEST_P(JSITest, DeleteProperty) {
|
||||
// This Runtime Decorator is used to test the default implementation of
|
||||
// Runtime::deleteProperty
|
||||
class RD : public RuntimeDecorator<Runtime, Runtime> {
|
||||
public:
|
||||
explicit RD(Runtime& rt) : RuntimeDecorator(rt) {}
|
||||
|
||||
void deleteProperty(const Object& object, const PropNameID& name) override {
|
||||
Runtime::deleteProperty(object, name);
|
||||
}
|
||||
void deleteProperty(const Object& object, const String& name) override {
|
||||
Runtime::deleteProperty(object, name);
|
||||
}
|
||||
void deleteProperty(const Object& object, const Value& name) override {
|
||||
Runtime::deleteProperty(object, name);
|
||||
}
|
||||
};
|
||||
RD rd = RD(rt);
|
||||
auto obj = eval("obj = {1:2, foo: 'bar', 3: 4, salt:'pepper'}").getObject(rd);
|
||||
|
||||
auto prop = PropNameID::forAscii(rd, "1");
|
||||
auto hasRes = obj.hasProperty(rd, prop);
|
||||
EXPECT_TRUE(hasRes);
|
||||
obj.deleteProperty(rd, prop);
|
||||
hasRes = obj.hasProperty(rd, prop);
|
||||
EXPECT_FALSE(hasRes);
|
||||
|
||||
auto str = String::createFromAscii(rd, "foo");
|
||||
hasRes = obj.hasProperty(rd, str);
|
||||
EXPECT_TRUE(hasRes);
|
||||
obj.deleteProperty(rd, str);
|
||||
hasRes = obj.hasProperty(rd, str);
|
||||
EXPECT_FALSE(hasRes);
|
||||
|
||||
auto valProp = Value(3);
|
||||
hasRes = obj.hasProperty(rd, "3");
|
||||
EXPECT_TRUE(hasRes);
|
||||
obj.deleteProperty(rd, valProp);
|
||||
auto getRes = obj.getProperty(rd, "3");
|
||||
EXPECT_TRUE(getRes.isUndefined());
|
||||
|
||||
hasRes = obj.hasProperty(rd, "salt");
|
||||
EXPECT_TRUE(hasRes);
|
||||
obj.deleteProperty(rd, "salt");
|
||||
hasRes = obj.hasProperty(rd, "salt");
|
||||
EXPECT_FALSE(hasRes);
|
||||
|
||||
obj = eval(
|
||||
"const obj = {};"
|
||||
"Object.defineProperty(obj, 'prop', {"
|
||||
" value: 10,"
|
||||
" configurable: false,});"
|
||||
"obj;")
|
||||
.getObject(rd);
|
||||
EXPECT_THROW(obj.deleteProperty(rd, "prop"), JSError);
|
||||
hasRes = obj.hasProperty(rd, "prop");
|
||||
EXPECT_TRUE(hasRes);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
Runtimes,
|
||||
JSITest,
|
||||
|
||||
Reference in New Issue
Block a user