aboutsummaryrefslogtreecommitdiff
path: root/xtask/src/codegen/gen_lint_completions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'xtask/src/codegen/gen_lint_completions.rs')
-rw-r--r--xtask/src/codegen/gen_lint_completions.rs78
1 files changed, 38 insertions, 40 deletions
diff --git a/xtask/src/codegen/gen_lint_completions.rs b/xtask/src/codegen/gen_lint_completions.rs
index 25f770eaf..24dbc6a39 100644
--- a/xtask/src/codegen/gen_lint_completions.rs
+++ b/xtask/src/codegen/gen_lint_completions.rs
@@ -1,41 +1,36 @@
1//! Generates descriptors structure for unstable feature from Unstable Book 1//! Generates descriptors structure for unstable feature from Unstable Book
2use std::fmt::Write;
2use std::path::{Path, PathBuf}; 3use std::path::{Path, PathBuf};
3 4
4use quote::quote;
5use walkdir::WalkDir; 5use walkdir::WalkDir;
6use xshell::{cmd, read_file}; 6use xshell::{cmd, read_file};
7 7
8use crate::{ 8use crate::codegen::{ensure_file_contents, project_root, reformat, Result};
9 codegen::{project_root, reformat, update, Mode, Result},
10 run_rustfmt,
11};
12 9
13pub fn generate_lint_completions(mode: Mode) -> Result<()> { 10pub(crate) fn generate_lint_completions() -> Result<()> {
14 if !Path::new("./target/rust").exists() { 11 if !project_root().join("./target/rust").exists() {
15 cmd!("git clone --depth=1 https://github.com/rust-lang/rust ./target/rust").run()?; 12 cmd!("git clone --depth=1 https://github.com/rust-lang/rust ./target/rust").run()?;
16 } 13 }
17 14
18 let ts_features = generate_descriptor("./target/rust/src/doc/unstable-book/src".into())?; 15 let mut contents = String::from("use crate::completions::attribute::LintCompletion;\n\n");
19 cmd!("curl http://rust-lang.github.io/rust-clippy/master/lints.json --output ./target/clippy_lints.json").run()?; 16 generate_descriptor(&mut contents, "./target/rust/src/doc/unstable-book/src".into())?;
17 contents.push('\n');
20 18
21 let ts_clippy = generate_descriptor_clippy(&Path::new("./target/clippy_lints.json"))?; 19 cmd!("curl http://rust-lang.github.io/rust-clippy/master/lints.json --output ./target/clippy_lints.json").run()?;
22 let ts = quote! { 20 generate_descriptor_clippy(&mut contents, &Path::new("./target/clippy_lints.json"))?;
23 use crate::completions::attribute::LintCompletion; 21 let contents = reformat(&contents)?;
24 #ts_features
25 #ts_clippy
26 };
27 let contents = reformat(ts.to_string().as_str())?;
28 22
29 let destination = 23 let destination =
30 project_root().join("crates/ide_completion/src/generated_lint_completions.rs"); 24 project_root().join("crates/ide_completion/src/generated_lint_completions.rs");
31 update(destination.as_path(), &contents, mode)?; 25 ensure_file_contents(destination.as_path(), &contents)?;
32 run_rustfmt(mode)?;
33 26
34 Ok(()) 27 Ok(())
35} 28}
36 29
37fn generate_descriptor(src_dir: PathBuf) -> Result<proc_macro2::TokenStream> { 30fn generate_descriptor(buf: &mut String, src_dir: PathBuf) -> Result<()> {
38 let definitions = ["language-features", "library-features"] 31 buf.push_str(r#"pub(super) const FEATURES: &[LintCompletion] = &["#);
32 buf.push('\n');
33 ["language-features", "library-features"]
39 .iter() 34 .iter()
40 .flat_map(|it| WalkDir::new(src_dir.join(it))) 35 .flat_map(|it| WalkDir::new(src_dir.join(it)))
41 .filter_map(|e| e.ok()) 36 .filter_map(|e| e.ok())
@@ -43,21 +38,15 @@ fn generate_descriptor(src_dir: PathBuf) -> Result<proc_macro2::TokenStream> {
43 // Get all `.md ` files 38 // Get all `.md ` files
44 entry.file_type().is_file() && entry.path().extension().unwrap_or_default() == "md" 39 entry.file_type().is_file() && entry.path().extension().unwrap_or_default() == "md"
45 }) 40 })
46 .map(|entry| { 41 .for_each(|entry| {
47 let path = entry.path(); 42 let path = entry.path();
48 let feature_ident = path.file_stem().unwrap().to_str().unwrap().replace("-", "_"); 43 let feature_ident = path.file_stem().unwrap().to_str().unwrap().replace("-", "_");
49 let doc = read_file(path).unwrap(); 44 let doc = read_file(path).unwrap();
50 45
51 quote! { LintCompletion { label: #feature_ident, description: #doc } } 46 push_lint_completion(buf, &feature_ident, &doc);
52 }); 47 });
53 48 buf.push_str("];\n");
54 let ts = quote! { 49 Ok(())
55 pub(super) const FEATURES: &[LintCompletion] = &[
56 #(#definitions),*
57 ];
58 };
59
60 Ok(ts)
61} 50}
62 51
63#[derive(Default)] 52#[derive(Default)]
@@ -66,7 +55,7 @@ struct ClippyLint {
66 id: String, 55 id: String,
67} 56}
68 57
69fn generate_descriptor_clippy(path: &Path) -> Result<proc_macro2::TokenStream> { 58fn generate_descriptor_clippy(buf: &mut String, path: &Path) -> Result<()> {
70 let file_content = read_file(path)?; 59 let file_content = read_file(path)?;
71 let mut clippy_lints: Vec<ClippyLint> = vec![]; 60 let mut clippy_lints: Vec<ClippyLint> = vec![];
72 61
@@ -97,18 +86,27 @@ fn generate_descriptor_clippy(path: &Path) -> Result<proc_macro2::TokenStream> {
97 } 86 }
98 } 87 }
99 88
100 let definitions = clippy_lints.into_iter().map(|clippy_lint| { 89 buf.push_str(r#"pub(super) const CLIPPY_LINTS: &[LintCompletion] = &["#);
90 buf.push('\n');
91 clippy_lints.into_iter().for_each(|clippy_lint| {
101 let lint_ident = format!("clippy::{}", clippy_lint.id); 92 let lint_ident = format!("clippy::{}", clippy_lint.id);
102 let doc = clippy_lint.help; 93 let doc = clippy_lint.help;
103 94 push_lint_completion(buf, &lint_ident, &doc);
104 quote! { LintCompletion { label: #lint_ident, description: #doc } }
105 }); 95 });
106 96
107 let ts = quote! { 97 buf.push_str("];\n");
108 pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[ 98
109 #(#definitions),* 99 Ok(())
110 ]; 100}
111 };
112 101
113 Ok(ts) 102fn push_lint_completion(buf: &mut String, label: &str, description: &str) {
103 writeln!(
104 buf,
105 r###" LintCompletion {{
106 label: "{}",
107 description: r##"{}"##
108 }},"###,
109 label, description
110 )
111 .unwrap();
114} 112}