11use emmylua_code_analysis:: {
2- instantiate_func_generic, LuaFunctionType , LuaSemanticDeclId , LuaSignature , LuaType ,
3- SemanticModel ,
2+ instantiate_func_generic, LuaCompilation , LuaFunctionType , LuaSemanticDeclId , LuaSignature ,
3+ LuaSignatureId , LuaType , SemanticDeclLevel , SemanticModel ,
44} ;
5- use emmylua_parser:: { LuaAstNode , LuaCallExpr , LuaSyntaxToken } ;
5+ use emmylua_parser:: { LuaAstNode , LuaCallExpr , LuaSyntaxToken , LuaTokenKind } ;
6+ use rowan:: { NodeOrToken , TokenAtOffset } ;
67use std:: sync:: Arc ;
78
8- pub fn find_call_match_function (
9+ pub fn find_call_match_function_for_member (
910 semantic_model : & SemanticModel ,
11+ compilation : & LuaCompilation ,
1012 trigger_token : & LuaSyntaxToken ,
1113 semantic_decls : & Vec < LuaSemanticDeclId > ,
1214) -> Option < Vec < LuaSemanticDeclId > > {
@@ -44,8 +46,14 @@ pub fn find_call_match_function(
4446 } ) {
4547 has_match = true ;
4648 }
47- // 此处为降低优先级, 因为如果返回多个选项, 那么 vscode 会默认指向最后的选项
48- result. insert ( 0 , decl. clone ( ) ) ;
49+ // 无论是否匹配, 都需要将真实的定义添加到结果中
50+ // 如果存在原始定义, 则优先使用原始定义
51+ let origin = get_signature_origin ( compilation, & signature_id) ;
52+ if let Some ( origin) = origin {
53+ result. insert ( 0 , origin) ;
54+ } else {
55+ result. insert ( 0 , decl. clone ( ) ) ;
56+ }
4957 }
5058 _ => continue ,
5159 }
@@ -61,6 +69,96 @@ pub fn find_call_match_function(
6169 }
6270}
6371
72+ fn get_signature_origin (
73+ compilation : & LuaCompilation ,
74+ signature_id : & LuaSignatureId ,
75+ ) -> Option < LuaSemanticDeclId > {
76+ let semantic_model = compilation. get_semantic_model ( signature_id. get_file_id ( ) ) ?;
77+ let root = semantic_model. get_root_by_file_id ( signature_id. get_file_id ( ) ) ?;
78+ let token = match root. syntax ( ) . token_at_offset ( signature_id. get_position ( ) ) {
79+ TokenAtOffset :: Single ( token) => token,
80+ TokenAtOffset :: Between ( left, right) => {
81+ if left. kind ( ) == LuaTokenKind :: TkName . into ( ) {
82+ left
83+ } else if left. kind ( ) == LuaTokenKind :: TkLeftBracket . into ( )
84+ && right. kind ( ) == LuaTokenKind :: TkInt . into ( )
85+ {
86+ left
87+ } else {
88+ right
89+ }
90+ }
91+ TokenAtOffset :: None => {
92+ return None ;
93+ }
94+ } ;
95+ let semantic_info =
96+ semantic_model. find_decl ( NodeOrToken :: Token ( token) , SemanticDeclLevel :: default ( ) ) ;
97+ semantic_info
98+ }
99+
100+ pub fn find_call_expr_origin_for_decl (
101+ semantic_model : & SemanticModel ,
102+ compilation : & LuaCompilation ,
103+ trigger_token : & LuaSyntaxToken ,
104+ semantic_decl : & LuaSemanticDeclId ,
105+ ) -> Option < LuaSemanticDeclId > {
106+ let call_expr = LuaCallExpr :: cast ( trigger_token. parent ( ) ?. parent ( ) ?) ?;
107+ let call_function = get_call_function ( semantic_model, & call_expr) ?;
108+ let decl_id = match semantic_decl {
109+ LuaSemanticDeclId :: LuaDecl ( decl_id) => decl_id,
110+ _ => return None ,
111+ } ;
112+
113+ let typ = semantic_model. get_type ( decl_id. clone ( ) . into ( ) ) ;
114+ match typ {
115+ LuaType :: DocFunction ( func) => {
116+ if compare_function_types ( semantic_model, & call_function, & func, & call_expr) ? {
117+ return Some ( decl_id. clone ( ) . into ( ) ) ;
118+ }
119+ }
120+ LuaType :: Signature ( signature_id) => {
121+ let signature = semantic_model
122+ . get_db ( )
123+ . get_signature_index ( )
124+ . get ( & signature_id) ?;
125+ let functions = get_signature_functions ( signature) ;
126+ if functions. iter ( ) . any ( |func| {
127+ compare_function_types ( semantic_model, & call_function, func, & call_expr)
128+ . unwrap_or ( false )
129+ } ) {
130+ let semantic_model = compilation. get_semantic_model ( signature_id. get_file_id ( ) ) ?;
131+ let root = semantic_model. get_root_by_file_id ( signature_id. get_file_id ( ) ) ?;
132+ let token = match root. syntax ( ) . token_at_offset ( signature_id. get_position ( ) ) {
133+ TokenAtOffset :: Single ( token) => token,
134+ TokenAtOffset :: Between ( left, right) => {
135+ if left. kind ( ) == LuaTokenKind :: TkName . into ( ) {
136+ left
137+ } else if left. kind ( ) == LuaTokenKind :: TkLeftBracket . into ( )
138+ && right. kind ( ) == LuaTokenKind :: TkInt . into ( )
139+ {
140+ left
141+ } else {
142+ right
143+ }
144+ }
145+ TokenAtOffset :: None => {
146+ return None ;
147+ }
148+ } ;
149+ let semantic_info = semantic_model
150+ . find_decl ( NodeOrToken :: Token ( token) , SemanticDeclLevel :: default ( ) ) ;
151+ if let Some ( semantic_info) = semantic_info {
152+ return Some ( semantic_info) ;
153+ }
154+ }
155+ }
156+ _ => return None ,
157+ } ;
158+
159+ None
160+ }
161+
64162/// 获取最匹配的函数(并不能确保完全匹配)
65163fn get_call_function (
66164 semantic_model : & SemanticModel ,
0 commit comments