BetterThanTomorrow / joyride

Making VS Code Hackable like Emacs since 2022
https://marketplace.visualstudio.com/items?itemName=betterthantomorrow.joyride
Other
469 stars 17 forks source link

Add `joyride.core/js-keys` for getting full API #148

Closed PEZ closed 1 year ago

PEZ commented 1 year ago

Adding a function to joyride.core for getting the full API of js objects. Utilizing the node repl, which goes through quite some length to find all attributes.

Not sure about naming it js-keys. Not sure about it returning a JavaScript array, but since cljs.core/js-keys does that, I followed suit, as long as it is named the same. WDYT?

borkdude commented 1 year ago

Should this also be used from the joyride nREPL completions?

borkdude commented 1 year ago

And can you tell me what exactly is the function doing on top of getOwnPropertyNames etc?

PEZ commented 1 year ago

Should this also be used from the joyride nREPL completions?

I was hoping we could do that in a follow-up. But I don't know how to do it, as it is async.

borkdude commented 1 year ago

@PEZ I'd like to take the opportunity to dig a little deeper here and see what this REPL completer actually is doing. Did you look at any of that?

PEZ commented 1 year ago

And can you tell me what exactly is the function doing on top of getOwnPropertyNames etc?

You mean what node:repl.completer is doing? I'm not completely in the know. But some things are that it also returns properties that are:

It also can consider stuff in the closure of the current scope, even if I don't think we are utilizing that in the way it is used in this PR.

If the question is more about how it does it, I am even less clued in. =) I did read the node docs a bit about it, and saw that it fires up an execution context where these completions happen. This is why we need to provide context objects, I think. Also makes it pretty safe to complete things, since it happens ”somewhere else”.

PEZ commented 1 year ago

Iiuc, it is the underpinnings of completions in the node repl meeting us when we just type node at the shell prompt.

borkdude commented 1 year ago

inherited from the prototype chain

This is what the nREPL completions are already doing I think.

https://github.com/BetterThanTomorrow/joyride/blob/0ed2ef9caaa26c45c4d0c40dce93e2d42fe5e716/src/joyride/repl_utils.cljs#L51-L58

Does that code (when extracted into a function) detect the extension properties?

PEZ commented 1 year ago

Does that code (when extracted into a function) detect the extension properties?

I doubt it will have them all, since there are probably things from getters and setters there and possibly non-enumerable stuff as well.

But I can check what we get.

PEZ commented 1 year ago

Now checked. We get all properties that node completer returns, and then some:

Node completer:

["__proto__"
 "hasOwnProperty"
 "isPrototypeOf"
 "propertyIsEnumerable"
 "toLocaleString"
 "toString"
 "valueOf"
 "activate"
 "constructor"
 "exports"
 "isActive"
 "extensionKind"
 "extensionPath"
 "extensionUri"
 "id"
 "isFromDifferentExtensionHost"
 "packageJSON"]

repl-util completions:

["id"
 "extensionUri"
 "extensionPath"
 "packageJSON"
 "extensionKind"
 "isFromDifferentExtensionHost"
 "constructor"
 "isActive"
 "exports"
 "activate"
 "constructor"
 "__defineGetter__"
 "__defineSetter__"
 "hasOwnProperty"
 "__lookupGetter__"
 "__lookupSetter__"
 "isPrototypeOf"
 "propertyIsEnumerable"
 "toString"
 "valueOf"
 "__proto__"
 "toLocaleString"]

The diff:

#{"__lookupGetter__"
  "__defineSetter__"
  "__lookupSetter__"
  "__defineGetter__"}
PEZ commented 1 year ago

I've pushed a commit using the existing repl-utils for getting the properties instead. Added a test with some explicitly non-enumerable properties to see that we get those.

PEZ commented 1 year ago

I opted for making it completer-alike, and included this in the doc string. Figured people coming from a JS background might wonder why it differs.

borkdude commented 1 year ago

Alright, LGTM