Skip to content

Commit 201e841

Browse files
committed
Support intersection type navigation
1 parent 42f79ba commit 201e841

File tree

2 files changed

+58
-3
lines changed

2 files changed

+58
-3
lines changed

crates/emmylua_code_analysis/src/semantic/semantic_info/infer_expr_semantic_decl.rs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use emmylua_parser::{
44
};
55

66
use crate::{
7-
DbIndex, LuaDeclId, LuaDeclOrMemberId, LuaInferCache, LuaInstanceType, LuaMemberId,
8-
LuaMemberKey, LuaMemberOwner, LuaSemanticDeclId, LuaType, LuaTypeCache, LuaTypeDeclId,
9-
LuaUnionType,
7+
DbIndex, LuaDeclId, LuaDeclOrMemberId, LuaInferCache, LuaInstanceType, LuaIntersectionType,
8+
LuaMemberId, LuaMemberKey, LuaMemberOwner, LuaSemanticDeclId, LuaType, LuaTypeCache,
9+
LuaTypeDeclId, LuaUnionType,
1010
semantic::{
1111
infer::find_self_decl_or_member_id, member::get_buildin_type_map_type_id,
1212
semantic_info::resolve_global_decl_id,
@@ -297,6 +297,13 @@ fn infer_member_semantic_decl_by_member_key(
297297
None
298298
}
299299
}
300+
LuaType::Intersection(intersection_type) => infer_intersection_member_semantic_info(
301+
db,
302+
cache,
303+
intersection_type,
304+
member_key,
305+
semantic_guard.next_level()?,
306+
),
300307
_ => None,
301308
}
302309
}
@@ -416,3 +423,25 @@ fn infer_global_member_semantic_decl_by_member_key(
416423
let name = member_key.get_name()?;
417424
resolve_global_decl_id(db, cache, name, None).map(LuaSemanticDeclId::LuaDecl)
418425
}
426+
427+
fn infer_intersection_member_semantic_info(
428+
db: &DbIndex,
429+
cache: &mut LuaInferCache,
430+
intersection_type: &LuaIntersectionType,
431+
member_key: &LuaMemberKey,
432+
semantic_guard: SemanticDeclGuard,
433+
) -> Option<LuaSemanticDeclId> {
434+
for typ in intersection_type.get_types() {
435+
if let Some(property_owner_id) = infer_member_semantic_decl_by_member_key(
436+
db,
437+
cache,
438+
typ,
439+
member_key,
440+
semantic_guard.next_level()?,
441+
) {
442+
return Some(property_owner_id);
443+
}
444+
}
445+
446+
None
447+
}

crates/emmylua_ls/src/handlers/test/definition_test.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,4 +554,30 @@ mod tests {
554554

555555
Ok(())
556556
}
557+
558+
#[gtest]
559+
fn test_intersection() -> Result<()> {
560+
let mut ws = ProviderVirtualWorkspace::new();
561+
ws.def(
562+
r#"
563+
---@class Matchers
564+
---@field toBe fun(expected: any)
565+
566+
---@class Inverse
567+
---@field negate number
568+
"#,
569+
);
570+
check!(ws.check_definition(
571+
r#"
572+
---@type Matchers & Inverse
573+
local a
574+
a.ne<??>gate = 0
575+
"#,
576+
vec![Expected {
577+
file: "".to_string(),
578+
line: 5,
579+
},],
580+
));
581+
Ok(())
582+
}
557583
}

0 commit comments

Comments
 (0)