Skip to content

add AST strong types#719

Merged
OmarTawfik merged 3 commits intoNomicFoundation:mainfrom
OmarTawfik-forks:ast-types
Dec 23, 2023
Merged

add AST strong types#719
OmarTawfik merged 3 commits intoNomicFoundation:mainfrom
OmarTawfik-forks:ast-types

Conversation

@OmarTawfik
Copy link
Copy Markdown
Contributor

@OmarTawfik OmarTawfik commented Dec 20, 2023

Adds TypeScript AST types, and some initial tests. Additionally:

  • changed the DSL Item to be an enum of Rc<> variants, instead of an Rc<> to an enum, to make it easier to clone/store individual variants separately.
  • unified some inconsistent Rust/TypeScript node helpers: *_with_kind(), *_with_kinds(), *_is_kind()), ...

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Dec 20, 2023

🦋 Changeset detected

Latest commit: a6d9180

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@nomicfoundation/slang Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@OmarTawfik OmarTawfik marked this pull request as ready for review December 20, 2023 15:36
@OmarTawfik OmarTawfik requested a review from a team as a code owner December 20, 2023 15:36
@OmarTawfik OmarTawfik enabled auto-merge December 20, 2023 15:52
@OmarTawfik OmarTawfik linked an issue Dec 21, 2023 that may be closed by this pull request
Copy link
Copy Markdown
Contributor

@Xanewok Xanewok left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial pass, I'll come back to this later. Overall, it's great to see that land soon; good job!

@Xanewok
Copy link
Copy Markdown
Contributor

Xanewok commented Dec 21, 2023 via email

@Xanewok
Copy link
Copy Markdown
Contributor

Xanewok commented Dec 21, 2023 via email

Copy link
Copy Markdown
Contributor

@Xanewok Xanewok left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm excited to finally have the AST types, great job 🎉 I left some comments for the doc example and for the frontend/backend distinction. Also, it'd be great to clean up a bit the codegen pipeline since it's getting messy but we decided to punt that to Q1.

I understand we have a holiday season now and so there's some time pressure, so I don't want to block this now; we can address further feedback separately/later in Q1.

Quite a holiday gift; happy holidays and again, great job 🎉

)?;

CodeGenerator::write_source(&crate_dir.join("src/generated"), &grammar)?;
CodeGenerator::write_frontend(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to change the backend/frontend naming here as well since it's slightly confusing, but let's do that in a follow-up.


#[derive(Debug, thiserror::Error)]
enum Error {
// Should not theoritically happen, since we're only called from our own generated AST types.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Should not theoritically happen, since we're only called from our own generated AST types.
// Should not theoretically happen, since we're only called from our own generated AST types.

#[error("Unexpected parent node with RuleKind '{0}'.")]
UnexpectedParent(RuleKind),

// Should not theoritically happen, since we're only called from our own generated AST types.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Should not theoritically happen, since we're only called from our own generated AST types.
// Should not theoretically happen, since we're only called from our own generated AST types.

#[error("Unexpected trailing children at index '{0}'.")]
UnexpectedTrailing(usize),

// Should not theoritically happen, unless AST error recovery was changed.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Should not theoritically happen, unless AST error recovery was changed.
// Should not theoretically happen, unless AST error recovery was changed.

Ok(None)
}

fn finalize(&mut self) -> Result<()> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: If I understand the intent correctly, this should probably consume the type with self to better express intent/disallow calling twice

```

### Example 2: List the top-level contracts and their names
### Example 2: Reading Contracts using Cursors
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Saying we "read" them in this example is, I feel like, a bit too generous - we're only fetching the name, which is a direct token child of the encompassing rule. It'd be better if we had some more examples on how to practically read the contracts (listing public/external functions, errors etc.) and use that wording there

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also I feel that "contracts" should be lower case since it refers to contracts generally; Cursor is okay since it's the Cursor API/structs we expose

The `Cursor` type provides procedural-style functions that allow you to navigate the source in a step-by-step manner. In addition to `goToNext`, we can go to the parent, first child, next sibling, etc., as well as nodes with a given kind.

To list the top-level contracts and their names, we need to visit the `ContractDefinition` rule nodes and then their `Identifier` children.
Let's start with this piece of solidity source code:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Let's start with this piece of solidity source code:
Let's start with this piece of Solidity source code:


AST types are a set of TypeScript classes that provide a typed view of the untyped CST nodes.
You can convert any untyped CST node to its corresponding AST type using their constructors.
AST types are immutable, and are constructed on the fly, as they are used/accessed for the first time.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
AST types are immutable, and are constructed on the fly, as they are used/accessed for the first time.
AST types are immutable and are constructed on the fly as they are used/accessed for the first time.

small suggestion: Maybe "lazily" would fit better instead of "on the fly"? Seems like it would be more intuitive for the (programming) reader.

@OmarTawfik OmarTawfik added this pull request to the merge queue Dec 23, 2023
Merged via the queue into NomicFoundation:main with commit 1ad6bb3 Dec 23, 2023
@OmarTawfik OmarTawfik deleted the ast-types branch December 23, 2023 11:02
@github-actions github-actions bot mentioned this pull request Dec 23, 2023
OmarTawfik added a commit to OmarTawfik-forks/slang that referenced this pull request Jan 3, 2024
- address later feedback on NomicFoundation#719
- fix syntax highlighting for TS templates
- use `ReadonlyArray<T>` in return types instead of `Array<T>`.
- use `undefined` instead of `null` for optional fields, as it is more idiomatic.
@OmarTawfik OmarTawfik mentioned this pull request Jan 3, 2024
github-merge-queue bot pushed a commit that referenced this pull request Jan 3, 2024
- address later feedback on #719
- fix syntax highlighting for TS templates
- use `ReadonlyArray<T>` in return types instead of `Array<T>`.
- use `undefined` instead of `null` for optional fields, as it is more
idiomatic.
github-merge-queue bot pushed a commit that referenced this pull request Jan 11, 2024
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and publish to npm
yourself or [setup this action to publish
automatically](https://github.com/changesets/action#with-publishing). If
you're not ready to do a release yet, that's fine, whenever you add more
changesets to main, this PR will be updated.


# Releases
## @nomicfoundation/slang@0.13.0

### Minor Changes

- [#710](#710)
[`2025b6cb`](2025b6c)
Thanks [@Xanewok](https://github.com/Xanewok)! - CST children nodes are
now named

- [#723](#723)
[`b3dc6bcd`](b3dc6bc)
Thanks [@Xanewok](https://github.com/Xanewok)! - Properly parse
unreserved keywords in an identifier position, i.e. `from`, `emit`,
`global` etc.

- [#728](#728)
[`662a672c`](662a672)
Thanks [@Xanewok](https://github.com/Xanewok)! - Remove Language#scan
API; use the parser API instead

- [#719](#719)
[`1ad6bb37`](1ad6bb3)
Thanks [@OmarTawfik](https://github.com/OmarTawfik)! - introduce strong
types for all Solidity non terminals in the TypeScript API.

### Patch Changes

- [#719](#719)
[`1ad6bb37`](1ad6bb3)
Thanks [@OmarTawfik](https://github.com/OmarTawfik)! - unify
Rust/TypeScript node helpers: `*_with_kind()`, `*_with_kinds()`,
`*_is_kind()`), ...

- [#731](#731)
[`3deaea2e`](3deaea2)
Thanks [@OmarTawfik](https://github.com/OmarTawfik)! - add
`RuleNode.unparse()` to the TypeScript API

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
rollup-smithbm0p added a commit to rollup-smithbm0p/slang that referenced this pull request Dec 26, 2025
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and publish to npm
yourself or [setup this action to publish
automatically](https://github.com/changesets/action#with-publishing). If
you're not ready to do a release yet, that's fine, whenever you add more
changesets to main, this PR will be updated.


# Releases
## @nomicfoundation/slang@0.13.0

### Minor Changes

- [#710](NomicFoundation/slang#710)
[`2025b6cb`](NomicFoundation/slang@2025b6c)
Thanks [@Xanewok](https://github.com/Xanewok)! - CST children nodes are
now named

- [#723](NomicFoundation/slang#723)
[`b3dc6bcd`](NomicFoundation/slang@b3dc6bc)
Thanks [@Xanewok](https://github.com/Xanewok)! - Properly parse
unreserved keywords in an identifier position, i.e. `from`, `emit`,
`global` etc.

- [#728](NomicFoundation/slang#728)
[`662a672c`](NomicFoundation/slang@662a672)
Thanks [@Xanewok](https://github.com/Xanewok)! - Remove Language#scan
API; use the parser API instead

- [#719](NomicFoundation/slang#719)
[`1ad6bb37`](NomicFoundation/slang@1ad6bb3)
Thanks [@OmarTawfik](https://github.com/OmarTawfik)! - introduce strong
types for all Solidity non terminals in the TypeScript API.

### Patch Changes

- [#719](NomicFoundation/slang#719)
[`1ad6bb37`](NomicFoundation/slang@1ad6bb3)
Thanks [@OmarTawfik](https://github.com/OmarTawfik)! - unify
Rust/TypeScript node helpers: `*_with_kind()`, `*_with_kinds()`,
`*_is_kind()`), ...

- [#731](NomicFoundation/slang#731)
[`3deaea2e`](NomicFoundation/slang@3deaea2)
Thanks [@OmarTawfik](https://github.com/OmarTawfik)! - add
`RuleNode.unparse()` to the TypeScript API

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement a Typed AST

3 participants