aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2020-11-18 22:14:33 +0100
committerDanielGavin <danielgavin5@hotmail.com>2020-11-18 22:14:33 +0100
commit3370a5e546ea9355068ba99b5e81f80527d2e582 (patch)
tree5a93eda4e2a5be4ec58d3ddf2595fa7dc1016cb3 /src
parentee4a7f64bcb9d6d7b60d5495fc072b2a62b5f790 (diff)
fixed all the memory leaks
Diffstat (limited to 'src')
-rw-r--r--src/common/ast.odin44
-rw-r--r--src/common/uri.odin6
-rw-r--r--src/index/build.odin45
-rw-r--r--src/index/clone.odin16
-rw-r--r--src/index/collector.odin14
-rw-r--r--src/index/symbol.odin17
-rw-r--r--src/main.odin31
-rw-r--r--src/server/analysis.odin77
-rw-r--r--src/server/documents.odin45
-rw-r--r--src/server/requests.odin40
-rw-r--r--src/server/unmarshal.odin4
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: