11use emmylua_code_analysis:: {
2- InferGuard , LuaDeclLocation , LuaFunctionType , LuaMember , LuaMemberKey , LuaMemberOwner ,
3- LuaMultiLineUnion , LuaPropertyOwnerId , LuaType , LuaTypeDeclId , LuaUnionType , RenderLevel ,
2+ get_closure_expr_comment, InferGuard , LuaDeclLocation , LuaFunctionType , LuaMember ,
3+ LuaMemberKey , LuaMemberOwner , LuaMultiLineUnion , LuaPropertyOwnerId , LuaType , LuaTypeDeclId ,
4+ LuaUnionType , RenderLevel ,
45} ;
56use emmylua_parser:: {
6- LuaAst , LuaAstNode , LuaAstToken , LuaCallArgList , LuaCallExpr , LuaComment , LuaNameToken ,
7- LuaSyntaxId , LuaSyntaxKind , LuaSyntaxToken , LuaTokenKind , LuaVarExpr ,
7+ LuaAst , LuaAstNode , LuaAstToken , LuaCallArgList , LuaCallExpr , LuaClosureExpr , LuaComment ,
8+ LuaDocTagParam , LuaNameToken , LuaParamList , LuaSyntaxId , LuaSyntaxKind , LuaSyntaxToken ,
9+ LuaTokenKind , LuaVarExpr ,
810} ;
911use itertools:: Itertools ;
1012use lsp_types:: { CompletionItem , Documentation } ;
@@ -168,6 +170,9 @@ fn get_token_should_type(builder: &mut CompletionBuilder) -> Option<Vec<LuaType>
168170 LuaSyntaxKind :: CallArgList => {
169171 return infer_call_arg_list ( builder, LuaCallArgList :: cast ( parent_node) ?, token) ;
170172 }
173+ LuaSyntaxKind :: ParamList => {
174+ return infer_param_list ( builder, LuaParamList :: cast ( parent_node) ?) ;
175+ }
171176 LuaSyntaxKind :: BinaryExpr => {
172177 // infer_binary_expr(builder, binary_expr)?;
173178 }
@@ -177,6 +182,55 @@ fn get_token_should_type(builder: &mut CompletionBuilder) -> Option<Vec<LuaType>
177182 None
178183}
179184
185+ fn infer_param_list (
186+ builder : & mut CompletionBuilder ,
187+ param_list : LuaParamList ,
188+ ) -> Option < Vec < LuaType > > {
189+ let closure_expr = param_list. get_parent :: < LuaClosureExpr > ( ) ?;
190+
191+ let doc_params = get_closure_expr_comment ( & closure_expr) ?. children :: < LuaDocTagParam > ( ) ;
192+ let mut names = Vec :: new ( ) ;
193+ for doc_param in doc_params {
194+ let name = doc_param. get_name_token ( ) ?. get_name_text ( ) . to_string ( ) ;
195+ if !names. contains ( & name) {
196+ // 不在这里添加补全项, 拼接的优先级应在单独添加之上
197+ names. push ( name. clone ( ) ) ;
198+ }
199+ }
200+ let params = param_list
201+ . get_params ( )
202+ . map ( |it| {
203+ if let Some ( name_token) = it. get_name_token ( ) {
204+ name_token. get_name_text ( ) . to_string ( )
205+ } else {
206+ "" . to_string ( )
207+ }
208+ } )
209+ . filter ( |it| !it. is_empty ( ) )
210+ . collect :: < Vec < _ > > ( ) ;
211+
212+ // names 去掉 params 已有的
213+ names. retain ( |name| !params. contains ( & name) ) ;
214+ if names. len ( ) > 1 {
215+ builder. add_completion_item ( CompletionItem {
216+ label : format ! ( "{}" , names. iter( ) . join( ", " ) ) ,
217+ kind : Some ( lsp_types:: CompletionItemKind :: INTERFACE ) ,
218+ ..Default :: default ( )
219+ } ) ;
220+ }
221+
222+ for name in names {
223+ builder. add_completion_item ( CompletionItem {
224+ label : name,
225+ kind : Some ( lsp_types:: CompletionItemKind :: INTERFACE ) ,
226+ ..Default :: default ( )
227+ } ) ;
228+ }
229+
230+ // 不返回类型, 因为字符串类型会被加上双引号, 但这里需要的是不带双引号的字符串, 我们选择直接在这里添加
231+ None
232+ }
233+
180234fn infer_call_arg_list (
181235 builder : & mut CompletionBuilder ,
182236 call_arg_list : LuaCallArgList ,
0 commit comments