-
Notifications
You must be signed in to change notification settings - Fork 666
feat(rome_rowan): expose the kind of AstNode as a constant #2774
Conversation
Parser conformance results on ubuntu-latestjs/262
jsx/babel
symbols/microsoft
ts/babel
ts/microsoft
|
/// bitfield here being twice as large as it needs to cover all nodes as well | ||
/// as all token kinds | ||
#[derive(Clone, Copy, Debug, PartialEq, Eq)] | ||
pub struct SyntaxKindSet<L: ?Sized + Language>([u128; 4], PhantomData<L>); |
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 the solution be to increase the array length if it happens that we encounter a union that has more than 32 (4*128/32) variants?
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 length of the array would need to be increased if any SyntaxKind
ever got more than 512 (128*4) variants, currently the largest one is JsSyntaxKind
with 481 variants
crates/rome_rowan/src/green.rs
Outdated
@@ -18,6 +18,20 @@ pub(crate) use self::node_cache::NodeCacheNodeEntryMut; | |||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | |||
pub struct RawSyntaxKind(pub u16); | |||
|
|||
impl RawSyntaxKind { | |||
pub(crate) const fn as_bits(self) -> [u128; 4] { |
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.
Can you add some documentation to this part that explains what is happening here? I wouldn't know what to make of this function or how to change it in the future.
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've inlined the as_bits
function in the 2 places it's used in SyntaxKindSet
to make it easier to understand what it's doing in context. I also modified how the function is implemented to make easier to extend the size of the bitfield without having to introduce additional branches (I wasn't sure Rust's constant folding would be able to statically check it for error like this, but it turned out to work just as well)
Deploying with Cloudflare Pages
|
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.
Could you please add some example, somewhere, of how to use this new feature?
crates/rome_analyze/src/registry.rs
Outdated
} | ||
} | ||
|
||
pub type MetadataIter<L> = | ||
Map<IntoIter<RegistryRule<L>>, fn(RegistryRule<L>) -> (&'static str, &'static str)>; | ||
struct KindRules<L: Language> { |
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.
What's a KindRules
? Should it be a RuleKind
? Could you add some doc?
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.
@leops I think you missed this comment. I believe this should be RulesKind
. KindRules
has a different meaning 😝
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.
Interesting, I added some documentation to this struct but it's not showing in the code block attached to the comment in the conversation tab.
I think KindRules
feels more natural to read left-to-right since it maps a single SyntaxKind
to multiple Rule
, whereas RulesKind
feels more ambiguous: the -Kind
suffix is generally used for enums, so it could be understood as "the kind of a collection of rules" when it's in fact a struct holding said collection of rules
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's more about english grammar here 😅 "kind rules" is like "kind person", which is the adjective to address a person that is "sweet, gentle, etc.", which is not the meaning we want to have. I'd suggest to find another wording
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 guess then SyntaxKindRules
would work, it makes it clearer that "kind" refers to the SyntaxKind
trait
The new feature is being used in registry.rs to store rules in a flat vector, with each index of the vector being associated with the corresponding |
That's exactly why I think having a documented example would be beneficial for us. I looked at it and honestly I didn't understand some parts of it (for example the |
c12f651
to
8408bb3
Compare
Summary
This PR adds a new
KIND_SET
associated constant to theAstNode
, representing the set ofSyntaxKind
values that can be cast into this node (thecan_cast
function would return true for these values). This allows code to statically list out all node types that match a certain node type, to optimize query matching in the analyzer for instance.Example
This code uses the new feature to list the variants of
JsSyntaxKind
that can be cast intoJsAnyRoot
:Test Plan
This is mostly a codegen change, and with most operations on
SyntaxKindSet
beingconst
almost all these operations are checked at compile time (adding enough variants toJsSyntaxKind
to make it overflow the 64 bytes of the bitfield would cause a compilation error for instance).The changes to the rule registry are tested indirectly through the integration tests of the analyzer, ensuring that queries are still matched correctly