Fix rust parser
This commit is contained in:
+72
-19
@@ -1,12 +1,14 @@
|
|||||||
// Build from project root:
|
// tools/src/main.rs
|
||||||
// rustc -O -o tools/parse_rust_ast tools/parse_rust_ast.rs
|
use serde::Serialize;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::process;
|
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 {
|
struct RustDecl {
|
||||||
name: String,
|
name: String,
|
||||||
type_: String,
|
type_: String,
|
||||||
@@ -49,6 +51,18 @@ fn main() {
|
|||||||
|
|
||||||
let mut decls = Vec::new();
|
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 {
|
for item in syntax.items {
|
||||||
match item {
|
match item {
|
||||||
Item::Fn(item_fn) => {
|
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);
|
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 start_line = item_fn.span().start().line;
|
||||||
let end_line = item_fn.span().end().line;
|
let end_line = item_fn.span().end().line;
|
||||||
|
|
||||||
@@ -120,7 +134,7 @@ fn parse_function(item_fn: ItemFn, content: &str) -> Option<RustDecl> {
|
|||||||
.generics
|
.generics
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|param| param.to_string())
|
.map(generic_param_to_string)
|
||||||
.collect(),
|
.collect(),
|
||||||
traits: Vec::new(),
|
traits: Vec::new(),
|
||||||
fields: 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 start_line = item_struct.span().start().line;
|
||||||
let end_line = item_struct.span().end().line;
|
let end_line = item_struct.span().end().line;
|
||||||
|
|
||||||
@@ -152,7 +166,7 @@ fn parse_struct(item_struct: ItemStruct, content: &str) -> Option<RustDecl> {
|
|||||||
.generics
|
.generics
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|param| param.to_string())
|
.map(generic_param_to_string)
|
||||||
.collect(),
|
.collect(),
|
||||||
traits: Vec::new(),
|
traits: Vec::new(),
|
||||||
fields,
|
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 start_line = item_enum.span().start().line;
|
||||||
let end_line = item_enum.span().end().line;
|
let end_line = item_enum.span().end().line;
|
||||||
|
|
||||||
@@ -184,7 +198,7 @@ fn parse_enum(item_enum: ItemEnum, content: &str) -> Option<RustDecl> {
|
|||||||
.generics
|
.generics
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|param| param.to_string())
|
.map(generic_param_to_string)
|
||||||
.collect(),
|
.collect(),
|
||||||
traits: Vec::new(),
|
traits: Vec::new(),
|
||||||
fields: variants,
|
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 start_line = item_trait.span().start().line;
|
||||||
let end_line = item_trait.span().end().line;
|
let end_line = item_trait.span().end().line;
|
||||||
|
|
||||||
@@ -222,7 +236,7 @@ fn parse_trait(item_trait: ItemTrait, content: &str) -> Option<RustDecl> {
|
|||||||
.generics
|
.generics
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|param| param.to_string())
|
.map(generic_param_to_string)
|
||||||
.collect(),
|
.collect(),
|
||||||
traits: Vec::new(),
|
traits: Vec::new(),
|
||||||
fields: 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 start_line = item_impl.span().start().line;
|
||||||
let end_line = item_impl.span().end().line;
|
let end_line = item_impl.span().end().line;
|
||||||
|
|
||||||
@@ -268,7 +282,7 @@ fn parse_impl(item_impl: ItemImpl, content: &str) -> Option<RustDecl> {
|
|||||||
.generics
|
.generics
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|param| param.to_string())
|
.map(generic_param_to_string)
|
||||||
.collect(),
|
.collect(),
|
||||||
traits,
|
traits,
|
||||||
fields: Vec::new(),
|
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 start_line = item_mod.span().start().line;
|
||||||
let end_line = item_mod.span().end().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 {
|
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 {
|
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