1- use emmylua_code_analysis:: SemanticModel ;
1+ use std:: collections:: HashSet ;
2+
3+ use emmylua_code_analysis:: { LuaMemberKey , LuaPropertyOwnerId , LuaType , SemanticModel } ;
24use emmylua_parser:: {
35 LuaAst , LuaAstNode , LuaAstToken , LuaDocFieldKey , LuaDocObjectFieldKey , LuaExpr , LuaNameToken ,
46 LuaSyntaxNode , LuaSyntaxToken , LuaTokenKind , LuaVarExpr ,
57} ;
68use lsp_types:: { SemanticToken , SemanticTokenModifier , SemanticTokenType } ;
7- use rowan:: NodeOrToken ;
9+ use rowan:: { NodeOrToken , TextRange } ;
810
911use crate :: context:: ClientId ;
1012
@@ -26,21 +28,33 @@ pub fn build_semantic_tokens(
2628 SEMANTIC_TOKEN_MODIFIERS . to_vec ( ) ,
2729 ) ;
2830
31+ // 用于渲染全局方法/标准库
32+ let mut use_range_set = HashSet :: new ( ) ;
33+ calc_name_expr_ref ( semantic_model, & mut use_range_set) ;
34+
2935 for node_or_token in root. syntax ( ) . descendants_with_tokens ( ) {
3036 match node_or_token {
3137 NodeOrToken :: Node ( node) => {
32- build_node_semantic_token ( & mut builder, node, client_id) ;
38+ build_node_semantic_token (
39+ semantic_model,
40+ & mut builder,
41+ node,
42+ & mut use_range_set,
43+ client_id,
44+ ) ;
3345 }
3446 NodeOrToken :: Token ( token) => {
35- build_tokens_semantic_token ( & mut builder, token, client_id) ;
47+ build_tokens_semantic_token ( semantic_model , & mut builder, token, client_id) ;
3648 }
3749 }
3850 }
3951
4052 Some ( builder. build ( ) )
4153}
4254
55+ #[ allow( unused) ]
4356fn build_tokens_semantic_token (
57+ semantic_model : & SemanticModel ,
4458 builder : & mut SemanticBuilder ,
4559 token : LuaSyntaxToken ,
4660 client_id : ClientId ,
@@ -184,15 +198,42 @@ fn build_tokens_semantic_token(
184198 }
185199 }
186200 let position = u32:: from ( range. start ( ) ) + start as u32 ;
187- builder. push_at_position ( position. into ( ) , 1 , SemanticTokenType :: KEYWORD , SemanticTokenModifier :: DOCUMENTATION ) ;
201+ builder. push_at_position (
202+ position. into ( ) ,
203+ 1 ,
204+ SemanticTokenType :: KEYWORD ,
205+ SemanticTokenModifier :: DOCUMENTATION ,
206+ ) ;
188207 }
208+ // LuaTokenKind::TkName => {
209+ // let property_owner = semantic_model.get_property_owner_id(token.clone().into());
210+ // match property_owner {
211+ // Some(LuaPropertyOwnerId::LuaDecl(decl_id)) => {
212+ // let decl = semantic_model.get_db().get_decl_index().get_decl(&decl_id);
213+ // if let Some(decl) = decl {
214+ // let decl_type = decl.get_type();
215+ // if let Some(decl_type) = decl_type {
216+ // match decl_type {
217+ // LuaType::Def(def) => {
218+ // builder.push(token, SemanticTokenType::CLASS);
219+ // }
220+ // _ => {}
221+ // }
222+ // }
223+ // }
224+ // }
225+ // _ => {}
226+ // }
227+ // }
189228 _ => { }
190229 }
191230}
192231
193232fn build_node_semantic_token (
233+ semantic_model : & SemanticModel ,
194234 builder : & mut SemanticBuilder ,
195235 node : LuaSyntaxNode ,
236+ use_range_set : & mut HashSet < TextRange > ,
196237 _: ClientId ,
197238) -> Option < ( ) > {
198239 match LuaAst :: cast ( node) ? {
@@ -289,10 +330,18 @@ fn build_node_semantic_token(
289330 }
290331 LuaAst :: LuaLocalName ( local_name) => {
291332 let name = local_name. get_name_token ( ) ?;
333+ if let Some ( true ) = is_class_def ( semantic_model, local_name. syntax ( ) . clone ( ) ) {
334+ builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: CLASS ) ;
335+ return Some ( ( ) ) ;
336+ }
292337 builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: VARIABLE ) ;
293338 }
294339 LuaAst :: LuaNameExpr ( name_expr) => {
295340 let name = name_expr. get_name_token ( ) ?;
341+ if let Some ( true ) = is_class_def ( semantic_model, name_expr. syntax ( ) . clone ( ) ) {
342+ builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: CLASS ) ;
343+ return Some ( ( ) ) ;
344+ }
296345 builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: VARIABLE ) ;
297346 }
298347 LuaAst :: LuaForRangeStat ( for_range_stat) => {
@@ -339,9 +388,34 @@ fn build_node_semantic_token(
339388 }
340389 LuaAst :: LuaCallExpr ( call_expr) => {
341390 let prefix = call_expr. get_prefix_expr ( ) ?;
391+ let prefix_type = semantic_model. infer_expr ( prefix. clone ( ) ) ;
392+
342393 match prefix {
343394 LuaExpr :: NameExpr ( name_expr) => {
344395 let name = name_expr. get_name_token ( ) ?;
396+
397+ if let Some ( prefix_type) = prefix_type {
398+ match prefix_type {
399+ LuaType :: Signature ( _) => {
400+ let name_text = name_expr. get_name_text ( ) ?;
401+ let name_range = name_expr. get_range ( ) ;
402+ if !use_range_set. contains ( & name_range) {
403+ let decl_index = semantic_model. get_db ( ) . get_decl_index ( ) ;
404+ let member_key = LuaMemberKey :: Name ( name_text. clone ( ) . into ( ) ) ;
405+ if decl_index. get_global_decl_id ( & member_key) . is_some ( ) {
406+ builder. push_with_modifier (
407+ name. syntax ( ) . clone ( ) ,
408+ SemanticTokenType :: FUNCTION ,
409+ SemanticTokenModifier :: DEFAULT_LIBRARY ,
410+ ) ;
411+ return Some ( ( ) ) ;
412+ }
413+ }
414+ }
415+ _ => { }
416+ }
417+ }
418+
345419 builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: FUNCTION ) ;
346420 }
347421 LuaExpr :: IndexExpr ( index_expr) => {
@@ -350,19 +424,6 @@ fn build_node_semantic_token(
350424 }
351425 _ => { }
352426 }
353- // print(a.b.c) -> b.c
354- let args = call_expr. get_args_list ( ) ?;
355- let args_var_exprs = args. descendants :: < LuaVarExpr > ( ) ;
356- for var_expr in args_var_exprs {
357- match var_expr {
358- LuaVarExpr :: IndexExpr ( name_expr) => {
359- let name = name_expr. get_name_token ( ) ?;
360- builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: PROPERTY ) ;
361- }
362- _ => { }
363- }
364- }
365-
366427 }
367428 LuaAst :: LuaDocNameType ( doc_name_type) => {
368429 let name = doc_name_type. get_name_token ( ) ?;
@@ -411,8 +472,46 @@ fn build_node_semantic_token(
411472 builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: PARAMETER ) ;
412473 }
413474 }
475+ LuaAst :: LuaIndexExpr ( index_expr) => {
476+ let name = index_expr. get_name_token ( ) ?;
477+ builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: PROPERTY ) ;
478+ }
414479 _ => { }
415480 }
416481
417482 Some ( ( ) )
418483}
484+
485+ fn is_class_def ( semantic_model : & SemanticModel , node : LuaSyntaxNode ) -> Option < bool > {
486+ let property_owner = semantic_model. get_property_owner_id ( node. into ( ) ) ?;
487+
488+ if let LuaPropertyOwnerId :: LuaDecl ( decl_id) = property_owner {
489+ let decl = semantic_model
490+ . get_db ( )
491+ . get_decl_index ( )
492+ . get_decl ( & decl_id) ?
493+ . get_type ( ) ?;
494+ match decl {
495+ LuaType :: Def ( _) => Some ( true ) ,
496+ _ => None ,
497+ }
498+ } else {
499+ None
500+ }
501+ }
502+
503+ fn calc_name_expr_ref (
504+ semantic_model : & SemanticModel ,
505+ use_range_set : & mut HashSet < TextRange > ,
506+ ) -> Option < ( ) > {
507+ let file_id = semantic_model. get_file_id ( ) ;
508+ let db = semantic_model. get_db ( ) ;
509+ let refs_index = db. get_reference_index ( ) . get_local_reference ( & file_id) ?;
510+ for ( _, decl_refs) in refs_index. get_decl_references_map ( ) {
511+ for decl_ref in decl_refs {
512+ use_range_set. insert ( decl_ref. range . clone ( ) ) ;
513+ }
514+ }
515+
516+ None
517+ }
0 commit comments