mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-01 04:18:20 +00:00
Merge pull request #19746 from Veykril/push-swvuyqwwplrt
fix: Fix proc-macro API creating malformed negative literals
This commit is contained in:
commit
aaefc26412
7 changed files with 413 additions and 42 deletions
|
|
@ -31,12 +31,17 @@ pub fn fn_like_mk_literals(_args: TokenStream) -> TokenStream {
|
|||
TokenTree::from(Literal::byte_string(b"byte_string")),
|
||||
TokenTree::from(Literal::character('c')),
|
||||
TokenTree::from(Literal::string("string")),
|
||||
TokenTree::from(Literal::c_string(c"cstring")),
|
||||
// as of 2022-07-21, there's no method on `Literal` to build a raw
|
||||
// string or a raw byte string
|
||||
TokenTree::from(Literal::f64_suffixed(3.14)),
|
||||
TokenTree::from(Literal::f64_suffixed(-3.14)),
|
||||
TokenTree::from(Literal::f64_unsuffixed(3.14)),
|
||||
TokenTree::from(Literal::f64_unsuffixed(-3.14)),
|
||||
TokenTree::from(Literal::i64_suffixed(123)),
|
||||
TokenTree::from(Literal::i64_suffixed(-123)),
|
||||
TokenTree::from(Literal::i64_unsuffixed(123)),
|
||||
TokenTree::from(Literal::i64_unsuffixed(-123)),
|
||||
];
|
||||
TokenStream::from_iter(trees)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,6 +168,26 @@ impl server::TokenStream for RaSpanServer {
|
|||
}
|
||||
|
||||
bridge::TokenTree::Literal(literal) => {
|
||||
let token_trees =
|
||||
if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
|
||||
let punct = tt::Punct {
|
||||
spacing: tt::Spacing::Alone,
|
||||
span: literal.span,
|
||||
char: '-' as char,
|
||||
};
|
||||
let leaf: tt::Leaf = tt::Leaf::from(punct);
|
||||
let minus_tree = tt::TokenTree::from(leaf);
|
||||
|
||||
let literal = tt::Literal {
|
||||
symbol: Symbol::intern(symbol),
|
||||
suffix: literal.suffix,
|
||||
span: literal.span,
|
||||
kind: literal_kind_to_internal(literal.kind),
|
||||
};
|
||||
let leaf: tt::Leaf = tt::Leaf::from(literal);
|
||||
let tree = tt::TokenTree::from(leaf);
|
||||
vec![minus_tree, tree]
|
||||
} else {
|
||||
let literal = tt::Literal {
|
||||
symbol: literal.symbol,
|
||||
suffix: literal.suffix,
|
||||
|
|
@ -177,7 +197,9 @@ impl server::TokenStream for RaSpanServer {
|
|||
|
||||
let leaf: tt::Leaf = tt::Leaf::from(literal);
|
||||
let tree = tt::TokenTree::from(leaf);
|
||||
TokenStream { token_trees: vec![tree] }
|
||||
vec![tree]
|
||||
};
|
||||
TokenStream { token_trees }
|
||||
}
|
||||
|
||||
bridge::TokenTree::Punct(p) => {
|
||||
|
|
|
|||
|
|
@ -153,6 +153,26 @@ impl server::TokenStream for TokenIdServer {
|
|||
}
|
||||
|
||||
bridge::TokenTree::Literal(literal) => {
|
||||
let token_trees =
|
||||
if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
|
||||
let punct = tt::Punct {
|
||||
spacing: tt::Spacing::Alone,
|
||||
span: literal.span,
|
||||
char: '-' as char,
|
||||
};
|
||||
let leaf: tt::Leaf = tt::Leaf::from(punct);
|
||||
let minus_tree = tt::TokenTree::from(leaf);
|
||||
|
||||
let literal = Literal {
|
||||
symbol: Symbol::intern(symbol),
|
||||
suffix: literal.suffix,
|
||||
span: literal.span,
|
||||
kind: literal_kind_to_internal(literal.kind),
|
||||
};
|
||||
let leaf: tt::Leaf = tt::Leaf::from(literal);
|
||||
let tree = tt::TokenTree::from(leaf);
|
||||
vec![minus_tree, tree]
|
||||
} else {
|
||||
let literal = Literal {
|
||||
symbol: literal.symbol,
|
||||
suffix: literal.suffix,
|
||||
|
|
@ -160,9 +180,11 @@ impl server::TokenStream for TokenIdServer {
|
|||
kind: literal_kind_to_internal(literal.kind),
|
||||
};
|
||||
|
||||
let leaf = tt::Leaf::from(literal);
|
||||
let tree = TokenTree::from(leaf);
|
||||
TokenStream { token_trees: vec![tree] }
|
||||
let leaf: tt::Leaf = tt::Leaf::from(literal);
|
||||
let tree = tt::TokenTree::from(leaf);
|
||||
vec![tree]
|
||||
};
|
||||
TokenStream { token_trees }
|
||||
}
|
||||
|
||||
bridge::TokenTree::Punct(p) => {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,11 @@ impl<S: Copy> TokenStream<S> {
|
|||
span: ident.span,
|
||||
}))
|
||||
}
|
||||
// Note, we do not have to assemble our `-` punct and literal split into a single
|
||||
// negative bridge literal here. As the proc-macro docs state
|
||||
// > Literals created from negative numbers might not survive round-trips through
|
||||
// > TokenStream or strings and may be broken into two tokens (- and positive
|
||||
// > literal).
|
||||
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
|
||||
result.push(bridge::TokenTree::Literal(bridge::Literal {
|
||||
span: lit.span,
|
||||
|
|
|
|||
|
|
@ -11,8 +11,24 @@ fn test_derive_empty() {
|
|||
assert_expand(
|
||||
"DeriveEmpty",
|
||||
r#"struct S;"#,
|
||||
expect!["SUBTREE $$ 1 1"],
|
||||
expect!["SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024"],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 1 1
|
||||
IDENT struct 1
|
||||
IDENT S 1
|
||||
PUNCH ; [alone] 1
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 1 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT struct 42:2@0..6#ROOT2024
|
||||
IDENT S 42:2@7..8#ROOT2024
|
||||
PUNCH ; [alone] 42:2@8..9#ROOT2024
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024"#]],
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -22,6 +38,13 @@ fn test_derive_error() {
|
|||
"DeriveError",
|
||||
r#"struct S;"#,
|
||||
expect![[r#"
|
||||
SUBTREE $$ 1 1
|
||||
IDENT struct 1
|
||||
IDENT S 1
|
||||
PUNCH ; [alone] 1
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 1 1
|
||||
IDENT compile_error 1
|
||||
PUNCH ! [alone] 1
|
||||
|
|
@ -29,6 +52,13 @@ fn test_derive_error() {
|
|||
LITERAL Str #[derive(DeriveError)] struct S ; 1
|
||||
PUNCH ; [alone] 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT struct 42:2@0..6#ROOT2024
|
||||
IDENT S 42:2@7..8#ROOT2024
|
||||
PUNCH ; [alone] 42:2@8..9#ROOT2024
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT compile_error 42:2@0..100#ROOT2024
|
||||
PUNCH ! [alone] 42:2@0..100#ROOT2024
|
||||
|
|
@ -44,6 +74,17 @@ fn test_fn_like_macro_noop() {
|
|||
"fn_like_noop",
|
||||
r#"ident, 0, 1, []"#,
|
||||
expect![[r#"
|
||||
SUBTREE $$ 1 1
|
||||
IDENT ident 1
|
||||
PUNCH , [alone] 1
|
||||
LITERAL Integer 0 1
|
||||
PUNCH , [alone] 1
|
||||
LITERAL Integer 1 1
|
||||
PUNCH , [alone] 1
|
||||
SUBTREE [] 1 1
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 1 1
|
||||
IDENT ident 1
|
||||
PUNCH , [alone] 1
|
||||
|
|
@ -53,6 +94,17 @@ fn test_fn_like_macro_noop() {
|
|||
PUNCH , [alone] 1
|
||||
SUBTREE [] 1 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT ident 42:2@0..5#ROOT2024
|
||||
PUNCH , [alone] 42:2@5..6#ROOT2024
|
||||
LITERAL Integer 0 42:2@7..8#ROOT2024
|
||||
PUNCH , [alone] 42:2@8..9#ROOT2024
|
||||
LITERAL Integer 1 42:2@10..11#ROOT2024
|
||||
PUNCH , [alone] 42:2@11..12#ROOT2024
|
||||
SUBTREE [] 42:2@13..14#ROOT2024 42:2@14..15#ROOT2024
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT ident 42:2@0..5#ROOT2024
|
||||
PUNCH , [alone] 42:2@5..6#ROOT2024
|
||||
|
|
@ -70,11 +122,25 @@ fn test_fn_like_macro_clone_ident_subtree() {
|
|||
"fn_like_clone_tokens",
|
||||
r#"ident, []"#,
|
||||
expect![[r#"
|
||||
SUBTREE $$ 1 1
|
||||
IDENT ident 1
|
||||
PUNCH , [alone] 1
|
||||
SUBTREE [] 1 1
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 1 1
|
||||
IDENT ident 1
|
||||
PUNCH , [alone] 1
|
||||
SUBTREE [] 1 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT ident 42:2@0..5#ROOT2024
|
||||
PUNCH , [alone] 42:2@5..6#ROOT2024
|
||||
SUBTREE [] 42:2@7..8#ROOT2024 42:2@8..9#ROOT2024
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT ident 42:2@0..5#ROOT2024
|
||||
PUNCH , [alone] 42:2@5..6#ROOT2024
|
||||
|
|
@ -88,9 +154,19 @@ fn test_fn_like_macro_clone_raw_ident() {
|
|||
"fn_like_clone_tokens",
|
||||
"r#async",
|
||||
expect![[r#"
|
||||
SUBTREE $$ 1 1
|
||||
IDENT r#async 1
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 1 1
|
||||
IDENT r#async 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT r#async 42:2@0..7#ROOT2024
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT r#async 42:2@0..7#ROOT2024"#]],
|
||||
);
|
||||
|
|
@ -103,9 +179,21 @@ fn test_fn_like_fn_like_span_join() {
|
|||
"fn_like_span_join",
|
||||
"foo bar",
|
||||
expect![[r#"
|
||||
SUBTREE $$ 1 1
|
||||
IDENT foo 1
|
||||
IDENT bar 1
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 1 1
|
||||
IDENT r#joined 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT foo 42:2@0..3#ROOT2024
|
||||
IDENT bar 42:2@8..11#ROOT2024
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT r#joined 42:2@0..11#ROOT2024"#]],
|
||||
);
|
||||
|
|
@ -118,11 +206,25 @@ fn test_fn_like_fn_like_span_ops() {
|
|||
"fn_like_span_ops",
|
||||
"set_def_site resolved_at_def_site start_span",
|
||||
expect![[r#"
|
||||
SUBTREE $$ 1 1
|
||||
IDENT set_def_site 1
|
||||
IDENT resolved_at_def_site 1
|
||||
IDENT start_span 1
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 1 1
|
||||
IDENT set_def_site 0
|
||||
IDENT resolved_at_def_site 1
|
||||
IDENT start_span 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT set_def_site 42:2@0..12#ROOT2024
|
||||
IDENT resolved_at_def_site 42:2@13..33#ROOT2024
|
||||
IDENT start_span 42:2@34..44#ROOT2024
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT set_def_site 41:1@0..150#ROOT2024
|
||||
IDENT resolved_at_def_site 42:2@13..33#ROOT2024
|
||||
|
|
@ -136,22 +238,48 @@ fn test_fn_like_mk_literals() {
|
|||
"fn_like_mk_literals",
|
||||
r#""#,
|
||||
expect![[r#"
|
||||
SUBTREE $$ 1 1
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 1 1
|
||||
LITERAL ByteStr byte_string 1
|
||||
LITERAL Char c 1
|
||||
LITERAL Str string 1
|
||||
LITERAL CStr cstring 1
|
||||
LITERAL Float 3.14f64 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Float 3.14f64 1
|
||||
LITERAL Float 3.14 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Float 3.14 1
|
||||
LITERAL Integer 123i64 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Integer 123i64 1
|
||||
LITERAL Integer 123 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Integer 123 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
LITERAL ByteStr byte_string 42:2@0..100#ROOT2024
|
||||
LITERAL Char c 42:2@0..100#ROOT2024
|
||||
LITERAL Str string 42:2@0..100#ROOT2024
|
||||
LITERAL CStr cstring 42:2@0..100#ROOT2024
|
||||
LITERAL Float 3.14f64 42:2@0..100#ROOT2024
|
||||
PUNCH - [alone] 42:2@0..100#ROOT2024
|
||||
LITERAL Float 3.14f64 42:2@0..100#ROOT2024
|
||||
LITERAL Float 3.14 42:2@0..100#ROOT2024
|
||||
PUNCH - [alone] 42:2@0..100#ROOT2024
|
||||
LITERAL Float 3.14 42:2@0..100#ROOT2024
|
||||
LITERAL Integer 123i64 42:2@0..100#ROOT2024
|
||||
PUNCH - [alone] 42:2@0..100#ROOT2024
|
||||
LITERAL Integer 123i64 42:2@0..100#ROOT2024
|
||||
LITERAL Integer 123 42:2@0..100#ROOT2024
|
||||
PUNCH - [alone] 42:2@0..100#ROOT2024
|
||||
LITERAL Integer 123 42:2@0..100#ROOT2024"#]],
|
||||
);
|
||||
}
|
||||
|
|
@ -162,10 +290,18 @@ fn test_fn_like_mk_idents() {
|
|||
"fn_like_mk_idents",
|
||||
r#""#,
|
||||
expect![[r#"
|
||||
SUBTREE $$ 1 1
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 1 1
|
||||
IDENT standard 1
|
||||
IDENT r#raw 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT standard 42:2@0..100#ROOT2024
|
||||
IDENT r#raw 42:2@0..100#ROOT2024"#]],
|
||||
|
|
@ -178,6 +314,30 @@ fn test_fn_like_macro_clone_literals() {
|
|||
"fn_like_clone_tokens",
|
||||
r###"1u16, 2_u32, -4i64, 3.14f32, "hello bridge", "suffixed"suffix, r##"raw"##, 'a', b'b', c"null""###,
|
||||
expect![[r#"
|
||||
SUBTREE $$ 1 1
|
||||
LITERAL Integer 1u16 1
|
||||
PUNCH , [alone] 1
|
||||
LITERAL Integer 2_u32 1
|
||||
PUNCH , [alone] 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Integer 4i64 1
|
||||
PUNCH , [alone] 1
|
||||
LITERAL Float 3.14f32 1
|
||||
PUNCH , [alone] 1
|
||||
LITERAL Str hello bridge 1
|
||||
PUNCH , [alone] 1
|
||||
LITERAL Str suffixedsuffix 1
|
||||
PUNCH , [alone] 1
|
||||
LITERAL StrRaw(2) raw 1
|
||||
PUNCH , [alone] 1
|
||||
LITERAL Char a 1
|
||||
PUNCH , [alone] 1
|
||||
LITERAL Byte b 1
|
||||
PUNCH , [alone] 1
|
||||
LITERAL CStr null 1
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 1 1
|
||||
LITERAL Integer 1u16 1
|
||||
PUNCH , [alone] 1
|
||||
|
|
@ -200,6 +360,30 @@ fn test_fn_like_macro_clone_literals() {
|
|||
PUNCH , [alone] 1
|
||||
LITERAL CStr null 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
LITERAL Integer 1u16 42:2@0..4#ROOT2024
|
||||
PUNCH , [alone] 42:2@4..5#ROOT2024
|
||||
LITERAL Integer 2_u32 42:2@6..11#ROOT2024
|
||||
PUNCH , [alone] 42:2@11..12#ROOT2024
|
||||
PUNCH - [alone] 42:2@13..14#ROOT2024
|
||||
LITERAL Integer 4i64 42:2@14..18#ROOT2024
|
||||
PUNCH , [alone] 42:2@18..19#ROOT2024
|
||||
LITERAL Float 3.14f32 42:2@20..27#ROOT2024
|
||||
PUNCH , [alone] 42:2@27..28#ROOT2024
|
||||
LITERAL Str hello bridge 42:2@29..43#ROOT2024
|
||||
PUNCH , [alone] 42:2@43..44#ROOT2024
|
||||
LITERAL Str suffixedsuffix 42:2@45..61#ROOT2024
|
||||
PUNCH , [alone] 42:2@61..62#ROOT2024
|
||||
LITERAL StrRaw(2) raw 42:2@63..73#ROOT2024
|
||||
PUNCH , [alone] 42:2@73..74#ROOT2024
|
||||
LITERAL Char a 42:2@75..78#ROOT2024
|
||||
PUNCH , [alone] 42:2@78..79#ROOT2024
|
||||
LITERAL Byte b 42:2@80..84#ROOT2024
|
||||
PUNCH , [alone] 42:2@84..85#ROOT2024
|
||||
LITERAL CStr null 42:2@86..93#ROOT2024
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
LITERAL Integer 1u16 42:2@0..4#ROOT2024
|
||||
PUNCH , [alone] 42:2@4..5#ROOT2024
|
||||
|
|
@ -224,6 +408,70 @@ fn test_fn_like_macro_clone_literals() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fn_like_macro_negative_literals() {
|
||||
assert_expand(
|
||||
"fn_like_clone_tokens",
|
||||
r###"-1u16, - 2_u32, -3.14f32, - 2.7"###,
|
||||
expect![[r#"
|
||||
SUBTREE $$ 1 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Integer 1u16 1
|
||||
PUNCH , [alone] 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Integer 2_u32 1
|
||||
PUNCH , [alone] 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Float 3.14f32 1
|
||||
PUNCH , [alone] 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Float 2.7 1
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 1 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Integer 1u16 1
|
||||
PUNCH , [alone] 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Integer 2_u32 1
|
||||
PUNCH , [alone] 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Float 3.14f32 1
|
||||
PUNCH , [alone] 1
|
||||
PUNCH - [alone] 1
|
||||
LITERAL Float 2.7 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
PUNCH - [alone] 42:2@0..1#ROOT2024
|
||||
LITERAL Integer 1u16 42:2@1..5#ROOT2024
|
||||
PUNCH , [alone] 42:2@5..6#ROOT2024
|
||||
PUNCH - [alone] 42:2@7..8#ROOT2024
|
||||
LITERAL Integer 2_u32 42:2@9..14#ROOT2024
|
||||
PUNCH , [alone] 42:2@14..15#ROOT2024
|
||||
PUNCH - [alone] 42:2@16..17#ROOT2024
|
||||
LITERAL Float 3.14f32 42:2@17..24#ROOT2024
|
||||
PUNCH , [alone] 42:2@24..25#ROOT2024
|
||||
PUNCH - [alone] 42:2@26..27#ROOT2024
|
||||
LITERAL Float 2.7 42:2@28..31#ROOT2024
|
||||
|
||||
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
PUNCH - [alone] 42:2@0..1#ROOT2024
|
||||
LITERAL Integer 1u16 42:2@1..5#ROOT2024
|
||||
PUNCH , [alone] 42:2@5..6#ROOT2024
|
||||
PUNCH - [alone] 42:2@7..8#ROOT2024
|
||||
LITERAL Integer 2_u32 42:2@9..14#ROOT2024
|
||||
PUNCH , [alone] 42:2@14..15#ROOT2024
|
||||
PUNCH - [alone] 42:2@16..17#ROOT2024
|
||||
LITERAL Float 3.14f32 42:2@17..24#ROOT2024
|
||||
PUNCH , [alone] 42:2@24..25#ROOT2024
|
||||
PUNCH - [alone] 42:2@26..27#ROOT2024
|
||||
LITERAL Float 2.7 42:2@28..31#ROOT2024"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_attr_macro() {
|
||||
// Corresponds to
|
||||
|
|
@ -234,6 +482,15 @@ fn test_attr_macro() {
|
|||
r#"mod m {}"#,
|
||||
r#"some arguments"#,
|
||||
expect![[r#"
|
||||
SUBTREE $$ 1 1
|
||||
IDENT mod 1
|
||||
IDENT m 1
|
||||
SUBTREE {} 1 1
|
||||
|
||||
SUBTREE $$ 1 1
|
||||
IDENT some 1
|
||||
IDENT arguments 1
|
||||
|
||||
SUBTREE $$ 1 1
|
||||
IDENT compile_error 1
|
||||
PUNCH ! [alone] 1
|
||||
|
|
@ -241,6 +498,15 @@ fn test_attr_macro() {
|
|||
LITERAL Str #[attr_error(some arguments)] mod m {} 1
|
||||
PUNCH ; [alone] 1"#]],
|
||||
expect![[r#"
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT mod 42:2@0..3#ROOT2024
|
||||
IDENT m 42:2@4..5#ROOT2024
|
||||
SUBTREE {} 42:2@6..7#ROOT2024 42:2@7..8#ROOT2024
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT some 42:2@0..4#ROOT2024
|
||||
IDENT arguments 42:2@5..14#ROOT2024
|
||||
|
||||
SUBTREE $$ 42:2@0..100#ROOT2024 42:2@0..100#ROOT2024
|
||||
IDENT compile_error 42:2@0..100#ROOT2024
|
||||
PUNCH ! [alone] 42:2@0..100#ROOT2024
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ pub fn assert_expand(
|
|||
macro_name: &str,
|
||||
#[rust_analyzer::rust_fixture] ra_fixture: &str,
|
||||
expect: Expect,
|
||||
expect_s: Expect,
|
||||
expect_spanned: Expect,
|
||||
) {
|
||||
assert_expand_impl(macro_name, ra_fixture, None, expect, expect_s);
|
||||
assert_expand_impl(macro_name, ra_fixture, None, expect, expect_spanned);
|
||||
}
|
||||
|
||||
pub fn assert_expand_attr(
|
||||
|
|
@ -42,9 +42,9 @@ pub fn assert_expand_attr(
|
|||
#[rust_analyzer::rust_fixture] ra_fixture: &str,
|
||||
attr_args: &str,
|
||||
expect: Expect,
|
||||
expect_s: Expect,
|
||||
expect_spanned: Expect,
|
||||
) {
|
||||
assert_expand_impl(macro_name, ra_fixture, Some(attr_args), expect, expect_s);
|
||||
assert_expand_impl(macro_name, ra_fixture, Some(attr_args), expect, expect_spanned);
|
||||
}
|
||||
|
||||
fn assert_expand_impl(
|
||||
|
|
@ -52,7 +52,7 @@ fn assert_expand_impl(
|
|||
input: &str,
|
||||
attr: Option<&str>,
|
||||
expect: Expect,
|
||||
expect_s: Expect,
|
||||
expect_spanned: Expect,
|
||||
) {
|
||||
let path = proc_macro_test_dylib_path();
|
||||
let expander = dylib::Expander::new(&path).unwrap();
|
||||
|
|
@ -60,20 +60,17 @@ fn assert_expand_impl(
|
|||
let def_site = TokenId(0);
|
||||
let call_site = TokenId(1);
|
||||
let mixed_site = TokenId(2);
|
||||
let input_ts = parse_string(call_site, input);
|
||||
let input_ts = parse_string(call_site, input).into_subtree(call_site);
|
||||
let attr_ts = attr.map(|attr| parse_string(call_site, attr).into_subtree(call_site));
|
||||
let input_ts_string = format!("{input_ts:?}");
|
||||
let attr_ts_string = attr_ts.as_ref().map(|it| format!("{it:?}"));
|
||||
|
||||
let res = expander
|
||||
.expand(
|
||||
macro_name,
|
||||
input_ts.into_subtree(call_site),
|
||||
attr_ts,
|
||||
def_site,
|
||||
call_site,
|
||||
mixed_site,
|
||||
)
|
||||
.unwrap();
|
||||
expect.assert_eq(&format!("{res:?}"));
|
||||
let res =
|
||||
expander.expand(macro_name, input_ts, attr_ts, def_site, call_site, mixed_site).unwrap();
|
||||
expect.assert_eq(&format!(
|
||||
"{input_ts_string}\n\n{}\n\n{res:?}",
|
||||
attr_ts_string.unwrap_or_default()
|
||||
));
|
||||
|
||||
let def_site = Span {
|
||||
range: TextRange::new(0.into(), 150.into()),
|
||||
|
|
@ -93,15 +90,17 @@ fn assert_expand_impl(
|
|||
};
|
||||
let mixed_site = call_site;
|
||||
|
||||
let fixture = parse_string_spanned(call_site.anchor, call_site.ctx, input);
|
||||
let fixture =
|
||||
parse_string_spanned(call_site.anchor, call_site.ctx, input).into_subtree(call_site);
|
||||
let attr = attr.map(|attr| {
|
||||
parse_string_spanned(call_site.anchor, call_site.ctx, attr).into_subtree(call_site)
|
||||
});
|
||||
let fixture_string = format!("{fixture:?}");
|
||||
let attr_string = attr.as_ref().map(|it| format!("{it:?}"));
|
||||
|
||||
let res = expander
|
||||
.expand(macro_name, fixture.into_subtree(call_site), attr, def_site, call_site, mixed_site)
|
||||
.unwrap();
|
||||
expect_s.assert_eq(&format!("{res:#?}"));
|
||||
let res = expander.expand(macro_name, fixture, attr, def_site, call_site, mixed_site).unwrap();
|
||||
expect_spanned
|
||||
.assert_eq(&format!("{fixture_string}\n\n{}\n\n{res:#?}", attr_string.unwrap_or_default()));
|
||||
}
|
||||
|
||||
pub(crate) fn list() -> Vec<String> {
|
||||
|
|
|
|||
|
|
@ -817,6 +817,58 @@ impl<S> fmt::Display for Ident<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S> Literal<S> {
|
||||
pub fn display_no_minus(&self) -> impl fmt::Display {
|
||||
struct NoMinus<'a, S>(&'a Literal<S>);
|
||||
impl<S> fmt::Display for NoMinus<'_, S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let symbol =
|
||||
self.0.symbol.as_str().strip_prefix('-').unwrap_or(self.0.symbol.as_str());
|
||||
match self.0.kind {
|
||||
LitKind::Byte => write!(f, "b'{}'", symbol),
|
||||
LitKind::Char => write!(f, "'{}'", symbol),
|
||||
LitKind::Integer | LitKind::Float | LitKind::Err(_) => write!(f, "{}", symbol),
|
||||
LitKind::Str => write!(f, "\"{}\"", symbol),
|
||||
LitKind::ByteStr => write!(f, "b\"{}\"", symbol),
|
||||
LitKind::CStr => write!(f, "c\"{}\"", symbol),
|
||||
LitKind::StrRaw(num_of_hashes) => {
|
||||
let num_of_hashes = num_of_hashes as usize;
|
||||
write!(
|
||||
f,
|
||||
r#"r{0:#<num_of_hashes$}"{text}"{0:#<num_of_hashes$}"#,
|
||||
"",
|
||||
text = symbol
|
||||
)
|
||||
}
|
||||
LitKind::ByteStrRaw(num_of_hashes) => {
|
||||
let num_of_hashes = num_of_hashes as usize;
|
||||
write!(
|
||||
f,
|
||||
r#"br{0:#<num_of_hashes$}"{text}"{0:#<num_of_hashes$}"#,
|
||||
"",
|
||||
text = symbol
|
||||
)
|
||||
}
|
||||
LitKind::CStrRaw(num_of_hashes) => {
|
||||
let num_of_hashes = num_of_hashes as usize;
|
||||
write!(
|
||||
f,
|
||||
r#"cr{0:#<num_of_hashes$}"{text}"{0:#<num_of_hashes$}"#,
|
||||
"",
|
||||
text = symbol
|
||||
)
|
||||
}
|
||||
}?;
|
||||
if let Some(suffix) = &self.0.suffix {
|
||||
write!(f, "{suffix}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
NoMinus(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> fmt::Display for Literal<S> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.kind {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue