Skip to content
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

Closed
wants to merge 3 commits into from

Conversation

BridgeAR
Copy link
Member

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), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. labels Aug 20, 2018
@BridgeAR
Copy link
Member Author

@nodejs/repl PTAL

Copy link
Member

@benjamingr benjamingr left a 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.

@@ -366,6 +366,14 @@ function isInsideNodeModules() {
return false;
}

const kPropertyFilter = Object.freeze({
Copy link
Member

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?

Copy link
Member

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.

node/src/pipe_wrap.cc

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)

Copy link
Member Author

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.

@@ -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');
Copy link
Member

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) {
Copy link
Member

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?

Copy link
Member Author

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())
Copy link
Member

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);
Copy link
Member

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.

Copy link
Member Author

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());
Copy link
Member

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)

@@ -366,6 +366,14 @@ function isInsideNodeModules() {
return false;
}

const kPropertyFilter = Object.freeze({
Copy link
Member

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.

node/src/pipe_wrap.cc

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) {
Copy link
Member

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).

Copy link
Member Author

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
@BridgeAR
Copy link
Member Author

Comments addressed. PTAL

CI https://ci.nodejs.org/job/node-test-pull-request/16612/

@addaleax addaleax added the repl Issues and PRs related to the REPL subsystem. label Aug 20, 2018
Copy link
Member

@addaleax addaleax left a 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 :)

@BridgeAR BridgeAR added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Aug 20, 2018
BridgeAR added a commit to BridgeAR/node that referenced this pull request Aug 22, 2018
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 <benjamingr@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@BridgeAR
Copy link
Member Author

Landed in 68b07de 🎉

@BridgeAR BridgeAR closed this Aug 22, 2018
targos pushed a commit that referenced this pull request Aug 24, 2018
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 <benjamingr@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
targos pushed a commit that referenced this pull request Sep 3, 2018
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 <benjamingr@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@BridgeAR BridgeAR deleted the auto-complete-big-arrays branch January 20, 2020 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. repl Issues and PRs related to the REPL subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

repl completion for large buffers fails to display named properties
5 participants