]> git.lizzy.rs Git - rust.git/commitdiff
Merge #10403
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>
Fri, 1 Oct 2021 11:18:52 +0000 (11:18 +0000)
committerGitHub <noreply@github.com>
Fri, 1 Oct 2021 11:18:52 +0000 (11:18 +0000)
10403: feat: Add semantic token modifier for crate root r=Veykril a=lhvy

Resolves #9073

I managed to implement crate root highlighting for crates mentioned specifically by name (e.g. `serde` in `use serde::Serialize;`), but not for crates referred to with `crate` or `super`. How could I implement this?

> P.S. I'm participating in [Hacktoberfest 2021](https://hacktoberfest.digitalocean.com/). If this PR is up to standard and merged, I'd appreciate if the `hacktoberfest-accepted` label could be added. Thanks!

Co-authored-by: lhvy <me@lhvy.dev>
crates/hir_expand/src/builtin_macro.rs
crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
crates/ide/src/syntax_highlighting/tests.rs
crates/ide_assists/src/handlers/convert_bool_then.rs

index 3d63e05195bc1ad2314e368e5d19ef0c41befa84..a4ddafbf7af4359299db81e88b7c749308509467 100644 (file)
@@ -267,13 +267,30 @@ fn format_args_expand(
 fn asm_expand(
     _db: &dyn AstDatabase,
     _id: MacroCallId,
-    _tt: &tt::Subtree,
+    tt: &tt::Subtree,
 ) -> ExpandResult<tt::Subtree> {
-    // both asm and llvm_asm don't return anything, so we can expand them to nothing,
-    // for now
-    let expanded = quote! {
+    // We expand all assembly snippets to `format_args!` invocations to get format syntax
+    // highlighting for them.
+
+    let krate = tt::Ident { text: "$crate".into(), id: tt::TokenId::unspecified() };
+
+    let mut literals = Vec::new();
+    for tt in tt.token_trees.chunks(2) {
+        match tt {
+            [tt::TokenTree::Leaf(tt::Leaf::Literal(lit))]
+            | [tt::TokenTree::Leaf(tt::Leaf::Literal(lit)), tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: ',', id: _, spacing: _ }))] =>
+            {
+                let krate = krate.clone();
+                literals.push(quote!(#krate::format_args!(#lit);));
+            }
+            _ => break,
+        }
+    }
+
+    let expanded = quote! {{
+        ##literals
         ()
-    };
+    }};
     ExpandResult::ok(expanded)
 }
 
index f6d9d9aa14a0b15d1326f6df7a7e1b6fef0bdd63..4f67c4316a4a14ada15bbf6fa1786a5b6dc7d44e 100644 (file)
@@ -82,6 +82,8 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">panic</span> <span class="brace">{</span><span class="brace">}</span>
 <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span>
 <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">assert</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">asm</span> <span class="brace">{</span><span class="brace">}</span>
 
 <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">toho</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panic<span class="punctuation">!</span><span class="parenthesis">(</span><span class="string_literal">"not yet implemented"</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
@@ -142,4 +144,5 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="macro">assert!</span><span class="parenthesis">(</span><span class="bool_literal">true</span><span class="comma">,</span> <span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="numeric_literal">1</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="macro">assert!</span><span class="parenthesis">(</span><span class="bool_literal">true</span><span class="comma">,</span> <span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> asdasd"</span><span class="comma">,</span> <span class="numeric_literal">1</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="macro">toho!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">fmt"</span><span class="comma">,</span> <span class="numeric_literal">0</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro">asm!</span><span class="parenthesis">(</span><span class="string_literal">"mov eax, </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="brace">}</span></code></pre>
\ No newline at end of file
index 05c80e403c52920aad71c9cd59abe46e17787f86..6972d431d245b1828a7475034aa7923399f79777 100644 (file)
@@ -477,6 +477,8 @@ mod panic {
 macro_rules! panic {}
 #[rustc_builtin_macro]
 macro_rules! assert {}
+#[rustc_builtin_macro]
+macro_rules! asm {}
 
 macro_rules! toho {
     () => ($crate::panic!("not yet implemented"));
@@ -537,6 +539,7 @@ fn main() {
     assert!(true, "{}", 1);
     assert!(true, "{} asdasd", 1);
     toho!("{}fmt", 0);
+    asm!("mov eax, {0}");
 }"#
         .trim(),
         expect_file!["./test_data/highlight_strings.html"],
index 2e24c22c9fcfbf564ea5519e40337ea8b409dd7d..b8c55eb852f4520eb7ff519ea707dc63bfc27cee 100644 (file)
@@ -39,7 +39,7 @@
 // }
 // ```
 pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
-    // todo, applies to match as well
+    // FIXME applies to match as well
     let expr = ctx.find_node_at_offset::<ast::IfExpr>()?;
     if !expr.if_token()?.text_range().contains_inclusive(ctx.offset()) {
         return None;
@@ -101,7 +101,29 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext) ->
                 e => e,
             };
 
+            let parenthesize = matches!(
+                cond,
+                ast::Expr::BinExpr(_)
+                    | ast::Expr::BlockExpr(_)
+                    | ast::Expr::BoxExpr(_)
+                    | ast::Expr::BreakExpr(_)
+                    | ast::Expr::CastExpr(_)
+                    | ast::Expr::ClosureExpr(_)
+                    | ast::Expr::ContinueExpr(_)
+                    | ast::Expr::ForExpr(_)
+                    | ast::Expr::IfExpr(_)
+                    | ast::Expr::LoopExpr(_)
+                    | ast::Expr::MacroCall(_)
+                    | ast::Expr::MatchExpr(_)
+                    | ast::Expr::PrefixExpr(_)
+                    | ast::Expr::RangeExpr(_)
+                    | ast::Expr::RefExpr(_)
+                    | ast::Expr::ReturnExpr(_)
+                    | ast::Expr::WhileExpr(_)
+                    | ast::Expr::YieldExpr(_)
+            );
             let cond = if invert_cond { invert_boolean_expression(cond) } else { cond };
+            let cond = if parenthesize { make::expr_paren(cond) } else { cond };
             let arg_list = make::arg_list(Some(make::expr_closure(None, closure_body)));
             let mcall = make::expr_method_call(cond, make::name_ref("then"), arg_list);
             builder.replace(target, mcall.to_string());