3
3
//! `ide` crate.
4
4
5
5
use std:: {
6
+ convert:: TryFrom ,
6
7
io:: Write as _,
7
8
process:: { self , Stdio } ,
8
9
} ;
@@ -20,15 +21,17 @@ use lsp_types::{
20
21
CallHierarchyIncomingCall , CallHierarchyIncomingCallsParams , CallHierarchyItem ,
21
22
CallHierarchyOutgoingCall , CallHierarchyOutgoingCallsParams , CallHierarchyPrepareParams ,
22
23
CodeLens , CompletionItem , Diagnostic , DiagnosticTag , DocumentFormattingParams , FoldingRange ,
23
- FoldingRangeParams , HoverContents , Location , NumberOrString , Position , PrepareRenameResponse ,
24
- Range , RenameParams , SemanticTokensDeltaParams , SemanticTokensFullDeltaResult ,
25
- SemanticTokensParams , SemanticTokensRangeParams , SemanticTokensRangeResult ,
26
- SemanticTokensResult , SymbolInformation , SymbolTag , TextDocumentIdentifier , Url , WorkspaceEdit ,
24
+ FoldingRangeParams , HoverContents , Location , LocationLink , NumberOrString , Position ,
25
+ PrepareRenameResponse , Range , RenameParams , SemanticTokensDeltaParams ,
26
+ SemanticTokensFullDeltaResult , SemanticTokensParams , SemanticTokensRangeParams ,
27
+ SemanticTokensRangeResult , SemanticTokensResult , SymbolInformation , SymbolTag ,
28
+ TextDocumentIdentifier , Url , WorkspaceEdit ,
27
29
} ;
28
- use project_model:: TargetKind ;
30
+ use project_model:: { ManifestPath , ProjectWorkspace , TargetKind } ;
29
31
use serde_json:: json;
30
32
use stdx:: { format_to, never} ;
31
33
use syntax:: { algo, ast, AstNode , TextRange , TextSize , T } ;
34
+ use vfs:: AbsPathBuf ;
32
35
33
36
use crate :: {
34
37
cargo_target_spec:: CargoTargetSpec ,
@@ -601,6 +604,62 @@ pub(crate) fn handle_parent_module(
601
604
params : lsp_types:: TextDocumentPositionParams ,
602
605
) -> Result < Option < lsp_types:: GotoDefinitionResponse > > {
603
606
let _p = profile:: span ( "handle_parent_module" ) ;
607
+ if let Ok ( file_path) = & params. text_document . uri . to_file_path ( ) {
608
+ if file_path. file_name ( ) . unwrap_or_default ( ) == "Cargo.toml" {
609
+ // search workspaces for parent packages or fallback to workspace root
610
+ let abs_path_buf = match AbsPathBuf :: try_from ( file_path. to_path_buf ( ) ) . ok ( ) {
611
+ Some ( abs_path_buf) => abs_path_buf,
612
+ None => return Ok ( None ) ,
613
+ } ;
614
+
615
+ let manifest_path = match ManifestPath :: try_from ( abs_path_buf) . ok ( ) {
616
+ Some ( manifest_path) => manifest_path,
617
+ None => return Ok ( None ) ,
618
+ } ;
619
+
620
+ let links: Vec < LocationLink > = snap
621
+ . workspaces
622
+ . iter ( )
623
+ . filter_map ( |ws| match ws {
624
+ ProjectWorkspace :: Cargo { cargo, .. } => cargo. parent_manifests ( & manifest_path) ,
625
+ _ => None ,
626
+ } )
627
+ . flatten ( )
628
+ . map ( |parent_manifest_path| LocationLink {
629
+ origin_selection_range : None ,
630
+ target_uri : to_proto:: url_from_abs_path ( & parent_manifest_path) ,
631
+ target_range : Range :: default ( ) ,
632
+ target_selection_range : Range :: default ( ) ,
633
+ } )
634
+ . collect :: < _ > ( ) ;
635
+ return Ok ( Some ( links. into ( ) ) ) ;
636
+ }
637
+
638
+ // check if invoked at the crate root
639
+ let file_id = from_proto:: file_id ( & snap, & params. text_document . uri ) ?;
640
+ let crate_id = match snap. analysis . crate_for ( file_id) ?. first ( ) {
641
+ Some ( & crate_id) => crate_id,
642
+ None => return Ok ( None ) ,
643
+ } ;
644
+ let cargo_spec = match CargoTargetSpec :: for_file ( & snap, file_id) ? {
645
+ Some ( it) => it,
646
+ None => return Ok ( None ) ,
647
+ } ;
648
+
649
+ if snap. analysis . crate_root ( crate_id) ? == file_id {
650
+ let cargo_toml_url = to_proto:: url_from_abs_path ( & cargo_spec. cargo_toml ) ;
651
+ let res = vec ! [ LocationLink {
652
+ origin_selection_range: None ,
653
+ target_uri: cargo_toml_url,
654
+ target_range: Range :: default ( ) ,
655
+ target_selection_range: Range :: default ( ) ,
656
+ } ]
657
+ . into ( ) ;
658
+ return Ok ( Some ( res) ) ;
659
+ }
660
+ }
661
+
662
+ // locate parent module by semantics
604
663
let position = from_proto:: file_position ( & snap, params) ?;
605
664
let navs = snap. analysis . parent_module ( position) ?;
606
665
let res = to_proto:: goto_definition_response ( & snap, None , navs) ?;
0 commit comments