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.rs6
-rw-r--r--xtask/src/codegen/gen_diagnostic_docs.rs74
-rw-r--r--xtask/src/codegen/gen_feature_docs.rs4
-rw-r--r--xtask/src/codegen/gen_features.rs12
-rw-r--r--xtask/src/codegen/gen_parser_tests.rs2
-rw-r--r--xtask/src/codegen/gen_syntax.rs15
6 files changed, 94 insertions, 19 deletions
diff --git a/xtask/src/codegen/gen_assists_docs.rs b/xtask/src/codegen/gen_assists_docs.rs
index f0ded8b87..d7c85ebe9 100644
--- a/xtask/src/codegen/gen_assists_docs.rs
+++ b/xtask/src/codegen/gen_assists_docs.rs
@@ -1,6 +1,6 @@
1//! Generates `assists.md` documentation. 1//! Generates `assists.md` documentation.
2 2
3use std::{fmt, fs, path::Path}; 3use std::{fmt, path::Path};
4 4
5use crate::{ 5use crate::{
6 codegen::{self, extract_comment_blocks_with_empty_lines, reformat, Location, Mode, PREAMBLE}, 6 codegen::{self, extract_comment_blocks_with_empty_lines, reformat, Location, Mode, PREAMBLE},
@@ -39,7 +39,7 @@ impl Assist {
39 return Ok(res); 39 return Ok(res);
40 40
41 fn collect_file(acc: &mut Vec<Assist>, path: &Path) -> Result<()> { 41 fn collect_file(acc: &mut Vec<Assist>, path: &Path) -> Result<()> {
42 let text = fs::read_to_string(path)?; 42 let text = xshell::read_file(path)?;
43 let comment_blocks = extract_comment_blocks_with_empty_lines("Assist", &text); 43 let comment_blocks = extract_comment_blocks_with_empty_lines("Assist", &text);
44 44
45 for block in comment_blocks { 45 for block in comment_blocks {
@@ -134,7 +134,7 @@ r#####"
134 134
135 buf.push_str(&test) 135 buf.push_str(&test)
136 } 136 }
137 let buf = reformat(buf)?; 137 let buf = reformat(&buf.to_string())?;
138 codegen::update(&project_root().join("crates/assists/src/tests/generated.rs"), &buf, mode) 138 codegen::update(&project_root().join("crates/assists/src/tests/generated.rs"), &buf, mode)
139} 139}
140 140
diff --git a/xtask/src/codegen/gen_diagnostic_docs.rs b/xtask/src/codegen/gen_diagnostic_docs.rs
new file mode 100644
index 000000000..00aaea5b7
--- /dev/null
+++ b/xtask/src/codegen/gen_diagnostic_docs.rs
@@ -0,0 +1,74 @@
1//! Generates `assists.md` documentation.
2
3use std::{fmt, path::PathBuf};
4
5use crate::{
6 codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode, PREAMBLE},
7 project_root, rust_files, Result,
8};
9
10pub fn generate_diagnostic_docs(mode: Mode) -> Result<()> {
11 let diagnostics = Diagnostic::collect()?;
12 let contents =
13 diagnostics.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
14 let contents = format!("//{}\n{}\n", PREAMBLE, contents.trim());
15 let dst = project_root().join("docs/user/generated_diagnostic.adoc");
16 codegen::update(&dst, &contents, mode)?;
17 Ok(())
18}
19
20#[derive(Debug)]
21struct Diagnostic {
22 id: String,
23 location: Location,
24 doc: String,
25}
26
27impl Diagnostic {
28 fn collect() -> Result<Vec<Diagnostic>> {
29 let mut res = Vec::new();
30 for path in rust_files(&project_root()) {
31 collect_file(&mut res, path)?;
32 }
33 res.sort_by(|lhs, rhs| lhs.id.cmp(&rhs.id));
34 return Ok(res);
35
36 fn collect_file(acc: &mut Vec<Diagnostic>, path: PathBuf) -> Result<()> {
37 let text = xshell::read_file(&path)?;
38 let comment_blocks = extract_comment_blocks_with_empty_lines("Diagnostic", &text);
39
40 for block in comment_blocks {
41 let id = block.id;
42 if let Err(msg) = is_valid_diagnostic_name(&id) {
43 panic!("invalid diagnostic name: {:?}:\n {}", id, msg)
44 }
45 let doc = block.contents.join("\n");
46 let location = Location::new(path.clone(), block.line);
47 acc.push(Diagnostic { id, location, doc })
48 }
49
50 Ok(())
51 }
52 }
53}
54
55fn is_valid_diagnostic_name(diagnostic: &str) -> Result<(), String> {
56 let diagnostic = diagnostic.trim();
57 if diagnostic.find(char::is_whitespace).is_some() {
58 return Err("Diagnostic names can't contain whitespace symbols".into());
59 }
60 if diagnostic.chars().any(|c| c.is_ascii_uppercase()) {
61 return Err("Diagnostic names can't contain uppercase symbols".into());
62 }
63 if diagnostic.chars().any(|c| !c.is_ascii()) {
64 return Err("Diagnostic can't contain non-ASCII symbols".into());
65 }
66
67 Ok(())
68}
69
70impl fmt::Display for Diagnostic {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 writeln!(f, "=== {}\n**Source:** {}\n{}", self.id, self.location, self.doc)
73 }
74}
diff --git a/xtask/src/codegen/gen_feature_docs.rs b/xtask/src/codegen/gen_feature_docs.rs
index 341e67c73..065dd33f1 100644
--- a/xtask/src/codegen/gen_feature_docs.rs
+++ b/xtask/src/codegen/gen_feature_docs.rs
@@ -1,6 +1,6 @@
1//! Generates `assists.md` documentation. 1//! Generates `assists.md` documentation.
2 2
3use std::{fmt, fs, path::PathBuf}; 3use std::{fmt, path::PathBuf};
4 4
5use crate::{ 5use crate::{
6 codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode, PREAMBLE}, 6 codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode, PREAMBLE},
@@ -33,7 +33,7 @@ impl Feature {
33 return Ok(res); 33 return Ok(res);
34 34
35 fn collect_file(acc: &mut Vec<Feature>, path: PathBuf) -> Result<()> { 35 fn collect_file(acc: &mut Vec<Feature>, path: PathBuf) -> Result<()> {
36 let text = fs::read_to_string(&path)?; 36 let text = xshell::read_file(&path)?;
37 let comment_blocks = extract_comment_blocks_with_empty_lines("Feature", &text); 37 let comment_blocks = extract_comment_blocks_with_empty_lines("Feature", &text);
38 38
39 for block in comment_blocks { 39 for block in comment_blocks {
diff --git a/xtask/src/codegen/gen_features.rs b/xtask/src/codegen/gen_features.rs
index 78268308b..3cf15ce02 100644
--- a/xtask/src/codegen/gen_features.rs
+++ b/xtask/src/codegen/gen_features.rs
@@ -3,15 +3,13 @@ use std::path::{Path, PathBuf};
3 3
4use quote::quote; 4use quote::quote;
5use walkdir::WalkDir; 5use walkdir::WalkDir;
6use xshell::{cmd, read_file};
6 7
7use crate::{ 8use crate::codegen::{project_root, reformat, update, Mode, Result};
8 codegen::{project_root, reformat, update, Mode, Result},
9 not_bash::{fs2, run},
10};
11 9
12pub fn generate_features(mode: Mode) -> Result<()> { 10pub fn generate_features(mode: Mode) -> Result<()> {
13 if !Path::new("./target/rust").exists() { 11 if !Path::new("./target/rust").exists() {
14 run!("git clone https://github.com/rust-lang/rust ./target/rust")?; 12 cmd!("git clone https://github.com/rust-lang/rust ./target/rust").run()?;
15 } 13 }
16 14
17 let contents = generate_descriptor("./target/rust/src/doc/unstable-book/src".into())?; 15 let contents = generate_descriptor("./target/rust/src/doc/unstable-book/src".into())?;
@@ -34,7 +32,7 @@ fn generate_descriptor(src_dir: PathBuf) -> Result<String> {
34 .map(|entry| { 32 .map(|entry| {
35 let path = entry.path(); 33 let path = entry.path();
36 let feature_ident = path.file_stem().unwrap().to_str().unwrap().replace("-", "_"); 34 let feature_ident = path.file_stem().unwrap().to_str().unwrap().replace("-", "_");
37 let doc = fs2::read_to_string(path).unwrap(); 35 let doc = read_file(path).unwrap();
38 36
39 quote! { LintCompletion { label: #feature_ident, description: #doc } } 37 quote! { LintCompletion { label: #feature_ident, description: #doc } }
40 }); 38 });
@@ -46,5 +44,5 @@ fn generate_descriptor(src_dir: PathBuf) -> Result<String> {
46 #(#definitions),* 44 #(#definitions),*
47 ]; 45 ];
48 }; 46 };
49 reformat(ts) 47 reformat(&ts.to_string())
50} 48}
diff --git a/xtask/src/codegen/gen_parser_tests.rs b/xtask/src/codegen/gen_parser_tests.rs
index 96fdd9216..19ae949d4 100644
--- a/xtask/src/codegen/gen_parser_tests.rs
+++ b/xtask/src/codegen/gen_parser_tests.rs
@@ -124,7 +124,7 @@ fn existing_tests(dir: &Path, ok: bool) -> Result<HashMap<String, (PathBuf, Test
124 let file_name = path.file_name().unwrap().to_str().unwrap(); 124 let file_name = path.file_name().unwrap().to_str().unwrap();
125 file_name[5..file_name.len() - 3].to_string() 125 file_name[5..file_name.len() - 3].to_string()
126 }; 126 };
127 let text = fs::read_to_string(&path)?; 127 let text = xshell::read_file(&path)?;
128 let test = Test { name: name.clone(), text, ok }; 128 let test = Test { name: name.clone(), text, ok };
129 if let Some(old) = res.insert(name, (path, test)) { 129 if let Some(old) = res.insert(name, (path, test)) {
130 println!("Duplicate test: {:?}", old); 130 println!("Duplicate test: {:?}", old);
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index 733493fef..02f4095ce 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -61,10 +61,13 @@ fn generate_tokens(grammar: &AstSrc) -> Result<String> {
61 } 61 }
62 }); 62 });
63 63
64 let pretty = reformat(quote! { 64 let pretty = reformat(
65 use crate::{SyntaxKind::{self, *}, SyntaxToken, ast::AstToken}; 65 &quote! {
66 #(#tokens)* 66 use crate::{SyntaxKind::{self, *}, SyntaxToken, ast::AstToken};
67 })? 67 #(#tokens)*
68 }
69 .to_string(),
70 )?
68 .replace("#[derive", "\n#[derive"); 71 .replace("#[derive", "\n#[derive");
69 Ok(pretty) 72 Ok(pretty)
70} 73}
@@ -261,7 +264,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> Result<String> {
261 } 264 }
262 } 265 }
263 266
264 let pretty = reformat(res)?; 267 let pretty = reformat(&res)?;
265 Ok(pretty) 268 Ok(pretty)
266} 269}
267 270
@@ -383,7 +386,7 @@ fn generate_syntax_kinds(grammar: KindsSrc<'_>) -> Result<String> {
383 } 386 }
384 }; 387 };
385 388
386 reformat(ast) 389 reformat(&ast.to_string())
387} 390}
388 391
389fn to_upper_snake_case(s: &str) -> String { 392fn to_upper_snake_case(s: &str) -> String {