refactor: Make handle_hover handle ranges too

This commit is contained in:
Alexander Gonzalez 2021-07-26 12:14:14 -04:00
parent 2b5798e927
commit 1a0a5da1a4
6 changed files with 42 additions and 84 deletions

View file

@ -423,7 +423,7 @@ impl Analysis {
self.with_db(|db| hover::hover(db, position, config)) self.with_db(|db| hover::hover(db, position, config))
} }
/// Returns a short text displaying the type for the expression. /// Returns a short text displaying the type of the expression.
pub fn hover_range( pub fn hover_range(
&self, &self,
config: &HoverConfig, config: &HoverConfig,

View file

@ -36,7 +36,10 @@ use crate::{
from_proto, from_proto,
global_state::{GlobalState, GlobalStateSnapshot}, global_state::{GlobalState, GlobalStateSnapshot},
line_index::LineEndings, line_index::LineEndings,
lsp_ext::{self, InlayHint, InlayHintsParams, ViewCrateGraphParams, WorkspaceSymbolParams}, lsp_ext::{
self, InlayHint, InlayHintsParams, PositionOrRange, ViewCrateGraphParams,
WorkspaceSymbolParams,
},
lsp_utils::all_edits_are_disjoint, lsp_utils::all_edits_are_disjoint,
to_proto, LspError, Result, to_proto, LspError, Result,
}; };
@ -867,42 +870,30 @@ pub(crate) fn handle_signature_help(
pub(crate) fn handle_hover( pub(crate) fn handle_hover(
snap: GlobalStateSnapshot, snap: GlobalStateSnapshot,
params: lsp_types::HoverParams, params: lsp_ext::HoverParams,
) -> Result<Option<lsp_ext::Hover>> { ) -> Result<Option<lsp_ext::Hover>> {
let _p = profile::span("handle_hover"); let _p = profile::span("handle_hover");
let position = from_proto::file_position(&snap, params.text_document_position_params)?;
let info = match snap.analysis.hover(&snap.config.hover(), position)? {
None => return Ok(None),
Some(info) => info,
};
let line_index = snap.file_line_index(position.file_id)?;
let range = to_proto::range(&line_index, info.range);
let hover = lsp_ext::Hover {
hover: lsp_types::Hover {
contents: HoverContents::Markup(to_proto::markup_content(info.info.markup)),
range: Some(range),
},
actions: prepare_hover_actions(&snap, &info.info.actions),
};
Ok(Some(hover))
}
pub(crate) fn handle_hover_range(
snap: GlobalStateSnapshot,
params: lsp_ext::HoverRangeParams,
) -> Result<Option<lsp_ext::Hover>> {
let _p = profile::span("handle_hover_range");
let file_id = from_proto::file_id(&snap, &params.text_document.uri)?; let file_id = from_proto::file_id(&snap, &params.text_document.uri)?;
let range = from_proto::file_range(&snap, params.text_document, params.range)?; let hover_result = match params.position {
PositionOrRange::Position(position) => {
let position = from_proto::file_position(
&snap,
lsp_types::TextDocumentPositionParams::new(params.text_document, position),
)?;
snap.analysis.hover(&snap.config.hover(), position)?
}
PositionOrRange::Range(range) => {
let range = from_proto::file_range(&snap, params.text_document, range)?;
snap.analysis.hover_range(&snap.config.hover(), range)?
}
};
let info = match snap.analysis.hover_range(&snap.config.hover(), range)? { let info = match hover_result {
None => return Ok(None), None => return Ok(None),
Some(info) => info, Some(info) => info,
}; };
let line_index = snap.file_line_index(range.file_id)?; let line_index = snap.file_line_index(file_id)?;
let range = to_proto::range(&line_index, info.range); let range = to_proto::range(&line_index, info.range);
let hover = lsp_ext::Hover { let hover = lsp_ext::Hover {
hover: lsp_types::Hover { hover: lsp_types::Hover {

View file

@ -376,24 +376,26 @@ pub struct SnippetTextEdit {
pub enum HoverRequest {} pub enum HoverRequest {}
impl Request for HoverRequest { impl Request for HoverRequest {
type Params = lsp_types::HoverParams; type Params = HoverParams;
type Result = Option<Hover>; type Result = Option<Hover>;
const METHOD: &'static str = "textDocument/hover"; const METHOD: &'static str = "textDocument/hover";
} }
pub enum HoverRangeRequest {} #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct HoverParams {
pub text_document: TextDocumentIdentifier,
pub position: PositionOrRange,
impl Request for HoverRangeRequest { #[serde(flatten)]
type Params = HoverRangeParams; pub work_done_progress_params: WorkDoneProgressParams,
type Result = Option<Hover>;
const METHOD: &'static str = "rust-analyzer/hoverRange";
} }
#[derive(Deserialize, Serialize, Debug)] #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(untagged)]
pub struct HoverRangeParams { pub enum PositionOrRange {
pub text_document: TextDocumentIdentifier, Position(lsp_types::Position),
pub range: Range, Range(lsp_types::Range),
} }
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]

View file

@ -542,7 +542,6 @@ impl GlobalState {
.on::<lsp_ext::CodeActionRequest>(handlers::handle_code_action) .on::<lsp_ext::CodeActionRequest>(handlers::handle_code_action)
.on::<lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve) .on::<lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve)
.on::<lsp_ext::HoverRequest>(handlers::handle_hover) .on::<lsp_ext::HoverRequest>(handlers::handle_hover)
.on::<lsp_ext::HoverRangeRequest>(handlers::handle_hover_range)
.on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs) .on::<lsp_ext::ExternalDocs>(handlers::handle_open_docs)
.on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml) .on::<lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml)
.on::<lsp_ext::MoveItem>(handlers::handle_move_item) .on::<lsp_ext::MoveItem>(handlers::handle_move_item)

View file

@ -57,45 +57,11 @@ export function createClient(serverPath: string, workspace: Workspace, extraEnv:
middleware: { middleware: {
async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, _next: lc.ProvideHoverSignature) { async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, _next: lc.ProvideHoverSignature) {
const editor = vscode.window.activeTextEditor; const editor = vscode.window.activeTextEditor;
const selection = editor?.selection; const positionOrRange = editor?.selection?.contains(position) ? client.code2ProtocolConverter.asRange(editor.selection) : client.code2ProtocolConverter.asPosition(position);
return selection?.contains(position) return client.sendRequest(ra.hover, {
? client textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
.sendRequest( position: positionOrRange
ra.hoverRange, }, token).then(
{
textDocument:
client.code2ProtocolConverter.asTextDocumentIdentifier(
document
),
range: client.code2ProtocolConverter.asRange(
editor?.selection
),
},
token
)
.then(
(result) =>
client.protocol2CodeConverter.asHover(result),
(error) => {
client.handleFailedRequest(
lc.HoverRequest.type,
undefined,
error,
null
);
return Promise.resolve(null);
}
)
: client
.sendRequest(
lc.HoverRequest.type,
client.code2ProtocolConverter.asTextDocumentPositionParams(
document,
position
),
token
)
.then(
(result) => { (result) => {
const hover = const hover =
client.protocol2CodeConverter.asHover(result); client.protocol2CodeConverter.asHover(result);

View file

@ -19,11 +19,11 @@ export const serverStatus = new lc.NotificationType<ServerStatusParams>("experim
export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace"); export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace");
export const hoverRange = new lc.RequestType<HoverRangeParams, lc.Hover | null, void>("rust-analyzer/hoverRange"); export const hover = new lc.RequestType<HoverParams, lc.Hover | null, void>("textDocument/hover");
export interface HoverRangeParams { export interface HoverParams extends lc.WorkDoneProgressParams{
textDocument: lc.TextDocumentIdentifier; textDocument: lc.TextDocumentIdentifier;
range: lc.Range; position: lc.Range | lc.Position;
} }
export interface SyntaxTreeParams { export interface SyntaxTreeParams {