Skip to content

Commit

Permalink
feat: completion for import builtin pkgs (kcl-lang#801)
Browse files Browse the repository at this point in the history
Signed-off-by: He1pa <[email protected]>
  • Loading branch information
He1pa authored Oct 26, 2023
1 parent f3d8614 commit b4a784e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 4 deletions.
3 changes: 0 additions & 3 deletions kclvm/config/src/vfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ pub fn fix_import_path(root: &str, filepath: &str, import_path: &str) -> String
// abspath: import path.to.sub
// FixImportPath(root, "path/to/app/file.k", "path.to.sub") => path.to.sub

debug_assert!(!filepath.is_empty());
debug_assert!(!import_path.is_empty());

if !import_path.starts_with('.') {
return import_path.to_string();
}
Expand Down
73 changes: 72 additions & 1 deletion kclvm/tools/src/LSP/src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ use kclvm_compiler::pkgpath_without_prefix;
use kclvm_config::modfile::KCL_FILE_EXTENSION;

use kclvm_error::Position as KCLPos;
use kclvm_sema::builtin::{get_system_module_members, STRING_MEMBER_FUNCTIONS};
use kclvm_sema::builtin::{
get_system_module_members, STANDARD_SYSTEM_MODULES, STRING_MEMBER_FUNCTIONS,
};
use kclvm_sema::resolver::scope::{ProgramScope, ScopeObjectKind};
use lsp_types::CompletionItem;

Expand All @@ -41,6 +43,8 @@ pub(crate) fn completion(

completions.extend(completion_attr(program, pos, prog_scope));

completions.extend(completion_import_builtin_pkg(program, pos, prog_scope));

Some(into_completion_items(&completions).into())
}
}
Expand Down Expand Up @@ -72,6 +76,32 @@ fn completion_dot(
}
}

fn completion_import_builtin_pkg(
program: &Program,
pos: &KCLPos,
_prog_scope: &ProgramScope,
) -> IndexSet<KCLCompletionItem> {
let mut completions: IndexSet<KCLCompletionItem> = IndexSet::new();
// completion position not contained in import stmt
// import <space> <cursor>
// | | | <- input `m` here for complete `math`
// |<----------->| <- import stmt only contains this range, so we need to check the beginning of line
let line_start_pos = &KCLPos {
filename: pos.filename.clone(),
line: pos.line,
column: Some(0),
};

if let Some(node) = program.pos_to_stmt(line_start_pos) {
if let Stmt::Import(_) = node.node {
completions.extend(STANDARD_SYSTEM_MODULES.iter().map(|s| KCLCompletionItem {
label: s.to_string(),
}))
}
}
completions
}

/// Complete schema attr
fn completion_attr(
program: &Program,
Expand Down Expand Up @@ -633,4 +663,45 @@ mod tests {
let expect: CompletionResponse = into_completion_items(&items).into();
assert_eq!(got, expect);
}

#[test]
#[bench_test]
fn import_builtin_package() {
let (file, program, prog_scope, _) =
compile_test_file("src/test_data/completion_test/import/import.k");
let mut items: IndexSet<KCLCompletionItem> = IndexSet::new();

// test completion for builtin packages
let pos = KCLPos {
filename: file.to_owned(),
line: 1,
column: Some(8),
};

let got = completion(None, &program, &pos, &prog_scope).unwrap();

items.extend(
[
"", // generate from error recovery
"collection",
"net",
"manifests",
"math",
"datetime",
"regex",
"yaml",
"json",
"crypto",
"base64",
"units",
]
.iter()
.map(|name| KCLCompletionItem {
label: name.to_string(),
})
.collect::<IndexSet<KCLCompletionItem>>(),
);
let expect: CompletionResponse = into_completion_items(&items).into();
assert_eq!(got, expect);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import

0 comments on commit b4a784e

Please sign in to comment.