diff options
Diffstat (limited to 'xtask/src/codegen.rs')
-rw-r--r-- | xtask/src/codegen.rs | 91 |
1 files changed, 72 insertions, 19 deletions
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs index 0e4dcb95a..5511c01d5 100644 --- a/xtask/src/codegen.rs +++ b/xtask/src/codegen.rs | |||
@@ -8,14 +8,18 @@ | |||
8 | mod gen_syntax; | 8 | mod gen_syntax; |
9 | mod gen_parser_tests; | 9 | mod gen_parser_tests; |
10 | mod gen_assists_docs; | 10 | mod gen_assists_docs; |
11 | mod gen_feature_docs; | ||
11 | 12 | ||
12 | use std::{mem, path::Path}; | 13 | use std::{ |
14 | fmt, mem, | ||
15 | path::{Path, PathBuf}, | ||
16 | }; | ||
13 | 17 | ||
14 | use crate::{not_bash::fs2, Result}; | 18 | use crate::{not_bash::fs2, project_root, Result}; |
15 | 19 | ||
16 | pub use self::{ | 20 | pub use self::{ |
17 | gen_assists_docs::generate_assists_docs, gen_parser_tests::generate_parser_tests, | 21 | gen_assists_docs::generate_assists_docs, gen_feature_docs::generate_feature_docs, |
18 | gen_syntax::generate_syntax, | 22 | gen_parser_tests::generate_parser_tests, gen_syntax::generate_syntax, |
19 | }; | 23 | }; |
20 | 24 | ||
21 | const GRAMMAR_DIR: &str = "crates/ra_parser/src/grammar"; | 25 | const GRAMMAR_DIR: &str = "crates/ra_parser/src/grammar"; |
@@ -27,8 +31,7 @@ const AST_NODES: &str = "crates/ra_syntax/src/ast/generated/nodes.rs"; | |||
27 | const AST_TOKENS: &str = "crates/ra_syntax/src/ast/generated/tokens.rs"; | 31 | const AST_TOKENS: &str = "crates/ra_syntax/src/ast/generated/tokens.rs"; |
28 | 32 | ||
29 | const ASSISTS_DIR: &str = "crates/ra_assists/src/handlers"; | 33 | const ASSISTS_DIR: &str = "crates/ra_assists/src/handlers"; |
30 | const ASSISTS_TESTS: &str = "crates/ra_assists/src/doc_tests/generated.rs"; | 34 | const ASSISTS_TESTS: &str = "crates/ra_assists/src/tests/generated.rs"; |
31 | const ASSISTS_DOCS: &str = "docs/user/assists.md"; | ||
32 | 35 | ||
33 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 36 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
34 | pub enum Mode { | 37 | pub enum Mode { |
@@ -40,7 +43,7 @@ pub enum Mode { | |||
40 | /// With verify = false, | 43 | /// With verify = false, |
41 | fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> { | 44 | fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> { |
42 | match fs2::read_to_string(path) { | 45 | match fs2::read_to_string(path) { |
43 | Ok(ref old_contents) if normalize(old_contents) == normalize(contents) => { | 46 | Ok(old_contents) if normalize(&old_contents) == normalize(contents) => { |
44 | return Ok(()); | 47 | return Ok(()); |
45 | } | 48 | } |
46 | _ => (), | 49 | _ => (), |
@@ -58,35 +61,85 @@ fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> { | |||
58 | } | 61 | } |
59 | 62 | ||
60 | fn extract_comment_blocks(text: &str) -> Vec<Vec<String>> { | 63 | fn extract_comment_blocks(text: &str) -> Vec<Vec<String>> { |
61 | do_extract_comment_blocks(text, false) | 64 | do_extract_comment_blocks(text, false).into_iter().map(|(_line, block)| block).collect() |
65 | } | ||
66 | |||
67 | fn extract_comment_blocks_with_empty_lines(tag: &str, text: &str) -> Vec<CommentBlock> { | ||
68 | assert!(tag.starts_with(char::is_uppercase)); | ||
69 | let tag = format!("{}:", tag); | ||
70 | let mut res = Vec::new(); | ||
71 | for (line, mut block) in do_extract_comment_blocks(text, true) { | ||
72 | let first = block.remove(0); | ||
73 | if first.starts_with(&tag) { | ||
74 | let id = first[tag.len()..].trim().to_string(); | ||
75 | let block = CommentBlock { id, line, contents: block }; | ||
76 | res.push(block); | ||
77 | } | ||
78 | } | ||
79 | res | ||
62 | } | 80 | } |
63 | 81 | ||
64 | fn extract_comment_blocks_with_empty_lines(text: &str) -> Vec<Vec<String>> { | 82 | struct CommentBlock { |
65 | do_extract_comment_blocks(text, true) | 83 | id: String, |
84 | line: usize, | ||
85 | contents: Vec<String>, | ||
66 | } | 86 | } |
67 | 87 | ||
68 | fn do_extract_comment_blocks(text: &str, allow_blocks_with_empty_lines: bool) -> Vec<Vec<String>> { | 88 | fn do_extract_comment_blocks( |
89 | text: &str, | ||
90 | allow_blocks_with_empty_lines: bool, | ||
91 | ) -> Vec<(usize, Vec<String>)> { | ||
69 | let mut res = Vec::new(); | 92 | let mut res = Vec::new(); |
70 | 93 | ||
71 | let prefix = "// "; | 94 | let prefix = "// "; |
72 | let lines = text.lines().map(str::trim_start); | 95 | let lines = text.lines().map(str::trim_start); |
73 | 96 | ||
74 | let mut block = vec![]; | 97 | let mut block = (0, vec![]); |
75 | for line in lines { | 98 | for (line_num, line) in lines.enumerate() { |
76 | if line == "//" && allow_blocks_with_empty_lines { | 99 | if line == "//" && allow_blocks_with_empty_lines { |
77 | block.push(String::new()); | 100 | block.1.push(String::new()); |
78 | continue; | 101 | continue; |
79 | } | 102 | } |
80 | 103 | ||
81 | let is_comment = line.starts_with(prefix); | 104 | let is_comment = line.starts_with(prefix); |
82 | if is_comment { | 105 | if is_comment { |
83 | block.push(line[prefix.len()..].to_string()); | 106 | block.1.push(line[prefix.len()..].to_string()); |
84 | } else if !block.is_empty() { | 107 | } else { |
85 | res.push(mem::replace(&mut block, Vec::new())); | 108 | if !block.1.is_empty() { |
109 | res.push(mem::take(&mut block)); | ||
110 | } | ||
111 | block.0 = line_num + 2; | ||
86 | } | 112 | } |
87 | } | 113 | } |
88 | if !block.is_empty() { | 114 | if !block.1.is_empty() { |
89 | res.push(mem::replace(&mut block, Vec::new())) | 115 | res.push(block) |
90 | } | 116 | } |
91 | res | 117 | res |
92 | } | 118 | } |
119 | |||
120 | #[derive(Debug)] | ||
121 | struct Location { | ||
122 | file: PathBuf, | ||
123 | line: usize, | ||
124 | } | ||
125 | |||
126 | impl Location { | ||
127 | fn new(file: PathBuf, line: usize) -> Self { | ||
128 | Self { file, line } | ||
129 | } | ||
130 | } | ||
131 | |||
132 | impl fmt::Display for Location { | ||
133 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
134 | let path = self.file.strip_prefix(&project_root()).unwrap().display().to_string(); | ||
135 | let path = path.replace('\\', "/"); | ||
136 | let name = self.file.file_name().unwrap(); | ||
137 | write!( | ||
138 | f, | ||
139 | "https://github.com/rust-analyzer/rust-analyzer/blob/master/{}#L{}[{}]", | ||
140 | path, | ||
141 | self.line, | ||
142 | name.to_str().unwrap() | ||
143 | ) | ||
144 | } | ||
145 | } | ||