diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2020-11-18 22:14:33 +0100 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2020-11-18 22:14:33 +0100 |
| commit | 3370a5e546ea9355068ba99b5e81f80527d2e582 (patch) | |
| tree | 5a93eda4e2a5be4ec58d3ddf2595fa7dc1016cb3 /src | |
| parent | ee4a7f64bcb9d6d7b60d5495fc072b2a62b5f790 (diff) | |
fixed all the memory leaks
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/ast.odin | 44 | ||||
| -rw-r--r-- | src/common/uri.odin | 6 | ||||
| -rw-r--r-- | src/index/build.odin | 45 | ||||
| -rw-r--r-- | src/index/clone.odin | 16 | ||||
| -rw-r--r-- | src/index/collector.odin | 14 | ||||
| -rw-r--r-- | src/index/symbol.odin | 17 | ||||
| -rw-r--r-- | src/main.odin | 31 | ||||
| -rw-r--r-- | src/server/analysis.odin | 77 | ||||
| -rw-r--r-- | src/server/documents.odin | 45 | ||||
| -rw-r--r-- | src/server/requests.odin | 40 | ||||
| -rw-r--r-- | src/server/unmarshal.odin | 4 |
11 files changed, 249 insertions, 90 deletions
diff --git a/src/common/ast.odin b/src/common/ast.odin index 8642afd..5e094a5 100644 --- a/src/common/ast.odin +++ b/src/common/ast.odin @@ -3,6 +3,7 @@ package common import "core:odin/ast" import "core:log" import "core:mem" +import "core:fmt" get_ast_node_string :: proc(node: ^ast.Node, src: [] byte) -> string { return string(src[node.pos.offset:node.end.offset]); @@ -11,19 +12,35 @@ get_ast_node_string :: proc(node: ^ast.Node, src: [] byte) -> string { free_ast :: proc{ free_ast_node, free_ast_array, - free_ast_dynamic_array + free_ast_dynamic_array, + free_ast_comment, }; +free_ast_comment :: proc(a: ^ast.Comment_Group) { + if a == nil { + return; + } + + if len(a.list) > 0 { + delete(a.list); + } + + free(a); +} + free_ast_array :: proc(array: $A/[]^$T) { for elem, i in array { free_ast(elem); } + delete(array); } free_ast_dynamic_array :: proc(array: $A/[dynamic]^$T) { for elem, i in array { free_ast(elem); } + + delete(array); } free_ast_node :: proc(node: ^ast.Node) { @@ -46,6 +63,7 @@ free_ast_node :: proc(node: ^ast.Node) { case Proc_Lit: free_ast(n.type); free_ast(n.body); + free_ast(n.where_clauses); case Comp_Lit: free_ast(n.type); free_ast(n.elems); @@ -160,14 +178,21 @@ free_ast_node :: proc(node: ^ast.Node) { free_ast(n.names); free_ast(n.type); free_ast(n.values); + //free_ast(n.docs); + //free_ast(n.comment); case Package_Decl: + //free_ast(n.docs); + //free_ast(n.comment); case Import_Decl: + //free_ast(n.docs); + //free_ast(n.comment); case Foreign_Block_Decl: free_ast(n.attributes); free_ast(n.foreign_library); free_ast(n.body); case Foreign_Import_Decl: free_ast(n.name); + free_ast(n.attributes); case Proc_Group: free_ast(n.args); case Attribute: @@ -176,6 +201,8 @@ free_ast_node :: proc(node: ^ast.Node) { free_ast(n.names); free_ast(n.type); free_ast(n.default_value); + //free_ast(n.docs); + //free_ast(n.comment); case Field_List: free_ast(n.list); case Typeid_Type: @@ -197,21 +224,26 @@ free_ast_node :: proc(node: ^ast.Node) { case Array_Type: free_ast(n.len); free_ast(n.elem); + free_ast(n.tag); case Dynamic_Array_Type: free_ast(n.elem); + free_ast(n.tag); case Struct_Type: free_ast(n.poly_params); free_ast(n.align); free_ast(n.fields); + free_ast(n.where_clauses); case Union_Type: free_ast(n.poly_params); free_ast(n.align); free_ast(n.variants); + free_ast(n.where_clauses); case Enum_Type: free_ast(n.base_type); free_ast(n.fields); case Bit_Field_Type: free_ast(n.fields); + free_ast(n.align); case Bit_Set_Type: free_ast(n.elem); free_ast(n.underlying); @@ -233,6 +265,15 @@ free_ast_file :: proc(file: ast.File) { free_ast(decl); } + free_ast(file.pkg_decl); + + for comment in file.comments { + free_ast(comment); + } + + delete(file.comments); + delete(file.imports); + delete(file.decls); } @@ -439,5 +480,4 @@ node_equal_node :: proc(a, b: ^ast.Node) -> bool { } return false; - }
\ No newline at end of file diff --git a/src/common/uri.odin b/src/common/uri.odin index f8bee9e..33a63c5 100644 --- a/src/common/uri.odin +++ b/src/common/uri.odin @@ -14,7 +14,7 @@ Uri :: struct { //Note(Daniel, This is an extremely incomplete uri parser and for now ignores fragment and query and only handles file schema) -parse_uri :: proc(value: string, allocator := context.allocator) -> (Uri, bool) { +parse_uri :: proc(value: string, allocator: mem.Allocator) -> (Uri, bool) { uri: Uri; @@ -30,7 +30,7 @@ parse_uri :: proc(value: string, allocator := context.allocator) -> (Uri, bool) return uri, false; } - uri.uri = strings.clone(value); + uri.uri = strings.clone(value, allocator); uri.decode_full = decoded; uri.path = decoded[len(starts):]; @@ -39,7 +39,7 @@ parse_uri :: proc(value: string, allocator := context.allocator) -> (Uri, bool) //Note(Daniel, Again some really incomplete and scuffed uri writer) -create_uri :: proc(path: string, allocator := context.allocator) -> Uri { +create_uri :: proc(path: string, allocator: mem.Allocator) -> Uri { builder := strings.make_builder(allocator); diff --git a/src/index/build.odin b/src/index/build.odin index f9529ba..ea75edc 100644 --- a/src/index/build.odin +++ b/src/index/build.odin @@ -7,6 +7,7 @@ import "core:odin/parser" import "core:odin/ast" import "core:log" import "core:odin/tokenizer" +import "core:strings" import "shared:common" @@ -20,26 +21,38 @@ import "shared:common" symbol_collection: SymbolCollection; +files: [dynamic] string; + +walk_static_index_build :: proc(info: os.File_Info, in_err: os.Errno) -> (err: os.Errno, skip_dir: bool) { + + if info.is_dir { + return 0, false; + } + + append(&files, strings.clone(info.fullpath, context.allocator)); + + return 0, false; +}; build_static_index :: proc(allocator := context.allocator, config: ^common.Config) { //right now just collect the symbols from core - core_path := config.collections["core"]; symbol_collection = make_symbol_collection(allocator, config); - walk_static_index_build := proc(info: os.File_Info, in_err: os.Errno) -> (err: os.Errno, skip_dir: bool) { + files = make([dynamic] string, context.allocator); - if info.is_dir { - return 0, false; - } + filepath.walk(core_path, walk_static_index_build); + + context.allocator = context.temp_allocator; - //bit worried about using temp allocator here since we might overwrite all our temp allocator budget - data, ok := os.read_entire_file(info.fullpath, context.temp_allocator); + for fullpath in files { + + data, ok := os.read_entire_file(fullpath, context.temp_allocator); if !ok { - return 1, false; + continue; } p := parser.Parser { @@ -48,26 +61,30 @@ build_static_index :: proc(allocator := context.allocator, config: ^common.Confi }; file := ast.File { - fullpath = info.fullpath, + fullpath = fullpath, src = data, }; ok = parser.parse_file(&p, &file); - uri := common.create_uri(info.fullpath, context.temp_allocator); + uri := common.create_uri(fullpath, context.temp_allocator); collect_symbols(&symbol_collection, file, uri.uri); - common.free_ast_file(file); + free_all(context.temp_allocator); - return 0, false; - }; + delete(fullpath, allocator); + } - filepath.walk(core_path, walk_static_index_build); + delete(files); indexer.static_index = make_memory_index(symbol_collection); } +free_static_index :: proc() { + free_symbol_collection(symbol_collection); +} + no_error_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) { diff --git a/src/index/clone.odin b/src/index/clone.odin index a09f1b7..2927de7 100644 --- a/src/index/clone.odin +++ b/src/index/clone.odin @@ -8,7 +8,7 @@ import "core:strings" import "core:log" new_type :: proc($T: typeid, pos, end: tokenizer.Pos, allocator := context.allocator) -> ^T { - n := mem.new(T); + n := mem.new(T, allocator); n.pos = pos; n.end = end; n.derived = n^; @@ -24,7 +24,7 @@ clone_type :: proc{ clone_dynamic_array, }; -clone_array :: proc(array: $A/[]^$T, allocator := context.allocator) -> A { +clone_array :: proc(array: $A/[]^$T, allocator: mem.Allocator) -> A { if len(array) == 0 { return nil; } @@ -35,7 +35,7 @@ clone_array :: proc(array: $A/[]^$T, allocator := context.allocator) -> A { return res; } -clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator := context.allocator) -> A { +clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator) -> A { if len(array) == 0 { return nil; } @@ -46,11 +46,11 @@ clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator := context.allocat return res; } -clone_expr :: proc(node: ^ast.Expr, allocator := context.allocator) -> ^ast.Expr { +clone_expr :: proc(node: ^ast.Expr, allocator: mem.Allocator) -> ^ast.Expr { return cast(^ast.Expr)clone_node(node, allocator); } -clone_node :: proc(node: ^ast.Node, allocator := context.allocator) -> ^ast.Node { +clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator) -> ^ast.Node { using ast; @@ -176,9 +176,9 @@ clone_node :: proc(node: ^ast.Node, allocator := context.allocator) -> ^ast.Node r.specialization = clone_type(r.specialization, allocator); case Ternary_When_Expr: r := cast(^Ternary_When_Expr)res; - r.x = clone_type(r.x); - r.cond = clone_type(r.cond); - r.y = clone_type(r.y); + r.x = clone_type(r.x, allocator); + r.cond = clone_type(r.cond, allocator); + r.y = clone_type(r.y, allocator); case: log.error("Unhandled node kind: %T", n); } diff --git a/src/index/collector.odin b/src/index/collector.odin index 89c64da..cc289c8 100644 --- a/src/index/collector.odin +++ b/src/index/collector.odin @@ -40,6 +40,20 @@ make_symbol_collection :: proc(allocator := context.allocator, config: ^common.C }; } +free_symbol_collection :: proc(collection: SymbolCollection) { + + for k, v in collection.unique_strings { + delete(v); + } + + for k, v in collection.symbols { + free_symbol(v); + } + + delete(collection.symbols); + delete(collection.unique_strings); +} + collect_struct_fields :: proc(collection: ^SymbolCollection, fields: ^ast.Field_List, package_map: map [string] string) -> SymbolStructValue { names := make([dynamic] string, 0, collection.allocator); diff --git a/src/index/symbol.odin b/src/index/symbol.odin index bc75d81..fae7537 100644 --- a/src/index/symbol.odin +++ b/src/index/symbol.odin @@ -69,4 +69,19 @@ SymbolType :: enum { Package = 9, //set by ast symbol Keyword = 14, //set by ast symbol Struct = 22, -};
\ No newline at end of file +}; + +free_symbol :: proc(symbol: Symbol) { + + #partial switch v in symbol.value { + case SymbolProcedureValue: + common.free_ast(v.return_types); + common.free_ast(v.arg_types); + case SymbolStructValue: + common.free_ast(v.types); + delete(v.names); + case SymbolGenericValue: + common.free_ast(v.expr); + } + +}
\ No newline at end of file diff --git a/src/main.odin b/src/main.odin index 62c75f6..817517d 100644 --- a/src/main.odin +++ b/src/main.odin @@ -9,12 +9,12 @@ import "core:slice" import "core:strconv" import "core:encoding/json" +import "intrinsics" + import "shared:index" import "shared:server" import "shared:common" -running: bool; - os_read :: proc(handle: rawptr, data: [] byte) -> (int, int) { return os.read(cast(os.Handle)handle, data); @@ -31,6 +31,13 @@ run :: proc(reader: ^server.Reader, writer: ^server.Writer) { config: common.Config; + /* + tracking_allocator: mem.Tracking_Allocator; + default_allocator := context.allocator; + mem.tracking_allocator_init(&tracking_allocator, default_allocator); + context.allocator = mem.tracking_allocator(&tracking_allocator); + */ + //temporary collections being set manually, need to get client configuration set up. config.collections = make(map [string] string); @@ -40,6 +47,7 @@ run :: proc(reader: ^server.Reader, writer: ^server.Writer) { index.build_static_index(context.allocator, &config); + log.info("Finished indexing"); config.running = true; @@ -69,9 +77,23 @@ run :: proc(reader: ^server.Reader, writer: ^server.Writer) { } free_all(context.temp_allocator); + } + + delete(config.collections); + delete(config.workspace_folders); + server.document_storage_shutdown(); + + index.free_static_index(); + + /* + for k, v in tracking_allocator.allocation_map { + fmt.println(v); } + + fmt.println(len(tracking_allocator.allocation_map)); + */ } end :: proc() { @@ -84,6 +106,11 @@ main :: proc() { reader := server.make_reader(os_read, cast(rawptr)os.stdin); writer := server.make_writer(os_write, cast(rawptr)os.stdout); + init_global_temporary_allocator(mem.megabytes(10)); + + //fd, err := os.open("C:/Users/danie/OneDrive/Desktop/Computer_Science/ols/log.txt", os.O_RDWR|os.O_CREATE|os.O_TRUNC ); + //context.logger = log.create_file_logger(fd); + context.logger = server.create_lsp_logger(&writer); run(&reader, &writer); diff --git a/src/server/analysis.odin b/src/server/analysis.odin index f4b9ddd..3f52e69 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -752,7 +752,7 @@ make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type for n in field.names { identifier := n.derived.(ast.Ident); append(&names, identifier.name); - append(&types, ast.clone_expr(field.type)); + append(&types, index.clone_type(field.type, context.temp_allocator)); } } @@ -973,8 +973,6 @@ get_definition_location :: proc(document: ^Document, position: common.Position) get_completion_list :: proc(document: ^Document, position: common.Position) -> (CompletionList, bool) { - symbols := make([dynamic] index.Symbol, context.temp_allocator); - list: CompletionList; ast_context := make_ast_context(document.ast, document.imports, document.package_name); @@ -992,6 +990,8 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> ( if position_context.selector != nil { + symbols := make([dynamic] index.Symbol, context.temp_allocator); + selector: index.Symbol; selector, ok = resolve_type_expression(&ast_context, position_context.selector); @@ -1057,19 +1057,72 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> ( } } + for symbol, i in symbols { + item := CompletionItem { + label = symbol.name, + kind = cast(CompletionItemKind) symbol.type, + }; + + append(&items, item); + } + + //if there is no field we had to recover from bad expr and create a node (remove when parser can accept temp_allocator) + if position_context.field == nil { + common.free_ast(position_context.selector); + } + + list.items = items[:]; } else { - return list, true; - } - list.items = make([] CompletionItem, len(symbols), context.temp_allocator); + /* + Just show the local and global symbols of the document + + TODO(Add fuzzy matching) + */ + + for k, v in ast_context.locals { + + item := CompletionItem { + label = k, + }; + + + append(&items, item); + } + + for k, v in ast_context.globals { + + item := CompletionItem { + label = k, + }; - for symbol, i in symbols { - list.items[i].label = symbol.name; - list.items[i].kind = cast(CompletionItemKind) symbol.type; + append(&items, item); + } + + ident := index.new_type(ast.Ident, tokenizer.Pos {}, tokenizer.Pos {}, context.temp_allocator); + + for item, i in items { + + ident.name = item.label; + + if symbol, ok := resolve_type_identifier(&ast_context, ident^, true); ok { + items[i].kind = .Variable; + } + + else if symbol, ok := resolve_type_identifier(&ast_context, ident^, false); ok { + items[i].kind = cast(CompletionItemKind)symbol.type; + } + + + } + + list.items = items[:]; } + + return list, true; } @@ -1176,6 +1229,7 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP case Bad_Expr: if position_context.hint == .Completion && position_context.file.src[max(0, node.end.offset-1)] == '.' { + str := position_context.file.src[node.pos.offset:max(0, node.end.offset-1)]; p := parser.default_parser(); @@ -1186,13 +1240,12 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP //do we still have recursive dots? if strings.contains(string(str), ".") { - e := parser.parse_expr(&p, true); //MEMORY LEAK - need to modify parser to allow for temp allocator + e := parser.parse_expr(&p, true); position_context.selector = e; } else { - //this might not hold be enough in the future - e := parser.parse_ident(&p); //MEMORY LEAK - need to modify parser to allow for temp allocator + e := parser.parse_ident(&p); position_context.selector = e; } diff --git a/src/server/documents.odin b/src/server/documents.odin index 35c0940..3d08766 100644 --- a/src/server/documents.odin +++ b/src/server/documents.odin @@ -8,6 +8,7 @@ import "core:odin/parser" import "core:odin/ast" import "core:odin/tokenizer" import "core:path" +import "core:mem" import "shared:common" @@ -42,6 +43,9 @@ DocumentStorage :: struct { document_storage: DocumentStorage; +document_storage_shutdown :: proc() { + delete(document_storage.documents); +} document_get :: proc(uri_string: string) -> ^Document { @@ -55,18 +59,12 @@ document_get :: proc(uri_string: string) -> ^Document { } /* - Note(Daniel, Should there be reference counting of documents or just clear everything on workspace change? - You usually always need the documents that are loaded in core files, your own files, etc.) - */ - - -/* Client opens a document with transferred text */ document_open :: proc(uri_string: string, text: string, config: ^common.Config, writer: ^Writer) -> common.Error { - uri, parsed_ok := common.parse_uri(uri_string); + uri, parsed_ok := common.parse_uri(uri_string, context.allocator); log.infof("document_open: %v", uri_string); @@ -87,7 +85,7 @@ document_open :: proc(uri_string: string, text: string, config: ^common.Config, document.text = transmute([] u8)text; document.used_text = len(document.text); - if err := document_refresh(document, config, writer, true); err != .None { + if err := document_refresh(document, config, writer); err != .None { return err; } @@ -102,7 +100,7 @@ document_open :: proc(uri_string: string, text: string, config: ^common.Config, used_text = len(text), }; - if err := document_refresh(&document, config, writer, true); err != .None { + if err := document_refresh(&document, config, writer); err != .None { return err; } @@ -203,11 +201,13 @@ document_apply_changes :: proc(uri_string: string, changes: [dynamic] TextDocume //log.info(string(document.text[:document.used_text])); - return document_refresh(document, config, writer, true); + return document_refresh(document, config, writer); } document_close :: proc(uri_string: string) -> common.Error { + log.infof("document_close: %v", uri_string); + uri, parsed_ok := common.parse_uri(uri_string, context.temp_allocator); if !parsed_ok { @@ -223,21 +223,18 @@ document_close :: proc(uri_string: string) -> common.Error { document.client_owned = false; - common.free_ast_file(document.ast); - common.delete_uri(document.uri); delete(document.text); document.used_text = 0; - return .None; } -document_refresh :: proc(document: ^Document, config: ^common.Config, writer: ^Writer, parse_imports: bool) -> common.Error { +document_refresh :: proc(document: ^Document, config: ^common.Config, writer: ^Writer) -> common.Error { errors, ok := parse_document(document, config); @@ -323,6 +320,8 @@ parser_warning_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) { parse_document :: proc(document: ^Document, config: ^common.Config) -> ([] ParserError, bool) { + context.allocator = context.temp_allocator; + p := parser.Parser { err = parser_error_handler, warn = parser_warning_handler, @@ -335,21 +334,10 @@ parse_document :: proc(document: ^Document, config: ^common.Config) -> ([] Parse src = document.text[:document.used_text], }; - common.free_ast_file(document.ast); - parser.parse_file(&p, &document.ast); - if document.imports != nil { - - for p in document.imports { - delete(p.name); - } - - delete(document.imports); - } - document.imports = make([]Package, len(document.ast.imports)); - document.package_name = path.dir(document.uri.path, context.allocator); //todo(memory leak) + document.package_name = path.dir(document.uri.path, context.temp_allocator); for imp, index in document.ast.imports { @@ -367,9 +355,8 @@ parse_document :: proc(document: ^Document, config: ^common.Config) -> ([] Parse continue; } - document.imports[index].name = path.join(dir, p); + document.imports[index].name = strings.clone(path.join(elems = {dir, p}, allocator = context.temp_allocator)); document.imports[index].base = path.base(document.imports[index].name, false); - } //relative @@ -379,7 +366,5 @@ parse_document :: proc(document: ^Document, config: ^common.Config) -> ([] Parse } - //fmt.println(document.imports); - return current_errors[:], true; } diff --git a/src/server/requests.odin b/src/server/requests.odin index e5cf22b..45f252f 100644 --- a/src/server/requests.odin +++ b/src/server/requests.odin @@ -65,14 +65,14 @@ read_and_parse_header :: proc(reader: ^Reader) -> (Header, bool) { break; } - index := strings.last_index_byte (message, ':'); + index := strings.last_index_byte(message, ':'); if index == -1 { log.error("Failed to find semicolon"); return header, false; } - header_name := message[0 : index]; + header_name := message[0:index]; header_value := message[len(header_name) + 2 : len(message)-1]; if strings.compare(header_name, "Content-Length") == 0 { @@ -131,6 +131,19 @@ read_and_parse_body :: proc(reader: ^Reader, header: Header) -> (json.Value, boo } +call_map : map [string] proc(json.Value, RequestId, ^common.Config, ^Writer) -> common.Error = + {"initialize" = request_initialize, + "initialized" = request_initialized, + "shutdown" = request_shutdown, + "exit" = notification_exit, + "textDocument/didOpen" = notification_did_open, + "textDocument/didChange" = notification_did_change, + "textDocument/didClose" = notification_did_close, + "textDocument/didSave" = notification_did_save, + "textDocument/definition" = request_definition, + "textDocument/completion" = request_completion, + "textDocument/signatureHelp" = request_signature_help}; + handle_request :: proc(request: json.Value, config: ^common.Config, writer: ^Writer) -> bool { root, ok := request.value.(json.Object); @@ -158,19 +171,6 @@ handle_request :: proc(request: json.Value, config: ^common.Config, writer: ^Wri method := root["method"].value.(json.String); - call_map : map [string] proc(json.Value, RequestId, ^common.Config, ^Writer) -> common.Error = - {"initialize" = request_initialize, - "initialized" = request_initialized, - "shutdown" = request_shutdown, - "exit" = notification_exit, - "textDocument/didOpen" = notification_did_open, - "textDocument/didChange" = notification_did_change, - "textDocument/didClose" = notification_did_close, - "textDocument/didSave" = notification_did_save, - "textDocument/definition" = request_definition, - "textDocument/completion" = request_completion, - "textDocument/signatureHelp" = request_signature_help}; - fn: proc(json.Value, RequestId, ^common.Config, ^Writer) -> common.Error; fn, ok = call_map[method]; @@ -198,6 +198,7 @@ handle_request :: proc(request: json.Value, config: ^common.Config, writer: ^Wri } } + return true; } @@ -295,6 +296,8 @@ request_definition :: proc(params: json.Value, id: RequestId, config: ^common.Co return .InternalError; } + document_refresh(document, config, writer); + location, ok2 := get_definition_location(document, definition_params.position); if !ok2 { @@ -324,18 +327,20 @@ request_completion :: proc(params: json.Value, id: RequestId, config: ^common.Co completition_params: CompletionParams; + if unmarshal(params, completition_params, context.temp_allocator) != .None { log.error("Failed to unmarshal completion request"); return .ParseError; } - document := document_get(completition_params.textDocument.uri); if document == nil { return .InternalError; } + document_refresh(document, config, writer); + list: CompletionList; list, ok = get_completion_list(document, completition_params.position); @@ -373,6 +378,8 @@ request_signature_help :: proc(params: json.Value, id: RequestId, config: ^commo return .InternalError; } + document_refresh(document, config, writer); + help: SignatureHelp; help, ok = get_signature_information(document, signature_params.position); @@ -424,6 +431,7 @@ notification_did_change :: proc(params: json.Value, id: RequestId, config: ^comm return .ParseError; } + document_apply_changes(change_params.textDocument.uri, change_params.contentChanges, config, writer); return .None; diff --git a/src/server/unmarshal.odin b/src/server/unmarshal.odin index 828e62c..908f83c 100644 --- a/src/server/unmarshal.odin +++ b/src/server/unmarshal.odin @@ -12,7 +12,7 @@ import "core:fmt" Right now union handling is type specific so you can only have one struct type, int type, etc. */ -unmarshal :: proc(json_value: json.Value, v: any, allocator := context.allocator) -> json.Marshal_Error { +unmarshal :: proc(json_value: json.Value, v: any, allocator: mem.Allocator) -> json.Marshal_Error { using runtime; @@ -52,7 +52,7 @@ unmarshal :: proc(json_value: json.Value, v: any, allocator := context.allocator id := variant.variants[0].id; - unmarshal(json_value, any{v.data, id}); + unmarshal(json_value, any{v.data, id}, allocator); } case json.Array: |