turbo_tasks_macros_shared/
ident.rs

1use quote::ToTokens;
2use syn::{GenericArgument, Ident, Path, PathArguments, Type, TypeParamBound, spanned::Spanned};
3
4pub fn get_register_value_type_ident(struct_ident: &Ident) -> Ident {
5    Ident::new(
6        &format!("__register_{struct_ident}_value_type"),
7        struct_ident.span(),
8    )
9}
10
11pub fn get_register_trait_methods_ident(trait_ident: &Ident, struct_ident: &Ident) -> Ident {
12    Ident::new(
13        &format!("__register_{struct_ident}_{trait_ident}_trait_methods"),
14        trait_ident.span(),
15    )
16}
17
18pub fn get_native_function_ident(ident: &Ident) -> Ident {
19    Ident::new(
20        &format!("{}_FUNCTION", ident.to_string().to_uppercase()),
21        ident.span(),
22    )
23}
24
25pub fn get_native_function_id_ident(ident: &Ident) -> Ident {
26    Ident::new(
27        &format!("{}_FUNCTION_ID", ident.to_string().to_uppercase()),
28        ident.span(),
29    )
30}
31
32pub fn get_trait_type_ident(ident: &Ident) -> Ident {
33    Ident::new(
34        &format!("{}_TRAIT_TYPE", ident.to_string().to_uppercase()),
35        ident.span(),
36    )
37}
38
39pub fn get_impl_function_ident(struct_ident: &Ident, ident: &Ident) -> Ident {
40    Ident::new(
41        &format!(
42            "{}_IMPL_{}_FUNCTION",
43            struct_ident.to_string().to_uppercase(),
44            ident.to_string().to_uppercase()
45        ),
46        ident.span(),
47    )
48}
49
50pub fn get_inherent_impl_function_ident(ty_ident: &Ident, fn_ident: &Ident) -> Ident {
51    Ident::new(
52        &format!(
53            "{}_IMPL_{}_FUNCTION",
54            ty_ident.to_string().to_uppercase(),
55            fn_ident.to_string().to_uppercase()
56        ),
57        fn_ident.span(),
58    )
59}
60
61pub fn get_inherent_impl_function_id_ident(ty_ident: &Ident, fn_ident: &Ident) -> Ident {
62    Ident::new(
63        &format!(
64            "{}_IMPL_{}_FUNCTION_ID",
65            ty_ident.to_string().to_uppercase(),
66            fn_ident.to_string().to_uppercase()
67        ),
68        fn_ident.span(),
69    )
70}
71
72pub fn get_trait_impl_function_ident(
73    struct_ident: &Ident,
74    trait_ident: &Ident,
75    ident: &Ident,
76) -> Ident {
77    Ident::new(
78        &format!(
79            "{}_IMPL_TRAIT_{}_{}_FUNCTION",
80            struct_ident.to_string().to_uppercase(),
81            trait_ident.to_string().to_uppercase(),
82            ident.to_string().to_uppercase()
83        ),
84        ident.span(),
85    )
86}
87
88pub fn get_trait_impl_function_id_ident(
89    struct_ident: &Ident,
90    trait_ident: &Ident,
91    ident: &Ident,
92) -> Ident {
93    Ident::new(
94        &format!(
95            "{}_IMPL_TRAIT_{}_{}_FUNCTION_ID",
96            struct_ident.to_string().to_uppercase(),
97            trait_ident.to_string().to_uppercase(),
98            ident.to_string().to_uppercase()
99        ),
100        ident.span(),
101    )
102}
103
104pub fn get_internal_trait_impl_function_ident(trait_ident: &Ident, ident: &Ident) -> Ident {
105    Ident::new(
106        &format!("__trait_call_{trait_ident}_{ident}"),
107        trait_ident.span(),
108    )
109}
110
111pub fn get_path_ident(path: &Path) -> Ident {
112    let mut result = String::new();
113
114    for (i, segment) in path.segments.iter().enumerate() {
115        let ident = segment.ident.to_string();
116
117        if i > 0 {
118            result.push('_');
119        }
120
121        result.push_str(&ident);
122
123        match &segment.arguments {
124            PathArguments::AngleBracketed(args) => {
125                for arg in &args.args {
126                    match arg {
127                        GenericArgument::Type(ty) => {
128                            if let Type::Path(type_path) = ty {
129                                let type_ident = get_path_ident(&type_path.path);
130                                result.push('_');
131                                result.push_str(&type_ident.to_string());
132                            } else if let Type::TraitObject(trait_obj) = ty {
133                                for bound in &trait_obj.bounds {
134                                    if let TypeParamBound::Trait(bound_trait) = bound {
135                                        let bound_ident = get_path_ident(&bound_trait.path);
136                                        result.push_str("_dyn_");
137                                        result.push_str(&bound_ident.to_string());
138                                    }
139                                }
140                            } else {
141                                arg.span()
142                                    .unwrap()
143                                    .error(
144                                        "#[turbo_tasks::value_impl] does not support this type \
145                                         argument",
146                                    )
147                                    .emit();
148                            }
149                        }
150                        _ => arg
151                            .span()
152                            .unwrap()
153                            .error("#[turbo_tasks::value_impl] does not support this type argument")
154                            .emit(),
155                    }
156                }
157            }
158            PathArguments::None => {}
159            _ => {
160                segment
161                    .span()
162                    .unwrap()
163                    .error("#[turbo_tasks::value_impl] does not support this type argument")
164                    .emit();
165            }
166        }
167    }
168
169    Ident::new(&result, path.span())
170}
171
172pub fn get_type_ident(ty: &Type) -> Option<Ident> {
173    match ty {
174        Type::Path(path) => Some(get_path_ident(&path.path)),
175        Type::Tuple(tuple) => Some(Ident::new("unit", tuple.span())),
176        _ => {
177            ty.span()
178                .unwrap()
179                .error(format!(
180                    "#[turbo_tasks::value_impl] does not support the type {}, expected T or \
181                     Box<dyn Trait>",
182                    ty.to_token_stream()
183                ))
184                .emit();
185            None
186        }
187    }
188}
189
190pub fn get_read_ref_ident(ident: &Ident) -> Ident {
191    Ident::new(&(ident.to_string() + "ReadRef"), ident.span())
192}
193
194pub fn get_trait_ref_ident(ident: &Ident) -> Ident {
195    Ident::new(&(ident.to_string() + "TraitRef"), ident.span())
196}
197
198pub fn get_trait_default_impl_function_ident(trait_ident: &Ident, ident: &Ident) -> Ident {
199    Ident::new(
200        &format!(
201            "{}_DEFAULT_IMPL_{}_FUNCTION",
202            trait_ident.to_string().to_uppercase(),
203            ident.to_string().to_uppercase()
204        ),
205        ident.span(),
206    )
207}
208
209pub fn get_trait_type_id_ident(ident: &Ident) -> Ident {
210    Ident::new(
211        &format!("{}_TRAIT_TYPE_ID", ident.to_string().to_uppercase()),
212        ident.span(),
213    )
214}
215
216pub fn get_trait_default_impl_function_id_ident(trait_ident: &Ident, ident: &Ident) -> Ident {
217    Ident::new(
218        &format!(
219            "{}_DEFAULT_IMPL_{}_FUNCTION_ID",
220            trait_ident.to_string().to_uppercase(),
221            ident.to_string().to_uppercase()
222        ),
223        ident.span(),
224    )
225}
226
227pub fn get_value_type_ident(ident: &Ident) -> Ident {
228    Ident::new(
229        &format!("{}_VALUE_TYPE", ident.to_string().to_uppercase()),
230        ident.span(),
231    )
232}
233
234pub fn get_value_type_id_ident(ident: &Ident) -> Ident {
235    Ident::new(
236        &format!("{}_VALUE_TYPE_ID", ident.to_string().to_uppercase()),
237        ident.span(),
238    )
239}
240
241pub fn get_value_type_init_ident(ident: &Ident) -> Ident {
242    Ident::new(
243        &format!("{}_VALUE_TYPE_INIT", ident.to_string().to_uppercase()),
244        ident.span(),
245    )
246}