refactor: Reduce codegen burden for SyntaxNode and SyntaxToken

This commit is contained in:
Lukas Wirth 2025-03-21 10:54:38 +01:00
parent d6dc1bf05e
commit d31301cbe7
4 changed files with 2767 additions and 426 deletions

View file

@ -67,7 +67,6 @@ fn generate_tokens(grammar: &AstSrc) -> String {
let name = format_ident!("{}", token);
let kind = format_ident!("{}", to_upper_snake_case(token));
quote! {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct #name {
pub(crate) syntax: SyntaxToken,
}
@ -83,6 +82,29 @@ fn generate_tokens(grammar: &AstSrc) -> String {
}
fn syntax(&self) -> &SyntaxToken { &self.syntax }
}
impl fmt::Debug for #name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct(#token).field("syntax", &self.syntax).finish()
}
}
impl Clone for #name {
fn clone(&self) -> Self {
Self { syntax: self.syntax.clone() }
}
}
impl hash::Hash for #name {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.syntax.hash(state);
}
}
impl Eq for #name {}
impl PartialEq for #name {
fn eq(&self, other: &Self) -> bool {
self.syntax == other.syntax
}
}
}
});
@ -90,7 +112,10 @@ fn generate_tokens(grammar: &AstSrc) -> String {
crate::flags::CodegenType::Grammar,
reformat(
quote! {
use std::{fmt, hash};
use crate::{SyntaxKind::{self, *}, SyntaxToken, ast::AstToken};
#(#tokens)*
}
.to_string(),
@ -104,6 +129,7 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String {
.nodes
.iter()
.map(|node| {
let node_str_name = &node.name;
let name = format_ident!("{}", node.name);
let kind = format_ident!("{}", to_upper_snake_case(&node.name));
let traits = node
@ -149,7 +175,6 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String {
(
quote! {
#[pretty_doc_comment_placeholder_workaround]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct #name {
pub(crate) syntax: SyntaxNode,
}
@ -180,6 +205,31 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String {
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl hash::Hash for #name {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.syntax.hash(state);
}
}
impl Eq for #name {}
impl PartialEq for #name {
fn eq(&self, other: &Self) -> bool {
self.syntax == other.syntax
}
}
impl Clone for #name {
fn clone(&self) -> Self {
Self { syntax: self.syntax.clone() }
}
}
impl fmt::Debug for #name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct(#node_str_name).field("syntax", &self.syntax).finish()
}
}
},
)
})
@ -265,6 +315,7 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String {
.sorted_by_key(|(name, _)| *name)
.map(|(trait_name, nodes)| {
let name = format_ident!("Any{}", trait_name);
let node_str_name = name.to_string();
let trait_name = format_ident!("{}", trait_name);
let kinds: Vec<_> = nodes
.iter()
@ -274,13 +325,9 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String {
(
quote! {
#[pretty_doc_comment_placeholder_workaround]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct #name {
pub(crate) syntax: SyntaxNode,
}
impl ast::#trait_name for #name {}
},
quote! {
impl #name {
#[inline]
pub fn new<T: ast::#trait_name>(node: T) -> #name {
@ -289,6 +336,9 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String {
}
}
}
},
quote! {
impl ast::#trait_name for #name {}
impl AstNode for #name {
#[inline]
fn can_cast(kind: SyntaxKind) -> bool {
@ -304,6 +354,31 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String {
}
}
impl hash::Hash for #name {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.syntax.hash(state);
}
}
impl Eq for #name {}
impl PartialEq for #name {
fn eq(&self, other: &Self) -> bool {
self.syntax == other.syntax
}
}
impl Clone for #name {
fn clone(&self) -> Self {
Self { syntax: self.syntax.clone() }
}
}
impl fmt::Debug for #name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct(#node_str_name).field("syntax", &self.syntax).finish()
}
}
#(
impl From<#nodes> for #name {
#[inline]
@ -346,6 +421,8 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String {
let ast = quote! {
#![allow(non_snake_case)]
use std::{fmt, hash};
use crate::{
SyntaxNode, SyntaxToken, SyntaxKind::{self, *},
ast::{self, AstNode, AstChildren, support},
@ -613,7 +690,7 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String {
impl ::core::cmp::PartialOrd for SyntaxKind {
#[inline]
fn partial_cmp(&self, other: &Self) -> core::option::Option<core::cmp::Ordering> {
(*self as u16).partial_cmp(&(*other as u16))
Some(self.cmp(other))
}
}
impl ::core::cmp::Ord for SyntaxKind {