#![allow(unreachable_pub)] use std::{fmt, str::FromStr}; use crate::install::{ClientOpt, ProcMacroServerOpt, ServerOpt}; #[derive(Debug, Clone)] pub enum PgoTrainingCrate { // Use RA's own sources for PGO training RustAnalyzer, // Download a Rust crate from `https://github.com/{0}` and use it for PGO training. GitHub(String), } impl FromStr for PgoTrainingCrate { type Err = String; fn from_str(s: &str) -> Result { match s { "rust-analyzer" => Ok(Self::RustAnalyzer), url => Ok(Self::GitHub(url.to_owned())), } } } xflags::xflags! { src "./src/flags.rs" /// Run custom build command. cmd xtask { /// Install rust-analyzer server or editor plugin. cmd install { /// Install only VS Code plugin. optional --client /// One of `code`, `code-exploration`, `code-insiders`, `codium`, or `code-oss`. optional --code-bin name: String /// Install only the language server. optional --server /// Use mimalloc allocator for server. optional --mimalloc /// Use jemalloc allocator for server. optional --jemalloc // Enable memory profiling support. // // **Warning:** This will produce a slower build of rust-analyzer, use only for profiling. optional --enable-profiling /// Install the proc-macro server. optional --proc-macro-server /// build in release with debug info set to 2. optional --dev-rel /// Make `never!()`, `always!()` etc. panic instead of just logging an error. optional --force-always-assert /// Apply PGO optimizations optional --pgo pgo: PgoTrainingCrate } cmd fuzz-tests {} cmd release { optional --dry-run } cmd dist { /// Use mimalloc allocator for server optional --mimalloc /// Use jemalloc allocator for server optional --jemalloc // Enable memory profiling support. // // **Warning:** This will produce a slower build of rust-analyzer, use only for profiling. optional --enable-profiling optional --client-patch-version version: String /// Use cargo-zigbuild optional --zig /// Apply PGO optimizations optional --pgo pgo: PgoTrainingCrate } /// Read a changelog AsciiDoc file and update the GitHub Releases entry in Markdown. cmd publish-release-notes { /// Only run conversion and show the result. optional --dry-run /// Target changelog file. required changelog: String } cmd metrics { optional measurement_type: MeasurementType } /// Builds a benchmark version of rust-analyzer and puts it into `./target`. cmd bb { required suffix: String } cmd codegen { optional codegen_type: CodegenType optional --check } cmd tidy {} } } // generated start // The following code is generated by `xflags` macro. // Run `env UPDATE_XFLAGS=1 cargo build` to regenerate. #[derive(Debug)] pub struct Xtask { pub subcommand: XtaskCmd, } #[derive(Debug)] pub enum XtaskCmd { Install(Install), FuzzTests(FuzzTests), Release(Release), Dist(Dist), PublishReleaseNotes(PublishReleaseNotes), Metrics(Metrics), Bb(Bb), Codegen(Codegen), Tidy(Tidy), } #[derive(Debug)] pub struct Install { pub client: bool, pub code_bin: Option, pub server: bool, pub mimalloc: bool, pub jemalloc: bool, pub enable_profiling: bool, pub proc_macro_server: bool, pub dev_rel: bool, pub force_always_assert: bool, pub pgo: Option, } #[derive(Debug)] pub struct FuzzTests; #[derive(Debug)] pub struct Release { pub dry_run: bool, } #[derive(Debug)] pub struct Dist { pub mimalloc: bool, pub jemalloc: bool, pub enable_profiling: bool, pub client_patch_version: Option, pub zig: bool, pub pgo: Option, } #[derive(Debug)] pub struct PublishReleaseNotes { pub changelog: String, pub dry_run: bool, } #[derive(Debug)] pub struct Metrics { pub measurement_type: Option, } #[derive(Debug)] pub struct Bb { pub suffix: String, } #[derive(Debug)] pub struct Codegen { pub codegen_type: Option, pub check: bool, } #[derive(Debug)] pub struct Tidy; impl Xtask { #[allow(dead_code)] pub fn from_env_or_exit() -> Self { Self::from_env_or_exit_() } #[allow(dead_code)] pub fn from_env() -> xflags::Result { Self::from_env_() } #[allow(dead_code)] pub fn from_vec(args: Vec) -> xflags::Result { Self::from_vec_(args) } } // generated end #[derive(Debug, Default)] pub enum CodegenType { #[default] All, Grammar, AssistsDocTests, DiagnosticsDocs, LintDefinitions, ParserTests, FeatureDocs, } impl fmt::Display for CodegenType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::All => write!(f, "all"), Self::Grammar => write!(f, "grammar"), Self::AssistsDocTests => write!(f, "assists-doc-tests"), Self::DiagnosticsDocs => write!(f, "diagnostics-docs"), Self::LintDefinitions => write!(f, "lint-definitions"), Self::ParserTests => write!(f, "parser-tests"), Self::FeatureDocs => write!(f, "feature-docs"), } } } impl FromStr for CodegenType { type Err = String; fn from_str(s: &str) -> Result { match s { "all" => Ok(Self::All), "grammar" => Ok(Self::Grammar), "assists-doc-tests" => Ok(Self::AssistsDocTests), "diagnostics-docs" => Ok(Self::DiagnosticsDocs), "lint-definitions" => Ok(Self::LintDefinitions), "parser-tests" => Ok(Self::ParserTests), "feature-docs" => Ok(Self::FeatureDocs), _ => Err("Invalid option".to_owned()), } } } #[derive(Debug)] pub enum MeasurementType { Build, RustcTests, AnalyzeSelf, AnalyzeRipgrep, AnalyzeWebRender, AnalyzeDiesel, AnalyzeHyper, } impl FromStr for MeasurementType { type Err = String; fn from_str(s: &str) -> Result { match s { "build" => Ok(Self::Build), "rustc_tests" => Ok(Self::RustcTests), "self" => Ok(Self::AnalyzeSelf), "ripgrep-13.0.0" => Ok(Self::AnalyzeRipgrep), "webrender-2022" => Ok(Self::AnalyzeWebRender), "diesel-1.4.8" => Ok(Self::AnalyzeDiesel), "hyper-0.14.18" => Ok(Self::AnalyzeHyper), _ => Err("Invalid option".to_owned()), } } } impl AsRef for MeasurementType { fn as_ref(&self) -> &str { match self { Self::Build => "build", Self::RustcTests => "rustc_tests", Self::AnalyzeSelf => "self", Self::AnalyzeRipgrep => "ripgrep-13.0.0", Self::AnalyzeWebRender => "webrender-2022", Self::AnalyzeDiesel => "diesel-1.4.8", Self::AnalyzeHyper => "hyper-0.14.18", } } } #[derive(Clone, Copy, Debug)] pub(crate) enum Malloc { System, Mimalloc, Jemalloc, Dhat, } impl Malloc { pub(crate) fn to_features(self) -> &'static [&'static str] { match self { Malloc::System => &[][..], Malloc::Mimalloc => &["--features", "mimalloc"], Malloc::Jemalloc => &["--features", "jemalloc"], Malloc::Dhat => &["--features", "dhat"], } } } impl Install { pub(crate) fn server(&self) -> Option { if (self.client || self.proc_macro_server) && !self.server { return None; } let malloc = if self.mimalloc { Malloc::Mimalloc } else if self.jemalloc { Malloc::Jemalloc } else if self.enable_profiling { Malloc::Dhat } else { Malloc::System }; Some(ServerOpt { malloc, // Profiling requires debug information. dev_rel: self.dev_rel || self.enable_profiling, pgo: self.pgo.clone(), force_always_assert: self.force_always_assert, }) } pub(crate) fn proc_macro_server(&self) -> Option { if !self.proc_macro_server { return None; } Some(ProcMacroServerOpt { dev_rel: self.dev_rel }) } pub(crate) fn client(&self) -> Option { if (self.server || self.proc_macro_server) && !self.client { return None; } Some(ClientOpt { code_bin: self.code_bin.clone() }) } } impl Dist { pub(crate) fn allocator(&self) -> Malloc { if self.mimalloc { Malloc::Mimalloc } else if self.jemalloc { Malloc::Jemalloc } else if self.enable_profiling { Malloc::Dhat } else { Malloc::System } } }