Skip to content

Commit

Permalink
feat: enhance lsp hover. Hover for schema varibale display schema pkg…
Browse files Browse the repository at this point in the history
…, schema name, doc and attrs
  • Loading branch information
He1pa committed Aug 2, 2023
1 parent fd85ed0 commit 4aad50f
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 9 deletions.
4 changes: 2 additions & 2 deletions kclvm/sema/src/resolver/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ pub(crate) fn parse_doc_string(ori: &String) -> Doc {
}

/// The Doc struct contains a summary of schema and all the attributes described in the the docstring.
#[derive(Debug)]
#[derive(Debug, PartialEq, Eq, Clone)]
pub(crate) struct Doc {
pub summary: String,
pub attrs: Vec<Attribute>,
Expand All @@ -287,7 +287,7 @@ impl Doc {
}

/// The Attribute struct contains the attribute name and the corresponding description.
#[derive(Debug)]
#[derive(Debug, PartialEq, Eq, Clone)]
pub(crate) struct Attribute {
pub name: String,
pub desc: Vec<String>,
Expand Down
47 changes: 42 additions & 5 deletions kclvm/tools/src/LSP/src/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,51 @@ pub(crate) fn hover(
if let crate::goto_def::Definition::Object(obj) = def {
match obj.kind {
ScopeObjectKind::Definition => {
docs.insert(obj.ty.ty_str());
let doc = obj.ty.into_schema_type().doc.clone();
if !doc.is_empty() {
docs.insert(doc);
// Schema Definition hover
// ```
// pkg
// schema Foo(Base)
// -----------------
// doc
// -----------------
// Attributes:
// attr1: type
// attr2? type
// ```
let schema_ty = obj.ty.into_schema_type();
let base: String = if let Some(base) = schema_ty.base {
format!("({})", base.name)
} else {
"".to_string()
};
docs.insert(format!(
"{}\n\nschema {}{}",
schema_ty.pkgpath, schema_ty.name, base
));
if !schema_ty.doc.is_empty() {
docs.insert(schema_ty.doc.clone());
}
let mut attrs = vec!["Attributes:".to_string()];
for (name, attr) in schema_ty.attrs {
attrs.push(format!(
"{}{}:{}",
name,
if attr.is_optional { "?" } else { "" },
format!(" {}", attr.ty.ty_str()),
));
}
docs.insert(attrs.join("\n\n"));
}
// todo: hover ScopeObjectKind::Attribute optional, default value
_ => {
docs.insert(obj.ty.ty_str());
// Variable
// ```
// name: type
//```
docs.insert(format!("{}: {}", obj.name, obj.ty.ty_str()));
if let Some(doc) = obj.doc {
docs.insert(doc);
}
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions kclvm/tools/src/LSP/src/test_data/hover_test/hover.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
schema Person:
"""
hover doc test

Attributes
----------
name : str, default is False, required
name doc test
age : int, default is False, optional
age doc test
"""
name: str
age?: int

p = Person{
name: "Alice"
age: 1
}
83 changes: 81 additions & 2 deletions kclvm/tools/src/LSP/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,11 +796,17 @@ fn schema_doc_hover_test() {
match got.contents {
lsp_types::HoverContents::Array(vec) => {
if let MarkedString::String(s) = vec[0].clone() {
assert_eq!(s, "Person");
assert_eq!(s, "pkg\n\nschema Person");
}
if let MarkedString::String(s) = vec[1].clone() {
assert_eq!(s, "hover doc test");
}
if let MarkedString::String(s) = vec[2].clone() {
assert_eq!(
s,
"Attributes:\n\n__settings__?: {str:any}\n\nname: str\n\nage: int"
);
}
}
_ => unreachable!("test error"),
}
Expand All @@ -813,7 +819,80 @@ fn schema_doc_hover_test() {
match got.contents {
lsp_types::HoverContents::Scalar(marked_string) => {
if let MarkedString::String(s) = marked_string {
assert_eq!(s, "str");
assert_eq!(s, "name: str");
}
}
_ => unreachable!("test error"),
}
}

#[test]
fn schema_doc_hover_test1() {
let (file, program, prog_scope, _) = compile_test_file("src/test_data/hover_test/hover.k");

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

match got.contents {
lsp_types::HoverContents::Array(vec) => {
if let MarkedString::String(s) = vec[0].clone() {
assert_eq!(s, "__main__\n\nschema Person");
}
if let MarkedString::String(s) = vec[1].clone() {
assert_eq!(s, "hover doc test");
}
if let MarkedString::String(s) = vec[2].clone() {
assert_eq!(
s,
"Attributes:\n\n__settings__?: {str:any}\n\nname: str\n\nage?: int"
);
}
}
_ => unreachable!("test error"),
}
}

#[test]
fn schema_attr_hover_test() {
let (file, program, prog_scope, _) = compile_test_file("src/test_data/hover_test/hover.k");

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

match got.contents {
lsp_types::HoverContents::Array(vec) => {
if let MarkedString::String(s) = vec[0].clone() {
assert_eq!(s, "name: str");
}
if let MarkedString::String(s) = vec[1].clone() {
assert_eq!(s, "name doc test");
}
}
_ => unreachable!("test error"),
}

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

match got.contents {
lsp_types::HoverContents::Array(vec) => {
if let MarkedString::String(s) = vec[0].clone() {
assert_eq!(s, "age: int");
}
if let MarkedString::String(s) = vec[1].clone() {
assert_eq!(s, "age doc test");
}
}
_ => unreachable!("test error"),
Expand Down

0 comments on commit 4aad50f

Please sign in to comment.