1- use std:: ops:: Deref ;
1+ use std:: { ops:: Deref , sync :: Arc } ;
22
33use emmylua_parser:: {
44 LuaAssignStat , LuaAst , LuaAstNode , LuaCallArgList , LuaCallExpr , LuaExpr , LuaIndexMemberExpr ,
@@ -8,7 +8,7 @@ use emmylua_parser::{
88use crate :: {
99 db_index:: { DbIndex , LuaType } ,
1010 infer_call_expr_func, infer_expr, InferGuard , LuaArrayType , LuaDeclId , LuaInferCache ,
11- LuaMemberId , LuaTupleStatus , LuaTupleType , VariadicType ,
11+ LuaMemberId , LuaTupleStatus , LuaTupleType , LuaUnionType , TypeOps , VariadicType ,
1212} ;
1313
1414use super :: {
@@ -221,12 +221,37 @@ fn infer_table_type_by_calleee(
221221 call_arg_number -= 1 ;
222222 }
223223 }
224- Ok ( param_types
224+ let typ = param_types
225225 . get ( call_arg_number)
226226 . ok_or ( InferFailReason :: None ) ?
227227 . 1
228228 . clone ( )
229- . unwrap_or ( LuaType :: Any ) )
229+ . unwrap_or ( LuaType :: Any ) ;
230+ match & typ {
231+ LuaType :: TableConst ( _) => { }
232+ LuaType :: Union ( union) => {
233+ // TODO: 假设存在多个匹配项, 我们需要根据字段的匹配情况来确定最终的类型
234+ return Ok ( union_remove_non_table_type ( db, union) ) ;
235+ }
236+ _ => { }
237+ }
238+
239+ Ok ( typ)
240+ }
241+
242+ /// 移除掉一些非`table`类型
243+ fn union_remove_non_table_type ( db : & DbIndex , union : & Arc < LuaUnionType > ) -> LuaType {
244+ let mut result = LuaType :: Unknown ;
245+ for typ in union. into_set ( ) . into_iter ( ) {
246+ match typ {
247+ LuaType :: Signature ( _) | LuaType :: DocFunction ( _) => { }
248+ _ if typ. is_string ( ) || typ. is_number ( ) || typ. is_boolean ( ) => { }
249+ _ => {
250+ result = TypeOps :: Union . apply ( db, & result, & typ) ;
251+ }
252+ }
253+ }
254+ result
230255}
231256
232257fn infer_table_field_type_by_parent (
0 commit comments