Fix nested rsx expansion by not using template titles (#2799)

* Fix nested rsx expansion by not using template titles

* fix writers with nameless templates

* fix clippy

* dont commit vscode fix

* fix release mode, pull out __template_name

* fix axum_desktop

* Fix core tests

* Make most fields of HotReloadedTemplate public for testing

* wip: formatting, compare all diff cases

* slightly smarter diffing for dynamic nodes

* add a comment about generic node diffing

* clean up mutations a bit

* fix load template

* simplify maybe_rebuild

* Restore write mutations flag in web

* write_mutations -> skip_mutations

---------

Co-authored-by: Evan Almloff <evanalmloff@gmail.com>
This commit is contained in:
Jonathan KelleyandEvan Almloff authored and GitHub committed 2024-08-13 01:59:04 +00:00
1 parent a2180b92e9
commit 0de3bf7aeb
40 files changed
+597 -1038

No files matched your search

-19
View File
@@ -70,9 +70,6 @@ use dioxus_core::internal::{
HotReloadLiteral, HotReloadedTemplate, NamedAttribute,
};
use std::collections::HashMap;
use std::hash::DefaultHasher;
use std::hash::Hash;
use std::hash::Hasher;
use super::last_build_state::LastBuildState;
@@ -200,23 +197,7 @@ impl HotReloadResult {
.collect();
let roots: &[dioxus_core::TemplateNode] = intern(&*roots);
// Add the template name, the dyn index and the hash of the template to get a unique name
let name = {
let mut hasher = DefaultHasher::new();
key.hash(&mut hasher);
new_dynamic_attributes.hash(&mut hasher);
new_dynamic_nodes.hash(&mut hasher);
literal_component_properties.hash(&mut hasher);
roots.hash(&mut hasher);
let hash = hasher.finish();
let name = &self.full_rebuild_state.name;
format!("{}:{}-{}", name, hash, new.template_idx.get())
};
let name = Box::leak(name.into_boxed_str());
let template = HotReloadedTemplate::new(
name,
key,
new_dynamic_nodes,
new_dynamic_attributes,
+47 -55
View File
@@ -139,65 +139,58 @@ impl ToTokens for TemplateBody {
let dynamic_text = self.dynamic_text_segments.iter();
let index = self.template_idx.get();
let diagnostics = &self.diagnostics;
let hot_reload_mapping = self.hot_reload_mapping(quote! { ___TEMPLATE_NAME });
let index = self.template_idx.get();
let hot_reload_mapping = self.hot_reload_mapping();
let vnode = quote! {
#[doc(hidden)] // vscode please stop showing these in symbol search
const ___TEMPLATE_NAME: &str = {
const PATH: &str = dioxus_core::const_format::str_replace!(file!(), "\\\\", "/");
const NORMAL: &str = dioxus_core::const_format::str_replace!(PATH, '\\', "/");
dioxus_core::const_format::concatcp!(NORMAL, ':', line!(), ':', column!(), ':', #index)
};
#[cfg(debug_assertions)]
{
// The key is important here - we're creating a new GlobalSignal each call to this
// But the key is what's keeping it stable
let __template = GlobalSignal::with_key(
|| #hot_reload_mapping,
___TEMPLATE_NAME
);
__template.maybe_with_rt(|__template_read| {
let mut __dynamic_literal_pool = dioxus_core::internal::DynamicLiteralPool::new(
vec![ #( #dynamic_text.to_string() ),* ],
);
let mut __dynamic_value_pool = dioxus_core::internal::DynamicValuePool::new(
vec![ #( #dynamic_nodes ),* ],
vec![ #( #dyn_attr_printer ),* ],
__dynamic_literal_pool
);
__dynamic_value_pool.render_with(__template_read)
})
}
#[cfg(not(debug_assertions))]
{
#[doc(hidden)] // vscode please stop showing these in symbol search
static ___TEMPLATE: dioxus_core::Template = dioxus_core::Template {
name: ___TEMPLATE_NAME,
roots: &[ #( #roots ),* ],
node_paths: &[ #( #node_paths ),* ],
attr_paths: &[ #( #attr_paths ),* ],
};
// NOTE: Allocating a temporary is important to make reads within rsx drop before the value is returned
#[allow(clippy::let_and_return)]
let __vnodes = dioxus_core::VNode::new(
#key_tokens,
___TEMPLATE,
Box::new([ #( #dynamic_nodes ),* ]),
Box::new([ #( #dyn_attr_printer ),* ]),
);
__vnodes
}
};
tokens.append_all(quote! {
dioxus_core::Element::Ok({
#diagnostics
#vnode
#[cfg(debug_assertions)]
{
// The key is important here - we're creating a new GlobalSignal each call to this
// But the key is what's keeping it stable
let __template = GlobalSignal::with_key(
|| #hot_reload_mapping,
{
const PATH: &str = dioxus_core::const_format::str_replace!(file!(), "\\\\", "/");
const NORMAL: &str = dioxus_core::const_format::str_replace!(PATH, '\\', "/");
dioxus_core::const_format::concatcp!(NORMAL, ':', line!(), ':', column!(), ':', #index)
}
);
__template.maybe_with_rt(|__template_read| {
let mut __dynamic_literal_pool = dioxus_core::internal::DynamicLiteralPool::new(
vec![ #( #dynamic_text.to_string() ),* ],
);
let mut __dynamic_value_pool = dioxus_core::internal::DynamicValuePool::new(
vec![ #( #dynamic_nodes ),* ],
vec![ #( #dyn_attr_printer ),* ],
__dynamic_literal_pool
);
__dynamic_value_pool.render_with(__template_read)
})
}
#[cfg(not(debug_assertions))]
{
#[doc(hidden)] // vscode please stop showing these in symbol search
static ___TEMPLATE: dioxus_core::Template = dioxus_core::Template {
roots: &[ #( #roots ),* ],
node_paths: &[ #( #node_paths ),* ],
attr_paths: &[ #( #attr_paths ),* ],
};
// NOTE: Allocating a temporary is important to make reads within rsx drop before the value is returned
#[allow(clippy::let_and_return)]
let __vnodes = dioxus_core::VNode::new(
#key_tokens,
___TEMPLATE,
Box::new([ #( #dynamic_nodes ),* ]),
Box::new([ #( #dyn_attr_printer ),* ]),
);
__vnodes
}
})
});
}
@@ -324,7 +317,7 @@ impl TemplateBody {
})
}
fn hot_reload_mapping(&self, name: impl ToTokens) -> TokenStream2 {
fn hot_reload_mapping(&self) -> TokenStream2 {
let key = if let Some(AttributeValue::AttrLiteral(HotLiteral::Fmted(key))) =
self.implicit_key()
{
@@ -346,7 +339,6 @@ impl TemplateBody {
.map(|literal| literal.quote_as_hot_reload_literal());
quote! {
dioxus_core::internal::HotReloadedTemplate::new(
#name,
#key,
vec![ #( #dynamic_nodes ),* ],
vec![ #( #dyn_attr_printer ),* ],