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 ,
@@ -120,7 +134,6 @@ fn build_tokens_semantic_token(
120134 | LuaTokenKind :: TkTagAsync
121135 | LuaTokenKind :: TkTagCast
122136 | LuaTokenKind :: TkTagOther
123- | LuaTokenKind :: TkTagVisibility
124137 | LuaTokenKind :: TkTagReadonly
125138 | LuaTokenKind :: TkTagDiagnostic
126139 | LuaTokenKind :: TkTagMeta
@@ -151,7 +164,7 @@ fn build_tokens_semantic_token(
151164 LuaTokenKind :: TkDocQuestion => {
152165 builder. push ( token, SemanticTokenType :: OPERATOR ) ;
153166 }
154- LuaTokenKind :: TkDocVisibility => {
167+ LuaTokenKind :: TkDocVisibility | LuaTokenKind :: TkTagVisibility => {
155168 builder. push_with_modifier (
156169 token,
157170 SemanticTokenType :: KEYWORD ,
@@ -192,19 +205,45 @@ fn build_tokens_semantic_token(
192205 SemanticTokenModifier :: DOCUMENTATION ,
193206 ) ;
194207 }
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+ // }
195228 _ => { }
196229 }
197230}
198231
199232fn build_node_semantic_token (
233+ semantic_model : & SemanticModel ,
200234 builder : & mut SemanticBuilder ,
201235 node : LuaSyntaxNode ,
236+ use_range_set : & mut HashSet < TextRange > ,
202237 _: ClientId ,
203238) -> Option < ( ) > {
204239 match LuaAst :: cast ( node) ? {
205240 LuaAst :: LuaDocTagClass ( doc_class) => {
206241 let name = doc_class. get_name_token ( ) ?;
207- builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: CLASS ) ;
242+ builder. push_with_modifier (
243+ name. syntax ( ) . clone ( ) ,
244+ SemanticTokenType :: CLASS ,
245+ SemanticTokenModifier :: DECLARATION ,
246+ ) ;
208247 if let Some ( attribs) = doc_class. get_attrib ( ) {
209248 for attrib_token in attribs. get_attrib_tokens ( ) {
210249 builder. push ( attrib_token. syntax ( ) . clone ( ) , SemanticTokenType :: MODIFIER ) ;
@@ -213,7 +252,11 @@ fn build_node_semantic_token(
213252 if let Some ( generic_list) = doc_class. get_generic_decl ( ) {
214253 for generic_decl in generic_list. get_generic_decl ( ) {
215254 if let Some ( name) = generic_decl. get_name_token ( ) {
216- builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: TYPE_PARAMETER ) ;
255+ builder. push_with_modifier (
256+ name. syntax ( ) . clone ( ) ,
257+ SemanticTokenType :: CLASS ,
258+ SemanticTokenModifier :: DECLARATION ,
259+ ) ;
217260 }
218261 }
219262 }
@@ -265,7 +308,11 @@ fn build_node_semantic_token(
265308 let type_parameter_list = doc_generic. get_generic_decl_list ( ) ?;
266309 for type_decl in type_parameter_list. get_generic_decl ( ) {
267310 if let Some ( name) = type_decl. get_name_token ( ) {
268- builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: TYPE_PARAMETER ) ;
311+ builder. push_with_modifier (
312+ name. syntax ( ) . clone ( ) ,
313+ SemanticTokenType :: TYPE ,
314+ SemanticTokenModifier :: DECLARATION ,
315+ ) ;
269316 }
270317 }
271318 }
@@ -283,10 +330,18 @@ fn build_node_semantic_token(
283330 }
284331 LuaAst :: LuaLocalName ( local_name) => {
285332 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+ }
286337 builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: VARIABLE ) ;
287338 }
288339 LuaAst :: LuaNameExpr ( name_expr) => {
289340 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+ }
290345 builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: VARIABLE ) ;
291346 }
292347 LuaAst :: LuaForRangeStat ( for_range_stat) => {
@@ -315,15 +370,52 @@ fn build_node_semantic_token(
315370 }
316371 }
317372 }
373+ LuaAst :: LuaLocalStat ( local_stat) => {
374+ let var_exprs = local_stat. descendants :: < LuaVarExpr > ( ) ;
375+ for var_expr in var_exprs {
376+ match var_expr {
377+ LuaVarExpr :: IndexExpr ( name_expr) => {
378+ let name = name_expr. get_name_token ( ) ?;
379+ builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: PROPERTY ) ;
380+ }
381+ _ => { }
382+ }
383+ }
384+ }
318385 LuaAst :: LuaLocalAttribute ( local_attribute) => {
319386 let name = local_attribute. get_name_token ( ) ?;
320387 builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: KEYWORD ) ;
321388 }
322389 LuaAst :: LuaCallExpr ( call_expr) => {
323390 let prefix = call_expr. get_prefix_expr ( ) ?;
391+ let prefix_type = semantic_model. infer_expr ( prefix. clone ( ) ) ;
392+
324393 match prefix {
325394 LuaExpr :: NameExpr ( name_expr) => {
326395 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+
327419 builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: FUNCTION ) ;
328420 }
329421 LuaExpr :: IndexExpr ( index_expr) => {
@@ -336,7 +428,11 @@ fn build_node_semantic_token(
336428 LuaAst :: LuaDocNameType ( doc_name_type) => {
337429 let name = doc_name_type. get_name_token ( ) ?;
338430 if name. get_name_text ( ) == "self" {
339- builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: KEYWORD ) ;
431+ builder. push_with_modifier (
432+ name. syntax ( ) . clone ( ) ,
433+ SemanticTokenType :: TYPE ,
434+ SemanticTokenModifier :: READONLY ,
435+ ) ;
340436 } else {
341437 builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: TYPE ) ;
342438 }
@@ -376,8 +472,46 @@ fn build_node_semantic_token(
376472 builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: PARAMETER ) ;
377473 }
378474 }
475+ LuaAst :: LuaIndexExpr ( index_expr) => {
476+ let name = index_expr. get_name_token ( ) ?;
477+ builder. push ( name. syntax ( ) . clone ( ) , SemanticTokenType :: PROPERTY ) ;
478+ }
379479 _ => { }
380480 }
381481
382482 Some ( ( ) )
383483}
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