From f1fe5f23c9edfb23fb1e5b483de2da374a91050b Mon Sep 17 00:00:00 2001 From: RedPhoenixQ Date: Tue, 14 Nov 2023 22:30:09 +0100 Subject: [PATCH 1/7] Parse many literals along side idents in names --- maud/tests/basic_syntax.rs | 9 +++++++++ maud_macros/src/parse.rs | 25 +++++++++++++------------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/maud/tests/basic_syntax.rs b/maud/tests/basic_syntax.rs index 96e0235e..5cc6f517 100644 --- a/maud/tests/basic_syntax.rs +++ b/maud/tests/basic_syntax.rs @@ -209,6 +209,15 @@ fn other_literals_in_attribute_names() { ); } +#[test] +fn idents_and_literals_in_names() { + let result = html! { custom:element-001 test:123-"test"="123" .m-2.p-2 {} }; + assert_eq!( + result.into_string(), + r#""# + ); +} + #[test] fn class_shorthand() { let result = html! { p { "Hi, " span.name { "Lyra" } "!" } }; diff --git a/maud_macros/src/parse.rs b/maud_macros/src/parse.rs index 662b8309..4e2c12f1 100644 --- a/maud_macros/src/parse.rs +++ b/maud_macros/src/parse.rs @@ -702,27 +702,28 @@ impl Parser { /// Parses an identifier, without dealing with namespaces. fn try_name(&mut self) -> Option { let mut result = Vec::new(); - match self.peek() { - Some(token @ TokenTree::Ident(_)) | Some(token @ TokenTree::Literal(_)) => { - self.advance(); - result.push(token); - } - _ => return None, - }; - let mut expect_ident = false; + let mut expect_ident_or_literal = true; loop { - expect_ident = match self.peek() { + expect_ident_or_literal = match self.peek() { Some(TokenTree::Punct(ref punct)) if punct.as_char() == '-' => { self.advance(); result.push(TokenTree::Punct(punct.clone())); true } - Some(TokenTree::Ident(ref ident)) if expect_ident => { + Some(token @ TokenTree::Ident(_)) | Some(token @ TokenTree::Literal(_)) + if expect_ident_or_literal => + { self.advance(); - result.push(TokenTree::Ident(ident.clone())); + result.push(token); false } - _ => break, + _ => { + if result.is_empty() { + return None; + } else { + break; + } + } }; } Some(result.into_iter().collect()) From f7b6250b89f915c8ca101cda6ebebb4c58c60173 Mon Sep 17 00:00:00 2001 From: RedPhoenixQ Date: Wed, 15 Nov 2023 12:06:59 +0100 Subject: [PATCH 2/7] Accept ints as literals We will not accept floats because `123.123` is a float literal, but `123 .123` is a int literal followed by a class called `123`. This could be confusing so it will not be accepted. Ints can have leading zeros, like `0123`, but this is not guarranteed by the rust compiler to always work, which could cause future errors. An example would be truncating `001` to `1`. --- maud_macros/src/parse.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/maud_macros/src/parse.rs b/maud_macros/src/parse.rs index 4e2c12f1..6d14914e 100644 --- a/maud_macros/src/parse.rs +++ b/maud_macros/src/parse.rs @@ -204,7 +204,13 @@ impl Parser { } // Boolean literals are idents, so `Lit::Bool` is handled in // `markup`, not here. - Lit::Int(..) | Lit::Float(..) => { + Lit::Int(lit_int) => { + return ast::Markup::Literal { + content: lit_int.to_string(), + span: SpanRange::single_span(literal.span()), + }; + } + Lit::Float(..) => { emit_error!(literal, r#"literal must be double-quoted: `"{}"`"#, literal); } Lit::Char(lit_char) => { From 16c492fd2a7daf5fd99ecd3dacba05d889c84cc2 Mon Sep 17 00:00:00 2001 From: RedPhoenixQ Date: Wed, 15 Nov 2023 12:07:21 +0100 Subject: [PATCH 3/7] Limit accepted literals using existing function --- maud/tests/basic_syntax.rs | 5 ++--- maud_macros/src/parse.rs | 10 +++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/maud/tests/basic_syntax.rs b/maud/tests/basic_syntax.rs index 5cc6f517..b6eb4d37 100644 --- a/maud/tests/basic_syntax.rs +++ b/maud/tests/basic_syntax.rs @@ -201,11 +201,10 @@ fn raw_string_literals_in_attribute_names() { #[test] fn other_literals_in_attribute_names() { - let result = - html! { this b"byte_string"="false" 123="123" 2.5 true 'a'="a" b'b'="b" of-course {} }; + let result = html! { this r#"byte_string"#="false" 123="123" "2.5" true of-course {} }; assert_eq!( result.into_string(), - r#""# + r#""# ); } diff --git a/maud_macros/src/parse.rs b/maud_macros/src/parse.rs index 6d14914e..1b85d1f3 100644 --- a/maud_macros/src/parse.rs +++ b/maud_macros/src/parse.rs @@ -716,13 +716,17 @@ impl Parser { result.push(TokenTree::Punct(punct.clone())); true } - Some(token @ TokenTree::Ident(_)) | Some(token @ TokenTree::Literal(_)) - if expect_ident_or_literal => - { + Some(token @ TokenTree::Ident(_)) if expect_ident_or_literal => { self.advance(); result.push(token); false } + Some(TokenTree::Literal(ref literal)) if expect_ident_or_literal => { + self.literal(literal.clone()); + self.advance(); + result.push(TokenTree::Literal(literal.clone())); + false + } _ => { if result.is_empty() { return None; From bb1f966687dad8af076e5ee9c9bcc1950a64af9e Mon Sep 17 00:00:00 2001 From: RedPhoenixQ Date: Wed, 15 Nov 2023 12:14:42 +0100 Subject: [PATCH 4/7] Update error output for non-string-literal --- maud/tests/warnings/non-string-literal.stderr | 38 +++++++------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/maud/tests/warnings/non-string-literal.stderr b/maud/tests/warnings/non-string-literal.stderr index 635617b8..39d06773 100644 --- a/maud/tests/warnings/non-string-literal.stderr +++ b/maud/tests/warnings/non-string-literal.stderr @@ -1,53 +1,43 @@ -error: literal must be double-quoted: `"42"` - --> $DIR/non-string-literal.rs:5:9 - | -5 | 42 - | ^^ - -error: literal must be double-quoted: `"42usize"` - --> $DIR/non-string-literal.rs:6:9 - | -6 | 42usize - | ^^^^^^^ - error: literal must be double-quoted: `"42.0"` - --> $DIR/non-string-literal.rs:7:9 + --> tests/warnings/non-string-literal.rs:7:9 | 7 | 42.0 | ^^^^ error: literal must be double-quoted: `"a"` - --> $DIR/non-string-literal.rs:8:9 + --> tests/warnings/non-string-literal.rs:8:9 | 8 | 'a' | ^^^ error: expected string - --> $DIR/non-string-literal.rs:9:9 + --> tests/warnings/non-string-literal.rs:9:9 | 9 | b"a" | ^^^^ error: expected string - --> $DIR/non-string-literal.rs:10:9 + --> tests/warnings/non-string-literal.rs:10:9 | 10 | b'a' | ^^^^ error: attribute value must be a string - --> $DIR/non-string-literal.rs:13:24 + + = help: to declare an empty attribute, omit the equals sign: `disabled` + = help: to toggle the attribute, use square brackets: `disabled[some_boolean_flag]` + + --> tests/warnings/non-string-literal.rs:13:24 | 13 | input disabled=true; | ^^^^ - | - = help: to declare an empty attribute, omit the equals sign: `disabled` - = help: to toggle the attribute, use square brackets: `disabled[some_boolean_flag]` error: attribute value must be a string - --> $DIR/non-string-literal.rs:14:24 + + = help: to declare an empty attribute, omit the equals sign: `disabled` + = help: to toggle the attribute, use square brackets: `disabled[some_boolean_flag]` + + --> tests/warnings/non-string-literal.rs:14:24 | 14 | input disabled=false; | ^^^^^ - | - = help: to declare an empty attribute, omit the equals sign: `disabled` - = help: to toggle the attribute, use square brackets: `disabled[some_boolean_flag]` From 241a20699bfbc4ed9e674743d78b277eddd6e9ef Mon Sep 17 00:00:00 2001 From: RedPhoenixQ Date: Wed, 15 Nov 2023 12:17:04 +0100 Subject: [PATCH 5/7] Test output of ints with specified type This outputs exactly what is written, which is the obvious behaviour --- maud/tests/basic_syntax.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maud/tests/basic_syntax.rs b/maud/tests/basic_syntax.rs index b6eb4d37..015895f6 100644 --- a/maud/tests/basic_syntax.rs +++ b/maud/tests/basic_syntax.rs @@ -201,10 +201,10 @@ fn raw_string_literals_in_attribute_names() { #[test] fn other_literals_in_attribute_names() { - let result = html! { this r#"byte_string"#="false" 123="123" "2.5" true of-course {} }; + let result = html! { this r#"byte_string"#="false" 123="123" 123usize "2.5" true of-course {} }; assert_eq!( result.into_string(), - r#""# + r#""# ); } From 2d32f9dd551a79ced156bcb21e7beb58b9c65b42 Mon Sep 17 00:00:00 2001 From: RedPhoenixQ Date: Wed, 15 Nov 2023 12:24:00 +0100 Subject: [PATCH 6/7] Use nightly version to generate output Previous verison was not using nightly, causing errors in the automated test that are using nightly --- maud/tests/warnings/non-string-literal.stderr | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/maud/tests/warnings/non-string-literal.stderr b/maud/tests/warnings/non-string-literal.stderr index 39d06773..7755e3f0 100644 --- a/maud/tests/warnings/non-string-literal.stderr +++ b/maud/tests/warnings/non-string-literal.stderr @@ -23,21 +23,19 @@ error: expected string | ^^^^ error: attribute value must be a string - - = help: to declare an empty attribute, omit the equals sign: `disabled` - = help: to toggle the attribute, use square brackets: `disabled[some_boolean_flag]` - --> tests/warnings/non-string-literal.rs:13:24 | 13 | input disabled=true; | ^^^^ + | + = help: to declare an empty attribute, omit the equals sign: `disabled` + = help: to toggle the attribute, use square brackets: `disabled[some_boolean_flag]` error: attribute value must be a string - - = help: to declare an empty attribute, omit the equals sign: `disabled` - = help: to toggle the attribute, use square brackets: `disabled[some_boolean_flag]` - --> tests/warnings/non-string-literal.rs:14:24 | 14 | input disabled=false; | ^^^^^ + | + = help: to declare an empty attribute, omit the equals sign: `disabled` + = help: to toggle the attribute, use square brackets: `disabled[some_boolean_flag]` From ab669657a700ed80f5fc2ba35a04b4d76cf6ecbf Mon Sep 17 00:00:00 2001 From: Chris Wong Date: Thu, 4 Jan 2024 15:25:39 +1100 Subject: [PATCH 7/7] Replace "byte_string" with "raw_string" in test --- maud/tests/basic_syntax.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maud/tests/basic_syntax.rs b/maud/tests/basic_syntax.rs index 015895f6..c2c5dc5f 100644 --- a/maud/tests/basic_syntax.rs +++ b/maud/tests/basic_syntax.rs @@ -201,10 +201,10 @@ fn raw_string_literals_in_attribute_names() { #[test] fn other_literals_in_attribute_names() { - let result = html! { this r#"byte_string"#="false" 123="123" 123usize "2.5" true of-course {} }; + let result = html! { this r#"raw_string"#="false" 123="123" 123usize "2.5" true of-course {} }; assert_eq!( result.into_string(), - r#""# + r#""# ); }