@@ -2,25 +2,26 @@ use crate::completion::{
22 CompletionContext , CompletionItem , CompletionItemKind , CompletionKind , Completions ,
33} ;
44
5- use hir:: { self , Docs } ;
5+ use ra_syntax:: { ast:: { self , edit} , AstNode , SyntaxKind , TextRange } ;
6+ use hir:: { self , Docs , HasSource } ;
67
78use ra_assists:: utils:: get_missing_impl_items;
89
910pub ( crate ) fn complete_trait_impl ( acc : & mut Completions , ctx : & CompletionContext ) {
10- let impl_block = ctx. impl_block . as_ref ( ) ;
11- let item_list = impl_block. and_then ( |i| i. item_list ( ) ) ;
1211
13- if item_list. is_none ( ) || impl_block. is_none ( ) || ctx. function_syntax . is_some ( ) {
12+ // it is possible to have a parent `fn` and `impl` block. Ignore completion
13+ // attempts from within a `fn` block.
14+ if ctx. function_syntax . is_some ( ) {
1415 return ;
1516 }
1617
17- let impl_block = impl_block . unwrap ( ) ;
18-
19- for item in get_missing_impl_items ( ctx . db , & ctx . analyzer , impl_block ) {
20- match item {
21- hir:: AssocItem :: Function ( f ) => add_function_impl ( acc, ctx, & f ) ,
22- hir:: AssocItem :: TypeAlias ( t ) => add_type_alias_impl ( acc, ctx, & t ) ,
23- _ => { }
18+ if let Some ( ref impl_block) = ctx . impl_block {
19+ for item in get_missing_impl_items ( ctx . db , & ctx . analyzer , impl_block ) {
20+ match item {
21+ hir :: AssocItem :: Function ( f ) => add_function_impl ( acc , ctx , & f ) ,
22+ hir:: AssocItem :: TypeAlias ( t ) => add_type_alias_impl ( acc, ctx, & t ) ,
23+ hir:: AssocItem :: Const ( c ) => add_const_impl ( acc, ctx, & c ) ,
24+ }
2425 }
2526 }
2627}
@@ -71,6 +72,47 @@ fn add_type_alias_impl(
7172 . add_to ( acc) ;
7273}
7374
75+ fn add_const_impl (
76+ acc : & mut Completions ,
77+ ctx : & CompletionContext ,
78+ const_ : & hir:: Const ,
79+ ) {
80+ let snippet = make_const_compl_syntax ( & const_. source ( ctx. db ) . value ) ;
81+
82+ CompletionItem :: new ( CompletionKind :: Magic , ctx. source_range ( ) , snippet. clone ( ) )
83+ . insert_text ( snippet)
84+ . kind ( CompletionItemKind :: Const )
85+ . set_documentation ( const_. docs ( ctx. db ) )
86+ . add_to ( acc) ;
87+ }
88+
89+ fn make_const_compl_syntax ( const_ : & ast:: ConstDef ) -> String {
90+ let const_ = edit:: strip_attrs_and_docs ( const_) ;
91+
92+ let const_start = const_. syntax ( ) . text_range ( ) . start ( ) ;
93+ let const_end = const_. syntax ( ) . text_range ( ) . end ( ) ;
94+
95+ let start = const_
96+ . syntax ( )
97+ . first_child_or_token ( )
98+ . map_or (
99+ const_start,
100+ |f| f. text_range ( ) . start ( ) ) ;
101+
102+ let end = const_
103+ . syntax ( )
104+ . children_with_tokens ( )
105+ . find ( |s| s. kind ( ) == SyntaxKind :: SEMI || s. kind ( ) == SyntaxKind :: EQ )
106+ . map_or ( const_end, |f| f. text_range ( ) . start ( ) ) ;
107+
108+ let len = end - start;
109+ let range = TextRange :: from_to ( 0 . into ( ) , len) ;
110+
111+ let syntax = const_. syntax ( ) . text ( ) . slice ( range) . to_string ( ) ;
112+
113+ format ! ( "{} = " , syntax. trim_end( ) )
114+ }
115+
74116#[ cfg( test) ]
75117mod tests {
76118 use crate :: completion:: { do_completion, CompletionItem , CompletionKind } ;
0 commit comments