Skip to content

Commit

Permalink
src: interject class TypeTaggable
Browse files Browse the repository at this point in the history
Derive class `TypeTaggable` from `Value`, and let it serve as the base
class for `Object` and `External`. That way, the type tagging is
implemented for both classes.

Additionally, exclude deleted .js files from linting.

Signed-off-by: Gabriel Schulhof <gabrielschulhof@gmail.com>
Refs: #1293

PR-URL: #1298
Reviewed-By: Michael Dawson <midawson@redhat.com
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
  • Loading branch information
gabrielschulhof authored and mhdawson committed Mar 27, 2023
1 parent d4942cc commit d013044
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 153 deletions.
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

0 comments on commit d013044

Please sign in to comment.