Skip to content

Commit 8a1718a

Browse files
committed
semantic_token: 如果导入的变量是类定义则会染为 class
1 parent fd88481 commit 8a1718a

File tree

1 file changed

+72
-49
lines changed

1 file changed

+72
-49
lines changed

crates/emmylua_ls/src/handlers/semantic_token/build_semantic_tokens.rs

Lines changed: 72 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use emmylua_code_analysis::{
2-
LuaMemberId, LuaMemberOwner, LuaSemanticDeclId, LuaType, SemanticDeclLevel, SemanticModel,
2+
LuaDecl, LuaMemberId, LuaMemberOwner, LuaSemanticDeclId, LuaType, LuaTypeDeclId,
3+
SemanticDeclLevel, SemanticModel,
34
};
45
use emmylua_parser::{
5-
LuaAst, LuaAstNode, LuaAstToken, LuaDocFieldKey, LuaDocObjectFieldKey, LuaExpr,
6-
LuaGeneralToken, LuaKind, LuaLiteralToken, LuaNameToken, LuaSyntaxNode, LuaSyntaxToken,
7-
LuaTokenKind, LuaVarExpr,
6+
LuaAst, LuaAstNode, LuaAstToken, LuaCallExpr, LuaDocFieldKey, LuaDocObjectFieldKey, LuaExpr,
7+
LuaGeneralToken, LuaKind, LuaLiteralToken, LuaNameToken, LuaSyntaxKind, LuaSyntaxNode,
8+
LuaSyntaxToken, LuaTokenKind, LuaVarExpr,
89
};
910
use lsp_types::{SemanticToken, SemanticTokenModifier, SemanticTokenType};
1011
use rowan::NodeOrToken;
@@ -29,6 +30,8 @@ pub fn build_semantic_tokens(
2930
SEMANTIC_TOKEN_MODIFIERS.to_vec(),
3031
);
3132

33+
dbg!(&root.syntax());
34+
3235
for node_or_token in root.syntax().descendants_with_tokens() {
3336
match node_or_token {
3437
NodeOrToken::Node(node) => {
@@ -257,32 +260,6 @@ fn build_node_semantic_token(
257260
}
258261
}
259262
LuaAst::LuaDocTagCast(doc_cast) => {
260-
// 在 call 后追加移除`nil`且同一行仍具有后续代码, 使之不显眼
261-
// if let Some(parent) = doc_cast.syntax().parent()?.parent() {
262-
// if LuaExpr::can_cast(parent.kind().into()) {
263-
// let expr = LuaExpr::cast(parent)?;
264-
// match expr {
265-
// LuaExpr::IndexExpr(index_expr) => {
266-
// let prefix_expr = index_expr.get_prefix_expr()?;
267-
// if let LuaExpr::CallExpr(_) = prefix_expr {
268-
// if doc_cast.get_op_types().any(|op_type| op_type.is_nullable()) {
269-
// let position = doc_cast.syntax().text_range().start();
270-
// let len = doc_cast.syntax().text_range().len();
271-
// builder.push_at_position(
272-
// position.into(),
273-
// len.into(),
274-
// SemanticTokenType::COMMENT,
275-
// None,
276-
// );
277-
// return Some(());
278-
// }
279-
// }
280-
// }
281-
// _ => {}
282-
// }
283-
// }
284-
// }
285-
286263
if let Some(target_expr) = doc_cast.get_key_expr() {
287264
match target_expr {
288265
LuaExpr::NameExpr(name_expr) => {
@@ -571,19 +548,6 @@ fn build_node_semantic_token(
571548
Some(())
572549
}
573550

574-
fn is_class_def(semantic_model: &SemanticModel, node: LuaSyntaxNode) -> Option<()> {
575-
let semantic_decl = semantic_model.find_decl(node.into(), SemanticDeclLevel::default())?;
576-
if let LuaSemanticDeclId::LuaDecl(decl_id) = semantic_decl {
577-
let decl_type = semantic_model.get_type(decl_id.into());
578-
match decl_type {
579-
LuaType::Def(_) => Some(()),
580-
_ => None,
581-
}
582-
} else {
583-
None
584-
}
585-
}
586-
587551
// 处理`local a = class``local a = class.method/field`
588552
fn handle_name_node(
589553
semantic_model: &SemanticModel,
@@ -599,13 +563,9 @@ fn handle_name_node(
599563
);
600564
return Some(());
601565
}
602-
if is_class_def(semantic_model, node.clone()).is_some() {
603-
builder.push(name_token.syntax(), SemanticTokenType::CLASS);
604-
return Some(());
605-
}
606566

607567
let semantic_decl =
608-
semantic_model.find_decl(node.clone().into(), SemanticDeclLevel::Trace(50))?;
568+
semantic_model.find_decl(node.clone().into(), SemanticDeclLevel::default())?;
609569

610570
match semantic_decl {
611571
LuaSemanticDeclId::Member(member_id) => {
@@ -617,13 +577,30 @@ fn handle_name_node(
617577
}
618578

619579
LuaSemanticDeclId::LuaDecl(decl_id) => {
620-
let decl_type = semantic_model.get_type(decl_id.into());
621580
let decl = semantic_model
622581
.get_db()
623582
.get_decl_index()
624583
.get_decl(&decl_id)?;
584+
let decl_type = semantic_model.get_type(decl_id.into());
625585

626586
let (token_type, modifier) = match decl_type {
587+
LuaType::Def(_) => (SemanticTokenType::CLASS, None),
588+
LuaType::Ref(ref_id) => {
589+
if let Some(is_require) =
590+
check_ref_is_require_def(semantic_model, &decl, &ref_id)
591+
{
592+
if is_require {
593+
(
594+
SemanticTokenType::CLASS,
595+
Some(SemanticTokenModifier::READONLY),
596+
)
597+
} else {
598+
(SemanticTokenType::VARIABLE, None)
599+
}
600+
} else {
601+
(SemanticTokenType::VARIABLE, None)
602+
}
603+
}
627604
LuaType::Signature(signature) => {
628605
let is_meta = semantic_model
629606
.get_db()
@@ -689,3 +666,49 @@ fn render_doc_at(builder: &mut SemanticBuilder, token: &LuaSyntaxToken) {
689666
Some(SemanticTokenModifier::DOCUMENTATION),
690667
);
691668
}
669+
670+
// 检查导入语句是否是类定义
671+
fn check_ref_is_require_def(
672+
semantic_model: &SemanticModel,
673+
decl: &LuaDecl,
674+
ref_id: &LuaTypeDeclId,
675+
) -> Option<bool> {
676+
let value_syntax_id = decl.get_value_syntax_id()?;
677+
if value_syntax_id.get_kind() != LuaSyntaxKind::RequireCallExpr {
678+
return None;
679+
}
680+
let node = semantic_model
681+
.get_db()
682+
.get_vfs()
683+
.get_syntax_tree(&decl.get_file_id())
684+
.and_then(|tree| {
685+
let root = tree.get_red_root();
686+
semantic_model
687+
.get_db()
688+
.get_decl_index()
689+
.get_decl(&decl.get_id())
690+
.and_then(|decl| decl.get_value_syntax_id())
691+
.and_then(|syntax_id| syntax_id.to_node_from_root(&root))
692+
})?;
693+
let call_expr = LuaCallExpr::cast(node)?;
694+
let arg_list = call_expr.get_args_list()?;
695+
let first_arg = arg_list.get_args().next()?;
696+
let require_path_type = semantic_model.infer_expr(first_arg.clone()).ok()?;
697+
let module_path: String = match &require_path_type {
698+
LuaType::StringConst(module_path) => module_path.as_ref().to_string(),
699+
_ => {
700+
return None;
701+
}
702+
};
703+
let module_info = semantic_model
704+
.get_db()
705+
.get_module_index()
706+
.find_module(&module_path)?;
707+
match &module_info.export_type {
708+
Some(ty) => match ty {
709+
LuaType::Def(id) => Some(id == ref_id),
710+
_ => Some(false),
711+
},
712+
None => None,
713+
}
714+
}

0 commit comments

Comments
 (0)