aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-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
31 files changed, 4430 insertions, 1670 deletions
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
}