diff --git a/kclvm/tools/src/LSP/src/goto_def.rs b/kclvm/tools/src/LSP/src/goto_def.rs index 2278bc133..ebbdb9f0a 100644 --- a/kclvm/tools/src/LSP/src/goto_def.rs +++ b/kclvm/tools/src/LSP/src/goto_def.rs @@ -14,7 +14,7 @@ use kclvm_ast::ast::{Expr, Identifier, ImportStmt, Node, Program, Stmt}; use kclvm_compiler::pkgpath_without_prefix; use kclvm_error::Position as KCLPos; -use kclvm_sema::builtin::get_system_member_function_ty; +use kclvm_sema::builtin::{get_system_member_function_ty, STRING_MEMBER_FUNCTIONS}; use kclvm_sema::resolver::scope::{ builtin_scope, ProgramScope, Scope, ScopeObject, ScopeObjectKind, }; @@ -334,6 +334,29 @@ pub(crate) fn resolve_var( None => None, } } + kclvm_sema::ty::TypeKind::Str => { + if names.len() == 2 { + let func_name_node = node_names[1].clone(); + let func_name = func_name_node.node.clone(); + if let Some(ty) = STRING_MEMBER_FUNCTIONS.get(&func_name) { + match &ty.kind { + kclvm_sema::ty::TypeKind::Function(func_ty) => { + return Some(Definition::Object(ScopeObject { + name: func_name, + start: func_name_node.get_pos(), + end: func_name_node.get_end_pos(), + ty: Rc::new(ty.clone()), + kind: ScopeObjectKind::FunctionCall, + doc: Some(func_ty.doc.clone()), + })) + } + // unreachable + _ => {} + } + } + } + None + } _ => None, }, None => None, diff --git a/kclvm/tools/src/LSP/src/hover.rs b/kclvm/tools/src/LSP/src/hover.rs index dc6755de5..5bd8cea5a 100644 --- a/kclvm/tools/src/LSP/src/hover.rs +++ b/kclvm/tools/src/LSP/src/hover.rs @@ -377,4 +377,31 @@ mod tests { _ => unreachable!("test error"), } } + + #[test] + #[bench_test] + fn str_var_func_hover() { + let (file, program, prog_scope, _) = compile_test_file("src/test_data/hover_test/hover.k"); + let pos = KCLPos { + filename: file.clone(), + line: 28, + column: Some(12), + }; + let got = hover(&program, &pos, &prog_scope).unwrap(); + match got.contents { + lsp_types::HoverContents::Array(vec) => { + assert_eq!(vec.len(), 3); + if let MarkedString::String(s) = vec[0].clone() { + assert_eq!(s, "str\n\n"); + } + if let MarkedString::String(s) = vec[1].clone() { + assert_eq!(s, "fn capitalize() -> str"); + } + if let MarkedString::String(s) = vec[2].clone() { + assert_eq!(s, "Return a copy of the string with its first character capitalized and the rest lowercased."); + } + } + _ => unreachable!("test error"), + } + } } diff --git a/kclvm/tools/src/LSP/src/test_data/hover_test/hover.k b/kclvm/tools/src/LSP/src/test_data/hover_test/hover.k index 8eeff9c47..db7a0f73d 100644 --- a/kclvm/tools/src/LSP/src/test_data/hover_test/hover.k +++ b/kclvm/tools/src/LSP/src/test_data/hover_test/hover.k @@ -23,3 +23,6 @@ abdc = base64.encode("1") abcd = "a".count() print(1) + +a = "".capitalize() +b = a.capitalize()