aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2020-11-29 19:25:15 +0100
committerDanielGavin <danielgavin5@hotmail.com>2020-11-29 19:25:15 +0100
commit0a49dec8e063d44b86c8c28bf77dbde17cdb35c8 (patch)
treedb86b6e300135df3474eda8625f5f957c7a86a2f
parent1b1860976d0a4ab6e23601c714df3f86f39e5691 (diff)
added sha1, fixed leaks, fixed crash on bad expr
-rw-r--r--src/common/ast.odin273
-rw-r--r--src/common/sha1.odin309
-rw-r--r--src/common/track_allocator.odin7
-rw-r--r--src/index/clone.odin133
-rw-r--r--src/index/collector.odin48
-rw-r--r--src/index/memory_index.odin4
-rw-r--r--src/index/symbol.odin24
-rw-r--r--src/main.odin10
-rw-r--r--src/server/analysis.odin12
-rw-r--r--src/server/requests.odin5
-rw-r--r--src/server/semantic_tokens.odin28
11 files changed, 622 insertions, 231 deletions
diff --git a/src/common/ast.odin b/src/common/ast.odin
index 93be57b..ca26726 100644
--- a/src/common/ast.odin
+++ b/src/common/ast.odin
@@ -14,7 +14,8 @@ keyword_map : map [string] bool =
"i32" = true,
"bool" = true,
"rawptr" = true,
- "any" = true};
+ "any" = true,
+ "u32" = true};
get_ast_node_string :: proc(node: ^ast.Node, src: [] byte) -> string {
return string(src[node.pos.offset:node.end.offset]);
@@ -27,34 +28,34 @@ free_ast :: proc{
free_ast_comment,
};
-free_ast_comment :: proc(a: ^ast.Comment_Group) {
+free_ast_comment :: proc(a: ^ast.Comment_Group, allocator: mem.Allocator) {
if a == nil {
return;
}
if len(a.list) > 0 {
- delete(a.list);
+ delete(a.list, allocator);
}
- free(a);
+ free(a, allocator);
}
-free_ast_array :: proc(array: $A/[]^$T) {
+free_ast_array :: proc(array: $A/[]^$T, allocator: mem.Allocator) {
for elem, i in array {
- free_ast(elem);
+ free_ast(elem, allocator);
}
- delete(array);
+ delete(array, allocator);
}
-free_ast_dynamic_array :: proc(array: $A/[dynamic]^$T) {
+free_ast_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator) {
for elem, i in array {
- free_ast(elem);
+ free_ast(elem, allocator);
}
delete(array);
}
-free_ast_node :: proc(node: ^ast.Node) {
+free_ast_node :: proc(node: ^ast.Node, allocator: mem.Allocator) {
using ast;
@@ -70,125 +71,125 @@ free_ast_node :: proc(node: ^ast.Node) {
case Basic_Directive:
case Basic_Lit:
case Ellipsis:
- free_ast(n.expr);
+ free_ast(n.expr, allocator);
case Proc_Lit:
- free_ast(n.type);
- free_ast(n.body);
- free_ast(n.where_clauses);
+ free_ast(n.type, allocator);
+ free_ast(n.body, allocator);
+ free_ast(n.where_clauses, allocator);
case Comp_Lit:
- free_ast(n.type);
- free_ast(n.elems);
+ free_ast(n.type, allocator);
+ free_ast(n.elems, allocator);
case Tag_Expr:
- free_ast(n.expr);
+ free_ast(n.expr, allocator);
case Unary_Expr:
- free_ast(n.expr);
+ free_ast(n.expr, allocator);
case Binary_Expr:
- free_ast(n.left);
- free_ast(n.right);
+ free_ast(n.left, allocator);
+ free_ast(n.right, allocator);
case Paren_Expr:
- free_ast(n.expr);
+ free_ast(n.expr, allocator);
case Call_Expr:
- free_ast(n.expr);
- free_ast(n.args);
+ free_ast(n.expr, allocator);
+ free_ast(n.args, allocator);
case Selector_Expr:
- free_ast(n.expr);
- free_ast(n.field);
+ free_ast(n.expr, allocator);
+ free_ast(n.field, allocator);
case Implicit_Selector_Expr:
- free_ast(n.field);
+ free_ast(n.field, allocator);
case Index_Expr:
- free_ast(n.expr);
- free_ast(n.index);
+ free_ast(n.expr, allocator);
+ free_ast(n.index, allocator);
case Deref_Expr:
- free_ast(n.expr);
+ free_ast(n.expr, allocator);
case Slice_Expr:
- free_ast(n.expr);
- free_ast(n.low);
- free_ast(n.high);
+ free_ast(n.expr, allocator);
+ free_ast(n.low, allocator);
+ free_ast(n.high, allocator);
case Field_Value:
- free_ast(n.field);
- free_ast(n.value);
+ free_ast(n.field, allocator);
+ free_ast(n.value, allocator);
case Ternary_Expr:
- free_ast(n.cond);
- free_ast(n.x);
- free_ast(n.y);
+ free_ast(n.cond, allocator);
+ free_ast(n.x, allocator);
+ free_ast(n.y, allocator);
case Ternary_If_Expr:
- free_ast(n.x);
- free_ast(n.cond);
- free_ast(n.y);
+ free_ast(n.x, allocator);
+ free_ast(n.cond, allocator);
+ free_ast(n.y, allocator);
case Ternary_When_Expr:
- free_ast(n.x);
- free_ast(n.cond);
- free_ast(n.y);
+ free_ast(n.x, allocator);
+ free_ast(n.cond, allocator);
+ free_ast(n.y, allocator);
case Type_Assertion:
- free_ast(n.expr);
- free_ast(n.type);
+ free_ast(n.expr, allocator);
+ free_ast(n.type, allocator);
case Type_Cast:
- free_ast(n.type);
- free_ast(n.expr);
+ free_ast(n.type, allocator);
+ free_ast(n.expr, allocator);
case Auto_Cast:
- free_ast(n.expr);
+ free_ast(n.expr, allocator);
case Bad_Stmt:
case Empty_Stmt:
case Expr_Stmt:
- free_ast(n.expr);
+ free_ast(n.expr, allocator);
case Tag_Stmt:
r := cast(^Expr_Stmt)node;
- free_ast(r.expr);
+ free_ast(r.expr, allocator);
case Assign_Stmt:
- free_ast(n.lhs);
- free_ast(n.rhs);
+ free_ast(n.lhs, allocator);
+ free_ast(n.rhs, allocator);
case Block_Stmt:
- free_ast(n.label);
- free_ast(n.stmts);
+ free_ast(n.label, allocator);
+ free_ast(n.stmts, allocator);
case If_Stmt:
- free_ast(n.label);
- free_ast(n.init);
- free_ast(n.cond);
- free_ast(n.body);
- free_ast(n.else_stmt);
+ free_ast(n.label, allocator);
+ free_ast(n.init, allocator);
+ free_ast(n.cond, allocator);
+ free_ast(n.body, allocator);
+ free_ast(n.else_stmt, allocator);
case When_Stmt:
- free_ast(n.cond);
- free_ast(n.body);
- free_ast(n.else_stmt);
+ free_ast(n.cond, allocator);
+ free_ast(n.body, allocator);
+ free_ast(n.else_stmt, allocator);
case Return_Stmt:
- free_ast(n.results);
+ free_ast(n.results, allocator);
case Defer_Stmt:
- free_ast(n.stmt);
+ free_ast(n.stmt, allocator);
case For_Stmt:
- free_ast(n.label);
- free_ast(n.init);
- free_ast(n.cond);
- free_ast(n.post);
- free_ast(n.body);
+ free_ast(n.label, allocator);
+ free_ast(n.init, allocator);
+ free_ast(n.cond, allocator);
+ free_ast(n.post, allocator);
+ free_ast(n.body, allocator);
case Range_Stmt:
- free_ast(n.label);
- free_ast(n.val0);
- free_ast(n.val1);
- free_ast(n.expr);
- free_ast(n.body);
+ free_ast(n.label, allocator);
+ free_ast(n.val0, allocator);
+ free_ast(n.val1, allocator);
+ free_ast(n.expr, allocator);
+ free_ast(n.body, allocator);
case Case_Clause:
- free_ast(n.list);
- free_ast(n.body);
+ free_ast(n.list, allocator);
+ free_ast(n.body, allocator);
case Switch_Stmt:
- free_ast(n.label);
- free_ast(n.init);
- free_ast(n.cond);
- free_ast(n.body);
+ free_ast(n.label, allocator);
+ free_ast(n.init, allocator);
+ free_ast(n.cond, allocator);
+ free_ast(n.body, allocator);
case Type_Switch_Stmt:
- free_ast(n.label);
- free_ast(n.tag);
- free_ast(n.expr);
- free_ast(n.body);
+ free_ast(n.label, allocator);
+ free_ast(n.tag, allocator);
+ free_ast(n.expr, allocator);
+ free_ast(n.body, allocator);
case Branch_Stmt:
- free_ast(n.label);
+ free_ast(n.label, allocator);
case Using_Stmt:
- free_ast(n.list);
+ free_ast(n.list, allocator);
case Bad_Decl:
case Value_Decl:
- free_ast(n.attributes);
- free_ast(n.names);
- free_ast(n.type);
- free_ast(n.values);
+ free_ast(n.attributes, allocator);
+ free_ast(n.names, allocator);
+ free_ast(n.type, allocator);
+ free_ast(n.values, allocator);
//free_ast(n.docs);
//free_ast(n.comment);
case Package_Decl:
@@ -198,88 +199,88 @@ free_ast_node :: proc(node: ^ast.Node) {
//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);
+ free_ast(n.attributes, allocator);
+ free_ast(n.foreign_library, allocator);
+ free_ast(n.body, allocator);
case Foreign_Import_Decl:
- free_ast(n.name);
- free_ast(n.attributes);
+ free_ast(n.name, allocator);
+ free_ast(n.attributes, allocator);
case Proc_Group:
- free_ast(n.args);
+ free_ast(n.args, allocator);
case Attribute:
- free_ast(n.elems);
+ free_ast(n.elems, allocator);
case Field:
- free_ast(n.names);
- free_ast(n.type);
- free_ast(n.default_value);
+ free_ast(n.names, allocator);
+ free_ast(n.type, allocator);
+ free_ast(n.default_value, allocator);
//free_ast(n.docs);
//free_ast(n.comment);
case Field_List:
- free_ast(n.list);
+ free_ast(n.list, allocator);
case Typeid_Type:
- free_ast(n.specialization);
+ free_ast(n.specialization, allocator);
case Helper_Type:
- free_ast(n.type);
+ free_ast(n.type, allocator);
case Distinct_Type:
- free_ast(n.type);
+ free_ast(n.type, allocator);
case Opaque_Type:
- free_ast(n.type);
+ free_ast(n.type, allocator);
case Poly_Type:
- free_ast(n.type);
- free_ast(n.specialization);
+ free_ast(n.type, allocator);
+ free_ast(n.specialization, allocator);
case Proc_Type:
- free_ast(n.params);
- free_ast(n.results);
+ free_ast(n.params, allocator);
+ free_ast(n.results, allocator);
case Pointer_Type:
- free_ast(n.elem);
+ free_ast(n.elem, allocator);
case Array_Type:
- free_ast(n.len);
- free_ast(n.elem);
- free_ast(n.tag);
+ free_ast(n.len, allocator);
+ free_ast(n.elem, allocator);
+ free_ast(n.tag, allocator);
case Dynamic_Array_Type:
- free_ast(n.elem);
- free_ast(n.tag);
+ free_ast(n.elem, allocator);
+ free_ast(n.tag, allocator);
case Struct_Type:
- free_ast(n.poly_params);
- free_ast(n.align);
- free_ast(n.fields);
- free_ast(n.where_clauses);
+ free_ast(n.poly_params, allocator);
+ free_ast(n.align, allocator);
+ free_ast(n.fields, allocator);
+ free_ast(n.where_clauses, allocator);
case Union_Type:
- free_ast(n.poly_params);
- free_ast(n.align);
- free_ast(n.variants);
- free_ast(n.where_clauses);
+ free_ast(n.poly_params, allocator);
+ free_ast(n.align, allocator);
+ free_ast(n.variants, allocator);
+ free_ast(n.where_clauses, allocator);
case Enum_Type:
- free_ast(n.base_type);
- free_ast(n.fields);
+ free_ast(n.base_type, allocator);
+ free_ast(n.fields, allocator);
case Bit_Field_Type:
- free_ast(n.fields);
- free_ast(n.align);
+ free_ast(n.fields, allocator);
+ free_ast(n.align, allocator);
case Bit_Set_Type:
- free_ast(n.elem);
- free_ast(n.underlying);
+ free_ast(n.elem, allocator);
+ free_ast(n.underlying, allocator);
case Map_Type:
- free_ast(n.key);
- free_ast(n.value);
+ free_ast(n.key, allocator);
+ free_ast(n.value, allocator);
case:
log.errorf("free Unhandled node kind: %T", n);
}
- mem.free(node);
+ mem.free(node, allocator);
}
-free_ast_file :: proc(file: ast.File) {
+free_ast_file :: proc(file: ast.File, allocator := context.allocator) {
for decl in file.decls {
- free_ast(decl);
+ free_ast(decl, allocator);
}
- free_ast(file.pkg_decl);
+ free_ast(file.pkg_decl, allocator);
for comment in file.comments {
- free_ast(comment);
+ free_ast(comment, allocator);
}
delete(file.comments);
diff --git a/src/common/sha1.odin b/src/common/sha1.odin
new file mode 100644
index 0000000..d3d2119
--- /dev/null
+++ b/src/common/sha1.odin
@@ -0,0 +1,309 @@
+package common
+
+import "core:fmt"
+
+//ported version of https://llvm.org/doxygen/SHa1_8cpp_source.html
+
+rol :: proc(number: u32, bits: u32) -> u32 {
+ return number << bits | number >> (32 - bits);
+}
+
+blk0 :: proc(buf: [] u32, i: int) -> u32 {
+ return buf[i];
+}
+
+blk :: proc(buf: [] u32, i: int) -> u32 {
+ buf[i & 15] = rol(buf[(i + 13) & 15] ~ buf[(i + 8) & 15] ~ buf[(i + 2) & 15]
+ ~ buf[i & 15], 1);
+
+ return buf[i & 15];
+}
+
+r0 :: proc(a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: [] u32) {
+ e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk0(buf, i) + 0x5a827999 + rol(a^, 5);
+ b^ = rol(b^, 30);
+}
+
+r1 :: proc(a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: [] u32) {
+ e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk(buf, i) + 0x5a827999 + rol(a^, 5);
+ b^ += rol(b^, 30);
+}
+
+r2 :: proc(a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: [] u32) {
+ e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0x6ed9eba1 + rol(a^, 5);
+ b^ += rol(b^, 30);
+}
+
+r3 :: proc(a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: [] u32) {
+ e^ += (((b^ | c^) & d^) | (b^ & c^)) + blk(buf, i) + 0x8F1bbcdc + rol(a^, 5);
+ b^ += rol(b^, 30);
+}
+
+r4 :: proc(a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: [] u32) {
+ e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0xca62c1d6 + rol(a^, 5);
+ b^ += rol(b^, 30);
+}
+
+SHA1_K0 :: 0x5a827999;
+SHA1_K20 :: 0x6ed9eba1;
+SHA1_K40 :: 0x8f1bbcdc;
+SHA1_K60 :: 0xca62c1d6;
+
+SEED_0 :: 0x67452301;
+SEED_1 :: 0xefcdab89;
+SEED_2 :: 0x98badcfe;
+SEED_3 :: 0x10325476;
+SEED_4 :: 0xc3d2e1f0;
+
+BLOCK_LENGTH :: 64;
+HASH_LENGTH :: 20;
+
+Sha1context :: struct {
+ buf: struct #raw_union {
+ c: [BLOCK_LENGTH] byte,
+ l: [BLOCK_LENGTH/4] u32,
+ },
+ state: [HASH_LENGTH / 4] u32,
+ byte_count: u32,
+ buf_offset: u8,
+};
+
+sha1_init :: proc(state_context: ^Sha1context) {
+ state_context.state[0] = SEED_0;
+ state_context.state[1] = SEED_1;
+ state_context.state[2] = SEED_2;
+ state_context.state[3] = SEED_3;
+ state_context.state[4] = SEED_4;
+ state_context.byte_count = 0;
+ state_context.buf_offset = 0;
+}
+
+sha1_hash_block :: proc(state_context: ^Sha1context) {
+ a := state_context.state[0];
+ b := state_context.state[1];
+ c := state_context.state[2];
+ d := state_context.state[3];
+ e := state_context.state[4];
+
+ // 4 rounds of 20 operations each. loop unrolled.
+ r0(&a, &b, &c, &d, &e, 0, state_context.buf.l[:]);
+ r0(&e, &a, &b, &c, &d, 1, state_context.buf.l[:]);
+ r0(&d, &e, &a, &b, &c, 2, state_context.buf.l[:]);
+ r0(&c, &d, &e, &a, &b, 3, state_context.buf.l[:]);
+ r0(&b, &c, &d, &e, &a, 4, state_context.buf.l[:]);
+ r0(&a, &b, &c, &d, &e, 5, state_context.buf.l[:]);
+ r0(&e, &a, &b, &c, &d, 6, state_context.buf.l[:]);
+ r0(&d, &e, &a, &b, &c, 7, state_context.buf.l[:]);
+ r0(&c, &d, &e, &a, &b, 8, state_context.buf.l[:]);
+ r0(&b, &c, &d, &e, &a, 9, state_context.buf.l[:]);
+ r0(&a, &b, &c, &d, &e, 10, state_context.buf.l[:]);
+ r0(&e, &a, &b, &c, &d, 11, state_context.buf.l[:]);
+ r0(&d, &e, &a, &b, &c, 12, state_context.buf.l[:]);
+ r0(&c, &d, &e, &a, &b, 13, state_context.buf.l[:]);
+ r0(&b, &c, &d, &e, &a, 14, state_context.buf.l[:]);
+ r0(&a, &b, &c, &d, &e, 15, state_context.buf.l[:]);
+ r1(&e, &a, &b, &c, &d, 16, state_context.buf.l[:]);
+ r1(&d, &e, &a, &b, &c, 17, state_context.buf.l[:]);
+ r1(&c, &d, &e, &a, &b, 18, state_context.buf.l[:]);
+ r1(&b, &c, &d, &e, &a, 19, state_context.buf.l[:]);
+
+ r2(&a, &b, &c, &d, &e, 20, state_context.buf.l[:]);
+ r2(&e, &a, &b, &c, &d, 21, state_context.buf.l[:]);
+ r2(&d, &e, &a, &b, &c, 22, state_context.buf.l[:]);
+ r2(&c, &d, &e, &a, &b, 23, state_context.buf.l[:]);
+ r2(&b, &c, &d, &e, &a, 24, state_context.buf.l[:]);
+ r2(&a, &b, &c, &d, &e, 25, state_context.buf.l[:]);
+ r2(&e, &a, &b, &c, &d, 26, state_context.buf.l[:]);
+ r2(&d, &e, &a, &b, &c, 27, state_context.buf.l[:]);
+ r2(&c, &d, &e, &a, &b, 28, state_context.buf.l[:]);
+ r2(&b, &c, &d, &e, &a, 29, state_context.buf.l[:]);
+ r2(&a, &b, &c, &d, &e, 30, state_context.buf.l[:]);
+ r2(&e, &a, &b, &c, &d, 31, state_context.buf.l[:]);
+ r2(&d, &e, &a, &b, &c, 32, state_context.buf.l[:]);
+ r2(&c, &d, &e, &a, &b, 33, state_context.buf.l[:]);
+ r2(&b, &c, &d, &e, &a, 34, state_context.buf.l[:]);
+ r2(&a, &b, &c, &d, &e, 35, state_context.buf.l[:]);
+ r2(&e, &a, &b, &c, &d, 36, state_context.buf.l[:]);
+ r2(&d, &e, &a, &b, &c, 37, state_context.buf.l[:]);
+ r2(&c, &d, &e, &a, &b, 38, state_context.buf.l[:]);
+ r2(&b, &c, &d, &e, &a, 39, state_context.buf.l[:]);
+
+ r3(&a, &b, &c, &d, &e, 40, state_context.buf.l[:]);
+ r3(&e, &a, &b, &c, &d, 41, state_context.buf.l[:]);
+ r3(&d, &e, &a, &b, &c, 42, state_context.buf.l[:]);
+ r3(&c, &d, &e, &a, &b, 43, state_context.buf.l[:]);
+ r3(&b, &c, &d, &e, &a, 44, state_context.buf.l[:]);
+ r3(&a, &b, &c, &d, &e, 45, state_context.buf.l[:]);
+ r3(&e, &a, &b, &c, &d, 46, state_context.buf.l[:]);
+ r3(&d, &e, &a, &b, &c, 47, state_context.buf.l[:]);
+ r3(&c, &d, &e, &a, &b, 48, state_context.buf.l[:]);
+ r3(&b, &c, &d, &e, &a, 49, state_context.buf.l[:]);
+ r3(&a, &b, &c, &d, &e, 50, state_context.buf.l[:]);
+ r3(&e, &a, &b, &c, &d, 51, state_context.buf.l[:]);
+ r3(&d, &e, &a, &b, &c, 52, state_context.buf.l[:]);
+ r3(&c, &d, &e, &a, &b, 53, state_context.buf.l[:]);
+ r3(&b, &c, &d, &e, &a, 54, state_context.buf.l[:]);
+ r3(&a, &b, &c, &d, &e, 55, state_context.buf.l[:]);
+ r3(&e, &a, &b, &c, &d, 56, state_context.buf.l[:]);
+ r3(&d, &e, &a, &b, &c, 57, state_context.buf.l[:]);
+ r3(&c, &d, &e, &a, &b, 58, state_context.buf.l[:]);
+ r3(&b, &c, &d, &e, &a, 59, state_context.buf.l[:]);
+
+ r4(&a, &b, &c, &d, &e, 60, state_context.buf.l[:]);
+ r4(&e, &a, &b, &c, &d, 61, state_context.buf.l[:]);
+ r4(&d, &e, &a, &b, &c, 62, state_context.buf.l[:]);
+ r4(&c, &d, &e, &a, &b, 63, state_context.buf.l[:]);
+ r4(&b, &c, &d, &e, &a, 64, state_context.buf.l[:]);
+ r4(&a, &b, &c, &d, &e, 65, state_context.buf.l[:]);
+ r4(&e, &a, &b, &c, &d, 66, state_context.buf.l[:]);
+ r4(&d, &e, &a, &b, &c, 67, state_context.buf.l[:]);
+ r4(&c, &d, &e, &a, &b, 68, state_context.buf.l[:]);
+ r4(&b, &c, &d, &e, &a, 69, state_context.buf.l[:]);
+ r4(&a, &b, &c, &d, &e, 70, state_context.buf.l[:]);
+ r4(&e, &a, &b, &c, &d, 71, state_context.buf.l[:]);
+ r4(&d, &e, &a, &b, &c, 72, state_context.buf.l[:]);
+ r4(&c, &d, &e, &a, &b, 73, state_context.buf.l[:]);
+ r4(&b, &c, &d, &e, &a, 74, state_context.buf.l[:]);
+ r4(&a, &b, &c, &d, &e, 75, state_context.buf.l[:]);
+ r4(&e, &a, &b, &c, &d, 76, state_context.buf.l[:]);
+ r4(&d, &e, &a, &b, &c, 77, state_context.buf.l[:]);
+ r4(&c, &d, &e, &a, &b, 78, state_context.buf.l[:]);
+ r4(&b, &c, &d, &e, &a, 79, state_context.buf.l[:]);
+
+ state_context.state[0] += a;
+ state_context.state[1] += b;
+ state_context.state[2] += c;
+ state_context.state[3] += d;
+ state_context.state[4] += e;
+ }
+
+
+sha1_add_uncounted :: proc(state_context: ^Sha1context, data: byte) {
+
+
+ when ODIN_ENDIAN == "big" {
+ state_context.buf.c[state_context.buf_offset] = data;
+ }
+
+ else {
+ state_context.buf.c[state_context.buf_offset ~ 3] = data;
+ }
+
+ state_context.buf_offset += 1;
+
+ if state_context.buf_offset == BLOCK_LENGTH {
+ sha1_hash_block(state_context);
+ state_context.buf_offset = 0;
+ }
+
+}
+
+sha1_write_byte :: proc(state_context: ^Sha1context, data: byte) {
+ state_context.byte_count += 1;
+ sha1_add_uncounted(state_context, data);
+}
+
+sha1_update :: proc(state_context: ^Sha1context, data: [] byte) {
+
+ state_context.byte_count += cast(u32)len(data);
+
+ current_data := data;
+
+ if state_context.buf_offset > 0 {
+ remainder := min(len(current_data), BLOCK_LENGTH - cast(int)state_context.buf_offset);
+
+ for i := 0; i < remainder; i += 1 {
+ sha1_add_uncounted(state_context, current_data[i]);
+ }
+
+ current_data = current_data[remainder-1:];
+ }
+
+ for len(current_data) >= BLOCK_LENGTH {
+ assert(state_context.buf_offset == 0);
+ assert(BLOCK_LENGTH % 4 == 0);
+
+ BLOCK_LENGTH_32 :: BLOCK_LENGTH / 4;
+
+ for i := 0; i < BLOCK_LENGTH_32; i += 1 {
+ n := (transmute([] u32)current_data)[i];
+
+ state_context.buf.l[i] = (((n & 0xFF) << 24) |
+ ((n & 0xFF00) << 8) |
+ ((n & 0xFF0000) >> 8) |
+ ((n & 0xFF000000) >> 24));
+ }
+
+ sha1_hash_block(state_context);
+
+ current_data = current_data[BLOCK_LENGTH-1:];
+ }
+
+ for c in current_data {
+ sha1_add_uncounted(state_context, c);
+ }
+
+}
+
+sha1_pad :: proc(state_context: ^Sha1context) {
+
+ sha1_add_uncounted(state_context, 0x80);
+
+ for state_context.buf_offset != 56 {
+ sha1_add_uncounted(state_context, 0x00);
+ }
+
+ sha1_add_uncounted(state_context, 0); // We're only using 32 bit lengths
+ sha1_add_uncounted(state_context, 0); // But SHA-1 supports 64 bit lengths
+ sha1_add_uncounted(state_context, 0); // So zero pad the top bits
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 29)); // Shifting to multiply by 8
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 21)); // as SHA-1 supports bitstreams as well as
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 13)); // byte.
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 5));
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count << 3));
+
+
+
+}
+sha1_final :: proc(state_context: ^Sha1context, result: ^[5] u32) {
+
+ sha1_pad(state_context);
+
+ when ODIN_ENDIAN == "big" {
+
+ for i := 0; i < 5; i += 1 {
+ result[i] = state_context.state[i];
+ }
+
+ }
+
+ else {
+ for i := 0; i < 5; i += 1 {
+ result[i] = (((state_context.state[i]) << 24) & 0xff000000) |
+ (((state_context.state[i]) << 8) & 0x00ff0000) |
+ (((state_context.state[i]) >> 8) & 0x0000ff00) |
+ (((state_context.state[i]) >> 24) & 0x000000ff);
+ }
+ }
+
+}
+
+
+
+sha1_hash :: proc(data: [] byte) -> [20] byte {
+
+ sha1_context: Sha1context;
+ sha1_init(&sha1_context);
+ sha1_update(&sha1_context, data);
+
+ result: [20] byte;
+
+ sha1_final(&sha1_context, cast(^[5] u32)&result);
+
+ ret: [20] byte;
+
+ copy(ret[:], result[:]);
+
+ return ret;
+}
+
diff --git a/src/common/track_allocator.odin b/src/common/track_allocator.odin
index a2ad37a..c5d4452 100644
--- a/src/common/track_allocator.odin
+++ b/src/common/track_allocator.odin
@@ -8,6 +8,7 @@ import "core:mem"
import "core:fmt"
import "core:runtime"
import "core:sync"
+import "core:log"
// ----------------------------------------------------------------------------------------------------
@@ -188,4 +189,8 @@ memleak_dump :: proc( memleak_alloc : mem.Allocator, dump_proc : proc(message:st
context.allocator = mem.Allocator {procedure = memleak_allocator_proc, data = memleak};
}
-// ---------------------------------------------------------------------------------------------------- \ No newline at end of file
+// ----------------------------------------------------------------------------------------------------
+
+log_dump :: proc(message:string, user_data:rawptr) {
+ log.info(message);
+} \ No newline at end of file
diff --git a/src/index/clone.odin b/src/index/clone.odin
index 92e79d9..19a4526 100644
--- a/src/index/clone.odin
+++ b/src/index/clone.odin
@@ -24,33 +24,33 @@ clone_type :: proc{
clone_dynamic_array,
};
-clone_array :: proc(array: $A/[]^$T, allocator: mem.Allocator) -> A {
+clone_array :: proc(array: $A/[]^$T, allocator: mem.Allocator, unique_strings: ^map[string] string) -> A {
if len(array) == 0 {
return nil;
}
res := make(A, len(array), allocator);
for elem, i in array {
- res[i] = auto_cast clone_type(elem, allocator);
+ res[i] = auto_cast clone_type(elem, allocator, unique_strings);
}
return res;
}
-clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator) -> A {
+clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator, unique_strings: ^map[string] string) -> A {
if len(array) == 0 {
return nil;
}
res := make(A, len(array), allocator);
for elem, i in array {
- res[i] = auto_cast clone_type(elem, allocator);
+ res[i] = auto_cast clone_type(elem, allocator, unique_strings);
}
return res;
}
-clone_expr :: proc(node: ^ast.Expr, allocator: mem.Allocator) -> ^ast.Expr {
- return cast(^ast.Expr)clone_node(node, allocator);
+clone_expr :: proc(node: ^ast.Expr, allocator: mem.Allocator, unique_strings: ^map[string] string) -> ^ast.Expr {
+ return cast(^ast.Expr)clone_node(node, allocator, unique_strings);
}
-clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator) -> ^ast.Node {
+clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator, unique_strings: ^map[string] string) -> ^ast.Node {
using ast;
@@ -81,127 +81,132 @@ clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator) -> ^ast.Node {
case Bad_Expr:
case Ident:
r := cast(^Ident)res;
- r.name = strings.clone(n.name, allocator);
+ if unique_strings == nil {
+ r.name = strings.clone(n.name, allocator);
+ }
+ else {
+ r.name = get_index_unique_string(unique_strings, allocator, n.name);
+ }
case Implicit:
case Undef:
case Basic_Lit:
case Basic_Directive:
case Ellipsis:
r := cast(^Ellipsis)res;
- r.expr = clone_type(r.expr, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
case Tag_Expr:
r := cast(^Tag_Expr)res;
- r.expr = clone_type(r.expr, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
case Unary_Expr:
r := cast(^Unary_Expr)res;
- r.expr = clone_type(r.expr, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
case Binary_Expr:
r := cast(^Binary_Expr)res;
- r.left = clone_type(r.left, allocator);
- r.right = clone_type(r.right, allocator);
+ r.left = clone_type(r.left, allocator, unique_strings);
+ r.right = clone_type(r.right, allocator, unique_strings);
case Paren_Expr:
r := cast(^Paren_Expr)res;
- r.expr = clone_type(r.expr, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
case Selector_Expr:
r := cast(^Selector_Expr)res;
- r.expr = clone_type(r.expr, allocator);
- r.field = auto_cast clone_type(r.field, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
+ r.field = auto_cast clone_type(r.field, allocator, unique_strings);
case Implicit_Selector_Expr:
r := cast(^Implicit_Selector_Expr)res;
- r.field = auto_cast clone_type(r.field, allocator);
+ r.field = auto_cast clone_type(r.field, allocator, unique_strings);
case Slice_Expr:
r := cast(^Slice_Expr)res;
- r.expr = clone_type(r.expr, allocator);
- r.low = clone_type(r.low, allocator);
- r.high = clone_type(r.high, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
+ r.low = clone_type(r.low, allocator, unique_strings);
+ r.high = clone_type(r.high, allocator, unique_strings);
case Attribute:
r := cast(^Attribute)res;
- r.elems = clone_type(r.elems, allocator);
+ r.elems = clone_type(r.elems, allocator, unique_strings);
case Distinct_Type:
r := cast(^Distinct_Type)res;
- r.type = clone_type(r.type, allocator);
+ r.type = clone_type(r.type, allocator, unique_strings);
case Opaque_Type:
r := cast(^Opaque_Type)res;
- r.type = clone_type(r.type, allocator);
+ r.type = clone_type(r.type, allocator, unique_strings);
case Proc_Type:
r := cast(^Proc_Type)res;
- r.params = auto_cast clone_type(r.params, allocator);
- r.results = auto_cast clone_type(r.results, allocator);
+ r.params = auto_cast clone_type(r.params, allocator, unique_strings);
+ r.results = auto_cast clone_type(r.results, allocator, unique_strings);
case Pointer_Type:
r := cast(^Pointer_Type)res;
- r.elem = clone_type(r.elem, allocator);
+ r.elem = clone_type(r.elem, allocator, unique_strings);
case Array_Type:
r := cast(^Array_Type)res;
- r.len = clone_type(r.len, allocator);
- r.elem = clone_type(r.elem, allocator);
- r.tag = clone_type(r.tag, allocator);
+ r.len = clone_type(r.len, allocator, unique_strings);
+ r.elem = clone_type(r.elem, allocator, unique_strings);
+ r.tag = clone_type(r.tag, allocator, unique_strings);
case Dynamic_Array_Type:
r := cast(^Dynamic_Array_Type)res;
- r.elem = clone_type(r.elem, allocator);
- r.tag = clone_type(r.tag, allocator);
+ r.elem = clone_type(r.elem, allocator, unique_strings);
+ r.tag = clone_type(r.tag, allocator, unique_strings);
case Struct_Type:
r := cast(^Struct_Type)res;
- r.poly_params = auto_cast clone_type(r.poly_params, allocator);
- r.align = clone_type(r.align, allocator);
- r.fields = auto_cast clone_type(r.fields, allocator);
- r.where_clauses = clone_type(r.where_clauses, allocator);
+ r.poly_params = auto_cast clone_type(r.poly_params, allocator, unique_strings);
+ r.align = clone_type(r.align, allocator, unique_strings);
+ r.fields = auto_cast clone_type(r.fields, allocator, unique_strings);
+ r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings);
case Field:
r := cast(^Field)res;
- r.names = clone_type(r.names, allocator);
- r.type = clone_type(r.type, allocator);
- r.default_value = clone_type(r.default_value, allocator);
+ r.names = clone_type(r.names, allocator, unique_strings);
+ r.type = clone_type(r.type, allocator, unique_strings);
+ r.default_value = clone_type(r.default_value, allocator, unique_strings);
case Field_List:
r := cast(^Field_List)res;
- r.list = clone_type(r.list, allocator);
+ r.list = clone_type(r.list, allocator, unique_strings);
case Field_Value:
r := cast(^Field_Value)res;
- r.field = clone_type(r.field, allocator);
- r.value = clone_type(r.value, allocator);
+ r.field = clone_type(r.field, allocator, unique_strings);
+ r.value = clone_type(r.value, allocator, unique_strings);
case Union_Type:
r := cast(^Union_Type)res;
- r.poly_params = auto_cast clone_type(r.poly_params, allocator);
- r.align = clone_type(r.align, allocator);
- r.variants = clone_type(r.variants, allocator);
- r.where_clauses = clone_type(r.where_clauses, allocator);
+ r.poly_params = auto_cast clone_type(r.poly_params, allocator, unique_strings);
+ r.align = clone_type(r.align, allocator, unique_strings);
+ r.variants = clone_type(r.variants, allocator, unique_strings);
+ r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings);
case Enum_Type:
r := cast(^Enum_Type)res;
- r.base_type = clone_type(r.base_type, allocator);
- r.fields = clone_type(r.fields, allocator);
+ r.base_type = clone_type(r.base_type, allocator, unique_strings);
+ r.fields = clone_type(r.fields, allocator, unique_strings);
case Bit_Field_Type:
r := cast(^Bit_Field_Type)res;
- r.fields = clone_type(r.fields, allocator);
- r.align = clone_type(r.align, allocator);
+ r.fields = clone_type(r.fields, allocator, unique_strings);
+ r.align = clone_type(r.align, allocator, unique_strings);
case Bit_Set_Type:
r := cast(^Bit_Set_Type)res;
- r.elem = clone_type(r.elem, allocator);
- r.underlying = clone_type(r.underlying, allocator);
+ r.elem = clone_type(r.elem, allocator, unique_strings);
+ r.underlying = clone_type(r.underlying, allocator, unique_strings);
case Map_Type:
r := cast(^Map_Type)res;
- r.key = clone_type(r.key, allocator);
- r.value = clone_type(r.value, allocator);
+ r.key = clone_type(r.key, allocator, unique_strings);
+ r.value = clone_type(r.value, allocator, unique_strings);
case Call_Expr:
r := cast(^Call_Expr)res;
- r.expr = clone_type(r.expr, allocator);
- r.args = clone_type(r.args, allocator);
+ r.expr = clone_type(r.expr, allocator, unique_strings);
+ r.args = clone_type(r.args, allocator, unique_strings);
case Typeid_Type:
r := cast(^Typeid_Type)res;
- r.specialization = clone_type(r.specialization, allocator);
+ r.specialization = clone_type(r.specialization, allocator, unique_strings);
case Ternary_When_Expr:
r := cast(^Ternary_When_Expr)res;
- r.x = clone_type(r.x, allocator);
- r.cond = clone_type(r.cond, allocator);
- r.y = clone_type(r.y, allocator);
+ r.x = clone_type(r.x, allocator, unique_strings);
+ r.cond = clone_type(r.cond, allocator, unique_strings);
+ r.y = clone_type(r.y, allocator, unique_strings);
case Poly_Type:
r := cast(^Poly_Type)res;
- r.type = auto_cast clone_type(r.type, allocator);
- r.specialization = clone_type(r.specialization, allocator);
+ r.type = auto_cast clone_type(r.type, allocator, unique_strings);
+ r.specialization = clone_type(r.specialization, allocator, unique_strings);
case Proc_Group:
r := cast(^Proc_Group)res;
- r.args = clone_type(r.args, allocator);
+ r.args = clone_type(r.args, allocator, unique_strings);
case Comp_Lit:
r := cast(^Comp_Lit)res;
- r.type = clone_type(r.type, allocator);
- r.elems = clone_type(r.elems, allocator);
+ r.type = clone_type(r.type, allocator, unique_strings);
+ r.elems = clone_type(r.elems, allocator, unique_strings);
case:
log.error("Clone type Unhandled node kind: %T", n);
}
diff --git a/src/index/collector.odin b/src/index/collector.odin
index 73ff8b9..f8dfb63 100644
--- a/src/index/collector.odin
+++ b/src/index/collector.odin
@@ -15,28 +15,34 @@ import "shared:common"
SymbolCollection :: struct {
allocator: mem.Allocator,
config: ^common.Config,
- symbols: map[string] Symbol,
+ symbols: map[uint] Symbol,
unique_strings: map[string] string, //store all our strings as unique strings and reference them to save memory.
};
+get_index_unique_string :: proc {
+ get_index_unique_string_collection,
+ get_index_unique_string_collection_raw,
+};
-get_index_unique_string :: proc(collection: ^SymbolCollection, s: string) -> string {
+get_index_unique_string_collection :: proc(collection: ^SymbolCollection, s: string) -> string {
+ return get_index_unique_string_collection_raw(&collection.unique_strings, collection.allocator, s);
+}
+get_index_unique_string_collection_raw :: proc(unique_strings: ^map[string] string, allocator: mem.Allocator, s: string) -> string {
//i'm hashing this string way to much
- if _, ok := collection.unique_strings[s]; !ok {
- str := strings.clone(s, collection.allocator);
- collection.unique_strings[str] = str; //yeah maybe I have to use some integer and hash it, tried that before but got name collisions.
+ if _, ok := unique_strings[s]; !ok {
+ str := strings.clone(s, allocator);
+ unique_strings[str] = str; //yeah maybe I have to use some integer and hash it, tried that before but got name collisions.
}
- return collection.unique_strings[s];
+ return unique_strings[s];
}
-
make_symbol_collection :: proc(allocator := context.allocator, config: ^common.Config) -> SymbolCollection {
return SymbolCollection {
allocator = allocator,
config = config,
- symbols = make(map[string] Symbol, 16, allocator),
+ symbols = make(map[uint] Symbol, 16, allocator),
unique_strings = make(map[string] string, 16, allocator),
};
}
@@ -44,8 +50,7 @@ make_symbol_collection :: proc(allocator := context.allocator, config: ^common.C
delete_symbol_collection :: proc(collection: SymbolCollection) {
for k, v in collection.symbols {
- free_symbol(v);
- delete(k, collection.allocator);
+ free_symbol(v, collection.allocator);
}
for k, v in collection.unique_strings {
@@ -63,13 +68,13 @@ collect_procedure_fields :: proc(collection: ^SymbolCollection, proc_type: ^ast.
args := make([dynamic] ^ast.Field, 0, collection.allocator);
for ret in return_list.list {
- cloned := cast(^ast.Field)clone_type(ret, collection.allocator);
+ cloned := cast(^ast.Field)clone_type(ret, collection.allocator, &collection.unique_strings);
replace_package_alias(cloned, package_map, collection);
append(&returns, cloned);
}
for arg in arg_list.list {
- cloned := cast(^ast.Field)clone_type(arg, collection.allocator);
+ cloned := cast(^ast.Field)clone_type(arg, collection.allocator, &collection.unique_strings);
replace_package_alias(cloned, package_map, collection);
append(&args, cloned);
}
@@ -94,7 +99,7 @@ collect_struct_fields :: proc(collection: ^SymbolCollection, fields: ^ast.Field_
identifier := n.derived.(ast.Ident);
append(&names, get_index_unique_string(collection, identifier.name));
- cloned := clone_type(field.type, collection.allocator);
+ cloned := clone_type(field.type, collection.allocator, &collection.unique_strings);
replace_package_alias(cloned, package_map, collection);
append(&types, cloned);
}
@@ -148,7 +153,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
token = v;
token_type = .Function;
symbol.value = SymbolProcedureGroupValue {
- group = clone_type(value_decl.values[0], collection.allocator),
+ group = clone_type(value_decl.values[0], collection.allocator, &collection.unique_strings),
};
case ast.Struct_Type:
token = v;
@@ -164,9 +169,20 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
symbol.type = token_type;
symbol.uri = get_index_unique_string(collection, uri);
- //id := hash.murmur64(transmute([]u8)strings.concatenate({symbol.scope, name}, context.temp_allocator));
+ cat := strings.concatenate({symbol.scope, name}, context.temp_allocator);
+
+ id := get_symbol_id(cat);
+
+ //right now i'm not checking comments whether is for windows, linux, etc, and some packages do not specify that(os)
+ if v, ok := collection.symbols[id]; !ok {
+ collection.symbols[id] = symbol;
+ //fmt.printf("FAILED COLLOSION! %v %v \n", id, cat);
+ }
+
+ else {
+ free_symbol(symbol, collection.allocator);
+ }
- collection.symbols[strings.concatenate({symbol.scope, name}, collection.allocator)] = symbol;
}
}
diff --git a/src/index/memory_index.odin b/src/index/memory_index.odin
index e99d759..05de53b 100644
--- a/src/index/memory_index.odin
+++ b/src/index/memory_index.odin
@@ -28,7 +28,9 @@ make_memory_index :: proc(collection: SymbolCollection) -> MemoryIndex {
memory_index_lookup :: proc(index: ^MemoryIndex, name: string, scope: string) -> (Symbol, bool) {
//hashed := hash.murmur64(transmute([]u8)strings.concatenate({scope, name}, context.temp_allocator));
- return index.collection.symbols[strings.concatenate({scope, name}, context.temp_allocator)];
+
+ id := get_symbol_id(strings.concatenate({scope, name}, context.temp_allocator));
+ return index.collection.symbols[id];
}
memory_index_fuzzy_search :: proc(index: ^MemoryIndex, name: string, scope: [] string) -> ([] Symbol, bool) {
diff --git a/src/index/symbol.odin b/src/index/symbol.odin
index 8c672d9..6630015 100644
--- a/src/index/symbol.odin
+++ b/src/index/symbol.odin
@@ -7,6 +7,7 @@ import "core:mem"
import "core:fmt"
import "core:path/filepath"
import "core:path"
+import "core:slice"
import "shared:common"
@@ -89,16 +90,29 @@ SymbolType :: enum {
Struct = 22,
};
-free_symbol :: proc(symbol: Symbol) {
+free_symbol :: proc(symbol: Symbol, allocator: mem.Allocator) {
#partial switch v in symbol.value {
case SymbolProcedureValue:
- common.free_ast(v.return_types);
- common.free_ast(v.arg_types);
+ common.free_ast(v.return_types, allocator);
+ common.free_ast(v.arg_types, allocator);
case SymbolStructValue:
- common.free_ast(v.types);
+ delete(v.names, allocator);
+ common.free_ast(v.types, allocator);
case SymbolGenericValue:
- common.free_ast(v.expr);
+ common.free_ast(v.expr, allocator);
+ case SymbolProcedureGroupValue:
+ common.free_ast(v.group, allocator);
+ case SymbolEnumValue:
+ delete(v.names, allocator);
+ case SymbolUnionValue:
+ delete(v.names, allocator);
}
+}
+
+get_symbol_id :: proc(str: string) -> uint {
+ ret := common.sha1_hash(transmute([]byte)str);
+ r := cast(^uint)slice.first_ptr(ret[:]);
+ return r^;
} \ No newline at end of file
diff --git a/src/main.odin b/src/main.odin
index 6246ba0..7518454 100644
--- a/src/main.odin
+++ b/src/main.odin
@@ -50,7 +50,6 @@ run :: proc(reader: ^server.Reader, writer: ^server.Writer) {
return;
}
-
value: json.Value;
value, success = server.read_and_parse_body(reader, header);
@@ -69,12 +68,21 @@ run :: proc(reader: ^server.Reader, writer: ^server.Writer) {
free_all(context.temp_allocator);
}
+ for k, v in config.collections {
+ delete(k);
+ delete(v);
+ }
+
delete(config.collections);
delete(config.workspace_folders);
server.document_storage_shutdown();
index.free_static_index();
+
+ //common.memleak_dump(tracking_allocator, common.log_dump, nil);
+
+
}
end :: proc() {
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index e026023..4f021b7 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -348,7 +348,7 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast
}
if ident, ok := result.type.derived.(Ident); ok {
- field := cast(^Field)index.clone_node(result, context.temp_allocator);
+ field := cast(^Field)index.clone_node(result, context.temp_allocator, nil);
if m := &poly_map[ident.name]; m != nil {
field.type = poly_map[ident.name];
@@ -938,7 +938,7 @@ make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type
}
else {
- append(&types, index.clone_type(field.type, context.temp_allocator));
+ append(&types, index.clone_type(field.type, context.temp_allocator, nil));
}
}
}
@@ -1558,7 +1558,7 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
//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);
+ common.free_ast(position_context.selector, context.allocator);
}
list.items = items[:];
@@ -1725,7 +1725,11 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP
str := position_context.file.src[node.pos.offset:max(0, node.end.offset-1)];
- p := parser.default_parser();
+ p := parser.Parser {
+ err = parser_warning_handler, //empty
+ warn = parser_warning_handler, //empty
+ file = &position_context.file,
+ };
tokenizer.init(&p.tok, str, position_context.file.fullpath);
diff --git a/src/server/requests.odin b/src/server/requests.odin
index 4eed483..149ea3a 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -269,8 +269,8 @@ request_initialize :: proc(params: json.Value, id: RequestId, config: ^common.Co
token_type := type_info_of(SemanticTokenTypes).variant.(runtime.Type_Info_Named).base.variant.(runtime.Type_Info_Enum);
token_modifier := type_info_of(SemanticTokenModifiers).variant.(runtime.Type_Info_Named).base.variant.(runtime.Type_Info_Enum);
- token_types := make([] string, len(token_type.names));
- token_modifiers := make([] string, len(token_modifier.names));
+ token_types := make([] string, len(token_type.names), context.temp_allocator);
+ token_modifiers := make([] string, len(token_modifier.names), context.temp_allocator);
for name, i in token_type.names {
token_types[i] = strings.to_lower(name, context.temp_allocator);
@@ -350,7 +350,6 @@ request_definition :: proc(params: json.Value, id: RequestId, config: ^common.Co
return .ParseError;
}
-
document := document_get(definition_params.textDocument.uri);
if document == nil {
diff --git a/src/server/semantic_tokens.odin b/src/server/semantic_tokens.odin
index d374cc0..03f739b 100644
--- a/src/server/semantic_tokens.odin
+++ b/src/server/semantic_tokens.odin
@@ -63,10 +63,38 @@ SemanticTokens :: struct {
data: [] uint,
};
+SemanticTokenInternal :: struct {
+ line: uint,
+ column: uint,
+ length: uint,
+};
+
+
+convert_to_finished_tokens :: proc(tokens: [dynamic]SemanticTokenInternal) -> [] SemanticTokens {
+ return {};
+}
+
get_semantic_tokens :: proc(document: ^Document) -> [] SemanticTokens {
+ tokens := make([dynamic]SemanticTokenInternal, context.temp_allocator);
+ /*
+ Temp parse the document again, right now there is too many leaks that need to be fixued in the parser.
+ */
return {};
}
+
+
+/*
+extract_semantic_tokens :: proc {
+ extract_semantic_tokens_node,
+ extract_semantic_tokens_dynamic_array,
+ extract_semantic_tokens_array,
+};
+
+extract_semantic_tokens_node :: proc() {
+
+}
+*/ \ No newline at end of file