aboutsummaryrefslogtreecommitdiff
path: root/xtask
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-08-18 18:31:06 +0100
committerAleksey Kladov <[email protected]>2020-08-18 18:36:27 +0100
commit27ccc95c60d5652d5e7ef0dd7bd50cf221385d00 (patch)
tree7ce49ed16d73f8183f4456be2299c2dea9d36f40 /xtask
parentf18f9da7d80c669cf14bc2e85e40d883c621262a (diff)
Cleanup feature generation
Diffstat (limited to 'xtask')
-rw-r--r--xtask/src/codegen.rs40
-rw-r--r--xtask/src/codegen/gen_assists_docs.rs4
-rw-r--r--xtask/src/codegen/gen_features.rs50
-rw-r--r--xtask/src/codegen/gen_parser_tests.rs8
-rw-r--r--xtask/src/codegen/gen_syntax.rs8
-rw-r--r--xtask/src/codegen/gen_unstable_future_descriptor.rs61
-rw-r--r--xtask/src/main.rs10
-rw-r--r--xtask/tests/tidy.rs2
8 files changed, 84 insertions, 99 deletions
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs
index c468468de..45b17bb48 100644
--- a/xtask/src/codegen.rs
+++ b/xtask/src/codegen.rs
@@ -9,7 +9,7 @@ mod gen_syntax;
9mod gen_parser_tests; 9mod gen_parser_tests;
10mod gen_assists_docs; 10mod gen_assists_docs;
11mod gen_feature_docs; 11mod gen_feature_docs;
12mod gen_unstable_future_descriptor; 12mod gen_features;
13 13
14use std::{ 14use std::{
15 fmt, mem, 15 fmt, mem,
@@ -25,35 +25,35 @@ use crate::{
25pub use self::{ 25pub use self::{
26 gen_assists_docs::{generate_assists_docs, generate_assists_tests}, 26 gen_assists_docs::{generate_assists_docs, generate_assists_tests},
27 gen_feature_docs::generate_feature_docs, 27 gen_feature_docs::generate_feature_docs,
28 gen_features::generate_features,
28 gen_parser_tests::generate_parser_tests, 29 gen_parser_tests::generate_parser_tests,
29 gen_syntax::generate_syntax, 30 gen_syntax::generate_syntax,
30 gen_unstable_future_descriptor::generate_unstable_future_descriptor,
31}; 31};
32 32
33// Directory used by xtask
34const STORAGE: &str = ".xtask";
35
36const GRAMMAR_DIR: &str = "crates/parser/src/grammar";
37const OK_INLINE_TESTS_DIR: &str = "crates/syntax/test_data/parser/inline/ok";
38const ERR_INLINE_TESTS_DIR: &str = "crates/syntax/test_data/parser/inline/err";
39
40const SYNTAX_KINDS: &str = "crates/parser/src/syntax_kind/generated.rs";
41const AST_NODES: &str = "crates/syntax/src/ast/generated/nodes.rs";
42const AST_TOKENS: &str = "crates/syntax/src/ast/generated/tokens.rs";
43
44const ASSISTS_DIR: &str = "crates/assists/src/handlers";
45const ASSISTS_TESTS: &str = "crates/assists/src/tests/generated.rs";
46
47const REPOSITORY_URL: &str = "https://github.com/rust-lang/rust";
48const UNSTABLE_FEATURE: &str = "crates/ide/src/completion/unstable_feature_descriptor.rs";
49const REPO_PATH: &str = "src/doc/unstable-book/src";
50
51#[derive(Debug, PartialEq, Eq, Clone, Copy)] 33#[derive(Debug, PartialEq, Eq, Clone, Copy)]
52pub enum Mode { 34pub enum Mode {
53 Overwrite, 35 Overwrite,
54 Verify, 36 Verify,
55} 37}
56 38
39pub struct CodegenCmd {
40 pub features: bool,
41}
42
43impl CodegenCmd {
44 pub fn run(self) -> Result<()> {
45 if self.features {
46 generate_features(Mode::Overwrite)?;
47 }
48 generate_syntax(Mode::Overwrite)?;
49 generate_parser_tests(Mode::Overwrite)?;
50 generate_assists_tests(Mode::Overwrite)?;
51 generate_assists_docs(Mode::Overwrite)?;
52 generate_feature_docs(Mode::Overwrite)?;
53 Ok(())
54 }
55}
56
57/// A helper to update file on disk if it has changed. 57/// A helper to update file on disk if it has changed.
58/// With verify = false, 58/// With verify = false,
59fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> { 59fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> {
diff --git a/xtask/src/codegen/gen_assists_docs.rs b/xtask/src/codegen/gen_assists_docs.rs
index 4f4968594..f0ded8b87 100644
--- a/xtask/src/codegen/gen_assists_docs.rs
+++ b/xtask/src/codegen/gen_assists_docs.rs
@@ -32,7 +32,7 @@ struct Assist {
32impl Assist { 32impl Assist {
33 fn collect() -> Result<Vec<Assist>> { 33 fn collect() -> Result<Vec<Assist>> {
34 let mut res = Vec::new(); 34 let mut res = Vec::new();
35 for path in rust_files(&project_root().join(codegen::ASSISTS_DIR)) { 35 for path in rust_files(&project_root().join("crates/assists/src/handlers")) {
36 collect_file(&mut res, path.as_path())?; 36 collect_file(&mut res, path.as_path())?;
37 } 37 }
38 res.sort_by(|lhs, rhs| lhs.id.cmp(&rhs.id)); 38 res.sort_by(|lhs, rhs| lhs.id.cmp(&rhs.id));
@@ -135,7 +135,7 @@ r#####"
135 buf.push_str(&test) 135 buf.push_str(&test)
136 } 136 }
137 let buf = reformat(buf)?; 137 let buf = reformat(buf)?;
138 codegen::update(&project_root().join(codegen::ASSISTS_TESTS), &buf, mode) 138 codegen::update(&project_root().join("crates/assists/src/tests/generated.rs"), &buf, mode)
139} 139}
140 140
141fn hide_hash_comments(text: &str) -> String { 141fn hide_hash_comments(text: &str) -> String {
diff --git a/xtask/src/codegen/gen_features.rs b/xtask/src/codegen/gen_features.rs
new file mode 100644
index 000000000..78268308b
--- /dev/null
+++ b/xtask/src/codegen/gen_features.rs
@@ -0,0 +1,50 @@
1//! Generates descriptors structure for unstable feature from Unstable Book
2use std::path::{Path, PathBuf};
3
4use quote::quote;
5use walkdir::WalkDir;
6
7use crate::{
8 codegen::{project_root, reformat, update, Mode, Result},
9 not_bash::{fs2, run},
10};
11
12pub fn generate_features(mode: Mode) -> Result<()> {
13 if !Path::new("./target/rust").exists() {
14 run!("git clone https://github.com/rust-lang/rust ./target/rust")?;
15 }
16
17 let contents = generate_descriptor("./target/rust/src/doc/unstable-book/src".into())?;
18
19 let destination = project_root().join("crates/ide/src/completion/generated_features.rs");
20 update(destination.as_path(), &contents, mode)?;
21
22 Ok(())
23}
24
25fn generate_descriptor(src_dir: PathBuf) -> Result<String> {
26 let definitions = ["language-features", "library-features"]
27 .iter()
28 .flat_map(|it| WalkDir::new(src_dir.join(it)))
29 .filter_map(|e| e.ok())
30 .filter(|entry| {
31 // Get all `.md ` files
32 entry.file_type().is_file() && entry.path().extension().unwrap_or_default() == "md"
33 })
34 .map(|entry| {
35 let path = entry.path();
36 let feature_ident = path.file_stem().unwrap().to_str().unwrap().replace("-", "_");
37 let doc = fs2::read_to_string(path).unwrap();
38
39 quote! { LintCompletion { label: #feature_ident, description: #doc } }
40 });
41
42 let ts = quote! {
43 use crate::completion::complete_attribute::LintCompletion;
44
45 pub(super) const FEATURES: &[LintCompletion] = &[
46 #(#definitions),*
47 ];
48 };
49 reformat(ts)
50}
diff --git a/xtask/src/codegen/gen_parser_tests.rs b/xtask/src/codegen/gen_parser_tests.rs
index 2977da2fa..96fdd9216 100644
--- a/xtask/src/codegen/gen_parser_tests.rs
+++ b/xtask/src/codegen/gen_parser_tests.rs
@@ -8,12 +8,12 @@ use std::{
8}; 8};
9 9
10use crate::{ 10use crate::{
11 codegen::{self, extract_comment_blocks, update, Mode}, 11 codegen::{extract_comment_blocks, update, Mode},
12 project_root, Result, 12 project_root, Result,
13}; 13};
14 14
15pub fn generate_parser_tests(mode: Mode) -> Result<()> { 15pub fn generate_parser_tests(mode: Mode) -> Result<()> {
16 let tests = tests_from_dir(&project_root().join(Path::new(codegen::GRAMMAR_DIR)))?; 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, mode: Mode) -> 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() {
@@ -39,8 +39,8 @@ pub fn generate_parser_tests(mode: Mode) -> Result<()> {
39 } 39 }
40 Ok(()) 40 Ok(())
41 } 41 }
42 install_tests(&tests.ok, codegen::OK_INLINE_TESTS_DIR, mode)?; 42 install_tests(&tests.ok, "crates/syntax/test_data/parser/inline/ok", mode)?;
43 install_tests(&tests.err, codegen::ERR_INLINE_TESTS_DIR, mode) 43 install_tests(&tests.err, "crates/syntax/test_data/parser/inline/err", mode)
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 df3ec22c8..53ae9f11c 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -14,7 +14,7 @@ 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::{self, reformat, update, Mode}, 17 codegen::{reformat, update, Mode},
18 project_root, Result, 18 project_root, Result,
19}; 19};
20 20
@@ -22,15 +22,15 @@ pub fn generate_syntax(mode: Mode) -> 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(codegen::SYNTAX_KINDS); 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 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?;
28 28
29 let ast_tokens_file = project_root().join(codegen::AST_TOKENS); 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 update(ast_tokens_file.as_path(), &contents, mode)?;
32 32
33 let ast_nodes_file = project_root().join(codegen::AST_NODES); 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 update(ast_nodes_file.as_path(), &contents, mode)?;
36 36
diff --git a/xtask/src/codegen/gen_unstable_future_descriptor.rs b/xtask/src/codegen/gen_unstable_future_descriptor.rs
deleted file mode 100644
index 907a9afae..000000000
--- a/xtask/src/codegen/gen_unstable_future_descriptor.rs
+++ /dev/null
@@ -1,61 +0,0 @@
1//! Generates descriptors structure for unstable feature from Unstable Book
2
3use crate::codegen::{self, project_root, Mode, Result};
4use crate::codegen::{reformat, update};
5use crate::not_bash::{fs2, pushd, run};
6use proc_macro2::TokenStream;
7use quote::quote;
8use std::path::PathBuf;
9use walkdir::WalkDir;
10
11fn generate_descriptor(src_dir: PathBuf) -> Result<TokenStream> {
12 let files = WalkDir::new(src_dir.join("language-features"))
13 .into_iter()
14 .chain(WalkDir::new(src_dir.join("library-features")))
15 .filter_map(|e| e.ok())
16 .filter(|entry| {
17 // Get all `.md ` files
18 entry.file_type().is_file() && entry.path().extension().unwrap_or_default() == "md"
19 })
20 .collect::<Vec<_>>();
21
22 let definitions = files
23 .iter()
24 .map(|entry| {
25 let path = entry.path();
26 let feature_ident =
27 format!("{}", path.file_stem().unwrap().to_str().unwrap().replace("-", "_"));
28 let doc = format!("{}", std::fs::read_to_string(path).unwrap());
29
30 quote! { LintCompletion { label: #feature_ident, description: #doc } }
31 })
32 .collect::<Vec<_>>();
33
34 let ts = quote! {
35 use crate::completion::LintCompletion;
36
37 pub(crate) const UNSTABLE_FEATURE_DESCRIPTOR: &[LintCompletion] = &[
38 #(#definitions),*
39 ];
40 };
41 Ok(ts)
42}
43
44pub fn generate_unstable_future_descriptor(mode: Mode) -> Result<()> {
45 let path = project_root().join(codegen::STORAGE);
46 fs2::create_dir_all(path.clone())?;
47
48 let _d = pushd(path.clone());
49 run!("git init")?;
50 run!("git remote add -f origin {}", codegen::REPOSITORY_URL)?;
51 run!("git pull origin master")?;
52
53 let src_dir = path.join(codegen::REPO_PATH);
54 let content = generate_descriptor(src_dir)?.to_string();
55
56 let contents = reformat(content)?;
57 let destination = project_root().join(codegen::UNSTABLE_FEATURE);
58 update(destination.as_path(), &contents, mode)?;
59
60 Ok(())
61}
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index c4a15f4bd..3f4aa5497 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -10,6 +10,7 @@
10 10
11use std::env; 11use std::env;
12 12
13use codegen::CodegenCmd;
13use pico_args::Arguments; 14use pico_args::Arguments;
14use xtask::{ 15use xtask::{
15 codegen::{self, Mode}, 16 codegen::{self, Mode},
@@ -75,14 +76,9 @@ FLAGS:
75 .run() 76 .run()
76 } 77 }
77 "codegen" => { 78 "codegen" => {
79 let features = args.contains("--features");
78 args.finish()?; 80 args.finish()?;
79 codegen::generate_syntax(Mode::Overwrite)?; 81 CodegenCmd { features }.run()
80 codegen::generate_unstable_future_descriptor(Mode::Overwrite)?;
81 codegen::generate_parser_tests(Mode::Overwrite)?;
82 codegen::generate_assists_tests(Mode::Overwrite)?;
83 codegen::generate_assists_docs(Mode::Overwrite)?;
84 codegen::generate_feature_docs(Mode::Overwrite)?;
85 Ok(())
86 } 82 }
87 "format" => { 83 "format" => {
88 args.finish()?; 84 args.finish()?;
diff --git a/xtask/tests/tidy.rs b/xtask/tests/tidy.rs
index bec3c630b..4fdff62ee 100644
--- a/xtask/tests/tidy.rs
+++ b/xtask/tests/tidy.rs
@@ -113,7 +113,7 @@ fn check_todo(path: &Path, text: &str) {
113 // `ast::make`. 113 // `ast::make`.
114 "ast/make.rs", 114 "ast/make.rs",
115 // The documentation in string literals may contain anything for its own purposes 115 // The documentation in string literals may contain anything for its own purposes
116 "completion/unstable_feature_descriptor.rs", 116 "completion/generated_features.rs",
117 ]; 117 ];
118 if need_todo.iter().any(|p| path.ends_with(p)) { 118 if need_todo.iter().any(|p| path.ends_with(p)) {
119 return; 119 return;