|
2 | 2 | //! and LSP types.
|
3 | 3 |
|
4 | 4 | use lsp_types::{
|
5 |
| - self, CreateFile, DiagnosticSeverity, DocumentChangeOperation, DocumentChanges, Documentation, |
6 |
| - Location, LocationLink, MarkupContent, MarkupKind, ParameterInformation, ParameterLabel, |
7 |
| - Position, Range, RenameFile, ResourceOp, SemanticTokenModifier, SemanticTokenType, |
8 |
| - SignatureInformation, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, TextDocumentItem, |
9 |
| - TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkspaceEdit, |
| 5 | + self, CreateFile, DiagnosticSeverity, DocumentChangeOperation, DocumentChanges, DocumentSymbol, |
| 6 | + Documentation, Location, LocationLink, MarkupContent, MarkupKind, ParameterInformation, |
| 7 | + ParameterLabel, Position, Range, RenameFile, ResourceOp, SemanticTokenModifier, |
| 8 | + SemanticTokenType, SignatureInformation, SymbolInformation, SymbolKind, TextDocumentEdit, |
| 9 | + TextDocumentIdentifier, TextDocumentItem, TextDocumentPositionParams, Url, |
| 10 | + VersionedTextDocumentIdentifier, WorkspaceEdit, |
10 | 11 | };
|
11 | 12 | use ra_ide::{
|
12 | 13 | translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition,
|
13 | 14 | FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag,
|
14 | 15 | InlayHint, InlayKind, InsertTextFormat, LineCol, LineIndex, NavigationTarget, RangeInfo,
|
15 |
| - ReferenceAccess, Severity, SourceChange, SourceFileEdit, |
| 16 | + ReferenceAccess, Severity, SourceChange, SourceFileEdit, StructureNode, |
16 | 17 | };
|
17 | 18 | use ra_syntax::{SyntaxKind, TextRange, TextUnit};
|
18 | 19 | use ra_text_edit::{AtomTextEdit, TextEdit};
|
@@ -325,6 +326,75 @@ impl ConvWith<&FoldConvCtx<'_>> for Fold {
|
325 | 326 | }
|
326 | 327 | }
|
327 | 328 |
|
| 329 | +impl ConvWith<(&FileId, &WorldSnapshot, &LineIndex)> for Vec<StructureNode> { |
| 330 | + type Output = lsp_types::DocumentSymbolResponse; |
| 331 | + |
| 332 | + fn conv_with(self, ctx: (&FileId, &WorldSnapshot, &LineIndex)) -> Self::Output { |
| 333 | + let file_id = ctx.0; |
| 334 | + let world = ctx.1; |
| 335 | + let line_index = ctx.2; |
| 336 | + let supports_hierarchy = world.config.client_caps.hierarchical_symbols; |
| 337 | + |
| 338 | + if supports_hierarchy { |
| 339 | + let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); |
| 340 | + |
| 341 | + for symbol in self.into_iter() { |
| 342 | + let doc_symbol = DocumentSymbol { |
| 343 | + name: symbol.label, |
| 344 | + detail: symbol.detail, |
| 345 | + kind: symbol.kind.conv(), |
| 346 | + deprecated: Some(symbol.deprecated), |
| 347 | + range: symbol.node_range.conv_with(line_index), |
| 348 | + selection_range: symbol.navigation_range.conv_with(line_index), |
| 349 | + children: None, |
| 350 | + }; |
| 351 | + parents.push((doc_symbol, symbol.parent)); |
| 352 | + } |
| 353 | + let mut res = Vec::new(); |
| 354 | + while let Some((node, parent)) = parents.pop() { |
| 355 | + match parent { |
| 356 | + None => res.push(node), |
| 357 | + Some(i) => { |
| 358 | + let children = &mut parents[i].0.children; |
| 359 | + if children.is_none() { |
| 360 | + *children = Some(Vec::new()); |
| 361 | + } |
| 362 | + children.as_mut().unwrap().push(node); |
| 363 | + } |
| 364 | + } |
| 365 | + } |
| 366 | + res.into() |
| 367 | + } else { |
| 368 | + let mut parents: Vec<(SymbolInformation, Option<usize>)> = Vec::new(); |
| 369 | + for symbol in self.into_iter() { |
| 370 | + parents.push(( |
| 371 | + SymbolInformation { |
| 372 | + name: symbol.label, |
| 373 | + kind: symbol.kind.conv(), |
| 374 | + deprecated: Some(symbol.deprecated), |
| 375 | + location: to_location(*file_id, symbol.navigation_range, world, line_index) |
| 376 | + .unwrap(), |
| 377 | + container_name: None, |
| 378 | + }, |
| 379 | + symbol.parent, |
| 380 | + )) |
| 381 | + } |
| 382 | + let mut res = Vec::new(); |
| 383 | + while let Some((mut node, parent)) = parents.pop() { |
| 384 | + match parent { |
| 385 | + None => res.push(node), |
| 386 | + Some(i) => { |
| 387 | + node.container_name = Some(parents[i].0.name.clone()); |
| 388 | + res.push(node) |
| 389 | + } |
| 390 | + } |
| 391 | + } |
| 392 | + |
| 393 | + res.into() |
| 394 | + } |
| 395 | + } |
| 396 | +} |
| 397 | + |
328 | 398 | impl ConvWith<&LineIndex> for InlayHint {
|
329 | 399 | type Output = req::InlayHint;
|
330 | 400 | fn conv_with(self, line_index: &LineIndex) -> Self::Output {
|
|
0 commit comments