Parse many literals along side idents in names (#398)
* Parse many literals along side idents in names * 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`. * Limit accepted literals using existing function * Update error output for non-string-literal * Test output of ints with specified type This outputs exactly what is written, which is the obvious behaviour * Use nightly version to generate output Previous verison was not using nightly, causing errors in the automated test that are using nightly * Replace "byte_string" with "raw_string" in test --------- Co-authored-by: Chris Wong <lambda.fairy@gmail.com>
This commit is contained in:
parent
0de60b0c86
commit
b3a98c98d5
3 changed files with 41 additions and 34 deletions
|
@ -201,11 +201,19 @@ 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#"raw_string"#="false" 123="123" 123usize "2.5" true of-course {} };
|
||||
assert_eq!(
|
||||
result.into_string(),
|
||||
r#"<this byte_string="false" 123="123" 2.5 true a="a" b="b" of-course></this>"#
|
||||
r#"<this raw_string="false" 123="123" 123usize 2.5 true of-course></this>"#
|
||||
);
|
||||
}
|
||||
|
||||
#[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#"<custom:element-001 class="m-2 p-2" test:123-test="123"></custom:element-001>"#
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,41 +1,29 @@
|
|||
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
|
||||
--> tests/warnings/non-string-literal.rs:13:24
|
||||
|
|
||||
13 | input disabled=true;
|
||||
| ^^^^
|
||||
|
@ -44,7 +32,7 @@ error: attribute value must be a string
|
|||
= 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
|
||||
--> tests/warnings/non-string-literal.rs:14:24
|
||||
|
|
||||
14 | input disabled=false;
|
||||
| ^^^^^
|
||||
|
|
|
@ -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) => {
|
||||
|
@ -702,27 +708,32 @@ impl Parser {
|
|||
/// Parses an identifier, without dealing with namespaces.
|
||||
fn try_name(&mut self) -> Option<TokenStream> {
|
||||
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(_)) if expect_ident_or_literal => {
|
||||
self.advance();
|
||||
result.push(TokenTree::Ident(ident.clone()));
|
||||
result.push(token);
|
||||
false
|
||||
}
|
||||
_ => break,
|
||||
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;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Some(result.into_iter().collect())
|
||||
|
|
Loading…
Add table
Reference in a new issue