Skip to content

Commit 46037a5

Browse files
committed
support basic visible check for code completion
1 parent f5bdedf commit 46037a5

File tree

6 files changed

+147
-13
lines changed

6 files changed

+147
-13
lines changed

.vscode/launch.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@
2020
}
2121
},
2222
"args": [
23-
"--port", "5007"
23+
"-c",
24+
"tcp",
25+
"--port",
26+
"5007",
27+
"--log-level",
28+
"debug"
2429
],
2530
"cwd": "${workspaceFolder}"
2631
},

crates/code_analysis/src/semantic/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,19 @@ impl<'a> SemanticModel<'a> {
139139
}
140140

141141
pub fn is_property_visiable(
142-
&self,
142+
&mut self,
143143
token: LuaSyntaxToken,
144144
property_owner: LuaPropertyOwnerId,
145145
) -> bool {
146-
check_visibility(self.db, self.file_id, &self.emmyrc, token, property_owner).unwrap_or(true)
146+
check_visibility(
147+
self.db,
148+
self.file_id,
149+
&self.emmyrc,
150+
&mut self.infer_config,
151+
token,
152+
property_owner,
153+
)
154+
.unwrap_or(true)
147155
}
148156

149157
pub fn get_emmyrc(&self) -> &Emmyrc {

crates/code_analysis/src/semantic/visibility/mod.rs

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
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

510
pub 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+
}

crates/emmylua_ls/src/handlers/completion/add_completions/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::util::humanize_type;
1212

1313
use super::completion_builder::CompletionBuilder;
1414

15-
fn check_visibility(builder: &CompletionBuilder, id: LuaPropertyOwnerId) -> Option<()> {
15+
fn check_visibility(builder: &mut CompletionBuilder, id: LuaPropertyOwnerId) -> Option<()> {
1616
match id {
1717
LuaPropertyOwnerId::Member(_) => {}
1818
LuaPropertyOwnerId::LuaDecl(_) => {}

crates/emmylua_parser/src/grammar/doc/test.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1849,7 +1849,50 @@ Syntax(Chunk)@0..74
18491849
Token(TkEndOfLine)@65..66 "\n"
18501850
Token(TkWhitespace)@66..74 " "
18511851
"#;
1852-
1852+
1853+
assert_ast_eq!(code, result);
1854+
}
1855+
1856+
#[test]
1857+
fn test_visiblity() {
1858+
let code = r#"
1859+
---@private
1860+
---@public
1861+
---@package
1862+
---@protected
1863+
"#;
1864+
1865+
let result = r#"
1866+
Syntax(Chunk)@0..90
1867+
Syntax(Block)@0..90
1868+
Token(TkEndOfLine)@0..1 "\n"
1869+
Token(TkWhitespace)@1..9 " "
1870+
Syntax(Comment)@9..81
1871+
Token(TkDocStart)@9..13 "---@"
1872+
Syntax(DocTagVisibility)@13..29
1873+
Token(TkTagVisibility)@13..20 "private"
1874+
Token(TkEndOfLine)@20..21 "\n"
1875+
Token(TkWhitespace)@21..29 " "
1876+
Syntax(DocDescription)@29..29
1877+
Token(TkDocStart)@29..33 "---@"
1878+
Syntax(DocTagVisibility)@33..48
1879+
Token(TkTagVisibility)@33..39 "public"
1880+
Token(TkEndOfLine)@39..40 "\n"
1881+
Token(TkWhitespace)@40..48 " "
1882+
Syntax(DocDescription)@48..48
1883+
Token(TkDocStart)@48..52 "---@"
1884+
Syntax(DocTagVisibility)@52..68
1885+
Token(TkTagVisibility)@52..59 "package"
1886+
Token(TkEndOfLine)@59..60 "\n"
1887+
Token(TkWhitespace)@60..68 " "
1888+
Syntax(DocDescription)@68..68
1889+
Token(TkDocStart)@68..72 "---@"
1890+
Syntax(DocTagVisibility)@72..81
1891+
Token(TkTagVisibility)@72..81 "protected"
1892+
Token(TkEndOfLine)@81..82 "\n"
1893+
Token(TkWhitespace)@82..90 " "
1894+
"#;
1895+
18531896
assert_ast_eq!(code, result);
18541897
}
18551898
}

crates/emmylua_parser/src/syntax/node/token/tokens.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use crate::{
2-
kind::{BinaryOperator, LuaTokenKind, UnaryOperator}, syntax::traits::LuaAstToken, LuaOpKind, LuaSyntaxToken, LuaTypeBinaryOperator, LuaTypeUnaryOperator, LuaVersionNumber, VisibilityKind
2+
kind::{BinaryOperator, LuaTokenKind, UnaryOperator},
3+
syntax::traits::LuaAstToken,
4+
LuaOpKind, LuaSyntaxToken, LuaTypeBinaryOperator, LuaTypeUnaryOperator, LuaVersionNumber,
5+
VisibilityKind,
36
};
47

58
use super::{float_token_value, int_token_value, string_token_value};
@@ -534,7 +537,7 @@ impl LuaAstToken for LuaDocVisibilityToken {
534537
where
535538
Self: Sized,
536539
{
537-
kind == LuaTokenKind::TkDocVisibility
540+
kind == LuaTokenKind::TkDocVisibility || kind == LuaTokenKind::TkTagVisibility
538541
}
539542

540543
fn cast(syntax: LuaSyntaxToken) -> Option<Self>
@@ -699,4 +702,4 @@ impl LuaPathToken {
699702
text
700703
}
701704
}
702-
}
705+
}

0 commit comments

Comments
 (0)