1- use emmylua_parser:: { LuaSyntaxToken , VisibilityKind } ;
1+ use emmylua_parser:: {
2+ LuaAstNode , LuaAstToken , LuaBlock , LuaClosureExpr , LuaFuncStat , LuaGeneralToken ,
3+ LuaSyntaxToken , LuaVarExpr , VisibilityKind ,
4+ } ;
25
3- use crate :: { DbIndex , Emmyrc , FileId , LuaPropertyOwnerId } ;
6+ use crate :: { DbIndex , Emmyrc , FileId , LuaMemberOwner , LuaPropertyOwnerId , LuaType } ;
7+
8+ use super :: { infer_expr, LuaInferConfig } ;
49
510pub fn check_visibility (
611 db : & DbIndex ,
712 file_id : FileId ,
813 emmyrc : & Emmyrc ,
14+ infer_config : & mut LuaInferConfig ,
915 token : LuaSyntaxToken ,
1016 property_owner : LuaPropertyOwnerId ,
1117) -> Option < bool > {
@@ -26,15 +32,84 @@ pub fn check_visibility(
2632 // this donot use
2733 VisibilityKind :: Internal |
2834 VisibilityKind :: Public => return Some ( true ) ,
29- VisibilityKind :: Protected => todo ! ( ) ,
30- VisibilityKind :: Private => todo ! ( ) ,
35+ VisibilityKind :: Protected |
36+ VisibilityKind :: Private => {
37+ return Some ( check_visibility_by_visibility ( db, infer_config, property_owner, token, visibility) . unwrap_or ( false ) ) ;
38+ } ,
3139 VisibilityKind :: Package => {
3240 return Some ( file_id == property_owner. get_file_id ( ) ?) ;
3341 } ,
3442 }
43+ }
44+
45+ Some ( true )
46+ }
47+
48+ fn check_visibility_by_visibility (
49+ db : & DbIndex ,
50+ infer_config : & mut LuaInferConfig ,
51+ property_owner : LuaPropertyOwnerId ,
52+ token : LuaSyntaxToken ,
53+ visibility : VisibilityKind ,
54+ ) -> Option < bool > {
55+ let member_owner = match property_owner {
56+ LuaPropertyOwnerId :: Member ( member_id) => {
57+ db. get_member_index ( ) . get_member ( & member_id) ?. get_owner ( )
58+ }
59+ _ => return Some ( true ) ,
60+ } ;
3561
62+ let token = LuaGeneralToken :: cast ( token) ?;
63+ let blocks = token. ancestors :: < LuaBlock > ( ) ;
64+ for block in blocks {
65+ if check_block_visibility ( db, infer_config, & member_owner, block, visibility)
66+ . unwrap_or ( false )
67+ {
68+ return Some ( true ) ;
69+ }
3670 }
37-
71+
3872 Some ( false )
3973}
4074
75+ fn check_block_visibility (
76+ db : & DbIndex ,
77+ infer_config : & mut LuaInferConfig ,
78+ member_owner : & LuaMemberOwner ,
79+ block : LuaBlock ,
80+ visibility : VisibilityKind ,
81+ ) -> Option < bool > {
82+ let func_stat = block
83+ . get_parent :: < LuaClosureExpr > ( ) ?
84+ . get_parent :: < LuaFuncStat > ( ) ?;
85+
86+ let func_name = func_stat. get_func_name ( ) ?;
87+ if let LuaVarExpr :: IndexExpr ( index_expr) = func_name {
88+ let prefix_expr = index_expr. get_prefix_expr ( ) ?;
89+ let typ = infer_expr ( db, infer_config, prefix_expr. into ( ) ) ?;
90+ if visibility == VisibilityKind :: Protected {
91+ match ( typ, member_owner) {
92+ ( LuaType :: Def ( left) , LuaMemberOwner :: Type ( right) ) => {
93+ if left == * right {
94+ return Some ( true ) ;
95+ }
96+
97+ // todo is subclass
98+ }
99+ _ => { }
100+ }
101+ } else if visibility == VisibilityKind :: Private {
102+ match ( typ, member_owner) {
103+ ( LuaType :: Def ( left) , LuaMemberOwner :: Type ( right) ) => {
104+ return Some ( left == * right) ;
105+ }
106+ ( LuaType :: TableConst ( left) , LuaMemberOwner :: Element ( right) ) => {
107+ return Some ( left == * right) ;
108+ }
109+ _ => { }
110+ }
111+ }
112+ }
113+
114+ Some ( false )
115+ }
0 commit comments