Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

feat: add rome_flags crate for feature flags #2487

Merged
merged 10 commits into from
Apr 26, 2022
13 changes: 11 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/rome_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 5 additions & 0 deletions crates/rome_cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use pico_args::Arguments;
use rome_core::App;
use rome_flags::FeatureFlags;

mod commands;
mod metrics;
Expand Down Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions crates/rome_flags/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[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"
96 changes: 96 additions & 0 deletions crates/rome_flags/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//! 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!();
1 change: 1 addition & 0 deletions crates/rome_lsp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"}
Expand Down
4 changes: 4 additions & 0 deletions crates/rome_lsp/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ pub struct WorkspaceSettings {
/// Analysis settings
#[serde(default)]
pub analysis: AnalysisWorkspaceSettings,

/// Unstable features enabled
#[serde(default)]
pub unstable: bool,
}

#[derive(Debug)]
Expand Down
4 changes: 4 additions & 0 deletions crates/rome_lsp/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
5 changes: 5 additions & 0 deletions editors/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@
"type": "boolean",
"default": false,
"markdownDescription": "Allows rome to compute and provide code actions"
},
"rome.unstable": {
"type": "boolean",
"default": false,
"markdownDescription": "Enables unstable features"
yassere marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Expand Down