@@ -26,6 +26,7 @@ use lsp_types::CompletionItem;
2626use lsp_types:: CompletionItemKind ;
2727use lsp_types:: Diagnostic ;
2828use lsp_types:: DiagnosticSeverity ;
29+ use lsp_types:: DocumentSymbol ;
2930use lsp_types:: GotoDefinitionResponse ;
3031use lsp_types:: Hover ;
3132use lsp_types:: HoverContents ;
@@ -35,6 +36,7 @@ use lsp_types::InsertTextFormat;
3536use lsp_types:: Location ;
3637use lsp_types:: MarkedString ;
3738use lsp_types:: SemanticTokenType ;
39+ use lsp_types:: SymbolKind ;
3840use lsp_types:: Url ;
3941use rustc_hash:: FxHashMap ;
4042use rustc_hash:: FxHashSet ;
@@ -95,6 +97,7 @@ pub struct Ctx<'a, 'ctx> {
9597 pub ditypes_placeholder : Rc < RefCell < FxHashMap < String , RefCell < Vec < MemberType < ' ctx > > > > > > , // hold the generated debug info type place holder
9698 pub ditypes : Rc < RefCell < FxHashMap < String , DIType < ' ctx > > > > , // hold the generated debug info type
9799 pub hints : Rc < RefCell < Box < Vec < InlayHint > > > > ,
100+ pub doc_symbols : Rc < RefCell < Box < Vec < DocumentSymbol > > > > ,
98101 pub semantic_tokens_builder : Rc < RefCell < Box < SemanticTokensBuilder > > > , // semantic token builder
99102 pub goto_def : Rc < Cell < Option < GotoDefinitionResponse > > > , // hold the goto definition result
100103 pub completion_items : Rc < Cell < Vec < CompletionItem > > > , // hold the completion items
@@ -493,7 +496,7 @@ impl PLType {
493496 PLType :: PRIMITIVE ( pri) => pri. get_name ( ) ,
494497 PLType :: ARR ( arr) => format ! ( "[{} * {}]" , arr. element_type. get_name( ) , arr. size) ,
495498 PLType :: VOID => "void" . to_string ( ) ,
496- PLType :: POINTER ( p) => "& " . to_string ( ) + & p. get_name ( ) ,
499+ PLType :: POINTER ( p) => "* " . to_string ( ) + & p. get_name ( ) ,
497500 }
498501 }
499502
@@ -792,6 +795,19 @@ impl Field {
792795 offset + debug_type. get_size_in_bits ( ) ,
793796 )
794797 }
798+ pub fn get_doc_symbol < ' a , ' ctx > ( & self , ctx : & Ctx < ' a , ' ctx > ) -> DocumentSymbol {
799+ #[ allow( deprecated) ]
800+ DocumentSymbol {
801+ name : self . name . clone ( ) ,
802+ detail : Some ( self . pltype . get_type ( ctx) . unwrap ( ) . get_name ( ) ) ,
803+ kind : SymbolKind :: FIELD ,
804+ tags : None ,
805+ deprecated : None ,
806+ range : self . range . to_diag_range ( ) ,
807+ selection_range : self . range . to_diag_range ( ) ,
808+ children : None ,
809+ }
810+ }
795811}
796812
797813#[ derive( Debug , Clone , PartialEq , Eq ) ]
@@ -804,6 +820,7 @@ pub struct FNType {
804820 pub range : Range ,
805821 pub refs : Rc < RefCell < Vec < Location > > > ,
806822 pub doc : Vec < Box < NodeEnum > > ,
823+ pub method : bool ,
807824}
808825
809826impl TryFrom < PLType > for FNType {
@@ -838,6 +855,47 @@ impl FNType {
838855 . add_function ( & self . llvmname , fn_type, Some ( Linkage :: External ) ) ;
839856 fn_value
840857 }
858+ pub fn get_doc_symbol ( & self ) -> DocumentSymbol {
859+ #[ allow( deprecated) ]
860+ DocumentSymbol {
861+ name : if self . method {
862+ self . name . split ( "::" ) . last ( ) . unwrap ( ) . to_string ( )
863+ } else {
864+ self . name . clone ( )
865+ } ,
866+ detail : Some ( self . get_signature ( ) ) ,
867+ kind : if self . method {
868+ SymbolKind :: METHOD
869+ } else {
870+ SymbolKind :: FUNCTION
871+ } ,
872+ tags : None ,
873+ deprecated : None ,
874+ range : self . range . to_diag_range ( ) ,
875+ selection_range : self . range . to_diag_range ( ) ,
876+ children : None ,
877+ }
878+ }
879+ pub fn get_signature ( & self ) -> String {
880+ let mut params = String :: new ( ) ;
881+ if !self . param_name . is_empty ( ) {
882+ if !self . method {
883+ params += & format ! (
884+ "{}: {}" ,
885+ self . param_name[ 0 ] ,
886+ self . param_pltypes[ 0 ] . get_name( )
887+ ) ;
888+ }
889+ for i in 1 ..self . param_name . len ( ) {
890+ params += & format ! (
891+ ", {}: {}" ,
892+ self . param_name[ i] ,
893+ self . param_pltypes[ i] . get_name( )
894+ ) ;
895+ }
896+ }
897+ format ! ( "fn ({}) {}" , params, self . ret_pltype. get_name( ) )
898+ }
841899}
842900
843901#[ derive( Debug , Clone , PartialEq , Eq ) ]
@@ -918,6 +976,24 @@ impl STType {
918976 pub fn get_st_full_name ( & self ) -> String {
919977 format ! ( "{}..{}" , self . path, self . name)
920978 }
979+ pub fn get_doc_symbol < ' a , ' ctx > ( & self , ctx : & Ctx < ' a , ' ctx > ) -> DocumentSymbol {
980+ let children: Vec < DocumentSymbol > = self
981+ . ordered_fields
982+ . iter ( )
983+ . map ( |order_field| order_field. get_doc_symbol ( ctx) )
984+ . collect ( ) ;
985+ #[ allow( deprecated) ]
986+ DocumentSymbol {
987+ name : self . name . clone ( ) ,
988+ detail : None ,
989+ kind : SymbolKind :: STRUCT ,
990+ tags : None ,
991+ deprecated : None ,
992+ range : self . range . to_diag_range ( ) ,
993+ selection_range : self . range . to_diag_range ( ) ,
994+ children : Some ( children) ,
995+ }
996+ }
921997}
922998
923999fn add_primitive_types < ' a , ' ctx > ( ctx : & mut Ctx < ' a , ' ctx > ) {
@@ -1082,6 +1158,7 @@ impl<'a, 'ctx> Ctx<'a, 'ctx> {
10821158 lspparams : completion,
10831159 refs : Rc :: new ( Cell :: new ( None ) ) ,
10841160 hints : Rc :: new ( RefCell :: new ( Box :: new ( vec ! [ ] ) ) ) ,
1161+ doc_symbols : Rc :: new ( RefCell :: new ( Box :: new ( vec ! [ ] ) ) ) ,
10851162 semantic_tokens_builder : Rc :: new ( RefCell :: new ( Box :: new ( SemanticTokensBuilder :: new (
10861163 src_file_path. to_string ( ) ,
10871164 ) ) ) ) ,
@@ -1129,6 +1206,7 @@ impl<'a, 'ctx> Ctx<'a, 'ctx> {
11291206 lspparams : self . lspparams . clone ( ) ,
11301207 refs : self . refs . clone ( ) ,
11311208 hints : self . hints . clone ( ) ,
1209+ doc_symbols : self . doc_symbols . clone ( ) ,
11321210 semantic_tokens_builder : self . semantic_tokens_builder . clone ( ) ,
11331211 goto_def : self . goto_def . clone ( ) ,
11341212 completion_items : self . completion_items . clone ( ) ,
@@ -1227,7 +1305,7 @@ impl<'a, 'ctx> Ctx<'a, 'ctx> {
12271305 & mut self ,
12281306 name : String ,
12291307 pv : PointerValue < ' ctx > ,
1230- tp : PLType ,
1308+ pltype : PLType ,
12311309 range : Range ,
12321310 is_const : bool ,
12331311 ) -> Result < ( ) , PLDiag > {
@@ -1237,9 +1315,10 @@ impl<'a, 'ctx> Ctx<'a, 'ctx> {
12371315 let refs = Rc :: new ( RefCell :: new ( vec ! [ ] ) ) ;
12381316 if is_const {
12391317 self . plmod
1240- . add_global_symbol ( name, tp , range, refs. clone ( ) ) ?;
1318+ . add_global_symbol ( name, pltype . clone ( ) , range, refs. clone ( ) ) ?;
12411319 } else {
1242- self . table . insert ( name, ( pv, tp, range, refs. clone ( ) ) ) ;
1320+ self . table
1321+ . insert ( name, ( pv, pltype. clone ( ) , range, refs. clone ( ) ) ) ;
12431322 }
12441323 self . send_if_go_to_def ( range, range, self . plmod . path . clone ( ) ) ;
12451324 self . set_if_refs ( refs, range) ;
@@ -1299,14 +1378,25 @@ impl<'a, 'ctx> Ctx<'a, 'ctx> {
12991378 set. insert ( name) ;
13001379 }
13011380
1302- pub fn add_type ( & mut self , name : String , tp : PLType , range : Range ) -> Result < ( ) , PLDiag > {
1381+ pub fn add_type ( & mut self , name : String , pltype : PLType , range : Range ) -> Result < ( ) , PLDiag > {
13031382 if self . plmod . types . contains_key ( & name) {
13041383 return Err ( self . add_err ( range, ErrorCode :: REDEFINE_TYPE ) ) ;
13051384 }
13061385 self . send_if_go_to_def ( range, range, self . plmod . path . clone ( ) ) ;
1307- self . plmod . types . insert ( name, tp . clone ( ) ) ;
1386+ self . plmod . types . insert ( name, pltype . clone ( ) ) ;
13081387 Ok ( ( ) )
13091388 }
1389+ pub fn add_doc_symbols ( & mut self , pltype : PLType ) {
1390+ match & pltype {
1391+ PLType :: FN ( f) => {
1392+ if !f. method {
1393+ self . doc_symbols . borrow_mut ( ) . push ( f. get_doc_symbol ( ) )
1394+ }
1395+ }
1396+ PLType :: STRUCT ( st) => self . doc_symbols . borrow_mut ( ) . push ( st. get_doc_symbol ( self ) ) ,
1397+ _ => { }
1398+ }
1399+ }
13101400
13111401 pub fn add_err ( & self , range : Range , code : ErrorCode ) -> PLDiag {
13121402 let dia = PLDiag :: new_error ( range, code) ;
0 commit comments