[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:
Dhruv Manilawala 2025-08-07 19:16:51 +05:30 committed by GitHub
parent c401a6d86e
commit b22586fa0e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 181 additions and 20 deletions

View 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(())
}

View file

@ -28,6 +28,7 @@
//! [`await_notification`]: TestServer::await_notification
mod initialize;
mod inlay_hints;
mod publish_diagnostics;
mod pull_diagnostics;
@ -48,20 +49,21 @@ use lsp_types::notification::{
Initialized, Notification,
};
use lsp_types::request::{
DocumentDiagnosticRequest, HoverRequest, Initialize, Request, Shutdown, WorkspaceConfiguration,
WorkspaceDiagnosticRequest,
DocumentDiagnosticRequest, HoverRequest, Initialize, InlayHintRequest, Request, Shutdown,
WorkspaceConfiguration, WorkspaceDiagnosticRequest,
};
use lsp_types::{
ClientCapabilities, ConfigurationParams, DiagnosticClientCapabilities,
DidChangeTextDocumentParams, DidChangeWatchedFilesClientCapabilities,
DidChangeWatchedFilesParams, DidCloseTextDocumentParams, DidOpenTextDocumentParams,
DocumentDiagnosticParams, DocumentDiagnosticReportResult, FileEvent, Hover, HoverParams,
InitializeParams, InitializeResult, InitializedParams, NumberOrString, PartialResultParams,
Position, PreviousResultId, PublishDiagnosticsClientCapabilities,
TextDocumentClientCapabilities, TextDocumentContentChangeEvent, TextDocumentIdentifier,
TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier,
WorkDoneProgressParams, WorkspaceClientCapabilities, WorkspaceDiagnosticParams,
WorkspaceDiagnosticReportResult, WorkspaceFolder,
InitializeParams, InitializeResult, InitializedParams, InlayHint, InlayHintClientCapabilities,
InlayHintParams, NumberOrString, PartialResultParams, Position, PreviousResultId,
PublishDiagnosticsClientCapabilities, Range, TextDocumentClientCapabilities,
TextDocumentContentChangeEvent, TextDocumentIdentifier, TextDocumentItem,
TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkDoneProgressParams,
WorkspaceClientCapabilities, WorkspaceDiagnosticParams, WorkspaceDiagnosticReportResult,
WorkspaceFolder,
};
use ruff_db::system::{OsSystem, SystemPath, SystemPathBuf, TestSystem};
use rustc_hash::FxHashMap;
@ -725,6 +727,23 @@ impl TestServer {
let id = self.send_request::<HoverRequest>(params);
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 {
@ -908,6 +927,19 @@ impl TestServerBuilder {
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
#[expect(dead_code)]
pub(crate) fn enable_did_change_watched_files(mut self, enabled: bool) -> Self {