refactor: Reduce codegen burden for SyntaxKind

This commit is contained in:
Lukas Wirth 2025-03-21 10:26:36 +01:00
parent 8316ffeab1
commit d6dc1bf05e
6 changed files with 76 additions and 38 deletions

View file

@ -21,7 +21,7 @@ impl flags::Codegen {
pub(crate) fn run(self, _sh: &Shell) -> anyhow::Result<()> {
match self.codegen_type.unwrap_or_default() {
flags::CodegenType::All => {
diagnostics_docs::generate(self.check);
grammar::generate(self.check);
assists_doc_tests::generate(self.check);
parser_inline_tests::generate(self.check);
feature_docs::generate(self.check)

View file

@ -476,7 +476,6 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String {
let tokens = grammar.tokens.iter().map(|name| format_ident!("{}", name)).collect::<Vec<_>>();
// FIXME: This generates enum kinds?
let nodes = grammar.nodes.iter().map(|name| format_ident!("{}", name)).collect::<Vec<_>>();
let ast = quote! {
@ -484,7 +483,7 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String {
use crate::Edition;
/// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT`.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(Debug)]
#[repr(u16)]
pub enum SyntaxKind {
// Technical SyntaxKinds: they appear temporally during parsing,
@ -585,7 +584,7 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String {
}
#[macro_export]
macro_rules! T {
macro_rules! T_ {
#([#punctuation_values] => { $crate::SyntaxKind::#punctuation };)*
#([#strict_keywords_tokens] => { $crate::SyntaxKind::#strict_keywords_variants };)*
#([#contextual_keywords_tokens] => { $crate::SyntaxKind::#contextual_keywords_variants };)*
@ -596,6 +595,38 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String {
[string] => { $crate::SyntaxKind::STRING };
[shebang] => { $crate::SyntaxKind::SHEBANG };
}
impl ::core::marker::Copy for SyntaxKind {}
impl ::core::clone::Clone for SyntaxKind {
#[inline]
fn clone(&self) -> Self {
*self
}
}
impl ::core::cmp::PartialEq for SyntaxKind {
#[inline]
fn eq(&self, other: &Self) -> bool {
(*self as u16) == (*other as u16)
}
}
impl ::core::cmp::Eq for SyntaxKind {}
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))
}
}
impl ::core::cmp::Ord for SyntaxKind {
#[inline]
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
(*self as u16).cmp(&(*other as u16))
}
}
impl ::core::hash::Hash for SyntaxKind {
fn hash<H: ::core::hash::Hasher>(&self, state: &mut H) {
::core::mem::discriminant(self).hash(state);
}
}
};
add_preamble(crate::flags::CodegenType::Grammar, reformat(ast.to_string()))

View file

@ -12,6 +12,7 @@ pub(crate) struct KindsSrc {
pub(crate) literals: &'static [&'static str],
pub(crate) tokens: &'static [&'static str],
pub(crate) nodes: &'static [&'static str],
pub(crate) _enums: &'static [&'static str],
pub(crate) edition_dependent_keywords: &'static [(&'static str, Edition)],
}
@ -206,13 +207,21 @@ pub(crate) fn generate_kind_src(
let nodes = nodes
.iter()
.map(|it| &it.name)
.chain(enums.iter().map(|it| &it.name))
.map(|it| to_upper_snake_case(it))
.map(String::leak)
.map(|it| &*it)
.collect();
let nodes = Vec::leak(nodes);
nodes.sort();
let enums = enums
.iter()
.map(|it| &it.name)
.map(|it| to_upper_snake_case(it))
.map(String::leak)
.map(|it| &*it)
.collect();
let enums = Vec::leak(enums);
enums.sort();
let keywords = Vec::leak(keywords);
let contextual_keywords = Vec::leak(contextual_keywords);
let edition_dependent_keywords = Vec::leak(edition_dependent_keywords);
@ -224,6 +233,7 @@ pub(crate) fn generate_kind_src(
KindsSrc {
punct: PUNCT,
nodes,
_enums: enums,
keywords,
contextual_keywords,
edition_dependent_keywords,