aboutsummaryrefslogtreecommitdiff
path: root/xtask
diff options
context:
space:
mode:
Diffstat (limited to 'xtask')
-rw-r--r--xtask/src/codegen.rs33
-rw-r--r--xtask/src/codegen/gen_assists_docs.rs71
-rw-r--r--xtask/src/codegen/gen_feature_docs.rs22
-rw-r--r--xtask/src/lib.rs2
4 files changed, 71 insertions, 57 deletions
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs
index f47d54125..f3917a244 100644
--- a/xtask/src/codegen.rs
+++ b/xtask/src/codegen.rs
@@ -10,9 +10,12 @@ mod gen_parser_tests;
10mod gen_assists_docs; 10mod gen_assists_docs;
11mod gen_feature_docs; 11mod gen_feature_docs;
12 12
13use std::{mem, path::Path}; 13use std::{
14 fmt, mem,
15 path::{Path, PathBuf},
16};
14 17
15use crate::{not_bash::fs2, Result}; 18use crate::{not_bash::fs2, project_root, Result};
16 19
17pub use self::{ 20pub use self::{
18 gen_assists_docs::generate_assists_docs, gen_feature_docs::generate_feature_docs, 21 gen_assists_docs::generate_assists_docs, gen_feature_docs::generate_feature_docs,
@@ -29,7 +32,6 @@ const AST_TOKENS: &str = "crates/ra_syntax/src/ast/generated/tokens.rs";
29 32
30const ASSISTS_DIR: &str = "crates/ra_assists/src/handlers"; 33const ASSISTS_DIR: &str = "crates/ra_assists/src/handlers";
31const ASSISTS_TESTS: &str = "crates/ra_assists/src/tests/generated.rs"; 34const ASSISTS_TESTS: &str = "crates/ra_assists/src/tests/generated.rs";
32const ASSISTS_DOCS: &str = "docs/user/assists.md";
33 35
34#[derive(Debug, PartialEq, Eq, Clone, Copy)] 36#[derive(Debug, PartialEq, Eq, Clone, Copy)]
35pub enum Mode { 37pub enum Mode {
@@ -107,3 +109,28 @@ fn do_extract_comment_blocks(text: &str, allow_blocks_with_empty_lines: bool) ->
107 } 109 }
108 res 110 res
109} 111}
112
113#[derive(Debug)]
114struct Location {
115 file: PathBuf,
116}
117
118impl Location {
119 fn new(file: PathBuf) -> Self {
120 Self { file }
121 }
122}
123
124impl fmt::Display for Location {
125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 let path = self.file.strip_prefix(&project_root()).unwrap().display().to_string();
127 let path = path.replace('\\', "/");
128 let name = self.file.file_name().unwrap();
129 write!(
130 f,
131 "https://github.com/rust-analyzer/rust-analyzer/blob/master/{}[{}]",
132 path,
133 name.to_str().unwrap()
134 )
135 }
136}
diff --git a/xtask/src/codegen/gen_assists_docs.rs b/xtask/src/codegen/gen_assists_docs.rs
index 6ebeb8aea..15a02d317 100644
--- a/xtask/src/codegen/gen_assists_docs.rs
+++ b/xtask/src/codegen/gen_assists_docs.rs
@@ -1,22 +1,28 @@
1//! Generates `assists.md` documentation. 1//! Generates `assists.md` documentation.
2 2
3use std::{fs, path::Path}; 3use std::{fmt, fs, path::Path};
4 4
5use crate::{ 5use crate::{
6 codegen::{self, extract_comment_blocks_with_empty_lines, Mode}, 6 codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode},
7 project_root, rust_files, Result, 7 project_root, rust_files, Result,
8}; 8};
9 9
10pub fn generate_assists_docs(mode: Mode) -> Result<()> { 10pub fn generate_assists_docs(mode: Mode) -> Result<()> {
11 let assists = Assist::collect()?; 11 let assists = Assist::collect()?;
12 generate_tests(&assists, mode)?; 12 generate_tests(&assists, mode)?;
13 generate_docs(&assists, mode)?; 13
14 let contents = assists.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n");
15 let contents = contents.trim().to_string() + "\n";
16 let dst = project_root().join("docs/user/generated_assists.adoc");
17 codegen::update(&dst, &contents, mode)?;
18
14 Ok(()) 19 Ok(())
15} 20}
16 21
17#[derive(Debug)] 22#[derive(Debug)]
18struct Assist { 23struct Assist {
19 id: String, 24 id: String,
25 location: Location,
20 doc: String, 26 doc: String,
21 before: String, 27 before: String,
22 after: String, 28 after: String,
@@ -58,7 +64,8 @@ impl Assist {
58 assert_eq!(lines.next().unwrap().as_str(), "->"); 64 assert_eq!(lines.next().unwrap().as_str(), "->");
59 assert_eq!(lines.next().unwrap().as_str(), "```"); 65 assert_eq!(lines.next().unwrap().as_str(), "```");
60 let after = take_until(lines.by_ref(), "```"); 66 let after = take_until(lines.by_ref(), "```");
61 acc.push(Assist { id, doc, before, after }) 67 let location = Location::new(path.to_path_buf());
68 acc.push(Assist { id, location, doc, before, after })
62 } 69 }
63 70
64 fn take_until<'a>(lines: impl Iterator<Item = &'a String>, marker: &str) -> String { 71 fn take_until<'a>(lines: impl Iterator<Item = &'a String>, marker: &str) -> String {
@@ -76,6 +83,31 @@ impl Assist {
76 } 83 }
77} 84}
78 85
86impl fmt::Display for Assist {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 let before = self.before.replace("<|>", "┃"); // Unicode pseudo-graphics bar
89 let after = self.after.replace("<|>", "┃");
90 writeln!(
91 f,
92 "[discrete]\n=== `{}`
93
94{}
95
96.Before
97```rust
98{}```
99
100.After
101```rust
102{}```",
103 self.id,
104 self.doc,
105 hide_hash_comments(&before),
106 hide_hash_comments(&after)
107 )
108 }
109}
110
79fn generate_tests(assists: &[Assist], mode: Mode) -> Result<()> { 111fn generate_tests(assists: &[Assist], mode: Mode) -> Result<()> {
80 let mut buf = String::from("use super::check_doc_test;\n"); 112 let mut buf = String::from("use super::check_doc_test;\n");
81 113
@@ -103,37 +135,6 @@ r#####"
103 codegen::update(&project_root().join(codegen::ASSISTS_TESTS), &buf, mode) 135 codegen::update(&project_root().join(codegen::ASSISTS_TESTS), &buf, mode)
104} 136}
105 137
106fn generate_docs(assists: &[Assist], mode: Mode) -> Result<()> {
107 let mut buf = String::from(
108 "# Assists\n\nCursor position or selection is signified by `┃` character.\n\n",
109 );
110
111 for assist in assists {
112 let before = assist.before.replace("<|>", "┃"); // Unicode pseudo-graphics bar
113 let after = assist.after.replace("<|>", "┃");
114 let docs = format!(
115 "
116## `{}`
117
118{}
119
120```rust
121// BEFORE
122{}
123// AFTER
124{}```
125",
126 assist.id,
127 assist.doc,
128 hide_hash_comments(&before),
129 hide_hash_comments(&after)
130 );
131 buf.push_str(&docs);
132 }
133
134 codegen::update(&project_root().join(codegen::ASSISTS_DOCS), &buf, mode)
135}
136
137fn hide_hash_comments(text: &str) -> String { 138fn hide_hash_comments(text: &str) -> String {
138 text.split('\n') // want final newline 139 text.split('\n') // want final newline
139 .filter(|&it| !(it.starts_with("# ") || it == "#")) 140 .filter(|&it| !(it.starts_with("# ") || it == "#"))
diff --git a/xtask/src/codegen/gen_feature_docs.rs b/xtask/src/codegen/gen_feature_docs.rs
index dbe583e8e..731e7ecf2 100644
--- a/xtask/src/codegen/gen_feature_docs.rs
+++ b/xtask/src/codegen/gen_feature_docs.rs
@@ -3,7 +3,7 @@
3use std::{fmt, fs, path::PathBuf}; 3use std::{fmt, fs, path::PathBuf};
4 4
5use crate::{ 5use crate::{
6 codegen::{self, extract_comment_blocks_with_empty_lines, Mode}, 6 codegen::{self, extract_comment_blocks_with_empty_lines, Location, Mode},
7 project_root, rust_files, Result, 7 project_root, rust_files, Result,
8}; 8};
9 9
@@ -19,7 +19,7 @@ pub fn generate_feature_docs(mode: Mode) -> Result<()> {
19#[derive(Debug)] 19#[derive(Debug)]
20struct Feature { 20struct Feature {
21 id: String, 21 id: String,
22 path: PathBuf, 22 location: Location,
23 doc: String, 23 doc: String,
24} 24}
25 25
@@ -40,7 +40,7 @@ impl Feature {
40 let id = block.id; 40 let id = block.id;
41 assert!(is_valid_feature_name(&id), "invalid feature name: {:?}", id); 41 assert!(is_valid_feature_name(&id), "invalid feature name: {:?}", id);
42 let doc = block.contents.join("\n"); 42 let doc = block.contents.join("\n");
43 acc.push(Feature { id, path: path.clone(), doc }) 43 acc.push(Feature { id, location: Location::new(path.clone()), doc })
44 } 44 }
45 45
46 Ok(()) 46 Ok(())
@@ -69,20 +69,6 @@ fn is_valid_feature_name(feature: &str) -> bool {
69 69
70impl fmt::Display for Feature { 70impl fmt::Display for Feature {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 writeln!(f, "=== {}", self.id)?; 72 writeln!(f, "=== {}\n**Source:** {}\n{}", self.id, self.location, self.doc)
73 let path = self.path.strip_prefix(&project_root()).unwrap().display().to_string();
74 let path = path.replace('\\', "/");
75 let name = self.path.file_name().unwrap();
76
77 //FIXME: generate line number as well
78 writeln!(
79 f,
80 "**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/{}[{}]",
81 path,
82 name.to_str().unwrap(),
83 )?;
84
85 writeln!(f, "{}", self.doc)?;
86 Ok(())
87 } 73 }
88} 74}
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs
index 06043d19f..874957885 100644
--- a/xtask/src/lib.rs
+++ b/xtask/src/lib.rs
@@ -191,7 +191,7 @@ Release: release:{}[]
191 let path = changelog_dir.join(format!("{}-changelog-{}.adoc", today, changelog_n)); 191 let path = changelog_dir.join(format!("{}-changelog-{}.adoc", today, changelog_n));
192 fs2::write(&path, &contents)?; 192 fs2::write(&path, &contents)?;
193 193
194 for &adoc in ["manual.adoc", "generated_features.adoc"].iter() { 194 for &adoc in ["manual.adoc", "generated_features.adoc", "generated_assists.adoc"].iter() {
195 let src = project_root().join("./docs/user/").join(adoc); 195 let src = project_root().join("./docs/user/").join(adoc);
196 let dst = website_root.join(adoc); 196 let dst = website_root.join(adoc);
197 fs2::copy(src, dst)?; 197 fs2::copy(src, dst)?;