Skip to content

Commit

Permalink
feat: add lsp hover for builtin function (#732)
Browse files Browse the repository at this point in the history
Signed-off-by: He1pa <[email protected]>
  • Loading branch information
He1pa authored Oct 7, 2023
1 parent bea9f06 commit 3156bd2
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 48 deletions.
5 changes: 2 additions & 3 deletions kclvm/sema/src/builtin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,12 @@ register_builtin! {
)
print => Type::function(
None,
Rc::new(Type::ANY),
Rc::new(Type::NONE),
&[],
r#"Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
"#,
end: string appended after the last value, default a newline."#,
true,
None,
)
Expand Down
2 changes: 1 addition & 1 deletion kclvm/sema/src/resolver/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ impl ProgramScope {
}

/// Construct a builtin scope
pub(crate) fn builtin_scope() -> Scope {
pub fn builtin_scope() -> Scope {
let mut elems = IndexMap::default();
for (name, builtin_func) in BUILTIN_FUNCTIONS.iter() {
elems.insert(
Expand Down
22 changes: 20 additions & 2 deletions kclvm/tools/src/LSP/src/goto_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ use kclvm_compiler::pkgpath_without_prefix;
use kclvm_error::Position as KCLPos;

use kclvm_sema::builtin::get_system_member_function_ty;
use kclvm_sema::resolver::scope::{ProgramScope, Scope, ScopeObject, ScopeObjectKind};
use kclvm_sema::resolver::scope::{
builtin_scope, ProgramScope, Scope, ScopeObject, ScopeObjectKind,
};
use kclvm_sema::ty::{DictType, SchemaType};
use lsp_types::{GotoDefinitionResponse, Url};
use lsp_types::{Location, Range};
Expand Down Expand Up @@ -204,7 +206,23 @@ pub(crate) fn resolve_var(
}
_ => Some(Definition::Object(obj.borrow().clone())),
},
None => None,
None => match builtin_scope().lookup(&name) {
Some(obj) => {
let mut obj = obj.borrow().clone();
let doc = {
match &obj.ty.kind {
kclvm_sema::ty::TypeKind::Function(func) => Some(func.doc.clone()),
_ => None,
}
};
obj.kind = ScopeObjectKind::FunctionCall;
obj.doc = doc;
obj.start = node_names[0].get_pos();
obj.end = node_names[0].get_end_pos();
Some(Definition::Object(obj))
}
None => None,
},
}
}
_ => {
Expand Down
22 changes: 21 additions & 1 deletion kclvm/tools/src/LSP/src/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ fn build_func_hover_content(func_ty: &FunctionType, name: String) -> Vec<String>
docs.push(sig);

if !func_ty.doc.is_empty() {
docs.push(func_ty.doc.clone());
docs.push(func_ty.doc.clone().replace("\n", "\n\n"));
}
docs
}
Expand Down Expand Up @@ -336,5 +336,25 @@ mod tests {
}
_ => unreachable!("test error"),
}

let pos = KCLPos {
filename: file.clone(),
line: 25,
column: Some(4),
};
let got = hover(&program, &pos, &prog_scope).unwrap();

match got.contents {
lsp_types::HoverContents::Array(vec) => {
assert_eq!(vec.len(), 2);
if let MarkedString::String(s) = vec[0].clone() {
assert_eq!(s, "fn print() -> NoneType");
}
if let MarkedString::String(s) = vec[1].clone() {
assert_eq!(s, "Prints the values to a stream, or to sys.stdout by default.\n\n Optional keyword arguments:\n\n sep: string inserted between values, default a space.\n\n end: string appended after the last value, default a newline.");
}
}
_ => unreachable!("test error"),
}
}
}
2 changes: 2 additions & 0 deletions kclvm/tools/src/LSP/src/test_data/hover_test/hover.k
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ p = Person{
import base64
abdc = base64.encode("1")
abcd = "a".count()

print(1)
74 changes: 33 additions & 41 deletions kclvm/tools/src/LSP/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1096,47 +1096,39 @@ fn konfig_completion_test_main() {
label: item.to_string(),
}));
let expect: CompletionResponse = into_completion_items(&items).into();
match got {
CompletionResponse::Array(arr) => {
for item in arr {
println!("{:?},", item.label);
}
}
CompletionResponse::List(_) => todo!(),
}
// assert_eq!(got, expect);
// items.clear();

// // import path completion
// let pos = KCLPos {
// filename: main_path_str.clone(),
// line: 1,
// column: Some(35),
// };
// let got = completion(Some('.'), &program, &pos, &prog_scope).unwrap();
// let pkgs = [
// "common",
// "configmap",
// "container",
// "ingress",
// "job",
// "rbac",
// "resource",
// "secret",
// "server",
// "service",
// "serviceaccount",
// "sidecar",
// "storage",
// "strategy",
// "volume",
// ];
// items.extend(pkgs.iter().map(|item| KCLCompletionItem {
// label: item.to_string(),
// }));
// let expect: CompletionResponse = into_completion_items(&items).into();

// assert_eq!(got, expect);
assert_eq!(got, expect);
items.clear();

// import path completion
let pos = KCLPos {
filename: main_path_str.clone(),
line: 1,
column: Some(35),
};
let got = completion(Some('.'), &program, &pos, &prog_scope).unwrap();
let pkgs = [
"common",
"configmap",
"container",
"ingress",
"job",
"rbac",
"resource",
"secret",
"server",
"service",
"serviceaccount",
"sidecar",
"storage",
"strategy",
"volume",
];
items.extend(pkgs.iter().map(|item| KCLCompletionItem {
label: item.to_string(),
}));
let expect: CompletionResponse = into_completion_items(&items).into();

assert_eq!(got, expect);
}

#[test]
Expand Down

0 comments on commit 3156bd2

Please sign in to comment.