Skip to content

Commit

Permalink
feat: syntax highlighting for hover content
Browse files Browse the repository at this point in the history
Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

fmt check

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

kcl formatting

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

fmt check

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

updated test cases

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

fmt check

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

feat: syntax highlighting for hover content

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

updated tests

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

updated tests

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

test check

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

feat: syntax highlighting for hover content

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

add markup

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

fmt check

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

resolved func formatting error

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

updated test cases

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

updated tests

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

feat: syntax highlighting for hover content

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

updated test cases for tests.rs

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

feat: syntax highlighting for hover content

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

syntax highlighting with LanguageString

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

fmt check

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

updated tests

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

fmt check

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

fmt check

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

feat: syntax highlighting for hover content

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

updated test case

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

updated tests.rs

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

feat: syntax highlighting for hover content

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

fmt check

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

fixed ci

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

add pkgpath without override

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

updated completion.rs

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

updated tests.rs

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>

feat: syntax highlighting for hover content

Signed-off-by: shruti2522 <shruti.apc01@gmail.com>
  • Loading branch information
shruti2522 committed May 20, 2024
1 parent 86f4a82 commit 2446911
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 64 deletions.
15 changes: 4 additions & 11 deletions kclvm/sema/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ impl SchemaType {
}
}

pub fn schema_ty_signature_str(&self) -> String {
pub fn schema_ty_signature_str(&self) -> (String, String) {
let base: String = if let Some(base) = &self.base {
format!("({})", base.name)
} else {
Expand All @@ -312,17 +312,10 @@ impl SchemaType {
.join(", ")
)
};
let params_str = if !params.is_empty() && !base.is_empty() {
format!("\\{}{}", params, base)
} else if !params.is_empty() {
format!("{}", params)
} else if !base.is_empty() {
format!("{}", base)
} else {
"".to_string()
};

format!("{}\n\nschema {}{}", self.pkgpath, self.name, params_str)
let rest_sign = format!("schema {}{}{}", self.name, params, base);

(self.pkgpath.clone(), rest_sign)
}
}

Expand Down
8 changes: 5 additions & 3 deletions kclvm/tools/src/LSP/src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,8 @@ fn schema_ty_to_value_complete_item(schema_ty: &SchemaType) -> KCLCompletionItem
);
let detail = {
let mut details = vec![];
details.push(schema_ty.schema_ty_signature_str());
let (pkgpath, rest_sign) = schema_ty.schema_ty_signature_str();
details.push(format!("{}\n\n{}", pkgpath, rest_sign));
details.push("Attributes:".to_string());
for (name, attr) in &schema_ty.attrs {
details.push(format!(
Expand Down Expand Up @@ -543,7 +544,8 @@ fn schema_ty_to_value_complete_item(schema_ty: &SchemaType) -> KCLCompletionItem
fn schema_ty_to_type_complete_item(schema_ty: &SchemaType) -> KCLCompletionItem {
let detail = {
let mut details = vec![];
details.push(schema_ty.schema_ty_signature_str());
let (pkgpath, rest_sign) = schema_ty.schema_ty_signature_str();
details.push(format!("{}\n\n{}", pkgpath, rest_sign));
details.push("Attributes:".to_string());
for (name, attr) in &schema_ty.attrs {
details.push(format!(
Expand Down Expand Up @@ -1259,7 +1261,7 @@ mod tests {
label: "Person(b){}".to_string(),
kind: Some(CompletionItemKind::CLASS),
detail: Some(
"__main__\n\nschema Person\\[b: int](Base)\nAttributes:\nc: int"
"__main__\n\nschema Person[b: int](Base)\nAttributes:\nc: int"
.to_string()
),
documentation: Some(lsp_types::Documentation::String("".to_string())),
Expand Down
108 changes: 76 additions & 32 deletions kclvm/tools/src/LSP/src/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use kclvm_sema::{
core::global_state::GlobalState,
ty::{FunctionType, ANY_TYPE_STR},
};
use lsp_types::{Hover, HoverContents, MarkedString};
use lsp_types::{Hover, HoverContents, LanguageString, MarkedString};

use crate::goto_def::find_def_with_gs;

Expand All @@ -17,6 +17,7 @@ pub(crate) fn hover(
gs: &GlobalState,
) -> Option<lsp_types::Hover> {
let mut docs: Vec<String> = vec![];
let mut pkg_path = String::new();
let def = find_def_with_gs(kcl_pos, gs, true);
match def {
Some(def_ref) => match gs.get_symbols().get_symbol(def_ref) {
Expand All @@ -36,7 +37,9 @@ pub(crate) fn hover(
// attr2? type
// ```
let schema_ty = ty.into_schema_type();
docs.push(schema_ty.schema_ty_signature_str());
let (pkgpath, rest_sign) = schema_ty.schema_ty_signature_str();
pkg_path = pkgpath;
docs.push(rest_sign);
if !schema_ty.doc.is_empty() {
docs.push(schema_ty.doc.clone());
}
Expand Down Expand Up @@ -120,26 +123,37 @@ pub(crate) fn hover(
},
None => {}
}
docs_to_hover(docs)
docs_to_hover(docs, pkg_path)
}

// Convert docs to Hover. This function will convert to
// None, Scalar or Array according to the number of positions
fn docs_to_hover(docs: Vec<String>) -> Option<lsp_types::Hover> {
fn docs_to_hover(docs: Vec<String>, pkg_path: String) -> Option<lsp_types::Hover> {
match docs.len() {
0 => None,
1 => Some(Hover {
contents: HoverContents::Scalar(MarkedString::String(docs[0].clone())),
range: None,
}),
_ => Some(Hover {
contents: HoverContents::Array(
docs.iter()
.map(|doc| MarkedString::String(doc.clone()))
.collect(),
),
contents: HoverContents::Scalar(MarkedString::LanguageString(LanguageString {
language: "KCL".to_owned(),
value: docs[0].clone(),
})),
range: None,
}),
_ => {
let mut all_docs = Vec::new();
if !pkg_path.is_empty() {
all_docs.push(MarkedString::String(pkg_path));
}
all_docs.extend(docs.iter().map(|doc| {
MarkedString::LanguageString(LanguageString {
language: "KCL".to_owned(),
value: doc.clone(),
})
}));
Some(Hover {
contents: HoverContents::Array(all_docs),
range: None,
})
}
}
}

Expand Down Expand Up @@ -186,7 +200,7 @@ mod tests {
use std::path::PathBuf;

use kclvm_error::Position as KCLPos;
use lsp_types::MarkedString;
use lsp_types::{LanguageString, MarkedString};
use proc_macro_crate::bench_test;

use crate::tests::compile_test_file;
Expand All @@ -213,12 +227,15 @@ mod tests {
match got.contents {
lsp_types::HoverContents::Array(vec) => {
if let MarkedString::String(s) = vec[0].clone() {
assert_eq!(s, "pkg\n\nschema Person");
assert_eq!(s, "pkg");
}
if let MarkedString::String(s) = vec[1].clone() {
assert_eq!(s, "hover doc test");
assert_eq!(s, "schema Person");
}
if let MarkedString::String(s) = vec[2].clone() {
assert_eq!(s, "hover doc test");
}
if let MarkedString::String(s) = vec[3].clone() {
assert_eq!(s, "Attributes:\n\nname: str\n\nage: int");
}
}
Expand Down Expand Up @@ -251,25 +268,34 @@ mod tests {
];

// When converting to hover content
let hover = docs_to_hover(docs.clone());
let hover = docs_to_hover(docs.clone(), "".to_string());

// Then the result should be a Hover object with an Array of MarkedString::String
// Then the result should be a Hover object with an Array of MarkedString::LanguageString
assert!(hover.is_some());
let hover = hover.unwrap();
match hover.contents {
lsp_types::HoverContents::Array(vec) => {
assert_eq!(vec.len(), 3);
assert_eq!(
vec[0],
MarkedString::String("Documentation string 1".to_string())
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "Documentation string 1".to_string()
})
);
assert_eq!(
vec[1],
MarkedString::String("Documentation string 2".to_string())
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "Documentation string 2".to_string()
})
);
assert_eq!(
vec[2],
MarkedString::String("Documentation string 3".to_string())
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "Documentation string 3".to_string()
})
);
}
_ => panic!("Unexpected hover contents"),
Expand All @@ -291,12 +317,15 @@ mod tests {
match got.contents {
lsp_types::HoverContents::Array(vec) => {
if let MarkedString::String(s) = vec[0].clone() {
assert_eq!(s, "__main__\n\nschema Person");
assert_eq!(s, "__main__");
}
if let MarkedString::String(s) = vec[1].clone() {
assert_eq!(s, "hover doc test");
assert_eq!(s, "schema Person");
}
if let MarkedString::String(s) = vec[2].clone() {
assert_eq!(s, "hover doc test");
}
if let MarkedString::String(s) = vec[3].clone() {
assert_eq!(s, "Attributes:\n\nname: str\n\nage?: int");
}
}
Expand Down Expand Up @@ -499,11 +528,14 @@ mod tests {
let got = hover(&program, &pos, &gs).unwrap();
match got.contents {
lsp_types::HoverContents::Array(vec) => {
assert_eq!(vec.len(), 2);
assert_eq!(vec.len(), 3);
if let MarkedString::String(s) = vec[0].clone() {
assert_eq!(s, "fib\n\nschema Fib");
assert_eq!(s, "fib");
}
if let MarkedString::String(s) = vec[1].clone() {
assert_eq!(s, "schema Fib");
}
if let MarkedString::String(s) = vec[2].clone() {
assert_eq!(s, "Attributes:\n\nn: int\n\nvalue: int");
}
}
Expand Down Expand Up @@ -561,11 +593,16 @@ mod tests {
column: Some(1),
};
let got = hover(&program, &pos, &gs).unwrap();
let expect_content = vec![MarkedString::String(
"fn deprecated(version: str, reason: str, strict: bool) -> any".to_string(),
), MarkedString::String(
"This decorator is used to get the deprecation message according to the wrapped key-value pair.".to_string(),
)];
let expect_content = vec![
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "fn deprecated(version: str, reason: str, strict: bool) -> any".to_string(),
}),
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "This decorator is used to get the deprecation message according to the wrapped key-value pair.".to_string(),
}),
];
match got.contents {
lsp_types::HoverContents::Array(vec) => {
assert_eq!(vec, expect_content)
Expand Down Expand Up @@ -599,8 +636,15 @@ mod tests {
let got = hover(&program, &pos, &gs).unwrap();

let expect_content = vec![
MarkedString::String("__main__\n\nschema Data1\\[m: {str:str}](Data)".to_string()),
MarkedString::String("Attributes:\n\nname: str\n\nage: int".to_string()),
MarkedString::String("__main__".to_string()),
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "schema Data1[m: {str:str}](Data)".to_string(),
}),
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "Attributes:\n\nname: str\n\nage: int".to_string(),
}),
];

match got.contents {
Expand Down
65 changes: 47 additions & 18 deletions kclvm/tools/src/LSP/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use lsp_types::Hover;
use lsp_types::HoverContents;
use lsp_types::HoverParams;
use lsp_types::InitializeParams;
use lsp_types::LanguageString;
use lsp_types::MarkedString;
use lsp_types::PublishDiagnosticsParams;
use lsp_types::ReferenceContext;
Expand Down Expand Up @@ -1169,9 +1170,19 @@ fn hover_test() {
res.result.unwrap(),
to_json(Hover {
contents: HoverContents::Array(vec![
MarkedString::String("__main__\n\nschema Person".to_string()),
MarkedString::String("hover doc test".to_string()),
MarkedString::String("Attributes:\n\nname: str\n\nage?: int".to_string()),
MarkedString::String("__main__".to_string()),
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "schema Person".to_string()
}),
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "hover doc test".to_string()
}),
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "Attributes:\n\nname: str\n\nage?: int".to_string()
}),
]),
range: None
})
Expand Down Expand Up @@ -1225,7 +1236,10 @@ fn hover_assign_in_lambda_test() {
assert_eq!(
res.result.unwrap(),
to_json(Hover {
contents: HoverContents::Scalar(MarkedString::String("images: [str]".to_string()),),
contents: HoverContents::Scalar(MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "images: [str]".to_string(),
})),
range: None
})
.unwrap()
Expand Down Expand Up @@ -1663,12 +1677,21 @@ fn konfig_hover_test_main() {
let got = hover(&program, &pos, &gs).unwrap();
match got.contents {
HoverContents::Array(arr) => {
let expect: Vec<MarkedString> = ["base.pkg.kusion_models.kube.frontend\n\nschema Server",
"Server is abstaction of Deployment and StatefulSet.",
"Attributes:\n\nname?: str\n\nworkloadType: str(Deployment) | str(StatefulSet)\n\nrenderType?: str(Server) | str(KubeVelaApplication)\n\nreplicas: int\n\nimage: str\n\nschedulingStrategy: SchedulingStrategy\n\nmainContainer: Main\n\nsidecarContainers?: [Sidecar]\n\ninitContainers?: [Sidecar]\n\nuseBuiltInLabels?: bool\n\nlabels?: {str:str}\n\nannotations?: {str:str}\n\nuseBuiltInSelector?: bool\n\nselector?: {str:str}\n\npodMetadata?: ObjectMeta\n\nvolumes?: [Volume]\n\nneedNamespace?: bool\n\nenableMonitoring?: bool\n\nconfigMaps?: [ConfigMap]\n\nsecrets?: [Secret]\n\nservices?: [Service]\n\ningresses?: [Ingress]\n\nserviceAccount?: ServiceAccount\n\nstorage?: ObjectStorage\n\ndatabase?: DataBase"]
.iter()
.map(|s| MarkedString::String(s.to_string()))
.collect();
let expect: Vec<MarkedString> = vec![
MarkedString::String("base.pkg.kusion_models.kube.frontend".to_string()),
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "schema Server".to_string(),
}),
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "Server is abstaction of Deployment and StatefulSet.".to_string(),
}),
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "Attributes:\n\nname?: str\n\nworkloadType: str(Deployment) | str(StatefulSet)\n\nrenderType?: str(Server) | str(KubeVelaApplication)\n\nreplicas: int\n\nimage: str\n\nschedulingStrategy: SchedulingStrategy\n\nmainContainer: Main\n\nsidecarContainers?: [Sidecar]\n\ninitContainers?: [Sidecar]\n\nuseBuiltInLabels?: bool\n\nlabels?: {str:str}\n\nannotations?: {str:str}\n\nuseBuiltInSelector?: bool\n\nselector?: {str:str}\n\npodMetadata?: ObjectMeta\n\nvolumes?: [Volume]\n\nneedNamespace?: bool\n\nenableMonitoring?: bool\n\nconfigMaps?: [ConfigMap]\n\nsecrets?: [Secret]\n\nservices?: [Service]\n\ningresses?: [Ingress]\n\nserviceAccount?: ServiceAccount\n\nstorage?: ObjectStorage\n\ndatabase?: DataBase".to_string(),
}),
];
assert_eq!(expect, arr);
}
_ => unreachable!("test error"),
Expand All @@ -1683,13 +1706,16 @@ fn konfig_hover_test_main() {
let got = hover(&program, &pos, &gs).unwrap();
match got.contents {
HoverContents::Array(arr) => {
let expect: Vec<MarkedString> = [
"schedulingStrategy: SchedulingStrategy",
"SchedulingStrategy represents scheduling strategy.",
]
.iter()
.map(|s| MarkedString::String(s.to_string()))
.collect();
let expect: Vec<MarkedString> = vec![
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "schedulingStrategy: SchedulingStrategy".to_string(),
}),
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "SchedulingStrategy represents scheduling strategy.".to_string(),
}),
];
assert_eq!(expect, arr);
}
_ => unreachable!("test error"),
Expand All @@ -1706,7 +1732,10 @@ fn konfig_hover_test_main() {
HoverContents::Scalar(s) => {
assert_eq!(
s,
MarkedString::String("appConfiguration: Server".to_string())
MarkedString::LanguageString(LanguageString {
language: "KCL".to_string(),
value: "appConfiguration: Server".to_string(),
})
);
}
_ => unreachable!("test error"),
Expand Down

0 comments on commit 2446911

Please sign in to comment.