Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/external.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# External (template)

Class `Napi::External<T>` inherits from class [`Napi::Value`][].
Class `Napi::External<T>` inherits from class [`Napi::TypeTaggable`][].

The `Napi::External` template class implements the ability to create a `Napi::Value` object with arbitrary C++ data. It is the user's responsibility to manage the memory for the arbitrary C++ data.

Expand Down Expand Up @@ -67,4 +67,4 @@ T* Napi::External::Data() const;

Returns a pointer to the arbitrary C++ data held by the `Napi::External` object.

[`Napi::Value`]: ./value.md
[`Napi::TypeTaggable`]: ./type_taggable.md
31 changes: 2 additions & 29 deletions doc/object.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Object

Class `Napi::Object` inherits from class [`Napi::Value`][].
Class `Napi::Object` inherits from class [`Napi::TypeTaggable`][].

The `Napi::Object` class corresponds to a JavaScript object. It is extended by the following node-addon-api classes that you may use when working with more specific types:

Expand Down Expand Up @@ -241,33 +241,6 @@ from being added to it and marking all existing properties as non-configurable.
Values of present properties can still be changed as long as they are
writable.

### TypeTag()

```cpp
void Napi::Object::TypeTag(const napi_type_tag* type_tag) const;
```

- `[in] type_tag`: The tag with which this object is to be marked.

The `Napi::Object::TypeTag()` method associates the value of the `type_tag`
pointer with this JavaScript object. `Napi::Object::CheckTypeTag()` can then be
used to compare the tag that was attached to this object with one owned by the
addon to ensure that this object has the right type.

### CheckTypeTag()

```cpp
bool Napi::Object::CheckTypeTag(const napi_type_tag* type_tag) const;
```

- `[in] type_tag`: The tag with which to compare any tag found on this object.

The `Napi::Object::CheckTypeTag()` method compares the pointer given as
`type_tag` with any that can be found on this JavaScript object. If no tag is
found on this object or, if a tag is found but it does not match `type_tag`,
then the return value is `false`. If a tag is found and it matches `type_tag`,
then the return value is `true`.

### operator\[\]()

```cpp
Expand Down Expand Up @@ -434,5 +407,5 @@ void Increment(const CallbackInfo& info) {
}
```

[`Napi::Value`]: ./value.md
[`Napi::TypeTaggable`]: ./type_taggable.md
[`Napi::Value::From`]: ./value.md#from
38 changes: 38 additions & 0 deletions doc/type_taggable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# TypeTaggable

Class `Napi::TypeTaggable` inherits from class [`Napi::Value`][].

The `Napi::TypeTaggable` class is the base class for [`Napi::Object`][] and
[`Napi::External`][]. It adds type-tagging capabilities to both. It is an
abstract-only base class.

### TypeTag()

```cpp
void Napi::TypeTaggable::TypeTag(const napi_type_tag* type_tag) const;
```

- `[in] type_tag`: The tag with which this object or external is to be marked.

The `Napi::TypeTaggable::TypeTag()` method associates the value of the
`type_tag` pointer with this JavaScript object or external.
`Napi::TypeTaggable::CheckTypeTag()` can then be used to compare the tag that
was attached with one owned by the add-on to ensure that this object or external
has the right type.

### CheckTypeTag()

```cpp
bool Napi::TypeTaggable::CheckTypeTag(const napi_type_tag* type_tag) const;
```

- `[in] type_tag`: The tag with which to compare any tag found on this object or
external.

The `Napi::TypeTaggable::CheckTypeTag()` method compares the pointer given as
`type_tag` with any that can be found on this JavaScript object or external. If
no tag is found or if a tag is found but it does not match `type_tag`, then the
return value is `false`. If a tag is found and it matches `type_tag`, then the
return value is `true`.

[`Napi::Value`]: ./value.md
48 changes: 31 additions & 17 deletions napi-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,32 @@ String String::From(napi_env env, const T& value) {
return Helper::From(env, value);
}

////////////////////////////////////////////////////////////////////////////////
// TypeTaggable class
////////////////////////////////////////////////////////////////////////////////

inline TypeTaggable::TypeTaggable() : Value() {}

inline TypeTaggable::TypeTaggable(napi_env _env, napi_value _value)
: Value(_env, _value) {}

#if NAPI_VERSION >= 8

inline void TypeTaggable::TypeTag(const napi_type_tag* type_tag) const {
napi_status status = napi_type_tag_object(_env, _value, type_tag);
NAPI_THROW_IF_FAILED_VOID(_env, status);
}

inline bool TypeTaggable::CheckTypeTag(const napi_type_tag* type_tag) const {
bool result;
napi_status status =
napi_check_object_type_tag(_env, _value, type_tag, &result);
NAPI_THROW_IF_FAILED(_env, status, false);
return result;
}

#endif // NAPI_VERSION >= 8

////////////////////////////////////////////////////////////////////////////////
// Object class
////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1287,9 +1313,10 @@ inline Object Object::New(napi_env env) {
return Object(env, value);
}

inline Object::Object() : Value() {}
inline Object::Object() : TypeTaggable() {}

inline Object::Object(napi_env env, napi_value value) : Value(env, value) {}
inline Object::Object(napi_env env, napi_value value)
: TypeTaggable(env, value) {}

inline Object::PropertyLValue<std::string> Object::operator[](
const char* utf8name) {
Expand Down Expand Up @@ -1632,19 +1659,6 @@ inline MaybeOrValue<bool> Object::Seal() const {
napi_status status = napi_object_seal(_env, _value);
NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
}

inline void Object::TypeTag(const napi_type_tag* type_tag) const {
napi_status status = napi_type_tag_object(_env, _value, type_tag);
NAPI_THROW_IF_FAILED_VOID(_env, status);
}

inline bool Object::CheckTypeTag(const napi_type_tag* type_tag) const {
bool result;
napi_status status =
napi_check_object_type_tag(_env, _value, type_tag, &result);
NAPI_THROW_IF_FAILED(_env, status, false);
return result;
}
#endif // NAPI_VERSION >= 8

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1706,11 +1720,11 @@ inline External<T> External<T>::New(napi_env env,
}

template <typename T>
inline External<T>::External() : Value() {}
inline External<T>::External() : TypeTaggable() {}

template <typename T>
inline External<T>::External(napi_env env, napi_value value)
: Value(env, value) {}
: TypeTaggable(env, value) {}

template <typename T>
inline T* External<T>::Data() const {
Expand Down
18 changes: 13 additions & 5 deletions napi.h
Original file line number Diff line number Diff line change
Expand Up @@ -714,8 +714,19 @@ class Symbol : public Name {
napi_value value); ///< Wraps a Node-API value primitive.
};

class TypeTaggable : public Value {
public:
#if NAPI_VERSION >= 8
void TypeTag(const napi_type_tag* type_tag) const;
bool CheckTypeTag(const napi_type_tag* type_tag) const;
#endif // NAPI_VERSION >= 8
protected:
TypeTaggable();
TypeTaggable(napi_env env, napi_value value);
};

/// A JavaScript object value.
class Object : public Value {
class Object : public TypeTaggable {
public:
/// Enables property and element assignments using indexing syntax.
///
Expand Down Expand Up @@ -991,14 +1002,11 @@ class Object : public Value {
/// See
/// https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof
MaybeOrValue<bool> Seal() const;

void TypeTag(const napi_type_tag* type_tag) const;
bool CheckTypeTag(const napi_type_tag* type_tag) const;
#endif // NAPI_VERSION >= 8
};

template <typename T>
class External : public Value {
class External : public TypeTaggable {
public:
static External New(napi_env env, T* data);

Expand Down
4 changes: 2 additions & 2 deletions test/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Object InitVersionManagement(Env env);
Object InitThunkingManual(Env env);
#if (NAPI_VERSION > 7)
Object InitObjectFreezeSeal(Env env);
Object InitObjectTypeTag(Env env);
Object InitTypeTaggable(Env env);
#endif

#if defined(NODE_ADDON_API_ENABLE_MAYBE)
Expand Down Expand Up @@ -169,7 +169,7 @@ Object Init(Env env, Object exports) {
exports.Set("thunking_manual", InitThunkingManual(env));
#if (NAPI_VERSION > 7)
exports.Set("object_freeze_seal", InitObjectFreezeSeal(env));
exports.Set("object_type_tag", InitObjectTypeTag(env));
exports.Set("type_taggable", InitTypeTaggable(env));
#endif

#if defined(NODE_ADDON_API_ENABLE_MAYBE)
Expand Down
2 changes: 1 addition & 1 deletion test/binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
'object/has_property.cc',
'object/object.cc',
'object/object_freeze_seal.cc',
'object/object_type_tag.cc',
'object/set_property.cc',
'object/subscript_operator.cc',
'promise.cc',
Expand All @@ -60,6 +59,7 @@
'threadsafe_function/threadsafe_function_sum.cc',
'threadsafe_function/threadsafe_function_unref.cc',
'threadsafe_function/threadsafe_function.cc',
'type_taggable.cc',
'typed_threadsafe_function/typed_threadsafe_function_ctx.cc',
'typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.cc',
'typed_threadsafe_function/typed_threadsafe_function_ptr.cc',
Expand Down
2 changes: 1 addition & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ if (majorNodeVersion < 12 && !filterConditionsProvided) {

if (napiVersion < 8 && !filterConditionsProvided) {
testModules.splice(testModules.indexOf('object/object_freeze_seal'), 1);
testModules.splice(testModules.indexOf('object/object_type_tag'), 1);
testModules.splice(testModules.indexOf('type_taggable'), 1);
}

(async function () {
Expand Down
39 changes: 0 additions & 39 deletions test/object/object_type_tag.cc

This file was deleted.

55 changes: 0 additions & 55 deletions test/object/object_type_tag.js

This file was deleted.

Loading