11use emmylua_code_analysis:: {
2- LuaMemberId , LuaMemberOwner , LuaSemanticDeclId , LuaType , SemanticDeclLevel , SemanticModel ,
2+ LuaDecl , LuaMemberId , LuaMemberOwner , LuaSemanticDeclId , LuaType , LuaTypeDeclId ,
3+ SemanticDeclLevel , SemanticModel ,
34} ;
45use 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} ;
910use lsp_types:: { SemanticToken , SemanticTokenModifier , SemanticTokenType } ;
1011use 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`
588552fn 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