mirror of
				https://github.com/astral-sh/ruff.git
				synced 2025-11-03 21:24:29 +00:00 
			
		
		
		
	[ty] Add ty.inlayHints.variableTypes server option (#19780)
				
					
				
			## Summary This PR adds a new `ty.inlayHints.variableTypes` server setting to configure ty to include / exclude inlay hints at variable position. Currently, we only support inlay hints at this position so this option basically translates to enabling / disabling inlay hints for now :) The VS Code extension PR is https://github.com/astral-sh/ty-vscode/pull/112. closes: astral-sh/ty#472 ## Test Plan Add E2E tests.
This commit is contained in:
		
							parent
							
								
									c401a6d86e
								
							
						
					
					
						commit
						b22586fa0e
					
				
					 8 changed files with 181 additions and 20 deletions
				
			
		| 
						 | 
					@ -51,8 +51,13 @@ impl fmt::Display for DisplayInlayHint<'_, '_> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn inlay_hints(db: &dyn Db, file: File, range: TextRange) -> Vec<InlayHint<'_>> {
 | 
					pub fn inlay_hints<'db>(
 | 
				
			||||||
    let mut visitor = InlayHintVisitor::new(db, file, range);
 | 
					    db: &'db dyn Db,
 | 
				
			||||||
 | 
					    file: File,
 | 
				
			||||||
 | 
					    range: TextRange,
 | 
				
			||||||
 | 
					    settings: &InlayHintSettings,
 | 
				
			||||||
 | 
					) -> Vec<InlayHint<'db>> {
 | 
				
			||||||
 | 
					    let mut visitor = InlayHintVisitor::new(db, file, range, settings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let ast = parsed_module(db, file).load(db);
 | 
					    let ast = parsed_module(db, file).load(db);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,20 +66,34 @@ pub fn inlay_hints(db: &dyn Db, file: File, range: TextRange) -> Vec<InlayHint<'
 | 
				
			||||||
    visitor.hints
 | 
					    visitor.hints
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct InlayHintVisitor<'db> {
 | 
					/// Settings to control the behavior of inlay hints.
 | 
				
			||||||
 | 
					#[derive(Clone, Default, Debug)]
 | 
				
			||||||
 | 
					pub struct InlayHintSettings {
 | 
				
			||||||
 | 
					    /// Whether to show variable type hints.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// For example, this would enable / disable hints like the ones quoted below:
 | 
				
			||||||
 | 
					    /// ```python
 | 
				
			||||||
 | 
					    /// x": Literal[1]" = 1
 | 
				
			||||||
 | 
					    /// ```
 | 
				
			||||||
 | 
					    pub variable_types: bool,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct InlayHintVisitor<'a, 'db> {
 | 
				
			||||||
    model: SemanticModel<'db>,
 | 
					    model: SemanticModel<'db>,
 | 
				
			||||||
    hints: Vec<InlayHint<'db>>,
 | 
					    hints: Vec<InlayHint<'db>>,
 | 
				
			||||||
    in_assignment: bool,
 | 
					    in_assignment: bool,
 | 
				
			||||||
    range: TextRange,
 | 
					    range: TextRange,
 | 
				
			||||||
 | 
					    settings: &'a InlayHintSettings,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'db> InlayHintVisitor<'db> {
 | 
					impl<'a, 'db> InlayHintVisitor<'a, 'db> {
 | 
				
			||||||
    fn new(db: &'db dyn Db, file: File, range: TextRange) -> Self {
 | 
					    fn new(db: &'db dyn Db, file: File, range: TextRange, settings: &'a InlayHintSettings) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            model: SemanticModel::new(db, file),
 | 
					            model: SemanticModel::new(db, file),
 | 
				
			||||||
            hints: Vec::new(),
 | 
					            hints: Vec::new(),
 | 
				
			||||||
            in_assignment: false,
 | 
					            in_assignment: false,
 | 
				
			||||||
            range,
 | 
					            range,
 | 
				
			||||||
 | 
					            settings,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,7 +105,7 @@ impl<'db> InlayHintVisitor<'db> {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl SourceOrderVisitor<'_> for InlayHintVisitor<'_> {
 | 
					impl SourceOrderVisitor<'_> for InlayHintVisitor<'_, '_> {
 | 
				
			||||||
    fn enter_node(&mut self, node: AnyNodeRef<'_>) -> TraversalSignal {
 | 
					    fn enter_node(&mut self, node: AnyNodeRef<'_>) -> TraversalSignal {
 | 
				
			||||||
        if self.range.intersect(node.range()).is_some() {
 | 
					        if self.range.intersect(node.range()).is_some() {
 | 
				
			||||||
            TraversalSignal::Traverse
 | 
					            TraversalSignal::Traverse
 | 
				
			||||||
| 
						 | 
					@ -104,6 +123,10 @@ impl SourceOrderVisitor<'_> for InlayHintVisitor<'_> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        match stmt {
 | 
					        match stmt {
 | 
				
			||||||
            Stmt::Assign(assign) => {
 | 
					            Stmt::Assign(assign) => {
 | 
				
			||||||
 | 
					                if !self.settings.variable_types {
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                self.in_assignment = true;
 | 
					                self.in_assignment = true;
 | 
				
			||||||
                for target in &assign.targets {
 | 
					                for target in &assign.targets {
 | 
				
			||||||
                    self.visit_expr(target);
 | 
					                    self.visit_expr(target);
 | 
				
			||||||
| 
						 | 
					@ -213,8 +236,21 @@ mod tests {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    impl InlayHintTest {
 | 
					    impl InlayHintTest {
 | 
				
			||||||
 | 
					        /// Returns the inlay hints for the given test case.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// All inlay hints are generated using the applicable settings. Use
 | 
				
			||||||
 | 
					        /// [`inlay_hints_with_settings`] to generate hints with custom settings.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// [`inlay_hints_with_settings`]: Self::inlay_hints_with_settings
 | 
				
			||||||
        fn inlay_hints(&self) -> String {
 | 
					        fn inlay_hints(&self) -> String {
 | 
				
			||||||
            let hints = inlay_hints(&self.db, self.file, self.range);
 | 
					            self.inlay_hints_with_settings(&InlayHintSettings {
 | 
				
			||||||
 | 
					                variable_types: true,
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Returns the inlay hints for the given test case with custom settings.
 | 
				
			||||||
 | 
					        fn inlay_hints_with_settings(&self, settings: &InlayHintSettings) -> String {
 | 
				
			||||||
 | 
					            let hints = inlay_hints(&self.db, self.file, self.range, settings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let mut buf = source_text(&self.db, self.file).as_str().to_string();
 | 
					            let mut buf = source_text(&self.db, self.file).as_str().to_string();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -276,4 +312,18 @@ mod tests {
 | 
				
			||||||
        y = 2
 | 
					        y = 2
 | 
				
			||||||
        ");
 | 
					        ");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn disabled_variable_types() {
 | 
				
			||||||
 | 
					        let test = inlay_hint_test("x = 1");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert_snapshot!(
 | 
				
			||||||
 | 
					            test.inlay_hints_with_settings(&InlayHintSettings {
 | 
				
			||||||
 | 
					                variable_types: false,
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					            @r"
 | 
				
			||||||
 | 
					        x = 1
 | 
				
			||||||
 | 
					        "
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,7 @@ pub use document_symbols::{document_symbols, document_symbols_with_options};
 | 
				
			||||||
pub use goto::{goto_declaration, goto_definition, goto_type_definition};
 | 
					pub use goto::{goto_declaration, goto_definition, goto_type_definition};
 | 
				
			||||||
pub use goto_references::goto_references;
 | 
					pub use goto_references::goto_references;
 | 
				
			||||||
pub use hover::hover;
 | 
					pub use hover::hover;
 | 
				
			||||||
pub use inlay_hints::inlay_hints;
 | 
					pub use inlay_hints::{InlayHintSettings, inlay_hints};
 | 
				
			||||||
pub use markup::MarkupKind;
 | 
					pub use markup::MarkupKind;
 | 
				
			||||||
pub use references::ReferencesMode;
 | 
					pub use references::ReferencesMode;
 | 
				
			||||||
pub use rename::{can_rename, rename};
 | 
					pub use rename::{can_rename, rename};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,7 +47,7 @@ impl BackgroundDocumentRequestHandler for InlayHintRequestHandler {
 | 
				
			||||||
            .range
 | 
					            .range
 | 
				
			||||||
            .to_text_range(&source, &index, snapshot.encoding());
 | 
					            .to_text_range(&source, &index, snapshot.encoding());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let inlay_hints = inlay_hints(db, file, range);
 | 
					        let inlay_hints = inlay_hints(db, file, range, snapshot.workspace_settings().inlay_hints());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let inlay_hints = inlay_hints
 | 
					        let inlay_hints = inlay_hints
 | 
				
			||||||
            .into_iter()
 | 
					            .into_iter()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
 | 
				
			||||||
use serde_json::Value;
 | 
					use serde_json::Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use ty_combine::Combine;
 | 
					use ty_combine::Combine;
 | 
				
			||||||
 | 
					use ty_ide::InlayHintSettings;
 | 
				
			||||||
use ty_project::metadata::Options as TyOptions;
 | 
					use ty_project::metadata::Options as TyOptions;
 | 
				
			||||||
use ty_project::metadata::options::ProjectOptionsOverrides;
 | 
					use ty_project::metadata::options::ProjectOptionsOverrides;
 | 
				
			||||||
use ty_project::metadata::value::{RangedValue, RelativePathBuf};
 | 
					use ty_project::metadata::value::{RangedValue, RelativePathBuf};
 | 
				
			||||||
| 
						 | 
					@ -106,6 +107,15 @@ impl ClientOptions {
 | 
				
			||||||
        self
 | 
					        self
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[must_use]
 | 
				
			||||||
 | 
					    pub fn with_variable_types_inlay_hints(mut self, variable_types: bool) -> Self {
 | 
				
			||||||
 | 
					        self.workspace
 | 
				
			||||||
 | 
					            .inlay_hints
 | 
				
			||||||
 | 
					            .get_or_insert_default()
 | 
				
			||||||
 | 
					            .variable_types = Some(variable_types);
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[must_use]
 | 
					    #[must_use]
 | 
				
			||||||
    pub fn with_experimental_rename(mut self, enabled: bool) -> Self {
 | 
					    pub fn with_experimental_rename(mut self, enabled: bool) -> Self {
 | 
				
			||||||
        self.global.experimental.get_or_insert_default().rename = Some(enabled);
 | 
					        self.global.experimental.get_or_insert_default().rename = Some(enabled);
 | 
				
			||||||
| 
						 | 
					@ -138,7 +148,7 @@ impl GlobalOptions {
 | 
				
			||||||
        let experimental = self
 | 
					        let experimental = self
 | 
				
			||||||
            .experimental
 | 
					            .experimental
 | 
				
			||||||
            .map(|experimental| ExperimentalSettings {
 | 
					            .map(|experimental| ExperimentalSettings {
 | 
				
			||||||
                rename: experimental.rename.unwrap_or_default(),
 | 
					                rename: experimental.rename.unwrap_or(true),
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
            .unwrap_or_default();
 | 
					            .unwrap_or_default();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -158,6 +168,9 @@ pub(crate) struct WorkspaceOptions {
 | 
				
			||||||
    /// Whether to disable language services like code completions, hover, etc.
 | 
					    /// Whether to disable language services like code completions, hover, etc.
 | 
				
			||||||
    disable_language_services: Option<bool>,
 | 
					    disable_language_services: Option<bool>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Options to configure inlay hints.
 | 
				
			||||||
 | 
					    inlay_hints: Option<InlayHintOptions>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Information about the currently active Python environment in the VS Code Python extension.
 | 
					    /// Information about the currently active Python environment in the VS Code Python extension.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// This is relevant only for VS Code and is populated by the ty VS Code extension.
 | 
					    /// This is relevant only for VS Code and is populated by the ty VS Code extension.
 | 
				
			||||||
| 
						 | 
					@ -211,11 +224,29 @@ impl WorkspaceOptions {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        WorkspaceSettings {
 | 
					        WorkspaceSettings {
 | 
				
			||||||
            disable_language_services: self.disable_language_services.unwrap_or_default(),
 | 
					            disable_language_services: self.disable_language_services.unwrap_or_default(),
 | 
				
			||||||
 | 
					            inlay_hints: self
 | 
				
			||||||
 | 
					                .inlay_hints
 | 
				
			||||||
 | 
					                .map(InlayHintOptions::into_settings)
 | 
				
			||||||
 | 
					                .unwrap_or_default(),
 | 
				
			||||||
            overrides,
 | 
					            overrides,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone, Combine, Debug, Serialize, Deserialize, Default)]
 | 
				
			||||||
 | 
					#[serde(rename_all = "camelCase")]
 | 
				
			||||||
 | 
					struct InlayHintOptions {
 | 
				
			||||||
 | 
					    variable_types: Option<bool>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl InlayHintOptions {
 | 
				
			||||||
 | 
					    fn into_settings(self) -> InlayHintSettings {
 | 
				
			||||||
 | 
					        InlayHintSettings {
 | 
				
			||||||
 | 
					            variable_types: self.variable_types.unwrap_or_default(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Diagnostic mode for the language server.
 | 
					/// Diagnostic mode for the language server.
 | 
				
			||||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
 | 
					#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
 | 
				
			||||||
#[serde(rename_all = "camelCase")]
 | 
					#[serde(rename_all = "camelCase")]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
use super::options::DiagnosticMode;
 | 
					use super::options::DiagnosticMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use ty_ide::InlayHintSettings;
 | 
				
			||||||
use ty_project::metadata::options::ProjectOptionsOverrides;
 | 
					use ty_project::metadata::options::ProjectOptionsOverrides;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Resolved client settings that are shared across all workspaces.
 | 
					/// Resolved client settings that are shared across all workspaces.
 | 
				
			||||||
| 
						 | 
					@ -33,6 +34,7 @@ pub(crate) struct ExperimentalSettings {
 | 
				
			||||||
#[derive(Clone, Default, Debug)]
 | 
					#[derive(Clone, Default, Debug)]
 | 
				
			||||||
pub(crate) struct WorkspaceSettings {
 | 
					pub(crate) struct WorkspaceSettings {
 | 
				
			||||||
    pub(super) disable_language_services: bool,
 | 
					    pub(super) disable_language_services: bool,
 | 
				
			||||||
 | 
					    pub(super) inlay_hints: InlayHintSettings,
 | 
				
			||||||
    pub(super) overrides: Option<ProjectOptionsOverrides>,
 | 
					    pub(super) overrides: Option<ProjectOptionsOverrides>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,4 +46,8 @@ impl WorkspaceSettings {
 | 
				
			||||||
    pub(crate) fn project_options_overrides(&self) -> Option<&ProjectOptionsOverrides> {
 | 
					    pub(crate) fn project_options_overrides(&self) -> Option<&ProjectOptionsOverrides> {
 | 
				
			||||||
        self.overrides.as_ref()
 | 
					        self.overrides.as_ref()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub(crate) fn inlay_hints(&self) -> &InlayHintSettings {
 | 
				
			||||||
 | 
					        &self.inlay_hints
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										38
									
								
								crates/ty_server/tests/e2e/inlay_hints.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								crates/ty_server/tests/e2e/inlay_hints.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					use anyhow::Result;
 | 
				
			||||||
 | 
					use lsp_types::{Position, Range, notification::PublishDiagnostics};
 | 
				
			||||||
 | 
					use ruff_db::system::SystemPath;
 | 
				
			||||||
 | 
					use ty_server::ClientOptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::TestServerBuilder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Tests that disabling variable types inlay hints works correctly.
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn variable_inlay_hints_disabled() -> Result<()> {
 | 
				
			||||||
 | 
					    let workspace_root = SystemPath::new("src");
 | 
				
			||||||
 | 
					    let foo = SystemPath::new("src/foo.py");
 | 
				
			||||||
 | 
					    let foo_content = "x = 1";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut server = TestServerBuilder::new()?
 | 
				
			||||||
 | 
					        .with_initialization_options(
 | 
				
			||||||
 | 
					            ClientOptions::default().with_variable_types_inlay_hints(false),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .with_workspace(workspace_root, None)?
 | 
				
			||||||
 | 
					        .with_file(foo, foo_content)?
 | 
				
			||||||
 | 
					        .enable_inlay_hints(true)
 | 
				
			||||||
 | 
					        .build()?
 | 
				
			||||||
 | 
					        .wait_until_workspaces_are_initialized()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    server.open_text_document(foo, &foo_content, 1);
 | 
				
			||||||
 | 
					    let _ = server.await_notification::<PublishDiagnostics>()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let hints = server
 | 
				
			||||||
 | 
					        .inlay_hints_request(foo, Range::new(Position::new(0, 0), Position::new(0, 5)))?
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert!(
 | 
				
			||||||
 | 
					        hints.is_empty(),
 | 
				
			||||||
 | 
					        "Expected no inlay hints, but found: {hints:?}"
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,7 @@
 | 
				
			||||||
//! [`await_notification`]: TestServer::await_notification
 | 
					//! [`await_notification`]: TestServer::await_notification
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod initialize;
 | 
					mod initialize;
 | 
				
			||||||
 | 
					mod inlay_hints;
 | 
				
			||||||
mod publish_diagnostics;
 | 
					mod publish_diagnostics;
 | 
				
			||||||
mod pull_diagnostics;
 | 
					mod pull_diagnostics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,20 +49,21 @@ use lsp_types::notification::{
 | 
				
			||||||
    Initialized, Notification,
 | 
					    Initialized, Notification,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use lsp_types::request::{
 | 
					use lsp_types::request::{
 | 
				
			||||||
    DocumentDiagnosticRequest, HoverRequest, Initialize, Request, Shutdown, WorkspaceConfiguration,
 | 
					    DocumentDiagnosticRequest, HoverRequest, Initialize, InlayHintRequest, Request, Shutdown,
 | 
				
			||||||
    WorkspaceDiagnosticRequest,
 | 
					    WorkspaceConfiguration, WorkspaceDiagnosticRequest,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use lsp_types::{
 | 
					use lsp_types::{
 | 
				
			||||||
    ClientCapabilities, ConfigurationParams, DiagnosticClientCapabilities,
 | 
					    ClientCapabilities, ConfigurationParams, DiagnosticClientCapabilities,
 | 
				
			||||||
    DidChangeTextDocumentParams, DidChangeWatchedFilesClientCapabilities,
 | 
					    DidChangeTextDocumentParams, DidChangeWatchedFilesClientCapabilities,
 | 
				
			||||||
    DidChangeWatchedFilesParams, DidCloseTextDocumentParams, DidOpenTextDocumentParams,
 | 
					    DidChangeWatchedFilesParams, DidCloseTextDocumentParams, DidOpenTextDocumentParams,
 | 
				
			||||||
    DocumentDiagnosticParams, DocumentDiagnosticReportResult, FileEvent, Hover, HoverParams,
 | 
					    DocumentDiagnosticParams, DocumentDiagnosticReportResult, FileEvent, Hover, HoverParams,
 | 
				
			||||||
    InitializeParams, InitializeResult, InitializedParams, NumberOrString, PartialResultParams,
 | 
					    InitializeParams, InitializeResult, InitializedParams, InlayHint, InlayHintClientCapabilities,
 | 
				
			||||||
    Position, PreviousResultId, PublishDiagnosticsClientCapabilities,
 | 
					    InlayHintParams, NumberOrString, PartialResultParams, Position, PreviousResultId,
 | 
				
			||||||
    TextDocumentClientCapabilities, TextDocumentContentChangeEvent, TextDocumentIdentifier,
 | 
					    PublishDiagnosticsClientCapabilities, Range, TextDocumentClientCapabilities,
 | 
				
			||||||
    TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier,
 | 
					    TextDocumentContentChangeEvent, TextDocumentIdentifier, TextDocumentItem,
 | 
				
			||||||
    WorkDoneProgressParams, WorkspaceClientCapabilities, WorkspaceDiagnosticParams,
 | 
					    TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkDoneProgressParams,
 | 
				
			||||||
    WorkspaceDiagnosticReportResult, WorkspaceFolder,
 | 
					    WorkspaceClientCapabilities, WorkspaceDiagnosticParams, WorkspaceDiagnosticReportResult,
 | 
				
			||||||
 | 
					    WorkspaceFolder,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use ruff_db::system::{OsSystem, SystemPath, SystemPathBuf, TestSystem};
 | 
					use ruff_db::system::{OsSystem, SystemPath, SystemPathBuf, TestSystem};
 | 
				
			||||||
use rustc_hash::FxHashMap;
 | 
					use rustc_hash::FxHashMap;
 | 
				
			||||||
| 
						 | 
					@ -725,6 +727,23 @@ impl TestServer {
 | 
				
			||||||
        let id = self.send_request::<HoverRequest>(params);
 | 
					        let id = self.send_request::<HoverRequest>(params);
 | 
				
			||||||
        self.await_response::<HoverRequest>(&id)
 | 
					        self.await_response::<HoverRequest>(&id)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Sends a `textDocument/inlayHint` request for the document at the given path and range.
 | 
				
			||||||
 | 
					    pub(crate) fn inlay_hints_request(
 | 
				
			||||||
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        path: impl AsRef<SystemPath>,
 | 
				
			||||||
 | 
					        range: Range,
 | 
				
			||||||
 | 
					    ) -> Result<Option<Vec<InlayHint>>> {
 | 
				
			||||||
 | 
					        let params = InlayHintParams {
 | 
				
			||||||
 | 
					            text_document: TextDocumentIdentifier {
 | 
				
			||||||
 | 
					                uri: self.file_uri(path),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            range,
 | 
				
			||||||
 | 
					            work_done_progress_params: WorkDoneProgressParams::default(),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        let id = self.send_request::<InlayHintRequest>(params);
 | 
				
			||||||
 | 
					        self.await_response::<InlayHintRequest>(&id)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl fmt::Debug for TestServer {
 | 
					impl fmt::Debug for TestServer {
 | 
				
			||||||
| 
						 | 
					@ -908,6 +927,19 @@ impl TestServerBuilder {
 | 
				
			||||||
        self
 | 
					        self
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Enable or disable inlay hints capability
 | 
				
			||||||
 | 
					    pub(crate) fn enable_inlay_hints(mut self, enabled: bool) -> Self {
 | 
				
			||||||
 | 
					        self.client_capabilities
 | 
				
			||||||
 | 
					            .text_document
 | 
				
			||||||
 | 
					            .get_or_insert_default()
 | 
				
			||||||
 | 
					            .inlay_hint = if enabled {
 | 
				
			||||||
 | 
					            Some(InlayHintClientCapabilities::default())
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            None
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Enable or disable file watching capability
 | 
					    /// Enable or disable file watching capability
 | 
				
			||||||
    #[expect(dead_code)]
 | 
					    #[expect(dead_code)]
 | 
				
			||||||
    pub(crate) fn enable_did_change_watched_files(mut self, enabled: bool) -> Self {
 | 
					    pub(crate) fn enable_did_change_watched_files(mut self, enabled: bool) -> Self {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,8 +16,8 @@ use ruff_python_formatter::formatted_file;
 | 
				
			||||||
use ruff_source_file::{LineIndex, OneIndexed, SourceLocation};
 | 
					use ruff_source_file::{LineIndex, OneIndexed, SourceLocation};
 | 
				
			||||||
use ruff_text_size::{Ranged, TextSize};
 | 
					use ruff_text_size::{Ranged, TextSize};
 | 
				
			||||||
use ty_ide::{
 | 
					use ty_ide::{
 | 
				
			||||||
    MarkupKind, RangedValue, document_highlights, goto_declaration, goto_definition,
 | 
					    InlayHintSettings, MarkupKind, RangedValue, document_highlights, goto_declaration,
 | 
				
			||||||
    goto_references, goto_type_definition, hover, inlay_hints,
 | 
					    goto_definition, goto_references, goto_type_definition, hover, inlay_hints,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use ty_ide::{NavigationTargets, signature_help};
 | 
					use ty_ide::{NavigationTargets, signature_help};
 | 
				
			||||||
use ty_project::metadata::options::Options;
 | 
					use ty_project::metadata::options::Options;
 | 
				
			||||||
| 
						 | 
					@ -435,6 +435,10 @@ impl Workspace {
 | 
				
			||||||
            &self.db,
 | 
					            &self.db,
 | 
				
			||||||
            file_id.file,
 | 
					            file_id.file,
 | 
				
			||||||
            range.to_text_range(&index, &source, self.position_encoding)?,
 | 
					            range.to_text_range(&index, &source, self.position_encoding)?,
 | 
				
			||||||
 | 
					            // TODO: Provide a way to configure this
 | 
				
			||||||
 | 
					            &InlayHintSettings {
 | 
				
			||||||
 | 
					                variable_types: true,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(result
 | 
					        Ok(result
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue