Skip to content

Commit 91d2c31

Browse files
committed
support file local type eg. ---@Class (private) typename
1 parent b2181a8 commit 91d2c31

19 files changed

Lines changed: 154 additions & 83 deletions

File tree

crates/emmylua_code_analysis/src/compilation/analyzer/decl/docs.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ fn get_type_flag_value(
4242
"key" => {
4343
attr |= LuaTypeFlag::Key;
4444
}
45-
// "global" => {
46-
// attr |= LuaTypeAttribute::Global;
47-
// }
4845
"exact" => {
4946
attr |= LuaTypeFlag::Exact;
5047
}
5148
"constructor" => {
5249
attr |= LuaTypeFlag::Constructor;
5350
}
51+
"private" => {
52+
attr |= LuaTypeFlag::Private;
53+
}
5454
_ => {}
5555
}
5656
}
@@ -196,7 +196,11 @@ fn add_type_decl(
196196
let full_name = option_namespace
197197
.map(|ns| format!("{}.{}", ns, basic_name))
198198
.unwrap_or(basic_name.to_string());
199-
let id = LuaTypeDeclId::new(&full_name);
199+
let id = if flag.contains(LuaTypeFlag::Private) {
200+
LuaTypeDeclId::local(file_id, &full_name)
201+
} else {
202+
LuaTypeDeclId::global(&full_name)
203+
};
200204
let simple_name = id.get_simple_name();
201205
type_index.add_type_decl(
202206
file_id,

crates/emmylua_code_analysis/src/compilation/analyzer/doc/infer_type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ fn infer_buildin_or_ref_type(
182182
founded = true;
183183
name_type_decl.get_id()
184184
} else {
185-
LuaTypeDeclId::new(name)
185+
LuaTypeDeclId::global(name)
186186
};
187187

188188
if !founded {

crates/emmylua_code_analysis/src/compilation/analyzer/unresolve/find_decl_function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ fn infer_namespace_member_decl_type(
872872
};
873873

874874
let namespace_or_type_id = format!("{}.{}", ns, member_key);
875-
let type_id = LuaTypeDeclId::new(&namespace_or_type_id);
875+
let type_id = LuaTypeDeclId::global(&namespace_or_type_id);
876876
if db.get_type_index().get_type_decl(&type_id).is_some() {
877877
return Ok(LuaType::Def(type_id));
878878
}

crates/emmylua_code_analysis/src/compilation/analyzer/unresolve/resolve.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ pub fn try_resolve_constructor(
323323

324324
// 添加根类
325325
if let Some(root_class) = root_class {
326-
let root_type_id = LuaTypeDeclId::new(&root_class);
326+
let root_type_id = LuaTypeDeclId::global(&root_class);
327327
if let Some(type_decl) = db.get_type_index().get_type_decl(&root_type_id) {
328328
if type_decl.is_class() {
329329
let root_type = LuaType::Ref(root_type_id.clone());
@@ -422,7 +422,7 @@ fn get_constructor_target_type(
422422
let prefix = str_tpl.get_prefix();
423423
let suffix = str_tpl.get_suffix();
424424
let type_decl_id: LuaTypeDeclId =
425-
LuaTypeDeclId::new(format!("{}{}{}", prefix, name, suffix).as_str());
425+
LuaTypeDeclId::global(format!("{}{}{}", prefix, name, suffix).as_str());
426426
let type_decl = db.get_type_index().get_type_decl(&type_decl_id)?;
427427
if type_decl.is_class() {
428428
return Some(type_decl_id);

crates/emmylua_code_analysis/src/db_index/type/mod.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ mod type_visit_trait;
88
mod types;
99

1010
use super::traits::LuaIndex;
11-
use crate::{DbIndex, FileId, InFiled};
11+
use crate::{DbIndex, FileId, InFiled, db_index::r#type::type_decl::LuaTypeIdentifier};
1212
pub use generic_param::GenericParam;
1313
pub use humanize_type::{RenderLevel, format_union_type, humanize_type};
1414
use std::collections::{HashMap, HashSet};
@@ -83,22 +83,27 @@ impl LuaTypeIndex {
8383

8484
pub fn find_type_decl(&self, file_id: FileId, name: &str) -> Option<&LuaTypeDecl> {
8585
if let Some(ns) = self.get_file_namespace(&file_id) {
86-
let full_name = LuaTypeDeclId::new(&format!("{}.{}", ns, name));
86+
let full_name = LuaTypeDeclId::global(&format!("{}.{}", ns, name));
8787
if let Some(decl) = self.full_name_type_map.get(&full_name) {
8888
return Some(decl);
8989
}
9090
}
9191
if let Some(usings) = self.get_file_using_namespace(&file_id) {
9292
for ns in usings {
93-
let full_name = LuaTypeDeclId::new(&format!("{}.{}", ns, name));
93+
let full_name = LuaTypeDeclId::global(&format!("{}.{}", ns, name));
9494
if let Some(decl) = self.full_name_type_map.get(&full_name) {
9595
return Some(decl);
9696
}
9797
}
9898
}
9999

100-
let id = LuaTypeDeclId::new(name);
101-
self.full_name_type_map.get(&id)
100+
let local_id = LuaTypeDeclId::local(file_id, name);
101+
if let Some(decl) = self.full_name_type_map.get(&local_id) {
102+
return Some(decl);
103+
}
104+
105+
let global_id = LuaTypeDeclId::global(name);
106+
self.full_name_type_map.get(&global_id)
102107
}
103108

104109
pub fn find_type_decls(
@@ -143,7 +148,15 @@ impl LuaTypeIndex {
143148
}
144149

145150
for id in all_type_ids {
146-
let id_name = id.get_name();
151+
let id_name = match id.get_id() {
152+
LuaTypeIdentifier::Local(f_id, name) => {
153+
if f_id != &file_id {
154+
continue;
155+
}
156+
name
157+
}
158+
LuaTypeIdentifier::Global(name) => name,
159+
};
147160
if id_name.starts_with(prefix)
148161
&& let Some(rest_name) = id_name.strip_prefix(prefix)
149162
{

crates/emmylua_code_analysis/src/db_index/type/test.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ mod test {
2727
"new_type".to_string(),
2828
LuaDeclTypeKind::Alias,
2929
LuaTypeFlag::Partial.into(),
30-
LuaTypeDeclId::new("test.new_type"),
30+
LuaTypeDeclId::global("test.new_type"),
3131
),
3232
);
3333

@@ -63,7 +63,7 @@ mod test {
6363
"new_type".to_string(),
6464
LuaDeclTypeKind::Alias,
6565
LuaTypeFlag::Partial.into(),
66-
LuaTypeDeclId::new("test.new_type"),
66+
LuaTypeDeclId::global("test.new_type"),
6767
),
6868
);
6969

@@ -93,7 +93,7 @@ mod test {
9393
"new_type".to_string(),
9494
LuaDeclTypeKind::Class,
9595
LuaTypeFlag::Partial.into(),
96-
LuaTypeDeclId::new("new_type"),
96+
LuaTypeDeclId::global("new_type"),
9797
),
9898
);
9999

@@ -111,7 +111,7 @@ mod test {
111111
"new_type".to_string(),
112112
LuaDeclTypeKind::Class,
113113
LuaTypeFlag::Partial.into(),
114-
LuaTypeDeclId::new(".new_type"),
114+
LuaTypeDeclId::global(".new_type"),
115115
),
116116
);
117117

@@ -124,7 +124,7 @@ mod test {
124124
"new_type".to_string(),
125125
LuaDeclTypeKind::Class,
126126
LuaTypeFlag::Partial.into(),
127-
LuaTypeDeclId::new("new_type"),
127+
LuaTypeDeclId::global("new_type"),
128128
),
129129
);
130130

@@ -151,7 +151,7 @@ mod test {
151151
"new_type".to_string(),
152152
LuaDeclTypeKind::Class,
153153
LuaTypeFlag::Partial.into(),
154-
LuaTypeDeclId::new("test.new_type"),
154+
LuaTypeDeclId::global("test.new_type"),
155155
),
156156
);
157157

crates/emmylua_code_analysis/src/db_index/type/type_decl.rs

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::fmt;
2+
13
use flagset::{FlagSet, flags};
24
use internment::ArcIntern;
35
use rowan::TextRange;
@@ -26,6 +28,7 @@ flags! {
2628
Exact,
2729
Meta,
2830
Constructor,
31+
Private
2932
}
3033
}
3134

@@ -232,24 +235,39 @@ impl LuaTypeDecl {
232235
}
233236
}
234237

238+
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
239+
pub enum LuaTypeIdentifier {
240+
Global(SmolStr),
241+
Local(FileId, SmolStr),
242+
}
243+
235244
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
236245
pub struct LuaTypeDeclId {
237-
id: ArcIntern<SmolStr>,
246+
id: ArcIntern<LuaTypeIdentifier>,
238247
}
239248

240249
impl LuaTypeDeclId {
241-
pub fn new_by_id(id: ArcIntern<SmolStr>) -> Self {
242-
Self { id }
250+
pub fn global(str: &str) -> Self {
251+
Self {
252+
id: ArcIntern::new(LuaTypeIdentifier::Global(SmolStr::new(str))),
253+
}
243254
}
244255

245-
pub fn new(str: &str) -> Self {
256+
pub fn local(file_id: FileId, str: &str) -> Self {
246257
Self {
247-
id: ArcIntern::new(SmolStr::new(str)),
258+
id: ArcIntern::new(LuaTypeIdentifier::Local(file_id, SmolStr::new(str))),
248259
}
249260
}
250261

262+
pub fn get_id(&self) -> &LuaTypeIdentifier {
263+
self.id.as_ref()
264+
}
265+
251266
pub fn get_name(&self) -> &str {
252-
&self.id
267+
match self.id.as_ref() {
268+
LuaTypeIdentifier::Global(name) => name.as_ref(),
269+
LuaTypeIdentifier::Local(_, name) => name.as_ref(),
270+
}
253271
}
254272

255273
pub fn get_simple_name(&self) -> &str {
@@ -301,7 +319,13 @@ impl Serialize for LuaTypeDeclId {
301319
where
302320
S: Serializer,
303321
{
304-
serializer.serialize_str(&self.id)
322+
match self.id.as_ref() {
323+
LuaTypeIdentifier::Global(name) => serializer.serialize_str(name.as_ref()),
324+
LuaTypeIdentifier::Local(file_id, name) => {
325+
let s = format!("{}|{}", file_id.id, &name);
326+
serializer.serialize_str(&s)
327+
}
328+
}
305329
}
306330
}
307331

@@ -310,10 +334,29 @@ impl<'de> Deserialize<'de> for LuaTypeDeclId {
310334
where
311335
D: Deserializer<'de>,
312336
{
313-
let s = String::deserialize(deserializer)?;
314-
Ok(LuaTypeDeclId {
315-
id: ArcIntern::new(SmolStr::new(s)),
316-
})
337+
struct LuaTypeDeclIdVisitor;
338+
339+
impl<'de> serde::de::Visitor<'de> for LuaTypeDeclIdVisitor {
340+
type Value = LuaTypeDeclId;
341+
342+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
343+
formatter.write_str("a string representing LuaTypeDeclId")
344+
}
345+
346+
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
347+
where
348+
E: serde::de::Error,
349+
{
350+
if let Some((file_id_str, name)) = value.split_once('|') {
351+
let file_id = file_id_str.parse::<u32>().map_err(E::custom)?;
352+
Ok(LuaTypeDeclId::local(FileId { id: file_id }, name))
353+
} else {
354+
Ok(LuaTypeDeclId::global(value))
355+
}
356+
}
357+
}
358+
359+
deserializer.deserialize_str(LuaTypeDeclIdVisitor)
317360
}
318361
}
319362

crates/emmylua_code_analysis/src/db_index/type/types.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,27 +1279,6 @@ impl VariadicType {
12791279
}
12801280
}
12811281

1282-
impl From<SmolStr> for LuaType {
1283-
fn from(s: SmolStr) -> Self {
1284-
let str: &str = s.as_ref();
1285-
match str {
1286-
"nil" => LuaType::Nil,
1287-
"table" => LuaType::Table,
1288-
"userdata" => LuaType::Userdata,
1289-
"function" => LuaType::Function,
1290-
"thread" => LuaType::Thread,
1291-
"boolean" => LuaType::Boolean,
1292-
"string" => LuaType::String,
1293-
"integer" => LuaType::Integer,
1294-
"number" => LuaType::Number,
1295-
"io" => LuaType::Io,
1296-
"global" => LuaType::Global,
1297-
"self" => LuaType::SelfInfer,
1298-
_ => LuaType::Ref(LuaTypeDeclId::new_by_id(s.into())),
1299-
}
1300-
}
1301-
}
1302-
13031282
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
13041283
pub struct LuaInstanceType {
13051284
base: LuaType,

crates/emmylua_code_analysis/src/diagnostic/checker/duplicate_field.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ fn get_decl_set(semantic_model: &SemanticModel) -> Option<HashSet<DeclInfo>> {
7272
for tag_class in root.descendants::<LuaDocTagClass>() {
7373
if let Some(class_name) = tag_class.get_name_token() {
7474
type_decl_id_set.insert(DeclInfo {
75-
id: LuaTypeDeclId::new(class_name.get_name_text()),
75+
id: LuaTypeDeclId::global(class_name.get_name_text()),
7676
is_require: false,
7777
});
7878
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use emmylua_parser::LuaAstNode;
2+
3+
use crate::{
4+
InferFailReason, LuaFunctionType, LuaSignatureId, TplContext,
5+
semantic::generic::tpl_pattern::TplPatternMatchResult,
6+
};
7+
8+
pub fn check_lambda_tpl_pattern(
9+
context: &mut TplContext,
10+
_tpl_func: &LuaFunctionType,
11+
signature_id: LuaSignatureId,
12+
) -> TplPatternMatchResult {
13+
let call_expr = context.call_expr.clone().ok_or(InferFailReason::None)?;
14+
let call_arg_list = call_expr.get_args_list().ok_or(InferFailReason::None)?;
15+
let closure_position = signature_id.get_position();
16+
let closure_expr = call_arg_list
17+
.get_args()
18+
.find(|arg| arg.get_position() == closure_position);
19+
20+
if closure_expr.is_none() {
21+
return Err(InferFailReason::UnResolveSignatureReturn(signature_id));
22+
}
23+
24+
Ok(())
25+
}

0 commit comments

Comments
 (0)