aboutsummaryrefslogtreecommitdiff
path: root/xtask/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'xtask/src/codegen')
-rw-r--r--xtask/src/codegen/gen_assists_docs.rs20
-rw-r--r--xtask/src/codegen/gen_diagnostic_docs.rs8
-rw-r--r--xtask/src/codegen/gen_feature_docs.rs8
-rw-r--r--xtask/src/codegen/gen_features.rs48
-rw-r--r--xtask/src/codegen/gen_lint_completions.rs78
-rw-r--r--xtask/src/codegen/gen_parser_tests.rs12
-rw-r--r--xtask/src/codegen/gen_syntax.rs10
7 files changed, 72 insertions, 112 deletions
diff --git a/xtask/src/codegen/gen_assists_docs.rs b/xtask/src/codegen/gen_assists_docs.rs
index 1ae1343a5..158680993 100644
--- a/xtask/src/codegen/gen_assists_docs.rs
+++ b/xtask/src/codegen/gen_assists_docs.rs
@@ -2,22 +2,25 @@
2 2
3use std::{fmt, path::Path}; 3use std::{fmt, path::Path};
4 4
5use xshell::write_file;
6
5use crate::{ 7use crate::{
6 codegen::{self, extract_comment_blocks_with_empty_lines, reformat, Location, Mode, PREAMBLE}, 8 codegen::{self, extract_comment_blocks_with_empty_lines, reformat, Location, PREAMBLE},
7 project_root, rust_files_in, Result, 9 project_root, rust_files_in, Result,
8}; 10};
9 11
10pub fn generate_assists_tests(mode: Mode) -> Result<()> { 12pub(crate) fn generate_assists_tests() -> Result<()> {
11 let assists = Assist::collect()?; 13 let assists = Assist::collect()?;
12 generate_tests(&assists, mode) 14 generate_tests(&assists)
13} 15}
14 16
15pub fn generate_assists_docs(mode: Mode) -> Result<()> { 17pub(crate) fn generate_assists_docs() -> Result<()> {
16 let assists = Assist::collect()?; 18 let assists = Assist::collect()?;
17 let contents = assists.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n"); 19 let contents = assists.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
18 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); 20 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim());
19 let dst = project_root().join("docs/user/generated_assists.adoc"); 21 let dst = project_root().join("docs/user/generated_assists.adoc");
20 codegen::update(&dst, &contents, mode) 22 write_file(dst, &contents)?;
23 Ok(())
21} 24}
22 25
23#[derive(Debug)] 26#[derive(Debug)]
@@ -111,7 +114,7 @@ impl fmt::Display for Assist {
111 } 114 }
112} 115}
113 116
114fn generate_tests(assists: &[Assist], mode: Mode) -> Result<()> { 117fn generate_tests(assists: &[Assist]) -> Result<()> {
115 let mut buf = String::from("use super::check_doc_test;\n"); 118 let mut buf = String::from("use super::check_doc_test;\n");
116 119
117 for assist in assists.iter() { 120 for assist in assists.iter() {
@@ -135,7 +138,10 @@ r#####"
135 buf.push_str(&test) 138 buf.push_str(&test)
136 } 139 }
137 let buf = reformat(&buf)?; 140 let buf = reformat(&buf)?;
138 codegen::update(&project_root().join("crates/ide_assists/src/tests/generated.rs"), &buf, mode) 141 codegen::ensure_file_contents(
142 &project_root().join("crates/ide_assists/src/tests/generated.rs"),
143 &buf,
144 )
139} 145}
140 146
141fn hide_hash_comments(text: &str) -> String { 147fn hide_hash_comments(text: &str) -> String {
diff --git a/xtask/src/codegen/gen_diagnostic_docs.rs b/xtask/src/codegen/gen_diagnostic_docs.rs
index 7c14d4a07..9cf4d0a88 100644
--- a/xtask/src/codegen/gen_diagnostic_docs.rs
+++ b/xtask/src/codegen/gen_diagnostic_docs.rs
@@ -2,18 +2,20 @@
2 2
3use std::{fmt, path::PathBuf}; 3use std::{fmt, path::PathBuf};
4 4
5use xshell::write_file;
6
5use crate::{ 7use crate::{
6 codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode, PREAMBLE}, 8 codegen::{extract_comment_blocks_with_empty_lines, Location, PREAMBLE},
7 project_root, rust_files, Result, 9 project_root, rust_files, Result,
8}; 10};
9 11
10pub fn generate_diagnostic_docs(mode: Mode) -> Result<()> { 12pub(crate) fn generate_diagnostic_docs() -> Result<()> {
11 let diagnostics = Diagnostic::collect()?; 13 let diagnostics = Diagnostic::collect()?;
12 let contents = 14 let contents =
13 diagnostics.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n"); 15 diagnostics.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
14 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); 16 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim());
15 let dst = project_root().join("docs/user/generated_diagnostic.adoc"); 17 let dst = project_root().join("docs/user/generated_diagnostic.adoc");
16 codegen::update(&dst, &contents, mode)?; 18 write_file(&dst, &contents)?;
17 Ok(()) 19 Ok(())
18} 20}
19 21
diff --git a/xtask/src/codegen/gen_feature_docs.rs b/xtask/src/codegen/gen_feature_docs.rs
index 61081063b..c373d7d70 100644
--- a/xtask/src/codegen/gen_feature_docs.rs
+++ b/xtask/src/codegen/gen_feature_docs.rs
@@ -2,17 +2,19 @@
2 2
3use std::{fmt, path::PathBuf}; 3use std::{fmt, path::PathBuf};
4 4
5use xshell::write_file;
6
5use crate::{ 7use crate::{
6 codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode, PREAMBLE}, 8 codegen::{extract_comment_blocks_with_empty_lines, Location, PREAMBLE},
7 project_root, rust_files, Result, 9 project_root, rust_files, Result,
8}; 10};
9 11
10pub fn generate_feature_docs(mode: Mode) -> Result<()> { 12pub(crate) fn generate_feature_docs() -> Result<()> {
11 let features = Feature::collect()?; 13 let features = Feature::collect()?;
12 let contents = features.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n"); 14 let contents = features.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
13 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim()); 15 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim());
14 let dst = project_root().join("docs/user/generated_features.adoc"); 16 let dst = project_root().join("docs/user/generated_features.adoc");
15 codegen::update(&dst, &contents, mode)?; 17 write_file(&dst, &contents)?;
16 Ok(()) 18 Ok(())
17} 19}
18 20
diff --git a/xtask/src/codegen/gen_features.rs b/xtask/src/codegen/gen_features.rs
deleted file mode 100644
index 3cf15ce02..000000000
--- a/xtask/src/codegen/gen_features.rs
+++ /dev/null
@@ -1,48 +0,0 @@
1//! Generates descriptors structure for unstable feature from Unstable Book
2use std::path::{Path, PathBuf};
3
4use quote::quote;
5use walkdir::WalkDir;
6use xshell::{cmd, read_file};
7
8use crate::codegen::{project_root, reformat, update, Mode, Result};
9
10pub fn generate_features(mode: Mode) -> Result<()> {
11 if !Path::new("./target/rust").exists() {
12 cmd!("git clone https://github.com/rust-lang/rust ./target/rust").run()?;
13 }
14
15 let contents = generate_descriptor("./target/rust/src/doc/unstable-book/src".into())?;
16
17 let destination = project_root().join("crates/ide/src/completion/generated_features.rs");
18 update(destination.as_path(), &contents, mode)?;
19
20 Ok(())
21}
22
23fn generate_descriptor(src_dir: PathBuf) -> Result<String> {
24 let definitions = ["language-features", "library-features"]
25 .iter()
26 .flat_map(|it| WalkDir::new(src_dir.join(it)))
27 .filter_map(|e| e.ok())
28 .filter(|entry| {
29 // Get all `.md ` files
30 entry.file_type().is_file() && entry.path().extension().unwrap_or_default() == "md"
31 })
32 .map(|entry| {
33 let path = entry.path();
34 let feature_ident = path.file_stem().unwrap().to_str().unwrap().replace("-", "_");
35 let doc = read_file(path).unwrap();
36
37 quote! { LintCompletion { label: #feature_ident, description: #doc } }
38 });
39
40 let ts = quote! {
41 use crate::completion::complete_attribute::LintCompletion;
42
43 pub(super) const FEATURES: &[LintCompletion] = &[
44 #(#definitions),*
45 ];
46 };
47 reformat(&ts.to_string())
48}
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}
diff --git a/xtask/src/codegen/gen_parser_tests.rs b/xtask/src/codegen/gen_parser_tests.rs
index 6e4abd10c..096590653 100644
--- a/xtask/src/codegen/gen_parser_tests.rs
+++ b/xtask/src/codegen/gen_parser_tests.rs
@@ -8,13 +8,13 @@ use std::{
8}; 8};
9 9
10use crate::{ 10use crate::{
11 codegen::{extract_comment_blocks, update, Mode}, 11 codegen::{ensure_file_contents, extract_comment_blocks},
12 project_root, Result, 12 project_root, Result,
13}; 13};
14 14
15pub fn generate_parser_tests(mode: Mode) -> Result<()> { 15pub(crate) fn generate_parser_tests() -> Result<()> {
16 let tests = tests_from_dir(&project_root().join(Path::new("crates/parser/src/grammar")))?; 16 let tests = tests_from_dir(&project_root().join(Path::new("crates/parser/src/grammar")))?;
17 fn install_tests(tests: &HashMap<String, Test>, into: &str, mode: Mode) -> Result<()> { 17 fn install_tests(tests: &HashMap<String, Test>, into: &str) -> Result<()> {
18 let tests_dir = project_root().join(into); 18 let tests_dir = project_root().join(into);
19 if !tests_dir.is_dir() { 19 if !tests_dir.is_dir() {
20 fs::create_dir_all(&tests_dir)?; 20 fs::create_dir_all(&tests_dir)?;
@@ -35,12 +35,12 @@ pub fn generate_parser_tests(mode: Mode) -> Result<()> {
35 tests_dir.join(file_name) 35 tests_dir.join(file_name)
36 } 36 }
37 }; 37 };
38 update(&path, &test.text, mode)?; 38 ensure_file_contents(&path, &test.text)?;
39 } 39 }
40 Ok(()) 40 Ok(())
41 } 41 }
42 install_tests(&tests.ok, "crates/syntax/test_data/parser/inline/ok", mode)?; 42 install_tests(&tests.ok, "crates/syntax/test_data/parser/inline/ok")?;
43 install_tests(&tests.err, "crates/syntax/test_data/parser/inline/err", mode) 43 install_tests(&tests.err, "crates/syntax/test_data/parser/inline/err")
44} 44}
45 45
46#[derive(Debug)] 46#[derive(Debug)]
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index eb524d85a..80f26e8f5 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -14,25 +14,25 @@ use ungrammar::{rust_grammar, Grammar, Rule};
14 14
15use crate::{ 15use crate::{
16 ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC}, 16 ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC},
17 codegen::{reformat, update, Mode}, 17 codegen::{ensure_file_contents, reformat},
18 project_root, Result, 18 project_root, Result,
19}; 19};
20 20
21pub fn generate_syntax(mode: Mode) -> Result<()> { 21pub(crate) fn generate_syntax() -> Result<()> {
22 let grammar = rust_grammar(); 22 let grammar = rust_grammar();
23 let ast = lower(&grammar); 23 let ast = lower(&grammar);
24 24
25 let syntax_kinds_file = project_root().join("crates/parser/src/syntax_kind/generated.rs"); 25 let syntax_kinds_file = project_root().join("crates/parser/src/syntax_kind/generated.rs");
26 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; 26 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?;
27 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; 27 ensure_file_contents(syntax_kinds_file.as_path(), &syntax_kinds)?;
28 28
29 let ast_tokens_file = project_root().join("crates/syntax/src/ast/generated/tokens.rs"); 29 let ast_tokens_file = project_root().join("crates/syntax/src/ast/generated/tokens.rs");
30 let contents = generate_tokens(&ast)?; 30 let contents = generate_tokens(&ast)?;
31 update(ast_tokens_file.as_path(), &contents, mode)?; 31 ensure_file_contents(ast_tokens_file.as_path(), &contents)?;
32 32
33 let ast_nodes_file = project_root().join("crates/syntax/src/ast/generated/nodes.rs"); 33 let ast_nodes_file = project_root().join("crates/syntax/src/ast/generated/nodes.rs");
34 let contents = generate_nodes(KINDS_SRC, &ast)?; 34 let contents = generate_nodes(KINDS_SRC, &ast)?;
35 update(ast_nodes_file.as_path(), &contents, mode)?; 35 ensure_file_contents(ast_nodes_file.as_path(), &contents)?;
36 36
37 Ok(()) 37 Ok(())
38} 38}