-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
repl: tab auto complete big arrays #22408
Conversation
@nodejs/repl PTAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work, not sure about semverness.
LGTM pending green CI. Left some nits I'd appreciate if you addressed but I'm still green with them.
Mostly - more tests would be fantastic.
lib/internal/util.js
Outdated
@@ -366,6 +366,14 @@ function isInsideNodeModules() { | |||
return false; | |||
} | |||
|
|||
const kPropertyFilter = Object.freeze({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to copy the whole enum as it is in V8 ( https://github.com/v8/v8/blob/master/src/property-details.h#L36-L45 ) for consistency and keeping a reference to the V8 source here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So far, we usually go all the way here and provide the real V8 constants as exports from the binding, e.g.
Lines 105 to 114 in 9bcb744
// Define constants | |
Local<Object> constants = Object::New(env->isolate()); | |
NODE_DEFINE_CONSTANT(constants, SOCKET); | |
NODE_DEFINE_CONSTANT(constants, SERVER); | |
NODE_DEFINE_CONSTANT(constants, IPC); | |
NODE_DEFINE_CONSTANT(constants, UV_READABLE); | |
NODE_DEFINE_CONSTANT(constants, UV_WRITABLE); | |
target->Set(context, | |
FIXED_ONE_BYTE_STRING(env->isolate(), "constants"), | |
constants).FromJust(); |
I’d encourage you to keep up with that pattern to prevent unexpected breakage from changes to the V8 definition, which is the source-of-truth for these values, even if it seems like a bit of extra work at this point (or leave to TODO comment for me, I’m happy to do the work myself if you prefer)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the comments. I definitely appreciate it as I try to teach myself more and more about C++ and the V8 side. So please always mention these things.
lib/internal/util/comparisons.js
Outdated
@@ -5,6 +5,7 @@ const { isArrayBufferView } = require('internal/util/types'); | |||
const { internalBinding } = require('internal/bootstrap/loaders'); | |||
const { isDate, isMap, isRegExp, isSet } = internalBinding('types'); | |||
const { getOwnNonIndexProperties } = process.binding('util'); | |||
const { kPropertyFilter: { ONLY_ENUMERABLE } } = require('internal/util'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: while I use this style of destructuring in my own code - a common criticism I've found is that it's more confusing and in this case it might make sense to import the whole filter similarly to how V8 does PropertyFilter:: ALL_PROPERTIES
although scoping rules would have allowed it to use the unqualified name allow.
if (keys1.length !== getOwnNonIndexProperties(val2).length) { | ||
const keys1 = getOwnNonIndexProperties(val1, ONLY_ENUMERABLE); | ||
const keys2 = getOwnNonIndexProperties(val2, ONLY_ENUMERABLE); | ||
if (keys1.length !== keys2.length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated optimization idea: would it make sense to return only the length from V8 rather than the properties themselves in the case of keys2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I already spoke with @nodejs/v8 to implement a API that does exactly that. Until that exists, I would rather keep it as is.
src/node_util.cc
Outdated
@@ -21,17 +21,20 @@ static void GetOwnNonIndexProperties( | |||
Environment* env = Environment::GetCurrent(args); | |||
Local<Context> context = env->context(); | |||
|
|||
if (!args[0]->IsObject()) | |||
if (!args[0]->IsObject() || !args[1]->IsUint32()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it make sense for this to be a CHECK
since we should never end up here without said args?
(Not critical for this PR)
@@ -443,13 +433,12 @@ const warningRegEx = new RegExp( | |||
Buffer.alloc(0) : | |||
new type(0)); | |||
|
|||
assert.strictEqual(data[0].includes('ele.biu'), true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great to have tests that specify the behaviour for long arrays better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is specifically for long arrays. Since this value shows up, we can be certain that it works. I would not know what to improve. Do you have a suggestion?
src/node_util.cc
Outdated
v8::Local<v8::Array> properties; | ||
v8::PropertyFilter filter = | ||
static_cast<v8::PropertyFilter>( | ||
args[1]->Uint32Value(env->context()).FromJust()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you already know at this point that args[1]
is an Uint32 here, I’d suggest using args[1].As<Uint32>()->Value()
(which is a static cast that fully compiles away, whereas Uint32Value()
performs the equivalent of value|0
in JS, i.e. performs a real conversion that can potentially run userland code for non-integer input)
lib/internal/util.js
Outdated
@@ -366,6 +366,14 @@ function isInsideNodeModules() { | |||
return false; | |||
} | |||
|
|||
const kPropertyFilter = Object.freeze({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So far, we usually go all the way here and provide the real V8 constants as exports from the binding, e.g.
Lines 105 to 114 in 9bcb744
// Define constants | |
Local<Object> constants = Object::New(env->isolate()); | |
NODE_DEFINE_CONSTANT(constants, SOCKET); | |
NODE_DEFINE_CONSTANT(constants, SERVER); | |
NODE_DEFINE_CONSTANT(constants, IPC); | |
NODE_DEFINE_CONSTANT(constants, UV_READABLE); | |
NODE_DEFINE_CONSTANT(constants, UV_WRITABLE); | |
target->Set(context, | |
FIXED_ONE_BYTE_STRING(env->isolate(), "constants"), | |
constants).FromJust(); |
I’d encourage you to keep up with that pattern to prevent unexpected breakage from changes to the V8 definition, which is the source-of-truth for these values, even if it seems like a bit of extra work at this point (or leave to TODO comment for me, I’m happy to do the work myself if you prefer)
if (keys1.length !== getOwnNonIndexProperties(val2).length) { | ||
const keys1 = getOwnNonIndexProperties(val1, ONLY_ENUMERABLE); | ||
const keys2 = getOwnNonIndexProperties(val2, ONLY_ENUMERABLE); | ||
if (keys1.length !== keys2.length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for needing getOwnNonIndexProperties
should be brought up to the TC39 (if it hasn't already). It'd be good to let them know that Node is having to use engine level APIs to work around a JS lang limitation (no way to return a value with methods that return arrays of keys).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I already spoke to @littledan and I am writing the proposal at the moment. It's almost done.
Due to a new API it's possible to skip the indices. That allows to use auto completion with big (typed) arrays. Fixes: nodejs#21446
5c0904f
to
7be3845
Compare
Comments addressed. PTAL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just reaffirming my LGTM here :)
Due to a new API it's possible to skip the indices. That allows to use auto completion with big (typed) arrays. PR-URL: nodejs#22408 Fixes: nodejs#21446 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
Landed in 68b07de 🎉 |
Due to a new API it's possible to skip the indices. That allows to use auto completion with big (typed) arrays. PR-URL: #22408 Fixes: #21446 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
Due to a new API it's possible to skip the indices. That allows to use auto completion with big (typed) arrays. PR-URL: #22408 Fixes: #21446 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
Due to a new API it's possible to skip the indices. That allows to
use auto completion with big (typed) arrays.
Fixes: #21446
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes