Jeremy Kolb
2019-12-30 09:12:06 -05:00
committed by kjeremy
parent 928ecd069a
commit 1b19a8aa5e
11 changed files with 502 additions and 15 deletions

View File

@@ -1,8 +1,8 @@
//! Advertizes the capabilities of the LSP Server.
use lsp_types::{
CodeActionProviderCapability, CodeLensOptions, CompletionOptions,
DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
CallHierarchyServerCapability, CodeActionProviderCapability, CodeLensOptions,
CompletionOptions, DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
SelectionRangeProviderCapability, ServerCapabilities, SignatureHelpOptions,
TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions,
@@ -56,7 +56,7 @@ pub fn server_capabilities() -> ServerCapabilities {
color_provider: None,
execute_command_provider: None,
workspace: None,
call_hierarchy_provider: None,
call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)),
experimental: Default::default(),
}
}

View File

@@ -490,6 +490,24 @@ impl TryConvWith<&WorldSnapshot> for (FileId, RangeInfo<Vec<NavigationTarget>>)
}
}
pub fn to_call_hierarchy_item(
file_id: FileId,
range: TextRange,
world: &WorldSnapshot,
line_index: &LineIndex,
nav: NavigationTarget,
) -> Result<lsp_types::CallHierarchyItem> {
Ok(lsp_types::CallHierarchyItem {
name: nav.name().to_string(),
kind: nav.kind().conv(),
tags: None,
detail: nav.description().map(|it| it.to_string()),
uri: file_id.try_conv_with(&world)?,
range: nav.range().conv_with(&line_index),
selection_range: range.conv_with(&line_index),
})
}
pub fn to_location(
file_id: FileId,
range: TextRange,

View File

@@ -499,6 +499,9 @@ fn on_request(
.on::<req::Formatting>(handlers::handle_formatting)?
.on::<req::DocumentHighlightRequest>(handlers::handle_document_highlight)?
.on::<req::InlayHints>(handlers::handle_inlay_hints)?
.on::<req::CallHierarchyPrepare>(handlers::handle_call_hierarchy_prepare)?
.on::<req::CallHierarchyIncomingCalls>(handlers::handle_call_hierarchy_incoming)?
.on::<req::CallHierarchyOutgoingCalls>(handlers::handle_call_hierarchy_outgoing)?
.finish();
Ok(())
}

View File

@@ -5,13 +5,16 @@ use std::{fmt::Write as _, io::Write as _};
use lsp_server::ErrorCode;
use lsp_types::{
CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem,
CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams,
CodeAction, CodeActionResponse, CodeLens, Command, CompletionItem, Diagnostic,
DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams,
Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, PrepareRenameResponse,
Range, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit,
};
use ra_ide::{
AssistId, FileId, FilePosition, FileRange, Query, Runnable, RunnableKind, SearchScope,
AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind,
SearchScope,
};
use ra_prof::profile;
use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit};
@@ -21,7 +24,10 @@ use serde_json::to_value;
use crate::{
cargo_target_spec::{runnable_args, CargoTargetSpec},
conv::{to_location, Conv, ConvWith, FoldConvCtx, MapConvWith, TryConvWith, TryConvWithToVec},
conv::{
to_call_hierarchy_item, to_location, Conv, ConvWith, FoldConvCtx, MapConvWith, TryConvWith,
TryConvWithToVec,
},
req::{self, Decoration, InlayHint, InlayHintsParams, InlayKind},
world::WorldSnapshot,
LspError, Result,
@@ -936,3 +942,91 @@ pub fn handle_inlay_hints(
})
.collect())
}
pub fn handle_call_hierarchy_prepare(
world: WorldSnapshot,
params: CallHierarchyPrepareParams,
) -> Result<Option<Vec<CallHierarchyItem>>> {
let _p = profile("handle_call_hierarchy_prepare");
let position = params.text_document_position_params.try_conv_with(&world)?;
let file_id = position.file_id;
let nav_info = match world.analysis().call_hierarchy(position)? {
None => return Ok(None),
Some(it) => it,
};
let line_index = world.analysis().file_line_index(file_id)?;
let RangeInfo { range, info: navs } = nav_info;
let res = navs
.into_iter()
.filter(|it| it.kind() == SyntaxKind::FN_DEF)
.filter_map(|it| to_call_hierarchy_item(file_id, range, &world, &line_index, it).ok())
.collect();
Ok(Some(res))
}
pub fn handle_call_hierarchy_incoming(
world: WorldSnapshot,
params: CallHierarchyIncomingCallsParams,
) -> Result<Option<Vec<CallHierarchyIncomingCall>>> {
let _p = profile("handle_call_hierarchy_incoming");
let item = params.item;
let doc = TextDocumentIdentifier::new(item.uri);
let frange: FileRange = (&doc, item.range).try_conv_with(&world)?;
let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() };
let call_items = match world.analysis().incoming_calls(fpos)? {
None => return Ok(None),
Some(it) => it,
};
let mut res = vec![];
for call_item in call_items.into_iter() {
let file_id = call_item.target.file_id();
let line_index = world.analysis().file_line_index(file_id)?;
let range = call_item.target.range();
let item = to_call_hierarchy_item(file_id, range, &world, &line_index, call_item.target)?;
res.push(CallHierarchyIncomingCall {
from: item,
from_ranges: call_item.ranges.iter().map(|it| it.conv_with(&line_index)).collect(),
});
}
Ok(Some(res))
}
pub fn handle_call_hierarchy_outgoing(
world: WorldSnapshot,
params: CallHierarchyOutgoingCallsParams,
) -> Result<Option<Vec<CallHierarchyOutgoingCall>>> {
let _p = profile("handle_call_hierarchy_outgoing");
let item = params.item;
let doc = TextDocumentIdentifier::new(item.uri);
let frange: FileRange = (&doc, item.range).try_conv_with(&world)?;
let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() };
let call_items = match world.analysis().outgoing_calls(fpos)? {
None => return Ok(None),
Some(it) => it,
};
let mut res = vec![];
for call_item in call_items.into_iter() {
let file_id = call_item.target.file_id();
let line_index = world.analysis().file_line_index(file_id)?;
let range = call_item.target.range();
let item = to_call_hierarchy_item(file_id, range, &world, &line_index, call_item.target)?;
res.push(CallHierarchyOutgoingCall {
to: item,
from_ranges: call_item.ranges.iter().map(|it| it.conv_with(&line_index)).collect(),
});
}
Ok(Some(res))
}

View File

@@ -6,13 +6,15 @@ use serde::{Deserialize, Serialize};
pub use lsp_types::{
notification::*, request::*, ApplyWorkspaceEditParams, CodeActionParams, CodeLens,
CodeLensParams, CompletionParams, CompletionResponse, DidChangeConfigurationParams,
DidChangeWatchedFilesParams, DidChangeWatchedFilesRegistrationOptions,
DocumentOnTypeFormattingParams, DocumentSymbolParams, DocumentSymbolResponse,
FileSystemWatcher, Hover, InitializeResult, MessageType, ProgressParams, ProgressParamsValue,
ProgressToken, PublishDiagnosticsParams, ReferenceParams, Registration, RegistrationParams,
SelectionRange, SelectionRangeParams, ShowMessageParams, SignatureHelp, TextDocumentEdit,
TextDocumentPositionParams, TextEdit, WorkspaceEdit, WorkspaceSymbolParams,
CodeLensParams, CompletionParams, CompletionResponse, DiagnosticTag,
DidChangeConfigurationParams, DidChangeWatchedFilesParams,
DidChangeWatchedFilesRegistrationOptions, DocumentOnTypeFormattingParams, DocumentSymbolParams,
DocumentSymbolResponse, FileSystemWatcher, Hover, InitializeResult, MessageType,
PartialResultParams, ProgressParams, ProgressParamsValue, ProgressToken,
PublishDiagnosticsParams, ReferenceParams, Registration, RegistrationParams, SelectionRange,
SelectionRangeParams, ServerCapabilities, ShowMessageParams, SignatureHelp, SymbolKind,
TextDocumentEdit, TextDocumentPositionParams, TextEdit, WorkDoneProgressParams, WorkspaceEdit,
WorkspaceSymbolParams,
};
pub enum AnalyzerStatus {}