Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ lalrpop-util = "0.19"
proc-macro2 = "1.0.54"
quote = "1.0.26"
console = "0.15.5"
rust-format = { version="0.3.4", features=["pretty_please"]}
pretty_assertions = "1.4.0"

[build-dependencies]
lalrpop = "0.19.9"
Expand Down
6 changes: 3 additions & 3 deletions macros/src/grammar.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ HtmlIdent: Ident = {
<init:(<Ident> "-")*> <last:Ident> => {
let mut init = init;
init.push(last);
let (span, name) = init.into_iter().fold((None, String::new()), |(span, name), token| {
let (span, name): (Option<proc_macro2::Span>, String) = init.into_iter().fold((None, String::new()), |(span, name), token| {
(
match span {
None => Some(token.span().unstable()),
None => Some(token.span()),
Some(span) => {
#[cfg(can_join_spans)]
{
span.join(token.span().unstable())
span.join(token.span())
}
#[cfg(not(can_join_spans))]
{
Expand Down
97 changes: 87 additions & 10 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#![recursion_limit = "128"]
#![cfg_attr(can_show_location_of_runtime_parse_error, feature(proc_macro_span))]

extern crate proc_macro;
#[allow(unused_imports)]
use rust_format::Formatter;

use proc_macro::TokenStream;
extern crate proc_macro;

mod config;
mod declare;
Expand All @@ -21,16 +22,19 @@ mod span;
///
/// [axohtml]: https://docs.rs/axohtml/
#[proc_macro]
pub fn html(input: TokenStream) -> TokenStream {
let stream = lexer::unroll_stream(input.into(), false);
pub fn html(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
html_impl(input.into()).into()
}
fn html_impl(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
let stream = lexer::unroll_stream(input, false);
let result = html::expand_html(&stream);
TokenStream::from(match result {
match result {
Err(err) => error::parse_error(&stream, &err),
Ok((node, ty)) => match node.into_token_stream(&ty) {
Err(err) => err,
Ok(success) => success,
},
})
}
}

/// Construct a Dodrio node.
Expand All @@ -56,10 +60,14 @@ pub fn dodrio(input: TokenStream) -> TokenStream {
/// This macro is used by `axohtml` internally to generate types and
/// implementations for HTML elements.
#[proc_macro]
pub fn declare_elements(input: TokenStream) -> TokenStream {
let stream = lexer::keywordise(lexer::unroll_stream(input.into(), true));
pub fn declare_elements(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
declare_elements_impl(input.into()).into()
}

fn declare_elements_impl(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
let stream = lexer::keywordise(lexer::unroll_stream(input, true));
let result = declare::expand_declare(&stream);
TokenStream::from(match result {
match result {
Err(err) => error::parse_error(&stream, &err),
Ok(decls) => {
let mut out = proc_macro2::TokenStream::new();
Expand All @@ -68,5 +76,74 @@ pub fn declare_elements(input: TokenStream) -> TokenStream {
}
out
}
})
}
}

#[test]
fn test_declare_anchor_element() {
use quote::quote;

let input = quote!(
a {
download: String,
href: Uri,
hreflang: LanguageTag,
ping: SpacedList<Uri>,
rel: SpacedList<LinkType>,
target: Target,
type: Mime,
} in [FlowContent, PhrasingContent, InteractiveContent] with FlowContent;
);

let output = declare_elements_impl(input);

pretty_assertions::assert_eq!(
rust_format::PrettyPlease::default()
.format_str(output.to_string())
.unwrap(),
include_str!("tests/declare-anchor-element.rs")
)
}

#[test]
fn test_html_anchor_element() {
use quote::quote;

let input = quote!(
<a href="https://www.w3schools.com">
"Visit W3Schools.com!"
</a>
);

let output = html_impl(input);
let output = format!("fn html() {}", output.to_string());

pretty_assertions::assert_eq!(
rust_format::PrettyPlease::default()
.format_str(output.to_string())
.unwrap(),
include_str!("tests/generate-anchor-element.rs")
)
}

#[test]
fn test_html_button_event() {
use quote::quote;

let input = quote!(
<button onclick="alert(1)">
"Click me"
</button>
: String
);

let output = html_impl(input);
let output = format!("fn html() {}", output.to_string());

pretty_assertions::assert_eq!(
rust_format::PrettyPlease::default()
.format_str(output.to_string())
.unwrap(),
include_str!("tests/generate-button-event.rs")
)
}
11 changes: 5 additions & 6 deletions macros/src/span.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
pub fn from_unstable(span: proc_macro::Span) -> proc_macro2::Span {
let ident = proc_macro::Ident::new("_", span);
let tt = proc_macro::TokenTree::Ident(ident);
let tts = proc_macro::TokenStream::from(tt);
let tts2 = proc_macro2::TokenStream::from(tts);
tts2.into_iter().next().unwrap().span()
pub fn from_unstable(span: proc_macro2::Span) -> proc_macro2::Span {
let ident = proc_macro2::Ident::new("_", span);
let tt = proc_macro2::TokenTree::Ident(ident);
let tts = proc_macro2::TokenStream::from(tt);
tts.into_iter().next().unwrap().span()
}
Loading