@@ -257,58 +257,92 @@ pub fn try_resolve_constructor(
257257 cache : & mut LuaInferCache ,
258258 unresolve_constructor : & mut UnResolveConstructor ,
259259) -> ResolveResult {
260- let signature = db
261- . get_signature_index ( )
262- . get ( & unresolve_constructor. signature_id )
263- . ok_or ( InferFailReason :: None ) ?;
264- let param_info = signature
265- . get_param_info_by_id ( unresolve_constructor. param_idx )
266- . ok_or ( InferFailReason :: None ) ?;
267- let constructor_use = param_info
268- . attributes
269- . iter ( )
270- . flatten ( )
271- . find ( |attr| attr. id . get_name ( ) == "constructor" )
272- . ok_or ( InferFailReason :: None ) ?;
273- let target_signature_type = constructor_use
274- . args
275- . first ( )
276- . and_then ( |( _, typ) | typ. as_ref ( ) )
277- . ok_or ( InferFailReason :: None ) ?;
278- let LuaType :: DocStringConst ( target_signature_name) = target_signature_type else {
279- return Err ( InferFailReason :: None ) ;
280- } ;
281- let target_type_decl_id = get_constructor_target_type (
260+ let ( param_type, target_signature_name, root_class, strip_self, return_self) = {
261+ let signature = db
262+ . get_signature_index ( )
263+ . get ( & unresolve_constructor. signature_id )
264+ . ok_or ( InferFailReason :: None ) ?;
265+ let param_info = signature
266+ . get_param_info_by_id ( unresolve_constructor. param_idx )
267+ . ok_or ( InferFailReason :: None ) ?;
268+ let constructor_use = param_info
269+ . get_attribute_by_name ( "constructor" )
270+ . ok_or ( InferFailReason :: None ) ?;
271+
272+ // 作为构造函数的方法名
273+ let target_signature_name = constructor_use
274+ . get_param_by_name ( "name" )
275+ . and_then ( |typ| match typ {
276+ LuaType :: DocStringConst ( value) => Some ( value. deref ( ) . clone ( ) ) ,
277+ _ => None ,
278+ } )
279+ . ok_or ( InferFailReason :: None ) ?;
280+ // 作为构造函数的根类
281+ let root_class =
282+ constructor_use
283+ . get_param_by_name ( "root_class" )
284+ . and_then ( |typ| match typ {
285+ LuaType :: DocStringConst ( value) => Some ( value. deref ( ) . clone ( ) ) ,
286+ _ => None ,
287+ } ) ;
288+ // 是否可以省略self参数
289+ let strip_self = constructor_use
290+ . get_param_by_name ( "strip_self" )
291+ . and_then ( |typ| match typ {
292+ LuaType :: DocBooleanConst ( value) => Some ( * value) ,
293+ _ => None ,
294+ } )
295+ . unwrap_or ( true ) ;
296+ // 是否返回self
297+ let return_self = constructor_use
298+ . get_param_by_name ( "return_self" )
299+ . and_then ( |typ| match typ {
300+ LuaType :: DocBooleanConst ( value) => Some ( * value) ,
301+ _ => None ,
302+ } )
303+ . unwrap_or ( true ) ;
304+
305+ Ok :: < _ , InferFailReason > ( (
306+ param_info. type_ref . clone ( ) ,
307+ target_signature_name,
308+ root_class,
309+ strip_self,
310+ return_self,
311+ ) )
312+ } ?;
313+
314+ // 需要添加构造函数的目标类型
315+ let target_id = get_constructor_target_type (
282316 db,
283317 cache,
284- & param_info . type_ref ,
318+ & param_type ,
285319 unresolve_constructor. call_expr . clone ( ) ,
286320 unresolve_constructor. param_idx ,
287321 )
288322 . ok_or ( InferFailReason :: None ) ?;
289- let target_type = LuaType :: Ref ( target_type_decl_id) ;
290- let member_key = LuaMemberKey :: Name ( target_signature_name. deref ( ) . clone ( ) ) ;
323+
324+ // 添加根类
325+ if let Some ( root_class) = root_class {
326+ let root_type_id = LuaTypeDeclId :: new ( & root_class) ;
327+ if let Some ( type_decl) = db. get_type_index ( ) . get_type_decl ( & root_type_id) {
328+ if type_decl. is_class ( ) {
329+ let root_type = LuaType :: Ref ( root_type_id. clone ( ) ) ;
330+ db. get_type_index_mut ( ) . add_super_type (
331+ target_id. clone ( ) ,
332+ unresolve_constructor. file_id ,
333+ root_type,
334+ ) ;
335+ }
336+ }
337+ }
338+
339+ // 添加构造函数
340+ let target_type = LuaType :: Ref ( target_id) ;
341+ let member_key = LuaMemberKey :: Name ( target_signature_name) ;
291342 let members =
292343 find_members_with_key ( db, & target_type, member_key, false ) . ok_or ( InferFailReason :: None ) ?;
293344 let ctor_signature_member = members. first ( ) . ok_or ( InferFailReason :: None ) ?;
294- let strip_self = constructor_use
295- . args
296- . get ( 1 )
297- . and_then ( |( _, typ) | typ. as_ref ( ) )
298- . and_then ( |typ| match typ {
299- LuaType :: DocBooleanConst ( value) => Some ( * value) ,
300- _ => None ,
301- } )
302- . unwrap_or ( true ) ;
303- let return_self = constructor_use
304- . args
305- . get ( 2 )
306- . and_then ( |( _, typ) | typ. as_ref ( ) )
307- . and_then ( |typ| match typ {
308- LuaType :: DocBooleanConst ( value) => Some ( * value) ,
309- _ => None ,
310- } )
311- . unwrap_or ( true ) ;
345+
312346 set_signature_to_default_call ( db, cache, ctor_signature_member, strip_self, return_self)
313347 . ok_or ( InferFailReason :: None ) ?;
314348
0 commit comments