1
1
use std:: path:: Path ;
2
2
3
+ use erg_common:: set:: Set ;
3
4
use erg_common:: shared:: MappedRwLockReadGuard ;
4
5
use erg_compiler:: artifact:: BuildRunnable ;
5
6
use erg_compiler:: erg_parser:: parse:: Parsable ;
6
7
8
+ use erg_compiler:: ty:: { HasType , Type } ;
7
9
use lsp_types:: request:: { GotoTypeDefinitionParams , GotoTypeDefinitionResponse } ;
8
- use lsp_types:: { GotoDefinitionResponse , Position , Url } ;
10
+ use lsp_types:: { GotoDefinitionResponse , Location , Position , Url } ;
9
11
10
12
use crate :: server:: { ELSResult , RedirectableStdout , Server } ;
11
13
use crate :: util:: { self , NormalizedUrl } ;
@@ -21,10 +23,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
21
23
Ok ( self . get_type_def ( & uri, pos) )
22
24
}
23
25
24
- fn get_type_def ( & self , uri : & NormalizedUrl , pos : Position ) -> Option < GotoDefinitionResponse > {
25
- let visitor = self . get_visitor ( uri) ?;
26
- let tok = self . file_cache . get_symbol ( uri, pos) ?;
27
- let typ = & visitor. get_info ( & tok) ?. t ;
26
+ fn make_type_definition ( & self , uri : & NormalizedUrl , typ : & Type ) -> Option < Location > {
28
27
let path = typ. namespace ( ) ;
29
28
let module = self
30
29
. shared
@@ -34,7 +33,26 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
34
33
let ( _, typ_info) = module. context . get_type_info ( typ) ?;
35
34
let path = typ_info. def_loc . module . as_ref ( ) ?;
36
35
let def_uri = Url :: from_file_path ( path) . ok ( ) ?;
37
- let loc = lsp_types:: Location :: new ( def_uri, util:: loc_to_range ( typ_info. def_loc . loc ) ?) ;
38
- Some ( GotoDefinitionResponse :: Scalar ( loc) )
36
+ Some ( Location :: new (
37
+ def_uri,
38
+ util:: loc_to_range ( typ_info. def_loc . loc ) ?,
39
+ ) )
40
+ }
41
+
42
+ fn get_type_def ( & self , uri : & NormalizedUrl , pos : Position ) -> Option < GotoDefinitionResponse > {
43
+ let mut locs = vec ! [ ] ;
44
+ let visitor = self . get_visitor ( uri) ?;
45
+ let tok = self . file_cache . get_symbol ( uri, pos) ?;
46
+ let typ = & visitor. get_info ( & tok) ?. t ;
47
+ if let Some ( loc) = self . make_type_definition ( uri, typ) {
48
+ locs. push ( loc) ;
49
+ }
50
+ let typs = typ. inner_ts ( ) . into_iter ( ) . collect :: < Set < _ > > ( ) ;
51
+ for typ in typs {
52
+ if let Some ( loc) = self . make_type_definition ( uri, & typ) {
53
+ locs. push ( loc) ;
54
+ }
55
+ }
56
+ Some ( GotoDefinitionResponse :: Array ( locs) )
39
57
}
40
58
}
0 commit comments