From 5ae3432f4c8e2f7b5c955ad5051fb2bdd3e75689 Mon Sep 17 00:00:00 2001 From: shruti2522 Date: Fri, 31 May 2024 16:06:53 +0530 Subject: [PATCH] feat: added FunctionSymbol Signed-off-by: shruti2522 fmt check Signed-off-by: shruti2522 feat: added FunctionSymbol Signed-off-by: shruti2522 fmt check Signed-off-by: shruti2522 feat: added FunctionSymbol Signed-off-by: shruti2522 add function symbol kind to lsp Signed-off-by: shruti2522 update function symbol def Signed-off-by: shruti2522 fmt check Signed-off-by: shruti2522 fix ci Signed-off-by: shruti2522 fix ci Signed-off-by: shruti2522 feat: added FunctionSymbol Signed-off-by: shruti2522 add tests to sema_token Signed-off-by: shruti2522 add get_function_symbol Signed-off-by: shruti2522 highlight for func call Signed-off-by: shruti2522 fmt check Signed-off-by: shruti2522 fmt check Signed-off-by: shruti2522 modify walk_call_expr Signed-off-by: shruti2522 update namer for func_name Signed-off-by: shruti2522 feat: distinguish highlight for func symbol and normal var symbol Signed-off-by: shruti2522 update alloc_function_symbol Signed-off-by: shruti2522 function symbol for builtin functions Signed-off-by: shruti2522 update function symbol def Signed-off-by: shruti2522 delete test.log Signed-off-by: shruti2522 remove func symbol from walk_call_expr Signed-off-by: shruti2522 update walk_call_expr for namer Signed-off-by: shruti2522 update sema test Signed-off-by: shruti2522 feat: added FunctionSymbol Signed-off-by: shruti2522 add function symbol kind in global state Signed-off-by: shruti2522 update hover to handle func symbolkind Signed-off-by: shruti2522 add condition for symbolkind in hover Signed-off-by: shruti2522 fmt check Signed-off-by: shruti2522 remove print statements Signed-off-by: shruti2522 update loader snapshots Signed-off-by: shruti2522 fix advanced resolver Signed-off-by: shruti2522 feat: added FunctionSymbol Signed-off-by: shruti2522 update assign stmt for lambda expr Signed-off-by: shruti2522 update resolve_names for identifier_expr Signed-off-by: shruti2522 update semantic tokens with function type Signed-off-by: shruti2522 feat: api list_variables supports get variables from multi-files (#1389) * feat: api list_variables supports get variables from multi-files Signed-off-by: zongz * fix: fix CR comments Signed-off-by: zongz * fix: fix test cases Signed-off-by: zongz --------- Signed-off-by: zongz feat: advance resolver incremental compile (#1209) feat: advanced resolver incremental compile. 1. Namer and Advanced Resolver support incremental compilation, clear cache by pkg and only update new pkg 2. Add gs cache in lsp state 3. Namer and Advanced Resolver modify gs in place(&mut) to reduce clone Signed-off-by: he1pa <18012015693@163.com> feat: added FunctionSymbol Signed-off-by: shruti2522 resolve conflicts Signed-off-by: shruti2522 resolve conflicts Signed-off-by: shruti2522 feat: added FunctionSymbol Signed-off-by: shruti2522 resolve conflicts Signed-off-by: shruti2522 remove duplicate code Signed-off-by: shruti2522 fmt check Signed-off-by: shruti2522 remove repititions Signed-off-by: shruti2522 fmt check Signed-off-by: shruti2522 feat: added FunctionSymbol Signed-off-by: shruti2522 --- kclvm/api/src/service/service_impl.rs | 8 +- kclvm/api/src/testdata/list-variables.json | 2 +- kclvm/api/src/testdata/rename/main.k | 0 kclvm/loader/src/lib.rs | 8 +- .../kclvm_loader__tests__assign_stmt_0.snap | 2 +- .../kclvm_loader__tests__assign_stmt_1.snap | 2 +- .../kclvm_loader__tests__assign_stmt_2.snap | 3 +- .../kclvm_loader__tests__builtin_call_0.snap | 61 ++-- .../kclvm_loader__tests__builtin_call_1.snap | 183 +++++------ .../kclvm_loader__tests__builtin_call_2.snap | 187 +++++------ .../kclvm_loader__tests__import_stmt_0.snap | 69 +++-- .../kclvm_loader__tests__import_stmt_1.snap | 3 +- kclvm/query/src/selector.rs | 38 ++- .../test_list_merged_variables/kcl.mod | 5 + .../override/base.k | 11 + .../override/main.k | 6 + .../test_list_merged_variables/test.k | 7 + .../test_list_merged_variables/union/base.k | 11 + .../test_list_merged_variables/union/main.k | 6 + kclvm/query/src/tests.rs | 67 +++- kclvm/sema/src/advanced_resolver/mod.rs | 39 ++- kclvm/sema/src/advanced_resolver/node.rs | 106 +++++-- kclvm/sema/src/core/global_state.rs | 165 +++++++--- kclvm/sema/src/core/package.rs | 8 + kclvm/sema/src/core/scope.rs | 31 +- kclvm/sema/src/core/symbol.rs | 293 +++++++++++++++++- kclvm/sema/src/namer/mod.rs | 113 ++++--- kclvm/sema/src/namer/node.rs | 30 ++ kclvm/sema/src/resolver/arg.rs | 1 + kclvm/sema/src/resolver/mod.rs | 12 +- kclvm/sema/src/resolver/node.rs | 22 +- kclvm/sema/src/resolver/schema.rs | 3 + kclvm/sema/src/resolver/scope.rs | 11 +- kclvm/sema/src/resolver/ty.rs | 3 + kclvm/spec/gpyrpc/gpyrpc.proto | 2 +- kclvm/tools/src/LSP/src/document_symbol.rs | 1 + kclvm/tools/src/LSP/src/find_refs.rs | 21 +- kclvm/tools/src/LSP/src/hover.rs | 3 +- kclvm/tools/src/LSP/src/quick_fix.rs | 1 + kclvm/tools/src/LSP/src/rename.rs | 10 +- kclvm/tools/src/LSP/src/request.rs | 6 - kclvm/tools/src/LSP/src/semantic_token.rs | 17 +- kclvm/tools/src/LSP/src/state.rs | 8 + .../tools/src/LSP/src/test_data/sema_token.k | 6 +- kclvm/tools/src/LSP/src/tests.rs | 10 + kclvm/tools/src/LSP/src/util.rs | 40 ++- 46 files changed, 1173 insertions(+), 468 deletions(-) create mode 100644 kclvm/api/src/testdata/rename/main.k create mode 100644 kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/kcl.mod create mode 100644 kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/override/base.k create mode 100644 kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/override/main.k create mode 100644 kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/test.k create mode 100644 kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/union/base.k create mode 100644 kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/union/main.k diff --git a/kclvm/api/src/service/service_impl.rs b/kclvm/api/src/service/service_impl.rs index cce3184e5..681088c16 100644 --- a/kclvm/api/src/service/service_impl.rs +++ b/kclvm/api/src/service/service_impl.rs @@ -231,7 +231,7 @@ impl KclvmServiceImpl { }, module_cache, scope_cache, - GlobalState::default(), + &mut GlobalState::default(), )?; if args.with_ast_index { // Thread local options @@ -351,7 +351,7 @@ impl KclvmServiceImpl { /// /// let serv = KclvmServiceImpl::default(); /// let args = &ListVariablesArgs { - /// file: Path::new(".").join("src").join("testdata").join("variables").join("main.k").canonicalize().unwrap().display().to_string(), + /// files: vec![Path::new(".").join("src").join("testdata").join("variables").join("main.k").canonicalize().unwrap().display().to_string()], /// specs: vec!["a".to_string()] /// }; /// let result = serv.list_variables(args).unwrap(); @@ -359,10 +359,10 @@ impl KclvmServiceImpl { /// assert_eq!(result.variables.get("a").unwrap().value, "1"); /// ``` pub fn list_variables(&self, args: &ListVariablesArgs) -> anyhow::Result { - let k_file = args.file.to_string(); + let k_files = args.files.clone(); let specs = args.specs.clone(); - let select_res = list_variables(k_file, specs)?; + let select_res = list_variables(k_files, specs)?; let variables: HashMap = select_res .variables diff --git a/kclvm/api/src/testdata/list-variables.json b/kclvm/api/src/testdata/list-variables.json index b03e74c3e..db27f88b9 100644 --- a/kclvm/api/src/testdata/list-variables.json +++ b/kclvm/api/src/testdata/list-variables.json @@ -1,4 +1,4 @@ { - "file": "./src/testdata/variables/main.k", + "files": ["./src/testdata/variables/main.k"], "specs": ["a", "b", "c"] } diff --git a/kclvm/api/src/testdata/rename/main.k b/kclvm/api/src/testdata/rename/main.k new file mode 100644 index 000000000..e69de29bb diff --git a/kclvm/loader/src/lib.rs b/kclvm/loader/src/lib.rs index a79a6dbcf..f418e6c5c 100644 --- a/kclvm/loader/src/lib.rs +++ b/kclvm/loader/src/lib.rs @@ -116,7 +116,7 @@ pub fn load_packages(opts: &LoadPackageOptions) -> Result { opts, KCLModuleCache::default(), KCLScopeCache::default(), - GlobalState::default(), + &mut GlobalState::default(), ) } @@ -126,7 +126,7 @@ pub fn load_packages_with_cache( opts: &LoadPackageOptions, module_cache: KCLModuleCache, scope_cache: KCLScopeCache, - gs: GlobalState, + gs: &mut GlobalState, ) -> Result { let sess = ParseSessionRef::default(); let paths: Vec<&str> = opts.paths.iter().map(|s| s.as_str()).collect(); @@ -149,8 +149,8 @@ pub fn load_packages_with_cache( Some(scope_cache), ); let node_ty_map = prog_scope.node_ty_map; - let gs = Namer::find_symbols(&program, gs); - let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map.clone())?; + Namer::find_symbols(&program, gs); + AdvancedResolver::resolve_program(&program, gs, node_ty_map.clone())?; (program, prog_scope.handler.diagnostics.clone(), gs) } else { (parse_result.program, IndexSet::default(), gs) diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_0.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_0.snap index 3cabd1912..1d06934cc 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_0.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_0.snap @@ -38,7 +38,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 165, + index: 0, generation: 0, }, kind: Value, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_1.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_1.snap index 3041ea0fb..a131247b2 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_1.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_1.snap @@ -38,7 +38,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 165, + index: 0, generation: 0, }, kind: Value, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_2.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_2.snap index 49364f4d5..1a58a78ce 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_2.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_2.snap @@ -1,5 +1,6 @@ --- source: loader/src/tests.rs +assertion_line: 27 expression: "format!(\"{:#?}\", p.symbols.values())" --- [ @@ -38,7 +39,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 165, + index: 0, generation: 0, }, kind: Value, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_0.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_0.snap index 0ab77f544..3a1c055e2 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_0.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_0.snap @@ -1,5 +1,6 @@ --- source: loader/src/tests.rs +assertion_line: 37 expression: "format!(\"{:#?}\", p.symbols.values())" --- [ @@ -46,7 +47,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 1, generation: 0, }, - kind: Value, + kind: Function, }, ), attrs: [], @@ -93,203 +94,203 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 136, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 137, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 138, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 139, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 140, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 141, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 142, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 143, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 144, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 145, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 146, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 147, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 148, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 149, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 150, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 151, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 152, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 153, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 154, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 155, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 156, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 157, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 158, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 159, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 160, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 161, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 162, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 163, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 164, generation: 0, }, - kind: Value, + kind: Function, }, ], is_global: false, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_1.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_1.snap index 7d3e01618..0669b76e1 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_1.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_1.snap @@ -1,5 +1,6 @@ --- source: loader/src/tests.rs +assertion_line: 38 expression: "format!(\"{:#?}\", p.symbols.values())" --- [ @@ -38,7 +39,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 165, + index: 0, generation: 0, }, kind: Value, @@ -138,7 +139,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 0, generation: 0, }, - kind: Value, + kind: Function, }, ), attrs: [], @@ -185,203 +186,203 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 136, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 137, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 138, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 139, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 140, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 141, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 142, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 143, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 144, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 145, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 146, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 147, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 148, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 149, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 150, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 151, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 152, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 153, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 154, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 155, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 156, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 157, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 158, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 159, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 160, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 161, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 162, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 163, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 164, generation: 0, }, - kind: Value, + kind: Function, }, ], is_global: false, @@ -415,7 +416,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 166, + index: 1, generation: 0, }, kind: Value, @@ -427,203 +428,203 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 136, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 137, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 138, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 139, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 140, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 141, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 142, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 143, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 144, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 145, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 146, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 147, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 148, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 149, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 150, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 151, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 152, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 153, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 154, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 155, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 156, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 157, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 158, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 159, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 160, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 161, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 162, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 163, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 164, generation: 0, }, - kind: Value, + kind: Function, }, ], is_global: false, @@ -669,203 +670,203 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 136, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 137, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 138, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 139, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 140, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 141, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 142, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 143, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 144, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 145, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 146, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 147, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 148, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 149, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 150, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 151, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 152, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 153, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 154, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 155, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 156, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 157, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 158, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 159, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 160, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 161, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 162, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 163, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 164, generation: 0, }, - kind: Value, + kind: Function, }, ], is_global: false, @@ -899,7 +900,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 167, + index: 2, generation: 0, }, kind: Value, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_2.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_2.snap index 0628821f2..4cb139e89 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_2.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_2.snap @@ -1,5 +1,6 @@ --- source: loader/src/tests.rs +assertion_line: 39 expression: "format!(\"{:#?}\", p.symbols.values())" --- [ @@ -99,7 +100,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 165, + index: 0, generation: 0, }, kind: Value, @@ -199,7 +200,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 0, generation: 0, }, - kind: Value, + kind: Function, }, ), attrs: [], @@ -240,7 +241,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 166, + index: 1, generation: 0, }, kind: Value, @@ -337,7 +338,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 165, + index: 0, generation: 0, }, kind: Value, @@ -387,203 +388,203 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 136, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 137, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 138, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 139, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 140, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 141, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 142, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 143, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 144, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 145, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 146, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 147, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 148, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 149, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 150, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 151, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 152, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 153, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 154, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 155, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 156, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 157, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 158, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 159, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 160, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 161, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 162, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 163, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 164, generation: 0, }, - kind: Value, + kind: Function, }, ], is_global: false, @@ -617,7 +618,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 167, + index: 2, generation: 0, }, kind: Value, @@ -629,203 +630,203 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 136, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 137, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 138, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 139, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 140, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 141, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 142, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 143, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 144, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 145, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 146, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 147, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 148, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 149, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 150, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 151, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 152, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 153, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 154, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 155, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 156, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 157, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 158, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 159, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 160, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 161, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 162, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 163, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 164, generation: 0, }, - kind: Value, + kind: Function, }, ], is_global: false, @@ -871,203 +872,203 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 136, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 137, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 138, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 139, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 140, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 141, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 142, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 143, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 144, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 145, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 146, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 147, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 148, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 149, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 150, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 151, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 152, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 153, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 154, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 155, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 156, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 157, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 158, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 159, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 160, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 161, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 162, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 163, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 164, generation: 0, }, - kind: Value, + kind: Function, }, ], is_global: false, @@ -1101,7 +1102,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 168, + index: 3, generation: 0, }, kind: Value, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_0.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_0.snap index dc09f2cb8..24e90308f 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_0.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_0.snap @@ -1,5 +1,6 @@ --- source: loader/src/tests.rs +assertion_line: 29 expression: "format!(\"{:#?}\", p.symbols.values())" --- [ @@ -50,112 +51,112 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 45, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 46, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 47, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 48, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 49, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 50, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 51, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 52, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 53, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 54, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 55, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 56, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 57, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 58, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 59, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 60, generation: 0, }, - kind: Value, + kind: Function, }, ], is_global: false, @@ -195,7 +196,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 165, + index: 0, generation: 0, }, kind: Value, @@ -251,112 +252,112 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 45, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 46, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 47, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 48, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 49, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 50, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 51, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 52, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 53, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 54, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 55, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 56, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 57, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 58, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 59, generation: 0, }, - kind: Value, + kind: Function, }, SymbolRef { id: Index { index: 60, generation: 0, }, - kind: Value, + kind: Function, }, ], is_global: false, @@ -436,7 +437,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" index: 55, generation: 0, }, - kind: Value, + kind: Function, }, ), attrs: [], diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_1.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_1.snap index e464b2559..5fb2328ac 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_1.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_1.snap @@ -1,5 +1,6 @@ --- source: loader/src/tests.rs +assertion_line: 33 expression: "format!(\"{:#?}\", p.symbols.values())" --- [ @@ -38,7 +39,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 165, + index: 0, generation: 0, }, kind: Value, diff --git a/kclvm/query/src/selector.rs b/kclvm/query/src/selector.rs index 01627bcd4..0096d61cb 100644 --- a/kclvm/query/src/selector.rs +++ b/kclvm/query/src/selector.rs @@ -2,21 +2,22 @@ use super::util::{invalid_symbol_selector_spec_error, split_field_path}; use anyhow::Result; use kclvm_ast::ast; use kclvm_error::diagnostic::Errors; +use kclvm_parser::ParseSession; use serde::{Deserialize, Serialize}; -use std::collections::{HashMap, VecDeque}; +use std::{ + collections::{HashMap, VecDeque}, + sync::Arc, +}; use kclvm_ast::path::get_key_path; use kclvm_ast::walker::MutSelfWalker; use kclvm_ast_pretty::{print_ast_node, ASTNode}; -use kclvm_parser::parse_file; +use kclvm_parser::load_program; -use kclvm_sema::resolver::Options; - -use kclvm_ast::MAIN_PKG; use kclvm_sema::pre_process::pre_process_program; -use maplit::hashmap; +use kclvm_sema::resolver::Options; #[derive(Debug, Default)] /// UnsupportedSelectee is used to store the unsupported selectee, such as if, for, etc. pub struct UnsupportedSelectee { @@ -461,26 +462,29 @@ impl Variable { /// list_options provides users with the ability to parse kcl program and get all option /// calling information. -pub fn list_variables(file: String, specs: Vec) -> Result { +pub fn list_variables(files: Vec, specs: Vec) -> Result { let mut selector = Selector::new(specs)?; - let parse_result = parse_file(&file, None)?; + let mut load_result = load_program( + Arc::new(ParseSession::default()), + &files.iter().map(AsRef::as_ref).collect::>(), + None, + None, + )?; let mut opts = Options::default(); opts.merge_program = true; - pre_process_program( - &mut ast::Program { - root: file, - pkgs: hashmap! { MAIN_PKG.to_string() => vec![parse_result.module.clone()] }, - }, - &opts, - ); + pre_process_program(&mut load_result.program, &opts); - selector.walk_module(&parse_result.module); + for (_, modules) in load_result.program.pkgs.iter() { + for module in modules.iter() { + selector.walk_module(&module); + } + } Ok(ListVariablesResult { variables: selector.select_result, unsupported: selector.unsupported, - parse_errors: parse_result.errors, + parse_errors: load_result.errors, }) } diff --git a/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/kcl.mod b/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/kcl.mod new file mode 100644 index 000000000..f893ac172 --- /dev/null +++ b/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/kcl.mod @@ -0,0 +1,5 @@ +[package] +name = "test_list_merged_variables" +edition = "v0.9.0" +version = "0.0.1" + diff --git a/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/override/base.k b/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/override/base.k new file mode 100644 index 000000000..cc4c5914b --- /dev/null +++ b/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/override/base.k @@ -0,0 +1,11 @@ + +import test + +_tests = test.Test { + pots: [ + test.Pot { + name: "http" + number: 90 + } + ] +} \ No newline at end of file diff --git a/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/override/main.k b/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/override/main.k new file mode 100644 index 000000000..074e18a18 --- /dev/null +++ b/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/override/main.k @@ -0,0 +1,6 @@ + +import test + +_tests = test.Test { + aType: "Internet" +} diff --git a/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/test.k b/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/test.k new file mode 100644 index 000000000..a484f7f47 --- /dev/null +++ b/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/test.k @@ -0,0 +1,7 @@ +schema Pot: + name: str + number: int + +schema Test: + aType?: str + pots?: [Pot] diff --git a/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/union/base.k b/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/union/base.k new file mode 100644 index 000000000..6f908c51e --- /dev/null +++ b/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/union/base.k @@ -0,0 +1,11 @@ + +import test + +tests = test.Test { + pots: [ + test.Pot { + name: "http" + number: 90 + } + ] +} \ No newline at end of file diff --git a/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/union/main.k b/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/union/main.k new file mode 100644 index 000000000..2c7f7aa3b --- /dev/null +++ b/kclvm/query/src/test_data/test_list_variables/test_list_merged_variables/union/main.k @@ -0,0 +1,6 @@ + +import test + +tests : test.Test { + aType: "Internet" +} diff --git a/kclvm/query/src/tests.rs b/kclvm/query/src/tests.rs index 0aaf84c29..28b905136 100644 --- a/kclvm/query/src/tests.rs +++ b/kclvm/query/src/tests.rs @@ -381,7 +381,7 @@ fn test_list_variables() { for (spec, expected, expected_name, op_sym) in test_cases { let specs = vec![spec.to_string()]; - let result = list_variables(file.clone(), specs).unwrap(); + let result = list_variables(vec![file.clone()], specs).unwrap(); assert_eq!(result.variables.get(spec).unwrap().value, expected); assert_eq!(result.variables.get(spec).unwrap().type_name, expected_name); assert_eq!(result.variables.get(spec).unwrap().op_sym, op_sym); @@ -470,7 +470,7 @@ fn test_list_all_variables() { ]; for (spec, expected, expected_name, op_sym) in test_cases { - let result = list_variables(file.clone(), vec![]).unwrap(); + let result = list_variables(vec![file.clone()], vec![]).unwrap(); assert_eq!(result.variables.get(spec).unwrap().value, expected); assert_eq!(result.variables.get(spec).unwrap().type_name, expected_name); assert_eq!(result.variables.get(spec).unwrap().op_sym, op_sym); @@ -521,7 +521,7 @@ fn test_list_unsupported_variables() { for (spec, expected_code) in test_cases { let specs = vec![spec.to_string()]; - let result = list_variables(file.clone(), specs).unwrap(); + let result = list_variables(vec![file.clone()], specs).unwrap(); assert_eq!(result.variables.get(spec), None); assert_eq!(result.unsupported[0].code, expected_code); assert_eq!(result.parse_errors.len(), 0); @@ -545,7 +545,7 @@ fn test_list_unsupported_variables() { for (spec, expected_code) in test_cases { let specs = vec![spec.to_string()]; - let result = list_variables(file.clone(), specs).unwrap(); + let result = list_variables(vec![file.clone()], specs).unwrap(); assert_eq!(result.variables.get(spec).unwrap().value, expected_code); } } @@ -626,7 +626,7 @@ fn test_list_variable_with_invalid_kcl() { .display() .to_string(); let specs = vec!["a".to_string()]; - let result = list_variables(file.clone(), specs).unwrap(); + let result = list_variables(vec![file.clone()], specs).unwrap(); assert_eq!(result.variables.get("a"), None); assert_eq!(result.parse_errors.len(), 2); assert_eq!(result.parse_errors[0].level, Level::Error); @@ -682,7 +682,7 @@ fn test_list_variables_with_file_noexist() { .display() .to_string(); let specs = vec!["a".to_string()]; - let result = list_variables(file.clone(), specs); + let result = list_variables(vec![file.clone()], specs); assert!(result.is_err()); let err = result.err().unwrap(); assert_eq!(err.to_string(), "Cannot find the kcl file, please check the file path ./src/test_data/test_list_variables/noexist.k"); @@ -702,3 +702,58 @@ fn test_override_file_with_invalid_spec() { let err = result.err().unwrap(); assert_eq!(err.to_string(), "Invalid spec format '....', expected =filed_value>, :filed_value>, +=filed_value> or -"); } + +#[test] +fn test_list_merged_variables() { + let file = PathBuf::from("./src/test_data/test_list_variables/test_list_merged_variables") + .canonicalize() + .unwrap(); + + let test_cases = vec![ + ( + "override/base.k", + "override/main.k", + vec!["_tests.aType".to_string(), "_tests.pots".to_string()], + r#""Internet""#.to_string(), + r#"[test.Pot { + name: "http" + number: 90 +}]"# + .to_string(), + ), + ( + "union/base.k", + "union/main.k", + vec!["tests.aType".to_string(), "tests.pots".to_string()], + r#""Internet""#.to_string(), + r#"[test.Pot { + name: "http" + number: 90 +}]"# + .to_string(), + ), + ]; + + for (base_file_name, main_file_name, specs, expected_value1, expected_value2) in test_cases { + let base_file = file.join(base_file_name).display().to_string(); + let main_file = file.join(main_file_name).display().to_string(); + + let result = list_variables(vec![main_file, base_file], specs.clone()).unwrap(); + assert_eq!( + result + .variables + .get(&specs.get(0).unwrap().to_string()) + .unwrap() + .value, + expected_value1 + ); + assert_eq!( + result + .variables + .get(&specs.get(1).unwrap().to_string()) + .unwrap() + .value, + expected_value2 + ); + } +} diff --git a/kclvm/sema/src/advanced_resolver/mod.rs b/kclvm/sema/src/advanced_resolver/mod.rs index 3d647de96..b63dfc168 100644 --- a/kclvm/sema/src/advanced_resolver/mod.rs +++ b/kclvm/sema/src/advanced_resolver/mod.rs @@ -34,6 +34,8 @@ └─────────────────────┘ */ +use std::{cell::RefCell, rc::Rc}; + use indexmap::IndexSet; use kclvm_error::Position; @@ -60,12 +62,12 @@ mod node; /// so that toolchain can query semantic information about the AST pub struct AdvancedResolver<'ctx> { pub(crate) ctx: Context<'ctx>, - pub(crate) gs: GlobalState, + pub(crate) gs: &'ctx mut GlobalState, } pub struct Context<'ctx> { pub program: &'ctx Program, - node_ty_map: NodeTyMap, + node_ty_map: Rc>, scopes: Vec, current_pkgpath: Option, current_filename: Option, @@ -93,9 +95,9 @@ impl<'ctx> Context<'ctx> { impl<'ctx> AdvancedResolver<'ctx> { pub fn resolve_program( program: &'ctx Program, - gs: GlobalState, - node_ty_map: NodeTyMap, - ) -> anyhow::Result { + gs: &'ctx mut GlobalState, + node_ty_map: Rc>, + ) -> anyhow::Result<()> { let mut advanced_resolver = Self { gs, ctx: Context { @@ -111,8 +113,10 @@ impl<'ctx> AdvancedResolver<'ctx> { maybe_def: false, }, }; - for (name, modules) in advanced_resolver.ctx.program.pkgs.iter() { + if !advanced_resolver.gs.new_or_invalidate_pkgs.contains(name) { + continue; + } advanced_resolver.ctx.current_pkgpath = Some(name.clone()); if let Some(pkg_info) = advanced_resolver.gs.get_packages().get_package_info(name) { if modules.is_empty() { @@ -135,7 +139,8 @@ impl<'ctx> AdvancedResolver<'ctx> { } advanced_resolver.gs.build_sema_db(); - Ok(advanced_resolver.gs) + advanced_resolver.gs.new_or_invalidate_pkgs.clear(); + Ok(()) } fn enter_root_scope( @@ -290,8 +295,8 @@ mod tests { let mut program = load_program(sess.clone(), &[&path], None, None) .unwrap() .program; - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); + let mut gs = GlobalState::default(); + Namer::find_symbols(&program, &mut gs); let node_ty_map = resolver::resolve_program_with_opts( &mut program, @@ -303,7 +308,7 @@ mod tests { None, ) .node_ty_map; - let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map).unwrap(); + AdvancedResolver::resolve_program(&program, &mut gs, node_ty_map).unwrap(); let base_path = Path::new(".").canonicalize().unwrap(); // print_symbols_info(&gs); let except_symbols = vec![ @@ -734,7 +739,7 @@ mod tests { 0, "".to_string() .replace("/", &std::path::MAIN_SEPARATOR.to_string()), - SymbolKind::Value, + SymbolKind::Function, ), (19, 20, 19, 24, "name".to_string(), SymbolKind::Unresolved), ( @@ -1229,10 +1234,10 @@ mod tests { let mut program = load_program(sess.clone(), &[&path], None, None) .unwrap() .program; - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); + let mut gs = GlobalState::default(); + Namer::find_symbols(&program, &mut gs); let node_ty_map = resolver::resolve_program(&mut program).node_ty_map; - let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map).unwrap(); + AdvancedResolver::resolve_program(&program, &mut gs, node_ty_map).unwrap(); let base_path = Path::new(".").canonicalize().unwrap(); let test_cases = vec![ @@ -1306,10 +1311,10 @@ mod tests { let mut program = load_program(sess.clone(), &[&path], None, None) .unwrap() .program; - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); + let mut gs = GlobalState::default(); + Namer::find_symbols(&program, &mut gs); let node_ty_map = resolver::resolve_program(&mut program).node_ty_map; - let gs = AdvancedResolver::resolve_program(&program, gs, node_ty_map).unwrap(); + AdvancedResolver::resolve_program(&program, &mut gs, node_ty_map).unwrap(); let base_path = Path::new(".").canonicalize().unwrap(); let scope_test_cases = vec![ diff --git a/kclvm/sema/src/advanced_resolver/node.rs b/kclvm/sema/src/advanced_resolver/node.rs index 8a475ac68..da2d82521 100644 --- a/kclvm/sema/src/advanced_resolver/node.rs +++ b/kclvm/sema/src/advanced_resolver/node.rs @@ -77,6 +77,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&type_alias_stmt.type_name.id)) .map(|ty| ty.clone()), doc: None, @@ -149,10 +150,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { None => return Ok(None), }; unresolved.def = Some(package_symbol); - let unresolved_ref = self - .gs - .get_symbols_mut() - .alloc_unresolved_symbol(unresolved, self.ctx.get_node_key(&ast_id)); + let unresolved_ref = self.gs.get_symbols_mut().alloc_unresolved_symbol( + unresolved, + self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), + ); self.gs .get_symbols_mut() .symbols_info @@ -170,8 +172,10 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let schema_ty = self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&schema_stmt.name.id)) - .ok_or(anyhow!("schema_ty not found"))?; + .ok_or(anyhow!("schema_ty not found"))? + .clone(); let schema_symbol = self .gs .get_symbols() @@ -204,6 +208,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let func_symbol_ref = self.gs.get_symbols_mut().alloc_value_symbol( func_value, self.ctx.get_node_key(&ast::AstIndex::default()), + self.ctx.current_pkgpath.clone().unwrap(), ); schema_builtin_member.insert(name.to_string(), func_symbol_ref); } @@ -277,12 +282,14 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let value = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(key_name.clone(), start, end, Some(schema_symbol), false), self.ctx.get_node_key(&index_signature.id), + self.ctx.current_pkgpath.clone().unwrap(), ); if let Some(symbol) = self.gs.get_symbols_mut().values.get_mut(value.get_id()) { symbol.sema_info = KCLSymbolSemanticInfo { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&index_signature.id)) .map(|ty| ty.clone()), doc: None, @@ -346,6 +353,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let rule_ty = self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&rule_stmt.name.id)) .ok_or(anyhow!("rule_ty not found"))? .clone(); @@ -364,6 +372,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&rule_stmt.name.id)) .map(|ty| ty.clone()), doc: rule_stmt.doc.as_ref().map(|doc| doc.node.clone()), @@ -419,6 +428,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let value = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(name.clone(), start_pos, end_pos, None, false), self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), ); self.gs .get_scopes_mut() @@ -428,6 +438,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(ast_id)) .map(|ty| ty.clone()), doc: None, @@ -478,6 +489,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&schema_attr.name.id)) .map(|ty| ty.clone()), doc, @@ -517,6 +529,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let mut parent_ty = match self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&selector_expr.value.id)) { Some(ty) => ty.clone(), @@ -536,16 +549,22 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let ast_id = name.id.clone(); let mut unresolved = UnresolvedSymbol::new(name.node.clone(), start_pos, end_pos, None); unresolved.def = Some(def_symbol_ref); - let unresolved_ref = self - .gs - .get_symbols_mut() - .alloc_unresolved_symbol(unresolved, self.ctx.get_node_key(&ast_id)); + let unresolved_ref = self.gs.get_symbols_mut().alloc_unresolved_symbol( + unresolved, + self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), + ); let cur_scope = *self.ctx.scopes.last().unwrap(); self.gs .get_scopes_mut() .add_ref_to_scope(cur_scope, unresolved_ref); - parent_ty = match self.ctx.node_ty_map.get(&self.ctx.get_node_key(&name.id)) { + parent_ty = match self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&name.id)) + { Some(ty) => ty.clone(), None => return Ok(None), }; @@ -683,6 +702,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { let schema_ty = self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&schema_expr.name.id)) .ok_or(anyhow!("schema_ty not found"))? .clone(); @@ -804,10 +824,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for AdvancedResolver<'ctx> { fn walk_comment(&mut self, comment: &'ctx ast::Comment) -> Self::Result { let (start, end) = (self.ctx.start_pos.clone(), self.ctx.end_pos.clone()); let comment_symbol = CommentSymbol::new(start, end, comment.text.clone()); - Ok(self - .gs - .get_symbols_mut() - .alloc_comment_symbol(comment_symbol, self.ctx.get_node_key(&self.ctx.cur_node))) + Ok(self.gs.get_symbols_mut().alloc_comment_symbol( + comment_symbol, + self.ctx.get_node_key(&self.ctx.cur_node), + self.ctx.current_pkgpath.clone().unwrap(), + )) } fn walk_missing_expr(&mut self, _missing_expr: &'ctx ast::MissingExpr) -> Self::Result { @@ -832,7 +853,12 @@ impl<'ctx> AdvancedResolver<'ctx> { } self.ctx.cur_node = expr.id.clone(); - if let Some(expr_ty) = self.ctx.node_ty_map.get(&self.ctx.get_node_key(&expr.id)) { + if let Some(expr_ty) = self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&expr.id)) + { match &expr_ty.kind { TypeKind::Schema(_) => { let schema_symbol = self @@ -852,7 +878,12 @@ impl<'ctx> AdvancedResolver<'ctx> { self.ctx.schema_symbol_stack.pop(); match expr_symbol { - Ok(None) => match self.ctx.node_ty_map.get(&self.ctx.get_node_key(&expr.id)) { + Ok(None) => match self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&expr.id)) + { Some(ty) => { if let ast::Expr::Missing(_) = expr.node { return Ok(None); @@ -865,10 +896,11 @@ impl<'ctx> AdvancedResolver<'ctx> { None, ); expr_symbol.sema_info.ty = Some(ty.clone()); - Ok(self - .gs - .get_symbols_mut() - .alloc_expression_symbol(expr_symbol, self.ctx.get_node_key(&expr.id))) + Ok(self.gs.get_symbols_mut().alloc_expression_symbol( + expr_symbol, + self.ctx.get_node_key(&expr.id), + self.ctx.current_pkgpath.clone().unwrap(), + )) } None => Ok(None), }, @@ -921,6 +953,7 @@ impl<'ctx> AdvancedResolver<'ctx> { if let Some(ty) = self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&first_name.id)) { self.gs @@ -946,10 +979,11 @@ impl<'ctx> AdvancedResolver<'ctx> { let mut first_unresolved = UnresolvedSymbol::new(first_name.node.clone(), start_pos, end_pos, None); first_unresolved.def = Some(symbol_ref); - let first_unresolved_ref = self - .gs - .get_symbols_mut() - .alloc_unresolved_symbol(first_unresolved, self.ctx.get_node_key(&ast_id)); + let first_unresolved_ref = self.gs.get_symbols_mut().alloc_unresolved_symbol( + first_unresolved, + self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), + ); let cur_scope = *self.ctx.scopes.last().unwrap(); self.gs .get_scopes_mut() @@ -959,6 +993,7 @@ impl<'ctx> AdvancedResolver<'ctx> { let mut parent_ty = match self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&first_name.id)) { Some(ty) => ty.clone(), @@ -981,17 +1016,22 @@ impl<'ctx> AdvancedResolver<'ctx> { let mut unresolved = UnresolvedSymbol::new(name.node.clone(), start_pos, end_pos, None); unresolved.def = Some(def_symbol_ref); - let unresolved_ref = self - .gs - .get_symbols_mut() - .alloc_unresolved_symbol(unresolved, self.ctx.get_node_key(&ast_id)); + let unresolved_ref = self.gs.get_symbols_mut().alloc_unresolved_symbol( + unresolved, + self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), + ); let cur_scope = *self.ctx.scopes.last().unwrap(); self.gs .get_scopes_mut() .add_ref_to_scope(cur_scope, unresolved_ref); - parent_ty = match self.ctx.node_ty_map.get(&self.ctx.get_node_key(&name.id)) + parent_ty = match self + .ctx + .node_ty_map + .borrow() + .get(&self.ctx.get_node_key(&name.id)) { Some(ty) => ty.clone(), None => return Ok(None), @@ -1010,6 +1050,7 @@ impl<'ctx> AdvancedResolver<'ctx> { let first_value = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(first_name.node.clone(), start_pos, end_pos, None, false), self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), ); self.gs.get_scopes_mut().add_def_to_scope( cur_scope, @@ -1027,6 +1068,7 @@ impl<'ctx> AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&first_name.id)) .map(|ty| ty.clone()), doc: None, @@ -1040,6 +1082,7 @@ impl<'ctx> AdvancedResolver<'ctx> { let value = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(name.node.clone(), start_pos, end_pos, None, false), self.ctx.get_node_key(&ast_id), + self.ctx.current_pkgpath.clone().unwrap(), ); self.gs.get_scopes_mut().add_def_to_scope( @@ -1055,6 +1098,7 @@ impl<'ctx> AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&name.id)) .map(|ty| ty.clone()), doc: None, @@ -1098,6 +1142,7 @@ impl<'ctx> AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(id)) .map(|ty| ty.clone()), doc: None, @@ -1183,6 +1228,7 @@ impl<'ctx> AdvancedResolver<'ctx> { let value = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(kw.node.arg.node.get_name(), start_pos, end_pos, None, false), self.ctx.get_node_key(&kw.id), + self.ctx.current_pkgpath.clone().unwrap(), ); if let Some(value) = self.gs.get_symbols_mut().values.get_mut(value.get_id()) { @@ -1190,6 +1236,7 @@ impl<'ctx> AdvancedResolver<'ctx> { ty: self .ctx .node_ty_map + .borrow() .get(&self.ctx.get_node_key(&kw.id)) .map(|ty| ty.clone()), doc: None, @@ -1257,6 +1304,7 @@ impl<'ctx> AdvancedResolver<'ctx> { self.gs.get_symbols_mut().alloc_decorator_symbol( decorator_symbol, self.ctx.get_node_key(&self.ctx.cur_node), + self.ctx.current_pkgpath.clone().unwrap(), ); } } diff --git a/kclvm/sema/src/core/global_state.rs b/kclvm/sema/src/core/global_state.rs index b5ec23208..6305bdd5a 100644 --- a/kclvm/sema/src/core/global_state.rs +++ b/kclvm/sema/src/core/global_state.rs @@ -1,4 +1,6 @@ -use indexmap::IndexMap; +use std::collections::HashSet; + +use indexmap::{IndexMap, IndexSet}; use kclvm_error::Position; use super::{ @@ -19,6 +21,8 @@ pub struct GlobalState { packages: PackageDB, // store semantic information after analysis pub(crate) sema_db: SemanticDB, + // new and invalidate(changed and affected by changed) pkg from CachedScope::update() + pub new_or_invalidate_pkgs: HashSet, } impl GlobalState { @@ -49,6 +53,10 @@ impl GlobalState { pub fn get_sema_db(&self) -> &SemanticDB { &self.sema_db } + + pub fn get_sema_db_mut(&mut self) -> &mut SemanticDB { + &mut self.sema_db + } } impl GlobalState { @@ -288,18 +296,26 @@ impl GlobalState { } impl GlobalState { - fn build_sema_db_with_symbols(&self, file_sema_map: &mut IndexMap) { + fn build_sema_db_with_symbols( + &self, + file_sema_map_cache: &mut IndexMap, + ) { // put symbols + let mut file_sema_map: IndexMap = IndexMap::new(); + for (index, symbol) in self.symbols.schemas.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Schema, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -310,15 +326,18 @@ impl GlobalState { ); } for (index, symbol) in self.symbols.type_aliases.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::TypeAlias, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -329,15 +348,18 @@ impl GlobalState { ); } for (index, symbol) in self.symbols.attributes.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Attribute, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -348,15 +370,18 @@ impl GlobalState { ); } for (index, symbol) in self.symbols.rules.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Rule, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -367,15 +392,18 @@ impl GlobalState { ); } for (index, symbol) in self.symbols.values.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Value, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -386,15 +414,18 @@ impl GlobalState { ); } for (index, symbol) in self.symbols.unresolved.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Unresolved, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -406,15 +437,19 @@ impl GlobalState { } for (index, symbol) in self.symbols.exprs.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } + let symbol_ref = SymbolRef { kind: SymbolKind::Expression, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -426,15 +461,18 @@ impl GlobalState { } for (index, symbol) in self.symbols.comments.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Comment, id: index, }; - let filename = symbol.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.symbols.push(symbol_ref); file_sema_info.symbol_locs.insert( symbol_ref, @@ -446,10 +484,33 @@ impl GlobalState { } for (index, symbol) in self.symbols.decorators.iter() { + if file_sema_map_cache.contains_key(&symbol.start.filename) { + continue; + } let symbol_ref = SymbolRef { kind: SymbolKind::Decorator, id: index, }; + let filename = &symbol.start.filename; + if !file_sema_map.contains_key(filename) { + file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); + } + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); + file_sema_info.symbols.push(symbol_ref); + file_sema_info.symbol_locs.insert( + symbol_ref, + CachedLocation { + line: symbol.start.line, + column: symbol.start.column.unwrap_or(0), + }, + ); + } + + for (index, symbol) in self.symbols.functions.iter() { + let symbol_ref = SymbolRef { + kind: SymbolKind::Function, + id: index, + }; let filename = symbol.start.filename.clone(); if !file_sema_map.contains_key(&filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); @@ -473,6 +534,8 @@ impl GlobalState { .symbols .sort_by_key(|symbol_ref| sema_info.symbol_locs.get(symbol_ref).unwrap()) } + + file_sema_map_cache.extend(file_sema_map); } fn build_sema_db_with_scopes(&self, file_sema_map: &mut IndexMap) { // put scope @@ -481,11 +544,11 @@ impl GlobalState { kind: ScopeKind::Local, id: index, }; - let filename = scope.start.filename.clone(); - if !file_sema_map.contains_key(&filename) { + let filename = &scope.start.filename; + if !file_sema_map.contains_key(filename) { file_sema_map.insert(filename.clone(), FileSemanticInfo::new(filename.clone())); } - let file_sema_info = file_sema_map.get_mut(&filename).unwrap(); + let file_sema_info = file_sema_map.get_mut(filename).unwrap(); file_sema_info.local_scope_locs.insert( scope_ref, CachedRange { @@ -500,7 +563,7 @@ impl GlobalState { }, ); file_sema_map - .get_mut(&filename) + .get_mut(filename) .unwrap() .scopes .push(scope_ref); @@ -535,11 +598,43 @@ impl GlobalState { } pub(crate) fn build_sema_db(&mut self) { - let mut file_sema_map = IndexMap::::default(); - self.build_sema_db_with_symbols(&mut file_sema_map); - self.build_sema_db_with_scopes(&mut file_sema_map); - self.sort_local_scopes(&mut file_sema_map); + let mut file_sema_map_cache = self.get_sema_db_mut().file_sema_map.clone(); + + self.build_sema_db_with_symbols(&mut file_sema_map_cache); + self.build_sema_db_with_scopes(&mut file_sema_map_cache); + self.sort_local_scopes(&mut file_sema_map_cache); + + self.sema_db.file_sema_map = file_sema_map_cache; + } - self.sema_db.file_sema_map = file_sema_map; + pub fn clear_cache(&mut self) { + let invalidate_pkgs = self.new_or_invalidate_pkgs.clone(); + self.clear_sema_db_cache(&invalidate_pkgs); + self.get_scopes_mut().clear_cache(&invalidate_pkgs); + self.get_packages_mut().clear_cache(&invalidate_pkgs); + self.get_symbols_mut().clear_cache(&invalidate_pkgs); + } + + fn clear_sema_db_cache(&mut self, invalidate_pkgs: &HashSet) { + let mut to_remove: Vec = Vec::new(); + let mut files: IndexSet = IndexSet::new(); + for invalidate_pkg in invalidate_pkgs { + if let Some(symbols) = self + .get_symbols() + .symbols_info + .pkg_symbol_map + .get(invalidate_pkg) + { + to_remove.extend(symbols.iter().cloned()); + } + } + for symbol in to_remove { + if let Some(s) = self.get_symbols().get_symbol(symbol) { + files.insert(s.get_range().0.filename); + } + } + for file in files { + self.sema_db.file_sema_map.remove(&file); + } } } diff --git a/kclvm/sema/src/core/package.rs b/kclvm/sema/src/core/package.rs index 3854fa9d4..a8488767c 100644 --- a/kclvm/sema/src/core/package.rs +++ b/kclvm/sema/src/core/package.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use indexmap::{IndexMap, IndexSet}; #[derive(Default, Debug, Clone)] @@ -39,6 +41,12 @@ impl PackageDB { pub fn get_module_info(&self, name: &str) -> Option<&ModuleInfo> { self.module_info.get(name) } + + pub fn clear_cache(&mut self, invalidate_pkgs: &HashSet) { + for invalidate_pkg in invalidate_pkgs { + self.package_info.remove(invalidate_pkg); + } + } } #[derive(Debug, Clone)] pub struct PackageInfo { diff --git a/kclvm/sema/src/core/scope.rs b/kclvm/sema/src/core/scope.rs index 0d98861c3..b1baf688b 100644 --- a/kclvm/sema/src/core/scope.rs +++ b/kclvm/sema/src/core/scope.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use indexmap::{IndexMap, IndexSet}; use kclvm_error::Position; @@ -108,6 +108,17 @@ impl ScopeData { } } + pub fn remove_scope(&mut self, scope: &ScopeRef) { + match scope.get_kind() { + ScopeKind::Local => { + self.locals.remove(scope.get_id()); + } + ScopeKind::Root => { + self.roots.remove(scope.get_id()); + } + } + } + pub fn try_get_local_scope(&self, scope: &ScopeRef) -> Option<&LocalSymbolScope> { match scope.get_kind() { ScopeKind::Local => Some(self.locals.get(scope.get_id())?), @@ -180,6 +191,24 @@ impl ScopeData { kind: ScopeKind::Local, } } + + pub fn clear_cache(&mut self, invalidate_pkgs: &HashSet) { + for invalidate_pkg in invalidate_pkgs { + if let Some(scope_ref) = self.root_map.remove(invalidate_pkg) { + self.clear_scope_and_child(scope_ref); + self.roots.remove(scope_ref.get_id()); + } + } + } + + pub fn clear_scope_and_child(&mut self, scope_ref: ScopeRef) { + if let Some(scope) = self.get_scope(&scope_ref) { + for c in scope.get_children() { + self.clear_scope_and_child(c) + } + } + self.remove_scope(&scope_ref) + } } #[derive(Debug, Clone)] diff --git a/kclvm/sema/src/core/symbol.rs b/kclvm/sema/src/core/symbol.rs index 37ace5323..6cea1c501 100644 --- a/kclvm/sema/src/core/symbol.rs +++ b/kclvm/sema/src/core/symbol.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::{collections::HashSet, sync::Arc}; use generational_arena::Arena; use indexmap::{IndexMap, IndexSet}; @@ -54,6 +54,7 @@ pub struct KCLSymbolSemanticInfo { } pub(crate) const BUILTIN_STR_PACKAGE: &'static str = "@str"; +pub(crate) const BUILTIN_FUNCTION_PACKAGE: &'static str = "@builtin"; #[derive(Default, Debug, Clone)] pub struct SymbolData { @@ -67,6 +68,7 @@ pub struct SymbolData { pub(crate) exprs: Arena, pub(crate) comments: Arena, pub(crate) decorators: Arena, + pub(crate) functions: Arena, pub(crate) symbols_info: SymbolDB, } @@ -79,6 +81,7 @@ pub struct SymbolDB { pub(crate) schema_builtin_symbols: IndexMap>, pub(crate) node_symbol_map: IndexMap, pub(crate) symbol_node_map: IndexMap, + pub(crate) pkg_symbol_map: IndexMap>, } impl SymbolData { @@ -138,6 +141,14 @@ impl SymbolData { } } + pub fn get_function_symbol(&self, id: SymbolRef) -> Option<&FunctionSymbol> { + if matches!(id.get_kind(), SymbolKind::Function) { + self.functions.get(id.get_id()) + } else { + None + } + } + pub fn get_symbol(&self, id: SymbolRef) -> Option<&KCLSymbol> { match id.get_kind() { SymbolKind::Schema => self @@ -180,6 +191,48 @@ impl SymbolData { .decorators .get(id.get_id()) .map(|symbol| symbol as &KCLSymbol), + SymbolKind::Function => self + .functions + .get(id.get_id()) + .map(|symbol| symbol as &KCLSymbol), + } + } + + pub fn remove_symbol(&mut self, id: &SymbolRef) { + match id.get_kind() { + SymbolKind::Schema => { + self.schemas.remove(id.get_id()); + } + SymbolKind::Attribute => { + self.attributes.remove(id.get_id()); + } + SymbolKind::Value => { + self.values.remove(id.get_id()); + } + SymbolKind::Package => { + self.packages.remove(id.get_id()); + } + SymbolKind::TypeAlias => { + self.type_aliases.remove(id.get_id()); + } + SymbolKind::Unresolved => { + self.unresolved.remove(id.get_id()); + } + SymbolKind::Rule => { + self.rules.remove(id.get_id()); + } + SymbolKind::Expression => { + self.exprs.remove(id.get_id()); + } + SymbolKind::Comment => { + self.comments.remove(id.get_id()); + } + SymbolKind::Decorator => { + self.decorators.remove(id.get_id()); + } + SymbolKind::Function => { + self.functions.remove(id.get_id()); + } } } @@ -245,6 +298,12 @@ impl SymbolData { symbol }); } + SymbolKind::Function => { + self.functions.get_mut(id.get_id()).map(|symbol| { + symbol.sema_info.ty = Some(ty); + symbol + }); + } } } @@ -496,19 +555,50 @@ impl SymbolData { symbol_ref, ); } + + for (id, _) in self.functions.iter() { + let symbol_ref = SymbolRef { + id, + kind: SymbolKind::Function, + }; + self.symbols_info.fully_qualified_name_map.insert( + self.get_fully_qualified_name(symbol_ref).unwrap(), + symbol_ref, + ); + } } - pub fn alloc_package_symbol(&mut self, pkg: PackageSymbol) -> SymbolRef { + pub fn insert_package_symbol(&mut self, symbol_ref: SymbolRef, pkg_name: String) { + if !self.symbols_info.pkg_symbol_map.contains_key(&pkg_name) { + self.symbols_info + .pkg_symbol_map + .insert(pkg_name.clone(), IndexSet::default()); + } + + self.symbols_info + .pkg_symbol_map + .get_mut(&pkg_name) + .unwrap() + .insert(symbol_ref); + } + + pub fn alloc_package_symbol(&mut self, pkg: PackageSymbol, pkg_name: String) -> SymbolRef { let symbol_id = self.packages.insert(pkg); let symbol_ref = SymbolRef { id: symbol_id, kind: SymbolKind::Package, }; self.packages.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } - pub fn alloc_schema_symbol(&mut self, schema: SchemaSymbol, node_key: NodeKey) -> SymbolRef { + pub fn alloc_schema_symbol( + &mut self, + schema: SchemaSymbol, + node_key: NodeKey, + pkg_name: String, + ) -> SymbolRef { self.symbols_info.symbol_pos_set.insert(schema.end.clone()); let symbol_id = self.schemas.insert(schema); let symbol_ref = SymbolRef { @@ -522,6 +612,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.schemas.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } @@ -529,6 +620,7 @@ impl SymbolData { &mut self, unresolved: UnresolvedSymbol, node_key: NodeKey, + pkg_name: String, ) -> SymbolRef { self.symbols_info .symbol_pos_set @@ -545,6 +637,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.unresolved.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } @@ -552,6 +645,7 @@ impl SymbolData { &mut self, alias: TypeAliasSymbol, node_key: NodeKey, + pkg_name: String, ) -> SymbolRef { self.symbols_info.symbol_pos_set.insert(alias.end.clone()); let symbol_id = self.type_aliases.insert(alias); @@ -566,10 +660,16 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.type_aliases.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } - pub fn alloc_rule_symbol(&mut self, rule: RuleSymbol, node_key: NodeKey) -> SymbolRef { + pub fn alloc_rule_symbol( + &mut self, + rule: RuleSymbol, + node_key: NodeKey, + pkg_name: String, + ) -> SymbolRef { self.symbols_info.symbol_pos_set.insert(rule.end.clone()); let symbol_id = self.rules.insert(rule); let symbol_ref = SymbolRef { @@ -583,6 +683,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.rules.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } @@ -590,6 +691,7 @@ impl SymbolData { &mut self, attribute: AttributeSymbol, node_key: NodeKey, + pkg_name: String, ) -> SymbolRef { self.symbols_info .symbol_pos_set @@ -606,10 +708,16 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.attributes.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } - pub fn alloc_value_symbol(&mut self, value: ValueSymbol, node_key: NodeKey) -> SymbolRef { + pub fn alloc_value_symbol( + &mut self, + value: ValueSymbol, + node_key: NodeKey, + pkg_name: String, + ) -> SymbolRef { self.symbols_info.symbol_pos_set.insert(value.end.clone()); let symbol_id = self.values.insert(value); let symbol_ref = SymbolRef { @@ -623,6 +731,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.values.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); symbol_ref } @@ -630,6 +739,7 @@ impl SymbolData { &mut self, expr: ExpressionSymbol, node_key: NodeKey, + pkg_name: String, ) -> Option { if self.symbols_info.symbol_pos_set.contains(&expr.end) { return None; @@ -647,6 +757,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.exprs.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); Some(symbol_ref) } @@ -654,6 +765,7 @@ impl SymbolData { &mut self, comment: CommentSymbol, node_key: NodeKey, + pkg_name: String, ) -> Option { let symbol_id = self.comments.insert(comment); let symbol_ref = SymbolRef { @@ -667,6 +779,7 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.comments.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); Some(symbol_ref) } @@ -674,6 +787,7 @@ impl SymbolData { &mut self, decorator: DecoratorSymbol, node_key: NodeKey, + pkg_name: String, ) -> Option { let symbol_id = self.decorators.insert(decorator); let symbol_ref = SymbolRef { @@ -687,9 +801,33 @@ impl SymbolData { .symbol_node_map .insert(symbol_ref, node_key); self.decorators.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); Some(symbol_ref) } + pub fn alloc_function_symbol( + &mut self, + func: FunctionSymbol, + node_key: NodeKey, + pkg_name: String, + ) -> SymbolRef { + self.symbols_info.symbol_pos_set.insert(func.end.clone()); + let symbol_id = self.functions.insert(func); + let symbol_ref = SymbolRef { + id: symbol_id, + kind: SymbolKind::Function, + }; + self.symbols_info + .node_symbol_map + .insert(node_key.clone(), symbol_ref); + self.symbols_info + .symbol_node_map + .insert(symbol_ref, node_key); + self.functions.get_mut(symbol_id).unwrap().id = Some(symbol_ref); + self.insert_package_symbol(symbol_ref, pkg_name); + symbol_ref + } + #[inline] pub fn get_node_symbol_map(&self) -> &IndexMap { &self.symbols_info.node_symbol_map @@ -709,6 +847,19 @@ impl SymbolData { pub fn get_builtin_symbols(&self) -> &IndexMap { &self.symbols_info.global_builtin_symbols } + + pub fn clear_cache(&mut self, invalidate_pkgs: &HashSet) { + let mut to_remove: Vec = Vec::new(); + + for invalidate_pkg in invalidate_pkgs { + if let Some(symbols) = self.symbols_info.pkg_symbol_map.get(invalidate_pkg) { + to_remove.extend(symbols.iter().cloned()); + } + } + for symbol in to_remove { + self.remove_symbol(&symbol); + } + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)] @@ -716,6 +867,7 @@ pub enum SymbolKind { Schema, Attribute, Value, + Function, Package, TypeAlias, Unresolved, @@ -2070,3 +2222,134 @@ impl DecoratorSymbol { self.name.clone() } } + +#[derive(Debug, Clone)] +pub struct FunctionSymbol { + pub(crate) id: Option, + pub(crate) name: String, + pub(crate) start: Position, + pub(crate) end: Position, + pub(crate) owner: Option, + pub(crate) sema_info: KCLSymbolSemanticInfo, + + pub(crate) is_global: bool, +} + +impl Symbol for FunctionSymbol { + type SymbolData = SymbolData; + type SemanticInfo = KCLSymbolSemanticInfo; + + fn is_global(&self) -> bool { + self.is_global + } + + fn get_range(&self) -> Range { + (self.start.clone(), self.end.clone()) + } + + fn get_owner(&self) -> Option { + self.owner.clone() + } + + fn get_definition(&self) -> Option { + self.id.clone() + } + + fn get_name(&self) -> String { + self.name.clone() + } + + fn get_id(&self) -> Option { + self.id.clone() + } + + fn get_attribute( + &self, + name: &str, + data: &Self::SymbolData, + module_info: Option<&ModuleInfo>, + ) -> Option { + data.get_type_attribute(self.sema_info.ty.as_ref()?, name, module_info) + } + + fn get_all_attributes( + &self, + data: &Self::SymbolData, + module_info: Option<&ModuleInfo>, + ) -> Vec { + let mut result = vec![]; + if let Some(ty) = self.sema_info.ty.as_ref() { + if let Some(symbol_ref) = data.get_type_symbol(ty, module_info) { + if let Some(symbol) = data.get_symbol(symbol_ref) { + result.append(&mut symbol.get_all_attributes(data, module_info)) + } + } + } + + result + } + + fn has_attribute( + &self, + name: &str, + data: &Self::SymbolData, + module_info: Option<&ModuleInfo>, + ) -> bool { + self.get_attribute(name, data, module_info).is_some() + } + + fn simple_dump(&self) -> String { + let mut output = "{\n".to_string(); + output.push_str("\"kind\": \"FunctionSymbol\",\n"); + output.push_str(&format!("\"name\":\"{}\",\n", self.name)); + output.push_str(&format!( + "\"range\": \"{}:{}", + self.start.filename, self.start.line + )); + if let Some(start_col) = self.start.column { + output.push_str(&format!(":{}", start_col)); + } + + output.push_str(&format!(" to {}", self.end.line)); + if let Some(end_col) = self.end.column { + output.push_str(&format!(":{}", end_col)); + } + output.push_str("\"\n}"); + output + } + + fn full_dump(&self, data: &Self::SymbolData) -> Option { + let mut output = format!("{{\n\"simple_info\": {},\n", self.simple_dump()); + output.push_str("\"additional_info\": {\n"); + if let Some(owner) = self.owner.as_ref() { + let owner_symbol = data.get_symbol(*owner)?; + output.push_str(&format!("\"owner\": {}\n", owner_symbol.simple_dump())); + } + output.push_str("\n}\n}"); + Some(output) + } + + fn get_sema_info(&self) -> &Self::SemanticInfo { + &self.sema_info + } +} + +impl FunctionSymbol { + pub fn new( + name: String, + start: Position, + end: Position, + owner: Option, + is_global: bool, + ) -> Self { + Self { + id: None, + name, + start, + end, + owner, + sema_info: KCLSymbolSemanticInfo::default(), + is_global, + } + } +} diff --git a/kclvm/sema/src/namer/mod.rs b/kclvm/sema/src/namer/mod.rs index 8f2d14a1d..2775a4b66 100644 --- a/kclvm/sema/src/namer/mod.rs +++ b/kclvm/sema/src/namer/mod.rs @@ -45,7 +45,9 @@ use crate::builtin::{ }; use crate::core::global_state::GlobalState; use crate::core::package::{ModuleInfo, PackageInfo}; -use crate::core::symbol::{PackageSymbol, SymbolRef, ValueSymbol, BUILTIN_STR_PACKAGE}; +use crate::core::symbol::{ + FunctionSymbol, PackageSymbol, SymbolRef, BUILTIN_FUNCTION_PACKAGE, BUILTIN_STR_PACKAGE, +}; use crate::resolver::scope::NodeKey; use indexmap::IndexSet; use kclvm_ast::ast::AstIndex; @@ -57,7 +59,7 @@ mod node; pub const BUILTIN_SYMBOL_PKG_PATH: &str = "@builtin"; pub struct Namer<'ctx> { - gs: GlobalState, + gs: &'ctx mut GlobalState, ctx: NamerContext<'ctx>, } @@ -83,7 +85,7 @@ impl<'ctx> NamerContext<'ctx> { } impl<'ctx> Namer<'ctx> { - fn new(program: &'ctx Program, gs: GlobalState) -> Self { + fn new(program: &'ctx Program, gs: &'ctx mut GlobalState) -> Self { Self { ctx: NamerContext { program, @@ -97,7 +99,7 @@ impl<'ctx> Namer<'ctx> { } // serial namer pass - pub fn find_symbols(program: &'ctx Program, gs: GlobalState) -> GlobalState { + pub fn find_symbols(program: &'ctx Program, gs: &'ctx mut GlobalState) { let mut namer = Self::new(program, gs); namer.ctx.current_package_info = Some(PackageInfo::new( BUILTIN_SYMBOL_PKG_PATH.to_string(), @@ -111,6 +113,16 @@ impl<'ctx> Namer<'ctx> { .add_package(namer.ctx.current_package_info.take().unwrap()); for (name, modules) in namer.ctx.program.pkgs.iter() { + // new pkgs or invalidate pkg + if namer.gs.get_packages().get_package_info(name).is_some() + && !namer.gs.new_or_invalidate_pkgs.contains(name) + { + continue; + } + + // add new pkgs to invalidate pkgs + namer.gs.new_or_invalidate_pkgs.insert(name.clone()); + { if modules.is_empty() { continue; @@ -131,7 +143,10 @@ impl<'ctx> Namer<'ctx> { }; let pkg_symbol = PackageSymbol::new(name.clone(), pkg_pos.clone(), pkg_pos); - let symbol_ref = namer.gs.get_symbols_mut().alloc_package_symbol(pkg_symbol); + let symbol_ref = namer + .gs + .get_symbols_mut() + .alloc_package_symbol(pkg_symbol, name.to_string()); namer.ctx.owner_symbols.push(symbol_ref); namer.ctx.current_package_info = @@ -164,25 +179,27 @@ impl<'ctx> Namer<'ctx> { namer.define_symbols(); - namer.gs + // namer.gs } fn init_builtin_symbols(&mut self) { //add global built functions for (name, builtin_func) in BUILTIN_FUNCTIONS.iter() { - let mut value_symbol = ValueSymbol::new( + let mut func_symbol = FunctionSymbol::new( name.to_string(), Position::dummy_pos(), Position::dummy_pos(), None, true, ); - value_symbol.sema_info.ty = Some(Arc::new(builtin_func.clone())); - value_symbol.sema_info.doc = builtin_func.ty_doc(); - let symbol_ref = self - .gs - .get_symbols_mut() - .alloc_value_symbol(value_symbol, self.ctx.get_node_key(&AstIndex::default())); + + func_symbol.sema_info.ty = Some(Arc::new(builtin_func.clone())); + func_symbol.sema_info.doc = builtin_func.ty_doc(); + let symbol_ref = self.gs.get_symbols_mut().alloc_function_symbol( + func_symbol, + self.ctx.get_node_key(&AstIndex::default()), + BUILTIN_FUNCTION_PACKAGE.to_string(), + ); self.gs .get_symbols_mut() .symbols_info @@ -192,29 +209,31 @@ impl<'ctx> Namer<'ctx> { //add system modules for system_pkg_name in STANDARD_SYSTEM_MODULES { - let package_symbol_ref = - self.gs - .get_symbols_mut() - .alloc_package_symbol(PackageSymbol::new( - system_pkg_name.to_string(), - Position::dummy_pos(), - Position::dummy_pos(), - )); + let package_symbol_ref = self.gs.get_symbols_mut().alloc_package_symbol( + PackageSymbol::new( + system_pkg_name.to_string(), + Position::dummy_pos(), + Position::dummy_pos(), + ), + system_pkg_name.to_string(), + ); for func_name in get_system_module_members(system_pkg_name) { let func_ty = get_system_member_function_ty(*system_pkg_name, func_name); - let mut value_symbol = ValueSymbol::new( + let mut func_symbol = FunctionSymbol::new( func_name.to_string(), Position::dummy_pos(), Position::dummy_pos(), Some(package_symbol_ref), false, ); - value_symbol.sema_info.ty = Some(func_ty.clone()); - value_symbol.sema_info.doc = func_ty.ty_doc(); - let func_symbol_ref = self - .gs - .get_symbols_mut() - .alloc_value_symbol(value_symbol, self.ctx.get_node_key(&AstIndex::default())); + + func_symbol.sema_info.ty = Some(func_ty.clone()); + func_symbol.sema_info.doc = func_ty.ty_doc(); + let func_symbol_ref = self.gs.get_symbols_mut().alloc_function_symbol( + func_symbol, + self.ctx.get_node_key(&AstIndex::default()), + system_pkg_name.to_string(), + ); self.gs .get_symbols_mut() .packages @@ -226,28 +245,30 @@ impl<'ctx> Namer<'ctx> { } //add string builtin function - let package_symbol_ref = - self.gs - .get_symbols_mut() - .alloc_package_symbol(PackageSymbol::new( - BUILTIN_STR_PACKAGE.to_string(), - Position::dummy_pos(), - Position::dummy_pos(), - )); + let package_symbol_ref = self.gs.get_symbols_mut().alloc_package_symbol( + PackageSymbol::new( + BUILTIN_STR_PACKAGE.to_string(), + Position::dummy_pos(), + Position::dummy_pos(), + ), + BUILTIN_STR_PACKAGE.to_string(), + ); for (name, builtin_func) in STRING_MEMBER_FUNCTIONS.iter() { - let mut value_symbol = ValueSymbol::new( + let mut func_symbol = FunctionSymbol::new( name.to_string(), Position::dummy_pos(), Position::dummy_pos(), Some(package_symbol_ref), true, ); - value_symbol.sema_info.ty = Some(Arc::new(builtin_func.clone())); - value_symbol.sema_info.doc = builtin_func.ty_doc(); - let symbol_ref = self - .gs - .get_symbols_mut() - .alloc_value_symbol(value_symbol, self.ctx.get_node_key(&AstIndex::default())); + + func_symbol.sema_info.ty = Some(Arc::new(builtin_func.clone())); + func_symbol.sema_info.doc = builtin_func.ty_doc(); + let symbol_ref = self.gs.get_symbols_mut().alloc_function_symbol( + func_symbol, + self.ctx.get_node_key(&AstIndex::default()), + BUILTIN_STR_PACKAGE.to_string(), + ); self.gs .get_symbols_mut() .packages @@ -283,8 +304,10 @@ mod tests { ) .unwrap() .program; - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); + let mut gs = GlobalState::default(); + Namer::find_symbols(&program, &mut gs); + let mut gs = GlobalState::default(); + Namer::find_symbols(&program, &mut gs); let symbols = gs.get_symbols(); diff --git a/kclvm/sema/src/namer/node.rs b/kclvm/sema/src/namer/node.rs index ab923cef7..e07af9545 100644 --- a/kclvm/sema/src/namer/node.rs +++ b/kclvm/sema/src/namer/node.rs @@ -68,6 +68,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { let value_ref = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(value_name, start_pos, end_pos, Some(owner), true), self.ctx.get_node_key(&unification_stmt.target.id), + self.ctx + .current_package_info + .clone() + .unwrap() + .fully_qualified_name, ); self.ctx .value_fully_qualified_name_set @@ -92,6 +97,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { owner, ), self.ctx.get_node_key(&type_alias_stmt.type_name.id), + self.ctx + .current_package_info + .clone() + .unwrap() + .fully_qualified_name, ); Some(vec![type_alias_ref]) } @@ -117,6 +127,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { let value_ref = self.gs.get_symbols_mut().alloc_value_symbol( ValueSymbol::new(value_name, start_pos, end_pos, Some(owner), true), self.ctx.get_node_key(&target.id), + self.ctx + .current_package_info + .clone() + .unwrap() + .fully_qualified_name, ); self.ctx .value_fully_qualified_name_set @@ -172,6 +187,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { let shcema_ref = self.gs.get_symbols_mut().alloc_schema_symbol( SchemaSymbol::new(schema_stmt.name.node.clone(), start_pos, end_pos, *owner), self.ctx.get_node_key(&schema_stmt.name.id), + self.ctx + .current_package_info + .clone() + .unwrap() + .fully_qualified_name, ); self.ctx.owner_symbols.push(shcema_ref); @@ -214,6 +234,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { let rule_ref = self.gs.get_symbols_mut().alloc_rule_symbol( RuleSymbol::new(rule_stmt.name.node.clone(), start_pos, end_pos, owner), self.ctx.get_node_key(&rule_stmt.name.id), + self.ctx + .current_package_info + .clone() + .unwrap() + .fully_qualified_name, ); Some(vec![rule_ref]) } @@ -234,6 +259,11 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Namer<'ctx> { schema_attr.is_optional, ), self.ctx.get_node_key(&schema_attr.name.id), + self.ctx + .current_package_info + .clone() + .unwrap() + .fully_qualified_name, ); Some(vec![attribute_ref]) } diff --git a/kclvm/sema/src/resolver/arg.rs b/kclvm/sema/src/resolver/arg.rs index e3c7aa0bc..9be8fbf61 100644 --- a/kclvm/sema/src/resolver/arg.rs +++ b/kclvm/sema/src/resolver/arg.rs @@ -57,6 +57,7 @@ impl<'ctx> Resolver<'ctx> { check_table.insert(arg_name.to_string()); let arg_value_type = self.expr_or_any_type(&kw.node.value); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(kw.id.clone()), arg_value_type.clone()); kwarg_types.push((arg_name.to_string(), arg_value_type.clone())); } else { diff --git a/kclvm/sema/src/resolver/mod.rs b/kclvm/sema/src/resolver/mod.rs index a49f1523b..a7f60c0dd 100644 --- a/kclvm/sema/src/resolver/mod.rs +++ b/kclvm/sema/src/resolver/mod.rs @@ -43,7 +43,7 @@ pub struct Resolver<'ctx> { pub scope_map: IndexMap>>, pub scope: Rc>, pub scope_level: usize, - pub node_ty_map: NodeTyMap, + pub node_ty_map: Rc>, pub builtin_scope: Rc>, pub ctx: Context, pub options: Options, @@ -61,7 +61,7 @@ impl<'ctx> Resolver<'ctx> { builtin_scope, scope, scope_level: 0, - node_ty_map: IndexMap::default(), + node_ty_map: Rc::new(RefCell::new(IndexMap::default())), ctx: Context::default(), options, handler: Handler::default(), @@ -181,11 +181,15 @@ pub fn resolve_program_with_opts( resolver.resolve_import(); if let Some(cached_scope) = cached_scope.as_ref() { if let Ok(mut cached_scope) = cached_scope.try_lock() { + cached_scope.invalidate_pkgs.clear(); cached_scope.update(program); resolver.scope_map = cached_scope.scope_map.clone(); resolver.scope_map.remove(kclvm_ast::MAIN_PKG); resolver.node_ty_map = cached_scope.node_ty_map.clone(); resolver.ctx.schema_mapping = cached_scope.schema_mapping.clone(); + cached_scope + .invalidate_pkgs + .insert(kclvm_ast::MAIN_PKG.to_string()); } } let scope = resolver.check_and_lint(kclvm_ast::MAIN_PKG); @@ -196,9 +200,11 @@ pub fn resolve_program_with_opts( cached_scope.node_ty_map = scope.node_ty_map.clone(); cached_scope.scope_map.remove(kclvm_ast::MAIN_PKG); cached_scope.schema_mapping = resolver.ctx.schema_mapping; + cached_scope + .invalidate_pkgs + .insert(kclvm_ast::MAIN_PKG.to_string()); } } - if opts.type_erasure { let type_alias_mapping = resolver.ctx.type_alias_mapping.clone(); // Erase all the function type to a named type "function" diff --git a/kclvm/sema/src/resolver/node.rs b/kclvm/sema/src/resolver/node.rs index 1e9d4cfa7..7f9ba1801 100644 --- a/kclvm/sema/src/resolver/node.rs +++ b/kclvm/sema/src/resolver/node.rs @@ -119,7 +119,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { doc: None, }, ); - self.node_ty_map.insert( + self.node_ty_map.borrow_mut().insert( self.get_node_key(type_alias_stmt.type_name.id.clone()), ty.clone(), ); @@ -191,7 +191,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { expected_ty.clone(), &assign_stmt.value.get_span_pos(), ); - self.node_ty_map.insert( + self.node_ty_map.borrow_mut().insert( self.get_node_key(assign_stmt.value.id.clone()), upgrade_schema_type.clone(), ); @@ -226,7 +226,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { expected_ty.clone(), &assign_stmt.value.get_span_pos(), ); - self.node_ty_map.insert( + self.node_ty_map.borrow_mut().insert( self.get_node_key(assign_stmt.value.id.clone()), upgrade_schema_type.clone(), ); @@ -402,7 +402,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { .get_type_of_attr(name) .map_or(self.any_ty(), |ty| ty); - self.node_ty_map.insert( + self.node_ty_map.borrow_mut().insert( self.get_node_key(schema_attr.name.id.clone()), expected_ty.clone(), ); @@ -534,7 +534,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { ); } - self.node_ty_map.insert( + self.node_ty_map.borrow_mut().insert( self.get_node_key(selector_expr.attr.id.clone()), value_ty.clone(), ); @@ -546,6 +546,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { selector_expr.attr.get_span_pos(), ); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), value_ty.clone()); } @@ -973,7 +974,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { ); let init_stack_depth = self.switch_config_expr_context(Some(obj)); self.expr(&schema_expr.config); - self.node_ty_map.insert( + self.node_ty_map.borrow_mut().insert( self.get_node_key(schema_expr.config.id.clone()), def_ty.clone(), ); @@ -1061,6 +1062,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { }; if let Some(name) = arg.node.names.last() { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), ty.clone()); } @@ -1137,6 +1139,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { let ty = self.parse_ty_with_scope(ty, arg.get_span_pos()); if let Some(name) = arg.node.names.last() { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), ty.clone()); } let value = &arguments.defaults[i]; @@ -1175,6 +1178,7 @@ impl<'ctx> MutSelfTypedResultWalker<'ctx> for Resolver<'ctx> { ); for (index, name) in identifier.names.iter().enumerate() { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), tys[index].clone()); } tys.last().unwrap().clone() @@ -1287,9 +1291,11 @@ impl<'ctx> Resolver<'ctx> { let upgrade_ty = self.upgrade_dict_to_schema(ty.clone(), expected_ty, &expr.get_span_pos()); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(expr.id.clone()), upgrade_ty); } else { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(expr.id.clone()), ty.clone()); } @@ -1303,6 +1309,7 @@ impl<'ctx> Resolver<'ctx> { self.ctx.end_pos = end; let ty = self.walk_stmt(&stmt.node); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(stmt.id.clone()), ty.clone()); ty } @@ -1316,6 +1323,7 @@ impl<'ctx> Resolver<'ctx> { Some(expr) => { let ty = self.walk_expr(&expr.node); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(expr.id.clone()), ty.clone()); ty } @@ -1335,10 +1343,12 @@ impl<'ctx> Resolver<'ctx> { ); for (index, name) in identifier.node.names.iter().enumerate() { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), tys[index].clone()); } let ident_ty = tys.last().unwrap().clone(); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(identifier.id.clone()), ident_ty.clone()); ident_ty diff --git a/kclvm/sema/src/resolver/schema.rs b/kclvm/sema/src/resolver/schema.rs index 01691c904..4b42df4f7 100644 --- a/kclvm/sema/src/resolver/schema.rs +++ b/kclvm/sema/src/resolver/schema.rs @@ -24,6 +24,7 @@ impl<'ctx> Resolver<'ctx> { let ty = self.lookup_type_from_scope(&schema_stmt.name.node, schema_stmt.name.get_span_pos()); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(schema_stmt.name.id.clone()), ty.clone()); let scope_ty = if ty.is_schema() { ty.into_schema_type() @@ -47,6 +48,7 @@ impl<'ctx> Resolver<'ctx> { let ty = self.parse_ty_with_scope(ty, arg.get_span_pos()); if let Some(name) = arg.node.names.last() { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), ty.clone()); } } @@ -136,6 +138,7 @@ impl<'ctx> Resolver<'ctx> { self.resolve_unique_key(&rule_stmt.name.node, &rule_stmt.name.get_span_pos()); let ty = self.lookup_type_from_scope(&rule_stmt.name.node, rule_stmt.name.get_span_pos()); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(rule_stmt.name.id.clone()), ty.clone()); let scope_ty = if ty.is_schema() { ty.into_schema_type() diff --git a/kclvm/sema/src/resolver/scope.rs b/kclvm/sema/src/resolver/scope.rs index e543af75a..e2ad853d8 100644 --- a/kclvm/sema/src/resolver/scope.rs +++ b/kclvm/sema/src/resolver/scope.rs @@ -286,7 +286,7 @@ pub struct ProgramScope { pub scope_map: IndexMap>>, pub import_names: IndexMap>, pub schema_mapping: IndexMap>>, - pub node_ty_map: NodeTyMap, + pub node_ty_map: Rc>, pub handler: Handler, } @@ -460,6 +460,7 @@ impl<'ctx> Resolver<'ctx> { let mut obj = obj.borrow_mut(); let infer_ty = self.ctx.ty_ctx.infer_to_variable_type(ty); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(node.id.clone()), infer_ty.clone()); obj.ty = infer_ty; } @@ -511,7 +512,8 @@ pub struct CachedScope { pub program_root: String, pub scope_map: IndexMap>>, pub schema_mapping: IndexMap>>, - pub node_ty_map: NodeTyMap, + pub node_ty_map: Rc>, + pub invalidate_pkgs: HashSet, dependency_graph: DependencyGraph, } @@ -674,6 +676,7 @@ impl CachedScope { program_root: program.root.to_string(), scope_map: scope.scope_map.clone(), node_ty_map: scope.node_ty_map.clone(), + invalidate_pkgs: HashSet::default(), dependency_graph: DependencyGraph::default(), schema_mapping: scope.schema_mapping.clone(), }; @@ -684,8 +687,9 @@ impl CachedScope { pub fn clear(&mut self) { self.scope_map.clear(); - self.node_ty_map.clear(); + self.node_ty_map.borrow_mut().clear(); self.dependency_graph.clear(); + self.invalidate_pkgs.clear(); } pub fn invalidate_cache(&mut self, invalidated_pkgs: Result<&HashSet, &String>) { @@ -694,6 +698,7 @@ impl CachedScope { for invalidated_pkg in invalidated_pkgs.iter() { self.scope_map.remove(invalidated_pkg); } + self.invalidate_pkgs = invalidated_pkgs.clone(); } Err(_) => self.clear(), } diff --git a/kclvm/sema/src/resolver/ty.rs b/kclvm/sema/src/resolver/ty.rs index 2971ed5a5..b8e338f24 100644 --- a/kclvm/sema/src/resolver/ty.rs +++ b/kclvm/sema/src/resolver/ty.rs @@ -76,6 +76,7 @@ impl<'ctx> Resolver<'ctx> { ); if let Some(ty) = ty_node { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(ty.id.clone()), ret_ty.clone()); }; ret_ty @@ -451,10 +452,12 @@ impl<'ctx> Resolver<'ctx> { if let ast::Type::Named(identifier) = &ty_node.node { for (index, name) in identifier.names.iter().enumerate() { self.node_ty_map + .borrow_mut() .insert(self.get_node_key(name.id.clone()), tys[index].clone()); } let ident_ty = tys.last().unwrap().clone(); self.node_ty_map + .borrow_mut() .insert(self.get_node_key(ty_node.id.clone()), ident_ty.clone()); } }; diff --git a/kclvm/spec/gpyrpc/gpyrpc.proto b/kclvm/spec/gpyrpc/gpyrpc.proto index 4225fa926..d33e944fc 100644 --- a/kclvm/spec/gpyrpc/gpyrpc.proto +++ b/kclvm/spec/gpyrpc/gpyrpc.proto @@ -285,7 +285,7 @@ message OverrideFile_Result { } message ListVariables_Args { - string file = 1; + repeated string files = 1; repeated string specs = 2; } diff --git a/kclvm/tools/src/LSP/src/document_symbol.rs b/kclvm/tools/src/LSP/src/document_symbol.rs index 7aae5434e..29b466b5d 100644 --- a/kclvm/tools/src/LSP/src/document_symbol.rs +++ b/kclvm/tools/src/LSP/src/document_symbol.rs @@ -130,6 +130,7 @@ fn symbol_kind_to_document_symbol_kind(kind: KCLSymbolKind) -> Option Some(SymbolKind::STRUCT), KCLSymbolKind::Attribute => Some(SymbolKind::PROPERTY), KCLSymbolKind::Value => Some(SymbolKind::VARIABLE), + KCLSymbolKind::Function => Some(SymbolKind::FUNCTION), KCLSymbolKind::Package => Some(SymbolKind::PACKAGE), KCLSymbolKind::TypeAlias => Some(SymbolKind::TYPE_PARAMETER), KCLSymbolKind::Unresolved => Some(SymbolKind::NULL), diff --git a/kclvm/tools/src/LSP/src/find_refs.rs b/kclvm/tools/src/LSP/src/find_refs.rs index f62a29344..37ed99ea6 100644 --- a/kclvm/tools/src/LSP/src/find_refs.rs +++ b/kclvm/tools/src/LSP/src/find_refs.rs @@ -9,9 +9,7 @@ use crate::state::{KCLEntryCache, KCLVfs, KCLWordIndexMap}; use anyhow::Result; use kclvm_driver::toolchain; use kclvm_error::Position as KCLPos; -use kclvm_parser::KCLModuleCache; use kclvm_sema::core::global_state::GlobalState; -use kclvm_sema::resolver::scope::KCLScopeCache; use lsp_types::Location; use parking_lot::lock_api::RwLock; @@ -24,8 +22,6 @@ pub(crate) fn find_refs Result<(), anyhow::Error>>( vfs: Option, logger: F, gs: &GlobalState, - module_cache: Option, - scope_cache: Option, entry_cache: Option, ) -> Result, String> { let def = find_def(kcl_pos, gs, true); @@ -43,8 +39,6 @@ pub(crate) fn find_refs Result<(), anyhow::Error>>( include_declaration, Some(FIND_REFS_LIMIT), logger, - module_cache, - scope_cache, entry_cache, )) } else { @@ -69,8 +63,6 @@ pub(crate) fn find_refs_from_def Result<(), anyhow::Error>>( include_declaration: bool, limit: Option, logger: F, - module_cache: Option, - scope_cache: Option, entry_cache: Option, ) -> Vec { let mut ref_locations = vec![]; @@ -94,9 +86,10 @@ pub(crate) fn find_refs_from_def Result<(), anyhow::Error>>( Ok(file_path) => { match compile_with_params(Params { file: file_path.clone(), - module_cache: module_cache.clone(), - scope_cache: scope_cache.clone(), + module_cache: None, + scope_cache: None, vfs: vfs.clone(), + gs_cache: None, entry_cache: entry_cache.clone(), tool: Arc::new(RwLock::new(toolchain::default())), }) @@ -222,8 +215,6 @@ mod tests { Some(20), logger, None, - None, - None, ), ); } @@ -280,8 +271,6 @@ mod tests { Some(20), logger, None, - None, - None, ), ); } @@ -338,8 +327,6 @@ mod tests { Some(20), logger, None, - None, - None, ), ); } @@ -389,8 +376,6 @@ mod tests { Some(20), logger, None, - None, - None, ), ); } diff --git a/kclvm/tools/src/LSP/src/hover.rs b/kclvm/tools/src/LSP/src/hover.rs index fc8215a9d..4b39351db 100644 --- a/kclvm/tools/src/LSP/src/hover.rs +++ b/kclvm/tools/src/LSP/src/hover.rs @@ -92,7 +92,8 @@ pub(crate) fn hover(kcl_pos: &KCLPos, gs: &GlobalState) -> Option {} } } - kclvm_sema::core::symbol::SymbolKind::Value => match &obj.get_sema_info().ty { + kclvm_sema::core::symbol::SymbolKind::Value + | kclvm_sema::core::symbol::SymbolKind::Function => match &obj.get_sema_info().ty { Some(ty) => match &ty.kind { kclvm_sema::ty::TypeKind::Function(func_ty) => { docs.append(&mut build_func_hover_content( diff --git a/kclvm/tools/src/LSP/src/quick_fix.rs b/kclvm/tools/src/LSP/src/quick_fix.rs index 00c8f050c..c0ae2ddd8 100644 --- a/kclvm/tools/src/LSP/src/quick_fix.rs +++ b/kclvm/tools/src/LSP/src/quick_fix.rs @@ -190,6 +190,7 @@ mod tests { vfs: Some(KCLVfs::default()), entry_cache: None, tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: None, }) .0; diff --git a/kclvm/tools/src/LSP/src/rename.rs b/kclvm/tools/src/LSP/src/rename.rs index ff08e6a08..31ea7f02a 100644 --- a/kclvm/tools/src/LSP/src/rename.rs +++ b/kclvm/tools/src/LSP/src/rename.rs @@ -189,12 +189,12 @@ where None, ); - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); - let node_ty_map = prog_scope.node_ty_map.clone(); - let global_state = AdvancedResolver::resolve_program(&program, gs, node_ty_map)?; + let mut gs = GlobalState::default(); + Namer::find_symbols(&program, &mut gs); + let node_ty_map = prog_scope.node_ty_map; + AdvancedResolver::resolve_program(&program, &mut gs, node_ty_map)?; - Ok((program, global_state)) + Ok((program, gs)) } fn apply_rename_changes( diff --git a/kclvm/tools/src/LSP/src/request.rs b/kclvm/tools/src/LSP/src/request.rs index d911cfc70..48bfb3fb0 100644 --- a/kclvm/tools/src/LSP/src/request.rs +++ b/kclvm/tools/src/LSP/src/request.rs @@ -273,8 +273,6 @@ pub(crate) fn handle_reference( }; let pos = kcl_pos(&file, params.text_document_position.position); let log = |msg: String| log_message(msg, &sender); - let module_cache = snapshot.module_cache.clone(); - let _scope_cache = snapshot.scope_cache.clone(); let entry_cache = snapshot.entry_cache.clone(); match find_refs( &pos, @@ -283,8 +281,6 @@ pub(crate) fn handle_reference( Some(snapshot.vfs.clone()), log, &db.gs, - Some(module_cache), - None, Some(entry_cache), ) { core::result::Result::Ok(locations) => Ok(Some(locations)), @@ -410,8 +406,6 @@ pub(crate) fn handle_rename( Some(snapshot.vfs.clone()), log, &db.gs, - Some(snapshot.module_cache), - Some(snapshot.scope_cache), Some(snapshot.entry_cache), ); match references { diff --git a/kclvm/tools/src/LSP/src/semantic_token.rs b/kclvm/tools/src/LSP/src/semantic_token.rs index 635b3ea82..f7784bc71 100644 --- a/kclvm/tools/src/LSP/src/semantic_token.rs +++ b/kclvm/tools/src/LSP/src/semantic_token.rs @@ -5,6 +5,7 @@ use kclvm_sema::core::{ global_state::GlobalState, symbol::{KCLSymbol, SymbolKind}, }; +use kclvm_sema::ty::TypeKind; use lsp_types::{SemanticToken, SemanticTokenType, SemanticTokens, SemanticTokensResult}; pub const LEGEND_TYPE: &[SemanticTokenType] = &[ @@ -16,6 +17,7 @@ pub const LEGEND_TYPE: &[SemanticTokenType] = &[ SemanticTokenType::MACRO, SemanticTokenType::COMMENT, SemanticTokenType::PARAMETER, + SemanticTokenType::FUNCTION, ]; pub(crate) struct KCLSemanticToken { @@ -62,7 +64,17 @@ pub(crate) fn get_kind(ty: SymbolKind, symbol: &KCLSymbol, gs: &GlobalState) -> SymbolKind::Attribute => Some(type_index(SemanticTokenType::PROPERTY)), SymbolKind::Package => Some(type_index(SemanticTokenType::NAMESPACE)), SymbolKind::TypeAlias => Some(type_index(SemanticTokenType::TYPE)), - SymbolKind::Value => Some(type_index(SemanticTokenType::VARIABLE)), + SymbolKind::Value => { + if let Some(ty) = &symbol.get_sema_info().ty { + match ty.kind { + TypeKind::Function(_) => Some(type_index(SemanticTokenType::FUNCTION)), + _ => Some(type_index(SemanticTokenType::VARIABLE)), + } + } else { + Some(type_index(SemanticTokenType::VARIABLE)) + } + } + SymbolKind::Function => Some(type_index(SemanticTokenType::FUNCTION)), SymbolKind::Rule => Some(type_index(SemanticTokenType::MACRO)), SymbolKind::Unresolved => match &symbol.get_definition() { Some(def_ref) => match gs.get_symbols().get_symbol(*def_ref) { @@ -153,6 +165,9 @@ mod tests { (1, 4, 4, 2), // name (2, 0, 1, 0), // n (0, 3, 3, 4), // num + (2, 0, 4, 8), // func + (0, 14, 1, 0), // x + (1, 4, 1, 0), // x ]; let res = semantic_tokens_full(&file, &gs); if let Some(tokens) = res { diff --git a/kclvm/tools/src/LSP/src/state.rs b/kclvm/tools/src/LSP/src/state.rs index b7e257eef..af671e2ab 100644 --- a/kclvm/tools/src/LSP/src/state.rs +++ b/kclvm/tools/src/LSP/src/state.rs @@ -8,6 +8,7 @@ use crossbeam_channel::{select, unbounded, Receiver, Sender}; use kclvm_driver::toolchain::{self, Toolchain}; use kclvm_driver::CompileUnitOptions; use kclvm_parser::KCLModuleCache; +use kclvm_sema::core::global_state::GlobalState; use kclvm_sema::resolver::scope::KCLScopeCache; use lsp_server::{ReqQueue, Request, Response}; use lsp_types::Url; @@ -18,6 +19,7 @@ use lsp_types::{ use parking_lot::RwLock; use ra_ap_vfs::{ChangeKind, ChangedFile, FileId, Vfs}; use std::collections::HashMap; +use std::sync::Mutex; use std::thread; use std::time::Duration; use std::{sync::Arc, time::Instant}; @@ -49,6 +51,7 @@ pub(crate) type KCLVfs = Arc>; pub(crate) type KCLWordIndexMap = Arc>>>>; pub(crate) type KCLEntryCache = Arc>>; pub(crate) type KCLToolChain = Arc>; +pub(crate) type KCLGlobalStateCache = Arc>; /// State for the language server pub(crate) struct LanguageServerState { @@ -82,6 +85,8 @@ pub(crate) struct LanguageServerState { pub entry_cache: KCLEntryCache, /// Toolchain is used to provider KCL tool features for the language server. pub tool: KCLToolChain, + /// KCL globalstate cache + pub gs_cache: KCLGlobalStateCache, } /// A snapshot of the state of the language server @@ -134,6 +139,7 @@ impl LanguageServerState { scope_cache: KCLScopeCache::default(), entry_cache: KCLEntryCache::default(), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: KCLGlobalStateCache::default(), }; let word_index_map = state.word_index_map.clone(); @@ -223,6 +229,7 @@ impl LanguageServerState { let scope_cache = Arc::clone(&self.scope_cache); let entry = Arc::clone(&self.entry_cache); let tool = Arc::clone(&self.tool); + let gs_cache = Arc::clone(&self.gs_cache); move || match url(&snapshot, file.file_id) { Ok(uri) => { let version = @@ -235,6 +242,7 @@ impl LanguageServerState { vfs: Some(snapshot.vfs), entry_cache: Some(entry), tool, + gs_cache: Some(gs_cache), }); let current_version = diff --git a/kclvm/tools/src/LSP/src/test_data/sema_token.k b/kclvm/tools/src/LSP/src/test_data/sema_token.k index 74be332c8..1b0e43ca3 100644 --- a/kclvm/tools/src/LSP/src/test_data/sema_token.k +++ b/kclvm/tools/src/LSP/src/test_data/sema_token.k @@ -6,4 +6,8 @@ schema Persons: p5: Persons = Persons { name: "alice" } -n: num = 1 \ No newline at end of file +n: num = 1 + +func = lambda x{ + x +} \ No newline at end of file diff --git a/kclvm/tools/src/LSP/src/tests.rs b/kclvm/tools/src/LSP/src/tests.rs index 7f4ba0cd8..31f37cd5c 100644 --- a/kclvm/tools/src/LSP/src/tests.rs +++ b/kclvm/tools/src/LSP/src/tests.rs @@ -77,6 +77,7 @@ use crate::goto_def::goto_def; use crate::hover::hover; use crate::main_loop::main_loop; use crate::state::KCLEntryCache; +use crate::state::KCLGlobalStateCache; use crate::state::KCLVfs; use crate::to_lsp::kcl_diag_to_lsp_diags; use crate::util::lookup_compile_unit_with_cache; @@ -134,6 +135,7 @@ pub(crate) fn compile_test_file( vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }); let (program, gs) = compile_res.unwrap(); (file, program, diags, gs) @@ -297,6 +299,7 @@ fn diagnostics_test() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .0; @@ -485,6 +488,7 @@ fn complete_import_external_file_test() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .1 .unwrap(); @@ -546,6 +550,7 @@ fn goto_import_external_file_test() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }); let gs = compile_res.unwrap().1; @@ -1401,6 +1406,7 @@ fn konfig_goto_def_test_base() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .1 .unwrap(); @@ -1495,6 +1501,7 @@ fn konfig_goto_def_test_main() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .1 .unwrap(); @@ -1561,6 +1568,7 @@ fn konfig_completion_test_main() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .1 .unwrap(); @@ -1676,6 +1684,7 @@ fn konfig_hover_test_main() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .1 .unwrap(); @@ -2111,6 +2120,7 @@ fn compile_unit_test() { vfs: Some(KCLVfs::default()), entry_cache: Some(KCLEntryCache::default()), tool: Arc::new(RwLock::new(toolchain::default())), + gs_cache: Some(KCLGlobalStateCache::default()), }) .1 .unwrap() diff --git a/kclvm/tools/src/LSP/src/util.rs b/kclvm/tools/src/LSP/src/util.rs index aab9c7661..fd63b9403 100644 --- a/kclvm/tools/src/LSP/src/util.rs +++ b/kclvm/tools/src/LSP/src/util.rs @@ -19,12 +19,14 @@ use kclvm_sema::resolver::resolve_program_with_opts; use kclvm_sema::resolver::scope::KCLScopeCache; use crate::from_lsp; -use crate::state::{KCLEntryCache, KCLToolChain, KCLVfs}; +use crate::state::{KCLEntryCache, KCLToolChain}; +use crate::state::{KCLGlobalStateCache, KCLVfs}; use lsp_types::Url; use parking_lot::RwLockReadGuard; use ra_ap_vfs::{FileId, Vfs}; use serde::{de::DeserializeOwned, Serialize}; +use std::collections::HashSet; use std::fs; use std::path::Path; @@ -66,6 +68,7 @@ pub(crate) struct Params { pub entry_cache: Option, pub vfs: Option, pub tool: KCLToolChain, + pub gs_cache: Option, } pub(crate) fn lookup_compile_unit_with_cache( @@ -125,6 +128,7 @@ pub(crate) fn compile_with_params( Err(e) => return (diags, Err(anyhow::anyhow!("Parse failed: {:?}", e))), }; diags.extend(sess.1.borrow().diagnostics.clone()); + // Resolver let prog_scope = resolve_program_with_opts( &mut program, @@ -133,15 +137,37 @@ pub(crate) fn compile_with_params( type_erasure: false, ..Default::default() }, - params.scope_cache, + params.scope_cache.clone(), ); diags.extend(prog_scope.handler.diagnostics); - // Please note that there is no global state cache at this stage. - let gs = GlobalState::default(); - let gs = Namer::find_symbols(&program, gs); - match AdvancedResolver::resolve_program(&program, gs, prog_scope.node_ty_map.clone()) { - Ok(gs) => (diags, Ok((program, gs))), + let mut default = GlobalState::default(); + let mut gs_ref; + + let mut gs = match ¶ms.gs_cache { + Some(cache) => match cache.try_lock() { + Ok(locked_state) => { + gs_ref = locked_state; + &mut gs_ref + } + Err(_) => &mut default, + }, + None => &mut default, + }; + + gs.new_or_invalidate_pkgs = match ¶ms.scope_cache { + Some(cache) => match cache.try_lock() { + Ok(scope) => scope.invalidate_pkgs.clone(), + Err(_) => HashSet::new(), + }, + None => HashSet::new(), + }; + gs.clear_cache(); + + Namer::find_symbols(&program, &mut gs); + + match AdvancedResolver::resolve_program(&program, gs, prog_scope.node_ty_map) { + Ok(_) => (diags, Ok((program, gs.clone()))), Err(e) => (diags, Err(anyhow::anyhow!("Resolve failed: {:?}", e))), } }