@@ -5,7 +5,10 @@ use emmylua_parser::{
55 LuaSyntaxToken , LuaVarExpr , VisibilityKind ,
66} ;
77
8- use crate :: { DbIndex , Emmyrc , FileId , LuaMemberOwner , LuaSemanticDeclId , LuaType } ;
8+ use crate :: {
9+ try_extract_signature_id_from_field, DbIndex , Emmyrc , FileId , LuaCommonProperty ,
10+ LuaMemberOwner , LuaSemanticDeclId , LuaType ,
11+ } ;
912
1013use super :: { infer_expr, type_check:: is_sub_type_of, LuaInferCache } ;
1114
@@ -19,7 +22,13 @@ pub fn check_visibility(
1922 token : LuaSyntaxToken ,
2023 property_owner : LuaSemanticDeclId ,
2124) -> Option < bool > {
22- let property = db. get_property_index ( ) . get_property ( & property_owner) ?;
25+ let property = match get_property ( db, & property_owner) {
26+ Some ( property) => property,
27+ None => {
28+ return check_member_name ( db, file_id, emmyrc, infer_config, token, property_owner) ;
29+ }
30+ } ;
31+
2332 if let Some ( version_conds) = & property. version_conds {
2433 let version_number = emmyrc. runtime . version . to_lua_version_number ( ) ;
2534 let visible = version_conds. iter ( ) . any ( |cond| cond. check ( & version_number) ) ;
@@ -59,37 +68,7 @@ pub fn check_visibility(
5968 }
6069 }
6170
62- if let LuaSemanticDeclId :: Member ( member_id) = property_owner {
63- if let Some ( member) = db. get_member_index ( ) . get_member ( & member_id) {
64- if let Some ( name) = member. get_key ( ) . get_name ( ) {
65- let config = emmyrc;
66- for pattern in & config. doc . private_name {
67- let is_match = if let Some ( prefix) = pattern. strip_suffix ( '*' ) {
68- name. starts_with ( prefix)
69- } else if let Some ( suffix) = pattern. strip_prefix ( '*' ) {
70- name. ends_with ( suffix)
71- } else {
72- name == pattern
73- } ;
74- if is_match {
75- return Some (
76- check_visibility_by_visibility (
77- db,
78- infer_config,
79- file_id,
80- property_owner,
81- token,
82- VisibilityKind :: Private ,
83- )
84- . unwrap_or ( false ) ,
85- ) ;
86- }
87- }
88- }
89- }
90- }
91-
92- Some ( true )
71+ check_member_name ( db, file_id, emmyrc, infer_config, token, property_owner)
9372}
9473
9574fn check_visibility_by_visibility (
@@ -180,7 +159,7 @@ fn check_block_visibility(
180159fn check_def_visibility (
181160 db : & DbIndex ,
182161 infer_config : & mut LuaInferCache ,
183- file_id : FileId ,
162+ _file_id : FileId ,
184163 member_owner : & LuaMemberOwner ,
185164 token : LuaGeneralToken ,
186165 visibility : VisibilityKind ,
@@ -189,9 +168,10 @@ fn check_def_visibility(
189168 let prefix_expr = index_expr. get_prefix_expr ( ) ?;
190169 let typ = infer_expr ( db, infer_config, prefix_expr. into ( ) ) . ok ( ) ?;
191170
192- if !in_def_file ( db, & typ, file_id) {
193- return Some ( false ) ;
194- }
171+ // 这是为解决 require 后仍然是`Def`类型的问题, 但现在不需要了, 不过还是留着以防万一
172+ // if !in_def_file(db, &typ, file_id) {
173+ // return Some(false);
174+ // }
195175
196176 match visibility {
197177 VisibilityKind :: Protected => match ( typ, member_owner) {
@@ -209,19 +189,77 @@ fn check_def_visibility(
209189 }
210190}
211191
212- fn in_def_file ( db : & DbIndex , typ : & LuaType , file_id : FileId ) -> bool {
213- match typ {
214- LuaType :: Def ( id) => {
215- let decl = db. get_type_index ( ) . get_type_decl ( id) ;
216- if let Some ( decl) = decl {
217- decl. get_locations ( )
218- . iter ( )
219- . any ( |location| location. file_id == file_id)
220- } else {
221- false
222- }
192+ // fn in_def_file(db: &DbIndex, typ: &LuaType, file_id: FileId) -> bool {
193+ // match typ {
194+ // LuaType::Def(id) => {
195+ // let decl = db.get_type_index().get_type_decl(id);
196+ // if let Some(decl) = decl {
197+ // decl.get_locations()
198+ // .iter()
199+ // .any(|location| location.file_id == file_id)
200+ // } else {
201+ // false
202+ // }
203+ // }
204+ // LuaType::TableConst(in_file) => in_file.file_id == file_id,
205+ // _ => false,
206+ // }
207+ // }
208+
209+ fn get_property < ' a > (
210+ db : & ' a DbIndex ,
211+ property_owner : & ' a LuaSemanticDeclId ,
212+ ) -> Option < & ' a LuaCommonProperty > {
213+ match db. get_property_index ( ) . get_property ( & property_owner) {
214+ Some ( common_property) => Some ( common_property) ,
215+ None => {
216+ let LuaSemanticDeclId :: Member ( member_id) = property_owner else {
217+ return None ;
218+ } ;
219+ let member = db. get_member_index ( ) . get_member ( & member_id) ?;
220+ let signature_id = try_extract_signature_id_from_field ( db, member) ?;
221+ db. get_property_index ( )
222+ . get_property ( & LuaSemanticDeclId :: Signature ( signature_id) )
223223 }
224- LuaType :: TableConst ( in_file) => in_file. file_id == file_id,
225- _ => false ,
226224 }
227225}
226+
227+ fn check_member_name (
228+ db : & DbIndex ,
229+ file_id : FileId ,
230+ emmyrc : & Emmyrc ,
231+ infer_config : & mut LuaInferCache ,
232+ token : LuaSyntaxToken ,
233+ property_owner : LuaSemanticDeclId ,
234+ ) -> Option < bool > {
235+ if let LuaSemanticDeclId :: Member ( member_id) = property_owner {
236+ if let Some ( member) = db. get_member_index ( ) . get_member ( & member_id) {
237+ if let Some ( name) = member. get_key ( ) . get_name ( ) {
238+ let config = emmyrc;
239+ for pattern in & config. doc . private_name {
240+ let is_match = if let Some ( prefix) = pattern. strip_suffix ( '*' ) {
241+ name. starts_with ( prefix)
242+ } else if let Some ( suffix) = pattern. strip_prefix ( '*' ) {
243+ name. ends_with ( suffix)
244+ } else {
245+ name == pattern
246+ } ;
247+ if is_match {
248+ return Some (
249+ check_visibility_by_visibility (
250+ db,
251+ infer_config,
252+ file_id,
253+ property_owner,
254+ token,
255+ VisibilityKind :: Private ,
256+ )
257+ . unwrap_or ( false ) ,
258+ ) ;
259+ }
260+ }
261+ }
262+ }
263+ } ;
264+ Some ( true )
265+ }
0 commit comments