Fix rust parser
This commit is contained in:
+72
-19
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user