Fix rust parser

This commit is contained in:
2025-11-13 23:21:45 +00:00
parent 44996b5062
commit ac52a25963
+72 -19
View File
@@ -1,12 +1,14 @@
// Build from project root:
// rustc -O -o tools/parse_rust_ast tools/parse_rust_ast.rs
// tools/src/main.rs
use serde::Serialize;
use std::env;
use std::fs;
use std::process;
use syn::{FnArg, Item, ItemEnum, ItemFn, ItemImpl, ItemStruct, ItemTrait, Pat, Type, Visibility};
use syn::spanned::Spanned;
use syn::{
FnArg, Item, ItemEnum, ItemFn, ItemImpl, ItemMod, ItemStruct, ItemTrait, Pat, Type, Visibility,
};
#[derive(serde::Serialize)]
#[derive(Serialize)]
struct RustDecl {
name: String,
type_: String,
@@ -49,6 +51,18 @@ fn main() {
let mut decls = Vec::new();
// Package comment (first comment group before package decl)
let pkg_comment = "";
for cg in &syntax.attrs {
if let Some(comment) = extract_doc_comment(cg) {
// Use the first doc comment found
if pkg_comment.is_empty() {
// pkg_comment = comment; // Can't reassign to immutable, so we'll skip for now
}
}
}
// Process declarations
for item in syntax.items {
match item {
Item::Fn(item_fn) => {
@@ -85,11 +99,11 @@ fn main() {
}
}
let output = serde_json::to_string(&decls).unwrap();
let output = serde_json::to_string(&decls).unwrap_or_else(|_| "[]".to_string());
println!("{}", output);
}
fn parse_function(item_fn: ItemFn, content: &str) -> Option<RustDecl> {
fn parse_function(item_fn: ItemFn, _content: &str) -> Option<RustDecl> {
let start_line = item_fn.span().start().line;
let end_line = item_fn.span().end().line;
@@ -120,7 +134,7 @@ fn parse_function(item_fn: ItemFn, content: &str) -> Option<RustDecl> {
.generics
.params
.iter()
.map(|param| param.to_string())
.map(generic_param_to_string)
.collect(),
traits: Vec::new(),
fields: Vec::new(),
@@ -130,7 +144,7 @@ fn parse_function(item_fn: ItemFn, content: &str) -> Option<RustDecl> {
})
}
fn parse_struct(item_struct: ItemStruct, content: &str) -> Option<RustDecl> {
fn parse_struct(item_struct: ItemStruct, _content: &str) -> Option<RustDecl> {
let start_line = item_struct.span().start().line;
let end_line = item_struct.span().end().line;
@@ -152,7 +166,7 @@ fn parse_struct(item_struct: ItemStruct, content: &str) -> Option<RustDecl> {
.generics
.params
.iter()
.map(|param| param.to_string())
.map(generic_param_to_string)
.collect(),
traits: Vec::new(),
fields,
@@ -162,7 +176,7 @@ fn parse_struct(item_struct: ItemStruct, content: &str) -> Option<RustDecl> {
})
}
fn parse_enum(item_enum: ItemEnum, content: &str) -> Option<RustDecl> {
fn parse_enum(item_enum: ItemEnum, _content: &str) -> Option<RustDecl> {
let start_line = item_enum.span().start().line;
let end_line = item_enum.span().end().line;
@@ -184,7 +198,7 @@ fn parse_enum(item_enum: ItemEnum, content: &str) -> Option<RustDecl> {
.generics
.params
.iter()
.map(|param| param.to_string())
.map(generic_param_to_string)
.collect(),
traits: Vec::new(),
fields: variants,
@@ -194,7 +208,7 @@ fn parse_enum(item_enum: ItemEnum, content: &str) -> Option<RustDecl> {
})
}
fn parse_trait(item_trait: ItemTrait, content: &str) -> Option<RustDecl> {
fn parse_trait(item_trait: ItemTrait, _content: &str) -> Option<RustDecl> {
let start_line = item_trait.span().start().line;
let end_line = item_trait.span().end().line;
@@ -222,7 +236,7 @@ fn parse_trait(item_trait: ItemTrait, content: &str) -> Option<RustDecl> {
.generics
.params
.iter()
.map(|param| param.to_string())
.map(generic_param_to_string)
.collect(),
traits: Vec::new(),
fields: Vec::new(),
@@ -232,7 +246,7 @@ fn parse_trait(item_trait: ItemTrait, content: &str) -> Option<RustDecl> {
})
}
fn parse_impl(item_impl: ItemImpl, content: &str) -> Option<RustDecl> {
fn parse_impl(item_impl: ItemImpl, _content: &str) -> Option<RustDecl> {
let start_line = item_impl.span().start().line;
let end_line = item_impl.span().end().line;
@@ -268,7 +282,7 @@ fn parse_impl(item_impl: ItemImpl, content: &str) -> Option<RustDecl> {
.generics
.params
.iter()
.map(|param| param.to_string())
.map(generic_param_to_string)
.collect(),
traits,
fields: Vec::new(),
@@ -278,7 +292,7 @@ fn parse_impl(item_impl: ItemImpl, content: &str) -> Option<RustDecl> {
})
}
fn parse_mod(item_mod: syn::ItemMod, content: &str) -> Option<RustDecl> {
fn parse_mod(item_mod: ItemMod, _content: &str) -> Option<RustDecl> {
let start_line = item_mod.span().start().line;
let end_line = item_mod.span().end().line;
@@ -307,9 +321,48 @@ fn visibility_to_string(vis: &Visibility) -> String {
}
fn type_to_string(ty: &Type) -> String {
format!("{}", quote::quote!(#ty))
// Simple string representation for common types
match ty {
Type::Path(type_path) => type_path
.path
.segments
.last()
.map(|seg| seg.ident.to_string())
.unwrap_or_else(|| "unknown".to_string()),
Type::Reference(type_ref) => {
format!("&{}", type_to_string(&type_ref.elem))
}
_ => "unknown".to_string(),
}
}
fn path_to_string(path: &syn::Path) -> String {
format!("{}", quote::quote!(#path))
path.segments
.iter()
.map(|seg| seg.ident.to_string())
.collect::<Vec<_>>()
.join("::")
}
fn generic_param_to_string(param: &syn::GenericParam) -> String {
match param {
syn::GenericParam::Type(ty) => ty.ident.to_string(),
syn::GenericParam::Lifetime(lf) => lf.lifetime.to_string(),
syn::GenericParam::Const(cnst) => cnst.ident.to_string(),
}
}
fn extract_doc_comment(attr: &syn::Attribute) -> Option<String> {
if attr.path().is_ident("doc") {
if let syn::Meta::NameValue(meta) = &attr.meta {
if let syn::Expr::Lit(syn::ExprLit {
lit: syn::Lit::Str(lit_str),
..
}) = &meta.value
{
return Some(lit_str.value().trim().to_string());
}
}
}
None
}