feat: add rome_flags crate for feature flags
MODIFY
Cargo.lock
Cargo.lock
@@ -978,9 +978,9 @@ dependencies = [
[[package]]
name = "once_cell"
-version = "1.9.0"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
+checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]]
name = "oorandom"
@@ -1277,6 +1277,7 @@ dependencies = [
"rome_console",
"rome_core",
"rome_diagnostics",
+ "rome_flags",
"rome_fs",
"rome_js_formatter",
"rome_js_parser",
@@ -1327,6 +1328,13 @@ dependencies = [
"unicode-width",
]
+[[package]]
+name = "rome_flags"
+version = "0.0.0"
+dependencies = [
+ "once_cell",
+]
+
[[package]]
name = "rome_formatter"
version = "0.1.0"
@@ -1416,6 +1424,7 @@ dependencies = [
"parking_lot",
"rome_analyze",
"rome_diagnostics",
+ "rome_flags",
"rome_fs",
"rome_js_formatter",
"rome_js_parser",

MODIFY
crates/rome_cli/Cargo.toml
crates/rome_cli/Cargo.toml
@@ -10,6 +10,7 @@ rome_js_formatter = { path = "../rome_js_formatter" }
rome_js_parser = { path = "../rome_js_parser" }
rome_diagnostics = { path = "../rome_diagnostics" }
rome_core = { path = "../rome_core" }
+rome_flags = { path = "../rome_flags" }
rome_fs = { path = "../rome_fs" }
rome_console = { path = "../rome_console" }
pico-args = "0.4.2"

MODIFY
crates/rome_cli/src/lib.rs
crates/rome_cli/src/lib.rs
use pico_args::Arguments;
use rome_core::App;
+use rome_flags::FeatureFlags;
mod commands;
mod metrics;
@@ -33,6 +34,10 @@ pub fn run_cli(mut session: CliSession) -> Result<(), Termination> {
crate::metrics::init_metrics();
}
+ if session.args.contains("--unstable") {
+ rome_flags::set_unstable_flags(FeatureFlags::ALL);
+ }
+
let has_help = session.args.contains("--help");
let subcommand = session
.args

ADD
crates/rome_flags/Cargo.toml
+[package]
+name = "rome_flags"
+version = "0.0.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+once_cell = "1.10"

ADD
crates/rome_flags/src/lib.rs
+//! A simple implementation of feature flags.
+//!
+//! Feature flags are created using the [declare_feature_flags] macro.
+//!
+//! ```ignore
+//! declare_feature_flags!(
+//! /// A feature that is not finished yet
+//! unfinished_feature,
+//! /// A new unstable approach to parsing
+//! modified_parsing
+//! )
+//! ```
+//!
+//! Flags are retrieved using the [unstable] function and checked by calling the method
+//! matching the name of the feature.
+//!
+//! ```ignore
+//! if rome_flags::unstable().unfinished_feature() {
+//! // Do something
+//! }
+//! ```
+//!
+//! The current implementation doesn't allow for runtime modification of flags. They can only
+//! be set once using [set_unstable_flags].
+
+use std::str::FromStr;
+
+use once_cell::sync::OnceCell;
+
+static FLAGS: OnceCell<FeatureFlags> = OnceCell::new();
+
+/// Returns the feature flags for this program run. Flags are all disabled until [set_unstable_flags] is called.
+pub fn unstable() -> &'static FeatureFlags {
+ FLAGS.get().unwrap_or(&FeatureFlags::NONE)
+}
+
+/// Sets feature flags for this program run if they weren't previously set.
+pub fn set_unstable_flags(flags: FeatureFlags) {
+ if FLAGS.set(flags).is_err() {
+ eprintln!("Attempted to set rome_feature unstable flags more than once")
+ }
+}
+
+macro_rules! declare_feature_flags {
+ ( $( $(#[doc = $doc:tt])* $feature:ident ),* )=> {
+ #[derive(Debug, Default)]
+ /// State of all feature flags
+ pub struct FeatureFlags {
+ $(
+ $feature: bool,
+ )*
+ }
+
+ impl FeatureFlags {
+ pub const ALL: Self = Self {
+ $( $feature: true, )*
+ };
+
+ pub const NONE: Self = Self {
+ $( $feature: false, )*
+ };
+
+ $(
+ $(#[doc = $doc])*
+ pub fn $feature(&self) -> bool { self.$feature }
+ )*
+ }
+
+ impl FromStr for FeatureFlags {
+ type Err = String;
+
+ // Must be a comma-separated list (no spaces) of features that exactly match
+ // the features declared with the declare_feature_flags macro
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ let mut unknown_features = Vec::new();
+ #[allow(unused_mut)]
+ let mut flags = FeatureFlags::default();
+ for feature in s.split(',') {
+ match feature {
+ $( stringify!($feature) => flags.$feature = true, )*
+ unknown => unknown_features.push(unknown)
+ }
+ }
+ if unknown_features.is_empty() {
+ Ok(flags)
+ } else {
+ Err(format!("Unknown features: {}", unknown_features.join(",")))
+ }
+ }
+ }
+ };
+}
+
+// Flags for unstable features are declared below and are intended to be temporary.
+// When it's no longer necessary to gate a feature, remove the flag from this list.
+declare_feature_flags!();

MODIFY
crates/rome_lsp/Cargo.toml
crates/rome_lsp/Cargo.toml
@@ -14,6 +14,7 @@ indexmap = "1.8.0"
rome_js_formatter = { path = "../rome_js_formatter" }
rome_analyze = { path = "../rome_analyze" }
rome_diagnostics = { path = "../rome_diagnostics" }
+rome_flags = { path = "../rome_flags" }
rome_js_parser = { path = "../rome_js_parser" }
rome_js_syntax = { path = "../rome_js_syntax" }
tower-lsp = { version = "0.17.0"}

MODIFY
crates/rome_lsp/src/config.rs
crates/rome_lsp/src/config.rs
@@ -41,6 +41,10 @@ pub struct WorkspaceSettings {
/// Analysis settings
#[serde(default)]
pub analysis: AnalysisWorkspaceSettings,
+
+ /// Unstable features enabled
+ #[serde(default)]
+ pub unstable: bool,
}
#[derive(Debug)]

MODIFY
crates/rome_lsp/src/server.rs
crates/rome_lsp/src/server.rs
@@ -66,6 +66,10 @@ impl LanguageServer for LSPServer {
async fn initialized(&self, _: InitializedParams) {
self.session.fetch_client_configuration().await;
+ if self.session.config.read().get_workspace_settings().unstable {
+ rome_flags::set_unstable_flags(rome_flags::FeatureFlags::ALL);
+ }
+
let msg = format!("Server initialized with PID: {}", std::process::id());
self.client.log_message(MessageType::INFO, msg).await;

MODIFY
editors/vscode/package.json
editors/vscode/package.json
"type": "boolean",
"default": false,
"markdownDescription": "Allows rome to compute and provide code actions"
+ },
+ "rome.unstable": {
+ "type": "boolean",
+ "default": false,
+ "markdownDescription": "**BETA**: enables unstable features"
}
}
}

feat: add rome_flags crate for feature flags (#2487)