gpui-rsx 0.2.2

A JSX-like macro for GPUI - simplify UI development with HTML-like syntax
Documentation
//! 属性处理
//!
//! 将 RSX 属性转换为 GPUI 方法调用:
//! - Flag 属性 → 无参方法调用
//! - Value 属性 → 带参数方法调用
//! - class 属性 → 展开为多个样式方法
//! - 事件处理器 → 映射到正确的 GPUI 方法
//! - when/whenSome → 条件渲染方法
//!
//! 优化:
//! - 使用 match-based `lookup_attr_method()` 替代双重线性扫描
//! - 直接 push 到调用方 Vec,避免中间 Vec 分配

use super::class::parse_class_string;
use super::runtime::generate_dynamic_class_code;
use super::tables::lookup_attr_method;
use crate::parser::RsxAttribute;
use proc_macro2::TokenStream;
use quote::quote;

/// 生成属性的方法链片段,直接 push 到 `out`(避免中间 Vec 分配)
pub(crate) fn generate_attr_methods(attr: &RsxAttribute, out: &mut Vec<TokenStream>) {
    match attr {
        // id 已在 generate_element 中处理,跳过避免重复
        RsxAttribute::Value { name, .. } if name == "id" => {}

        RsxAttribute::Flag(name) => {
            if name == "invisible" {
                // invisible 标志特殊处理 → .visible(false)
                out.push(quote! { .visible(false) });
            } else if name != "styled" {
                // styled 标志已在 generate_element 中处理,不生成 .styled()
                out.push(quote! { .#name() });
            }
        }

        RsxAttribute::Value { name, value } => {
            // class 属性 → 展开为多个样式方法(静态)或运行时解析(动态)
            if name == "class" {
                // 情况 1:字符串字面量 → 编译期解析(最优性能)
                if let syn::Expr::Lit(syn::ExprLit {
                    lit: syn::Lit::Str(lit_str),
                    ..
                }) = value
                {
                    let s = lit_str.value();
                    out.extend(parse_class_string(&s));
                    return;
                }

                // 情况 2:动态表达式 → 生成运行时解析代码
                let dynamic_code = generate_dynamic_class_code(value);
                out.push(quote! { .map(|__el| #dynamic_code) });
                return;
            }

            // 使用 match-based 查找替代原先的双重线性扫描
            let name_str = name.to_string();
            if let Some(mapped) = lookup_attr_method(&name_str) {
                let method_ident = syn::Ident::new(mapped, name.span());
                out.push(quote! { .#method_ident(#value) });
                return;
            }

            // 默认:直接作为方法调用
            out.push(quote! { .#name(#value) });
        }

        // when 条件渲染
        RsxAttribute::When { condition, closure } => {
            out.push(quote! { .when(#condition, #closure) });
        }

        // when_some 条件渲染
        RsxAttribute::WhenSome { option, closure } => {
            out.push(quote! { .when_some(#option, #closure) });
        }
    }
}