aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/allocator.odin73
-rw-r--r--src/common/ast.odin650
-rw-r--r--src/common/config.odin4
-rw-r--r--src/common/fuzzy.odin3
-rw-r--r--src/common/position.odin121
-rw-r--r--src/common/types.odin2
-rw-r--r--src/common/uri.odin23
-rw-r--r--src/common/util.odin41
-rw-r--r--src/common/util_windows.odin84
-rw-r--r--src/dump_windows.odin85
-rw-r--r--src/main.odin16
-rw-r--r--src/odin/format/format.odin24
-rw-r--r--src/odin/printer/document.odin364
-rw-r--r--src/odin/printer/printer.odin115
-rw-r--r--src/odin/printer/visit.odin1192
-rw-r--r--src/server/action.odin2
-rw-r--r--src/server/analysis.odin1865
-rw-r--r--src/server/build.odin62
-rw-r--r--src/server/caches.odin10
-rw-r--r--src/server/check.odin100
-rw-r--r--src/server/clone.odin367
-rw-r--r--src/server/collector.odin375
-rw-r--r--src/server/completion.odin883
-rw-r--r--src/server/definition.odin49
-rw-r--r--src/server/document_links.odin16
-rw-r--r--src/server/document_symbols.odin23
-rw-r--r--src/server/documents.odin166
-rw-r--r--src/server/format.odin26
-rw-r--r--src/server/hover.odin138
-rw-r--r--src/server/indexer.odin11
-rw-r--r--src/server/inlay_hints.odin34
-rw-r--r--src/server/lens.odin26
-rw-r--r--src/server/log.odin42
-rw-r--r--src/server/memory_index.odin38
-rw-r--r--src/server/reader.odin8
-rw-r--r--src/server/references.odin122
-rw-r--r--src/server/rename.odin20
-rw-r--r--src/server/requests.odin649
-rw-r--r--src/server/response.odin9
-rw-r--r--src/server/semantic_tokens.odin792
-rw-r--r--src/server/signature.odin105
-rw-r--r--src/server/snippets.odin12
-rw-r--r--src/server/symbol.odin44
-rw-r--r--src/server/types.odin19
-rw-r--r--src/server/unmarshal.odin82
-rw-r--r--src/server/writer.odin5
-rw-r--r--src/testing/testing.odin299
-rw-r--r--tools/odinfmt/main.odin129
-rw-r--r--tools/odinfmt/snapshot/snapshot.odin56
-rw-r--r--tools/odinfmt/tests.odin6
50 files changed, 6718 insertions, 2669 deletions
diff --git a/src/common/allocator.odin b/src/common/allocator.odin
index 6d2d371..c231102 100644
--- a/src/common/allocator.odin
+++ b/src/common/allocator.odin
@@ -11,15 +11,24 @@ Scratch_Allocator :: struct {
leaked_allocations: [dynamic][]byte,
}
-scratch_allocator_init :: proc (s: ^Scratch_Allocator, size: int, backup_allocator := context.allocator) {
- s.data, _ = mem.make_aligned([]byte, size, 2 * align_of(rawptr), backup_allocator)
- s.curr_offset = 0
- s.prev_allocation = nil
- s.backup_allocator = backup_allocator
+scratch_allocator_init :: proc(
+ s: ^Scratch_Allocator,
+ size: int,
+ backup_allocator := context.allocator,
+) {
+ s.data, _ = mem.make_aligned(
+ []byte,
+ size,
+ 2 * align_of(rawptr),
+ backup_allocator,
+ )
+ s.curr_offset = 0
+ s.prev_allocation = nil
+ s.backup_allocator = backup_allocator
s.leaked_allocations.allocator = backup_allocator
}
-scratch_allocator_destroy :: proc (s: ^Scratch_Allocator) {
+scratch_allocator_destroy :: proc(s: ^Scratch_Allocator) {
if s == nil {
return
}
@@ -31,14 +40,25 @@ scratch_allocator_destroy :: proc (s: ^Scratch_Allocator) {
s^ = {}
}
-scratch_allocator_proc :: proc (allocator_data: rawptr, mode: mem.Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, mem.Allocator_Error) {
+scratch_allocator_proc :: proc(
+ allocator_data: rawptr,
+ mode: mem.Allocator_Mode,
+ size,
+ alignment: int,
+ old_memory: rawptr,
+ old_size: int,
+ loc := #caller_location,
+) -> (
+ []byte,
+ mem.Allocator_Error,
+) {
s := (^Scratch_Allocator)(allocator_data)
if s.data == nil {
DEFAULT_BACKING_SIZE :: 1 << 22
if !(context.allocator.procedure != scratch_allocator_proc &&
- context.allocator.data != allocator_data) {
+ context.allocator.data != allocator_data) {
panic("cyclic initialization of the scratch allocator with itself")
}
scratch_allocator_init(s, DEFAULT_BACKING_SIZE)
@@ -50,7 +70,7 @@ scratch_allocator_proc :: proc (allocator_data: rawptr, mode: mem.Allocator_Mode
case .Alloc:
size = mem.align_forward_int(size, alignment)
- switch {
+ switch {
case s.curr_offset + size <= len(s.data):
start := uintptr(raw_data(s.data))
ptr := start + uintptr(s.curr_offset)
@@ -80,7 +100,13 @@ scratch_allocator_proc :: proc (allocator_data: rawptr, mode: mem.Allocator_Mode
if logger := context.logger; logger.lowest_level <= .Warning {
if logger.procedure != nil {
- logger.procedure(logger.data, .Warning, "mem.Scratch_Allocator resorted to backup_allocator" , logger.options, loc)
+ logger.procedure(
+ logger.data,
+ .Warning,
+ "mem.Scratch_Allocator resorted to backup_allocator",
+ logger.options,
+ loc,
+ )
}
}
@@ -100,13 +126,29 @@ scratch_allocator_proc :: proc (allocator_data: rawptr, mode: mem.Allocator_Mode
end := begin + uintptr(len(s.data))
old_ptr := uintptr(old_memory)
- data, err := scratch_allocator_proc(allocator_data, .Alloc, size, alignment, old_memory, old_size, loc)
+ data, err := scratch_allocator_proc(
+ allocator_data,
+ .Alloc,
+ size,
+ alignment,
+ old_memory,
+ old_size,
+ loc,
+ )
if err != nil {
return data, err
}
runtime.copy(data, mem.byte_slice(old_memory, old_size))
- _, err = scratch_allocator_proc(allocator_data, .Free, 0, alignment, old_memory, old_size, loc)
+ _, err = scratch_allocator_proc(
+ allocator_data,
+ .Free,
+ 0,
+ alignment,
+ old_memory,
+ old_size,
+ loc,
+ )
return data, err
case .Query_Features:
@@ -122,9 +164,6 @@ scratch_allocator_proc :: proc (allocator_data: rawptr, mode: mem.Allocator_Mode
return nil, nil
}
-scratch_allocator :: proc (allocator: ^Scratch_Allocator) -> mem.Allocator {
- return mem.Allocator {
- procedure = scratch_allocator_proc,
- data = allocator,
- }
+scratch_allocator :: proc(allocator: ^Scratch_Allocator) -> mem.Allocator {
+ return mem.Allocator{procedure = scratch_allocator_proc, data = allocator}
}
diff --git a/src/common/ast.odin b/src/common/ast.odin
index 71f74a4..e4eb0fd 100644
--- a/src/common/ast.odin
+++ b/src/common/ast.odin
@@ -8,61 +8,61 @@ import "core:strings"
import path "core:path/slashpath"
keyword_map: map[string]bool = {
- "int" = true,
- "uint" = true,
- "string" = true,
- "cstring" = true,
- "u64" = true,
- "f32" = true,
- "f64" = true,
- "i64" = true,
- "i128" = true,
- "i32" = true,
- "i16" = true,
- "u16" = true,
- "bool" = true,
- "rawptr" = true,
- "any" = true,
- "u32" = true,
- "u128" = true,
- "b32" = true,
- "b64" = true,
- "true" = true,
- "false" = true,
- "nil" = true,
- "byte" = true,
- "u8" = true,
- "i8" = true,
- "rune" = true,
- "f16be" = true,
- "f16le" = true,
- "f32be" = true,
- "f32le" = true,
- "f64be" = true,
- "f64le" = true,
- "i16be" = true,
- "i16le" = true,
- "i32be" = true,
- "i32le" = true,
- "i64be" = true,
- "i64le" = true,
- "u16be" = true,
- "u16le" = true,
- "u32be" = true,
- "u32le" = true,
- "u64be" = true,
- "u64le" = true,
- "i128be" = true,
- "i128le" = true,
- "u128be" = true,
- "u128le" = true,
- "complex32" = true,
- "complex64" = true,
- "complex128" = true,
- "quaternion64" = true,
- "quaternion128" = true,
- "quaternion256" = true,
- "uintptr" = true,
+ "int" = true,
+ "uint" = true,
+ "string" = true,
+ "cstring" = true,
+ "u64" = true,
+ "f32" = true,
+ "f64" = true,
+ "i64" = true,
+ "i128" = true,
+ "i32" = true,
+ "i16" = true,
+ "u16" = true,
+ "bool" = true,
+ "rawptr" = true,
+ "any" = true,
+ "u32" = true,
+ "u128" = true,
+ "b32" = true,
+ "b64" = true,
+ "true" = true,
+ "false" = true,
+ "nil" = true,
+ "byte" = true,
+ "u8" = true,
+ "i8" = true,
+ "rune" = true,
+ "f16be" = true,
+ "f16le" = true,
+ "f32be" = true,
+ "f32le" = true,
+ "f64be" = true,
+ "f64le" = true,
+ "i16be" = true,
+ "i16le" = true,
+ "i32be" = true,
+ "i32le" = true,
+ "i64be" = true,
+ "i64le" = true,
+ "u16be" = true,
+ "u16le" = true,
+ "u32be" = true,
+ "u32le" = true,
+ "u64be" = true,
+ "u64le" = true,
+ "i128be" = true,
+ "i128le" = true,
+ "u128be" = true,
+ "u128le" = true,
+ "complex32" = true,
+ "complex64" = true,
+ "complex128" = true,
+ "quaternion64" = true,
+ "quaternion128" = true,
+ "quaternion256" = true,
+ "uintptr" = true,
}
GlobalExpr :: struct {
@@ -99,7 +99,12 @@ unwrap_pointer :: proc(expr: ^ast.Expr) -> (ast.Ident, bool) {
return {}, false
}
-collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^ast.Node, skip_private: bool) {
+collect_value_decl :: proc(
+ exprs: ^[dynamic]GlobalExpr,
+ file: ast.File,
+ stmt: ^ast.Node,
+ skip_private: bool,
+) {
if value_decl, ok := stmt.derived.(^ast.Value_Decl); ok {
is_deprecated := false
is_private_file := false
@@ -112,7 +117,8 @@ collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^a
if ident, ok := value.field.derived.(^ast.Ident); ok {
switch ident.name {
case "private":
- if val, ok := value.value.derived.(^ast.Basic_Lit); ok {
+ if val, ok := value.value.derived.(^ast.Basic_Lit);
+ ok {
switch val.tok.text {
case "\"file\"":
is_private_file = true
@@ -141,35 +147,44 @@ collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^a
str := get_ast_node_string(name, file.src)
if value_decl.type != nil {
- append(exprs, GlobalExpr {
- name = str,
- name_expr = name,
- expr = value_decl.type,
- mutable = value_decl.is_mutable,
- docs = value_decl.docs,
- attributes = value_decl.attributes[:],
- deprecated = is_deprecated,
- builtin = is_builtin,
- })
- } else {
- if len(value_decl.values) > i {
- append(exprs, GlobalExpr {
+ append(
+ exprs,
+ GlobalExpr{
name = str,
name_expr = name,
- expr = value_decl.values[i],
- mutable = value_decl.is_mutable,
- docs = value_decl.docs,
+ expr = value_decl.type,
+ mutable = value_decl.is_mutable,
+ docs = value_decl.docs,
attributes = value_decl.attributes[:],
deprecated = is_deprecated,
builtin = is_builtin,
- })
+ },
+ )
+ } else {
+ if len(value_decl.values) > i {
+ append(
+ exprs,
+ GlobalExpr{
+ name = str,
+ name_expr = name,
+ expr = value_decl.values[i],
+ mutable = value_decl.is_mutable,
+ docs = value_decl.docs,
+ attributes = value_decl.attributes[:],
+ deprecated = is_deprecated,
+ builtin = is_builtin,
+ },
+ )
}
}
}
}
}
-collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr {
+collect_globals :: proc(
+ file: ast.File,
+ skip_private := false,
+) -> []GlobalExpr {
exprs := make([dynamic]GlobalExpr, context.temp_allocator)
for decl in file.decls {
@@ -205,16 +220,29 @@ collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr {
}
if ident != nil && implicit != nil {
- if ident.name == "ODIN_OS" && implicit.tok.text == fmt.tprint(ODIN_OS) {
- if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok {
+ if ident.name == "ODIN_OS" &&
+ implicit.tok.text == fmt.tprint(ODIN_OS) {
+ if block, ok := when_decl.body.derived.(^ast.Block_Stmt);
+ ok {
for stmt in block.stmts {
- collect_value_decl(&exprs, file, stmt, skip_private)
+ collect_value_decl(
+ &exprs,
+ file,
+ stmt,
+ skip_private,
+ )
}
}
} else if ident.name != "ODIN_OS" {
- if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok {
+ if block, ok := when_decl.body.derived.(^ast.Block_Stmt);
+ ok {
for stmt in block.stmts {
- collect_value_decl(&exprs, file, stmt, skip_private)
+ collect_value_decl(
+ &exprs,
+ file,
+ stmt,
+ skip_private,
+ )
}
}
}
@@ -226,7 +254,8 @@ collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr {
}
}
}
- } else if foreign_decl, ok := decl.derived.(^ast.Foreign_Block_Decl); ok {
+ } else if foreign_decl, ok := decl.derived.(^ast.Foreign_Block_Decl);
+ ok {
if foreign_decl.body == nil {
continue
}
@@ -246,18 +275,39 @@ get_ast_node_string :: proc(node: ^ast.Node, src: string) -> string {
return string(src[node.pos.offset:node.end.offset])
}
-get_doc :: proc(comment: ^ast.Comment_Group, allocator: mem.Allocator) -> string {
+get_doc :: proc(
+ comment: ^ast.Comment_Group,
+ allocator: mem.Allocator,
+) -> string {
if comment != nil {
tmp: string
for doc in comment.list {
- tmp = strings.concatenate({tmp, "\n", doc.text}, context.temp_allocator)
+ tmp = strings.concatenate(
+ {tmp, "\n", doc.text},
+ context.temp_allocator,
+ )
}
if tmp != "" {
- no_lines, _ := strings.replace_all(tmp, "//", "", context.temp_allocator)
- no_begin_comments, _ := strings.replace_all(no_lines, "/*", "", context.temp_allocator)
- no_end_comments, _ := strings.replace_all(no_begin_comments, "*/", "", context.temp_allocator)
+ no_lines, _ := strings.replace_all(
+ tmp,
+ "//",
+ "",
+ context.temp_allocator,
+ )
+ no_begin_comments, _ := strings.replace_all(
+ no_lines,
+ "/*",
+ "",
+ context.temp_allocator,
+ )
+ no_end_comments, _ := strings.replace_all(
+ no_begin_comments,
+ "*/",
+ "",
+ context.temp_allocator,
+ )
return strings.clone(no_end_comments, allocator)
}
}
@@ -265,7 +315,7 @@ get_doc :: proc(comment: ^ast.Comment_Group, allocator: mem.Allocator) -> string
return ""
}
-free_ast :: proc{
+free_ast :: proc {
free_ast_node,
free_ast_array,
free_ast_dynamic_array,
@@ -291,7 +341,10 @@ free_ast_array :: proc(array: $A/[]^$T, allocator: mem.Allocator) {
delete(array, allocator)
}
-free_ast_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator) {
+free_ast_dynamic_array :: proc(
+ array: $A/[dynamic]^$T,
+ allocator: mem.Allocator,
+) {
for elem, i in array {
free_ast(elem, allocator)
}
@@ -307,195 +360,195 @@ free_ast_node :: proc(node: ^ast.Node, allocator: mem.Allocator) {
}
if node.derived != nil do #partial switch n in node.derived {
- case ^Bad_Expr:
- case ^Ident:
- case ^Implicit:
- case ^Undef:
- case ^Basic_Directive:
- case ^Basic_Lit:
- case ^Ellipsis:
- free_ast(n.expr, allocator)
- case ^Proc_Lit:
- free_ast(n.type, allocator)
- free_ast(n.body, allocator)
- free_ast(n.where_clauses, allocator)
- case ^Comp_Lit:
- free_ast(n.type, allocator)
- free_ast(n.elems, allocator)
- case ^Tag_Expr:
- free_ast(n.expr, allocator)
- case ^Unary_Expr:
- free_ast(n.expr, allocator)
- case ^Binary_Expr:
- free_ast(n.left, allocator)
- free_ast(n.right, allocator)
- case ^Paren_Expr:
- free_ast(n.expr, allocator)
- case ^Call_Expr:
- free_ast(n.expr, allocator)
- free_ast(n.args, allocator)
- case ^Selector_Expr:
- free_ast(n.expr, allocator)
- free_ast(n.field, allocator)
- case ^Implicit_Selector_Expr:
- free_ast(n.field, allocator)
- case ^Index_Expr:
- free_ast(n.expr, allocator)
- free_ast(n.index, allocator)
- case ^Deref_Expr:
- free_ast(n.expr, allocator)
- case ^Slice_Expr:
- free_ast(n.expr, allocator)
- free_ast(n.low, allocator)
- free_ast(n.high, allocator)
- case ^Field_Value:
- free_ast(n.field, allocator)
- free_ast(n.value, allocator)
- case ^Ternary_If_Expr:
- free_ast(n.x, allocator)
- free_ast(n.cond, allocator)
- free_ast(n.y, allocator)
- case ^Ternary_When_Expr:
- free_ast(n.x, allocator)
- free_ast(n.cond, allocator)
- free_ast(n.y, allocator)
- case ^Type_Assertion:
- free_ast(n.expr, allocator)
- free_ast(n.type, allocator)
- case ^Type_Cast:
- free_ast(n.type, allocator)
- free_ast(n.expr, allocator)
- case ^Auto_Cast:
- free_ast(n.expr, allocator)
- case ^Bad_Stmt:
- case ^Empty_Stmt:
- case ^Expr_Stmt:
- free_ast(n.expr, allocator)
- case ^Tag_Stmt:
- r := cast(^Expr_Stmt)node
- free_ast(r.expr, allocator)
- case ^Assign_Stmt:
- free_ast(n.lhs, allocator)
- free_ast(n.rhs, allocator)
- case ^Block_Stmt:
- free_ast(n.label, allocator)
- free_ast(n.stmts, allocator)
- case ^If_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, allocator)
- free_ast(n.body, allocator)
- free_ast(n.else_stmt, allocator)
- case ^Return_Stmt:
- free_ast(n.results, allocator)
- case ^Defer_Stmt:
- free_ast(n.stmt, allocator)
- case ^For_Stmt:
- 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, allocator)
- free_ast(n.vals, allocator)
- free_ast(n.expr, allocator)
- free_ast(n.body, allocator)
- case ^Case_Clause:
- free_ast(n.list, allocator)
- free_ast(n.body, allocator)
- case ^Switch_Stmt:
- 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, allocator)
- free_ast(n.tag, allocator)
- free_ast(n.expr, allocator)
- free_ast(n.body, allocator)
- case ^Branch_Stmt:
- free_ast(n.label, allocator)
- case ^Using_Stmt:
- free_ast(n.list, allocator)
- case ^Bad_Decl:
- case ^Value_Decl:
- free_ast(n.attributes, allocator)
- free_ast(n.names, allocator)
- free_ast(n.type, allocator)
- free_ast(n.values, allocator)
- case ^Package_Decl:
- case ^Import_Decl:
- case ^Foreign_Block_Decl:
- free_ast(n.attributes, allocator)
- free_ast(n.foreign_library, allocator)
- free_ast(n.body, allocator)
- case ^Foreign_Import_Decl:
- free_ast(n.name, allocator)
- free_ast(n.attributes, allocator)
- case ^Proc_Group:
- free_ast(n.args, allocator)
- case ^Attribute:
- free_ast(n.elems, allocator)
- case ^Field:
- 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, allocator)
- case ^Typeid_Type:
- free_ast(n.specialization, allocator)
- case ^Helper_Type:
- free_ast(n.type, allocator)
- case ^Distinct_Type:
- free_ast(n.type, allocator)
- case ^Poly_Type:
- free_ast(n.type, allocator)
- free_ast(n.specialization, allocator)
- case ^Proc_Type:
- free_ast(n.params, allocator)
- free_ast(n.results, allocator)
- case ^Pointer_Type:
- free_ast(n.elem, allocator)
- case ^Array_Type:
- free_ast(n.len, allocator)
- free_ast(n.elem, allocator)
- free_ast(n.tag, allocator)
- case ^Dynamic_Array_Type:
- free_ast(n.elem, allocator)
- free_ast(n.tag, allocator)
- case ^Struct_Type:
- 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, 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, allocator)
- free_ast(n.fields, allocator)
- case ^Bit_Set_Type:
- free_ast(n.elem, allocator)
- free_ast(n.underlying, allocator)
- case ^Map_Type:
- free_ast(n.key, allocator)
- free_ast(n.value, allocator)
- case ^Multi_Pointer_Type:
- free_ast(n.elem, allocator)
- case ^Matrix_Type:
- free_ast(n.elem, allocator)
- case:
- panic(fmt.aprintf("free Unhandled node kind: %T", n))
- }
+ case ^Bad_Expr:
+ case ^Ident:
+ case ^Implicit:
+ case ^Undef:
+ case ^Basic_Directive:
+ case ^Basic_Lit:
+ case ^Ellipsis:
+ free_ast(n.expr, allocator)
+ case ^Proc_Lit:
+ free_ast(n.type, allocator)
+ free_ast(n.body, allocator)
+ free_ast(n.where_clauses, allocator)
+ case ^Comp_Lit:
+ free_ast(n.type, allocator)
+ free_ast(n.elems, allocator)
+ case ^Tag_Expr:
+ free_ast(n.expr, allocator)
+ case ^Unary_Expr:
+ free_ast(n.expr, allocator)
+ case ^Binary_Expr:
+ free_ast(n.left, allocator)
+ free_ast(n.right, allocator)
+ case ^Paren_Expr:
+ free_ast(n.expr, allocator)
+ case ^Call_Expr:
+ free_ast(n.expr, allocator)
+ free_ast(n.args, allocator)
+ case ^Selector_Expr:
+ free_ast(n.expr, allocator)
+ free_ast(n.field, allocator)
+ case ^Implicit_Selector_Expr:
+ free_ast(n.field, allocator)
+ case ^Index_Expr:
+ free_ast(n.expr, allocator)
+ free_ast(n.index, allocator)
+ case ^Deref_Expr:
+ free_ast(n.expr, allocator)
+ case ^Slice_Expr:
+ free_ast(n.expr, allocator)
+ free_ast(n.low, allocator)
+ free_ast(n.high, allocator)
+ case ^Field_Value:
+ free_ast(n.field, allocator)
+ free_ast(n.value, allocator)
+ case ^Ternary_If_Expr:
+ free_ast(n.x, allocator)
+ free_ast(n.cond, allocator)
+ free_ast(n.y, allocator)
+ case ^Ternary_When_Expr:
+ free_ast(n.x, allocator)
+ free_ast(n.cond, allocator)
+ free_ast(n.y, allocator)
+ case ^Type_Assertion:
+ free_ast(n.expr, allocator)
+ free_ast(n.type, allocator)
+ case ^Type_Cast:
+ free_ast(n.type, allocator)
+ free_ast(n.expr, allocator)
+ case ^Auto_Cast:
+ free_ast(n.expr, allocator)
+ case ^Bad_Stmt:
+ case ^Empty_Stmt:
+ case ^Expr_Stmt:
+ free_ast(n.expr, allocator)
+ case ^Tag_Stmt:
+ r := cast(^Expr_Stmt)node
+ free_ast(r.expr, allocator)
+ case ^Assign_Stmt:
+ free_ast(n.lhs, allocator)
+ free_ast(n.rhs, allocator)
+ case ^Block_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.stmts, allocator)
+ case ^If_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, allocator)
+ free_ast(n.body, allocator)
+ free_ast(n.else_stmt, allocator)
+ case ^Return_Stmt:
+ free_ast(n.results, allocator)
+ case ^Defer_Stmt:
+ free_ast(n.stmt, allocator)
+ case ^For_Stmt:
+ 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, allocator)
+ free_ast(n.vals, allocator)
+ free_ast(n.expr, allocator)
+ free_ast(n.body, allocator)
+ case ^Case_Clause:
+ free_ast(n.list, allocator)
+ free_ast(n.body, allocator)
+ case ^Switch_Stmt:
+ 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, allocator)
+ free_ast(n.tag, allocator)
+ free_ast(n.expr, allocator)
+ free_ast(n.body, allocator)
+ case ^Branch_Stmt:
+ free_ast(n.label, allocator)
+ case ^Using_Stmt:
+ free_ast(n.list, allocator)
+ case ^Bad_Decl:
+ case ^Value_Decl:
+ free_ast(n.attributes, allocator)
+ free_ast(n.names, allocator)
+ free_ast(n.type, allocator)
+ free_ast(n.values, allocator)
+ case ^Package_Decl:
+ case ^Import_Decl:
+ case ^Foreign_Block_Decl:
+ free_ast(n.attributes, allocator)
+ free_ast(n.foreign_library, allocator)
+ free_ast(n.body, allocator)
+ case ^Foreign_Import_Decl:
+ free_ast(n.name, allocator)
+ free_ast(n.attributes, allocator)
+ case ^Proc_Group:
+ free_ast(n.args, allocator)
+ case ^Attribute:
+ free_ast(n.elems, allocator)
+ case ^Field:
+ 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, allocator)
+ case ^Typeid_Type:
+ free_ast(n.specialization, allocator)
+ case ^Helper_Type:
+ free_ast(n.type, allocator)
+ case ^Distinct_Type:
+ free_ast(n.type, allocator)
+ case ^Poly_Type:
+ free_ast(n.type, allocator)
+ free_ast(n.specialization, allocator)
+ case ^Proc_Type:
+ free_ast(n.params, allocator)
+ free_ast(n.results, allocator)
+ case ^Pointer_Type:
+ free_ast(n.elem, allocator)
+ case ^Array_Type:
+ free_ast(n.len, allocator)
+ free_ast(n.elem, allocator)
+ free_ast(n.tag, allocator)
+ case ^Dynamic_Array_Type:
+ free_ast(n.elem, allocator)
+ free_ast(n.tag, allocator)
+ case ^Struct_Type:
+ 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, 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, allocator)
+ free_ast(n.fields, allocator)
+ case ^Bit_Set_Type:
+ free_ast(n.elem, allocator)
+ free_ast(n.underlying, allocator)
+ case ^Map_Type:
+ free_ast(n.key, allocator)
+ free_ast(n.value, allocator)
+ case ^Multi_Pointer_Type:
+ free_ast(n.elem, allocator)
+ case ^Matrix_Type:
+ free_ast(n.elem, allocator)
+ case:
+ panic(fmt.aprintf("free Unhandled node kind: %T", n))
+ }
mem.free(node, allocator)
}
@@ -516,7 +569,7 @@ free_ast_file :: proc(file: ast.File, allocator := context.allocator) {
delete(file.decls)
}
-node_equal :: proc{
+node_equal :: proc {
node_equal_node,
node_equal_array,
node_equal_dynamic_array,
@@ -722,37 +775,52 @@ node_to_string :: proc(node: ^ast.Node, remove_pointers := false) -> string {
return strings.to_string(builder)
}
-build_string :: proc{
+build_string :: proc {
build_string_ast_array,
build_string_dynamic_array,
build_string_node,
}
-build_string_dynamic_array :: proc(array: $A/[]^$T, builder: ^strings.Builder, remove_pointers: bool) {
+build_string_dynamic_array :: proc(
+ array: $A/[]^$T,
+ builder: ^strings.Builder,
+ remove_pointers: bool,
+) {
for elem, i in array {
build_string(elem, builder, remove_pointers)
}
}
-build_string_ast_array :: proc(array: $A/[dynamic]^$T, builder: ^strings.Builder, remove_pointers: bool) {
+build_string_ast_array :: proc(
+ array: $A/[dynamic]^$T,
+ builder: ^strings.Builder,
+ remove_pointers: bool,
+) {
for elem, i in array {
build_string(elem, builder, remove_pointers)
}
}
-build_string_node :: proc(node: ^ast.Node, builder: ^strings.Builder, remove_pointers: bool) {
-
+build_string_node :: proc(
+ node: ^ast.Node,
+ builder: ^strings.Builder,
+ remove_pointers: bool,
+) {
+
using ast
-
+
if node == nil {
return
}
-
+
#partial switch n in node.derived {
case ^Bad_Expr:
case ^Ident:
if strings.contains(n.name, "/") {
- strings.write_string(builder, path.base(n.name, false, context.temp_allocator))
+ strings.write_string(
+ builder,
+ path.base(n.name, false, context.temp_allocator),
+ )
} else {
strings.write_string(builder, n.name)
}
@@ -760,7 +828,7 @@ build_string_node :: proc(node: ^ast.Node, builder: ^strings.Builder, remove_poi
strings.write_string(builder, n.tok.text)
case ^Undef:
case ^Basic_Lit:
- strings.write_string(builder, n.tok.text)
+ strings.write_string(builder, n.tok.text)
case ^Basic_Directive:
strings.write_string(builder, n.name)
case ^Implicit_Selector_Expr:
@@ -850,7 +918,7 @@ build_string_node :: proc(node: ^ast.Node, builder: ^strings.Builder, remove_poi
} else {
build_string(n.type, builder, remove_pointers)
}
-
+
build_string(n.default_value, builder, remove_pointers)
case ^Field_List:
for field, i in n.list {
@@ -919,7 +987,11 @@ build_string_node :: proc(node: ^ast.Node, builder: ^strings.Builder, remove_poi
}
}
-repeat :: proc(value: string, count: int, allocator := context.allocator) -> string {
+repeat :: proc(
+ value: string,
+ count: int,
+ allocator := context.allocator,
+) -> string {
if count == 0 {
return ""
}
diff --git a/src/common/config.odin b/src/common/config.odin
index b4114c0..62e80cc 100644
--- a/src/common/config.odin
+++ b/src/common/config.odin
@@ -11,7 +11,7 @@ Config :: struct {
enable_format: bool,
enable_hover: bool,
enable_document_symbols: bool,
- enable_semantic_tokens: bool,
+ enable_semantic_tokens: bool,
enable_inlay_hints: bool,
enable_procedure_context: bool,
enable_snippets: bool,
@@ -24,4 +24,4 @@ Config :: struct {
checker_args: string,
}
-config: Config; \ No newline at end of file
+config: Config
diff --git a/src/common/fuzzy.odin b/src/common/fuzzy.odin
index 04bb0ad..c425051 100644
--- a/src/common/fuzzy.odin
+++ b/src/common/fuzzy.odin
@@ -52,6 +52,7 @@ FuzzyMatcher :: struct {
word_role: [max_word]FuzzyCharRole,
}
+//odinfmt: disable
char_roles: []u8 = {
// clang-format off
// Curr= Empty Lower Upper Separ
@@ -76,6 +77,8 @@ char_types: []u8 = {
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
}
+//odinfmt: enable
+
make_fuzzy_matcher :: proc(pattern: string, allocator := context.temp_allocator) -> ^FuzzyMatcher {
matcher := new(FuzzyMatcher, allocator)
diff --git a/src/common/position.odin b/src/common/position.odin
index e8c5ff2..5d2ae4f 100644
--- a/src/common/position.odin
+++ b/src/common/position.odin
@@ -33,7 +33,13 @@ AbsoluteRange :: struct {
AbsolutePosition :: int
-get_absolute_position :: proc(position: Position, document_text: []u8) -> (AbsolutePosition, bool) {
+get_absolute_position :: proc(
+ position: Position,
+ document_text: []u8,
+) -> (
+ AbsolutePosition,
+ bool,
+) {
absolute: AbsolutePosition
if len(document_text) == 0 {
@@ -45,16 +51,31 @@ get_absolute_position :: proc(position: Position, document_text: []u8) -> (Absol
index := 1
last := document_text[0]
- if !get_index_at_line(&index, &line_count, &last, document_text, position.line) {
+ if !get_index_at_line(
+ &index,
+ &line_count,
+ &last,
+ document_text,
+ position.line,
+ ) {
return absolute, false
}
- absolute = index + get_character_offset_u16_to_u8(position.character, document_text[index:])
+ absolute =
+ index +
+ get_character_offset_u16_to_u8(
+ position.character,
+ document_text[index:],
+ )
return absolute, true
}
-get_relative_token_position :: proc(offset: int, document_text: []u8, current_start: int) -> Position {
+get_relative_token_position :: proc(
+ offset: int,
+ document_text: []u8,
+ current_start: int,
+) -> Position {
start_index := current_start
data := document_text[start_index:]
@@ -66,10 +87,10 @@ get_relative_token_position :: proc(offset: int, document_text: []u8, current_st
for i + start_index < offset {
r, w := utf8.decode_rune(data[i:])
- if r == '\n' { //\r?
+ if r == '\n' { //\r?
position.character = 0
position.line += 1
- i += 1
+ i += 1
} else if w == 0 {
return position
} else {
@@ -95,7 +116,10 @@ get_token_range :: proc(node: ast.Node, document_text: string) -> Range {
go_backwards_to_endline :: proc(offset: int, document_text: []u8) -> int {
index := offset
- for index > 0 && document_text[index] != '\n' && document_text[index] != '\r' {
+ for
+ index > 0 &&
+ document_text[index] != '\n' &&
+ document_text[index] != '\r' {
index -= 1
}
@@ -112,34 +136,60 @@ get_token_range :: proc(node: ast.Node, document_text: string) -> Range {
offset := go_backwards_to_endline(pos_offset, transmute([]u8)document_text)
range.start.line = node.pos.line - 1
- range.start.character = get_character_offset_u8_to_u16(node.pos.column - 1, transmute([]u8)document_text[offset:])
+ range.start.character = get_character_offset_u8_to_u16(
+ node.pos.column - 1,
+ transmute([]u8)document_text[offset:],
+ )
- offset = go_backwards_to_endline(end_offset - 1, transmute([]u8)document_text)
+ offset = go_backwards_to_endline(
+ end_offset - 1,
+ transmute([]u8)document_text,
+ )
range.end.line = node.end.line - 1
- range.end.character = get_character_offset_u8_to_u16(node.end.column - 1, transmute([]u8)document_text[offset:])
+ range.end.character = get_character_offset_u8_to_u16(
+ node.end.column - 1,
+ transmute([]u8)document_text[offset:],
+ )
return range
}
-get_absolute_range :: proc(range: Range, document_text: []u8) -> (AbsoluteRange, bool) {
+get_absolute_range :: proc(
+ range: Range,
+ document_text: []u8,
+) -> (
+ AbsoluteRange,
+ bool,
+) {
absolute: AbsoluteRange
if len(document_text) == 0 {
absolute.start = 0
- absolute.end = 0
+ absolute.end = 0
return absolute, true
}
line_count := 0
- index := 1
- last := document_text[0]
+ index := 1
+ last := document_text[0]
- if !get_index_at_line(&index, &line_count, &last, document_text, range.start.line) {
+ if !get_index_at_line(
+ &index,
+ &line_count,
+ &last,
+ document_text,
+ range.start.line,
+ ) {
return absolute, false
}
- absolute.start = index + get_character_offset_u16_to_u8(range.start.character, document_text[index:])
+ absolute.start =
+ index +
+ get_character_offset_u16_to_u8(
+ range.start.character,
+ document_text[index:],
+ )
//if the last line was indexed at zero we have to move it back to index 1.
//This happens when line = 0
@@ -147,16 +197,33 @@ get_absolute_range :: proc(range: Range, document_text: []u8) -> (AbsoluteRange,
index = 1
}
- if !get_index_at_line(&index, &line_count, &last, document_text, range.end.line) {
+ if !get_index_at_line(
+ &index,
+ &line_count,
+ &last,
+ document_text,
+ range.end.line,
+ ) {
return absolute, false
}
- absolute.end = index + get_character_offset_u16_to_u8(range.end.character, document_text[index:])
+ absolute.end =
+ index +
+ get_character_offset_u16_to_u8(
+ range.end.character,
+ document_text[index:],
+ )
return absolute, true
}
-get_index_at_line :: proc(current_index: ^int, current_line: ^int, last: ^u8, document_text: []u8, end_line: int) -> bool {
+get_index_at_line :: proc(
+ current_index: ^int,
+ current_line: ^int,
+ last: ^u8,
+ document_text: []u8,
+ end_line: int,
+) -> bool {
if end_line == 0 {
current_index^ = 0
return true
@@ -193,8 +260,11 @@ get_index_at_line :: proc(current_index: ^int, current_line: ^int, last: ^u8, do
return false
}
-get_character_offset_u16_to_u8 :: proc(character_offset: int, document_text: []u8) -> int {
- utf8_idx := 0
+get_character_offset_u16_to_u8 :: proc(
+ character_offset: int,
+ document_text: []u8,
+) -> int {
+ utf8_idx := 0
utf16_idx := 0
for utf16_idx < character_offset {
@@ -216,8 +286,11 @@ get_character_offset_u16_to_u8 :: proc(character_offset: int, document_text: []u
return utf8_idx
}
-get_character_offset_u8_to_u16 :: proc(character_offset: int, document_text: []u8) -> int {
- utf8_idx := 0
+get_character_offset_u8_to_u16 :: proc(
+ character_offset: int,
+ document_text: []u8,
+) -> int {
+ utf8_idx := 0
utf16_idx := 0
for utf8_idx < character_offset {
@@ -237,4 +310,4 @@ get_character_offset_u8_to_u16 :: proc(character_offset: int, document_text: []u
}
return utf16_idx
-} \ No newline at end of file
+}
diff --git a/src/common/types.odin b/src/common/types.odin
index 8481f50..e95b86a 100644
--- a/src/common/types.odin
+++ b/src/common/types.odin
@@ -24,4 +24,4 @@ WorkspaceFolder :: struct {
}
parser_warning_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) {
-} \ No newline at end of file
+}
diff --git a/src/common/uri.odin b/src/common/uri.odin
index 4dbed0f..0e2c705 100644
--- a/src/common/uri.odin
+++ b/src/common/uri.odin
@@ -14,7 +14,6 @@ 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: mem.Allocator) -> (Uri, bool) {
uri: Uri
@@ -57,7 +56,10 @@ create_uri :: proc(path: string, allocator: mem.Allocator) -> Uri {
strings.write_string(&builder, "file://")
}
- strings.write_string(&builder, encode_percent(path_forward, context.temp_allocator))
+ strings.write_string(
+ &builder,
+ encode_percent(path_forward, context.temp_allocator),
+ )
uri: Uri
@@ -89,8 +91,13 @@ encode_percent :: proc(value: string, allocator: mem.Allocator) -> string {
if r > 127 || r == ':' {
for i := 0; i < w; i += 1 {
- strings.write_string(&builder, strings.concatenate({"%", fmt.tprintf("%X", data[index + i])},
- context.temp_allocator))
+ strings.write_string(
+ &builder,
+ strings.concatenate(
+ {"%", fmt.tprintf("%X", data[index + i])},
+ context.temp_allocator,
+ ),
+ )
}
} else {
strings.write_byte(&builder, data[index])
@@ -118,7 +125,13 @@ starts_with :: proc(value: string, starts_with: string) -> bool {
}
@(private)
-decode_percent :: proc(value: string, allocator: mem.Allocator) -> (string, bool) {
+decode_percent :: proc(
+ value: string,
+ allocator: mem.Allocator,
+) -> (
+ string,
+ bool,
+) {
builder := strings.builder_make(allocator)
for i := 0; i < len(value); i += 1 {
diff --git a/src/common/util.odin b/src/common/util.odin
index aa113ae..0466b6e 100644
--- a/src/common/util.odin
+++ b/src/common/util.odin
@@ -22,14 +22,22 @@ lookup_in_path :: proc(name: string) -> (string, bool) {
for directory in strings.split_iterator(&path, delimiter) {
when ODIN_OS == .Windows {
- name := filepath.join(elems = {directory, fmt.tprintf("%v.exe", name)}, allocator = context.temp_allocator)
+ name := filepath.join(
+ elems = {directory, fmt.tprintf("%v.exe", name)},
+ allocator = context.temp_allocator,
+ )
if os.exists(name) {
return name, true
}
} else {
- name := filepath.join(elems = {directory, name}, allocator = context.temp_allocator)
+ name := filepath.join(
+ elems = {directory, name},
+ allocator = context.temp_allocator,
+ )
if os.exists(name) {
- if info, err := os.stat(name, context.temp_allocator); err == os.ERROR_NONE && (File_Mode_User_Executable & info.mode) != 0 {
+ if info, err := os.stat(name, context.temp_allocator);
+ err == os.ERROR_NONE &&
+ (File_Mode_User_Executable & info.mode) != 0 {
return name, true
}
}
@@ -42,30 +50,39 @@ lookup_in_path :: proc(name: string) -> (string, bool) {
when ODIN_OS == .Darwin || ODIN_OS == .Linux {
FILE :: struct {}
- run_executable :: proc(command: string, stdout: ^[]byte) -> (u32, bool, []byte) {
- fp := popen(strings.clone_to_cstring(command, context.temp_allocator), "r")
+ run_executable :: proc(
+ command: string,
+ stdout: ^[]byte,
+ ) -> (
+ u32,
+ bool,
+ []byte,
+ ) {
+ fp := popen(
+ strings.clone_to_cstring(command, context.temp_allocator),
+ "r",
+ )
if fp == nil {
return 0, false, stdout[0:]
}
defer pclose(fp)
-
+
read_buffer: [50]byte
index: int
-
+
for fgets(&read_buffer[0], size_of(read_buffer), fp) != nil {
read := bytes.index_byte(read_buffer[:], 0)
defer index += cast(int)read
-
+
if read > 0 && index + cast(int)read <= len(stdout) {
mem.copy(&stdout[index], &read_buffer[0], cast(int)read)
}
}
-
-
-
+
+
return 0, true, stdout[0:index]
}
-
+
foreign libc
{
popen :: proc(command: cstring, type: cstring) -> ^FILE ---
diff --git a/src/common/util_windows.odin b/src/common/util_windows.odin
index 23a58cd..59a9bcf 100644
--- a/src/common/util_windows.odin
+++ b/src/common/util_windows.odin
@@ -27,19 +27,34 @@ foreign kernel32 {
) -> u32 ---
}
-get_case_sensitive_path :: proc(path: string, allocator := context.temp_allocator) -> string {
+get_case_sensitive_path :: proc(
+ path: string,
+ allocator := context.temp_allocator,
+) -> string {
wide := win32.utf8_to_utf16(path)
- file := win32.CreateFileW(&wide[0], 0, win32.FILE_SHARE_READ, nil, win32.OPEN_EXISTING, win32.FILE_FLAG_BACKUP_SEMANTICS, nil)
-
- if(file == win32.INVALID_HANDLE)
- {
+ file := win32.CreateFileW(
+ &wide[0],
+ 0,
+ win32.FILE_SHARE_READ,
+ nil,
+ win32.OPEN_EXISTING,
+ win32.FILE_FLAG_BACKUP_SEMANTICS,
+ nil,
+ )
+
+ if (file == win32.INVALID_HANDLE) {
log_last_error()
- return "";
- }
+ return ""
+ }
buffer := make([]u16, 512, context.temp_allocator)
- ret := win32.GetFinalPathNameByHandleW(file, &buffer[0], cast(u32)len(buffer), 0)
+ ret := win32.GetFinalPathNameByHandleW(
+ file,
+ &buffer[0],
+ cast(u32)len(buffer),
+ 0,
+ )
res, _ := win32.utf16_to_utf8(buffer[4:], allocator)
@@ -56,21 +71,29 @@ log_last_error :: proc() {
error_string := cstring(&err_text[0])
if (format_message_a(
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- nil,
- err,
- (1 << 10) | 0,
- error_string,
- len(err_text) - 1,
- nil,
- ) != 0) {
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ nil,
+ err,
+ (1 << 10) | 0,
+ error_string,
+ len(err_text) - 1,
+ nil,
+ ) !=
+ 0) {
log.error(error_string)
}
}
-run_executable :: proc(command: string, stdout: ^[]byte) -> (u32, bool, []byte) {
- stdout_read: win32.HANDLE
+run_executable :: proc(
+ command: string,
+ stdout: ^[]byte,
+) -> (
+ u32,
+ bool,
+ []byte,
+) {
+ stdout_read: win32.HANDLE
stdout_write: win32.HANDLE
attributes: win32.SECURITY_ATTRIBUTES
@@ -95,21 +118,38 @@ run_executable :: proc(command: string, stdout: ^[]byte) -> (u32, bool, []byte)
startup_info.hStdOutput = stdout_write
startup_info.dwFlags |= win32.STARTF_USESTDHANDLES
- if !win32.CreateProcessW(nil, &win32.utf8_to_utf16(command)[0], nil, nil, true, 0, nil, nil, &startup_info, &process_info) {
+ if !win32.CreateProcessW(
+ nil,
+ &win32.utf8_to_utf16(command)[0],
+ nil,
+ nil,
+ true,
+ 0,
+ nil,
+ nil,
+ &startup_info,
+ &process_info,
+ ) {
return 0, false, stdout[0:]
}
win32.CloseHandle(stdout_write)
index: int
- read: u32
+ read: u32
read_buffer: [50]byte
success: win32.BOOL = true
for success {
- success = win32.ReadFile(stdout_read, &read_buffer[0], len(read_buffer), &read, nil)
+ success = win32.ReadFile(
+ stdout_read,
+ &read_buffer[0],
+ len(read_buffer),
+ &read,
+ nil,
+ )
if read > 0 && index + cast(int)read <= len(stdout) {
mem.copy(&stdout[index], &read_buffer[0], cast(int)read)
@@ -135,4 +175,4 @@ run_executable :: proc(command: string, stdout: ^[]byte) -> (u32, bool, []byte)
import "core:mem/virtual"
Growing_Arena :: virtual.Growing_Arena
-growing_arena_allocator :: virtual.growing_arena_allocator \ No newline at end of file
+growing_arena_allocator :: virtual.growing_arena_allocator
diff --git a/src/dump_windows.odin b/src/dump_windows.odin
index 96908fd..d44aaa3 100644
--- a/src/dump_windows.odin
+++ b/src/dump_windows.odin
@@ -19,60 +19,71 @@ set_stacktrace :: proc() {
pdb.SetUnhandledExceptionFilter(dump_stack_trace_on_exception_logger)
}
-print_source_code_location_builder :: proc (using scl: runtime.Source_Code_Location) -> string {
- using runtime
+print_source_code_location_builder :: proc(
+ using scl: runtime.Source_Code_Location,
+) -> string {
+ using runtime
builder := strings.builder_make()
- strings.write_string(&builder, file_path)
- when ODIN_ERROR_POS_STYLE == .Unix {
- strings.write_string(&builder, ':')
+ strings.write_string(&builder, file_path)
+ when ODIN_ERROR_POS_STYLE == .Unix {
+ strings.write_string(&builder, ':')
strings.write_i64(&builder, cast(i64)line)
strings.write_string(&builder, ':')
strings.write_i64(&builder, cast(i64)column)
strings.write_string(&builder, ':')
- } else {
- strings.write_string(&builder, "(")
+ } else {
+ strings.write_string(&builder, "(")
strings.write_i64(&builder, cast(i64)line)
- strings.write_string(&builder,":")
+ strings.write_string(&builder, ":")
strings.write_i64(&builder, cast(i64)column)
strings.write_string(&builder, ")")
- }
- strings.write_string(&builder,procedure)
- strings.write_string(&builder,"()\n")
+ }
+ strings.write_string(&builder, procedure)
+ strings.write_string(&builder, "()\n")
return strings.to_string(builder)
}
-dump_stack_trace_on_exception_logger :: proc "stdcall" (ExceptionInfo: ^windows.EXCEPTION_POINTERS) -> windows.LONG {
+dump_stack_trace_on_exception_logger :: proc "stdcall" (
+ ExceptionInfo: ^windows.EXCEPTION_POINTERS,
+) -> windows.LONG {
using pdb
- context = runtime.default_context() // TODO: use a more efficient one-off allocators
+ context = runtime.default_context() // TODO: use a more efficient one-off allocators
context.logger = logger
- builder := strings.builder_make()
-
- sync.guard(&_dumpStackTrackMutex)
-
- if ExceptionInfo.ExceptionRecord != nil {
- strings.write_string(&builder, fmt.tprintf("%v, Flags: 0x %v", ExceptionInfo.ExceptionRecord.ExceptionCode, ExceptionInfo.ExceptionRecord.ExceptionFlags))
- }
-
- ctxt := cast(^CONTEXT)ExceptionInfo.ContextRecord
- traceBuf : [64]StackFrame
- traceCount := capture_stack_trace_from_context(ctxt, traceBuf[:])
- strings.write_string(&builder, " Stacktrace:")
- strings.write_uint(&builder, traceCount)
- strings.write_string(&builder, "\n")
- srcCodeLocs : RingBuffer(runtime.Source_Code_Location)
- init_rb(&srcCodeLocs, 64)
- parse_stack_trace(traceBuf[:traceCount], true, &srcCodeLocs)
- for i in 0..<srcCodeLocs.len {
- scl := get_rb(&srcCodeLocs, i)
- strings.write_string(&builder, print_source_code_location_builder(scl))
- }
-
- log.error(strings.to_string(builder))
+ builder := strings.builder_make()
- return windows.EXCEPTION_CONTINUE_SEARCH
+ sync.guard(&_dumpStackTrackMutex)
+
+ if ExceptionInfo.ExceptionRecord != nil {
+ strings.write_string(
+ &builder,
+ fmt.tprintf(
+ "%v, Flags: 0x %v",
+ ExceptionInfo.ExceptionRecord.ExceptionCode,
+ ExceptionInfo.ExceptionRecord.ExceptionFlags,
+ ),
+ )
+ }
+
+ ctxt := cast(^CONTEXT)ExceptionInfo.ContextRecord
+ traceBuf: [64]StackFrame
+ traceCount := capture_stack_trace_from_context(ctxt, traceBuf[:])
+ strings.write_string(&builder, " Stacktrace:")
+ strings.write_uint(&builder, traceCount)
+ strings.write_string(&builder, "\n")
+ srcCodeLocs: RingBuffer(runtime.Source_Code_Location)
+ init_rb(&srcCodeLocs, 64)
+ parse_stack_trace(traceBuf[:traceCount], true, &srcCodeLocs)
+ for i in 0 ..< srcCodeLocs.len {
+ scl := get_rb(&srcCodeLocs, i)
+ strings.write_string(&builder, print_source_code_location_builder(scl))
+ }
+
+ log.error(strings.to_string(builder))
+
+ return windows.EXCEPTION_CONTINUE_SEARCH
}
diff --git a/src/main.odin b/src/main.odin
index ac9cf72..b685147 100644
--- a/src/main.odin
+++ b/src/main.odin
@@ -18,13 +18,13 @@ import "shared:server"
import "shared:common"
os_read :: proc(handle: rawptr, data: []byte) -> (int, int) {
- ptr := cast(^os.Handle)handle
+ ptr := cast(^os.Handle)handle
a, b := os.read(ptr^, data)
return a, cast(int)b
}
os_write :: proc(handle: rawptr, data: []byte) -> (int, int) {
- ptr := cast(^os.Handle)handle
+ ptr := cast(^os.Handle)handle
a, b := os.write(ptr^, data)
return a, cast(int)b
}
@@ -56,9 +56,12 @@ run :: proc(reader: ^server.Reader, writer: ^server.Writer) {
server.requests = make([dynamic]server.Request, context.allocator)
server.deletings = make([dynamic]server.Request, context.allocator)
- request_thread = thread.create_and_start_with_data(cast(rawptr)&request_thread_data, server.thread_request_main)
+ request_thread = thread.create_and_start_with_data(
+ cast(rawptr)&request_thread_data,
+ server.thread_request_main,
+ )
- server.setup_index();
+ server.setup_index()
for common.config.running {
if common.config.verbose {
@@ -95,7 +98,6 @@ end :: proc() {
}
-
main :: proc() {
reader := server.make_reader(os_read, cast(rawptr)&os.stdin)
@@ -117,9 +119,9 @@ main :: proc() {
}
when ODIN_OS == .Darwin {
- init_global_temporary_allocator(mem.Megabyte*100)
+ init_global_temporary_allocator(mem.Megabyte * 100)
} else {
- init_global_temporary_allocator(mem.Megabyte*100)
+ init_global_temporary_allocator(mem.Megabyte * 100)
//Gives weird allocation errors
//growing_arena: common.Growing_Arena
//context.temp_allocator = common.growing_arena_allocator(&growing_arena)
diff --git a/src/odin/format/format.odin b/src/odin/format/format.odin
index eee51b3..be6bd87 100644
--- a/src/odin/format/format.odin
+++ b/src/odin/format/format.odin
@@ -4,7 +4,7 @@ import "shared:odin/printer"
import "core:odin/parser"
import "core:odin/ast"
import "core:encoding/json"
-import "core:os"
+import "core:os"
import "core:path/filepath"
import "core:fmt"
@@ -34,7 +34,10 @@ find_config_file_or_default :: proc(path: string) -> printer.Config {
}
}
} else {
- new_path := filepath.join(elems = {path, ".."}, allocator = context.temp_allocator)
+ new_path := filepath.join(
+ elems = {path, ".."},
+ allocator = context.temp_allocator,
+ )
//Currently the filepath implementation seems to stop at the root level, this might not be the best solution.
if new_path == path {
return default_style
@@ -49,7 +52,16 @@ find_config_file_or_default :: proc(path: string) -> printer.Config {
return config
}
-format :: proc(filepath: string, source: string, config: printer.Config, parser_flags := parser.Flags{.Optional_Semicolons}, allocator := context.allocator) -> (string, bool) {
+format :: proc(
+ filepath: string,
+ source: string,
+ config: printer.Config,
+ parser_flags := parser.Flags{.Optional_Semicolons},
+ allocator := context.allocator,
+) -> (
+ string,
+ bool,
+) {
config := config
pkg := ast.Package {
@@ -57,8 +69,8 @@ format :: proc(filepath: string, source: string, config: printer.Config, parser_
}
file := ast.File {
- pkg = &pkg,
- src = source,
+ pkg = &pkg,
+ src = source,
fullpath = filepath,
}
@@ -69,7 +81,7 @@ format :: proc(filepath: string, source: string, config: printer.Config, parser_
ok := parser.parse_file(&p, &file)
- if !ok || file.syntax_error_count > 0 {
+ if !ok || file.syntax_error_count > 0 {
return {}, false
}
diff --git a/src/odin/printer/document.odin b/src/odin/printer/document.odin
index c2e59ea..3f3ed00 100644
--- a/src/odin/printer/document.odin
+++ b/src/odin/printer/document.odin
@@ -17,9 +17,7 @@ Document :: union {
Document_Line_Suffix,
}
-Document_Nil :: struct {
-
-}
+Document_Nil :: struct {}
Document_Newline :: struct {
amount: int,
@@ -35,8 +33,8 @@ Document_Line_Suffix :: struct {
Document_Nest :: struct {
alignment: int, //Is only used when hanging a document
- negate: bool,
- document: ^Document,
+ negate: bool,
+ document: ^Document,
}
Document_Nest_If_Break :: struct {
@@ -45,7 +43,7 @@ Document_Nest_If_Break :: struct {
}
Document_Break :: struct {
- value: string,
+ value: string,
newline: bool,
}
@@ -55,8 +53,8 @@ Document_If_Break :: struct {
Document_Group :: struct {
document: ^Document,
- mode: Document_Group_Mode,
- options: Document_Group_Options,
+ mode: Document_Group_Mode,
+ options: Document_Group_Options,
}
Document_Cons :: struct {
@@ -77,12 +75,11 @@ Document_Group_Options :: struct {
id: string,
}
-Document_Break_Parent :: struct {
-}
+Document_Break_Parent :: struct {}
empty :: proc(allocator := context.allocator) -> ^Document {
document := new(Document, allocator)
- document^ = Document_Nil {}
+ document^ = Document_Nil{}
return document
}
@@ -102,7 +99,10 @@ newline :: proc(amount: int, allocator := context.allocator) -> ^Document {
return document
}
-nest :: proc(nested_document: ^Document, allocator := context.allocator) -> ^Document {
+nest :: proc(
+ nested_document: ^Document,
+ allocator := context.allocator,
+) -> ^Document {
document := new(Document, allocator)
document^ = Document_Nest {
document = nested_document,
@@ -110,16 +110,23 @@ nest :: proc(nested_document: ^Document, allocator := context.allocator) -> ^Doc
return document
}
-escape_nest :: proc(nested_document: ^Document, allocator := context.allocator) -> ^Document {
+escape_nest :: proc(
+ nested_document: ^Document,
+ allocator := context.allocator,
+) -> ^Document {
document := new(Document, allocator)
document^ = Document_Nest {
document = nested_document,
- negate = true,
+ negate = true,
}
return document
}
-nest_if_break :: proc(nested_document: ^Document, group_id := "", allocator := context.allocator) -> ^Document {
+nest_if_break :: proc(
+ nested_document: ^Document,
+ group_id := "",
+ allocator := context.allocator,
+) -> ^Document {
document := new(Document, allocator)
document^ = Document_Nest_If_Break {
document = nested_document,
@@ -128,35 +135,49 @@ nest_if_break :: proc(nested_document: ^Document, group_id := "", allocator := c
return document
}
-hang :: proc(align: int, hanged_document: ^Document, allocator := context.allocator) -> ^Document {
+hang :: proc(
+ align: int,
+ hanged_document: ^Document,
+ allocator := context.allocator,
+) -> ^Document {
document := new(Document, allocator)
document^ = Document_Nest {
alignment = align,
- document = hanged_document,
+ document = hanged_document,
}
return document
}
-enforce_fit :: proc(fitted_document: ^Document, allocator := context.allocator) -> ^Document {
+enforce_fit :: proc(
+ fitted_document: ^Document,
+ allocator := context.allocator,
+) -> ^Document {
document := new(Document, allocator)
- document^ = Document_Group {
+ document^ = Document_Group {
document = fitted_document,
- mode = .Fit,
+ mode = .Fit,
}
return document
}
-enforce_break :: proc(fitted_document: ^Document, options := Document_Group_Options{}, allocator := context.allocator) -> ^Document {
+enforce_break :: proc(
+ fitted_document: ^Document,
+ options := Document_Group_Options{},
+ allocator := context.allocator,
+) -> ^Document {
document := new(Document, allocator)
- document^ = Document_Group {
+ document^ = Document_Group {
document = fitted_document,
- mode = .Break,
- options = options,
+ mode = .Break,
+ options = options,
}
return document
}
-align :: proc(aligned_document: ^Document, allocator := context.allocator) -> ^Document {
+align :: proc(
+ aligned_document: ^Document,
+ allocator := context.allocator,
+) -> ^Document {
document := new(Document, allocator)
document^ = Document_Align {
document = aligned_document,
@@ -172,10 +193,14 @@ if_break :: proc(value: string, allocator := context.allocator) -> ^Document {
return document
}
-break_with :: proc(value: string, newline := true, allocator := context.allocator) -> ^Document {
+break_with :: proc(
+ value: string,
+ newline := true,
+ allocator := context.allocator,
+) -> ^Document {
document := new(Document, allocator)
document^ = Document_Break {
- value = value,
+ value = value,
newline = newline,
}
return document
@@ -183,12 +208,14 @@ break_with :: proc(value: string, newline := true, allocator := context.allocato
break_parent :: proc(allocator := context.allocator) -> ^Document {
document := new(Document, allocator)
- document^ = Document_Break_Parent {
- }
+ document^ = Document_Break_Parent{}
return document
}
-line_suffix :: proc(value: string, allocator := context.allocator) -> ^Document {
+line_suffix :: proc(
+ value: string,
+ allocator := context.allocator,
+) -> ^Document {
document := new(Document, allocator)
document^ = Document_Line_Suffix {
value = value,
@@ -204,11 +231,15 @@ break_with_no_newline :: proc(allocator := context.allocator) -> ^Document {
return break_with(" ", false, allocator)
}
-group :: proc(grouped_document: ^Document, options := Document_Group_Options{}, allocator := context.allocator) -> ^Document {
+group :: proc(
+ grouped_document: ^Document,
+ options := Document_Group_Options{},
+ allocator := context.allocator,
+) -> ^Document {
document := new(Document, allocator)
document^ = Document_Group {
document = grouped_document,
- options = options,
+ options = options,
}
return document
}
@@ -220,7 +251,7 @@ cons :: proc(elems: ..^Document, allocator := context.allocator) -> ^Document {
for elem in elems {
append(&elements, elem)
}
-
+
c := Document_Cons {
elements = elements[:],
}
@@ -228,7 +259,11 @@ cons :: proc(elems: ..^Document, allocator := context.allocator) -> ^Document {
return document
}
-cons_with_opl :: proc(lhs: ^Document, rhs: ^Document, allocator := context.allocator) -> ^Document {
+cons_with_opl :: proc(
+ lhs: ^Document,
+ rhs: ^Document,
+ allocator := context.allocator,
+) -> ^Document {
if _, ok := lhs.(Document_Nil); ok {
return rhs
}
@@ -237,10 +272,17 @@ cons_with_opl :: proc(lhs: ^Document, rhs: ^Document, allocator := context.alloc
return lhs
}
- return cons(elems = {lhs, break_with_space(allocator), rhs}, allocator = allocator)
+ return cons(
+ elems = {lhs, break_with_space(allocator), rhs},
+ allocator = allocator,
+ )
}
-cons_with_nopl:: proc(lhs: ^Document, rhs: ^Document, allocator := context.allocator) -> ^Document {
+cons_with_nopl :: proc(
+ lhs: ^Document,
+ rhs: ^Document,
+ allocator := context.allocator,
+) -> ^Document {
if _, ok := lhs.(Document_Nil); ok {
return rhs
}
@@ -249,14 +291,17 @@ cons_with_nopl:: proc(lhs: ^Document, rhs: ^Document, allocator := context.alloc
return lhs
}
- return cons(elems = {lhs, break_with_no_newline(allocator), rhs}, allocator = allocator)
+ return cons(
+ elems = {lhs, break_with_no_newline(allocator), rhs},
+ allocator = allocator,
+ )
}
Tuple :: struct {
indentation: int,
- alignment: int,
- mode: Document_Group_Mode,
- document: ^Document,
+ alignment: int,
+ mode: Document_Group_Mode,
+ document: ^Document,
}
list_fits: [dynamic]Tuple
@@ -291,16 +336,48 @@ fits :: proc(width: int, list: ^[dynamic]Tuple) -> bool {
}
case Document_Cons:
for i := len(v.elements) - 1; i >= 0; i -= 1 {
- append(list, Tuple {indentation = data.indentation, mode = data.mode, document = v.elements[i], alignment = data.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation,
+ mode = data.mode,
+ document = v.elements[i],
+ alignment = data.alignment,
+ },
+ )
}
case Document_Align:
- append(list, Tuple {indentation = 0, mode = data.mode, document = v.document, alignment = start_width - width})
+ append(
+ list,
+ Tuple{
+ indentation = 0,
+ mode = data.mode,
+ document = v.document,
+ alignment = start_width - width,
+ },
+ )
case Document_Nest:
if v.alignment != 0 {
- append(list, Tuple {indentation = data.indentation, mode = data.mode, document = v.document, alignment = data.alignment + v.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation,
+ mode = data.mode,
+ document = v.document,
+ alignment = data.alignment + v.alignment,
+ },
+ )
} else {
- append(list, Tuple {indentation = data.indentation + (v.negate ? -1 : 1), mode = data.mode, document = v.document, alignment = data.alignment + v.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation + (v.negate ? -1 : 1),
+ mode = data.mode,
+ document = v.document,
+ alignment = data.alignment + v.alignment,
+ },
+ )
}
case Document_Text:
width -= len(v.value)
@@ -316,19 +393,49 @@ fits :: proc(width: int, list: ^[dynamic]Tuple) -> bool {
}
case Document_Nest_If_Break:
if data.mode == .Break {
- append(list, Tuple {indentation = data.indentation + 1, mode = data.mode, document = v.document, alignment = data.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation + 1,
+ mode = data.mode,
+ document = v.document,
+ alignment = data.alignment,
+ },
+ )
} else {
- append(list, Tuple {indentation = data.indentation, mode = data.mode, document = v.document, alignment = data.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation,
+ mode = data.mode,
+ document = v.document,
+ alignment = data.alignment,
+ },
+ )
}
case Document_Group:
- append(list, Tuple {indentation = data.indentation, mode = (v.mode == .Break ? .Break : data.mode), document = v.document, alignment = data.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation,
+ mode = (v.mode == .Break ? .Break : data.mode),
+ document = v.document,
+ alignment = data.alignment,
+ },
+ )
}
}
return width > 0
}
-format_newline :: proc(indentation: int, alignment: int, consumed: ^int, builder: ^strings.Builder, p: ^Printer) {
+format_newline :: proc(
+ indentation: int,
+ alignment: int,
+ consumed: ^int,
+ builder: ^strings.Builder,
+ p: ^Printer,
+) {
strings.write_string(builder, p.newline)
for i := 0; i < indentation; i += 1 {
strings.write_string(builder, p.indentation)
@@ -340,17 +447,25 @@ format_newline :: proc(indentation: int, alignment: int, consumed: ^int, builder
consumed^ = indentation * p.indentation_width + alignment
}
-flush_line_suffix :: proc(builder: ^strings.Builder, suffix_builder: ^strings.Builder) {
+flush_line_suffix :: proc(
+ builder: ^strings.Builder,
+ suffix_builder: ^strings.Builder,
+) {
strings.write_string(builder, strings.to_string(suffix_builder^))
strings.builder_reset(suffix_builder)
}
-format :: proc(width: int, list: ^[dynamic]Tuple, builder: ^strings.Builder, p: ^Printer) {
+format :: proc(
+ width: int,
+ list: ^[dynamic]Tuple,
+ builder: ^strings.Builder,
+ p: ^Printer,
+) {
assert(list != nil)
assert(builder != nil)
consumed := 0
- recalculate := false;
+ recalculate := false
suffix_builder := strings.builder_make()
@@ -361,8 +476,8 @@ format :: proc(width: int, list: ^[dynamic]Tuple, builder: ^strings.Builder, p:
switch v in data.document {
case Document_Nil:
- case Document_Line_Suffix:
- strings.write_string(&suffix_builder, v.value)
+ case Document_Line_Suffix:
+ strings.write_string(&suffix_builder, v.value)
case Document_Break_Parent:
case Document_Newline:
if v.amount > 0 {
@@ -376,36 +491,75 @@ format :: proc(width: int, list: ^[dynamic]Tuple, builder: ^strings.Builder, p:
for i := 0; i < data.alignment; i += 1 {
strings.write_string(builder, " ")
}
- consumed = data.indentation * p.indentation_width + data.alignment
+ consumed =
+ data.indentation * p.indentation_width + data.alignment
if data.mode == .Flat {
recalculate = true
}
- }
+ }
case Document_Cons:
for i := len(v.elements) - 1; i >= 0; i -= 1 {
- append(list, Tuple {indentation = data.indentation, mode = data.mode, document = v.elements[i], alignment = data.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation,
+ mode = data.mode,
+ document = v.elements[i],
+ alignment = data.alignment,
+ },
+ )
}
case Document_Nest:
if v.alignment != 0 {
- append(list, Tuple {indentation = data.indentation, mode = data.mode, document = v.document, alignment = data.alignment + v.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation,
+ mode = data.mode,
+ document = v.document,
+ alignment = data.alignment + v.alignment,
+ },
+ )
} else {
- append(list, Tuple {indentation = data.indentation + (v.negate ? -1 : 1), mode = data.mode, document = v.document, alignment = data.alignment + v.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation + (v.negate ? -1 : 1),
+ mode = data.mode,
+ document = v.document,
+ alignment = data.alignment + v.alignment,
+ },
+ )
}
case Document_Align:
- append(list, Tuple {indentation = 0, mode = data.mode, document = v.document, alignment = consumed})
+ append(
+ list,
+ Tuple{
+ indentation = 0,
+ mode = data.mode,
+ document = v.document,
+ alignment = consumed,
+ },
+ )
case Document_Text:
strings.write_string(builder, v.value)
consumed += len(v.value)
case Document_Break:
if data.mode == .Break && v.newline {
flush_line_suffix(builder, &suffix_builder)
- format_newline(data.indentation, data.alignment, &consumed, builder, p)
+ format_newline(
+ data.indentation,
+ data.alignment,
+ &consumed,
+ builder,
+ p,
+ )
} else {
strings.write_string(builder, v.value)
consumed += len(v.value)
- }
+ }
case Document_If_Break:
if data.mode == .Break {
strings.write_string(builder, v.value)
@@ -414,41 +568,103 @@ format :: proc(width: int, list: ^[dynamic]Tuple, builder: ^strings.Builder, p:
case Document_Nest_If_Break:
mode := v.group_id != "" ? p.group_modes[v.group_id] : data.mode
if mode == .Break {
- append(list, Tuple {indentation = data.indentation + 1, mode = data.mode, document = v.document, alignment = data.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation + 1,
+ mode = data.mode,
+ document = v.document,
+ alignment = data.alignment,
+ },
+ )
} else {
- append(list, Tuple {indentation = data.indentation, mode = data.mode, document = v.document, alignment = data.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation,
+ mode = data.mode,
+ document = v.document,
+ alignment = data.alignment,
+ },
+ )
}
case Document_Group:
if data.mode == .Flat && !recalculate {
- append(list, Tuple {indentation = data.indentation, mode = v.mode, document = v.document, alignment = data.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation,
+ mode = v.mode,
+ document = v.document,
+ alignment = data.alignment,
+ },
+ )
break
}
clear(&list_fits)
-
+
for element in list {
append(&list_fits, element)
}
- append(&list_fits, Tuple {indentation = data.indentation, mode = .Fit, document = v.document, alignment = data.alignment})
+ append(
+ &list_fits,
+ Tuple{
+ indentation = data.indentation,
+ mode = .Fit,
+ document = v.document,
+ alignment = data.alignment,
+ },
+ )
recalculate = false
if data.mode == .Fit {
- append(list, Tuple {indentation = data.indentation, mode = .Fit, document = v.document, alignment = data.alignment})
- }
- else if fits(width-consumed, &list_fits) && v.mode != .Break {
- append(list, Tuple {indentation = data.indentation, mode = .Flat, document = v.document, alignment = data.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation,
+ mode = .Fit,
+ document = v.document,
+ alignment = data.alignment,
+ },
+ )
+ } else if fits(width - consumed, &list_fits) && v.mode != .Break {
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation,
+ mode = .Flat,
+ document = v.document,
+ alignment = data.alignment,
+ },
+ )
} else {
if v.mode == .Fit {
- append(list, Tuple {indentation = data.indentation, mode = .Fit, document = v.document, alignment = data.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation,
+ mode = .Fit,
+ document = v.document,
+ alignment = data.alignment,
+ },
+ )
} else {
- append(list, Tuple {indentation = data.indentation, mode = .Break, document = v.document, alignment = data.alignment})
+ append(
+ list,
+ Tuple{
+ indentation = data.indentation,
+ mode = .Break,
+ document = v.document,
+ alignment = data.alignment,
+ },
+ )
}
}
- p.group_modes[v.options.id] = list[len(list)-1].mode
+ p.group_modes[v.options.id] = list[len(list) - 1].mode
}
}
}
-
diff --git a/src/odin/printer/printer.odin b/src/odin/printer/printer.odin
index 7c444a1..b033d68 100644
--- a/src/odin/printer/printer.odin
+++ b/src/odin/printer/printer.odin
@@ -30,20 +30,20 @@ Printer :: struct {
}
Disabled_Info :: struct {
- text: string,
+ text: string,
end_line: int,
}
Config :: struct {
- character_width: int,
- spaces: int, //Spaces per indentation
- newline_limit: int, //The limit of newlines between statements and declarations.
- tabs: bool, //Enable or disable tabs
- tabs_width: int,
- convert_do: bool, //Convert all do statements to brace blocks
- brace_style: Brace_Style,
- indent_cases: bool,
- newline_style: Newline_Style,
+ character_width: int,
+ spaces: int, //Spaces per indentation
+ newline_limit: int, //The limit of newlines between statements and declarations.
+ tabs: bool, //Enable or disable tabs
+ tabs_width: int,
+ convert_do: bool, //Convert all do statements to brace blocks
+ brace_style: Brace_Style,
+ indent_cases: bool,
+ newline_style: Newline_Style,
}
Brace_Style :: enum {
@@ -81,41 +81,41 @@ Line_Suffix_Option :: enum {
}
-when ODIN_OS == .Windows {
+when ODIN_OS == .Windows {
default_style := Config {
- spaces = 4,
- newline_limit = 2,
- convert_do = false,
- tabs = true,
- tabs_width = 4,
- brace_style = ._1TBS,
- indent_cases = false,
- newline_style = .CRLF,
- character_width = 100,
+ spaces = 4,
+ newline_limit = 2,
+ convert_do = false,
+ tabs = true,
+ tabs_width = 4,
+ brace_style = ._1TBS,
+ indent_cases = false,
+ newline_style = .CRLF,
+ character_width = 100,
}
} else {
default_style := Config {
- spaces = 4,
- newline_limit = 2,
- convert_do = false,
- tabs = true,
- tabs_width = 4,
- brace_style = ._1TBS,
- indent_cases = false,
- newline_style = .LF,
- character_width = 100,
+ spaces = 4,
+ newline_limit = 2,
+ convert_do = false,
+ tabs = true,
+ tabs_width = 4,
+ brace_style = ._1TBS,
+ indent_cases = false,
+ newline_style = .LF,
+ character_width = 100,
}
}
-make_printer :: proc(config: Config, allocator := context.allocator) -> Printer {
- return {
- config = config,
- allocator = allocator,
- }
+make_printer :: proc(
+ config: Config,
+ allocator := context.allocator,
+) -> Printer {
+ return {config = config, allocator = allocator}
}
-@private
+@(private)
build_disabled_lines_info :: proc(p: ^Printer) {
found_disable := false
disable_position: tokenizer.Pos
@@ -125,27 +125,34 @@ build_disabled_lines_info :: proc(p: ^Printer) {
if strings.contains(comment.text[:], "//odinfmt: disable") {
found_disable = true
disable_position = comment.pos
- } else if strings.contains(comment.text[:], "//odinfmt: enable") && found_disable {
+ } else if strings.contains(comment.text[:], "//odinfmt: enable") &&
+ found_disable {
begin := disable_position.offset - (comment.pos.column - 1)
- end := comment.pos.offset+len(comment.text)
+ end := comment.pos.offset + len(comment.text)
disabled_info := Disabled_Info {
end_line = comment.pos.line,
- text = p.src[begin:end],
+ text = p.src[begin:end],
}
- for line := disable_position.line; line <= comment.pos.line; line += 1 {
+ for line := disable_position.line;
+ line <= comment.pos.line;
+ line += 1 {
p.disabled_lines[line] = disabled_info
}
-
+
found_disable = false
}
}
}
}
-@private
-set_comment_option :: proc(p: ^Printer, line: int, option: Line_Suffix_Option) {
+@(private)
+set_comment_option :: proc(
+ p: ^Printer,
+ line: int,
+ option: Line_Suffix_Option,
+) {
p.comments_option[line] = option
}
@@ -155,17 +162,14 @@ print :: proc {
}
print_expr :: proc(p: ^Printer, expr: ^ast.Expr) -> string {
- p.document = empty();
+ p.document = empty()
p.document = cons(p.document, visit_expr(p, expr))
p.string_builder = strings.builder_make(p.allocator)
context.allocator = p.allocator
list := make([dynamic]Tuple, p.allocator)
- append(&list, Tuple {
- document = p.document,
- indentation = 0,
- })
+ append(&list, Tuple{document = p.document, indentation = 0})
format(p.config.character_width, &list, &p.string_builder, p)
@@ -174,10 +178,10 @@ print_expr :: proc(p: ^Printer, expr: ^ast.Expr) -> string {
print_file :: proc(p: ^Printer, file: ^ast.File) -> string {
p.comments = file.comments
- p.string_builder = strings.builder_make(0, len(file.src)*2, p.allocator)
+ p.string_builder = strings.builder_make(0, len(file.src) * 2, p.allocator)
p.src = file.src
context.allocator = p.allocator
-
+
if p.config.tabs {
p.indentation = "\t"
p.indentation_width = p.config.tabs_width
@@ -193,12 +197,15 @@ print_file :: proc(p: ^Printer, file: ^ast.File) -> string {
}
build_disabled_lines_info(p)
-
+
p.source_position.line = 1
p.source_position.column = 1
p.document = move_line(p, file.pkg_token.pos)
- p.document = cons(p.document, cons_with_nopl(text(file.pkg_token.text), text(file.pkg_name)))
+ p.document = cons(
+ p.document,
+ cons_with_nopl(text(file.pkg_token.text), text(file.pkg_name)),
+ )
for decl in file.decls {
p.document = cons(p.document, visit_decl(p, cast(^ast.Decl)decl))
@@ -215,13 +222,9 @@ print_file :: proc(p: ^Printer, file: ^ast.File) -> string {
list := make([dynamic]Tuple, p.allocator)
- append(&list, Tuple {
- document = p.document,
- indentation = 0,
- })
+ append(&list, Tuple{document = p.document, indentation = 0})
format(p.config.character_width, &list, &p.string_builder, p)
return strings.to_string(p.string_builder)
}
-
diff --git a/src/odin/printer/visit.odin b/src/odin/printer/visit.odin
index 43e4321..134c4ee 100644
--- a/src/odin/printer/visit.odin
+++ b/src/odin/printer/visit.odin
@@ -11,21 +11,23 @@ import "core:strconv"
//right now the attribute order is not linearly parsed(bug?)
@(private)
sort_attribute :: proc(s: ^[dynamic]^ast.Attribute) -> sort.Interface {
- return sort.Interface {
- collection = rawptr(s),
- len = proc(it: sort.Interface) -> int {
- s := (^[dynamic]^ast.Attribute)(it.collection)
- return len(s^)
- },
- less = proc(it: sort.Interface, i, j: int) -> bool {
- s := (^[dynamic]^ast.Attribute)(it.collection)
- return s[i].pos.offset < s[j].pos.offset
- },
- swap = proc(it: sort.Interface, i, j: int) {
- s := (^[dynamic]^ast.Attribute)(it.collection)
- s[i], s[j] = s[j], s[i]
- },
- }
+ return(
+ sort.Interface{
+ collection = rawptr(s),
+ len = proc(it: sort.Interface) -> int {
+ s := (^[dynamic]^ast.Attribute)(it.collection)
+ return len(s^)
+ },
+ less = proc(it: sort.Interface, i, j: int) -> bool {
+ s := (^[dynamic]^ast.Attribute)(it.collection)
+ return s[i].pos.offset < s[j].pos.offset
+ },
+ swap = proc(it: sort.Interface, i, j: int) {
+ s := (^[dynamic]^ast.Attribute)(it.collection)
+ s[i], s[j] = s[j], s[i]
+ },
+ } \
+ )
}
@(private)
@@ -62,13 +64,21 @@ text_token :: proc(p: ^Printer, token: tokenizer.Token) -> ^Document {
}
@(private)
-text_position :: proc(p: ^Printer, value: string, pos: tokenizer.Pos) -> ^Document {
+text_position :: proc(
+ p: ^Printer,
+ value: string,
+ pos: tokenizer.Pos,
+) -> ^Document {
document, _ := visit_comments(p, pos)
return cons(document, text(value))
}
@(private)
-newline_position :: proc(p: ^Printer, amount: int, pos: tokenizer.Pos) -> ^Document {
+newline_position :: proc(
+ p: ^Printer,
+ amount: int,
+ pos: tokenizer.Pos,
+) -> ^Document {
document, _ := visit_comments(p, pos)
return cons(document, newline(amount))
}
@@ -80,12 +90,19 @@ set_source_position :: proc(p: ^Printer, pos: tokenizer.Pos) {
@(private)
move_line :: proc(p: ^Printer, pos: tokenizer.Pos) -> ^Document {
- l, _ := move_line_limit(p, pos, p.config.newline_limit+1)
+ l, _ := move_line_limit(p, pos, p.config.newline_limit + 1)
return l
}
@(private)
-move_line_limit :: proc(p: ^Printer, pos: tokenizer.Pos, limit: int) -> (^Document, bool) {
+move_line_limit :: proc(
+ p: ^Printer,
+ pos: tokenizer.Pos,
+ limit: int,
+) -> (
+ ^Document,
+ bool,
+) {
lines := pos.line - p.source_position.line
if lines < 0 {
@@ -96,18 +113,30 @@ move_line_limit :: proc(p: ^Printer, pos: tokenizer.Pos, limit: int) -> (^Docume
p.source_position = pos
- return cons(document, newline(max(min(lines-comments_newlined, limit), 0))), lines > 0
+ return cons(
+ document,
+ newline(max(min(lines - comments_newlined, limit), 0)),
+ ), lines > 0
}
@(private)
-visit_comment :: proc(p: ^Printer, comment: tokenizer.Token) -> (int, ^Document) {
+visit_comment :: proc(
+ p: ^Printer,
+ comment: tokenizer.Token,
+) -> (
+ int,
+ ^Document,
+) {
document := empty()
if len(comment.text) == 0 {
return 0, document
}
-
+
newlines_before_comment := comment.pos.line - p.source_position.line
- newlines_before_comment_limited := min(newlines_before_comment, p.config.newline_limit + 1)
+ newlines_before_comment_limited := min(
+ newlines_before_comment,
+ p.config.newline_limit + 1,
+ )
document = cons(document, newline(newlines_before_comment_limited))
@@ -115,33 +144,45 @@ visit_comment :: proc(p: ^Printer, comment: tokenizer.Token) -> (int, ^Document)
if comment.pos.line in p.disabled_lines {
p.source_position = comment.pos
return 1, empty()
- } else if comment.pos.line == p.source_position.line && p.source_position.column != 1 {
+ } else if comment.pos.line == p.source_position.line &&
+ p.source_position.column != 1 {
p.source_position = comment.pos
- if comment_option, exist := p.comments_option[comment.pos.line]; exist && comment_option == .Indent {
+ if comment_option, exist := p.comments_option[comment.pos.line];
+ exist && comment_option == .Indent {
delete_key(&p.comments_option, comment.pos.line)
- return newlines_before_comment, cons_with_nopl(document, cons(text(p.indentation), line_suffix(comment.text)))
+ return newlines_before_comment, cons_with_nopl(
+ document,
+ cons(text(p.indentation), line_suffix(comment.text)),
+ )
} else {
- return newlines_before_comment, cons_with_nopl(document, line_suffix(comment.text))
+ return newlines_before_comment, cons_with_nopl(
+ document,
+ line_suffix(comment.text),
+ )
}
} else {
p.source_position = comment.pos
- return newlines_before_comment, cons(document, line_suffix(comment.text))
+ return newlines_before_comment, cons(
+ document,
+ line_suffix(comment.text),
+ )
}
- } else {
+ } else {
newlines := strings.count(comment.text, "\n")
if comment.pos.line in p.disabled_lines {
p.source_position = comment.pos
p.source_position.line += newlines
return 1, empty()
- } else if comment.pos.line == p.source_position.line && p.source_position.column != 1 {
+ } else if comment.pos.line == p.source_position.line &&
+ p.source_position.column != 1 {
p.source_position = comment.pos
p.source_position.line += newlines
- return newlines_before_comment+newlines, cons_with_opl(document, text(comment.text))
+ return newlines_before_comment + newlines, cons_with_opl(document, text(comment.text))
} else {
p.source_position = comment.pos
p.source_position.line += newlines
- return newlines_before_comment+newlines, cons(document, text(comment.text))
+ return newlines_before_comment + newlines, cons(document, text(comment.text))
}
return 0, document
@@ -170,7 +211,7 @@ visit_comments :: proc(p: ^Printer, pos: tokenizer.Pos) -> (^Document, int) {
@(private)
visit_disabled :: proc(p: ^Printer, node: ^ast.Node) -> ^Document {
-
+
if node.pos.line not_in p.disabled_lines {
return empty()
}
@@ -198,9 +239,13 @@ visit_disabled :: proc(p: ^Printer, node: ^ast.Node) -> ^Document {
}
@(private)
-visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) -> ^Document {
+visit_decl :: proc(
+ p: ^Printer,
+ decl: ^ast.Decl,
+ called_in_stmt := false,
+) -> ^Document {
using ast
-
+
if decl == nil {
return empty()
}
@@ -222,14 +267,23 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) -> ^Do
case ^Foreign_Import_Decl:
document := empty()
if len(v.attributes) > 0 {
- document = cons(document, visit_attributes(p, &v.attributes, v.pos))
+ document = cons(
+ document,
+ visit_attributes(p, &v.attributes, v.pos),
+ )
}
document = cons(document, move_line(p, decl.pos))
- document = cons(document, cons_with_opl(text(v.foreign_tok.text), text(v.import_tok.text)))
+ document = cons(
+ document,
+ cons_with_opl(text(v.foreign_tok.text), text(v.import_tok.text)),
+ )
if v.name != nil {
- document = cons_with_opl(document, text_position(p, v.name.name, v.pos))
+ document = cons_with_opl(
+ document,
+ text_position(p, v.name.name, v.pos),
+ )
}
if len(v.fullpaths) > 1 {
@@ -238,7 +292,7 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) -> ^Do
document = cons(document, text(path))
if i != len(v.fullpaths) - 1 {
document = cons(document, text(","), break_with_space())
- }
+ }
}
document = cons(document, text("}"))
} else if len(v.fullpaths) == 1 {
@@ -249,11 +303,17 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) -> ^Do
case ^Foreign_Block_Decl:
document := empty()
if len(v.attributes) > 0 {
- document = cons(document, visit_attributes(p, &v.attributes, v.pos))
+ document = cons(
+ document,
+ visit_attributes(p, &v.attributes, v.pos),
+ )
}
document = cons(document, move_line(p, decl.pos))
- document = cons(document, cons_with_opl(text("foreign"), visit_expr(p, v.foreign_library)))
+ document = cons(
+ document,
+ cons_with_opl(text("foreign"), visit_expr(p, v.foreign_library)),
+ )
document = cons_with_nopl(document, visit_stmt(p, v.body))
return document
case ^Import_Decl:
@@ -274,7 +334,10 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) -> ^Do
case ^Value_Decl:
document := empty()
if len(v.attributes) > 0 {
- document = cons(document, visit_attributes(p, &v.attributes, v.pos))
+ document = cons(
+ document,
+ visit_attributes(p, &v.attributes, v.pos),
+ )
}
document = cons(document, move_line(p, decl.pos))
@@ -306,22 +369,49 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) -> ^Do
lhs = cons(lhs, text("="))
}
- rhs = cons_with_nopl(rhs, visit_exprs(p, v.values, {.Add_Comma}, .Value_Decl))
+ rhs = cons_with_nopl(
+ rhs,
+ visit_exprs(p, v.values, {.Add_Comma}, .Value_Decl),
+ )
} else if len(v.values) > 0 && v.type != nil {
- rhs = cons_with_nopl(rhs, cons_with_nopl(text(":"), visit_exprs(p, v.values, {.Add_Comma})))
+ rhs = cons_with_nopl(
+ rhs,
+ cons_with_nopl(
+ text(":"),
+ visit_exprs(p, v.values, {.Add_Comma}),
+ ),
+ )
} else {
- rhs = cons_with_nopl(rhs, visit_exprs(p, v.values, {.Add_Comma}, .Value_Decl))
+ rhs = cons_with_nopl(
+ rhs,
+ visit_exprs(p, v.values, {.Add_Comma}, .Value_Decl),
+ )
}
if len(v.values) > 0 {
if is_values_nestable_assign(v.values) {
- return cons(document, group(nest(cons_with_opl(lhs, group(rhs)))))
+ return cons(
+ document,
+ group(nest(cons_with_opl(lhs, group(rhs)))),
+ )
} else if is_values_nestable_if_break_assign(v.values) {
- assignments := cons(lhs, group(nest(break_with_space()), Document_Group_Options { id = "assignments"}))
- assignments = cons(assignments, nest_if_break(group(rhs), "assignments"))
+ assignments := cons(
+ lhs,
+ group(
+ nest(break_with_space()),
+ Document_Group_Options{id = "assignments"},
+ ),
+ )
+ assignments = cons(
+ assignments,
+ nest_if_break(group(rhs), "assignments"),
+ )
return cons(document, group(assignments))
} else {
- return cons(document, group(cons_with_nopl(group(lhs), group(rhs))))
+ return cons(
+ document,
+ group(cons_with_nopl(group(lhs), group(rhs))),
+ )
}
} else {
return cons(document, group(lhs))
@@ -338,7 +428,7 @@ exprs_contain_empty_idents :: proc(list: []^ast.Expr) -> bool {
for expr in list {
if ident, ok := expr.derived.(^ast.Ident); ok && ident.name == "_" {
continue
- }
+ }
return false
}
return true
@@ -350,11 +440,11 @@ is_call_expr_nestable :: proc(list: []^ast.Expr) -> bool {
return true
}
- #partial switch v in list[len(list)-1].derived {
+ #partial switch v in list[len(list) - 1].derived {
case ^ast.Comp_Lit, ^ast.Proc_Type, ^ast.Proc_Lit:
return false
}
-
+
return true
}
@@ -366,9 +456,8 @@ is_values_nestable_assign :: proc(list: []^ast.Expr) -> bool {
for expr in list {
#partial switch v in expr.derived {
- case ^ast.Ident, ^ast.Binary_Expr, ^ast.Index_Expr, ^ast.Selector_Expr, ^ast.Paren_Expr,
- ^ast.Ternary_If_Expr, ^ast.Ternary_When_Expr, ^ast.Or_Else_Expr:
- return true
+ case ^ast.Ident, ^ast.Binary_Expr, ^ast.Index_Expr, ^ast.Selector_Expr, ^ast.Paren_Expr, ^ast.Ternary_If_Expr, ^ast.Ternary_When_Expr, ^ast.Or_Else_Expr:
+ return true
}
}
return false
@@ -388,28 +477,32 @@ is_values_return_stmt_callable :: proc(list: []^ast.Expr) -> bool {
}
#partial switch v in result.derived {
- case ^ast.Call_Expr:
- return false
+ case ^ast.Call_Expr:
+ return false
}
}
return true
}
-
@(private)
is_values_nestable_if_break_assign :: proc(list: []^ast.Expr) -> bool {
for expr in list {
#partial switch v in expr.derived {
- case ^ast.Call_Expr, ^ast.Comp_Lit, ^ast.Or_Return_Expr:
- return true
+ case ^ast.Call_Expr, ^ast.Comp_Lit, ^ast.Or_Return_Expr:
+ return true
}
}
return false
}
@(private)
-visit_exprs :: proc(p: ^Printer, list: []^ast.Expr, options := List_Options{}, called_from: Expr_Called_Type = .Generic) -> ^Document {
+visit_exprs :: proc(
+ p: ^Printer,
+ list: []^ast.Expr,
+ options := List_Options{},
+ called_from: Expr_Called_Type = .Generic,
+) -> ^Document {
if len(list) == 0 {
return empty()
}
@@ -420,19 +513,35 @@ visit_exprs :: proc(p: ^Printer, list: []^ast.Expr, options := List_Options{}, c
p.source_position = expr.pos
if .Enforce_Newline in options {
- document = cons(document, .Group in options ? group(visit_expr(p, expr, called_from, options)) : visit_expr(p, expr, called_from, options))
+ document = cons(
+ document,
+ .Group in options \
+ ? group(visit_expr(p, expr, called_from, options)) \
+ : visit_expr(p, expr, called_from, options),
+ )
} else if .Glue in options {
- document = cons_with_nopl(document, .Group in options ? group(visit_expr(p, expr, called_from, options)) : visit_expr(p, expr, called_from, options))
+ document = cons_with_nopl(
+ document,
+ .Group in options \
+ ? group(visit_expr(p, expr, called_from, options)) \
+ : visit_expr(p, expr, called_from, options),
+ )
} else {
- document = cons_with_opl(document, .Group in options ? group(visit_expr(p, expr, called_from, options)) : visit_expr(p, expr, called_from, options))
+ document = cons_with_opl(
+ document,
+ .Group in options \
+ ? group(visit_expr(p, expr, called_from, options)) \
+ : visit_expr(p, expr, called_from, options),
+ )
}
- if (i != len(list) - 1 || .Trailing in options) && .Add_Comma in options {
+ if (i != len(list) - 1 || .Trailing in options) &&
+ .Add_Comma in options {
document = cons(document, text(","))
}
if (i != len(list) - 1 && .Enforce_Newline in options) {
- comment, _ := visit_comments(p, list[i+1].pos)
+ comment, _ := visit_comments(p, list[i + 1].pos)
document = cons(document, comment, newline(1))
} else if .Enforce_Newline in options {
comment, _ := visit_comments(p, list[i].end)
@@ -444,7 +553,11 @@ visit_exprs :: proc(p: ^Printer, list: []^ast.Expr, options := List_Options{}, c
}
@(private)
-visit_enum_exprs :: proc(p: ^Printer, enum_type: ast.Enum_Type, options := List_Options{}) -> ^Document {
+visit_enum_exprs :: proc(
+ p: ^Printer,
+ enum_type: ast.Enum_Type,
+ options := List_Options{},
+) -> ^Document {
if len(enum_type.fields) == 0 {
return empty()
}
@@ -453,7 +566,7 @@ visit_enum_exprs :: proc(p: ^Printer, enum_type: ast.Enum_Type, options := List_
for expr, i in enum_type.fields {
if i == 0 && .Enforce_Newline in options {
- comment, _ := visit_comments(p, enum_type.fields[i].pos)
+ comment, _ := visit_comments(p, enum_type.fields[i].pos)
if _, is_nil := comment.(Document_Nil); !is_nil {
comment = cons(comment, newline(1))
}
@@ -463,21 +576,44 @@ visit_enum_exprs :: proc(p: ^Printer, enum_type: ast.Enum_Type, options := List_
if (.Enforce_Newline in options) {
alignment := get_possible_enum_alignment(enum_type.fields)
- if value, ok := expr.derived.(^ast.Field_Value); ok && alignment > 0 {
- document = cons(document, cons_with_nopl(visit_expr(p, value.field), cons_with_nopl(cons(repeat_space(alignment - get_node_length(value.field)), text_position(p, "=", value.sep)), visit_expr(p, value.value))))
+ if value, ok := expr.derived.(^ast.Field_Value);
+ ok && alignment > 0 {
+ document = cons(
+ document,
+ cons_with_nopl(
+ visit_expr(p, value.field),
+ cons_with_nopl(
+ cons(
+ repeat_space(
+ alignment - get_node_length(value.field),
+ ),
+ text_position(p, "=", value.sep),
+ ),
+ visit_expr(p, value.value),
+ ),
+ ),
+ )
} else {
- document = group(cons(document, visit_expr(p, expr, .Generic, options)))
+ document = group(
+ cons(document, visit_expr(p, expr, .Generic, options)),
+ )
}
} else {
- document = group(cons_with_opl(document, visit_expr(p, expr, .Generic, options)))
+ document = group(
+ cons_with_opl(
+ document,
+ visit_expr(p, expr, .Generic, options),
+ ),
+ )
}
- if (i != len(enum_type.fields) - 1 || .Trailing in options) && .Add_Comma in options {
+ if (i != len(enum_type.fields) - 1 || .Trailing in options) &&
+ .Add_Comma in options {
document = cons(document, text(","))
}
if (i != len(enum_type.fields) - 1 && .Enforce_Newline in options) {
- comment, _ := visit_comments(p, enum_type.fields[i+1].pos)
+ comment, _ := visit_comments(p, enum_type.fields[i + 1].pos)
document = cons(document, comment, newline(1))
} else if .Enforce_Newline in options {
comment, _ := visit_comments(p, enum_type.end)
@@ -489,7 +625,11 @@ visit_enum_exprs :: proc(p: ^Printer, enum_type: ast.Enum_Type, options := List_
}
@(private)
-visit_union_exprs :: proc(p: ^Printer, union_type: ast.Union_Type, options := List_Options{}) -> ^Document {
+visit_union_exprs :: proc(
+ p: ^Printer,
+ union_type: ast.Union_Type,
+ options := List_Options{},
+) -> ^Document {
if len(union_type.variants) == 0 {
return empty()
}
@@ -498,7 +638,7 @@ visit_union_exprs :: proc(p: ^Printer, union_type: ast.Union_Type, options := Li
for expr, i in union_type.variants {
if i == 0 && .Enforce_Newline in options {
- comment, _ := visit_comments(p, union_type.variants[i].pos)
+ comment, _ := visit_comments(p, union_type.variants[i].pos)
if _, is_nil := comment.(Document_Nil); !is_nil {
comment = cons(comment, newline(1))
}
@@ -508,21 +648,44 @@ visit_union_exprs :: proc(p: ^Printer, union_type: ast.Union_Type, options := Li
if (.Enforce_Newline in options) {
alignment := get_possible_enum_alignment(union_type.variants)
- if value, ok := expr.derived.(^ast.Field_Value); ok && alignment > 0 {
- document = cons(document, cons_with_nopl(visit_expr(p, value.field), cons_with_nopl(cons(repeat_space(alignment - get_node_length(value.field)), text_position(p, "=", value.sep)), visit_expr(p, value.value))))
+ if value, ok := expr.derived.(^ast.Field_Value);
+ ok && alignment > 0 {
+ document = cons(
+ document,
+ cons_with_nopl(
+ visit_expr(p, value.field),
+ cons_with_nopl(
+ cons(
+ repeat_space(
+ alignment - get_node_length(value.field),
+ ),
+ text_position(p, "=", value.sep),
+ ),
+ visit_expr(p, value.value),
+ ),
+ ),
+ )
} else {
- document = group(cons(document, visit_expr(p, expr, .Generic, options)))
+ document = group(
+ cons(document, visit_expr(p, expr, .Generic, options)),
+ )
}
} else {
- document = group(cons_with_opl(document, visit_expr(p, expr, .Generic, options)))
+ document = group(
+ cons_with_opl(
+ document,
+ visit_expr(p, expr, .Generic, options),
+ ),
+ )
}
- if (i != len(union_type.variants) - 1 || .Trailing in options) && .Add_Comma in options {
+ if (i != len(union_type.variants) - 1 || .Trailing in options) &&
+ .Add_Comma in options {
document = cons(document, text(","))
}
if (i != len(union_type.variants) - 1 && .Enforce_Newline in options) {
- comment, _ := visit_comments(p, union_type.variants[i+1].pos)
+ comment, _ := visit_comments(p, union_type.variants[i + 1].pos)
document = cons(document, comment, newline(1))
} else if .Enforce_Newline in options {
comment, _ := visit_comments(p, union_type.end)
@@ -534,7 +697,11 @@ visit_union_exprs :: proc(p: ^Printer, union_type: ast.Union_Type, options := Li
}
@(private)
-visit_comp_lit_exprs :: proc(p: ^Printer, comp_lit: ast.Comp_Lit, options := List_Options{}) -> ^Document {
+visit_comp_lit_exprs :: proc(
+ p: ^Printer,
+ comp_lit: ast.Comp_Lit,
+ options := List_Options{},
+) -> ^Document {
if len(comp_lit.elems) == 0 {
return empty()
}
@@ -543,7 +710,7 @@ visit_comp_lit_exprs :: proc(p: ^Printer, comp_lit: ast.Comp_Lit, options := Lis
for expr, i in comp_lit.elems {
if i == 0 && .Enforce_Newline in options {
- comment, _ := visit_comments(p, comp_lit.elems[i].pos)
+ comment, _ := visit_comments(p, comp_lit.elems[i].pos)
if _, is_nil := comment.(Document_Nil); !is_nil {
comment = cons(comment, newline(1))
}
@@ -552,25 +719,45 @@ visit_comp_lit_exprs :: proc(p: ^Printer, comp_lit: ast.Comp_Lit, options := Lis
if (.Enforce_Newline in options) {
alignment := get_possible_comp_lit_alignment(comp_lit.elems)
- if value, ok := expr.derived.(^ast.Field_Value); ok && alignment > 0 {
+ if value, ok := expr.derived.(^ast.Field_Value);
+ ok && alignment > 0 {
align := empty()
if should_align_comp_lit(p, comp_lit) {
- align = repeat_space(alignment - get_node_length(value.field))
+ align = repeat_space(
+ alignment - get_node_length(value.field),
+ )
}
- document = cons(document, cons_with_nopl(visit_expr(p, value.field), cons_with_nopl(cons(align, text_position(p, "=", value.sep)), visit_expr(p, value.value))))
+ document = cons(
+ document,
+ cons_with_nopl(
+ visit_expr(p, value.field),
+ cons_with_nopl(
+ cons(align, text_position(p, "=", value.sep)),
+ visit_expr(p, value.value),
+ ),
+ ),
+ )
} else {
- document = group(cons(document, visit_expr(p, expr, .Generic, options)))
+ document = group(
+ cons(document, visit_expr(p, expr, .Generic, options)),
+ )
}
} else {
- document = group(cons_with_nopl(document, visit_expr(p, expr, .Generic, options)))
+ document = group(
+ cons_with_nopl(
+ document,
+ visit_expr(p, expr, .Generic, options),
+ ),
+ )
}
- if (i != len(comp_lit.elems) - 1 || .Trailing in options) && .Add_Comma in options {
+ if (i != len(comp_lit.elems) - 1 || .Trailing in options) &&
+ .Add_Comma in options {
document = cons(document, text(","))
}
if (i != len(comp_lit.elems) - 1 && .Enforce_Newline in options) {
- comment, _ := visit_comments(p, comp_lit.elems[i+1].pos)
+ comment, _ := visit_comments(p, comp_lit.elems[i + 1].pos)
document = cons(document, comment, newline(1))
} else if .Enforce_Newline in options {
comment, _ := visit_comments(p, comp_lit.end)
@@ -582,7 +769,11 @@ visit_comp_lit_exprs :: proc(p: ^Printer, comp_lit: ast.Comp_Lit, options := Lis
}
@(private)
-visit_attributes :: proc(p: ^Printer, attributes: ^[dynamic]^ast.Attribute, pos: tokenizer.Pos) -> ^Document {
+visit_attributes :: proc(
+ p: ^Printer,
+ attributes: ^[dynamic]^ast.Attribute,
+ pos: tokenizer.Pos,
+) -> ^Document {
document := empty()
if len(attributes) == 0 {
return document
@@ -592,7 +783,13 @@ visit_attributes :: proc(p: ^Printer, attributes: ^[dynamic]^ast.Attribute, pos:
document = cons(document, move_line(p, attributes[0].pos))
for attribute, i in attributes {
- document = cons(document, text("@"), text("("), visit_exprs(p, attribute.elems, {.Add_Comma}), text(")"))
+ document = cons(
+ document,
+ text("@"),
+ text("("),
+ visit_exprs(p, attribute.elems, {.Add_Comma}),
+ text(")"),
+ )
// document = cons(document, visit_exprs(p, attribute.elems, {.Add_Comma}))
// document = cons(document, text(")"))
@@ -607,7 +804,10 @@ visit_attributes :: proc(p: ^Printer, attributes: ^[dynamic]^ast.Attribute, pos:
}
@(private)
-visit_state_flags :: proc(p: ^Printer, flags: ast.Node_State_Flags) -> ^Document {
+visit_state_flags :: proc(
+ p: ^Printer,
+ flags: ast.Node_State_Flags,
+) -> ^Document {
if .No_Bounds_Check in flags {
return cons(text("#no_bounds_check"), break_with_no_newline())
}
@@ -622,14 +822,20 @@ enforce_fit_if_do :: proc(stmt: ^ast.Stmt, document: ^Document) -> ^Document {
if v, ok := stmt.derived.(^ast.Block_Stmt); ok {
if v.uses_do {
return enforce_fit(document)
- }
+ }
}
return document
}
@(private)
-visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Generic, empty_block := false, block_stmt := false) -> ^Document {
+visit_stmt :: proc(
+ p: ^Printer,
+ stmt: ^ast.Stmt,
+ block_type: Block_Type = .Generic,
+ empty_block := false,
+ block_stmt := false,
+) -> ^Document {
using ast
if stmt == nil {
@@ -642,7 +848,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
#partial switch v in stmt.derived {
case ^Import_Decl:
- return visit_decl(p, cast(^Decl)stmt, true)
+ return visit_decl(p, cast(^Decl)stmt, true)
case ^Value_Decl:
return visit_decl(p, cast(^Decl)stmt, true)
case ^Foreign_Import_Decl:
@@ -656,20 +862,38 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
#partial switch v in stmt.derived {
case ^Using_Stmt:
- document = cons(document, cons_with_nopl(text("using"), visit_exprs(p, v.list, {.Add_Comma})))
- case ^Block_Stmt:
+ document = cons(
+ document,
+ cons_with_nopl(
+ text("using"),
+ visit_exprs(p, v.list, {.Add_Comma}),
+ ),
+ )
+ case ^Block_Stmt:
uses_do := v.uses_do
if v.label != nil {
- document = cons(document,visit_expr(p, v.label), text(":"), break_with_space())
+ document = cons(
+ document,
+ visit_expr(p, v.label),
+ text(":"),
+ break_with_space(),
+ )
}
if .Bounds_Check in v.state_flags {
- document = cons(document, text("#bounds_check"), break_with_space())
+ document = cons(
+ document,
+ text("#bounds_check"),
+ break_with_space(),
+ )
}
if !uses_do {
- document = cons(document, visit_begin_brace(p, v.pos, block_type, len(v.stmts)))
+ document = cons(
+ document,
+ visit_begin_brace(p, v.pos, block_type, len(v.stmts)),
+ )
} else {
document = cons(document, text("do"), break_with(" ", false))
}
@@ -677,7 +901,10 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
set_source_position(p, v.pos)
block := visit_block_stmts(p, v.stmts, len(v.stmts) > 1)
- comment_end, _ := visit_comments(p, tokenizer.Pos {line = v.end.line, offset = v.end.offset})
+ comment_end, _ := visit_comments(
+ p,
+ tokenizer.Pos{line = v.end.line, offset = v.end.offset},
+ )
if block_type == .Switch_Stmt && !p.config.indent_cases {
document = cons(document, block, comment_end)
@@ -690,19 +917,33 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
}
case ^If_Stmt:
if v.label != nil {
- document = cons(document, visit_expr(p, v.label), text(":"), break_with_space())
+ document = cons(
+ document,
+ visit_expr(p, v.label),
+ text(":"),
+ break_with_space(),
+ )
}
if_document := text("if")
if v.init != nil {
- if_document = cons_with_nopl(if_document, cons(group(visit_stmt(p, v.init)), text(";")))
+ if_document = cons_with_nopl(
+ if_document,
+ cons(group(visit_stmt(p, v.init)), text(";")),
+ )
}
if v.cond != nil && v.init != nil {
- if_document = cons(if_document, group(cons(break_with_space(), visit_expr(p, v.cond))))
+ if_document = cons(
+ if_document,
+ group(cons(break_with_space(), group(visit_expr(p, v.cond)))),
+ )
} else if v.cond != nil {
- if_document = cons_with_nopl(if_document, group(visit_expr(p, v.cond)))
+ if_document = cons_with_nopl(
+ if_document,
+ group(visit_expr(p, v.cond)),
+ )
}
document = cons(document, group(hang(3, if_document)))
@@ -714,28 +955,40 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
set_source_position(p, v.body.end)
if v.else_stmt != nil {
- if p.config.brace_style == .Allman || p.config.brace_style == .Stroustrup {
+ if p.config.brace_style == .Allman ||
+ p.config.brace_style == .Stroustrup {
document = cons(document, newline(1))
}
set_source_position(p, v.else_stmt.pos)
if _, ok := v.else_stmt.derived.(^ast.If_Stmt); ok {
- document = cons_with_opl(document, cons_with_nopl(text("else"), visit_stmt(p, v.else_stmt)))
+ document = cons_with_opl(
+ document,
+ cons_with_nopl(text("else"), visit_stmt(p, v.else_stmt)),
+ )
} else {
- document = cons_with_opl(document, cons_with_nopl(text("else"), visit_stmt(p, v.else_stmt)))
+ document = cons_with_opl(
+ document,
+ cons_with_nopl(text("else"), visit_stmt(p, v.else_stmt)),
+ )
}
}
document = enforce_fit_if_do(v.body, document)
- case ^Switch_Stmt:
- if v.label != nil {
- document = cons(document, visit_expr(p, v.label), text(":"), break_with_space())
- }
-
+ case ^Switch_Stmt:
if v.partial {
document = cons(document, text("#partial"), break_with_space())
}
+ if v.label != nil {
+ document = cons(
+ document,
+ visit_expr(p, v.label),
+ text(":"),
+ break_with_space(),
+ )
+ }
+
document = cons(document, text("switch"))
if v.init != nil {
@@ -747,47 +1000,78 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
}
document = cons_with_opl(document, visit_expr(p, v.cond))
- document = cons_with_nopl(document, visit_stmt(p, v.body, .Switch_Stmt))
+ document = cons_with_nopl(
+ document,
+ visit_stmt(p, v.body, .Switch_Stmt),
+ )
case ^Case_Clause:
document = cons(document, text("case"))
if v.list != nil {
- document = cons_with_nopl(document, visit_exprs(p, v.list, {.Add_Comma}))
+ document = cons_with_nopl(
+ document,
+ visit_exprs(p, v.list, {.Add_Comma}),
+ )
}
document = cons(document, text(v.terminator.text))
if len(v.body) != 0 {
set_source_position(p, v.body[0].pos)
- document = cons(document, nest(cons(newline(1), visit_block_stmts(p, v.body))))
+ document = cons(
+ document,
+ nest(cons(newline(1), visit_block_stmts(p, v.body))),
+ )
}
case ^Type_Switch_Stmt:
- if v.label != nil {
- document = cons(document, visit_expr(p, v.label), text(":"), break_with_space())
- }
-
if v.partial {
document = cons(document, text("#partial"), break_with_space())
}
+ if v.label != nil {
+ document = cons(
+ document,
+ visit_expr(p, v.label),
+ text(":"),
+ break_with_space(),
+ )
+ }
+
document = cons(document, text("switch"))
document = cons_with_nopl(document, visit_stmt(p, v.tag, .Switch_Stmt))
- document = cons_with_nopl(document, visit_stmt(p, v.body, .Switch_Stmt))
+ document = cons_with_nopl(
+ document,
+ visit_stmt(p, v.body, .Switch_Stmt),
+ )
case ^Assign_Stmt:
assign_document: ^Document
//If the switch contains `switch in v`
- if exprs_contain_empty_idents(v.lhs) && block_type == .Switch_Stmt {
+ if exprs_contain_empty_idents(v.lhs) && block_type == .Switch_Stmt {
assign_document = cons(document, text(v.op.text))
} else {
- assign_document = cons(document, group(cons(visit_exprs(p, v.lhs, {.Add_Comma, .Glue}), cons(text(" "), text(v.op.text)))))
+ assign_document = cons(
+ document,
+ group(
+ cons(
+ visit_exprs(p, v.lhs, {.Add_Comma, .Glue}),
+ cons(text(" "), text(v.op.text)),
+ ),
+ ),
+ )
}
rhs := visit_exprs(p, v.rhs, {.Add_Comma}, .Assignment_Stmt)
if is_values_nestable_assign(v.rhs) {
document = group(nest(cons_with_opl(assign_document, group(rhs))))
} else if is_values_nestable_if_break_assign(v.rhs) {
- document = cons(assign_document, group(nest(break_with_space()), Document_Group_Options { id = "assignments"}))
+ document = cons(
+ assign_document,
+ group(
+ nest(break_with_space()),
+ Document_Group_Options{id = "assignments"},
+ ),
+ )
document = cons(document, nest_if_break(group(rhs), "assignments"))
document = group(document)
} else {
@@ -797,27 +1081,41 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
document = cons(document, visit_expr(p, v.expr))
case ^For_Stmt:
if v.label != nil {
- document = cons(document, visit_expr(p, v.label), text(":"), break_with_space())
+ document = cons(
+ document,
+ visit_expr(p, v.label),
+ text(":"),
+ break_with_space(),
+ )
}
for_document := text("for")
if v.init != nil {
set_source_position(p, v.init.pos)
- for_document = cons_with_nopl(for_document, cons(group(visit_stmt(p, v.init)), text(";")))
+ for_document = cons_with_nopl(
+ for_document,
+ cons(group(visit_stmt(p, v.init)), text(";")),
+ )
} else if v.post != nil {
for_document = cons_with_nopl(for_document, text(";"))
}
if v.cond != nil {
set_source_position(p, v.cond.pos)
- for_document = cons_with_opl(for_document, group(visit_expr(p, v.cond)))
+ for_document = cons_with_opl(
+ for_document,
+ group(visit_expr(p, v.cond)),
+ )
}
if v.post != nil {
set_source_position(p, v.post.pos)
for_document = cons(for_document, text(";"))
- for_document = cons_with_opl(for_document, group(visit_stmt(p, v.post)))
+ for_document = cons_with_opl(
+ for_document,
+ group(visit_stmt(p, v.post)),
+ )
} else if v.post == nil && v.cond != nil && v.init != nil {
for_document = cons(for_document, text(";"))
}
@@ -825,13 +1123,18 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
document = cons(document, group(hang(4, for_document)))
set_source_position(p, v.body.pos)
- document = cons_with_nopl(document, visit_stmt(p, v.body))
+ document = cons_with_nopl(document, visit_stmt(p, v.body))
set_source_position(p, v.body.end)
document = enforce_fit_if_do(v.body, document)
case ^Inline_Range_Stmt:
if v.label != nil {
- document = cons(document, visit_expr(p, v.label), text(":"), break_with_space())
+ document = cons(
+ document,
+ visit_expr(p, v.label),
+ text(":"),
+ break_with_space(),
+ )
}
document = cons(document, text("#unroll"))
@@ -840,7 +1143,10 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
document = cons_with_nopl(document, visit_expr(p, v.val0))
if v.val1 != nil {
- document = cons(document, cons_with_opl(text(","), visit_expr(p, v.val1)))
+ document = cons(
+ document,
+ cons_with_opl(text(","), visit_expr(p, v.val1)),
+ )
}
document = cons_with_nopl(document, text("in"))
@@ -848,13 +1154,18 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
document = cons_with_nopl(document, visit_expr(p, v.expr))
set_source_position(p, v.body.pos)
- document = cons_with_nopl(document, visit_stmt(p, v.body))
+ document = cons_with_nopl(document, visit_stmt(p, v.body))
set_source_position(p, v.body.end)
document = enforce_fit_if_do(v.body, document)
case ^Range_Stmt:
if v.label != nil {
- document = cons(document, visit_expr(p, v.label), text(":"), break_with_space())
+ document = cons(
+ document,
+ visit_expr(p, v.label),
+ text(":"),
+ break_with_space(),
+ )
}
document = cons(document, text("for"))
@@ -864,15 +1175,18 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
}
if len(v.vals) >= 2 {
- document = cons(document, cons_with_opl(text(","), visit_expr(p, v.vals[1])))
+ document = cons(
+ document,
+ cons_with_opl(text(","), visit_expr(p, v.vals[1])),
+ )
}
document = cons_with_opl(document, text("in"))
document = cons_with_opl(document, visit_expr(p, v.expr))
-
+
set_source_position(p, v.body.pos)
- document = cons_with_nopl(document, visit_stmt(p, v.body))
+ document = cons_with_nopl(document, visit_stmt(p, v.body))
set_source_position(p, v.body.end)
document = enforce_fit_if_do(v.body, document)
@@ -896,11 +1210,16 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
visit_expr(p, result),
)
- document = nest(document)
- document = group(cons(document, if_break(" \\"), break_with(""), if_break(")")))
+ document = nest(document)
+ document = group(
+ cons(document, if_break(" \\"), break_with(""), if_break(")")),
+ )
} else {
document = cons(document, text("return"))
- document = cons_with_nopl(document, visit_exprs(p, v.results, {.Add_Comma}))
+ document = cons_with_nopl(
+ document,
+ visit_exprs(p, v.results, {.Add_Comma}),
+ )
}
@@ -908,7 +1227,10 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
document = cons(document, text("defer"))
document = cons_with_nopl(document, visit_stmt(p, v.stmt))
case ^When_Stmt:
- document = cons(document, cons_with_nopl(text("when"), visit_expr(p, v.cond)))
+ document = cons(
+ document,
+ cons_with_nopl(text("when"), visit_expr(p, v.cond)),
+ )
document = cons_with_nopl(document, visit_stmt(p, v.body))
@@ -919,7 +1241,10 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
set_source_position(p, v.else_stmt.pos)
- document = cons_with_nopl(document, cons_with_nopl(text("else"), visit_stmt(p, v.else_stmt)))
+ document = cons_with_nopl(
+ document,
+ cons_with_nopl(text("else"), visit_stmt(p, v.else_stmt)),
+ )
}
case ^Branch_Stmt:
document = cons(document, text(v.tok.text))
@@ -945,12 +1270,12 @@ should_align_comp_lit :: proc(p: ^Printer, comp_lit: ast.Comp_Lit) -> bool {
for expr in comp_lit.elems {
if field, ok := expr.derived.(^ast.Field_Value); ok {
#partial switch v in field.value.derived {
- case ^ast.Proc_Type, ^ast.Proc_Lit:
- return false
+ case ^ast.Proc_Type, ^ast.Proc_Lit:
+ return false
}
}
}
-
+
return true
}
@@ -966,7 +1291,7 @@ comp_lit_contains_fields :: proc(p: ^Printer, comp_lit: ast.Comp_Lit) -> bool {
return true
}
}
-
+
return false
}
@@ -979,17 +1304,21 @@ comp_lit_contains_blocks :: proc(p: ^Printer, comp_lit: ast.Comp_Lit) -> bool {
for expr in comp_lit.elems {
if field, ok := expr.derived.(^ast.Field_Value); ok {
#partial switch v in field.value.derived {
- case ^ast.Proc_Type, ^ast.Proc_Lit:
- return true
+ case ^ast.Proc_Type, ^ast.Proc_Lit:
+ return true
}
}
}
-
+
return false
}
@(private)
-contains_comments_in_range :: proc(p: ^Printer, pos: tokenizer.Pos, end: tokenizer.Pos) -> bool {
+contains_comments_in_range :: proc(
+ p: ^Printer,
+ pos: tokenizer.Pos,
+ end: tokenizer.Pos,
+) -> bool {
for i := p.latest_comment_index; i < len(p.comments); i += 1 {
for c in p.comments[i].list {
if pos.offset <= c.pos.offset && c.pos.offset <= end.offset {
@@ -1003,7 +1332,7 @@ contains_comments_in_range :: proc(p: ^Printer, pos: tokenizer.Pos, end: tokeniz
@(private)
contains_do_in_expression :: proc(p: ^Printer, expr: ^ast.Expr) -> bool {
found_do := false
-
+
visit_fn :: proc(visitor: ^ast.Visitor, node: ^ast.Node) -> ^ast.Visitor {
if node == nil {
return nil
@@ -1034,21 +1363,40 @@ push_where_clauses :: proc(p: ^Printer, clauses: []^ast.Expr) -> ^Document {
if len(clauses) == 0 {
return empty()
}
-
- return group(nest(cons_with_nopl(text("where"), visit_exprs(p, clauses, {.Add_Comma, .Enforce_Newline}))))
+
+ return group(
+ nest(
+ cons_with_nopl(
+ text("where"),
+ visit_exprs(p, clauses, {.Add_Comma, .Enforce_Newline}),
+ ),
+ ),
+ )
}
@(private)
-visit_poly_params :: proc(p: ^Printer, poly_params: ^ast.Field_List) -> ^Document {
+visit_poly_params :: proc(
+ p: ^Printer,
+ poly_params: ^ast.Field_List,
+) -> ^Document {
if poly_params != nil {
- return cons(text("("), visit_signature_list(p, poly_params, true, false), text(")"))
+ return cons(
+ text("("),
+ visit_signature_list(p, poly_params, true, false),
+ text(")"),
+ )
} else {
return empty()
}
}
@(private)
-visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type = .Generic, options := List_Options{}) -> ^Document {
+visit_expr :: proc(
+ p: ^Printer,
+ expr: ^ast.Expr,
+ called_from: Expr_Called_Type = .Generic,
+ options := List_Options{},
+) -> ^Document {
using ast
if expr == nil {
@@ -1062,25 +1410,25 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
}
comments, _ := visit_comments(p, expr.pos)
- document := empty();
+ document := empty()
#partial switch v in expr.derived {
case ^Inline_Asm_Expr:
document = cons(
- text_token(p, v.tok),
- text("("),
- visit_exprs(p, v.param_types, {.Add_Comma}),
+ text_token(p, v.tok),
+ text("("),
+ visit_exprs(p, v.param_types, {.Add_Comma}),
text(")"),
)
document = cons_with_opl(document, cons(text("-"), text(">")))
document = cons_with_opl(document, visit_expr(p, v.return_type))
document = cons(
- document,
- text("{"),
- visit_expr(p, v.asm_string),
- text(","),
- visit_expr(p, v.constraints_string),
+ document,
+ text("{"),
+ visit_expr(p, v.asm_string),
+ text(","),
+ visit_expr(p, v.constraints_string),
text("}"),
)
case ^Undef:
@@ -1109,7 +1457,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
break_with_space(),
text_token(p, v.op1),
break_with_no_newline(),
- group(visit_expr(p,v.x)),
+ group(visit_expr(p, v.x)),
if_break(" \\"),
break_with_space(),
text_token(p, v.op2),
@@ -1117,7 +1465,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
group(visit_expr(p, v.y)),
)
}
- document = group(document)
+ document = group(document)
case ^Ternary_When_Expr:
document = visit_expr(p, v.x)
document = cons_with_nopl(document, text_token(p, v.op1))
@@ -1129,10 +1477,13 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons_with_opl(document, text_token(p, v.token))
document = cons_with_opl(document, visit_expr(p, v.y))
case ^Or_Return_Expr:
- document = cons_with_nopl(visit_expr(p, v.expr), text_token(p, v.token))
+ document = cons_with_nopl(
+ visit_expr(p, v.expr),
+ text_token(p, v.token),
+ )
case ^Selector_Call_Expr:
document = cons(
- visit_expr(p, v.call.expr),
+ visit_expr(p, v.call.expr),
text("("),
visit_exprs(p, v.call.args, {.Add_Comma}),
text(")"),
@@ -1144,12 +1495,12 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
case ^Slice_Expr:
document = visit_expr(p, v.expr)
document = cons(
- visit_expr(p, v.expr),
+ visit_expr(p, v.expr),
text("["),
visit_expr(p, v.low),
text(v.interval.text),
)
-
+
if v.high != nil {
document = cons(document, visit_expr(p, v.high))
}
@@ -1160,7 +1511,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons(visit_expr(p, v.expr), text_token(p, v.op))
case ^Type_Cast:
document = cons(
- text_token(p, v.tok),
+ text_token(p, v.tok),
text("("),
visit_expr(p, v.type),
text(")"),
@@ -1169,30 +1520,38 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
case ^Basic_Directive:
document = cons(text_token(p, v.tok), text_position(p, v.name, v.pos))
case ^Distinct_Type:
- document = cons_with_opl(text_position(p, "distinct", v.pos), visit_expr(p, v.type))
+ document = cons_with_opl(
+ text_position(p, "distinct", v.pos),
+ visit_expr(p, v.type),
+ )
case ^Dynamic_Array_Type:
document = cons(
- visit_expr(p, v.tag),
- document, text("["),
+ visit_expr(p, v.tag),
+ document,
+ text("["),
text("dynamic"),
text("]"),
visit_expr(p, v.elem),
)
case ^Bit_Set_Type:
document = cons(
- text_position(p, "bit_set", v.pos),
- document, text("["),
+ text_position(p, "bit_set", v.pos),
+ document,
+ text("["),
visit_expr(p, v.elem),
)
if v.underlying != nil {
- document = cons(document, cons(text(";"), visit_expr(p, v.underlying)))
+ document = cons(
+ document,
+ cons(text(";"), visit_expr(p, v.underlying)),
+ )
}
document = cons(document, text("]"))
case ^Union_Type:
document = cons(
- text_position(p, "union", v.pos),
+ text_position(p, "union", v.pos),
visit_poly_params(p, v.poly_params),
)
@@ -1202,16 +1561,34 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
case .shared_nil:
document = cons_with_opl(document, text("#shared_nil"))
}
-
- document = cons_with_nopl(document, push_where_clauses(p, v.where_clauses))
+
+ document = cons_with_nopl(
+ document,
+ push_where_clauses(p, v.where_clauses),
+ )
if len(v.variants) == 0 {
document = cons_with_nopl(document, text("{"))
document = cons(document, text("}"))
} else {
- document = cons_with_nopl(document, visit_begin_brace(p, v.pos, .Generic))
+ document = cons_with_nopl(
+ document,
+ visit_begin_brace(p, v.pos, .Generic),
+ )
set_source_position(p, v.variants[0].pos)
- document = cons(document, nest(cons(newline_position(p, 1, v.pos), visit_union_exprs(p, v^, {.Add_Comma, .Trailing, .Enforce_Newline}))))
+ document = cons(
+ document,
+ nest(
+ cons(
+ newline_position(p, 1, v.pos),
+ visit_union_exprs(
+ p,
+ v^,
+ {.Add_Comma, .Trailing, .Enforce_Newline},
+ ),
+ ),
+ ),
+ )
set_source_position(p, v.end)
document = cons(document, newline(1), text_position(p, "}", v.end))
@@ -1227,18 +1604,34 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons_with_nopl(document, text("{"))
document = cons(document, text("}"))
} else {
- document = cons(document, break_with_space(), visit_begin_brace(p, v.pos, .Generic))
+ document = cons(
+ document,
+ break_with_space(),
+ visit_begin_brace(p, v.pos, .Generic),
+ )
set_source_position(p, v.fields[0].pos)
- document = cons(document, nest(cons(newline_position(p, 1, v.open), visit_enum_exprs(p, v^, {.Add_Comma, .Trailing, .Enforce_Newline}))))
+ document = cons(
+ document,
+ nest(
+ cons(
+ newline_position(p, 1, v.open),
+ visit_enum_exprs(
+ p,
+ v^,
+ {.Add_Comma, .Trailing, .Enforce_Newline},
+ ),
+ ),
+ ),
+ )
set_source_position(p, v.end)
-
+
document = cons(document, newline(1), text_position(p, "}", v.end))
}
set_source_position(p, v.end)
case ^Struct_Type:
document = text_position(p, "struct", v.pos)
-
+
document = cons(document, visit_poly_params(p, v.poly_params))
if v.is_packed {
@@ -1254,21 +1647,44 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons_with_nopl(document, visit_expr(p, v.align))
}
- document = cons_with_nopl(document, push_where_clauses(p, v.where_clauses))
+ document = cons_with_nopl(
+ document,
+ push_where_clauses(p, v.where_clauses),
+ )
if v.fields != nil && len(v.fields.list) == 0 {
document = cons_with_nopl(document, text("{"))
- document = cons(document, visit_struct_field_list(p, v.fields, {.Add_Comma}), text("}"))
+ document = cons(
+ document,
+ visit_struct_field_list(p, v.fields, {.Add_Comma}),
+ text("}"),
+ )
} else if v.fields != nil {
- document = cons(document, break_with_space(), visit_begin_brace(p, v.pos, .Generic))
-
+ document = cons(
+ document,
+ break_with_space(),
+ visit_begin_brace(p, v.pos, .Generic),
+ )
+
set_source_position(p, v.fields.pos)
- document = cons(document, nest(cons(newline_position(p, 1, v.fields.open), visit_struct_field_list(p, v.fields, {.Add_Comma, .Trailing, .Enforce_Newline}))))
+ document = cons(
+ document,
+ nest(
+ cons(
+ newline_position(p, 1, v.fields.open),
+ visit_struct_field_list(
+ p,
+ v.fields,
+ {.Add_Comma, .Trailing, .Enforce_Newline},
+ ),
+ ),
+ ),
+ )
set_source_position(p, v.fields.end)
document = cons(document, newline(1), text_position(p, "}", v.end))
}
-
+
set_source_position(p, v.end)
case ^Proc_Lit:
switch v.inlining {
@@ -1279,13 +1695,22 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons(document, text("#force_no_inline"))
}
- document = cons_with_nopl(document, visit_proc_type(p, v.type^, v.body != nil))
- document = cons_with_nopl(document, push_where_clauses(p, v.where_clauses))
+ document = cons_with_nopl(
+ document,
+ visit_proc_type(p, v.type^, v.body != nil),
+ )
+ document = cons_with_nopl(
+ document,
+ push_where_clauses(p, v.where_clauses),
+ )
document = cons_with_opl(document, visit_proc_tags(p, v.tags))
if v.body != nil {
set_source_position(p, v.body.pos)
- document = cons_with_nopl(document, group(visit_stmt(p, v.body, .Proc)))
+ document = cons_with_nopl(
+ document,
+ group(visit_stmt(p, v.body, .Proc)),
+ )
} else {
document = cons_with_nopl(document, text("---"))
}
@@ -1308,11 +1733,20 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
}
if is_call_expr_nestable(v.args) {
- document = cons(document, nest(cons(break_with(""), visit_call_exprs(p, v))))
+ document = cons(
+ document,
+ nest(cons(break_with(""), visit_call_exprs(p, v))),
+ )
} else {
- document = cons(document, nest_if_break(cons(break_with(""), visit_call_exprs(p, v)), "call_expr"))
+ document = cons(
+ document,
+ nest_if_break(
+ cons(break_with(""), visit_call_exprs(p, v)),
+ "call_expr",
+ ),
+ )
}
-
+
document = cons(document, break_with(""), text(")"))
//Binary expression are nested on operators, and therefore undo the nesting in the call expression.
@@ -1322,25 +1756,41 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
//We enforce a break if comments exists inside the call args
if contains_comments {
- document = enforce_break(document, Document_Group_Options { id = "call_expr" })
- } else if contains_do {
+ document = enforce_break(
+ document,
+ Document_Group_Options{id = "call_expr"},
+ )
+ } else if contains_do {
document = enforce_fit(document)
} else {
- document = group(document, Document_Group_Options { id = "call_expr" })
+ document = group(
+ document,
+ Document_Group_Options{id = "call_expr"},
+ )
}
case ^Typeid_Type:
document = text("typeid")
if v.specialization != nil {
- document = cons(document, text("/"), visit_expr(p, v.specialization))
+ document = cons(
+ document,
+ text("/"),
+ visit_expr(p, v.specialization),
+ )
}
case ^Selector_Expr:
- document = cons(visit_expr(p, v.expr), text_token(p, v.op), visit_expr(p, v.field))
+ document = cons(
+ visit_expr(p, v.expr),
+ text_token(p, v.op),
+ visit_expr(p, v.field),
+ )
case ^Paren_Expr:
- document = group(cons(text("("), nest(visit_expr(p, v.expr)), text(")")))
+ document = group(
+ cons(text("("), nest(visit_expr(p, v.expr)), text(")")),
+ )
case ^Index_Expr:
document = cons(
- visit_expr(p, v.expr),
+ visit_expr(p, v.expr),
text("["),
nest(
cons(
@@ -1356,13 +1806,28 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = text_token(p, v.tok)
if len(v.args) != 0 {
- document = cons_with_nopl(document, visit_begin_brace(p, v.pos, .Generic))
+ document = cons_with_nopl(
+ document,
+ visit_begin_brace(p, v.pos, .Generic),
+ )
set_source_position(p, v.args[0].pos)
- document = cons(document, nest(cons(newline_position(p, 1, v.args[0].pos), visit_exprs(p, v.args, {.Add_Comma, .Trailing, .Enforce_Newline}))))
+ document = cons(
+ document,
+ nest(
+ cons(
+ newline_position(p, 1, v.args[0].pos),
+ visit_exprs(
+ p,
+ v.args,
+ {.Add_Comma, .Trailing, .Enforce_Newline},
+ ),
+ ),
+ ),
+ )
document = cons(document, visit_end_brace(p, v.end, 1))
} else {
document = cons(
- document,
+ document,
text("{"),
visit_exprs(p, v.args, {.Add_Comma}),
text("}"),
@@ -1375,37 +1840,78 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
if v.type != nil {
document = cons_with_nopl(document, visit_expr(p, v.type))
-
- if matrix_type, ok := v.type.derived.(^ast.Matrix_Type); ok && len(v.elems) > 0 && is_matrix_type_constant(matrix_type) {
- document = cons_with_nopl(document, visit_begin_brace(p, v.pos, .Generic))
+
+ if matrix_type, ok := v.type.derived.(^ast.Matrix_Type);
+ ok && len(v.elems) > 0 && is_matrix_type_constant(matrix_type) {
+ document = cons_with_nopl(
+ document,
+ visit_begin_brace(p, v.pos, .Generic),
+ )
set_source_position(p, v.open)
- document = cons(document, nest(cons(newline_position(p, 1, v.elems[0].pos), visit_matrix_comp_lit(p, v, matrix_type))))
+ document = cons(
+ document,
+ nest(
+ cons(
+ newline_position(p, 1, v.elems[0].pos),
+ visit_matrix_comp_lit(p, v, matrix_type),
+ ),
+ ),
+ )
set_source_position(p, v.end)
- document = cons(document, newline(1), text_position(p, "}", v.end))
-
+ document = cons(
+ document,
+ newline(1),
+ text_position(p, "}", v.end),
+ )
+
break
}
}
- should_newline := comp_lit_contains_fields(p, v^) || contains_comments_in_range(p, v.pos, v.end)
- should_newline &= (called_from == .Value_Decl || called_from == .Assignment_Stmt || (called_from == .Call_Expr && comp_lit_contains_blocks(p, v^)))
+ should_newline :=
+ comp_lit_contains_fields(p, v^) ||
+ contains_comments_in_range(p, v.pos, v.end)
+ should_newline &=
+ (called_from == .Value_Decl ||
+ called_from == .Assignment_Stmt ||
+ (called_from == .Call_Expr && comp_lit_contains_blocks(p, v^)))
should_newline &= len(v.elems) != 0
-
+
if should_newline {
- document = cons_with_nopl(document, visit_begin_brace(p, v.pos, .Generic))
-
+ document = cons_with_nopl(
+ document,
+ visit_begin_brace(p, v.pos, .Generic),
+ )
+
set_source_position(p, v.open)
- document = cons(document, nest(cons(newline_position(p, 1, v.elems[0].pos), visit_comp_lit_exprs(p, v^, {.Add_Comma, .Trailing, .Enforce_Newline}))))
+ document = cons(
+ document,
+ nest(
+ cons(
+ newline_position(p, 1, v.elems[0].pos),
+ visit_comp_lit_exprs(
+ p,
+ v^,
+ {.Add_Comma, .Trailing, .Enforce_Newline},
+ ),
+ ),
+ ),
+ )
set_source_position(p, v.end)
document = cons(document, newline(1), text_position(p, "}", v.end))
} else {
document = cons(
- document,
+ document,
text("{"),
- nest(cons(break_with(""), visit_exprs(p, v.elems, {.Add_Comma, .Group}))),
+ nest(
+ cons(
+ break_with(""),
+ visit_exprs(p, v.elems, {.Add_Comma, .Group}),
+ ),
+ ),
if_break(","),
break_with(""),
text("}"),
@@ -1415,15 +1921,22 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
case ^Unary_Expr:
document = cons(text_token(p, v.op), visit_expr(p, v.expr))
case ^Field_Value:
- document = cons_with_nopl(visit_expr(p, v.field), cons_with_nopl(text_position(p, "=", v.sep), visit_expr(p, v.value)))
+ document = cons_with_nopl(
+ visit_expr(p, v.field),
+ cons_with_nopl(
+ text_position(p, "=", v.sep),
+ visit_expr(p, v.value),
+ ),
+ )
case ^Type_Assertion:
document = visit_expr(p, v.expr)
- if unary, ok := v.type.derived.(^Unary_Expr); ok && unary.op.text == "?" {
+ if unary, ok := v.type.derived.(^Unary_Expr);
+ ok && unary.op.text == "?" {
document = cons(document, text("."), visit_expr(p, v.type))
} else {
document = cons(
- document,
+ document,
text("."),
text("("),
visit_expr(p, v.type),
@@ -1441,14 +1954,14 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
if v.specialization != nil {
document = cons(
- document,
+ document,
text("/"),
visit_expr(p, v.specialization),
)
}
case ^Array_Type:
document = cons(
- visit_expr(p, v.tag),
+ visit_expr(p, v.tag),
text("["),
visit_expr(p, v.len),
text("]"),
@@ -1456,7 +1969,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
)
case ^Map_Type:
document = cons(
- text("map"),
+ text("map"),
text("["),
visit_expr(p, v.key),
text("]"),
@@ -1469,7 +1982,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons_with_nopl(document, visit_expr(p, v.type))
case ^Matrix_Type:
document = cons(
- text_position(p, "matrix", v.pos),
+ text_position(p, "matrix", v.pos),
text("["),
visit_expr(p, v.row_count),
text(","),
@@ -1479,7 +1992,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons(group(document), visit_expr(p, v.elem))
case ^Matrix_Index_Expr:
document = cons(
- visit_expr(p, v.expr),
+ visit_expr(p, v.expr),
text("["),
visit_expr(p, v.row_index),
text(","),
@@ -1495,12 +2008,14 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
@(private)
is_matrix_type_constant :: proc(matrix_type: ^ast.Matrix_Type) -> bool {
- if row_count, is_lit := matrix_type.row_count.derived.(^ast.Basic_Lit); is_lit {
+ if row_count, is_lit := matrix_type.row_count.derived.(^ast.Basic_Lit);
+ is_lit {
_, ok := strconv.parse_int(row_count.tok.text)
return ok
}
- if column_count, is_lit := matrix_type.column_count.derived.(^ast.Basic_Lit); is_lit {
+ if column_count, is_lit := matrix_type.column_count.derived.(^ast.Basic_Lit);
+ is_lit {
_, ok := strconv.parse_int(column_count.tok.text)
return ok
}
@@ -1509,16 +2024,27 @@ is_matrix_type_constant :: proc(matrix_type: ^ast.Matrix_Type) -> bool {
}
@(private)
-visit_matrix_comp_lit :: proc(p: ^Printer, comp_lit: ^ast.Comp_Lit, matrix_type: ^ast.Matrix_Type) -> ^Document {
+visit_matrix_comp_lit :: proc(
+ p: ^Printer,
+ comp_lit: ^ast.Comp_Lit,
+ matrix_type: ^ast.Matrix_Type,
+) -> ^Document {
document := empty()
//these values have already been validated
- row_count, _ := strconv.parse_int(matrix_type.row_count.derived.(^ast.Basic_Lit).tok.text)
- column_count, _ := strconv.parse_int(matrix_type.column_count.derived.(^ast.Basic_Lit).tok.text)
+ row_count, _ := strconv.parse_int(
+ matrix_type.row_count.derived.(^ast.Basic_Lit).tok.text,
+ )
+ column_count, _ := strconv.parse_int(
+ matrix_type.column_count.derived.(^ast.Basic_Lit).tok.text,
+ )
for row := 0; row < row_count; row += 1 {
for column := 0; column < column_count; column += 1 {
- document = cons(document, visit_expr(p, comp_lit.elems[column + row * column_count]))
+ document = cons(
+ document,
+ visit_expr(p, comp_lit.elems[column + row * column_count]),
+ )
document = cons(document, text(", "))
}
@@ -1526,13 +2052,19 @@ visit_matrix_comp_lit :: proc(p: ^Printer, comp_lit: ^ast.Comp_Lit, matrix_type:
document = cons(document, newline(1))
}
}
-
+
return document
}
@(private)
-visit_begin_brace :: proc(p: ^Printer, begin: tokenizer.Pos, type: Block_Type, count := 0, same_line_spaces_before := 1) -> ^Document {
+visit_begin_brace :: proc(
+ p: ^Printer,
+ begin: tokenizer.Pos,
+ type: Block_Type,
+ count := 0,
+ same_line_spaces_before := 1,
+) -> ^Document {
set_source_position(p, begin)
set_comment_option(p, begin.line, .Indent)
@@ -1550,7 +2082,11 @@ visit_begin_brace :: proc(p: ^Printer, begin: tokenizer.Pos, type: Block_Type, c
}
@(private)
-visit_end_brace :: proc(p: ^Printer, end: tokenizer.Pos, limit := 0) -> ^Document {
+visit_end_brace :: proc(
+ p: ^Printer,
+ end: tokenizer.Pos,
+ limit := 0,
+) -> ^Document {
if limit == 0 {
return cons(move_line(p, end), text("}"))
} else {
@@ -1564,12 +2100,16 @@ visit_end_brace :: proc(p: ^Printer, end: tokenizer.Pos, limit := 0) -> ^Documen
}
@(private)
-visit_block_stmts :: proc(p: ^Printer, stmts: []^ast.Stmt, split := false) -> ^Document {
+visit_block_stmts :: proc(
+ p: ^Printer,
+ stmts: []^ast.Stmt,
+ split := false,
+) -> ^Document {
document := empty()
for stmt, i in stmts {
- last_index := max(0, i-1)
- if stmts[last_index].end.line == stmt.pos.line && i != 0 {
+ last_index := max(0, i - 1)
+ if stmts[last_index].end.line == stmt.pos.line && i != 0 {
document = cons(document, break_with(";"))
}
document = cons(document, visit_stmt(p, stmt, .Generic, false, true))
@@ -1589,7 +2129,11 @@ List_Option :: enum u8 {
List_Options :: distinct bit_set[List_Option]
@(private)
-visit_struct_field_list :: proc(p: ^Printer, list: ^ast.Field_List, options := List_Options{}) -> ^Document {
+visit_struct_field_list :: proc(
+ p: ^Printer,
+ list: ^ast.Field_List,
+ options := List_Options{},
+) -> ^Document {
document := empty()
if list.list == nil {
return document
@@ -1601,7 +2145,7 @@ visit_struct_field_list :: proc(p: ^Printer, list: ^ast.Field_List, options := L
p.source_position = field.pos
if i == 0 && .Enforce_Newline in options {
- comment, ok := visit_comments(p, list.list[i].pos)
+ comment, ok := visit_comments(p, list.list[i].pos)
if _, is_nil := comment.(Document_Nil); !is_nil {
comment = cons(comment, newline(1))
}
@@ -1613,7 +2157,11 @@ visit_struct_field_list :: proc(p: ^Printer, list: ^ast.Field_List, options := L
}
if .Subtype in field.flags {
- document = cons(document, text("#subtype"), break_with_no_newline())
+ document = cons(
+ document,
+ text("#subtype"),
+ break_with_no_newline(),
+ )
}
name_options := List_Options{.Add_Comma}
@@ -1633,10 +2181,16 @@ visit_struct_field_list :: proc(p: ^Printer, list: ^ast.Field_List, options := L
}
}
align = repeat_space(alignment - length)
- }
- document = cons(document, visit_exprs(p, field.names, name_options))
+ }
+ document = cons(
+ document,
+ visit_exprs(p, field.names, name_options),
+ )
} else {
- document = cons_with_opl(document, visit_exprs(p, field.names, name_options))
+ document = cons_with_opl(
+ document,
+ visit_exprs(p, field.names, name_options),
+ )
}
if field.type != nil {
@@ -1646,19 +2200,23 @@ visit_struct_field_list :: proc(p: ^Printer, list: ^ast.Field_List, options := L
document = cons_with_opl(document, visit_expr(p, field.type))
} else {
document = cons(document, text(":"), text("="))
- document = cons_with_opl(document, visit_expr(p, field.default_value))
+ document = cons_with_opl(
+ document,
+ visit_expr(p, field.default_value),
+ )
}
if field.tag.text != "" {
document = cons_with_nopl(document, text_token(p, field.tag))
}
- if (i != len(list.list) - 1 || .Trailing in options) && .Add_Comma in options {
+ if (i != len(list.list) - 1 || .Trailing in options) &&
+ .Add_Comma in options {
document = cons(document, text(","))
}
if i != len(list.list) - 1 && .Enforce_Newline in options {
- comment, _ := visit_comments(p, list.list[i+1].pos)
+ comment, _ := visit_comments(p, list.list[i + 1].pos)
document = cons(document, comment, newline(1))
} else {
comment, _ := visit_comments(p, list.end)
@@ -1692,7 +2250,11 @@ visit_proc_tags :: proc(p: ^Printer, proc_tags: ast.Proc_Tags) -> ^Document {
}
@(private)
-visit_proc_type :: proc(p: ^Printer, proc_type: ast.Proc_Type, contains_body: bool) -> ^Document {
+visit_proc_type :: proc(
+ p: ^Printer,
+ proc_type: ast.Proc_Type,
+ contains_body: bool,
+) -> ^Document {
document := text("proc")
explicit_calling := false
@@ -1708,7 +2270,15 @@ visit_proc_type :: proc(p: ^Printer, proc_type: ast.Proc_Type, contains_body: bo
document = cons(document, text("("))
}
- document = cons(document, nest(cons(break_with(""), visit_signature_list(p, proc_type.params, true, false))))
+ document = cons(
+ document,
+ nest(
+ cons(
+ break_with(""),
+ visit_signature_list(p, proc_type.params, true, false),
+ ),
+ ),
+ )
document = cons(document, break_with(""), text(")"))
if proc_type.results != nil && len(proc_type.results.list) > 0 {
@@ -1731,10 +2301,35 @@ visit_proc_type :: proc(p: ^Printer, proc_type: ast.Proc_Type, contains_body: bo
if use_parens {
document = cons_with_nopl(document, text("("))
- document = cons(document, nest(cons(break_with(""), visit_signature_list(p, proc_type.results, contains_body, true))))
+ document = cons(
+ document,
+ nest(
+ cons(
+ break_with(""),
+ visit_signature_list(
+ p,
+ proc_type.results,
+ contains_body,
+ true,
+ ),
+ ),
+ ),
+ )
document = cons(document, break_with(""), text(")"))
} else {
- document = cons_with_nopl(document, nest(group(visit_signature_list(p, proc_type.results, contains_body, true))))
+ document = cons_with_nopl(
+ document,
+ nest(
+ group(
+ visit_signature_list(
+ p,
+ proc_type.results,
+ contains_body,
+ true,
+ ),
+ ),
+ ),
+ )
}
} else if proc_type.diverging {
document = cons_with_nopl(document, text("-"))
@@ -1747,22 +2342,34 @@ visit_proc_type :: proc(p: ^Printer, proc_type: ast.Proc_Type, contains_body: bo
@(private)
-visit_binary_expr :: proc(p: ^Printer, binary: ast.Binary_Expr, nested := false) -> ^Document {
+visit_binary_expr :: proc(
+ p: ^Printer,
+ binary: ast.Binary_Expr,
+ nested := false,
+) -> ^Document {
document := empty()
nest_expression := false
- if binary.left != nil {
+ if binary.left != nil {
if b, ok := binary.left.derived.(^ast.Binary_Expr); ok {
pa := parser.Parser {
allow_in_expr = true,
}
- nest_expression = parser.token_precedence(&pa, b.op.kind) != parser.token_precedence(&pa, binary.op.kind)
- document = cons(document, visit_binary_expr(p, b^, nest_expression))
+ nest_expression =
+ parser.token_precedence(&pa, b.op.kind) !=
+ parser.token_precedence(&pa, binary.op.kind)
+ document = cons(
+ document,
+ visit_binary_expr(p, b^, nest_expression),
+ )
} else {
- document = cons(document, visit_expr(p, binary.left, nested ? .Binary_Expr : .Generic))
+ document = cons(
+ document,
+ visit_expr(p, binary.left, nested ? .Binary_Expr : .Generic),
+ )
}
- }
+ }
if nest_expression {
document = nest(document)
@@ -1773,9 +2380,15 @@ visit_binary_expr :: proc(p: ^Printer, binary: ast.Binary_Expr, nested := false)
if binary.right != nil {
if b, ok := binary.right.derived.(^ast.Binary_Expr); ok {
- document = cons_with_opl(document, group(nest(visit_binary_expr(p, b^, true))))
+ document = cons_with_opl(
+ document,
+ group(nest(visit_binary_expr(p, b^, true))),
+ )
} else {
- document = cons_with_opl(document, group(nest(visit_expr(p, binary.right, .Binary_Expr))))
+ document = cons_with_opl(
+ document,
+ group(nest(visit_expr(p, binary.right, .Binary_Expr))),
+ )
}
}
@@ -1794,25 +2407,28 @@ visit_call_exprs :: proc(p: ^Printer, call_expr: ^ast.Call_Expr) -> ^Document {
}
document = cons(document, group(visit_expr(p, expr, .Call_Expr)))
-
+
if i != len(call_expr.args) - 1 {
document = cons(document, text(","))
//need to look for comments before we write the comma with break
- comments, _ := visit_comments(p, call_expr.args[i+1].pos)
+ comments, _ := visit_comments(p, call_expr.args[i + 1].pos)
document = cons(document, comments, break_with_space())
} else {
comments, _ := visit_comments(p, call_expr.close)
document = cons(document, if_break(","), comments)
- }
+ }
}
return document
}
@(private)
-visit_signature_field_flag :: proc(p: ^Printer, flags: ast.Field_Flags) -> ^Document {
+visit_signature_field_flag :: proc(
+ p: ^Printer,
+ flags: ast.Field_Flags,
+) -> ^Document {
document := empty()
if .Auto_Cast in flags {
@@ -1847,24 +2463,39 @@ visit_signature_field_flag :: proc(p: ^Printer, flags: ast.Field_Flags) -> ^Docu
}
@(private)
-visit_signature_list :: proc(p: ^Printer, list: ^ast.Field_List, contains_body: bool, remove_blank: bool) -> ^Document {
+visit_signature_list :: proc(
+ p: ^Printer,
+ list: ^ast.Field_List,
+ contains_body: bool,
+ remove_blank: bool,
+) -> ^Document {
document := empty()
for field, i in list.list {
- document = cons(document, visit_signature_field(p, field, remove_blank))
+ document = cons(
+ document,
+ visit_signature_field(p, field, remove_blank),
+ )
if i != len(list.list) - 1 {
document = cons(document, text(","), break_with_space())
} else {
- document = len(list.list) > 1 || contains_body ? cons(document, if_break(",")) : document
- }
+ document =
+ len(list.list) > 1 || contains_body \
+ ? cons(document, if_break(",")) \
+ : document
+ }
}
return document
}
@(private)
-visit_signature_field :: proc(p: ^Printer, field: ^ast.Field, remove_blank := true) -> ^Document {
+visit_signature_field :: proc(
+ p: ^Printer,
+ field: ^ast.Field,
+ remove_blank := true,
+) -> ^Document {
document := empty()
flag := visit_signature_field_flag(p, field.flags)
@@ -1883,7 +2514,10 @@ visit_signature_field :: proc(p: ^Printer, field: ^ast.Field, remove_blank := tr
}
if named {
- document = cons(document, cons_with_nopl(flag, visit_exprs(p, field.names, {.Add_Comma})))
+ document = cons(
+ document,
+ cons_with_nopl(flag, visit_exprs(p, field.names, {.Add_Comma})),
+ )
if len(field.names) != 0 && field.type != nil {
document = cons(document, text(":"), break_with_no_newline())
@@ -1927,8 +2561,12 @@ get_node_length :: proc(node: ^ast.Node) -> int {
case ^ast.Paren_Expr:
return 1 + get_node_length(v.expr) + 1
case ^ast.Selector_Expr:
- return get_node_length(v.expr) + strings.rune_count(v.op.text) + strings.rune_count(v.field.name)
- case:
+ return(
+ get_node_length(v.expr) +
+ strings.rune_count(v.op.text) +
+ strings.rune_count(v.field.name) \
+ )
+ case:
panic(fmt.aprintf("unhandled get_node_length case %v", node.derived))
}
}
diff --git a/src/server/action.odin b/src/server/action.odin
index 44b3458..ba1b367 100644
--- a/src/server/action.odin
+++ b/src/server/action.odin
@@ -13,4 +13,4 @@ CodeActionClientCapabilities :: struct {
CodeActionOptions :: struct {
codeActionKinds: []CodeActionKind,
resolveProvider: bool,
-} \ No newline at end of file
+}
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index facc202..6113b63 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -29,30 +29,30 @@ DocumentPositionContext :: struct {
position: common.AbsolutePosition,
line: int,
function: ^ast.Proc_Lit, //used to help with type resolving in function scope
- selector: ^ast.Expr, //used for completion
+ selector: ^ast.Expr, //used for completion
selector_expr: ^ast.Selector_Expr,
identifier: ^ast.Node,
implicit_context: ^ast.Implicit,
tag: ^ast.Node,
- field: ^ast.Expr, //used for completion
- call: ^ast.Expr, //used for signature help
+ field: ^ast.Expr, //used for completion
+ call: ^ast.Expr, //used for signature help
returns: ^ast.Return_Stmt, //used for completion
- comp_lit: ^ast.Comp_Lit, //used for completion
- parent_comp_lit: ^ast.Comp_Lit, //used for completion
+ comp_lit: ^ast.Comp_Lit, //used for completion
+ parent_comp_lit: ^ast.Comp_Lit, //used for completion
struct_type: ^ast.Struct_Type,
union_type: ^ast.Union_Type,
bitset_type: ^ast.Bit_Set_Type,
enum_type: ^ast.Enum_Type,
field_value: ^ast.Field_Value,
- implicit: bool, //used for completion
+ implicit: bool, //used for completion
arrow: bool,
- binary: ^ast.Binary_Expr, //used for completion
- parent_binary: ^ast.Binary_Expr, //used for completion
- assign: ^ast.Assign_Stmt, //used for completion
- switch_stmt: ^ast.Switch_Stmt, //used for completion
+ binary: ^ast.Binary_Expr, //used for completion
+ parent_binary: ^ast.Binary_Expr, //used for completion
+ assign: ^ast.Assign_Stmt, //used for completion
+ switch_stmt: ^ast.Switch_Stmt, //used for completion
switch_type_stmt: ^ast.Type_Switch_Stmt, //used for completion
- case_clause: ^ast.Case_Clause, //used for completion
- value_decl: ^ast.Value_Decl, //used for completion
+ case_clause: ^ast.Case_Clause, //used for completion
+ value_decl: ^ast.Value_Decl, //used for completion
abort_completion: bool,
hint: DocumentPositionContextHint,
global_lhs_stmt: bool,
@@ -61,10 +61,10 @@ DocumentPositionContext :: struct {
}
DocumentLocal :: struct {
- lhs: ^ast.Expr,
- rhs: ^ast.Expr,
+ lhs: ^ast.Expr,
+ rhs: ^ast.Expr,
offset: int,
- id: int, //Id that can used to connect the local to something, i.e. for stmt begin offset
+ id: int, //Id that can used to connect the local to something, i.e. for stmt begin offset
}
AstContext :: struct {
@@ -81,7 +81,7 @@ AstContext :: struct {
document_package: string,
use_globals: bool,
use_locals: bool,
- local_id: int,
+ local_id: int,
call: ^ast.Call_Expr, //used to determene the types for generics and the correct function for overloaded functions
position: common.AbsolutePosition,
value_decl: ^ast.Value_Decl,
@@ -91,23 +91,34 @@ AstContext :: struct {
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, fullpath: 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),
- variables = make(map[string]bool, 0, allocator),
- usings = make([dynamic]string, allocator),
- parameters = make(map[string]bool, 0, allocator),
- in_package = make(map[string]string, 0, allocator),
- file = file,
- imports = imports,
- use_locals = true,
- use_globals = true,
+ locals = make(
+ map[int]map[string][dynamic]DocumentLocal,
+ 0,
+ allocator,
+ ),
+ globals = make(map[string]common.GlobalExpr, 0, allocator),
+ variables = make(map[string]bool, 0, allocator),
+ usings = make([dynamic]string, allocator),
+ parameters = make(map[string]bool, 0, allocator),
+ in_package = make(map[string]string, 0, allocator),
+ file = file,
+ imports = imports,
+ use_locals = true,
+ use_globals = true,
document_package = package_name,
- current_package = package_name,
- uri = uri,
- fullpath = fullpath,
- allocator = allocator,
+ current_package = package_name,
+ uri = uri,
+ fullpath = fullpath,
+ allocator = allocator,
}
add_local_group(&ast_context, 0)
@@ -128,7 +139,12 @@ resolve_poly_spec :: proc {
resolve_poly_spec_dynamic_array,
}
-resolve_poly_spec_array :: proc(ast_context: ^AstContext, call_array: $A/[]^$T, spec_array: $D/[]^$K, poly_map: ^map[string]^ast.Expr) {
+resolve_poly_spec_array :: proc(
+ ast_context: ^AstContext,
+ call_array: $A/[]^$T,
+ spec_array: $D/[]^$K,
+ poly_map: ^map[string]^ast.Expr,
+) {
if len(call_array) != len(spec_array) {
return
}
@@ -138,7 +154,12 @@ resolve_poly_spec_array :: proc(ast_context: ^AstContext, call_array: $A/[]^$T,
}
}
-resolve_poly_spec_dynamic_array :: proc(ast_context: ^AstContext, call_array: $A/[dynamic]^$T, spec_array: $D/[dynamic]^$K, poly_map: ^map[string]^ast.Expr) {
+resolve_poly_spec_dynamic_array :: proc(
+ ast_context: ^AstContext,
+ call_array: $A/[dynamic]^$T,
+ spec_array: $D/[dynamic]^$K,
+ poly_map: ^map[string]^ast.Expr,
+) {
if len(call_array) != len(spec_array) {
return
}
@@ -163,7 +184,12 @@ get_poly_node_to_expr :: proc(node: ^ast.Node) -> ^ast.Expr {
return nil
}
-resolve_poly_spec_node :: proc(ast_context: ^AstContext, call_node: ^ast.Node, spec_node: ^ast.Node, poly_map: ^map[string]^ast.Expr) {
+resolve_poly_spec_node :: proc(
+ ast_context: ^AstContext,
+ call_node: ^ast.Node,
+ spec_node: ^ast.Node,
+ poly_map: ^map[string]^ast.Expr,
+) {
using ast
if call_node == nil || spec_node == nil {
@@ -176,7 +202,7 @@ resolve_poly_spec_node :: proc(ast_context: ^AstContext, call_node: ^ast.Node, s
case ^Implicit:
case ^Undef:
case ^Basic_Lit:
- case ^Poly_Type:
+ case ^Poly_Type:
if expr := get_poly_node_to_expr(call_node); expr != nil {
poly_map[m.type.name] = expr
}
@@ -236,7 +262,12 @@ resolve_poly_spec_node :: proc(ast_context: ^AstContext, call_node: ^ast.Node, s
}
case ^Struct_Type:
if n, ok := call_node.derived.(^Struct_Type); ok {
- resolve_poly_spec(ast_context, n.poly_params, m.poly_params, poly_map)
+ resolve_poly_spec(
+ ast_context,
+ n.poly_params,
+ m.poly_params,
+ poly_map,
+ )
resolve_poly_spec(ast_context, n.align, m.align, poly_map)
resolve_poly_spec(ast_context, n.fields, m.fields, poly_map)
}
@@ -244,7 +275,12 @@ resolve_poly_spec_node :: proc(ast_context: ^AstContext, call_node: ^ast.Node, s
if n, ok := call_node.derived.(^Field); ok {
resolve_poly_spec(ast_context, n.names, m.names, poly_map)
resolve_poly_spec(ast_context, n.type, m.type, poly_map)
- resolve_poly_spec(ast_context, n.default_value, m.default_value, poly_map)
+ resolve_poly_spec(
+ ast_context,
+ n.default_value,
+ m.default_value,
+ poly_map,
+ )
}
case ^Field_List:
if n, ok := call_node.derived.(^Field_List); ok {
@@ -257,7 +293,12 @@ resolve_poly_spec_node :: proc(ast_context: ^AstContext, call_node: ^ast.Node, s
}
case ^Union_Type:
if n, ok := call_node.derived.(^Union_Type); ok {
- resolve_poly_spec(ast_context, n.poly_params, m.poly_params, poly_map)
+ resolve_poly_spec(
+ ast_context,
+ n.poly_params,
+ m.poly_params,
+ poly_map,
+ )
resolve_poly_spec(ast_context, n.align, m.align, poly_map)
resolve_poly_spec(ast_context, n.variants, m.variants, poly_map)
}
@@ -269,7 +310,12 @@ resolve_poly_spec_node :: proc(ast_context: ^AstContext, call_node: ^ast.Node, s
case ^Bit_Set_Type:
if n, ok := call_node.derived.(^Bit_Set_Type); ok {
resolve_poly_spec(ast_context, n.elem, m.elem, poly_map)
- resolve_poly_spec(ast_context, n.underlying, m.underlying, poly_map)
+ resolve_poly_spec(
+ ast_context,
+ n.underlying,
+ m.underlying,
+ poly_map,
+ )
}
case ^Map_Type:
if n, ok := call_node.derived.(^Map_Type); ok {
@@ -283,14 +329,28 @@ resolve_poly_spec_node :: proc(ast_context: ^AstContext, call_node: ^ast.Node, s
}
case ^Typeid_Type:
if n, ok := call_node.derived.(^Typeid_Type); ok {
- resolve_poly_spec(ast_context, n.specialization, m.specialization, poly_map)
+ resolve_poly_spec(
+ ast_context,
+ n.specialization,
+ m.specialization,
+ poly_map,
+ )
}
case:
log.error("Unhandled poly node kind: %T", m)
}
}
-resolve_type_comp_literal :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, current_symbol: Symbol, current_comp_lit: ^ast.Comp_Lit) -> (Symbol, ^ast.Comp_Lit, bool) {
+resolve_type_comp_literal :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+ current_symbol: Symbol,
+ current_comp_lit: ^ast.Comp_Lit,
+) -> (
+ Symbol,
+ ^ast.Comp_Lit,
+ bool,
+) {
if position_context.comp_lit == current_comp_lit {
return current_symbol, current_comp_lit, true
} else if current_comp_lit == nil {
@@ -301,7 +361,7 @@ resolve_type_comp_literal :: proc(ast_context: ^AstContext, position_context: ^D
prev_package := ast_context.current_package
ast_context.current_package = current_symbol.pkg
-
+
defer ast_context.current_package = prev_package
for elem, i in current_comp_lit.elems {
@@ -314,35 +374,53 @@ resolve_type_comp_literal :: proc(ast_context: ^AstContext, position_context: ^D
if !position_in_node(elem, position_context.position) {
continue
}
-
- if field_value, ok := elem.derived.(^ast.Field_Value); ok { //named
+
+ if field_value, ok := elem.derived.(^ast.Field_Value); ok { //named
if comp_lit, ok := field_value.value.derived.(^ast.Comp_Lit); ok {
if s, ok := current_symbol.value.(SymbolStructValue); ok {
for name, i in s.names {
- if name == field_value.field.derived.(^ast.Ident).name {
- if symbol, ok := resolve_type_expression(ast_context, s.types[i]); ok {
+ if name ==
+ field_value.field.derived.(^ast.Ident).name {
+ if symbol, ok := resolve_type_expression(
+ ast_context,
+ s.types[i],
+ ); ok {
//Stop at bitset, because we don't want to enter a comp_lit of a bitset
- if _, ok := symbol.value.(SymbolBitSetValue); ok {
+ if _, ok := symbol.value.(SymbolBitSetValue);
+ ok {
return current_symbol, current_comp_lit, true
}
- return resolve_type_comp_literal(ast_context, position_context, symbol, cast(^ast.Comp_Lit)field_value.value)
+ return resolve_type_comp_literal(
+ ast_context,
+ position_context,
+ symbol,
+ cast(^ast.Comp_Lit)field_value.value,
+ )
}
}
}
}
}
- } else if comp_value, ok := elem.derived.(^ast.Comp_Lit); ok { //indexed
+ } else if comp_value, ok := elem.derived.(^ast.Comp_Lit); ok { //indexed
if s, ok := current_symbol.value.(SymbolStructValue); ok {
if len(s.types) <= element_index {
return {}, {}, false
}
- if symbol, ok := resolve_type_expression(ast_context, s.types[element_index]); ok {
+ if symbol, ok := resolve_type_expression(
+ ast_context,
+ s.types[element_index],
+ ); ok {
//Stop at bitset, because we don't want to enter a comp_lit of a bitset
if _, ok := symbol.value.(SymbolBitSetValue); ok {
return current_symbol, current_comp_lit, true
}
- return resolve_type_comp_literal(ast_context, position_context, symbol, comp_value)
+ return resolve_type_comp_literal(
+ ast_context,
+ position_context,
+ symbol,
+ comp_value,
+ )
}
}
}
@@ -356,7 +434,14 @@ resolve_generic_function :: proc {
resolve_generic_function_symbol,
}
-resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast.Field, results: []^ast.Field) -> (Symbol, bool) {
+resolve_generic_function_symbol :: proc(
+ ast_context: ^AstContext,
+ params: []^ast.Field,
+ results: []^ast.Field,
+) -> (
+ Symbol,
+ bool,
+) {
if params == nil {
return {}, false
}
@@ -372,7 +457,7 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast
call_expr := ast_context.call
poly_map := make(map[string]^ast.Expr, 0, context.temp_allocator)
i := 0
- count_required_params := 0
+ count_required_params := 0
for param in params {
if param.default_value == nil {
@@ -393,18 +478,29 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast
}
if type_id, ok := param.type.derived.(^ast.Typeid_Type); ok {
- if type_id.specialization != nil && !common.node_equal(call_expr.args[i], type_id.specialization) {
+ if type_id.specialization != nil &&
+ !common.node_equal(
+ call_expr.args[i],
+ type_id.specialization,
+ ) {
return {}, false
}
}
- resolve_poly_spec_node(ast_context, call_expr.args[i], param.type, &poly_map)
+ resolve_poly_spec_node(
+ ast_context,
+ call_expr.args[i],
+ param.type,
+ &poly_map,
+ )
i += 1
}
}
- if count_required_params > len(call_expr.args) || count_required_params == 0 || len(call_expr.args) == 0 {
+ if count_required_params > len(call_expr.args) ||
+ count_required_params == 0 ||
+ len(call_expr.args) == 0 {
return {}, false
}
@@ -423,8 +519,8 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast
symbol := Symbol {
range = function_range,
- type = .Function,
- name = function_name,
+ type = .Function,
+ name = function_name,
}
return_types := make([dynamic]^ast.Field, ast_context.allocator)
@@ -439,7 +535,11 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast
if ok {
if m, ok := poly_map[ident.name]; ok {
- field := cast(^ast.Field)clone_node(result, ast_context.allocator, nil)
+ field := cast(^ast.Field)clone_node(
+ result,
+ ast_context.allocator,
+ nil,
+ )
field.type = m
append(&return_types, field)
} else {
@@ -456,9 +556,14 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast
}
//check the name for poly
- if poly_type, ok := param.names[0].derived.(^ast.Poly_Type); ok && param.type != nil {
+ if poly_type, ok := param.names[0].derived.(^ast.Poly_Type);
+ ok && param.type != nil {
if m, ok := poly_map[poly_type.type.name]; ok {
- field := cast(^ast.Field)clone_node(param, ast_context.allocator, nil)
+ field := cast(^ast.Field)clone_node(
+ param,
+ ast_context.allocator,
+ nil,
+ )
field.type = m
append(&argument_types, field)
}
@@ -469,55 +574,78 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast
symbol.value = SymbolProcedureValue {
return_types = return_types[:],
- arg_types = argument_types[:],
+ arg_types = argument_types[:],
}
return symbol, true
}
-resolve_generic_function_ast :: proc(ast_context: ^AstContext, proc_lit: ast.Proc_Lit) -> (Symbol, bool) {
+resolve_generic_function_ast :: proc(
+ ast_context: ^AstContext,
+ proc_lit: ast.Proc_Lit,
+) -> (
+ Symbol,
+ bool,
+) {
using ast
if proc_lit.type.params == nil {
- return Symbol {}, false
+ return Symbol{}, false
}
if proc_lit.type.results == nil {
- return Symbol {}, false
+ return Symbol{}, false
}
if ast_context.call == nil {
- return Symbol {}, false
+ return Symbol{}, false
}
- return resolve_generic_function_symbol(ast_context, proc_lit.type.params.list, proc_lit.type.results.list)
+ return resolve_generic_function_symbol(
+ ast_context,
+ proc_lit.type.params.list,
+ proc_lit.type.results.list,
+ )
}
-is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: Symbol, flags: ast.Field_Flags = {}) -> bool {
+is_symbol_same_typed :: proc(
+ ast_context: ^AstContext,
+ a,
+ b: Symbol,
+ flags: ast.Field_Flags = {},
+) -> bool {
//relying on the fact that a is the call argument to avoid checking both sides for untyped.
if untyped, ok := a.value.(SymbolUntypedValue); ok {
if basic, ok := b.value.(SymbolBasicValue); ok {
switch untyped.type {
case .Integer:
switch basic.ident.name {
- case "int", "uint", "u32", "i32", "u8", "i8", "u64", "u16", "i16": return true
- case: return false
+ case "int", "uint", "u32", "i32", "u8", "i8", "u64", "u16", "i16":
+ return true
+ case:
+ return false
}
case .Bool:
switch basic.ident.name {
- case "bool", "b32", "b64": return true
- case: return false
+ case "bool", "b32", "b64":
+ return true
+ case:
+ return false
}
case .String:
switch basic.ident.name {
- case "string", "cstring": return true
- case: return false
+ case "string", "cstring":
+ return true
+ case:
+ return false
}
case .Float:
switch basic.ident.name {
- case "f32", "f64": return true
- case: return false
+ case "f32", "f64":
+ return true
+ case:
+ return false
}
}
}
@@ -538,12 +666,12 @@ is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: Symbol, flags: ast.
return false
}
- if .Distinct in a.flags == .Distinct in b.flags &&
+ if .Distinct in a.flags == .Distinct in b.flags &&
.Distinct in a.flags &&
a.name == b.name &&
a.pkg == b.pkg {
return true
- }
+ }
#partial switch b_value in b.value {
case SymbolBasicValue:
@@ -553,9 +681,10 @@ is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: Symbol, flags: ast.
//Temporary - make a function that finds the base type of basic values
//This code only works with non distinct ints
switch a.name {
- case "int", "uint", "u32", "i32", "u8", "i8", "u64", "u16", "i16": return true
+ case "int", "uint", "u32", "i32", "u8", "i8", "u64", "u16", "i16":
+ return true
}
- }
+ }
}
#partial switch a_value in a.value {
@@ -664,32 +793,47 @@ is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: Symbol, flags: ast.
return false
}
- a_value_symbol, ok = resolve_type_expression(ast_context, a_value.value)
+ a_value_symbol, ok = resolve_type_expression(
+ ast_context,
+ a_value.value,
+ )
if !ok {
return false
}
- b_value_symbol, ok = resolve_type_expression(ast_context, b_value.value)
+ b_value_symbol, ok = resolve_type_expression(
+ ast_context,
+ b_value.value,
+ )
if !ok {
return false
}
- return is_symbol_same_typed(ast_context, a_key_symbol, b_key_symbol) && is_symbol_same_typed(ast_context, a_value_symbol, b_value_symbol)
+ return(
+ is_symbol_same_typed(ast_context, a_key_symbol, b_key_symbol) &&
+ is_symbol_same_typed(ast_context, a_value_symbol, b_value_symbol) \
+ )
}
-
+
return false
}
-get_field_list_name_index :: proc(name: string, field_list: []^ast.Field) -> (int, bool) {
+get_field_list_name_index :: proc(
+ name: string,
+ field_list: []^ast.Field,
+) -> (
+ int,
+ bool,
+) {
for field, i in field_list {
for field_name in field.names {
if ident, ok := field_name.derived.(^ast.Ident); ok {
if name == ident.name {
return i, true
}
- }
+ }
}
}
@@ -699,7 +843,13 @@ get_field_list_name_index :: proc(name: string, field_list: []^ast.Field) -> (in
/*
Figure out which function the call expression is using out of the list from proc group
*/
-resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Group) -> (Symbol, bool) {
+resolve_function_overload :: proc(
+ ast_context: ^AstContext,
+ group: ast.Proc_Group,
+) -> (
+ Symbol,
+ bool,
+) {
using ast
call_expr := ast_context.call
@@ -707,7 +857,8 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
candidates := make([dynamic]Symbol, context.temp_allocator)
for arg_expr in group.args {
- next_fn: if f, ok := resolve_type_expression(ast_context, arg_expr); ok {
+ next_fn: if f, ok := resolve_type_expression(ast_context, arg_expr);
+ ok {
if call_expr == nil || len(call_expr.args) == 0 {
append(&candidates, f)
break next_fn
@@ -730,8 +881,8 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
ast_context.use_locals = true
call_symbol: Symbol
- arg_symbol: Symbol
- ok: bool
+ arg_symbol: Symbol
+ ok: bool
i := i
if _, ok = arg.derived.(^ast.Bad_Expr); ok {
@@ -739,22 +890,33 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
}
//named parameter
- if field, is_field := arg.derived.(^ast.Field_Value); is_field {
- call_symbol, ok = resolve_type_expression(ast_context, field.value)
+ if field, is_field := arg.derived.(^ast.Field_Value);
+ is_field {
+ call_symbol, ok = resolve_type_expression(
+ ast_context,
+ field.value,
+ )
if !ok {
break next_fn
}
- if ident, is_ident := field.field.derived.(^ast.Ident); is_ident {
- i, ok = get_field_list_name_index(field.field.derived.(^ast.Ident).name, procedure.arg_types)
+ if ident, is_ident := field.field.derived.(^ast.Ident);
+ is_ident {
+ i, ok = get_field_list_name_index(
+ field.field.derived.(^ast.Ident).name,
+ procedure.arg_types,
+ )
} else {
break next_fn
}
} else {
- call_symbol, ok = resolve_type_expression(ast_context, arg)
+ call_symbol, ok = resolve_type_expression(
+ ast_context,
+ arg,
+ )
}
- if !ok {
+ if !ok {
break next_fn
}
@@ -762,48 +924,66 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
if len(p.return_types) != 1 {
break next_fn
}
- if s, ok := resolve_type_expression(ast_context, p.return_types[0].type); ok {
+ if s, ok := resolve_type_expression(
+ ast_context,
+ p.return_types[0].type,
+ ); ok {
call_symbol = s
}
}
if procedure.arg_types[i].type != nil {
- arg_symbol, ok = resolve_type_expression(ast_context, procedure.arg_types[i].type)
- } else {
- arg_symbol, ok = resolve_type_expression(ast_context, procedure.arg_types[i].default_value)
+ arg_symbol, ok = resolve_type_expression(
+ ast_context,
+ procedure.arg_types[i].type,
+ )
+ } else {
+ arg_symbol, ok = resolve_type_expression(
+ ast_context,
+ procedure.arg_types[i].default_value,
+ )
}
- if !ok {
+ if !ok {
break next_fn
}
- if !is_symbol_same_typed(ast_context, call_symbol, arg_symbol, procedure.arg_types[i].flags) {
+ if !is_symbol_same_typed(
+ ast_context,
+ call_symbol,
+ arg_symbol,
+ procedure.arg_types[i].flags,
+ ) {
break next_fn
- }
+ }
}
-
+
append(&candidates, f)
}
}
}
if len(candidates) > 1 {
- return Symbol {
+ return Symbol{
type = candidates[0].type,
name = candidates[0].name,
pkg = candidates[0].pkg,
- value = SymbolAggregateValue {
- symbols = candidates[:],
- },
+ value = SymbolAggregateValue{symbols = candidates[:]},
}, true
} else if len(candidates) == 1 {
return candidates[0], true
}
- return Symbol {}, false
+ return Symbol{}, false
}
-resolve_basic_lit :: proc(ast_context: ^AstContext, basic_lit: ast.Basic_Lit) -> (Symbol, bool) {
+resolve_basic_lit :: proc(
+ ast_context: ^AstContext,
+ basic_lit: ast.Basic_Lit,
+) -> (
+ Symbol,
+ bool,
+) {
symbol := Symbol {
type = .Constant,
}
@@ -826,10 +1006,22 @@ resolve_basic_lit :: proc(ast_context: ^AstContext, basic_lit: ast.Basic_Lit) ->
return symbol, true
}
-resolve_basic_directive :: proc(ast_context: ^AstContext, directive: ast.Basic_Directive, a := #caller_location) -> (Symbol, bool) {
+resolve_basic_directive :: proc(
+ ast_context: ^AstContext,
+ directive: ast.Basic_Directive,
+ a := #caller_location,
+) -> (
+ Symbol,
+ bool,
+) {
switch directive.name {
case "caller_location":
- ident := new_type(ast.Ident, directive.pos, directive.end, ast_context.allocator)
+ ident := new_type(
+ ast.Ident,
+ directive.pos,
+ directive.end,
+ ast_context.allocator,
+ )
ident.name = "Source_Code_Location"
ast_context.current_package = ast_context.document_package
return resolve_type_identifier(ast_context, ident^)
@@ -839,7 +1031,13 @@ resolve_basic_directive :: proc(ast_context: ^AstContext, directive: ast.Basic_D
}
-resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (Symbol, bool) {
+resolve_type_expression :: proc(
+ ast_context: ^AstContext,
+ node: ^ast.Expr,
+) -> (
+ Symbol,
+ bool,
+) {
if node == nil {
return {}, false
}
@@ -865,33 +1063,74 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
#partial switch v in node.derived {
case ^Union_Type:
- return make_symbol_union_from_ast(ast_context, v^, ast_context.field_name, true), true
+ return make_symbol_union_from_ast(
+ ast_context,
+ v^,
+ ast_context.field_name,
+ true,
+ ), true
case ^Enum_Type:
- return make_symbol_enum_from_ast(ast_context, v^, ast_context.field_name, true), true
+ return make_symbol_enum_from_ast(
+ ast_context,
+ v^,
+ ast_context.field_name,
+ true,
+ ), true
case ^Struct_Type:
- return make_symbol_struct_from_ast(ast_context, v^, ast_context.field_name, true), true
+ return make_symbol_struct_from_ast(
+ ast_context,
+ v^,
+ ast_context.field_name,
+ true,
+ ), true
case ^Bit_Set_Type:
- return make_symbol_bitset_from_ast(ast_context, v^, ast_context.field_name, true), true
+ return make_symbol_bitset_from_ast(
+ ast_context,
+ v^,
+ ast_context.field_name,
+ true,
+ ), true
case ^Array_Type:
- return make_symbol_array_from_ast(ast_context, v^, ast_context.field_name), true
+ return make_symbol_array_from_ast(
+ ast_context,
+ v^,
+ ast_context.field_name,
+ ), true
case ^Dynamic_Array_Type:
- return make_symbol_dynamic_array_from_ast(ast_context, v^, ast_context.field_name), true
+ return make_symbol_dynamic_array_from_ast(
+ ast_context,
+ v^,
+ ast_context.field_name,
+ ), true
case ^Multi_Pointer_Type:
- return make_symbol_multi_pointer_from_ast(ast_context, v^, ast_context.field_name), true
+ return make_symbol_multi_pointer_from_ast(
+ ast_context,
+ v^,
+ ast_context.field_name,
+ ), true
case ^Map_Type:
- return make_symbol_map_from_ast(ast_context, v^, ast_context.field_name), true
+ return make_symbol_map_from_ast(
+ ast_context,
+ v^,
+ ast_context.field_name,
+ ), true
case ^Proc_Type:
- return make_symbol_procedure_from_ast(ast_context, node, v^, ast_context.field_name), true
+ return make_symbol_procedure_from_ast(
+ ast_context,
+ node,
+ v^,
+ ast_context.field_name,
+ ), true
case ^Basic_Directive:
return resolve_basic_directive(ast_context, v^)
case ^Binary_Expr:
- return resolve_first_symbol_from_binary_expression(ast_context, v)
+ return resolve_first_symbol_from_binary_expression(ast_context, v)
case ^Ident:
return resolve_type_identifier(ast_context, v^)
case ^Basic_Lit:
return resolve_basic_lit(ast_context, v^)
case ^Type_Cast:
- return resolve_type_expression(ast_context, v.type)
+ return resolve_type_expression(ast_context, v.type)
case ^Auto_Cast:
return resolve_type_expression(ast_context, v.expr)
case ^Comp_Lit:
@@ -925,22 +1164,29 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
case ^Type_Assertion:
if unary, ok := v.type.derived.(^ast.Unary_Expr); ok {
if unary.op.kind == .Question {
- if symbol, ok := resolve_type_expression(ast_context, v.expr); ok {
+ if symbol, ok := resolve_type_expression(ast_context, v.expr);
+ ok {
if union_value, ok := symbol.value.(SymbolUnionValue); ok {
if len(union_value.types) != 1 {
return {}, false
}
- return resolve_type_expression(ast_context, union_value.types[0])
+ return resolve_type_expression(
+ ast_context,
+ union_value.types[0],
+ )
}
}
}
} else {
return resolve_type_expression(ast_context, v.type)
- }
+ }
case ^Proc_Lit:
if v.type.results != nil {
if len(v.type.results.list) == 1 {
- return resolve_type_expression(ast_context, v.type.results.list[0].type)
+ return resolve_type_expression(
+ ast_context,
+ v.type.results.list[0].type,
+ )
}
}
case ^Pointer_Type:
@@ -976,7 +1222,7 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
ast_context.call = cast(^Call_Expr)node
return resolve_type_expression(ast_context, v.expr)
case ^Implicit_Selector_Expr:
- return Symbol {}, false
+ return Symbol{}, false
case ^Selector_Call_Expr:
return resolve_type_expression(ast_context, v.expr)
case ^Selector_Expr:
@@ -987,8 +1233,14 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
case SymbolFixedArrayValue:
components_count := 0
for c in v.field.name {
- if c == 'x' || c == 'y' || c == 'z' || c == 'w' ||
- c == 'r' || c == 'g' || c == 'b' || c == 'a' {
+ if c == 'x' ||
+ c == 'y' ||
+ c == 'z' ||
+ c == 'w' ||
+ c == 'r' ||
+ c == 'g' ||
+ c == 'b' ||
+ c == 'a' {
components_count += 1
}
}
@@ -1001,7 +1253,8 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
if selector.pkg != "" {
ast_context.current_package = selector.pkg
} else {
- ast_context.current_package = ast_context.document_package
+ ast_context.current_package =
+ ast_context.document_package
}
symbol, ok := resolve_type_expression(ast_context, s.expr)
symbol.type = .Variable
@@ -1009,7 +1262,10 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
} else {
value := SymbolFixedArrayValue {
expr = s.expr,
- len = make_int_basic_value(ast_context, components_count),
+ len = make_int_basic_value(
+ ast_context,
+ components_count,
+ ),
}
selector.value = value
selector.type = .Variable
@@ -1017,7 +1273,12 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
}
case SymbolProcedureValue:
if len(s.return_types) == 1 {
- selector_expr := new_type(ast.Selector_Expr, s.return_types[0].node.pos, s.return_types[0].node.end, ast_context.allocator)
+ selector_expr := new_type(
+ ast.Selector_Expr,
+ s.return_types[0].node.pos,
+ s.return_types[0].node.end,
+ ast_context.allocator,
+ )
selector_expr.expr = s.return_types[0].type
selector_expr.field = v.field
return resolve_type_expression(ast_context, selector_expr)
@@ -1032,7 +1293,10 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
for name, i in s.names {
if v.field != nil && name == v.field.name {
ast_context.field_name = v.field^
- symbol, ok := resolve_type_expression(ast_context, s.types[i])
+ symbol, ok := resolve_type_expression(
+ ast_context,
+ s.types[i],
+ )
symbol.type = .Variable
return symbol, ok
}
@@ -1043,13 +1307,16 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
try_build_package(ast_context.current_package)
if v.field != nil {
- return resolve_symbol_return(ast_context, lookup(v.field.name, selector.pkg))
+ return resolve_symbol_return(
+ ast_context,
+ lookup(v.field.name, selector.pkg),
+ )
} else {
- return Symbol {}, false
+ return Symbol{}, false
}
}
} else {
- return Symbol {}, false
+ return Symbol{}, false
}
case:
log.warnf("default node kind, resolve_type_expression: %T", v)
@@ -1058,10 +1325,17 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (S
}
}
- return Symbol {}, false
+ return Symbol{}, false
}
-store_local :: proc(ast_context: ^AstContext, lhs: ^ast.Expr, rhs: ^ast.Expr, offset: int, name: string, id := 0) {
+store_local :: proc(
+ ast_context: ^AstContext,
+ lhs: ^ast.Expr,
+ rhs: ^ast.Expr,
+ offset: int,
+ name: string,
+ id := 0,
+) {
local_stack := &ast_context.locals[id][name]
if local_stack == nil {
@@ -1070,18 +1344,32 @@ store_local :: proc(ast_context: ^AstContext, lhs: ^ast.Expr, rhs: ^ast.Expr, of
local_stack = &locals[name]
}
- append(local_stack, DocumentLocal {lhs = lhs, rhs = rhs, offset = offset, id = id})
+ append(
+ local_stack,
+ DocumentLocal{lhs = lhs, rhs = rhs, offset = offset, id = id},
+ )
}
add_local_group :: proc(ast_context: ^AstContext, id: int) {
- ast_context.locals[id] = make(map[string][dynamic]DocumentLocal, 100, ast_context.allocator)
+ ast_context.locals[id] = make(
+ map[string][dynamic]DocumentLocal,
+ 100,
+ ast_context.allocator,
+ )
}
clear_local_group :: proc(ast_context: ^AstContext, id: int) {
ast_context.locals[id] = {}
}
-get_local_lhs_and_rhs :: proc(ast_context: ^AstContext, offset: int, name: string) -> (^ast.Expr, ^ast.Expr) {
+get_local_lhs_and_rhs :: proc(
+ ast_context: ^AstContext,
+ offset: int,
+ name: string,
+) -> (
+ ^ast.Expr,
+ ^ast.Expr,
+) {
previous := 0
//is the local we are getting being declared?
@@ -1104,31 +1392,43 @@ get_local_lhs_and_rhs :: proc(ast_context: ^AstContext, offset: int, name: strin
return nil, nil
} else {
ret := local_stack[i - previous].rhs
- if ident, ok := ret.derived.(^ast.Ident); ok && ident.name == name {
+ if ident, ok := ret.derived.(^ast.Ident);
+ ok && ident.name == name {
if i - previous - 1 < 0 {
return nil, nil
}
- if _, ok := ast_context.parameters[ident.name]; ok {
- return local_stack[i - previous].lhs, local_stack[i - previous].rhs
+ if _, ok := ast_context.parameters[ident.name];
+ ok {
+ return local_stack[i -
+ previous].lhs, local_stack[i - previous].rhs
}
}
- return local_stack[i - previous].lhs, local_stack[i - previous].rhs;
- }
+ return local_stack[i -
+ previous].lhs, local_stack[i - previous].rhs
+ }
}
}
}
}
-
+
return nil, nil
}
-get_local :: proc(ast_context: ^AstContext, offset: int, name: string) -> ^ast.Expr {
+get_local :: proc(
+ ast_context: ^AstContext,
+ offset: int,
+ name: string,
+) -> ^ast.Expr {
lhs, rhs := get_local_lhs_and_rhs(ast_context, offset, name)
return rhs
}
-get_local_offset :: proc(ast_context: ^AstContext, offset: int, name: string) -> int {
+get_local_offset :: proc(
+ ast_context: ^AstContext,
+ offset: int,
+ name: string,
+) -> int {
for _, locals in &ast_context.locals {
if local_stack, ok := locals[name]; ok {
for i := len(local_stack) - 1; i >= 0; i -= 1 {
@@ -1137,7 +1437,7 @@ get_local_offset :: proc(ast_context: ^AstContext, offset: int, name: string) ->
return -1
} else {
return local_stack[i].offset
- }
+ }
}
}
}
@@ -1146,7 +1446,13 @@ get_local_offset :: proc(ast_context: ^AstContext, offset: int, name: string) ->
return -1
}
-resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (Symbol, bool) {
+resolve_type_identifier :: proc(
+ ast_context: ^AstContext,
+ node: ast.Ident,
+) -> (
+ Symbol,
+ bool,
+) {
using ast
if ast_context.recursion_counter > 200 {
@@ -1183,9 +1489,7 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (S
type = .Keyword,
signature = node.name,
pkg = ast_context.current_package,
- value = SymbolUntypedValue {
- type = .Bool,
- },
+ value = SymbolUntypedValue{type = .Bool},
}
case:
symbol = Symbol {
@@ -1193,9 +1497,7 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (S
signature = node.name,
name = ident.name,
pkg = ast_context.current_package,
- value = SymbolBasicValue {
- ident = ident,
- },
+ value = SymbolBasicValue{ident = ident},
}
}
@@ -1206,20 +1508,21 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (S
symbol := Symbol {
type = .Package,
pkg = imp.name,
- value = SymbolPackageValue {},
+ value = SymbolPackageValue{},
}
return symbol, true
}
}
- }
-
- if local := get_local(ast_context, node.pos.offset, node.name); local != nil && ast_context.use_locals {
+ }
+
+ if local := get_local(ast_context, node.pos.offset, node.name);
+ local != nil && ast_context.use_locals {
is_distinct := false
if dist, ok := local.derived.(^ast.Distinct_Type); ok {
if dist.type != nil {
- local = dist.type
+ local = dist.type
is_distinct = true
}
}
@@ -1231,37 +1534,62 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (S
case ^Ident:
return_symbol, ok = resolve_type_identifier(ast_context, v^)
case ^Union_Type:
- return_symbol, ok = make_symbol_union_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_union_from_ast(ast_context, v^, node), true
return_symbol.name = node.name
case ^Enum_Type:
- return_symbol, ok = make_symbol_enum_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_enum_from_ast(ast_context, v^, node), true
return_symbol.name = node.name
case ^Struct_Type:
- return_symbol, ok = make_symbol_struct_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_struct_from_ast(ast_context, v^, node), true
return_symbol.name = node.name
case ^Bit_Set_Type:
- return_symbol, ok = make_symbol_bitset_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_bitset_from_ast(ast_context, v^, node), true
return_symbol.name = node.name
case ^Proc_Lit:
if !v.type.generic {
- return_symbol, ok = make_symbol_procedure_from_ast(ast_context, local, v.type^, node), true
+ return_symbol, ok =
+ make_symbol_procedure_from_ast(
+ ast_context,
+ local,
+ v.type^,
+ node,
+ ),
+ true
} else {
- if return_symbol, ok = resolve_generic_function(ast_context, v^); !ok {
- return_symbol, ok = make_symbol_procedure_from_ast(ast_context, local, v.type^, node), true
+ if return_symbol, ok = resolve_generic_function(
+ ast_context,
+ v^,
+ ); !ok {
+ return_symbol, ok =
+ make_symbol_procedure_from_ast(
+ ast_context,
+ local,
+ v.type^,
+ node,
+ ),
+ true
}
}
case ^Proc_Group:
return_symbol, ok = resolve_function_overload(ast_context, v^)
case ^Array_Type:
- return_symbol, ok = make_symbol_array_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_array_from_ast(ast_context, v^, node), true
case ^Dynamic_Array_Type:
- return_symbol, ok = make_symbol_dynamic_array_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_dynamic_array_from_ast(ast_context, v^, node), true
case ^Map_Type:
- return_symbol, ok = make_symbol_map_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_map_from_ast(ast_context, v^, node), true
case ^Basic_Lit:
return_symbol, ok = resolve_basic_lit(ast_context, v^)
return_symbol.name = node.name
- return_symbol.type = ast_context.variables[node.name] ? .Variable : .Constant
+ return_symbol.type =
+ ast_context.variables[node.name] ? .Variable : .Constant
case:
return_symbol, ok = resolve_type_expression(ast_context, local)
}
@@ -1271,7 +1599,8 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (S
return_symbol.flags |= {.Distinct}
}
- if is_variable, ok := ast_context.variables[node.name]; ok && is_variable {
+ if is_variable, ok := ast_context.variables[node.name];
+ ok && is_variable {
//return_symbol.name = node.name
return_symbol.type = .Variable
}
@@ -1280,7 +1609,8 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (S
return return_symbol, ok
- } else if global, ok := ast_context.globals[node.name]; ast_context.use_globals && ok {
+ } else if global, ok := ast_context.globals[node.name];
+ ast_context.use_globals && ok {
is_distinct := false
if dist, ok := global.expr.derived.(^ast.Distinct_Type); ok {
@@ -1297,39 +1627,66 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (S
case ^Ident:
return_symbol, ok = resolve_type_identifier(ast_context, v^)
case ^Struct_Type:
- return_symbol, ok = make_symbol_struct_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_struct_from_ast(ast_context, v^, node), true
return_symbol.name = node.name
case ^Bit_Set_Type:
- return_symbol, ok = make_symbol_bitset_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_bitset_from_ast(ast_context, v^, node), true
return_symbol.name = node.name
case ^Union_Type:
- return_symbol, ok = make_symbol_union_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_union_from_ast(ast_context, v^, node), true
return_symbol.name = node.name
case ^Enum_Type:
- return_symbol, ok = make_symbol_enum_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_enum_from_ast(ast_context, v^, node), true
return_symbol.name = node.name
case ^Proc_Lit:
if !v.type.generic {
- return_symbol, ok = make_symbol_procedure_from_ast(ast_context, global.expr, v.type^, node), true
+ return_symbol, ok =
+ make_symbol_procedure_from_ast(
+ ast_context,
+ global.expr,
+ v.type^,
+ node,
+ ),
+ true
} else {
- if return_symbol, ok = resolve_generic_function(ast_context, v^); !ok {
- return_symbol, ok = make_symbol_procedure_from_ast(ast_context, global.expr, v.type^, node), true
+ if return_symbol, ok = resolve_generic_function(
+ ast_context,
+ v^,
+ ); !ok {
+ return_symbol, ok =
+ make_symbol_procedure_from_ast(
+ ast_context,
+ global.expr,
+ v.type^,
+ node,
+ ),
+ true
}
}
case ^Proc_Group:
return_symbol, ok = resolve_function_overload(ast_context, v^)
case ^Array_Type:
- return_symbol, ok = make_symbol_array_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_array_from_ast(ast_context, v^, node), true
case ^Dynamic_Array_Type:
- return_symbol, ok = make_symbol_dynamic_array_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_dynamic_array_from_ast(ast_context, v^, node), true
case ^Map_Type:
- return_symbol, ok = make_symbol_map_from_ast(ast_context, v^, node), true
+ return_symbol, ok =
+ make_symbol_map_from_ast(ast_context, v^, node), true
case ^Basic_Lit:
return_symbol, ok = resolve_basic_lit(ast_context, v^)
return_symbol.name = node.name
return_symbol.type = global.mutable ? .Variable : .Constant
case:
- return_symbol, ok = resolve_type_expression(ast_context, global.expr)
+ return_symbol, ok = resolve_type_expression(
+ ast_context,
+ global.expr,
+ )
}
if is_distinct {
@@ -1337,7 +1694,8 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (S
return_symbol.flags |= {.Distinct}
}
- if is_variable, ok := ast_context.variables[node.name]; ok && is_variable {
+ if is_variable, ok := ast_context.variables[node.name];
+ ok && is_variable {
return_symbol.type = .Variable
}
@@ -1357,13 +1715,13 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (S
symbol := Symbol {
type = .Package,
pkg = node.name,
- value = SymbolPackageValue {},
+ value = SymbolPackageValue{},
}
try_build_package(symbol.pkg)
return symbol, true
- }
+ }
//last option is to check the index
if symbol, ok := lookup(node.name, ast_context.current_package); ok {
@@ -1375,7 +1733,7 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (S
symbol := Symbol {
type = .Package,
pkg = imp.name,
- value = SymbolPackageValue {},
+ value = SymbolPackageValue{},
}
try_build_package(symbol.pkg)
@@ -1408,10 +1766,14 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (S
}
}
- return Symbol {}, false
+ return Symbol{}, false
}
-expand_struct_usings :: proc(ast_context: ^AstContext, symbol: Symbol, value: SymbolStructValue) -> SymbolStructValue {
+expand_struct_usings :: proc(
+ ast_context: ^AstContext,
+ symbol: Symbol,
+ value: SymbolStructValue,
+) -> SymbolStructValue {
names := slice.to_dynamic(value.names, ast_context.allocator)
types := slice.to_dynamic(value.types, ast_context.allocator)
ranges := slice.to_dynamic(value.ranges, ast_context.allocator)
@@ -1444,19 +1806,22 @@ expand_struct_usings :: proc(ast_context: ^AstContext, symbol: Symbol, value: Sy
for range in struct_value.ranges {
append(&ranges, range)
- }
+ }
}
}
}
- return {
- names = names[:],
- types = types[:],
- ranges = ranges[:],
- }
+ return {names = names[:], types = types[:], ranges = ranges[:]}
}
-resolve_symbol_return :: proc(ast_context: ^AstContext, symbol: Symbol, ok := true) -> (Symbol, bool) {
+resolve_symbol_return :: proc(
+ ast_context: ^AstContext,
+ symbol: Symbol,
+ ok := true,
+) -> (
+ Symbol,
+ bool,
+) {
if !ok {
return symbol, ok
}
@@ -1468,17 +1833,24 @@ resolve_symbol_return :: proc(ast_context: ^AstContext, symbol: Symbol, ok := tr
return {}, false
}
}
-
+
#partial switch v in &symbol.value {
case SymbolProcedureGroupValue:
- if symbol, ok := resolve_function_overload(ast_context, v.group.derived.(^ast.Proc_Group)^); ok {
+ if symbol, ok := resolve_function_overload(
+ ast_context,
+ v.group.derived.(^ast.Proc_Group)^,
+ ); ok {
return symbol, true
} else {
return symbol, false
}
case SymbolProcedureValue:
if v.generic {
- if resolved_symbol, ok := resolve_generic_function(ast_context, v.arg_types, v.return_types); ok {
+ if resolved_symbol, ok := resolve_generic_function(
+ ast_context,
+ v.arg_types,
+ v.return_types,
+ ); ok {
return resolved_symbol, ok
} else {
return symbol, true
@@ -1512,7 +1884,7 @@ resolve_symbol_return :: proc(ast_context: ^AstContext, symbol: Symbol, ok := tr
expanded.value = expand_struct_usings(ast_context, symbol, v)
return expanded, true
} else {
- return symbol, true
+ return symbol, true
}
case SymbolGenericValue:
ret, ok := resolve_type_expression(ast_context, v.expr)
@@ -1525,7 +1897,10 @@ resolve_symbol_return :: proc(ast_context: ^AstContext, symbol: Symbol, ok := tr
return symbol, true
}
-resolve_unresolved_symbol :: proc(ast_context: ^AstContext, symbol: ^Symbol) -> bool {
+resolve_unresolved_symbol :: proc(
+ ast_context: ^AstContext,
+ symbol: ^Symbol,
+) -> bool {
if symbol.type != .Unresolved {
return true
}
@@ -1533,15 +1908,15 @@ resolve_unresolved_symbol :: proc(ast_context: ^AstContext, symbol: ^Symbol) ->
#partial switch v in symbol.value {
case SymbolStructValue:
symbol.type = .Struct
- case SymbolPackageValue:
+ case SymbolPackageValue:
symbol.type = .Package
- case SymbolProcedureValue, SymbolProcedureGroupValue:
+ case SymbolProcedureValue, SymbolProcedureGroupValue:
symbol.type = .Function
- case SymbolUnionValue:
+ case SymbolUnionValue:
symbol.type = .Enum
- case SymbolEnumValue:
+ case SymbolEnumValue:
symbol.type = .Enum
- case SymbolBitSetValue:
+ case SymbolBitSetValue:
symbol.type = .Enum
case SymbolGenericValue:
ast_context.current_package = symbol.pkg
@@ -1556,17 +1931,30 @@ resolve_unresolved_symbol :: proc(ast_context: ^AstContext, symbol: ^Symbol) ->
return true
}
-resolve_location_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (Symbol, bool) {
+resolve_location_identifier :: proc(
+ ast_context: ^AstContext,
+ node: ast.Ident,
+) -> (
+ Symbol,
+ bool,
+) {
symbol: Symbol
- if local, _ := get_local_lhs_and_rhs(ast_context, node.pos.offset, node.name); local != nil {
+ if local, _ := get_local_lhs_and_rhs(
+ ast_context,
+ node.pos.offset,
+ node.name,
+ ); local != nil {
symbol.range = common.get_token_range(local, ast_context.file.src)
uri := common.create_uri(local.pos.file, ast_context.allocator)
symbol.pkg = ast_context.document_package
symbol.uri = uri.uri
return symbol, true
} else if global, ok := ast_context.globals[node.name]; ok {
- symbol.range = common.get_token_range(global.expr, ast_context.file.src)
+ symbol.range = common.get_token_range(
+ global.expr,
+ ast_context.file.src,
+ )
uri := common.create_uri(global.expr.pos.file, ast_context.allocator)
symbol.pkg = ast_context.document_package
symbol.uri = uri.uri
@@ -1588,7 +1976,13 @@ resolve_location_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -
return {}, false
}
-resolve_location_selector :: proc(ast_context: ^AstContext, selector: ^ast.Selector_Expr) -> (Symbol, bool) {
+resolve_location_selector :: proc(
+ ast_context: ^AstContext,
+ selector: ^ast.Selector_Expr,
+) -> (
+ Symbol,
+ bool,
+) {
ast_context.use_locals = true
ast_context.use_globals = true
ast_context.current_package = ast_context.document_package
@@ -1628,7 +2022,13 @@ resolve_location_selector :: proc(ast_context: ^AstContext, selector: ^ast.Selec
}
-resolve_first_symbol_from_binary_expression :: proc(ast_context: ^AstContext, binary: ^ast.Binary_Expr) -> (Symbol, bool) {
+resolve_first_symbol_from_binary_expression :: proc(
+ ast_context: ^AstContext,
+ binary: ^ast.Binary_Expr,
+) -> (
+ Symbol,
+ bool,
+) {
//Fairly simple function to find the earliest identifier symbol in binary expression.
if binary.left != nil {
@@ -1638,7 +2038,10 @@ resolve_first_symbol_from_binary_expression :: proc(ast_context: ^AstContext, bi
return s, ok
}
} else if _, ok := binary.left.derived.(^ast.Binary_Expr); ok {
- if s, ok := resolve_first_symbol_from_binary_expression(ast_context, cast(^ast.Binary_Expr)binary.left); ok {
+ if s, ok := resolve_first_symbol_from_binary_expression(
+ ast_context,
+ cast(^ast.Binary_Expr)binary.left,
+ ); ok {
return s, ok
}
}
@@ -1650,7 +2053,10 @@ resolve_first_symbol_from_binary_expression :: proc(ast_context: ^AstContext, bi
return s, ok
}
} else if _, ok := binary.right.derived.(^ast.Binary_Expr); ok {
- if s, ok := resolve_first_symbol_from_binary_expression(ast_context, cast(^ast.Binary_Expr)binary.right); ok {
+ if s, ok := resolve_first_symbol_from_binary_expression(
+ ast_context,
+ cast(^ast.Binary_Expr)binary.right,
+ ); ok {
return s, ok
}
}
@@ -1659,7 +2065,13 @@ resolve_first_symbol_from_binary_expression :: proc(ast_context: ^AstContext, bi
return {}, false
}
-find_position_in_call_param :: proc(ast_context: ^AstContext, call: ast.Call_Expr) -> (int, bool) {
+find_position_in_call_param :: proc(
+ ast_context: ^AstContext,
+ call: ast.Call_Expr,
+) -> (
+ int,
+ bool,
+) {
if call.args == nil {
return 0, false
}
@@ -1673,8 +2085,16 @@ find_position_in_call_param :: proc(ast_context: ^AstContext, call: ast.Call_Exp
return len(call.args) - 1, true
}
-make_pointer_ast :: proc(ast_context: ^AstContext, elem: ^ast.Expr) -> ^ast.Pointer_Type {
- pointer := new_type(ast.Pointer_Type, elem.pos, elem.end, ast_context.allocator)
+make_pointer_ast :: proc(
+ ast_context: ^AstContext,
+ elem: ^ast.Expr,
+) -> ^ast.Pointer_Type {
+ pointer := new_type(
+ ast.Pointer_Type,
+ elem.pos,
+ elem.end,
+ ast_context.allocator,
+ )
pointer.elem = elem
return pointer
}
@@ -1691,10 +2111,13 @@ make_int_ast :: proc(ast_context: ^AstContext) -> ^ast.Ident {
return ident
}
-make_int_basic_value :: proc(ast_context: ^AstContext, n: int) -> ^ast.Basic_Lit {
+make_int_basic_value :: proc(
+ ast_context: ^AstContext,
+ n: int,
+) -> ^ast.Basic_Lit {
basic := new_type(ast.Basic_Lit, {}, {}, ast_context.allocator)
basic.tok.text = fmt.tprintf("%v", n)
- return basic
+ return basic
}
get_package_from_node :: proc(node: ast.Node) -> string {
@@ -1722,16 +2145,21 @@ get_using_packages :: proc(ast_context: ^AstContext) -> []string {
return usings
}
-make_symbol_procedure_from_ast :: proc(ast_context: ^AstContext, n: ^ast.Node, v: ast.Proc_Type, name: ast.Ident) -> Symbol {
+make_symbol_procedure_from_ast :: proc(
+ ast_context: ^AstContext,
+ n: ^ast.Node,
+ v: ast.Proc_Type,
+ name: ast.Ident,
+) -> Symbol {
symbol := Symbol {
range = common.get_token_range(n^, ast_context.file.src),
- type = .Function,
- pkg = get_package_from_node(n^),
- name = name.name,
+ type = .Function,
+ pkg = get_package_from_node(n^),
+ name = name.name,
}
return_types := make([dynamic]^ast.Field, ast_context.allocator)
- arg_types := make([dynamic]^ast.Field, ast_context.allocator)
+ arg_types := make([dynamic]^ast.Field, ast_context.allocator)
if v.results != nil {
for ret in v.results.list {
@@ -1753,25 +2181,29 @@ make_symbol_procedure_from_ast :: proc(ast_context: ^AstContext, n: ^ast.Node, v
symbol.value = SymbolProcedureValue {
return_types = return_types[:],
- arg_types = arg_types[:],
- generic = v.generic,
+ arg_types = arg_types[:],
+ generic = v.generic,
}
return symbol
}
-make_symbol_array_from_ast :: proc(ast_context: ^AstContext, v: ast.Array_Type, name: ast.Ident) -> Symbol {
+make_symbol_array_from_ast :: proc(
+ ast_context: ^AstContext,
+ v: ast.Array_Type,
+ name: ast.Ident,
+) -> Symbol {
symbol := Symbol {
range = common.get_token_range(v.node, ast_context.file.src),
- type = .Variable,
- pkg = get_package_from_node(v.node),
- name = name.name,
+ type = .Variable,
+ pkg = get_package_from_node(v.node),
+ name = name.name,
}
if v.len != nil {
symbol.value = SymbolFixedArrayValue {
expr = v.elem,
- len = v.len,
+ len = v.len,
}
} else {
symbol.value = SymbolSliceValue {
@@ -1782,12 +2214,16 @@ make_symbol_array_from_ast :: proc(ast_context: ^AstContext, v: ast.Array_Type,
return symbol
}
-make_symbol_dynamic_array_from_ast :: proc(ast_context: ^AstContext, v: ast.Dynamic_Array_Type, name: ast.Ident) -> Symbol {
+make_symbol_dynamic_array_from_ast :: proc(
+ ast_context: ^AstContext,
+ v: ast.Dynamic_Array_Type,
+ name: ast.Ident,
+) -> Symbol {
symbol := Symbol {
range = common.get_token_range(v.node, ast_context.file.src),
- type = .Variable,
- pkg = get_package_from_node(v.node),
- name = name.name,
+ type = .Variable,
+ pkg = get_package_from_node(v.node),
+ name = name.name,
}
symbol.value = SymbolDynamicArrayValue {
@@ -1797,12 +2233,16 @@ make_symbol_dynamic_array_from_ast :: proc(ast_context: ^AstContext, v: ast.Dyna
return symbol
}
-make_symbol_multi_pointer_from_ast :: proc(ast_context: ^AstContext, v: ast.Multi_Pointer_Type, name: ast.Ident) -> Symbol {
+make_symbol_multi_pointer_from_ast :: proc(
+ ast_context: ^AstContext,
+ v: ast.Multi_Pointer_Type,
+ name: ast.Ident,
+) -> Symbol {
symbol := Symbol {
range = common.get_token_range(v.node, ast_context.file.src),
- type = .Variable,
- pkg = get_package_from_node(v.node),
- name = name.name,
+ type = .Variable,
+ pkg = get_package_from_node(v.node),
+ name = name.name,
}
symbol.value = SymbolMultiPointer {
@@ -1812,27 +2252,35 @@ make_symbol_multi_pointer_from_ast :: proc(ast_context: ^AstContext, v: ast.Mult
return symbol
}
-make_symbol_map_from_ast :: proc(ast_context: ^AstContext, v: ast.Map_Type, name: ast.Ident) -> Symbol {
+make_symbol_map_from_ast :: proc(
+ ast_context: ^AstContext,
+ v: ast.Map_Type,
+ name: ast.Ident,
+) -> Symbol {
symbol := Symbol {
range = common.get_token_range(v.node, ast_context.file.src),
- type = .Variable,
- pkg = get_package_from_node(v.node),
- name = name.name,
+ type = .Variable,
+ pkg = get_package_from_node(v.node),
+ name = name.name,
}
symbol.value = SymbolMapValue {
- key = v.key,
+ key = v.key,
value = v.value,
}
return symbol
}
-make_symbol_basic_type_from_ast :: proc(ast_context: ^AstContext, n: ^ast.Node, v: ^ast.Ident) -> Symbol {
+make_symbol_basic_type_from_ast :: proc(
+ ast_context: ^AstContext,
+ n: ^ast.Node,
+ v: ^ast.Ident,
+) -> Symbol {
symbol := Symbol {
range = common.get_token_range(n^, ast_context.file.src),
- type = .Variable,
- pkg = get_package_from_node(n^),
+ type = .Variable,
+ pkg = get_package_from_node(n^),
}
symbol.value = SymbolBasicValue {
@@ -1842,12 +2290,17 @@ make_symbol_basic_type_from_ast :: proc(ast_context: ^AstContext, n: ^ast.Node,
return symbol
}
-make_symbol_union_from_ast :: proc(ast_context: ^AstContext, v: ast.Union_Type, ident: ast.Ident, inlined := false) -> Symbol {
+make_symbol_union_from_ast :: proc(
+ ast_context: ^AstContext,
+ v: ast.Union_Type,
+ ident: ast.Ident,
+ inlined := false,
+) -> Symbol {
symbol := Symbol {
range = common.get_token_range(v, ast_context.file.src),
- type = .Union,
- pkg = get_package_from_node(v.node),
- name = ident.name,
+ type = .Union,
+ pkg = get_package_from_node(v.node),
+ name = ident.name,
}
if inlined {
@@ -1855,7 +2308,7 @@ make_symbol_union_from_ast :: proc(ast_context: ^AstContext, v: ast.Union_Type,
symbol.name = "union"
}
- types := make([dynamic]^ast.Expr, ast_context.allocator)
+ types := make([dynamic]^ast.Expr, ast_context.allocator)
for variant in v.variants {
if v.poly_params != nil {
@@ -1876,12 +2329,17 @@ make_symbol_union_from_ast :: proc(ast_context: ^AstContext, v: ast.Union_Type,
return symbol
}
-make_symbol_enum_from_ast :: proc(ast_context: ^AstContext, v: ast.Enum_Type, ident: ast.Ident, inlined := false) -> Symbol {
+make_symbol_enum_from_ast :: proc(
+ ast_context: ^AstContext,
+ v: ast.Enum_Type,
+ ident: ast.Ident,
+ inlined := false,
+) -> Symbol {
symbol := Symbol {
range = common.get_token_range(v, ast_context.file.src),
- type = .Enum,
- name = ident.name,
- pkg = get_package_from_node(v.node),
+ type = .Enum,
+ name = ident.name,
+ pkg = get_package_from_node(v.node),
}
if inlined {
@@ -1898,9 +2356,10 @@ make_symbol_enum_from_ast :: proc(ast_context: ^AstContext, v: ast.Enum_Type, id
} else if field, ok := n.derived.(^ast.Field_Value); ok {
if ident, ok := field.field.derived.(^ast.Ident); ok {
append(&names, ident.name)
- } else if binary, ok := field.field.derived.(^ast.Binary_Expr); ok {
+ } else if binary, ok := field.field.derived.(^ast.Binary_Expr);
+ ok {
append(&names, binary.left.derived.(^ast.Ident).name)
- }
+ }
}
}
@@ -1911,12 +2370,17 @@ make_symbol_enum_from_ast :: proc(ast_context: ^AstContext, v: ast.Enum_Type, id
return symbol
}
-make_symbol_bitset_from_ast :: proc(ast_context: ^AstContext, v: ast.Bit_Set_Type, ident: ast.Ident, inlined := false) -> Symbol {
+make_symbol_bitset_from_ast :: proc(
+ ast_context: ^AstContext,
+ v: ast.Bit_Set_Type,
+ ident: ast.Ident,
+ inlined := false,
+) -> Symbol {
symbol := Symbol {
range = common.get_token_range(v, ast_context.file.src),
- type = .Enum,
- name = ident.name,
- pkg = get_package_from_node(v.node),
+ type = .Enum,
+ name = ident.name,
+ pkg = get_package_from_node(v.node),
}
if inlined {
@@ -1931,12 +2395,17 @@ make_symbol_bitset_from_ast :: proc(ast_context: ^AstContext, v: ast.Bit_Set_Typ
return symbol
}
-make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type, ident: ast.Ident, inlined := false) -> Symbol {
+make_symbol_struct_from_ast :: proc(
+ ast_context: ^AstContext,
+ v: ast.Struct_Type,
+ ident: ast.Ident,
+ inlined := false,
+) -> Symbol {
symbol := Symbol {
range = common.get_token_range(v, ast_context.file.src),
- type = .Struct,
- pkg = get_package_from_node(v.node),
- name = ident.name,
+ type = .Struct,
+ pkg = get_package_from_node(v.node),
+ name = ident.name,
}
if inlined {
@@ -1951,13 +2420,17 @@ make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type
for field in v.fields.list {
for n in field.names {
- if identifier, ok := n.derived.(^ast.Ident); ok && field.type != nil {
+ if identifier, ok := n.derived.(^ast.Ident);
+ ok && field.type != nil {
if identifier.name == "_" {
continue
}
append(&names, identifier.name)
if v.poly_params != nil {
- append(&types, clone_type(field.type, ast_context.allocator, nil))
+ append(
+ &types,
+ clone_type(field.type, ast_context.allocator, nil),
+ )
} else {
append(&types, field.type)
}
@@ -1965,14 +2438,17 @@ make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type
usings[identifier.name] = true
}
- append(&ranges, common.get_token_range(n, ast_context.file.src))
+ append(
+ &ranges,
+ common.get_token_range(n, ast_context.file.src),
+ )
}
}
}
symbol.value = SymbolStructValue {
- names = names[:],
- types = types[:],
+ names = names[:],
+ types = types[:],
ranges = ranges[:],
usings = usings,
}
@@ -1983,13 +2459,21 @@ make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type
//TODO change the expand to not double copy the array, but just pass the dynamic arrays
if len(usings) > 0 {
- symbol.value = expand_struct_usings(ast_context, symbol, symbol.value.(SymbolStructValue))
+ symbol.value = expand_struct_usings(
+ ast_context,
+ symbol,
+ symbol.value.(SymbolStructValue),
+ )
}
return symbol
}
-resolve_poly_union :: proc(ast_context: ^AstContext, poly_params: ^ast.Field_List, symbol: ^Symbol) {
+resolve_poly_union :: proc(
+ ast_context: ^AstContext,
+ poly_params: ^ast.Field_List,
+ symbol: ^Symbol,
+) {
if ast_context.call == nil {
return
}
@@ -2013,11 +2497,11 @@ resolve_poly_union :: proc(ast_context: ^AstContext, poly_params: ^ast.Field_Lis
if param.type == nil {
continue
}
-
+
if poly, ok := param.type.derived.(^ast.Typeid_Type); ok {
if ident, ok := name.derived.(^ast.Ident); ok {
poly_map[ident.name] = ast_context.call.args[i]
- } else if poly, ok := name.derived.(^ast.Poly_Type); ok {
+ } else if poly, ok := name.derived.(^ast.Poly_Type); ok {
if poly.type != nil {
poly_map[poly.type.name] = ast_context.call.args[i]
}
@@ -2027,7 +2511,7 @@ resolve_poly_union :: proc(ast_context: ^AstContext, poly_params: ^ast.Field_Lis
i += 1
}
}
-
+
for type, i in symbol_value.types {
if ident, ok := type.derived.(^ast.Ident); ok {
if expr, ok := poly_map[ident.name]; ok {
@@ -2049,7 +2533,11 @@ resolve_poly_union :: proc(ast_context: ^AstContext, poly_params: ^ast.Field_Lis
}
}
-resolve_poly_struct :: proc(ast_context: ^AstContext, poly_params: ^ast.Field_List, symbol: ^Symbol) {
+resolve_poly_struct :: proc(
+ ast_context: ^AstContext,
+ poly_params: ^ast.Field_List,
+ symbol: ^Symbol,
+) {
if ast_context.call == nil {
return
}
@@ -2073,11 +2561,11 @@ resolve_poly_struct :: proc(ast_context: ^AstContext, poly_params: ^ast.Field_Li
if param.type == nil {
continue
}
-
+
if poly, ok := param.type.derived.(^ast.Typeid_Type); ok {
if ident, ok := name.derived.(^ast.Ident); ok {
poly_map[ident.name] = ast_context.call.args[i]
- } else if poly, ok := name.derived.(^ast.Poly_Type); ok {
+ } else if poly, ok := name.derived.(^ast.Poly_Type); ok {
if poly.type != nil {
poly_map[poly.type.name] = ast_context.call.args[i]
}
@@ -2087,7 +2575,7 @@ resolve_poly_struct :: proc(ast_context: ^AstContext, poly_params: ^ast.Field_Li
i += 1
}
}
-
+
for type, i in symbol_value.types {
if ident, ok := type.derived.(^ast.Ident); ok {
if expr, ok := poly_map[ident.name]; ok {
@@ -2120,7 +2608,12 @@ get_globals :: proc(file: ast.File, ast_context: ^AstContext) {
}
}
-get_generic_assignment :: proc(file: ast.File, value: ^ast.Expr, ast_context: ^AstContext, results: ^[dynamic]^ast.Expr) {
+get_generic_assignment :: proc(
+ file: ast.File,
+ value: ^ast.Expr,
+ ast_context: ^AstContext,
+ results: ^[dynamic]^ast.Expr,
+) {
using ast
ast_context.use_locals = true
@@ -2131,7 +2624,7 @@ get_generic_assignment :: proc(file: ast.File, value: ^ast.Expr, ast_context: ^A
get_generic_assignment(file, v.expr, ast_context, results)
case ^Call_Expr:
ast_context.call = cast(^ast.Call_Expr)value
-
+
if symbol, ok := resolve_type_expression(ast_context, v.expr); ok {
if procedure, ok := symbol.value.(SymbolProcedureValue); ok {
for ret in procedure.return_types {
@@ -2157,7 +2650,8 @@ get_generic_assignment :: proc(file: ast.File, value: ^ast.Expr, ast_context: ^A
}
case ^Type_Assertion:
if v.type != nil {
- if unary, ok := v.type.derived.(^ast.Unary_Expr); ok && unary.op.kind == .Question {
+ if unary, ok := v.type.derived.(^ast.Unary_Expr);
+ ok && unary.op.kind == .Question {
append(results, cast(^ast.Expr)&v.node)
} else {
append(results, v.type)
@@ -2173,7 +2667,11 @@ get_generic_assignment :: proc(file: ast.File, value: ^ast.Expr, ast_context: ^A
}
}
-get_locals_value_decl :: proc(file: ast.File, value_decl: ast.Value_Decl, ast_context: ^AstContext) {
+get_locals_value_decl :: proc(
+ file: ast.File,
+ value_decl: ast.Value_Decl,
+ ast_context: ^AstContext,
+) {
using ast
if len(value_decl.names) <= 0 {
@@ -2184,7 +2682,14 @@ get_locals_value_decl :: proc(file: ast.File, value_decl: ast.Value_Decl, ast_co
for name, i in value_decl.names {
str := common.get_ast_node_string(value_decl.names[i], file.src)
ast_context.variables[str] = value_decl.is_mutable
- store_local(ast_context, name, value_decl.type, value_decl.end.offset, str, ast_context.local_id)
+ store_local(
+ ast_context,
+ name,
+ value_decl.type,
+ value_decl.end.offset,
+ str,
+ ast_context.local_id,
+ )
}
return
}
@@ -2200,15 +2705,28 @@ get_locals_value_decl :: proc(file: ast.File, value_decl: ast.Value_Decl, ast_co
}
for name, i in value_decl.names {
- result_i := min(len(results)-1, i)
+ result_i := min(len(results) - 1, i)
str := common.get_ast_node_string(name, file.src)
ast_context.in_package[str] = get_package_from_node(results[result_i]^)
- store_local(ast_context, name, results[result_i], value_decl.end.offset, str, ast_context.local_id)
+ store_local(
+ ast_context,
+ name,
+ results[result_i],
+ value_decl.end.offset,
+ str,
+ ast_context.local_id,
+ )
ast_context.variables[str] = value_decl.is_mutable
}
}
-get_locals_stmt :: proc(file: ast.File, stmt: ^ast.Stmt, ast_context: ^AstContext, document_position: ^DocumentPositionContext, save_assign := false) {
+get_locals_stmt :: proc(
+ file: ast.File,
+ stmt: ^ast.Stmt,
+ ast_context: ^AstContext,
+ document_position: ^DocumentPositionContext,
+ save_assign := false,
+) {
ast_context.use_locals = true
ast_context.use_globals = true
ast_context.current_package = ast_context.document_package
@@ -2256,12 +2774,18 @@ get_locals_stmt :: proc(file: ast.File, stmt: ^ast.Stmt, ast_context: ^AstContex
get_locals_stmt(file, stmt, ast_context, document_position)
}
case:
- //log.debugf("default node local stmt %v", v);
+ //log.debugf("default node local stmt %v", v);
}
}
-get_locals_block_stmt :: proc(file: ast.File, block: ast.Block_Stmt, ast_context: ^AstContext, document_position: ^DocumentPositionContext) {
- if !(block.pos.offset <= document_position.position && document_position.position <= block.end.offset) {
+get_locals_block_stmt :: proc(
+ file: ast.File,
+ block: ast.Block_Stmt,
+ ast_context: ^AstContext,
+ document_position: ^DocumentPositionContext,
+) {
+ if !(block.pos.offset <= document_position.position &&
+ document_position.position <= block.end.offset) {
return
}
@@ -2280,11 +2804,28 @@ get_locals_using_stmt :: proc(stmt: ast.Using_Stmt, ast_context: ^AstContext) {
}
case SymbolStructValue:
for name, i in v.names {
- selector := new_type(ast.Selector_Expr, v.types[i].pos, v.types[i].end, ast_context.allocator)
+ selector := new_type(
+ ast.Selector_Expr,
+ v.types[i].pos,
+ v.types[i].end,
+ ast_context.allocator,
+ )
selector.expr = u
- selector.field = new_type(ast.Ident, v.types[i].pos, v.types[i].end, ast_context.allocator)
+ selector.field = new_type(
+ ast.Ident,
+ v.types[i].pos,
+ v.types[i].end,
+ ast_context.allocator,
+ )
selector.field.name = name
- store_local(ast_context, u, selector, 0, name, ast_context.local_id)
+ store_local(
+ ast_context,
+ u,
+ selector,
+ 0,
+ name,
+ ast_context.local_id,
+ )
ast_context.variables[name] = true
}
}
@@ -2292,7 +2833,11 @@ get_locals_using_stmt :: proc(stmt: ast.Using_Stmt, ast_context: ^AstContext) {
}
}
-get_locals_assign_stmt :: proc(file: ast.File, stmt: ast.Assign_Stmt, ast_context: ^AstContext) {
+get_locals_assign_stmt :: proc(
+ file: ast.File,
+ stmt: ast.Assign_Stmt,
+ ast_context: ^AstContext,
+) {
using ast
if stmt.lhs == nil || stmt.rhs == nil {
@@ -2311,14 +2856,27 @@ get_locals_assign_stmt :: proc(file: ast.File, stmt: ast.Assign_Stmt, ast_contex
for lhs, i in stmt.lhs {
if ident, ok := lhs.derived.(^ast.Ident); ok {
- store_local(ast_context, lhs, results[i], ident.pos.offset, ident.name, ast_context.local_id)
+ store_local(
+ ast_context,
+ lhs,
+ results[i],
+ ident.pos.offset,
+ ident.name,
+ ast_context.local_id,
+ )
ast_context.variables[ident.name] = true
}
}
}
-get_locals_if_stmt :: proc(file: ast.File, stmt: ast.If_Stmt, ast_context: ^AstContext, document_position: ^DocumentPositionContext) {
- if !(stmt.pos.offset <= document_position.position && document_position.position <= stmt.end.offset) {
+get_locals_if_stmt :: proc(
+ file: ast.File,
+ stmt: ast.If_Stmt,
+ ast_context: ^AstContext,
+ document_position: ^DocumentPositionContext,
+) {
+ if !(stmt.pos.offset <= document_position.position &&
+ document_position.position <= stmt.end.offset) {
return
}
@@ -2327,10 +2885,16 @@ get_locals_if_stmt :: proc(file: ast.File, stmt: ast.If_Stmt, ast_context: ^AstC
get_locals_stmt(file, stmt.else_stmt, ast_context, document_position)
}
-get_locals_for_range_stmt :: proc(file: ast.File, stmt: ast.Range_Stmt, ast_context: ^AstContext, document_position: ^DocumentPositionContext) {
+get_locals_for_range_stmt :: proc(
+ file: ast.File,
+ stmt: ast.Range_Stmt,
+ ast_context: ^AstContext,
+ document_position: ^DocumentPositionContext,
+) {
using ast
- if !(stmt.body.pos.offset <= document_position.position && document_position.position <= stmt.body.end.offset) {
+ if !(stmt.body.pos.offset <= document_position.position &&
+ document_position.position <= stmt.body.end.offset) {
return
}
@@ -2344,7 +2908,14 @@ get_locals_for_range_stmt :: proc(file: ast.File, stmt: ast.Range_Stmt, ast_cont
if binary.op.kind == .Range_Half {
if len(stmt.vals) >= 1 {
if ident, ok := stmt.vals[0].derived.(^Ident); ok {
- store_local(ast_context, ident, make_int_ast(ast_context), ident.pos.offset, ident.name, ast_context.local_id)
+ store_local(
+ ast_context,
+ ident,
+ make_int_ast(ast_context),
+ ident.pos.offset,
+ ident.name,
+ ast_context.local_id,
+ )
ast_context.variables[ident.name] = true
}
}
@@ -2356,14 +2927,28 @@ get_locals_for_range_stmt :: proc(file: ast.File, stmt: ast.Range_Stmt, ast_cont
case SymbolMapValue:
if len(stmt.vals) >= 1 {
if ident, ok := stmt.vals[0].derived.(^Ident); ok {
- store_local(ast_context, ident, v.key, ident.pos.offset, ident.name, ast_context.local_id)
+ store_local(
+ ast_context,
+ ident,
+ v.key,
+ ident.pos.offset,
+ ident.name,
+ ast_context.local_id,
+ )
ast_context.variables[ident.name] = true
ast_context.in_package[ident.name] = symbol.pkg
}
}
if len(stmt.vals) >= 2 {
if ident, ok := stmt.vals[1].derived.(^Ident); ok {
- store_local(ast_context, ident, v.value, ident.pos.offset, ident.name, ast_context.local_id)
+ store_local(
+ ast_context,
+ ident,
+ v.value,
+ ident.pos.offset,
+ ident.name,
+ ast_context.local_id,
+ )
ast_context.variables[ident.name] = true
ast_context.in_package[ident.name] = symbol.pkg
}
@@ -2371,14 +2956,28 @@ get_locals_for_range_stmt :: proc(file: ast.File, stmt: ast.Range_Stmt, ast_cont
case SymbolDynamicArrayValue:
if len(stmt.vals) >= 1 {
if ident, ok := stmt.vals[0].derived.(^Ident); ok {
- store_local(ast_context, ident, v.expr, ident.pos.offset, ident.name, ast_context.local_id)
+ store_local(
+ ast_context,
+ ident,
+ v.expr,
+ ident.pos.offset,
+ ident.name,
+ ast_context.local_id,
+ )
ast_context.variables[ident.name] = true
ast_context.in_package[ident.name] = symbol.pkg
}
}
if len(stmt.vals) >= 2 {
if ident, ok := stmt.vals[1].derived.(^Ident); ok {
- store_local(ast_context, ident, make_int_ast(ast_context), ident.pos.offset, ident.name, ast_context.local_id)
+ store_local(
+ ast_context,
+ ident,
+ make_int_ast(ast_context),
+ ident.pos.offset,
+ ident.name,
+ ast_context.local_id,
+ )
ast_context.variables[ident.name] = true
ast_context.in_package[ident.name] = symbol.pkg
}
@@ -2386,7 +2985,14 @@ get_locals_for_range_stmt :: proc(file: ast.File, stmt: ast.Range_Stmt, ast_cont
case SymbolFixedArrayValue:
if len(stmt.vals) >= 1 {
if ident, ok := stmt.vals[0].derived.(^Ident); ok {
- store_local(ast_context, ident, v.expr, ident.pos.offset, ident.name, ast_context.local_id)
+ store_local(
+ ast_context,
+ ident,
+ v.expr,
+ ident.pos.offset,
+ ident.name,
+ ast_context.local_id,
+ )
ast_context.variables[ident.name] = true
ast_context.in_package[ident.name] = symbol.pkg
}
@@ -2394,7 +3000,14 @@ get_locals_for_range_stmt :: proc(file: ast.File, stmt: ast.Range_Stmt, ast_cont
if len(stmt.vals) >= 2 {
if ident, ok := stmt.vals[1].derived.(^Ident); ok {
- store_local(ast_context, ident, make_int_ast(ast_context), ident.pos.offset, ident.name, ast_context.local_id)
+ store_local(
+ ast_context,
+ ident,
+ make_int_ast(ast_context),
+ ident.pos.offset,
+ ident.name,
+ ast_context.local_id,
+ )
ast_context.variables[ident.name] = true
ast_context.in_package[ident.name] = symbol.pkg
}
@@ -2402,26 +3015,46 @@ get_locals_for_range_stmt :: proc(file: ast.File, stmt: ast.Range_Stmt, ast_cont
case SymbolSliceValue:
if len(stmt.vals) >= 1 {
if ident, ok := stmt.vals[0].derived.(^Ident); ok {
- store_local(ast_context, ident, v.expr, ident.pos.offset, ident.name, ast_context.local_id)
+ store_local(
+ ast_context,
+ ident,
+ v.expr,
+ ident.pos.offset,
+ ident.name,
+ ast_context.local_id,
+ )
ast_context.variables[ident.name] = true
ast_context.in_package[ident.name] = symbol.pkg
}
}
if len(stmt.vals) >= 2 {
if ident, ok := stmt.vals[1].derived.(^Ident); ok {
- store_local(ast_context, ident, make_int_ast(ast_context), ident.pos.offset, ident.name, ast_context.local_id)
+ store_local(
+ ast_context,
+ ident,
+ make_int_ast(ast_context),
+ ident.pos.offset,
+ ident.name,
+ ast_context.local_id,
+ )
ast_context.variables[ident.name] = true
ast_context.in_package[ident.name] = symbol.pkg
}
}
}
}
-
+
get_locals_stmt(file, stmt.body, ast_context, document_position)
}
-get_locals_for_stmt :: proc(file: ast.File, stmt: ast.For_Stmt, ast_context: ^AstContext, document_position: ^DocumentPositionContext) {
- if !(stmt.pos.offset <= document_position.position && document_position.position <= stmt.end.offset) {
+get_locals_for_stmt :: proc(
+ file: ast.File,
+ stmt: ast.For_Stmt,
+ ast_context: ^AstContext,
+ document_position: ^DocumentPositionContext,
+) {
+ if !(stmt.pos.offset <= document_position.position &&
+ document_position.position <= stmt.end.offset) {
return
}
@@ -2429,18 +3062,30 @@ get_locals_for_stmt :: proc(file: ast.File, stmt: ast.For_Stmt, ast_context: ^As
get_locals_stmt(file, stmt.body, ast_context, document_position)
}
-get_locals_switch_stmt :: proc(file: ast.File, stmt: ast.Switch_Stmt, ast_context: ^AstContext, document_position: ^DocumentPositionContext) {
- if !(stmt.pos.offset <= document_position.position && document_position.position <= stmt.end.offset) {
+get_locals_switch_stmt :: proc(
+ file: ast.File,
+ stmt: ast.Switch_Stmt,
+ ast_context: ^AstContext,
+ document_position: ^DocumentPositionContext,
+) {
+ if !(stmt.pos.offset <= document_position.position &&
+ document_position.position <= stmt.end.offset) {
return
}
get_locals_stmt(file, stmt.body, ast_context, document_position)
}
-get_locals_type_switch_stmt :: proc(file: ast.File, stmt: ast.Type_Switch_Stmt, ast_context: ^AstContext, document_position: ^DocumentPositionContext) {
+get_locals_type_switch_stmt :: proc(
+ file: ast.File,
+ stmt: ast.Type_Switch_Stmt,
+ ast_context: ^AstContext,
+ document_position: ^DocumentPositionContext,
+) {
using ast
- if !(stmt.pos.offset <= document_position.position && document_position.position <= stmt.end.offset) {
+ if !(stmt.pos.offset <= document_position.position &&
+ document_position.position <= stmt.end.offset) {
return
}
@@ -2450,12 +3095,22 @@ get_locals_type_switch_stmt :: proc(file: ast.File, stmt: ast.Type_Switch_Stmt,
if block, ok := stmt.body.derived.(^Block_Stmt); ok {
for block_stmt in block.stmts {
- if cause, ok := block_stmt.derived.(^Case_Clause); ok && cause.pos.offset <= document_position.position && document_position.position <= cause.end.offset {
+ if cause, ok := block_stmt.derived.(^Case_Clause);
+ ok &&
+ cause.pos.offset <= document_position.position &&
+ document_position.position <= cause.end.offset {
tag := stmt.tag.derived.(^Assign_Stmt)
if len(tag.lhs) == 1 && len(cause.list) == 1 {
ident := tag.lhs[0].derived.(^Ident)
- store_local(ast_context, ident, cause.list[0], ident.pos.offset, ident.name, ast_context.local_id)
+ store_local(
+ ast_context,
+ ident,
+ cause.list[0],
+ ident.pos.offset,
+ ident.name,
+ ast_context.local_id,
+ )
ast_context.variables[ident.name] = true
}
@@ -2467,7 +3122,12 @@ get_locals_type_switch_stmt :: proc(file: ast.File, stmt: ast.Type_Switch_Stmt,
}
}
-get_locals_proc_param_and_results :: proc(file: ast.File, function: ast.Proc_Lit, ast_context: ^AstContext, document_position: ^DocumentPositionContext) {
+get_locals_proc_param_and_results :: proc(
+ file: ast.File,
+ function: ast.Proc_Lit,
+ ast_context: ^AstContext,
+ document_position: ^DocumentPositionContext,
+) {
proc_lit, ok := function.derived.(^ast.Proc_Lit)
if !ok || proc_lit.body == nil {
@@ -2479,19 +3139,37 @@ get_locals_proc_param_and_results :: proc(file: ast.File, function: ast.Proc_Lit
for name in arg.names {
if arg.type != nil {
str := common.get_ast_node_string(name, file.src)
- store_local(ast_context, name, arg.type, name.pos.offset, str, ast_context.local_id)
+ store_local(
+ ast_context,
+ name,
+ arg.type,
+ name.pos.offset,
+ str,
+ ast_context.local_id,
+ )
ast_context.variables[str] = true
ast_context.parameters[str] = true
if .Using in arg.flags {
using_stmt: ast.Using_Stmt
- using_stmt.list = make([]^ast.Expr, 1, context.temp_allocator)
+ using_stmt.list = make(
+ []^ast.Expr,
+ 1,
+ context.temp_allocator,
+ )
using_stmt.list[0] = arg.type
get_locals_using_stmt(using_stmt, ast_context)
}
} else {
str := common.get_ast_node_string(name, file.src)
- store_local(ast_context, name, arg.default_value, name.pos.offset, str, ast_context.local_id)
+ store_local(
+ ast_context,
+ name,
+ arg.default_value,
+ name.pos.offset,
+ str,
+ ast_context.local_id,
+ )
ast_context.variables[str] = true
ast_context.parameters[str] = true
}
@@ -2504,7 +3182,14 @@ get_locals_proc_param_and_results :: proc(file: ast.File, function: ast.Proc_Lit
for name in result.names {
if result.type != nil {
str := common.get_ast_node_string(name, file.src)
- store_local(ast_context, name, result.type, name.pos.offset, str, ast_context.local_id)
+ store_local(
+ ast_context,
+ name,
+ result.type,
+ name.pos.offset,
+ str,
+ ast_context.local_id,
+ )
ast_context.variables[str] = true
ast_context.parameters[str] = true
}
@@ -2513,14 +3198,24 @@ get_locals_proc_param_and_results :: proc(file: ast.File, function: ast.Proc_Lit
}
}
-get_locals :: proc(file: ast.File, function: ^ast.Node, ast_context: ^AstContext, document_position: ^DocumentPositionContext) {
+get_locals :: proc(
+ file: ast.File,
+ function: ^ast.Node,
+ ast_context: ^AstContext,
+ document_position: ^DocumentPositionContext,
+) {
proc_lit, ok := function.derived.(^ast.Proc_Lit)
if !ok || proc_lit.body == nil {
return
}
- get_locals_proc_param_and_results(file, proc_lit^, ast_context, document_position)
+ get_locals_proc_param_and_results(
+ file,
+ proc_lit^,
+ ast_context,
+ document_position,
+ )
block: ^ast.Block_Stmt
block, ok = proc_lit.body.derived.(^ast.Block_Stmt)
@@ -2549,8 +3244,20 @@ ResolveReferenceFlag :: enum {
StructElement,
}
-resolve_entire_file :: proc(document: ^Document, reference := "", flag := ResolveReferenceFlag.None, allocator := context.allocator) -> map[uintptr]SymbolAndNode {
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath, allocator)
+resolve_entire_file :: proc(
+ document: ^Document,
+ reference := "",
+ flag := ResolveReferenceFlag.None,
+ allocator := context.allocator,
+) -> map[uintptr]SymbolAndNode {
+ ast_context := make_ast_context(
+ document.ast,
+ document.imports,
+ document.package_name,
+ document.uri.uri,
+ document.fullpath,
+ allocator,
+ )
get_globals(document.ast, &ast_context)
@@ -2559,37 +3266,53 @@ resolve_entire_file :: proc(document: ^Document, reference := "", flag := Resolv
symbols := make(map[uintptr]SymbolAndNode, 10000, allocator)
for decl in document.ast.decls {
- resolve_entire_decl(&ast_context, document, decl, &symbols, reference, flag, allocator)
+ resolve_entire_decl(
+ &ast_context,
+ document,
+ decl,
+ &symbols,
+ reference,
+ flag,
+ allocator,
+ )
clear(&ast_context.locals)
}
return symbols
}
-resolve_entire_decl :: proc(ast_context: ^AstContext, document: ^Document, decl: ^ast.Node, symbols: ^map[uintptr]SymbolAndNode, reference := "", flag := ResolveReferenceFlag.None, allocator := context.allocator) {
+resolve_entire_decl :: proc(
+ ast_context: ^AstContext,
+ document: ^Document,
+ decl: ^ast.Node,
+ symbols: ^map[uintptr]SymbolAndNode,
+ reference := "",
+ flag := ResolveReferenceFlag.None,
+ allocator := context.allocator,
+) {
Scope :: struct {
offset: int,
id: int,
}
-
+
Visit_Data :: struct {
- ast_context: ^AstContext,
- symbols: ^map[uintptr]SymbolAndNode,
- scopes: [dynamic]Scope,
- id_counter: int,
- last_visit: ^ast.Node,
+ ast_context: ^AstContext,
+ symbols: ^map[uintptr]SymbolAndNode,
+ scopes: [dynamic]Scope,
+ id_counter: int,
+ last_visit: ^ast.Node,
resolve_flag: ResolveReferenceFlag,
- reference: string,
- document: ^Document,
+ reference: string,
+ document: ^Document,
}
data := Visit_Data {
- ast_context = ast_context,
- symbols = symbols,
- scopes = make([dynamic]Scope, allocator),
+ ast_context = ast_context,
+ symbols = symbols,
+ scopes = make([dynamic]Scope, allocator),
resolve_flag = flag,
- reference = reference,
- document = document,
+ reference = reference,
+ document = document,
}
visit :: proc(visitor: ^ast.Visitor, node: ^ast.Node) -> ^ast.Visitor {
@@ -2601,11 +3324,11 @@ resolve_entire_decl :: proc(ast_context: ^AstContext, document: ^Document, decl:
ast_context.use_locals = true
ast_context.use_globals = true
- data.last_visit = node;
+ data.last_visit = node
//It's somewhat silly to check the scope everytime, but the alternative is to implement my own walker function.
if len(data.scopes) > 0 {
- current_scope := data.scopes[len(data.scopes)-1]
+ current_scope := data.scopes[len(data.scopes) - 1]
if current_scope.offset < node.end.offset {
clear_local_group(ast_context, current_scope.id)
@@ -2613,12 +3336,12 @@ resolve_entire_decl :: proc(ast_context: ^AstContext, document: ^Document, decl:
pop(&data.scopes)
if len(data.scopes) > 0 {
- current_scope = data.scopes[len(data.scopes)-1]
+ current_scope = data.scopes[len(data.scopes) - 1]
ast_context.local_id = current_scope.id
} else {
ast_context.local_id = 0
}
- }
+ }
}
#partial switch v in node.derived {
@@ -2639,8 +3362,18 @@ resolve_entire_decl :: proc(ast_context: ^AstContext, document: ^Document, decl:
position_context: DocumentPositionContext
position_context.position = node.end.offset
- get_locals_proc_param_and_results(ast_context.file, v^, ast_context, &position_context)
- get_locals_stmt(ast_context.file, cast(^ast.Stmt)node, ast_context, &position_context)
+ get_locals_proc_param_and_results(
+ ast_context.file,
+ v^,
+ ast_context,
+ &position_context,
+ )
+ get_locals_stmt(
+ ast_context.file,
+ cast(^ast.Stmt)node,
+ ast_context,
+ &position_context,
+ )
case ^ast.If_Stmt, ^ast.For_Stmt, ^ast.Range_Stmt, ^ast.Inline_Range_Stmt:
scope: Scope
scope.id = data.id_counter
@@ -2653,73 +3386,92 @@ resolve_entire_decl :: proc(ast_context: ^AstContext, document: ^Document, decl:
position_context: DocumentPositionContext
position_context.position = node.end.offset
- get_locals_stmt(ast_context.file, cast(^ast.Stmt)node, ast_context, &position_context)
+ get_locals_stmt(
+ ast_context.file,
+ cast(^ast.Stmt)node,
+ ast_context,
+ &position_context,
+ )
}
if data.resolve_flag == .None {
- #partial switch v in node.derived {
- case ^ast.Ident:
+ #partial switch v in node.derived {
+ case ^ast.Ident:
if symbol, ok := resolve_type_identifier(ast_context, v^); ok {
data.symbols[cast(uintptr)node] = SymbolAndNode {
- node = v,
+ node = v,
symbol = symbol,
}
- }
+ }
case ^ast.Selector_Expr:
- if symbol, ok := resolve_type_expression(ast_context, &v.node); ok {
+ if symbol, ok := resolve_type_expression(ast_context, &v.node);
+ ok {
data.symbols[cast(uintptr)node] = SymbolAndNode {
- node = v,
+ node = v,
symbol = symbol,
}
}
case ^ast.Call_Expr:
- if symbol, ok := resolve_type_expression(ast_context, &v.node); ok {
+ if symbol, ok := resolve_type_expression(ast_context, &v.node);
+ ok {
data.symbols[cast(uintptr)node] = SymbolAndNode {
- node = v,
+ node = v,
symbol = symbol,
}
- }
+ }
}
} else {
- #partial done: switch v in node.derived {
+ #partial done: switch v in node.derived {
case ^ast.Selector_Expr:
- document : ^Document = data.document
+ document: ^Document = data.document
position_context := DocumentPositionContext {
position = v.pos.offset,
}
- get_document_position_decls(document.ast.decls[:], &position_context)
+ get_document_position_decls(
+ document.ast.decls[:],
+ &position_context,
+ )
- if symbol, ok := resolve_location_selector(ast_context, v); ok {
+ if symbol, ok := resolve_location_selector(ast_context, v);
+ ok {
data.symbols[cast(uintptr)node] = SymbolAndNode {
- node = v,
+ node = v,
symbol = symbol,
}
- }
- case ^ast.Ident:
+ }
+ case ^ast.Ident:
if data.resolve_flag == .Variable && v.name != data.reference {
break done
}
- document : ^Document = data.document
+ document: ^Document = data.document
position_context := DocumentPositionContext {
position = v.pos.offset,
}
- get_document_position_decls(document.ast.decls[:], &position_context)
+ get_document_position_decls(
+ document.ast.decls[:],
+ &position_context,
+ )
- if position_context.field_value != nil && position_in_node(position_context.field_value.field, v.pos.offset) {
+ if position_context.field_value != nil &&
+ position_in_node(
+ position_context.field_value.field,
+ v.pos.offset,
+ ) {
break done
}
- if symbol, ok := resolve_location_identifier(ast_context, v^); ok {
+ if symbol, ok := resolve_location_identifier(ast_context, v^);
+ ok {
data.symbols[cast(uintptr)node] = SymbolAndNode {
- node = v,
+ node = v,
symbol = symbol,
}
- }
+ }
}
}
@@ -2727,7 +3479,7 @@ resolve_entire_decl :: proc(ast_context: ^AstContext, document: ^Document, decl:
}
visitor := ast.Visitor {
- data = &data,
+ data = &data,
visit = visit,
}
@@ -2739,11 +3491,29 @@ concatenate_symbol_information :: proc {
concatenate_raw_string_information,
}
-concatenate_raw_symbol_information :: proc(ast_context: ^AstContext, symbol: Symbol, is_completion: bool) -> string {
- return concatenate_raw_string_information(ast_context, symbol.pkg, symbol.name, symbol.signature, symbol.type, is_completion)
+concatenate_raw_symbol_information :: proc(
+ ast_context: ^AstContext,
+ symbol: Symbol,
+ is_completion: bool,
+) -> string {
+ return concatenate_raw_string_information(
+ ast_context,
+ symbol.pkg,
+ symbol.name,
+ symbol.signature,
+ symbol.type,
+ is_completion,
+ )
}
-concatenate_raw_string_information :: proc(ast_context: ^AstContext, pkg: string, name: string, signature: string, type: SymbolType, is_completion: bool) -> string {
+concatenate_raw_string_information :: proc(
+ ast_context: ^AstContext,
+ pkg: string,
+ name: string,
+ signature: string,
+ type: SymbolType,
+ is_completion: bool,
+) -> string {
pkg := path.base(pkg, false, context.temp_allocator)
if type == .Package {
@@ -2759,7 +3529,13 @@ concatenate_raw_string_information :: proc(ast_context: ^AstContext, pkg: string
}
}
-unwrap_enum :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (SymbolEnumValue, bool) {
+unwrap_enum :: proc(
+ ast_context: ^AstContext,
+ node: ^ast.Expr,
+) -> (
+ SymbolEnumValue,
+ bool,
+) {
if node == nil {
return {}, false
}
@@ -2773,7 +3549,13 @@ unwrap_enum :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (SymbolEnumVal
return {}, false
}
-unwrap_union :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (SymbolUnionValue, bool) {
+unwrap_union :: proc(
+ ast_context: ^AstContext,
+ node: ^ast.Expr,
+) -> (
+ SymbolUnionValue,
+ bool,
+) {
if union_symbol, ok := resolve_type_expression(ast_context, node); ok {
if union_value, ok := union_symbol.value.(SymbolUnionValue); ok {
return union_value, true
@@ -2783,9 +3565,18 @@ unwrap_union :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (SymbolUnionV
return {}, false
}
-unwrap_bitset :: proc(ast_context: ^AstContext, bitset_symbol: Symbol) -> (SymbolEnumValue, bool) {
+unwrap_bitset :: proc(
+ ast_context: ^AstContext,
+ bitset_symbol: Symbol,
+) -> (
+ SymbolEnumValue,
+ bool,
+) {
if bitset_value, ok := bitset_symbol.value.(SymbolBitSetValue); ok {
- if enum_symbol, ok := resolve_type_expression(ast_context, bitset_value.expr); ok {
+ if enum_symbol, ok := resolve_type_expression(
+ ast_context,
+ bitset_value.expr,
+ ); ok {
if enum_value, ok := enum_symbol.value.(SymbolEnumValue); ok {
return enum_value, true
}
@@ -2795,7 +3586,12 @@ unwrap_bitset :: proc(ast_context: ^AstContext, bitset_symbol: Symbol) -> (Symbo
return {}, false
}
-get_signature :: proc(ast_context: ^AstContext, ident: ast.Ident, symbol: Symbol, was_variable := false) -> string {
+get_signature :: proc(
+ ast_context: ^AstContext,
+ ident: ast.Ident,
+ symbol: Symbol,
+ was_variable := false,
+) -> string {
if symbol.type == .Function {
return symbol.signature
}
@@ -2814,51 +3610,79 @@ get_signature :: proc(ast_context: ^AstContext, ident: ast.Ident, symbol: Symbol
case SymbolEnumValue:
if is_variable {
return symbol.name
- }
- else {
+ } else {
return "enum"
}
case SymbolMapValue:
- return strings.concatenate(a = {"map[", common.node_to_string(v.key), "]", common.node_to_string(v.value)}, allocator = ast_context.allocator)
+ return strings.concatenate(
+ a = {
+ "map[",
+ common.node_to_string(v.key),
+ "]",
+ common.node_to_string(v.value),
+ },
+ allocator = ast_context.allocator,
+ )
case SymbolProcedureValue:
return "proc"
case SymbolStructValue:
if is_variable {
return symbol.name
- }
- else {
+ } else {
return "struct"
}
case SymbolUnionValue:
if is_variable {
return symbol.name
- }
- else {
+ } else {
return "union"
}
case SymbolMultiPointer:
- return strings.concatenate(a = {"[^]", common.node_to_string(v.expr)}, allocator = ast_context.allocator)
+ return strings.concatenate(
+ a = {"[^]", common.node_to_string(v.expr)},
+ allocator = ast_context.allocator,
+ )
case SymbolDynamicArrayValue:
- return strings.concatenate(a = {"[dynamic]", common.node_to_string(v.expr)}, allocator = ast_context.allocator)
+ return strings.concatenate(
+ a = {"[dynamic]", common.node_to_string(v.expr)},
+ allocator = ast_context.allocator,
+ )
case SymbolSliceValue:
- return strings.concatenate(a = {"[]", common.node_to_string(v.expr)}, allocator = ast_context.allocator)
+ return strings.concatenate(
+ a = {"[]", common.node_to_string(v.expr)},
+ allocator = ast_context.allocator,
+ )
case SymbolFixedArrayValue:
- return strings.concatenate(a = {"[", common.node_to_string(v.len), "]", common.node_to_string(v.expr)}, allocator = ast_context.allocator)
+ return strings.concatenate(
+ a = {
+ "[",
+ common.node_to_string(v.len),
+ "]",
+ common.node_to_string(v.expr),
+ },
+ allocator = ast_context.allocator,
+ )
case SymbolPackageValue:
return "package"
case SymbolUntypedValue:
switch v.type {
- case .Float: return "float"
- case .String: return "string"
- case .Bool: return "bool"
- case .Integer: return "int"
+ case .Float:
+ return "float"
+ case .String:
+ return "string"
+ case .Bool:
+ return "bool"
+ case .Integer:
+ return "int"
}
}
-
+
return ""
}
-position_in_proc_decl :: proc(position_context: ^DocumentPositionContext) -> bool {
+position_in_proc_decl :: proc(
+ position_context: ^DocumentPositionContext,
+) -> bool {
if position_context.value_decl == nil {
return false
}
@@ -2867,12 +3691,16 @@ position_in_proc_decl :: proc(position_context: ^DocumentPositionContext) -> boo
return false
}
- if _, ok := position_context.value_decl.values[0].derived.(^ast.Proc_Type); ok {
+ if _, ok := position_context.value_decl.values[0].derived.(^ast.Proc_Type);
+ ok {
return true
}
- if proc_lit, ok := position_context.value_decl.values[0].derived.(^ast.Proc_Lit); ok {
- if proc_lit.type != nil && position_in_node(proc_lit.type, position_context.position) {
+ if proc_lit, ok := position_context.value_decl.values[
+ 0 \
+ ].derived.(^ast.Proc_Lit); ok {
+ if proc_lit.type != nil &&
+ position_in_node(proc_lit.type, position_context.position) {
return true
}
}
@@ -2906,7 +3734,10 @@ is_lhs_comp_lit :: proc(position_context: ^DocumentPositionContext) -> bool {
return true
}
-field_exists_in_comp_lit :: proc(comp_lit: ^ast.Comp_Lit, name: string) -> bool {
+field_exists_in_comp_lit :: proc(
+ comp_lit: ^ast.Comp_Lit,
+ name: string,
+) -> bool {
for elem in comp_lit.elems {
if field, ok := elem.derived.(^ast.Field_Value); ok {
if field.field != nil {
@@ -2925,7 +3756,10 @@ field_exists_in_comp_lit :: proc(comp_lit: ^ast.Comp_Lit, name: string) -> bool
/*
Parser gives ranges of expression, but not actually where the commas are placed.
*/
-get_call_commas :: proc(position_context: ^DocumentPositionContext, document: ^Document) {
+get_call_commas :: proc(
+ position_context: ^DocumentPositionContext,
+ document: ^Document,
+) {
if position_context.call == nil {
return
}
@@ -2942,12 +3776,18 @@ get_call_commas :: proc(position_context: ^DocumentPositionContext, document: ^D
}
for i := call.open.offset; i < call.close.offset; i += 1 {
switch document.text[i] {
- case '[': paren_count += 1
- case ']': paren_count -= 1
- case '{': brace_count += 1
- case '}': brace_count -= 1
- case '(': paren_count += 1
- case ')': paren_count -= 1
+ case '[':
+ paren_count += 1
+ case ']':
+ paren_count -= 1
+ case '{':
+ brace_count += 1
+ case '}':
+ brace_count -= 1
+ case '(':
+ paren_count += 1
+ case ')':
+ paren_count -= 1
case ',':
if paren_count == 0 && brace_count == 0 && bracket_count == 0 {
append(&commas, i)
@@ -2966,10 +3806,13 @@ type_to_string :: proc(ast_context: ^AstContext, expr: ^ast.Expr) -> string {
}
}
- return common.node_to_string(expr)
+ return common.node_to_string(expr)
}
-get_document_position_decls :: proc(decls: []^ast.Stmt, position_context: ^DocumentPositionContext) -> bool {
+get_document_position_decls :: proc(
+ decls: []^ast.Stmt,
+ position_context: ^DocumentPositionContext,
+) -> bool {
exists_in_decl := false
for decl in decls {
if position_in_node(decl, position_context.position) {
@@ -2988,14 +3831,24 @@ get_document_position_decls :: proc(decls: []^ast.Stmt, position_context: ^Docum
/*
Figure out what exactly is at the given position and whether it is in a function, struct, etc.
*/
-get_document_position_context :: proc(document: ^Document, position: common.Position, hint: DocumentPositionContextHint) -> (DocumentPositionContext, bool) {
+get_document_position_context :: proc(
+ document: ^Document,
+ position: common.Position,
+ hint: DocumentPositionContextHint,
+) -> (
+ DocumentPositionContext,
+ bool,
+) {
position_context: DocumentPositionContext
position_context.hint = hint
position_context.file = document.ast
position_context.line = position.line
- absolute_position, ok := common.get_absolute_position(position, document.text)
+ absolute_position, ok := common.get_absolute_position(
+ position,
+ document.text,
+ )
if !ok {
log.error("failed to get absolute position")
@@ -3004,7 +3857,10 @@ get_document_position_context :: proc(document: ^Document, position: common.Posi
position_context.position = absolute_position
- exists_in_decl := get_document_position_decls(document.ast.decls[:], &position_context)
+ exists_in_decl := get_document_position_decls(
+ document.ast.decls[:],
+ &position_context,
+ )
for import_stmt in document.ast.imports {
if position_in_node(import_stmt, position_context.position) {
@@ -3017,11 +3873,17 @@ get_document_position_context :: proc(document: ^Document, position: common.Posi
position_context.abort_completion = true
}
- if !position_in_node(position_context.comp_lit, position_context.position) {
+ if !position_in_node(
+ position_context.comp_lit,
+ position_context.position,
+ ) {
position_context.comp_lit = nil
}
- if !position_in_node(position_context.parent_comp_lit, position_context.position) {
+ if !position_in_node(
+ position_context.parent_comp_lit,
+ position_context.position,
+ ) {
position_context.parent_comp_lit = nil
}
@@ -3033,16 +3895,30 @@ get_document_position_context :: proc(document: ^Document, position: common.Posi
position_context.binary = nil
}
- if !position_in_node(position_context.parent_binary, position_context.position) {
+ if !position_in_node(
+ position_context.parent_binary,
+ position_context.position,
+ ) {
position_context.parent_binary = nil
}
- if hint == .Completion && position_context.selector == nil && position_context.field == nil {
- fallback_position_context_completion(document, position, &position_context)
+ if hint == .Completion &&
+ position_context.selector == nil &&
+ position_context.field == nil {
+ fallback_position_context_completion(
+ document,
+ position,
+ &position_context,
+ )
}
- if (hint == .SignatureHelp || hint == .Completion) && position_context.call == nil {
- fallback_position_context_signature(document, position, &position_context)
+ if (hint == .SignatureHelp || hint == .Completion) &&
+ position_context.call == nil {
+ fallback_position_context_signature(
+ document,
+ position,
+ &position_context,
+ )
}
if hint == .SignatureHelp {
@@ -3053,16 +3929,20 @@ get_document_position_context :: proc(document: ^Document, position: common.Posi
}
//terrible fallback code
-fallback_position_context_completion :: proc(document: ^Document, position: common.Position, position_context: ^DocumentPositionContext) {
- paren_count: int
+fallback_position_context_completion :: proc(
+ document: ^Document,
+ position: common.Position,
+ position_context: ^DocumentPositionContext,
+) {
+ paren_count: int
bracket_count: int
- end: int
- start: int
- empty_dot: bool
- empty_arrow: bool
- last_dot: bool
- last_arrow: bool
- dots_seen: int
+ end: int
+ start: int
+ empty_dot: bool
+ empty_arrow: bool
+ last_dot: bool
+ last_arrow: bool
+ dots_seen: int
partial_arrow: bool
i := position_context.position - 1
@@ -3110,11 +3990,21 @@ fallback_position_context_completion :: proc(document: ^Document, position: comm
}
//yeah..
- if c == ' ' || c == '{' || c == ',' ||
- c == '}' || c == '^' || c == ':' ||
- c == '\n' || c == '\r' || c == '=' ||
- c == '<' || c == '-' || c == '!' ||
- c == '+' || c == '&'|| c == '|' {
+ if c == ' ' ||
+ c == '{' ||
+ c == ',' ||
+ c == '}' ||
+ c == '^' ||
+ c == ':' ||
+ c == '\n' ||
+ c == '\r' ||
+ c == '=' ||
+ c == '<' ||
+ c == '-' ||
+ c == '!' ||
+ c == '+' ||
+ c == '&' ||
+ c == '|' {
start = i + 1
break
} else if c == '>' {
@@ -3130,14 +4020,16 @@ fallback_position_context_completion :: proc(document: ^Document, position: comm
if i >= 0 && position_context.file.src[end] == '.' {
empty_dot = true
end -= 1
- } else if i >= 0 && position_context.file.src[max(0, end - 1)] == '-' && position_context.file.src[end] == '>' {
+ } else if i >= 0 &&
+ position_context.file.src[max(0, end - 1)] == '-' &&
+ position_context.file.src[end] == '>' {
empty_arrow = true
end -= 2
position_context.arrow = true
}
begin_offset := max(0, start)
- end_offset := max(start, end + 1)
+ end_offset := max(start, end + 1)
line_offset := begin_offset
if line_offset < len(position_context.file.src) {
@@ -3176,17 +4068,22 @@ fallback_position_context_completion :: proc(document: ^Document, position: comm
}
p := parser.Parser {
- err = common.parser_warning_handler, //empty
+ err = common.parser_warning_handler, //empty
warn = common.parser_warning_handler, //empty
flags = {.Optional_Semicolons},
file = &position_context.file,
}
- tokenizer.init(&p.tok, str, position_context.file.fullpath, common.parser_warning_handler)
+ tokenizer.init(
+ &p.tok,
+ str,
+ position_context.file.fullpath,
+ common.parser_warning_handler,
+ )
p.tok.ch = ' '
p.tok.line_count = position.line + 1
- p.tok.line_offset = line_offset
+ p.tok.line_offset = line_offset
p.tok.offset = begin_offset
p.tok.read_offset = begin_offset
@@ -3215,18 +4112,28 @@ fallback_position_context_completion :: proc(document: ^Document, position: comm
//this is most likely because of use of 'in', 'context', etc.
//try to go back one dot.
- src_with_dot := string(position_context.file.src[0:min(len(position_context.file.src), end_offset + 1)])
- last_dot := strings.last_index(src_with_dot, ".")
+ src_with_dot := string(
+ position_context.file.src[0:min(
+ len(position_context.file.src),
+ end_offset + 1,
+ )],
+ )
+ last_dot := strings.last_index(src_with_dot, ".")
if last_dot == -1 {
return
}
- tokenizer.init(&p.tok, position_context.file.src[0:last_dot], position_context.file.fullpath, common.parser_warning_handler)
+ tokenizer.init(
+ &p.tok,
+ position_context.file.src[0:last_dot],
+ position_context.file.fullpath,
+ common.parser_warning_handler,
+ )
p.tok.ch = ' '
p.tok.line_count = position.line + 1
- p.tok.line_offset = line_offset
+ p.tok.line_offset = line_offset
p.tok.offset = begin_offset
p.tok.read_offset = begin_offset
@@ -3261,8 +4168,12 @@ fallback_position_context_completion :: proc(document: ^Document, position: comm
}
}
-fallback_position_context_signature :: proc(document: ^Document, position: common.Position, position_context: ^DocumentPositionContext) {
- end: int
+fallback_position_context_signature :: proc(
+ document: ^Document,
+ position: common.Position,
+ position_context: ^DocumentPositionContext,
+) {
+ end: int
start: int
i := position_context.position - 1
end = i
@@ -3290,7 +4201,7 @@ fallback_position_context_signature :: proc(document: ^Document, position: commo
end -= 1
begin_offset := max(0, start)
- end_offset := max(start, end + 1)
+ end_offset := max(start, end + 1)
if end_offset - begin_offset <= 1 {
return
@@ -3299,12 +4210,17 @@ fallback_position_context_signature :: proc(document: ^Document, position: commo
str := position_context.file.src[0:end_offset]
p := parser.Parser {
- err = common.parser_warning_handler, //empty
+ err = common.parser_warning_handler, //empty
warn = common.parser_warning_handler, //empty
file = &position_context.file,
}
- tokenizer.init(&p.tok, str, position_context.file.fullpath, common.parser_warning_handler)
+ tokenizer.init(
+ &p.tok,
+ str,
+ position_context.file.fullpath,
+ common.parser_warning_handler,
+ )
p.tok.ch = ' '
p.tok.line_count = position.line
@@ -3326,7 +4242,7 @@ fallback_position_context_signature :: proc(document: ^Document, position: commo
if _, ok := position_context.call.derived.(^ast.Proc_Type); ok {
position_context.call = nil
}
-
+
//log.error(string(position_context.file.src[begin_offset:end_offset]));
}
@@ -3334,29 +4250,45 @@ fallback_position_context_signature :: proc(document: ^Document, position: commo
All these fallback functions are not perfect and should be fixed. A lot of weird use of the odin tokenizer and parser.
*/
-get_document_position ::proc {
+get_document_position :: proc {
get_document_position_array,
get_document_position_dynamic_array,
get_document_position_node,
}
-get_document_position_array :: proc(array: $A/[]^$T, position_context: ^DocumentPositionContext) {
+get_document_position_array :: proc(
+ array: $A/[]^$T,
+ position_context: ^DocumentPositionContext,
+) {
for elem, i in array {
get_document_position(elem, position_context)
}
}
-get_document_position_dynamic_array :: proc(array: $A/[dynamic]^$T, position_context: ^DocumentPositionContext) {
+get_document_position_dynamic_array :: proc(
+ array: $A/[dynamic]^$T,
+ position_context: ^DocumentPositionContext,
+) {
for elem, i in array {
get_document_position(elem, position_context)
}
}
-position_in_node :: proc(node: ^ast.Node, position: common.AbsolutePosition) -> bool {
- return node != nil && node.pos.offset <= position && position <= node.end.offset
+position_in_node :: proc(
+ node: ^ast.Node,
+ position: common.AbsolutePosition,
+) -> bool {
+ return(
+ node != nil &&
+ node.pos.offset <= position &&
+ position <= node.end.offset \
+ )
}
-get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentPositionContext) {
+get_document_position_node :: proc(
+ node: ^ast.Node,
+ position_context: ^DocumentPositionContext,
+) {
using ast
if node == nil {
@@ -3385,7 +4317,7 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP
if position_in_node(n.body, position_context.position) {
position_context.function = cast(^Proc_Lit)node
get_document_position(n.body, position_context)
- }
+ }
case ^Comp_Lit:
//only set this for the parent comp literal, since we will need to walk through it to infer types.
if position_context.parent_comp_lit == nil {
@@ -3410,19 +4342,23 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP
case ^Paren_Expr:
get_document_position(n.expr, position_context)
case ^Call_Expr:
- if position_context.hint == .SignatureHelp || position_context.hint == .Completion {
+ if position_context.hint == .SignatureHelp ||
+ position_context.hint == .Completion {
position_context.call = cast(^Expr)node
}
get_document_position(n.expr, position_context)
get_document_position(n.args, position_context)
case ^Selector_Expr:
if position_context.hint == .Completion {
- if n.field != nil && n.field.pos.line - 1 == position_context.line {
+ if n.field != nil &&
+ n.field.pos.line - 1 == position_context.line {
//The parser is not fault tolerant enough, relying on the fallback as the main completion parsing for now
//position_context.selector = n.expr;
//position_context.field = n.field;
}
- } else if (position_context.hint == .Definition || position_context.hint == .Hover) && n.field != nil {
+ } else if (position_context.hint == .Definition ||
+ position_context.hint == .Hover) &&
+ n.field != nil {
position_context.selector = n.expr
position_context.field = n.field
position_context.selector_expr = cast(^Selector_Expr)node
@@ -3533,7 +4469,8 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP
get_document_position(n.attributes, position_context)
for name in n.names {
- if position_in_node(name, position_context.position) && n.end.line - 1 == position_context.line {
+ if position_in_node(name, position_context.position) &&
+ n.end.line - 1 == position_context.line {
position_context.abort_completion = true
break
}
diff --git a/src/server/build.odin b/src/server/build.odin
index 7abe95c..4f97dfd 100644
--- a/src/server/build.odin
+++ b/src/server/build.odin
@@ -17,22 +17,22 @@ import "shared:common"
platform_os: map[string]bool = {
"windows" = true,
- "linux" = true,
+ "linux" = true,
"essence" = true,
- "js" = true,
+ "js" = true,
"freebsd" = true,
- "darwin" = true,
- "wasm32" = true,
+ "darwin" = true,
+ "wasm32" = true,
}
os_enum_to_string: map[runtime.Odin_OS_Type]string = {
- .Windows = "windows",
- .Darwin = "darwin",
- .Linux = "linux",
- .Essence = "essence",
- .FreeBSD = "freebsd",
- .WASI = "wasi",
- .JS = "js",
+ .Windows = "windows",
+ .Darwin = "darwin",
+ .Linux = "linux",
+ .Essence = "essence",
+ .FreeBSD = "freebsd",
+ .WASI = "wasi",
+ .JS = "js",
.Freestanding = "freestanding",
}
@@ -41,7 +41,10 @@ try_build_package :: proc(pkg_name: string) {
return
}
- matches, err := filepath.glob(fmt.tprintf("%v/*.odin", pkg_name), context.temp_allocator)
+ matches, err := filepath.glob(
+ fmt.tprintf("%v/*.odin", pkg_name),
+ context.temp_allocator,
+ )
if err != .None {
log.errorf("Failed to glob %v for indexing package", pkg_name)
@@ -49,9 +52,12 @@ try_build_package :: proc(pkg_name: string) {
temp_arena: mem.Arena
- mem.arena_init(&temp_arena, make([]byte, mem.Megabyte*25, runtime.default_allocator()))
+ mem.arena_init(
+ &temp_arena,
+ make([]byte, mem.Megabyte * 25, runtime.default_allocator()),
+ )
defer delete(temp_arena.data)
-
+
{
context.allocator = mem.arena_allocator(&temp_arena)
@@ -59,7 +65,10 @@ try_build_package :: proc(pkg_name: string) {
data, ok := os.read_entire_file(fullpath, context.allocator)
if !ok {
- log.errorf("failed to read entire file for indexing %v", fullpath)
+ log.errorf(
+ "failed to read entire file for indexing %v",
+ fullpath,
+ )
continue
}
@@ -82,8 +91,8 @@ try_build_package :: proc(pkg_name: string) {
file := ast.File {
fullpath = fullpath,
- src = string(data),
- pkg = pkg,
+ src = string(data),
+ pkg = pkg,
}
ok = parser.parse_file(&p, &file)
@@ -101,18 +110,27 @@ try_build_package :: proc(pkg_name: string) {
}
}
- build_cache.loaded_pkgs[strings.clone(pkg_name, indexer.index.collection.allocator)] = PackageCacheInfo {
+ build_cache.loaded_pkgs[
+ strings.clone(pkg_name, indexer.index.collection.allocator) \
+ ] = PackageCacheInfo {
timestamp = time.now(),
- }
+ }
}
setup_index :: proc() {
- build_cache.loaded_pkgs = make(map[string]PackageCacheInfo, 50, context.allocator)
- symbol_collection := make_symbol_collection(context.allocator, &common.config)
+ 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)
dir_exe := path.dir(os.args[0])
-
+
try_build_package(path.join({dir_exe, "builtin"}))
}
diff --git a/src/server/caches.odin b/src/server/caches.odin
index 80128f4..55091fd 100644
--- a/src/server/caches.odin
+++ b/src/server/caches.odin
@@ -17,7 +17,9 @@ FileResolveCache :: struct {
file_resolve_cache: FileResolveCache
-resolve_entire_file_cached :: proc(document: ^Document) -> map[uintptr]SymbolAndNode{
+resolve_entire_file_cached :: proc(
+ document: ^Document,
+) -> map[uintptr]SymbolAndNode {
if document.uri.uri not_in file_resolve_cache.files {
file_resolve_cache.files[document.uri.uri] = FileResolve {
symbols = resolve_entire_file(
@@ -27,9 +29,9 @@ resolve_entire_file_cached :: proc(document: ^Document) -> map[uintptr]SymbolAnd
common.scratch_allocator(document.allocator),
),
}
- }
+ }
- return file_resolve_cache.files[document.uri.uri].symbols;
+ return file_resolve_cache.files[document.uri.uri].symbols
}
BuildCache :: struct {
@@ -40,4 +42,4 @@ PackageCacheInfo :: struct {
timestamp: time.Time,
}
-build_cache: BuildCache \ No newline at end of file
+build_cache: BuildCache
diff --git a/src/server/check.odin b/src/server/check.odin
index 6d57b95..056783a 100644
--- a/src/server/check.odin
+++ b/src/server/check.odin
@@ -19,11 +19,11 @@ import "core:text/scanner"
import "shared:common"
is_package :: proc(file: string, pkg: string) {
-
+
}
check :: proc(uri: common.Uri, writer: ^Writer, config: ^common.Config) {
- data := make([]byte, mem.Kilobyte*10, context.temp_allocator)
+ data := make([]byte, mem.Kilobyte * 10, context.temp_allocator)
buffer: []byte
code: u32
@@ -35,7 +35,10 @@ check :: proc(uri: common.Uri, writer: ^Writer, config: ^common.Config) {
if k == "" || k == "core" || k == "vendor" {
continue
}
- strings.write_string(&collection_builder, fmt.aprintf("-collection:%v=%v ", k, v))
+ strings.write_string(
+ &collection_builder,
+ fmt.aprintf("-collection:%v=%v ", k, v),
+ )
}
command: string
@@ -47,32 +50,37 @@ check :: proc(uri: common.Uri, writer: ^Writer, config: ^common.Config) {
}
if code, ok, buffer = common.run_executable(
- fmt.tprintf("%v check %s %s -no-entry-point %s %s",
- command,
- path.dir(uri.path, context.temp_allocator),
- strings.to_string(collection_builder),
- config.checker_args,
- ODIN_OS == .Linux || ODIN_OS == .Darwin ? "2>&1" : "",
- ),
- &data
- ); !ok {
- log.errorf("Odin check failed with code %v for file %v", code, uri.path)
+ fmt.tprintf(
+ "%v check %s %s -no-entry-point %s %s",
+ command,
+ path.dir(uri.path, context.temp_allocator),
+ strings.to_string(collection_builder),
+ config.checker_args,
+ ODIN_OS == .Linux || ODIN_OS == .Darwin ? "2>&1" : "",
+ ),
+ &data,
+ ); !ok {
+ log.errorf(
+ "Odin check failed with code %v for file %v",
+ code,
+ uri.path,
+ )
return
- }
+ }
s: scanner.Scanner
scanner.init(&s, string(buffer))
- s.whitespace = {'\t', ' '}
+ s.whitespace = {'\t', ' '}
current: rune
ErrorSeperator :: struct {
message: string,
- line: int,
- column: int,
- uri: string,
+ line: int,
+ column: int,
+ uri: string,
}
error_seperators := make([dynamic]ErrorSeperator, context.temp_allocator)
@@ -93,10 +101,10 @@ check :: proc(uri: common.Uri, writer: ^Writer, config: ^common.Config) {
if n == scanner.EOF {
break loop
- }
+ }
}
- error.uri = string(buffer[source_pos:s.src_pos-1])
+ error.uri = string(buffer[source_pos:s.src_pos - 1])
left_paren := scanner.scan(&s)
@@ -123,7 +131,7 @@ check :: proc(uri: common.Uri, writer: ^Writer, config: ^common.Config) {
if seperator != ':' {
break loop
- }
+ }
rhs_digit := scanner.scan(&s)
@@ -157,7 +165,7 @@ check :: proc(uri: common.Uri, writer: ^Writer, config: ^common.Config) {
continue
}
- error.message = string(buffer[source_pos:s.src_pos-1])
+ error.message = string(buffer[source_pos:s.src_pos - 1])
error.column = column
error.line = line
@@ -169,32 +177,34 @@ check :: proc(uri: common.Uri, writer: ^Writer, config: ^common.Config) {
for error in error_seperators {
if error.uri not_in errors {
- errors[error.uri] = make([dynamic]Diagnostic, context.temp_allocator)
- }
-
- append(&errors[error.uri], Diagnostic {
- code = "checker",
- severity = .Error,
- range = {
- start = {
- character = 0,
- line = error.line - 1,
- },
- end = {
- character = 0,
- line = error.line,
+ errors[error.uri] = make(
+ [dynamic]Diagnostic,
+ context.temp_allocator,
+ )
+ }
+
+ append(
+ &errors[error.uri],
+ Diagnostic{
+ code = "checker",
+ severity = .Error,
+ range = {
+ start = {character = 0, line = error.line - 1},
+ end = {character = 0, line = error.line},
},
+ message = error.message,
},
- message = error.message,
- })
+ )
}
- matches, err := filepath.glob(fmt.tprintf("%v/*.odin", path.dir(uri.path, context.temp_allocator)))
+ matches, err := filepath.glob(
+ fmt.tprintf("%v/*.odin", path.dir(uri.path, context.temp_allocator)),
+ )
if err == .None {
for match in matches {
uri := common.create_uri(match, context.temp_allocator)
-
+
params := NotificationPublishDiagnosticsParams {
uri = uri.uri,
diagnostics = {},
@@ -202,8 +212,8 @@ check :: proc(uri: common.Uri, writer: ^Writer, config: ^common.Config) {
notifaction := Notification {
jsonrpc = "2.0",
- method = "textDocument/publishDiagnostics",
- params = params,
+ method = "textDocument/publishDiagnostics",
+ params = params,
}
if writer != nil {
@@ -216,14 +226,14 @@ check :: proc(uri: common.Uri, writer: ^Writer, config: ^common.Config) {
uri := common.create_uri(k, context.temp_allocator)
params := NotificationPublishDiagnosticsParams {
- uri = uri.uri,
+ uri = uri.uri,
diagnostics = v[:],
}
notifaction := Notification {
jsonrpc = "2.0",
- method = "textDocument/publishDiagnostics",
- params = params,
+ method = "textDocument/publishDiagnostics",
+ params = params,
}
if writer != nil {
diff --git a/src/server/clone.odin b/src/server/clone.odin
index 9a4af46..9db9ecb 100644
--- a/src/server/clone.odin
+++ b/src/server/clone.odin
@@ -10,7 +10,12 @@ import "core:intrinsics"
import "core:reflect"
_ :: intrinsics
-new_type :: proc($T: typeid, pos, end: tokenizer.Pos, allocator: mem.Allocator) -> ^T {
+new_type :: proc(
+ $T: typeid,
+ pos,
+ end: tokenizer.Pos,
+ allocator: mem.Allocator,
+) -> ^T {
n, _ := mem.new(T, allocator)
n.pos = pos
n.end = end
@@ -33,7 +38,11 @@ clone_type :: proc {
clone_dynamic_array,
}
-clone_array :: proc(array: $A/[]^$T, allocator: mem.Allocator, unique_strings: ^map[string]string) -> A {
+clone_array :: proc(
+ array: $A/[]^$T,
+ allocator: mem.Allocator,
+ unique_strings: ^map[string]string,
+) -> A {
if len(array) == 0 {
return nil
}
@@ -44,7 +53,11 @@ clone_array :: proc(array: $A/[]^$T, allocator: mem.Allocator, unique_strings: ^
return res
}
-clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator, unique_strings: ^map[string]string) -> A {
+clone_dynamic_array :: proc(
+ array: $A/[dynamic]^$T,
+ allocator: mem.Allocator,
+ unique_strings: ^map[string]string,
+) -> A {
if len(array) == 0 {
return nil
}
@@ -52,25 +65,33 @@ clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator, un
for elem, i in array {
res[i] = auto_cast clone_type(elem, allocator, unique_strings)
}
- return res
+ return res
}
-clone_expr :: proc(node: ^ast.Expr, allocator: mem.Allocator, unique_strings: ^map[string]string) -> ^ast.Expr {
+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, unique_strings: ^map[string]string) -> ^ast.Node {
+clone_node :: proc(
+ node: ^ast.Node,
+ allocator: mem.Allocator,
+ unique_strings: ^map[string]string,
+) -> ^ast.Node {
using ast
if node == nil {
return nil
}
- size := size_of(Node)
+ size := size_of(Node)
align := align_of(Node)
ti := reflect.union_variant_type_info(node.derived)
if ti != nil {
elem := ti.variant.(reflect.Type_Info_Pointer).elem
- size = elem.size
+ size = elem.size
align = elem.align
}
@@ -90,13 +111,21 @@ clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator, unique_strings: ^m
res_ptr_any.id = ti.id
if unique_strings != nil && node.pos.file != "" {
- res.pos.file = get_index_unique_string(unique_strings, allocator, node.pos.file)
+ res.pos.file = get_index_unique_string(
+ unique_strings,
+ allocator,
+ node.pos.file,
+ )
} else {
res.pos.file = node.pos.file
}
if unique_strings != nil && node.end.file != "" {
- res.end.file = get_index_unique_string(unique_strings, allocator, node.end.file)
+ res.end.file = get_index_unique_string(
+ unique_strings,
+ allocator,
+ node.end.file,
+ )
} else {
res.end.file = node.end.file
}
@@ -105,149 +134,197 @@ clone_node :: proc(node: ^ast.Node, allocator: mem.Allocator, unique_strings: ^m
res_ptr := reflect.deref(res_ptr_any)
- if de := reflect.struct_field_value_by_name(res_ptr, "derived_expr", true); de != nil {
+ if de := reflect.struct_field_value_by_name(res_ptr, "derived_expr", true);
+ de != nil {
reflect.set_union_value(de, res_ptr_any)
}
- if ds := reflect.struct_field_value_by_name(res_ptr, "derived_stmt", true); ds != nil {
+ if ds := reflect.struct_field_value_by_name(res_ptr, "derived_stmt", true);
+ ds != nil {
reflect.set_union_value(ds, res_ptr_any)
}
if res.derived != nil do #partial switch r in res.derived {
- case ^Ident:
- n := node.derived.(^Ident)
+ case ^Ident:
+ n := node.derived.(^Ident)
- 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:
- n := node.derived.(^Implicit)
- if unique_strings == nil {
- r.tok.text = strings.clone(n.tok.text, allocator)
- } else {
- r.tok.text = get_index_unique_string(unique_strings, allocator, n.tok.text)
- }
- case ^Undef:
- case ^Basic_Lit:
- n := node.derived.(^Basic_Lit)
- if unique_strings == nil {
- r.tok.text = strings.clone(n.tok.text, allocator)
- } else {
- r.tok.text = get_index_unique_string(unique_strings, allocator, n.tok.text)
- }
- case ^Basic_Directive:
- n := node.derived.(^Basic_Directive)
- if unique_strings == nil {
- r.name = strings.clone(n.name, allocator)
- } else {
- r.name = get_index_unique_string(unique_strings, allocator, n.name)
- }
- case ^Ellipsis:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- case ^Tag_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- case ^Unary_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- case ^Binary_Expr:
- r.left = clone_type(r.left, allocator, unique_strings)
- r.right = clone_type(r.right, allocator, unique_strings)
- case ^Paren_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- case ^Selector_Expr:
- 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.field = auto_cast clone_type(r.field, allocator, unique_strings)
- case ^Slice_Expr:
- 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.elems = clone_type(r.elems, allocator, unique_strings)
- case ^Distinct_Type:
- r.type = clone_type(r.type, allocator, unique_strings)
- case ^Proc_Type:
- 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.elem = clone_type(r.elem, allocator, unique_strings)
- case ^Array_Type:
- 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.elem = clone_type(r.elem, allocator, unique_strings)
- r.tag = clone_type(r.tag, allocator, unique_strings)
- case ^Struct_Type:
- 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.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.list = clone_type(r.list, allocator, unique_strings)
- case ^Field_Value:
- r.field = clone_type(r.field, allocator, unique_strings)
- r.value = clone_type(r.value, allocator, unique_strings)
- case ^Union_Type:
- 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.base_type = clone_type(r.base_type, allocator, unique_strings)
- r.fields = clone_type(r.fields, allocator, unique_strings)
- case ^Bit_Set_Type:
- r.elem = clone_type(r.elem, allocator, unique_strings)
- r.underlying = clone_type(r.underlying, allocator, unique_strings)
- case ^Map_Type:
- r.key = clone_type(r.key, allocator, unique_strings)
- r.value = clone_type(r.value, allocator, unique_strings)
- case ^Call_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- r.args = clone_type(r.args, allocator, unique_strings)
- case ^Typeid_Type:
- r.specialization = clone_type(r.specialization, allocator, unique_strings)
- case ^Ternary_When_Expr:
- 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.type = auto_cast clone_type(r.type, allocator, unique_strings)
- r.specialization = clone_type(r.specialization, allocator, unique_strings)
- case ^Proc_Group:
- r.args = clone_type(r.args, allocator, unique_strings)
- case ^Comp_Lit:
- r.type = clone_type(r.type, allocator, unique_strings)
- r.elems = clone_type(r.elems, allocator, unique_strings)
- case ^Proc_Lit:
- r.type = cast(^Proc_Type)clone_type(cast(^Node)r.type, allocator, unique_strings)
- r.body = nil
- r.where_clauses = nil
- case ^Helper_Type:
- r.type = clone_type(r.type, allocator, unique_strings)
- case ^Type_Cast:
- r.type = clone_type(r.type, allocator, unique_strings)
- r.expr = clone_type(r.expr, allocator, unique_strings)
- case ^Deref_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- case ^Index_Expr:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- r.index = clone_type(r.index, allocator, unique_strings)
- case ^Multi_Pointer_Type:
- r.elem = clone_type(r.elem, allocator, unique_strings)
- case ^Matrix_Type:
- r.elem = clone_type(r.elem, allocator, unique_strings)
- case ^Type_Assertion:
- r.expr = clone_type(r.expr, allocator, unique_strings)
- r.type = clone_type(r.type, allocator, unique_strings)
- case:
+ 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:
+ n := node.derived.(^Implicit)
+ if unique_strings == nil {
+ r.tok.text = strings.clone(n.tok.text, allocator)
+ } else {
+ r.tok.text = get_index_unique_string(
+ unique_strings,
+ allocator,
+ n.tok.text,
+ )
+ }
+ case ^Undef:
+ case ^Basic_Lit:
+ n := node.derived.(^Basic_Lit)
+ if unique_strings == nil {
+ r.tok.text = strings.clone(n.tok.text, allocator)
+ } else {
+ r.tok.text = get_index_unique_string(
+ unique_strings,
+ allocator,
+ n.tok.text,
+ )
+ }
+ case ^Basic_Directive:
+ n := node.derived.(^Basic_Directive)
+ if unique_strings == nil {
+ r.name = strings.clone(n.name, allocator)
+ } else {
+ r.name = get_index_unique_string(
+ unique_strings,
+ allocator,
+ n.name,
+ )
+ }
+ case ^Ellipsis:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ case ^Tag_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ case ^Unary_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ case ^Binary_Expr:
+ r.left = clone_type(r.left, allocator, unique_strings)
+ r.right = clone_type(r.right, allocator, unique_strings)
+ case ^Paren_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ case ^Selector_Expr:
+ 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.field = auto_cast clone_type(r.field, allocator, unique_strings)
+ case ^Slice_Expr:
+ 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.elems = clone_type(r.elems, allocator, unique_strings)
+ case ^Distinct_Type:
+ r.type = clone_type(r.type, allocator, unique_strings)
+ case ^Proc_Type:
+ 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.elem = clone_type(r.elem, allocator, unique_strings)
+ case ^Array_Type:
+ 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.elem = clone_type(r.elem, allocator, unique_strings)
+ r.tag = clone_type(r.tag, allocator, unique_strings)
+ case ^Struct_Type:
+ 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.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.list = clone_type(r.list, allocator, unique_strings)
+ case ^Field_Value:
+ r.field = clone_type(r.field, allocator, unique_strings)
+ r.value = clone_type(r.value, allocator, unique_strings)
+ case ^Union_Type:
+ 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.base_type = clone_type(r.base_type, allocator, unique_strings)
+ r.fields = clone_type(r.fields, allocator, unique_strings)
+ case ^Bit_Set_Type:
+ r.elem = clone_type(r.elem, allocator, unique_strings)
+ r.underlying = clone_type(r.underlying, allocator, unique_strings)
+ case ^Map_Type:
+ r.key = clone_type(r.key, allocator, unique_strings)
+ r.value = clone_type(r.value, allocator, unique_strings)
+ case ^Call_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ r.args = clone_type(r.args, allocator, unique_strings)
+ case ^Typeid_Type:
+ r.specialization = clone_type(
+ r.specialization,
+ allocator,
+ unique_strings,
+ )
+ case ^Ternary_When_Expr:
+ 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.type = auto_cast clone_type(r.type, allocator, unique_strings)
+ r.specialization = clone_type(
+ r.specialization,
+ allocator,
+ unique_strings,
+ )
+ case ^Proc_Group:
+ r.args = clone_type(r.args, allocator, unique_strings)
+ case ^Comp_Lit:
+ r.type = clone_type(r.type, allocator, unique_strings)
+ r.elems = clone_type(r.elems, allocator, unique_strings)
+ case ^Proc_Lit:
+ r.type =
+ cast(^Proc_Type)clone_type(
+ cast(^Node)r.type,
+ allocator,
+ unique_strings,
+ )
+ r.body = nil
+ r.where_clauses = nil
+ case ^Helper_Type:
+ r.type = clone_type(r.type, allocator, unique_strings)
+ case ^Type_Cast:
+ r.type = clone_type(r.type, allocator, unique_strings)
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ case ^Deref_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ case ^Index_Expr:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ r.index = clone_type(r.index, allocator, unique_strings)
+ case ^Multi_Pointer_Type:
+ r.elem = clone_type(r.elem, allocator, unique_strings)
+ case ^Matrix_Type:
+ r.elem = clone_type(r.elem, allocator, unique_strings)
+ case ^Type_Assertion:
+ r.expr = clone_type(r.expr, allocator, unique_strings)
+ r.type = clone_type(r.type, allocator, unique_strings)
+ case:
//fmt.logf("Unhandled node kind: %T", r)
- }
+ }
return res
}
diff --git a/src/server/collector.odin b/src/server/collector.odin
index 464b22f..5cea81f 100644
--- a/src/server/collector.odin
+++ b/src/server/collector.odin
@@ -24,33 +24,49 @@ get_index_unique_string :: proc {
get_index_unique_string_collection_raw,
}
-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 :: 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 {
+get_index_unique_string_collection_raw :: proc(
+ unique_strings: ^map[string]string,
+ allocator: mem.Allocator,
+ s: string,
+) -> string {
if _, ok := unique_strings[s]; !ok {
str := strings.clone(s, allocator)
- unique_strings[str] = str
+ unique_strings[str] = str
}
return unique_strings[s]
}
-make_symbol_collection :: proc(allocator := context.allocator, config: ^common.Config) -> SymbolCollection {
- return SymbolCollection {
- allocator = allocator,
- config = config,
- packages = make(map[string]map[string]Symbol, 16, allocator),
- unique_strings = make(map[string]string, 16, allocator),
- }
+make_symbol_collection :: proc(
+ allocator := context.allocator,
+ config: ^common.Config,
+) -> SymbolCollection {
+ return(
+ SymbolCollection{
+ allocator = allocator,
+ config = config,
+ packages = make(map[string]map[string]Symbol, 16, allocator),
+ unique_strings = make(map[string]string, 16, allocator),
+ } \
+ )
}
delete_symbol_collection :: proc(collection: SymbolCollection) {
for k, v in collection.packages {
for k2, v2 in v {
free_symbol(v2, collection.allocator)
- }
+ }
}
for k, v in collection.unique_strings {
@@ -65,13 +81,23 @@ delete_symbol_collection :: proc(collection: SymbolCollection) {
delete(collection.unique_strings)
}
-collect_procedure_fields :: proc(collection: ^SymbolCollection, proc_type: ^ast.Proc_Type, arg_list: ^ast.Field_List, return_list: ^ast.Field_List, package_map: map[string]string) -> SymbolProcedureValue {
+collect_procedure_fields :: proc(
+ collection: ^SymbolCollection,
+ proc_type: ^ast.Proc_Type,
+ arg_list: ^ast.Field_List,
+ return_list: ^ast.Field_List,
+ package_map: map[string]string,
+) -> SymbolProcedureValue {
returns := make([dynamic]^ast.Field, 0, collection.allocator)
args := make([dynamic]^ast.Field, 0, collection.allocator)
if return_list != nil {
for ret in return_list.list {
- cloned := cast(^ast.Field)clone_type(ret, collection.allocator, &collection.unique_strings)
+ cloned := cast(^ast.Field)clone_type(
+ ret,
+ collection.allocator,
+ &collection.unique_strings,
+ )
replace_package_alias(cloned, package_map, collection)
append(&returns, cloned)
}
@@ -79,7 +105,11 @@ collect_procedure_fields :: proc(collection: ^SymbolCollection, proc_type: ^ast.
if arg_list != nil {
for arg in arg_list.list {
- cloned := cast(^ast.Field)clone_type(arg, collection.allocator, &collection.unique_strings)
+ cloned := cast(^ast.Field)clone_type(
+ arg,
+ collection.allocator,
+ &collection.unique_strings,
+ )
replace_package_alias(cloned, package_map, collection)
append(&args, cloned)
}
@@ -87,13 +117,18 @@ collect_procedure_fields :: proc(collection: ^SymbolCollection, proc_type: ^ast.
value := SymbolProcedureValue {
return_types = returns[:],
- arg_types = args[:],
- generic = proc_type.generic,
+ arg_types = args[:],
+ generic = proc_type.generic,
}
return value
}
-collect_struct_fields :: proc(collection: ^SymbolCollection, struct_type: ast.Struct_Type, package_map: map[string]string, file: ast.File) -> SymbolStructValue {
+collect_struct_fields :: proc(
+ collection: ^SymbolCollection,
+ struct_type: ast.Struct_Type,
+ package_map: map[string]string,
+ file: ast.File,
+) -> SymbolStructValue {
names := make([dynamic]string, 0, collection.allocator)
types := make([dynamic]^ast.Expr, 0, collection.allocator)
usings := make(map[string]bool, 0, collection.allocator)
@@ -104,7 +139,11 @@ collect_struct_fields :: proc(collection: ^SymbolCollection, struct_type: ast.St
ident := n.derived.(^ast.Ident)
append(&names, get_index_unique_string(collection, ident.name))
- cloned := clone_type(field.type, collection.allocator, &collection.unique_strings)
+ cloned := clone_type(
+ field.type,
+ collection.allocator,
+ &collection.unique_strings,
+ )
replace_package_alias(cloned, package_map, collection)
append(&types, cloned)
@@ -117,17 +156,25 @@ collect_struct_fields :: proc(collection: ^SymbolCollection, struct_type: ast.St
}
value := SymbolStructValue {
- names = names[:],
- types = types[:],
+ names = names[:],
+ types = types[:],
ranges = ranges[:],
usings = usings,
- poly = cast(^ast.Field_List)clone_type(struct_type.poly_params, collection.allocator, &collection.unique_strings),
+ poly = cast(^ast.Field_List)clone_type(
+ struct_type.poly_params,
+ collection.allocator,
+ &collection.unique_strings,
+ ),
}
return value
}
-collect_enum_fields :: proc(collection: ^SymbolCollection, fields: []^ast.Expr, package_map: map[string]string) -> SymbolEnumValue {
+collect_enum_fields :: proc(
+ collection: ^SymbolCollection,
+ fields: []^ast.Expr,
+ package_map: map[string]string,
+) -> SymbolEnumValue {
names := make([dynamic]string, 0, collection.allocator)
//ERROR no hover on n in the for, but elsewhere is fine
@@ -137,9 +184,16 @@ collect_enum_fields :: proc(collection: ^SymbolCollection, fields: []^ast.Expr,
} else if field, ok := n.derived.(^ast.Field_Value); ok {
if ident, ok := field.field.derived.(^ast.Ident); ok {
append(&names, get_index_unique_string(collection, ident.name))
- } else if binary, ok := field.field.derived.(^ast.Binary_Expr); ok {
- append(&names, get_index_unique_string(collection, binary.left.derived.(^ast.Ident).name))
- }
+ } else if binary, ok := field.field.derived.(^ast.Binary_Expr);
+ ok {
+ append(
+ &names,
+ get_index_unique_string(
+ collection,
+ binary.left.derived.(^ast.Ident).name,
+ ),
+ )
+ }
}
}
@@ -150,95 +204,155 @@ collect_enum_fields :: proc(collection: ^SymbolCollection, fields: []^ast.Expr,
return value
}
-collect_union_fields :: proc(collection: ^SymbolCollection, union_type: ast.Union_Type, package_map: map[string]string) -> SymbolUnionValue {
+collect_union_fields :: proc(
+ collection: ^SymbolCollection,
+ union_type: ast.Union_Type,
+ package_map: map[string]string,
+) -> SymbolUnionValue {
types := make([dynamic]^ast.Expr, 0, collection.allocator)
for variant in union_type.variants {
- cloned := clone_type(variant, collection.allocator, &collection.unique_strings)
+ cloned := clone_type(
+ variant,
+ collection.allocator,
+ &collection.unique_strings,
+ )
replace_package_alias(cloned, package_map, collection)
append(&types, cloned)
}
value := SymbolUnionValue {
types = types[:],
- poly = cast(^ast.Field_List)clone_type(union_type.poly_params, collection.allocator, &collection.unique_strings),
+ poly = cast(^ast.Field_List)clone_type(
+ union_type.poly_params,
+ collection.allocator,
+ &collection.unique_strings,
+ ),
}
return value
}
-collect_bitset_field :: proc(collection: ^SymbolCollection, bitset_type: ast.Bit_Set_Type, package_map: map[string]string) -> SymbolBitSetValue {
- cloned := clone_type(bitset_type.elem, collection.allocator, &collection.unique_strings)
+collect_bitset_field :: proc(
+ collection: ^SymbolCollection,
+ bitset_type: ast.Bit_Set_Type,
+ package_map: map[string]string,
+) -> SymbolBitSetValue {
+ cloned := clone_type(
+ bitset_type.elem,
+ collection.allocator,
+ &collection.unique_strings,
+ )
replace_package_alias(cloned, package_map, collection)
- return SymbolBitSetValue {
- expr = cloned,
- }
+ return SymbolBitSetValue{expr = cloned}
}
-collect_slice :: proc(collection: ^SymbolCollection, array: ast.Array_Type, package_map: map[string]string) -> SymbolFixedArrayValue {
- elem := clone_type(array.elem, collection.allocator, &collection.unique_strings)
- len := clone_type(array.len, collection.allocator, &collection.unique_strings)
+collect_slice :: proc(
+ collection: ^SymbolCollection,
+ array: ast.Array_Type,
+ package_map: map[string]string,
+) -> SymbolFixedArrayValue {
+ elem := clone_type(
+ array.elem,
+ collection.allocator,
+ &collection.unique_strings,
+ )
+ len := clone_type(
+ array.len,
+ collection.allocator,
+ &collection.unique_strings,
+ )
replace_package_alias(elem, package_map, collection)
replace_package_alias(len, package_map, collection)
- return SymbolFixedArrayValue {
- expr = elem,
- len = len,
- }
+ return SymbolFixedArrayValue{expr = elem, len = len}
}
-collect_array :: proc(collection: ^SymbolCollection, array: ast.Array_Type, package_map: map[string]string) -> SymbolSliceValue {
- elem := clone_type(array.elem, collection.allocator, &collection.unique_strings)
+collect_array :: proc(
+ collection: ^SymbolCollection,
+ array: ast.Array_Type,
+ package_map: map[string]string,
+) -> SymbolSliceValue {
+ elem := clone_type(
+ array.elem,
+ collection.allocator,
+ &collection.unique_strings,
+ )
replace_package_alias(elem, package_map, collection)
- return SymbolSliceValue {
- expr = elem,
- }
+ return SymbolSliceValue{expr = elem}
}
-collect_map :: proc(collection: ^SymbolCollection, m: ast.Map_Type, package_map: map[string]string) -> SymbolMapValue {
- key := clone_type(m.key, collection.allocator, &collection.unique_strings)
- value := clone_type(m.value, collection.allocator, &collection.unique_strings)
+collect_map :: proc(
+ collection: ^SymbolCollection,
+ m: ast.Map_Type,
+ package_map: map[string]string,
+) -> SymbolMapValue {
+ key := clone_type(m.key, collection.allocator, &collection.unique_strings)
+ value := clone_type(
+ m.value,
+ collection.allocator,
+ &collection.unique_strings,
+ )
replace_package_alias(key, package_map, collection)
replace_package_alias(value, package_map, collection)
- return SymbolMapValue {
- key = key,
- value = value,
- }
+ return SymbolMapValue{key = key, value = value}
}
-collect_dynamic_array :: proc(collection: ^SymbolCollection, array: ast.Dynamic_Array_Type, package_map: map[string]string) -> SymbolDynamicArrayValue {
- elem := clone_type(array.elem, collection.allocator, &collection.unique_strings)
+collect_dynamic_array :: proc(
+ collection: ^SymbolCollection,
+ array: ast.Dynamic_Array_Type,
+ package_map: map[string]string,
+) -> SymbolDynamicArrayValue {
+ elem := clone_type(
+ array.elem,
+ collection.allocator,
+ &collection.unique_strings,
+ )
replace_package_alias(elem, package_map, collection)
- return SymbolDynamicArrayValue {
- expr = elem,
- }
+ return SymbolDynamicArrayValue{expr = elem}
}
-collect_multi_pointer :: proc(collection: ^SymbolCollection, array: ast.Multi_Pointer_Type, package_map: map[string]string) -> SymbolMultiPointer {
- elem := clone_type(array.elem, collection.allocator, &collection.unique_strings)
+collect_multi_pointer :: proc(
+ collection: ^SymbolCollection,
+ array: ast.Multi_Pointer_Type,
+ package_map: map[string]string,
+) -> SymbolMultiPointer {
+ elem := clone_type(
+ array.elem,
+ collection.allocator,
+ &collection.unique_strings,
+ )
replace_package_alias(elem, package_map, collection)
- return SymbolMultiPointer {
- expr = elem,
- }
+ return SymbolMultiPointer{expr = elem}
}
-collect_generic :: proc(collection: ^SymbolCollection, expr: ^ast.Expr, package_map: map[string]string, uri: string) -> SymbolGenericValue {
+collect_generic :: proc(
+ collection: ^SymbolCollection,
+ expr: ^ast.Expr,
+ package_map: map[string]string,
+ uri: string,
+) -> SymbolGenericValue {
//Bit hacky right now, but it's hopefully a temporary solution.
//In the c package code it uses a documentation package(builtin).
if selector, ok := expr.derived.(^ast.Selector_Expr); ok {
if ident, ok := selector.expr.derived.(^ast.Ident); ok {
- if ident.name == "builtin" && strings.contains(uri, "Odin/core/c/c.odin") {
- cloned := clone_type(selector.field, collection.allocator, &collection.unique_strings)
+ if ident.name == "builtin" &&
+ strings.contains(uri, "Odin/core/c/c.odin") {
+ cloned := clone_type(
+ selector.field,
+ collection.allocator,
+ &collection.unique_strings,
+ )
replace_package_alias(cloned, package_map, collection)
value := SymbolGenericValue {
expr = cloned,
@@ -248,7 +362,11 @@ collect_generic :: proc(collection: ^SymbolCollection, expr: ^ast.Expr, package_
}
}
- cloned := clone_type(expr, collection.allocator, &collection.unique_strings)
+ cloned := clone_type(
+ expr,
+ collection.allocator,
+ &collection.unique_strings,
+ )
replace_package_alias(cloned, package_map, collection)
value := SymbolGenericValue {
@@ -258,7 +376,11 @@ collect_generic :: proc(collection: ^SymbolCollection, expr: ^ast.Expr, package_
return value
}
-collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: string) -> common.Error {
+collect_symbols :: proc(
+ collection: ^SymbolCollection,
+ file: ast.File,
+ uri: string,
+) -> common.Error {
forward, _ := filepath.to_slash(file.fullpath, context.temp_allocator)
directory := path.dir(forward, context.temp_allocator)
package_map := get_package_mapping(file, collection.config, directory)
@@ -293,27 +415,52 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
token_type = .Function
if v.type != nil {
- symbol.value = collect_procedure_fields(collection, v.type, v.type.params, v.type.results, package_map)
+ symbol.value = collect_procedure_fields(
+ collection,
+ v.type,
+ v.type.params,
+ v.type.results,
+ package_map,
+ )
}
case ^ast.Proc_Type:
token = v^
token_type = .Function
- symbol.value = collect_procedure_fields(collection, cast(^ast.Proc_Type)col_expr, v.params, v.results, package_map)
+ symbol.value = collect_procedure_fields(
+ collection,
+ cast(^ast.Proc_Type)col_expr,
+ v.params,
+ v.results,
+ package_map,
+ )
case ^ast.Proc_Group:
token = v^
token_type = .Function
symbol.value = SymbolProcedureGroupValue {
- group = clone_type(col_expr, collection.allocator, &collection.unique_strings),
+ group = clone_type(
+ col_expr,
+ collection.allocator,
+ &collection.unique_strings,
+ ),
}
case ^ast.Struct_Type:
token = v^
token_type = .Struct
- symbol.value = collect_struct_fields(collection, v^, package_map, file)
+ symbol.value = collect_struct_fields(
+ collection,
+ v^,
+ package_map,
+ file,
+ )
symbol.signature = "struct"
case ^ast.Enum_Type:
token = v^
token_type = .Enum
- symbol.value = collect_enum_fields(collection, v.fields, package_map)
+ symbol.value = collect_enum_fields(
+ collection,
+ v.fields,
+ package_map,
+ )
symbol.signature = "enum"
case ^ast.Union_Type:
token = v^
@@ -347,7 +494,12 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
symbol.value = collect_multi_pointer(collection, v^, package_map)
case ^ast.Basic_Lit:
token = v^
- symbol.value = collect_generic(collection, col_expr, package_map, uri)
+ symbol.value = collect_generic(
+ collection,
+ col_expr,
+ package_map,
+ uri,
+ )
if expr.mutable {
token_type = .Variable
} else {
@@ -355,14 +507,25 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
}
case ^ast.Ident:
token = v^
- symbol.value = collect_generic(collection, col_expr, package_map, uri)
+ symbol.value = collect_generic(
+ collection,
+ col_expr,
+ package_map,
+ uri,
+ )
if expr.mutable {
token_type = .Variable
} else {
token_type = .Unresolved
}
- case: // default
- symbol.value = collect_generic(collection, col_expr, package_map, uri)
+ case:
+ // default
+ symbol.value = collect_generic(
+ collection,
+ col_expr,
+ package_map,
+ uri,
+ )
if expr.mutable {
token_type = .Variable
} else {
@@ -375,7 +538,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
symbol.name = get_index_unique_string(collection, name)
symbol.type = token_type
symbol.doc = common.get_doc(expr.docs, collection.allocator)
-
+
if expr.builtin || strings.contains(uri, "builtin.odin") {
symbol.pkg = "$builtin"
} else if strings.contains(uri, "intrinsics.odin") {
@@ -397,34 +560,42 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
}
symbol.uri = get_index_unique_string(collection, uri)
-
+
pkg: ^map[string]Symbol
ok: bool
if pkg, ok = &collection.packages[symbol.pkg]; !ok {
- collection.packages[symbol.pkg] = make(map[string]Symbol, 100, collection.allocator)
+ collection.packages[symbol.pkg] = make(
+ map[string]Symbol,
+ 100,
+ collection.allocator,
+ )
pkg = &collection.packages[symbol.pkg]
- }
+ }
if v, ok := pkg[symbol.name]; !ok || v.name == "" {
pkg[symbol.name] = symbol
} else {
free_symbol(symbol, collection.allocator)
- }
+ }
}
return .None
}
Reference :: struct {
- identifiers: [dynamic]common.Location,
- selectors: map[string][dynamic]common.Range,
+ identifiers: [dynamic]common.Location,
+ selectors: map[string][dynamic]common.Range,
}
/*
Gets the map from import alias to absolute package directory
*/
-get_package_mapping :: proc(file: ast.File, config: ^common.Config, directory: string) -> map[string]string {
+get_package_mapping :: proc(
+ file: ast.File,
+ config: ^common.Config,
+ directory: string,
+) -> map[string]string {
package_map := make(map[string]string, 0, context.temp_allocator)
for imp, index in file.imports {
@@ -441,7 +612,10 @@ get_package_mapping :: proc(file: ast.File, config: ^common.Config, directory: s
name: string
- full := path.join(elems = {dir, p}, allocator = context.temp_allocator)
+ full := path.join(
+ elems = {dir, p},
+ allocator = context.temp_allocator,
+ )
if imp.name.text != "" {
name = imp.name.text
@@ -453,7 +627,10 @@ get_package_mapping :: proc(file: ast.File, config: ^common.Config, directory: s
} else {
name: string
- full := path.join(elems = {directory, imp.fullpath[1:len(imp.fullpath) - 1]}, allocator = context.temp_allocator)
+ full := path.join(
+ elems = {directory, imp.fullpath[1:len(imp.fullpath) - 1]},
+ allocator = context.temp_allocator,
+ )
full = path.clean(full, context.temp_allocator)
if imp.name.text != "" {
@@ -481,23 +658,39 @@ replace_package_alias :: proc {
replace_package_alias_dynamic_array,
}
-replace_package_alias_array :: proc(array: $A/[]^$T, package_map: map[string]string, collection: ^SymbolCollection) {
+replace_package_alias_array :: proc(
+ array: $A/[]^$T,
+ package_map: map[string]string,
+ collection: ^SymbolCollection,
+) {
for elem, i in array {
replace_package_alias(elem, package_map, collection)
}
}
-replace_package_alias_dynamic_array :: proc(array: $A/[dynamic]^$T, package_map: map[string]string, collection: ^SymbolCollection) {
+replace_package_alias_dynamic_array :: proc(
+ array: $A/[dynamic]^$T,
+ package_map: map[string]string,
+ collection: ^SymbolCollection,
+) {
for elem, i in array {
replace_package_alias(elem, package_map, collection)
}
}
-replace_package_alias_expr :: proc(node: ^ast.Expr, package_map: map[string]string, collection: ^SymbolCollection) {
+replace_package_alias_expr :: proc(
+ node: ^ast.Expr,
+ package_map: map[string]string,
+ collection: ^SymbolCollection,
+) {
replace_package_alias_node(node, package_map, collection)
}
-replace_package_alias_node :: proc(node: ^ast.Node, package_map: map[string]string, collection: ^SymbolCollection) {
+replace_package_alias_node :: proc(
+ node: ^ast.Node,
+ package_map: map[string]string,
+ collection: ^SymbolCollection,
+) {
using ast
if node == nil {
diff --git a/src/server/completion.odin b/src/server/completion.odin
index a3b80c1..2f695af 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -32,20 +32,38 @@ Completion_Type :: enum {
Package,
}
-get_completion_list :: proc(document: ^Document, position: common.Position, completion_context: CompletionContext) -> (CompletionList, bool) {
+get_completion_list :: proc(
+ document: ^Document,
+ position: common.Position,
+ completion_context: CompletionContext,
+) -> (
+ CompletionList,
+ bool,
+) {
list: CompletionList
- position_context, ok := get_document_position_context(document, position, .Completion)
+ position_context, ok := get_document_position_context(
+ document,
+ position,
+ .Completion,
+ )
if !ok || position_context.abort_completion {
return list, true
}
- if position_context.import_stmt == nil && strings.contains_any(completion_context.triggerCharacter, "/:\"") {
+ if position_context.import_stmt == nil &&
+ strings.contains_any(completion_context.triggerCharacter, "/:\"") {
return list, true
}
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath)
+ ast_context := make_ast_context(
+ document.ast,
+ document.imports,
+ document.package_name,
+ document.uri.uri,
+ document.fullpath,
+ )
get_globals(document.ast, &ast_context)
@@ -53,7 +71,12 @@ get_completion_list :: proc(document: ^Document, position: common.Position, comp
ast_context.value_decl = position_context.value_decl
if position_context.function != nil {
- get_locals(document.ast, position_context.function, &ast_context, &position_context)
+ get_locals(
+ document.ast,
+ position_context.function,
+ &ast_context,
+ &position_context,
+ )
}
completion_type: Completion_Type = .Identifier
@@ -78,12 +101,17 @@ get_completion_list :: proc(document: ^Document, position: common.Position, comp
completion_type = .Package
}
- if position_context.switch_type_stmt != nil && position_context.case_clause != nil {
- if assign, ok := position_context.switch_type_stmt.tag.derived.(^ast.Assign_Stmt); ok && assign.rhs != nil && len(assign.rhs) == 1 {
+ if position_context.switch_type_stmt != nil &&
+ position_context.case_clause != nil {
+ if assign, ok := position_context.switch_type_stmt.tag.derived.(^ast.Assign_Stmt);
+ ok && assign.rhs != nil && len(assign.rhs) == 1 {
ast_context.use_globals = true
ast_context.use_locals = true
- if symbol, ok := resolve_type_expression(&ast_context, assign.rhs[0]); ok {
+ if symbol, ok := resolve_type_expression(
+ &ast_context,
+ assign.rhs[0],
+ ); ok {
if union_value, ok := symbol.value.(SymbolUnionValue); ok {
completion_type = .Switch_Type
}
@@ -111,21 +139,29 @@ get_completion_list :: proc(document: ^Document, position: common.Position, comp
return list, true
}
-get_attribute_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) {
-
+get_attribute_completion :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+ list: ^CompletionList,
+) {
+
}
-get_directive_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) {
+get_directive_completion :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+ list: ^CompletionList,
+) {
list.isIncomplete = false
-
+
items := make([dynamic]CompletionItem, context.temp_allocator)
/*
Right now just return all the possible completions, but later on I should give the context specific ones
*/
- directive_list := []string {
+ directive_list := []string{
"file",
"line",
"packed",
@@ -150,8 +186,8 @@ get_directive_completion :: proc(ast_context: ^AstContext, position_context: ^Do
for elem in directive_list {
item := CompletionItem {
detail = elem,
- label = elem,
- kind = .Constant,
+ label = elem,
+ kind = .Constant,
}
append(&items, item)
@@ -160,30 +196,53 @@ get_directive_completion :: proc(ast_context: ^AstContext, position_context: ^Do
list.items = items[:]
}
-get_comp_lit_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) {
+get_comp_lit_completion :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+ list: ^CompletionList,
+) {
items := make([dynamic]CompletionItem, context.temp_allocator)
if position_context.parent_comp_lit.type == nil {
return
}
- if symbol, ok := resolve_type_expression(ast_context, position_context.parent_comp_lit.type); ok {
- if comp_symbol, _, ok := resolve_type_comp_literal(ast_context, position_context, symbol, position_context.parent_comp_lit); ok {
- ast_context.current_package = comp_symbol.pkg;
+ if symbol, ok := resolve_type_expression(
+ ast_context,
+ position_context.parent_comp_lit.type,
+ ); ok {
+ if comp_symbol, _, ok := resolve_type_comp_literal(
+ ast_context,
+ position_context,
+ symbol,
+ position_context.parent_comp_lit,
+ ); ok {
+ ast_context.current_package = comp_symbol.pkg
#partial switch v in comp_symbol.value {
case SymbolStructValue:
for name, i in v.names {
ast_context.current_package = comp_symbol.pkg
- if resolved, ok := resolve_type_expression(ast_context, v.types[i]); ok {
- if field_exists_in_comp_lit(position_context.comp_lit, name) {
+ if resolved, ok := resolve_type_expression(
+ ast_context,
+ v.types[i],
+ ); ok {
+ if field_exists_in_comp_lit(
+ position_context.comp_lit,
+ name,
+ ) {
continue
}
item := CompletionItem {
- label = name,
- kind = .Field,
- detail = fmt.tprintf("%v.%v: %v", comp_symbol.name, name, common.node_to_string(v.types[i])),
+ label = name,
+ kind = .Field,
+ detail = fmt.tprintf(
+ "%v.%v: %v",
+ comp_symbol.name,
+ name,
+ common.node_to_string(v.types[i]),
+ ),
documentation = resolved.doc,
}
@@ -197,7 +256,11 @@ get_comp_lit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
list.items = items[:]
}
-get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) {
+get_selector_completion :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+ list: ^CompletionList,
+) {
items := make([dynamic]CompletionItem, context.temp_allocator)
ast_context.current_package = ast_context.document_package
@@ -208,13 +271,18 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
ast_context.use_locals = true
ast_context.use_globals = true
- selector, ok = resolve_type_expression(ast_context, position_context.selector)
+ selector, ok = resolve_type_expression(
+ ast_context,
+ position_context.selector,
+ )
if !ok {
return
}
- if selector.type != .Variable && selector.type != .Package && selector.type != .Enum {
+ if selector.type != .Variable &&
+ selector.type != .Package &&
+ selector.type != .Enum {
return
}
@@ -235,7 +303,10 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
if s, ok := selector.value.(SymbolProcedureValue); ok {
if len(s.return_types) == 1 {
- if selector, ok = resolve_type_expression(ast_context, s.return_types[0].type); !ok {
+ if selector, ok = resolve_type_expression(
+ ast_context,
+ s.return_types[0].type,
+ ); !ok {
return
}
}
@@ -265,7 +336,7 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
containsCoord += 1
}
}
- }
+ }
if containsColor == 1 && containsCoord == 1 {
save := expr_len
@@ -277,13 +348,18 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
expr_len -= 1
item := CompletionItem {
- label = fmt.tprintf("%v%c", field, k),
- kind = .Property,
- detail = fmt.tprintf("%v%c: %v", field, k, common.node_to_string(v.expr)),
+ label = fmt.tprintf("%v%c", field, k),
+ kind = .Property,
+ detail = fmt.tprintf(
+ "%v%c: %v",
+ field,
+ k,
+ common.node_to_string(v.expr),
+ ),
}
append(&items, item)
}
-
+
expr_len = save
for k in swizzle_coord_components {
@@ -294,13 +370,18 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
expr_len -= 1
item := CompletionItem {
- label = fmt.tprintf("%v%c", field, k),
- kind = .Property,
- detail = fmt.tprintf("%v%c: %v", field, k, common.node_to_string(v.expr)),
+ label = fmt.tprintf("%v%c", field, k),
+ kind = .Property,
+ detail = fmt.tprintf(
+ "%v%c: %v",
+ field,
+ k,
+ common.node_to_string(v.expr),
+ ),
}
append(&items, item)
}
- }
+ }
if containsColor > 1 {
for k in swizzle_color_components {
@@ -311,9 +392,15 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
expr_len -= 1
item := CompletionItem {
- label = fmt.tprintf("%v%c", field, k),
- kind = .Property,
- detail = fmt.tprintf("%v%c: [%v]%v", field, k, containsColor, common.node_to_string(v.expr)),
+ label = fmt.tprintf("%v%c", field, k),
+ kind = .Property,
+ detail = fmt.tprintf(
+ "%v%c: [%v]%v",
+ field,
+ k,
+ containsColor,
+ common.node_to_string(v.expr),
+ ),
}
append(&items, item)
}
@@ -326,13 +413,19 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
expr_len -= 1
item := CompletionItem {
- label = fmt.tprintf("%v%c", field, k),
- kind = .Property,
- detail = fmt.tprintf("%v%c: [%v]%v", field, k, containsCoord, common.node_to_string(v.expr)),
+ label = fmt.tprintf("%v%c", field, k),
+ kind = .Property,
+ detail = fmt.tprintf(
+ "%v%c: [%v]%v",
+ field,
+ k,
+ containsCoord,
+ common.node_to_string(v.expr),
+ ),
}
append(&items, item)
}
- }
+ }
case SymbolUnionValue:
list.isIncomplete = false
@@ -343,16 +436,35 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
base := path.base(symbol.pkg, false, context.temp_allocator)
item := CompletionItem {
- kind = .EnumMember,
- detail = fmt.tprintf("%v", selector.name),
+ kind = .EnumMember,
+ detail = fmt.tprintf("%v", selector.name),
documentation = symbol.doc,
}
- if symbol.pkg == ast_context.document_package || base == "runtime" || base == "$builtin" {
- item.label = fmt.aprintf("(%v%v)", common.repeat("^", symbol.pointers, context.temp_allocator), common.node_to_string(type, true))
+ if symbol.pkg == ast_context.document_package ||
+ base == "runtime" ||
+ base == "$builtin" {
+ item.label = fmt.aprintf(
+ "(%v%v)",
+ common.repeat(
+ "^",
+ symbol.pointers,
+ context.temp_allocator,
+ ),
+ common.node_to_string(type, true),
+ )
} else {
- item.label = fmt.aprintf("(%v%v.%v)", common.repeat("^", symbol.pointers, context.temp_allocator), path.base(symbol.pkg, false, context.temp_allocator), common.node_to_string(type, true))
- }
+ item.label = fmt.aprintf(
+ "(%v%v.%v)",
+ common.repeat(
+ "^",
+ symbol.pointers,
+ context.temp_allocator,
+ ),
+ path.base(symbol.pkg, false, context.temp_allocator),
+ common.node_to_string(type, true),
+ )
+ }
append(&items, item)
}
@@ -363,8 +475,8 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
for name in v.names {
item := CompletionItem {
- label = name,
- kind = .EnumMember,
+ label = name,
+ kind = .EnumMember,
detail = fmt.tprintf("%v.%v", selector.name, name),
}
append(&items, item)
@@ -380,8 +492,10 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
ast_context.current_package = ast_context.document_package
}
- if symbol, ok := resolve_type_expression(ast_context, v.types[i]); ok {
- if expr, ok := position_context.selector.derived.(^ast.Selector_Expr); ok {
+ if symbol, ok := resolve_type_expression(ast_context, v.types[i]);
+ ok {
+ if expr, ok := position_context.selector.derived.(^ast.Selector_Expr);
+ ok {
if expr.op.text == "->" && symbol.type != .Function {
continue
}
@@ -392,9 +506,14 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
}
item := CompletionItem {
- label = name,
- kind = .Field,
- detail = fmt.tprintf("%v.%v: %v", selector.name, name, type_to_string(ast_context, v.types[i])),
+ label = name,
+ kind = .Field,
+ detail = fmt.tprintf(
+ "%v.%v: %v",
+ selector.name,
+ name,
+ type_to_string(ast_context, v.types[i]),
+ ),
documentation = symbol.doc,
}
@@ -402,9 +521,13 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
} else {
//just give some generic symbol with name.
item := CompletionItem {
- label = symbol.name,
- kind = .Field,
- detail = fmt.tprintf("%v: %v", name, common.node_to_string(v.types[i])),
+ label = symbol.name,
+ kind = .Field,
+ detail = fmt.tprintf(
+ "%v: %v",
+ name,
+ common.node_to_string(v.types[i]),
+ ),
documentation = symbol.doc,
}
@@ -423,45 +546,62 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
resolve_unresolved_symbol(ast_context, &symbol)
build_procedure_symbol_signature(&symbol)
-
+
item := CompletionItem {
- label = symbol.name,
- kind = cast(CompletionItemKind)symbol.type,
- detail = concatenate_symbol_information(ast_context, symbol, true),
+ label = symbol.name,
+ kind = cast(CompletionItemKind)symbol.type,
+ detail = concatenate_symbol_information(
+ ast_context,
+ symbol,
+ true,
+ ),
documentation = symbol.doc,
}
if symbol.type == .Function && common.config.enable_snippets {
item.insertText = fmt.tprintf("%v($0)", item.label)
item.insertTextFormat = .Snippet
- item.command.command = "editor.action.triggerParameterHints"
- item.deprecated = .Deprecated in symbol.flags
+ item.command.command =
+ "editor.action.triggerParameterHints"
+ item.deprecated = .Deprecated in symbol.flags
}
append(&items, item)
}
} else {
- log.errorf("Failed to fuzzy search, field: %v, package: %v", field, selector.pkg)
+ log.errorf(
+ "Failed to fuzzy search, field: %v, package: %v",
+ field,
+ selector.pkg,
+ )
return
}
case SymbolDynamicArrayValue:
list.isIncomplete = false
- append_magic_dynamic_array_completion(position_context, selector, &items)
+ append_magic_dynamic_array_completion(
+ position_context,
+ selector,
+ &items,
+ )
case SymbolMapValue:
- list.isIncomplete = false
+ list.isIncomplete = false
append_magic_map_completion(position_context, selector, &items)
}
list.items = items[:]
}
-get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) {
+get_implicit_completion :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+ list: ^CompletionList,
+) {
items := make([dynamic]CompletionItem, context.temp_allocator)
list.isIncomplete = false
selector: Symbol
-
+
ast_context.use_locals = true
ast_context.use_globals = true
@@ -472,12 +612,16 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
}
//value decl infer a : My_Enum = .*
- if position_context.value_decl != nil && position_context.value_decl.type != nil {
- if enum_value, ok := unwrap_enum(ast_context, position_context.value_decl.type); ok {
+ if position_context.value_decl != nil &&
+ position_context.value_decl.type != nil {
+ if enum_value, ok := unwrap_enum(
+ ast_context,
+ position_context.value_decl.type,
+ ); ok {
for name in enum_value.names {
item := CompletionItem {
- label = name,
- kind = .EnumMember,
+ label = name,
+ kind = .EnumMember,
detail = name,
}
append(&items, item)
@@ -489,14 +633,18 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
}
//enum switch infer
- if position_context.switch_stmt != nil && position_context.case_clause != nil && position_context.switch_stmt.cond != nil {
+ if position_context.switch_stmt != nil &&
+ position_context.case_clause != nil &&
+ position_context.switch_stmt.cond != nil {
used_enums := make(map[string]bool, 5, context.temp_allocator)
- if block, ok := position_context.switch_stmt.body.derived.(^ast.Block_Stmt); ok {
+ if block, ok := position_context.switch_stmt.body.derived.(^ast.Block_Stmt);
+ ok {
for stmt in block.stmts {
if case_clause, ok := stmt.derived.(^ast.Case_Clause); ok {
for name in case_clause.list {
- if implicit, ok := name.derived.(^ast.Implicit_Selector_Expr); ok {
+ if implicit, ok := name.derived.(^ast.Implicit_Selector_Expr);
+ ok {
used_enums[implicit.field.name] = true
}
}
@@ -504,15 +652,18 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
}
}
- if enum_value, ok := unwrap_enum(ast_context, position_context.switch_stmt.cond); ok {
+ if enum_value, ok := unwrap_enum(
+ ast_context,
+ position_context.switch_stmt.cond,
+ ); ok {
for name in enum_value.names {
if name in used_enums {
continue
}
item := CompletionItem {
- label = name,
- kind = .EnumMember,
+ label = name,
+ kind = .EnumMember,
detail = name,
}
@@ -524,15 +675,21 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
}
}
- if position_context.assign != nil && position_context.assign.lhs != nil && len(position_context.assign.lhs) == 1 && is_bitset_assignment_operator(position_context.assign.op.text) {
+ if position_context.assign != nil &&
+ position_context.assign.lhs != nil &&
+ len(position_context.assign.lhs) == 1 &&
+ is_bitset_assignment_operator(position_context.assign.op.text) {
//bitsets
- if symbol, ok := resolve_type_expression(ast_context, position_context.assign.lhs[0]); ok {
+ if symbol, ok := resolve_type_expression(
+ ast_context,
+ position_context.assign.lhs[0],
+ ); ok {
if value, ok := unwrap_bitset(ast_context, symbol); ok {
for name in value.names {
item := CompletionItem {
- label = name,
- kind = .EnumMember,
+ label = name,
+ kind = .EnumMember,
detail = name,
}
@@ -545,14 +702,19 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
}
}
- if position_context.comp_lit != nil && position_context.parent_binary != nil && is_bitset_binary_operator(position_context.binary.op.text) {
+ if position_context.comp_lit != nil &&
+ position_context.parent_binary != nil &&
+ is_bitset_binary_operator(position_context.binary.op.text) {
//bitsets
- if symbol, ok := resolve_first_symbol_from_binary_expression(ast_context, position_context.parent_binary); ok {
+ if symbol, ok := resolve_first_symbol_from_binary_expression(
+ ast_context,
+ position_context.parent_binary,
+ ); ok {
if value, ok := unwrap_bitset(ast_context, symbol); ok {
for name in value.names {
item := CompletionItem {
- label = name,
- kind = .EnumMember,
+ label = name,
+ kind = .EnumMember,
detail = name,
}
@@ -574,17 +736,26 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
field_name: string
if position_context.field_value != nil {
- if field, ok := position_context.field_value.field.derived.(^ast.Ident); ok {
+ if field, ok := position_context.field_value.field.derived.(^ast.Ident);
+ ok {
field_name = field.name
} else {
return
- }
+ }
}
- if symbol, ok := resolve_type_expression(ast_context, position_context.parent_comp_lit.type); ok {
- if comp_symbol, comp_lit, ok := resolve_type_comp_literal(ast_context, position_context, symbol, position_context.parent_comp_lit); ok {
+ if symbol, ok := resolve_type_expression(
+ ast_context,
+ position_context.parent_comp_lit.type,
+ ); ok {
+ if comp_symbol, comp_lit, ok := resolve_type_comp_literal(
+ ast_context,
+ position_context,
+ symbol,
+ position_context.parent_comp_lit,
+ ); ok {
if s, ok := comp_symbol.value.(SymbolStructValue); ok {
- ast_context.current_package = comp_symbol.pkg;
+ ast_context.current_package = comp_symbol.pkg
//We can either have the final
elem_index := -1
@@ -600,21 +771,21 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
for name, i in s.names {
if name != field_name {
continue
- }
+ }
type = s.types[i]
break
}
- if type == nil && len(s.types) > elem_index {
+ if type == nil && len(s.types) > elem_index {
type = s.types[elem_index]
}
if enum_value, ok := unwrap_enum(ast_context, type); ok {
for enum_name in enum_value.names {
item := CompletionItem {
- label = enum_name,
- kind = .EnumMember,
+ label = enum_name,
+ kind = .EnumMember,
detail = enum_name,
}
@@ -623,27 +794,34 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
list.items = items[:]
return
- } else if bitset_symbol, ok := resolve_type_expression(ast_context, type); ok {
- if value, ok := unwrap_bitset(ast_context, bitset_symbol); ok {
+ } else if bitset_symbol, ok := resolve_type_expression(
+ ast_context,
+ type,
+ ); ok {
+ if value, ok := unwrap_bitset(
+ ast_context,
+ bitset_symbol,
+ ); ok {
for name in value.names {
-
+
item := CompletionItem {
- label = name,
- kind = .EnumMember,
+ label = name,
+ kind = .EnumMember,
detail = name,
}
-
+
append(&items, item)
- }
+ }
list.items = items[:]
return
}
}
- } else if s, ok := unwrap_bitset(ast_context, comp_symbol); ok {
+ } else if s, ok := unwrap_bitset(ast_context, comp_symbol);
+ ok {
for enum_name in s.names {
item := CompletionItem {
- label = enum_name,
- kind = .EnumMember,
+ label = enum_name,
+ kind = .EnumMember,
detail = enum_name,
}
@@ -655,16 +833,24 @@ 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 == "!=") {
+ }
+
+ if position_context.binary != nil &&
+ (position_context.binary.op.text == "==" ||
+ position_context.binary.op.text == "!=") {
context_node: ^ast.Expr
enum_node: ^ast.Expr
- if position_in_node(position_context.binary.right, position_context.position) {
+ if position_in_node(
+ position_context.binary.right,
+ position_context.position,
+ ) {
context_node = position_context.binary.right
enum_node = position_context.binary.left
- } else if position_in_node(position_context.binary.left, position_context.position) {
+ } else if position_in_node(
+ position_context.binary.left,
+ position_context.position,
+ ) {
context_node = position_context.binary.left
enum_node = position_context.binary.right
}
@@ -673,8 +859,8 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
if enum_value, ok := unwrap_enum(ast_context, enum_node); ok {
for name in enum_value.names {
item := CompletionItem {
- label = name,
- kind = .EnumMember,
+ label = name,
+ kind = .EnumMember,
detail = name,
}
@@ -687,7 +873,9 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
}
}
- if position_context.assign != nil && position_context.assign.rhs != nil && position_context.assign.lhs != nil {
+ if position_context.assign != nil &&
+ position_context.assign.rhs != nil &&
+ position_context.assign.lhs != nil {
rhs_index: int
for elem in position_context.assign.rhs {
@@ -695,8 +883,10 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
break
} else {
//procedures are the only types that can return more than one value
- if symbol, ok := resolve_type_expression(ast_context, elem); ok {
- if procedure, ok := symbol.value.(SymbolProcedureValue); ok {
+ if symbol, ok := resolve_type_expression(ast_context, elem);
+ ok {
+ if procedure, ok := symbol.value.(SymbolProcedureValue);
+ ok {
if procedure.return_types == nil {
return
}
@@ -710,7 +900,10 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
}
if len(position_context.assign.lhs) > rhs_index {
- if enum_value, ok := unwrap_enum(ast_context, position_context.assign.lhs[rhs_index]); ok {
+ if enum_value, ok := unwrap_enum(
+ ast_context,
+ position_context.assign.lhs[rhs_index],
+ ); ok {
for name in enum_value.names {
item := CompletionItem {
label = name,
@@ -750,11 +943,16 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
}
if len(position_context.function.type.results.list) > return_index {
- if enum_value, ok := unwrap_enum(ast_context, position_context.function.type.results.list[return_index].type); ok {
+ if enum_value, ok := unwrap_enum(
+ ast_context,
+ position_context.function.type.results.list[
+ return_index \
+ ].type,
+ ); ok {
for name in enum_value.names {
item := CompletionItem {
- label = name,
- kind = .EnumMember,
+ label = name,
+ kind = .EnumMember,
detail = name,
}
@@ -769,18 +967,25 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
if position_context.call != nil {
if call, ok := position_context.call.derived.(^ast.Call_Expr); ok {
- parameter_index, parameter_ok := find_position_in_call_param(ast_context, call^)
- if symbol, ok := resolve_type_expression(ast_context, call.expr); ok && parameter_ok {
+ parameter_index, parameter_ok := find_position_in_call_param(
+ ast_context,
+ call^,
+ )
+ if symbol, ok := resolve_type_expression(ast_context, call.expr);
+ ok && parameter_ok {
if proc_value, ok := symbol.value.(SymbolProcedureValue); ok {
if len(proc_value.arg_types) <= parameter_index {
return
}
- if enum_value, ok := unwrap_enum(ast_context, proc_value.arg_types[parameter_index].type); ok {
+ if enum_value, ok := unwrap_enum(
+ ast_context,
+ proc_value.arg_types[parameter_index].type,
+ ); ok {
for name in enum_value.names {
item := CompletionItem {
- label = name,
- kind = .EnumMember,
+ label = name,
+ kind = .EnumMember,
detail = name,
}
@@ -796,10 +1001,14 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc
}
}
-get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) {
+get_identifier_completion :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+ list: ^CompletionList,
+) {
CombinedResult :: struct {
score: f32,
- snippet: Snippet_Info,
+ snippet: Snippet_Info,
name: string,
type: SymbolType,
doc: string,
@@ -832,7 +1041,7 @@ 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
@@ -841,15 +1050,18 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D
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,
- name = r.symbol.name,
- doc = r.symbol.doc,
- flags = r.symbol.flags,
- signature = r.symbol.signature,
- pkg = r.symbol.pkg,
- })
+ append(
+ &combined,
+ CombinedResult{
+ score = r.score,
+ type = r.symbol.type,
+ name = r.symbol.name,
+ doc = r.symbol.doc,
+ flags = r.symbol.flags,
+ signature = r.symbol.signature,
+ pkg = r.symbol.pkg,
+ },
+ )
}
}
}
@@ -872,24 +1084,32 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D
ast_context.use_globals = true
ast_context.current_package = ast_context.document_package
- ident := new_type(ast.Ident, v.expr.pos, v.expr.end, context.temp_allocator)
+ ident := new_type(
+ ast.Ident,
+ v.expr.pos,
+ v.expr.end,
+ context.temp_allocator,
+ )
ident.name = k
- if symbol, ok := resolve_type_identifier(ast_context, ident^); ok {
+ if symbol, ok := resolve_type_identifier(ast_context, ident^); ok {
symbol.signature = get_signature(ast_context, ident^, symbol)
build_procedure_symbol_signature(&symbol)
if score, ok := common.fuzzy_match(matcher, ident.name); ok == 1 {
- append(&combined, CombinedResult {
- score = score * 1.1,
- type = symbol.type,
- name = ident.name,
- doc = symbol.doc,
- flags = symbol.flags,
- pkg = symbol.pkg,
- signature = symbol.signature,
- })
+ append(
+ &combined,
+ CombinedResult{
+ score = score * 1.1,
+ type = symbol.type,
+ name = ident.name,
+ doc = symbol.doc,
+ flags = symbol.flags,
+ pkg = symbol.pkg,
+ signature = symbol.signature,
+ },
+ )
}
}
}
@@ -900,30 +1120,43 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D
break
}
- local_offset := get_local_offset(ast_context, position_context.position, k)
+ local_offset := get_local_offset(
+ ast_context,
+ position_context.position,
+ k,
+ )
ast_context.use_locals = true
ast_context.use_globals = true
ast_context.current_package = ast_context.document_package
- ident := new_type(ast.Ident, {offset = local_offset}, {offset = local_offset}, context.temp_allocator)
+ ident := new_type(
+ ast.Ident,
+ {offset = local_offset},
+ {offset = local_offset},
+ context.temp_allocator,
+ )
ident.name = k
- if symbol, ok := resolve_type_identifier(ast_context, ident^); ok {
+ if symbol, ok := resolve_type_identifier(ast_context, ident^); ok {
symbol.signature = get_signature(ast_context, ident^, symbol)
build_procedure_symbol_signature(&symbol)
- if score, ok := common.fuzzy_match(matcher, ident.name); ok == 1 {
- append(&combined, CombinedResult {
- score = score * 1.7,
- type = symbol.type,
- name = ident.name,
- doc = symbol.doc,
- flags = symbol.flags,
- pkg = symbol.pkg,
- signature = symbol.signature,
- })
+ if score, ok := common.fuzzy_match(matcher, ident.name);
+ ok == 1 {
+ append(
+ &combined,
+ CombinedResult{
+ score = score * 1.7,
+ type = symbol.type,
+ name = ident.name,
+ doc = symbol.doc,
+ flags = symbol.flags,
+ pkg = symbol.pkg,
+ signature = symbol.signature,
+ },
+ )
}
}
}
@@ -940,15 +1173,18 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D
}
if score, ok := common.fuzzy_match(matcher, symbol.name); ok == 1 {
- append(&combined, CombinedResult {
- score = score * 1.1,
- type = symbol.type,
- name = symbol.name,
- doc = symbol.doc,
- flags = symbol.flags,
- signature = symbol.signature,
- pkg = symbol.pkg,
- })
+ append(
+ &combined,
+ CombinedResult{
+ score = score * 1.1,
+ type = symbol.type,
+ name = symbol.name,
+ doc = symbol.doc,
+ flags = symbol.flags,
+ signature = symbol.signature,
+ pkg = symbol.pkg,
+ },
+ )
}
}
@@ -959,18 +1195,21 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D
}
if score, ok := common.fuzzy_match(matcher, keyword); ok == 1 {
- append(&combined, CombinedResult {
- score = score,
- type = symbol.type,
- name = symbol.name,
- doc = symbol.doc,
- flags = symbol.flags,
- signature = symbol.signature,
- pkg = symbol.pkg,
- })
+ append(
+ &combined,
+ CombinedResult{
+ score = score,
+ type = symbol.type,
+ name = symbol.name,
+ doc = symbol.doc,
+ flags = symbol.flags,
+ signature = symbol.signature,
+ pkg = symbol.pkg,
+ },
+ )
}
}
-
+
for keyword, _ in language_keywords {
symbol := Symbol {
name = keyword,
@@ -978,22 +1217,28 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D
}
if score, ok := common.fuzzy_match(matcher, keyword); ok == 1 {
- append(&combined, CombinedResult {
- score = score * 1.1,
- type = symbol.type,
- name = symbol.name,
- doc = symbol.doc,
- flags = symbol.flags,
- signature = symbol.signature,
- pkg = symbol.pkg,
- })
+ append(
+ &combined,
+ CombinedResult{
+ score = score * 1.1,
+ type = symbol.type,
+ name = symbol.name,
+ doc = symbol.doc,
+ flags = symbol.flags,
+ signature = symbol.signature,
+ pkg = symbol.pkg,
+ },
+ )
}
}
if common.config.enable_snippets {
for k, v in snippets {
if score, ok := common.fuzzy_match(matcher, k); ok == 1 {
- append(&combined, CombinedResult {score = score * 1.1, snippet = v, name = k})
+ append(
+ &combined,
+ CombinedResult{score = score * 1.1, snippet = v, name = k},
+ )
}
}
}
@@ -1009,23 +1254,28 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D
result := result
//Skip procedures when the position is in proc decl
- if position_in_proc_decl(position_context) && result.type == .Function && common.config.enable_procedure_context {
+ if position_in_proc_decl(position_context) &&
+ result.type == .Function &&
+ common.config.enable_procedure_context {
continue
}
if result.snippet.insert != "" {
item := CompletionItem {
- label = result.name,
- insertText = result.snippet.insert,
- kind = .Snippet,
- detail = result.snippet.detail,
+ label = result.name,
+ insertText = result.snippet.insert,
+ kind = .Snippet,
+ detail = result.snippet.detail,
insertTextFormat = .Snippet,
}
edits := make([dynamic]TextEdit, context.temp_allocator)
for pkg in result.snippet.packages {
- edit, ok := get_core_insert_package_if_non_existent(ast_context, pkg)
+ edit, ok := get_core_insert_package_if_non_existent(
+ ast_context,
+ pkg,
+ )
if ok {
append(&edits, edit)
}
@@ -1036,7 +1286,7 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D
append(&items, item)
} else {
item := CompletionItem {
- label = result.name,
+ label = result.name,
documentation = result.doc,
}
@@ -1045,11 +1295,18 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D
if result.type == .Function && common.config.enable_snippets {
item.insertText = fmt.tprintf("%v($0)", item.label)
item.insertTextFormat = .Snippet
- item.deprecated = .Deprecated in result.flags
+ item.deprecated = .Deprecated in result.flags
item.command.command = "editor.action.triggerParameterHints"
}
-
- item.detail = concatenate_symbol_information(ast_context, result.pkg, result.name, result.signature, result.type, true)
+
+ item.detail = concatenate_symbol_information(
+ ast_context,
+ result.pkg,
+ result.name,
+ result.signature,
+ result.type,
+ true,
+ )
append(&items, item)
}
@@ -1058,7 +1315,11 @@ get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^D
list.items = items[:]
}
-get_package_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) {
+get_package_completion :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+ list: ^CompletionList,
+) {
items := make([dynamic]CompletionItem, context.temp_allocator)
list.isIncomplete = false
@@ -1069,30 +1330,47 @@ get_package_completion :: proc(ast_context: ^AstContext, position_context: ^Docu
return
}
- without_quotes := position_context.import_stmt.fullpath[1:fullpath_length-1]
+ without_quotes := position_context.import_stmt.fullpath[1:fullpath_length -
+ 1]
absolute_path := without_quotes
colon_index := strings.index(without_quotes, ":")
if colon_index >= 0 {
c := without_quotes[0:colon_index]
- if colon_index+1 < len(without_quotes) {
- absolute_path = filepath.join(elems = {common.config.collections[c], filepath.dir(without_quotes[colon_index+1:], context.temp_allocator)}, allocator = context.temp_allocator)
+ if colon_index + 1 < len(without_quotes) {
+ absolute_path = filepath.join(
+ elems = {
+ common.config.collections[c],
+ filepath.dir(
+ without_quotes[colon_index + 1:],
+ context.temp_allocator,
+ ),
+ },
+ allocator = context.temp_allocator,
+ )
} else {
absolute_path = common.config.collections[c]
}
} else {
- import_file_dir := filepath.dir(position_context.import_stmt.pos.file, context.temp_allocator)
+ import_file_dir := filepath.dir(
+ position_context.import_stmt.pos.file,
+ context.temp_allocator,
+ )
import_dir := filepath.dir(without_quotes, context.temp_allocator)
- absolute_path = filepath.join(elems = {import_file_dir, import_dir}, allocator = context.temp_allocator)
+ absolute_path = filepath.join(
+ elems = {import_file_dir, import_dir},
+ allocator = context.temp_allocator,
+ )
}
- if !strings.contains(position_context.import_stmt.fullpath, "/") && !strings.contains(position_context.import_stmt.fullpath, ":") {
+ if !strings.contains(position_context.import_stmt.fullpath, "/") &&
+ !strings.contains(position_context.import_stmt.fullpath, ":") {
for key, _ in common.config.collections {
item := CompletionItem {
detail = "collection",
- label = key,
- kind = .Module,
+ label = key,
+ kind = .Module,
}
append(&items, item)
@@ -1102,8 +1380,8 @@ get_package_completion :: proc(ast_context: ^AstContext, position_context: ^Docu
for pkg in search_for_packages(absolute_path) {
item := CompletionItem {
detail = pkg,
- label = filepath.base(pkg),
- kind = .Folder,
+ label = filepath.base(pkg),
+ kind = .Folder,
}
if item.label[0] == '.' {
@@ -1116,7 +1394,7 @@ get_package_completion :: proc(ast_context: ^AstContext, position_context: ^Docu
list.items = items[:]
}
-search_for_packages :: proc(fullpath: string) -> [] string {
+search_for_packages :: proc(fullpath: string) -> []string {
packages := make([dynamic]string, context.temp_allocator)
fh, err := os.open(fullpath)
@@ -1137,13 +1415,18 @@ search_for_packages :: proc(fullpath: string) -> [] string {
return packages[:]
}
-get_type_switch_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) {
+get_type_switch_completion :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+ list: ^CompletionList,
+) {
items := make([dynamic]CompletionItem, context.temp_allocator)
list.isIncomplete = false
used_unions := make(map[string]bool, 5, context.temp_allocator)
- if block, ok := position_context.switch_type_stmt.body.derived.(^ast.Block_Stmt); ok {
+ if block, ok := position_context.switch_type_stmt.body.derived.(^ast.Block_Stmt);
+ ok {
for stmt in block.stmts {
if case_clause, ok := stmt.derived.(^ast.Case_Clause); ok {
for name in case_clause.list {
@@ -1155,26 +1438,51 @@ get_type_switch_completion :: proc(ast_context: ^AstContext, position_context: ^
}
}
- ast_context.use_locals = true
+ ast_context.use_locals = true
ast_context.use_globals = true
- if assign, ok := position_context.switch_type_stmt.tag.derived.(^ast.Assign_Stmt); ok && assign.rhs != nil && len(assign.rhs) == 1 {
+ if assign, ok := position_context.switch_type_stmt.tag.derived.(^ast.Assign_Stmt);
+ ok && assign.rhs != nil && len(assign.rhs) == 1 {
if union_value, ok := unwrap_union(ast_context, assign.rhs[0]); ok {
for type, i in union_value.types {
- if symbol, ok := resolve_type_expression(ast_context, union_value.types[i]); ok {
+ if symbol, ok := resolve_type_expression(
+ ast_context,
+ union_value.types[i],
+ ); ok {
name := symbol.name
if name in used_unions {
continue
}
-
+
item := CompletionItem {
kind = .EnumMember,
}
-
+
if symbol.pkg == ast_context.document_package {
- item.label = fmt.aprintf("%v%v", common.repeat("^", symbol.pointers, context.temp_allocator), name)
+ item.label = fmt.aprintf(
+ "%v%v",
+ common.repeat(
+ "^",
+ symbol.pointers,
+ context.temp_allocator,
+ ),
+ name,
+ )
} else {
- item.label = fmt.aprintf("%v%v.%v", common.repeat("^", symbol.pointers, context.temp_allocator), path.base(symbol.pkg, false, context.temp_allocator), name)
+ item.label = fmt.aprintf(
+ "%v%v.%v",
+ common.repeat(
+ "^",
+ symbol.pointers,
+ context.temp_allocator,
+ ),
+ path.base(
+ symbol.pkg,
+ false,
+ context.temp_allocator,
+ ),
+ name,
+ )
}
append(&items, item)
@@ -1186,7 +1494,13 @@ get_type_switch_completion :: proc(ast_context: ^AstContext, position_context: ^
list.items = items[:]
}
-get_core_insert_package_if_non_existent :: proc(ast_context: ^AstContext, pkg: string) -> (TextEdit, bool) {
+get_core_insert_package_if_non_existent :: proc(
+ ast_context: ^AstContext,
+ pkg: string,
+) -> (
+ TextEdit,
+ bool,
+) {
builder := strings.builder_make(context.temp_allocator)
for imp in ast_context.imports {
@@ -1212,9 +1526,17 @@ get_core_insert_package_if_non_existent :: proc(ast_context: ^AstContext, pkg: s
}, true
}
-get_range_from_selection_start_to_dot :: proc(position_context: ^DocumentPositionContext) -> (common.Range, bool) {
+get_range_from_selection_start_to_dot :: proc(
+ position_context: ^DocumentPositionContext,
+) -> (
+ common.Range,
+ bool,
+) {
if position_context.selector != nil {
- range := common.get_token_range(position_context.selector, position_context.file.src)
+ range := common.get_token_range(
+ position_context.selector,
+ position_context.file.src,
+ )
range.end.character += 1
return range, true
}
@@ -1222,20 +1544,24 @@ get_range_from_selection_start_to_dot :: proc(position_context: ^DocumentPositio
return {}, false
}
-append_magic_map_completion :: proc(position_context: ^DocumentPositionContext, symbol: Symbol, items: ^[dynamic]CompletionItem) {
+append_magic_map_completion :: proc(
+ position_context: ^DocumentPositionContext,
+ symbol: Symbol,
+ items: ^[dynamic]CompletionItem,
+) {
range, ok := get_range_from_selection_start_to_dot(position_context)
if !ok {
- return
+ return
}
remove_range := common.Range {
start = range.start,
- end = range.end,
+ end = range.end,
}
remove_edit := TextEdit {
- range = remove_range,
+ range = remove_range,
newText = "",
}
@@ -1249,37 +1575,41 @@ append_magic_map_completion :: proc(position_context: ^DocumentPositionContext,
kind = .Snippet,
detail = "for",
additionalTextEdits = additionalTextEdits,
- textEdit = TextEdit {
- newText = fmt.tprintf("for ${{1:k}}, ${{2:v}} in %v {{\n\t$0 \n}}", symbol.name),
- range = {
- start = range.end,
- end = range.end,
- },
+ textEdit = TextEdit{
+ newText = fmt.tprintf(
+ "for ${{1:k}}, ${{2:v}} in %v {{\n\t$0 \n}}",
+ symbol.name,
+ ),
+ range = {start = range.end, end = range.end},
},
insertTextFormat = .Snippet,
InsertTextMode = .adjustIndentation,
}
-
+
append(items, item)
}
}
-append_magic_dynamic_array_completion :: proc(position_context: ^DocumentPositionContext, symbol: Symbol, items: ^[dynamic]CompletionItem) {
+append_magic_dynamic_array_completion :: proc(
+ position_context: ^DocumentPositionContext,
+ symbol: Symbol,
+ items: ^[dynamic]CompletionItem,
+) {
range, ok := get_range_from_selection_start_to_dot(position_context)
if !ok {
- return
+ return
}
remove_range := common.Range {
start = range.start,
- end = range.end,
+ end = range.end,
}
remove_edit := TextEdit {
- range = remove_range,
+ range = remove_range,
newText = "",
}
@@ -1294,12 +1624,9 @@ append_magic_dynamic_array_completion :: proc(position_context: ^DocumentPositio
label = "len",
kind = .Function,
detail = "len",
- textEdit = TextEdit {
+ textEdit = TextEdit{
newText = text,
- range = {
- start = range.end,
- end = range.end,
- },
+ range = {start = range.end, end = range.end},
},
additionalTextEdits = additionalTextEdits,
}
@@ -1314,42 +1641,46 @@ append_magic_dynamic_array_completion :: proc(position_context: ^DocumentPositio
kind = .Snippet,
detail = "for",
additionalTextEdits = additionalTextEdits,
- textEdit = TextEdit {
- newText = fmt.tprintf("for i in %v {{\n\t$0 \n}}", symbol.name),
- range = {
- start = range.end,
- end = range.end,
- },
+ textEdit = TextEdit{
+ newText = fmt.tprintf(
+ "for i in %v {{\n\t$0 \n}}",
+ symbol.name,
+ ),
+ range = {start = range.end, end = range.end},
},
insertTextFormat = .Snippet,
InsertTextMode = .adjustIndentation,
}
-
+
append(items, item)
}
-
+
}
-append_magic_union_completion :: proc(position_context: ^DocumentPositionContext, symbol: Symbol, items: ^[dynamic]CompletionItem) {
+append_magic_union_completion :: proc(
+ position_context: ^DocumentPositionContext,
+ symbol: Symbol,
+ items: ^[dynamic]CompletionItem,
+) {
range, ok := get_range_from_selection_start_to_dot(position_context)
if !ok {
- return
+ return
}
remove_range := common.Range {
start = range.start,
- end = range.end,
+ end = range.end,
}
remove_edit := TextEdit {
- range = remove_range,
+ range = remove_range,
newText = "",
}
additionalTextEdits := make([]TextEdit, 1, context.temp_allocator)
additionalTextEdits[0] = remove_edit
-
+
//switch
{
item := CompletionItem {
@@ -1357,28 +1688,28 @@ append_magic_union_completion :: proc(position_context: ^DocumentPositionContext
kind = .Snippet,
detail = "switch",
additionalTextEdits = additionalTextEdits,
- textEdit = TextEdit {
- newText = fmt.tprintf("switch v in %v {{\n\t$0 \n}}", symbol.name),
- range = {
- start = range.end,
- end = range.end,
- },
+ textEdit = TextEdit{
+ newText = fmt.tprintf(
+ "switch v in %v {{\n\t$0 \n}}",
+ symbol.name,
+ ),
+ range = {start = range.end, end = range.end},
},
insertTextFormat = .Snippet,
InsertTextMode = .adjustIndentation,
}
-
+
append(items, item)
}
}
bitset_operators: map[string]bool = {
- "|" = true,
- "&" = true,
- "~" = true,
- "<" = true,
- ">" = true,
+ "|" = true,
+ "&" = true,
+ "~" = true,
+ "<" = true,
+ ">" = true,
"==" = true,
}
@@ -1388,7 +1719,7 @@ bitset_assignment_operators: map[string]bool = {
"~=" = true,
"<=" = true,
">=" = true,
- "=" = true,
+ "=" = true,
"+=" = true,
}
@@ -1445,9 +1776,9 @@ language_keywords: []string = {
}
swizzle_color_components: map[u8]bool = {
- 'r' = true,
- 'g' = true,
- 'b' = true,
+ 'r' = true,
+ 'g' = true,
+ 'b' = true,
'a' = true,
}
@@ -1456,4 +1787,4 @@ swizzle_coord_components: map[u8]bool = {
'y' = true,
'z' = true,
'w' = true,
-};
+}
diff --git a/src/server/definition.odin b/src/server/definition.odin
index ad9e7a8..309cde1 100644
--- a/src/server/definition.odin
+++ b/src/server/definition.odin
@@ -16,16 +16,32 @@ import "core:os"
import "shared:common"
-get_definition_location :: proc(document: ^Document, position: common.Position) -> ([]common.Location, bool) {
+get_definition_location :: proc(
+ document: ^Document,
+ position: common.Position,
+) -> (
+ []common.Location,
+ bool,
+) {
locations := make([dynamic]common.Location, context.temp_allocator)
location: common.Location
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath)
+ ast_context := make_ast_context(
+ document.ast,
+ document.imports,
+ document.package_name,
+ document.uri.uri,
+ document.fullpath,
+ )
uri: string
- position_context, ok := get_document_position_context(document, position, .Definition)
+ position_context, ok := get_document_position_context(
+ document,
+ position,
+ .Definition,
+ )
if !ok {
log.warn("Failed to get position context")
@@ -35,16 +51,25 @@ get_definition_location :: proc(document: ^Document, position: common.Position)
get_globals(document.ast, &ast_context)
if position_context.function != nil {
- get_locals(document.ast, position_context.function, &ast_context, &position_context)
+ get_locals(
+ document.ast,
+ position_context.function,
+ &ast_context,
+ &position_context,
+ )
}
if position_context.selector_expr != nil {
//if the base selector is the client wants to go to.
- if base, ok := position_context.selector.derived.(^ast.Ident); ok && position_context.identifier != nil {
+ if base, ok := position_context.selector.derived.(^ast.Ident);
+ ok && position_context.identifier != nil {
ident := position_context.identifier.derived.(^ast.Ident)
if position_in_node(base, position_context.position) {
- if resolved, ok := resolve_location_identifier(&ast_context, ident^); ok {
+ if resolved, ok := resolve_location_identifier(
+ &ast_context,
+ ident^,
+ ); ok {
location.range = resolved.range
if resolved.uri == "" {
@@ -62,12 +87,18 @@ get_definition_location :: proc(document: ^Document, position: common.Position)
}
}
- if resolved, ok := resolve_location_selector(&ast_context, position_context.selector_expr); ok {
+ if resolved, ok := resolve_location_selector(
+ &ast_context,
+ position_context.selector_expr,
+ ); ok {
location.range = resolved.range
uri = resolved.uri
}
} else if position_context.identifier != nil {
- if resolved, ok := resolve_location_identifier(&ast_context, position_context.identifier.derived.(^ast.Ident)^); ok {
+ if resolved, ok := resolve_location_identifier(
+ &ast_context,
+ position_context.identifier.derived.(^ast.Ident)^,
+ ); ok {
location.range = resolved.range
uri = resolved.uri
} else {
@@ -87,4 +118,4 @@ get_definition_location :: proc(document: ^Document, position: common.Position)
append(&locations, location)
return locations[:], true
-} \ No newline at end of file
+}
diff --git a/src/server/document_links.odin b/src/server/document_links.odin
index 0049509..17113ff 100644
--- a/src/server/document_links.odin
+++ b/src/server/document_links.odin
@@ -25,7 +25,11 @@ get_document_links :: proc(document: ^Document) -> ([]DocumentLink, bool) {
continue
}
- e := strings.split(imp.relpath.text[1:len(imp.relpath.text)-1], ":", context.temp_allocator)
+ e := strings.split(
+ imp.relpath.text[1:len(imp.relpath.text) - 1],
+ ":",
+ context.temp_allocator,
+ )
if len(e) != 2 {
continue
@@ -43,7 +47,7 @@ get_document_links :: proc(document: ^Document) -> ([]DocumentLink, bool) {
line = imp.relpath.pos.line,
},
end = {
- offset = imp.relpath.pos.offset + len(imp.relpath.text) - 1,
+ offset = imp.relpath.pos.offset + len(imp.relpath.text) - 1,
column = imp.relpath.pos.column + len(imp.relpath.text) - 1,
line = imp.relpath.pos.line,
},
@@ -52,8 +56,12 @@ get_document_links :: proc(document: ^Document) -> ([]DocumentLink, bool) {
range := common.get_token_range(node, string(document.text))
link := DocumentLink {
- range = range,
- target = fmt.tprintf("https://pkg.odin-lang.org/%v/%v", e[0], e[1]),
+ range = range,
+ target = fmt.tprintf(
+ "https://pkg.odin-lang.org/%v/%v",
+ e[0],
+ e[1],
+ ),
tooltip = "Documentation",
}
diff --git a/src/server/document_symbols.odin b/src/server/document_symbols.odin
index 274c37f..bed5734 100644
--- a/src/server/document_symbols.odin
+++ b/src/server/document_symbols.odin
@@ -18,7 +18,13 @@ 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, document.fullpath)
+ ast_context := make_ast_context(
+ document.ast,
+ document.imports,
+ document.package_name,
+ document.uri.uri,
+ document.fullpath,
+ )
get_globals(document.ast, &ast_context)
@@ -31,11 +37,13 @@ get_document_symbols :: proc(document: ^Document) -> []DocumentSymbol {
}
package_symbol.kind = .Package
- package_symbol.name = path.base(document.package_name, false, context.temp_allocator)
+ package_symbol.name = path.base(
+ document.package_name,
+ false,
+ context.temp_allocator,
+ )
package_symbol.range = {
- start = {
- line = document.ast.decls[0].pos.line,
- },
+ start = {line = document.ast.decls[0].pos.line},
end = {
line = document.ast.decls[len(document.ast.decls) - 1].end.line,
},
@@ -47,7 +55,10 @@ get_document_symbols :: proc(document: ^Document) -> []DocumentSymbol {
for k, global in ast_context.globals {
symbol: DocumentSymbol
- symbol.range = common.get_token_range(global.expr, ast_context.file.src)
+ symbol.range = common.get_token_range(
+ global.expr,
+ ast_context.file.src,
+ )
symbol.selectionRange = symbol.range
symbol.name = k
diff --git a/src/server/documents.odin b/src/server/documents.odin
index 52309ed..5adfdfb 100644
--- a/src/server/documents.odin
+++ b/src/server/documents.odin
@@ -72,7 +72,7 @@ document_get_allocator :: proc() -> ^common.Scratch_Allocator {
return pop(&document_storage.free_allocators)
} else {
allocator := new(common.Scratch_Allocator)
- common.scratch_allocator_init(allocator, mem.Megabyte*3)
+ common.scratch_allocator_init(allocator, mem.Megabyte * 3)
return allocator
}
}
@@ -111,7 +111,12 @@ document_release :: proc(document: ^Document) {
Client opens a document with transferred text
*/
-document_open :: proc(uri_string: string, text: string, config: ^common.Config, writer: ^Writer) -> common.Error {
+document_open :: proc(
+ uri_string: string,
+ text: string,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
uri, parsed_ok := common.parse_uri(uri_string, context.allocator)
if !parsed_ok {
@@ -121,7 +126,10 @@ document_open :: proc(uri_string: string, text: string, config: ^common.Config,
if document := &document_storage.documents[uri.path]; document != nil {
if document.client_owned {
- log.errorf("Client called open on an already open document: %v ", document.uri.path)
+ log.errorf(
+ "Client called open on an already open document: %v ",
+ document.uri.path,
+ )
return .InvalidRequest
}
@@ -138,11 +146,11 @@ document_open :: proc(uri_string: string, text: string, config: ^common.Config,
}
} else {
document := Document {
- uri = uri,
- text = transmute([]u8)text,
+ uri = uri,
+ text = transmute([]u8)text,
client_owned = true,
- used_text = len(text),
- allocator = document_get_allocator(),
+ used_text = len(text),
+ allocator = document_get_allocator(),
}
document_setup(&document)
@@ -160,37 +168,46 @@ document_open :: proc(uri_string: string, text: string, config: ^common.Config,
}
document_setup :: proc(document: ^Document) {
- //Right now not all clients return the case correct windows path, and that causes issues with indexing, so we ensure that it's case correct.
- when ODIN_OS == .Windows {
- package_name := path.dir(document.uri.path, context.temp_allocator)
- forward, _ := filepath.to_slash(common.get_case_sensitive_path(package_name), context.temp_allocator)
- if forward == "" {
- document.package_name = package_name
- } else {
- document.package_name = strings.clone(forward)
- }
+ //Right now not all clients return the case correct windows path, and that causes issues with indexing, so we ensure that it's case correct.
+ when ODIN_OS == .Windows {
+ package_name := path.dir(document.uri.path, context.temp_allocator)
+ forward, _ := filepath.to_slash(
+ common.get_case_sensitive_path(package_name),
+ context.temp_allocator,
+ )
+ if forward == "" {
+ document.package_name = package_name
} else {
- document.package_name = path.dir(document.uri.path)
+ document.package_name = strings.clone(forward)
}
+ } else {
+ document.package_name = path.dir(document.uri.path)
+ }
- when ODIN_OS == .Windows {
- correct := common.get_case_sensitive_path(document.uri.path)
- fullpath: string
- if correct == "" {
- //This is basically here to handle the tests where the physical file doesn't actual exist.
- document.fullpath, _ = filepath.to_slash(document.uri.path)
- } else {
- document.fullpath, _ = filepath.to_slash(correct)
- }
+ when ODIN_OS == .Windows {
+ correct := common.get_case_sensitive_path(document.uri.path)
+ fullpath: string
+ if correct == "" {
+ //This is basically here to handle the tests where the physical file doesn't actual exist.
+ document.fullpath, _ = filepath.to_slash(document.uri.path)
} else {
- document.fullpath = document.uri.path
+ document.fullpath, _ = filepath.to_slash(correct)
}
+ } else {
+ document.fullpath = document.uri.path
+ }
}
/*
Function that applies changes to the given document through incremental syncronization
*/
-document_apply_changes :: proc(uri_string: string, changes: [dynamic]TextDocumentContentChangeEvent, version: Maybe(int), config: ^common.Config, writer: ^Writer) -> common.Error {
+document_apply_changes :: proc(
+ uri_string: string,
+ changes: [dynamic]TextDocumentContentChangeEvent,
+ version: Maybe(int),
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
uri, parsed_ok := common.parse_uri(uri_string, context.temp_allocator)
if !parsed_ok {
@@ -202,14 +219,20 @@ document_apply_changes :: proc(uri_string: string, changes: [dynamic]TextDocumen
document.version = version
if !document.client_owned {
- log.errorf("Client called change on an document not opened: %v ", document.uri.path)
+ log.errorf(
+ "Client called change on an document not opened: %v ",
+ document.uri.path,
+ )
return .InvalidRequest
}
for change in changes {
//for some reason sublime doesn't seem to care even if i tell it to do incremental sync
if range, ok := change.range.(common.Range); ok {
- absolute_range, ok := common.get_absolute_range(range, document.text[:document.used_text])
+ absolute_range, ok := common.get_absolute_range(
+ range,
+ document.text[:document.used_text],
+ )
if !ok {
return .ParseError
@@ -276,7 +299,10 @@ document_close :: proc(uri_string: string) -> common.Error {
document := &document_storage.documents[uri.path]
if document == nil || !document.client_owned {
- log.errorf("Client called close on a document that was never opened: %v ", document.uri.path)
+ log.errorf(
+ "Client called close on a document that was never opened: %v ",
+ document.uri.path,
+ )
return .InvalidRequest
}
@@ -294,7 +320,11 @@ document_close :: proc(uri_string: string) -> common.Error {
return .None
}
-document_refresh :: proc(document: ^Document, config: ^common.Config, writer: ^Writer) -> common.Error {
+document_refresh :: proc(
+ document: ^Document,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
errors, ok := parse_document(document, config)
if !ok {
@@ -305,32 +335,33 @@ document_refresh :: proc(document: ^Document, config: ^common.Config, writer: ^W
document.diagnosed_errors = true
params := NotificationPublishDiagnosticsParams {
- uri = document.uri.uri,
- diagnostics = make([]Diagnostic, len(errors), context.temp_allocator),
+ uri = document.uri.uri,
+ diagnostics = make(
+ []Diagnostic,
+ len(errors),
+ context.temp_allocator,
+ ),
}
for error, i in errors {
params.diagnostics[i] = Diagnostic {
- range = common.Range {
- start = common.Position {
+ range = common.Range{
+ start = common.Position{
line = error.line - 1,
character = 0,
},
- end = common.Position {
- line = error.line,
- character = 0,
- },
+ end = common.Position{line = error.line, character = 0},
},
severity = DiagnosticSeverity.Error,
code = "Syntax",
message = error.message,
}
}
-
+
notifaction := Notification {
jsonrpc = "2.0",
- method = "textDocument/publishDiagnostics",
- params = params,
+ method = "textDocument/publishDiagnostics",
+ params = params,
}
send_notification(notifaction, writer)
@@ -343,9 +374,13 @@ document_refresh :: proc(document: ^Document, config: ^common.Config, writer: ^W
notifaction := Notification {
jsonrpc = "2.0",
method = "textDocument/publishDiagnostics",
- params = NotificationPublishDiagnosticsParams {
+ params = NotificationPublishDiagnosticsParams{
uri = document.uri.uri,
- diagnostics = make([]Diagnostic, len(errors), context.temp_allocator),
+ diagnostics = make(
+ []Diagnostic,
+ len(errors),
+ context.temp_allocator,
+ ),
},
}
@@ -362,13 +397,22 @@ current_errors: [dynamic]ParserError
parser_error_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) {
error := ParserError {
- line = pos.line,column = pos.column,file = pos.file,
- offset = pos.offset,message = fmt.tprintf(msg, ..args),
+ line = pos.line,
+ column = pos.column,
+ file = pos.file,
+ offset = pos.offset,
+ message = fmt.tprintf(msg, ..args),
}
append(&current_errors, error)
}
-parse_document :: proc(document: ^Document, config: ^common.Config) -> ([]ParserError, bool) {
+parse_document :: proc(
+ document: ^Document,
+ config: ^common.Config,
+) -> (
+ []ParserError,
+ bool,
+) {
p := parser.Parser {
err = parser_error_handler,
warn = common.parser_warning_handler,
@@ -391,8 +435,8 @@ parse_document :: proc(document: ^Document, config: ^common.Config) -> ([]Parser
document.ast = ast.File {
fullpath = document.fullpath,
- src = string(document.text[:document.used_text]),
- pkg = pkg,
+ src = string(document.text[:document.used_text]),
+ pkg = pkg,
}
parser.parse_file(&p, &document.ast)
@@ -404,14 +448,15 @@ parse_document :: proc(document: ^Document, config: ^common.Config) -> ([]Parser
parse_imports :: proc(document: ^Document, config: ^common.Config) {
imports := make([dynamic]Package)
-
+
for imp, index in document.ast.imports {
if i := strings.index(imp.fullpath, "\""); i == -1 {
continue
}
//collection specified
- if i := strings.index(imp.fullpath, ":"); i != -1 && i > 1 && i < len(imp.fullpath) - 1 {
+ if i := strings.index(imp.fullpath, ":");
+ i != -1 && i > 1 && i < len(imp.fullpath) - 1 {
if len(imp.fullpath) < 2 {
continue
}
@@ -426,14 +471,19 @@ parse_imports :: proc(document: ^Document, config: ^common.Config) {
}
import_: Package
- import_.name = strings.clone(path.join(elems = {dir, p}, allocator = context.temp_allocator))
+ import_.name = strings.clone(
+ path.join(
+ elems = {dir, p},
+ allocator = context.temp_allocator,
+ ),
+ )
if imp.name.text != "" {
import_.base = imp.name.text
} else {
import_.base = path.base(import_.name, false)
}
-
+
append(&imports, import_)
} else {
//relative
@@ -442,7 +492,13 @@ parse_imports :: proc(document: ^Document, config: ^common.Config) {
}
import_: Package
- import_.name = path.join(elems = {document.package_name, imp.fullpath[1:len(imp.fullpath) - 1]}, allocator = context.temp_allocator)
+ import_.name = path.join(
+ elems = {
+ document.package_name,
+ imp.fullpath[1:len(imp.fullpath) - 1],
+ },
+ allocator = context.temp_allocator,
+ )
import_.name = path.clean(import_.name)
if imp.name.text != "" {
diff --git a/src/server/format.odin b/src/server/format.odin
index 236bee2..cbb4082 100644
--- a/src/server/format.odin
+++ b/src/server/format.odin
@@ -20,7 +20,13 @@ DocumentFormattingParams :: struct {
options: FormattingOptions,
}
-get_complete_format :: proc(document: ^Document, config: ^common.Config) -> ([]TextEdit, bool) {
+get_complete_format :: proc(
+ document: ^Document,
+ config: ^common.Config,
+) -> (
+ []TextEdit,
+ bool,
+) {
if document.ast.syntax_error_count > 0 {
return {}, true
}
@@ -29,7 +35,9 @@ get_complete_format :: proc(document: ^Document, config: ^common.Config) -> ([]T
return {}, true
}
- style := format.find_config_file_or_default(filepath.dir(document.fullpath, context.temp_allocator))
+ style := format.find_config_file_or_default(
+ filepath.dir(document.fullpath, context.temp_allocator),
+ )
prnt := printer.make_printer(style, context.temp_allocator)
src := printer.print(&prnt, &document.ast)
@@ -42,7 +50,9 @@ get_complete_format :: proc(document: ^Document, config: ^common.Config) -> ([]T
last := document.text[0]
line := 0
- for current_index := 0; current_index < len(document.text); current_index += 1 {
+ for current_index := 0;
+ current_index < len(document.text);
+ current_index += 1 {
current := document.text[current_index]
if last == '\r' && current == '\n' {
@@ -58,14 +68,8 @@ get_complete_format :: proc(document: ^Document, config: ^common.Config) -> ([]T
edit := TextEdit {
newText = src,
range = {
- start = {
- character = 0,
- line = 0,
- },
- end = {
- character = 1,
- line = line+1,
- },
+ start = {character = 0, line = 0},
+ end = {character = 1, line = line + 1},
},
}
diff --git a/src/server/hover.odin b/src/server/hover.odin
index 0e00fa0..580038f 100644
--- a/src/server/hover.odin
+++ b/src/server/hover.odin
@@ -15,17 +15,24 @@ import "core:slice"
import "shared:common"
-write_hover_content :: proc(ast_context: ^AstContext, symbol: Symbol) -> MarkupContent {
+write_hover_content :: proc(
+ ast_context: ^AstContext,
+ symbol: Symbol,
+) -> MarkupContent {
content: MarkupContent
symbol := symbol
if untyped, ok := symbol.value.(SymbolUntypedValue); ok {
switch untyped.type {
- case .String: symbol.signature = "string"
- case .Bool: symbol.signature = "bool"
- case .Float: symbol.signature = "float"
- case .Integer: symbol.signature = "int"
+ case .String:
+ symbol.signature = "string"
+ case .Bool:
+ symbol.signature = "bool"
+ case .Float:
+ symbol.signature = "float"
+ case .Integer:
+ symbol.signature = "int"
}
}
@@ -44,80 +51,133 @@ write_hover_content :: proc(ast_context: ^AstContext, symbol: Symbol) -> MarkupC
}
builtin_identifier_hover: map[string]string = {
- "context" = fmt.aprintf("```odin\n%v\n```\n%v", "runtime.context: Context", "This context variable is local to each scope and is implicitly passed by pointer to any procedure call in that scope (if the procedure has the Odin calling convention)."),
+ "context" = fmt.aprintf(
+ "```odin\n%v\n```\n%v",
+ "runtime.context: Context",
+ "This context variable is local to each scope and is implicitly passed by pointer to any procedure call in that scope (if the procedure has the Odin calling convention).",
+ ),
}
-get_hover_information :: proc(document: ^Document, position: common.Position) -> (Hover, bool, bool) {
+get_hover_information :: proc(
+ document: ^Document,
+ position: common.Position,
+) -> (
+ Hover,
+ bool,
+ bool,
+) {
hover := Hover {
- contents = {
- kind = "plaintext",
- },
+ contents = {kind = "plaintext"},
}
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath)
+ 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)
+ position_context, ok := get_document_position_context(
+ document,
+ position,
+ .Hover,
+ )
get_globals(document.ast, &ast_context)
if position_context.function != nil {
- get_locals(document.ast, position_context.function, &ast_context, &position_context)
+ get_locals(
+ document.ast,
+ position_context.function,
+ &ast_context,
+ &position_context,
+ )
}
if position_context.identifier != nil {
if ident, ok := position_context.identifier.derived.(^ast.Ident); ok {
if _, ok := common.keyword_map[ident.name]; ok {
hover.contents.kind = "plaintext"
- hover.range = common.get_token_range(position_context.identifier^, ast_context.file.src)
+ hover.range = common.get_token_range(
+ position_context.identifier^,
+ ast_context.file.src,
+ )
return hover, true, true
}
if str, ok := builtin_identifier_hover[ident.name]; ok {
hover.contents.kind = "markdown"
hover.contents.value = str
- hover.range = common.get_token_range(position_context.identifier^, ast_context.file.src)
+ hover.range = common.get_token_range(
+ position_context.identifier^,
+ ast_context.file.src,
+ )
return hover, true, true
}
- }
+ }
}
if position_context.implicit_context != nil {
- if str, ok := builtin_identifier_hover[position_context.implicit_context.tok.text]; ok {
+ if str, ok :=
+ builtin_identifier_hover[
+ position_context.implicit_context.tok.text \
+ ]; ok {
hover.contents.kind = "markdown"
hover.contents.value = str
- hover.range = common.get_token_range(position_context.implicit_context^, ast_context.file.src)
+ hover.range = common.get_token_range(
+ position_context.implicit_context^,
+ ast_context.file.src,
+ )
return hover, true, true
}
}
if position_context.selector != nil && position_context.identifier != nil {
- hover.range = common.get_token_range(position_context.identifier^, ast_context.file.src)
+ hover.range = common.get_token_range(
+ position_context.identifier^,
+ ast_context.file.src,
+ )
ast_context.use_locals = true
ast_context.use_globals = true
ast_context.current_package = ast_context.document_package
//if the base selector is the client wants to go to.
- if base, ok := position_context.selector.derived.(^ast.Ident); ok && position_context.identifier != nil {
+ if base, ok := position_context.selector.derived.(^ast.Ident);
+ ok && position_context.identifier != nil {
ident := position_context.identifier.derived.(^ast.Ident)^
if position_in_node(base, position_context.position) {
- if resolved, ok := resolve_type_identifier(&ast_context, ident); ok {
- resolved.signature = get_signature(&ast_context, ident, resolved)
+ if resolved, ok := resolve_type_identifier(
+ &ast_context,
+ ident,
+ ); ok {
+ resolved.signature = get_signature(
+ &ast_context,
+ ident,
+ resolved,
+ )
resolved.name = ident.name
if resolved.type == .Variable {
resolved.pkg = ast_context.document_package
}
- hover.contents = write_hover_content(&ast_context, resolved)
+ hover.contents = write_hover_content(
+ &ast_context,
+ resolved,
+ )
return hover, true, true
}
}
}
selector: Symbol
- selector, ok = resolve_type_expression(&ast_context, position_context.selector)
+ selector, ok = resolve_type_expression(
+ &ast_context,
+ position_context.selector,
+ )
if !ok {
return hover, false, true
@@ -138,20 +198,33 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
case SymbolStructValue:
for name, i in v.names {
if name == field {
- if symbol, ok := resolve_type_expression(&ast_context, v.types[i]); ok {
+ if symbol, ok := resolve_type_expression(
+ &ast_context,
+ v.types[i],
+ ); ok {
symbol.name = name //TODO refractor - never set symbol name after creation - change writer_hover_content
symbol.pkg = selector.name
symbol.signature = common.node_to_string(v.types[i])
- hover.contents = write_hover_content(&ast_context, symbol)
+ hover.contents = write_hover_content(
+ &ast_context,
+ symbol,
+ )
return hover, true, true
}
}
}
case SymbolPackageValue:
if position_context.field != nil {
- if ident, ok := position_context.field.derived.(^ast.Ident); ok {
- if symbol, ok := resolve_type_identifier(&ast_context, ident^); ok {
- hover.contents = write_hover_content(&ast_context, symbol)
+ if ident, ok := position_context.field.derived.(^ast.Ident);
+ ok {
+ if symbol, ok := resolve_type_identifier(
+ &ast_context,
+ ident^,
+ ); ok {
+ hover.contents = write_hover_content(
+ &ast_context,
+ symbol,
+ )
return hover, true, true
}
}
@@ -164,9 +237,12 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
ident := position_context.identifier.derived.(^ast.Ident)^
- hover.range = common.get_token_range(position_context.identifier^, document.ast.src)
+ hover.range = common.get_token_range(
+ position_context.identifier^,
+ document.ast.src,
+ )
- if resolved, ok := resolve_type_identifier(&ast_context, ident); ok {
+ if resolved, ok := resolve_type_identifier(&ast_context, ident); ok {
resolved.signature = get_signature(&ast_context, ident, resolved)
resolved.name = ident.name
diff --git a/src/server/indexer.odin b/src/server/indexer.odin
index 581bd37..7b7d071 100644
--- a/src/server/indexer.odin
+++ b/src/server/indexer.odin
@@ -9,7 +9,7 @@ import "core:slice"
Indexer :: struct {
builtin_packages: [dynamic]string,
- index: MemoryIndex,
+ index: MemoryIndex,
}
indexer: Indexer
@@ -19,7 +19,14 @@ FuzzyResult :: struct {
score: f32,
}
-lookup :: proc(name: string, pkg: string, loc := #caller_location) -> (Symbol, bool) {
+lookup :: proc(
+ name: string,
+ pkg: string,
+ loc := #caller_location,
+) -> (
+ Symbol,
+ bool,
+) {
if symbol, ok := memory_index_lookup(&indexer.index, name, pkg); ok {
return symbol, true
}
diff --git a/src/server/inlay_hints.odin b/src/server/inlay_hints.odin
index fb989db..59f3c86 100644
--- a/src/server/inlay_hints.odin
+++ b/src/server/inlay_hints.odin
@@ -1,14 +1,26 @@
-package server
+package server
import "core:odin/ast"
import "core:fmt"
import "shared:common"
-get_inlay_hints :: proc(document: ^Document, symbols: map[uintptr]SymbolAndNode) -> ([]InlayHint, bool) {
+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, document.fullpath)
+ ast_context := make_ast_context(
+ document.ast,
+ document.imports,
+ document.package_name,
+ document.uri.uri,
+ document.fullpath,
+ )
Visit_Data :: struct {
calls: [dynamic]^ast.Node,
@@ -33,7 +45,7 @@ get_inlay_hints :: proc(document: ^Document, symbols: map[uintptr]SymbolAndNode)
}
visitor := ast.Visitor {
- data = &data,
+ data = &data,
visit = visit,
}
@@ -53,7 +65,8 @@ get_inlay_hints :: proc(document: ^Document, symbols: map[uintptr]SymbolAndNode)
}
if symbol_and_node, ok := symbols[cast(uintptr)node_call]; ok {
- if symbol_call, ok := symbol_and_node.symbol.value.(SymbolProcedureValue); ok {
+ if symbol_call, ok := symbol_and_node.symbol.value.(SymbolProcedureValue);
+ ok {
for arg in symbol_call.arg_types {
for name in arg.names {
if symbol_arg_count >= len(call.args) {
@@ -62,12 +75,15 @@ get_inlay_hints :: proc(document: ^Document, symbols: map[uintptr]SymbolAndNode)
if ident, ok := name.derived.(^ast.Ident); ok {
hint := InlayHint {
- kind = "parameter",
+ kind = "parameter",
label = fmt.tprintf("%v = ", ident.name),
- range = common.get_token_range(call.args[symbol_arg_count], string(document.text)),
+ range = common.get_token_range(
+ call.args[symbol_arg_count],
+ string(document.text),
+ ),
}
append(&hints, hint)
- }
+ }
symbol_arg_count += 1
}
}
@@ -76,4 +92,4 @@ get_inlay_hints :: proc(document: ^Document, symbols: map[uintptr]SymbolAndNode)
}
return hints[:], true
-} \ No newline at end of file
+}
diff --git a/src/server/lens.odin b/src/server/lens.odin
index 5525554..99eaea3 100644
--- a/src/server/lens.odin
+++ b/src/server/lens.odin
@@ -15,13 +15,25 @@ CodeLensOptions :: struct {
}
CodeLens :: struct {
- range: common.Range,
+ range: common.Range,
command: Command,
- data: string,
+ data: string,
}
-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, document.fullpath)
+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,
+ document.fullpath,
+ )
get_globals(document.ast, &ast_context)
@@ -33,18 +45,16 @@ get_code_lenses :: proc(document: ^Document, position: common.Position) -> ([]Co
for name, global in ast_context.globals {
-
+
if proc_lit, ok := global.expr.derived.(^ast.Proc_Lit); ok {
-
}
}
-
+
return {}, false
}
-
diff --git a/src/server/log.odin b/src/server/log.odin
index c23270d..8660e88 100644
--- a/src/server/log.odin
+++ b/src/server/log.odin
@@ -6,29 +6,35 @@ import "core:os"
import "core:time"
import "core:log"
-Default_Console_Logger_Opts :: log.Options {
- .Level,
- .Terminal_Color,
- .Short_File_Path,
- .Line,
- .Procedure,
-} | log.Full_Timestamp_Opts
+Default_Console_Logger_Opts ::
+ log.Options{.Level, .Terminal_Color, .Short_File_Path, .Line, .Procedure} |
+ log.Full_Timestamp_Opts
Lsp_Logger_Data :: struct {
writer: ^Writer,
}
-create_lsp_logger :: proc(writer: ^Writer, lowest := log.Level.Debug, opt := Default_Console_Logger_Opts) -> log.Logger {
+create_lsp_logger :: proc(
+ writer: ^Writer,
+ lowest := log.Level.Debug,
+ opt := Default_Console_Logger_Opts,
+) -> log.Logger {
data := new(Lsp_Logger_Data)
data.writer = writer
- return log.Logger {lsp_logger_proc, data, lowest, opt}
+ return log.Logger{lsp_logger_proc, data, lowest, opt}
}
destroy_lsp_logger :: proc(log: ^log.Logger) {
free(log.data)
}
-lsp_logger_proc :: proc(logger_data: rawptr, level: log.Level, text: string, options: log.Options, location := #caller_location) {
+lsp_logger_proc :: proc(
+ logger_data: rawptr,
+ level: log.Level,
+ text: string,
+ options: log.Options,
+ location := #caller_location,
+) {
data := cast(^Lsp_Logger_Data)logger_data
@@ -36,16 +42,20 @@ lsp_logger_proc :: proc(logger_data: rawptr, level: log.Level, text: string, opt
message_type: DiagnosticSeverity
switch level {
- case .Debug: message_type = DiagnosticSeverity.Hint
- case .Info: message_type = DiagnosticSeverity.Information
- case .Warning: message_type = DiagnosticSeverity.Warning
- case .Error, .Fatal: message_type = DiagnosticSeverity.Error
+ case .Debug:
+ message_type = DiagnosticSeverity.Hint
+ case .Info:
+ message_type = DiagnosticSeverity.Information
+ case .Warning:
+ message_type = DiagnosticSeverity.Warning
+ case .Error, .Fatal:
+ message_type = DiagnosticSeverity.Error
}
-
+
notification := Notification {
jsonrpc = "2.0",
method = "window/logMessage",
- params = NotificationLoggingParams {
+ params = NotificationLoggingParams{
type = message_type,
message = message,
},
diff --git a/src/server/memory_index.odin b/src/server/memory_index.odin
index edb3dd6..3af9ea0 100644
--- a/src/server/memory_index.odin
+++ b/src/server/memory_index.odin
@@ -9,24 +9,29 @@ import "core:slice"
import "shared:common"
MemoryIndex :: struct {
- collection: SymbolCollection,
+ collection: SymbolCollection,
last_package_name: string,
- last_package: ^map[string]Symbol,
+ last_package: ^map[string]Symbol,
}
make_memory_index :: proc(collection: SymbolCollection) -> MemoryIndex {
- return MemoryIndex {
- collection = collection,
- }
+ return MemoryIndex{collection = collection}
}
-memory_index_lookup :: proc(index: ^MemoryIndex, name: string, pkg: string) -> (Symbol, bool) {
+memory_index_lookup :: proc(
+ index: ^MemoryIndex,
+ name: string,
+ pkg: string,
+) -> (
+ Symbol,
+ bool,
+) {
if index.last_package_name == pkg && index.last_package != nil {
return index.last_package[name]
}
if _pkg, ok := &index.collection.packages[pkg]; ok {
- index.last_package = _pkg
+ index.last_package = _pkg
index.last_package_name = pkg
return _pkg[name]
} else {
@@ -37,7 +42,14 @@ memory_index_lookup :: proc(index: ^MemoryIndex, name: string, pkg: string) -> (
return {}, false
}
-memory_index_fuzzy_search :: proc(index: ^MemoryIndex, name: string, pkgs: []string) -> ([]FuzzyResult, bool) {
+memory_index_fuzzy_search :: proc(
+ index: ^MemoryIndex,
+ name: string,
+ pkgs: []string,
+) -> (
+ []FuzzyResult,
+ bool,
+) {
symbols := make([dynamic]FuzzyResult, 0, context.temp_allocator)
fuzzy_matcher := common.make_fuzzy_matcher(name)
@@ -47,16 +59,17 @@ memory_index_fuzzy_search :: proc(index: ^MemoryIndex, name: string, pkgs: []str
for pkg in pkgs {
if pkg, ok := index.collection.packages[pkg]; ok {
for _, symbol in pkg {
- if score, ok := common.fuzzy_match(fuzzy_matcher, symbol.name); ok == 1 {
+ if score, ok := common.fuzzy_match(fuzzy_matcher, symbol.name);
+ ok == 1 {
result := FuzzyResult {
symbol = symbol,
- score = score,
+ score = score,
}
-
+
append(&symbols, result)
}
}
- }
+ }
}
slice.sort_by(symbols[:], proc(i, j: FuzzyResult) -> bool {
@@ -69,4 +82,3 @@ memory_index_fuzzy_search :: proc(index: ^MemoryIndex, name: string, pkgs: []str
return symbols[:min(top, len(symbols))], true
}
}
-
diff --git a/src/server/reader.odin b/src/server/reader.odin
index e704ad8..1a32b6f 100644
--- a/src/server/reader.odin
+++ b/src/server/reader.odin
@@ -12,7 +12,7 @@ Reader :: struct {
}
make_reader :: proc(reader_fn: ReaderFn, reader_context: rawptr) -> Reader {
- return Reader {reader_context = reader_context, reader_fn = reader_fn}
+ return Reader{reader_context = reader_context, reader_fn = reader_fn}
}
read_u8 :: proc(reader: ^Reader) -> (u8, bool) {
@@ -27,7 +27,11 @@ read_u8 :: proc(reader: ^Reader) -> (u8, bool) {
return value[0], true
}
-read_until_delimiter :: proc(reader: ^Reader, delimiter: u8, builder: ^strings.Builder) -> bool {
+read_until_delimiter :: proc(
+ reader: ^Reader,
+ delimiter: u8,
+ builder: ^strings.Builder,
+) -> bool {
for true {
value, success := read_u8(reader)
diff --git a/src/server/references.odin b/src/server/references.odin
index 11631b2..4b3a6d3 100644
--- a/src/server/references.odin
+++ b/src/server/references.odin
@@ -1,4 +1,4 @@
-package server
+package server
import "shared:common"
@@ -16,7 +16,13 @@ import "core:runtime"
fullpaths: [dynamic]string
-walk_directories :: proc(info: os.File_Info, in_err: os.Errno) -> (err: os.Errno, skip_dir: bool) {
+walk_directories :: proc(
+ info: os.File_Info,
+ in_err: os.Errno,
+) -> (
+ err: os.Errno,
+ skip_dir: bool,
+) {
if info.is_dir {
return 0, false
}
@@ -32,7 +38,10 @@ walk_directories :: proc(info: os.File_Info, in_err: os.Errno) -> (err: os.Errno
return 0, false
}
-position_in_struct_names :: proc(position_context: ^DocumentPositionContext, type: ^ast.Struct_Type) -> bool {
+position_in_struct_names :: proc(
+ position_context: ^DocumentPositionContext,
+ type: ^ast.Struct_Type,
+) -> bool {
for field in type.fields.list {
for name in field.names {
if position_in_node(name, position_context.position) {
@@ -45,7 +54,13 @@ position_in_struct_names :: proc(position_context: ^DocumentPositionContext, typ
}
-resolve_references :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext) -> ([]common.Location, bool) {
+resolve_references :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+) -> (
+ []common.Location,
+ bool,
+) {
locations := make([dynamic]common.Location, 0, ast_context.allocator)
fullpaths = make([dynamic]string, 10, ast_context.allocator)
@@ -56,14 +71,21 @@ resolve_references :: proc(ast_context: ^AstContext, position_context: ^Document
pkg := ""
walker_arena: mem.Arena
- mem.arena_init(&walker_arena, make([]byte, mem.Megabyte*5))
-
+ mem.arena_init(&walker_arena, make([]byte, mem.Megabyte * 5))
+
{
context.temp_allocator = mem.arena_allocator(&walker_arena)
- filepath.walk(filepath.dir(os.args[0], context.allocator), walk_directories)
+ filepath.walk(
+ filepath.dir(os.args[0], context.allocator),
+ walk_directories,
+ )
}
- if position_context.struct_type != nil && position_in_struct_names(position_context, position_context.struct_type) {
+ if position_context.struct_type != nil &&
+ position_in_struct_names(
+ position_context,
+ position_context.struct_type,
+ ) {
return {}, true
} else if position_context.enum_type != nil {
return {}, true
@@ -88,19 +110,22 @@ resolve_references :: proc(ast_context: ^AstContext, position_context: ^Document
symbol, ok = resolve_location_identifier(ast_context, ident^)
location := common.Location {
- range = common.get_token_range(position_context.identifier^, string(ast_context.file.src)),
- uri = strings.clone(symbol.uri, ast_context.allocator),
+ range = common.get_token_range(
+ position_context.identifier^,
+ string(ast_context.file.src),
+ ),
+ uri = strings.clone(symbol.uri, ast_context.allocator),
}
append(&locations, location)
}
-
+
if !ok {
return {}, true
}
resolve_arena: mem.Arena
- mem.arena_init(&resolve_arena, make([]byte, mem.Megabyte*25))
+ mem.arena_init(&resolve_arena, make([]byte, mem.Megabyte * 25))
context.allocator = mem.arena_allocator(&resolve_arena)
@@ -131,8 +156,8 @@ resolve_references :: proc(ast_context: ^AstContext, position_context: ^Document
file := ast.File {
fullpath = fullpath,
- src = string(data),
- pkg = pkg,
+ src = string(data),
+ pkg = pkg,
}
ok = parser.parse_file(&p, &file)
@@ -148,7 +173,7 @@ resolve_references :: proc(ast_context: ^AstContext, position_context: ^Document
ast = file,
}
- document.uri = uri
+ document.uri = uri
document.text = transmute([]u8)file.src
document.used_text = len(file.src)
@@ -159,20 +184,33 @@ resolve_references :: proc(ast_context: ^AstContext, position_context: ^Document
in_pkg := false
for pkg in document.imports {
- if pkg.name == symbol.pkg || symbol.pkg == ast_context.document_package {
+ if pkg.name == symbol.pkg ||
+ symbol.pkg == ast_context.document_package {
in_pkg = true
}
}
if in_pkg {
- symbols_and_nodes := resolve_entire_file(&document, reference, resolve_flag, context.allocator)
+ symbols_and_nodes := resolve_entire_file(
+ &document,
+ reference,
+ resolve_flag,
+ context.allocator,
+ )
for k, v in symbols_and_nodes {
- if v.symbol.uri == symbol.uri && v.symbol.range == symbol.range {
+ if v.symbol.uri == symbol.uri &&
+ v.symbol.range == symbol.range {
location := common.Location {
- range = common.get_token_range(v.node^, string(document.text)),
- uri = strings.clone(v.symbol.uri, ast_context.allocator),
- }
+ range = common.get_token_range(
+ v.node^,
+ string(document.text),
+ ),
+ uri = strings.clone(
+ v.symbol.uri,
+ ast_context.allocator,
+ ),
+ }
append(&locations, location)
}
}
@@ -184,25 +222,47 @@ resolve_references :: proc(ast_context: ^AstContext, position_context: ^Document
return locations[:], true
}
-get_references :: proc(document: ^Document, position: common.Position) -> ([]common.Location, bool) {
- data := make([]byte, mem.Megabyte*55, runtime.default_allocator())
+get_references :: proc(
+ document: ^Document,
+ position: common.Position,
+) -> (
+ []common.Location,
+ bool,
+) {
+ data := make([]byte, mem.Megabyte * 55, runtime.default_allocator())
//defer delete(data)
-
+
arena: mem.Arena
mem.arena_init(&arena, data)
-
- context.allocator = mem.arena_allocator(&arena)
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, document.fullpath, context.allocator)
+ context.allocator = mem.arena_allocator(&arena)
- position_context, ok := get_document_position_context(document, position, .Hover)
+ ast_context := make_ast_context(
+ document.ast,
+ document.imports,
+ document.package_name,
+ document.uri.uri,
+ document.fullpath,
+ context.allocator,
+ )
+
+ position_context, ok := get_document_position_context(
+ document,
+ position,
+ .Hover,
+ )
get_globals(document.ast, &ast_context)
ast_context.current_package = ast_context.document_package
if position_context.function != nil {
- get_locals(document.ast, position_context.function, &ast_context, &position_context)
+ get_locals(
+ document.ast,
+ position_context.function,
+ &ast_context,
+ &position_context,
+ )
}
locations, ok2 := resolve_references(&ast_context, &position_context)
@@ -212,10 +272,10 @@ get_references :: proc(document: ^Document, position: common.Position) -> ([]com
for location in locations {
temp_location := common.Location {
range = location.range,
- uri = strings.clone(location.uri, context.temp_allocator),
+ uri = strings.clone(location.uri, context.temp_allocator),
}
append(&temp_locations, temp_location)
}
return temp_locations[:], ok2
-} \ No newline at end of file
+}
diff --git a/src/server/rename.odin b/src/server/rename.odin
index 45fad45..0ab27ab 100644
--- a/src/server/rename.odin
+++ b/src/server/rename.odin
@@ -1,11 +1,18 @@
-package server
+package server
import "shared:common"
import "core:log"
import "core:odin/ast"
-get_rename :: proc(document: ^Document, new_text: string, position: common.Position) -> (WorkspaceEdit, bool) {
+get_rename :: proc(
+ document: ^Document,
+ new_text: string,
+ position: common.Position,
+) -> (
+ WorkspaceEdit,
+ bool,
+) {
workspace: WorkspaceEdit
document_changes := make([dynamic]TextDocumentEdit, context.temp_allocator)
@@ -15,16 +22,13 @@ get_rename :: proc(document: ^Document, new_text: string, position: common.Posit
document_change := TextDocumentEdit {
edits = edits[:],
- textDocument = {
- uri = document.uri.uri,
- version = document.version,
- },
+ textDocument = {uri = document.uri.uri, version = document.version},
}
append(&document_changes, document_change)
workspace.documentChanges = document_changes[:]
-
+
return workspace, true
-} \ No newline at end of file
+}
diff --git a/src/server/requests.odin b/src/server/requests.odin
index 29e78c1..55052e0 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -57,20 +57,18 @@ RequestInfo :: struct {
}
-make_response_message :: proc (id: RequestId, params: ResponseParams) -> ResponseMessage {
- return ResponseMessage {
- jsonrpc = "2.0",
- id = id,
- result = params,
- }
+make_response_message :: proc(
+ id: RequestId,
+ params: ResponseParams,
+) -> ResponseMessage {
+ return ResponseMessage{jsonrpc = "2.0", id = id, result = params}
}
-make_response_message_error :: proc (id: RequestId, error: ResponseError) -> ResponseMessageError {
- return ResponseMessageError {
- jsonrpc = "2.0",
- id = id,
- error = error,
- }
+make_response_message_error :: proc(
+ id: RequestId,
+ error: ResponseError,
+) -> ResponseMessageError {
+ return ResponseMessageError{jsonrpc = "2.0", id = id, error = error}
}
RequestThreadData :: struct {
@@ -137,13 +135,13 @@ thread_request_main :: proc(data: rawptr) {
method := root["method"].(json.String)
if method == "$/cancelRequest" {
- append(&deletings, Request { id = id })
+ append(&deletings, Request{id = id})
json.destroy_value(root)
} else if method in notification_map {
- append(&requests, Request { value = root, is_notification = true})
+ append(&requests, Request{value = root, is_notification = true})
sync.sema_post(&requests_sempahore)
} else {
- append(&requests, Request { id = id, value = root})
+ append(&requests, Request{id = id, value = root})
sync.sema_post(&requests_sempahore)
}
@@ -153,11 +151,11 @@ thread_request_main :: proc(data: rawptr) {
}
}
-read_and_parse_header :: proc (reader: ^Reader) -> (Header, bool) {
+read_and_parse_header :: proc(reader: ^Reader) -> (Header, bool) {
header: Header
builder := strings.builder_make(context.temp_allocator)
-
+
found_content_length := false
for true {
@@ -186,7 +184,7 @@ read_and_parse_header :: proc (reader: ^Reader) -> (Header, bool) {
return header, false
}
- header_name := message[0:index]
+ header_name := message[0:index]
header_value := message[len(header_name) + 2:len(message) - 2]
if strings.compare(header_name, "Content-Length") == 0 {
@@ -216,7 +214,13 @@ read_and_parse_header :: proc (reader: ^Reader) -> (Header, bool) {
return header, found_content_length
}
-read_and_parse_body :: proc (reader: ^Reader, header: Header) -> (json.Value, bool) {
+read_and_parse_body :: proc(
+ reader: ^Reader,
+ header: Header,
+) -> (
+ json.Value,
+ bool,
+) {
value: json.Value
data := make([]u8, header.content_length, context.temp_allocator)
@@ -228,7 +232,11 @@ read_and_parse_body :: proc (reader: ^Reader, header: Header) -> (json.Value, bo
err: json.Error
- value, err = json.parse(data = data, allocator = context.allocator, parse_integers = true)
+ value, err = json.parse(
+ data = data,
+ allocator = context.allocator,
+ parse_integers = true,
+ )
if (err != json.Error.None) {
log.error("Failed to parse body")
@@ -238,39 +246,43 @@ read_and_parse_body :: proc (reader: ^Reader, header: Header) -> (json.Value, bo
return value, true
}
-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,
- "textDocument/documentSymbol" = request_document_symbols,
- "textDocument/semanticTokens/full" = request_semantic_token_full,
+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,
+ "textDocument/documentSymbol" = request_document_symbols,
+ "textDocument/semanticTokens/full" = request_semantic_token_full,
"textDocument/semanticTokens/range" = request_semantic_token_range,
- "textDocument/hover" = request_hover,
- "textDocument/formatting" = request_format_document,
- "odin/inlayHints" = request_inlay_hint,
- "textDocument/documentLink" = request_document_links,
- "textDocument/rename" = request_rename,
- "textDocument/references" = request_references,
+ "textDocument/hover" = request_hover,
+ "textDocument/formatting" = request_format_document,
+ "odin/inlayHints" = request_inlay_hint,
+ "textDocument/documentLink" = request_document_links,
+ "textDocument/rename" = request_rename,
+ "textDocument/references" = request_references,
}
-notification_map: map [string] bool = {
- "textDocument/didOpen" = true,
+notification_map: map[string]bool = {
+ "textDocument/didOpen" = true,
"textDocument/didChange" = true,
- "textDocument/didClose" = true,
- "textDocument/didSave" = true,
- "initialized" = true,
+ "textDocument/didClose" = true,
+ "textDocument/didSave" = true,
+ "initialized" = true,
}
-consume_requests :: proc (config: ^common.Config, writer: ^Writer) -> bool {
+consume_requests :: proc(config: ^common.Config, writer: ^Writer) -> bool {
temp_requests := make([dynamic]Request, 0, context.allocator)
defer delete(temp_requests)
@@ -278,14 +290,19 @@ consume_requests :: proc (config: ^common.Config, writer: ^Writer) -> bool {
for d in deletings {
delete_index := -1
- for request, i in requests {
+ for request, i in requests {
if request.id == d.id {
delete_index := i
break
}
- }
+ }
if delete_index != -1 {
- cancel(requests[delete_index].value, requests[delete_index].id, writer, config)
+ cancel(
+ requests[delete_index].value,
+ requests[delete_index].id,
+ writer,
+ config,
+ )
ordered_remove(&requests, delete_index)
}
}
@@ -304,9 +321,9 @@ consume_requests :: proc (config: ^common.Config, writer: ^Writer) -> bool {
json.destroy_value(request.value)
free_all(context.temp_allocator)
}
-
+
sync.mutex_lock(&requests_mutex)
-
+
for i := 0; i < request_index; i += 1 {
pop_front(&requests)
}
@@ -325,34 +342,44 @@ consume_requests :: proc (config: ^common.Config, writer: ^Writer) -> bool {
}
-cancel :: proc(value: json.Value, id: RequestId, writer: ^Writer, config: ^common.Config) {
- response := make_response_message(
- id = id,
- params = ResponseParams {},
- )
+cancel :: proc(
+ value: json.Value,
+ id: RequestId,
+ writer: ^Writer,
+ config: ^common.Config,
+) {
+ response := make_response_message(id = id, params = ResponseParams{})
json.destroy_value(value)
send_response(response, writer)
}
-call :: proc(value: json.Value, id: RequestId, writer: ^Writer, config: ^common.Config) {
+call :: proc(
+ value: json.Value,
+ id: RequestId,
+ writer: ^Writer,
+ config: ^common.Config,
+) {
root := value.(json.Object)
method := root["method"].(json.String)
diff: time.Duration
{
time.SCOPED_TICK_DURATION(&diff)
-
+
if fn, ok := call_map[method]; !ok {
- response := make_response_message_error(id = id, error = ResponseError {code = .MethodNotFound, message = ""})
+ response := make_response_message_error(
+ id = id,
+ error = ResponseError{code = .MethodNotFound, message = ""},
+ )
send_error(response, writer)
} else {
err := fn(root["params"], id, config, writer)
if err != .None {
response := make_response_message_error(
id = id,
- error = ResponseError {code = err, message = ""},
+ error = ResponseError{code = err, message = ""},
)
send_error(response, writer)
}
@@ -362,10 +389,15 @@ call :: proc(value: json.Value, id: RequestId, writer: ^Writer, config: ^common.
//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 {
+request_initialize :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
-
- if !ok {
+
+ if !ok {
return .ParseError
}
@@ -381,41 +413,77 @@ request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.C
append(&config.workspace_folders, s)
}
- read_ols_config :: proc(file: string, config: ^common.Config, uri: common.Uri) {
+ read_ols_config :: proc(
+ file: string,
+ config: ^common.Config,
+ uri: common.Uri,
+ ) {
if data, ok := os.read_entire_file(file, context.temp_allocator); ok {
- if value, err := json.parse(data = data, allocator = context.temp_allocator, parse_integers = true); err == .None {
- ols_config: OlsConfig
-
- if unmarshal(value, ols_config, context.temp_allocator) == nil {
+ if value, err := json.parse(
+ data = data,
+ allocator = context.temp_allocator,
+ parse_integers = true,
+ ); err == .None {
+ ols_config: OlsConfig
+
+ if unmarshal(value, ols_config, context.temp_allocator) ==
+ nil {
config.thread_count = ols_config.thread_pool_count
- config.enable_document_symbols = ols_config.enable_document_symbols.(bool) or_else true
- config.enable_hover = ols_config.enable_hover.(bool) or_else true
- config.enable_semantic_tokens = ols_config.enable_semantic_tokens
- config.enable_procedure_context = ols_config.enable_procedure_context
+ config.enable_document_symbols =
+ ols_config.enable_document_symbols.(bool) or_else true
+ config.enable_hover =
+ ols_config.enable_hover.(bool) or_else true
+ config.enable_semantic_tokens =
+ ols_config.enable_semantic_tokens
+ config.enable_procedure_context =
+ ols_config.enable_procedure_context
config.enable_snippets = ols_config.enable_snippets
config.enable_references = false
config.verbose = ols_config.verbose
config.file_log = ols_config.file_log
- config.odin_command = strings.clone(ols_config.odin_command, context.allocator)
- config.checker_args = strings.clone(ols_config.checker_args, context.allocator)
+ config.odin_command = strings.clone(
+ ols_config.odin_command,
+ context.allocator,
+ )
+ config.checker_args = strings.clone(
+ ols_config.checker_args,
+ context.allocator,
+ )
config.enable_inlay_hints = ols_config.enable_inlay_hints
config.enable_format = true
-
+
for p in ols_config.collections {
- forward_path, _ := filepath.to_slash(p.path, context.temp_allocator)
+ forward_path, _ := filepath.to_slash(
+ p.path,
+ context.temp_allocator,
+ )
//Support a basic use of '~'
when ODIN_OS != .Windows {
if forward_path[0] == '~' {
- home := os.get_env("HOME", context.temp_allocator)
- strings.replace(forward_path, "~", home, 1, context.temp_allocator)
+ home := os.get_env(
+ "HOME",
+ context.temp_allocator,
+ )
+ strings.replace(
+ forward_path,
+ "~",
+ home,
+ 1,
+ context.temp_allocator,
+ )
}
}
if filepath.is_abs(p.path) {
- config.collections[strings.clone(p.name)] = strings.clone(forward_path)
+ config.collections[strings.clone(p.name)] =
+ strings.clone(forward_path)
} else {
- config.collections[strings.clone(p.name)] = path.join(elems = {uri.path, forward_path}, allocator = context.allocator)
+ config.collections[strings.clone(p.name)] =
+ path.join(
+ elems = {uri.path, forward_path},
+ allocator = context.allocator,
+ )
}
}
@@ -439,7 +507,10 @@ request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.C
}
if uri, ok := common.parse_uri(project_uri, context.temp_allocator); ok {
- ols_config_path := path.join(elems = {uri.path, "ols.json"}, allocator = context.temp_allocator)
+ ols_config_path := path.join(
+ elems = {uri.path, "ols.json"},
+ allocator = context.temp_allocator,
+ )
read_ols_config(ols_config_path, config, uri)
}
@@ -452,18 +523,33 @@ request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.C
}
if "core" not_in config.collections && odin_core_env != "" {
- forward_path, _ := filepath.to_slash(odin_core_env, context.temp_allocator)
- config.collections["core"] = path.join(elems = {forward_path, "core"}, allocator = context.allocator)
+ forward_path, _ := filepath.to_slash(
+ odin_core_env,
+ context.temp_allocator,
+ )
+ config.collections["core"] = path.join(
+ elems = {forward_path, "core"},
+ allocator = context.allocator,
+ )
}
if "vendor" not_in config.collections && odin_core_env != "" {
- forward_path, _ := filepath.to_slash(odin_core_env, context.temp_allocator)
- config.collections["vendor"] = path.join(elems = {forward_path, "vendor"}, allocator = context.allocator)
+ forward_path, _ := filepath.to_slash(
+ odin_core_env,
+ context.temp_allocator,
+ )
+ config.collections["vendor"] = path.join(
+ elems = {forward_path, "vendor"},
+ allocator = context.allocator,
+ )
}
when ODIN_OS == .Windows {
for k, v in config.collections {
- forward, _ := filepath.to_slash(common.get_case_sensitive_path(v), context.temp_allocator)
+ forward, _ := filepath.to_slash(
+ common.get_case_sensitive_path(v),
+ context.temp_allocator,
+ )
config.collections[k] = strings.clone(forward, context.allocator)
}
}
@@ -480,24 +566,37 @@ request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.C
}
}
- config.enable_snippets &= initialize_params.capabilities.textDocument.completion.completionItem.snippetSupport
- config.signature_offset_support = initialize_params.capabilities.textDocument.signatureHelp.signatureInformation.parameterInformation.labelOffsetSupport
+ config.enable_snippets &=
+ initialize_params.capabilities.textDocument.completion.completionItem.snippetSupport
+ config.signature_offset_support =
+ initialize_params.capabilities.textDocument.signatureHelp.signatureInformation.parameterInformation.labelOffsetSupport
- completionTriggerCharacters := []string {".", ">", "#", "\"", "/", ":"}
- signatureTriggerCharacters := []string {"(", ","}
- signatureRetriggerCharacters := []string {","}
+ completionTriggerCharacters := []string{".", ">", "#", "\"", "/", ":"}
+ signatureTriggerCharacters := []string{"(", ","}
+ signatureRetriggerCharacters := []string{","}
- 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_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), context.temp_allocator)
- token_modifiers := make([]string, len(token_modifier.names), context.temp_allocator)
+ 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 {
- if name == "EnumMember" {
+ if name == "EnumMember" {
token_types[i] = "enumMember"
- }
- else {
+ } else {
token_types[i] = strings.to_lower(name, context.temp_allocator)
}
}
@@ -507,43 +606,41 @@ request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.C
}
response := make_response_message(
- params = ResponseInitializeParams {
- capabilities = ServerCapabilities {
- textDocumentSync = TextDocumentSyncOptions {
- openClose = true,
- change = 2, //incremental
- save = {
- includeText = true,
+ params = ResponseInitializeParams{
+ capabilities = ServerCapabilities{
+ textDocumentSync = TextDocumentSyncOptions{
+ openClose = true,
+ change = 2,
+ save = {includeText = true},
},
- },
- renameProvider = config.enable_rename,
- referencesProvider = config.enable_references,
- definitionProvider = true,
- completionProvider = CompletionOptions {
- resolveProvider = false,
- triggerCharacters = completionTriggerCharacters,
- },
- signatureHelpProvider = SignatureHelpOptions {
- triggerCharacters = signatureTriggerCharacters,
- retriggerCharacters = signatureRetriggerCharacters,
- },
- semanticTokensProvider = SemanticTokensOptions {
- range = config.enable_semantic_tokens,
- full = config.enable_semantic_tokens,
- legend = SemanticTokensLegend {
- tokenTypes = token_types,
- tokenModifiers = token_modifiers,
+ renameProvider = config.enable_rename,//incremental
+ referencesProvider = config.enable_references,
+ definitionProvider = true,
+ completionProvider = CompletionOptions{
+ resolveProvider = false,
+ triggerCharacters = completionTriggerCharacters,
},
- },
- inlayHintsProvider = config.enable_inlay_hints,
- documentSymbolProvider = config.enable_document_symbols,
- hoverProvider = config.enable_hover,
- documentFormattingProvider = config.enable_format,
- documentLinkProvider = {
- resolveProvider = false,
+ signatureHelpProvider = SignatureHelpOptions{
+ triggerCharacters = signatureTriggerCharacters,
+ retriggerCharacters = signatureRetriggerCharacters,
+ },
+ semanticTokensProvider = SemanticTokensOptions{
+ range = config.enable_semantic_tokens,
+ full = config.enable_semantic_tokens,
+ legend = SemanticTokensLegend{
+ tokenTypes = token_types,
+ tokenModifiers = token_modifiers,
+ },
+ },
+ inlayHintsProvider = config.enable_inlay_hints,
+ documentSymbolProvider = config.enable_document_symbols,
+ hoverProvider = config.enable_hover,
+ documentFormattingProvider = config.enable_format,
+ documentLinkProvider = {resolveProvider = false},
},
},
- }, id = id)
+ id = id,
+ )
send_response(response, writer)
@@ -562,11 +659,21 @@ request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.C
return .None
}
-request_initialized :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- return .None
+request_initialized :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
+ return .None
}
-request_shutdown :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_shutdown :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
response := make_response_message(params = nil, id = id)
send_response(response, writer)
@@ -574,7 +681,12 @@ request_shutdown :: proc (params: json.Value, id: RequestId, config: ^common.Con
return .None
}
-request_definition :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_definition :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -586,14 +698,17 @@ request_definition :: proc (params: json.Value, id: RequestId, config: ^common.C
if unmarshal(params, definition_params, context.temp_allocator) != nil {
return .ParseError
}
-
+
document := document_get(definition_params.textDocument.uri)
- if document == nil {
- return .InternalError
- }
+ if document == nil {
+ return .InternalError
+ }
- locations, ok2 := get_definition_location(document, definition_params.position)
+ locations, ok2 := get_definition_location(
+ document,
+ definition_params.position,
+ )
if !ok2 {
log.warn("Failed to get definition location")
@@ -610,7 +725,12 @@ request_definition :: proc (params: json.Value, id: RequestId, config: ^common.C
return .None
}
-request_completion :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_completion :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -626,12 +746,16 @@ request_completion :: proc (params: json.Value, id: RequestId, config: ^common.C
document := document_get(completition_params.textDocument.uri)
- if document == nil {
- return .InternalError
- }
+ if document == nil {
+ return .InternalError
+ }
list: CompletionList
- list, ok = get_completion_list(document, completition_params.position, completition_params.context_)
+ list, ok = get_completion_list(
+ document,
+ completition_params.position,
+ completition_params.context_,
+ )
if !ok {
return .InternalError
@@ -644,7 +768,12 @@ request_completion :: proc (params: json.Value, id: RequestId, config: ^common.C
return .None
}
-request_signature_help :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_signature_help :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -659,9 +788,9 @@ request_signature_help :: proc (params: json.Value, id: RequestId, config: ^comm
document := document_get(signature_params.textDocument.uri)
- if document == nil {
- return .InternalError
- }
+ if document == nil {
+ return .InternalError
+ }
help: SignatureHelp
help, ok = get_signature_information(document, signature_params.position)
@@ -682,7 +811,12 @@ request_signature_help :: proc (params: json.Value, id: RequestId, config: ^comm
return .None
}
-request_format_document :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_format_document :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -696,10 +830,10 @@ request_format_document :: proc (params: json.Value, id: RequestId, config: ^com
}
document := document_get(format_params.textDocument.uri)
-
- if document == nil {
- return .InternalError
- }
+
+ if document == nil {
+ return .InternalError
+ }
edit: []TextEdit
edit, ok = get_complete_format(document, config)
@@ -715,12 +849,22 @@ request_format_document :: proc (params: json.Value, id: RequestId, config: ^com
return .None
}
-notification_exit :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+notification_exit :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
config.running = false
return .None
}
-notification_did_open :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+notification_did_open :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -735,14 +879,24 @@ notification_did_open :: proc (params: json.Value, id: RequestId, config: ^commo
return .ParseError
}
- if n := document_open(open_params.textDocument.uri, open_params.textDocument.text, config, writer); n != .None {
+ if n := document_open(
+ open_params.textDocument.uri,
+ open_params.textDocument.text,
+ config,
+ writer,
+ ); n != .None {
return .InternalError
}
return .None
}
-notification_did_change :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+notification_did_change :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -755,12 +909,23 @@ notification_did_change :: proc (params: json.Value, id: RequestId, config: ^com
return .ParseError
}
- document_apply_changes(change_params.textDocument.uri, change_params.contentChanges, change_params.textDocument.version, config, writer)
+ document_apply_changes(
+ change_params.textDocument.uri,
+ change_params.contentChanges,
+ change_params.textDocument.version,
+ config,
+ writer,
+ )
return .None
}
-notification_did_close :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+notification_did_close :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -780,7 +945,12 @@ notification_did_close :: proc(params: json.Value, id: RequestId, config: ^commo
return .None
}
-notification_did_save :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+notification_did_save :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -795,7 +965,10 @@ notification_did_save :: proc (params: json.Value, id: RequestId, config: ^commo
uri: common.Uri
- if uri, ok = common.parse_uri(save_params.textDocument.uri, context.temp_allocator); !ok {
+ if uri, ok = common.parse_uri(
+ save_params.textDocument.uri,
+ context.temp_allocator,
+ ); !ok {
return .ParseError
}
@@ -808,9 +981,12 @@ notification_did_save :: proc (params: json.Value, id: RequestId, config: ^commo
}
when ODIN_OS == .Windows {
- correct := common.get_case_sensitive_path(fullpath, context.temp_allocator)
+ correct := common.get_case_sensitive_path(
+ fullpath,
+ context.temp_allocator,
+ )
fullpath, _ = filepath.to_slash(correct, context.temp_allocator)
- }
+ }
dir := filepath.base(filepath.dir(fullpath, context.temp_allocator))
@@ -825,8 +1001,8 @@ notification_did_save :: proc (params: json.Value, id: RequestId, config: ^commo
file := ast.File {
fullpath = fullpath,
- src = save_params.text,
- pkg = pkg,
+ src = save_params.text,
+ pkg = pkg,
}
ok = parser.parse_file(&p, &file)
@@ -836,27 +1012,36 @@ notification_did_save :: proc (params: json.Value, id: RequestId, config: ^commo
}
corrected_uri := common.create_uri(fullpath, context.temp_allocator)
-
+
for k, v in &indexer.index.collection.packages {
for k2, v2 in &v {
if corrected_uri.uri == v2.uri {
free_symbol(v2, indexer.index.collection.allocator)
v[k2] = {}
- }
+ }
}
}
- if ret := collect_symbols(&indexer.index.collection, file, corrected_uri.uri); ret != .None {
+ if ret := collect_symbols(
+ &indexer.index.collection,
+ file,
+ corrected_uri.uri,
+ ); ret != .None {
log.errorf("failed to collect symbols on save %v", ret)
}
-
+
check(uri, writer, config)
return .None
}
-request_semantic_token_full :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_semantic_token_full :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -871,17 +1056,13 @@ request_semantic_token_full :: proc (params: json.Value, id: RequestId, config:
document := document_get(semantic_params.textDocument.uri)
- if document == nil {
- return .InternalError
- }
+ if document == nil {
+ return .InternalError
+ }
range := common.Range {
- start = common.Position {
- line = 0,
- },
- end = common.Position {
- line = 9000000, //should be enough
- },
+ start = common.Position{line = 0},
+ end = common.Position{line = 9000000}, //should be enough
}
symbols: SemanticTokens
@@ -901,7 +1082,12 @@ request_semantic_token_full :: proc (params: json.Value, id: RequestId, config:
return .None
}
-request_semantic_token_range :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_semantic_token_range :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -916,15 +1102,19 @@ request_semantic_token_range :: proc (params: json.Value, id: RequestId, config:
document := document_get(semantic_params.textDocument.uri)
- if document == nil {
- return .InternalError
- }
+ if document == nil {
+ return .InternalError
+ }
symbols: SemanticTokens
if config.enable_semantic_tokens {
if file, ok := file_resolve_cache.files[document.uri.uri]; ok {
- symbols = get_semantic_tokens(document, semantic_params.range, file.symbols)
+ symbols = get_semantic_tokens(
+ document,
+ semantic_params.range,
+ file.symbols,
+ )
}
}
@@ -935,7 +1125,12 @@ request_semantic_token_range :: proc (params: json.Value, id: RequestId, config:
return .None
}
-request_document_symbols :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_document_symbols :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -950,9 +1145,9 @@ request_document_symbols :: proc (params: json.Value, id: RequestId, config: ^co
document := document_get(symbol_params.textDocument.uri)
- if document == nil {
- return .InternalError
- }
+ if document == nil {
+ return .InternalError
+ }
symbols := get_document_symbols(document)
@@ -963,7 +1158,12 @@ request_document_symbols :: proc (params: json.Value, id: RequestId, config: ^co
return .None
}
-request_hover :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_hover :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -978,9 +1178,9 @@ request_hover :: proc (params: json.Value, id: RequestId, config: ^common.Config
document := document_get(hover_params.textDocument.uri)
- if document == nil {
- return .InternalError
- }
+ if document == nil {
+ return .InternalError
+ }
hover: Hover
valid: bool
@@ -993,8 +1193,7 @@ request_hover :: proc (params: json.Value, id: RequestId, config: ^common.Config
if valid {
response := make_response_message(params = hover, id = id)
send_response(response, writer)
- }
- else {
+ } else {
response := make_response_message(params = nil, id = id)
send_response(response, writer)
}
@@ -1002,7 +1201,12 @@ request_hover :: proc (params: json.Value, id: RequestId, config: ^common.Config
return .None
}
-request_inlay_hint :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_inlay_hint :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -1017,9 +1221,9 @@ request_inlay_hint :: proc (params: json.Value, id: RequestId, config: ^common.C
document := document_get(inlay_params.textDocument.uri)
- if document == nil {
- return .InternalError
- }
+ if document == nil {
+ return .InternalError
+ }
hints: []InlayHint
@@ -1040,7 +1244,12 @@ request_inlay_hint :: proc (params: json.Value, id: RequestId, config: ^common.C
return .None
}
-request_document_links :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_document_links :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -1055,9 +1264,9 @@ request_document_links :: proc (params: json.Value, id: RequestId, config: ^comm
document := document_get(link_params.textDocument.uri)
- if document == nil {
- return .InternalError
- }
+ if document == nil {
+ return .InternalError
+ }
links: []DocumentLink
links, ok = get_document_links(document)
@@ -1073,7 +1282,12 @@ request_document_links :: proc (params: json.Value, id: RequestId, config: ^comm
return .None
}
-request_rename :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_rename :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -1088,12 +1302,16 @@ request_rename :: proc (params: json.Value, id: RequestId, config: ^common.Confi
document := document_get(rename_param.textDocument.uri)
- if document == nil {
- return .InternalError
- }
+ if document == nil {
+ return .InternalError
+ }
workspace_edit: WorkspaceEdit
- workspace_edit, ok = get_rename(document, rename_param.newName, rename_param.position)
+ workspace_edit, ok = get_rename(
+ document,
+ rename_param.newName,
+ rename_param.position,
+ )
if !ok {
return .InternalError
@@ -1106,7 +1324,12 @@ request_rename :: proc (params: json.Value, id: RequestId, config: ^common.Confi
return .None
}
-request_references :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+request_references :: proc(
+ params: json.Value,
+ id: RequestId,
+ config: ^common.Config,
+ writer: ^Writer,
+) -> common.Error {
params_object, ok := params.(json.Object)
if !ok {
@@ -1121,9 +1344,9 @@ request_references :: proc (params: json.Value, id: RequestId, config: ^common.C
document := document_get(reference_param.textDocument.uri)
- if document == nil {
- return .InternalError
- }
+ if document == nil {
+ return .InternalError
+ }
locations: []common.Location
locations, ok = get_references(document, reference_param.position)
diff --git a/src/server/response.odin b/src/server/response.odin
index e42f9ae..d31b3cd 100644
--- a/src/server/response.odin
+++ b/src/server/response.odin
@@ -3,7 +3,10 @@ package server
import "core:fmt"
import "core:encoding/json"
-send_notification :: proc (notification: Notification, writer: ^Writer) -> bool {
+send_notification :: proc(
+ notification: Notification,
+ writer: ^Writer,
+) -> bool {
data, error := json.marshal(notification, {}, context.temp_allocator)
header := fmt.tprintf("Content-Length: %v\r\n\r\n", len(data))
@@ -23,7 +26,7 @@ send_notification :: proc (notification: Notification, writer: ^Writer) -> bool
return true
}
-send_response :: proc (response: ResponseMessage, writer: ^Writer) -> bool {
+send_response :: proc(response: ResponseMessage, writer: ^Writer) -> bool {
data, error := json.marshal(response, {}, context.temp_allocator)
header := fmt.tprintf("Content-Length: %v\r\n\r\n", len(data))
@@ -43,7 +46,7 @@ send_response :: proc (response: ResponseMessage, writer: ^Writer) -> bool {
return true
}
-send_error :: proc (response: ResponseMessageError, writer: ^Writer) -> bool {
+send_error :: proc(response: ResponseMessageError, writer: ^Writer) -> bool {
data, error := json.marshal(response, {}, context.temp_allocator)
header := fmt.tprintf("Content-Length: %v\r\n\r\n", len(data))
diff --git a/src/server/semantic_tokens.odin b/src/server/semantic_tokens.odin
index b936419..b22d53f 100644
--- a/src/server/semantic_tokens.odin
+++ b/src/server/semantic_tokens.odin
@@ -32,15 +32,15 @@ SemanticTokenTypes :: enum {
Method,
}
-SemanticTokenModifiers :: enum(u32) {
- None = 0,
+SemanticTokenModifiers :: enum (u32) {
+ None = 0,
Declaration = 2,
- Definition = 4,
- Deprecated = 8,
+ Definition = 4,
+ Deprecated = 8,
}
SemanticTokensClientCapabilities :: struct {
- requests: struct {
+ requests: struct {
range: bool,
},
tokenTypes: []string,
@@ -81,33 +81,48 @@ SemanticTokenBuilder :: struct {
selector: bool,
}
-make_token_builder :: proc(allocator := context.temp_allocator) -> SemanticTokenBuilder {
- return {
- tokens = make([dynamic]u32, 1000, context.temp_allocator),
- }
+make_token_builder :: proc(
+ allocator := context.temp_allocator,
+) -> SemanticTokenBuilder {
+ return {tokens = make([dynamic]u32, 1000, context.temp_allocator)}
}
get_tokens :: proc(builder: SemanticTokenBuilder) -> SemanticTokens {
- return {
- data = builder.tokens[:],
- }
+ return {data = builder.tokens[:]}
}
-get_semantic_tokens :: proc(document: ^Document, range: common.Range, symbols: map[uintptr]SymbolAndNode) -> SemanticTokens {
+get_semantic_tokens :: proc(
+ document: ^Document,
+ range: common.Range,
+ symbols: map[uintptr]SymbolAndNode,
+) -> SemanticTokens {
builder := make_token_builder()
if document.ast.pkg_decl != nil {
- write_semantic_token(&builder, document.ast.pkg_token, document.ast.src, .Keyword, .None)
+ 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, document.fullpath)
+ ast_context := make_ast_context(
+ document.ast,
+ document.imports,
+ document.package_name,
+ document.uri.uri,
+ document.fullpath,
+ )
builder.symbols = symbols
ast_context.current_package = ast_context.document_package
for decl in document.ast.decls {
- if range.start.line <= decl.pos.line && decl.end.line <= range.end.line {
+ if range.start.line <= decl.pos.line &&
+ decl.end.line <= range.end.line {
visit(decl, &builder, &ast_context)
}
}
@@ -115,22 +130,74 @@ get_semantic_tokens :: proc(document: ^Document, range: common.Range, symbols: m
return get_tokens(builder)
}
-write_semantic_node :: proc(builder: ^SemanticTokenBuilder, node: ^ast.Node, src: string, type: SemanticTokenTypes, modifier: SemanticTokenModifiers) {
- position := common.get_relative_token_position(node.pos.offset, transmute([]u8)src, builder.current_start)
+write_semantic_node :: proc(
+ builder: ^SemanticTokenBuilder,
+ node: ^ast.Node,
+ src: string,
+ type: SemanticTokenTypes,
+ modifier: SemanticTokenModifiers,
+) {
+ position := common.get_relative_token_position(
+ node.pos.offset,
+ transmute([]u8)src,
+ builder.current_start,
+ )
name := common.get_ast_node_string(node, src)
- append(&builder.tokens, cast(u32)position.line, cast(u32)position.character, cast(u32)len(name), cast(u32)type, cast(u32)modifier)
+ append(
+ &builder.tokens,
+ cast(u32)position.line,
+ cast(u32)position.character,
+ cast(u32)len(name),
+ cast(u32)type,
+ cast(u32)modifier,
+ )
builder.current_start = node.pos.offset
}
-write_semantic_token :: proc(builder: ^SemanticTokenBuilder, token: tokenizer.Token, src: string, type: SemanticTokenTypes, modifier: SemanticTokenModifiers) {
- position := common.get_relative_token_position(token.pos.offset, transmute([]u8)src, builder.current_start)
- append(&builder.tokens, cast(u32)position.line, cast(u32)position.character, cast(u32)len(token.text), cast(u32)type, cast(u32)modifier)
+write_semantic_token :: proc(
+ builder: ^SemanticTokenBuilder,
+ token: tokenizer.Token,
+ src: string,
+ type: SemanticTokenTypes,
+ modifier: SemanticTokenModifiers,
+) {
+ position := common.get_relative_token_position(
+ token.pos.offset,
+ transmute([]u8)src,
+ builder.current_start,
+ )
+ append(
+ &builder.tokens,
+ cast(u32)position.line,
+ cast(u32)position.character,
+ cast(u32)len(token.text),
+ cast(u32)type,
+ cast(u32)modifier,
+ )
builder.current_start = token.pos.offset
}
-write_semantic_string :: proc(builder: ^SemanticTokenBuilder, pos: tokenizer.Pos, name: string, src: string, type: SemanticTokenTypes, modifier: SemanticTokenModifiers) {
- position := common.get_relative_token_position(pos.offset, transmute([]u8)src, builder.current_start)
- append(&builder.tokens, cast(u32)position.line, cast(u32)position.character, cast(u32)len(name), cast(u32)type, cast(u32)modifier)
+write_semantic_string :: proc(
+ builder: ^SemanticTokenBuilder,
+ pos: tokenizer.Pos,
+ name: string,
+ src: string,
+ type: SemanticTokenTypes,
+ modifier: SemanticTokenModifiers,
+) {
+ position := common.get_relative_token_position(
+ pos.offset,
+ transmute([]u8)src,
+ builder.current_start,
+ )
+ append(
+ &builder.tokens,
+ cast(u32)position.line,
+ cast(u32)position.character,
+ cast(u32)len(name),
+ cast(u32)type,
+ cast(u32)modifier,
+ )
builder.current_start = pos.offset
}
@@ -141,23 +208,39 @@ visit :: proc {
visit_stmt,
}
-visit_array :: proc(array: $A/[]^$T, builder: ^SemanticTokenBuilder, ast_context: ^AstContext) {
+visit_array :: proc(
+ array: $A/[]^$T,
+ builder: ^SemanticTokenBuilder,
+ ast_context: ^AstContext,
+) {
for elem, i in array {
visit(elem, builder, ast_context)
}
}
-visit_dynamic_array :: proc(array: $A/[dynamic]^$T, builder: ^SemanticTokenBuilder, ast_context: ^AstContext) {
+visit_dynamic_array :: proc(
+ array: $A/[dynamic]^$T,
+ builder: ^SemanticTokenBuilder,
+ ast_context: ^AstContext,
+) {
for elem, i in array {
visit(elem, builder, ast_context)
}
}
-visit_stmt :: proc(node: ^ast.Stmt, builder: ^SemanticTokenBuilder, ast_context: ^AstContext) {
+visit_stmt :: proc(
+ node: ^ast.Stmt,
+ builder: ^SemanticTokenBuilder,
+ ast_context: ^AstContext,
+) {
visit_node(node, builder, ast_context)
}
-visit_node :: proc(node: ^ast.Node, builder: ^SemanticTokenBuilder, ast_context: ^AstContext) {
+visit_node :: proc(
+ node: ^ast.Node,
+ builder: ^SemanticTokenBuilder,
+ ast_context: ^AstContext,
+) {
using ast
if node == nil {
@@ -166,47 +249,123 @@ visit_node :: proc(node: ^ast.Node, builder: ^SemanticTokenBuilder, ast_context:
#partial switch n in node.derived {
case ^Ellipsis:
- write_semantic_string(builder, node.pos, "..", ast_context.file.src, .Operator, .None)
+ write_semantic_string(
+ builder,
+ node.pos,
+ "..",
+ ast_context.file.src,
+ .Operator,
+ .None,
+ )
visit(n.expr, builder, ast_context)
case ^Ident:
if symbol_and_node, ok := builder.symbols[cast(uintptr)node]; ok {
- if symbol_and_node.symbol.type == .Variable || symbol_and_node.symbol.type == .Constant {
- write_semantic_node(builder, node, ast_context.file.src, .Variable, .None)
+ if symbol_and_node.symbol.type == .Variable ||
+ symbol_and_node.symbol.type == .Constant {
+ write_semantic_node(
+ builder,
+ node,
+ ast_context.file.src,
+ .Variable,
+ .None,
+ )
return
- }
+ }
- #partial switch v in symbol_and_node.symbol.value {
+ #partial switch v in symbol_and_node.symbol.value {
case SymbolPackageValue:
- write_semantic_node(builder, node, ast_context.file.src, .Namespace, .None)
+ write_semantic_node(
+ builder,
+ node,
+ ast_context.file.src,
+ .Namespace,
+ .None,
+ )
case SymbolStructValue:
- write_semantic_node(builder, node, ast_context.file.src, .Struct, .None)
+ write_semantic_node(
+ builder,
+ node,
+ ast_context.file.src,
+ .Struct,
+ .None,
+ )
case SymbolEnumValue:
- write_semantic_node(builder, node, ast_context.file.src, .Enum, .None)
+ write_semantic_node(
+ builder,
+ node,
+ ast_context.file.src,
+ .Enum,
+ .None,
+ )
case SymbolUnionValue:
- write_semantic_node(builder, node, ast_context.file.src, .Enum, .None)
+ write_semantic_node(
+ builder,
+ node,
+ ast_context.file.src,
+ .Enum,
+ .None,
+ )
case SymbolProcedureValue:
- write_semantic_node(builder, node, ast_context.file.src, .Function, .None)
+ write_semantic_node(
+ builder,
+ node,
+ ast_context.file.src,
+ .Function,
+ .None,
+ )
case SymbolProcedureGroupValue:
- write_semantic_node(builder, node, ast_context.file.src, .Function, .None)
+ write_semantic_node(
+ builder,
+ node,
+ ast_context.file.src,
+ .Function,
+ .None,
+ )
case SymbolUntypedValue:
- write_semantic_node(builder, node, ast_context.file.src, .Type, .None)
+ write_semantic_node(
+ builder,
+ node,
+ ast_context.file.src,
+ .Type,
+ .None,
+ )
case SymbolBasicValue:
- write_semantic_node(builder, node, ast_context.file.src, .Type, .None)
+ write_semantic_node(
+ builder,
+ node,
+ ast_context.file.src,
+ .Type,
+ .None,
+ )
case:
- //log.errorf("Unexpected symbol value: %v", symbol.value);
- //panic(fmt.tprintf("Unexpected symbol value: %v", symbol.value));
+ //log.errorf("Unexpected symbol value: %v", symbol.value);
+ //panic(fmt.tprintf("Unexpected symbol value: %v", symbol.value));
}
}
case ^Selector_Expr:
visit_selector(cast(^Selector_Expr)node, builder, ast_context)
builder.selector = false
case ^When_Stmt:
- write_semantic_string(builder, n.when_pos, "when", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.when_pos,
+ "when",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.cond, builder, ast_context)
visit(n.body, builder, ast_context)
visit(n.else_stmt, builder, ast_context)
case ^Pointer_Type:
- write_semantic_string(builder, node.pos, "^", ast_context.file.src, .Operator, .None)
+ write_semantic_string(
+ builder,
+ node.pos,
+ "^",
+ ast_context.file.src,
+ .Operator,
+ .None,
+ )
visit(n.elem, builder, ast_context)
case ^Value_Decl:
visit_value_decl(n^, builder, ast_context)
@@ -215,52 +374,126 @@ visit_node :: proc(node: ^ast.Node, builder: ^SemanticTokenBuilder, ast_context:
case ^Expr_Stmt:
visit(n.expr, builder, ast_context)
case ^Branch_Stmt:
- write_semantic_token(builder, n.tok, ast_context.file.src, .Keyword, .None)
+ write_semantic_token(
+ builder,
+ n.tok,
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
case ^Poly_Type:
- write_semantic_string(builder, n.dollar, "$", ast_context.file.src, .Operator, .None)
+ write_semantic_string(
+ builder,
+ n.dollar,
+ "$",
+ ast_context.file.src,
+ .Operator,
+ .None,
+ )
visit(n.type, builder, ast_context)
visit(n.specialization, builder, ast_context)
case ^Range_Stmt:
- write_semantic_string(builder, n.for_pos, "for", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.for_pos,
+ "for",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
for val in n.vals {
if ident, ok := val.derived.(^Ident); ok {
- write_semantic_node(builder, val, ast_context.file.src, .Variable, .None)
+ write_semantic_node(
+ builder,
+ val,
+ ast_context.file.src,
+ .Variable,
+ .None,
+ )
}
}
- write_semantic_string(builder, n.in_pos, "in", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.in_pos,
+ "in",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.expr, builder, ast_context)
visit(n.body, builder, ast_context)
case ^If_Stmt:
- write_semantic_string(builder, n.if_pos, "if", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.if_pos,
+ "if",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.init, builder, ast_context)
visit(n.cond, builder, ast_context)
visit(n.body, builder, ast_context)
if n.else_stmt != nil {
- write_semantic_string(builder, n.else_pos, "else", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.else_pos,
+ "else",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.else_stmt, builder, ast_context)
}
case ^For_Stmt:
- write_semantic_string(builder, n.for_pos, "for", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.for_pos,
+ "for",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.init, builder, ast_context)
visit(n.cond, builder, ast_context)
visit(n.post, builder, ast_context)
visit(n.body, builder, ast_context)
case ^Switch_Stmt:
- write_semantic_string(builder, n.switch_pos, "switch", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.switch_pos,
+ "switch",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.init, builder, ast_context)
visit(n.cond, builder, ast_context)
visit(n.body, builder, ast_context)
case ^Type_Switch_Stmt:
- write_semantic_string(builder, n.switch_pos, "switch", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.switch_pos,
+ "switch",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.tag, builder, ast_context)
visit(n.expr, builder, ast_context)
visit(n.body, builder, ast_context)
case ^Assign_Stmt:
for l in n.lhs {
if ident, ok := l.derived.(^Ident); ok {
- write_semantic_node(builder, l, ast_context.file.src, .Variable, .None)
+ write_semantic_node(
+ builder,
+ l,
+ ast_context.file.src,
+ .Variable,
+ .None,
+ )
} else {
visit(l, builder, ast_context)
}
@@ -269,14 +502,27 @@ visit_node :: proc(node: ^ast.Node, builder: ^SemanticTokenBuilder, ast_context:
visit_token_op(builder, n.op, ast_context.file.src)
visit(n.rhs, builder, ast_context)
case ^Case_Clause:
- write_semantic_string(builder, n.case_pos, "case", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.case_pos,
+ "case",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.list, builder, ast_context)
visit(n.body, builder, ast_context)
case ^Call_Expr:
visit(n.expr, builder, ast_context)
visit(n.args, builder, ast_context)
case ^Implicit_Selector_Expr:
- write_semantic_node(builder, n.field, ast_context.file.src, .Enum, .None)
+ write_semantic_node(
+ builder,
+ n.field,
+ ast_context.file.src,
+ .EnumMember,
+ .None,
+ )
case ^Array_Type:
visit(n.elem, builder, ast_context)
case ^Binary_Expr:
@@ -287,13 +533,27 @@ visit_node :: proc(node: ^ast.Node, builder: ^SemanticTokenBuilder, ast_context:
visit(n.type, builder, ast_context)
visit(n.elems, builder, ast_context)
case ^Struct_Type:
- write_semantic_string(builder, n.pos, "struct", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.pos,
+ "struct",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit_struct_fields(n^, builder, ast_context)
case ^Type_Assertion:
visit(n.expr, builder, ast_context)
visit(n.type, builder, ast_context)
case ^Type_Cast:
- write_semantic_string(builder, n.pos, "cast", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.pos,
+ "cast",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.type, builder, ast_context)
visit(n.expr, builder, ast_context)
case ^Paren_Expr:
@@ -301,17 +561,44 @@ visit_node :: proc(node: ^ast.Node, builder: ^SemanticTokenBuilder, ast_context:
case ^Deref_Expr:
visit(n.expr, builder, ast_context)
case ^Return_Stmt:
- write_semantic_string(builder, n.pos, "return", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.pos,
+ "return",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.results, builder, ast_context)
case ^Dynamic_Array_Type:
- write_semantic_string(builder, n.dynamic_pos, "dynamic", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.dynamic_pos,
+ "dynamic",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.elem, builder, ast_context)
case ^Multi_Pointer_Type:
- write_semantic_string(builder, n.pos, "[^]", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.pos,
+ "[^]",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.elem, builder, ast_context)
case ^Field_Value:
if ident, ok := n.field.derived.(^Ident); ok {
- write_semantic_node(builder, n.field, ast_context.file.src, .Property, .None)
+ write_semantic_node(
+ builder,
+ n.field,
+ ast_context.file.src,
+ .Property,
+ .None,
+ )
}
visit(n.value, builder, ast_context)
@@ -326,29 +613,80 @@ visit_node :: proc(node: ^ast.Node, builder: ^SemanticTokenBuilder, ast_context:
case ^Slice_Expr:
visit(n.expr, builder, ast_context)
case ^Using_Stmt:
- write_semantic_string(builder, n.pos, "using", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.pos,
+ "using",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.list, builder, ast_context)
case ^Map_Type:
- write_semantic_string(builder, n.tok_pos, "map", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.tok_pos,
+ "map",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.key, builder, ast_context)
visit(n.value, builder, ast_context)
case ^Defer_Stmt:
- write_semantic_string(builder, n.pos, "defer", ast_context.file.src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ n.pos,
+ "defer",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.stmt, builder, ast_context)
case ^Import_Decl:
- write_semantic_token(builder, n.import_tok, ast_context.file.src, .Keyword, .None)
+ write_semantic_token(
+ builder,
+ n.import_tok,
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
if n.name.text != "" {
- write_semantic_token(builder, n.name, ast_context.file.src, .Namespace, .None)
+ write_semantic_token(
+ builder,
+ n.name,
+ ast_context.file.src,
+ .Namespace,
+ .None,
+ )
}
- write_semantic_token(builder, n.relpath, ast_context.file.src, .String, .None)
+ write_semantic_token(
+ builder,
+ n.relpath,
+ ast_context.file.src,
+ .String,
+ .None,
+ )
case ^Or_Return_Expr:
visit(n.expr, builder, ast_context)
- write_semantic_token(builder, n.token, ast_context.file.src, .Keyword, .None)
+ write_semantic_token(
+ builder,
+ n.token,
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
case ^Or_Else_Expr:
visit(n.x, builder, ast_context)
- write_semantic_token(builder, n.token, ast_context.file.src, .Keyword, .None)
+ write_semantic_token(
+ builder,
+ n.token,
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(n.y, builder, ast_context)
case ^Ternary_If_Expr:
if n.op1.text == "if" {
@@ -359,38 +697,70 @@ visit_node :: proc(node: ^ast.Node, builder: ^SemanticTokenBuilder, ast_context:
visit(n.cond, builder, ast_context)
visit(n.x, builder, ast_context)
visit(n.y, builder, ast_context)
- }
+ }
case ^Ternary_When_Expr:
visit(n.cond, builder, ast_context)
visit(n.x, builder, ast_context)
visit(n.y, builder, ast_context)
case:
- //log.errorf("unhandled semantic token node %v", n);
- //panic(fmt.tprintf("Missed semantic token handling %v", n));
+ //log.errorf("unhandled semantic token node %v", n);
+ //panic(fmt.tprintf("Missed semantic token handling %v", n));
}
}
-visit_basic_lit :: proc(basic_lit: ast.Basic_Lit, builder: ^SemanticTokenBuilder, ast_context: ^AstContext) {
+visit_basic_lit :: proc(
+ basic_lit: ast.Basic_Lit,
+ builder: ^SemanticTokenBuilder,
+ ast_context: ^AstContext,
+) {
if symbol, ok := resolve_basic_lit(ast_context, basic_lit); ok {
if untyped, ok := symbol.value.(SymbolUntypedValue); ok {
switch untyped.type {
case .Bool:
- write_semantic_token(builder, basic_lit.tok, ast_context.file.src, .Keyword, .None)
+ write_semantic_token(
+ builder,
+ basic_lit.tok,
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
case .Float, .Integer:
- write_semantic_token(builder, basic_lit.tok, ast_context.file.src, .Number, .None)
+ write_semantic_token(
+ builder,
+ basic_lit.tok,
+ ast_context.file.src,
+ .Number,
+ .None,
+ )
case .String:
- write_semantic_token(builder, basic_lit.tok, ast_context.file.src, .String, .None)
+ write_semantic_token(
+ builder,
+ basic_lit.tok,
+ ast_context.file.src,
+ .String,
+ .None,
+ )
}
}
}
}
-visit_value_decl :: proc(value_decl: ast.Value_Decl, builder: ^SemanticTokenBuilder, ast_context: ^AstContext) {
+visit_value_decl :: proc(
+ value_decl: ast.Value_Decl,
+ builder: ^SemanticTokenBuilder,
+ ast_context: ^AstContext,
+) {
using ast
if value_decl.type != nil {
for name in value_decl.names {
- write_semantic_node(builder, name, ast_context.file.src, .Variable, .None)
+ write_semantic_node(
+ builder,
+ name,
+ ast_context.file.src,
+ .Variable,
+ .None,
+ )
}
visit(value_decl.type, builder, ast_context)
@@ -401,41 +771,124 @@ visit_value_decl :: proc(value_decl: ast.Value_Decl, builder: ^SemanticTokenBuil
if len(value_decl.values) == 1 {
#partial switch v in value_decl.values[0].derived {
case ^Union_Type:
- write_semantic_node(builder, value_decl.names[0], ast_context.file.src, .Enum, .None)
- write_semantic_string(builder, v.pos, "union", ast_context.file.src, .Keyword, .None)
+ write_semantic_node(
+ builder,
+ value_decl.names[0],
+ ast_context.file.src,
+ .Enum,
+ .None,
+ )
+ write_semantic_string(
+ builder,
+ v.pos,
+ "union",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit(v.variants, builder, ast_context)
case ^Struct_Type:
- write_semantic_node(builder, value_decl.names[0], ast_context.file.src, .Struct, .None)
- write_semantic_string(builder, v.pos, "struct", ast_context.file.src, .Keyword, .None)
+ write_semantic_node(
+ builder,
+ value_decl.names[0],
+ ast_context.file.src,
+ .Struct,
+ .None,
+ )
+ write_semantic_string(
+ builder,
+ v.pos,
+ "struct",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit_struct_fields(v^, builder, ast_context)
case ^Enum_Type:
- write_semantic_node(builder, value_decl.names[0], ast_context.file.src, .Enum, .None)
- write_semantic_string(builder, v.pos, "enum", ast_context.file.src, .Keyword, .None)
+ write_semantic_node(
+ builder,
+ value_decl.names[0],
+ ast_context.file.src,
+ .Enum,
+ .None,
+ )
+ write_semantic_string(
+ builder,
+ v.pos,
+ "enum",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit_enum_fields(v^, builder, ast_context)
case ^Proc_Group:
- write_semantic_node(builder, value_decl.names[0], ast_context.file.src, .Function, .None)
- write_semantic_string(builder, v.pos, "proc", ast_context.file.src, .Keyword, .None)
+ write_semantic_node(
+ builder,
+ value_decl.names[0],
+ ast_context.file.src,
+ .Function,
+ .None,
+ )
+ write_semantic_string(
+ builder,
+ v.pos,
+ "proc",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
for arg in v.args {
if ident, ok := arg.derived.(^Ident); ok {
- write_semantic_node(builder, arg, ast_context.file.src, .Function, .None)
+ write_semantic_node(
+ builder,
+ arg,
+ ast_context.file.src,
+ .Function,
+ .None,
+ )
}
}
case ^Proc_Lit:
- write_semantic_node(builder, value_decl.names[0], ast_context.file.src, .Function, .None)
- write_semantic_string(builder, v.pos, "proc", ast_context.file.src, .Keyword, .None)
+ write_semantic_node(
+ builder,
+ value_decl.names[0],
+ ast_context.file.src,
+ .Function,
+ .None,
+ )
+ write_semantic_string(
+ builder,
+ v.pos,
+ "proc",
+ ast_context.file.src,
+ .Keyword,
+ .None,
+ )
visit_proc_type(v.type, builder, ast_context)
visit(v.body, builder, ast_context)
case:
for name in value_decl.names {
- write_semantic_node(builder, name, ast_context.file.src, .Variable, .None)
+ write_semantic_node(
+ builder,
+ name,
+ ast_context.file.src,
+ .Variable,
+ .None,
+ )
}
visit(value_decl.values[0], builder, ast_context)
}
} else {
for name in value_decl.names {
- write_semantic_node(builder, name, ast_context.file.src, .Variable, .None)
+ write_semantic_node(
+ builder,
+ name,
+ ast_context.file.src,
+ .Variable,
+ .None,
+ )
}
for value in value_decl.values {
@@ -444,15 +897,37 @@ visit_value_decl :: proc(value_decl: ast.Value_Decl, builder: ^SemanticTokenBuil
}
}
-visit_token_op :: proc(builder: ^SemanticTokenBuilder, token: tokenizer.Token, src: string) {
+visit_token_op :: proc(
+ builder: ^SemanticTokenBuilder,
+ token: tokenizer.Token,
+ src: string,
+) {
if token.text == "in" {
- write_semantic_string(builder, token.pos, token.text, src, .Keyword, .None)
+ write_semantic_string(
+ builder,
+ token.pos,
+ token.text,
+ src,
+ .Keyword,
+ .None,
+ )
} else {
- write_semantic_string(builder, token.pos, token.text, src, .Operator, .None)
+ write_semantic_string(
+ builder,
+ token.pos,
+ token.text,
+ src,
+ .Operator,
+ .None,
+ )
}
}
-visit_proc_type :: proc(node: ^ast.Proc_Type, builder: ^SemanticTokenBuilder, ast_context: ^AstContext) {
+visit_proc_type :: proc(
+ node: ^ast.Proc_Type,
+ builder: ^SemanticTokenBuilder,
+ ast_context: ^AstContext,
+) {
using ast
if node == nil {
@@ -463,7 +938,13 @@ visit_proc_type :: proc(node: ^ast.Proc_Type, builder: ^SemanticTokenBuilder, as
for param in node.params.list {
for name in param.names {
if ident, ok := name.derived.(^Ident); ok {
- write_semantic_node(builder, name, ast_context.file.src, .Parameter, .None)
+ write_semantic_node(
+ builder,
+ name,
+ ast_context.file.src,
+ .Parameter,
+ .None,
+ )
}
}
@@ -479,7 +960,11 @@ visit_proc_type :: proc(node: ^ast.Proc_Type, builder: ^SemanticTokenBuilder, as
}
}
-visit_enum_fields :: proc(node: ast.Enum_Type, builder: ^SemanticTokenBuilder, ast_context: ^AstContext) {
+visit_enum_fields :: proc(
+ node: ast.Enum_Type,
+ builder: ^SemanticTokenBuilder,
+ ast_context: ^AstContext,
+) {
using ast
if node.fields == nil {
@@ -488,18 +973,33 @@ visit_enum_fields :: proc(node: ast.Enum_Type, builder: ^SemanticTokenBuilder, a
for field in node.fields {
if ident, ok := field.derived.(^Ident); ok {
- write_semantic_node(builder, field, ast_context.file.src, .EnumMember, .None)
- }
- else if f, ok := field.derived.(^Field_Value); ok {
+ write_semantic_node(
+ builder,
+ field,
+ ast_context.file.src,
+ .EnumMember,
+ .None,
+ )
+ } else if f, ok := field.derived.(^Field_Value); ok {
if _, ok := f.field.derived.(^Ident); ok {
- write_semantic_node(builder, f.field, ast_context.file.src, .EnumMember, .None)
+ write_semantic_node(
+ builder,
+ f.field,
+ ast_context.file.src,
+ .EnumMember,
+ .None,
+ )
}
visit(f.value, builder, ast_context)
}
}
}
-visit_struct_fields :: proc(node: ast.Struct_Type, builder: ^SemanticTokenBuilder, ast_context: ^AstContext) {
+visit_struct_fields :: proc(
+ node: ast.Struct_Type,
+ builder: ^SemanticTokenBuilder,
+ ast_context: ^AstContext,
+) {
using ast
if node.fields == nil {
@@ -509,7 +1009,13 @@ visit_struct_fields :: proc(node: ast.Struct_Type, builder: ^SemanticTokenBuilde
for field in node.fields.list {
for name in field.names {
if ident, ok := name.derived.(^Ident); ok {
- write_semantic_node(builder, name, ast_context.file.src, .Property, .None)
+ write_semantic_node(
+ builder,
+ name,
+ ast_context.file.src,
+ .Property,
+ .None,
+ )
}
}
@@ -517,9 +1023,17 @@ visit_struct_fields :: proc(node: ast.Struct_Type, builder: ^SemanticTokenBuilde
}
}
-visit_selector :: proc(selector: ^ast.Selector_Expr, builder: ^SemanticTokenBuilder, ast_context: ^AstContext) {
+visit_selector :: proc(
+ selector: ^ast.Selector_Expr,
+ builder: ^SemanticTokenBuilder,
+ ast_context: ^AstContext,
+) {
if _, ok := selector.expr.derived.(^ast.Selector_Expr); ok {
- visit_selector(cast(^ast.Selector_Expr)selector.expr, builder, ast_context)
+ visit_selector(
+ cast(^ast.Selector_Expr)selector.expr,
+ builder,
+ ast_context,
+ )
} else {
visit(selector.expr, builder, ast_context)
builder.selector = true
@@ -527,21 +1041,63 @@ visit_selector :: proc(selector: ^ast.Selector_Expr, builder: ^SemanticTokenBuil
if symbol_and_node, ok := builder.symbols[cast(uintptr)selector]; ok {
if symbol_and_node.symbol.type == .Variable {
- write_semantic_node(builder, selector.field, ast_context.file.src, .Property, .None)
+ write_semantic_node(
+ builder,
+ selector.field,
+ ast_context.file.src,
+ .Property,
+ .None,
+ )
}
- #partial switch v in symbol_and_node.symbol.value {
+ #partial switch v in symbol_and_node.symbol.value {
case SymbolPackageValue:
- write_semantic_node(builder, selector.field, ast_context.file.src, .Namespace, .None)
+ write_semantic_node(
+ builder,
+ selector.field,
+ ast_context.file.src,
+ .Namespace,
+ .None,
+ )
case SymbolStructValue:
- write_semantic_node(builder, selector.field, ast_context.file.src, .Struct, .None)
+ write_semantic_node(
+ builder,
+ selector.field,
+ ast_context.file.src,
+ .Struct,
+ .None,
+ )
case SymbolEnumValue:
- write_semantic_node(builder, selector.field, ast_context.file.src, .Enum, .None)
+ write_semantic_node(
+ builder,
+ selector.field,
+ ast_context.file.src,
+ .Enum,
+ .None,
+ )
case SymbolUnionValue:
- write_semantic_node(builder, selector.field, ast_context.file.src, .Enum, .None)
+ write_semantic_node(
+ builder,
+ selector.field,
+ ast_context.file.src,
+ .Enum,
+ .None,
+ )
case SymbolProcedureValue:
- write_semantic_node(builder, selector.field, ast_context.file.src, .Function, .None)
+ write_semantic_node(
+ builder,
+ selector.field,
+ ast_context.file.src,
+ .Function,
+ .None,
+ )
case SymbolProcedureGroupValue:
- write_semantic_node(builder, selector.field, ast_context.file.src, .Function, .None)
+ write_semantic_node(
+ builder,
+ selector.field,
+ ast_context.file.src,
+ .Function,
+ .None,
+ )
}
}
-} \ No newline at end of file
+}
diff --git a/src/server/signature.odin b/src/server/signature.odin
index 0036bf2..e5acfa9 100644
--- a/src/server/signature.odin
+++ b/src/server/signature.odin
@@ -52,7 +52,7 @@ ParameterInformation :: struct {
build_procedure_symbol_signature :: proc(symbol: ^Symbol) {
if value, ok := symbol.value.(SymbolProcedureValue); ok {
builder := strings.builder_make(context.temp_allocator)
-
+
strings.write_string(&builder, "proc")
strings.write_string(&builder, "(")
for arg, i in value.arg_types {
@@ -69,14 +69,14 @@ build_procedure_symbol_signature :: proc(symbol: ^Symbol) {
if len(value.return_types) > 1 {
strings.write_string(&builder, "(")
}
-
+
for arg, i in value.return_types {
strings.write_string(&builder, common.node_to_string(arg))
if i != len(value.return_types) - 1 {
strings.write_string(&builder, ", ")
}
}
-
+
if len(value.return_types) > 1 {
strings.write_string(&builder, ")")
}
@@ -90,7 +90,7 @@ build_procedure_symbol_signature :: proc(symbol: ^Symbol) {
seperate_proc_field_arguments :: proc(procedure: ^Symbol) {
if value, ok := &procedure.value.(SymbolProcedureValue); ok {
types := make([dynamic]^ast.Field, context.temp_allocator)
-
+
for arg, i in value.arg_types {
if len(arg.names) == 1 {
append(&types, arg)
@@ -98,7 +98,12 @@ seperate_proc_field_arguments :: proc(procedure: ^Symbol) {
}
for name in arg.names {
- field : ^ast.Field = new_type(ast.Field, {}, {}, context.temp_allocator)
+ field: ^ast.Field = new_type(
+ ast.Field,
+ {},
+ {},
+ context.temp_allocator,
+ )
field.names = make([]^ast.Expr, 1, context.temp_allocator)
field.names[0] = name
field.type = arg.type
@@ -110,12 +115,28 @@ seperate_proc_field_arguments :: proc(procedure: ^Symbol) {
}
}
-get_signature_information :: proc(document: ^Document, position: common.Position) -> (SignatureHelp, bool) {
+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, document.fullpath)
+ 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)
+ position_context, ok := get_document_position_context(
+ document,
+ position,
+ .SignatureHelp,
+ )
if !ok {
return signature_help, true
@@ -129,12 +150,17 @@ get_signature_information :: proc(document: ^Document, position: common.Position
get_globals(document.ast, &ast_context)
if position_context.function != nil {
- get_locals(document.ast, position_context.function, &ast_context, &position_context)
+ get_locals(
+ document.ast,
+ position_context.function,
+ &ast_context,
+ &position_context,
+ )
}
for comma, i in position_context.call_commas {
if position_context.position > comma {
- signature_help.activeParameter = i+1
+ signature_help.activeParameter = i + 1
} else if position_context.position == comma {
signature_help.activeParameter = i
}
@@ -144,20 +170,31 @@ get_signature_information :: proc(document: ^Document, position: common.Position
call, ok = resolve_type_expression(&ast_context, position_context.call)
if !ok {
- return signature_help, true
+ return signature_help, true
}
seperate_proc_field_arguments(&call)
- signature_information := make([dynamic]SignatureInformation, context.temp_allocator)
+ signature_information := make(
+ [dynamic]SignatureInformation,
+ context.temp_allocator,
+ )
if value, ok := call.value.(SymbolProcedureValue); ok {
- parameters := make([]ParameterInformation, len(value.arg_types), context.temp_allocator)
-
+ parameters := make(
+ []ParameterInformation,
+ len(value.arg_types),
+ context.temp_allocator,
+ )
+
for arg, i in value.arg_types {
if arg.type != nil {
- if _, is_ellipsis := arg.type.derived.(^ast.Ellipsis); is_ellipsis {
- signature_help.activeParameter = min(i, signature_help.activeParameter)
+ if _, is_ellipsis := arg.type.derived.(^ast.Ellipsis);
+ is_ellipsis {
+ signature_help.activeParameter = min(
+ i,
+ signature_help.activeParameter,
+ )
}
}
@@ -167,10 +204,14 @@ get_signature_information :: proc(document: ^Document, position: common.Position
build_procedure_symbol_signature(&call)
info := SignatureInformation {
- label = concatenate_symbol_information(&ast_context, call, false),
+ label = concatenate_symbol_information(
+ &ast_context,
+ call,
+ false,
+ ),
documentation = call.doc,
- parameters = parameters,
- }
+ parameters = parameters,
+ }
append(&signature_information, info)
} else if value, ok := call.value.(SymbolAggregateValue); ok {
//function overloaded procedures
@@ -178,12 +219,20 @@ get_signature_information :: proc(document: ^Document, position: common.Position
symbol := symbol
if value, ok := symbol.value.(SymbolProcedureValue); ok {
- parameters := make([]ParameterInformation, len(value.arg_types), context.temp_allocator)
+ parameters := make(
+ []ParameterInformation,
+ len(value.arg_types),
+ context.temp_allocator,
+ )
- for arg, i in value.arg_types {
+ for arg, i in value.arg_types {
if arg.type != nil {
- if _, is_ellipsis := arg.type.derived.(^ast.Ellipsis); is_ellipsis {
- signature_help.activeParameter = min(i, signature_help.activeParameter)
+ if _, is_ellipsis := arg.type.derived.(^ast.Ellipsis);
+ is_ellipsis {
+ signature_help.activeParameter = min(
+ i,
+ signature_help.activeParameter,
+ )
}
}
@@ -193,9 +242,13 @@ get_signature_information :: proc(document: ^Document, position: common.Position
build_procedure_symbol_signature(&symbol)
info := SignatureInformation {
- label = concatenate_symbol_information(&ast_context, symbol, false),
+ label = concatenate_symbol_information(
+ &ast_context,
+ symbol,
+ false,
+ ),
documentation = symbol.doc,
- }
+ }
append(&signature_information, info)
}
@@ -205,4 +258,4 @@ get_signature_information :: proc(document: ^Document, position: common.Position
signature_help.signatures = signature_information[:]
return signature_help, true
-} \ No newline at end of file
+}
diff --git a/src/server/snippets.odin b/src/server/snippets.odin
index 94cb919..c8144bb 100644
--- a/src/server/snippets.odin
+++ b/src/server/snippets.odin
@@ -7,6 +7,14 @@ Snippet_Info :: struct {
}
snippets: map[string]Snippet_Info = {
- "ff" = {insert = "fmt.printf(\"${1:text}\", ${0:args})", packages = []string{"fmt"}, detail = "printf"},
- "fl" = {insert = "fmt.println(\"${1:text}\")", packages = []string{"fmt"}, detail = "println"},
+ "ff" = {
+ insert = "fmt.printf(\"${1:text}\", ${0:args})",
+ packages = []string{"fmt"},
+ detail = "printf",
+ },
+ "fl" = {
+ insert = "fmt.println(\"${1:text}\")",
+ packages = []string{"fmt"},
+ detail = "println",
+ },
}
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 4b4eea7..f143e5c 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -12,7 +12,7 @@ import "shared:common"
SymbolAndNode :: struct {
symbol: Symbol,
- node: ^ast.Node,
+ node: ^ast.Node,
}
SymbolStructValue :: struct {
@@ -46,7 +46,7 @@ SymbolEnumValue :: struct {
SymbolUnionValue :: struct {
types: []^ast.Expr,
- poly: ^ast.Field_List,
+ poly: ^ast.Field_List,
}
SymbolDynamicArrayValue :: struct {
@@ -75,7 +75,12 @@ SymbolBitSetValue :: struct {
}
SymbolUntypedValue :: struct {
- type: enum {Integer, Float, String, Bool},
+ type: enum {
+ Integer,
+ Float,
+ String,
+ Bool,
+ },
}
SymbolMapValue :: struct {
@@ -122,16 +127,16 @@ SymbolFlag :: enum {
SymbolFlags :: bit_set[SymbolFlag]
Symbol :: struct {
- range: common.Range, //the range of the symbol in the file
- uri: string, //uri of the file the symbol resides
- pkg: string, //absolute directory path where the symbol resides
- name: string, //name of the symbol
- doc: string,
- signature: string, //type signature
- type: SymbolType,
- value: SymbolValue,
- pointers: int, //how many `^` are applied to the symbol
- flags: SymbolFlags,
+ range: common.Range, //the range of the symbol in the file
+ uri: string, //uri of the file the symbol resides
+ pkg: string, //absolute directory path where the symbol resides
+ name: string, //name of the symbol
+ doc: string,
+ signature: string, //type signature
+ type: SymbolType,
+ value: SymbolValue,
+ pointers: int, //how many `^` are applied to the symbol
+ flags: SymbolFlags,
}
SymbolType :: enum {
@@ -148,7 +153,10 @@ SymbolType :: enum {
Unresolved = 1, //Use text if not being able to resolve it.
}
-new_clone_symbol :: proc(data: Symbol, allocator := context.allocator) -> (^Symbol) {
+new_clone_symbol :: proc(
+ data: Symbol,
+ allocator := context.allocator,
+) -> ^Symbol {
new_symbol := new(Symbol, allocator)
new_symbol^ = data
new_symbol.value = data.value
@@ -156,8 +164,10 @@ new_clone_symbol :: proc(data: Symbol, allocator := context.allocator) -> (^Symb
}
free_symbol :: proc(symbol: Symbol, allocator: mem.Allocator) {
- if symbol.signature != "" && symbol.signature != "struct" &&
- symbol.signature != "union" && symbol.signature != "enum" &&
+ if symbol.signature != "" &&
+ symbol.signature != "struct" &&
+ symbol.signature != "union" &&
+ symbol.signature != "enum" &&
symbol.signature != "bitset" {
delete(symbol.signature, allocator)
}
@@ -203,4 +213,4 @@ free_symbol :: proc(symbol: Symbol, allocator: mem.Allocator) {
common.free_ast(v.value, allocator)
case SymbolUntypedValue, SymbolPackageValue:
}
-} \ No newline at end of file
+}
diff --git a/src/server/types.odin b/src/server/types.odin
index dcc741a..80f13ad 100644
--- a/src/server/types.odin
+++ b/src/server/types.odin
@@ -119,7 +119,7 @@ HoverClientCapabilities :: struct {
}
DocumentSymbolClientCapabilities :: struct {
- symbolKind: struct {
+ symbolKind: struct {
valueSet: [dynamic]SymbolKind,
},
hierarchicalDocumentSymbolSupport: bool,
@@ -147,7 +147,7 @@ CompletionItemCapabilities :: struct {
CompletionClientCapabilities :: struct {
documentationFormat: [dynamic]string,
completionItem: CompletionItemCapabilities,
-}
+}
ParameterInformationCapabilities :: struct {
labelOffsetSupport: bool,
@@ -155,7 +155,7 @@ ParameterInformationCapabilities :: struct {
ClientCapabilities :: struct {
textDocument: TextDocumentClientCapabilities,
- general: GeneralClientCapabilities,
+ general: GeneralClientCapabilities,
}
RangeOptional :: union {
@@ -283,7 +283,7 @@ InsertTextFormat :: enum {
}
InsertTextMode :: enum {
- asIs = 1,
+ asIs = 1,
adjustIndentation = 2,
}
@@ -410,8 +410,8 @@ DocumentLinkParams :: struct {
}
DocumentLink :: struct {
- range: common.Range,
- target: string,
+ range: common.Range,
+ target: string,
tooltip: string,
}
@@ -424,9 +424,9 @@ PrepareSupportDefaultBehavior :: enum {
}
RenameClientCapabilities :: struct {
- prepareSupport: bool,
+ prepareSupport: bool,
prepareSupportDefaultBehavior: PrepareSupportDefaultBehavior,
- honorsChangeAnnotations: bool,
+ honorsChangeAnnotations: bool,
}
RenameParams :: struct {
@@ -447,10 +447,9 @@ OptionalVersionedTextDocumentIdentifier :: struct {
TextDocumentEdit :: struct {
textDocument: OptionalVersionedTextDocumentIdentifier,
- edits: []TextEdit,
+ edits: []TextEdit,
}
WorkspaceEdit :: struct {
documentChanges: []TextDocumentEdit,
}
-
diff --git a/src/server/unmarshal.odin b/src/server/unmarshal.odin
index 7aba429..bda15a7 100644
--- a/src/server/unmarshal.odin
+++ b/src/server/unmarshal.odin
@@ -10,7 +10,11 @@ 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: mem.Allocator) -> json.Marshal_Error {
+unmarshal :: proc(
+ json_value: json.Value,
+ v: any,
+ allocator: mem.Allocator,
+) -> json.Marshal_Error {
using runtime
@@ -29,11 +33,18 @@ unmarshal :: proc(json_value: json.Value, v: any, allocator: mem.Allocator) -> j
#partial switch variant in type_info.variant {
case Type_Info_Struct:
for field, i in variant.names {
- a := any {rawptr(uintptr(v.data) + uintptr(variant.offsets[i])), variant.types[i].id}
+ a := any{
+ rawptr(uintptr(v.data) + uintptr(variant.offsets[i])),
+ variant.types[i].id,
+ }
//TEMP most likely have to rewrite the entire unmarshal using tags instead, because i sometimes have to support names like 'context', which can't be written like that
- if field[len(field)-1] == '_' {
- if ret := unmarshal(j[field[:len(field)-1]], a, allocator); ret != nil {
+ if field[len(field) - 1] == '_' {
+ if ret := unmarshal(
+ j[field[:len(field) - 1]],
+ a,
+ allocator,
+ ); ret != nil {
return ret
}
} else {
@@ -47,31 +58,44 @@ unmarshal :: proc(json_value: json.Value, v: any, allocator: mem.Allocator) -> j
case Type_Info_Union:
tag_ptr := uintptr(v.data) + variant.tag_offset
- tag_any := any {rawptr(tag_ptr), variant.tag_type.id}
+ tag_any := any{rawptr(tag_ptr), variant.tag_type.id}
not_optional := 1
- mem.copy(cast(rawptr)tag_ptr, &not_optional, size_of(variant.tag_type))
+ mem.copy(
+ cast(rawptr)tag_ptr,
+ &not_optional,
+ size_of(variant.tag_type),
+ )
id := variant.variants[0].id
- unmarshal(json_value, any {v.data, id}, allocator)
+ unmarshal(json_value, any{v.data, id}, allocator)
}
case json.Array:
#partial switch variant in type_info.variant {
case Type_Info_Dynamic_Array:
array := (^mem.Raw_Dynamic_Array)(v.data)
if array.data == nil {
- array.data = mem.alloc(len(j) * variant.elem_size, variant.elem.align, allocator)
- array.len = len(j)
- array.cap = len(j)
+ array.data = mem.alloc(
+ len(j) * variant.elem_size,
+ variant.elem.align,
+ allocator,
+ )
+ array.len = len(j)
+ array.cap = len(j)
array.allocator = allocator
} else {
return .Unsupported_Type
}
- for i in 0..<array.len {
- a := any {rawptr(uintptr(array.data) + uintptr(variant.elem_size * i)), variant.elem.id}
+ for i in 0 ..< array.len {
+ a := any{
+ rawptr(
+ uintptr(array.data) + uintptr(variant.elem_size * i),
+ ),
+ variant.elem.id,
+ }
if ret := unmarshal(j[i], a, allocator); ret != nil {
return ret
@@ -91,7 +115,7 @@ unmarshal :: proc(json_value: json.Value, v: any, allocator: mem.Allocator) -> j
for name, i in variant.names {
lower_name := strings.to_lower(name, allocator)
- lower_j := strings.to_lower(string(j), allocator)
+ lower_j := strings.to_lower(string(j), allocator)
if lower_name == lower_j {
mem.copy(v.data, &variant.values[i], size_of(variant.base))
@@ -142,20 +166,24 @@ unmarshal :: proc(json_value: json.Value, v: any, allocator: mem.Allocator) -> j
case json.Null:
case json.Boolean:
#partial switch variant in &type_info.variant {
- case Type_Info_Boolean:
- tmp := bool(j)
- mem.copy(v.data, &tmp, type_info.size)
- case Type_Info_Union:
- tag_ptr := uintptr(v.data) + variant.tag_offset
- tag_any := any {rawptr(tag_ptr), variant.tag_type.id}
-
- not_optional := 1
-
- mem.copy(cast(rawptr)tag_ptr, &not_optional, size_of(variant.tag_type))
-
- id := variant.variants[0].id
-
- unmarshal(json_value, any {v.data, id}, allocator)
+ case Type_Info_Boolean:
+ tmp := bool(j)
+ mem.copy(v.data, &tmp, type_info.size)
+ case Type_Info_Union:
+ tag_ptr := uintptr(v.data) + variant.tag_offset
+ tag_any := any{rawptr(tag_ptr), variant.tag_type.id}
+
+ not_optional := 1
+
+ mem.copy(
+ cast(rawptr)tag_ptr,
+ &not_optional,
+ size_of(variant.tag_type),
+ )
+
+ id := variant.variants[0].id
+
+ unmarshal(json_value, any{v.data, id}, allocator)
}
case:
return .Unsupported_Type
diff --git a/src/server/writer.odin b/src/server/writer.odin
index bbd0cac..5c39f69 100644
--- a/src/server/writer.odin
+++ b/src/server/writer.odin
@@ -15,7 +15,10 @@ Writer :: struct {
}
make_writer :: proc(writer_fn: WriterFn, writer_context: rawptr) -> Writer {
- writer := Writer {writer_context = writer_context, writer_fn = writer_fn}
+ writer := Writer {
+ writer_context = writer_context,
+ writer_fn = writer_fn,
+ }
return writer
}
diff --git a/src/testing/testing.odin b/src/testing/testing.odin
index 5b0e30b..65694e6 100644
--- a/src/testing/testing.odin
+++ b/src/testing/testing.odin
@@ -12,13 +12,13 @@ import "shared:server"
import "shared:common"
Package :: struct {
- pkg: string,
- source: string,
+ pkg: string,
+ source: string,
}
Source :: struct {
main: string,
- packages: [] Package,
+ packages: []Package,
document: ^server.Document,
collections: map[string]string,
config: common.Config,
@@ -27,261 +27,360 @@ Source :: struct {
@(private)
setup :: proc(src: ^Source) {
- src.main = strings.clone(src.main);
- 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;
- src.document.used_text = len(src.document.text);
- src.document.allocator = new(common.Scratch_Allocator);
- src.document.package_name = "test";
-
- common.scratch_allocator_init(src.document.allocator, mem.Kilobyte * 200, context.temp_allocator);
+ src.main = strings.clone(src.main)
+ 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
+ src.document.used_text = len(src.document.text)
+ src.document.allocator = new(common.Scratch_Allocator)
+ src.document.package_name = "test"
+
+ common.scratch_allocator_init(
+ src.document.allocator,
+ mem.Kilobyte * 200,
+ context.temp_allocator,
+ )
//no unicode in tests currently
- current, last: u8;
- current_line, current_character: int;
+ current, last: u8
+ current_line, current_character: int
for current_index := 0; current_index < len(src.main); current_index += 1 {
- current = src.main[current_index];
+ current = src.main[current_index]
if last == '\r' {
- current_line += 1;
- current_character = 0;
+ current_line += 1
+ current_character = 0
} else if current == '\n' {
- current_line += 1;
- current_character = 0;
+ current_line += 1
+ current_character = 0
} else if current == '*' {
- dst_slice := transmute([]u8)src.main[current_index:];
- src_slice := transmute([]u8)src.main[current_index + 1:];
- copy(dst_slice, src_slice);
- src.position.character = current_character;
- src.position.line = current_line;
- break;
+ dst_slice := transmute([]u8)src.main[current_index:]
+ src_slice := transmute([]u8)src.main[current_index + 1:]
+ copy(dst_slice, src_slice)
+ src.position.character = current_character
+ src.position.line = current_line
+ break
} else {
- current_character += 1;
+ current_character += 1
}
- last = current;
+ last = current
}
server.setup_index()
-
+
server.document_setup(src.document)
- server.document_refresh(src.document, &src.config, nil);
-
+ server.document_refresh(src.document, &src.config, nil)
+
/*
There is a lot code here that is used in the real code, then i'd like to see.
*/
for src_pkg in src.packages {
- uri := common.create_uri(fmt.aprintf("test/%v/package.odin", src_pkg.pkg), context.temp_allocator);
+ uri := common.create_uri(
+ fmt.aprintf("test/%v/package.odin", src_pkg.pkg),
+ context.temp_allocator,
+ )
- fullpath := uri.path;
+ fullpath := uri.path
p := parser.Parser {
//err = parser.default_error_handler,
- err = server.log_error_handler,
+ err = server.log_error_handler,
warn = server.log_warning_handler,
- };
+ }
- dir := filepath.base(filepath.dir(fullpath, context.temp_allocator));
+ dir := filepath.base(filepath.dir(fullpath, context.temp_allocator))
- pkg := new(ast.Package);
- pkg.kind = .Normal;
- pkg.fullpath = fullpath;
- pkg.name = dir;
+ pkg := new(ast.Package)
+ pkg.kind = .Normal
+ pkg.fullpath = fullpath
+ pkg.name = dir
if dir == "runtime" {
- pkg.kind = .Runtime;
+ pkg.kind = .Runtime
}
-
+
file := ast.File {
fullpath = fullpath,
- src = src_pkg.source,
- pkg = pkg,
- };
+ src = src_pkg.source,
+ pkg = pkg,
+ }
- ok := parser.parse_file(&p, &file);
+ ok := parser.parse_file(&p, &file)
if !ok || file.syntax_error_count > 0 {
- panic("Parser error in test package source");
+ panic("Parser error in test package source")
}
- if ret := server.collect_symbols(&server.indexer.index.collection, file, uri.uri); ret != .None {
- return;
+ if ret := server.collect_symbols(
+ &server.indexer.index.collection,
+ file,
+ uri.uri,
+ );
+ ret != .None {
+ return
}
}
}
-@private
+@(private)
teardown :: proc(src: ^Source) {
server.free_index()
server.indexer.index = {}
}
-expect_signature_labels :: proc(t: ^testing.T, src: ^Source, expect_labels: []string) {
- setup(src);
- defer teardown(src);
+expect_signature_labels :: proc(
+ t: ^testing.T,
+ src: ^Source,
+ expect_labels: []string,
+) {
+ setup(src)
+ defer teardown(src)
- help, ok := server.get_signature_information(src.document, src.position);
+ help, ok := server.get_signature_information(src.document, src.position)
if !ok {
- testing.error(t, "Failed get_signature_information");
+ testing.error(t, "Failed get_signature_information")
}
if len(expect_labels) == 0 && len(help.signatures) > 0 {
- testing.errorf(t, "Expected empty signature label, but received %v", help.signatures);
+ testing.errorf(
+ t,
+ "Expected empty signature label, but received %v",
+ help.signatures,
+ )
}
- flags := make([]int, len(expect_labels));
+ flags := make([]int, len(expect_labels))
for expect_label, i in expect_labels {
for signature, j in help.signatures {
if expect_label == signature.label {
- flags[i] += 1;
+ flags[i] += 1
}
}
}
for flag, i in flags {
if flag != 1 {
- testing.errorf(t, "Expected signature label %v, but received %v", expect_labels[i], help.signatures);
+ testing.errorf(
+ t,
+ "Expected signature label %v, but received %v",
+ expect_labels[i],
+ help.signatures,
+ )
}
}
}
-expect_signature_parameter_position :: proc(t: ^testing.T, src: ^Source, position: int) {
- setup(src);
- defer teardown(src);
+expect_signature_parameter_position :: proc(
+ t: ^testing.T,
+ src: ^Source,
+ position: int,
+) {
+ setup(src)
+ defer teardown(src)
- help, ok := server.get_signature_information(src.document, src.position);
+ help, ok := server.get_signature_information(src.document, src.position)
if help.activeParameter != position {
- testing.errorf(t, "expected parameter position %v, but received %v", position, help.activeParameter);
+ testing.errorf(
+ t,
+ "expected parameter position %v, but received %v",
+ position,
+ help.activeParameter,
+ )
}
}
-expect_completion_labels :: proc(t: ^testing.T, src: ^Source, trigger_character: string, expect_labels: []string) {
- setup(src);
- defer teardown(src);
+expect_completion_labels :: proc(
+ t: ^testing.T,
+ src: ^Source,
+ trigger_character: string,
+ expect_labels: []string,
+) {
+ setup(src)
+ defer teardown(src)
completion_context := server.CompletionContext {
triggerCharacter = trigger_character,
- };
+ }
- completion_list, ok := server.get_completion_list(src.document, src.position, completion_context);
+ completion_list, ok := server.get_completion_list(
+ src.document,
+ src.position,
+ completion_context,
+ )
if !ok {
- testing.error(t, "Failed get_completion_list");
+ testing.error(t, "Failed get_completion_list")
}
if len(expect_labels) == 0 && len(completion_list.items) > 0 {
- testing.errorf(t, "Expected empty completion label, but received %v", completion_list.items);
+ testing.errorf(
+ t,
+ "Expected empty completion label, but received %v",
+ completion_list.items,
+ )
}
- flags := make([]int, len(expect_labels));
+ flags := make([]int, len(expect_labels))
for expect_label, i in expect_labels {
for completion, j in completion_list.items {
if expect_label == completion.label {
- flags[i] += 1;
+ flags[i] += 1
}
}
}
for flag, i in flags {
if flag != 1 {
- testing.errorf(t, "Expected completion detail %v, but received %v", expect_labels[i], completion_list.items);
+ testing.errorf(
+ t,
+ "Expected completion detail %v, but received %v",
+ expect_labels[i],
+ completion_list.items,
+ )
}
}
}
-expect_completion_details :: proc(t: ^testing.T, src: ^Source, trigger_character: string, expect_details: []string) {
- setup(src);
- defer teardown(src);
+expect_completion_details :: proc(
+ t: ^testing.T,
+ src: ^Source,
+ trigger_character: string,
+ expect_details: []string,
+) {
+ setup(src)
+ defer teardown(src)
completion_context := server.CompletionContext {
triggerCharacter = trigger_character,
- };
+ }
- completion_list, ok := server.get_completion_list(src.document, src.position, completion_context);
+ completion_list, ok := server.get_completion_list(
+ src.document,
+ src.position,
+ completion_context,
+ )
if !ok {
- testing.error(t, "Failed get_completion_list");
+ testing.error(t, "Failed get_completion_list")
}
if len(expect_details) == 0 && len(completion_list.items) > 0 {
- testing.errorf(t, "Expected empty completion label, but received %v", completion_list.items);
+ testing.errorf(
+ t,
+ "Expected empty completion label, but received %v",
+ completion_list.items,
+ )
}
- flags := make([]int, len(expect_details));
+ flags := make([]int, len(expect_details))
for expect_detail, i in expect_details {
for completion, j in completion_list.items {
if expect_detail == completion.detail {
- flags[i] += 1;
+ flags[i] += 1
}
}
}
for flag, i in flags {
if flag != 1 {
- testing.errorf(t, "Expected completion label %v, but received %v", expect_details[i], completion_list.items);
+ testing.errorf(
+ t,
+ "Expected completion label %v, but received %v",
+ expect_details[i],
+ completion_list.items,
+ )
}
}
}
-expect_hover :: proc(t: ^testing.T, src: ^Source, expect_hover_string: string) {
- setup(src);
- defer teardown(src);
+expect_hover :: proc(
+ t: ^testing.T,
+ src: ^Source,
+ expect_hover_string: string,
+) {
+ setup(src)
+ defer teardown(src)
- hover, _, ok := server.get_hover_information(src.document, src.position);
+ hover, _, ok := server.get_hover_information(src.document, src.position)
if !ok {
- testing.error(t, "Failed get_hover_information");
+ testing.error(t, "Failed get_hover_information")
}
if expect_hover_string == "" && hover.contents.value != "" {
- testing.errorf(t, "Expected empty hover string, but received %v", hover.contents.value);
+ testing.errorf(
+ t,
+ "Expected empty hover string, but received %v",
+ hover.contents.value,
+ )
}
if !strings.contains(hover.contents.value, expect_hover_string) {
- testing.errorf(t, "Expected hover string %v, but received %v", expect_hover_string, hover.contents.value);
+ testing.errorf(
+ t,
+ "Expected hover string %v, but received %v",
+ expect_hover_string,
+ hover.contents.value,
+ )
}
}
-expect_definition_locations :: proc(t: ^testing.T, src: ^Source, expect_locations: []common.Location) {
- setup(src);
- defer teardown(src);
+expect_definition_locations :: proc(
+ t: ^testing.T,
+ src: ^Source,
+ expect_locations: []common.Location,
+) {
+ setup(src)
+ defer teardown(src)
- locations, ok := server.get_definition_location(src.document, src.position);
+ locations, ok := server.get_definition_location(src.document, src.position)
if !ok {
- testing.error(t, "Failed get_definition_location");
+ testing.error(t, "Failed get_definition_location")
}
if len(expect_locations) == 0 && len(locations) > 0 {
- testing.errorf(t, "Expected empty locations, but received %v", locations);
+ testing.errorf(
+ t,
+ "Expected empty locations, but received %v",
+ locations,
+ )
}
- flags := make([]int, len(expect_locations));
+ flags := make([]int, len(expect_locations))
for expect_location, i in expect_locations {
for location, j in locations {
if location == expect_location {
- flags[i] += 1;
+ flags[i] += 1
}
}
}
for flag, i in flags {
if flag != 1 {
- testing.errorf(t, "Expected location %v, but received %v", expect_locations[i], locations);
+ testing.errorf(
+ t,
+ "Expected location %v, but received %v",
+ expect_locations[i],
+ locations,
+ )
}
}
}
diff --git a/tools/odinfmt/main.odin b/tools/odinfmt/main.odin
index 60e4f82..52ecdaa 100644
--- a/tools/odinfmt/main.odin
+++ b/tools/odinfmt/main.odin
@@ -23,134 +23,157 @@ print_help :: proc(args: []string) {
print_arg_error :: proc(args: []string, error: flag.Flag_Error) {
switch error {
case .None:
- print_help(args);
+ print_help(args)
case .No_Base_Struct:
- fmt.eprintln(args[0], "no base struct");
+ fmt.eprintln(args[0], "no base struct")
case .Arg_Error:
- fmt.eprintln(args[0], "argument error");
+ fmt.eprintln(args[0], "argument error")
case .Arg_Unsupported_Field_Type:
- fmt.eprintln(args[0], "argument: unsupported field type");
+ fmt.eprintln(args[0], "argument: unsupported field type")
case .Arg_Not_Defined:
- fmt.eprintln(args[0], "argument: no defined");
+ fmt.eprintln(args[0], "argument: no defined")
case .Arg_Non_Optional:
- fmt.eprintln(args[0], "argument: non optional");
+ fmt.eprintln(args[0], "argument: non optional")
case .Value_Parse_Error:
- fmt.eprintln(args[0], "argument: value parse error");
+ fmt.eprintln(args[0], "argument: value parse error")
case .Tag_Error:
- fmt.eprintln(args[0], "argument: tag error");
+ fmt.eprintln(args[0], "argument: tag error")
}
}
-format_file :: proc(filepath: string, config: printer.Config, allocator := context.allocator) -> (string, bool) {
+format_file :: proc(
+ filepath: string,
+ config: printer.Config,
+ allocator := context.allocator,
+) -> (
+ string,
+ bool,
+) {
if data, ok := os.read_entire_file(filepath, allocator); ok {
- return format.format(filepath, string(data), config, {.Optional_Semicolons}, allocator);
+ return format.format(
+ filepath,
+ string(data),
+ config,
+ {.Optional_Semicolons},
+ allocator,
+ )
} else {
- return "", false;
+ return "", false
}
}
-files: [dynamic]string;
+files: [dynamic]string
-walk_files :: proc(info: os.File_Info, in_err: os.Errno) -> (err: os.Errno, skip_dir: bool) {
+walk_files :: proc(
+ info: os.File_Info,
+ in_err: os.Errno,
+) -> (
+ err: os.Errno,
+ skip_dir: bool,
+) {
if info.is_dir {
- return 0, false;
+ return 0, false
}
if filepath.ext(info.name) != ".odin" {
- return 0, false;
+ return 0, false
}
- append(&files, strings.clone(info.fullpath));
+ append(&files, strings.clone(info.fullpath))
- return 0, false;
+ return 0, false
}
main :: proc() {
- arena: mem.Arena;
- mem.init_arena(&arena, make([]byte, 50 * mem.Megabyte));
+ arena: mem.Arena
+ mem.init_arena(&arena, make([]byte, 50 * mem.Megabyte))
- arena_allocator := mem.arena_allocator(&arena);
+ arena_allocator := mem.arena_allocator(&arena)
- init_global_temporary_allocator(mem.Megabyte*20) //enough space for the walk
+ init_global_temporary_allocator(mem.Megabyte * 20) //enough space for the walk
- args: Args;
+ args: Args
if len(os.args) < 2 {
- print_help(os.args);
- os.exit(1);
+ print_help(os.args)
+ os.exit(1)
}
if res := flag.parse(args, os.args[1:len(os.args) - 1]); res != .None {
- print_arg_error(os.args, res);
- os.exit(1);
+ print_arg_error(os.args, res)
+ os.exit(1)
}
- path := os.args[len(os.args) - 1];
+ path := os.args[len(os.args) - 1]
- tick_time := time.tick_now();
+ tick_time := time.tick_now()
- write_failure := false;
+ write_failure := false
watermark := 0
if os.is_file(path) {
- config := format.find_config_file_or_default(path);
+ config := format.find_config_file_or_default(path)
if _, ok := args.write.(bool); ok {
- backup_path := strings.concatenate({path, "_bk"});
- defer delete(backup_path);
+ backup_path := strings.concatenate({path, "_bk"})
+ defer delete(backup_path)
if data, ok := format_file(path, config, arena_allocator); ok {
- os.rename(path, backup_path);
+ os.rename(path, backup_path)
if os.write_entire_file(path, transmute([]byte)data) {
- os.remove(backup_path);
+ os.remove(backup_path)
}
} else {
- fmt.eprintf("Failed to write %v", path);
- write_failure = true;
+ fmt.eprintf("Failed to write %v", path)
+ write_failure = true
}
} else {
if data, ok := format_file(path, config, arena_allocator); ok {
- fmt.println(data);
+ fmt.println(data)
}
}
} else if os.is_dir(path) {
- config := format.find_config_file_or_default(path);
- filepath.walk(path, walk_files);
+ config := format.find_config_file_or_default(path)
+ filepath.walk(path, walk_files)
for file in files {
- fmt.println(file);
+ fmt.println(file)
- backup_path := strings.concatenate({file, "_bk"});
- defer delete(backup_path);
+ backup_path := strings.concatenate({file, "_bk"})
+ defer delete(backup_path)
if data, ok := format_file(file, config, arena_allocator); ok {
if _, ok := args.write.(bool); ok {
- os.rename(file, backup_path);
+ os.rename(file, backup_path)
if os.write_entire_file(file, transmute([]byte)data) {
- os.remove(backup_path);
+ os.remove(backup_path)
}
} else {
- fmt.println(data);
+ fmt.println(data)
}
} else {
- fmt.eprintf("Failed to format %v", file);
- write_failure = true;
+ fmt.eprintf("Failed to format %v", file)
+ write_failure = true
}
watermark = max(watermark, arena.offset)
- free_all(arena_allocator);
+ free_all(arena_allocator)
}
-
- fmt.printf("Formatted %v files in %vms \n", len(files), time.duration_milliseconds(time.tick_lap_time(&tick_time)));
+
+ fmt.printf(
+ "Formatted %v files in %vms \n",
+ len(files),
+ time.duration_milliseconds(time.tick_lap_time(&tick_time)),
+ )
fmt.printf("Peak memory used: %v \n", watermark / mem.Megabyte)
} else {
- fmt.eprintf("%v is neither a directory nor a file \n", path);
- os.exit(1);
+ fmt.eprintf("%v is neither a directory nor a file \n", path)
+ os.exit(1)
}
- os.exit(1 if write_failure else 0);
+ os.exit(1 if write_failure else 0)
}
diff --git a/tools/odinfmt/snapshot/snapshot.odin b/tools/odinfmt/snapshot/snapshot.odin
index 2f658a5..d5bdbd2 100644
--- a/tools/odinfmt/snapshot/snapshot.odin
+++ b/tools/odinfmt/snapshot/snapshot.odin
@@ -1,4 +1,4 @@
-package odinfmt_testing
+package odinfmt_testing
import "core:testing"
import "core:os"
@@ -9,15 +9,27 @@ import "core:fmt"
import "shared:odin/format"
-format_file :: proc(filepath: string, allocator := context.allocator) -> (string, bool) {
+format_file :: proc(
+ filepath: string,
+ allocator := context.allocator,
+) -> (
+ string,
+ bool,
+) {
style := format.default_style
style.character_width = 80
style.newline_style = .LF //We want to make sure it works on linux and windows.
- if data, ok := os.read_entire_file(filepath, allocator); ok {
- return format.format(filepath, string(data), style, {.Optional_Semicolons}, allocator);
+ if data, ok := os.read_entire_file(filepath, allocator); ok {
+ return format.format(
+ filepath,
+ string(data),
+ style,
+ {.Optional_Semicolons},
+ allocator,
+ )
} else {
- return "", false;
+ return "", false
}
}
@@ -28,7 +40,7 @@ snapshot_directory :: proc(directory: string) -> bool {
fmt.eprintf("Error in globbing directory: %v", directory)
}
- for match in matches {
+ for match in matches {
if strings.contains(match, ".odin") {
snapshot_file(match) or_return
}
@@ -49,20 +61,30 @@ snapshot_file :: proc(path: string) -> bool {
fmt.printf("Testing snapshot %v", path)
- snapshot_path := filepath.join(elems = {filepath.dir(path, context.temp_allocator), "/.snapshots", filepath.base(path)}, allocator = context.temp_allocator);
+ snapshot_path := filepath.join(
+ elems = {
+ filepath.dir(path, context.temp_allocator),
+ "/.snapshots",
+ filepath.base(path),
+ },
+ allocator = context.temp_allocator,
+ )
formatted, ok := format_file(path, context.temp_allocator)
if !ok {
- fmt.eprintf("Format failed on file %v", path)
+ fmt.eprintf("Format failed on file %v", path)
return false
}
if os.exists(snapshot_path) {
- if snapshot_data, ok := os.read_entire_file(snapshot_path, context.temp_allocator); ok {
- snapshot_scanner := scanner.Scanner {}
+ if snapshot_data, ok := os.read_entire_file(
+ snapshot_path,
+ context.temp_allocator,
+ ); ok {
+ snapshot_scanner := scanner.Scanner{}
scanner.init(&snapshot_scanner, string(snapshot_data))
- formatted_scanner := scanner.Scanner {}
+ formatted_scanner := scanner.Scanner{}
scanner.init(&formatted_scanner, string(formatted))
for {
s_ch := scanner.next(&snapshot_scanner)
@@ -75,7 +97,7 @@ snapshot_file :: proc(path: string) -> bool {
if scanner.peek(&snapshot_scanner) == '\n' {
s_ch = scanner.next(&snapshot_scanner)
}
- }
+ }
if f_ch == '\r' {
if scanner.peek(&formatted_scanner) == '\n' {
f_ch = scanner.next(&formatted_scanner)
@@ -83,8 +105,14 @@ snapshot_file :: proc(path: string) -> bool {
}
if s_ch != f_ch {
- fmt.eprintf("\nFormatted file was different from snapshot file: %v", snapshot_path)
- os.write_entire_file(fmt.tprintf("%v_failed", snapshot_path), transmute([]u8)formatted)
+ fmt.eprintf(
+ "\nFormatted file was different from snapshot file: %v",
+ snapshot_path,
+ )
+ os.write_entire_file(
+ fmt.tprintf("%v_failed", snapshot_path),
+ transmute([]u8)formatted,
+ )
return false
}
}
diff --git a/tools/odinfmt/tests.odin b/tools/odinfmt/tests.odin
index 8bd0399..313e33c 100644
--- a/tools/odinfmt/tests.odin
+++ b/tools/odinfmt/tests.odin
@@ -9,10 +9,10 @@ import "snapshot"
main :: proc() {
- init_global_temporary_allocator(mem.Megabyte*100)
-
+ init_global_temporary_allocator(mem.Megabyte * 100)
+
if !snapshot.snapshot_directory("tests") {
os.exit(1)
- }
+ }
}