Skip to content

Commit 857c3e2

Browse files
authored
Fix rsx expression autocomplete (#3568)
* Fix autocomplete in node and attribute expressions * Fix release expansion * revert changes to expr_node * fix rsx expansion in release mode
1 parent d5a04c6 commit 857c3e2

File tree

1 file changed

+41
-26
lines changed

1 file changed

+41
-26
lines changed

packages/rsx/src/template_body.rs

+41-26
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,15 @@ impl ToTokens for TemplateBody {
129129
// For printing dynamic nodes, we rely on the ToTokens impl
130130
// Elements have a weird ToTokens - they actually are the entrypoint for Template creation
131131
let dynamic_nodes: Vec<_> = self.dynamic_nodes().collect();
132+
let dynamic_nodes_len = dynamic_nodes.len();
132133

133134
// We could add a ToTokens for Attribute but since we use that for both components and elements
134135
// They actually need to be different, so we just localize that here
135136
let dyn_attr_printer: Vec<_> = self
136137
.dynamic_attributes()
137138
.map(|attr| attr.rendered_as_dynamic_attr())
138139
.collect();
140+
let dynamic_attr_len = dyn_attr_printer.len();
139141

140142
let dynamic_text = self.dynamic_text_segments.iter();
141143

@@ -147,45 +149,59 @@ impl ToTokens for TemplateBody {
147149
dioxus_core::Element::Ok({
148150
#diagnostics
149151

152+
// Components pull in the dynamic literal pool and template in debug mode, so they need to be defined before dynamic nodes
150153
#[cfg(debug_assertions)]
151-
{
154+
fn __original_template() -> &'static dioxus_core::internal::HotReloadedTemplate {
152155
static __ORIGINAL_TEMPLATE: ::std::sync::OnceLock<dioxus_core::internal::HotReloadedTemplate> = ::std::sync::OnceLock::new();
153-
fn __original_template() -> &'static dioxus_core::internal::HotReloadedTemplate {
154-
if __ORIGINAL_TEMPLATE.get().is_none() {
155-
_ = __ORIGINAL_TEMPLATE.set(#hot_reload_mapping);
156-
}
157-
__ORIGINAL_TEMPLATE.get().unwrap()
156+
if __ORIGINAL_TEMPLATE.get().is_none() {
157+
_ = __ORIGINAL_TEMPLATE.set(#hot_reload_mapping);
158158
}
159-
159+
__ORIGINAL_TEMPLATE.get().unwrap()
160+
}
161+
#[cfg(debug_assertions)]
162+
let __template_read = {
160163
static __NORMALIZED_FILE: &'static str = {
161164
const PATH: &str = dioxus_core::const_format::str_replace!(file!(), "\\\\", "/");
162165
dioxus_core::const_format::str_replace!(PATH, '\\', "/")
163166
};
164167

165168
// The key is important here - we're creating a new GlobalSignal each call to this
166169
// But the key is what's keeping it stable
167-
let __template = GlobalSignal::with_location(
170+
static __TEMPLATE: GlobalSignal<Option<dioxus_core::internal::HotReloadedTemplate>> = GlobalSignal::with_location(
168171
|| None::<dioxus_core::internal::HotReloadedTemplate>,
169172
__NORMALIZED_FILE,
170173
line!(),
171174
column!(),
172175
#index
173176
);
174177

175-
// If the template has not been hot reloaded, we always use the original template
176-
// Templates nested within macros may be merged because they have the same file-line-column-index
177-
// They cannot be hot reloaded, so this prevents incorrect rendering
178-
let __template_read = dioxus_core::Runtime::current().ok().map(|_| __template.read());
179-
let __template_read = match __template_read.as_ref().map(|__template_read| __template_read.as_ref()) {
180-
Some(Some(__template_read)) => &__template_read,
181-
_ => __original_template(),
182-
};
183-
let mut __dynamic_literal_pool = dioxus_core::internal::DynamicLiteralPool::new(
184-
vec![ #( #dynamic_text.to_string() ),* ],
185-
);
178+
dioxus_core::Runtime::current().ok().map(|_| __TEMPLATE.read())
179+
};
180+
// If the template has not been hot reloaded, we always use the original template
181+
// Templates nested within macros may be merged because they have the same file-line-column-index
182+
// They cannot be hot reloaded, so this prevents incorrect rendering
183+
#[cfg(debug_assertions)]
184+
let __template_read = match __template_read.as_ref().map(|__template_read| __template_read.as_ref()) {
185+
Some(Some(__template_read)) => &__template_read,
186+
_ => __original_template(),
187+
};
188+
#[cfg(debug_assertions)]
189+
let mut __dynamic_literal_pool = dioxus_core::internal::DynamicLiteralPool::new(
190+
vec![ #( #dynamic_text.to_string() ),* ],
191+
);
192+
193+
// These items are used in both the debug and release expansions of rsx. Pulling them out makes the expansion
194+
// slightly smaller and easier to understand. Rust analyzer also doesn't autocomplete well when it sees an ident show up twice in the expansion
195+
let __dynamic_nodes: [dioxus_core::DynamicNode; #dynamic_nodes_len] = [ #( #dynamic_nodes ),* ];
196+
let __dynamic_attributes: [Box<[dioxus_core::Attribute]>; #dynamic_attr_len] = [ #( #dyn_attr_printer ),* ];
197+
#[doc(hidden)]
198+
static __TEMPLATE_ROOTS: &[dioxus_core::TemplateNode] = &[ #( #roots ),* ];
199+
200+
#[cfg(debug_assertions)]
201+
{
186202
let mut __dynamic_value_pool = dioxus_core::internal::DynamicValuePool::new(
187-
vec![ #( #dynamic_nodes ),* ],
188-
vec![ #( #dyn_attr_printer ),* ],
203+
Vec::from(__dynamic_nodes),
204+
Vec::from(__dynamic_attributes),
189205
__dynamic_literal_pool
190206
);
191207
__dynamic_value_pool.render_with(__template_read)
@@ -194,7 +210,7 @@ impl ToTokens for TemplateBody {
194210
{
195211
#[doc(hidden)] // vscode please stop showing these in symbol search
196212
static ___TEMPLATE: dioxus_core::Template = dioxus_core::Template {
197-
roots: &[ #( #roots ),* ],
213+
roots: __TEMPLATE_ROOTS,
198214
node_paths: &[ #( #node_paths ),* ],
199215
attr_paths: &[ #( #attr_paths ),* ],
200216
};
@@ -204,8 +220,8 @@ impl ToTokens for TemplateBody {
204220
let __vnodes = dioxus_core::VNode::new(
205221
#key_tokens,
206222
___TEMPLATE,
207-
Box::new([ #( #dynamic_nodes ),* ]),
208-
Box::new([ #( #dyn_attr_printer ),* ]),
223+
Box::new(__dynamic_nodes),
224+
Box::new(__dynamic_attributes),
209225
);
210226
__vnodes
211227
}
@@ -343,7 +359,6 @@ impl TemplateBody {
343359
} else {
344360
quote! { None }
345361
};
346-
let roots = self.quote_roots();
347362
let dynamic_nodes = self.dynamic_nodes().map(|node| {
348363
let id = node.get_dyn_idx();
349364
quote! { dioxus_core::internal::HotReloadDynamicNode::Dynamic(#id) }
@@ -361,7 +376,7 @@ impl TemplateBody {
361376
vec![ #( #dynamic_nodes ),* ],
362377
vec![ #( #dyn_attr_printer ),* ],
363378
vec![ #( #component_values ),* ],
364-
&[ #( #roots ),* ],
379+
__TEMPLATE_ROOTS,
365380
)
366381
}
367382
}

0 commit comments

Comments
 (0)