half-build-times
This commit is contained in:
1 parent
f69b84bf34
commit
3d8d8a1b6f
24 files changed
+489
-456
No files matched your search
@@ -1,15 +1,18 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// An error produced when interperting the rsx
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub enum Error {
|
||||
ParseError(ParseError),
|
||||
RecompileRequiredError(RecompileReason),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub enum RecompileReason {
|
||||
Variable(String),
|
||||
Expression(String),
|
||||
@@ -18,14 +21,16 @@ pub enum RecompileReason {
|
||||
Attribute(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct CodeLocation {
|
||||
pub line: u32,
|
||||
pub column: u32,
|
||||
pub file_path: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct ParseError {
|
||||
pub message: String,
|
||||
pub location: CodeLocation,
|
||||
|
||||
@@ -85,7 +85,7 @@ fn find_rsx_item(
|
||||
(syn::ImplItem::Const(new_item), syn::ImplItem::Const(old_item)) => {
|
||||
find_rsx_expr(&new_item.expr, &old_item.expr, rsx_calls)
|
||||
}
|
||||
(syn::ImplItem::Method(new_item), syn::ImplItem::Method(old_item)) => {
|
||||
(syn::ImplItem::Fn(new_item), syn::ImplItem::Fn(old_item)) => {
|
||||
find_rsx_block(&new_item.block, &old_item.block, rsx_calls)
|
||||
}
|
||||
(syn::ImplItem::Type(new_item), syn::ImplItem::Type(old_item)) => {
|
||||
@@ -114,7 +114,6 @@ fn find_rsx_item(
|
||||
|| new_item.semi_token != old_item.semi_token
|
||||
|| new_item.ident != old_item.ident
|
||||
}
|
||||
(syn::Item::Macro2(new_item), syn::Item::Macro2(old_item)) => old_item != new_item,
|
||||
(syn::Item::Mod(new_item), syn::Item::Mod(old_item)) => {
|
||||
match (&new_item.content, &old_item.content) {
|
||||
(Some((_, new_items)), Some((_, old_items))) => {
|
||||
@@ -186,7 +185,7 @@ fn find_rsx_trait(
|
||||
true
|
||||
}
|
||||
}
|
||||
(syn::TraitItem::Method(new_item), syn::TraitItem::Method(old_item)) => {
|
||||
(syn::TraitItem::Fn(new_item), syn::TraitItem::Fn(old_item)) => {
|
||||
if let (Some(new_block), Some(old_block)) = (&new_item.default, &old_item.default) {
|
||||
find_rsx_block(new_block, old_block, rsx_calls)
|
||||
} else {
|
||||
@@ -239,8 +238,9 @@ fn find_rsx_stmt(
|
||||
match (new_stmt, old_stmt) {
|
||||
(syn::Stmt::Local(new_local), syn::Stmt::Local(old_local)) => {
|
||||
(match (&new_local.init, &old_local.init) {
|
||||
(Some((new_eq, new_expr)), Some((old_eq, old_expr))) => {
|
||||
find_rsx_expr(new_expr, old_expr, rsx_calls) || new_eq != old_eq
|
||||
(Some(new_local), Some(old_local)) => {
|
||||
find_rsx_expr(&new_local.expr, &old_local.expr, rsx_calls)
|
||||
|| new_local != old_local
|
||||
}
|
||||
(None, None) => false,
|
||||
_ => true,
|
||||
@@ -252,11 +252,13 @@ fn find_rsx_stmt(
|
||||
(syn::Stmt::Item(new_item), syn::Stmt::Item(old_item)) => {
|
||||
find_rsx_item(new_item, old_item, rsx_calls)
|
||||
}
|
||||
(syn::Stmt::Expr(new_expr), syn::Stmt::Expr(old_expr)) => {
|
||||
(syn::Stmt::Expr(new_expr, _), syn::Stmt::Expr(old_expr, _)) => {
|
||||
find_rsx_expr(new_expr, old_expr, rsx_calls)
|
||||
}
|
||||
(syn::Stmt::Semi(new_expr, new_semi), syn::Stmt::Semi(old_expr, old_semi)) => {
|
||||
find_rsx_expr(new_expr, old_expr, rsx_calls) || new_semi != old_semi
|
||||
(syn::Stmt::Macro(new_macro), syn::Stmt::Macro(old_macro)) => {
|
||||
find_rsx_macro(&new_macro.mac, &old_macro.mac, rsx_calls)
|
||||
|| new_macro.attrs != old_macro.attrs
|
||||
|| new_macro.semi_token != old_macro.semi_token
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
@@ -285,12 +287,6 @@ fn find_rsx_expr(
|
||||
|| new_expr.attrs != old_expr.attrs
|
||||
|| new_expr.eq_token != old_expr.eq_token
|
||||
}
|
||||
(syn::Expr::AssignOp(new_expr), syn::Expr::AssignOp(old_expr)) => {
|
||||
find_rsx_expr(&new_expr.left, &old_expr.left, rsx_calls)
|
||||
|| find_rsx_expr(&new_expr.right, &old_expr.right, rsx_calls)
|
||||
|| new_expr.attrs != old_expr.attrs
|
||||
|| new_expr.op != old_expr.op
|
||||
}
|
||||
(syn::Expr::Async(new_expr), syn::Expr::Async(old_expr)) => {
|
||||
find_rsx_block(&new_expr.block, &old_expr.block, rsx_calls)
|
||||
|| new_expr.attrs != old_expr.attrs
|
||||
@@ -314,11 +310,6 @@ fn find_rsx_expr(
|
||||
|| new_expr.attrs != old_expr.attrs
|
||||
|| new_expr.label != old_expr.label
|
||||
}
|
||||
(syn::Expr::Box(new_expr), syn::Expr::Box(old_expr)) => {
|
||||
find_rsx_expr(&new_expr.expr, &old_expr.expr, rsx_calls)
|
||||
|| new_expr.attrs != old_expr.attrs
|
||||
|| new_expr.box_token != old_expr.box_token
|
||||
}
|
||||
(syn::Expr::Break(new_expr), syn::Expr::Break(old_expr)) => {
|
||||
match (&new_expr.expr, &old_expr.expr) {
|
||||
(Some(new_inner), Some(old_inner)) => {
|
||||
@@ -478,7 +469,7 @@ fn find_rsx_expr(
|
||||
}
|
||||
(syn::Expr::Path(new_expr), syn::Expr::Path(old_expr)) => old_expr != new_expr,
|
||||
(syn::Expr::Range(new_expr), syn::Expr::Range(old_expr)) => {
|
||||
match (&new_expr.from, &old_expr.from) {
|
||||
match (&new_expr.start, &old_expr.start) {
|
||||
(Some(new_expr), Some(old_expr)) => {
|
||||
if find_rsx_expr(new_expr, old_expr, rsx_calls) {
|
||||
return true;
|
||||
@@ -487,7 +478,7 @@ fn find_rsx_expr(
|
||||
(None, None) => (),
|
||||
_ => return true,
|
||||
}
|
||||
match (&new_expr.to, &old_expr.to) {
|
||||
match (&new_expr.end, &old_expr.end) {
|
||||
(Some(new_inner), Some(old_inner)) => {
|
||||
find_rsx_expr(new_inner, old_inner, rsx_calls)
|
||||
|| new_expr.attrs != old_expr.attrs
|
||||
@@ -568,12 +559,6 @@ fn find_rsx_expr(
|
||||
}
|
||||
new_expr.attrs != old_expr.attrs || new_expr.paren_token != old_expr.paren_token
|
||||
}
|
||||
(syn::Expr::Type(new_expr), syn::Expr::Type(old_expr)) => {
|
||||
find_rsx_expr(&new_expr.expr, &old_expr.expr, rsx_calls)
|
||||
|| new_expr.attrs != old_expr.attrs
|
||||
|| new_expr.colon_token != old_expr.colon_token
|
||||
|| new_expr.ty != old_expr.ty
|
||||
}
|
||||
(syn::Expr::Unary(new_expr), syn::Expr::Unary(old_expr)) => {
|
||||
find_rsx_expr(&new_expr.expr, &old_expr.expr, rsx_calls)
|
||||
|| new_expr.attrs != old_expr.attrs
|
||||
|
||||
+15
-3
@@ -15,18 +15,22 @@
|
||||
mod errors;
|
||||
mod component;
|
||||
mod element;
|
||||
#[cfg(feature = "hot_reload")]
|
||||
pub mod hot_reload;
|
||||
mod ifmt;
|
||||
mod node;
|
||||
|
||||
use std::{collections::HashMap, fmt::Debug, hash::Hash};
|
||||
use std::{fmt::Debug, hash::Hash};
|
||||
|
||||
// Re-export the namespaces into each other
|
||||
pub use component::*;
|
||||
#[cfg(feature = "hot_reload")]
|
||||
use dioxus_core::{Template, TemplateAttribute, TemplateNode};
|
||||
pub use element::*;
|
||||
#[cfg(feature = "hot_reload")]
|
||||
pub use hot_reload::HotReloadingContext;
|
||||
pub use ifmt::*;
|
||||
#[cfg(feature = "hot_reload")]
|
||||
use internment::Intern;
|
||||
pub use node::*;
|
||||
|
||||
@@ -38,6 +42,7 @@ use syn::{
|
||||
Result, Token,
|
||||
};
|
||||
|
||||
#[cfg(feature = "hot_reload")]
|
||||
// interns a object into a static object, resusing the value if it already exists
|
||||
fn intern<T: Eq + Hash + Send + Sync + ?Sized + 'static>(s: impl Into<Intern<T>>) -> &'static T {
|
||||
s.into().as_ref()
|
||||
@@ -50,6 +55,7 @@ pub struct CallBody {
|
||||
}
|
||||
|
||||
impl CallBody {
|
||||
#[cfg(feature = "hot_reload")]
|
||||
/// This will try to create a new template from the current body and the previous body. This will return None if the rsx has some dynamic part that has changed.
|
||||
/// This function intentionally leaks memory to create a static template.
|
||||
/// Keeping the template static allows us to simplify the core of dioxus and leaking memory in dev mode is less of an issue.
|
||||
@@ -140,6 +146,7 @@ pub struct TemplateRenderer<'a> {
|
||||
}
|
||||
|
||||
impl<'a> TemplateRenderer<'a> {
|
||||
#[cfg(feature = "hot_reload")]
|
||||
fn update_template<Ctx: HotReloadingContext>(
|
||||
&mut self,
|
||||
previous_call: Option<CallBody>,
|
||||
@@ -248,14 +255,16 @@ impl<'a> ToTokens for TemplateRenderer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "hot_reload")]
|
||||
#[derive(Default, Debug)]
|
||||
struct DynamicMapping {
|
||||
attribute_to_idx: HashMap<ElementAttr, Vec<usize>>,
|
||||
attribute_to_idx: std::collections::HashMap<ElementAttr, Vec<usize>>,
|
||||
last_attribute_idx: usize,
|
||||
node_to_idx: HashMap<BodyNode, Vec<usize>>,
|
||||
node_to_idx: std::collections::HashMap<BodyNode, Vec<usize>>,
|
||||
last_element_idx: usize,
|
||||
}
|
||||
|
||||
#[cfg(feature = "hot_reload")]
|
||||
impl DynamicMapping {
|
||||
fn from(nodes: Vec<BodyNode>) -> Self {
|
||||
let mut new = Self::default();
|
||||
@@ -349,6 +358,7 @@ pub struct DynamicContext<'a> {
|
||||
}
|
||||
|
||||
impl<'a> DynamicContext<'a> {
|
||||
#[cfg(feature = "hot_reload")]
|
||||
fn update_node<Ctx: HotReloadingContext>(
|
||||
&mut self,
|
||||
root: &'a BodyNode,
|
||||
@@ -558,6 +568,7 @@ impl<'a> DynamicContext<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "hot_reload")]
|
||||
#[test]
|
||||
fn create_template() {
|
||||
let input = quote! {
|
||||
@@ -643,6 +654,7 @@ fn create_template() {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "hot_reload")]
|
||||
#[test]
|
||||
fn diff_template() {
|
||||
use dioxus_core::Scope;
|
||||
|
||||
@@ -222,7 +222,7 @@ impl Parse for ForLoop {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let for_token: Token![for] = input.parse()?;
|
||||
|
||||
let pat = input.parse()?;
|
||||
let pat = Pat::parse_single(input)?;
|
||||
|
||||
let in_token: Token![in] = input.parse()?;
|
||||
let expr: Expr = input.call(Expr::parse_without_eager_brace)?;
|
||||
|
||||
Reference in new issue
Block a user