adze-macro 0.8.0

Procedural macros for Rust Sitter
Documentation
// This is a proposed fix for the Extract trait implementation in expansion.rs
//! Proposed fixes for Extract trait implementation using symbol IDs.

// The key insight is that we need to generate code that uses symbol IDs
// rather than heuristics based on child counts and string matching

// For the pure-rust Extract implementation, instead of:
/*
if node.child_count() == 1 {
    return #extract_expr;
}
*/

// We should generate:
/*
// The generated parser includes a function to look up symbol names
// We need to match on the actual symbol of the parse tree node
match node.symbol {
    // These symbol IDs would be determined at build time
    SYMBOL_ID_NUMBER => { /* extract Number variant */ }
    SYMBOL_ID_STRING => { /* extract String variant */ }
    SYMBOL_ID_IDENTIFIER => { /* extract Identifier variant */ }
    _ => panic!("Unknown symbol ID: {}", node.symbol)
}
*/

// The challenge is that at macro expansion time, we don't know the symbol IDs
// So we need to generate code that will work with the build-time generated mappings

// One approach is to generate code like this:
/*
impl Extract<PrimaryExpression> for PrimaryExpression {
    fn extract(node: Option<&ParsedNode>, source: &[u8], _last_idx: usize, _leaf_fn: Option<&Self::LeafFn>) -> Self {
        let node = node.unwrap();

        // Get the actual node (might be wrapped)
        let actual_node = if node.children.len() == 1 {
            &node.children[0]
        } else {
            node
        };

        // Use the symbol name to determine the variant
        // The parser generator ensures each variant gets a unique symbol
        let symbol_name = actual_node.kind();

        match symbol_name {
            "number_literal" => Self::Number(NumberLiteral::extract(Some(actual_node), source, _last_idx, None)),
            "string_literal" => Self::String(StringLiteral::extract(Some(actual_node), source, _last_idx, None)),
            "identifier" => Self::Identifier(Identifier::extract(Some(actual_node), source, _last_idx, None)),
            _ => panic!("Unknown symbol name for PrimaryExpression: {}", symbol_name)
        }
    }
}
*/

// But even better would be to use the symbol IDs directly:
/*
// In the generated parser file, we have:
pub const PRIMARY_EXPRESSION_VARIANTS: &[(&str, u16)] = &[
    ("Number", 57),      // symbol ID for number_literal
    ("String", 58),      // symbol ID for string_literal
    ("Identifier", 56),  // symbol ID for identifier
];

// Then in the Extract impl:
match actual_node.symbol {
    57 => Self::Number(...),
    58 => Self::String(...),
    56 => Self::Identifier(...),
    _ => panic!(...)
}
*/