//! 宪法宏代码生成模块 - 完整实现 //! //! 提供完整的代码生成、测试生成和文档生成功能。 use crate::error::MacroError; use crate::metadata::{FunctionMetadata, ClauseMetadata}; use quote::quote; use syn::{Ident, ItemFn, Type}; /// 代码生成器 pub struct CodeGenerator; impl CodeGenerator { /// 生成宪法检查代码 pub fn generate_constitutional_check( clause_id: &str, strict: bool, ) -> proc_macro2::TokenStream { if strict { quote! { // 严格模式:条款不存在或未激活时panic let clause = nac_constitution_state::get_clause(#clause_id) .expect(&format!("Constitutional clause '{}' not found", #clause_id)); if !clause.is_active() { panic!("Constitutional clause '{}' is not active", #clause_id); } log::debug!("Constitutional check passed: clause={}, version={}", #clause_id, clause.version); } } else { quote! { // 非严格模式:返回错误 if let Some(clause) = nac_constitution_state::get_clause(#clause_id) { if !clause.is_active() { log::error!("Constitutional clause '{}' is not active", #clause_id); return Err(ConstitutionalError::ClauseNotActive(#clause_id.to_string()).into()); } log::debug!("Constitutional check passed: clause={}, version={}", #clause_id, clause.version); } else { log::error!("Constitutional clause '{}' not found", #clause_id); return Err(ConstitutionalError::ClauseNotFound(#clause_id.to_string()).into()); } } } } /// 生成前置条件检查代码 pub fn generate_precondition_check( check_expr: &str, error_message: &str, strict: bool, ) -> Result { let check_tokens: proc_macro2::TokenStream = check_expr.parse() .map_err(|e| MacroError::expression_parse_failed(check_expr, format!("{}", e)))?; if strict { Ok(quote! { // 严格模式:检查失败时panic if !(#check_tokens) { panic!("Precondition check failed: {} - {}", #check_expr, #error_message); } log::debug!("Precondition check passed: {}", #check_expr); }) } else { Ok(quote! { // 非严格模式:返回错误 if !(#check_tokens) { log::error!("Precondition check failed: {}", #check_expr); return Err(ConstitutionalError::PreconditionFailed(#error_message.to_string()).into()); } log::debug!("Precondition check passed: {}", #check_expr); }) } } /// 生成义务记录代码 pub fn generate_obligation_record( clause_id: &str, obligation_type: &str, function_name: &Ident, ) -> proc_macro2::TokenStream { quote! { // 记录宪法义务 nac_constitution_state::record_obligation( #clause_id, #obligation_type, stringify!(#function_name), &format!("{:?}", std::any::type_name::()) ); log::info!( "Constitutional obligation recorded: clause={}, type={}, function={}", #clause_id, #obligation_type, stringify!(#function_name) ); } } /// 生成元数据注册代码 pub fn generate_metadata_registration( metadata: &FunctionMetadata, ) -> proc_macro2::TokenStream { let clause_id = metadata.clause_id; let function_name = metadata.function_name; let inputs = metadata.inputs; let output = metadata.output; let check_expression = metadata.check_expression; let obligation_type = metadata.obligation_type; quote! { // 注册函数元数据到全局注册表 #[doc(hidden)] #[allow(non_upper_case_globals)] const _: () = { #[used] #[link_section = ".constitutional_metadata"] static METADATA: nac_constitution_macros::FunctionMetadata = nac_constitution_macros::FunctionMetadata { clause_id: #clause_id, function_name: #function_name, inputs: #inputs, output: #output, check_expression: #check_expression, obligation_type: #obligation_type, }; }; } } /// 生成日志记录代码 pub fn generate_logging( clause_id: &str, function_name: &Ident, log_level: &str, ) -> proc_macro2::TokenStream { match log_level { "trace" => quote! { log::trace!("Constitutional function invoked: clause={}, function={}", #clause_id, stringify!(#function_name)); }, "debug" => quote! { log::debug!("Constitutional function invoked: clause={}, function={}", #clause_id, stringify!(#function_name)); }, "info" => quote! { log::info!("Constitutional function invoked: clause={}, function={}", #clause_id, stringify!(#function_name)); }, _ => quote! { log::trace!("Constitutional function invoked: clause={}, function={}", #clause_id, stringify!(#function_name)); }, } } /// 生成错误处理代码 pub fn generate_error_handling( function_name: &Ident, error_type: Option<&Type>, ) -> proc_macro2::TokenStream { if let Some(err_ty) = error_type { quote! { .map_err(|e: #err_ty| { log::error!("Constitutional function failed: function={}, error={:?}", stringify!(#function_name), e); e }) } } else { quote! { .map_err(|e| { log::error!("Constitutional function failed: function={}, error={:?}", stringify!(#function_name), e); e }) } } } } /// 测试生成器 pub struct TestGenerator; impl TestGenerator { /// 生成单元测试代码 pub fn generate_unit_tests( function: &ItemFn, clause_id: &str, ) -> proc_macro2::TokenStream { let fn_name = &function.sig.ident; let test_name = syn::Ident::new( &format!("test_{}_constitutional_check", fn_name), fn_name.span(), ); quote! { #[cfg(test)] mod constitutional_tests { use super::*; #[test] fn #test_name() { // 测试宪法条款检查 let clause = nac_constitution_state::get_clause(#clause_id); assert!(clause.is_some(), "Constitutional clause '{}' should exist", #clause_id); let clause = clause.unwrap(); assert!(clause.is_active(), "Constitutional clause '{}' should be active", #clause_id); } #[test] fn test_precondition_validation() { // 测试前置条件验证 // TODO: 添加具体的前置条件测试 } #[test] fn test_obligation_recording() { // 测试义务记录 // TODO: 添加义务记录测试 } } } } /// 生成集成测试代码 pub fn generate_integration_tests( metadata: &ClauseMetadata, ) -> proc_macro2::TokenStream { let clause_id = &metadata.id; let test_mod_name = syn::Ident::new( &format!("integration_tests_{}", clause_id.to_lowercase().replace("-", "_")), proc_macro2::Span::call_site(), ); quote! { #[cfg(test)] mod #test_mod_name { use super::*; #[test] fn test_clause_lifecycle() { // 测试条款生命周期 let clause = nac_constitution_state::get_clause(#clause_id); assert!(clause.is_some()); } #[test] fn test_clause_parameters() { // 测试条款参数 let clause = nac_constitution_state::get_clause(#clause_id).unwrap(); // TODO: 验证参数值 } #[test] fn test_clause_functions() { // 测试条款关联函数 // TODO: 调用并验证所有关联函数 } } } } /// 生成边界测试代码 pub fn generate_boundary_tests( function_name: &Ident, param_name: &str, min_value: Option<&str>, max_value: Option<&str>, ) -> proc_macro2::TokenStream { let test_name = syn::Ident::new( &format!("test_{}_boundary_{}", function_name, param_name), function_name.span(), ); let min_test = if let Some(min) = min_value { let min_tokens: proc_macro2::TokenStream = min.parse().unwrap(); quote! { // 测试最小边界 let result = #function_name(#min_tokens - 1); assert!(result.is_err(), "Should fail with value below minimum"); let result = #function_name(#min_tokens); assert!(result.is_ok(), "Should succeed with minimum value"); } } else { quote! {} }; let max_test = if let Some(max) = max_value { let max_tokens: proc_macro2::TokenStream = max.parse().unwrap(); quote! { // 测试最大边界 let result = #function_name(#max_tokens); assert!(result.is_ok(), "Should succeed with maximum value"); let result = #function_name(#max_tokens + 1); assert!(result.is_err(), "Should fail with value above maximum"); } } else { quote! {} }; quote! { #[cfg(test)] #[test] fn #test_name() { #min_test #max_test } } } } /// 文档生成器 pub struct DocGenerator; impl DocGenerator { /// 生成函数文档 pub fn generate_function_doc( metadata: &FunctionMetadata, ) -> String { let mut doc = String::new(); doc.push_str(&format!("# Constitutional Function: {}\n\n", metadata.function_name)); doc.push_str(&format!("**Clause ID**: `{}`\n\n", metadata.clause_id)); doc.push_str(&format!("**Signature**: `{}({}) -> {}`\n\n", metadata.function_name, metadata.inputs, metadata.output)); if !metadata.check_expression.is_empty() { doc.push_str(&format!("**Precondition**: `{}`\n\n", metadata.check_expression)); } if !metadata.obligation_type.is_empty() { doc.push_str(&format!("**Obligation**: `{}`\n\n", metadata.obligation_type)); } doc.push_str("## Description\n\n"); doc.push_str("This function is subject to constitutional constraints and validation.\n\n"); doc.push_str("## Constitutional Checks\n\n"); doc.push_str("1. Verifies that the constitutional clause exists and is active\n"); doc.push_str("2. Validates preconditions before execution\n"); doc.push_str("3. Records constitutional obligations\n"); doc.push_str("4. Logs function invocation and completion\n\n"); doc } /// 生成条款文档 pub fn generate_clause_doc( metadata: &ClauseMetadata, ) -> String { let mut doc = String::new(); doc.push_str(&format!("# Constitutional Clause: {}\n\n", metadata.name)); doc.push_str(&format!("**ID**: `{}`\n\n", metadata.id)); doc.push_str(&format!("**Version**: `{}`\n\n", metadata.version)); doc.push_str(&format!("**Description**: {}\n\n", metadata.description)); if !metadata.parameters.is_empty() { doc.push_str("## Parameters\n\n"); for (name, param) in &metadata.parameters { doc.push_str(&format!("- **{}** (`{}`): {}\n", name, param.param_type, param.description)); if let Some(default) = ¶m.default_value { doc.push_str(&format!(" - Default: `{}`\n", default)); } if let Some(min) = ¶m.min_value { doc.push_str(&format!(" - Minimum: `{}`\n", min)); } if let Some(max) = ¶m.max_value { doc.push_str(&format!(" - Maximum: `{}`\n", max)); } } doc.push_str("\n"); } if !metadata.functions.is_empty() { doc.push_str("## Associated Functions\n\n"); for func in &metadata.functions { doc.push_str(&format!("- `{}`\n", func)); } doc.push_str("\n"); } doc.push_str(&format!("**Created**: {}\n", metadata.created_at)); doc.push_str(&format!("**Updated**: {}\n", metadata.updated_at)); doc } /// 生成API文档 pub fn generate_api_doc( functions: &[FunctionMetadata], clauses: &[ClauseMetadata], ) -> String { let mut doc = String::new(); doc.push_str("# NAC Constitutional API Documentation\n\n"); doc.push_str("This document provides comprehensive documentation for all constitutional functions and clauses.\n\n"); doc.push_str("## Constitutional Clauses\n\n"); for clause in clauses { doc.push_str(&Self::generate_clause_doc(clause)); doc.push_str("\n---\n\n"); } doc.push_str("## Constitutional Functions\n\n"); for func in functions { doc.push_str(&Self::generate_function_doc(func)); doc.push_str("\n---\n\n"); } doc } } #[cfg(test)] mod tests { use super::*; #[test] fn test_generate_constitutional_check() { let code = CodeGenerator::generate_constitutional_check("TEST_CLAUSE", false); let code_str = quote::quote!(#code).to_string(); assert!(code_str.contains("TEST_CLAUSE")); assert!(code_str.contains("get_clause")); } #[test] fn test_generate_precondition_check() { let code = CodeGenerator::generate_precondition_check( "amount > 0", "Amount must be positive", false ).unwrap(); let code_str = quote::quote!(#code).to_string(); assert!(code_str.contains("amount > 0")); } #[test] fn test_generate_function_doc() { let metadata = FunctionMetadata::new( "TEST_CLAUSE", "test_function", "amount: u64", "Result<(), Error>", "amount > 0", "test_obligation", ); let doc = DocGenerator::generate_function_doc(&metadata); assert!(doc.contains("Constitutional Function")); assert!(doc.contains("TEST_CLAUSE")); assert!(doc.contains("test_function")); } }