NAC_Blockchain/nac-constitution-macros/src/codegen.rs

454 lines
16 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! 宪法宏代码生成模块 - 完整实现
//!
//! 提供完整的代码生成、测试生成和文档生成功能。
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<proc_macro2::TokenStream, MacroError> {
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::<Self>())
);
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) = &param.default_value {
doc.push_str(&format!(" - Default: `{}`\n", default));
}
if let Some(min) = &param.min_value {
doc.push_str(&format!(" - Minimum: `{}`\n", min));
}
if let Some(max) = &param.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"));
}
}