Skip to content

Commit 06cbc9d

Browse files
committed
optimize semantic
1 parent 75ea6fe commit 06cbc9d

File tree

4 files changed

+125
-22
lines changed

4 files changed

+125
-22
lines changed

crates/emmylua_code_analysis/src/semantic/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ impl<'a> SemanticModel<'a> {
136136
}
137137

138138
pub fn get_property_owner_id(
139-
&mut self,
139+
&self,
140140
node_or_token: NodeOrToken<LuaSyntaxNode, LuaSyntaxToken>,
141141
) -> Option<LuaPropertyOwnerId> {
142142
match node_or_token {

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
mod infer_expr_property_owner;
22

33
use emmylua_parser::{
4-
LuaAstNode, LuaDocNameType, LuaDocTag, LuaExpr, LuaSyntaxKind, LuaSyntaxNode, LuaSyntaxToken,
5-
LuaTableField,
4+
LuaAstNode, LuaAstToken, LuaDocNameType, LuaDocTag, LuaExpr, LuaLocalName, LuaSyntaxKind, LuaSyntaxNode, LuaSyntaxToken, LuaTableField
65
};
76
use infer_expr_property_owner::infer_expr_property_owner;
87

@@ -207,6 +206,11 @@ pub fn infer_node_property_owner(
207206
_ => return None,
208207
}
209208
}
209+
local_name if LuaLocalName::can_cast(local_name.kind().into()) => {
210+
let local_name = LuaLocalName::cast(local_name)?;
211+
let name_token = local_name.get_name_token()?;
212+
infer_token_property_owner(db, infer_config, name_token.syntax().clone())
213+
}
210214
_ => None,
211215
}
212216
}

crates/emmylua_ls/src/handlers/definition/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub async fn on_goto_definition_handler(
2525
let analysis = context.analysis.read().await;
2626
let file_id = analysis.get_file_id(&uri)?;
2727
let position = params.text_document_position_params.position;
28-
let mut semantic_model = analysis.compilation.get_semantic_model(file_id)?;
28+
let semantic_model = analysis.compilation.get_semantic_model(file_id)?;
2929
let root = semantic_model.get_root();
3030
let position_offset = {
3131
let document = semantic_model.get_document();

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

Lines changed: 117 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
use emmylua_code_analysis::SemanticModel;
1+
use std::collections::HashSet;
2+
3+
use emmylua_code_analysis::{LuaMemberKey, LuaPropertyOwnerId, LuaType, SemanticModel};
24
use emmylua_parser::{
35
LuaAst, LuaAstNode, LuaAstToken, LuaDocFieldKey, LuaDocObjectFieldKey, LuaExpr, LuaNameToken,
46
LuaSyntaxNode, LuaSyntaxToken, LuaTokenKind, LuaVarExpr,
57
};
68
use lsp_types::{SemanticToken, SemanticTokenModifier, SemanticTokenType};
7-
use rowan::NodeOrToken;
9+
use rowan::{NodeOrToken, TextRange};
810

911
use 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)]
4356
fn 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

193232
fn 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

Comments
 (0)