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]
|
#[test]
|
||||||
fn other_literals_in_attribute_names() {
|
fn other_literals_in_attribute_names() {
|
||||||
let result =
|
let result = html! { this r#"raw_string"#="false" 123="123" 123usize "2.5" true of-course {} };
|
||||||
html! { this b"byte_string"="false" 123="123" 2.5 true 'a'="a" b'b'="b" of-course {} };
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.into_string(),
|
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"`
|
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
|
7 | 42.0
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: literal must be double-quoted: `"a"`
|
error: literal must be double-quoted: `"a"`
|
||||||
--> $DIR/non-string-literal.rs:8:9
|
--> tests/warnings/non-string-literal.rs:8:9
|
||||||
|
|
|
|
||||||
8 | 'a'
|
8 | 'a'
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: expected string
|
error: expected string
|
||||||
--> $DIR/non-string-literal.rs:9:9
|
--> tests/warnings/non-string-literal.rs:9:9
|
||||||
|
|
|
|
||||||
9 | b"a"
|
9 | b"a"
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: expected string
|
error: expected string
|
||||||
--> $DIR/non-string-literal.rs:10:9
|
--> tests/warnings/non-string-literal.rs:10:9
|
||||||
|
|
|
|
||||||
10 | b'a'
|
10 | b'a'
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: attribute value must be a string
|
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;
|
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]`
|
= help: to toggle the attribute, use square brackets: `disabled[some_boolean_flag]`
|
||||||
|
|
||||||
error: attribute value must be a string
|
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;
|
14 | input disabled=false;
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
@ -204,7 +204,13 @@ impl Parser {
|
||||||
}
|
}
|
||||||
// Boolean literals are idents, so `Lit::Bool` is handled in
|
// Boolean literals are idents, so `Lit::Bool` is handled in
|
||||||
// `markup`, not here.
|
// `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);
|
emit_error!(literal, r#"literal must be double-quoted: `"{}"`"#, literal);
|
||||||
}
|
}
|
||||||
Lit::Char(lit_char) => {
|
Lit::Char(lit_char) => {
|
||||||
|
@ -702,27 +708,32 @@ impl Parser {
|
||||||
/// Parses an identifier, without dealing with namespaces.
|
/// Parses an identifier, without dealing with namespaces.
|
||||||
fn try_name(&mut self) -> Option<TokenStream> {
|
fn try_name(&mut self) -> Option<TokenStream> {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
match self.peek() {
|
let mut expect_ident_or_literal = true;
|
||||||
Some(token @ TokenTree::Ident(_)) | Some(token @ TokenTree::Literal(_)) => {
|
|
||||||
self.advance();
|
|
||||||
result.push(token);
|
|
||||||
}
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
let mut expect_ident = false;
|
|
||||||
loop {
|
loop {
|
||||||
expect_ident = match self.peek() {
|
expect_ident_or_literal = match self.peek() {
|
||||||
Some(TokenTree::Punct(ref punct)) if punct.as_char() == '-' => {
|
Some(TokenTree::Punct(ref punct)) if punct.as_char() == '-' => {
|
||||||
self.advance();
|
self.advance();
|
||||||
result.push(TokenTree::Punct(punct.clone()));
|
result.push(TokenTree::Punct(punct.clone()));
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
Some(TokenTree::Ident(ref ident)) if expect_ident => {
|
Some(token @ TokenTree::Ident(_)) if expect_ident_or_literal => {
|
||||||
self.advance();
|
self.advance();
|
||||||
result.push(TokenTree::Ident(ident.clone()));
|
result.push(token);
|
||||||
false
|
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())
|
Some(result.into_iter().collect())
|
||||||
|
|
Loading…
Add table
Reference in a new issue