stylex_transform/shared/transformers/
stylex_create.rs1use std::{collections::VecDeque, rc::Rc};
2
3use indexmap::{IndexMap, IndexSet};
4use stylex_macros::stylex_panic;
5
6use crate::shared::enums::data_structures::evaluate_result_value::EvaluateResultValue;
7use crate::shared::enums::data_structures::flat_compiled_styles_value::FlatCompiledStylesValue;
8use crate::shared::structures::functions::FunctionMap;
9use crate::shared::structures::pre_rule::{CompiledResult, ComputedStyle, PreRule, PreRules};
10use crate::shared::structures::state::EvaluationState;
11use crate::shared::structures::state_manager::StateManager;
12use crate::shared::structures::types::{
13 ClassPathsInNamespace, ClassPathsMap, FlatCompiledStyles, InjectableStylesMap, StylesObjectMap,
14};
15use crate::shared::utils::ast::convertors::convert_expr_to_str;
16use crate::shared::utils::common::create_short_hash;
17use crate::shared::utils::core::flatten_raw_style_object::flatten_raw_style_object;
18use crate::shared::utils::validators::validate_namespace;
19use stylex_constants::constants::common::COMPILED_KEY;
20use stylex_constants::constants::messages::{EXPRESSION_IS_NOT_A_STRING, VALUES_MUST_BE_OBJECT};
21use stylex_types::enums::data_structures::injectable_style::InjectableStyleKind;
22
23pub(crate) fn stylex_create_set(
24 namespaces: &EvaluateResultValue,
25 state: &mut EvaluationState,
26 traversal_state: &mut StateManager,
27 functions: &FunctionMap,
28) -> (StylesObjectMap, InjectableStylesMap, ClassPathsMap) {
29 let mut resolved_namespaces = IndexMap::new();
30 let mut injected_styles_map = IndexMap::new();
31 let mut namespace_to_class_paths = IndexMap::new();
32
33 for (namespace_name, namespace) in match namespaces.as_map() {
34 Some(map) => map,
35 None => stylex_panic!("{}", VALUES_MUST_BE_OBJECT),
36 } {
37 validate_namespace(namespace, &[], traversal_state);
38
39 let mut class_paths_in_namespace: ClassPathsInNamespace = IndexMap::new();
40
41 let mut seen_properties = IndexSet::<String>::new();
42
43 let mut flattened_namespace =
44 flatten_raw_style_object(namespace, state, traversal_state, functions)
45 .into_iter()
46 .rev()
47 .fold(VecDeque::new(), |mut arr, curr| {
48 if !seen_properties.contains(&curr.0) {
49 seen_properties.insert(curr.0.clone());
50 arr.push_front(curr);
51 }
52 arr
53 });
54
55 let compiled_namespace_tuples = flattened_namespace
56 .iter_mut()
57 .map(|(key, value)| {
58 let key = if traversal_state.options.enable_minified_keys && !key.starts_with("--") {
59 let hashed_key = create_short_hash(&format!("<>{}", key));
60 if traversal_state.options.debug {
61 format!("{}-k{}", key, hashed_key)
62 } else {
63 format!("k{}", hashed_key)
64 }
65 } else {
66 key.clone()
67 };
68
69 let compiled_value = match value {
70 PreRules::PreRuleSet(rule_set) => rule_set.compiled(traversal_state),
71 PreRules::StylesPreRule(styles_pre_rule) => styles_pre_rule.compiled(traversal_state),
72 PreRules::NullPreRule(rule_set) => rule_set.compiled(traversal_state),
73 };
74 (key, compiled_value)
75 })
76 .collect::<Vec<(String, CompiledResult)>>();
77
78 let mut namespace_obj: FlatCompiledStyles = IndexMap::new();
79
80 for (key, value) in compiled_namespace_tuples {
81 match value {
82 CompiledResult::ComputedStyles(class_name_tuples) => {
83 let mut unique_class_names = IndexSet::new();
84
85 for ComputedStyle(class_name, _, classes_to_original_path) in class_name_tuples.iter() {
86 unique_class_names.insert(class_name.as_str());
87 class_paths_in_namespace.extend(classes_to_original_path.clone());
88 }
89
90 let class_name = unique_class_names
91 .iter()
92 .cloned()
93 .collect::<Vec<&str>>()
94 .join(" ");
95
96 namespace_obj.insert(
97 key.clone(),
98 if !class_name.is_empty() {
99 Rc::new(FlatCompiledStylesValue::String(class_name.clone()))
100 } else {
101 Rc::new(FlatCompiledStylesValue::Null)
102 },
103 );
104
105 for ComputedStyle(class_name, injectable_styles, _) in class_name_tuples.iter() {
106 injected_styles_map
107 .entry(class_name.clone())
108 .or_insert_with(|| Rc::new(InjectableStyleKind::Regular(injectable_styles.clone())));
109 }
110 },
111 _ => {
112 namespace_obj.insert(key.clone(), Rc::new(FlatCompiledStylesValue::Null));
113 },
114 }
115 }
116
117 let resolved_namespace_name =
118 match convert_expr_to_str(namespace_name, traversal_state, functions) {
119 Some(s) => s,
120 None => stylex_panic!("{}", EXPRESSION_IS_NOT_A_STRING),
121 };
122
123 namespace_obj.insert(
124 COMPILED_KEY.to_owned(),
125 Rc::new(FlatCompiledStylesValue::Bool(true)),
126 );
127
128 resolved_namespaces.insert(resolved_namespace_name.clone(), Rc::new(namespace_obj));
129
130 namespace_to_class_paths.insert(resolved_namespace_name, Rc::new(class_paths_in_namespace));
131 }
132
133 (
134 resolved_namespaces,
135 injected_styles_map,
136 namespace_to_class_paths,
137 )
138}