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

NAPI Serialization for Nodes #466

Closed
OmarTawfik opened this issue May 16, 2023 · 1 comment · Fixed by #908
Closed

NAPI Serialization for Nodes #466

OmarTawfik opened this issue May 16, 2023 · 1 comment · Fixed by #908
Assignees

Comments

@OmarTawfik
Copy link
Collaborator

OmarTawfik commented May 16, 2023

First reported by @antico5

On Rust, our types do have [serde] attributes for serialization. But on TS side, the types are properties that cannot be JSON.stringify()ied or visualized easily. One workaround is to do:

console.log(
  util.inspect(parseTree, {
    getters: true,
    showHidden: true,
    showProxy: true,
    depth: Infinity,
  })
);

Which produces something like:

RuleNode {
  kind: [Getter: 93],
  range: [Getter] [ 0n, 170n, [length]: 2 ],
  rangeIncludingTrivia: [Getter] [ 0n, 170n, [length]: 2 ],
  type: [Getter: 0]
}

But that is not enough. To make it easier for developers to use this, we can do two things:

One: JSON serialization

  • Expose the [serde] JSON serialization/deserialization through TypeScript APIs on each node. Example:
    • node.toJSON() -> string
    • Node.fromJSON(string) -> Node
  • Expose TypeScript types for the RAW nodes (plain object fields instead of properties), to make it easy to share the CST nodes with other consumers, without having to rely on Slang NAPI boundary to interact with them.

Two: Debugger Visualization

They also reported having to implement their own serialization just to visualize the tree. Example:

Rule: SourceUnit "// SPDX-License-I..."
  Rule: _REPEATED "// SPDX-License-I..."
    Rule: Directive "// SPDX-License-I..."
      Rule: PragmaDirective "// SPDX-License-I..."
# ... redacted

However, instead of leaving it up to users, we can also provide such API, especially that we already have an internal one for unit tests snapshots:

- MappingType (Rule): # 0..30 "mapping(string => bytes32 Bar)"
- MappingKeyword (Token): "mapping" # 0..7
- OpenParen (Token): "(" # 7..8
- MappingKeyType (Rule): # 8..14 "string"
- ElementaryType (Rule): # 8..14 "string"
- StringKeyword (Token): "string" # 8..14
- EqualGreaterThan (Token): "=>" # 15..17
- MappingValueType (Rule): # 18..29 "bytes32 Bar"
- TypeName (Rule): # 18..25 "bytes32"
- ElementaryType (Rule): # 18..25 "bytes32"
- FixedBytesType (Token): "bytes32" # 18..25
- Identifier (Token): "Bar" # 26..29
- CloseParen (Token): ")" # 29..30

We can probably expose this for both Rust and TypeScript, as a public API, with explicitly warning users that this is for dev-time visualization only, and its structure is subject to change at any time.

An additional benefit to this is that TypeScript will be able to generate the same visualization as Rust, unblocking #439

@OmarTawfik OmarTawfik added this to the 2️⃣ Beta Preview milestone May 16, 2023
@OmarTawfik OmarTawfik removed this from the 2️⃣ Beta Preview milestone Jul 11, 2023
@OmarTawfik OmarTawfik self-assigned this Jul 19, 2023
@OmarTawfik OmarTawfik removed their assignment Dec 5, 2023
This was referenced Feb 13, 2024
@Xanewok
Copy link
Contributor

Xanewok commented Mar 7, 2024

This might be a handy resource for the debugger visualisation: microsoft/vscode#26234

github-merge-queue bot pushed a commit that referenced this issue Apr 11, 2024
Closes #466 

## JSON serialization
Adds the `toJSON` method to the RuleNode/TokenNode classes with the
comment stating that it's unstable and for debugging purposes only. I
explicitly didn't type it (it's a string) as I didn't want to publicly
encode any assumptions about the shape of the data.

We can discuss further what we want to explore as part of having pure
data external interface (JSON) for Slang, whether that's exporting or
importing JSON, but I'd consider this a separate issue as it requires
more thought and design; the original issue, from what I understand, was
primarily about improving the debugging/inspection experience.

## Debugger
Adds hidden getter properties that is only eagerly evaluated by
debugger; since it's a getter function, it shouldn't add overhead to the
runtime but I have to admit, I didn't double-check that with numbers. It
adds both `__children` and `__text`, allowing to quickly explore the
tree structure recursively and also the enclosing text scope of the
node:

### vscode-js-debug (built-in to VS Code)

![image](https://github.com/NomicFoundation/slang/assets/3093213/193702fa-02b6-4853-9dcd-8af58469cf23)
### Chrome DevTools for Node

![image](https://github.com/NomicFoundation/slang/assets/3093213/a7b81836-ad7e-495c-aded-ebcc48f3bb6b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Status: ✅ Done
Development

Successfully merging a pull request may close this issue.

3 participants