1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

feat(lsp): support more vscode built-in settings (#20679)

This commit is contained in:
Nayeem Rahman 2023-09-26 03:54:07 +01:00 committed by GitHub
parent 8e1304ced4
commit 939279aa10
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 399 additions and 175 deletions

View file

@ -94,26 +94,67 @@ pub struct DenoCompletionSettings {
pub imports: ImportCompletionSettings,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct ClassMemberSnippets {
#[serde(default = "is_true")]
pub enabled: bool,
}
impl Default for ClassMemberSnippets {
fn default() -> Self {
Self { enabled: true }
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct ObjectLiteralMethodSnippets {
#[serde(default = "is_true")]
pub enabled: bool,
}
impl Default for ObjectLiteralMethodSnippets {
fn default() -> Self {
Self { enabled: true }
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct CompletionSettings {
#[serde(default)]
pub complete_function_calls: bool,
#[serde(default = "is_true")]
pub include_automatic_optional_chain_completions: bool,
#[serde(default = "is_true")]
pub include_completions_for_import_statements: bool,
#[serde(default = "is_true")]
pub names: bool,
#[serde(default = "is_true")]
pub paths: bool,
#[serde(default = "is_true")]
pub auto_imports: bool,
#[serde(default = "is_true")]
pub enabled: bool,
#[serde(default)]
pub class_member_snippets: ClassMemberSnippets,
#[serde(default)]
pub object_literal_method_snippets: ObjectLiteralMethodSnippets,
}
impl Default for CompletionSettings {
fn default() -> Self {
Self {
complete_function_calls: false,
include_automatic_optional_chain_completions: true,
include_completions_for_import_statements: true,
names: true,
paths: true,
auto_imports: true,
enabled: true,
class_member_snippets: Default::default(),
object_literal_method_snippets: Default::default(),
}
}
}
@ -286,13 +327,91 @@ fn empty_string_none<'de, D: serde::Deserializer<'de>>(
Ok(o.filter(|s| !s.is_empty()))
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum ImportModuleSpecifier {
NonRelative,
ProjectRelative,
Relative,
Shortest,
}
impl Default for ImportModuleSpecifier {
fn default() -> Self {
Self::Shortest
}
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum JsxAttributeCompletionStyle {
Auto,
Braces,
None,
}
impl Default for JsxAttributeCompletionStyle {
fn default() -> Self {
Self::Auto
}
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct LanguagePreferences {
#[serde(default)]
pub import_module_specifier: ImportModuleSpecifier,
#[serde(default)]
pub jsx_attribute_completion_style: JsxAttributeCompletionStyle,
#[serde(default)]
pub auto_import_file_exclude_patterns: Vec<String>,
#[serde(default = "is_true")]
pub use_aliases_for_renames: bool,
}
impl Default for LanguagePreferences {
fn default() -> Self {
LanguagePreferences {
import_module_specifier: Default::default(),
jsx_attribute_completion_style: Default::default(),
auto_import_file_exclude_patterns: vec![],
use_aliases_for_renames: true,
}
}
}
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct UpdateImportsOnFileMoveOptions {
#[serde(default)]
pub enabled: UpdateImportsOnFileMoveEnabled,
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum UpdateImportsOnFileMoveEnabled {
Always,
Prompt,
Never,
}
impl Default for UpdateImportsOnFileMoveEnabled {
fn default() -> Self {
Self::Prompt
}
}
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct LanguageWorkspaceSettings {
#[serde(default)]
pub inlay_hints: InlayHintsSettings,
#[serde(default)]
pub preferences: LanguagePreferences,
#[serde(default)]
pub suggest: CompletionSettings,
#[serde(default)]
pub update_imports_on_file_move: UpdateImportsOnFileMoveOptions,
}
/// Deno language server specific settings that are applied to a workspace.
@ -1244,12 +1363,28 @@ mod tests {
enabled: false
},
},
preferences: LanguagePreferences {
import_module_specifier: ImportModuleSpecifier::Shortest,
jsx_attribute_completion_style: JsxAttributeCompletionStyle::Auto,
auto_import_file_exclude_patterns: vec![],
use_aliases_for_renames: true,
},
suggest: CompletionSettings {
complete_function_calls: false,
include_automatic_optional_chain_completions: true,
include_completions_for_import_statements: true,
names: true,
paths: true,
auto_imports: true,
enabled: true,
class_member_snippets: ClassMemberSnippets { enabled: true },
object_literal_method_snippets: ObjectLiteralMethodSnippets {
enabled: true,
},
},
update_imports_on_file_move: UpdateImportsOnFileMoveOptions {
enabled: UpdateImportsOnFileMoveEnabled::Prompt
}
},
typescript: LanguageWorkspaceSettings {
inlay_hints: InlayHintsSettings {
@ -1272,12 +1407,28 @@ mod tests {
enabled: false
},
},
preferences: LanguagePreferences {
import_module_specifier: ImportModuleSpecifier::Shortest,
jsx_attribute_completion_style: JsxAttributeCompletionStyle::Auto,
auto_import_file_exclude_patterns: vec![],
use_aliases_for_renames: true,
},
suggest: CompletionSettings {
complete_function_calls: false,
include_automatic_optional_chain_completions: true,
include_completions_for_import_statements: true,
names: true,
paths: true,
auto_imports: true,
enabled: true,
class_member_snippets: ClassMemberSnippets { enabled: true },
object_literal_method_snippets: ObjectLiteralMethodSnippets {
enabled: true,
},
},
update_imports_on_file_move: UpdateImportsOnFileMoveOptions {
enabled: UpdateImportsOnFileMoveEnabled::Prompt
}
},
}
);

View file

@ -45,6 +45,7 @@ use super::code_lens;
use super::completions;
use super::config::Config;
use super::config::ConfigSnapshot;
use super::config::UpdateImportsOnFileMoveEnabled;
use super::config::WorkspaceSettings;
use super::config::SETTINGS_SECTION;
use super::diagnostics;
@ -1933,13 +1934,11 @@ impl Inner {
..line_index.offset_tsc(diagnostic.range.end)?,
codes,
(&self.fmt_options.options).into(),
tsc::UserPreferences {
quote_preference: Some((&self.fmt_options.options).into()),
..tsc::UserPreferences::from_workspace_settings_for_specifier(
self.config.workspace_settings(),
&specifier,
)
},
tsc::UserPreferences::from_config_for_specifier(
&self.config,
&self.fmt_options.options,
&specifier,
),
)
.await;
for action in actions {
@ -2024,13 +2023,11 @@ impl Inner {
specifier.clone(),
line_index.offset_tsc(params.range.start)?
..line_index.offset_tsc(params.range.end)?,
Some(tsc::UserPreferences {
quote_preference: Some((&self.fmt_options.options).into()),
..tsc::UserPreferences::from_workspace_settings_for_specifier(
self.config.workspace_settings(),
&specifier,
)
}),
Some(tsc::UserPreferences::from_config_for_specifier(
&self.config,
&self.fmt_options.options,
&specifier,
)),
only,
)
.await?;
@ -2086,13 +2083,11 @@ impl Inner {
self.snapshot(),
&code_action_data,
(&self.fmt_options.options).into(),
tsc::UserPreferences {
quote_preference: Some((&self.fmt_options.options).into()),
..tsc::UserPreferences::from_workspace_settings_for_specifier(
self.config.workspace_settings(),
&code_action_data.specifier,
)
},
tsc::UserPreferences::from_config_for_specifier(
&self.config,
&self.fmt_options.options,
&code_action_data.specifier,
),
)
.await?;
if combined_code_actions.commands.is_some() {
@ -2138,13 +2133,11 @@ impl Inner {
..line_index.offset_tsc(action_data.range.end)?,
action_data.refactor_name,
action_data.action_name,
Some(tsc::UserPreferences {
quote_preference: Some((&self.fmt_options.options).into()),
..tsc::UserPreferences::from_workspace_settings_for_specifier(
self.config.workspace_settings(),
&action_data.specifier,
)
}),
Some(tsc::UserPreferences::from_config_for_specifier(
&self.config,
&self.fmt_options.options,
&action_data.specifier,
)),
)
.await?;
code_action.edit = refactor_edit_info.to_workspace_edit(self).await?;
@ -2413,8 +2406,13 @@ impl Inner {
&params.text_document_position.text_document.uri,
LspUrlKind::File,
);
let language_settings = self
.config
.workspace_settings()
.language_settings_for_specifier(&specifier);
if !self.is_diagnosable(&specifier)
|| !self.config.specifier_enabled(&specifier)
|| !language_settings.map(|s| s.suggest.enabled).unwrap_or(true)
{
return Ok(None);
}
@ -2425,20 +2423,24 @@ impl Inner {
// completions, we will use internal logic and if there are completions
// for imports, we will return those and not send a message into tsc, where
// other completions come from.
let response = if let Some(response) = completions::get_import_completions(
&specifier,
&params.text_document_position.position,
&self.config.snapshot(),
&self.client,
&self.module_registries,
&self.npm.search_api,
&self.documents,
self.maybe_import_map.clone(),
)
.await
let mut response = None;
if language_settings
.map(|s| s.suggest.include_completions_for_import_statements)
.unwrap_or(true)
{
Some(response)
} else {
response = completions::get_import_completions(
&specifier,
&params.text_document_position.position,
&self.config.snapshot(),
&self.client,
&self.module_registries,
&self.npm.search_api,
&self.documents,
self.maybe_import_map.clone(),
)
.await;
}
if response.is_none() {
let line_index = asset_or_doc.line_index();
let (trigger_character, trigger_kind) =
if let Some(context) = &params.context {
@ -2451,7 +2453,6 @@ impl Inner {
};
let position =
line_index.offset_tsc(params.text_document_position.position)?;
let use_snippets = self.config.client_capabilities.snippet_support;
let maybe_completion_info = self
.ts_server
.get_completions(
@ -2459,38 +2460,11 @@ impl Inner {
specifier.clone(),
position,
tsc::GetCompletionsAtPositionOptions {
user_preferences: tsc::UserPreferences {
quote_preference: Some((&self.fmt_options.options).into()),
allow_incomplete_completions: Some(true),
allow_text_changes_in_new_files: Some(
specifier.scheme() == "file",
),
import_module_specifier_ending: Some(
tsc::ImportModuleSpecifierEnding::Index,
),
include_automatic_optional_chain_completions: Some(true),
include_completions_for_import_statements: Some(true),
include_completions_for_module_exports: self
.config
.workspace_settings()
.language_settings_for_specifier(&specifier)
.map(|s| s.suggest.auto_imports),
include_completions_with_object_literal_method_snippets: Some(
use_snippets,
),
include_completions_with_class_member_snippets: Some(
use_snippets,
),
include_completions_with_insert_text: Some(true),
include_completions_with_snippet_text: Some(use_snippets),
jsx_attribute_completion_style: Some(
tsc::JsxAttributeCompletionStyle::Auto,
),
provide_prefix_and_suffix_text_for_rename: Some(true),
provide_refactor_not_applicable_reason: Some(true),
use_label_details_in_completion_entries: Some(true),
..Default::default()
},
user_preferences: tsc::UserPreferences::from_config_for_specifier(
&self.config,
&self.fmt_options.options,
&specifier,
),
trigger_character,
trigger_kind,
},
@ -2499,22 +2473,21 @@ impl Inner {
.await;
if let Some(completions) = maybe_completion_info {
let results = completions.as_completion_response(
line_index,
&self
.config
.workspace_settings()
.language_settings_for_specifier(&specifier)
.cloned()
.unwrap_or_default()
.suggest,
&specifier,
position,
self,
response = Some(
completions.as_completion_response(
line_index,
&self
.config
.workspace_settings()
.language_settings_for_specifier(&specifier)
.cloned()
.unwrap_or_default()
.suggest,
&specifier,
position,
self,
),
);
Some(results)
} else {
None
}
};
self.performance.measure(mark);
@ -2536,17 +2509,22 @@ impl Inner {
})?;
if let Some(data) = &data.tsc {
let specifier = &data.specifier;
let mut args = GetCompletionDetailsArgs {
format_code_settings: Some((&self.fmt_options.options).into()),
..data.into()
};
args
.preferences
.get_or_insert(Default::default())
.quote_preference = Some((&self.fmt_options.options).into());
let result = self
.ts_server
.get_completion_details(self.snapshot(), args)
.get_completion_details(
self.snapshot(),
GetCompletionDetailsArgs {
format_code_settings: Some((&self.fmt_options.options).into()),
preferences: Some(
tsc::UserPreferences::from_config_for_specifier(
&self.config,
&self.fmt_options.options,
specifier,
),
),
..data.into()
},
)
.await;
match result {
Ok(maybe_completion_info) => {
@ -3029,15 +3007,27 @@ impl Inner {
) -> LspResult<Option<WorkspaceEdit>> {
let mut changes = vec![];
for rename in params.files {
let old_specifier = self.url_map.normalize_url(
&resolve_url(&rename.old_uri).unwrap(),
LspUrlKind::File,
);
let options = self
.config
.workspace_settings()
.language_settings_for_specifier(&old_specifier)
.map(|s| s.update_imports_on_file_move.clone())
.unwrap_or_default();
// Note that `Always` and `Prompt` are treated the same in the server, the
// client will worry about that after receiving the edits.
if options.enabled == UpdateImportsOnFileMoveEnabled::Never {
continue;
}
changes.extend(
self
.ts_server
.get_edits_for_file_rename(
self.snapshot(),
self.url_map.normalize_url(
&resolve_url(&rename.old_uri).unwrap(),
LspUrlKind::File,
),
old_specifier,
self.url_map.normalize_url(
&resolve_url(&rename.new_uri).unwrap(),
LspUrlKind::File,
@ -3300,20 +3290,19 @@ impl tower_lsp::LanguageServer for LanguageServer {
async fn did_save(&self, params: DidSaveTextDocumentParams) {
let uri = &params.text_document.uri;
let Ok(path) = specifier_to_file_path(uri) else {
return;
};
if !is_importable_ext(&path) {
return;
}
{
let inner = self.0.read().await;
let specifier = inner.url_map.normalize_url(uri, LspUrlKind::File);
if !inner.config.workspace_settings().cache_on_save
|| !inner.config.specifier_enabled(uri)
|| !inner.diagnostics_state.has_no_cache_diagnostics(uri)
|| !inner.config.specifier_enabled(&specifier)
|| !inner.diagnostics_state.has_no_cache_diagnostics(&specifier)
{
return;
}
match specifier_to_file_path(&specifier) {
Ok(path) if is_importable_ext(&path) => {}
_ => return,
}
}
if let Err(err) = self
.cache_request(Some(
@ -3677,10 +3666,12 @@ impl Inner {
let specifier = self
.url_map
.normalize_url(&params.text_document.uri, LspUrlKind::File);
let workspace_settings = self.config.workspace_settings();
if !self.is_diagnosable(&specifier)
|| !self.config.specifier_enabled(&specifier)
|| !workspace_settings.enabled_inlay_hints(&specifier)
|| !self
.config
.workspace_settings()
.enabled_inlay_hints(&specifier)
{
return Ok(None);
}
@ -3701,13 +3692,11 @@ impl Inner {
self.snapshot(),
specifier.clone(),
text_span,
tsc::UserPreferences {
quote_preference: Some((&self.fmt_options.options).into()),
..tsc::UserPreferences::from_workspace_settings_for_specifier(
workspace_settings,
&specifier,
)
},
tsc::UserPreferences::from_config_for_specifier(
&self.config,
&self.fmt_options.options,
&specifier,
),
)
.await?;
let maybe_inlay_hints = maybe_inlay_hints.map(|hints| {

View file

@ -32,10 +32,12 @@ use tower_lsp::lsp_types::WorkDoneProgressParams;
use tower_lsp::LanguageServer;
use super::client::Client;
use super::config::ClassMemberSnippets;
use super::config::CompletionSettings;
use super::config::DenoCompletionSettings;
use super::config::ImportCompletionSettings;
use super::config::LanguageWorkspaceSettings;
use super::config::ObjectLiteralMethodSnippets;
use super::config::TestingSettings;
use super::config::WorkspaceSettings;
@ -309,22 +311,36 @@ pub fn get_repl_workspace_settings() -> WorkspaceSettings {
},
testing: TestingSettings { args: vec![] },
javascript: LanguageWorkspaceSettings {
inlay_hints: Default::default(),
suggest: CompletionSettings {
complete_function_calls: false,
names: false,
paths: false,
auto_imports: false,
class_member_snippets: ClassMemberSnippets { enabled: false },
complete_function_calls: false,
enabled: true,
include_automatic_optional_chain_completions: false,
include_completions_for_import_statements: true,
names: false,
object_literal_method_snippets: ObjectLiteralMethodSnippets {
enabled: false,
},
paths: false,
},
..Default::default()
},
typescript: LanguageWorkspaceSettings {
inlay_hints: Default::default(),
suggest: CompletionSettings {
complete_function_calls: false,
names: false,
paths: false,
auto_imports: false,
class_member_snippets: ClassMemberSnippets { enabled: false },
complete_function_calls: false,
enabled: true,
include_automatic_optional_chain_completions: false,
include_completions_for_import_statements: true,
names: false,
object_literal_method_snippets: ObjectLiteralMethodSnippets {
enabled: false,
},
paths: false,
},
..Default::default()
},
}
}

View file

@ -3532,14 +3532,7 @@ impl From<&FmtOptionsConfig> for QuotePreference {
}
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "kebab-case")]
#[allow(dead_code)]
pub enum ImportModuleSpecifierPreference {
Auto,
Relative,
NonRelative,
}
pub type ImportModuleSpecifierPreference = config::ImportModuleSpecifier;
#[derive(Debug, Serialize)]
#[serde(rename_all = "kebab-case")]
@ -3581,14 +3574,7 @@ pub enum IncludePackageJsonAutoImports {
Off,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "kebab-case")]
#[allow(dead_code)]
pub enum JsxAttributeCompletionStyle {
Auto,
Braces,
None,
}
pub type JsxAttributeCompletionStyle = config::JsxAttributeCompletionStyle;
#[derive(Debug, Default, Serialize)]
#[serde(rename_all = "camelCase")]
@ -3666,35 +3652,115 @@ pub struct UserPreferences {
}
impl UserPreferences {
pub fn from_workspace_settings_for_specifier(
settings: &config::WorkspaceSettings,
pub fn from_config_for_specifier(
config: &config::Config,
fmt_config: &FmtOptionsConfig,
specifier: &ModuleSpecifier,
) -> Self {
let language_settings = settings.language_settings_for_specifier(specifier);
Self {
include_inlay_parameter_name_hints: language_settings
.map(|s| (&s.inlay_hints.parameter_names.enabled).into()),
include_inlay_parameter_name_hints_when_argument_matches_name:
language_settings.map(|s| {
!s.inlay_hints
.parameter_names
.suppress_when_argument_matches_name
}),
include_inlay_function_parameter_type_hints: language_settings
.map(|s| s.inlay_hints.parameter_types.enabled),
include_inlay_variable_type_hints: language_settings
.map(|s| s.inlay_hints.variable_types.enabled),
include_inlay_variable_type_hints_when_type_matches_name:
language_settings.map(|s| {
!s.inlay_hints.variable_types.suppress_when_type_matches_name
}),
include_inlay_property_declaration_type_hints: language_settings
.map(|s| s.inlay_hints.property_declaration_types.enabled),
include_inlay_function_like_return_type_hints: language_settings
.map(|s| s.inlay_hints.function_like_return_types.enabled),
include_inlay_enum_member_value_hints: language_settings
.map(|s| s.inlay_hints.enum_member_values.enabled),
let base_preferences = Self {
allow_incomplete_completions: Some(true),
allow_text_changes_in_new_files: Some(specifier.scheme() == "file"),
// TODO(nayeemrmn): Investigate why we use `Index` here.
import_module_specifier_ending: Some(ImportModuleSpecifierEnding::Index),
include_completions_with_snippet_text: Some(
config.client_capabilities.snippet_support,
),
provide_refactor_not_applicable_reason: Some(true),
quote_preference: Some(fmt_config.into()),
use_label_details_in_completion_entries: Some(true),
..Default::default()
};
let Some(language_settings) = config
.workspace_settings()
.language_settings_for_specifier(specifier)
else {
return base_preferences;
};
Self {
auto_import_file_exclude_patterns: Some(
language_settings
.preferences
.auto_import_file_exclude_patterns
.clone(),
),
include_automatic_optional_chain_completions: Some(
language_settings.suggest.enabled
&& language_settings
.suggest
.include_automatic_optional_chain_completions,
),
include_completions_for_import_statements: Some(
language_settings.suggest.enabled
&& language_settings
.suggest
.include_completions_for_import_statements,
),
include_completions_for_module_exports: Some(
language_settings.suggest.enabled
&& language_settings.suggest.auto_imports,
),
include_completions_with_class_member_snippets: Some(
language_settings.suggest.enabled
&& language_settings.suggest.class_member_snippets.enabled
&& config.client_capabilities.snippet_support,
),
include_completions_with_insert_text: Some(
language_settings.suggest.enabled,
),
include_completions_with_object_literal_method_snippets: Some(
language_settings.suggest.enabled
&& language_settings
.suggest
.object_literal_method_snippets
.enabled
&& config.client_capabilities.snippet_support,
),
import_module_specifier_preference: Some(
language_settings.preferences.import_module_specifier,
),
include_inlay_parameter_name_hints: Some(
(&language_settings.inlay_hints.parameter_names.enabled).into(),
),
include_inlay_parameter_name_hints_when_argument_matches_name: Some(
!language_settings
.inlay_hints
.parameter_names
.suppress_when_argument_matches_name,
),
include_inlay_function_parameter_type_hints: Some(
language_settings.inlay_hints.parameter_types.enabled,
),
include_inlay_variable_type_hints: Some(
language_settings.inlay_hints.variable_types.enabled,
),
include_inlay_variable_type_hints_when_type_matches_name: Some(
!language_settings
.inlay_hints
.variable_types
.suppress_when_type_matches_name,
),
include_inlay_property_declaration_type_hints: Some(
language_settings
.inlay_hints
.property_declaration_types
.enabled,
),
include_inlay_function_like_return_type_hints: Some(
language_settings
.inlay_hints
.function_like_return_types
.enabled,
),
include_inlay_enum_member_value_hints: Some(
language_settings.inlay_hints.enum_member_values.enabled,
),
jsx_attribute_completion_style: Some(
language_settings.preferences.jsx_attribute_completion_style,
),
provide_prefix_and_suffix_text_for_rename: Some(
language_settings.preferences.use_aliases_for_renames,
),
..base_preferences
}
}
}
@ -5149,7 +5215,7 @@ mod tests {
}
#[test]
fn include_suppress_inlay_hit_settings() {
fn include_suppress_inlay_hint_settings() {
let mut settings = WorkspaceSettings::default();
settings
.typescript
@ -5161,11 +5227,13 @@ mod tests {
.inlay_hints
.variable_types
.suppress_when_type_matches_name = true;
let user_preferences =
UserPreferences::from_workspace_settings_for_specifier(
&settings,
&ModuleSpecifier::parse("file:///foo.ts").unwrap(),
);
let mut config = config::Config::new();
config.set_workspace_settings(settings);
let user_preferences = UserPreferences::from_config_for_specifier(
&config,
&Default::default(),
&ModuleSpecifier::parse("file:///foo.ts").unwrap(),
);
assert_eq!(
user_preferences.include_inlay_variable_type_hints_when_type_matches_name,
Some(false)