Skip to content

Commit

Permalink
Add feature flag support to GlobalState (#2826)
Browse files Browse the repository at this point in the history
### Motivation

This PR starts passing the enabled feature flags to the server and storing it in the global state. That way the Ruby LSP and its add-ons can check for specific feature flags. This also allows users of other editors to opt into features through `initializationOptions`.

### Implementation

- Started passing all enabled flag information to the server
- Started storing this information in the global state

### Automated Tests

Added unit tests to verify feature flag processing and retrieval functionality.
  • Loading branch information
vinistock authored Nov 5, 2024
1 parent 2044b7c commit 6f83f74
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
9 changes: 9 additions & 0 deletions lib/ruby_lsp/global_state.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def initialize
T::Boolean,
)
@client_capabilities = T.let(ClientCapabilities.new, ClientCapabilities)
@enabled_feature_flags = T.let({}, T::Hash[Symbol, T::Boolean])
end

sig { params(addon_name: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
Expand Down Expand Up @@ -139,9 +140,17 @@ def apply_options(options)
@addon_settings.merge!(addon_settings)
end

enabled_flags = options.dig(:initializationOptions, :enabledFeatureFlags)
@enabled_feature_flags = enabled_flags if enabled_flags

notifications
end

sig { params(flag: Symbol).returns(T.nilable(T::Boolean)) }
def enabled_feature?(flag)
@enabled_feature_flags[flag]
end

sig { returns(String) }
def workspace_path
T.must(@workspace_uri.to_standardized_path)
Expand Down
17 changes: 17 additions & 0 deletions test/global_state_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,23 @@ def test_delegates_supports_watching_files_to_client_capabilities
global_state.supports_watching_files
end

def test_feature_flags_are_processed_by_apply_options
state = GlobalState.new

state.apply_options({
initializationOptions: {
enabledFeatureFlags: {
semantic_highlighting: true,
code_lens: false,
},
},
})

assert(state.enabled_feature?(:semantic_highlighting))
refute(state.enabled_feature?(:code_lens))
assert_nil(state.enabled_feature?(:unknown_flag))
end

private

def stub_direct_dependencies(dependencies)
Expand Down
11 changes: 11 additions & 0 deletions vscode/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import {
ClientInterface,
Addon,
SUPPORTED_LANGUAGE_IDS,
FEATURE_FLAGS,
featureEnabled,
} from "./common";
import { Ruby } from "./ruby";
import { WorkspaceChannel } from "./workspaceChannel";
Expand All @@ -50,6 +52,14 @@ interface ServerErrorTelemetryEvent {

type ServerTelemetryEvent = ServerErrorTelemetryEvent;

function enabledFeatureFlags() {
const allKeys = Object.keys(FEATURE_FLAGS) as (keyof typeof FEATURE_FLAGS)[];

return allKeys.map((key) => {
return { [key]: featureEnabled(key) };
});
}

// Get the executables to start the server based on the user's configuration
function getLspExecutables(
workspaceFolder: vscode.WorkspaceFolder,
Expand Down Expand Up @@ -216,6 +226,7 @@ function collectClientOptions(
linters: configuration.get("linters"),
indexing: configuration.get("indexing"),
addonSettings: configuration.get("addonSettings"),
enabledFeatureFlags: enabledFeatureFlags(),
},
};
}
Expand Down

0 comments on commit 6f83f74

Please sign in to comment.