Skip to content

Commit

Permalink
Revert "Improve nested html! expansion by unwrapping VNodes (yewstack…
Browse files Browse the repository at this point in the history
…#820)" (yewstack#842)

This reverts commit a900fbe.
  • Loading branch information
jstarry authored Jan 4, 2020
1 parent f731334 commit 70862a4
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 197 deletions.
2 changes: 1 addition & 1 deletion crates/macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ lazy_static = "1.3.0"
proc-macro-hack = "0.5"
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "1.0", features = ["full", "extra-traits", "visit-mut"] }
syn = { version = "1.0", features = ["full", "extra-traits"] }

[dev-dependencies]
yew = { path = "../.." }
Expand Down
2 changes: 1 addition & 1 deletion crates/macro/src/html_tree/html_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl PeekValue<()> for HtmlBlock {

impl Parse for HtmlBlock {
fn parse(input: ParseStream) -> ParseResult<Self> {
let content: syn::parse::ParseBuffer<'_>;
let content;
let brace = braced!(content in input);
let content = if HtmlIterable::peek(content.cursor()).is_some() {
BlockContent::Iterable(content.parse()?)
Expand Down
17 changes: 5 additions & 12 deletions crates/macro/src/html_tree/html_component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use syn::parse::{Parse, ParseStream, Result as ParseResult};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{
AngleBracketedGenericArguments, Expr, GenericArgument, Ident, Index, Path, PathArguments,
PathSegment, Token, Type, TypePath,
AngleBracketedGenericArguments, Expr, GenericArgument, Ident, Path, PathArguments, PathSegment,
Token, Type, TypePath,
};

pub struct HtmlComponent {
Expand Down Expand Up @@ -126,17 +126,10 @@ impl ToTokens for HtmlComponent {
};

let set_children = if !children.is_empty() {
let i = (0..children.len())
.map(|x| Index::from(x))
.collect::<Vec<_>>();
quote! {
.children(::yew::html::ChildrenRenderer::new({
let mut v = Vec::new();
let comps = (#(#children,)*);
#(::yew::utils::NodeSeq::from(comps.#i).into_iter()
.for_each(|x| v.push(x.into()));)*
v
}))
.children(::yew::html::ChildrenRenderer::new(
vec![#(#children.into(),)*]
))
}
} else {
quote! {}
Expand Down
22 changes: 1 addition & 21 deletions crates/macro/src/html_tree/html_iterable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ use syn::parse::{Parse, ParseStream, Result as ParseResult};
use syn::spanned::Spanned;
use syn::{Expr, Token};

use proc_macro2::{Ident, Span};
use syn::visit_mut::{self, VisitMut};
use syn::Macro;

pub struct HtmlIterable(Expr);

impl PeekValue<()> for HtmlIterable {
Expand All @@ -20,28 +16,12 @@ impl PeekValue<()> for HtmlIterable {
}
}

struct HtmlInnerModifier;
impl VisitMut for HtmlInnerModifier {
fn visit_macro_mut(&mut self, node: &mut Macro) {
if node.path.is_ident("html") {
let ident = &mut node.path.segments.last_mut().unwrap().ident;
*ident = Ident::new("html_nested", Span::call_site());
}

// Delegate to the default impl to visit any nested functions.
visit_mut::visit_macro_mut(self, node);
}
}

impl Parse for HtmlIterable {
fn parse(input: ParseStream) -> ParseResult<Self> {
let for_token = input.parse::<Token![for]>()?;

match input.parse() {
Ok(mut expr) => {
HtmlInnerModifier.visit_expr_mut(&mut expr);
Ok(HtmlIterable(expr))
}
Ok(expr) => Ok(HtmlIterable(expr)),
Err(err) => {
if err.to_string().starts_with("unexpected end of input") {
Err(syn::Error::new_spanned(
Expand Down
32 changes: 8 additions & 24 deletions crates/macro/src/html_tree/html_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,8 @@ use quote::{quote, quote_spanned, ToTokens};
use syn::buffer::Cursor;
use syn::parse::{Parse, ParseStream, Result};
use syn::spanned::Spanned;
use syn::Expr;
use syn::Lit;

use proc_macro2::{Ident, Span};
use syn::visit_mut::{self, VisitMut};
use syn::Macro;

struct HtmlInnerModifier;
impl VisitMut for HtmlInnerModifier {
fn visit_macro_mut(&mut self, node: &mut Macro) {
if node.path.is_ident("html") {
let ident = &mut node.path.segments.last_mut().unwrap().ident;
*ident = Ident::new("html_nested", Span::call_site());
}

// Delegate to the default impl to visit any nested functions.
visit_mut::visit_macro_mut(self, node);
}
}

pub struct HtmlNode(Node);

impl Parse for HtmlNode {
Expand All @@ -36,9 +18,7 @@ impl Parse for HtmlNode {
}
Node::Literal(lit)
} else {
let mut expr: Expr = input.parse()?;
HtmlInnerModifier.visit_expr_mut(&mut expr);
Node::Expression(expr)
Node::Raw(input.parse()?)
};

Ok(HtmlNode(node))
Expand Down Expand Up @@ -66,8 +46,12 @@ impl ToTokens for HtmlNode {
impl ToTokens for Node {
fn to_tokens(&self, tokens: &mut TokenStream) {
let node_token = match &self {
Node::Literal(lit) => quote! {#lit},
Node::Expression(expr) => quote_spanned! {expr.span()=> {#expr} },
Node::Literal(lit) => quote! {
::yew::virtual_dom::VNode::from(#lit)
},
Node::Raw(stream) => quote_spanned! {stream.span()=>
::yew::virtual_dom::VNode::from({#stream})
},
};

tokens.extend(node_token);
Expand All @@ -76,5 +60,5 @@ impl ToTokens for Node {

enum Node {
Literal(Lit),
Expression(Expr),
Raw(TokenStream),
}
13 changes: 0 additions & 13 deletions crates/macro/src/html_tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,19 +126,6 @@ impl HtmlTree {
}
}

pub struct HtmlRootNested(HtmlTreeNested);
impl Parse for HtmlRootNested {
fn parse(input: ParseStream) -> Result<Self> {
Ok(HtmlRootNested(HtmlTreeNested::parse(input)?))
}
}

impl ToTokens for HtmlRootNested {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
self.0.to_tokens(tokens);
}
}

pub struct HtmlTreeNested(HtmlTree);
impl Parse for HtmlTreeNested {
fn parse(input: ParseStream) -> Result<Self> {
Expand Down
8 changes: 1 addition & 7 deletions crates/macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ mod derive_props;
mod html_tree;

use derive_props::DerivePropsInput;
use html_tree::{HtmlRoot, HtmlRootNested};
use html_tree::HtmlRoot;
use proc_macro::TokenStream;
use proc_macro_hack::proc_macro_hack;
use quote::{quote, ToTokens};
Expand Down Expand Up @@ -94,12 +94,6 @@ pub fn derive_props(input: TokenStream) -> TokenStream {
TokenStream::from(input.into_token_stream())
}

#[proc_macro_hack]
pub fn html_nested(input: TokenStream) -> TokenStream {
let root = parse_macro_input!(input as HtmlRootNested);
TokenStream::from(quote! {#root})
}

#[proc_macro_hack]
pub fn html(input: TokenStream) -> TokenStream {
let root = parse_macro_input!(input as HtmlRoot);
Expand Down
6 changes: 0 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,9 @@ use proc_macro_hack::proc_macro_hack;
#[proc_macro_hack(support_nested)]
pub use yew_macro::html;

#[doc(hidden)]
#[proc_macro_hack(support_nested)]
pub use yew_macro::html_nested;

/// This module contains macros which implements html! macro and JSX-like templates
pub mod macros {
pub use crate::html;
pub use crate::html_nested;
pub use yew_macro::Properties;
}

Expand Down Expand Up @@ -163,7 +158,6 @@ pub mod prelude {
Renderable, ShouldRender,
};
pub use crate::macros::*;
pub use crate::utils::NodeSeq;
pub use crate::virtual_dom::Classes;

/// Prelude module for creating worker.
Expand Down
29 changes: 0 additions & 29 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,10 @@
use failure::{err_msg, Error};
use stdweb::web::document;

use crate::virtual_dom::VNode;

/// Returns `host` for the current document. Useful to connect to a server that server the app.
pub fn host() -> Result<String, Error> {
document()
.location()
.ok_or_else(|| err_msg("can't get location"))
.and_then(|l| l.host().map_err(Error::from))
}

/// Specialty type necessary for helping flattening components returned from nested html macros.
#[derive(Debug)]
pub struct NodeSeq<T>(Vec<T>)
where
T: Into<VNode>;

impl<T: Into<VNode>> From<T> for NodeSeq<T> {
fn from(val: T) -> Self {
NodeSeq(vec![val])
}
}

impl<T: Into<VNode>> From<Vec<T>> for NodeSeq<T> {
fn from(val: Vec<T>) -> Self {
NodeSeq(val)
}
}

impl<T: Into<VNode>> IntoIterator for NodeSeq<T> {
type Item = T;
type IntoIter = std::vec::IntoIter<Self::Item>;

fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
13 changes: 13 additions & 0 deletions tests/macro/html-component-fail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use std::marker::PhantomData;
use yew::prelude::*;
use yew::virtual_dom::{VChild, VComp, VNode};

#[derive(Clone, Properties, PartialEq)]
pub struct ChildProperties {
Expand All @@ -20,6 +21,18 @@ impl Component for Child {
fn view(&self) -> Html { unimplemented!() }
}

impl From<VChild<Child>> for ChildProperties {
fn from(comp: VChild<Child>) -> Self {
comp.props
}
}

impl Into<VNode> for ChildProperties {
fn into(self) -> VNode {
VComp::new::<Child>(self, NodeRef::default()).into()
}
}

#[derive(Clone, Properties)]
pub struct ChildContainerProperties {
#[props(required)]
Expand Down
Loading

0 comments on commit 70862a4

Please sign in to comment.