diff options
| author | Daniel Gavin <danielgavin5@hotmail.com> | 2022-07-09 20:45:57 +0200 |
|---|---|---|
| committer | Daniel Gavin <danielgavin5@hotmail.com> | 2022-07-09 20:45:57 +0200 |
| commit | 22617323ab40d28480541527957f76697e308d2c (patch) | |
| tree | a423d1b4f87da05dad700d1035d6cce04151dc52 | |
| parent | 28d4e76ecc635c1c386ff914d4db6c92eea092e8 (diff) | |
Restructed the indexer
| -rw-r--r-- | src/main.odin | 6 | ||||
| -rw-r--r-- | src/server/analysis.odin | 6 | ||||
| -rw-r--r-- | src/server/build.odin | 162 | ||||
| -rw-r--r-- | src/server/caches.odin | 13 | ||||
| -rw-r--r-- | src/server/completion.odin | 67 | ||||
| -rw-r--r-- | src/server/definition.odin | 2 | ||||
| -rw-r--r-- | src/server/document_symbols.odin | 2 | ||||
| -rw-r--r-- | src/server/documents.odin | 8 | ||||
| -rw-r--r-- | src/server/hover.odin | 2 | ||||
| -rw-r--r-- | src/server/indexer.odin | 28 | ||||
| -rw-r--r-- | src/server/inlay_hints.odin | 2 | ||||
| -rw-r--r-- | src/server/lens.odin | 2 | ||||
| -rw-r--r-- | src/server/memory_index.odin | 12 | ||||
| -rw-r--r-- | src/server/references.odin | 2 | ||||
| -rw-r--r-- | src/server/requests.odin | 4 | ||||
| -rw-r--r-- | src/server/semantic_tokens.odin | 2 | ||||
| -rw-r--r-- | src/server/signature.odin | 2 | ||||
| -rw-r--r-- | src/testing/testing.odin | 16 |
18 files changed, 116 insertions, 222 deletions
diff --git a/src/main.odin b/src/main.odin index e3d3bee..b68f90d 100644 --- a/src/main.odin +++ b/src/main.odin @@ -53,6 +53,8 @@ run :: proc(reader: ^server.Reader, writer: ^server.Writer) { request_thread = thread.create_and_start_with_data(cast(rawptr)&request_thread_data, server.thread_request_main) + server.setup_index(); + for common.config.running { if common.config.file_log { if !file_logger_init { @@ -80,7 +82,7 @@ run :: proc(reader: ^server.Reader, writer: ^server.Writer) { server.document_storage_shutdown() - server.free_static_index() + server.free_index() } end :: proc() { @@ -96,6 +98,6 @@ main :: proc() { context.logger = verbose_logger init_global_temporary_allocator(mem.Megabyte*100) - + run(&reader, &writer) } diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 933ce8a..aabaf79 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -81,10 +81,11 @@ AstContext :: struct { value_decl: ^ast.Value_Decl, field_name: string, uri: string, + fullpath: string, recursion_counter: int, //Sometimes the ast is so malformed that it causes infinite recursion. } -make_ast_context :: proc(file: ast.File, imports: []Package, package_name: string, uri: string, allocator := context.temp_allocator) -> AstContext { +make_ast_context :: proc(file: ast.File, imports: []Package, package_name: string, uri: string, fullpath: string, allocator := context.temp_allocator) -> AstContext { ast_context := AstContext { locals = make(map[int]map[string][dynamic]DocumentLocal, 0, allocator), globals = make(map[string]common.GlobalExpr, 0, allocator), @@ -99,6 +100,7 @@ make_ast_context :: proc(file: ast.File, imports: []Package, package_name: strin document_package = package_name, current_package = package_name, uri = uri, + fullpath = fullpath, allocator = allocator, } @@ -2470,7 +2472,7 @@ clear_locals :: proc(ast_context: ^AstContext) { } resolve_entire_file :: proc(document: ^Document, skip_locals := false, allocator := context.allocator) -> map[uintptr]SymbolAndNode { - ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, allocator) + ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath, allocator) get_globals(document.ast, &ast_context) diff --git a/src/server/build.odin b/src/server/build.odin index 94bc4f3..a903b3d 100644 --- a/src/server/build.odin +++ b/src/server/build.odin @@ -11,14 +11,10 @@ import "core:odin/tokenizer" import "core:strings" import "core:mem" import "core:runtime" +import "core:time" import "shared:common" - -symbol_collection: SymbolCollection - -files: [dynamic]string - platform_os: map[string]bool = { "windows" = true, "linux" = true, @@ -40,126 +36,25 @@ os_enum_to_string: map[runtime.Odin_OS_Type]string = { .Freestanding = "freestanding", } -walk_directory :: proc(info: os.File_Info, in_err: os.Errno) -> (err: os.Errno, skip_dir: bool) { - if info.is_dir { - return 0, true - } - - if filepath.ext(info.name) != ".odin" { - return 0, false +try_build_package :: proc(pkg_name: string) { + if pkg, ok := build_cache.loaded_pkgs[pkg_name]; ok { + return } - last_underscore_index := strings.last_index(info.name, "_") - last_dot_index := strings.last_index(info.name, ".") + matches, err := filepath.glob(fmt.tprintf("%v/*.odin", pkg_name), context.temp_allocator) - if last_underscore_index + 1 < last_dot_index { - name_between := info.name[last_underscore_index + 1:last_dot_index] - - if _, ok := platform_os[name_between]; ok { - if name_between != os_enum_to_string[ODIN_OS] { - return 0, false - } - } + if err != .None { + log.errorf("Failed to glob %v for indexing package", pkg_name) } - forward, _ := filepath.to_slash(info.fullpath, context.temp_allocator) - - append(&files, strings.clone(forward, context.allocator)) - - return 0, false -} - -/* -try_build_package :: proc(pkg: string) { - - - - - -} - -evict_old_build_packages :: proc() { - -} -*/ - -/* - - -build_static_index :: proc(allocator := context.allocator, config: ^common.Config) { - symbol_collection = make_symbol_collection(allocator, config) - - files = make([dynamic]string, context.allocator) - - for k, v in config.collections { - filepath.walk(v, walk_static_index_build) - } - - when ODIN_OS == .Windows { - slashed, _ := filepath.to_slash(os.get_current_directory(context.temp_allocator), context.temp_allocator) - } else { - slashed, _ := filepath.to_slash(os.get_current_directory(), context.temp_allocator) - } - - builtin_package := path.join(elems = {slashed, "builtin"}, allocator = context.allocator) - - filepath.walk(builtin_package, walk_static_index_build) - temp_arena: mem.Arena - mem.init_arena(&temp_arena, make([]byte, mem.Megabyte*100)) - - context.allocator = mem.arena_allocator(&temp_arena) + mem.init_arena(&temp_arena, make([]byte, mem.Megabyte*25)) - for fullpath in files { - data, ok := os.read_entire_file(fullpath, context.allocator) + { + context.allocator = mem.arena_allocator(&temp_arena) - if !ok { - log.errorf("failed to read entire file for indexing %v", fullpath) - continue - } - - p := parser.Parser { - err = log_error_handler, - warn = log_warning_handler, - flags = {.Optional_Semicolons}, - } - - dir := filepath.base(filepath.dir(fullpath, context.allocator)) - - pkg := new(ast.Package) - pkg.kind = .Normal - pkg.fullpath = fullpath - pkg.name = dir - - if dir == "runtime" { - pkg.kind = .Runtime - } - - file := ast.File { - fullpath = fullpath, - src = string(data), - pkg = pkg, - } - - ok = parser.parse_file(&p, &file) - - if !ok { - log.info(pkg) - log.errorf("error in parse file for indexing %v", fullpath) - } - - uri := common.create_uri(fullpath, context.allocator) - - collect_symbols(&symbol_collection, file, uri.uri) - - free_all(context.allocator) - } - - indexer.index = make_memory_index(symbol_collection) - - if config.enable_references { - for fullpath in files { + for fullpath in matches { data, ok := os.read_entire_file(fullpath, context.allocator) if !ok { @@ -167,11 +62,6 @@ build_static_index :: proc(allocator := context.allocator, config: ^common.Confi continue } - //TODO(daniel): Implement path code to handle whether paths are contained in core - if !config.enable_std_references && (strings.contains(fullpath, "Odin/core") || strings.contains(fullpath, "odin/core") || strings.contains(fullpath, "Odin/vendor") || strings.contains(fullpath, "odin/vendor")) { - continue; - } - p := parser.Parser { err = log_error_handler, warn = log_warning_handler, @@ -198,31 +88,39 @@ build_static_index :: proc(allocator := context.allocator, config: ^common.Confi ok = parser.parse_file(&p, &file) if !ok { - log.info(pkg) log.errorf("error in parse file for indexing %v", fullpath) } uri := common.create_uri(fullpath, context.allocator) - { - context.temp_allocator = context.allocator - collect_references(&symbol_collection, file, uri.uri) - } + collect_symbols(&indexer.index.collection, file, uri.uri) free_all(context.allocator) - - delete(fullpath, allocator) } } - delete(files) delete(temp_arena.data) - indexer.index = make_memory_index(symbol_collection) + build_cache.loaded_pkgs[strings.clone(pkg_name, indexer.index.collection.allocator)] = PackageCacheInfo { + timestamp = time.now(), + } +} + +/* + +evict_old_build_packages :: proc() { + } */ -free_static_index :: proc() { - delete_symbol_collection(symbol_collection) + +setup_index :: proc() { + build_cache.loaded_pkgs = make(map[string]PackageCacheInfo, 50, context.allocator) + symbol_collection := make_symbol_collection(context.allocator, &common.config) + indexer.index = make_memory_index(symbol_collection) +} + +free_index :: proc() { + delete_symbol_collection(indexer.index.collection) } log_error_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) { diff --git a/src/server/caches.odin b/src/server/caches.odin index d260de2..aee5e00 100644 --- a/src/server/caches.odin +++ b/src/server/caches.odin @@ -2,6 +2,8 @@ package server import "shared:common" +import "core:time" + //Used in semantic tokens and inlay hints to handle the entire file being resolved. FileResolveCache :: struct { files: map[string]map[uintptr]SymbolAndNode, @@ -20,3 +22,14 @@ resolve_entire_file_cached :: proc(document: ^Document) -> map[uintptr]SymbolAnd return file_resolve_cache.files[document.uri.uri]; } + + +BuildCache :: struct { + loaded_pkgs: map[string]PackageCacheInfo, +} + +PackageCacheInfo :: struct { + timestamp: time.Time, +} + +build_cache: BuildCache
\ No newline at end of file diff --git a/src/server/completion.odin b/src/server/completion.odin index 218bbc3..3de9ee9 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -45,7 +45,7 @@ get_completion_list :: proc(document: ^Document, position: common.Position, comp return list, true } - ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri) + ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath) get_globals(document.ast, &ast_context) @@ -662,7 +662,7 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc if position_context.binary != nil && (position_context.binary.op.text == "==" || position_context.binary.op.text == "!=") { context_node: ^ast.Expr - enum_node: ^ast.Expr + enum_node: ^ast.Expr if position_in_node(position_context.binary.right, position_context.position) { context_node = position_context.binary.right @@ -799,40 +799,22 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc } } +CombinedResult :: struct { + score: f32, + snippet: Snippet_Info, + name: string, + type: SymbolType, + doc: string, + pkg: string, + signature: string, + flags: SymbolFlags, +} + get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) { items := make([dynamic]CompletionItem, context.temp_allocator) list.isIncomplete = true - CombinedResult :: struct { - score: f32, - snippet: Snippet_Info, - name: string, - type: SymbolType, - doc: string, - pkg: string, - signature: string, - flags: SymbolFlags, - } - - combined_sort_interface :: proc(s: ^[dynamic]CombinedResult) -> sort.Interface { - return sort.Interface { - collection = rawptr(s), - len = proc(it: sort.Interface) -> int { - s := (^[dynamic]CombinedResult)(it.collection) - return len(s^) - }, - less = proc(it: sort.Interface, i, j: int) -> bool { - s := (^[dynamic]CombinedResult)(it.collection) - return s[i].score > s[j].score - }, - swap = proc(it: sort.Interface, i, j: int) { - s := (^[dynamic]CombinedResult)(it.collection) - s[i], s[j] = s[j], s[i] - }, - } - } - combined := make([dynamic]CombinedResult) lookup_name := "" @@ -853,13 +835,15 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D append(&pkgs, ast_context.document_package) append(&pkgs, "$builtin") - + if results, ok := fuzzy_search(lookup_name, pkgs[:]); ok { for r in results { r := r resolve_unresolved_symbol(ast_context, &r.symbol) build_procedure_symbol_signature(&r.symbol) - if r.symbol.uri != ast_context.uri { + + uri, _ := common.parse_uri(r.symbol.uri, context.temp_allocator) + if uri.path != ast_context.fullpath { append(&combined, CombinedResult { score = r.score, type = r.symbol.type, @@ -989,7 +973,7 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D }) } } - + for keyword, _ in language_keywords { symbol := Symbol { name = keyword, @@ -1017,8 +1001,21 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D } } - sort.sort(combined_sort_interface(&combined)) + for f in combined { + //log.error(f.name, " ") + } + + //log.error("sorting done \n") + slice.sort_by(combined[:], proc(i, j: CombinedResult) -> bool { + return j.score < i.score + }) + + for f in combined { + //log.error(f.name, " ") + } + + //hard code for now top_results := combined[0:(min(50, len(combined)))] diff --git a/src/server/definition.odin b/src/server/definition.odin index a01c6a9..6a0d07b 100644 --- a/src/server/definition.odin +++ b/src/server/definition.odin @@ -21,7 +21,7 @@ get_definition_location :: proc(document: ^Document, position: common.Position) location: common.Location - ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri) + ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath) uri: string diff --git a/src/server/document_symbols.odin b/src/server/document_symbols.odin index 9fa170b..274c37f 100644 --- a/src/server/document_symbols.odin +++ b/src/server/document_symbols.odin @@ -18,7 +18,7 @@ import "core:os" import "shared:common" get_document_symbols :: proc(document: ^Document) -> []DocumentSymbol { - ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri) + ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath) get_globals(document.ast, &ast_context) diff --git a/src/server/documents.odin b/src/server/documents.odin index 3e3cb3c..335fc87 100644 --- a/src/server/documents.odin +++ b/src/server/documents.odin @@ -182,7 +182,7 @@ document_setup :: proc(document: ^Document) { } } else { document.fullpath = document.uri.path - } + } } /* @@ -453,5 +453,11 @@ parse_imports :: proc(document: ^Document, config: ^common.Config) { } } + for imp in imports { + try_build_package(imp.name) + } + + try_build_package(document.package_name) + document.imports = imports[:] } diff --git a/src/server/hover.odin b/src/server/hover.odin index 98eaa50..0a419dd 100644 --- a/src/server/hover.odin +++ b/src/server/hover.odin @@ -55,7 +55,7 @@ get_hover_information :: proc(document: ^Document, position: common.Position) -> }, } - ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri) + ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath) position_context, ok := get_document_position_context(document, position, .Hover) diff --git a/src/server/indexer.odin b/src/server/indexer.odin index 095dd60..cb24cec 100644 --- a/src/server/indexer.odin +++ b/src/server/indexer.odin @@ -4,12 +4,12 @@ import "core:odin/ast" import "core:fmt" import "core:strings" import "core:log" -import "core:sort" +import "core:slice" Indexer :: struct { - builtin_packages: [dynamic]string, - index: MemoryIndex, + builtin_packages: [dynamic]string, + index: MemoryIndex, } indexer: Indexer @@ -41,25 +41,9 @@ fuzzy_search :: proc(name: string, pkgs: []string) -> ([]FuzzyResult, bool) { append(&result, r) } - sort.sort(fuzzy_sort_interface(&result)) + slice.sort_by(result[:], proc(i, j: FuzzyResult) -> bool { + return j.score < i.score + }) return result[:], true } - -fuzzy_sort_interface :: proc(s: ^[dynamic]FuzzyResult) -> sort.Interface { - return sort.Interface { - collection = rawptr(s), - len = proc(it: sort.Interface) -> int { - s := (^[dynamic]FuzzyResult)(it.collection) - return len(s^) - }, - less = proc(it: sort.Interface, i, j: int) -> bool { - s := (^[dynamic]FuzzyResult)(it.collection) - return s[i].score > s[j].score - }, - swap = proc(it: sort.Interface, i, j: int) { - s := (^[dynamic]FuzzyResult)(it.collection) - s[i], s[j] = s[j], s[i] - }, - } -} diff --git a/src/server/inlay_hints.odin b/src/server/inlay_hints.odin index 9833309..fb989db 100644 --- a/src/server/inlay_hints.odin +++ b/src/server/inlay_hints.odin @@ -8,7 +8,7 @@ import "shared:common" get_inlay_hints :: proc(document: ^Document, symbols: map[uintptr]SymbolAndNode) -> ([]InlayHint, bool) { hints := make([dynamic]InlayHint, context.temp_allocator) - ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri) + ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath) Visit_Data :: struct { calls: [dynamic]^ast.Node, diff --git a/src/server/lens.odin b/src/server/lens.odin index ab25b47..5525554 100644 --- a/src/server/lens.odin +++ b/src/server/lens.odin @@ -21,7 +21,7 @@ CodeLens :: struct { } get_code_lenses :: proc(document: ^Document, position: common.Position) -> ([]CodeLens, bool) { - ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri) + ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath) get_globals(document.ast, &ast_context) diff --git a/src/server/memory_index.odin b/src/server/memory_index.odin index 9ab3c13..edb3dd6 100644 --- a/src/server/memory_index.odin +++ b/src/server/memory_index.odin @@ -4,16 +4,10 @@ import "core:hash" import "core:strings" import "core:fmt" import "core:log" -import "core:sort" +import "core:slice" import "shared:common" -/* - This is a in memory index designed for the dynamic indexing of symbols and files. - Designed for few files and should be fast at rebuilding. - - Right now the implementation is extremely naive. -*/ MemoryIndex :: struct { collection: SymbolCollection, last_package_name: string, @@ -65,7 +59,9 @@ memory_index_fuzzy_search :: proc(index: ^MemoryIndex, name: string, pkgs: []str } } - sort.sort(fuzzy_sort_interface(&symbols)) + slice.sort_by(symbols[:], proc(i, j: FuzzyResult) -> bool { + return j.score < i.score + }) if name == "" { return symbols[:], true diff --git a/src/server/references.odin b/src/server/references.odin index 70b06b6..7e68fbd 100644 --- a/src/server/references.odin +++ b/src/server/references.odin @@ -12,7 +12,7 @@ import "core:log" get_references :: proc(document: ^Document, position: common.Position) -> ([]common.Location, bool) { locations := make([dynamic]common.Location, context.temp_allocator) - ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri) + ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath) position_context, ok := get_document_position_context(document, position, .Hover) diff --git a/src/server/requests.odin b/src/server/requests.odin index 819a730..6e6fdc3 100644 --- a/src/server/requests.odin +++ b/src/server/requests.odin @@ -360,7 +360,7 @@ call :: proc(value: json.Value, id: RequestId, writer: ^Writer, config: ^common. } } - log.errorf("time duration %v for %v", time.duration_milliseconds(diff), method) + //log.errorf("time duration %v for %v", time.duration_milliseconds(diff), method) } request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error { @@ -551,8 +551,6 @@ request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.C append(&indexer.builtin_packages, path.join(core, "runtime")) } - log.info("Finished indexing") - return .None } diff --git a/src/server/semantic_tokens.odin b/src/server/semantic_tokens.odin index 7f0f322..b936419 100644 --- a/src/server/semantic_tokens.odin +++ b/src/server/semantic_tokens.odin @@ -100,7 +100,7 @@ get_semantic_tokens :: proc(document: ^Document, range: common.Range, symbols: m write_semantic_token(&builder, document.ast.pkg_token, document.ast.src, .Keyword, .None) } - ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri) + ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath) builder.symbols = symbols diff --git a/src/server/signature.odin b/src/server/signature.odin index b9c400c..bed0f59 100644 --- a/src/server/signature.odin +++ b/src/server/signature.odin @@ -113,7 +113,7 @@ seperate_proc_field_arguments :: proc(procedure: ^Symbol) { get_signature_information :: proc(document: ^Document, position: common.Position) -> (SignatureHelp, bool) { signature_help: SignatureHelp - ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri) + ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath) position_context, ok := get_document_position_context(document, position, .SignatureHelp) diff --git a/src/testing/testing.odin b/src/testing/testing.odin index 3b5a03c..5b0e30b 100644 --- a/src/testing/testing.odin +++ b/src/testing/testing.odin @@ -19,7 +19,7 @@ Package :: struct { Source :: struct { main: string, packages: [] Package, - document: ^common.Document, + document: ^server.Document, collections: map[string]string, config: common.Config, position: common.Position, @@ -28,7 +28,7 @@ Source :: struct { @(private) setup :: proc(src: ^Source) { src.main = strings.clone(src.main); - src.document = new(common.Document, context.temp_allocator); + src.document = new(server.Document, context.temp_allocator); src.document.uri = common.create_uri("test/test.odin", context.temp_allocator); src.document.client_owned = true; src.document.text = transmute([]u8)src.main; @@ -65,6 +65,8 @@ setup :: proc(src: ^Source) { last = current; } + server.setup_index() + server.document_setup(src.document) server.document_refresh(src.document, &src.config, nil); @@ -73,9 +75,6 @@ setup :: proc(src: ^Source) { There is a lot code here that is used in the real code, then i'd like to see. */ - server.indexer.dynamic_index = server.make_memory_index(server.make_symbol_collection(context.allocator, &common.config)); - - server.build_static_index(context.allocator, &common.config); for src_pkg in src.packages { uri := common.create_uri(fmt.aprintf("test/%v/package.odin", src_pkg.pkg), context.temp_allocator); @@ -112,7 +111,7 @@ setup :: proc(src: ^Source) { panic("Parser error in test package source"); } - if ret := server.collect_symbols(&server.indexer.static_index.collection, file, uri.uri); ret != .None { + if ret := server.collect_symbols(&server.indexer.index.collection, file, uri.uri); ret != .None { return; } } @@ -120,9 +119,8 @@ setup :: proc(src: ^Source) { @private teardown :: proc(src: ^Source) { - server.free_static_index() - server.indexer.dynamic_index = {} - server.indexer.static_index = {} + server.free_index() + server.indexer.index = {} } expect_signature_labels :: proc(t: ^testing.T, src: ^Source, expect_labels: []string) { |