aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gavin <danielgavin5@hotmail.com>2022-03-04 12:17:00 +0100
committerDaniel Gavin <danielgavin5@hotmail.com>2022-03-04 12:17:00 +0100
commit58287455d64ab16091522bf8a358b079ef05daad (patch)
tree7b6655d6d34b5ad6d719523e4938b8002c43d8ab
parent63d0bd412a8817445d6dc18e79d5d54c94caf401 (diff)
strip colons and update ast to use unions
-rw-r--r--src/analysis/analysis.odin2836
-rw-r--r--src/common/allocator.odin104
-rw-r--r--src/common/ast.odin1116
-rw-r--r--src/common/fuzzy.odin254
-rw-r--r--src/common/position.odin166
-rw-r--r--src/common/sha1.odin334
-rw-r--r--src/common/uri.odin92
-rw-r--r--src/common/util_windows.odin62
-rw-r--r--src/index/build.odin122
-rw-r--r--src/index/clone.odin378
-rw-r--r--src/index/collector.odin577
-rw-r--r--src/index/indexer.odin50
-rw-r--r--src/index/memory_index.odin28
-rw-r--r--src/index/symbol.odin46
-rw-r--r--src/main.odin72
-rw-r--r--src/odin/printer/document.odin2
-rw-r--r--src/odin/printer/printer.odin4
-rw-r--r--src/odin/printer/visit.odin224
-rw-r--r--src/server/check.odin118
-rw-r--r--src/server/completion.odin652
-rw-r--r--src/server/definition.odin91
-rw-r--r--src/server/document_links.odin20
-rw-r--r--src/server/document_symbols.odin56
-rw-r--r--src/server/documents.odin252
-rw-r--r--src/server/format.odin40
-rw-r--r--src/server/hover.odin126
-rw-r--r--src/server/inlay_hints.odin36
-rw-r--r--src/server/lens.odin14
-rw-r--r--src/server/log.odin18
-rw-r--r--src/server/reader.odin42
-rw-r--r--src/server/requests.odin648
-rw-r--r--src/server/response.odin36
-rw-r--r--src/server/semantic_tokens.odin468
-rw-r--r--src/server/signature.odin110
-rw-r--r--src/server/unmarshal.odin96
-rw-r--r--src/server/writer.odin18
-rw-r--r--src/testing/testing.odin4
-rw-r--r--tests/completions_test.odin25
38 files changed, 4649 insertions, 4688 deletions
diff --git a/src/analysis/analysis.odin b/src/analysis/analysis.odin
index 34e8ac1..400bde6 100644
--- a/src/analysis/analysis.odin
+++ b/src/analysis/analysis.odin
@@ -104,15 +104,15 @@ make_ast_context :: proc(file: ast.File, imports: []common.Package, package_name
current_package = package_name,
uri = uri,
allocator = allocator,
- };
+ }
- add_local_group(&ast_context, 0);
+ add_local_group(&ast_context, 0)
- when ODIN_OS == "windows" {
- ast_context.uri = strings.to_lower(ast_context.uri, allocator);
+ when ODIN_OS == .Windows {
+ ast_context.uri = strings.to_lower(ast_context.uri, allocator)
}
- return ast_context;
+ return ast_context
}
tokenizer_error_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) {
@@ -126,205 +126,203 @@ resolve_poly_spec :: proc {
resolve_poly_spec_node,
resolve_poly_spec_array,
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) {
if len(call_array) != len(spec_array) {
- return;
+ return
}
for elem, i in call_array {
- resolve_poly_spec(ast_context, elem, spec_array[i], poly_map);
+ resolve_poly_spec(ast_context, elem, spec_array[i], poly_map)
}
}
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;
+ return
}
for elem, i in call_array {
- resolve_poly_spec(ast_context, elem, spec_array[i], poly_map);
+ resolve_poly_spec(ast_context, elem, spec_array[i], poly_map)
}
}
get_poly_node_to_expr :: proc(node: ^ast.Node) -> ^ast.Expr {
- using ast;
+ using ast
- switch v in node.derived {
- case Ident:
- return cast(^Expr)node;
+ #partial switch v in node.derived {
+ case ^Ident:
+ return cast(^Expr)node
case:
- log.warnf("Unhandled poly to node kind %v", v);
+ log.warnf("Unhandled poly to node kind %v", v)
}
- return nil;
+ return nil
}
resolve_poly_spec_node :: proc(ast_context: ^AstContext, call_node: ^ast.Node, spec_node: ^ast.Node, poly_map: ^map[string]^ast.Expr) {
- using ast;
+ using ast
if call_node == nil || spec_node == nil {
- return;
+ return
}
- switch m in spec_node.derived {
- case Bad_Expr:
- case Ident:
- case Implicit:
- case Undef:
- case Basic_Lit:
- case Poly_Type:
+ #partial switch m in spec_node.derived {
+ case ^Bad_Expr:
+ case ^Ident:
+ case ^Implicit:
+ case ^Undef:
+ case ^Basic_Lit:
+ case ^Poly_Type:
if expr := get_poly_node_to_expr(call_node); expr != nil {
- poly_map[m.type.name] = expr;
- }
- case Ellipsis:
- if n, ok := call_node.derived.(Ellipsis); ok {
- resolve_poly_spec(ast_context, n.expr, m.expr, poly_map);
- }
- case Tag_Expr:
- if n, ok := call_node.derived.(Tag_Expr); ok {
- resolve_poly_spec(ast_context, n.expr, m.expr, poly_map);
- }
- case Unary_Expr:
- if n, ok := call_node.derived.(Unary_Expr); ok {
- resolve_poly_spec(ast_context, n.expr, m.expr, poly_map);
- }
- case Binary_Expr:
- if n, ok := call_node.derived.(Binary_Expr); ok {
- resolve_poly_spec(ast_context, n.left, m.left, poly_map);
- resolve_poly_spec(ast_context, n.right, m.right, poly_map);
- }
- case Paren_Expr:
- if n, ok := call_node.derived.(Paren_Expr); ok {
- resolve_poly_spec(ast_context, n.expr, m.expr, poly_map);
- }
- case Selector_Expr:
- if n, ok := call_node.derived.(Selector_Expr); ok {
- resolve_poly_spec(ast_context, n.expr, m.expr, poly_map);
- resolve_poly_spec(ast_context, n.field, m.field, poly_map);
- }
- case Slice_Expr:
- if n, ok := call_node.derived.(Slice_Expr); ok {
- resolve_poly_spec(ast_context, n.expr, m.expr, poly_map);
- resolve_poly_spec(ast_context, n.low, m.low, poly_map);
- resolve_poly_spec(ast_context, n.high, m.high, poly_map);
- }
- case Distinct_Type:
- if n, ok := call_node.derived.(Distinct_Type); ok {
- resolve_poly_spec(ast_context, n.type, m.type, poly_map);
- }
- case Proc_Type:
- if n, ok := call_node.derived.(Proc_Type); ok {
- resolve_poly_spec(ast_context, n.params, m.params, poly_map);
- resolve_poly_spec(ast_context, n.results, m.results, poly_map);
- }
- case Pointer_Type:
- if n, ok := call_node.derived.(Pointer_Type); ok {
- resolve_poly_spec(ast_context, n.elem, m.elem, poly_map);
- }
- case Array_Type:
- if n, ok := call_node.derived.(Array_Type); ok {
- resolve_poly_spec(ast_context, n.len, m.len, poly_map);
- resolve_poly_spec(ast_context, n.elem, m.elem, poly_map);
- }
- case Dynamic_Array_Type:
- if n, ok := call_node.derived.(Dynamic_Array_Type); ok {
- resolve_poly_spec(ast_context, n.elem, m.elem, poly_map);
- }
- 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.align, m.align, poly_map);
- resolve_poly_spec(ast_context, n.fields, m.fields, poly_map);
- }
- case Field:
- 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);
- }
- case Field_List:
- if n, ok := call_node.derived.(Field_List); ok {
- resolve_poly_spec(ast_context, n.list, m.list, poly_map);
- }
- case Field_Value:
- if n, ok := call_node.derived.(Field_Value); ok {
- resolve_poly_spec(ast_context, n.field, m.field, poly_map);
- resolve_poly_spec(ast_context, n.value, m.value, poly_map);
- }
- 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.align, m.align, poly_map);
- resolve_poly_spec(ast_context, n.variants, m.variants, poly_map);
- }
- case Enum_Type:
- if n, ok := call_node.derived.(Enum_Type); ok {
- resolve_poly_spec(ast_context, n.base_type, m.base_type, poly_map);
- resolve_poly_spec(ast_context, n.fields, m.fields, poly_map);
- }
- 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);
- }
- case Map_Type:
- if n, ok := call_node.derived.(Map_Type); ok {
- resolve_poly_spec(ast_context, n.key, m.key, poly_map);
- resolve_poly_spec(ast_context, n.value, m.value, poly_map);
- }
- case Call_Expr:
- if n, ok := call_node.derived.(Call_Expr); ok {
- resolve_poly_spec(ast_context, n.expr, m.expr, poly_map);
- resolve_poly_spec(ast_context, n.args, m.args, poly_map);
- }
- case Typeid_Type:
- if n, ok := call_node.derived.(Typeid_Type); ok {
- resolve_poly_spec(ast_context, n.specialization, m.specialization, poly_map);
+ poly_map[m.type.name] = expr
+ }
+ case ^Ellipsis:
+ if n, ok := call_node.derived.(^Ellipsis); ok {
+ resolve_poly_spec(ast_context, n.expr, m.expr, poly_map)
+ }
+ case ^Tag_Expr:
+ if n, ok := call_node.derived.(^Tag_Expr); ok {
+ resolve_poly_spec(ast_context, n.expr, m.expr, poly_map)
+ }
+ case ^Unary_Expr:
+ if n, ok := call_node.derived.(^Unary_Expr); ok {
+ resolve_poly_spec(ast_context, n.expr, m.expr, poly_map)
+ }
+ case ^Binary_Expr:
+ if n, ok := call_node.derived.(^Binary_Expr); ok {
+ resolve_poly_spec(ast_context, n.left, m.left, poly_map)
+ resolve_poly_spec(ast_context, n.right, m.right, poly_map)
+ }
+ case ^Paren_Expr:
+ if n, ok := call_node.derived.(^Paren_Expr); ok {
+ resolve_poly_spec(ast_context, n.expr, m.expr, poly_map)
+ }
+ case ^Selector_Expr:
+ if n, ok := call_node.derived.(^Selector_Expr); ok {
+ resolve_poly_spec(ast_context, n.expr, m.expr, poly_map)
+ resolve_poly_spec(ast_context, n.field, m.field, poly_map)
+ }
+ case ^Slice_Expr:
+ if n, ok := call_node.derived.(^Slice_Expr); ok {
+ resolve_poly_spec(ast_context, n.expr, m.expr, poly_map)
+ resolve_poly_spec(ast_context, n.low, m.low, poly_map)
+ resolve_poly_spec(ast_context, n.high, m.high, poly_map)
+ }
+ case ^Distinct_Type:
+ if n, ok := call_node.derived.(^Distinct_Type); ok {
+ resolve_poly_spec(ast_context, n.type, m.type, poly_map)
+ }
+ case ^Proc_Type:
+ if n, ok := call_node.derived.(^Proc_Type); ok {
+ resolve_poly_spec(ast_context, n.params, m.params, poly_map)
+ resolve_poly_spec(ast_context, n.results, m.results, poly_map)
+ }
+ case ^Pointer_Type:
+ if n, ok := call_node.derived.(^Pointer_Type); ok {
+ resolve_poly_spec(ast_context, n.elem, m.elem, poly_map)
+ }
+ case ^Array_Type:
+ if n, ok := call_node.derived.(^Array_Type); ok {
+ resolve_poly_spec(ast_context, n.len, m.len, poly_map)
+ resolve_poly_spec(ast_context, n.elem, m.elem, poly_map)
+ }
+ case ^Dynamic_Array_Type:
+ if n, ok := call_node.derived.(^Dynamic_Array_Type); ok {
+ resolve_poly_spec(ast_context, n.elem, m.elem, poly_map)
+ }
+ 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.align, m.align, poly_map)
+ resolve_poly_spec(ast_context, n.fields, m.fields, poly_map)
+ }
+ case ^Field:
+ 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)
+ }
+ case ^Field_List:
+ if n, ok := call_node.derived.(^Field_List); ok {
+ resolve_poly_spec(ast_context, n.list, m.list, poly_map)
+ }
+ case ^Field_Value:
+ if n, ok := call_node.derived.(^Field_Value); ok {
+ resolve_poly_spec(ast_context, n.field, m.field, poly_map)
+ resolve_poly_spec(ast_context, n.value, m.value, poly_map)
+ }
+ 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.align, m.align, poly_map)
+ resolve_poly_spec(ast_context, n.variants, m.variants, poly_map)
+ }
+ case ^Enum_Type:
+ if n, ok := call_node.derived.(^Enum_Type); ok {
+ resolve_poly_spec(ast_context, n.base_type, m.base_type, poly_map)
+ resolve_poly_spec(ast_context, n.fields, m.fields, poly_map)
+ }
+ 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)
+ }
+ case ^Map_Type:
+ if n, ok := call_node.derived.(^Map_Type); ok {
+ resolve_poly_spec(ast_context, n.key, m.key, poly_map)
+ resolve_poly_spec(ast_context, n.value, m.value, poly_map)
+ }
+ case ^Call_Expr:
+ if n, ok := call_node.derived.(^Call_Expr); ok {
+ resolve_poly_spec(ast_context, n.expr, m.expr, poly_map)
+ resolve_poly_spec(ast_context, n.args, m.args, poly_map)
+ }
+ case ^Typeid_Type:
+ if n, ok := call_node.derived.(^Typeid_Type); ok {
+ resolve_poly_spec(ast_context, n.specialization, m.specialization, poly_map)
}
case:
- log.error("Unhandled poly node kind: %T", m);
+ log.error("Unhandled poly node kind: %T", m)
}
}
resolve_type_comp_literal :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, current_symbol: index.Symbol, current_comp_lit: ^ast.Comp_Lit) -> (index.Symbol, ^ast.Comp_Lit, bool) {
-
if position_context.comp_lit == current_comp_lit {
- return current_symbol, current_comp_lit, true;
+ return current_symbol, current_comp_lit, true
} else if current_comp_lit == nil {
return {}, nil, false
}
if current_comp_lit == nil {
- return {}, nil, false;
+ return {}, nil, false
}
- element_index := 0;
+ element_index := 0
for elem, i in current_comp_lit.elems {
if position_in_node(elem, position_context.position) {
- element_index = i;
+ element_index = i
}
}
for elem in current_comp_lit.elems {
-
if !position_in_node(elem, position_context.position) {
- continue;
+ continue
}
- if field_value, ok := elem.derived.(ast.Field_Value); ok { //named
- if comp_lit, ok := field_value.value.derived.(ast.Comp_Lit); ok {
+ 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.(index.SymbolStructValue); ok {
for name, i in s.names {
- if name == field_value.field.derived.(ast.Ident).name {
+ 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.(index.SymbolBitSetValue); ok {
- return current_symbol, current_comp_lit, true;
+ 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)
}
}
}
@@ -334,166 +332,166 @@ resolve_type_comp_literal :: proc(ast_context: ^AstContext, position_context: ^D
if s, ok := current_symbol.value.(index.SymbolStructValue); ok {
if len(s.types) <= element_index {
- return {}, {}, false;
+ return {}, {}, false
}
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.(index.SymbolBitSetValue); ok {
- return current_symbol, current_comp_lit, true;
+ 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)
}
}
}
}
- return current_symbol, current_comp_lit, true;
+ return current_symbol, current_comp_lit, true
}
resolve_generic_function :: proc {
resolve_generic_function_ast,
resolve_generic_function_symbol,
-};
+}
resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast.Field, results: []^ast.Field) -> (index.Symbol, bool) {
- using ast;
+ using ast
if params == nil {
- return {}, false;
+ return {}, false
}
if results == nil {
- return {}, false;
+ return {}, false
}
if ast_context.call == nil {
- return {}, false;
+ return {}, false
}
- call_expr := ast_context.call;
- poly_map := make(map[string]^Expr, 0, context.temp_allocator);
- i := 0;
- count_required_params := 0;
+ call_expr := ast_context.call
+ poly_map := make(map[string]^Expr, 0, context.temp_allocator)
+ i := 0
+ count_required_params := 0
for param in params {
if param.default_value == nil {
- count_required_params += 1;
+ count_required_params += 1
}
for name in param.names {
if len(call_expr.args) <= i {
- break;
+ break
}
- if poly, ok := name.derived.(Poly_Type); ok {
- poly_map[poly.type.name] = call_expr.args[i];
+ if poly, ok := name.derived.(^Poly_Type); ok {
+ poly_map[poly.type.name] = call_expr.args[i]
}
if param.type == nil {
- continue;
+ continue
}
- if type_id, ok := param.type.derived.(Typeid_Type); ok {
+ if type_id, ok := param.type.derived.(^Typeid_Type); ok {
if type_id.specialization != nil && !common.node_equal(call_expr.args[i], type_id.specialization) {
- return {}, false;
+ 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;
+ i += 1
}
}
if count_required_params > len(call_expr.args) || count_required_params == 0 || len(call_expr.args) == 0 {
- return {}, false;
+ return {}, false
}
- function_name := "";
- function_range: common.Range;
+ function_name := ""
+ function_range: common.Range
- if ident, ok := call_expr.expr.derived.(Ident); ok {
- function_name = ident.name;
- function_range = common.get_token_range(ident, ast_context.file.src);
- } else if selector, ok := call_expr.expr.derived.(Selector_Expr); ok {
- function_name = selector.field.name;
- function_range = common.get_token_range(selector, ast_context.file.src);
+ if ident, ok := call_expr.expr.derived.(^Ident); ok {
+ function_name = ident.name
+ function_range = common.get_token_range(ident, ast_context.file.src)
+ } else if selector, ok := call_expr.expr.derived.(^Selector_Expr); ok {
+ function_name = selector.field.name
+ function_range = common.get_token_range(selector, ast_context.file.src)
} else {
- return {}, false;
+ return {}, false
}
symbol := index.Symbol {
range = function_range,
type = .Function,
name = function_name,
- };
+ }
- return_types := make([dynamic]^ast.Field, ast_context.allocator);
- argument_types := make([dynamic]^ast.Field, ast_context.allocator);
+ return_types := make([dynamic]^ast.Field, ast_context.allocator)
+ argument_types := make([dynamic]^ast.Field, ast_context.allocator)
for result in results {
if result.type == nil {
- continue;
+ continue
}
- ident, ok := common.unwrap_pointer(result.type);
+ ident, ok := common.unwrap_pointer(result.type)
if ok {
if m, ok := poly_map[ident.name]; ok {
- field := cast(^Field)index.clone_node(result, ast_context.allocator, nil);
- field.type = m;
- append(&return_types, field);
+ field := cast(^Field)index.clone_node(result, ast_context.allocator, nil)
+ field.type = m
+ append(&return_types, field)
} else {
- append(&return_types, result);
+ append(&return_types, result)
}
} else {
- append(&return_types, result);
+ append(&return_types, result)
}
}
for param in params {
if len(param.names) == 0 {
- continue;
+ continue
}
//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(^Field)index.clone_node(param, ast_context.allocator, nil);
- field.type = m;
- append(&argument_types, field);
+ field := cast(^Field)index.clone_node(param, ast_context.allocator, nil)
+ field.type = m
+ append(&argument_types, field)
}
} else {
- append(&argument_types, param);
+ append(&argument_types, param)
}
}
symbol.value = index.SymbolProcedureValue {
return_types = return_types[:],
arg_types = argument_types[:],
- };
+ }
- return symbol, true;
+ return symbol, true
}
resolve_generic_function_ast :: proc(ast_context: ^AstContext, proc_lit: ast.Proc_Lit) -> (index.Symbol, bool) {
- using ast;
+ using ast
if proc_lit.type.params == nil {
- return index.Symbol {}, false;
+ return index.Symbol {}, false
}
if proc_lit.type.results == nil {
- return index.Symbol {}, false;
+ return index.Symbol {}, false
}
if ast_context.call == nil {
- return index.Symbol {}, false;
+ return index.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: index.Symbol, flags: ast.Field_Flags = {}) -> bool {
@@ -503,59 +501,59 @@ is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: index.Symbol, flags
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
}
}
}
}
- a_id := reflect.union_variant_typeid(a.value);
- b_id := reflect.union_variant_typeid(b.value);
+ a_id := reflect.union_variant_typeid(a.value)
+ b_id := reflect.union_variant_typeid(b.value)
if a_id != b_id {
- return false;
+ return false
}
if a.pointers != b.pointers {
- return false;
+ return false
}
if .Distinct in a.flags != .Distinct in b.flags {
- return false;
+ return false
}
if .Distinct in a.flags == .Distinct in b.flags &&
.Distinct in a.flags &&
a.name == b.name &&
a.pkg == b.pkg {
- return true;
+ return true
}
#partial switch b_value in b.value {
case index.SymbolBasicValue:
if .Auto_Cast in flags {
- return true;
+ return true
} else if .Any_Int in flags {
//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
}
}
}
@@ -564,211 +562,211 @@ is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: index.Symbol, flags
case index.SymbolBasicValue:
return a.name == b.name && a.pkg == b.pkg
case index.SymbolStructValue, index.SymbolEnumValue, index.SymbolUnionValue, index.SymbolBitSetValue:
- return a.name == b.name && a.pkg == b.pkg;
+ return a.name == b.name && a.pkg == b.pkg
case index.SymbolSliceValue:
- b_value := b.value.(index.SymbolSliceValue);
+ b_value := b.value.(index.SymbolSliceValue)
- a_symbol: index.Symbol;
- b_symbol: index.Symbol;
- ok: bool;
+ a_symbol: index.Symbol
+ b_symbol: index.Symbol
+ ok: bool
- a_symbol, ok = resolve_type_expression(ast_context, a_value.expr);
+ a_symbol, ok = resolve_type_expression(ast_context, a_value.expr)
if !ok {
- return false;
+ return false
}
- b_symbol, ok = resolve_type_expression(ast_context, b_value.expr);
+ b_symbol, ok = resolve_type_expression(ast_context, b_value.expr)
if !ok {
- return false;
+ return false
}
- return is_symbol_same_typed(ast_context, a_symbol, b_symbol);
+ return is_symbol_same_typed(ast_context, a_symbol, b_symbol)
case index.SymbolFixedArrayValue:
- b_value := b.value.(index.SymbolFixedArrayValue);
+ b_value := b.value.(index.SymbolFixedArrayValue)
- a_symbol: index.Symbol;
- b_symbol: index.Symbol;
- ok: bool;
+ a_symbol: index.Symbol
+ b_symbol: index.Symbol
+ ok: bool
- a_symbol, ok = resolve_type_expression(ast_context, a_value.expr);
+ a_symbol, ok = resolve_type_expression(ast_context, a_value.expr)
if !ok {
- return false;
+ return false
}
- b_symbol, ok = resolve_type_expression(ast_context, b_value.expr);
+ b_symbol, ok = resolve_type_expression(ast_context, b_value.expr)
if !ok {
- return false;
+ return false
}
- return is_symbol_same_typed(ast_context, a_symbol, b_symbol);
+ return is_symbol_same_typed(ast_context, a_symbol, b_symbol)
case index.SymbolDynamicArrayValue:
- b_value := b.value.(index.SymbolDynamicArrayValue);
+ b_value := b.value.(index.SymbolDynamicArrayValue)
- a_symbol: index.Symbol;
- b_symbol: index.Symbol;
- ok: bool;
+ a_symbol: index.Symbol
+ b_symbol: index.Symbol
+ ok: bool
- a_symbol, ok = resolve_type_expression(ast_context, a_value.expr);
+ a_symbol, ok = resolve_type_expression(ast_context, a_value.expr)
if !ok {
- return false;
+ return false
}
- b_symbol, ok = resolve_type_expression(ast_context, b_value.expr);
+ b_symbol, ok = resolve_type_expression(ast_context, b_value.expr)
if !ok {
- return false;
+ return false
}
- return is_symbol_same_typed(ast_context, a_symbol, b_symbol);
+ return is_symbol_same_typed(ast_context, a_symbol, b_symbol)
case index.SymbolMapValue:
- b_value := b.value.(index.SymbolMapValue);
+ b_value := b.value.(index.SymbolMapValue)
- a_key_symbol: index.Symbol;
- b_key_symbol: index.Symbol;
- a_value_symbol: index.Symbol;
- b_value_symbol: index.Symbol;
- ok: bool;
+ a_key_symbol: index.Symbol
+ b_key_symbol: index.Symbol
+ a_value_symbol: index.Symbol
+ b_value_symbol: index.Symbol
+ ok: bool
- a_key_symbol, ok = resolve_type_expression(ast_context, a_value.key);
+ a_key_symbol, ok = resolve_type_expression(ast_context, a_value.key)
if !ok {
- return false;
+ return false
}
- b_key_symbol, ok = resolve_type_expression(ast_context, b_value.key);
+ b_key_symbol, ok = resolve_type_expression(ast_context, b_value.key)
if !ok {
- return false;
+ 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;
+ 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 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;
+ return false
}
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 ident, ok := field_name.derived.(^ast.Ident); ok {
if name == ident.name {
- return i, true;
+ return i, true
}
}
}
}
- return 0, false;
+ return 0, false
}
/*
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) -> (index.Symbol, bool) {
- using ast;
+ using ast
- call_expr := ast_context.call;
+ call_expr := ast_context.call
- candidates := make([dynamic]index.Symbol, context.temp_allocator);
+ candidates := make([dynamic]index.Symbol, context.temp_allocator)
for arg_expr in group.args {
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;
+ append(&candidates, f)
+ break next_fn
}
if procedure, ok := f.value.(index.SymbolProcedureValue); ok {
- count_required_params := 0;
+ count_required_params := 0
for arg in procedure.arg_types {
if arg.default_value == nil {
- count_required_params += 1;
+ count_required_params += 1
}
}
if len(procedure.arg_types) < len(call_expr.args) {
- continue;
+ continue
}
for arg, i in call_expr.args {
- ast_context.use_locals = true;
+ ast_context.use_locals = true
- call_symbol: index.Symbol;
- arg_symbol: index.Symbol;
- ok: bool;
- i := i;
+ call_symbol: index.Symbol
+ arg_symbol: index.Symbol
+ ok: bool
+ i := i
- if _, ok = arg.derived.(ast.Bad_Expr); ok {
- continue;
+ if _, ok = arg.derived.(^ast.Bad_Expr); ok {
+ continue
}
//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;
+ 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;
+ break next_fn
}
} else {
- call_symbol, ok = resolve_type_expression(ast_context, arg);
+ call_symbol, ok = resolve_type_expression(ast_context, arg)
}
if !ok {
- break next_fn;
+ break next_fn
}
if p, ok := call_symbol.value.(index.SymbolProcedureValue); ok {
if len(p.return_types) != 1 {
- break next_fn;
+ break next_fn
}
if s, ok := resolve_type_expression(ast_context, p.return_types[0].type); ok {
- call_symbol = s;
+ call_symbol = s
}
}
if procedure.arg_types[i].type != nil {
- arg_symbol, ok = resolve_type_expression(ast_context, procedure.arg_types[i].type);
+ 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].default_value)
}
if !ok {
- break next_fn;
+ break next_fn
}
if !is_symbol_same_typed(ast_context, call_symbol, arg_symbol, procedure.arg_types[i].flags) {
- break next_fn;
+ break next_fn
}
}
- append(&candidates, f);
+ append(&candidates, f)
}
}
}
@@ -781,300 +779,300 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
value = index.SymbolAggregateValue {
symbols = candidates[:],
},
- }, true;
+ }, true
} else if len(candidates) == 1 {
- return candidates[0], true;
+ return candidates[0], true
}
- return index.Symbol {}, false;
+ return index.Symbol {}, false
}
resolve_basic_lit :: proc(ast_context: ^AstContext, basic_lit: ast.Basic_Lit) -> (index.Symbol, bool) {
symbol := index.Symbol {
type = .Constant,
- };
+ }
- value: index.SymbolUntypedValue;
+ value: index.SymbolUntypedValue
if v, ok := strconv.parse_int(basic_lit.tok.text); ok {
- value.type = .Integer;
+ value.type = .Integer
} else if v, ok := strconv.parse_bool(basic_lit.tok.text); ok {
- value.type = .Bool;
+ value.type = .Bool
} else if v, ok := strconv.parse_f64(basic_lit.tok.text); ok {
- value.type = .Float;
+ value.type = .Float
} else {
- value.type = .String;
+ value.type = .String
}
symbol.pkg = ast_context.current_package
- symbol.value = value;
+ symbol.value = value
- return symbol, true;
+ return symbol, true
}
resolve_basic_directive :: proc(ast_context: ^AstContext, directive: ast.Basic_Directive, a := #caller_location) -> (index.Symbol, bool) {
switch directive.name {
case "caller_location":
- ident := index.new_type(ast.Ident, directive.pos, directive.end, ast_context.allocator);
- ident.name = "Source_Code_Location";
- ast_context.current_package = ast_context.document_package;
+ ident := index.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^)
}
- return {}, false;
+ return {}, false
}
resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (index.Symbol, bool) {
if node == nil {
- return {}, false;
+ return {}, false
}
- saved_package := ast_context.current_package;
+ saved_package := ast_context.current_package
defer {
- ast_context.current_package = saved_package;
+ ast_context.current_package = saved_package
}
if ast_context.recursion_counter > 15 {
- log.error("Recursion passed 15 attempts - giving up");
- return {}, false;
+ log.error("Recursion passed 15 attempts - giving up")
+ return {}, false
}
- ast_context.recursion_counter += 1;
+ ast_context.recursion_counter += 1
defer {
- ast_context.recursion_counter -= 1;
- }
-
- using ast;
-
- switch v in &node.derived {
- case Union_Type:
- 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;
- case Struct_Type:
- 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;
- case Array_Type:
- return make_symbol_array_from_ast(ast_context, v), true;
- case Dynamic_Array_Type:
- return make_symbol_dynamic_array_from_ast(ast_context, v), true;
- case Map_Type:
- return make_symbol_map_from_ast(ast_context, v), true;
- case Proc_Type:
- 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);
- 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);
- case Auto_Cast:
- return resolve_type_expression(ast_context, v.expr);
- case Comp_Lit:
- return resolve_type_expression(ast_context, v.type);
- case Unary_Expr:
+ ast_context.recursion_counter -= 1
+ }
+
+ using ast
+
+ #partial switch v in node.derived {
+ case ^Union_Type:
+ 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
+ case ^Struct_Type:
+ 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
+ case ^Array_Type:
+ return make_symbol_array_from_ast(ast_context, v^), true
+ case ^Dynamic_Array_Type:
+ return make_symbol_dynamic_array_from_ast(ast_context, v^), true
+ case ^Map_Type:
+ return make_symbol_map_from_ast(ast_context, v^), true
+ case ^Proc_Type:
+ 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)
+ 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)
+ case ^Auto_Cast:
+ return resolve_type_expression(ast_context, v.expr)
+ case ^Comp_Lit:
+ return resolve_type_expression(ast_context, v.type)
+ case ^Unary_Expr:
if v.op.kind == .And {
- symbol, ok := resolve_type_expression(ast_context, v.expr);
- symbol.pointers += 1;
- return symbol, ok;
+ symbol, ok := resolve_type_expression(ast_context, v.expr)
+ symbol.pointers += 1
+ return symbol, ok
} else {
- return resolve_type_expression(ast_context, v.expr);
- }
- case Deref_Expr:
- symbol, ok := resolve_type_expression(ast_context, v.expr);
- symbol.pointers -= 1;
- return symbol, ok;
- case Paren_Expr:
- return resolve_type_expression(ast_context, v.expr);
- case Slice_Expr:
- return resolve_type_expression(ast_context, v.expr);
- case Tag_Expr:
- return resolve_type_expression(ast_context, v.expr);
- case Helper_Type:
- return resolve_type_expression(ast_context, v.type);
- case Ellipsis:
- return resolve_type_expression(ast_context, v.expr);
- case Implicit:
- ident := index.new_type(Ident, v.node.pos, v.node.end, context.temp_allocator);
- ident.name = v.tok.text;
- return resolve_type_identifier(ast_context, ident^);
- case Type_Assertion:
- if unary, ok := v.type.derived.(ast.Unary_Expr); ok {
+ return resolve_type_expression(ast_context, v.expr)
+ }
+ case ^Deref_Expr:
+ symbol, ok := resolve_type_expression(ast_context, v.expr)
+ symbol.pointers -= 1
+ return symbol, ok
+ case ^Paren_Expr:
+ return resolve_type_expression(ast_context, v.expr)
+ case ^Slice_Expr:
+ return resolve_type_expression(ast_context, v.expr)
+ case ^Tag_Expr:
+ return resolve_type_expression(ast_context, v.expr)
+ case ^Helper_Type:
+ return resolve_type_expression(ast_context, v.type)
+ case ^Ellipsis:
+ return resolve_type_expression(ast_context, v.expr)
+ case ^Implicit:
+ ident := index.new_type(Ident, v.node.pos, v.node.end, context.temp_allocator)
+ ident.name = v.tok.text
+ return resolve_type_identifier(ast_context, ident^)
+ 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 union_value, ok := symbol.value.(index.SymbolUnionValue); ok {
if len(union_value.types) != 1 {
- return {}, false;
+ 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);
+ return resolve_type_expression(ast_context, v.type)
}
- case Proc_Lit:
+ 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:
- symbol, ok := resolve_type_expression(ast_context, v.elem);
- symbol.pointers += 1;
- return symbol, ok;
- case Multi_Pointer_Type:
- symbol, ok := resolve_type_expression(ast_context, v.elem);
- symbol.pointers += 1;
- return symbol, ok;
- case Index_Expr:
- indexed, ok := resolve_type_expression(ast_context, v.expr);
+ case ^Pointer_Type:
+ symbol, ok := resolve_type_expression(ast_context, v.elem)
+ symbol.pointers += 1
+ return symbol, ok
+ case ^Multi_Pointer_Type:
+ symbol, ok := resolve_type_expression(ast_context, v.elem)
+ symbol.pointers += 1
+ return symbol, ok
+ case ^Index_Expr:
+ indexed, ok := resolve_type_expression(ast_context, v.expr)
if !ok {
- return {}, false;
+ return {}, false
}
- symbol: index.Symbol;
+ symbol: index.Symbol
#partial switch v2 in indexed.value {
case index.SymbolDynamicArrayValue:
- symbol, ok = resolve_type_expression(ast_context, v2.expr);
+ symbol, ok = resolve_type_expression(ast_context, v2.expr)
case index.SymbolSliceValue:
- symbol, ok = resolve_type_expression(ast_context, v2.expr);
+ symbol, ok = resolve_type_expression(ast_context, v2.expr)
case index.SymbolFixedArrayValue:
- symbol, ok = resolve_type_expression(ast_context, v2.expr);
+ symbol, ok = resolve_type_expression(ast_context, v2.expr)
case index.SymbolMapValue:
- symbol, ok = resolve_type_expression(ast_context, v2.value);
+ symbol, ok = resolve_type_expression(ast_context, v2.value)
}
- symbol.type = indexed.type;
+ symbol.type = indexed.type
- return symbol, ok;
- case Call_Expr:
- ast_context.call = cast(^Call_Expr)node;
- return resolve_type_expression(ast_context, v.expr);
- case Implicit_Selector_Expr:
- return index.Symbol {}, false;
- case Selector_Call_Expr:
- return resolve_type_expression(ast_context, v.expr);
- case Selector_Expr:
+ return symbol, ok
+ case ^Call_Expr:
+ ast_context.call = cast(^Call_Expr)node
+ return resolve_type_expression(ast_context, v.expr)
+ case ^Implicit_Selector_Expr:
+ return index.Symbol {}, false
+ case ^Selector_Call_Expr:
+ return resolve_type_expression(ast_context, v.expr)
+ case ^Selector_Expr:
if selector, ok := resolve_type_expression(ast_context, v.expr); ok {
- ast_context.use_locals = false;
+ ast_context.use_locals = false
#partial switch s in selector.value {
case index.SymbolFixedArrayValue:
- components_count := 0;
+ 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' {
- components_count += 1;
+ components_count += 1
}
}
if components_count == 0 {
- return {}, false;
+ return {}, false
}
if components_count == 1 {
if selector.pkg != "" {
- ast_context.current_package = 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;
- return symbol, ok;
+ symbol, ok := resolve_type_expression(ast_context, s.expr)
+ symbol.type = .Variable
+ return symbol, ok
} else {
value := index.SymbolFixedArrayValue {
expr = s.expr,
len = make_int_basic_value(ast_context, components_count),
- };
- selector.value = value;
- selector.type = .Variable;
- return selector, true;
+ }
+ selector.value = value
+ selector.type = .Variable
+ return selector, true
}
case index.SymbolProcedureValue:
if len(s.return_types) == 1 {
- selector_expr := index.new_type(ast.Selector_Expr, s.return_types[0].node.pos, s.return_types[0].node.end, context.temp_allocator);
- selector_expr.expr = s.return_types[0].type;
- selector_expr.field = v.field;
- return resolve_type_expression(ast_context, selector_expr);
+ selector_expr := index.new_type(ast.Selector_Expr, s.return_types[0].node.pos, s.return_types[0].node.end, context.temp_allocator)
+ selector_expr.expr = s.return_types[0].type
+ selector_expr.field = v.field
+ return resolve_type_expression(ast_context, selector_expr)
}
case index.SymbolStructValue:
if selector.pkg != "" {
- ast_context.current_package = 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
}
for name, i in s.names {
if v.field != nil && name == v.field.name {
- ast_context.field_name = v.field.name;
- symbol, ok := resolve_type_expression(ast_context, s.types[i]);
- symbol.type = .Variable;
- return symbol, ok;
+ ast_context.field_name = v.field.name
+ symbol, ok := resolve_type_expression(ast_context, s.types[i])
+ symbol.type = .Variable
+ return symbol, ok
}
}
case index.SymbolPackageValue:
- ast_context.current_package = selector.pkg;
+ ast_context.current_package = selector.pkg
if v.field != nil {
- return resolve_symbol_return(ast_context, index.lookup(v.field.name, selector.pkg));
+ return resolve_symbol_return(ast_context, index.lookup(v.field.name, selector.pkg))
} else {
- return index.Symbol {}, false;
+ return index.Symbol {}, false
}
}
} else {
- return index.Symbol {}, false;
+ return index.Symbol {}, false
}
case:
- log.warnf("default node kind, resolve_type_expression: %T", v);
+ log.warnf("default node kind, resolve_type_expression: %T", v)
if v == nil {
- return {}, false;
+ return {}, false
}
}
- return index.Symbol {}, false;
+ return index.Symbol {}, false
}
store_local :: proc(ast_context: ^AstContext, expr: ^ast.Expr, offset: int, name: string, id := 0) {
- local_stack := &ast_context.locals[id][name];
+ local_stack := &ast_context.locals[id][name]
if local_stack == nil {
- locals := &ast_context.locals[id];
- locals[name] = make([dynamic]DocumentLocal, ast_context.allocator);
- local_stack = &locals[name];
+ locals := &ast_context.locals[id]
+ locals[name] = make([dynamic]DocumentLocal, ast_context.allocator)
+ local_stack = &locals[name]
}
- append(local_stack, DocumentLocal {expr = expr, offset = offset, id = id});
+ append(local_stack, DocumentLocal {expr = expr, 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] = {};
+ ast_context.locals[id] = {}
}
get_local :: proc(ast_context: ^AstContext, offset: int, name: string) -> ^ast.Expr {
- previous := 0;
+ previous := 0
//is the local we are getting being declared?
if ast_context.value_decl != nil {
for value_decl_name in ast_context.value_decl.names {
- if ident, ok := value_decl_name.derived.(ast.Ident); ok {
+ if ident, ok := value_decl_name.derived.(^ast.Ident); ok {
if ident.name == name {
- previous = 1;
- break;
+ previous = 1
+ break
}
}
}
@@ -1085,16 +1083,16 @@ get_local :: proc(ast_context: ^AstContext, offset: int, name: string) -> ^ast.E
for i := len(local_stack) - 1; i >= 0; i -= 1 {
if local_stack[i].offset <= offset {
if i - previous < 0 {
- return nil;
+ return nil
} else {
- return local_stack[i - previous].expr;
+ return local_stack[i - previous].expr
}
}
}
}
}
- return nil;
+ return nil
}
get_local_offset :: proc(ast_context: ^AstContext, offset: int, name: string) -> int {
@@ -1103,40 +1101,40 @@ get_local_offset :: proc(ast_context: ^AstContext, offset: int, name: string) ->
for i := len(local_stack) - 1; i >= 0; i -= 1 {
if local_stack[i].offset <= offset {
if i < 0 {
- return -1;
+ return -1
} else {
- return local_stack[i].offset;
+ return local_stack[i].offset
}
}
}
}
}
- return -1;
+ return -1
}
resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (index.Symbol, bool) {
- using ast;
+ using ast
if ast_context.recursion_counter > 15 {
- log.error("Recursion passed 15 attempts - giving up");
- return {}, false;
+ log.error("Recursion passed 15 attempts - giving up")
+ return {}, false
}
- saved_package := ast_context.current_package;
+ saved_package := ast_context.current_package
defer {
- ast_context.current_package = saved_package;
+ ast_context.current_package = saved_package
}
- ast_context.recursion_counter += 1;
+ ast_context.recursion_counter += 1
defer {
- ast_context.recursion_counter -= 1;
+ ast_context.recursion_counter -= 1
}
if pkg, ok := ast_context.in_package[node.name]; ok {
- ast_context.current_package = pkg;
+ ast_context.current_package = pkg
}
if _, ok := ast_context.parameters[node.name]; ok {
@@ -1146,152 +1144,152 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (i
type = .Package,
pkg = imp.name,
value = index.SymbolPackageValue {},
- };
+ }
- return symbol, true;
+ return symbol, true
}
}
}
//note(Daniel, if global and local ends up being 100% same just make a function that takes the map)
if local := get_local(ast_context, node.pos.offset, node.name); local != nil && ast_context.use_locals {
- is_distinct := false;
+ is_distinct := false
- if dist, ok := local.derived.(ast.Distinct_Type); ok {
+ if dist, ok := local.derived.(^ast.Distinct_Type); ok {
if dist.type != nil {
- local = dist.type;
- is_distinct = true;
- }
- }
-
- return_symbol: index.Symbol;
- ok: bool;
-
- switch v in local.derived {
- 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.name), true;
- return_symbol.name = node.name;
- case Enum_Type:
- return_symbol, ok = make_symbol_enum_from_ast(ast_context, v, node.name), true;
- return_symbol.name = node.name;
- case Struct_Type:
- return_symbol, ok = make_symbol_struct_from_ast(ast_context, v, node.name), true;
- return_symbol.name = node.name;
- case Bit_Set_Type:
- return_symbol, ok = make_symbol_bitset_from_ast(ast_context, v, node.name), true;
- return_symbol.name = node.name;
- case Proc_Lit:
+ local = dist.type
+ is_distinct = true
+ }
+ }
+
+ return_symbol: index.Symbol
+ ok: bool
+
+ #partial switch v in local.derived {
+ 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.name), true
+ return_symbol.name = node.name
+ case ^Enum_Type:
+ return_symbol, ok = make_symbol_enum_from_ast(ast_context, v^, node.name), true
+ return_symbol.name = node.name
+ case ^Struct_Type:
+ return_symbol, ok = make_symbol_struct_from_ast(ast_context, v^, node.name), true
+ return_symbol.name = node.name
+ case ^Bit_Set_Type:
+ return_symbol, ok = make_symbol_bitset_from_ast(ast_context, v^, node.name), 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.name), true;
+ return_symbol, ok = make_symbol_procedure_from_ast(ast_context, local, v.type^, node.name), 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.name), 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.name), 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), true;
- case Dynamic_Array_Type:
- return_symbol, ok = make_symbol_dynamic_array_from_ast(ast_context, v), true;
- case Map_Type:
- return_symbol, ok = make_symbol_map_from_ast(ast_context, v), 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;
+ 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^), true
+ case ^Dynamic_Array_Type:
+ return_symbol, ok = make_symbol_dynamic_array_from_ast(ast_context, v^), true
+ case ^Map_Type:
+ return_symbol, ok = make_symbol_map_from_ast(ast_context, v^), 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
case:
- return_symbol, ok = resolve_type_expression(ast_context, local);
+ return_symbol, ok = resolve_type_expression(ast_context, local)
}
if is_distinct {
- return_symbol.name = node.name;
- return_symbol.flags |= {.Distinct};
+ return_symbol.name = node.name
+ return_symbol.flags |= {.Distinct}
}
if is_variable, ok := ast_context.variables[node.name]; ok && is_variable {
- return_symbol.type = .Variable;
+ return_symbol.type = .Variable
}
- return return_symbol, ok;
+ return return_symbol, ok
} else if global, ok := ast_context.globals[node.name]; ast_context.use_globals && ok {
- is_distinct := false;
+ is_distinct := false
- if dist, ok := global.expr.derived.(ast.Distinct_Type); ok {
+ if dist, ok := global.expr.derived.(^ast.Distinct_Type); ok {
if dist.type != nil {
- global.expr = dist.type;
- is_distinct = true;
- }
- }
-
- return_symbol: index.Symbol;
- ok: bool;
-
- switch v in global.expr.derived {
- 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.name), true;
- return_symbol.name = node.name;
- case Bit_Set_Type:
- return_symbol, ok = make_symbol_bitset_from_ast(ast_context, v, node.name), true;
- return_symbol.name = node.name;
- case Union_Type:
- return_symbol, ok = make_symbol_union_from_ast(ast_context, v, node.name), true;
- return_symbol.name = node.name;
- case Enum_Type:
- return_symbol, ok = make_symbol_enum_from_ast(ast_context, v, node.name), true;
- return_symbol.name = node.name;
- case Proc_Lit:
+ global.expr = dist.type
+ is_distinct = true
+ }
+ }
+
+ return_symbol: index.Symbol
+ ok: bool
+
+ #partial switch v in global.expr.derived {
+ 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.name), true
+ return_symbol.name = node.name
+ case ^Bit_Set_Type:
+ return_symbol, ok = make_symbol_bitset_from_ast(ast_context, v^, node.name), true
+ return_symbol.name = node.name
+ case ^Union_Type:
+ return_symbol, ok = make_symbol_union_from_ast(ast_context, v^, node.name), true
+ return_symbol.name = node.name
+ case ^Enum_Type:
+ return_symbol, ok = make_symbol_enum_from_ast(ast_context, v^, node.name), 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.name), true;
+ return_symbol, ok = make_symbol_procedure_from_ast(ast_context, global.expr, v.type^, node.name), 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.name), 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.name), 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), true;
- case Dynamic_Array_Type:
- return_symbol, ok = make_symbol_dynamic_array_from_ast(ast_context, v), 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 ^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^), true
+ case ^Dynamic_Array_Type:
+ return_symbol, ok = make_symbol_dynamic_array_from_ast(ast_context, v^), 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 {
- return_symbol.name = node.name;
- return_symbol.flags |= {.Distinct};
+ return_symbol.name = node.name
+ return_symbol.flags |= {.Distinct}
}
if is_variable, ok := ast_context.variables[node.name]; ok && is_variable {
- return_symbol.type = .Variable;
+ return_symbol.type = .Variable
}
- return_symbol.doc = common.get_doc(global.docs, ast_context.allocator);
+ return_symbol.doc = common.get_doc(global.docs, ast_context.allocator)
- return return_symbol, ok;
+ return return_symbol, ok
} else if node.name == "context" {
for built in index.indexer.builtin_packages {
if symbol, ok := index.lookup("Context", built); ok {
- symbol.type = .Variable;
- return symbol, ok;
+ symbol.type = .Variable
+ return symbol, ok
}
}
} else if v, ok := common.keyword_map[node.name]; ok {
//keywords
- ident := index.new_type(Ident, node.pos, node.end, ast_context.allocator);
- ident.name = node.name;
+ ident := index.new_type(Ident, node.pos, node.end, ast_context.allocator)
+ ident.name = node.name
- symbol: index.Symbol;
+ symbol: index.Symbol
switch ident.name {
case "true", "false":
@@ -1302,7 +1300,7 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (i
value = index.SymbolUntypedValue {
type = .Bool,
},
- };
+ }
case:
symbol = index.Symbol {
type = .Keyword,
@@ -1312,10 +1310,10 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (i
value = index.SymbolBasicValue {
ident = ident,
},
- };
+ }
}
- return symbol, true;
+ return symbol, true
} else {
//right now we replace the package ident with the absolute directory name, so it should have '/' which is not a valid ident character
if strings.contains(node.name, "/") {
@@ -1323,9 +1321,9 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (i
type = .Package,
pkg = node.name,
value = index.SymbolPackageValue {},
- };
+ }
- return symbol, true;
+ return symbol, true
} else {
//part of the ast so we check the imports of the document
for imp in ast_context.imports {
@@ -1334,23 +1332,23 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (i
type = .Package,
pkg = imp.name,
value = index.SymbolPackageValue {},
- };
+ }
- return symbol, true;
+ return symbol, true
}
}
}
//last option is to check the index
if symbol, ok := index.lookup(node.name, ast_context.current_package); ok {
- return resolve_symbol_return(ast_context, symbol);
+ return resolve_symbol_return(ast_context, symbol)
}
//If we are resolving a symbol that is in the document package, then we'll check the builtin packages.
if ast_context.current_package == ast_context.document_package {
for built in index.indexer.builtin_packages {
if symbol, ok := index.lookup(node.name, built); ok {
- return resolve_symbol_return(ast_context, symbol);
+ return resolve_symbol_return(ast_context, symbol)
}
}
}
@@ -1360,59 +1358,59 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (i
for imp in ast_context.imports {
if strings.compare(imp.base, u) == 0 {
if symbol, ok := index.lookup(node.name, imp.name); ok {
- return resolve_symbol_return(ast_context, symbol);
+ return resolve_symbol_return(ast_context, symbol)
}
}
}
}
}
- return index.Symbol {}, false;
+ return index.Symbol {}, false
}
resolve_ident_is_package :: proc(ast_context: ^AstContext, node: ast.Ident) -> bool {
if strings.contains(node.name, "/") {
- return true;
+ return true
} else {
for imp in ast_context.imports {
if imp.base == node.name {
- return true;
+ return true
}
}
}
- return false;
+ return false
}
expand_struct_usings :: proc(ast_context: ^AstContext, symbol: index.Symbol, value: index.SymbolStructValue) -> index.SymbolStructValue {
- names := slice.to_dynamic(value.names, ast_context.allocator);
- types := slice.to_dynamic(value.types, ast_context.allocator);
+ names := slice.to_dynamic(value.names, ast_context.allocator)
+ types := slice.to_dynamic(value.types, ast_context.allocator)
for k, v in value.usings {
- ast_context.current_package = symbol.pkg;
+ ast_context.current_package = symbol.pkg
- field_expr: ^ast.Expr;
+ field_expr: ^ast.Expr
for name, i in value.names {
if name == k && v {
- field_expr = value.types[i];
+ field_expr = value.types[i]
}
}
if field_expr == nil {
- continue;
+ continue
}
if s, ok := resolve_type_expression(ast_context, field_expr); ok {
if struct_value, ok := s.value.(index.SymbolStructValue); ok {
for name in struct_value.names {
- append(&names, name);
+ append(&names, name)
}
for type in struct_value.types {
- append(&types, type);
+ append(&types, type)
}
}
}
@@ -1421,126 +1419,126 @@ expand_struct_usings :: proc(ast_context: ^AstContext, symbol: index.Symbol, val
return {
names = names[:],
types = types[:],
- };
+ }
}
resolve_symbol_return :: proc(ast_context: ^AstContext, symbol: index.Symbol, ok := true) -> (index.Symbol, bool) {
if !ok {
- return symbol, ok;
+ return symbol, ok
}
- symbol := symbol;
+ symbol := symbol
if symbol.type == .Unresolved {
- resolve_unresolved_symbol(ast_context, &symbol);
+ resolve_unresolved_symbol(ast_context, &symbol)
}
#partial switch v in &symbol.value {
case index.SymbolProcedureGroupValue:
- if symbol, ok := resolve_function_overload(ast_context, v.group.derived.(ast.Proc_Group)); ok {
- return symbol, true;
+ if symbol, ok := resolve_function_overload(ast_context, v.group.derived.(^ast.Proc_Group)^); ok {
+ return symbol, true
} else {
- return symbol, false;
+ return symbol, false
}
case index.SymbolProcedureValue:
if v.generic {
if resolved_symbol, ok := resolve_generic_function(ast_context, v.arg_types, v.return_types); ok {
- return resolved_symbol, ok;
+ return resolved_symbol, ok
} else {
- return symbol, true;
+ return symbol, true
}
} else {
- return symbol, true;
+ return symbol, true
}
case index.SymbolUnionValue:
if v.poly != nil {
//Todo(daniel): Maybe change the function to return a new symbol instead of referencing it.
//resolving the poly union means changing the type, so we do a copy of it.
- types := make([dynamic]^ast.Expr, ast_context.allocator);
- append_elems(&types, ..v.types);
- v.types = types[:];
- resolve_poly_union(ast_context, v.poly, &symbol);
+ types := make([dynamic]^ast.Expr, ast_context.allocator)
+ append_elems(&types, ..v.types)
+ v.types = types[:]
+ resolve_poly_union(ast_context, v.poly, &symbol)
}
- return symbol, ok;
+ return symbol, ok
case index.SymbolStructValue:
if v.poly != nil {
//Todo(daniel): Maybe change the function to return a new symbol instead of referencing it.
//resolving the struct union means changing the type, so we do a copy of it.
- types := make([dynamic]^ast.Expr, ast_context.allocator);
- append_elems(&types, ..v.types);
- v.types = types[:];
- resolve_poly_struct(ast_context, v.poly, &symbol);
+ types := make([dynamic]^ast.Expr, ast_context.allocator)
+ append_elems(&types, ..v.types)
+ v.types = types[:]
+ resolve_poly_struct(ast_context, v.poly, &symbol)
}
//expand the types and names from the using - can't be done while indexing without complicating everything(this also saves memory)
if len(v.usings) > 0 {
- expanded := symbol;
- expanded.value = expand_struct_usings(ast_context, symbol, v);
- return expanded, true;
+ expanded := symbol
+ expanded.value = expand_struct_usings(ast_context, symbol, v)
+ return expanded, true
} else {
- return symbol, true;
+ return symbol, true
}
case index.SymbolGenericValue:
- ret, ok := resolve_type_expression(ast_context, v.expr);
- return ret, ok;
+ ret, ok := resolve_type_expression(ast_context, v.expr)
+ return ret, ok
}
- return symbol, true;
+ return symbol, true
}
resolve_unresolved_symbol :: proc(ast_context: ^AstContext, symbol: ^index.Symbol) {
- using index;
+ using index
if symbol.type != .Unresolved {
- return;
+ return
}
#partial switch v in symbol.value {
case SymbolStructValue:
- symbol.type = .Struct;
+ symbol.type = .Struct
case SymbolPackageValue:
- symbol.type = .Package;
+ symbol.type = .Package
case SymbolProcedureValue, SymbolProcedureGroupValue:
- symbol.type = .Function;
+ symbol.type = .Function
case SymbolUnionValue:
- symbol.type = .Enum;
+ symbol.type = .Enum
case SymbolEnumValue:
- symbol.type = .Enum;
+ symbol.type = .Enum
case SymbolBitSetValue:
- symbol.type = .Enum;
+ symbol.type = .Enum
case index.SymbolGenericValue:
- ast_context.current_package = symbol.pkg;
+ ast_context.current_package = symbol.pkg
if ret, ok := resolve_type_expression(ast_context, v.expr); ok {
- symbol.type = ret.type;
- symbol.signature = ret.signature;
+ symbol.type = ret.type
+ symbol.signature = ret.signature
}
}
}
resolve_location_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (index.Symbol, bool) {
- symbol: index.Symbol;
+ symbol: index.Symbol
if local := get_local(ast_context, node.pos.offset, node.name); local != nil {
- symbol.range = common.get_token_range(get_local(ast_context, node.pos.offset, node.name), ast_context.file.src);
- return symbol, true;
+ symbol.range = common.get_token_range(get_local(ast_context, node.pos.offset, node.name), ast_context.file.src)
+ 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);
- return symbol, true;
+ symbol.range = common.get_token_range(global.expr, ast_context.file.src)
+ return symbol, true
}
if symbol, ok := index.lookup(node.name, ast_context.document_package); ok {
- return symbol, ok;
+ return symbol, ok
}
- usings := get_using_packages(ast_context);
+ usings := get_using_packages(ast_context)
for pkg in usings {
if symbol, ok := index.lookup(node.name, pkg); ok {
- return symbol, ok;
+ return symbol, ok
}
}
- return {}, false;
+ return {}, false
}
resolve_first_symbol_from_binary_expression :: proc(ast_context: ^AstContext, binary: ^ast.Binary_Expr) -> (index.Symbol, bool) {
@@ -1548,87 +1546,87 @@ resolve_first_symbol_from_binary_expression :: proc(ast_context: ^AstContext, bi
if binary.left != nil {
- if ident, ok := binary.left.derived.(ast.Ident); ok {
- if s, ok := resolve_type_identifier(ast_context, ident); ok {
- return s, ok;
+ if ident, ok := binary.left.derived.(^ast.Ident); ok {
+ if s, ok := resolve_type_identifier(ast_context, ident^); ok {
+ return s, ok
}
- } else if _, ok := binary.left.derived.(ast.Binary_Expr); 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 {
- return s, ok;
+ return s, ok
}
}
}
if binary.right != nil {
- if ident, ok := binary.right.derived.(ast.Ident); ok {
- if s, ok := resolve_type_identifier(ast_context, ident); ok {
- return s, ok;
+ if ident, ok := binary.right.derived.(^ast.Ident); ok {
+ if s, ok := resolve_type_identifier(ast_context, ident^); ok {
+ return s, ok
}
- } else if _, ok := binary.right.derived.(ast.Binary_Expr); 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 {
- return s, ok;
+ return s, ok
}
}
}
- return {}, false;
+ return {}, false
}
find_position_in_call_param :: proc(ast_context: ^AstContext, call: ast.Call_Expr) -> (int, bool) {
if call.args == nil {
- return 0, false;
+ return 0, false
}
for arg, i in call.args {
if position_in_node(arg, ast_context.position) {
- return i, true;
+ return i, true
}
}
- return len(call.args) - 1, true;
+ return len(call.args) - 1, true
}
make_pointer_ast :: proc(ast_context: ^AstContext, elem: ^ast.Expr) -> ^ast.Pointer_Type {
- pointer := index.new_type(ast.Pointer_Type, elem.pos, elem.end, ast_context.allocator);
- pointer.elem = elem;
- return pointer;
+ pointer := index.new_type(ast.Pointer_Type, elem.pos, elem.end, ast_context.allocator)
+ pointer.elem = elem
+ return pointer
}
make_bool_ast :: proc(ast_context: ^AstContext) -> ^ast.Ident {
- ident := index.new_type(ast.Ident, {}, {}, ast_context.allocator);
- ident.name = "bool";
- return ident;
+ ident := index.new_type(ast.Ident, {}, {}, ast_context.allocator)
+ ident.name = "bool"
+ return ident
}
make_int_ast :: proc(ast_context: ^AstContext) -> ^ast.Ident {
- ident := index.new_type(ast.Ident, {}, {}, ast_context.allocator);
- ident.name = "int";
- return ident;
+ ident := index.new_type(ast.Ident, {}, {}, ast_context.allocator)
+ ident.name = "int"
+ return ident
}
make_int_basic_value :: proc(ast_context: ^AstContext, n: int) -> ^ast.Basic_Lit {
- basic := index.new_type(ast.Basic_Lit, {}, {}, ast_context.allocator);
- basic.tok.text = fmt.tprintf("%v", n);
- return basic;
+ basic := index.new_type(ast.Basic_Lit, {}, {}, ast_context.allocator)
+ basic.tok.text = fmt.tprintf("%v", n)
+ return basic
}
get_package_from_node :: proc(node: ast.Node) -> string {
- slashed, _ := filepath.to_slash(node.pos.file, context.temp_allocator);
+ slashed, _ := filepath.to_slash(node.pos.file, context.temp_allocator)
- when ODIN_OS == "windows" {
- ret := strings.to_lower(path.dir(slashed, context.temp_allocator), context.temp_allocator);
+ when ODIN_OS == .Windows {
+ ret := strings.to_lower(path.dir(slashed, context.temp_allocator), context.temp_allocator)
} else {
- ret := path.dir(slashed, context.temp_allocator);
+ ret := path.dir(slashed, context.temp_allocator)
}
- return ret;
+ return ret
}
get_using_packages :: proc(ast_context: ^AstContext) -> []string {
- usings := make([]string, len(ast_context.usings), context.temp_allocator);
+ usings := make([]string, len(ast_context.usings), context.temp_allocator)
if len(ast_context.usings) == 0 {
- return usings;
+ return usings
}
//probably map instead
@@ -1637,12 +1635,12 @@ get_using_packages :: proc(ast_context: ^AstContext) -> []string {
for imp in ast_context.imports {
if strings.compare(imp.base, u) == 0 {
- usings[i] = imp.name;
+ usings[i] = imp.name
}
}
}
- return usings;
+ return usings
}
make_symbol_procedure_from_ast :: proc(ast_context: ^AstContext, n: ^ast.Node, v: ast.Proc_Type, name: string) -> index.Symbol {
@@ -1651,35 +1649,35 @@ make_symbol_procedure_from_ast :: proc(ast_context: ^AstContext, n: ^ast.Node, v
type = .Function,
pkg = get_package_from_node(n^),
name = name,
- };
+ }
- return_types := make([dynamic]^ast.Field, ast_context.allocator);
- arg_types := make([dynamic]^ast.Field, ast_context.allocator);
+ return_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 {
- append(&return_types, ret);
+ append(&return_types, ret)
}
}
if v.params != nil {
for param in v.params.list {
- append(&arg_types, param);
+ append(&arg_types, param)
}
}
if expr, ok := ast_context.globals[name]; ok {
if expr.deprecated {
- symbol.flags |= {.Distinct};
+ symbol.flags |= {.Distinct}
}
}
symbol.value = index.SymbolProcedureValue {
return_types = return_types[:],
arg_types = arg_types[:],
- };
+ }
- return symbol;
+ return symbol
}
make_symbol_array_from_ast :: proc(ast_context: ^AstContext, v: ast.Array_Type) -> index.Symbol {
@@ -1687,20 +1685,20 @@ make_symbol_array_from_ast :: proc(ast_context: ^AstContext, v: ast.Array_Type)
range = common.get_token_range(v.node, ast_context.file.src),
type = .Variable,
pkg = get_package_from_node(v.node),
- };
+ }
if v.len != nil {
symbol.value = index.SymbolFixedArrayValue {
expr = v.elem,
len = v.len,
- };
+ }
} else {
symbol.value = index.SymbolSliceValue {
expr = v.elem,
- };
+ }
}
- return symbol;
+ return symbol
}
make_symbol_dynamic_array_from_ast :: proc(ast_context: ^AstContext, v: ast.Dynamic_Array_Type) -> index.Symbol {
@@ -1708,13 +1706,13 @@ make_symbol_dynamic_array_from_ast :: proc(ast_context: ^AstContext, v: ast.Dyna
range = common.get_token_range(v.node, ast_context.file.src),
type = .Variable,
pkg = get_package_from_node(v.node),
- };
+ }
symbol.value = index.SymbolDynamicArrayValue {
expr = v.elem,
- };
+ }
- return symbol;
+ return symbol
}
make_symbol_map_from_ast :: proc(ast_context: ^AstContext, v: ast.Map_Type) -> index.Symbol {
@@ -1722,14 +1720,14 @@ make_symbol_map_from_ast :: proc(ast_context: ^AstContext, v: ast.Map_Type) -> i
range = common.get_token_range(v.node, ast_context.file.src),
type = .Variable,
pkg = get_package_from_node(v.node),
- };
+ }
symbol.value = index.SymbolMapValue {
key = v.key,
value = v.value,
- };
+ }
- return symbol;
+ return symbol
}
make_symbol_basic_type_from_ast :: proc(ast_context: ^AstContext, n: ^ast.Node, v: ^ast.Ident) -> index.Symbol {
@@ -1737,13 +1735,13 @@ make_symbol_basic_type_from_ast :: proc(ast_context: ^AstContext, n: ^ast.Node,
range = common.get_token_range(n^, ast_context.file.src),
type = .Variable,
pkg = get_package_from_node(n^),
- };
+ }
symbol.value = index.SymbolBasicValue {
ident = v,
- };
+ }
- return symbol;
+ return symbol
}
make_symbol_union_from_ast :: proc(ast_context: ^AstContext, v: ast.Union_Type, ident: string, inlined := false) -> index.Symbol {
@@ -1752,22 +1750,22 @@ make_symbol_union_from_ast :: proc(ast_context: ^AstContext, v: ast.Union_Type,
type = .Union,
pkg = get_package_from_node(v.node),
name = ident,
- };
+ }
if inlined {
- symbol.flags |= {.Anonymous};
- symbol.name = "union";
+ symbol.flags |= {.Anonymous}
+ symbol.name = "union"
}
symbol.value = index.SymbolUnionValue {
types = v.variants,
- };
+ }
if v.poly_params != nil {
- resolve_poly_union(ast_context, v.poly_params, &symbol);
+ resolve_poly_union(ast_context, v.poly_params, &symbol)
}
- return symbol;
+ return symbol
}
make_symbol_enum_from_ast :: proc(ast_context: ^AstContext, v: ast.Enum_Type, ident: string, inlined := false) -> index.Symbol {
@@ -1776,33 +1774,33 @@ make_symbol_enum_from_ast :: proc(ast_context: ^AstContext, v: ast.Enum_Type, id
type = .Enum,
name = ident,
pkg = get_package_from_node(v.node),
- };
+ }
if inlined {
- symbol.flags |= {.Anonymous};
- symbol.name = "enum";
+ symbol.flags |= {.Anonymous}
+ symbol.name = "enum"
}
- names := make([dynamic]string, ast_context.allocator);
+ names := make([dynamic]string, ast_context.allocator)
for n in v.fields {
- if ident, ok := n.derived.(ast.Ident); ok {
- append(&names, ident.name);
- } 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 {
- append(&names, binary.left.derived.(ast.Ident).name);
+ if ident, ok := n.derived.(^ast.Ident); ok {
+ append(&names, ident.name)
+ } 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 {
+ append(&names, binary.left.derived.(^ast.Ident).name)
}
}
}
symbol.value = index.SymbolEnumValue {
names = names[:],
- };
+ }
- return symbol;
+ return symbol
}
make_symbol_bitset_from_ast :: proc(ast_context: ^AstContext, v: ast.Bit_Set_Type, ident: string, inlined := false) -> index.Symbol {
@@ -1811,18 +1809,18 @@ make_symbol_bitset_from_ast :: proc(ast_context: ^AstContext, v: ast.Bit_Set_Typ
type = .Enum,
name = ident,
pkg = get_package_from_node(v.node),
- };
+ }
if inlined {
- symbol.flags |= {.Anonymous};
- symbol.name = "bitset";
+ symbol.flags |= {.Anonymous}
+ symbol.name = "bitset"
}
symbol.value = index.SymbolBitSetValue {
expr = v.elem,
- };
+ }
- return symbol;
+ return symbol
}
make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type, ident: string, inlined := false) -> index.Symbol {
@@ -1831,25 +1829,25 @@ make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type
type = .Struct,
pkg = get_package_from_node(v.node),
name = ident,
- };
+ }
if inlined {
- symbol.flags |= {.Anonymous};
- symbol.name = "struct";
+ symbol.flags |= {.Anonymous}
+ symbol.name = "struct"
}
- names := make([dynamic]string, ast_context.allocator);
- types := make([dynamic]^ast.Expr, ast_context.allocator);
- usings := make(map[string]bool, 0, ast_context.allocator);
+ names := make([dynamic]string, ast_context.allocator)
+ types := make([dynamic]^ast.Expr, ast_context.allocator)
+ usings := make(map[string]bool, 0, ast_context.allocator)
for field in v.fields.list {
for n in field.names {
- if identifier, ok := n.derived.(ast.Ident); ok {
- append(&names, identifier.name);
- append(&types, index.clone_type(field.type, ast_context.allocator, nil));
+ if identifier, ok := n.derived.(^ast.Ident); ok {
+ append(&names, identifier.name)
+ append(&types, index.clone_type(field.type, ast_context.allocator, nil))
if .Using in field.flags {
- usings[identifier.name] = true;
+ usings[identifier.name] = true
}
}
}
@@ -1859,73 +1857,73 @@ make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type
names = names[:],
types = types[:],
usings = usings,
- };
+ }
if v.poly_params != nil {
- resolve_poly_struct(ast_context, v.poly_params, &symbol);
+ resolve_poly_struct(ast_context, v.poly_params, &symbol)
}
//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.(index.SymbolStructValue));
+ symbol.value = expand_struct_usings(ast_context, symbol, symbol.value.(index.SymbolStructValue))
}
- return symbol;
+ return symbol
}
resolve_poly_union :: proc(ast_context: ^AstContext, poly_params: ^ast.Field_List, symbol: ^index.Symbol) {
if ast_context.call == nil {
- return;
+ return
}
- symbol_value := &symbol.value.(index.SymbolUnionValue);
+ symbol_value := &symbol.value.(index.SymbolUnionValue)
if symbol_value == nil {
- return;
+ return
}
- i := 0;
+ i := 0
- poly_map := make(map[string]^ast.Expr, 0, context.temp_allocator);
+ poly_map := make(map[string]^ast.Expr, 0, context.temp_allocator)
for param in poly_params.list {
for name in param.names {
if len(ast_context.call.args) <= i {
- break;
+ break
}
if param.type == nil {
- continue;
+ 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 {
+ 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 {
if poly.type != nil {
- poly_map[poly.type.name] = ast_context.call.args[i];
+ poly_map[poly.type.name] = ast_context.call.args[i]
}
}
}
- i += 1;
+ i += 1
}
}
for type, i in symbol_value.types {
- if ident, ok := type.derived.(ast.Ident); ok {
+ if ident, ok := type.derived.(^ast.Ident); ok {
if expr, ok := poly_map[ident.name]; ok {
- symbol_value.types[i] = expr;
+ symbol_value.types[i] = expr
}
- } else if call_expr, ok := type.derived.(ast.Call_Expr); ok {
+ } else if call_expr, ok := type.derived.(^ast.Call_Expr); ok {
if call_expr.args == nil {
- continue;
+ continue
}
for arg, i in call_expr.args {
- if ident, ok := arg.derived.(ast.Ident); ok {
+ if ident, ok := arg.derived.(^ast.Ident); ok {
if expr, ok := poly_map[ident.name]; ok {
- symbol_value.types[i] = expr;
+ symbol_value.types[i] = expr
}
}
}
@@ -1935,57 +1933,57 @@ 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: ^index.Symbol) {
if ast_context.call == nil {
- return;
+ return
}
- symbol_value := &symbol.value.(index.SymbolStructValue);
+ symbol_value := &symbol.value.(index.SymbolStructValue)
if symbol_value == nil {
- return;
+ return
}
- i := 0;
+ i := 0
- poly_map := make(map[string]^ast.Expr, 0, context.temp_allocator);
+ poly_map := make(map[string]^ast.Expr, 0, context.temp_allocator)
for param in poly_params.list {
for name in param.names {
if len(ast_context.call.args) <= i {
- break;
+ break
}
if param.type == nil {
- continue;
+ 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 {
+ 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 {
if poly.type != nil {
- poly_map[poly.type.name] = ast_context.call.args[i];
+ poly_map[poly.type.name] = ast_context.call.args[i]
}
}
}
- i += 1;
+ i += 1
}
}
for type, i in symbol_value.types {
- if ident, ok := type.derived.(ast.Ident); ok {
+ if ident, ok := type.derived.(^ast.Ident); ok {
if expr, ok := poly_map[ident.name]; ok {
- symbol_value.types[i] = expr;
+ symbol_value.types[i] = expr
}
- } else if call_expr, ok := type.derived.(ast.Call_Expr); ok {
+ } else if call_expr, ok := type.derived.(^ast.Call_Expr); ok {
if call_expr.args == nil {
- continue;
+ continue
}
for arg, i in call_expr.args {
- if ident, ok := arg.derived.(ast.Ident); ok {
+ if ident, ok := arg.derived.(^ast.Ident); ok {
if expr, ok := poly_map[ident.name]; ok {
- symbol_value.types[i] = expr;
+ symbol_value.types[i] = expr
}
}
}
@@ -1994,149 +1992,149 @@ resolve_poly_struct :: proc(ast_context: ^AstContext, poly_params: ^ast.Field_Li
}
get_globals :: proc(file: ast.File, ast_context: ^AstContext) {
- ast_context.variables["context"] = true;
+ ast_context.variables["context"] = true
- exprs := common.collect_globals(file);
+ exprs := common.collect_globals(file)
for expr in exprs {
- ast_context.variables[expr.name] = expr.mutable;
- ast_context.globals[expr.name] = expr;
+ ast_context.variables[expr.name] = expr.mutable
+ ast_context.globals[expr.name] = expr
}
}
get_generic_assignment :: proc(file: ast.File, value: ^ast.Expr, ast_context: ^AstContext, results: ^[dynamic]^ast.Expr) {
- using ast;
+ using ast
- ast_context.use_locals = true;
- ast_context.use_globals = true;
+ ast_context.use_locals = true
+ ast_context.use_globals = true
- switch v in &value.derived {
- case Call_Expr:
- ast_context.call = cast(^ast.Call_Expr)value;
+ #partial switch v in value.derived {
+ 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.(index.SymbolProcedureValue); ok {
for ret in procedure.return_types {
- append(results, ret.type);
+ append(results, ret.type)
}
}
}
- case Comp_Lit:
+ case ^Comp_Lit:
if v.type != nil {
- append(results, v.type);
+ append(results, v.type)
}
- case Array_Type:
+ case ^Array_Type:
if v.elem != nil {
- append(results, v.elem);
+ append(results, v.elem)
}
- case Dynamic_Array_Type:
+ case ^Dynamic_Array_Type:
if v.elem != nil {
- append(results, v.elem);
+ append(results, v.elem)
}
- case Selector_Expr:
+ case ^Selector_Expr:
if v.expr != nil {
- append(results, value);
+ append(results, value)
}
- case Type_Assertion:
+ case ^Type_Assertion:
if v.type != nil {
//This is the unique .? that can only be used with maybe
- if unary, ok := v.type.derived.(ast.Unary_Expr); ok && unary.op.kind == .Question {
- append(results, cast(^ast.Expr)&v.node);
+ 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);
+ append(results, v.type)
}
- b := make_bool_ast(ast_context);
- b.pos.file = v.type.pos.file;
- append(results, b);
+ b := make_bool_ast(ast_context)
+ b.pos.file = v.type.pos.file
+ append(results, b)
}
case:
//log.debugf("default node get_generic_assignment %v", v);
- append(results, value);
+ append(results, value)
}
}
get_locals_value_decl :: proc(file: ast.File, value_decl: ast.Value_Decl, ast_context: ^AstContext) {
- using ast;
+ using ast
if len(value_decl.names) <= 0 {
- return;
+ return
}
if value_decl.type != nil {
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, value_decl.type, value_decl.end.offset, str, ast_context.local_id);
+ str := common.get_ast_node_string(value_decl.names[i], file.src)
+ ast_context.variables[str] = value_decl.is_mutable
+ store_local(ast_context, value_decl.type, value_decl.end.offset, str, ast_context.local_id)
}
- return;
+ return
}
- results := make([dynamic]^Expr, context.temp_allocator);
+ results := make([dynamic]^Expr, context.temp_allocator)
for value in value_decl.values {
- get_generic_assignment(file, value, ast_context, &results);
+ get_generic_assignment(file, value, ast_context, &results)
}
if len(results) == 0 {
- return;
+ return
}
for name, i in value_decl.names {
- 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, results[result_i], value_decl.end.offset, str, ast_context.local_id);
- ast_context.variables[str] = value_decl.is_mutable;
+ 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, 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) {
- ast_context.use_locals = true;
- ast_context.use_globals = true;
- ast_context.current_package = ast_context.document_package;
+ ast_context.use_locals = true
+ ast_context.use_globals = true
+ ast_context.current_package = ast_context.document_package
- using ast;
+ using ast
if stmt == nil {
- return;
+ return
}
if stmt.pos.offset > document_position.position {
- return;
- }
-
- switch v in stmt.derived {
- case Value_Decl:
- get_locals_value_decl(file, v, ast_context);
- case Type_Switch_Stmt:
- get_locals_type_switch_stmt(file, v, ast_context, document_position);
- case Switch_Stmt:
- get_locals_switch_stmt(file, v, ast_context, document_position);
- case For_Stmt:
- get_locals_for_stmt(file, v, ast_context, document_position);
- case Inline_Range_Stmt:
- get_locals_stmt(file, v.body, ast_context, document_position);
- case Range_Stmt:
- get_locals_for_range_stmt(file, v, ast_context, document_position);
- case If_Stmt:
- get_locals_if_stmt(file, v, ast_context, document_position);
- case Block_Stmt:
- get_locals_block_stmt(file, v, ast_context, document_position);
- case Proc_Lit:
- get_locals_stmt(file, v.body, ast_context, document_position);
- case Assign_Stmt:
+ return
+ }
+
+ #partial switch v in stmt.derived {
+ case ^Value_Decl:
+ get_locals_value_decl(file, v^, ast_context)
+ case ^Type_Switch_Stmt:
+ get_locals_type_switch_stmt(file, v^, ast_context, document_position)
+ case ^Switch_Stmt:
+ get_locals_switch_stmt(file, v^, ast_context, document_position)
+ case ^For_Stmt:
+ get_locals_for_stmt(file, v^, ast_context, document_position)
+ case ^Inline_Range_Stmt:
+ get_locals_stmt(file, v.body, ast_context, document_position)
+ case ^Range_Stmt:
+ get_locals_for_range_stmt(file, v^, ast_context, document_position)
+ case ^If_Stmt:
+ get_locals_if_stmt(file, v^, ast_context, document_position)
+ case ^Block_Stmt:
+ get_locals_block_stmt(file, v^, ast_context, document_position)
+ case ^Proc_Lit:
+ get_locals_stmt(file, v.body, ast_context, document_position)
+ case ^Assign_Stmt:
if save_assign {
- get_locals_assign_stmt(file, v, ast_context);
- }
- case Using_Stmt:
- get_locals_using_stmt(v, ast_context);
- case When_Stmt:
- get_locals_stmt(file, v.else_stmt, ast_context, document_position);
- get_locals_stmt(file, v.body, ast_context, document_position);
- case Case_Clause:
+ get_locals_assign_stmt(file, v^, ast_context)
+ }
+ case ^Using_Stmt:
+ get_locals_using_stmt(v^, ast_context)
+ case ^When_Stmt:
+ get_locals_stmt(file, v.else_stmt, ast_context, document_position)
+ get_locals_stmt(file, v.body, ast_context, document_position)
+ case ^Case_Clause:
for stmt in v.body {
- get_locals_stmt(file, stmt, ast_context, document_position);
+ get_locals_stmt(file, stmt, ast_context, document_position)
}
case:
//log.debugf("default node local stmt %v", v);
@@ -2145,11 +2143,11 @@ get_locals_stmt :: proc(file: ast.File, stmt: ^ast.Stmt, ast_context: ^AstContex
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;
+ return
}
for stmt in block.stmts {
- get_locals_stmt(file, stmt, ast_context, document_position);
+ get_locals_stmt(file, stmt, ast_context, document_position)
}
}
@@ -2158,17 +2156,17 @@ get_locals_using_stmt :: proc(stmt: ast.Using_Stmt, ast_context: ^AstContext) {
if symbol, ok := resolve_type_expression(ast_context, u); ok {
#partial switch v in symbol.value {
case index.SymbolPackageValue:
- if ident, ok := u.derived.(ast.Ident); ok {
- append(&ast_context.usings, ident.name);
+ if ident, ok := u.derived.(^ast.Ident); ok {
+ append(&ast_context.usings, ident.name)
}
case index.SymbolStructValue:
for name, i in v.names {
- selector := index.new_type(ast.Selector_Expr, v.types[i].pos, v.types[i].end, context.temp_allocator);
- selector.expr = u;
- selector.field = index.new_type(ast.Ident, v.types[i].pos, v.types[i].end, context.temp_allocator);
- selector.field.name = name;
- store_local(ast_context, selector, 0, name, ast_context.local_id);
- ast_context.variables[name] = true;
+ selector := index.new_type(ast.Selector_Expr, v.types[i].pos, v.types[i].end, context.temp_allocator)
+ selector.expr = u
+ selector.field = index.new_type(ast.Ident, v.types[i].pos, v.types[i].end, context.temp_allocator)
+ selector.field.name = name
+ store_local(ast_context, selector, 0, name, ast_context.local_id)
+ ast_context.variables[name] = true
}
}
}
@@ -2176,163 +2174,163 @@ 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) {
- using ast;
+ using ast
if stmt.lhs == nil || stmt.rhs == nil {
- return;
+ return
}
- results := make([dynamic]^Expr, context.temp_allocator);
+ results := make([dynamic]^Expr, context.temp_allocator)
for rhs in stmt.rhs {
- get_generic_assignment(file, rhs, ast_context, &results);
+ get_generic_assignment(file, rhs, ast_context, &results)
}
if len(stmt.lhs) != len(results) {
- return;
+ return
}
for lhs, i in stmt.lhs {
- if ident, ok := lhs.derived.(ast.Ident); ok {
- store_local(ast_context, results[i], ident.pos.offset, ident.name, ast_context.local_id);
- ast_context.variables[ident.name] = true;
+ if ident, ok := lhs.derived.(^ast.Ident); ok {
+ store_local(ast_context, 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) {
- return;
+ return
}
- get_locals_stmt(file, stmt.init, ast_context, document_position, true);
- get_locals_stmt(file, stmt.body, ast_context, document_position);
- get_locals_stmt(file, stmt.else_stmt, ast_context, document_position);
+ get_locals_stmt(file, stmt.init, ast_context, document_position, true)
+ get_locals_stmt(file, stmt.body, ast_context, document_position)
+ 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) {
- using ast;
+ using ast
if !(stmt.body.pos.offset <= document_position.position && document_position.position <= stmt.body.end.offset) {
- return;
+ return
}
- results := make([dynamic]^Expr, context.temp_allocator);
+ results := make([dynamic]^Expr, context.temp_allocator)
if stmt.expr == nil {
- return;
+ return
}
if symbol, ok := resolve_type_expression(ast_context, stmt.expr); ok {
#partial switch v in symbol.value {
case index.SymbolMapValue:
if len(stmt.vals) >= 1 {
- if ident, ok := stmt.vals[0].derived.(Ident); ok {
- store_local(ast_context, 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 ident, ok := stmt.vals[0].derived.(^Ident); ok {
+ store_local(ast_context, 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, 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;
+ if ident, ok := stmt.vals[1].derived.(^Ident); ok {
+ store_local(ast_context, 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
}
}
case index.SymbolDynamicArrayValue:
if len(stmt.vals) >= 1 {
- if ident, ok := stmt.vals[0].derived.(Ident); ok {
- store_local(ast_context, 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 ident, ok := stmt.vals[0].derived.(^Ident); ok {
+ store_local(ast_context, 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, 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;
+ if ident, ok := stmt.vals[1].derived.(^Ident); ok {
+ store_local(ast_context, 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
}
}
case index.SymbolFixedArrayValue:
if len(stmt.vals) >= 1 {
- if ident, ok := stmt.vals[0].derived.(Ident); ok {
- store_local(ast_context, 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 ident, ok := stmt.vals[0].derived.(^Ident); ok {
+ store_local(ast_context, 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, 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;
+ if ident, ok := stmt.vals[1].derived.(^Ident); ok {
+ store_local(ast_context, 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
}
}
case index.SymbolSliceValue:
if len(stmt.vals) >= 1 {
- if ident, ok := stmt.vals[0].derived.(Ident); ok {
- store_local(ast_context, 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 ident, ok := stmt.vals[0].derived.(^Ident); ok {
+ store_local(ast_context, 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, 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;
+ if ident, ok := stmt.vals[1].derived.(^Ident); ok {
+ store_local(ast_context, 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_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) {
- return;
+ return
}
- get_locals_stmt(file, stmt.init, ast_context, document_position, true);
- get_locals_stmt(file, stmt.body, ast_context, document_position);
+ get_locals_stmt(file, stmt.init, ast_context, document_position, true)
+ 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) {
- return;
+ return
}
- get_locals_stmt(file, stmt.body, ast_context, document_position);
+ 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) {
- using ast;
+ using ast
if !(stmt.pos.offset <= document_position.position && document_position.position <= stmt.end.offset) {
- return;
+ return
}
if stmt.body == nil {
- return;
+ return
}
- if block, ok := stmt.body.derived.(Block_Stmt); ok {
+ 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 {
for b in cause.body {
- get_locals_stmt(file, b, ast_context, document_position);
+ get_locals_stmt(file, b, ast_context, document_position)
}
- tag := stmt.tag.derived.(Assign_Stmt);
+ 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, cause.list[0], ident.pos.offset, ident.name, ast_context.local_id);
- ast_context.variables[ident.name] = true;
+ ident := tag.lhs[0].derived.(^Ident)
+ store_local(ast_context, cause.list[0], ident.pos.offset, ident.name, ast_context.local_id)
+ ast_context.variables[ident.name] = true
}
}
}
@@ -2340,32 +2338,32 @@ 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) {
- proc_lit, ok := function.derived.(ast.Proc_Lit);
+ proc_lit, ok := function.derived.(^ast.Proc_Lit)
if !ok || proc_lit.body == nil {
- return;
+ return
}
if proc_lit.type != nil && proc_lit.type.params != nil {
for arg in proc_lit.type.params.list {
for name in arg.names {
if arg.type != nil {
- str := common.get_ast_node_string(name, file.src);
- store_local(ast_context, arg.type, name.pos.offset, str, ast_context.local_id);
- ast_context.variables[str] = true;
- ast_context.parameters[str] = true;
+ str := common.get_ast_node_string(name, file.src)
+ store_local(ast_context, 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[0] = arg.type;
- get_locals_using_stmt(using_stmt, ast_context);
+ using_stmt: ast.Using_Stmt
+ 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, arg.default_value, name.pos.offset, str, ast_context.local_id);
- ast_context.variables[str] = true;
- ast_context.parameters[str] = true;
+ str := common.get_ast_node_string(name, file.src)
+ store_local(ast_context, arg.default_value, name.pos.offset, str, ast_context.local_id)
+ ast_context.variables[str] = true
+ ast_context.parameters[str] = true
}
}
}
@@ -2375,10 +2373,10 @@ get_locals_proc_param_and_results :: proc(file: ast.File, function: ast.Proc_Lit
for result in proc_lit.type.results.list {
for name in result.names {
if result.type != nil {
- str := common.get_ast_node_string(name, file.src);
- store_local(ast_context, result.type, name.pos.offset, str, ast_context.local_id);
- ast_context.variables[str] = true;
- ast_context.parameters[str] = true;
+ str := common.get_ast_node_string(name, file.src)
+ store_local(ast_context, result.type, name.pos.offset, str, ast_context.local_id)
+ ast_context.variables[str] = true
+ ast_context.parameters[str] = true
}
}
}
@@ -2386,50 +2384,50 @@ 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) {
- proc_lit, ok := function.derived.(ast.Proc_Lit);
+ proc_lit, ok := function.derived.(^ast.Proc_Lit)
if !ok || proc_lit.body == nil {
- return;
+ 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);
+ block: ^ast.Block_Stmt
+ block, ok = proc_lit.body.derived.(^ast.Block_Stmt)
if !ok {
- log.error("Proc_List body not block");
- return;
+ log.error("Proc_List body not block")
+ return
}
for stmt in block.stmts {
- get_locals_stmt(file, stmt, ast_context, document_position);
+ get_locals_stmt(file, stmt, ast_context, document_position)
}
}
clear_locals :: proc(ast_context: ^AstContext) {
- clear(&ast_context.locals);
- clear(&ast_context.parameters);
- clear(&ast_context.variables);
- clear(&ast_context.usings);
+ clear(&ast_context.locals)
+ clear(&ast_context.parameters)
+ clear(&ast_context.variables)
+ clear(&ast_context.usings)
}
resolve_entire_file :: proc(document: ^common.Document, allocator := context.allocator) -> map[uintptr]index.Symbol {
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, allocator);
+ ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri, allocator)
- get_globals(document.ast, &ast_context);
+ get_globals(document.ast, &ast_context)
- ast_context.current_package = ast_context.document_package;
+ ast_context.current_package = ast_context.document_package
- symbols := make(map[uintptr]index.Symbol, 100, allocator);
+ symbols := make(map[uintptr]index.Symbol, 100, allocator)
for k, v in ast_context.globals {
- resolve_entire_decl(&ast_context, v.expr, &symbols, allocator);
- clear_local_group(&ast_context, 0);
- add_local_group(&ast_context, 0);
+ resolve_entire_decl(&ast_context, v.expr, &symbols, allocator)
+ clear_local_group(&ast_context, 0)
+ add_local_group(&ast_context, 0)
}
- return symbols;
+ return symbols
}
resolve_entire_decl :: proc(ast_context: ^AstContext, decl: ^ast.Expr, symbols: ^map[uintptr]index.Symbol, allocator := context.allocator) {
@@ -2449,75 +2447,75 @@ resolve_entire_decl :: proc(ast_context: ^AstContext, decl: ^ast.Expr, symbols:
ast_context = ast_context,
symbols = symbols,
scopes = make([dynamic]Scope, allocator),
- };
+ }
visit :: proc(visitor: ^ast.Visitor, node: ^ast.Node) -> ^ast.Visitor {
if node == nil || visitor == nil {
- return nil;
+ return nil
}
- data := cast(^Visit_Data)visitor.data;
- ast_context := data.ast_context;
- ast_context.use_locals = true;
- ast_context.use_globals = true;
+ data := cast(^Visit_Data)visitor.data
+ ast_context := data.ast_context
+ ast_context.use_locals = true
+ ast_context.use_globals = true
//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);
+ clear_local_group(ast_context, current_scope.id)
- pop(&data.scopes);
+ pop(&data.scopes)
if len(data.scopes) > 0 {
- current_scope = data.scopes[len(data.scopes)-1];
- ast_context.local_id = current_scope.id;
+ current_scope = data.scopes[len(data.scopes)-1]
+ ast_context.local_id = current_scope.id
} else {
- ast_context.local_id = 0;
+ ast_context.local_id = 0
}
}
}
- switch v in &node.derived {
- case ast.If_Stmt, ast.For_Stmt, ast.Range_Stmt, ast.Inline_Range_Stmt, ast.Proc_Lit:
- scope: Scope;
- scope.id = data.id_counter;
- scope.offset = node.end.offset;
- data.id_counter += 1;
- ast_context.local_id = scope.id;
+ #partial switch v in node.derived {
+ case ^ast.If_Stmt, ^ast.For_Stmt, ^ast.Range_Stmt, ^ast.Inline_Range_Stmt, ^ast.Proc_Lit:
+ scope: Scope
+ scope.id = data.id_counter
+ scope.offset = node.end.offset
+ data.id_counter += 1
+ ast_context.local_id = scope.id
- append(&data.scopes, scope);
- add_local_group(ast_context, scope.id);
+ append(&data.scopes, scope)
+ add_local_group(ast_context, scope.id)
- position_context: DocumentPositionContext;
- position_context.position = node.end.offset;
- get_locals_stmt(ast_context.file, cast(^ast.Stmt)node, ast_context, &position_context);
- case ast.Ident:
- if symbol, ok := resolve_type_identifier(ast_context, v); ok {
- data.symbols[cast(uintptr)node] = symbol;
+ position_context: DocumentPositionContext
+ position_context.position = node.end.offset
+ get_locals_stmt(ast_context.file, cast(^ast.Stmt)node, ast_context, &position_context)
+ case ^ast.Ident:
+ if symbol, ok := resolve_type_identifier(ast_context, v^); ok {
+ data.symbols[cast(uintptr)node] = symbol
}
- case ast.Selector_Expr:
+ case ^ast.Selector_Expr:
if symbol, ok := resolve_type_expression(ast_context, &v.node); ok {
- data.symbols[cast(uintptr)node] = symbol;
+ data.symbols[cast(uintptr)node] = symbol
}
- case ast.Call_Expr:
+ case ^ast.Call_Expr:
if symbol, ok := resolve_type_expression(ast_context, &v.node); ok {
- data.symbols[cast(uintptr)node] = symbol;
+ data.symbols[cast(uintptr)node] = symbol
}
}
- switch v in &node.derived {
- case ast.Proc_Lit:
+ #partial switch v in node.derived {
+ case ^ast.Proc_Lit:
if v.body == nil {
- break;
+ break
}
- type_position_context: DocumentPositionContext;
- type_position_context.position = v.end.offset;
- get_locals_proc_param_and_results(ast_context.file, v, ast_context, &type_position_context);
+ type_position_context: DocumentPositionContext
+ type_position_context.position = v.end.offset
+ get_locals_proc_param_and_results(ast_context.file, v^, ast_context, &type_position_context)
}
- return visitor;
+ return visitor
}
visitor := ast.Visitor {
@@ -2525,7 +2523,7 @@ resolve_entire_decl :: proc(ast_context: ^AstContext, decl: ^ast.Expr, symbols:
visit = visit,
}
- ast.walk(&visitor, decl);
+ ast.walk(&visitor, decl)
}
concatenate_symbol_information :: proc {
@@ -2534,113 +2532,113 @@ concatenate_symbol_information :: proc {
}
concatenate_raw_symbol_information :: proc(ast_context: ^AstContext, symbol: index.Symbol, is_completion: bool) -> string {
- return concatenate_raw_string_information(ast_context, symbol.pkg, symbol.name, symbol.signature, symbol.type, is_completion);
+ 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: index.SymbolType, is_completion: bool) -> string {
- pkg := path.base(pkg, false, context.temp_allocator);
+ pkg := path.base(pkg, false, context.temp_allocator)
if type == .Package {
- return fmt.tprintf("%v: package", name);
+ return fmt.tprintf("%v: package", name)
} else if type == .Keyword && is_completion {
- return name;
+ return name
} else {
if signature != "" {
- return fmt.tprintf("%v.%v: %v", pkg, name, signature);
+ return fmt.tprintf("%v.%v: %v", pkg, name, signature)
} else {
- return fmt.tprintf("%v.%v", pkg, name);
+ return fmt.tprintf("%v.%v", pkg, name)
}
}
}
unwrap_enum :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (index.SymbolEnumValue, bool) {
if node == nil {
- return {}, false;
+ return {}, false
}
if enum_symbol, ok := resolve_type_expression(ast_context, node); ok {
if enum_value, ok := enum_symbol.value.(index.SymbolEnumValue); ok {
- return enum_value, true;
+ return enum_value, true
}
}
- return {}, false;
+ return {}, false
}
unwrap_union :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (index.SymbolUnionValue, bool) {
if union_symbol, ok := resolve_type_expression(ast_context, node); ok {
if union_value, ok := union_symbol.value.(index.SymbolUnionValue); ok {
- return union_value, true;
+ return union_value, true
}
}
- return {}, false;
+ return {}, false
}
unwrap_bitset :: proc(ast_context: ^AstContext, bitset_symbol: index.Symbol) -> (index.SymbolEnumValue, bool) {
if bitset_value, ok := bitset_symbol.value.(index.SymbolBitSetValue); ok {
if enum_symbol, ok := resolve_type_expression(ast_context, bitset_value.expr); ok {
if enum_value, ok := enum_symbol.value.(index.SymbolEnumValue); ok {
- return enum_value, true;
+ return enum_value, true
}
}
}
- return {}, false;
+ return {}, false
}
get_signature :: proc(ast_context: ^AstContext, ident: ast.Ident, symbol: index.Symbol, was_variable := false) -> string {
- using index;
+ using index
if symbol.type == .Function {
- return symbol.signature;
+ return symbol.signature
}
if .Distinct in symbol.flags {
- return symbol.name;
+ return symbol.name
}
- is_variable := symbol.type == .Variable;
+ is_variable := symbol.type == .Variable
#partial switch v in symbol.value {
case SymbolBasicValue:
- return common.node_to_string(v.ident);
+ return common.node_to_string(v.ident)
case SymbolBitSetValue:
- return common.node_to_string(v.expr);
+ return common.node_to_string(v.expr)
case SymbolEnumValue:
if is_variable {
- return symbol.name;
+ return symbol.name
}
else {
- return "enum";
+ 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";
+ return "proc"
case SymbolStructValue:
if is_variable {
- return symbol.name;
+ return symbol.name
}
else {
- return "struct";
+ return "struct"
}
case SymbolUnionValue:
if is_variable {
- return symbol.name;
+ return symbol.name
}
else {
- return "union";
+ return "union"
}
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";
+ return "package"
case SymbolUntypedValue:
switch v.type {
case .Float: return "float"
@@ -2650,74 +2648,71 @@ get_signature :: proc(ast_context: ^AstContext, ident: ast.Ident, symbol: index.
}
}
- return "";
+ return ""
}
position_in_proc_decl :: proc(position_context: ^DocumentPositionContext) -> bool {
if position_context.value_decl == nil {
- return false;
+ return false
}
if len(position_context.value_decl.values) != 1 {
- return false;
+ return false
}
- if _, ok := position_context.value_decl.values[0].derived.(ast.Proc_Type); ok {
- return true;
+ 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, 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;
+ return true
}
}
- return false;
+ return false
}
is_lhs_comp_lit :: proc(position_context: ^DocumentPositionContext) -> bool {
-
if position_context.position <= position_context.comp_lit.open.offset {
- return false;
+ return false
}
if len(position_context.comp_lit.elems) == 0 {
- return true;
+ return true
}
for elem in position_context.comp_lit.elems {
-
if position_in_node(elem, position_context.position) {
-
- if ident, ok := elem.derived.(ast.Ident); ok {
- return true;
- } else if field, ok := elem.derived.(ast.Field_Value); ok {
+ if ident, ok := elem.derived.(^ast.Ident); ok {
+ return true
+ } else if field, ok := elem.derived.(^ast.Field_Value); ok {
if position_in_node(field.value, position_context.position) {
- return false;
+ return false
}
}
}
}
- return true;
+ return true
}
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, ok := elem.derived.(^ast.Field_Value); ok {
if field.field != nil {
- if ident, ok := field.field.derived.(ast.Ident); ok {
+ if ident, ok := field.field.derived.(^ast.Ident); ok {
if ident.name == name {
- return true;
+ return true
}
}
}
}
}
- return false;
+ return false
}
/*
@@ -2725,183 +2720,183 @@ field_exists_in_comp_lit :: proc(comp_lit: ^ast.Comp_Lit, name: string) -> bool
*/
get_call_commas :: proc(position_context: ^DocumentPositionContext, document: ^common.Document) {
if position_context.call == nil {
- return;
+ return
}
- commas := make([dynamic]int, 0, 10, context.temp_allocator);
+ commas := make([dynamic]int, 0, 10, context.temp_allocator)
- paren_count := 0;
- bracket_count := 0;
- brace_count := 0;
+ paren_count := 0
+ bracket_count := 0
+ brace_count := 0
- if call, ok := position_context.call.derived.(ast.Call_Expr); ok {
+ if call, ok := position_context.call.derived.(^ast.Call_Expr); ok {
if document.text[call.open.offset] == '(' {
- paren_count -= 1;
+ paren_count -= 1
}
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);
+ append(&commas, i)
}
}
}
}
- position_context.call_commas = commas[:];
+ position_context.call_commas = commas[:]
}
type_to_string :: proc(ast_context: ^AstContext, expr: ^ast.Expr) -> string {
if symbol, ok := resolve_type_expression(ast_context, expr); ok {
if .Anonymous in symbol.flags {
- return symbol.name;
+ return symbol.name
}
}
- return common.node_to_string(expr);
+ return common.node_to_string(expr)
}
/*
Figure out what exactly is at the given position and whether it is in a function, struct, etc.
*/
get_document_position_context :: proc(document: ^common.Document, position: common.Position, hint: DocumentPositionContextHint) -> (DocumentPositionContext, bool) {
- position_context: DocumentPositionContext;
+ position_context: DocumentPositionContext
- position_context.hint = hint;
- position_context.file = document.ast;
- position_context.line = position.line;
+ 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");
- return position_context, false;
+ log.error("failed to get absolute position")
+ return position_context, false
}
- position_context.position = absolute_position;
+ position_context.position = absolute_position
- exists_in_decl := false;
+ exists_in_decl := false
for decl in document.ast.decls {
if position_in_node(decl, position_context.position) {
- get_document_position(decl, &position_context);
- exists_in_decl = true;
- switch v in decl.derived {
- case ast.Expr_Stmt:
- position_context.global_lhs_stmt = true;
+ get_document_position(decl, &position_context)
+ exists_in_decl = true
+ #partial switch v in decl.derived {
+ case ^ast.Expr_Stmt:
+ position_context.global_lhs_stmt = true
}
- break;
+ break
}
}
for import_stmt in document.ast.imports {
if position_in_node(import_stmt, position_context.position) {
- position_context.import_stmt = import_stmt;
- break;
+ position_context.import_stmt = import_stmt
+ break
}
}
if !exists_in_decl && position_context.import_stmt == nil {
- position_context.abort_completion = true;
+ position_context.abort_completion = true
}
if !position_in_node(position_context.comp_lit, position_context.position) {
- position_context.comp_lit = nil;
+ position_context.comp_lit = nil
}
if !position_in_node(position_context.parent_comp_lit, position_context.position) {
- position_context.parent_comp_lit = nil;
+ position_context.parent_comp_lit = nil
}
if !position_in_node(position_context.assign, position_context.position) {
- position_context.assign = nil;
+ position_context.assign = nil
}
if !position_in_node(position_context.binary, position_context.position) {
- position_context.binary = nil;
+ position_context.binary = nil
}
if !position_in_node(position_context.parent_binary, position_context.position) {
- position_context.parent_binary = nil;
+ position_context.parent_binary = nil
}
if hint == .Completion && position_context.selector == nil && position_context.field == nil {
- fallback_position_context_completion(document, position, &position_context);
+ 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);
+ fallback_position_context_signature(document, position, &position_context)
}
if hint == .SignatureHelp {
- get_call_commas(&position_context, document);
+ get_call_commas(&position_context, document)
}
- return position_context, true;
+ return position_context, true
}
//terrible fallback code
fallback_position_context_completion :: proc(document: ^common.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;
- partial_arrow: bool;
+ 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
+ partial_arrow: bool
- i := position_context.position - 1;
+ i := position_context.position - 1
- end = i;
+ end = i
for i > 0 {
- c := position_context.file.src[i];
+ c := position_context.file.src[i]
if c == '(' && paren_count == 0 {
- start = i + 1;
- break;
+ start = i + 1
+ break
} else if c == '[' && bracket_count == 0 {
- start = i + 1;
- break;
+ start = i + 1
+ break
} else if c == ']' && !last_dot {
- start = i + 1;
- break;
+ start = i + 1
+ break
} else if c == ')' && !last_dot {
- start = i + 1;
- break;
+ start = i + 1
+ break
} else if c == ')' {
- paren_count -= 1;
+ paren_count -= 1
} else if c == '(' {
- paren_count += 1;
+ paren_count += 1
} else if c == '[' {
- bracket_count += 1;
+ bracket_count += 1
} else if c == ']' {
- bracket_count -= 1;
+ bracket_count -= 1
} else if c == '.' {
- dots_seen += 1;
- last_dot = true;
- i -= 1;
- continue;
+ dots_seen += 1
+ last_dot = true
+ i -= 1
+ continue
} else if position_context.file.src[max(0, i - 1)] == '-' && c == '>' {
- last_arrow = true;
- i -= 2;
- continue;
+ last_arrow = true
+ i -= 2
+ continue
}
//ignore everything in the bracket
if bracket_count != 0 || paren_count != 0 {
- i -= 1;
- continue;
+ i -= 1
+ continue
}
//yeah..
@@ -2910,51 +2905,51 @@ fallback_position_context_completion :: proc(document: ^common.Document, positio
c == '\n' || c == '\r' || c == '=' ||
c == '<' || c == '-' || c == '!' ||
c == '+' || c == '&'|| c == '|' {
- start = i + 1;
- break;
+ start = i + 1
+ break
} else if c == '>' {
- partial_arrow = true;
+ partial_arrow = true
}
- last_dot = false;
- last_arrow = false;
+ last_dot = false
+ last_arrow = false
- i -= 1;
+ i -= 1
}
if i >= 0 && position_context.file.src[end] == '.' {
- empty_dot = true;
- end -= 1;
+ empty_dot = true
+ end -= 1
} 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;
+ empty_arrow = true
+ end -= 2
+ position_context.arrow = true
}
- begin_offset := max(0, start);
- end_offset := max(start, end + 1);
+ begin_offset := max(0, start)
+ end_offset := max(start, end + 1)
- str := position_context.file.src[0:end_offset];
+ str := position_context.file.src[0:end_offset]
if empty_dot && end_offset - begin_offset == 0 {
- position_context.implicit = true;
- return;
+ position_context.implicit = true
+ return
}
- s := string(position_context.file.src[begin_offset:end_offset]);
+ s := string(position_context.file.src[begin_offset:end_offset])
if !partial_arrow {
- only_whitespaces := true;
+ only_whitespaces := true
for r in s {
if !strings.is_space(r) {
- only_whitespaces = false;
+ only_whitespaces = false
}
}
if only_whitespaces {
- return;
+ return
}
}
@@ -2962,149 +2957,149 @@ fallback_position_context_completion :: proc(document: ^common.Document, positio
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;
- p.tok.offset = begin_offset;
- p.tok.read_offset = begin_offset;
+ p.tok.ch = ' '
+ p.tok.line_count = position.line
+ p.tok.offset = begin_offset
+ p.tok.read_offset = begin_offset
- tokenizer.advance_rune(&p.tok);
+ tokenizer.advance_rune(&p.tok)
if p.tok.ch == utf8.RUNE_BOM {
- tokenizer.advance_rune(&p.tok);
+ tokenizer.advance_rune(&p.tok)
}
- parser.advance_token(&p);
+ parser.advance_token(&p)
- context.allocator = context.temp_allocator;
+ context.allocator = context.temp_allocator
- e := parser.parse_expr(&p, true);
+ e := parser.parse_expr(&p, true)
if empty_dot || empty_arrow {
- position_context.selector = e;
- } else if s, ok := e.derived.(ast.Selector_Expr); ok {
- position_context.selector = s.expr;
- position_context.field = s.field;
- } else if s, ok := e.derived.(ast.Implicit_Selector_Expr); ok {
- position_context.implicit = true;
- } else if s, ok := e.derived.(ast.Tag_Expr); ok {
- position_context.tag = s.expr;
- } else if bad_expr, ok := e.derived.(ast.Bad_Expr); ok {
+ position_context.selector = e
+ } else if s, ok := e.derived.(^ast.Selector_Expr); ok {
+ position_context.selector = s.expr
+ position_context.field = s.field
+ } else if s, ok := e.derived.(^ast.Implicit_Selector_Expr); ok {
+ position_context.implicit = true
+ } else if s, ok := e.derived.(^ast.Tag_Expr); ok {
+ position_context.tag = s.expr
+ } else if bad_expr, ok := e.derived.(^ast.Bad_Expr); ok {
//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;
+ 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;
- p.tok.offset = begin_offset;
- p.tok.read_offset = begin_offset;
+ p.tok.ch = ' '
+ p.tok.line_count = position.line
+ p.tok.offset = begin_offset
+ p.tok.read_offset = begin_offset
- tokenizer.advance_rune(&p.tok);
+ tokenizer.advance_rune(&p.tok)
if p.tok.ch == utf8.RUNE_BOM {
- tokenizer.advance_rune(&p.tok);
+ tokenizer.advance_rune(&p.tok)
}
- parser.advance_token(&p);
+ parser.advance_token(&p)
- e := parser.parse_expr(&p, true);
+ e := parser.parse_expr(&p, true)
if e == nil {
- position_context.abort_completion = true;
- return;
- } else if e, ok := e.derived.(ast.Bad_Expr); ok {
- position_context.abort_completion = true;
- return;
+ position_context.abort_completion = true
+ return
+ } else if e, ok := e.derived.(^ast.Bad_Expr); ok {
+ position_context.abort_completion = true
+ return
}
- position_context.selector = e;
+ position_context.selector = e
- ident := index.new_type(ast.Ident, e.pos, e.end, context.temp_allocator);
- ident.name = string(position_context.file.src[last_dot + 1:end_offset]);
+ ident := index.new_type(ast.Ident, e.pos, e.end, context.temp_allocator)
+ ident.name = string(position_context.file.src[last_dot + 1:end_offset])
if ident.name != "" {
- position_context.field = ident;
+ position_context.field = ident
}
} else {
- position_context.identifier = e;
+ position_context.identifier = e
}
}
fallback_position_context_signature :: proc(document: ^common.Document, position: common.Position, position_context: ^DocumentPositionContext) {
- end: int;
- start: int;
- i := position_context.position - 1;
- end = i;
+ end: int
+ start: int
+ i := position_context.position - 1
+ end = i
for i > 0 {
- c := position_context.file.src[i];
+ c := position_context.file.src[i]
if c == ' ' || c == '\n' || c == '\r' {
- start = i + 1;
- break;
+ start = i + 1
+ break
}
- i -= 1;
+ i -= 1
}
if end < 0 {
- return;
+ return
}
if position_context.file.src[end] != '(' {
- return;
+ return
}
- end -= 1;
+ end -= 1
- begin_offset := max(0, start);
- end_offset := max(start, end + 1);
+ begin_offset := max(0, start)
+ end_offset := max(start, end + 1)
if end_offset - begin_offset <= 1 {
- return;
+ return
}
- str := position_context.file.src[0:end_offset];
+ str := position_context.file.src[0:end_offset]
p := parser.Parser {
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;
- p.tok.offset = begin_offset;
- p.tok.read_offset = begin_offset;
+ p.tok.ch = ' '
+ p.tok.line_count = position.line
+ p.tok.offset = begin_offset
+ p.tok.read_offset = begin_offset
- tokenizer.advance_rune(&p.tok);
+ tokenizer.advance_rune(&p.tok)
if p.tok.ch == utf8.RUNE_BOM {
- tokenizer.advance_rune(&p.tok);
+ tokenizer.advance_rune(&p.tok)
}
- parser.advance_token(&p);
+ parser.advance_token(&p)
- context.allocator = context.temp_allocator;
+ context.allocator = context.temp_allocator
- position_context.call = parser.parse_expr(&p, true);
+ position_context.call = parser.parse_expr(&p, true)
- if _, ok := position_context.call.derived.(ast.Proc_Type); ok {
- position_context.call = nil;
+ 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]));
@@ -3118,81 +3113,81 @@ 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) {
for elem, i in array {
- get_document_position(elem, position_context);
+ get_document_position(elem, position_context)
}
}
get_document_position_dynamic_array :: proc(array: $A/[dynamic]^$T, position_context: ^DocumentPositionContext) {
for elem, i in array {
- get_document_position(elem, position_context);
+ 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;
+ return node != nil && node.pos.offset <= position && position <= node.end.offset
}
get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentPositionContext) {
- using ast;
+ using ast
if node == nil {
- return;
+ return
}
if !position_in_node(node, position_context.position) {
- return;
+ return
}
- switch n in node.derived {
- case Bad_Expr:
- case Ident:
- position_context.identifier = node;
- case Implicit:
- case Undef:
- case Basic_Lit:
- case Ellipsis:
- get_document_position(n.expr, position_context);
- case Proc_Lit:
- get_document_position(n.type, position_context);
+ #partial switch n in node.derived {
+ case ^Bad_Expr:
+ case ^Ident:
+ position_context.identifier = node
+ case ^Implicit:
+ case ^Undef:
+ case ^Basic_Lit:
+ case ^Ellipsis:
+ get_document_position(n.expr, position_context)
+ case ^Proc_Lit:
+ get_document_position(n.type, position_context)
if position_in_node(n.body, position_context.position) {
- position_context.function = cast(^Proc_Lit)node;
- get_document_position(n.body, position_context);
+ position_context.function = cast(^Proc_Lit)node
+ get_document_position(n.body, position_context)
}
- case Comp_Lit:
+ 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 {
- position_context.parent_comp_lit = cast(^Comp_Lit)node;
+ position_context.parent_comp_lit = cast(^Comp_Lit)node
}
- position_context.comp_lit = cast(^Comp_Lit)node;
+ position_context.comp_lit = cast(^Comp_Lit)node
- get_document_position(n.type, position_context);
- get_document_position(n.elems, position_context);
- case Tag_Expr:
- get_document_position(n.expr, position_context);
- case Unary_Expr:
- get_document_position(n.expr, position_context);
- case Binary_Expr:
+ get_document_position(n.type, position_context)
+ get_document_position(n.elems, position_context)
+ case ^Tag_Expr:
+ get_document_position(n.expr, position_context)
+ case ^Unary_Expr:
+ get_document_position(n.expr, position_context)
+ case ^Binary_Expr:
if position_context.parent_binary == nil {
- position_context.parent_binary = cast(^Binary_Expr)node;
- }
- position_context.binary = cast(^Binary_Expr)node;
- get_document_position(n.left, position_context);
- get_document_position(n.right, position_context);
- case Paren_Expr:
- get_document_position(n.expr, position_context);
- case Call_Expr:
+ position_context.parent_binary = cast(^Binary_Expr)node
+ }
+ position_context.binary = cast(^Binary_Expr)node
+ get_document_position(n.left, position_context)
+ get_document_position(n.right, position_context)
+ case ^Paren_Expr:
+ get_document_position(n.expr, position_context)
+ case ^Call_Expr:
if position_context.hint == .SignatureHelp || position_context.hint == .Completion {
- position_context.call = cast(^Expr)node;
+ position_context.call = cast(^Expr)node
}
- get_document_position(n.expr, position_context);
- get_document_position(n.args, position_context);
- case Selector_Expr:
+ 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 {
//The parser is not fault tolerant enough, relying on the fallback as the main completion parsing for now
@@ -3200,182 +3195,181 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP
//position_context.field = n.field;
}
} else if (position_context.hint == .Definition || position_context.hint == .Hover) && n.field != nil {
- position_context.selector = n.expr;
- position_context.field = n.field;
- get_document_position(n.expr, position_context);
- get_document_position(n.field, position_context);
+ position_context.selector = n.expr
+ position_context.field = n.field
+ get_document_position(n.expr, position_context)
+ get_document_position(n.field, position_context)
} else {
- get_document_position(n.expr, position_context);
- get_document_position(n.field, position_context);
- }
- case Index_Expr:
- get_document_position(n.expr, position_context);
- get_document_position(n.index, position_context);
- case Deref_Expr:
- get_document_position(n.expr, position_context);
- case Slice_Expr:
- get_document_position(n.expr, position_context);
- get_document_position(n.low, position_context);
- get_document_position(n.high, position_context);
- case Field_Value:
- position_context.field_value = cast(^Field_Value)node;
- get_document_position(n.field, position_context);
- get_document_position(n.value, position_context);
- case Ternary_If_Expr:
- get_document_position(n.x, position_context);
- get_document_position(n.cond, position_context);
- get_document_position(n.y, position_context);
- case Ternary_When_Expr:
- get_document_position(n.x, position_context);
- get_document_position(n.cond, position_context);
- get_document_position(n.y, position_context);
- case Type_Assertion:
- get_document_position(n.expr, position_context);
- get_document_position(n.type, position_context);
- case Type_Cast:
- get_document_position(n.type, position_context);
- get_document_position(n.expr, position_context);
- case Auto_Cast:
- get_document_position(n.expr, position_context);
- case Bad_Stmt:
- case Empty_Stmt:
- case Expr_Stmt:
- get_document_position(n.expr, position_context);
- case Tag_Stmt:
- r := cast(^Tag_Stmt)node;
- get_document_position(r.stmt, position_context);
- case Assign_Stmt:
- position_context.assign = cast(^Assign_Stmt)node;
- get_document_position(n.lhs, position_context);
- get_document_position(n.rhs, position_context);
- case Block_Stmt:
- get_document_position(n.label, position_context);
- get_document_position(n.stmts, position_context);
- case If_Stmt:
- get_document_position(n.label, position_context);
- get_document_position(n.init, position_context);
- get_document_position(n.cond, position_context);
- get_document_position(n.body, position_context);
- get_document_position(n.else_stmt, position_context);
- case When_Stmt:
- get_document_position(n.cond, position_context);
- get_document_position(n.body, position_context);
- get_document_position(n.else_stmt, position_context);
- case Return_Stmt:
- position_context.returns = cast(^Return_Stmt)node;
- get_document_position(n.results, position_context);
- case Defer_Stmt:
- get_document_position(n.stmt, position_context);
- case For_Stmt:
- get_document_position(n.label, position_context);
- get_document_position(n.init, position_context);
- get_document_position(n.cond, position_context);
- get_document_position(n.post, position_context);
- get_document_position(n.body, position_context);
- case Range_Stmt:
- get_document_position(n.label, position_context);
- get_document_position(n.vals, position_context);
- get_document_position(n.expr, position_context);
- get_document_position(n.body, position_context);
- case Case_Clause:
-
+ get_document_position(n.expr, position_context)
+ get_document_position(n.field, position_context)
+ }
+ case ^Index_Expr:
+ get_document_position(n.expr, position_context)
+ get_document_position(n.index, position_context)
+ case ^Deref_Expr:
+ get_document_position(n.expr, position_context)
+ case ^Slice_Expr:
+ get_document_position(n.expr, position_context)
+ get_document_position(n.low, position_context)
+ get_document_position(n.high, position_context)
+ case ^Field_Value:
+ position_context.field_value = cast(^Field_Value)node
+ get_document_position(n.field, position_context)
+ get_document_position(n.value, position_context)
+ case ^Ternary_If_Expr:
+ get_document_position(n.x, position_context)
+ get_document_position(n.cond, position_context)
+ get_document_position(n.y, position_context)
+ case ^Ternary_When_Expr:
+ get_document_position(n.x, position_context)
+ get_document_position(n.cond, position_context)
+ get_document_position(n.y, position_context)
+ case ^Type_Assertion:
+ get_document_position(n.expr, position_context)
+ get_document_position(n.type, position_context)
+ case ^Type_Cast:
+ get_document_position(n.type, position_context)
+ get_document_position(n.expr, position_context)
+ case ^Auto_Cast:
+ get_document_position(n.expr, position_context)
+ case ^Bad_Stmt:
+ case ^Empty_Stmt:
+ case ^Expr_Stmt:
+ get_document_position(n.expr, position_context)
+ case ^Tag_Stmt:
+ r := cast(^Tag_Stmt)node
+ get_document_position(r.stmt, position_context)
+ case ^Assign_Stmt:
+ position_context.assign = cast(^Assign_Stmt)node
+ get_document_position(n.lhs, position_context)
+ get_document_position(n.rhs, position_context)
+ case ^Block_Stmt:
+ get_document_position(n.label, position_context)
+ get_document_position(n.stmts, position_context)
+ case ^If_Stmt:
+ get_document_position(n.label, position_context)
+ get_document_position(n.init, position_context)
+ get_document_position(n.cond, position_context)
+ get_document_position(n.body, position_context)
+ get_document_position(n.else_stmt, position_context)
+ case ^When_Stmt:
+ get_document_position(n.cond, position_context)
+ get_document_position(n.body, position_context)
+ get_document_position(n.else_stmt, position_context)
+ case ^Return_Stmt:
+ position_context.returns = cast(^Return_Stmt)node
+ get_document_position(n.results, position_context)
+ case ^Defer_Stmt:
+ get_document_position(n.stmt, position_context)
+ case ^For_Stmt:
+ get_document_position(n.label, position_context)
+ get_document_position(n.init, position_context)
+ get_document_position(n.cond, position_context)
+ get_document_position(n.post, position_context)
+ get_document_position(n.body, position_context)
+ case ^Range_Stmt:
+ get_document_position(n.label, position_context)
+ get_document_position(n.vals, position_context)
+ get_document_position(n.expr, position_context)
+ get_document_position(n.body, position_context)
+ case ^Case_Clause:
for elem in n.list {
if position_in_node(elem, position_context.position) {
- position_context.case_clause = cast(^Case_Clause)node;
- break;
- }
- }
-
- get_document_position(n.list, position_context);
- get_document_position(n.body, position_context);
- case Switch_Stmt:
- position_context.switch_stmt = cast(^Switch_Stmt)node;
- get_document_position(n.label, position_context);
- get_document_position(n.init, position_context);
- get_document_position(n.cond, position_context);
- get_document_position(n.body, position_context);
- case Type_Switch_Stmt:
- position_context.switch_type_stmt = cast(^Type_Switch_Stmt)node;
- get_document_position(n.label, position_context);
- get_document_position(n.tag, position_context);
- get_document_position(n.expr, position_context);
- get_document_position(n.body, position_context);
- case Branch_Stmt:
- get_document_position(n.label, position_context);
- case Using_Stmt:
- get_document_position(n.list, position_context);
- case Bad_Decl:
- case Value_Decl:
- position_context.value_decl = cast(^Value_Decl)node;
- get_document_position(n.attributes, position_context);
+ position_context.case_clause = cast(^Case_Clause)node
+ break
+ }
+ }
+
+ get_document_position(n.list, position_context)
+ get_document_position(n.body, position_context)
+ case ^Switch_Stmt:
+ position_context.switch_stmt = cast(^Switch_Stmt)node
+ get_document_position(n.label, position_context)
+ get_document_position(n.init, position_context)
+ get_document_position(n.cond, position_context)
+ get_document_position(n.body, position_context)
+ case ^Type_Switch_Stmt:
+ position_context.switch_type_stmt = cast(^Type_Switch_Stmt)node
+ get_document_position(n.label, position_context)
+ get_document_position(n.tag, position_context)
+ get_document_position(n.expr, position_context)
+ get_document_position(n.body, position_context)
+ case ^Branch_Stmt:
+ get_document_position(n.label, position_context)
+ case ^Using_Stmt:
+ get_document_position(n.list, position_context)
+ case ^Bad_Decl:
+ case ^Value_Decl:
+ position_context.value_decl = cast(^Value_Decl)node
+ 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 {
- position_context.abort_completion = true;
- break;
- }
- }
- get_document_position(n.names, position_context);
- get_document_position(n.type, position_context);
- get_document_position(n.values, position_context);
- case Package_Decl:
- case Import_Decl:
- case Foreign_Block_Decl:
- get_document_position(n.attributes, position_context);
- get_document_position(n.foreign_library, position_context);
- get_document_position(n.body, position_context);
- case Foreign_Import_Decl:
- get_document_position(n.name, position_context);
- case Proc_Group:
- get_document_position(n.args, position_context);
- case Attribute:
- get_document_position(n.elems, position_context);
- case Field:
- get_document_position(n.names, position_context);
- get_document_position(n.type, position_context);
- get_document_position(n.default_value, position_context);
- case Field_List:
- get_document_position(n.list, position_context);
- case Typeid_Type:
- get_document_position(n.specialization, position_context);
- case Helper_Type:
- get_document_position(n.type, position_context);
- case Distinct_Type:
- get_document_position(n.type, position_context);
- case Poly_Type:
- get_document_position(n.type, position_context);
- get_document_position(n.specialization, position_context);
- case Proc_Type:
- get_document_position(n.params, position_context);
- get_document_position(n.results, position_context);
- case Pointer_Type:
- get_document_position(n.elem, position_context);
- case Array_Type:
- get_document_position(n.len, position_context);
- get_document_position(n.elem, position_context);
- case Dynamic_Array_Type:
- get_document_position(n.elem, position_context);
- case Struct_Type:
- get_document_position(n.poly_params, position_context);
- get_document_position(n.align, position_context);
- get_document_position(n.fields, position_context);
- case Union_Type:
- get_document_position(n.poly_params, position_context);
- get_document_position(n.align, position_context);
- get_document_position(n.variants, position_context);
- case Enum_Type:
- get_document_position(n.base_type, position_context);
- get_document_position(n.fields, position_context);
- case Bit_Set_Type:
- get_document_position(n.elem, position_context);
- get_document_position(n.underlying, position_context);
- case Map_Type:
- get_document_position(n.key, position_context);
- get_document_position(n.value, position_context);
- case Implicit_Selector_Expr:
- position_context.implicit = true;
- get_document_position(n.field, position_context);
+ position_context.abort_completion = true
+ break
+ }
+ }
+ get_document_position(n.names, position_context)
+ get_document_position(n.type, position_context)
+ get_document_position(n.values, position_context)
+ case ^Package_Decl:
+ case ^Import_Decl:
+ case ^Foreign_Block_Decl:
+ get_document_position(n.attributes, position_context)
+ get_document_position(n.foreign_library, position_context)
+ get_document_position(n.body, position_context)
+ case ^Foreign_Import_Decl:
+ get_document_position(n.name, position_context)
+ case ^Proc_Group:
+ get_document_position(n.args, position_context)
+ case ^Attribute:
+ get_document_position(n.elems, position_context)
+ case ^Field:
+ get_document_position(n.names, position_context)
+ get_document_position(n.type, position_context)
+ get_document_position(n.default_value, position_context)
+ case ^Field_List:
+ get_document_position(n.list, position_context)
+ case ^Typeid_Type:
+ get_document_position(n.specialization, position_context)
+ case ^Helper_Type:
+ get_document_position(n.type, position_context)
+ case ^Distinct_Type:
+ get_document_position(n.type, position_context)
+ case ^Poly_Type:
+ get_document_position(n.type, position_context)
+ get_document_position(n.specialization, position_context)
+ case ^Proc_Type:
+ get_document_position(n.params, position_context)
+ get_document_position(n.results, position_context)
+ case ^Pointer_Type:
+ get_document_position(n.elem, position_context)
+ case ^Array_Type:
+ get_document_position(n.len, position_context)
+ get_document_position(n.elem, position_context)
+ case ^Dynamic_Array_Type:
+ get_document_position(n.elem, position_context)
+ case ^Struct_Type:
+ get_document_position(n.poly_params, position_context)
+ get_document_position(n.align, position_context)
+ get_document_position(n.fields, position_context)
+ case ^Union_Type:
+ get_document_position(n.poly_params, position_context)
+ get_document_position(n.align, position_context)
+ get_document_position(n.variants, position_context)
+ case ^Enum_Type:
+ get_document_position(n.base_type, position_context)
+ get_document_position(n.fields, position_context)
+ case ^Bit_Set_Type:
+ get_document_position(n.elem, position_context)
+ get_document_position(n.underlying, position_context)
+ case ^Map_Type:
+ get_document_position(n.key, position_context)
+ get_document_position(n.value, position_context)
+ case ^Implicit_Selector_Expr:
+ position_context.implicit = true
+ get_document_position(n.field, position_context)
case:
- log.errorf("Unhandled node kind: %T", n);
+ log.errorf("Unhandled node kind: %T", n)
}
}
diff --git a/src/common/allocator.odin b/src/common/allocator.odin
index bbb654c..6d2d371 100644
--- a/src/common/allocator.odin
+++ b/src/common/allocator.odin
@@ -12,119 +12,119 @@ Scratch_Allocator :: struct {
}
scratch_allocator_init :: proc (s: ^Scratch_Allocator, size: int, backup_allocator := context.allocator) {
- s.data, _ = mem.make_aligned([]byte, size, 2 * align_of(rawptr), backup_allocator);
- s.curr_offset = 0;
- s.prev_allocation = nil;
- s.backup_allocator = backup_allocator;
- s.leaked_allocations.allocator = backup_allocator;
+ s.data, _ = mem.make_aligned([]byte, size, 2 * align_of(rawptr), backup_allocator)
+ s.curr_offset = 0
+ s.prev_allocation = nil
+ s.backup_allocator = backup_allocator
+ s.leaked_allocations.allocator = backup_allocator
}
scratch_allocator_destroy :: proc (s: ^Scratch_Allocator) {
if s == nil {
- return;
+ return
}
for ptr in s.leaked_allocations {
- mem.free_bytes(ptr, s.backup_allocator);
+ mem.free_bytes(ptr, s.backup_allocator)
}
- delete(s.leaked_allocations);
- delete(s.data, s.backup_allocator);
- s^ = {};
+ delete(s.leaked_allocations)
+ delete(s.data, s.backup_allocator)
+ s^ = {}
}
scratch_allocator_proc :: proc (allocator_data: rawptr, mode: mem.Allocator_Mode, size, alignment: int, old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, mem.Allocator_Error) {
- s := (^Scratch_Allocator)(allocator_data);
+ s := (^Scratch_Allocator)(allocator_data)
if s.data == nil {
- DEFAULT_BACKING_SIZE :: 1 << 22;
+ DEFAULT_BACKING_SIZE :: 1 << 22
if !(context.allocator.procedure != scratch_allocator_proc &&
context.allocator.data != allocator_data) {
- panic("cyclic initialization of the scratch allocator with itself");
+ panic("cyclic initialization of the scratch allocator with itself")
}
- scratch_allocator_init(s, DEFAULT_BACKING_SIZE);
+ scratch_allocator_init(s, DEFAULT_BACKING_SIZE)
}
- size := size;
+ size := size
switch mode {
case .Alloc:
- size = mem.align_forward_int(size, alignment);
+ size = mem.align_forward_int(size, alignment)
switch {
case s.curr_offset + size <= len(s.data):
- start := uintptr(raw_data(s.data));
- ptr := start + uintptr(s.curr_offset);
- ptr = mem.align_forward_uintptr(ptr, uintptr(alignment));
- mem.zero(rawptr(ptr), size);
-
- s.prev_allocation = rawptr(ptr);
- offset := int(ptr - start);
- s.curr_offset = offset + size;
- return mem.byte_slice(rawptr(ptr), size), nil;
+ start := uintptr(raw_data(s.data))
+ ptr := start + uintptr(s.curr_offset)
+ ptr = mem.align_forward_uintptr(ptr, uintptr(alignment))
+ mem.zero(rawptr(ptr), size)
+
+ s.prev_allocation = rawptr(ptr)
+ offset := int(ptr - start)
+ s.curr_offset = offset + size
+ return mem.byte_slice(rawptr(ptr), size), nil
}
- a := s.backup_allocator;
+ a := s.backup_allocator
if a.procedure == nil {
- a = context.allocator;
- s.backup_allocator = a;
+ a = context.allocator
+ s.backup_allocator = a
}
- ptr, err := mem.alloc_bytes(size, alignment, a, loc);
+ ptr, err := mem.alloc_bytes(size, alignment, a, loc)
if err != nil {
- return ptr, err;
+ return ptr, err
}
if s.leaked_allocations == nil {
- s.leaked_allocations = make([dynamic][]byte, a);
+ s.leaked_allocations = make([dynamic][]byte, a)
}
- append(&s.leaked_allocations, ptr);
+ append(&s.leaked_allocations, ptr)
if logger := context.logger; logger.lowest_level <= .Warning {
if logger.procedure != nil {
- logger.procedure(logger.data, .Warning, "mem.Scratch_Allocator resorted to backup_allocator" , logger.options, loc);
+ logger.procedure(logger.data, .Warning, "mem.Scratch_Allocator resorted to backup_allocator" , logger.options, loc)
}
}
- return ptr, err;
+ return ptr, err
case .Free:
case .Free_All:
- s.curr_offset = 0;
- s.prev_allocation = nil;
+ s.curr_offset = 0
+ s.prev_allocation = nil
for ptr in s.leaked_allocations {
- mem.free_bytes(ptr, s.backup_allocator);
+ mem.free_bytes(ptr, s.backup_allocator)
}
- clear(&s.leaked_allocations);
+ clear(&s.leaked_allocations)
case .Resize:
- begin := uintptr(raw_data(s.data));
- end := begin + uintptr(len(s.data));
- old_ptr := uintptr(old_memory);
+ begin := uintptr(raw_data(s.data))
+ end := begin + uintptr(len(s.data))
+ old_ptr := uintptr(old_memory)
- data, err := scratch_allocator_proc(allocator_data, .Alloc, size, alignment, old_memory, old_size, loc);
+ data, err := scratch_allocator_proc(allocator_data, .Alloc, size, alignment, old_memory, old_size, loc)
if err != nil {
- return data, err;
+ return data, err
}
- runtime.copy(data, mem.byte_slice(old_memory, old_size));
- _, err = scratch_allocator_proc(allocator_data, .Free, 0, alignment, old_memory, old_size, loc);
- return data, err;
+ runtime.copy(data, mem.byte_slice(old_memory, old_size))
+ _, err = scratch_allocator_proc(allocator_data, .Free, 0, alignment, old_memory, old_size, loc)
+ return data, err
case .Query_Features:
- set := (^mem.Allocator_Mode_Set)(old_memory);
+ set := (^mem.Allocator_Mode_Set)(old_memory)
if set != nil {
- set^ = {.Alloc, .Free, .Free_All, .Resize, .Query_Features};
+ set^ = {.Alloc, .Free, .Free_All, .Resize, .Query_Features}
}
- return nil, nil;
+ return nil, nil
case .Query_Info:
- return nil, nil;
+ return nil, nil
}
- return nil, nil;
+ return nil, nil
}
scratch_allocator :: proc (allocator: ^Scratch_Allocator) -> mem.Allocator {
return mem.Allocator {
procedure = scratch_allocator_proc,
data = allocator,
- };
+ }
}
diff --git a/src/common/ast.odin b/src/common/ast.odin
index 69f35e0..7677634 100644
--- a/src/common/ast.odin
+++ b/src/common/ast.odin
@@ -62,7 +62,7 @@ keyword_map: map[string]bool = {
"quaternion64" = true,
"quaternion128" = true,
"quaternion256" = true,
-};
+}
GlobalExpr :: struct {
name: string,
@@ -77,63 +77,63 @@ GlobalExpr :: struct {
unwrap_pointer :: proc(expr: ^ast.Expr) -> (ast.Ident, bool) {
- expr := expr;
+ expr := expr
for expr != nil {
- if pointer, ok := expr.derived.(ast.Pointer_Type); ok {
- expr = pointer.elem;
+ if pointer, ok := expr.derived.(^ast.Pointer_Type); ok {
+ expr = pointer.elem
} else {
- break;
+ break
}
}
if expr != nil {
- ident, ok := expr.derived.(ast.Ident);
- return ident, ok;
+ ident, ok := expr.derived.(^ast.Ident)
+ return ident^, ok
}
- return {}, false;
+ return {}, false
}
collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^ast.Node, skip_private: bool) {
- if value_decl, ok := stmt.derived.(ast.Value_Decl); ok {
+ if value_decl, ok := stmt.derived.(^ast.Value_Decl); ok {
- is_deprecated := false;
- is_private_file := false;
- is_package_file := false;
+ is_deprecated := false
+ is_private_file := false
+ is_package_file := false
for attribute in value_decl.attributes {
for elem in attribute.elems {
- if value, ok := elem.derived.(ast.Field_Value); ok {
- if ident, ok := value.field.derived.(ast.Ident); ok {
+ if value, ok := elem.derived.(^ast.Field_Value); ok {
+ if ident, ok := value.field.derived.(^ast.Ident); ok {
switch ident.name {
case "private":
- if val, ok := value.value.derived.(ast.Basic_Lit); ok {
+ if val, ok := value.value.derived.(^ast.Basic_Lit); ok {
switch val.tok.text {
case "\"file\"":
- is_private_file = true;
+ is_private_file = true
case "package":
- is_package_file = true;
+ is_package_file = true
}
}
case "deprecated":
- is_deprecated = true;
+ is_deprecated = true
}
}
- } else if ident, ok := elem.derived.(ast.Ident); ok {
+ } else if ident, ok := elem.derived.(^ast.Ident); ok {
switch ident.name {
case "deprecated":
- is_deprecated = true;
+ is_deprecated = true
}
}
}
}
if is_private_file && skip_private {
- return;
+ return
}
for name, i in value_decl.names {
- str := get_ast_node_string(name, file.src);
+ str := get_ast_node_string(name, file.src)
if value_decl.type != nil {
append(exprs, GlobalExpr {
@@ -143,7 +143,7 @@ collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^a
docs = value_decl.docs,
attributes = value_decl.attributes[:],
deprecated = is_deprecated,
- });
+ })
} else {
if len(value_decl.values) > i {
append(exprs, GlobalExpr {
@@ -153,7 +153,7 @@ collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^a
docs = value_decl.docs,
attributes = value_decl.attributes[:],
deprecated = is_deprecated,
- });
+ })
}
}
}
@@ -161,98 +161,97 @@ collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^a
}
collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr {
- exprs := make([dynamic]GlobalExpr, context.temp_allocator);
+ exprs := make([dynamic]GlobalExpr, context.temp_allocator)
for decl in file.decls {
- if value_decl, ok := decl.derived.(ast.Value_Decl); ok {
- collect_value_decl(&exprs, file, decl, skip_private);
- } else if when_decl, ok := decl.derived.(ast.When_Stmt); ok {
+ if value_decl, ok := decl.derived.(^ast.Value_Decl); ok {
+ collect_value_decl(&exprs, file, decl, skip_private)
+ } else if when_decl, ok := decl.derived.(^ast.When_Stmt); ok {
if when_decl.cond == nil {
- continue;
+ continue
}
if when_decl.body == nil {
- continue;
+ continue
}
- if binary, ok := when_decl.cond.derived.(ast.Binary_Expr); ok {
+ if binary, ok := when_decl.cond.derived.(^ast.Binary_Expr); ok {
if binary.left == nil || binary.right == nil {
- continue;
+ continue
}
- ident: ^ast.Ident;
- basic_lit: ^ast.Basic_Lit;
+ ident: ^ast.Ident
+ implicit: ^ast.Implicit
- if t, ok := binary.left.derived.(ast.Ident); ok {
- ident = cast(^ast.Ident)binary.left;
- } else if t, ok := binary.left.derived.(ast.Basic_Lit); ok {
- basic_lit = cast(^ast.Basic_Lit)binary.left;
+ if t, ok := binary.left.derived.(^ast.Ident); ok {
+ ident = cast(^ast.Ident)binary.left
+ } else if t, ok := binary.left.derived.(^ast.Basic_Lit); ok {
+ implicit = cast(^ast.Implicit)binary.left
}
- if t, ok := binary.right.derived.(ast.Ident); ok {
- ident = cast(^ast.Ident)binary.right;
- } else if t, ok := binary.right.derived.(ast.Basic_Lit); ok {
- basic_lit = cast(^ast.Basic_Lit)binary.right;
+ if t, ok := binary.right.derived.(^ast.Ident); ok {
+ ident = cast(^ast.Ident)binary.right
+ } else if t, ok := binary.right.derived.(^ast.Basic_Lit); ok {
+ implicit = cast(^ast.Implicit)binary.right
}
- if ident != nil && basic_lit != nil {
- if ident.name == "ODIN_OS" && basic_lit.tok.text[1:len(basic_lit.tok.text)-1] == ODIN_OS {
- if block, ok := when_decl.body.derived.(ast.Block_Stmt); ok {
+ if ident != nil && implicit != nil {
+ if ident.name == "ODIN_OS" && implicit.tok.text == fmt.tprint(ODIN_OS) {
+ if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok {
for stmt in block.stmts {
- collect_value_decl(&exprs, file, stmt, skip_private);
+ collect_value_decl(&exprs, file, stmt, skip_private)
}
}
} else if ident.name != "ODIN_OS" {
- if block, ok := when_decl.body.derived.(ast.Block_Stmt); ok {
+ if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok {
for stmt in block.stmts {
- collect_value_decl(&exprs, file, stmt, skip_private);
+ collect_value_decl(&exprs, file, stmt, skip_private)
}
}
}
}
} else {
- if block, ok := when_decl.body.derived.(ast.Block_Stmt); ok {
+ if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok {
for stmt in block.stmts {
- collect_value_decl(&exprs, file, stmt, skip_private);
+ collect_value_decl(&exprs, file, stmt, skip_private)
}
}
}
- } else if foreign_decl, ok := decl.derived.(ast.Foreign_Block_Decl); ok {
+ } else if foreign_decl, ok := decl.derived.(^ast.Foreign_Block_Decl); ok {
if foreign_decl.body == nil {
- continue;
+ continue
}
- if block, ok := foreign_decl.body.derived.(ast.Block_Stmt); ok {
+ if block, ok := foreign_decl.body.derived.(^ast.Block_Stmt); ok {
for stmt in block.stmts {
- collect_value_decl(&exprs, file, stmt, skip_private);
+ collect_value_decl(&exprs, file, stmt, skip_private)
}
}
}
}
- return exprs[:];
+ return exprs[:]
}
get_ast_node_string :: proc(node: ^ast.Node, src: string) -> string {
- return string(src[node.pos.offset:node.end.offset]);
+ return string(src[node.pos.offset:node.end.offset])
}
get_doc :: proc(comment: ^ast.Comment_Group, allocator: mem.Allocator) -> string {
-
if comment != nil {
- tmp: string;
+ tmp: string
for doc in comment.list {
- tmp = strings.concatenate({tmp, "\n", doc.text}, context.temp_allocator);
+ tmp = strings.concatenate({tmp, "\n", doc.text}, context.temp_allocator)
}
if tmp != "" {
- replaced, allocated := strings.replace_all(tmp, "//", "", context.temp_allocator);
- return strings.clone(replaced, allocator);
+ replaced, allocated := strings.replace_all(tmp, "//", "", context.temp_allocator)
+ return strings.clone(replaced, allocator)
}
}
- return "";
+ return ""
}
free_ast :: proc{
@@ -260,451 +259,443 @@ free_ast :: proc{
free_ast_array,
free_ast_dynamic_array,
free_ast_comment,
-};
+}
free_ast_comment :: proc(a: ^ast.Comment_Group, allocator: mem.Allocator) {
if a == nil {
- return;
+ return
}
if len(a.list) > 0 {
- delete(a.list, allocator);
+ delete(a.list, allocator)
}
- free(a, allocator);
+ free(a, allocator)
}
free_ast_array :: proc(array: $A/[]^$T, allocator: mem.Allocator) {
for elem, i in array {
- free_ast(elem, allocator);
+ free_ast(elem, allocator)
}
- delete(array, allocator);
+ delete(array, allocator)
}
free_ast_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator) {
for elem, i in array {
- free_ast(elem, allocator);
+ free_ast(elem, allocator)
}
- delete(array);
+ delete(array)
}
free_ast_node :: proc(node: ^ast.Node, allocator: mem.Allocator) {
-
- using ast;
+ using ast
if node == nil {
- return;
+ return
}
- switch n in node.derived {
- case Bad_Expr:
- case Ident:
- case Implicit:
- case Undef:
- case Basic_Directive:
- case Basic_Lit:
- case Ellipsis:
- free_ast(n.expr, allocator);
- case Proc_Lit:
- free_ast(n.type, allocator);
- free_ast(n.body, allocator);
- free_ast(n.where_clauses, allocator);
- case Comp_Lit:
- free_ast(n.type, allocator);
- free_ast(n.elems, allocator);
- case Tag_Expr:
- free_ast(n.expr, allocator);
- case Unary_Expr:
- free_ast(n.expr, allocator);
- case Binary_Expr:
- free_ast(n.left, allocator);
- free_ast(n.right, allocator);
- case Paren_Expr:
- free_ast(n.expr, allocator);
- case Call_Expr:
- free_ast(n.expr, allocator);
- free_ast(n.args, allocator);
- case Selector_Expr:
- free_ast(n.expr, allocator);
- free_ast(n.field, allocator);
- case Implicit_Selector_Expr:
- free_ast(n.field, allocator);
- case Index_Expr:
- free_ast(n.expr, allocator);
- free_ast(n.index, allocator);
- case Deref_Expr:
- free_ast(n.expr, allocator);
- case Slice_Expr:
- free_ast(n.expr, allocator);
- free_ast(n.low, allocator);
- free_ast(n.high, allocator);
- case Field_Value:
- free_ast(n.field, allocator);
- free_ast(n.value, allocator);
- case Ternary_If_Expr:
- free_ast(n.x, allocator);
- free_ast(n.cond, allocator);
- free_ast(n.y, allocator);
- case Ternary_When_Expr:
- free_ast(n.x, allocator);
- free_ast(n.cond, allocator);
- free_ast(n.y, allocator);
- case Type_Assertion:
- free_ast(n.expr, allocator);
- free_ast(n.type, allocator);
- case Type_Cast:
- free_ast(n.type, allocator);
- free_ast(n.expr, allocator);
- case Auto_Cast:
- free_ast(n.expr, allocator);
- case Bad_Stmt:
- case Empty_Stmt:
- case Expr_Stmt:
- free_ast(n.expr, allocator);
- case Tag_Stmt:
- r := cast(^Expr_Stmt)node;
- free_ast(r.expr, allocator);
- case Assign_Stmt:
- free_ast(n.lhs, allocator);
- free_ast(n.rhs, allocator);
- case Block_Stmt:
- free_ast(n.label, allocator);
- free_ast(n.stmts, allocator);
- case If_Stmt:
- free_ast(n.label, allocator);
- free_ast(n.init, allocator);
- free_ast(n.cond, allocator);
- free_ast(n.body, allocator);
- free_ast(n.else_stmt, allocator);
- case When_Stmt:
- free_ast(n.cond, allocator);
- free_ast(n.body, allocator);
- free_ast(n.else_stmt, allocator);
- case Return_Stmt:
- free_ast(n.results, allocator);
- case Defer_Stmt:
- free_ast(n.stmt, allocator);
- case For_Stmt:
- free_ast(n.label, allocator);
- free_ast(n.init, allocator);
- free_ast(n.cond, allocator);
- free_ast(n.post, allocator);
- free_ast(n.body, allocator);
- case Range_Stmt:
- free_ast(n.label, allocator);
- free_ast(n.vals, allocator);
- free_ast(n.expr, allocator);
- free_ast(n.body, allocator);
- case Case_Clause:
- free_ast(n.list, allocator);
- free_ast(n.body, allocator);
- case Switch_Stmt:
- free_ast(n.label, allocator);
- free_ast(n.init, allocator);
- free_ast(n.cond, allocator);
- free_ast(n.body, allocator);
- case Type_Switch_Stmt:
- free_ast(n.label, allocator);
- free_ast(n.tag, allocator);
- free_ast(n.expr, allocator);
- free_ast(n.body, allocator);
- case Branch_Stmt:
- free_ast(n.label, allocator);
- case Using_Stmt:
- free_ast(n.list, allocator);
- case Bad_Decl:
- case Value_Decl:
- free_ast(n.attributes, allocator);
- free_ast(n.names, allocator);
- free_ast(n.type, allocator);
- free_ast(n.values, allocator);
- //free_ast(n.docs);
- //free_ast(n.comment);
- case Package_Decl:
- //free_ast(n.docs);
- //free_ast(n.comment);
- case Import_Decl:
- //free_ast(n.docs);
- //free_ast(n.comment);
- case Foreign_Block_Decl:
- free_ast(n.attributes, allocator);
- free_ast(n.foreign_library, allocator);
- free_ast(n.body, allocator);
- case Foreign_Import_Decl:
- free_ast(n.name, allocator);
- free_ast(n.attributes, allocator);
- case Proc_Group:
- free_ast(n.args, allocator);
- case Attribute:
- free_ast(n.elems, allocator);
- case Field:
- free_ast(n.names, allocator);
- free_ast(n.type, allocator);
- free_ast(n.default_value, allocator);
+ if node.derived != nil do #partial switch n in node.derived {
+ case ^Bad_Expr:
+ case ^Ident:
+ case ^Implicit:
+ case ^Undef:
+ case ^Basic_Directive:
+ case ^Basic_Lit:
+ case ^Ellipsis:
+ free_ast(n.expr, allocator)
+ case ^Proc_Lit:
+ free_ast(n.type, allocator)
+ free_ast(n.body, allocator)
+ free_ast(n.where_clauses, allocator)
+ case ^Comp_Lit:
+ free_ast(n.type, allocator)
+ free_ast(n.elems, allocator)
+ case ^Tag_Expr:
+ free_ast(n.expr, allocator)
+ case ^Unary_Expr:
+ free_ast(n.expr, allocator)
+ case ^Binary_Expr:
+ free_ast(n.left, allocator)
+ free_ast(n.right, allocator)
+ case ^Paren_Expr:
+ free_ast(n.expr, allocator)
+ case ^Call_Expr:
+ free_ast(n.expr, allocator)
+ free_ast(n.args, allocator)
+ case ^Selector_Expr:
+ free_ast(n.expr, allocator)
+ free_ast(n.field, allocator)
+ case ^Implicit_Selector_Expr:
+ free_ast(n.field, allocator)
+ case ^Index_Expr:
+ free_ast(n.expr, allocator)
+ free_ast(n.index, allocator)
+ case ^Deref_Expr:
+ free_ast(n.expr, allocator)
+ case ^Slice_Expr:
+ free_ast(n.expr, allocator)
+ free_ast(n.low, allocator)
+ free_ast(n.high, allocator)
+ case ^Field_Value:
+ free_ast(n.field, allocator)
+ free_ast(n.value, allocator)
+ case ^Ternary_If_Expr:
+ free_ast(n.x, allocator)
+ free_ast(n.cond, allocator)
+ free_ast(n.y, allocator)
+ case ^Ternary_When_Expr:
+ free_ast(n.x, allocator)
+ free_ast(n.cond, allocator)
+ free_ast(n.y, allocator)
+ case ^Type_Assertion:
+ free_ast(n.expr, allocator)
+ free_ast(n.type, allocator)
+ case ^Type_Cast:
+ free_ast(n.type, allocator)
+ free_ast(n.expr, allocator)
+ case ^Auto_Cast:
+ free_ast(n.expr, allocator)
+ case ^Bad_Stmt:
+ case ^Empty_Stmt:
+ case ^Expr_Stmt:
+ free_ast(n.expr, allocator)
+ case ^Tag_Stmt:
+ r := cast(^Expr_Stmt)node
+ free_ast(r.expr, allocator)
+ case ^Assign_Stmt:
+ free_ast(n.lhs, allocator)
+ free_ast(n.rhs, allocator)
+ case ^Block_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.stmts, allocator)
+ case ^If_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.init, allocator)
+ free_ast(n.cond, allocator)
+ free_ast(n.body, allocator)
+ free_ast(n.else_stmt, allocator)
+ case ^When_Stmt:
+ free_ast(n.cond, allocator)
+ free_ast(n.body, allocator)
+ free_ast(n.else_stmt, allocator)
+ case ^Return_Stmt:
+ free_ast(n.results, allocator)
+ case ^Defer_Stmt:
+ free_ast(n.stmt, allocator)
+ case ^For_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.init, allocator)
+ free_ast(n.cond, allocator)
+ free_ast(n.post, allocator)
+ free_ast(n.body, allocator)
+ case ^Range_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.vals, allocator)
+ free_ast(n.expr, allocator)
+ free_ast(n.body, allocator)
+ case ^Case_Clause:
+ free_ast(n.list, allocator)
+ free_ast(n.body, allocator)
+ case ^Switch_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.init, allocator)
+ free_ast(n.cond, allocator)
+ free_ast(n.body, allocator)
+ case ^Type_Switch_Stmt:
+ free_ast(n.label, allocator)
+ free_ast(n.tag, allocator)
+ free_ast(n.expr, allocator)
+ free_ast(n.body, allocator)
+ case ^Branch_Stmt:
+ free_ast(n.label, allocator)
+ case ^Using_Stmt:
+ free_ast(n.list, allocator)
+ case ^Bad_Decl:
+ case ^Value_Decl:
+ free_ast(n.attributes, allocator)
+ free_ast(n.names, allocator)
+ free_ast(n.type, allocator)
+ free_ast(n.values, allocator)
+ case ^Package_Decl:
+ case ^Import_Decl:
+ case ^Foreign_Block_Decl:
+ free_ast(n.attributes, allocator)
+ free_ast(n.foreign_library, allocator)
+ free_ast(n.body, allocator)
+ case ^Foreign_Import_Decl:
+ free_ast(n.name, allocator)
+ free_ast(n.attributes, allocator)
+ case ^Proc_Group:
+ free_ast(n.args, allocator)
+ case ^Attribute:
+ free_ast(n.elems, allocator)
+ case ^Field:
+ free_ast(n.names, allocator)
+ free_ast(n.type, allocator)
+ free_ast(n.default_value, allocator)
//free_ast(n.docs);
//free_ast(n.comment);
- case Field_List:
- free_ast(n.list, allocator);
- case Typeid_Type:
- free_ast(n.specialization, allocator);
- case Helper_Type:
- free_ast(n.type, allocator);
- case Distinct_Type:
- free_ast(n.type, allocator);
- case Poly_Type:
- free_ast(n.type, allocator);
- free_ast(n.specialization, allocator);
- case Proc_Type:
- free_ast(n.params, allocator);
- free_ast(n.results, allocator);
- case Pointer_Type:
- free_ast(n.elem, allocator);
- case Array_Type:
- free_ast(n.len, allocator);
- free_ast(n.elem, allocator);
- free_ast(n.tag, allocator);
- case Dynamic_Array_Type:
- free_ast(n.elem, allocator);
- free_ast(n.tag, allocator);
- case Struct_Type:
- free_ast(n.poly_params, allocator);
- free_ast(n.align, allocator);
- free_ast(n.fields, allocator);
- free_ast(n.where_clauses, allocator);
- case Union_Type:
- free_ast(n.poly_params, allocator);
- free_ast(n.align, allocator);
- free_ast(n.variants, allocator);
- free_ast(n.where_clauses, allocator);
- case Enum_Type:
- free_ast(n.base_type, allocator);
- free_ast(n.fields, allocator);
- case Bit_Set_Type:
- free_ast(n.elem, allocator);
- free_ast(n.underlying, allocator);
- case Map_Type:
- free_ast(n.key, allocator);
- free_ast(n.value, allocator);
- case Multi_Pointer_Type:
- free_ast(n.elem, allocator);
- case Matrix_Type:
- free_ast(n.elem, allocator);
+ case ^Field_List:
+ free_ast(n.list, allocator)
+ case ^Typeid_Type:
+ free_ast(n.specialization, allocator)
+ case ^Helper_Type:
+ free_ast(n.type, allocator)
+ case ^Distinct_Type:
+ free_ast(n.type, allocator)
+ case ^Poly_Type:
+ free_ast(n.type, allocator)
+ free_ast(n.specialization, allocator)
+ case ^Proc_Type:
+ free_ast(n.params, allocator)
+ free_ast(n.results, allocator)
+ case ^Pointer_Type:
+ free_ast(n.elem, allocator)
+ case ^Array_Type:
+ free_ast(n.len, allocator)
+ free_ast(n.elem, allocator)
+ free_ast(n.tag, allocator)
+ case ^Dynamic_Array_Type:
+ free_ast(n.elem, allocator)
+ free_ast(n.tag, allocator)
+ case ^Struct_Type:
+ free_ast(n.poly_params, allocator)
+ free_ast(n.align, allocator)
+ free_ast(n.fields, allocator)
+ free_ast(n.where_clauses, allocator)
+ case ^Union_Type:
+ free_ast(n.poly_params, allocator)
+ free_ast(n.align, allocator)
+ free_ast(n.variants, allocator)
+ free_ast(n.where_clauses, allocator)
+ case ^Enum_Type:
+ free_ast(n.base_type, allocator)
+ free_ast(n.fields, allocator)
+ case ^Bit_Set_Type:
+ free_ast(n.elem, allocator)
+ free_ast(n.underlying, allocator)
+ case ^Map_Type:
+ free_ast(n.key, allocator)
+ free_ast(n.value, allocator)
+ case ^Multi_Pointer_Type:
+ free_ast(n.elem, allocator)
+ case ^Matrix_Type:
+ free_ast(n.elem, allocator)
case:
- panic(fmt.aprintf("free Unhandled node kind: %T", n));
+ panic(fmt.aprintf("free Unhandled node kind: %T", n))
}
- mem.free(node, allocator);
+ mem.free(node, allocator)
}
free_ast_file :: proc(file: ast.File, allocator := context.allocator) {
for decl in file.decls {
- free_ast(decl, allocator);
+ free_ast(decl, allocator)
}
- free_ast(file.pkg_decl, allocator);
+ free_ast(file.pkg_decl, allocator)
for comment in file.comments {
- free_ast(comment, allocator);
+ free_ast(comment, allocator)
}
- delete(file.comments);
- delete(file.imports);
- delete(file.decls);
+ delete(file.comments)
+ delete(file.imports)
+ delete(file.decls)
}
node_equal :: proc{
node_equal_node,
node_equal_array,
node_equal_dynamic_array,
-};
+}
node_equal_array :: proc(a, b: $A/[]^$T) -> bool {
- ret := true;
+ ret := true
if len(a) != len(b) {
- return false;
+ return false
}
for elem, i in a {
- ret &= node_equal(elem, b[i]);
+ ret &= node_equal(elem, b[i])
}
- return ret;
+ return ret
}
node_equal_dynamic_array :: proc(a, b: $A/[dynamic]^$T) -> bool {
- ret := true;
+ ret := true
if len(a) != len(b) {
- return false;
+ return false
}
for elem, i in a {
- ret &= node_equal(elem, b[i]);
+ ret &= node_equal(elem, b[i])
}
- return ret;
+ return ret
}
node_equal_node :: proc(a, b: ^ast.Node) -> bool {
-
- using ast;
+ using ast
if a == nil || b == nil {
- return false;
+ return false
}
- switch m in b.derived {
- case Bad_Expr:
- if n, ok := a.derived.(Bad_Expr); ok {
- return true;
+ #partial switch m in b.derived {
+ case ^Bad_Expr:
+ if n, ok := a.derived.(^Bad_Expr); ok {
+ return true
}
- case Ident:
- if n, ok := a.derived.(Ident); ok {
- return true;
+ case ^Ident:
+ if n, ok := a.derived.(^Ident); ok {
+ return true
//return n.name == m.name;
}
- case Implicit:
- if n, ok := a.derived.(Implicit); ok {
- return true;
- }
- case Undef:
- if n, ok := a.derived.(Undef); ok {
- return true;
- }
- case Basic_Lit:
- if n, ok := a.derived.(Basic_Lit); ok {
- return true;
- }
- case Poly_Type:
- return true;
- case Ellipsis:
- if n, ok := a.derived.(Ellipsis); ok {
- return node_equal(n.expr, m.expr);
- }
- case Tag_Expr:
- if n, ok := a.derived.(Tag_Expr); ok {
- return node_equal(n.expr, m.expr);
- }
- case Unary_Expr:
- if n, ok := a.derived.(Unary_Expr); ok {
- return node_equal(n.expr, m.expr);
- }
- case Binary_Expr:
- if n, ok := a.derived.(Binary_Expr); ok {
- ret := node_equal(n.left, m.left);
- ret &= node_equal(n.right, m.right);
- return ret;
- }
- case Paren_Expr:
- if n, ok := a.derived.(Paren_Expr); ok {
- return node_equal(n.expr, m.expr);
- }
- case Selector_Expr:
- if n, ok := a.derived.(Selector_Expr); ok {
- ret := node_equal(n.expr, m.expr);
- ret &= node_equal(n.field, m.field);
- return ret;
- }
- case Slice_Expr:
- if n, ok := a.derived.(Slice_Expr); ok {
- ret := node_equal(n.expr, m.expr);
- ret &= node_equal(n.low, m.low);
- ret &= node_equal(n.high, m.high);
- return ret;
- }
- case Distinct_Type:
- if n, ok := a.derived.(Distinct_Type); ok {
- return node_equal(n.type, m.type);
- }
- case Proc_Type:
- if n, ok := a.derived.(Proc_Type); ok {
- ret := node_equal(n.params, m.params);
- ret &= node_equal(n.results, m.results);
- return ret;
- }
- case Pointer_Type:
- if n, ok := a.derived.(Pointer_Type); ok {
- return node_equal(n.elem, m.elem);
- }
- case Array_Type:
- if n, ok := a.derived.(Array_Type); ok {
- ret := node_equal(n.elem, m.elem);
+ case ^Implicit:
+ if n, ok := a.derived.(^Implicit); ok {
+ return true
+ }
+ case ^Undef:
+ if n, ok := a.derived.(^Undef); ok {
+ return true
+ }
+ case ^Basic_Lit:
+ if n, ok := a.derived.(^Basic_Lit); ok {
+ return true
+ }
+ case ^Poly_Type:
+ return true
+ case ^Ellipsis:
+ if n, ok := a.derived.(^Ellipsis); ok {
+ return node_equal(n.expr, m.expr)
+ }
+ case ^Tag_Expr:
+ if n, ok := a.derived.(^Tag_Expr); ok {
+ return node_equal(n.expr, m.expr)
+ }
+ case ^Unary_Expr:
+ if n, ok := a.derived.(^Unary_Expr); ok {
+ return node_equal(n.expr, m.expr)
+ }
+ case ^Binary_Expr:
+ if n, ok := a.derived.(^Binary_Expr); ok {
+ ret := node_equal(n.left, m.left)
+ ret &= node_equal(n.right, m.right)
+ return ret
+ }
+ case ^Paren_Expr:
+ if n, ok := a.derived.(^Paren_Expr); ok {
+ return node_equal(n.expr, m.expr)
+ }
+ case ^Selector_Expr:
+ if n, ok := a.derived.(^Selector_Expr); ok {
+ ret := node_equal(n.expr, m.expr)
+ ret &= node_equal(n.field, m.field)
+ return ret
+ }
+ case ^Slice_Expr:
+ if n, ok := a.derived.(^Slice_Expr); ok {
+ ret := node_equal(n.expr, m.expr)
+ ret &= node_equal(n.low, m.low)
+ ret &= node_equal(n.high, m.high)
+ return ret
+ }
+ case ^Distinct_Type:
+ if n, ok := a.derived.(^Distinct_Type); ok {
+ return node_equal(n.type, m.type)
+ }
+ case ^Proc_Type:
+ if n, ok := a.derived.(^Proc_Type); ok {
+ ret := node_equal(n.params, m.params)
+ ret &= node_equal(n.results, m.results)
+ return ret
+ }
+ case ^Pointer_Type:
+ if n, ok := a.derived.(^Pointer_Type); ok {
+ return node_equal(n.elem, m.elem)
+ }
+ case ^Array_Type:
+ if n, ok := a.derived.(^Array_Type); ok {
+ ret := node_equal(n.elem, m.elem)
if n.len != nil && m.len != nil {
- ret &= node_equal(n.len, m.len);
+ ret &= node_equal(n.len, m.len)
}
- return ret;
- }
- case Dynamic_Array_Type:
- if n, ok := a.derived.(Dynamic_Array_Type); ok {
- return node_equal(n.elem, m.elem);
- }
- case Struct_Type:
- if n, ok := a.derived.(Struct_Type); ok {
- ret := node_equal(n.poly_params, m.poly_params);
- ret &= node_equal(n.align, m.align);
- ret &= node_equal(n.fields, m.fields);
- return ret;
- }
- case Field:
- if n, ok := a.derived.(Field); ok {
- ret := node_equal(n.names, m.names);
- ret &= node_equal(n.type, m.type);
- ret &= node_equal(n.default_value, m.default_value);
- return ret;
- }
- case Field_List:
- if n, ok := a.derived.(Field_List); ok {
- return node_equal(n.list, m.list);
- }
- case Field_Value:
- if n, ok := a.derived.(Field_Value); ok {
- ret := node_equal(n.field, m.field);
- ret &= node_equal(n.value, m.value);
- return ret;
- }
- case Union_Type:
- if n, ok := a.derived.(Union_Type); ok {
- ret := node_equal(n.poly_params, m.poly_params);
- ret &= node_equal(n.align, m.align);
- ret &= node_equal(n.variants, m.variants);
- return ret;
- }
- case Enum_Type:
- if n, ok := a.derived.(Enum_Type); ok {
- ret := node_equal(n.base_type, m.base_type);
- ret &= node_equal(n.fields, m.fields);
- return ret;
- }
- case Bit_Set_Type:
- if n, ok := a.derived.(Bit_Set_Type); ok {
- ret := node_equal(n.elem, m.elem);
- ret &= node_equal(n.underlying, m.underlying);
- return ret;
- }
- case Map_Type:
- if n, ok := a.derived.(Map_Type); ok {
- ret := node_equal(n.key, m.key);
- ret &= node_equal(n.value, m.value);
- return ret;
- }
- case Call_Expr:
- if n, ok := a.derived.(Call_Expr); ok {
- ret := node_equal(n.expr, m.expr);
- ret &= node_equal(n.args, m.args);
- return ret;
- }
- case Typeid_Type:
- return true;
+ return ret
+ }
+ case ^Dynamic_Array_Type:
+ if n, ok := a.derived.(^Dynamic_Array_Type); ok {
+ return node_equal(n.elem, m.elem)
+ }
+ case ^Struct_Type:
+ if n, ok := a.derived.(^Struct_Type); ok {
+ ret := node_equal(n.poly_params, m.poly_params)
+ ret &= node_equal(n.align, m.align)
+ ret &= node_equal(n.fields, m.fields)
+ return ret
+ }
+ case ^Field:
+ if n, ok := a.derived.(^Field); ok {
+ ret := node_equal(n.names, m.names)
+ ret &= node_equal(n.type, m.type)
+ ret &= node_equal(n.default_value, m.default_value)
+ return ret
+ }
+ case ^Field_List:
+ if n, ok := a.derived.(^Field_List); ok {
+ return node_equal(n.list, m.list)
+ }
+ case ^Field_Value:
+ if n, ok := a.derived.(^Field_Value); ok {
+ ret := node_equal(n.field, m.field)
+ ret &= node_equal(n.value, m.value)
+ return ret
+ }
+ case ^Union_Type:
+ if n, ok := a.derived.(^Union_Type); ok {
+ ret := node_equal(n.poly_params, m.poly_params)
+ ret &= node_equal(n.align, m.align)
+ ret &= node_equal(n.variants, m.variants)
+ return ret
+ }
+ case ^Enum_Type:
+ if n, ok := a.derived.(^Enum_Type); ok {
+ ret := node_equal(n.base_type, m.base_type)
+ ret &= node_equal(n.fields, m.fields)
+ return ret
+ }
+ case ^Bit_Set_Type:
+ if n, ok := a.derived.(^Bit_Set_Type); ok {
+ ret := node_equal(n.elem, m.elem)
+ ret &= node_equal(n.underlying, m.underlying)
+ return ret
+ }
+ case ^Map_Type:
+ if n, ok := a.derived.(^Map_Type); ok {
+ ret := node_equal(n.key, m.key)
+ ret &= node_equal(n.value, m.value)
+ return ret
+ }
+ case ^Call_Expr:
+ if n, ok := a.derived.(^Call_Expr); ok {
+ ret := node_equal(n.expr, m.expr)
+ ret &= node_equal(n.args, m.args)
+ return ret
+ }
+ case ^Typeid_Type:
+ return true
case:
- log.warn("Unhandled poly node kind: %T", m);
+ log.warn("Unhandled poly node kind: %T", m)
}
- return false;
+ return false
}
/*
@@ -712,199 +703,198 @@ node_equal_node :: proc(a, b: ^ast.Node) -> bool {
*/
node_to_string :: proc(node: ^ast.Node) -> string {
- builder := strings.make_builder(context.temp_allocator);
+ builder := strings.make_builder(context.temp_allocator)
- build_string(node, &builder);
+ build_string(node, &builder)
- return strings.to_string(builder);
+ return strings.to_string(builder)
}
build_string :: proc{
build_string_ast_array,
build_string_dynamic_array,
build_string_node,
-};
+}
build_string_dynamic_array :: proc(array: $A/[]^$T, builder: ^strings.Builder) {
for elem, i in array {
- build_string(elem, builder);
+ build_string(elem, builder)
}
}
build_string_ast_array :: proc(array: $A/[dynamic]^$T, builder: ^strings.Builder) {
for elem, i in array {
- build_string(elem, builder);
+ build_string(elem, builder)
}
}
build_string_node :: proc(node: ^ast.Node, builder: ^strings.Builder) {
- using ast;
+ using ast
if node == nil {
- return;
+ return
}
- switch n in node.derived {
- case Bad_Expr:
- case Ident:
+ #partial switch n in node.derived {
+ case ^Bad_Expr:
+ case ^Ident:
if strings.contains(n.name, "/") {
- strings.write_string(builder, path.base(n.name, false, context.temp_allocator));
+ strings.write_string(builder, path.base(n.name, false, context.temp_allocator))
} else {
- strings.write_string(builder, n.name);
- }
- case Implicit:
- strings.write_string(builder, n.tok.text);
- case Undef:
- case Basic_Lit:
- strings.write_string(builder, n.tok.text);
- case Basic_Directive:
- strings.write_string(builder, n.name);
- case Implicit_Selector_Expr:
- strings.write_string(builder, ".");
- build_string(n.field, builder);
- case Ellipsis:
- strings.write_string(builder, "..");
- build_string(n.expr, builder);
- case Proc_Lit:
- build_string(n.type, builder);
- build_string(n.body, builder);
- case Comp_Lit:
- build_string(n.type, builder);
- strings.write_string(builder, "{");
- build_string(n.elems, builder);
- strings.write_string(builder, "}");
- case Tag_Expr:
- build_string(n.expr, builder);
- case Unary_Expr:
- build_string(n.expr, builder);
- case Binary_Expr:
- build_string(n.left, builder);
- build_string(n.right, builder);
- case Paren_Expr:
- strings.write_string(builder, "(");
- build_string(n.expr, builder);
- strings.write_string(builder, ")");
- case Call_Expr:
- build_string(n.expr, builder);
- strings.write_string(builder, "(");
+ strings.write_string(builder, n.name)
+ }
+ case ^Implicit:
+ strings.write_string(builder, n.tok.text)
+ case ^Undef:
+ case ^Basic_Lit:
+ strings.write_string(builder, n.tok.text)
+ case ^Basic_Directive:
+ strings.write_string(builder, n.name)
+ case ^Implicit_Selector_Expr:
+ strings.write_string(builder, ".")
+ build_string(n.field, builder)
+ case ^Ellipsis:
+ strings.write_string(builder, "..")
+ build_string(n.expr, builder)
+ case ^Proc_Lit:
+ build_string(n.type, builder)
+ build_string(n.body, builder)
+ case ^Comp_Lit:
+ build_string(n.type, builder)
+ strings.write_string(builder, "{")
+ build_string(n.elems, builder)
+ strings.write_string(builder, "}")
+ case ^Tag_Expr:
+ build_string(n.expr, builder)
+ case ^Unary_Expr:
+ build_string(n.expr, builder)
+ case ^Binary_Expr:
+ build_string(n.left, builder)
+ build_string(n.right, builder)
+ case ^Paren_Expr:
+ strings.write_string(builder, "(")
+ build_string(n.expr, builder)
+ strings.write_string(builder, ")")
+ case ^Call_Expr:
+ build_string(n.expr, builder)
+ strings.write_string(builder, "(")
for arg, i in n.args {
- build_string(arg, builder);
+ build_string(arg, builder)
if len(n.args) - 1 != i {
- strings.write_string(builder, ", ");
+ strings.write_string(builder, ", ")
}
}
- strings.write_string(builder, ")");
- case Selector_Expr:
- build_string(n.expr, builder);
- strings.write_string(builder, ".");
- build_string(n.field, builder);
- case Index_Expr:
- build_string(n.expr, builder);
- strings.write_string(builder, "[");
- build_string(n.index, builder);
- strings.write_string(builder, "]");
- case Deref_Expr:
- build_string(n.expr, builder);
- case Slice_Expr:
- build_string(n.expr, builder);
- build_string(n.low, builder);
- build_string(n.high, builder);
- case Field_Value:
- build_string(n.field, builder);
- strings.write_string(builder, ": ");
- build_string(n.value, builder);
- case Type_Cast:
- build_string(n.type, builder);
- build_string(n.expr, builder);
- case Bad_Stmt:
- case Bad_Decl:
- case Attribute:
- build_string(n.elems, builder);
- case Field:
-
+ strings.write_string(builder, ")")
+ case ^Selector_Expr:
+ build_string(n.expr, builder)
+ strings.write_string(builder, ".")
+ build_string(n.field, builder)
+ case ^Index_Expr:
+ build_string(n.expr, builder)
+ strings.write_string(builder, "[")
+ build_string(n.index, builder)
+ strings.write_string(builder, "]")
+ case ^Deref_Expr:
+ build_string(n.expr, builder)
+ case ^Slice_Expr:
+ build_string(n.expr, builder)
+ build_string(n.low, builder)
+ build_string(n.high, builder)
+ case ^Field_Value:
+ build_string(n.field, builder)
+ strings.write_string(builder, ": ")
+ build_string(n.value, builder)
+ case ^Type_Cast:
+ build_string(n.type, builder)
+ build_string(n.expr, builder)
+ case ^Bad_Stmt:
+ case ^Bad_Decl:
+ case ^Attribute:
+ build_string(n.elems, builder)
+ case ^Field:
for name, i in n.names {
- build_string(name, builder);
+ build_string(name, builder)
if len(n.names) - 1 != i {
- strings.write_string(builder, ", ");
+ strings.write_string(builder, ", ")
}
}
if len(n.names) > 0 && n.type != nil {
- strings.write_string(builder, ": ");
- build_string(n.type, builder);
+ strings.write_string(builder, ": ")
+ build_string(n.type, builder)
if n.default_value != nil && n.type != nil {
- strings.write_string(builder, " = ");
+ strings.write_string(builder, " = ")
}
} else if len(n.names) > 0 && n.default_value != nil {
- strings.write_string(builder, " := ");
+ strings.write_string(builder, " := ")
} else {
- build_string(n.type, builder);
+ build_string(n.type, builder)
}
- build_string(n.default_value, builder);
- case Field_List:
+ build_string(n.default_value, builder)
+ case ^Field_List:
for field, i in n.list {
- build_string(field, builder);
+ build_string(field, builder)
if len(n.list) - 1 != i {
- strings.write_string(builder, ",");
+ strings.write_string(builder, ",")
}
}
- case Typeid_Type:
- strings.write_string(builder, "$");
- build_string(n.specialization, builder);
- case Helper_Type:
- build_string(n.type, builder);
- case Distinct_Type:
- build_string(n.type, builder);
- case Poly_Type:
- strings.write_string(builder, "$");
+ case ^Typeid_Type:
+ strings.write_string(builder, "$")
+ build_string(n.specialization, builder)
+ case ^Helper_Type:
+ build_string(n.type, builder)
+ case ^Distinct_Type:
+ build_string(n.type, builder)
+ case ^Poly_Type:
+ strings.write_string(builder, "$")
- build_string(n.type, builder);
+ build_string(n.type, builder)
if n.specialization != nil {
- strings.write_string(builder, "/");
- build_string(n.specialization, builder);
- }
- case Proc_Type:
- strings.write_string(builder, "proc(");
- build_string(n.params, builder);
- strings.write_string(builder, ") -> ");
- build_string(n.results, builder);
- case Pointer_Type:
- strings.write_string(builder, "^");
- build_string(n.elem, builder);
- case Array_Type:
- strings.write_string(builder, "[");
- build_string(n.len, builder);
- strings.write_string(builder, "]");
- build_string(n.elem, builder);
- case Dynamic_Array_Type:
- strings.write_string(builder, "[dynamic]");
- build_string(n.elem, builder);
- case Struct_Type:
- build_string(n.poly_params, builder);
- build_string(n.align, builder);
- build_string(n.fields, builder);
- case Union_Type:
- build_string(n.poly_params, builder);
- build_string(n.align, builder);
- build_string(n.variants, builder);
- case Enum_Type:
- build_string(n.base_type, builder);
- build_string(n.fields, builder);
- case Bit_Set_Type:
- build_string(n.elem, builder);
- build_string(n.underlying, builder);
- case Map_Type:
- strings.write_string(builder, "map");
- strings.write_string(builder, "[");
- build_string(n.key, builder);
- strings.write_string(builder, "]");
- build_string(n.value, builder);
+ strings.write_string(builder, "/")
+ build_string(n.specialization, builder)
+ }
+ case ^Proc_Type:
+ strings.write_string(builder, "proc(")
+ build_string(n.params, builder)
+ strings.write_string(builder, ") -> ")
+ build_string(n.results, builder)
+ case ^Pointer_Type:
+ strings.write_string(builder, "^")
+ build_string(n.elem, builder)
+ case ^Array_Type:
+ strings.write_string(builder, "[")
+ build_string(n.len, builder)
+ strings.write_string(builder, "]")
+ build_string(n.elem, builder)
+ case ^Dynamic_Array_Type:
+ strings.write_string(builder, "[dynamic]")
+ build_string(n.elem, builder)
+ case ^Struct_Type:
+ build_string(n.poly_params, builder)
+ build_string(n.align, builder)
+ build_string(n.fields, builder)
+ case ^Union_Type:
+ build_string(n.poly_params, builder)
+ build_string(n.align, builder)
+ build_string(n.variants, builder)
+ case ^Enum_Type:
+ build_string(n.base_type, builder)
+ build_string(n.fields, builder)
+ case ^Bit_Set_Type:
+ build_string(n.elem, builder)
+ build_string(n.underlying, builder)
+ case ^Map_Type:
+ strings.write_string(builder, "map")
+ strings.write_string(builder, "[")
+ build_string(n.key, builder)
+ strings.write_string(builder, "]")
+ build_string(n.value, builder)
}
}
diff --git a/src/common/fuzzy.odin b/src/common/fuzzy.odin
index 68223e0..f6c8b11 100644
--- a/src/common/fuzzy.odin
+++ b/src/common/fuzzy.odin
@@ -7,15 +7,15 @@ import "core:fmt"
Ported from https://github.com/llvm/llvm-project/blob/master/clang-tools-extra/clangd/FuzzyMatch.cpp
*/
-max_pattern :: 63;
-max_word :: 127;
+max_pattern :: 63
+max_word :: 127
-awful_score: int = -(1 << 13);
-perfect_bonus :: 4;
-miss :: 0;
-match :: 1;
+awful_score: int = -(1 << 13)
+perfect_bonus :: 4
+miss :: 0
+match :: 1
-FuzzyCharTypeSet :: u8;
+FuzzyCharTypeSet :: u8
//do bitfield instead
FuzzyScoreInfo :: struct {
@@ -60,7 +60,7 @@ char_roles: []u8 = {
/*Prev=Upper */0x00,0x55,0x59,0xff, // Ditto, but U(U)U->Tail
/*Prev=Separ */0x00,0xaa,0xaa,0xff, // After separator, like at start
// clang-format on
-};
+}
char_types: []u8 = {
0x00,0x00,0x00,0x00, // Control characters
@@ -75,266 +75,266 @@ char_types: []u8 = {
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, // (probably UTF-8).
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
-};
+}
make_fuzzy_matcher :: proc(pattern: string, allocator := context.temp_allocator) -> ^FuzzyMatcher {
- matcher := new(FuzzyMatcher, allocator);
+ matcher := new(FuzzyMatcher, allocator)
- matcher.pattern_count = min(len(pattern), max_pattern);
- matcher.score_scale = matcher.pattern_count > 0 ? 1 / cast(f32)(perfect_bonus * matcher.pattern_count) : 0;
- matcher.pattern = pattern[0:matcher.pattern_count];
- matcher.lower_pattern = strings.to_lower(matcher.pattern, context.temp_allocator);
+ matcher.pattern_count = min(len(pattern), max_pattern)
+ matcher.score_scale = matcher.pattern_count > 0 ? 1 / cast(f32)(perfect_bonus * matcher.pattern_count) : 0
+ matcher.pattern = pattern[0:matcher.pattern_count]
+ matcher.lower_pattern = strings.to_lower(matcher.pattern, context.temp_allocator)
- score_info_miss: FuzzyScoreInfo;
- score_info_miss.score = 0;
- score_info_miss.prev = miss;
+ score_info_miss: FuzzyScoreInfo
+ score_info_miss.score = 0
+ score_info_miss.prev = miss
- matcher.scores[0][0][miss] = score_info_miss;
+ matcher.scores[0][0][miss] = score_info_miss
- score_info_match: FuzzyScoreInfo;
- score_info_match.score = awful_score;
- score_info_match.prev = match;
+ score_info_match: FuzzyScoreInfo
+ score_info_match.score = awful_score
+ score_info_match.prev = match
- matcher.scores[0][0][match] = score_info_match;
+ matcher.scores[0][0][match] = score_info_match
for p := 0; p < matcher.pattern_count; p += 1 {
for w := 0; w < p; w += 1 {
for a := 0; a < 2; a += 1 {
- score_info: FuzzyScoreInfo;
- score_info.score = awful_score;
- score_info.prev = miss;
- matcher.scores[p][w][a] = score_info;
- ref := matcher.pattern_role[:matcher.pattern_count];
- matcher.pattern_type_set = fuzzy_calculate_roles(matcher.pattern, &ref);
+ score_info: FuzzyScoreInfo
+ score_info.score = awful_score
+ score_info.prev = miss
+ matcher.scores[p][w][a] = score_info
+ ref := matcher.pattern_role[:matcher.pattern_count]
+ matcher.pattern_type_set = fuzzy_calculate_roles(matcher.pattern, &ref)
}
}
}
- return matcher;
+ return matcher
}
fuzzy_to_acronym :: proc(word: string) -> (string, bool) {
- builder := strings.make_builder(context.temp_allocator);
+ builder := strings.make_builder(context.temp_allocator)
if len(word) <= 1 {
- return "", false;
+ return "", false
}
- i := 1;
- last_char := word[0];
+ i := 1
+ last_char := word[0]
- strings.write_byte(&builder, last_char);
+ strings.write_byte(&builder, last_char)
for i < len(word) {
if last_char == '_' {
- strings.write_byte(&builder, word[i]);
+ strings.write_byte(&builder, word[i])
}
- last_char = word[i];
+ last_char = word[i]
- i += 1;
+ i += 1
}
- str := strings.to_string(builder);
+ str := strings.to_string(builder)
if len(str) <= 1 {
- return "", false;
+ return "", false
}
- return str, true;
+ return str, true
}
//changed from bool to int because of a linux bug - 10.05.2021
fuzzy_match :: proc(matcher: ^FuzzyMatcher, word: string) -> (f32, int) {
if !fuzzy_init(matcher, word) {
- return 0, 0;
+ return 0, 0
}
if matcher.pattern_count <= 0 {
- return 1, 1;
+ return 1, 1
}
if acronym, ok := fuzzy_to_acronym(word); ok {
if acronym == matcher.pattern {
- return 20, 1;
+ return 20, 1
}
}
- fuzzy_build_graph(matcher);
+ fuzzy_build_graph(matcher)
best := max(cast(int)matcher.scores[matcher.pattern_count][matcher.word_count][miss].score,
- cast(int)matcher.scores[matcher.pattern_count][matcher.word_count][match].score);
+ cast(int)matcher.scores[matcher.pattern_count][matcher.word_count][match].score)
if fuzzy_is_awful(best) {
- return 0.0, 0;
+ return 0.0, 0
}
- score := matcher.score_scale * min(perfect_bonus * cast(f32)matcher.pattern_count, cast(f32)max(0, best));
+ score := matcher.score_scale * min(perfect_bonus * cast(f32)matcher.pattern_count, cast(f32)max(0, best))
if matcher.word_count == matcher.pattern_count {
- score *= 2;
+ score *= 2
}
- return score, 1;
+ return score, 1
}
fuzzy_is_awful :: proc(s: int) -> bool {
- return s < awful_score / 2;
+ return s < awful_score / 2
}
fuzzy_calculate_roles :: proc(text: string, roles: ^[]FuzzyCharRole) -> FuzzyCharTypeSet {
- assert(len(text) == len(roles));
+ assert(len(text) == len(roles))
if len(text) == 0 {
- return 0;
+ return 0
}
- type: FuzzyCharType = cast(FuzzyCharType)fuzzy_packed_lookup(char_types, cast(uint)text[0]);
+ type: FuzzyCharType = cast(FuzzyCharType)fuzzy_packed_lookup(char_types, cast(uint)text[0])
- type_set: FuzzyCharTypeSet = cast(u8)(1 << cast(uint)type);
+ type_set: FuzzyCharTypeSet = cast(u8)(1 << cast(uint)type)
- types := type;
+ types := type
for i := 0; i < len(text) - 1; i += 1 {
- type = cast(FuzzyCharType)fuzzy_packed_lookup(char_types, cast(uint)text[i + 1]);
- type_set |= 1 << cast(uint)type;
+ type = cast(FuzzyCharType)fuzzy_packed_lookup(char_types, cast(uint)text[i + 1])
+ type_set |= 1 << cast(uint)type
- fuzzy_rotate(type, &types);
+ fuzzy_rotate(type, &types)
- roles[i] = cast(FuzzyCharRole)fuzzy_packed_lookup(char_roles, cast(uint)types);
+ roles[i] = cast(FuzzyCharRole)fuzzy_packed_lookup(char_roles, cast(uint)types)
}
- fuzzy_rotate(.Empty, &types);
+ fuzzy_rotate(.Empty, &types)
- roles[len(text) - 1] = cast(FuzzyCharRole)fuzzy_packed_lookup(char_roles, cast(uint)types);
+ roles[len(text) - 1] = cast(FuzzyCharRole)fuzzy_packed_lookup(char_roles, cast(uint)types)
- return type_set;
+ return type_set
}
fuzzy_rotate :: proc(t: FuzzyCharType, types: ^FuzzyCharType) {
- types^ = cast(FuzzyCharType)(((cast(uint)types^ << 2) | cast(uint)t) & 0x3f);
+ types^ = cast(FuzzyCharType)(((cast(uint)types^ << 2) | cast(uint)t) & 0x3f)
}
fuzzy_packed_lookup :: proc(data: $A/[]$T, i: uint) -> T {
- return (data[i >> 2] >> ((i & 3) * 2)) & 3;
+ return (data[i >> 2] >> ((i & 3) * 2)) & 3
}
fuzzy_init :: proc(matcher: ^FuzzyMatcher, word: string) -> bool {
- matcher.word = word;
- matcher.word_count = min(max_word, len(matcher.word));
+ matcher.word = word
+ matcher.word_count = min(max_word, len(matcher.word))
if matcher.pattern_count > matcher.word_count {
- return false;
+ return false
}
if matcher.pattern_count == 0 {
- return true;
+ return true
}
- matcher.lower_word = strings.to_lower(word, context.temp_allocator);
+ matcher.lower_word = strings.to_lower(word, context.temp_allocator)
- w, p := 0, 0;
+ w, p := 0, 0
for ; p != matcher.pattern_count; w += 1 {
if w == matcher.word_count {
- return false;
+ return false
}
if matcher.lower_word[w] == matcher.lower_pattern[p] {
- p += 1;
+ p += 1
}
}
- ref := matcher.word_role[:matcher.word_count];
+ ref := matcher.word_role[:matcher.word_count]
- matcher.word_type_set = fuzzy_calculate_roles(word, &ref);
+ matcher.word_type_set = fuzzy_calculate_roles(word, &ref)
- return true;
+ return true
}
fuzzy_skip_penalty :: proc(matcher: ^FuzzyMatcher, w: int) -> int {
if w == 0 { // Skipping the first character.
- return 3;
+ return 3
}
if matcher.word_role[w] == .Head { // Skipping a segment.
- return 1;
+ return 1
}
- return 0;
+ return 0
}
fuzzy_build_graph :: proc(matcher: ^FuzzyMatcher) {
for w := 0; w < matcher.word_count; w += 1 {
- s: FuzzyScoreInfo;
+ s: FuzzyScoreInfo
- score := cast(int)matcher.scores[0][w][miss].score;
- penalty := fuzzy_skip_penalty(matcher, w);
- sum := score - penalty;
+ score := cast(int)matcher.scores[0][w][miss].score
+ penalty := fuzzy_skip_penalty(matcher, w)
+ sum := score - penalty
- s.score = sum;
- s.prev = miss;
+ s.score = sum
+ s.prev = miss
- matcher.scores[0][w + 1][miss] = s;
+ matcher.scores[0][w + 1][miss] = s
- s.score = awful_score;
- s.prev = miss;
+ s.score = awful_score
+ s.prev = miss
- matcher.scores[0][w + 1][match] = s;
+ matcher.scores[0][w + 1][match] = s
}
for p := 0; p < matcher.pattern_count; p += 1 {
for w := p; w < matcher.word_count; w += 1 {
- score := &matcher.scores[p + 1][w + 1];
- pre_miss := &matcher.scores[p + 1][w];
+ score := &matcher.scores[p + 1][w + 1]
+ pre_miss := &matcher.scores[p + 1][w]
- match_miss_score := pre_miss[match].score;
- miss_miss_score := pre_miss[miss].score;
+ match_miss_score := pre_miss[match].score
+ miss_miss_score := pre_miss[miss].score
if p < matcher.pattern_count - 1 {
- match_miss_score -= fuzzy_skip_penalty(matcher, w);
- miss_miss_score -= fuzzy_skip_penalty(matcher, w);
+ match_miss_score -= fuzzy_skip_penalty(matcher, w)
+ miss_miss_score -= fuzzy_skip_penalty(matcher, w)
}
if match_miss_score > miss_miss_score {
- s: FuzzyScoreInfo;
- s.score = match_miss_score;
- s.prev = match;
- score[miss] = s;
+ s: FuzzyScoreInfo
+ s.score = match_miss_score
+ s.prev = match
+ score[miss] = s
} else {
- s: FuzzyScoreInfo;
- s.score = miss_miss_score;
- s.prev = miss;
- score[miss] = s;
+ s: FuzzyScoreInfo
+ s.score = miss_miss_score
+ s.prev = miss
+ score[miss] = s
}
- pre_match := &matcher.scores[p][w];
+ pre_match := &matcher.scores[p][w]
- match_match_score := fuzzy_allow_match(matcher, p, w, match) ? cast(int)pre_match[match].score + fuzzy_match_bonus(matcher, p, w, match) : awful_score;
+ match_match_score := fuzzy_allow_match(matcher, p, w, match) ? cast(int)pre_match[match].score + fuzzy_match_bonus(matcher, p, w, match) : awful_score
- miss_match_score := fuzzy_allow_match(matcher, p, w, miss) ? cast(int)pre_match[miss].score + fuzzy_match_bonus(matcher, p, w, miss) : awful_score;
+ miss_match_score := fuzzy_allow_match(matcher, p, w, miss) ? cast(int)pre_match[miss].score + fuzzy_match_bonus(matcher, p, w, miss) : awful_score
if match_match_score > miss_match_score {
- s: FuzzyScoreInfo;
- s.score = match_match_score;
- s.prev = match;
- score[match] = s;
+ s: FuzzyScoreInfo
+ s.score = match_match_score
+ s.prev = match
+ score[match] = s
} else {
- s: FuzzyScoreInfo;
- s.score = miss_match_score;
- s.prev = miss;
- score[match] = s;
+ s: FuzzyScoreInfo
+ s.score = miss_match_score
+ s.prev = miss
+ score[match] = s
}
}
}
@@ -342,12 +342,12 @@ fuzzy_build_graph :: proc(matcher: ^FuzzyMatcher) {
fuzzy_match_bonus :: proc(matcher: ^FuzzyMatcher, p: int, w: int, last: int) -> int {
- assert(matcher.lower_pattern[p] == matcher.lower_word[w]);
+ assert(matcher.lower_pattern[p] == matcher.lower_word[w])
- s := 1;
+ s := 1
- is_pattern_single_case := (cast(uint)matcher.pattern_type_set == 1 << cast(uint)FuzzyCharType.Lower);
- is_pattern_single_case |= (cast(uint)matcher.pattern_type_set == 1 << cast(uint)FuzzyCharType.Upper);
+ is_pattern_single_case := (cast(uint)matcher.pattern_type_set == 1 << cast(uint)FuzzyCharType.Lower)
+ is_pattern_single_case |= (cast(uint)matcher.pattern_type_set == 1 << cast(uint)FuzzyCharType.Upper)
// Bonus: case matches, or a Head in the pattern aligns with one in the word.
// Single-case patterns lack segmentation signals and we assume any character
@@ -355,53 +355,53 @@ fuzzy_match_bonus :: proc(matcher: ^FuzzyMatcher, p: int, w: int, last: int) ->
if matcher.pattern[p] == matcher.word[w] ||
(matcher.word_role[w] == FuzzyCharRole.Head &&
(is_pattern_single_case || matcher.pattern_role[p] == FuzzyCharRole.Head)) {
- s += 1;
+ s += 1
//fmt.println("match 1");
}
// Bonus: a consecutive match. First character match also gets a bonus to
// ensure prefix final match score normalizes to 1.0.
if w == 0 || last == match {
- s += 2;
+ s += 2
//fmt.println("match 2");
}
// Penalty: matching inside a segment (and previous char wasn't matched).
if matcher.word_role[w] == FuzzyCharRole.Tail && p > 0 && last == miss {
- s -= 3;
+ s -= 3
//fmt.println("match 3");
}
// Penalty: a Head in the pattern matches in the middle of a word segment.
if matcher.pattern_role[p] == FuzzyCharRole.Head && matcher.word_role[w] == FuzzyCharRole.Tail {
- s -= 1;
+ s -= 1
//fmt.println("match 4");
}
// Penalty: matching the first pattern character in the middle of a segment.
if p == 0 && matcher.word_role[w] == FuzzyCharRole.Tail {
- s -= 4;
+ s -= 4
//fmt.println("match 5");
}
- assert(s <= perfect_bonus);
+ assert(s <= perfect_bonus)
- return s;
+ return s
}
fuzzy_allow_match :: proc(matcher: ^FuzzyMatcher, p: int, w: int, last: int) -> bool {
if matcher.lower_pattern[p] != matcher.lower_word[w] {
- return false;
+ return false
}
if last == miss {
if matcher.word_role[w] == FuzzyCharRole.Tail && (matcher.word[w] == matcher.lower_word[w] ||
0 >= (cast(uint)matcher.word_type_set & 1 << cast(uint)FuzzyCharType.Lower)) {
- return false;
+ return false
}
}
- return true;
+ return true
}
diff --git a/src/common/position.odin b/src/common/position.odin
index 4e84568..2ccd0a8 100644
--- a/src/common/position.odin
+++ b/src/common/position.odin
@@ -31,219 +31,219 @@ AbsoluteRange :: struct {
end: int,
}
-AbsolutePosition :: int;
+AbsolutePosition :: int
get_absolute_position :: proc(position: Position, document_text: []u8) -> (AbsolutePosition, bool) {
- absolute: AbsolutePosition;
+ absolute: AbsolutePosition
if len(document_text) == 0 {
- absolute = 0;
- return absolute, true;
+ absolute = 0
+ return absolute, true
}
- line_count := 0;
- index := 1;
- last := document_text[0];
+ line_count := 0
+ index := 1
+ last := document_text[0]
if !get_index_at_line(&index, &line_count, &last, document_text, position.line) {
- return absolute, false;
+ return absolute, false
}
- absolute = index + get_character_offset_u16_to_u8(position.character, document_text[index:]);
+ absolute = index + get_character_offset_u16_to_u8(position.character, document_text[index:])
- return absolute, true;
+ return absolute, true
}
get_relative_token_position :: proc(offset: int, document_text: []u8, current_start: int) -> Position {
- start_index := current_start;
+ start_index := current_start
- data := document_text[start_index:];
+ data := document_text[start_index:]
- i: int;
+ i: int
- position: Position;
+ position: Position
for i + start_index < offset {
- r, w := utf8.decode_rune(data[i:]);
+ r, w := utf8.decode_rune(data[i:])
if r == '\n' { //\r?
- position.character = 0;
- position.line += 1;
- i += 1;
+ position.character = 0
+ position.line += 1
+ i += 1
} else if w == 0 {
- return position;
+ return position
} else {
if r < 0x10000 {
- position.character += 1;
+ position.character += 1
} else {
- position.character += 2;
+ position.character += 2
}
- i += w;
+ i += w
}
}
- return position;
+ return position
}
/*
Get the range of a token in utf16 space
*/
get_token_range :: proc(node: ast.Node, document_text: string) -> Range {
- range: Range;
+ range: Range
go_backwards_to_endline :: proc(offset: int, document_text: []u8) -> int {
- index := offset;
+ index := offset
for index > 0 && document_text[index] != '\n' && document_text[index] != '\r' {
- index -= 1;
+ index -= 1
}
if index == 0 {
- return 0;
+ return 0
}
- return index + 1;
- };
+ return index + 1
+ }
- pos_offset := min(len(document_text) - 1, node.pos.offset);
- end_offset := min(len(document_text) - 1, node.end.offset);
+ pos_offset := min(len(document_text) - 1, node.pos.offset)
+ end_offset := min(len(document_text) - 1, node.end.offset)
- offset := go_backwards_to_endline(pos_offset, transmute([]u8)document_text);
+ offset := go_backwards_to_endline(pos_offset, transmute([]u8)document_text)
- range.start.line = node.pos.line - 1;
- range.start.character = get_character_offset_u8_to_u16(node.pos.column - 1, transmute([]u8)document_text[offset:]);
+ range.start.line = node.pos.line - 1
+ range.start.character = get_character_offset_u8_to_u16(node.pos.column - 1, transmute([]u8)document_text[offset:])
- offset = go_backwards_to_endline(end_offset, transmute([]u8)document_text);
+ offset = go_backwards_to_endline(end_offset, transmute([]u8)document_text)
- range.end.line = node.end.line - 1;
- range.end.character = get_character_offset_u8_to_u16(node.end.column - 1, transmute([]u8)document_text[offset:]);
+ range.end.line = node.end.line - 1
+ range.end.character = get_character_offset_u8_to_u16(node.end.column - 1, transmute([]u8)document_text[offset:])
- return range;
+ return range
}
get_absolute_range :: proc(range: Range, document_text: []u8) -> (AbsoluteRange, bool) {
- absolute: AbsoluteRange;
+ absolute: AbsoluteRange
if len(document_text) == 0 {
- absolute.start = 0;
- absolute.end = 0;
- return absolute, true;
+ absolute.start = 0
+ absolute.end = 0
+ return absolute, true
}
- line_count := 0;
- index := 1;
- last := document_text[0];
+ line_count := 0
+ index := 1
+ last := document_text[0]
if !get_index_at_line(&index, &line_count, &last, document_text, range.start.line) {
- return absolute, false;
+ return absolute, false
}
- absolute.start = index + get_character_offset_u16_to_u8(range.start.character, document_text[index:]);
+ absolute.start = index + get_character_offset_u16_to_u8(range.start.character, document_text[index:])
//if the last line was indexed at zero we have to move it back to index 1.
//This happens when line = 0
if index == 0 {
- index = 1;
+ index = 1
}
if !get_index_at_line(&index, &line_count, &last, document_text, range.end.line) {
- return absolute, false;
+ return absolute, false
}
- absolute.end = index + get_character_offset_u16_to_u8(range.end.character, document_text[index:]);
+ absolute.end = index + get_character_offset_u16_to_u8(range.end.character, document_text[index:])
- return absolute, true;
+ return absolute, true
}
get_index_at_line :: proc(current_index: ^int, current_line: ^int, last: ^u8, document_text: []u8, end_line: int) -> bool {
if end_line == 0 {
- current_index^ = 0;
- return true;
+ current_index^ = 0
+ return true
}
if current_line^ == end_line {
- return true;
+ return true
}
for ; current_index^ < len(document_text); current_index^ += 1 {
- current := document_text[current_index^];
+ current := document_text[current_index^]
if last^ == '\r' {
- current_line^ += 1;
+ current_line^ += 1
if current_line^ == end_line {
- last^ = current;
- current_index^ += 1;
- return true;
+ last^ = current
+ current_index^ += 1
+ return true
}
} else if current == '\n' {
- current_line^ += 1;
+ current_line^ += 1
if current_line^ == end_line {
- last^ = current;
- current_index^ += 1;
- return true;
+ last^ = current
+ current_index^ += 1
+ return true
}
}
- last^ = document_text[current_index^];
+ last^ = document_text[current_index^]
}
- return false;
+ return false
}
get_character_offset_u16_to_u8 :: proc(character_offset: int, document_text: []u8) -> int {
- utf8_idx := 0;
- utf16_idx := 0;
+ utf8_idx := 0
+ utf16_idx := 0
for utf16_idx < character_offset {
- r, w := utf8.decode_rune(document_text[utf8_idx:]);
+ r, w := utf8.decode_rune(document_text[utf8_idx:])
if r == '\n' || r == '\r' {
- return utf8_idx;
+ return utf8_idx
} else if w == 0 {
- return utf8_idx;
+ return utf8_idx
} else if r < 0x10000 {
- utf16_idx += 1;
+ utf16_idx += 1
} else {
- utf16_idx += 2;
+ utf16_idx += 2
}
- utf8_idx += w;
+ utf8_idx += w
}
- return utf8_idx;
+ return utf8_idx
}
get_character_offset_u8_to_u16 :: proc(character_offset: int, document_text: []u8) -> int {
- utf8_idx := 0;
- utf16_idx := 0;
+ utf8_idx := 0
+ utf16_idx := 0
for utf8_idx < character_offset {
- r, w := utf8.decode_rune(document_text[utf8_idx:]);
+ r, w := utf8.decode_rune(document_text[utf8_idx:])
if r == '\n' || r == '\r' {
- return utf16_idx;
+ return utf16_idx
} else if w == 0 {
- return utf16_idx;
+ return utf16_idx
} else if r < 0x10000 {
- utf16_idx += 1;
+ utf16_idx += 1
} else {
- utf16_idx += 2;
+ utf16_idx += 2
}
- utf8_idx += w;
+ utf8_idx += w
}
- return utf16_idx;
+ return utf16_idx
} \ No newline at end of file
diff --git a/src/common/sha1.odin b/src/common/sha1.odin
index 4516467..4f1d62f 100644
--- a/src/common/sha1.odin
+++ b/src/common/sha1.odin
@@ -5,58 +5,58 @@ import "core:fmt"
//ported version of https://llvm.org/doxygen/SHa1_8cpp_source.html
rol :: proc (number: u32, bits: u32) -> u32 {
- return number << bits | number >> (32 - bits);
+ return number << bits | number >> (32 - bits)
}
blk0 :: proc (buf: []u32, i: int) -> u32 {
- return buf[i];
+ return buf[i]
}
blk :: proc (buf: []u32, i: int) -> u32 {
buf[i & 15] = rol(buf[(i + 13) & 15] ~ buf[(i + 8) & 15] ~ buf[(i + 2) & 15] ~
- buf[i & 15], 1);
+ buf[i & 15], 1)
- return buf[i & 15];
+ return buf[i & 15]
}
r0 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) {
- e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk0(buf, i) + 0x5a827999 + rol(a^, 5);
- b^ = rol(b^, 30);
+ e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk0(buf, i) + 0x5a827999 + rol(a^, 5)
+ b^ = rol(b^, 30)
}
r1 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) {
- e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk(buf, i) + 0x5a827999 + rol(a^, 5);
- b^ += rol(b^, 30);
+ e^ += ((b^ & (c^ ~ d^)) ~ d^) + blk(buf, i) + 0x5a827999 + rol(a^, 5)
+ b^ += rol(b^, 30)
}
r2 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) {
- e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0x6ed9eba1 + rol(a^, 5);
- b^ += rol(b^, 30);
+ e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0x6ed9eba1 + rol(a^, 5)
+ b^ += rol(b^, 30)
}
r3 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) {
- e^ += (((b^ | c^) & d^) | (b^ & c^)) + blk(buf, i) + 0x8F1bbcdc + rol(a^, 5);
- b^ += rol(b^, 30);
+ e^ += (((b^ | c^) & d^) | (b^ & c^)) + blk(buf, i) + 0x8F1bbcdc + rol(a^, 5)
+ b^ += rol(b^, 30)
}
r4 :: proc (a: ^u32, b: ^u32, c: ^u32, d: ^u32, e: ^u32, i: int, buf: []u32) {
- e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0xca62c1d6 + rol(a^, 5);
- b^ += rol(b^, 30);
+ e^ += (b^ ~ c^ ~ d^) + blk(buf, i) + 0xca62c1d6 + rol(a^, 5)
+ b^ += rol(b^, 30)
}
-SHA1_K0 :: 0x5a827999;
-SHA1_K20 :: 0x6ed9eba1;
-SHA1_K40 :: 0x8f1bbcdc;
-SHA1_K60 :: 0xca62c1d6;
+SHA1_K0 :: 0x5a827999
+SHA1_K20 :: 0x6ed9eba1
+SHA1_K40 :: 0x8f1bbcdc
+SHA1_K60 :: 0xca62c1d6
-SEED_0 :: 0x67452301;
-SEED_1 :: 0xefcdab89;
-SEED_2 :: 0x98badcfe;
-SEED_3 :: 0x10325476;
-SEED_4 :: 0xc3d2e1f0;
+SEED_0 :: 0x67452301
+SEED_1 :: 0xefcdab89
+SEED_2 :: 0x98badcfe
+SEED_3 :: 0x10325476
+SEED_4 :: 0xc3d2e1f0
-BLOCK_LENGTH :: 64;
-HASH_LENGTH :: 20;
+BLOCK_LENGTH :: 64
+HASH_LENGTH :: 20
Sha1context :: struct {
buf: struct #raw_union {
@@ -69,222 +69,222 @@ Sha1context :: struct {
}
sha1_init :: proc (state_context: ^Sha1context) {
- state_context.state[0] = SEED_0;
- state_context.state[1] = SEED_1;
- state_context.state[2] = SEED_2;
- state_context.state[3] = SEED_3;
- state_context.state[4] = SEED_4;
- state_context.byte_count = 0;
- state_context.buf_offset = 0;
+ state_context.state[0] = SEED_0
+ state_context.state[1] = SEED_1
+ state_context.state[2] = SEED_2
+ state_context.state[3] = SEED_3
+ state_context.state[4] = SEED_4
+ state_context.byte_count = 0
+ state_context.buf_offset = 0
}
sha1_hash_block :: proc (state_context: ^Sha1context) {
- a := state_context.state[0];
- b := state_context.state[1];
- c := state_context.state[2];
- d := state_context.state[3];
- e := state_context.state[4];
+ a := state_context.state[0]
+ b := state_context.state[1]
+ c := state_context.state[2]
+ d := state_context.state[3]
+ e := state_context.state[4]
// 4 rounds of 20 operations each. loop unrolled.
- r0(&a, &b, &c, &d, &e, 0, state_context.buf.l[:]);
- r0(&e, &a, &b, &c, &d, 1, state_context.buf.l[:]);
- r0(&d, &e, &a, &b, &c, 2, state_context.buf.l[:]);
- r0(&c, &d, &e, &a, &b, 3, state_context.buf.l[:]);
- r0(&b, &c, &d, &e, &a, 4, state_context.buf.l[:]);
- r0(&a, &b, &c, &d, &e, 5, state_context.buf.l[:]);
- r0(&e, &a, &b, &c, &d, 6, state_context.buf.l[:]);
- r0(&d, &e, &a, &b, &c, 7, state_context.buf.l[:]);
- r0(&c, &d, &e, &a, &b, 8, state_context.buf.l[:]);
- r0(&b, &c, &d, &e, &a, 9, state_context.buf.l[:]);
- r0(&a, &b, &c, &d, &e, 10, state_context.buf.l[:]);
- r0(&e, &a, &b, &c, &d, 11, state_context.buf.l[:]);
- r0(&d, &e, &a, &b, &c, 12, state_context.buf.l[:]);
- r0(&c, &d, &e, &a, &b, 13, state_context.buf.l[:]);
- r0(&b, &c, &d, &e, &a, 14, state_context.buf.l[:]);
- r0(&a, &b, &c, &d, &e, 15, state_context.buf.l[:]);
- r1(&e, &a, &b, &c, &d, 16, state_context.buf.l[:]);
- r1(&d, &e, &a, &b, &c, 17, state_context.buf.l[:]);
- r1(&c, &d, &e, &a, &b, 18, state_context.buf.l[:]);
- r1(&b, &c, &d, &e, &a, 19, state_context.buf.l[:]);
-
- r2(&a, &b, &c, &d, &e, 20, state_context.buf.l[:]);
- r2(&e, &a, &b, &c, &d, 21, state_context.buf.l[:]);
- r2(&d, &e, &a, &b, &c, 22, state_context.buf.l[:]);
- r2(&c, &d, &e, &a, &b, 23, state_context.buf.l[:]);
- r2(&b, &c, &d, &e, &a, 24, state_context.buf.l[:]);
- r2(&a, &b, &c, &d, &e, 25, state_context.buf.l[:]);
- r2(&e, &a, &b, &c, &d, 26, state_context.buf.l[:]);
- r2(&d, &e, &a, &b, &c, 27, state_context.buf.l[:]);
- r2(&c, &d, &e, &a, &b, 28, state_context.buf.l[:]);
- r2(&b, &c, &d, &e, &a, 29, state_context.buf.l[:]);
- r2(&a, &b, &c, &d, &e, 30, state_context.buf.l[:]);
- r2(&e, &a, &b, &c, &d, 31, state_context.buf.l[:]);
- r2(&d, &e, &a, &b, &c, 32, state_context.buf.l[:]);
- r2(&c, &d, &e, &a, &b, 33, state_context.buf.l[:]);
- r2(&b, &c, &d, &e, &a, 34, state_context.buf.l[:]);
- r2(&a, &b, &c, &d, &e, 35, state_context.buf.l[:]);
- r2(&e, &a, &b, &c, &d, 36, state_context.buf.l[:]);
- r2(&d, &e, &a, &b, &c, 37, state_context.buf.l[:]);
- r2(&c, &d, &e, &a, &b, 38, state_context.buf.l[:]);
- r2(&b, &c, &d, &e, &a, 39, state_context.buf.l[:]);
-
- r3(&a, &b, &c, &d, &e, 40, state_context.buf.l[:]);
- r3(&e, &a, &b, &c, &d, 41, state_context.buf.l[:]);
- r3(&d, &e, &a, &b, &c, 42, state_context.buf.l[:]);
- r3(&c, &d, &e, &a, &b, 43, state_context.buf.l[:]);
- r3(&b, &c, &d, &e, &a, 44, state_context.buf.l[:]);
- r3(&a, &b, &c, &d, &e, 45, state_context.buf.l[:]);
- r3(&e, &a, &b, &c, &d, 46, state_context.buf.l[:]);
- r3(&d, &e, &a, &b, &c, 47, state_context.buf.l[:]);
- r3(&c, &d, &e, &a, &b, 48, state_context.buf.l[:]);
- r3(&b, &c, &d, &e, &a, 49, state_context.buf.l[:]);
- r3(&a, &b, &c, &d, &e, 50, state_context.buf.l[:]);
- r3(&e, &a, &b, &c, &d, 51, state_context.buf.l[:]);
- r3(&d, &e, &a, &b, &c, 52, state_context.buf.l[:]);
- r3(&c, &d, &e, &a, &b, 53, state_context.buf.l[:]);
- r3(&b, &c, &d, &e, &a, 54, state_context.buf.l[:]);
- r3(&a, &b, &c, &d, &e, 55, state_context.buf.l[:]);
- r3(&e, &a, &b, &c, &d, 56, state_context.buf.l[:]);
- r3(&d, &e, &a, &b, &c, 57, state_context.buf.l[:]);
- r3(&c, &d, &e, &a, &b, 58, state_context.buf.l[:]);
- r3(&b, &c, &d, &e, &a, 59, state_context.buf.l[:]);
-
- r4(&a, &b, &c, &d, &e, 60, state_context.buf.l[:]);
- r4(&e, &a, &b, &c, &d, 61, state_context.buf.l[:]);
- r4(&d, &e, &a, &b, &c, 62, state_context.buf.l[:]);
- r4(&c, &d, &e, &a, &b, 63, state_context.buf.l[:]);
- r4(&b, &c, &d, &e, &a, 64, state_context.buf.l[:]);
- r4(&a, &b, &c, &d, &e, 65, state_context.buf.l[:]);
- r4(&e, &a, &b, &c, &d, 66, state_context.buf.l[:]);
- r4(&d, &e, &a, &b, &c, 67, state_context.buf.l[:]);
- r4(&c, &d, &e, &a, &b, 68, state_context.buf.l[:]);
- r4(&b, &c, &d, &e, &a, 69, state_context.buf.l[:]);
- r4(&a, &b, &c, &d, &e, 70, state_context.buf.l[:]);
- r4(&e, &a, &b, &c, &d, 71, state_context.buf.l[:]);
- r4(&d, &e, &a, &b, &c, 72, state_context.buf.l[:]);
- r4(&c, &d, &e, &a, &b, 73, state_context.buf.l[:]);
- r4(&b, &c, &d, &e, &a, 74, state_context.buf.l[:]);
- r4(&a, &b, &c, &d, &e, 75, state_context.buf.l[:]);
- r4(&e, &a, &b, &c, &d, 76, state_context.buf.l[:]);
- r4(&d, &e, &a, &b, &c, 77, state_context.buf.l[:]);
- r4(&c, &d, &e, &a, &b, 78, state_context.buf.l[:]);
- r4(&b, &c, &d, &e, &a, 79, state_context.buf.l[:]);
-
- state_context.state[0] += a;
- state_context.state[1] += b;
- state_context.state[2] += c;
- state_context.state[3] += d;
- state_context.state[4] += e;
+ r0(&a, &b, &c, &d, &e, 0, state_context.buf.l[:])
+ r0(&e, &a, &b, &c, &d, 1, state_context.buf.l[:])
+ r0(&d, &e, &a, &b, &c, 2, state_context.buf.l[:])
+ r0(&c, &d, &e, &a, &b, 3, state_context.buf.l[:])
+ r0(&b, &c, &d, &e, &a, 4, state_context.buf.l[:])
+ r0(&a, &b, &c, &d, &e, 5, state_context.buf.l[:])
+ r0(&e, &a, &b, &c, &d, 6, state_context.buf.l[:])
+ r0(&d, &e, &a, &b, &c, 7, state_context.buf.l[:])
+ r0(&c, &d, &e, &a, &b, 8, state_context.buf.l[:])
+ r0(&b, &c, &d, &e, &a, 9, state_context.buf.l[:])
+ r0(&a, &b, &c, &d, &e, 10, state_context.buf.l[:])
+ r0(&e, &a, &b, &c, &d, 11, state_context.buf.l[:])
+ r0(&d, &e, &a, &b, &c, 12, state_context.buf.l[:])
+ r0(&c, &d, &e, &a, &b, 13, state_context.buf.l[:])
+ r0(&b, &c, &d, &e, &a, 14, state_context.buf.l[:])
+ r0(&a, &b, &c, &d, &e, 15, state_context.buf.l[:])
+ r1(&e, &a, &b, &c, &d, 16, state_context.buf.l[:])
+ r1(&d, &e, &a, &b, &c, 17, state_context.buf.l[:])
+ r1(&c, &d, &e, &a, &b, 18, state_context.buf.l[:])
+ r1(&b, &c, &d, &e, &a, 19, state_context.buf.l[:])
+
+ r2(&a, &b, &c, &d, &e, 20, state_context.buf.l[:])
+ r2(&e, &a, &b, &c, &d, 21, state_context.buf.l[:])
+ r2(&d, &e, &a, &b, &c, 22, state_context.buf.l[:])
+ r2(&c, &d, &e, &a, &b, 23, state_context.buf.l[:])
+ r2(&b, &c, &d, &e, &a, 24, state_context.buf.l[:])
+ r2(&a, &b, &c, &d, &e, 25, state_context.buf.l[:])
+ r2(&e, &a, &b, &c, &d, 26, state_context.buf.l[:])
+ r2(&d, &e, &a, &b, &c, 27, state_context.buf.l[:])
+ r2(&c, &d, &e, &a, &b, 28, state_context.buf.l[:])
+ r2(&b, &c, &d, &e, &a, 29, state_context.buf.l[:])
+ r2(&a, &b, &c, &d, &e, 30, state_context.buf.l[:])
+ r2(&e, &a, &b, &c, &d, 31, state_context.buf.l[:])
+ r2(&d, &e, &a, &b, &c, 32, state_context.buf.l[:])
+ r2(&c, &d, &e, &a, &b, 33, state_context.buf.l[:])
+ r2(&b, &c, &d, &e, &a, 34, state_context.buf.l[:])
+ r2(&a, &b, &c, &d, &e, 35, state_context.buf.l[:])
+ r2(&e, &a, &b, &c, &d, 36, state_context.buf.l[:])
+ r2(&d, &e, &a, &b, &c, 37, state_context.buf.l[:])
+ r2(&c, &d, &e, &a, &b, 38, state_context.buf.l[:])
+ r2(&b, &c, &d, &e, &a, 39, state_context.buf.l[:])
+
+ r3(&a, &b, &c, &d, &e, 40, state_context.buf.l[:])
+ r3(&e, &a, &b, &c, &d, 41, state_context.buf.l[:])
+ r3(&d, &e, &a, &b, &c, 42, state_context.buf.l[:])
+ r3(&c, &d, &e, &a, &b, 43, state_context.buf.l[:])
+ r3(&b, &c, &d, &e, &a, 44, state_context.buf.l[:])
+ r3(&a, &b, &c, &d, &e, 45, state_context.buf.l[:])
+ r3(&e, &a, &b, &c, &d, 46, state_context.buf.l[:])
+ r3(&d, &e, &a, &b, &c, 47, state_context.buf.l[:])
+ r3(&c, &d, &e, &a, &b, 48, state_context.buf.l[:])
+ r3(&b, &c, &d, &e, &a, 49, state_context.buf.l[:])
+ r3(&a, &b, &c, &d, &e, 50, state_context.buf.l[:])
+ r3(&e, &a, &b, &c, &d, 51, state_context.buf.l[:])
+ r3(&d, &e, &a, &b, &c, 52, state_context.buf.l[:])
+ r3(&c, &d, &e, &a, &b, 53, state_context.buf.l[:])
+ r3(&b, &c, &d, &e, &a, 54, state_context.buf.l[:])
+ r3(&a, &b, &c, &d, &e, 55, state_context.buf.l[:])
+ r3(&e, &a, &b, &c, &d, 56, state_context.buf.l[:])
+ r3(&d, &e, &a, &b, &c, 57, state_context.buf.l[:])
+ r3(&c, &d, &e, &a, &b, 58, state_context.buf.l[:])
+ r3(&b, &c, &d, &e, &a, 59, state_context.buf.l[:])
+
+ r4(&a, &b, &c, &d, &e, 60, state_context.buf.l[:])
+ r4(&e, &a, &b, &c, &d, 61, state_context.buf.l[:])
+ r4(&d, &e, &a, &b, &c, 62, state_context.buf.l[:])
+ r4(&c, &d, &e, &a, &b, 63, state_context.buf.l[:])
+ r4(&b, &c, &d, &e, &a, 64, state_context.buf.l[:])
+ r4(&a, &b, &c, &d, &e, 65, state_context.buf.l[:])
+ r4(&e, &a, &b, &c, &d, 66, state_context.buf.l[:])
+ r4(&d, &e, &a, &b, &c, 67, state_context.buf.l[:])
+ r4(&c, &d, &e, &a, &b, 68, state_context.buf.l[:])
+ r4(&b, &c, &d, &e, &a, 69, state_context.buf.l[:])
+ r4(&a, &b, &c, &d, &e, 70, state_context.buf.l[:])
+ r4(&e, &a, &b, &c, &d, 71, state_context.buf.l[:])
+ r4(&d, &e, &a, &b, &c, 72, state_context.buf.l[:])
+ r4(&c, &d, &e, &a, &b, 73, state_context.buf.l[:])
+ r4(&b, &c, &d, &e, &a, 74, state_context.buf.l[:])
+ r4(&a, &b, &c, &d, &e, 75, state_context.buf.l[:])
+ r4(&e, &a, &b, &c, &d, 76, state_context.buf.l[:])
+ r4(&d, &e, &a, &b, &c, 77, state_context.buf.l[:])
+ r4(&c, &d, &e, &a, &b, 78, state_context.buf.l[:])
+ r4(&b, &c, &d, &e, &a, 79, state_context.buf.l[:])
+
+ state_context.state[0] += a
+ state_context.state[1] += b
+ state_context.state[2] += c
+ state_context.state[3] += d
+ state_context.state[4] += e
}
sha1_add_uncounted :: proc (state_context: ^Sha1context, data: byte) {
when ODIN_ENDIAN == .Big {
- state_context.buf.c[state_context.buf_offset] = data;
+ state_context.buf.c[state_context.buf_offset] = data
} else
{
- state_context.buf.c[state_context.buf_offset ~ 3] = data;
+ state_context.buf.c[state_context.buf_offset ~ 3] = data
}
- state_context.buf_offset += 1;
+ state_context.buf_offset += 1
if state_context.buf_offset == BLOCK_LENGTH {
- sha1_hash_block(state_context);
- state_context.buf_offset = 0;
+ sha1_hash_block(state_context)
+ state_context.buf_offset = 0
}
}
sha1_write_byte :: proc (state_context: ^Sha1context, data: byte) {
- state_context.byte_count += 1;
- sha1_add_uncounted(state_context, data);
+ state_context.byte_count += 1
+ sha1_add_uncounted(state_context, data)
}
sha1_update :: proc (state_context: ^Sha1context, data: []byte) {
- state_context.byte_count += cast(u32)len(data);
+ state_context.byte_count += cast(u32)len(data)
- current_data := data;
+ current_data := data
if state_context.buf_offset > 0 {
- remainder := min(len(current_data), BLOCK_LENGTH - cast(int)state_context.buf_offset);
+ remainder := min(len(current_data), BLOCK_LENGTH - cast(int)state_context.buf_offset)
for i := 0; i < remainder; i += 1 {
- sha1_add_uncounted(state_context, current_data[i]);
+ sha1_add_uncounted(state_context, current_data[i])
}
- current_data = current_data[remainder - 1:];
+ current_data = current_data[remainder - 1:]
}
for len(current_data) >= BLOCK_LENGTH {
- assert(state_context.buf_offset == 0);
- assert(BLOCK_LENGTH % 4 == 0);
+ assert(state_context.buf_offset == 0)
+ assert(BLOCK_LENGTH % 4 == 0)
- BLOCK_LENGTH_32 :: BLOCK_LENGTH / 4;
+ BLOCK_LENGTH_32 :: BLOCK_LENGTH / 4
for i := 0; i < BLOCK_LENGTH_32; i += 1 {
- n := (transmute([]u32)current_data)[i];
+ n := (transmute([]u32)current_data)[i]
state_context.buf.l[i] = (((n & 0xFF) << 24) |
((n & 0xFF00) << 8) |
((n & 0xFF0000) >> 8) |
- ((n & 0xFF000000) >> 24));
+ ((n & 0xFF000000) >> 24))
}
- sha1_hash_block(state_context);
+ sha1_hash_block(state_context)
- current_data = current_data[BLOCK_LENGTH - 1:];
+ current_data = current_data[BLOCK_LENGTH - 1:]
}
for c in current_data {
- sha1_add_uncounted(state_context, c);
+ sha1_add_uncounted(state_context, c)
}
}
sha1_pad :: proc (state_context: ^Sha1context) {
- sha1_add_uncounted(state_context, 0x80);
+ sha1_add_uncounted(state_context, 0x80)
for state_context.buf_offset != 56 {
- sha1_add_uncounted(state_context, 0x00);
+ sha1_add_uncounted(state_context, 0x00)
}
- sha1_add_uncounted(state_context, 0); // We're only using 32 bit lengths
- sha1_add_uncounted(state_context, 0); // But SHA-1 supports 64 bit lengths
- sha1_add_uncounted(state_context, 0); // So zero pad the top bits
- sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 29)); // Shifting to multiply by 8
- sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 21)); // as SHA-1 supports bitstreams as well as
- sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 13)); // byte.
- sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 5));
- sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count << 3));
+ sha1_add_uncounted(state_context, 0) // We're only using 32 bit lengths
+ sha1_add_uncounted(state_context, 0) // But SHA-1 supports 64 bit lengths
+ sha1_add_uncounted(state_context, 0) // So zero pad the top bits
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 29)) // Shifting to multiply by 8
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 21)) // as SHA-1 supports bitstreams as well as
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 13)) // byte.
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count >> 5))
+ sha1_add_uncounted(state_context, cast(u8)(state_context.byte_count << 3))
}
sha1_final :: proc (state_context: ^Sha1context, result: ^[5]u32) {
- sha1_pad(state_context);
+ sha1_pad(state_context)
when ODIN_ENDIAN == .Big {
for i := 0; i < 5; i += 1 {
- result[i] = state_context.state[i];
+ result[i] = state_context.state[i]
}
} else {
for i := 0; i < 5; i += 1 {
result[i] = (((state_context.state[i]) << 24) & 0xff000000) |
(((state_context.state[i]) << 8) & 0x00ff0000) |
(((state_context.state[i]) >> 8) & 0x0000ff00) |
- (((state_context.state[i]) >> 24) & 0x000000ff);
+ (((state_context.state[i]) >> 24) & 0x000000ff)
}
}
}
sha1_hash :: proc (data: []byte) -> [20]byte {
- sha1_context: Sha1context;
- sha1_init(&sha1_context);
- sha1_update(&sha1_context, data);
+ sha1_context: Sha1context
+ sha1_init(&sha1_context)
+ sha1_update(&sha1_context, data)
- result: [20]byte;
+ result: [20]byte
- sha1_final(&sha1_context, cast(^[5]u32)&result);
+ sha1_final(&sha1_context, cast(^[5]u32)&result)
- ret: [20]byte;
+ ret: [20]byte
- copy(ret[:], result[:]);
+ copy(ret[:], result[:])
- return ret;
+ return ret
}
diff --git a/src/common/uri.odin b/src/common/uri.odin
index ee25393..d93eab3 100644
--- a/src/common/uri.odin
+++ b/src/common/uri.odin
@@ -17,116 +17,116 @@ Uri :: struct {
parse_uri :: proc(value: string, allocator: mem.Allocator) -> (Uri, bool) {
- uri: Uri;
+ uri: Uri
- decoded, ok := decode_percent(value, allocator);
+ decoded, ok := decode_percent(value, allocator)
if !ok {
- return uri, false;
+ return uri, false
}
- starts := "file:///";
+ starts := "file:///"
- start_index := len(starts);
+ start_index := len(starts)
if !starts_with(decoded, starts) {
- return uri, false;
+ return uri, false
}
- when ODIN_OS != "windows" {
- start_index -= 1;
+ when ODIN_OS != .Windows {
+ start_index -= 1
}
- uri.uri = strings.clone(value, allocator);
- uri.decode_full = decoded;
- uri.path = decoded[start_index:];
+ uri.uri = strings.clone(value, allocator)
+ uri.decode_full = decoded
+ uri.path = decoded[start_index:]
- return uri, true;
+ return uri, true
}
//Note(Daniel, Again some really incomplete and scuffed uri writer)
create_uri :: proc(path: string, allocator: mem.Allocator) -> Uri {
- path_forward, _ := filepath.to_slash(path, context.temp_allocator);
+ path_forward, _ := filepath.to_slash(path, context.temp_allocator)
- builder := strings.make_builder(allocator);
+ builder := strings.make_builder(allocator)
//bad
- when ODIN_OS == "windows" {
- strings.write_string(&builder, "file:///");
+ when ODIN_OS == .Windows {
+ strings.write_string(&builder, "file:///")
} else {
- strings.write_string(&builder, "file://");
+ strings.write_string(&builder, "file://")
}
- strings.write_string(&builder, encode_percent(path_forward, context.temp_allocator));
+ strings.write_string(&builder, encode_percent(path_forward, context.temp_allocator))
- uri: Uri;
+ uri: Uri
- uri.uri = strings.to_string(builder);
- uri.decode_full = strings.clone(path_forward, allocator);
- uri.path = uri.decode_full;
+ uri.uri = strings.to_string(builder)
+ uri.decode_full = strings.clone(path_forward, allocator)
+ uri.path = uri.decode_full
- return uri;
+ return uri
}
delete_uri :: proc(uri: Uri) {
if uri.uri != "" {
- delete(uri.uri);
+ delete(uri.uri)
}
if uri.decode_full != "" {
- delete(uri.decode_full);
+ delete(uri.decode_full)
}
}
encode_percent :: proc(value: string, allocator: mem.Allocator) -> string {
- builder := strings.make_builder(allocator);
+ builder := strings.make_builder(allocator)
- data := transmute([]u8)value;
- index: int;
+ data := transmute([]u8)value
+ index: int
for index < len(value) {
- r, w := utf8.decode_rune(data[index:]);
+ r, w := utf8.decode_rune(data[index:])
if r > 127 || r == ':' {
for i := 0; i < w; i += 1 {
strings.write_string(&builder, strings.concatenate({"%", fmt.tprintf("%X", data[index + i])},
- context.temp_allocator));
+ context.temp_allocator))
}
} else {
- strings.write_byte(&builder, data[index]);
+ strings.write_byte(&builder, data[index])
}
- index += w;
+ index += w
}
- return strings.to_string(builder);
+ return strings.to_string(builder)
}
@(private)
starts_with :: proc(value: string, starts_with: string) -> bool {
if len(value) < len(starts_with) {
- return false;
+ return false
}
for i := 0; i < len(starts_with); i += 1 {
if value[i] != starts_with[i] {
- return false;
+ return false
}
}
- return true;
+ return true
}
@(private)
decode_percent :: proc(value: string, allocator: mem.Allocator) -> (string, bool) {
- builder := strings.make_builder(allocator);
+ builder := strings.make_builder(allocator)
for i := 0; i < len(value); i += 1 {
@@ -134,24 +134,24 @@ decode_percent :: proc(value: string, allocator: mem.Allocator) -> (string, bool
if i + 2 < len(value) {
- v, ok := strconv.parse_i64_of_base(value[i + 1:i + 3], 16);
+ v, ok := strconv.parse_i64_of_base(value[i + 1:i + 3], 16)
if !ok {
- strings.destroy_builder(&builder);
- return "", false;
+ strings.destroy_builder(&builder)
+ return "", false
}
- strings.write_byte(&builder, cast(byte)v);
+ strings.write_byte(&builder, cast(byte)v)
- i += 2;
+ i += 2
} else {
- strings.destroy_builder(&builder);
- return "", false;
+ strings.destroy_builder(&builder)
+ return "", false
}
} else {
- strings.write_byte(&builder, value[i]);
+ strings.write_byte(&builder, value[i])
}
}
- return strings.to_string(builder), true;
+ return strings.to_string(builder), true
}
diff --git a/src/common/util_windows.odin b/src/common/util_windows.odin
index 835348a..bf89c47 100644
--- a/src/common/util_windows.odin
+++ b/src/common/util_windows.odin
@@ -11,71 +11,71 @@ foreign import kernel32 "system:kernel32.lib"
@(default_calling_convention = "std")
foreign kernel32 {
- @(link_name = "CreatePipe")create_pipe :: proc (hReadPipe, hWritePipe: ^win32.Handle, lpPipeAttributes: ^win32.Security_Attributes, nSize: i32) -> i32 ---;
+ @(link_name = "CreatePipe")create_pipe :: proc (hReadPipe, hWritePipe: ^win32.Handle, lpPipeAttributes: ^win32.Security_Attributes, nSize: i32) -> i32 ---
}
run_executable :: proc(command: string, stdout: ^[]byte) -> (u32, bool, []byte) {
- stdout_read: win32.Handle;
- stdout_write: win32.Handle;
+ stdout_read: win32.Handle
+ stdout_write: win32.Handle
- command := strings.clone_to_cstring(command, context.temp_allocator);
+ command := strings.clone_to_cstring(command, context.temp_allocator)
- attributes: win32.Security_Attributes;
- attributes.length = size_of(win32.Security_Attributes);
- attributes.inherit_handle = true;
- attributes.security_descriptor = nil;
+ attributes: win32.Security_Attributes
+ attributes.length = size_of(win32.Security_Attributes)
+ attributes.inherit_handle = true
+ attributes.security_descriptor = nil
if create_pipe(&stdout_read, &stdout_write, &attributes, 0) == 0 {
- return 0, false, stdout[0:];
+ return 0, false, stdout[0:]
}
if !win32.set_handle_information(stdout_read, win32.HANDLE_FLAG_INHERIT, 0) {
- return 0, false, stdout[0:];
+ return 0, false, stdout[0:]
}
- startup_info: win32.Startup_Info;
- process_info: win32.Process_Information;
+ startup_info: win32.Startup_Info
+ process_info: win32.Process_Information
- startup_info.cb = size_of(win32.Startup_Info);
+ startup_info.cb = size_of(win32.Startup_Info)
- startup_info.stderr = stdout_write;
- startup_info.stdout = stdout_write;
- startup_info.flags |= win32.STARTF_USESTDHANDLES;
+ startup_info.stderr = stdout_write
+ startup_info.stdout = stdout_write
+ startup_info.flags |= win32.STARTF_USESTDHANDLES
if !win32.create_process_a(nil, command, nil, nil, true, 0, nil, nil, &startup_info, &process_info) {
- return 0, false, stdout[0:];
+ return 0, false, stdout[0:]
}
- win32.close_handle(stdout_write);
+ win32.close_handle(stdout_write)
- index: int;
- read: i32;
+ index: int
+ read: i32
- read_buffer: [50]byte;
+ read_buffer: [50]byte
- success: win32.Bool = true;
+ success: win32.Bool = true
for success {
- success = win32.read_file(stdout_read, &read_buffer[0], len(read_buffer), &read, nil);
+ success = win32.read_file(stdout_read, &read_buffer[0], len(read_buffer), &read, nil)
if read > 0 && index + cast(int)read <= len(stdout) {
- mem.copy(&stdout[index], &read_buffer[0], cast(int)read);
+ mem.copy(&stdout[index], &read_buffer[0], cast(int)read)
}
- index += cast(int)read;
+ index += cast(int)read
}
- stdout[index + 1] = 0;
+ stdout[index + 1] = 0
- exit_code: u32;
+ exit_code: u32
- win32.wait_for_single_object(process_info.process, win32.INFINITE);
+ win32.wait_for_single_object(process_info.process, win32.INFINITE)
- win32.get_exit_code_process(process_info.process, &exit_code);
+ win32.get_exit_code_process(process_info.process, &exit_code)
- win32.close_handle(stdout_read);
+ win32.close_handle(stdout_read)
- return exit_code, true, stdout[0:index];
+ return exit_code, true, stdout[0:index]
} \ No newline at end of file
diff --git a/src/index/build.odin b/src/index/build.odin
index c8b1996..a7944f0 100644
--- a/src/index/build.odin
+++ b/src/index/build.odin
@@ -10,13 +10,14 @@ import "core:log"
import "core:odin/tokenizer"
import "core:strings"
import "core:mem"
+import "core:runtime"
import "shared:common"
-symbol_collection: SymbolCollection;
+symbol_collection: SymbolCollection
-files: [dynamic]string;
+files: [dynamic]string
platform_os: map[string]bool = {
"windows" = true,
@@ -26,135 +27,144 @@ platform_os: map[string]bool = {
"freebsd" = true,
"darwin" = true,
"wasm32" = true,
-};
+}
+
+
+os_enum_to_string: map[runtime.Odin_OS_Type]string = {
+ .Windows = "windows",
+ .Darwin = "dawrin",
+ .Linux = "linux",
+ .Essence = "essence",
+ .FreeBSD = "freebsd",
+ .WASI = "wasi",
+ .JS = "js",
+ .Freestanding = "freestanding",
+}
-walk_static_index_build :: proc(info: os.File_Info, in_err: os.Errno) -> (err: os.Errno, skip_dir: bool) {
+walk_static_index_build :: proc(info: os.File_Info, in_err: os.Errno) -> (err: os.Errno, skip_dir: bool) {
if info.is_dir {
- return 0, false;
+ return 0, false
}
if filepath.ext(info.name) != ".odin" {
- return 0, false;
+ return 0, false
}
- last_underscore_index := strings.last_index(info.name, "_");
- last_dot_index := strings.last_index(info.name, ".");
+ last_underscore_index := strings.last_index(info.name, "_")
+ last_dot_index := strings.last_index(info.name, ".")
if last_underscore_index + 1 < last_dot_index {
-
- name_between := info.name[last_underscore_index + 1:last_dot_index];
+ name_between := info.name[last_underscore_index + 1:last_dot_index]
if _, ok := platform_os[name_between]; ok {
- if name_between != ODIN_OS {
- return 0, false;
+ if name_between != os_enum_to_string[ODIN_OS] {
+ return 0, false
}
}
}
- forward, _ := filepath.to_slash(info.fullpath, context.temp_allocator);
+ forward, _ := filepath.to_slash(info.fullpath, context.temp_allocator)
- append(&files, strings.clone(forward, context.allocator));
+ append(&files, strings.clone(forward, context.allocator))
- return 0, false;
+ return 0, false
}
build_static_index :: proc(allocator := context.allocator, config: ^common.Config) {
+ symbol_collection = make_symbol_collection(allocator, config)
- symbol_collection = make_symbol_collection(allocator, config);
-
- files = make([dynamic]string, context.allocator);
+ files = make([dynamic]string, context.allocator)
for k, v in config.collections {
- filepath.walk(v, walk_static_index_build);
+ filepath.walk(v, walk_static_index_build)
}
- when ODIN_OS == "windows" {
- slashed, _ := filepath.to_slash(os.get_current_directory(context.temp_allocator), context.temp_allocator);
+ when ODIN_OS == .Windows {
+ slashed, _ := filepath.to_slash(os.get_current_directory(context.temp_allocator), context.temp_allocator)
} else {
- slashed, _ := filepath.to_slash(os.get_current_directory(), context.temp_allocator);
+ slashed, _ := filepath.to_slash(os.get_current_directory(), context.temp_allocator)
}
- when ODIN_OS == "windows" {
- builtin_package := path.join(elems = {slashed, "builtin"}, allocator = context.temp_allocator);
- append(&indexer.builtin_packages, strings.to_lower(builtin_package));
+ when ODIN_OS == .Windows {
+ builtin_package := path.join(elems = {slashed, "builtin"}, allocator = context.temp_allocator)
+ append(&indexer.builtin_packages, strings.to_lower(builtin_package))
} else {
- builtin_package := path.join(elems = {slashed, "builtin"}, allocator = context.allocator);
- append(&indexer.builtin_packages, builtin_package);
+ builtin_package := path.join(elems = {slashed, "builtin"}, allocator = context.allocator)
+ append(&indexer.builtin_packages, builtin_package)
}
- filepath.walk(builtin_package, walk_static_index_build);
+ filepath.walk(builtin_package, walk_static_index_build)
- temp_arena: mem.Arena;
+ temp_arena: mem.Arena
- mem.init_arena(&temp_arena, make([]byte, mem.megabytes(100)));
+ mem.init_arena(&temp_arena, make([]byte, mem.megabytes(100)))
- context.allocator = mem.arena_allocator(&temp_arena);
+ context.allocator = mem.arena_allocator(&temp_arena)
for fullpath in files {
-
- data, ok := os.read_entire_file(fullpath, context.allocator);
+ data, ok := os.read_entire_file(fullpath, context.allocator)
if !ok {
- log.errorf("failed to read entire file for indexing %v", fullpath);
- continue;
+ log.errorf("failed to read entire file for indexing %v", fullpath)
+ continue
}
p := parser.Parser {
err = log_error_handler,
warn = log_warning_handler,
- };
+ }
//have to cheat the parser since it really wants to parse an entire package with the new changes...
- dir := filepath.base(filepath.dir(fullpath, context.allocator));
+ dir := filepath.base(filepath.dir(fullpath, context.allocator))
- pkg := new(ast.Package);
- pkg.kind = .Normal;
- pkg.fullpath = fullpath;
- pkg.name = dir;
+ pkg := new(ast.Package)
+ pkg.kind = .Normal
+ pkg.fullpath = fullpath
+ pkg.name = dir
if dir == "runtime" {
- pkg.kind = .Runtime;
+ pkg.kind = .Runtime
}
file := ast.File {
fullpath = fullpath,
src = string(data),
pkg = pkg,
- };
+ }
- ok = parser.parse_file(&p, &file);
+ ok = parser.parse_file(&p, &file)
if !ok {
- log.info(pkg);
- log.errorf("error in parse file for indexing %v", fullpath);
+ log.info(pkg)
+ log.errorf("error in parse file for indexing %v", fullpath)
}
- uri := common.create_uri(fullpath, context.allocator);
+ uri := common.create_uri(fullpath, context.allocator)
//ERROR hover on uri does not show string
- collect_symbols(&symbol_collection, file, uri.uri);
+ collect_symbols(&symbol_collection, file, uri.uri)
- free_all(context.allocator);
+ free_all(context.allocator)
- delete(fullpath, allocator);
+ delete(fullpath, allocator)
}
- delete(files);
- delete(temp_arena.data);
+ delete(files)
+ delete(temp_arena.data)
- indexer.static_index = make_memory_index(symbol_collection);
+ indexer.static_index = make_memory_index(symbol_collection)
}
free_static_index :: proc() {
- delete_symbol_collection(symbol_collection);
+ delete_symbol_collection(symbol_collection)
}
log_error_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) {
- log.warnf("%v %v %v", pos, msg, args);
+ log.warnf("%v %v %v", pos, msg, args)
}
log_warning_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) {
- log.warnf("%v %v %v", pos, msg, args);
+ log.warnf("%v %v %v", pos, msg, args)
}
diff --git a/src/index/clone.odin b/src/index/clone.odin
index a9b6f33..24a1138 100644
--- a/src/index/clone.odin
+++ b/src/index/clone.odin
@@ -6,15 +6,24 @@ import "core:odin/tokenizer"
import "core:odin/ast"
import "core:strings"
import "core:log"
+import "core:intrinsics"
+import "core:reflect"
+_ :: intrinsics
new_type :: proc($T: typeid, pos, end: tokenizer.Pos, allocator: mem.Allocator) -> ^T {
- n, _ := mem.new(T, allocator);
- n.pos = pos;
- n.end = end;
- n.derived = n^;
- base: ^ast.Node = n; // dummy check
- _ = base; // "Use" type to make -vet happy
- return n;
+ n, _ := mem.new(T, allocator)
+ n.pos = pos
+ n.end = end
+ n.derived = n
+ base: ^ast.Node = n // dummy check
+ _ = base // "Use" type to make -vet happy
+ when intrinsics.type_has_field(T, "derived_expr") {
+ n.derived_expr = n
+ }
+ when intrinsics.type_has_field(T, "derived_stmt") {
+ n.derived_stmt = n
+ }
+ return n
}
clone_type :: proc {
@@ -22,242 +31,223 @@ clone_type :: proc {
clone_expr,
clone_array,
clone_dynamic_array,
-};
+}
clone_array :: proc(array: $A/[]^$T, allocator: mem.Allocator, unique_strings: ^map[string]string) -> A {
if len(array) == 0 {
- return nil;
+ return nil
}
- res := make(A, len(array), allocator);
+ res := make(A, len(array), allocator)
for elem, i in array {
- res[i] = cast(^T)clone_type(elem, allocator, unique_strings);
+ res[i] = cast(^T)clone_type(elem, allocator, unique_strings)
}
- return res;
+ return res
}
clone_dynamic_array :: proc(array: $A/[dynamic]^$T, allocator: mem.Allocator, unique_strings: ^map[string]string) -> A {
if len(array) == 0 {
- return nil;
+ return nil
}
- res := make(A, len(array), allocator);
+ res := make(A, len(array), allocator)
for elem, i in array {
- res[i] = auto_cast clone_type(elem, allocator, unique_strings);
+ 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 {
- return cast(^ast.Expr)clone_node(node, allocator, unique_strings);
+ 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 {
-
- using ast;
-
+ using ast
if node == nil {
- return nil;
+ return nil
}
- size := size_of(Node);
- align := align_of(Node);
- ti := type_info_of(node.derived.id);
+ size := size_of(Node)
+ align := align_of(Node)
+ ti := reflect.union_variant_type_info(node.derived)
if ti != nil {
- size = ti.size;
- align = ti.align;
+ elem := ti.variant.(reflect.Type_Info_Pointer).elem
+ size = elem.size
+ align = elem.align
+ }
+
+ #partial switch in node.derived {
+ case ^Package, ^File:
+ panic("Cannot clone this node type")
}
- res := cast(^Node)mem.alloc(size, align, allocator);
- src: rawptr = node;
+ res := cast(^Node)mem.alloc(size, align, allocator)
+ src: rawptr = node
if node.derived != nil {
- src = node.derived.data;
+ src = (^rawptr)(&node.derived)^
}
- mem.copy(res, src, size);
- res.derived.data = rawptr(res);
+ mem.copy(res, src, size)
+ res_ptr_any: any
+ res_ptr_any.data = &res
+ 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;
+ 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;
+ res.end.file = node.end.file
}
- switch n in node.derived {
- case Bad_Expr:
- case Ident:
- r := cast(^Ident)res;
+ reflect.set_union_value(res.derived, res_ptr_any)
+
+ res_ptr := reflect.deref(res_ptr_any)
+
+ 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 {
+ 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)
+
if unique_strings == nil {
- r.name = strings.clone(n.name, allocator);
+ r.name = strings.clone(n.name, allocator)
} else {
- r.name = get_index_unique_string(unique_strings, allocator, n.name);
+ r.name = get_index_unique_string(unique_strings, allocator, n.name)
}
- case Implicit:
- r := cast(^Implicit)res;
+ case ^Implicit:
+ n := node.derived.(^Implicit)
if unique_strings == nil {
- r.tok.text = strings.clone(n.tok.text, allocator);
+ r.tok.text = strings.clone(n.tok.text, allocator)
} else {
- r.tok.text = get_index_unique_string(unique_strings, allocator, n.tok.text);
+ r.tok.text = get_index_unique_string(unique_strings, allocator, n.tok.text)
}
- case Undef:
- case Basic_Lit:
- r := cast(^Basic_Lit)res;
+ case ^Undef:
+ case ^Basic_Lit:
+ n := node.derived.(^Basic_Lit)
if unique_strings == nil {
- r.tok.text = strings.clone(n.tok.text, allocator);
+ r.tok.text = strings.clone(n.tok.text, allocator)
} else {
- r.tok.text = get_index_unique_string(unique_strings, allocator, n.tok.text);
+ r.tok.text = get_index_unique_string(unique_strings, allocator, n.tok.text)
}
- case Basic_Directive:
- r := cast(^Basic_Directive)res;
+ case ^Basic_Directive:
+ n := node.derived.(^Basic_Directive)
if unique_strings == nil {
- r.name = strings.clone(n.name, allocator);
+ r.name = strings.clone(n.name, allocator)
} else {
- r.name = get_index_unique_string(unique_strings, allocator, n.name);
+ r.name = get_index_unique_string(unique_strings, allocator, n.name)
}
- case Ellipsis:
- r := cast(^Ellipsis)res;
- r.expr = clone_type(r.expr, allocator, unique_strings);
- case Tag_Expr:
- r := cast(^Tag_Expr)res;
- r.expr = clone_type(r.expr, allocator, unique_strings);
- case Unary_Expr:
- r := cast(^Unary_Expr)res;
- r.expr = clone_type(r.expr, allocator, unique_strings);
- case Binary_Expr:
- r := cast(^Binary_Expr)res;
- r.left = clone_type(r.left, allocator, unique_strings);
- r.right = clone_type(r.right, allocator, unique_strings);
- case Paren_Expr:
- r := cast(^Paren_Expr)res;
- r.expr = clone_type(r.expr, allocator, unique_strings);
- case Selector_Expr:
- r := cast(^Selector_Expr)res;
- r.expr = clone_type(r.expr, allocator, unique_strings);
- r.field = auto_cast clone_type(r.field, allocator, unique_strings);
- case Implicit_Selector_Expr:
- r := cast(^Implicit_Selector_Expr)res;
- r.field = auto_cast clone_type(r.field, allocator, unique_strings);
- case Slice_Expr:
- r := cast(^Slice_Expr)res;
- r.expr = clone_type(r.expr, allocator, unique_strings);
- r.low = clone_type(r.low, allocator, unique_strings);
- r.high = clone_type(r.high, allocator, unique_strings);
- case Attribute:
- r := cast(^Attribute)res;
- r.elems = clone_type(r.elems, allocator, unique_strings);
- case Distinct_Type:
- r := cast(^Distinct_Type)res;
- r.type = clone_type(r.type, allocator, unique_strings);
- case Proc_Type:
- r := cast(^Proc_Type)res;
- r.params = auto_cast clone_type(r.params, allocator, unique_strings);
- r.results = auto_cast clone_type(r.results, allocator, unique_strings);
- case Pointer_Type:
- r := cast(^Pointer_Type)res;
- r.elem = clone_type(r.elem, allocator, unique_strings);
- case Array_Type:
- r := cast(^Array_Type)res;
- r.len = clone_type(r.len, allocator, unique_strings);
- r.elem = clone_type(r.elem, allocator, unique_strings);
- r.tag = clone_type(r.tag, allocator, unique_strings);
- case Dynamic_Array_Type:
- r := cast(^Dynamic_Array_Type)res;
- r.elem = clone_type(r.elem, allocator, unique_strings);
- r.tag = clone_type(r.tag, allocator, unique_strings);
- case Struct_Type:
- r := cast(^Struct_Type)res;
- r.poly_params = auto_cast clone_type(r.poly_params, allocator, unique_strings);
- r.align = clone_type(r.align, allocator, unique_strings);
- r.fields = auto_cast clone_type(r.fields, allocator, unique_strings);
- r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings);
- case Field:
- r := cast(^Field)res;
- r.names = clone_type(r.names, allocator, unique_strings);
- r.type = clone_type(r.type, allocator, unique_strings);
- r.default_value = clone_type(r.default_value, allocator, unique_strings);
- case Field_List:
- r := cast(^Field_List)res;
- r.list = clone_type(r.list, allocator, unique_strings);
- case Field_Value:
- r := cast(^Field_Value)res;
- r.field = clone_type(r.field, allocator, unique_strings);
- r.value = clone_type(r.value, allocator, unique_strings);
- case Union_Type:
- r := cast(^Union_Type)res;
- r.poly_params = auto_cast clone_type(r.poly_params, allocator, unique_strings);
- r.align = clone_type(r.align, allocator, unique_strings);
- r.variants = clone_type(r.variants, allocator, unique_strings);
- r.where_clauses = clone_type(r.where_clauses, allocator, unique_strings);
- case Enum_Type:
- r := cast(^Enum_Type)res;
- r.base_type = clone_type(r.base_type, allocator, unique_strings);
- r.fields = clone_type(r.fields, allocator, unique_strings);
- case Bit_Set_Type:
- r := cast(^Bit_Set_Type)res;
- r.elem = clone_type(r.elem, allocator, unique_strings);
- r.underlying = clone_type(r.underlying, allocator, unique_strings);
- case Map_Type:
- r := cast(^Map_Type)res;
- r.key = clone_type(r.key, allocator, unique_strings);
- r.value = clone_type(r.value, allocator, unique_strings);
- case Call_Expr:
- r := cast(^Call_Expr)res;
- r.expr = clone_type(r.expr, allocator, unique_strings);
- r.args = clone_type(r.args, allocator, unique_strings);
- case Typeid_Type:
- r := cast(^Typeid_Type)res;
- r.specialization = clone_type(r.specialization, allocator, unique_strings);
- case Ternary_When_Expr:
- r := cast(^Ternary_When_Expr)res;
- r.x = clone_type(r.x, allocator, unique_strings);
- r.cond = clone_type(r.cond, allocator, unique_strings);
- r.y = clone_type(r.y, allocator, unique_strings);
- case Poly_Type:
- r := cast(^Poly_Type)res;
- r.type = auto_cast clone_type(r.type, allocator, unique_strings);
- r.specialization = clone_type(r.specialization, allocator, unique_strings);
- case Proc_Group:
- r := cast(^Proc_Group)res;
- r.args = clone_type(r.args, allocator, unique_strings);
- case Comp_Lit:
- r := cast(^Comp_Lit)res;
- r.type = clone_type(r.type, allocator, unique_strings);
- r.elems = clone_type(r.elems, allocator, unique_strings);
- case Proc_Lit:
- r := cast(^Proc_Lit)res;
- 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 := cast(^Helper_Type)res;
- r.type = clone_type(r.type, allocator, unique_strings);
- case Type_Cast:
- r := cast(^Type_Cast)res;
- r.type = clone_type(r.type, allocator, unique_strings);
- r.expr = clone_type(r.expr, allocator, unique_strings);
- case Deref_Expr:
- r := cast(^Deref_Expr)res;
- r.expr = clone_type(r.expr, allocator, unique_strings);
- case Index_Expr:
- r := cast(^Index_Expr)res;
- r.expr = clone_type(r.expr, allocator, unique_strings);
- r.index = clone_type(r.index, allocator, unique_strings);
- case Multi_Pointer_Type:
- r := cast(^Multi_Pointer_Type)res;
- r.elem = clone_type(r.elem, allocator, unique_strings);
- case Matrix_Type:
- r := cast(^Matrix_Type)res;
- r.elem = clone_type(r.elem, allocator, unique_strings);
- case Type_Assertion:
- r := cast(^Type_Assertion)res;
- r.expr = clone_type(r.expr, allocator, unique_strings);
- r.type = clone_type(r.type, allocator, unique_strings);
+ 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:
- panic(fmt.aprintf("Clone type Unhandled node kind: %T", node.derived));
+ //fmt.logf("Unhandled node kind: %T", r)
}
- return res;
+ return res
}
diff --git a/src/index/collector.odin b/src/index/collector.odin
index 49df1e6..495e2a3 100644
--- a/src/index/collector.odin
+++ b/src/index/collector.odin
@@ -22,20 +22,19 @@ SymbolCollection :: struct {
get_index_unique_string :: proc {
get_index_unique_string_collection,
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);
+ return get_index_unique_string_collection_raw(&collection.unique_strings, collection.allocator, s)
}
get_index_unique_string_collection_raw :: proc(unique_strings: ^map[string]string, allocator: mem.Allocator, s: string) -> string {
- //i'm hashing this string way to much
if _, ok := unique_strings[s]; !ok {
- str := strings.clone(s, allocator);
- unique_strings[str] = str; //yeah maybe I have to use some integer and hash it, tried that before but got name collisions.
+ str := strings.clone(s, allocator)
+ unique_strings[str] = str
}
- return unique_strings[s];
+ return unique_strings[s]
}
make_symbol_collection :: proc(allocator := context.allocator, config: ^common.Config) -> SymbolCollection {
@@ -44,42 +43,39 @@ make_symbol_collection :: proc(allocator := context.allocator, config: ^common.C
config = config,
symbols = make(map[uint]Symbol, 16, allocator),
unique_strings = make(map[string]string, 16, allocator),
- };
+ }
}
delete_symbol_collection :: proc(collection: SymbolCollection) {
-
for k, v in collection.symbols {
- free_symbol(v, collection.allocator);
+ free_symbol(v, collection.allocator)
}
for k, v in collection.unique_strings {
- delete(v, collection.allocator);
+ delete(v, collection.allocator)
}
- delete(collection.symbols);
- delete(collection.unique_strings);
+ delete(collection.symbols)
+ 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 {
- returns := make([dynamic]^ast.Field, 0, collection.allocator);
- args := make([dynamic]^ast.Field, 0, collection.allocator);
+ 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);
- replace_package_alias(cloned, package_map, collection);
- append(&returns, cloned);
+ cloned := cast(^ast.Field)clone_type(ret, collection.allocator, &collection.unique_strings)
+ replace_package_alias(cloned, package_map, collection)
+ append(&returns, cloned)
}
}
if arg_list != nil {
-
for arg in arg_list.list {
- cloned := cast(^ast.Field)clone_type(arg, collection.allocator, &collection.unique_strings);
- replace_package_alias(cloned, package_map, collection);
- append(&args, cloned);
+ cloned := cast(^ast.Field)clone_type(arg, collection.allocator, &collection.unique_strings)
+ replace_package_alias(cloned, package_map, collection)
+ append(&args, cloned)
}
}
@@ -87,27 +83,26 @@ collect_procedure_fields :: proc(collection: ^SymbolCollection, proc_type: ^ast.
return_types = returns[:],
arg_types = args[:],
generic = proc_type.generic,
- };
- return value;
+ }
+ return value
}
collect_struct_fields :: proc(collection: ^SymbolCollection, struct_type: ast.Struct_Type, package_map: map[string]string) -> SymbolStructValue {
- names := make([dynamic]string, 0, collection.allocator);
- types := make([dynamic]^ast.Expr, 0, collection.allocator);
- usings := make(map[string]bool, 0, collection.allocator);
+ names := make([dynamic]string, 0, collection.allocator)
+ types := make([dynamic]^ast.Expr, 0, collection.allocator)
+ usings := make(map[string]bool, 0, collection.allocator)
for field in struct_type.fields.list {
-
for n in field.names {
- ident := n.derived.(ast.Ident);
- append(&names, get_index_unique_string(collection, ident.name));
+ ident := n.derived.(^ast.Ident)
+ append(&names, get_index_unique_string(collection, ident.name))
- cloned := clone_type(field.type, collection.allocator, &collection.unique_strings);
- replace_package_alias(cloned, package_map, collection);
- append(&types, cloned);
+ cloned := clone_type(field.type, collection.allocator, &collection.unique_strings)
+ replace_package_alias(cloned, package_map, collection)
+ append(&types, cloned)
if .Using in field.flags {
- usings[names[len(names) - 1]] = true;
+ usings[names[len(names) - 1]] = true
}
}
}
@@ -117,345 +112,345 @@ collect_struct_fields :: proc(collection: ^SymbolCollection, struct_type: ast.St
types = types[:],
usings = usings,
poly = cast(^ast.Field_List)clone_type(struct_type.poly_params, collection.allocator, &collection.unique_strings),
- };
+ }
- return value;
+ return value
}
collect_enum_fields :: proc(collection: ^SymbolCollection, fields: []^ast.Expr, package_map: map[string]string) -> SymbolEnumValue {
- names := make([dynamic]string, 0, collection.allocator);
+ names := make([dynamic]string, 0, collection.allocator)
//ERROR no hover on n in the for, but elsewhere is fine
for n in fields {
- if ident, ok := n.derived.(ast.Ident); ok {
- append(&names, get_index_unique_string(collection, ident.name));
- } 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));
+ if ident, ok := n.derived.(^ast.Ident); ok {
+ append(&names, get_index_unique_string(collection, ident.name))
+ } 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))
}
}
}
value := SymbolEnumValue {
names = names[:],
- };
+ }
- return value;
+ return value
}
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);
+ types := make([dynamic]^ast.Expr, 0, collection.allocator)
for variant in union_type.variants {
- cloned := clone_type(variant, collection.allocator, &collection.unique_strings);
- replace_package_alias(cloned, package_map, collection);
- append(&types, cloned);
+ 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),
- };
+ }
- return value;
+ 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);
- replace_package_alias(cloned, package_map, collection);
+ cloned := clone_type(bitset_type.elem, collection.allocator, &collection.unique_strings)
+ replace_package_alias(cloned, package_map, collection)
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);
+ 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);
+ replace_package_alias(elem, package_map, collection)
+ replace_package_alias(len, package_map, collection)
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);
+ elem := clone_type(array.elem, collection.allocator, &collection.unique_strings)
- replace_package_alias(elem, package_map, collection);
+ replace_package_alias(elem, package_map, collection)
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);
+ 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);
+ replace_package_alias(key, package_map, collection)
+ replace_package_alias(value, package_map, collection)
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);
+ elem := clone_type(array.elem, collection.allocator, &collection.unique_strings)
- replace_package_alias(elem, package_map, collection);
+ replace_package_alias(elem, package_map, collection)
return SymbolDynamicArrayValue {
expr = elem,
- };
+ }
}
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 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);
- replace_package_alias(cloned, package_map, collection);
+ cloned := clone_type(selector.field, collection.allocator, &collection.unique_strings)
+ replace_package_alias(cloned, package_map, collection)
value := SymbolGenericValue {
expr = cloned,
- };
- return value;
+ }
+ return value
}
}
}
- cloned := clone_type(expr, collection.allocator, &collection.unique_strings);
- replace_package_alias(cloned, package_map, collection);
+ cloned := clone_type(expr, collection.allocator, &collection.unique_strings)
+ replace_package_alias(cloned, package_map, collection)
value := SymbolGenericValue {
expr = cloned,
- };
+ }
- return value;
+ return value
}
collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: string) -> common.Error {
- forward, _ := filepath.to_slash(file.fullpath, context.temp_allocator);
+ forward, _ := filepath.to_slash(file.fullpath, context.temp_allocator)
- when ODIN_OS == "windows" {
- directory := strings.to_lower(path.dir(forward, context.temp_allocator), context.temp_allocator);
+ when ODIN_OS == .Windows {
+ directory := strings.to_lower(path.dir(forward, context.temp_allocator), context.temp_allocator)
} else {
- directory := path.dir(forward, context.temp_allocator);
+ directory := path.dir(forward, context.temp_allocator)
}
- package_map := get_package_mapping(file, collection.config, directory);
+ package_map := get_package_mapping(file, collection.config, directory)
- exprs := common.collect_globals(file, true);
+ exprs := common.collect_globals(file, true)
for expr in exprs {
- symbol: Symbol;
+ symbol: Symbol
- token: ast.Node;
- token_type: SymbolType;
+ token: ast.Node
+ token_type: SymbolType
- name := expr.name;
+ name := expr.name
- col_expr := expr.expr;
+ col_expr := expr.expr
- if helper, ok := col_expr.derived.(ast.Helper_Type); ok {
+ if helper, ok := col_expr.derived.(^ast.Helper_Type); ok {
if helper.type != nil {
- col_expr = helper.type;
+ col_expr = helper.type
}
}
- if dist, ok := col_expr.derived.(ast.Distinct_Type); ok {
+ if dist, ok := col_expr.derived.(^ast.Distinct_Type); ok {
if dist.type != nil {
- col_expr = dist.type;
+ col_expr = dist.type
}
}
- switch v in col_expr.derived {
- case ast.Proc_Lit:
- token = v;
- token_type = .Function;
+ #partial switch v in col_expr.derived {
+ case ^ast.Proc_Lit:
+ token = v^
+ 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);
- case ast.Proc_Group:
- token = v;
- token_type = .Function;
+ 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)
+ case ^ast.Proc_Group:
+ token = v^
+ token_type = .Function
symbol.value = SymbolProcedureGroupValue {
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);
- symbol.signature = "struct";
- case ast.Enum_Type:
- token = v;
- token_type = .Enum;
- symbol.value = collect_enum_fields(collection, v.fields, package_map);
- symbol.signature = "enum";
- case ast.Union_Type:
- token = v;
- token_type = .Union;
- symbol.value = collect_union_fields(collection, v, package_map);
- symbol.signature = "union";
- case ast.Bit_Set_Type:
- token = v;
- token_type = .Enum;
- symbol.value = collect_bitset_field(collection, v, package_map);
- symbol.signature = "bitset";
- case ast.Map_Type:
- token = v;
- token_type = .Variable;
- symbol.value = collect_map(collection, v, package_map);
- case ast.Array_Type:
- token = v;
- token_type = .Variable;
+ }
+ case ^ast.Struct_Type:
+ token = v^
+ token_type = .Struct
+ symbol.value = collect_struct_fields(collection, v^, package_map)
+ symbol.signature = "struct"
+ case ^ast.Enum_Type:
+ token = v^
+ token_type = .Enum
+ symbol.value = collect_enum_fields(collection, v.fields, package_map)
+ symbol.signature = "enum"
+ case ^ast.Union_Type:
+ token = v^
+ token_type = .Union
+ symbol.value = collect_union_fields(collection, v^, package_map)
+ symbol.signature = "union"
+ case ^ast.Bit_Set_Type:
+ token = v^
+ token_type = .Enum
+ symbol.value = collect_bitset_field(collection, v^, package_map)
+ symbol.signature = "bitset"
+ case ^ast.Map_Type:
+ token = v^
+ token_type = .Variable
+ symbol.value = collect_map(collection, v^, package_map)
+ case ^ast.Array_Type:
+ token = v^
+ token_type = .Variable
if v.len == nil {
- symbol.value = collect_slice(collection, v, package_map);
+ symbol.value = collect_slice(collection, v^, package_map)
} else {
- symbol.value = collect_array(collection, v, package_map);
+ symbol.value = collect_array(collection, v^, package_map)
}
- case ast.Dynamic_Array_Type:
- token = v;
- token_type = .Variable;
- symbol.value = collect_dynamic_array(collection, v, package_map);
- case ast.Basic_Lit:
- token = v;
- symbol.value = collect_generic(collection, col_expr, package_map, uri);
+ case ^ast.Dynamic_Array_Type:
+ token = v^
+ token_type = .Variable
+ symbol.value = collect_dynamic_array(collection, v^, package_map)
+ case ^ast.Basic_Lit:
+ token = v^
+ symbol.value = collect_generic(collection, col_expr, package_map, uri)
if expr.mutable {
- token_type = .Variable;
+ token_type = .Variable
} else {
- token_type = .Constant;
+ token_type = .Constant
}
- case ast.Ident:
- token = v;
- symbol.value = collect_generic(collection, col_expr, package_map, uri);
+ case ^ast.Ident:
+ token = v^
+ symbol.value = collect_generic(collection, col_expr, package_map, uri)
if expr.mutable {
- token_type = .Variable;
+ token_type = .Variable
} else {
- token_type = .Unresolved;
+ token_type = .Unresolved
}
case: // default
- 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;
+ token_type = .Variable
} else {
- token_type = .Unresolved;
+ token_type = .Unresolved
}
- token = expr.expr;
+ token = expr.expr
}
- symbol.range = common.get_token_range(token, file.src);
- symbol.name = get_index_unique_string(collection, name);
- symbol.pkg = get_index_unique_string(collection, directory);
- symbol.type = token_type;
- symbol.doc = common.get_doc(expr.docs, collection.allocator);
+ symbol.range = common.get_token_range(token, file.src)
+ symbol.name = get_index_unique_string(collection, name)
+ symbol.pkg = get_index_unique_string(collection, directory)
+ symbol.type = token_type
+ symbol.doc = common.get_doc(expr.docs, collection.allocator)
if expr.deprecated {
- symbol.flags |= {.Deprecated};
+ symbol.flags |= {.Deprecated}
}
if expr.file_private {
- symbol.flags |= {.PrivateFile};
+ symbol.flags |= {.PrivateFile}
}
if expr.package_private {
- symbol.flags |= {.PrivatePackage};
+ symbol.flags |= {.PrivatePackage}
}
- when ODIN_OS == "windows" {
- symbol.uri = get_index_unique_string(collection, strings.to_lower(uri, context.temp_allocator));
+ when ODIN_OS == .Windows {
+ symbol.uri = get_index_unique_string(collection, strings.to_lower(uri, context.temp_allocator))
} else {
- symbol.uri = get_index_unique_string(collection, uri);
+ symbol.uri = get_index_unique_string(collection, uri)
}
- cat := strings.concatenate({symbol.pkg, name}, context.temp_allocator);
+ cat := strings.concatenate({symbol.pkg, name}, context.temp_allocator)
- id := get_symbol_id(cat);
+ id := get_symbol_id(cat)
if v, ok := collection.symbols[id]; !ok || v.name == "" {
- collection.symbols[id] = symbol;
+ collection.symbols[id] = symbol
} else {
- free_symbol(symbol, collection.allocator);
+ free_symbol(symbol, collection.allocator)
}
}
- return .None;
+ return .None
}
/*
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 {
- package_map := make(map[string]string, 0, context.temp_allocator);
+ package_map := make(map[string]string, 0, context.temp_allocator)
for imp, index in file.imports {
//collection specified
if i := strings.index(imp.fullpath, ":"); i != -1 {
//ERROR hover on collection should show string
- collection := imp.fullpath[1:i];
- p := imp.fullpath[i + 1:len(imp.fullpath) - 1];
+ collection := imp.fullpath[1:i]
+ p := imp.fullpath[i + 1:len(imp.fullpath) - 1]
- dir, ok := config.collections[collection];
+ dir, ok := config.collections[collection]
if !ok {
- continue;
+ continue
}
- name: string;
+ name: string
- when ODIN_OS == "windows" {
- full := path.join(elems = {strings.to_lower(dir, context.temp_allocator), p}, allocator = context.temp_allocator);
+ when ODIN_OS == .Windows {
+ full := path.join(elems = {strings.to_lower(dir, context.temp_allocator), p}, allocator = context.temp_allocator)
} else {
- 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;
+ name = imp.name.text
} else {
- name = path.base(full, false, context.temp_allocator);
+ name = path.base(full, false, context.temp_allocator)
}
- when ODIN_OS == "windows" {
- package_map[name] = strings.to_lower(full, context.temp_allocator);
+ when ODIN_OS == .Windows {
+ package_map[name] = strings.to_lower(full, context.temp_allocator)
} else {
- package_map[name] = full;
+ package_map[name] = full
}
} else {
- name: string;
+ 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);
+ full = path.clean(full, context.temp_allocator)
if imp.name.text != "" {
- name = imp.name.text;
+ name = imp.name.text
} else {
- name = path.base(full, false, context.temp_allocator);
+ name = path.base(full, false, context.temp_allocator)
}
- when ODIN_OS == "windows" {
- package_map[name] = strings.to_lower(full, context.temp_allocator);
+ when ODIN_OS == .Windows {
+ package_map[name] = strings.to_lower(full, context.temp_allocator)
} else {
- package_map[name] = full;
+ package_map[name] = full
}
}
}
- return package_map;
+ return package_map
}
/*
@@ -468,127 +463,125 @@ replace_package_alias :: proc {
replace_package_alias_expr,
replace_package_alias_array,
replace_package_alias_dynamic_array,
-};
+}
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(elem, package_map, collection)
}
}
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(elem, package_map, collection)
}
}
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(node, package_map, collection)
}
replace_package_alias_node :: proc(node: ^ast.Node, package_map: map[string]string, collection: ^SymbolCollection) {
- using ast;
+ using ast
if node == nil {
- return;
+ return
}
- switch n in node.derived {
- case Bad_Expr:
- case Ident:
- case Implicit:
- case Undef:
- case Basic_Lit:
- case Basic_Directive:
- case Ellipsis:
- replace_package_alias(n.expr, package_map, collection);
- case Tag_Expr:
- replace_package_alias(n.expr, package_map, collection);
- case Unary_Expr:
- replace_package_alias(n.expr, package_map, collection);
- case Binary_Expr:
- replace_package_alias(n.left, package_map, collection);
- replace_package_alias(n.right, package_map, collection);
- case Paren_Expr:
- replace_package_alias(n.expr, package_map, collection);
- case Selector_Expr:
-
- if _, ok := n.expr.derived.(Ident); ok {
-
- ident := &n.expr.derived.(Ident);
+ #partial switch n in node.derived {
+ case ^Bad_Expr:
+ case ^Ident:
+ case ^Implicit:
+ case ^Undef:
+ case ^Basic_Lit:
+ case ^Basic_Directive:
+ case ^Ellipsis:
+ replace_package_alias(n.expr, package_map, collection)
+ case ^Tag_Expr:
+ replace_package_alias(n.expr, package_map, collection)
+ case ^Unary_Expr:
+ replace_package_alias(n.expr, package_map, collection)
+ case ^Binary_Expr:
+ replace_package_alias(n.left, package_map, collection)
+ replace_package_alias(n.right, package_map, collection)
+ case ^Paren_Expr:
+ replace_package_alias(n.expr, package_map, collection)
+ case ^Selector_Expr:
+ if _, ok := n.expr.derived.(^Ident); ok {
+ ident := n.expr.derived.(^Ident)
if package_name, ok := package_map[ident.name]; ok {
- ident.name = get_index_unique_string(collection, package_name);
+ ident.name = get_index_unique_string(collection, package_name)
}
} else {
- replace_package_alias(n.expr, package_map, collection);
- replace_package_alias(n.field, package_map, collection);
+ replace_package_alias(n.expr, package_map, collection)
+ replace_package_alias(n.field, package_map, collection)
}
- case Implicit_Selector_Expr:
- replace_package_alias(n.field, package_map, collection);
- case Slice_Expr:
- replace_package_alias(n.expr, package_map, collection);
- replace_package_alias(n.low, package_map, collection);
- replace_package_alias(n.high, package_map, collection);
- case Attribute:
- replace_package_alias(n.elems, package_map, collection);
- case Distinct_Type:
- replace_package_alias(n.type, package_map, collection);
- case Proc_Type:
- replace_package_alias(n.params, package_map, collection);
- replace_package_alias(n.results, package_map, collection);
- case Pointer_Type:
- replace_package_alias(n.elem, package_map, collection);
- case Array_Type:
- replace_package_alias(n.len, package_map, collection);
- replace_package_alias(n.elem, package_map, collection);
- case Dynamic_Array_Type:
- replace_package_alias(n.elem, package_map, collection);
- case Struct_Type:
- replace_package_alias(n.poly_params, package_map, collection);
- replace_package_alias(n.align, package_map, collection);
- replace_package_alias(n.fields, package_map, collection);
- case Field:
- replace_package_alias(n.names, package_map, collection);
- replace_package_alias(n.type, package_map, collection);
- replace_package_alias(n.default_value, package_map, collection);
- case Field_List:
- replace_package_alias(n.list, package_map, collection);
- case Field_Value:
- replace_package_alias(n.field, package_map, collection);
- replace_package_alias(n.value, package_map, collection);
- case Union_Type:
- replace_package_alias(n.poly_params, package_map, collection);
- replace_package_alias(n.align, package_map, collection);
- replace_package_alias(n.variants, package_map, collection);
- case Enum_Type:
- replace_package_alias(n.base_type, package_map, collection);
- replace_package_alias(n.fields, package_map, collection);
- case Bit_Set_Type:
- replace_package_alias(n.elem, package_map, collection);
- replace_package_alias(n.underlying, package_map, collection);
- case Map_Type:
- replace_package_alias(n.key, package_map, collection);
- replace_package_alias(n.value, package_map, collection);
- case Call_Expr:
- replace_package_alias(n.expr, package_map, collection);
- replace_package_alias(n.args, package_map, collection);
- case Typeid_Type:
- replace_package_alias(n.specialization, package_map, collection);
- case Poly_Type:
- replace_package_alias(n.type, package_map, collection);
- replace_package_alias(n.specialization, package_map, collection);
- case Proc_Group:
- replace_package_alias(n.args, package_map, collection);
- case Comp_Lit:
- replace_package_alias(n.type, package_map, collection);
- replace_package_alias(n.elems, package_map, collection);
- case Helper_Type:
- replace_package_alias(n.type, package_map, collection);
- case Proc_Lit:
- case Multi_Pointer_Type:
- replace_package_alias(n.elem, package_map, collection);
+ case ^Implicit_Selector_Expr:
+ replace_package_alias(n.field, package_map, collection)
+ case ^Slice_Expr:
+ replace_package_alias(n.expr, package_map, collection)
+ replace_package_alias(n.low, package_map, collection)
+ replace_package_alias(n.high, package_map, collection)
+ case ^Attribute:
+ replace_package_alias(n.elems, package_map, collection)
+ case ^Distinct_Type:
+ replace_package_alias(n.type, package_map, collection)
+ case ^Proc_Type:
+ replace_package_alias(n.params, package_map, collection)
+ replace_package_alias(n.results, package_map, collection)
+ case ^Pointer_Type:
+ replace_package_alias(n.elem, package_map, collection)
+ case ^Array_Type:
+ replace_package_alias(n.len, package_map, collection)
+ replace_package_alias(n.elem, package_map, collection)
+ case ^Dynamic_Array_Type:
+ replace_package_alias(n.elem, package_map, collection)
+ case ^Struct_Type:
+ replace_package_alias(n.poly_params, package_map, collection)
+ replace_package_alias(n.align, package_map, collection)
+ replace_package_alias(n.fields, package_map, collection)
+ case ^Field:
+ replace_package_alias(n.names, package_map, collection)
+ replace_package_alias(n.type, package_map, collection)
+ replace_package_alias(n.default_value, package_map, collection)
+ case ^Field_List:
+ replace_package_alias(n.list, package_map, collection)
+ case ^Field_Value:
+ replace_package_alias(n.field, package_map, collection)
+ replace_package_alias(n.value, package_map, collection)
+ case ^Union_Type:
+ replace_package_alias(n.poly_params, package_map, collection)
+ replace_package_alias(n.align, package_map, collection)
+ replace_package_alias(n.variants, package_map, collection)
+ case ^Enum_Type:
+ replace_package_alias(n.base_type, package_map, collection)
+ replace_package_alias(n.fields, package_map, collection)
+ case ^Bit_Set_Type:
+ replace_package_alias(n.elem, package_map, collection)
+ replace_package_alias(n.underlying, package_map, collection)
+ case ^Map_Type:
+ replace_package_alias(n.key, package_map, collection)
+ replace_package_alias(n.value, package_map, collection)
+ case ^Call_Expr:
+ replace_package_alias(n.expr, package_map, collection)
+ replace_package_alias(n.args, package_map, collection)
+ case ^Typeid_Type:
+ replace_package_alias(n.specialization, package_map, collection)
+ case ^Poly_Type:
+ replace_package_alias(n.type, package_map, collection)
+ replace_package_alias(n.specialization, package_map, collection)
+ case ^Proc_Group:
+ replace_package_alias(n.args, package_map, collection)
+ case ^Comp_Lit:
+ replace_package_alias(n.type, package_map, collection)
+ replace_package_alias(n.elems, package_map, collection)
+ case ^Helper_Type:
+ replace_package_alias(n.type, package_map, collection)
+ case ^Proc_Lit:
+ case ^Multi_Pointer_Type:
+ replace_package_alias(n.elem, package_map, collection)
case:
- log.warnf("Replace Unhandled node kind: %T", n);
+ log.warnf("Replace Unhandled node kind: %T", n)
}
}
diff --git a/src/index/indexer.odin b/src/index/indexer.odin
index 42b111c..a67c147 100644
--- a/src/index/indexer.odin
+++ b/src/index/indexer.odin
@@ -41,7 +41,7 @@ Indexer :: struct {
dynamic_index: MemoryIndex,
}
-indexer: Indexer;
+indexer: Indexer
FuzzyResult :: struct {
symbol: Symbol,
@@ -50,62 +50,62 @@ FuzzyResult :: struct {
lookup :: proc(name: string, pkg: string, loc := #caller_location) -> (Symbol, bool) {
if symbol, ok := memory_index_lookup(&indexer.dynamic_index, name, pkg); ok {
- log.infof("lookup dynamic name: %v pkg: %v, symbol %v location %v", name, pkg, symbol, loc);
- return symbol, true;
+ log.infof("lookup dynamic name: %v pkg: %v, symbol %v location %v", name, pkg, symbol, loc)
+ return symbol, true
}
if symbol, ok := memory_index_lookup(&indexer.static_index, name, pkg); ok {
- log.infof("lookup name: %v pkg: %v, symbol %v location %v", name, pkg, symbol, loc);
- return symbol, true;
+ log.infof("lookup name: %v pkg: %v, symbol %v location %v", name, pkg, symbol, loc)
+ return symbol, true
}
- log.infof("lookup failed name: %v pkg: %v location %v", name, pkg, loc);
- return {}, false;
+ log.infof("lookup failed name: %v pkg: %v location %v", name, pkg, loc)
+ return {}, false
}
fuzzy_search :: proc(name: string, pkgs: []string) -> ([]FuzzyResult, bool) {
- dynamic_results, dynamic_ok := memory_index_fuzzy_search(&indexer.dynamic_index, name, pkgs);
- static_results, static_ok := memory_index_fuzzy_search(&indexer.static_index, name, pkgs);
- result := make([dynamic]FuzzyResult, context.temp_allocator);
- files := make(map[string]bool, 0, context.temp_allocator);
+ dynamic_results, dynamic_ok := memory_index_fuzzy_search(&indexer.dynamic_index, name, pkgs)
+ static_results, static_ok := memory_index_fuzzy_search(&indexer.static_index, name, pkgs)
+ result := make([dynamic]FuzzyResult, context.temp_allocator)
+ files := make(map[string]bool, 0, context.temp_allocator)
if !dynamic_ok || !static_ok {
- return {}, false;
+ return {}, false
}
for r in dynamic_results {
- files[r.symbol.uri] = true;
- append(&result, r);
+ files[r.symbol.uri] = true
+ append(&result, r)
}
for r in static_results {
if r.symbol.uri in files {
- continue;
+ continue
}
- append(&result, r);
+ append(&result, r)
}
- sort.sort(fuzzy_sort_interface(&result));
+ sort.sort(fuzzy_sort_interface(&result))
- return result[:], true;
+ return result[:], true
}
fuzzy_sort_interface :: proc(s: ^[dynamic]FuzzyResult) -> sort.Interface {
return sort.Interface {
collection = rawptr(s),
len = proc(it: sort.Interface) -> int {
- s := (^[dynamic]FuzzyResult)(it.collection);
- return len(s^);
+ s := (^[dynamic]FuzzyResult)(it.collection)
+ return len(s^)
},
less = proc(it: sort.Interface, i, j: int) -> bool {
- s := (^[dynamic]FuzzyResult)(it.collection);
- return s[i].score > s[j].score;
+ s := (^[dynamic]FuzzyResult)(it.collection)
+ return s[i].score > s[j].score
},
swap = proc(it: sort.Interface, i, j: int) {
- s := (^[dynamic]FuzzyResult)(it.collection);
- s[i], s[j] = s[j], s[i];
+ s := (^[dynamic]FuzzyResult)(it.collection)
+ s[i], s[j] = s[j], s[i]
},
- };
+ }
}
diff --git a/src/index/memory_index.odin b/src/index/memory_index.odin
index e946811..d4e7e6e 100644
--- a/src/index/memory_index.odin
+++ b/src/index/memory_index.odin
@@ -22,44 +22,44 @@ make_memory_index :: proc(collection: SymbolCollection) -> MemoryIndex {
return MemoryIndex {
collection = collection,
- };
+ }
}
memory_index_lookup :: proc(index: ^MemoryIndex, name: string, pkg: string) -> (Symbol, bool) {
- id := get_symbol_id(strings.concatenate({pkg, name}, context.temp_allocator));
- return index.collection.symbols[id];
+ id := get_symbol_id(strings.concatenate({pkg, name}, context.temp_allocator))
+ return index.collection.symbols[id]
}
memory_index_fuzzy_search :: proc(index: ^MemoryIndex, name: string, pkgs: []string) -> ([]FuzzyResult, bool) {
- symbols := make([dynamic]FuzzyResult, 0, context.temp_allocator);
+ symbols := make([dynamic]FuzzyResult, 0, context.temp_allocator)
- fuzzy_matcher := common.make_fuzzy_matcher(name);
+ fuzzy_matcher := common.make_fuzzy_matcher(name)
- top := 20;
+ top := 20
for _, symbol in index.collection.symbols {
if !exists_in_scope(symbol.pkg, pkgs) {
- continue;
+ continue
}
if score, ok := common.fuzzy_match(fuzzy_matcher, symbol.name); ok == 1 {
result := FuzzyResult {
symbol = symbol,
score = score,
- };
+ }
- append(&symbols, result);
+ append(&symbols, result)
}
}
- sort.sort(fuzzy_sort_interface(&symbols));
+ sort.sort(fuzzy_sort_interface(&symbols))
if name == "" {
- return symbols[:], true;
+ return symbols[:], true
} else {
- return symbols[:min(top, len(symbols))], true;
+ return symbols[:min(top, len(symbols))], true
}
}
@@ -67,9 +67,9 @@ exists_in_scope :: proc(symbol_scope: string, scope: []string) -> bool {
for s in scope {
if strings.compare(symbol_scope, s) == 0 {
- return true;
+ return true
}
}
- return false;
+ return false
}
diff --git a/src/index/symbol.odin b/src/index/symbol.odin
index 3ee808f..c00c08e 100644
--- a/src/index/symbol.odin
+++ b/src/index/symbol.odin
@@ -138,54 +138,54 @@ SymbolType :: enum {
}
new_clone_symbol :: proc(data: Symbol, allocator := context.allocator) -> (^Symbol) {
- new_symbol := new(Symbol, allocator);
- new_symbol^ = data;
- new_symbol.value = data.value;
- return new_symbol;
+ new_symbol := new(Symbol, allocator)
+ new_symbol^ = data
+ new_symbol.value = data.value
+ return new_symbol
}
free_symbol :: proc(symbol: Symbol, allocator: mem.Allocator) {
if symbol.signature != "" && symbol.signature != "struct" &&
symbol.signature != "union" && symbol.signature != "enum" &&
symbol.signature != "bitset" {
- delete(symbol.signature, allocator);
+ delete(symbol.signature, allocator)
}
if symbol.doc != "" {
- delete(symbol.doc, allocator);
+ delete(symbol.doc, allocator)
}
#partial switch v in symbol.value {
case SymbolProcedureValue:
- common.free_ast(v.return_types, allocator);
- common.free_ast(v.arg_types, allocator);
+ common.free_ast(v.return_types, allocator)
+ common.free_ast(v.arg_types, allocator)
case SymbolStructValue:
- delete(v.names, allocator);
- common.free_ast(v.types, allocator);
+ delete(v.names, allocator)
+ common.free_ast(v.types, allocator)
case SymbolGenericValue:
- common.free_ast(v.expr, allocator);
+ common.free_ast(v.expr, allocator)
case SymbolProcedureGroupValue:
- common.free_ast(v.group, allocator);
+ common.free_ast(v.group, allocator)
case SymbolEnumValue:
- delete(v.names, allocator);
+ delete(v.names, allocator)
case SymbolUnionValue:
- common.free_ast(v.types, allocator);
+ common.free_ast(v.types, allocator)
case SymbolBitSetValue:
- common.free_ast(v.expr, allocator);
+ common.free_ast(v.expr, allocator)
case SymbolDynamicArrayValue:
- common.free_ast(v.expr, allocator);
+ common.free_ast(v.expr, allocator)
case SymbolFixedArrayValue:
- common.free_ast(v.expr, allocator);
- common.free_ast(v.len, allocator);
+ common.free_ast(v.expr, allocator)
+ common.free_ast(v.len, allocator)
case SymbolSliceValue:
- common.free_ast(v.expr, allocator);
+ common.free_ast(v.expr, allocator)
case SymbolBasicValue:
- common.free_ast(v.ident, allocator);
+ common.free_ast(v.ident, allocator)
}
}
get_symbol_id :: proc(str: string) -> uint {
- ret := common.sha1_hash(transmute([]byte)str);
- r := cast(^uint)slice.first_ptr(ret[:]);
- return r^;
+ ret := common.sha1_hash(transmute([]byte)str)
+ r := cast(^uint)slice.first_ptr(ret[:])
+ return r^
}
diff --git a/src/main.odin b/src/main.odin
index 69ad85b..b30cd5b 100644
--- a/src/main.odin
+++ b/src/main.odin
@@ -19,72 +19,72 @@ import "shared:server"
import "shared:common"
os_read :: proc(handle: rawptr, data: []byte) -> (int, int) {
- ptr := cast(^os.Handle)handle;
- a, b := os.read(ptr^, data);
- return a, cast(int)b;
+ ptr := cast(^os.Handle)handle
+ a, b := os.read(ptr^, data)
+ return a, cast(int)b
}
os_write :: proc(handle: rawptr, data: []byte) -> (int, int) {
- ptr := cast(^os.Handle)handle;
- a, b := os.write(ptr^, data);
- return a, cast(int)b;
+ ptr := cast(^os.Handle)handle
+ a, b := os.write(ptr^, data)
+ return a, cast(int)b
}
//Note(Daniel, Should look into handling errors without crashing from parsing)
-verbose_logger: log.Logger;
-file_logger: log.Logger;
-file_logger_init: bool;
-request_thread: ^thread.Thread;
+verbose_logger: log.Logger
+file_logger: log.Logger
+file_logger_init: bool
+request_thread: ^thread.Thread
run :: proc(reader: ^server.Reader, writer: ^server.Writer) {
- common.config.collections = make(map[string]string);
+ common.config.collections = make(map[string]string)
- log.info("Starting Odin Language Server");
+ log.info("Starting Odin Language Server")
- common.config.running = true;
+ common.config.running = true
request_thread_data := server.RequestThreadData {
reader = reader,
writer = writer,
- };
+ }
- sync.mutex_init(&server.requests_mutex);
- sync.semaphore_init(&server.requests_sempahore);
+ sync.mutex_init(&server.requests_mutex)
+ sync.semaphore_init(&server.requests_sempahore)
- server.requests = make([dynamic]server.Request, context.allocator);
- server.deletings = make([dynamic]server.Request, context.allocator);
+ server.requests = make([dynamic]server.Request, context.allocator)
+ server.deletings = make([dynamic]server.Request, context.allocator)
- request_thread = thread.create_and_start_with_data(cast(rawptr)&request_thread_data, server.thread_request_main);
+ request_thread = thread.create_and_start_with_data(cast(rawptr)&request_thread_data, server.thread_request_main)
for common.config.running {
if common.config.file_log {
if !file_logger_init {
if fh, err := os.open("log.txt"); err == 0 {
- file_logger = log.create_file_logger(fh, log.Level.Info);
+ file_logger = log.create_file_logger(fh, log.Level.Info)
}
}
- context.logger = file_logger;
+ context.logger = file_logger
} else if common.config.verbose {
- context.logger = verbose_logger;
+ context.logger = verbose_logger
} else {
- context.logger = log.Logger {nil, nil, log.Level.Debug, nil};
+ context.logger = log.Logger {nil, nil, log.Level.Debug, nil}
}
- server.consume_requests(&common.config, writer);
+ server.consume_requests(&common.config, writer)
}
for k, v in common.config.collections {
- delete(k);
- delete(v);
+ delete(k)
+ delete(v)
}
- delete(common.config.collections);
- delete(common.config.workspace_folders);
+ delete(common.config.collections)
+ delete(common.config.workspace_folders)
- server.document_storage_shutdown();
+ server.document_storage_shutdown()
- index.free_static_index();
+ index.free_static_index()
}
end :: proc() {
@@ -92,14 +92,14 @@ end :: proc() {
main :: proc() {
- reader := server.make_reader(os_read, cast(rawptr)&os.stdin);
- writer := server.make_writer(os_write, cast(rawptr)&os.stdout);
+ reader := server.make_reader(os_read, cast(rawptr)&os.stdin)
+ writer := server.make_writer(os_write, cast(rawptr)&os.stdout)
- verbose_logger := server.create_lsp_logger(&writer, log.Level.Error);
+ verbose_logger := server.create_lsp_logger(&writer, log.Level.Error)
- context.logger = verbose_logger;
+ context.logger = verbose_logger
- init_global_temporary_allocator(mem.megabytes(100));
+ init_global_temporary_allocator(mem.megabytes(100))
- run(&reader, &writer);
+ run(&reader, &writer)
}
diff --git a/src/odin/printer/document.odin b/src/odin/printer/document.odin
index 76c94ea..3f7bb69 100644
--- a/src/odin/printer/document.odin
+++ b/src/odin/printer/document.odin
@@ -219,7 +219,7 @@ fits :: proc(width: int, list: ^[dynamic]Tuple, consumed: ^int) -> bool {
case Document_Newline:
if v.amount > 0 {
consumed^ = start_width - width
- return true;
+ return true
}
case Document_Cons:
append(list, Tuple {indentation = data.indentation, mode = data.mode, document = v.rhs, alignment = data.alignment})
diff --git a/src/odin/printer/printer.odin b/src/odin/printer/printer.odin
index 88c1c41..1438b34 100644
--- a/src/odin/printer/printer.odin
+++ b/src/odin/printer/printer.odin
@@ -71,7 +71,7 @@ Newline_Style :: enum {
}
-when ODIN_OS == "windows" {
+when ODIN_OS == .Windows {
default_style := Config {
spaces = 4,
newline_limit = 2,
@@ -156,7 +156,7 @@ print :: proc(p: ^Printer, file: ^ast.File) -> string {
p.source_position.line = 1
p.source_position.column = 1
- p.document = move_line(p, file.pkg_token.pos);
+ p.document = move_line(p, file.pkg_token.pos)
p.document = cons(p.document, cons_with_nopl(text(file.pkg_token.text), text(file.pkg_name)))
for decl in file.decls {
diff --git a/src/odin/printer/visit.odin b/src/odin/printer/visit.odin
index 84a6b9c..f67dcee 100644
--- a/src/odin/printer/visit.odin
+++ b/src/odin/printer/visit.odin
@@ -202,13 +202,13 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) -> ^Do
return visit_disabled(p, decl)
}
- switch v in &decl.derived {
- case Expr_Stmt:
+ #partial switch v in decl.derived {
+ case ^Expr_Stmt:
document := move_line(p, decl.pos)
return cons(document, visit_expr(p, v.expr))
- case When_Stmt:
+ case ^When_Stmt:
return visit_stmt(p, cast(^Stmt)decl)
- case Foreign_Import_Decl:
+ case ^Foreign_Import_Decl:
document := empty()
if len(v.attributes) > 0 {
document = cons(document, visit_attributes(p, &v.attributes, v.pos))
@@ -235,7 +235,7 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) -> ^Do
}
return document
- case Foreign_Block_Decl:
+ case ^Foreign_Block_Decl:
document := empty()
if len(v.attributes) > 0 {
document = cons(document, visit_attributes(p, &v.attributes, v.pos))
@@ -245,7 +245,7 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) -> ^Do
document = cons(document, cons_with_opl(text("foreign"), visit_expr(p, v.foreign_library)))
document = cons_with_nopl(document, visit_stmt(p, v.body))
return document
- case Import_Decl:
+ case ^Import_Decl:
document := move_line(p, decl.pos)
if v.name.text != "" {
@@ -260,7 +260,7 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) -> ^Do
document = cons(document, text(v.fullpath))
}
return document
- case Value_Decl:
+ case ^Value_Decl:
document := empty()
if len(v.attributes) > 0 {
document = cons(document, visit_attributes(p, &v.attributes, v.pos))
@@ -321,7 +321,7 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) -> ^Do
@(private)
is_values_binary :: proc(p: ^Printer, list: []^ast.Expr) -> bool {
for expr in list {
- if _, bin := expr.derived.(ast.Binary_Expr); bin {
+ if _, bin := expr.derived.(^ast.Binary_Expr); bin {
return true
}
}
@@ -384,7 +384,7 @@ visit_enum_exprs :: proc(p: ^Printer, enum_type: ast.Enum_Type, options := List_
if (.Enforce_Newline in options) {
alignment := get_possible_enum_alignment(p, enum_type.fields)
- if value, ok := expr.derived.(ast.Field_Value); ok && alignment > 0 {
+ if value, ok := expr.derived.(^ast.Field_Value); ok && alignment > 0 {
document = cons(document, cons_with_nopl(visit_expr(p, value.field), cons_with_nopl(cons(repeat_space(alignment - get_node_length(value.field)), text_position(p, "=", value.sep)), visit_expr(p, value.value))))
} else {
document = group(cons(document, visit_expr(p, expr, .Generic, options)))
@@ -429,7 +429,7 @@ visit_union_exprs :: proc(p: ^Printer, union_type: ast.Union_Type, options := Li
if (.Enforce_Newline in options) {
alignment := get_possible_enum_alignment(p, union_type.variants)
- if value, ok := expr.derived.(ast.Field_Value); ok && alignment > 0 {
+ if value, ok := expr.derived.(^ast.Field_Value); ok && alignment > 0 {
document = cons(document, cons_with_nopl(visit_expr(p, value.field), cons_with_nopl(cons(repeat_space(alignment - get_node_length(value.field)), text_position(p, "=", value.sep)), visit_expr(p, value.value))))
} else {
document = group(cons(document, visit_expr(p, expr, .Generic, options)))
@@ -473,7 +473,7 @@ visit_comp_lit_exprs :: proc(p: ^Printer, comp_lit: ast.Comp_Lit, options := Lis
if (.Enforce_Newline in options) {
alignment := get_possible_comp_lit_alignment(p, comp_lit.elems)
- if value, ok := expr.derived.(ast.Field_Value); ok && alignment > 0 {
+ if value, ok := expr.derived.(^ast.Field_Value); ok && alignment > 0 {
document = cons(document, cons_with_nopl(visit_expr(p, value.field), cons_with_nopl(cons(repeat_space(alignment - get_node_length(value.field)), text_position(p, "=", value.sep)), visit_expr(p, value.value))))
} else {
document = group(cons(document, visit_expr(p, expr, .Generic, options)))
@@ -535,23 +535,23 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
return visit_disabled(p, stmt)
}
- switch v in stmt.derived {
- case Import_Decl:
+ #partial switch v in stmt.derived {
+ case ^Import_Decl:
return visit_decl(p, cast(^Decl)stmt, true)
- case Value_Decl:
+ case ^Value_Decl:
return visit_decl(p, cast(^Decl)stmt, true)
- case Foreign_Import_Decl:
+ case ^Foreign_Import_Decl:
return visit_decl(p, cast(^Decl)stmt, true)
- case Foreign_Block_Decl:
+ case ^Foreign_Block_Decl:
return visit_decl(p, cast(^Decl)stmt, true)
}
- switch v in stmt.derived {
- case Using_Stmt:
+ #partial switch v in stmt.derived {
+ case ^Using_Stmt:
document := move_line(p, v.pos)
document = cons(document, cons_with_nopl(text("using"), visit_exprs(p, v.list, {.Add_Comma})))
return document
- case Block_Stmt:
+ case ^Block_Stmt:
document := move_line(p, v.pos)
@@ -586,7 +586,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
document = cons(document, visit_end_brace(p, v.end))
}
return document
- case If_Stmt:
+ case ^If_Stmt:
document := move_line(p, v.pos)
if v.label != nil {
@@ -619,14 +619,14 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
set_source_position(p, v.else_stmt.pos)
- if _, ok := v.else_stmt.derived.(ast.If_Stmt); ok {
+ if _, ok := v.else_stmt.derived.(^ast.If_Stmt); ok {
document = cons_with_opl(document, cons_with_nopl(text("else"), visit_stmt(p, v.else_stmt)))
} else {
document = cons_with_opl(document, cons_with_nopl(text("else"), visit_stmt(p, v.else_stmt)))
}
}
return document
- case Switch_Stmt:
+ case ^Switch_Stmt:
document := move_line(p, v.pos)
if v.label != nil {
@@ -650,7 +650,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
document = cons_with_opl(document, visit_expr(p, v.cond))
document = cons_with_nopl(document, visit_stmt(p, v.body, .Switch_Stmt))
return document
- case Case_Clause:
+ case ^Case_Clause:
document := move_line(p, v.pos)
document = cons(document, text("case"))
@@ -666,7 +666,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
}
return document
- case Type_Switch_Stmt:
+ case ^Type_Switch_Stmt:
document := move_line(p, v.pos)
if v.label != nil {
@@ -682,13 +682,13 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
document = cons_with_nopl(document, visit_stmt(p, v.tag))
document = cons_with_nopl(document, visit_stmt(p, v.body, .Switch_Stmt))
return document
- case Assign_Stmt:
+ case ^Assign_Stmt:
document := move_line(p, v.pos)
assign_document := group(cons_with_nopl(visit_exprs(p, v.lhs, {.Add_Comma, .Glue}), text(v.op.text)))
if block_stmt {
- if should_align_assignment_stmt(p, v) {
+ if should_align_assignment_stmt(p, v^) {
assign_document = fill_group(cons(assign_document, align(cons(break_with_space(), visit_exprs(p, v.rhs, {.Add_Comma}, .Assignment_Stmt)))))
} else {
assign_document = fill_group(cons(assign_document, cons(break_with_space(), visit_exprs(p, v.rhs, {.Add_Comma}, .Assignment_Stmt))))
@@ -697,11 +697,11 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
assign_document = cons_with_nopl(assign_document, visit_exprs(p, v.rhs, {.Add_Comma}, .Assignment_Stmt))
}
return cons(document, group(assign_document))
- case Expr_Stmt:
+ case ^Expr_Stmt:
document := move_line(p, v.pos)
document = cons(document, visit_expr(p, v.expr))
return document
- case For_Stmt:
+ case ^For_Stmt:
document := move_line(p, v.pos)
if v.label != nil {
@@ -711,19 +711,19 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
for_document := text("for")
if v.init != nil {
- set_source_position(p, v.init.pos);
+ set_source_position(p, v.init.pos)
for_document = cons_with_nopl(for_document, cons(group(visit_stmt(p, v.init)), text(";")))
} else if v.post != nil {
for_document = cons_with_nopl(for_document, text(";"))
}
if v.cond != nil {
- set_source_position(p, v.cond.pos);
+ set_source_position(p, v.cond.pos)
for_document = cons_with_opl(for_document, fill_group(visit_expr(p, v.cond)))
}
if v.post != nil {
- set_source_position(p, v.post.pos);
+ set_source_position(p, v.post.pos)
for_document = cons(for_document, text(";"))
for_document = cons_with_opl(for_document, group(visit_stmt(p, v.post)))
} else if v.post == nil && v.cond != nil && v.init != nil {
@@ -737,7 +737,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
set_source_position(p, v.body.end)
return document
- case Inline_Range_Stmt:
+ case ^Inline_Range_Stmt:
document := move_line(p, v.pos)
if v.label != nil {
@@ -762,7 +762,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
set_source_position(p, v.body.end)
return document
- case Range_Stmt:
+ case ^Range_Stmt:
document := move_line(p, v.pos)
if v.label != nil {
@@ -788,7 +788,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
set_source_position(p, v.body.end)
return document
- case Return_Stmt:
+ case ^Return_Stmt:
document := move_line(p, v.pos)
document = cons(document, text("return"))
@@ -798,12 +798,12 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
}
return document
- case Defer_Stmt:
+ case ^Defer_Stmt:
document := move_line(p, v.pos)
document = cons(document, text("defer"))
document = cons_with_nopl(document, visit_stmt(p, v.stmt))
return document
- case When_Stmt:
+ case ^When_Stmt:
document := move_line(p, v.pos)
document = cons(document, cons_with_nopl(text("when"), visit_expr(p, v.cond)))
@@ -820,7 +820,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
document = cons_with_nopl(document, cons_with_nopl(text("else"), visit_stmt(p, v.else_stmt)))
}
return document
- case Branch_Stmt:
+ case ^Branch_Stmt:
document := move_line(p, v.pos)
document = cons(document, text(v.tok.text))
@@ -846,7 +846,7 @@ should_align_comp_lit :: proc(p: ^Printer, comp_lit: ast.Comp_Lit) -> bool {
}
for expr in comp_lit.elems {
- if _, ok := expr.derived.(ast.Field_Value); ok {
+ if _, ok := expr.derived.(^ast.Field_Value); ok {
return true
}
}
@@ -859,11 +859,11 @@ contains_comments_in_range :: proc(p: ^Printer, pos: tokenizer.Pos, end: tokeniz
for i := p.latest_comment_index; i < len(p.comments); i += 1 {
for c in p.comments[i].list {
if pos.offset <= c.pos.offset && c.pos.offset <= end.offset {
- return true;
+ return true
}
}
}
- return false;
+ return false
}
@(private)
@@ -873,7 +873,7 @@ should_align_assignment_stmt :: proc(p: ^Printer, stmt: ast.Assign_Stmt) -> bool
}
for expr in stmt.rhs {
- if _, ok := stmt.rhs[0].derived.(ast.Binary_Expr); ok {
+ if _, ok := stmt.rhs[0].derived.(^ast.Binary_Expr); ok {
return true
}
}
@@ -913,8 +913,8 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
set_source_position(p, expr.end)
}
- switch v in expr.derived {
- case Inline_Asm_Expr:
+ #partial switch v in expr.derived {
+ case ^Inline_Asm_Expr:
document := cons(text_token(p, v.tok), text("("))
document = cons(document, visit_exprs(p, v.param_types, {.Add_Comma}))
document = cons(document, text(")"))
@@ -926,11 +926,11 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons(document, text(","))
document = cons(document, visit_expr(p, v.constraints_string))
document = cons(document, text("}"))
- case Undef:
+ case ^Undef:
return text("---")
- case Auto_Cast:
+ case ^Auto_Cast:
return cons_with_nopl(text_token(p, v.op), visit_expr(p, v.expr))
- case Ternary_If_Expr:
+ case ^Ternary_If_Expr:
if v.op1.text == "if" {
document := visit_expr(p, v.x)
document = cons_with_nopl(document, text_token(p, v.op1))
@@ -946,31 +946,31 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons_with_nopl(document, visit_expr(p, v.y))
return document
}
- case Ternary_When_Expr:
+ case ^Ternary_When_Expr:
document := visit_expr(p, v.cond)
document = cons_with_nopl(document, text_token(p, v.op1))
document = cons_with_nopl(document, visit_expr(p, v.x))
document = cons_with_nopl(document, text_token(p, v.op2))
document = cons_with_nopl(document, visit_expr(p, v.y))
return document
- case Or_Else_Expr:
+ case ^Or_Else_Expr:
document := visit_expr(p, v.x)
document = cons_with_opl(document, text_token(p, v.token))
document = cons_with_opl(document, visit_expr(p, v.y))
return document
- case Or_Return_Expr:
+ case ^Or_Return_Expr:
return cons_with_opl(visit_expr(p, v.expr), text_token(p, v.token))
- case Selector_Call_Expr:
+ case ^Selector_Call_Expr:
document := visit_expr(p, v.call.expr)
document = cons(document, text("("))
document = cons(document, visit_exprs(p, v.call.args, {.Add_Comma}))
document = cons(document, text(")"))
return document
- case Ellipsis:
+ case ^Ellipsis:
return cons(text(".."), visit_expr(p, v.expr))
- case Relative_Type:
+ case ^Relative_Type:
return cons_with_opl(visit_expr(p, v.tag), visit_expr(p, v.type))
- case Slice_Expr:
+ case ^Slice_Expr:
document := visit_expr(p, v.expr)
document = cons(document, text("["))
document = cons(document, visit_expr(p, v.low))
@@ -981,32 +981,32 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
}
document = cons(document, text("]"))
return document
- case Ident:
+ case ^Ident:
if .Enforce_Poly_Names in options {
return cons(text("$"), text(v.name))
} else {
return text_position(p, v.name, v.pos)
}
- case Deref_Expr:
+ case ^Deref_Expr:
return cons(visit_expr(p, v.expr), text_token(p, v.op))
- case Type_Cast:
+ case ^Type_Cast:
document := cons(text_token(p, v.tok), text("("))
document = cons(document, visit_expr(p, v.type))
document = cons(document, text(")"))
document = cons(document, visit_expr(p, v.expr))
return document
- case Basic_Directive:
+ case ^Basic_Directive:
return cons(text_token(p, v.tok), text_position(p, v.name, v.pos))
- case Distinct_Type:
+ case ^Distinct_Type:
return cons_with_opl(text_position(p, "distinct", v.pos), visit_expr(p, v.type))
- case Dynamic_Array_Type:
+ case ^Dynamic_Array_Type:
document := visit_expr(p, v.tag)
document = cons(document, text("["))
document = cons(document, text("dynamic"))
document = cons(document, text("]"))
document = cons(document, visit_expr(p, v.elem))
return document
- case Bit_Set_Type:
+ case ^Bit_Set_Type:
document := text_position(p, "bit_set", v.pos)
document = cons(document, text("["))
document = cons(document, visit_expr(p, v.elem))
@@ -1017,7 +1017,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons(document, text("]"))
return document
- case Union_Type:
+ case ^Union_Type:
document := text_position(p, "union", v.pos)
document = cons(document, visit_poly_params(p, v.poly_params))
@@ -1034,13 +1034,13 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
} else {
document = cons_with_opl(document, visit_begin_brace(p, v.pos, .Generic))
set_source_position(p, v.variants[0].pos)
- document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.pos), visit_union_exprs(p, v, {.Add_Comma, .Trailing, .Enforce_Newline}))))
+ document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.pos), visit_union_exprs(p, v^, {.Add_Comma, .Trailing, .Enforce_Newline}))))
set_source_position(p, v.end)
document = cons(document, cons(newline(1), text_position(p, "}", v.end)))
}
return document
- case Enum_Type:
+ case ^Enum_Type:
document := text_position(p, "enum", v.pos)
if v.base_type != nil {
@@ -1053,7 +1053,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
} else {
document = cons(document, cons(break_with_space(), visit_begin_brace(p, v.pos, .Generic)))
set_source_position(p, v.fields[0].pos)
- document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.open), visit_enum_exprs(p, v, {.Add_Comma, .Trailing, .Enforce_Newline}))))
+ document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.open), visit_enum_exprs(p, v^, {.Add_Comma, .Trailing, .Enforce_Newline}))))
set_source_position(p, v.end)
document = cons(document, cons(newline(1), text_position(p, "}", v.end)))
@@ -1061,7 +1061,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
set_source_position(p, v.end)
return document
- case Struct_Type:
+ case ^Struct_Type:
document := text_position(p, "struct", v.pos)
document = cons(document, visit_poly_params(p, v.poly_params))
@@ -1097,7 +1097,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
set_source_position(p, v.end)
return document
- case Proc_Lit:
+ case ^Proc_Lit:
document := empty()
switch v.inlining {
case .None:
@@ -1118,38 +1118,38 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
}
return document
- case Proc_Type:
- return group(visit_proc_type(p, v))
- case Basic_Lit:
+ case ^Proc_Type:
+ return group(visit_proc_type(p, v^))
+ case ^Basic_Lit:
return text_token(p, v.tok)
- case Binary_Expr:
- return visit_binary_expr(p, v)
- case Implicit_Selector_Expr:
+ case ^Binary_Expr:
+ return visit_binary_expr(p, v^)
+ case ^Implicit_Selector_Expr:
return cons(text("."), text_position(p, v.field.name, v.field.pos))
- case Call_Expr:
+ case ^Call_Expr:
document := visit_expr(p, v.expr)
document = cons(document, text("("))
document = cons(document, nest(p.indentation_count, cons(break_with(""), visit_call_exprs(p, v.args, v.ellipsis.kind == .Ellipsis))))
document = cons(document, cons(break_with(""), text(")")))
return group(document)
- case Typeid_Type:
+ case ^Typeid_Type:
document := text("typeid")
if v.specialization != nil {
document = cons(document, cons(text("/"), visit_expr(p, v.specialization)))
}
return document
- case Selector_Expr:
+ case ^Selector_Expr:
return cons(visit_expr(p, v.expr), cons(text_token(p, v.op), visit_expr(p, v.field)))
- case Paren_Expr:
+ case ^Paren_Expr:
return cons(text("("), cons(visit_expr(p, v.expr), text(")")))
- case Index_Expr:
+ case ^Index_Expr:
document := visit_expr(p, v.expr)
document = cons(document, text("["))
document = cons(document, fill_group(align(visit_expr(p, v.index))))
document = cons(document, text("]"))
return document
- case Proc_Group:
+ case ^Proc_Group:
document := text_token(p, v.tok)
if len(v.args) != 0 {
@@ -1163,18 +1163,18 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons(document, text("}"))
}
return document
- case Comp_Lit:
+ case ^Comp_Lit:
document := empty()
if v.type != nil {
document = cons(document, visit_expr(p, v.type))
}
//If we call from the value declartion, we want it to be nicely newlined and aligned
- if (should_align_comp_lit(p, v) || contains_comments_in_range(p, v.pos, v.end)) && (called_from == .Value_Decl || called_from == .Assignment_Stmt) && len(v.elems) != 0 {
+ if (should_align_comp_lit(p, v^) || contains_comments_in_range(p, v.pos, v.end)) && (called_from == .Value_Decl || called_from == .Assignment_Stmt) && len(v.elems) != 0 {
document = cons_with_opl(document, visit_begin_brace(p, v.pos, .Generic))
set_source_position(p, v.open)
- document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.elems[0].pos), visit_comp_lit_exprs(p, v, {.Add_Comma, .Trailing, .Enforce_Newline}))))
+ document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.elems[0].pos), visit_comp_lit_exprs(p, v^, {.Add_Comma, .Trailing, .Enforce_Newline}))))
set_source_position(p, v.end)
document = cons(document, cons(newline(1), text_position(p, "}", v.end)))
@@ -1186,15 +1186,15 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
}
return document
- case Unary_Expr:
+ case ^Unary_Expr:
return cons(text_token(p, v.op), visit_expr(p, v.expr))
- case Field_Value:
+ case ^Field_Value:
document := cons_with_nopl(visit_expr(p, v.field), cons_with_nopl(text_position(p, "=", v.sep), visit_expr(p, v.value)))
return document
- case Type_Assertion:
+ case ^Type_Assertion:
document := visit_expr(p, v.expr)
- if unary, ok := v.type.derived.(Unary_Expr); ok && unary.op.text == "?" {
+ if unary, ok := v.type.derived.(^Unary_Expr); ok && unary.op.text == "?" {
document = cons(document, cons(text("."), visit_expr(p, v.type)))
} else {
document = cons(document, text("."))
@@ -1203,13 +1203,13 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons(document, text(")"))
}
return document
- case Pointer_Type:
+ case ^Pointer_Type:
return cons(text("^"), visit_expr(p, v.elem))
- case Multi_Pointer_Type:
+ case ^Multi_Pointer_Type:
return cons(text("[^]"), visit_expr(p, v.elem))
- case Implicit:
+ case ^Implicit:
return text_token(p, v.tok)
- case Poly_Type:
+ case ^Poly_Type:
document := cons(text("$"), visit_expr(p, v.type))
if v.specialization != nil {
@@ -1217,22 +1217,22 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons(document, visit_expr(p, v.specialization))
}
return document
- case Array_Type:
+ case ^Array_Type:
document := visit_expr(p, v.tag)
document = cons(document, text("["))
document = cons(document, visit_expr(p, v.len))
document = cons(document, text("]"))
document = cons(document, visit_expr(p, v.elem))
return document
- case Map_Type:
+ case ^Map_Type:
document := cons(text("map"), text("["))
document = cons(document, visit_expr(p, v.key))
document = cons(document, text("]"))
document = cons(document, visit_expr(p, v.value))
return document
- case Helper_Type:
+ case ^Helper_Type:
return visit_expr(p, v.type)
- case Matrix_Type:
+ case ^Matrix_Type:
document := text_position(p, "matrix", v.pos)
document = cons(document, text("["))
document = cons(document, visit_expr(p, v.row_count))
@@ -1241,7 +1241,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons(document, text("]"))
document = cons(document, visit_expr(p, v.elem))
return document
- case Matrix_Index_Expr:
+ case ^Matrix_Index_Expr:
document := visit_expr(p, v.expr)
document = cons(document, text("["))
document = cons(document, visit_expr(p, v.row_index))
@@ -1289,9 +1289,9 @@ visit_block_stmts :: proc(p: ^Printer, stmts: []^ast.Stmt, split := false) -> ^D
document := empty()
for stmt, i in stmts {
- last_index := max(0, i-1);
+ last_index := max(0, i-1)
if stmts[last_index].end.line == stmt.pos.line && i != 0 {
- document = cons(document, break_with(";"));
+ document = cons(document, break_with(";"))
}
document = cons(document, group(visit_stmt(p, stmt, .Generic, false, true)))
}
@@ -1414,7 +1414,7 @@ visit_proc_type :: proc(p: ^Printer, proc_type: ast.Proc_Type) -> ^Document {
use_parens = true
} else if len(proc_type.results.list) == 1 {
for name in proc_type.results.list[0].names {
- if ident, ok := name.derived.(ast.Ident); ok {
+ if ident, ok := name.derived.(^ast.Ident); ok {
if ident.name != "_" {
use_parens = true
}
@@ -1442,14 +1442,14 @@ visit_binary_expr :: proc(p: ^Printer, binary: ast.Binary_Expr) -> ^Document {
lhs: ^Document
rhs: ^Document
- if v, ok := binary.left.derived.(ast.Binary_Expr); ok {
- lhs = visit_binary_expr(p, v)
+ if v, ok := binary.left.derived.(^ast.Binary_Expr); ok {
+ lhs = visit_binary_expr(p, v^)
} else {
lhs = visit_expr(p, binary.left)
}
- if v, ok := binary.right.derived.(ast.Binary_Expr); ok {
- rhs = visit_binary_expr(p, v)
+ if v, ok := binary.right.derived.(^ast.Binary_Expr); ok {
+ rhs = visit_binary_expr(p, v^)
} else {
rhs = visit_expr(p, binary.right)
}
@@ -1522,12 +1522,12 @@ visit_signature_list :: proc(p: ^Printer, list: ^ast.Field_List, remove_blank :=
for field, i in list.list {
- flag := visit_field_flag(p, field.flags);
+ flag := visit_field_flag(p, field.flags)
named := false
for name in field.names {
- if ident, ok := name.derived.(ast.Ident); ok {
+ if ident, ok := name.derived.(^ast.Ident); ok {
//for some reason the parser uses _ to mean empty
if ident.name != "_" || !remove_blank {
named = true
@@ -1578,14 +1578,14 @@ repeat_space :: proc(amount: int) -> ^Document {
}
get_node_length :: proc(node: ^ast.Node) -> int {
- switch v in node.derived {
- case ast.Ident:
+ #partial switch v in node.derived {
+ case ^ast.Ident:
return len(v.name)
- case ast.Basic_Lit:
+ case ^ast.Basic_Lit:
return len(v.tok.text)
- case ast.Implicit_Selector_Expr:
+ case ^ast.Implicit_Selector_Expr:
return len(v.field.name) + 1
- case ast.Binary_Expr:
+ case ^ast.Binary_Expr:
return 0
case:
panic(fmt.aprintf("unhandled get_node_length case %v", node.derived))
@@ -1615,14 +1615,13 @@ get_possible_comp_lit_alignment :: proc(p: ^Printer, exprs: []^ast.Expr) -> int
longest_name := 0
for expr in exprs {
-
- value, ok := expr.derived.(ast.Field_Value)
+ value, ok := expr.derived.(^ast.Field_Value)
if !ok {
return 0
}
- if _, ok := value.value.derived.(ast.Comp_Lit); ok {
+ if _, ok := value.value.derived.(^ast.Comp_Lit); ok {
return 0
}
@@ -1636,8 +1635,7 @@ get_possible_enum_alignment :: proc(p: ^Printer, exprs: []^ast.Expr) -> int {
longest_name := 0
for expr in exprs {
-
- value, ok := expr.derived.(ast.Field_Value)
+ value, ok := expr.derived.(^ast.Field_Value)
if !ok {
return 0
diff --git a/src/server/check.odin b/src/server/check.odin
index ab6dfb2..8273084 100644
--- a/src/server/check.odin
+++ b/src/server/check.odin
@@ -18,49 +18,49 @@ import "core:text/scanner"
import "shared:common"
-when ODIN_OS == "windows" {
+when ODIN_OS == .Windows {
is_package :: proc(file: string, pkg: string) {
}
check :: proc(uri: common.Uri, writer: ^Writer, config: ^common.Config) {
- data := make([]byte, mem.kilobytes(10), context.temp_allocator);
+ data := make([]byte, mem.kilobytes(10), context.temp_allocator)
- buffer: []byte;
- code: u32;
- ok: bool;
+ buffer: []byte
+ code: u32
+ ok: bool
- collection_builder := strings.make_builder(context.temp_allocator);
+ collection_builder := strings.make_builder(context.temp_allocator)
for k, v in common.config.collections {
if k == "" || k == "core" || k == "vendor" {
- continue;
+ 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;
+ command: string
if config.odin_command != "" {
- command = config.odin_command;
+ command = config.odin_command
} else {
- command = "odin";
+ command = "odin"
}
if code, ok, buffer = common.run_executable(fmt.tprintf("%v check %s %s -no-entry-point %s", command, path.dir(uri.path, context.temp_allocator), strings.to_string(collection_builder), config.checker_args), &data); !ok {
- log.errorf("Odin check failed with code %v for file %v", code, uri.path);
- return;
+ log.errorf("Odin check failed with code %v for file %v", code, uri.path)
+ return
}
- s: scanner.Scanner;
+ s: scanner.Scanner
- scanner.init(&s, string(buffer));
+ scanner.init(&s, string(buffer))
- s.whitespace = {'\t', ' '};
+ s.whitespace = {'\t', ' '}
- current: rune;
+ current: rune
ErrorSeperator :: struct {
message: string,
@@ -69,101 +69,101 @@ when ODIN_OS == "windows" {
uri: string,
}
- error_seperators := make([dynamic]ErrorSeperator, context.temp_allocator);
+ error_seperators := make([dynamic]ErrorSeperator, context.temp_allocator)
//find all the signatures string(digit:digit)
loop: for scanner.peek(&s) != scanner.EOF {
- error: ErrorSeperator;
+ error: ErrorSeperator
- source_pos := s.src_pos;
+ source_pos := s.src_pos
if source_pos == 1 {
- source_pos = 0;
+ source_pos = 0
}
for scanner.peek(&s) != '(' {
- n := scanner.scan(&s);
+ n := scanner.scan(&s)
if n == scanner.EOF {
- break loop;
+ 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);
+ left_paren := scanner.scan(&s)
if left_paren != '(' {
- break loop;
+ break loop
}
- lhs_digit := scanner.scan(&s);
+ lhs_digit := scanner.scan(&s)
if lhs_digit != scanner.Int {
- break loop;
+ break loop
}
- line, column: int;
- ok: bool;
+ line, column: int
+ ok: bool
- line, ok = strconv.parse_int(scanner.token_text(&s));
+ line, ok = strconv.parse_int(scanner.token_text(&s))
if !ok {
- break loop;
+ break loop
}
- seperator := scanner.scan(&s);
+ seperator := scanner.scan(&s)
if seperator != ':' {
- break loop;
+ break loop
}
rhs_digit := scanner.scan(&s)
if rhs_digit != scanner.Int {
- break loop;
+ break loop
}
- column, ok = strconv.parse_int(scanner.token_text(&s));
+ column, ok = strconv.parse_int(scanner.token_text(&s))
if !ok {
- break loop;
+ break loop
}
- right_paren := scanner.scan(&s);
+ right_paren := scanner.scan(&s)
if right_paren != ')' {
- break loop;
+ break loop
}
- source_pos = s.src_pos;
+ source_pos = s.src_pos
for scanner.peek(&s) != '\n' {
- n := scanner.scan(&s);
+ n := scanner.scan(&s)
if n == scanner.EOF {
- break;
+ break
}
}
if source_pos == s.src_pos {
- continue;
+ continue
}
- error.message = string(buffer[source_pos:s.src_pos-1]);
- error.column = column;
- error.line = line;
+ error.message = string(buffer[source_pos:s.src_pos-1])
+ error.column = column
+ error.line = line
- append(&error_seperators, error);
+ append(&error_seperators, error)
}
- errors := make(map[string][dynamic]Diagnostic, 0, context.temp_allocator);
+ errors := make(map[string][dynamic]Diagnostic, 0, context.temp_allocator)
for error in error_seperators {
if error.uri not_in errors {
- errors[error.uri] = make([dynamic]Diagnostic, context.temp_allocator);
+ errors[error.uri] = make([dynamic]Diagnostic, context.temp_allocator)
}
append(&errors[error.uri], Diagnostic {
@@ -180,48 +180,48 @@ when ODIN_OS == "windows" {
},
},
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);
+ uri := common.create_uri(match, context.temp_allocator)
params := NotificationPublishDiagnosticsParams {
uri = uri.uri,
diagnostics = {},
- };
+ }
notifaction := Notification {
jsonrpc = "2.0",
method = "textDocument/publishDiagnostics",
params = params,
- };
+ }
if writer != nil {
- send_notification(notifaction, writer);
+ send_notification(notifaction, writer)
}
}
}
for k, v in errors {
- uri := common.create_uri(k, context.temp_allocator);
+ uri := common.create_uri(k, context.temp_allocator)
params := NotificationPublishDiagnosticsParams {
uri = uri.uri,
diagnostics = v[:],
- };
+ }
notifaction := Notification {
jsonrpc = "2.0",
method = "textDocument/publishDiagnostics",
params = params,
- };
+ }
if writer != nil {
- send_notification(notifaction, writer);
+ send_notification(notifaction, writer)
}
}
}
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 59df7a3..ae9d4e3 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -35,64 +35,64 @@ Completion_Type :: enum {
}
get_completion_list :: proc(document: ^common.Document, position: common.Position, completion_context: CompletionContext) -> (CompletionList, bool) {
- using analysis;
+ using analysis
- list: CompletionList;
+ 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;
+ return list, true
}
if position_context.import_stmt == nil && strings.contains_any(completion_context.triggerCharacter, "/:\"") {
- return list, true;
+ return list, true
}
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri);
+ ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri)
- get_globals(document.ast, &ast_context);
+ get_globals(document.ast, &ast_context)
- ast_context.current_package = ast_context.document_package;
- ast_context.value_decl = position_context.value_decl;
+ ast_context.current_package = ast_context.document_package
+ 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;
+ completion_type: Completion_Type = .Identifier
if position_context.comp_lit != nil && is_lhs_comp_lit(&position_context) {
- completion_type = .Comp_Lit;
+ completion_type = .Comp_Lit
}
if position_context.selector != nil {
- completion_type = .Selector;
+ completion_type = .Selector
}
if position_context.tag != nil {
- completion_type = .Directive;
+ completion_type = .Directive
}
if position_context.implicit {
- completion_type = .Implicit;
+ completion_type = .Implicit
}
if position_context.import_stmt != nil {
- completion_type = .Package;
+ 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 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;
+ ast_context.use_globals = true
+ ast_context.use_locals = true
if symbol, ok := resolve_type_expression(&ast_context, assign.rhs[0]); ok {
if union_value, ok := symbol.value.(index.SymbolUnionValue); ok {
- completion_type = .Switch_Type;
+ completion_type = .Switch_Type
}
}
}
@@ -100,22 +100,22 @@ get_completion_list :: proc(document: ^common.Document, position: common.Positio
switch completion_type {
case .Comp_Lit:
- get_comp_lit_completion(&ast_context, &position_context, &list);
+ get_comp_lit_completion(&ast_context, &position_context, &list)
case .Identifier:
- get_identifier_completion(&ast_context, &position_context, &list);
+ get_identifier_completion(&ast_context, &position_context, &list)
case .Implicit:
- get_implicit_completion(&ast_context, &position_context, &list);
+ get_implicit_completion(&ast_context, &position_context, &list)
case .Selector:
- get_selector_completion(&ast_context, &position_context, &list);
+ get_selector_completion(&ast_context, &position_context, &list)
case .Switch_Type:
- get_type_switch_completion(&ast_context, &position_context, &list);
+ get_type_switch_completion(&ast_context, &position_context, &list)
case .Directive:
- get_directive_completion(&ast_context, &position_context, &list);
+ get_directive_completion(&ast_context, &position_context, &list)
case .Package:
- get_package_completion(&ast_context, &position_context, &list);
+ get_package_completion(&ast_context, &position_context, &list)
}
- return list, true;
+ return list, true
}
get_attribute_completion :: proc(ast_context: ^analysis.AstContext, position_context: ^analysis.DocumentPositionContext, list: ^CompletionList) {
@@ -124,9 +124,9 @@ get_attribute_completion :: proc(ast_context: ^analysis.AstContext, position_con
get_directive_completion :: proc(ast_context: ^analysis.AstContext, position_context: ^analysis.DocumentPositionContext, list: ^CompletionList) {
- list.isIncomplete = false;
+ list.isIncomplete = false
- items := make([dynamic]CompletionItem, context.temp_allocator);
+ 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
@@ -151,28 +151,28 @@ get_directive_completion :: proc(ast_context: ^analysis.AstContext, position_con
"procedure",
"load",
"partial",
- };
+ }
for elem in directive_list {
item := CompletionItem {
detail = elem,
label = elem,
kind = .Constant,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
- list.items = items[:];
+ list.items = items[:]
}
get_comp_lit_completion :: proc(ast_context: ^analysis.AstContext, position_context: ^analysis.DocumentPositionContext, list: ^CompletionList) {
- using analysis;
+ using analysis
- items := make([dynamic]CompletionItem, context.temp_allocator);
+ items := make([dynamic]CompletionItem, context.temp_allocator)
if position_context.parent_comp_lit.type == nil {
- return;
+ return
}
if symbol, ok := resolve_type_expression(ast_context, position_context.parent_comp_lit.type); ok {
@@ -180,11 +180,11 @@ get_comp_lit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
#partial switch v in comp_symbol.value {
case index.SymbolStructValue:
for name, i in v.names {
- ast_context.current_package = comp_symbol.pkg;
+ 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) {
- continue;
+ continue
}
item := CompletionItem {
@@ -192,126 +192,126 @@ get_comp_lit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
kind = .Field,
detail = fmt.tprintf("%v.%v: %v", comp_symbol.name, name, common.node_to_string(v.types[i])),
documentation = resolved.doc,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
}
}
}
}
- list.items = items[:];
+ list.items = items[:]
}
get_selector_completion :: proc(ast_context: ^analysis.AstContext, position_context: ^analysis.DocumentPositionContext, list: ^CompletionList) {
- using analysis;
+ using analysis
- items := make([dynamic]CompletionItem, context.temp_allocator);
+ items := make([dynamic]CompletionItem, context.temp_allocator)
- ast_context.current_package = ast_context.document_package;
+ ast_context.current_package = ast_context.document_package
- selector: index.Symbol;
- ok: bool;
+ selector: index.Symbol
+ ok: bool
- ast_context.use_locals = true;
- ast_context.use_globals = true;
+ 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;
+ return
}
//if (selector.type != .Variable && selector.type != .Package && selector.type != .Enum && selector.name != "") || (selector.type == .Variable && selector.type == .Enum) {
if selector.type != .Variable && selector.type != .Package {
- return;
+ return
}
if selector.pkg != "" {
- ast_context.current_package = 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
}
- field: string;
+ field: string
if position_context.field != nil {
- switch v in position_context.field.derived {
- case ast.Ident:
- field = v.name;
+ #partial switch v in position_context.field.derived {
+ case ^ast.Ident:
+ field = v.name
}
}
if s, ok := selector.value.(index.SymbolProcedureValue); ok {
if len(s.return_types) == 1 {
if selector, ok = resolve_type_expression(ast_context, s.return_types[0].type); !ok {
- return;
+ return
}
}
}
#partial switch v in selector.value {
case index.SymbolFixedArrayValue:
- list.isIncomplete = true;
+ list.isIncomplete = true
- containsColor := 1;
- containsCoord := 1;
+ containsColor := 1
+ containsCoord := 1
- expr_len := 0;
+ expr_len := 0
- if basic, ok := v.len.derived.(ast.Basic_Lit); ok {
+ if basic, ok := v.len.derived.(^ast.Basic_Lit); ok {
if expr_len, ok = strconv.parse_int(basic.tok.text); !ok {
- expr_len = 0;
+ expr_len = 0
}
}
if field != "" {
for i := 0; i < len(field); i += 1 {
- c := field[i];
+ c := field[i]
if _, ok := swizzle_color_components[c]; ok {
- containsColor += 1;
+ containsColor += 1
} else if _, ok := swizzle_coord_components[c]; ok {
- containsCoord += 1;
+ containsCoord += 1
}
}
}
if containsColor == 1 && containsCoord == 1 {
- save := expr_len;
+ save := expr_len
for k in swizzle_color_components {
if expr_len <= 0 {
- break;
+ break
}
- expr_len -= 1;
+ 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)),
- };
- append(&items, item);
+ }
+ append(&items, item)
}
- expr_len = save;
+ expr_len = save
for k in swizzle_coord_components {
if expr_len <= 0 {
- break;
+ break
}
- expr_len -= 1;
+ 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)),
- };
- append(&items, item);
+ }
+ append(&items, item)
}
}
@@ -319,90 +319,90 @@ get_selector_completion :: proc(ast_context: ^analysis.AstContext, position_cont
for k in swizzle_color_components {
if expr_len <= 0 {
- break;
+ break
}
- expr_len -= 1;
+ 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)),
- };
- append(&items, item);
+ }
+ append(&items, item)
}
} else if containsCoord > 1 {
for k in swizzle_coord_components {
if expr_len <= 0 {
- break;
+ break
}
- expr_len -= 1;
+ 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)),
- };
- append(&items, item);
+ }
+ append(&items, item)
}
}
case index.SymbolUnionValue:
- list.isIncomplete = false;
+ list.isIncomplete = false
for type in v.types {
if symbol, ok := resolve_type_expression(ast_context, type); ok {
- base := path.base(symbol.pkg, false, context.temp_allocator);
+ base := path.base(symbol.pkg, false, context.temp_allocator)
item := CompletionItem {
kind = .EnumMember,
detail = fmt.tprintf("%v", selector.name),
documentation = symbol.doc,
- };
+ }
if symbol.pkg == ast_context.document_package || base == "runtime" {
- item.label = fmt.aprintf("(%v)", common.node_to_string(type));
+ item.label = fmt.aprintf("(%v)", common.node_to_string(type))
} else {
- item.label = fmt.aprintf("(%v.%v)", path.base(symbol.pkg, false, context.temp_allocator), common.node_to_string(type));
+ item.label = fmt.aprintf("(%v.%v)", path.base(symbol.pkg, false, context.temp_allocator), common.node_to_string(type))
}
- append(&items, item);
+ append(&items, item)
}
}
case index.SymbolEnumValue:
- list.isIncomplete = false;
+ list.isIncomplete = false
for name in v.names {
item := CompletionItem {
label = name,
kind = .EnumMember,
detail = fmt.tprintf("%v.%v", selector.name, name),
- };
+ }
- append(&items, item);
+ append(&items, item)
}
case index.SymbolStructValue:
- list.isIncomplete = false;
+ list.isIncomplete = false
for name, i in v.names {
if selector.pkg != "" {
- ast_context.current_package = 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
}
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, ok := position_context.selector.derived.(^ast.Selector_Expr); ok {
if expr.op.text == "->" && symbol.type != .Function {
- continue;
+ continue
}
}
if position_context.arrow && symbol.type != .Function {
- continue;
+ continue
}
item := CompletionItem {
@@ -410,9 +410,9 @@ get_selector_completion :: proc(ast_context: ^analysis.AstContext, position_cont
kind = .Field,
detail = fmt.tprintf("%v.%v: %v", selector.name, name, type_to_string(ast_context, v.types[i])),
documentation = symbol.doc,
- };
+ }
- append(&items, item);
+ append(&items, item)
} else {
//just give some generic symbol with name.
item := CompletionItem {
@@ -420,75 +420,75 @@ get_selector_completion :: proc(ast_context: ^analysis.AstContext, position_cont
kind = .Field,
detail = fmt.tprintf("%v: %v", name, common.node_to_string(v.types[i])),
documentation = symbol.doc,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
}
case index.SymbolPackageValue:
- list.isIncomplete = true;
+ list.isIncomplete = true
if searched, ok := index.fuzzy_search(field, {selector.pkg}); ok {
for search in searched {
- symbol := search.symbol;
+ symbol := search.symbol
- resolve_unresolved_symbol(ast_context, &symbol);
- build_procedure_symbol_signature(&symbol);
+ 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),
documentation = symbol.doc,
- };
+ }
if symbol.type == .Function {
- item.insertText = fmt.tprintf("%v($0)", item.label);
- item.insertTextFormat = .Snippet;
- item.command.command = "editor.action.triggerParameterHints";
- item.deprecated = .Deprecated in symbol.flags;
+ item.insertText = fmt.tprintf("%v($0)", item.label)
+ item.insertTextFormat = .Snippet
+ item.command.command = "editor.action.triggerParameterHints"
+ item.deprecated = .Deprecated in symbol.flags
}
- append(&items, item);
+ append(&items, item)
}
} else {
- log.errorf("Failed to fuzzy search, field: %v, package: %v", field, selector.pkg);
- return;
+ log.errorf("Failed to fuzzy search, field: %v, package: %v", field, selector.pkg)
+ return
}
}
- list.items = items[:];
+ list.items = items[:]
}
get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_context: ^analysis.DocumentPositionContext, list: ^CompletionList) {
- using analysis;
+ using analysis
- items := make([dynamic]CompletionItem, context.temp_allocator);
+ items := make([dynamic]CompletionItem, context.temp_allocator)
- list.isIncomplete = false;
+ list.isIncomplete = false
- selector: index.Symbol;
+ selector: index.Symbol
- ast_context.use_locals = true;
- ast_context.use_globals = true;
+ ast_context.use_locals = true
+ ast_context.use_globals = true
if selector.pkg != "" {
- ast_context.current_package = 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
}
//enum switch infer
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);
+ 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 {
+ 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 {
- used_enums[implicit.field.name] = true;
+ if implicit, ok := name.derived.(^ast.Implicit_Selector_Expr); ok {
+ used_enums[implicit.field.name] = true
}
}
}
@@ -498,20 +498,20 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
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;
+ continue
}
item := CompletionItem {
label = name,
kind = .EnumMember,
detail = name,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
- list.items = items[:];
- return;
+ list.items = items[:]
+ return
}
}
@@ -527,13 +527,13 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
label = name,
kind = .EnumMember,
detail = name,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
- list.items = items[:];
- return;
+ list.items = items[:]
+ return
}
}
}
@@ -549,13 +549,13 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
label = name,
kind = .EnumMember,
detail = name,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
- list.items = items[:];
- return;
+ list.items = items[:]
+ return
}
}
}
@@ -563,13 +563,17 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
//infer bitset and enums based on the identifier comp_lit, i.e. a := My_Struct { my_ident = . }
if position_context.comp_lit != nil {
if position_context.parent_comp_lit.type == nil {
- return;
+ return
}
- field_name: string;
+ field_name: string
if position_context.field_value != nil {
- field_name = position_context.field_value.field.derived.(ast.Ident).name;
+ 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 {
@@ -577,27 +581,27 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
if s, ok := comp_symbol.value.(index.SymbolStructValue); ok {
//We can either have the final
- elem_index := -1;
+ elem_index := -1
for elem, i in comp_lit.elems {
if position_in_node(elem, position_context.position) {
- elem_index = i;
+ elem_index = i
}
}
- type: ^ast.Expr;
+ type: ^ast.Expr
for name, i in s.names {
if name != field_name {
- continue;
+ continue
}
- type = s.types[i];
- break;
+ type = s.types[i]
+ break
}
if type == nil && len(s.types) > elem_index {
- type = s.types[elem_index];
+ type = s.types[elem_index]
}
if enum_value, ok := unwrap_enum(ast_context, type); ok {
@@ -606,13 +610,13 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
label = enum_name,
kind = .EnumMember,
detail = enum_name,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
- list.items = items[:];
- return;
+ 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 {
for name in value.names {
@@ -621,12 +625,12 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
label = name,
kind = .EnumMember,
detail = name,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
- list.items = items[:];
- return;
+ list.items = items[:]
+ return
}
}
}
@@ -635,15 +639,15 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
}
if position_context.binary != nil && (position_context.binary.op.text == "==" || position_context.binary.op.text == "!=") {
- context_node: ^ast.Expr;
- enum_node: ^ast.Expr;
+ context_node: ^ast.Expr
+ enum_node: ^ast.Expr
if position_in_node(position_context.binary.right, position_context.position) {
- context_node = position_context.binary.right;
- enum_node = position_context.binary.left;
+ context_node = position_context.binary.right
+ enum_node = position_context.binary.left
} else if position_in_node(position_context.binary.left, position_context.position) {
- context_node = position_context.binary.left;
- enum_node = position_context.binary.right;
+ context_node = position_context.binary.left
+ enum_node = position_context.binary.right
}
if context_node != nil && enum_node != nil {
@@ -653,34 +657,34 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
label = name,
kind = .EnumMember,
detail = name,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
- list.items = items[:];
- return;
+ list.items = items[:]
+ return
}
}
}
if position_context.assign != nil && position_context.assign.rhs != nil && position_context.assign.lhs != nil {
- rhs_index: int;
+ rhs_index: int
for elem in position_context.assign.rhs {
if position_in_node(elem, position_context.position) {
- break;
+ 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.(index.SymbolProcedureValue); ok {
if procedure.return_types == nil {
- return;
+ return
}
- rhs_index += len(procedure.return_types);
+ rhs_index += len(procedure.return_types)
} else {
- rhs_index += 1;
+ rhs_index += 1
}
}
}
@@ -693,37 +697,37 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
label = name,
kind = .EnumMember,
detail = name,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
- list.items = items[:];
- return;
+ list.items = items[:]
+ return
}
}
}
if position_context.returns != nil && position_context.function != nil {
- return_index: int;
+ return_index: int
if position_context.returns.results == nil {
- return;
+ return
}
for result, i in position_context.returns.results {
if position_in_node(result, position_context.position) {
- return_index = i;
- break;
+ return_index = i
+ break
}
}
if position_context.function.type == nil {
- return;
+ return
}
if position_context.function.type.results == nil {
- return;
+ return
}
if len(position_context.function.type.results.list) > return_index {
@@ -733,24 +737,24 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
label = name,
kind = .EnumMember,
detail = name,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
- list.items = items[:];
- return;
+ list.items = items[:]
+ return
}
}
}
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 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 {
if proc_value, ok := symbol.value.(index.SymbolProcedureValue); ok {
if len(proc_value.arg_types) <= parameter_index {
- return;
+ return
}
if enum_value, ok := unwrap_enum(ast_context, proc_value.arg_types[parameter_index].type); ok {
@@ -759,13 +763,13 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
label = name,
kind = .EnumMember,
detail = name,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
- list.items = items[:];
- return;
+ list.items = items[:]
+ return
}
}
}
@@ -774,11 +778,11 @@ get_implicit_completion :: proc(ast_context: ^analysis.AstContext, position_cont
}
get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_context: ^analysis.DocumentPositionContext, list: ^CompletionList) {
- using analysis;
+ using analysis
- items := make([dynamic]CompletionItem, context.temp_allocator);
+ items := make([dynamic]CompletionItem, context.temp_allocator)
- list.isIncomplete = true;
+ list.isIncomplete = true
CombinedResult :: struct {
score: f32,
@@ -789,51 +793,51 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
pkg: string,
signature: string,
flags: index.SymbolFlags,
- };
+ }
combined_sort_interface :: proc(s: ^[dynamic]CombinedResult) -> sort.Interface {
return sort.Interface {
collection = rawptr(s),
len = proc(it: sort.Interface) -> int {
- s := (^[dynamic]CombinedResult)(it.collection);
- return len(s^);
+ s := (^[dynamic]CombinedResult)(it.collection)
+ return len(s^)
},
less = proc(it: sort.Interface, i, j: int) -> bool {
- s := (^[dynamic]CombinedResult)(it.collection);
- return s[i].score > s[j].score;
+ s := (^[dynamic]CombinedResult)(it.collection)
+ return s[i].score > s[j].score
},
swap = proc(it: sort.Interface, i, j: int) {
- s := (^[dynamic]CombinedResult)(it.collection);
- s[i], s[j] = s[j], s[i];
+ s := (^[dynamic]CombinedResult)(it.collection)
+ s[i], s[j] = s[j], s[i]
},
- };
- };
+ }
+ }
- combined := make([dynamic]CombinedResult);
+ combined := make([dynamic]CombinedResult)
- lookup := "";
+ lookup := ""
if position_context.identifier != nil {
- if ident, ok := position_context.identifier.derived.(ast.Ident); ok {
- lookup = ident.name;
+ if ident, ok := position_context.identifier.derived.(^ast.Ident); ok {
+ lookup = ident.name
}
}
- pkgs := make([dynamic]string, context.temp_allocator);
+ pkgs := make([dynamic]string, context.temp_allocator)
- usings := get_using_packages(ast_context);
+ usings := get_using_packages(ast_context)
for u in usings {
- append(&pkgs, u);
+ append(&pkgs, u)
}
- append(&pkgs, ast_context.document_package);
+ append(&pkgs, ast_context.document_package)
if results, ok := index.fuzzy_search(lookup, pkgs[:]); ok {
for r in results {
- r := r;
- resolve_unresolved_symbol(ast_context, &r.symbol);
- build_procedure_symbol_signature(&r.symbol);
+ r := r
+ resolve_unresolved_symbol(ast_context, &r.symbol)
+ build_procedure_symbol_signature(&r.symbol)
if r.symbol.uri != ast_context.uri {
append(&combined, CombinedResult {
score = r.score,
@@ -843,36 +847,36 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
flags = r.symbol.flags,
signature = r.symbol.signature,
pkg = r.symbol.pkg,
- });
+ })
}
}
}
- matcher := common.make_fuzzy_matcher(lookup);
+ matcher := common.make_fuzzy_matcher(lookup)
global: for k, v in ast_context.globals {
if position_context.global_lhs_stmt {
- break;
+ break
}
//combined is sorted and should do binary search instead.
for result in combined {
if result.name == k {
- continue global;
+ continue global
}
}
- ast_context.use_locals = true;
- ast_context.use_globals = true;
- ast_context.current_package = ast_context.document_package;
+ ast_context.use_locals = true
+ ast_context.use_globals = true
+ ast_context.current_package = ast_context.document_package
- ident := index.new_type(ast.Ident, v.expr.pos, v.expr.end, context.temp_allocator);
- ident.name = k;
+ ident := index.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 {
- symbol.signature = get_signature(ast_context, ident^, symbol);
+ symbol.signature = get_signature(ast_context, ident^, symbol)
- build_procedure_symbol_signature(&symbol);
+ build_procedure_symbol_signature(&symbol)
if score, ok := common.fuzzy_match(matcher, ident.name); ok == 1 {
append(&combined, CombinedResult {
@@ -883,7 +887,7 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
flags = symbol.flags,
pkg = symbol.pkg,
signature = symbol.signature,
- });
+ })
}
}
}
@@ -891,22 +895,22 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
for _, local in ast_context.locals {
for k, v in local {
if position_context.global_lhs_stmt {
- break;
+ 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;
+ ast_context.use_locals = true
+ ast_context.use_globals = true
+ ast_context.current_package = ast_context.document_package
- ident := index.new_type(ast.Ident, {offset = local_offset}, {offset = local_offset}, context.temp_allocator);
- ident.name = k;
+ ident := index.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 {
- symbol.signature = get_signature(ast_context, ident^, symbol);
+ symbol.signature = get_signature(ast_context, ident^, symbol)
- build_procedure_symbol_signature(&symbol);
+ build_procedure_symbol_signature(&symbol)
if score, ok := common.fuzzy_match(matcher, ident.name); ok == 1 {
append(&combined, CombinedResult {
@@ -917,7 +921,7 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
flags = symbol.flags,
pkg = symbol.pkg,
signature = symbol.signature,
- });
+ })
}
}
}
@@ -925,13 +929,13 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
for pkg in ast_context.imports {
if position_context.global_lhs_stmt {
- break;
+ break
}
symbol := index.Symbol {
name = pkg.base,
type = .Package,
- };
+ }
if score, ok := common.fuzzy_match(matcher, symbol.name); ok == 1 {
append(&combined, CombinedResult {
@@ -942,7 +946,7 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
flags = symbol.flags,
signature = symbol.signature,
pkg = symbol.pkg,
- });
+ })
}
}
@@ -950,7 +954,7 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
symbol := index.Symbol {
name = keyword,
type = .Keyword,
- };
+ }
if score, ok := common.fuzzy_match(matcher, keyword); ok == 1 {
append(&combined, CombinedResult {
@@ -961,7 +965,7 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
flags = symbol.flags,
signature = symbol.signature,
pkg = symbol.pkg,
- });
+ })
}
}
@@ -969,7 +973,7 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
symbol := index.Symbol {
name = keyword,
type = .Keyword,
- };
+ }
if score, ok := common.fuzzy_match(matcher, keyword); ok == 1 {
append(&combined, CombinedResult {
@@ -980,29 +984,29 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
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})
}
}
}
- sort.sort(combined_sort_interface(&combined));
+ sort.sort(combined_sort_interface(&combined))
//hard code for now
- top_results := combined[0:(min(50, len(combined)))];
+ top_results := combined[0:(min(50, len(combined)))]
for result in top_results {
- result := result;
+ 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 {
- continue;
+ continue
}
if result.snippet.insert != "" {
@@ -1012,72 +1016,72 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
kind = .Snippet,
detail = result.snippet.detail,
insertTextFormat = .Snippet,
- };
+ }
- edits := make([dynamic]TextEdit, context.temp_allocator);
+ 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);
+ append(&edits, edit)
}
}
- item.additionalTextEdits = edits[:];
+ item.additionalTextEdits = edits[:]
- append(&items, item);
+ append(&items, item)
} else {
item := CompletionItem {
label = result.name,
documentation = result.doc,
- };
+ }
- item.kind = cast(CompletionItemKind)result.type;
+ item.kind = cast(CompletionItemKind)result.type
if result.type == .Function {
- item.insertText = fmt.tprintf("%v($0)", item.label);
- item.insertTextFormat = .Snippet;
- item.deprecated = .Deprecated in result.flags;
- item.command.command = "editor.action.triggerParameterHints";
+ item.insertText = fmt.tprintf("%v($0)", item.label)
+ item.insertTextFormat = .Snippet
+ 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);
+ append(&items, item)
}
}
- list.items = items[:];
+ list.items = items[:]
}
get_package_completion :: proc(ast_context: ^analysis.AstContext, position_context: ^analysis.DocumentPositionContext, list: ^CompletionList) {
- items := make([dynamic]CompletionItem, context.temp_allocator);
+ items := make([dynamic]CompletionItem, context.temp_allocator)
- list.isIncomplete = false;
+ list.isIncomplete = false
- fullpath_length := len(position_context.import_stmt.fullpath);
+ fullpath_length := len(position_context.import_stmt.fullpath)
if fullpath_length <= 1 {
- return;
+ return
}
- without_quotes := position_context.import_stmt.fullpath[1:fullpath_length-1];
- absolute_path := without_quotes;
- colon_index := strings.index(without_quotes, ":");
+ 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];
+ 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);
+ 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];
+ absolute_path = common.config.collections[c]
}
} else {
- 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);
+ 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)
}
if !strings.contains(position_context.import_stmt.fullpath, "/") && !strings.contains(position_context.import_stmt.fullpath, ":") {
@@ -1087,9 +1091,9 @@ get_package_completion :: proc(ast_context: ^analysis.AstContext, position_conte
detail = "collection",
label = key,
kind = .Module,
- };
+ }
- append(&items, item);
+ append(&items, item)
}
}
@@ -1099,103 +1103,103 @@ get_package_completion :: proc(ast_context: ^analysis.AstContext, position_conte
detail = pkg,
label = filepath.base(pkg),
kind = .Folder,
- };
+ }
if item.label[0] == '.' {
- continue;
+ continue
}
- append(&items, item);
+ append(&items, item)
}
- list.items = items[:];
+ list.items = items[:]
}
search_for_packages :: proc(fullpath: string) -> [] string {
- packages := make([dynamic]string, context.temp_allocator);
+ packages := make([dynamic]string, context.temp_allocator)
- fh, err := os.open(fullpath);
+ fh, err := os.open(fullpath)
if err != 0 {
- return {};
+ return {}
}
if files, err := os.read_dir(fh, 0, context.temp_allocator); err == 0 {
for file in files {
if file.is_dir {
- append(&packages, file.fullpath);
+ append(&packages, file.fullpath)
}
}
}
- return packages[:];
+ return packages[:]
}
get_type_switch_completion :: proc(ast_context: ^analysis.AstContext, position_context: ^analysis.DocumentPositionContext, list: ^CompletionList) {
- using analysis;
+ using analysis
- items := make([dynamic]CompletionItem, context.temp_allocator);
- list.isIncomplete = false;
+ items := make([dynamic]CompletionItem, context.temp_allocator)
+ list.isIncomplete = false
- used_unions := make(map[string]bool, 5, context.temp_allocator);
+ 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 {
+ if case_clause, ok := stmt.derived.(^ast.Case_Clause); ok {
for name in case_clause.list {
- if ident, ok := name.derived.(ast.Ident); ok {
- used_unions[ident.name] = true;
+ if ident, ok := name.derived.(^ast.Ident); ok {
+ used_unions[ident.name] = true
}
}
}
}
}
- ast_context.use_locals = true;
- ast_context.use_globals = 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 {
- name := common.node_to_string(type);
+ name := common.node_to_string(type)
if name in used_unions {
- continue;
+ continue
}
if symbol, ok := resolve_type_expression(ast_context, union_value.types[i]); ok {
item := CompletionItem {
kind = .EnumMember,
- };
+ }
if symbol.pkg == ast_context.document_package {
- item.label = fmt.aprintf("%v", common.node_to_string(union_value.types[i]));
- item.detail = item.label;
+ item.label = fmt.aprintf("%v", common.node_to_string(union_value.types[i]))
+ item.detail = item.label
} else {
- item.label = fmt.aprintf("%v.%v", path.base(symbol.pkg, false, context.temp_allocator), name);
- item.detail = item.label;
+ item.label = fmt.aprintf("%v.%v", path.base(symbol.pkg, false, context.temp_allocator), name)
+ item.detail = item.label
}
- append(&items, item);
+ append(&items, item)
}
}
}
}
- list.items = items[:];
+ list.items = items[:]
}
get_core_insert_package_if_non_existent :: proc(ast_context: ^analysis.AstContext, pkg: string) -> (TextEdit, bool) {
- builder := strings.make_builder(context.temp_allocator);
+ builder := strings.make_builder(context.temp_allocator)
for imp in ast_context.imports {
if imp.base == pkg {
- return {}, false;
+ return {}, false
}
}
- strings.write_string(&builder, fmt.tprintf("import \"core:%v\"", pkg));
+ strings.write_string(&builder, fmt.tprintf("import \"core:%v\"", pkg))
return {
newText = strings.to_string(builder),
@@ -1209,7 +1213,7 @@ get_core_insert_package_if_non_existent :: proc(ast_context: ^analysis.AstContex
character = 0,
},
},
- }, true;
+ }, true
}
bitset_operators: map[string]bool = {
@@ -1219,7 +1223,7 @@ bitset_operators: map[string]bool = {
"<" = true,
">" = true,
"==" = true,
-};
+}
bitset_assignment_operators: map[string]bool = {
"|=" = true,
@@ -1228,14 +1232,14 @@ bitset_assignment_operators: map[string]bool = {
"<=" = true,
">=" = true,
"=" = true,
-};
+}
is_bitset_binary_operator :: proc(op: string) -> bool {
- return op in bitset_operators;
+ return op in bitset_operators
}
is_bitset_assignment_operator :: proc(op: string) -> bool {
- return op in bitset_assignment_operators;
+ return op in bitset_assignment_operators
}
language_keywords: []string = {
@@ -1280,14 +1284,14 @@ language_keywords: []string = {
"using",
"or_return",
"or_else",
-};
+}
swizzle_color_components: map[u8]bool = {
'r' = true,
'g' = true,
'b' = true,
'a' = true,
-};
+}
swizzle_coord_components: map[u8]bool = {
'x' = true,
diff --git a/src/server/definition.odin b/src/server/definition.odin
index 116fbd9..cfa2c49 100644
--- a/src/server/definition.odin
+++ b/src/server/definition.odin
@@ -20,123 +20,120 @@ import "shared:index"
import "shared:analysis"
get_definition_location :: proc(document: ^common.Document, position: common.Position) -> ([]common.Location, bool) {
- using analysis;
+ using analysis
- locations := make([dynamic]common.Location, context.temp_allocator);
+ locations := make([dynamic]common.Location, context.temp_allocator)
- location: common.Location;
+ location: common.Location
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri);
+ ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri)
- uri: string;
+ 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");
- return {}, false;
+ log.warn("Failed to get position context")
+ return {}, false
}
- get_globals(document.ast, &ast_context);
+ 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 != 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 {
-
- ident := position_context.identifier.derived.(ast.Ident);
+ if base, ok := position_context.selector.derived.(^ast.Ident); ok && position_context.identifier != nil {
+ ident := position_context.identifier.derived.(^ast.Ident)
if ident.name == base.name {
-
- if resolved, ok := resolve_location_identifier(&ast_context, ident); ok {
- location.range = resolved.range;
+ if resolved, ok := resolve_location_identifier(&ast_context, ident^); ok {
+ location.range = resolved.range
if resolved.uri == "" {
- location.uri = document.uri.uri;
+ location.uri = document.uri.uri
} else {
- location.uri = resolved.uri;
+ location.uri = resolved.uri
}
- append(&locations, location);
+ append(&locations, location)
- return locations[:], true;
+ return locations[:], true
} else {
- return {}, false;
+ return {}, false
}
}
}
//otherwise it's the field the client wants to go to.
- selector: index.Symbol;
+ selector: index.Symbol
- ast_context.use_locals = true;
- ast_context.use_globals = true;
- ast_context.current_package = ast_context.document_package;
+ ast_context.use_locals = true
+ ast_context.use_globals = true
+ ast_context.current_package = ast_context.document_package
- selector, ok = resolve_type_expression(&ast_context, position_context.selector);
+ selector, ok = resolve_type_expression(&ast_context, position_context.selector)
if !ok {
- return {}, false;
+ return {}, false
}
- field: string;
+ field: string
if position_context.field != nil {
- switch v in position_context.field.derived {
- case ast.Ident:
- field = v.name;
+ #partial switch v in position_context.field.derived {
+ case ^ast.Ident:
+ field = v.name
}
}
- uri = selector.uri;
+ uri = selector.uri
#partial switch v in selector.value {
case index.SymbolEnumValue:
- location.range = selector.range;
+ location.range = selector.range
case index.SymbolStructValue:
for name, i in v.names {
if strings.compare(name, field) == 0 {
- location.range = common.get_token_range(v.types[i]^, document.ast.src);
+ location.range = common.get_token_range(v.types[i]^, document.ast.src)
}
}
case index.SymbolPackageValue:
if symbol, ok := index.lookup(field, selector.pkg); ok {
- location.range = symbol.range;
- uri = symbol.uri;
+ location.range = symbol.range
+ uri = symbol.uri
} else {
- return {}, false;
+ return {}, false
}
}
if !ok {
- return {}, false;
+ return {}, false
}
} else if position_context.identifier != nil {
- if resolved, ok := resolve_location_identifier(&ast_context, position_context.identifier.derived.(ast.Ident)); ok {
- location.range = resolved.range;
- uri = resolved.uri;
+ if resolved, ok := resolve_location_identifier(&ast_context, position_context.identifier.derived.(^ast.Ident)^); ok {
+ location.range = resolved.range
+ uri = resolved.uri
} else {
- return {}, false;
+ return {}, false
}
} else {
- return {}, false;
+ return {}, false
}
//if the symbol is generated by the ast we don't set the uri.
if uri == "" {
- location.uri = document.uri.uri;
+ location.uri = document.uri.uri
} else {
- location.uri = uri;
+ location.uri = uri
}
append(&locations, location)
- return locations[:], true;
+ return locations[:], true
} \ No newline at end of file
diff --git a/src/server/document_links.odin b/src/server/document_links.odin
index 9295c33..ec1cecb 100644
--- a/src/server/document_links.odin
+++ b/src/server/document_links.odin
@@ -20,23 +20,23 @@ import "shared:index"
import "shared:analysis"
get_document_links :: proc(document: ^common.Document) -> ([]DocumentLink, bool) {
- using analysis;
+ using analysis
- links := make([dynamic]DocumentLink, 0, context.temp_allocator);
+ links := make([dynamic]DocumentLink, 0, context.temp_allocator)
for imp in document.ast.imports {
if len(imp.relpath.text) <= 1 {
- continue;
+ 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;
+ continue
}
if e[0] != "core" {
- continue;
+ continue
}
//Temporarly assuming non unicode
@@ -53,16 +53,16 @@ get_document_links :: proc(document: ^common.Document) -> ([]DocumentLink, bool)
},
}
- range := common.get_token_range(node, string(document.text));
+ 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]),
tooltip = "Documentation",
- };
+ }
- append(&links, link);
+ append(&links, link)
}
- return links[:], true;
+ return links[:], true
}
diff --git a/src/server/document_symbols.odin b/src/server/document_symbols.odin
index 7105465..667b94a 100644
--- a/src/server/document_symbols.odin
+++ b/src/server/document_symbols.odin
@@ -21,22 +21,22 @@ import "shared:analysis"
get_document_symbols :: proc(document: ^common.Document) -> []DocumentSymbol {
- using analysis;
+ using analysis
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri);
+ ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri)
- get_globals(document.ast, &ast_context);
+ get_globals(document.ast, &ast_context)
- symbols := make([dynamic]DocumentSymbol, context.temp_allocator);
+ symbols := make([dynamic]DocumentSymbol, context.temp_allocator)
- package_symbol: DocumentSymbol;
+ package_symbol: DocumentSymbol
if len(document.ast.decls) == 0 {
- return {};
+ return {}
}
- package_symbol.kind = .Package;
- package_symbol.name = path.base(document.package_name, false, context.temp_allocator);
+ package_symbol.kind = .Package
+ package_symbol.name = path.base(document.package_name, false, context.temp_allocator)
package_symbol.range = {
start = {
line = document.ast.decls[0].pos.line,
@@ -44,35 +44,35 @@ get_document_symbols :: proc(document: ^common.Document) -> []DocumentSymbol {
end = {
line = document.ast.decls[len(document.ast.decls) - 1].end.line,
},
- };
- package_symbol.selectionRange = package_symbol.range;
+ }
+ package_symbol.selectionRange = package_symbol.range
- children_symbols := make([dynamic]DocumentSymbol, context.temp_allocator);
+ children_symbols := make([dynamic]DocumentSymbol, context.temp_allocator)
for k, global in ast_context.globals {
- symbol: DocumentSymbol;
- symbol.range = common.get_token_range(global.expr, ast_context.file.src);
- symbol.selectionRange = symbol.range;
- symbol.name = k;
-
- switch v in global.expr.derived {
- case ast.Struct_Type:
- symbol.kind = .Struct;
- case ast.Proc_Lit, ast.Proc_Group:
- symbol.kind = .Function;
- case ast.Enum_Type, ast.Union_Type:
- symbol.kind = .Enum;
+ symbol: DocumentSymbol
+ symbol.range = common.get_token_range(global.expr, ast_context.file.src)
+ symbol.selectionRange = symbol.range
+ symbol.name = k
+
+ #partial switch v in global.expr.derived {
+ case ^ast.Struct_Type:
+ symbol.kind = .Struct
+ case ^ast.Proc_Lit, ^ast.Proc_Group:
+ symbol.kind = .Function
+ case ^ast.Enum_Type, ^ast.Union_Type:
+ symbol.kind = .Enum
case:
- symbol.kind = .Variable;
+ symbol.kind = .Variable
}
- append(&children_symbols, symbol);
+ append(&children_symbols, symbol)
}
- package_symbol.children = children_symbols[:];
+ package_symbol.children = children_symbols[:]
- append(&symbols, package_symbol);
+ append(&symbols, package_symbol)
- return symbols[:];
+ return symbols[:]
}
diff --git a/src/server/documents.odin b/src/server/documents.odin
index 07800e0..3bb4a01 100644
--- a/src/server/documents.odin
+++ b/src/server/documents.odin
@@ -27,58 +27,58 @@ DocumentStorage :: struct {
free_allocators: [dynamic]^common.Scratch_Allocator,
}
-document_storage: DocumentStorage;
+document_storage: DocumentStorage
document_storage_shutdown :: proc() {
for k, v in document_storage.documents {
- delete(k);
+ delete(k)
}
for alloc in document_storage.free_allocators {
- common.scratch_allocator_destroy(alloc);
- free(alloc);
+ common.scratch_allocator_destroy(alloc)
+ free(alloc)
}
- delete(document_storage.free_allocators);
- delete(document_storage.documents);
+ delete(document_storage.free_allocators)
+ delete(document_storage.documents)
}
document_get_allocator :: proc() -> ^common.Scratch_Allocator {
if len(document_storage.free_allocators) > 0 {
- return pop(&document_storage.free_allocators);
+ return pop(&document_storage.free_allocators)
} else {
- allocator := new(common.Scratch_Allocator);
- common.scratch_allocator_init(allocator, mem.megabytes(1));
- return allocator;
+ allocator := new(common.Scratch_Allocator)
+ common.scratch_allocator_init(allocator, mem.megabytes(1))
+ return allocator
}
}
document_free_allocator :: proc(allocator: ^common.Scratch_Allocator) {
- append(&document_storage.free_allocators, allocator);
+ append(&document_storage.free_allocators, allocator)
}
document_get :: proc(uri_string: string) -> ^common.Document {
- uri, parsed_ok := common.parse_uri(uri_string, context.temp_allocator);
+ uri, parsed_ok := common.parse_uri(uri_string, context.temp_allocator)
if !parsed_ok {
- return nil;
+ return nil
}
- document := &document_storage.documents[uri.path];
+ document := &document_storage.documents[uri.path]
if document == nil {
- log.errorf("Failed to get document %v", uri.path);
- return nil;
+ log.errorf("Failed to get document %v", uri.path)
+ return nil
}
- intrinsics.atomic_add(&document.operating_on, 1);
+ intrinsics.atomic_add(&document.operating_on, 1)
- return document;
+ return document
}
document_release :: proc(document: ^common.Document) {
if document != nil {
- intrinsics.atomic_sub(&document.operating_on, 1);
+ intrinsics.atomic_sub(&document.operating_on, 1)
}
}
@@ -87,27 +87,27 @@ document_release :: proc(document: ^common.Document) {
*/
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);
+ uri, parsed_ok := common.parse_uri(uri_string, context.allocator)
if !parsed_ok {
- log.error("Failed to parse uri");
- return .ParseError;
+ log.error("Failed to parse uri")
+ return .ParseError
}
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);
- return .InvalidRequest;
+ log.errorf("Client called open on an already open document: %v ", document.uri.path)
+ return .InvalidRequest
}
- document.uri = uri;
- document.client_owned = true;
- document.text = transmute([]u8)text;
- document.used_text = len(document.text);
- document.allocator = document_get_allocator();
+ document.uri = uri
+ document.client_owned = true
+ document.text = transmute([]u8)text
+ document.used_text = len(document.text)
+ document.allocator = document_get_allocator()
if err := document_refresh(document, config, writer); err != .None {
- return err;
+ return err
}
} else {
document := common.Document {
@@ -116,142 +116,142 @@ document_open :: proc(uri_string: string, text: string, config: ^common.Config,
client_owned = true,
used_text = len(text),
allocator = document_get_allocator(),
- };
+ }
if err := document_refresh(&document, config, writer); err != .None {
- return err;
+ return err
}
- document_storage.documents[strings.clone(uri.path)] = document;
+ document_storage.documents[strings.clone(uri.path)] = document
}
- delete(uri_string);
+ delete(uri_string)
- return .None;
+ return .None
}
/*
Function that applies changes to the given document through incremental syncronization
*/
document_apply_changes :: proc(uri_string: string, changes: [dynamic]TextDocumentContentChangeEvent, config: ^common.Config, writer: ^Writer) -> common.Error {
- uri, parsed_ok := common.parse_uri(uri_string, context.temp_allocator);
+ uri, parsed_ok := common.parse_uri(uri_string, context.temp_allocator)
if !parsed_ok {
- return .ParseError;
+ return .ParseError
}
- document := &document_storage.documents[uri.path];
+ document := &document_storage.documents[uri.path]
if !document.client_owned {
- log.errorf("Client called change on an document not opened: %v ", document.uri.path);
- return .InvalidRequest;
+ 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;
+ return .ParseError
}
//lower bound is before the change
- lower := document.text[:absolute_range.start];
+ lower := document.text[:absolute_range.start]
//new change between lower and upper
- middle := change.text;
+ middle := change.text
//upper bound is after the change
- upper := document.text[absolute_range.end:document.used_text];
+ upper := document.text[absolute_range.end:document.used_text]
//total new size needed
- document.used_text = len(lower) + len(change.text) + len(upper);
+ document.used_text = len(lower) + len(change.text) + len(upper)
//Reduce the amount of allocation by allocating more memory than needed
if document.used_text > len(document.text) {
- new_text := make([]u8, document.used_text * 2);
+ new_text := make([]u8, document.used_text * 2)
//join the 3 splices into the text
- copy(new_text, lower);
- copy(new_text[len(lower):], middle);
- copy(new_text[len(lower) + len(middle):], upper);
+ copy(new_text, lower)
+ copy(new_text[len(lower):], middle)
+ copy(new_text[len(lower) + len(middle):], upper)
- delete(document.text);
+ delete(document.text)
- document.text = new_text;
+ document.text = new_text
} else {
//order matters here, we need to make sure we swap the data already in the text before the middle
- copy(document.text, lower);
- copy(document.text[len(lower) + len(middle):], upper);
- copy(document.text[len(lower):], middle);
+ copy(document.text, lower)
+ copy(document.text[len(lower) + len(middle):], upper)
+ copy(document.text[len(lower):], middle)
}
} else {
- document.used_text = len(change.text);
+ document.used_text = len(change.text)
if document.used_text > len(document.text) {
- new_text := make([]u8, document.used_text * 2);
- copy(new_text, change.text);
- delete(document.text);
- document.text = new_text;
+ new_text := make([]u8, document.used_text * 2)
+ copy(new_text, change.text)
+ delete(document.text)
+ document.text = new_text
} else {
- copy(document.text, change.text);
+ copy(document.text, change.text)
}
}
}
//log.info(string(document.text[:document.used_text]));
- return document_refresh(document, config, writer);
+ return document_refresh(document, config, writer)
}
document_close :: proc(uri_string: string) -> common.Error {
- log.infof("document_close: %v", uri_string);
+ log.infof("document_close: %v", uri_string)
- uri, parsed_ok := common.parse_uri(uri_string, context.temp_allocator);
+ uri, parsed_ok := common.parse_uri(uri_string, context.temp_allocator)
if !parsed_ok {
- return .ParseError;
+ return .ParseError
}
- document := &document_storage.documents[uri.path];
+ 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);
- return .InvalidRequest;
+ log.errorf("Client called close on a document that was never opened: %v ", document.uri.path)
+ return .InvalidRequest
}
- free_all(common.scratch_allocator(document.allocator));
- document_free_allocator(document.allocator);
+ free_all(common.scratch_allocator(document.allocator))
+ document_free_allocator(document.allocator)
- document.allocator = nil;
- document.client_owned = false;
+ document.allocator = nil
+ document.client_owned = false
- common.delete_uri(document.uri);
+ common.delete_uri(document.uri)
- delete(document.text);
+ delete(document.text)
- document.used_text = 0;
+ document.used_text = 0
- return .None;
+ return .None
}
document_refresh :: proc(document: ^common.Document, config: ^common.Config, writer: ^Writer) -> common.Error {
- errors, ok := parse_document(document, config);
+ errors, ok := parse_document(document, config)
if !ok {
- return .ParseError;
+ return .ParseError
}
if writer != nil && len(errors) > 0 {
- document.diagnosed_errors = true;
+ document.diagnosed_errors = true
params := NotificationPublishDiagnosticsParams {
uri = document.uri.uri,
diagnostics = make([]Diagnostic, len(errors), context.temp_allocator),
- };
+ }
for error, i in errors {
params.diagnostics[i] = Diagnostic {
@@ -268,16 +268,16 @@ document_refresh :: proc(document: ^common.Document, config: ^common.Config, wri
severity = DiagnosticSeverity.Error,
code = "test",
message = error.message,
- };
+ }
}
notifaction := Notification {
jsonrpc = "2.0",
method = "textDocument/publishDiagnostics",
params = params,
- };
+ }
- send_notification(notifaction, writer);
+ send_notification(notifaction, writer)
}
if writer != nil && len(errors) == 0 {
@@ -291,31 +291,31 @@ document_refresh :: proc(document: ^common.Document, config: ^common.Config, wri
uri = document.uri.uri,
diagnostics = make([]Diagnostic, len(errors), context.temp_allocator),
},
- };
+ }
- document.diagnosed_errors = false;
+ document.diagnosed_errors = false
- send_notification(notifaction, writer);
+ send_notification(notifaction, writer)
}
}
//We only resolve the entire file, if we are dealing with the heavy features that require the entire file resolved.
//This gives the user a choice to use "fast mode" with only completion and gotos.
if config.enable_semantic_tokens || config.enable_inlay_hints {
- resolve_entire_file(document);
+ resolve_entire_file(document)
}
- return .None;
+ return .None
}
-current_errors: [dynamic]ParserError;
+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),
- };
- append(&current_errors, error);
+ }
+ append(&current_errors, error)
}
parse_document :: proc(document: ^common.Document, config: ^common.Config) -> ([]ParserError, bool) {
@@ -323,92 +323,92 @@ parse_document :: proc(document: ^common.Document, config: ^common.Config) -> ([
err = parser_error_handler,
warn = common.parser_warning_handler,
flags = {.Optional_Semicolons},
- };
+ }
- current_errors = make([dynamic]ParserError, context.temp_allocator);
+ current_errors = make([dynamic]ParserError, context.temp_allocator)
- free_all(common.scratch_allocator(document.allocator));
+ free_all(common.scratch_allocator(document.allocator))
- context.allocator = common.scratch_allocator(document.allocator);
+ context.allocator = common.scratch_allocator(document.allocator)
//have to cheat the parser since it really wants to parse an entire package with the new changes...
- pkg := new(ast.Package);
- pkg.kind = .Normal;
- pkg.fullpath = document.uri.path;
+ pkg := new(ast.Package)
+ pkg.kind = .Normal
+ pkg.fullpath = document.uri.path
document.ast = ast.File {
fullpath = document.uri.path,
src = string(document.text[:document.used_text]),
pkg = pkg,
- };
+ }
- parser.parse_file(&p, &document.ast);
+ parser.parse_file(&p, &document.ast)
- imports := make([dynamic]common.Package);
+ imports := make([dynamic]common.Package)
- when ODIN_OS == "windows" {
- document.package_name = strings.to_lower(path.dir(document.uri.path, context.temp_allocator));
+ when ODIN_OS == .Windows {
+ document.package_name = strings.to_lower(path.dir(document.uri.path, context.temp_allocator))
} else {
- document.package_name = path.dir(document.uri.path);
+ document.package_name = path.dir(document.uri.path)
}
for imp, index in document.ast.imports {
if i := strings.index(imp.fullpath, "\""); i == -1 {
- continue;
+ continue
}
//collection specified
if i := strings.index(imp.fullpath, ":"); i != -1 && i > 1 && i < len(imp.fullpath) - 1 {
if len(imp.fullpath) < 2 {
- continue;
+ continue
}
- collection := imp.fullpath[1:i];
- p := imp.fullpath[i + 1:len(imp.fullpath) - 1];
+ collection := imp.fullpath[1:i]
+ p := imp.fullpath[i + 1:len(imp.fullpath) - 1]
- dir, ok := config.collections[collection];
+ dir, ok := config.collections[collection]
if !ok {
- continue;
+ continue
}
- import_: common.Package;
+ import_: common.Package
- when ODIN_OS == "windows" {
- import_.name = strings.clone(path.join(elems = {strings.to_lower(dir, context.temp_allocator), p}, allocator = context.temp_allocator));
+ when ODIN_OS == .Windows {
+ import_.name = strings.clone(path.join(elems = {strings.to_lower(dir, context.temp_allocator), p}, allocator = context.temp_allocator))
} else {
- 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;
+ import_.base = imp.name.text
} else {
- import_.base = path.base(import_.name, false);
+ import_.base = path.base(import_.name, false)
}
- append(&imports, import_);
+ append(&imports, import_)
} else {
//relative
if len(imp.fullpath) < 2 {
- continue;
+ continue
}
- import_: common.Package;
- 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);
+ import_: common.Package
+ 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 != "" {
- import_.base = imp.name.text;
+ import_.base = imp.name.text
} else {
- import_.base = path.base(import_.name, false);
+ import_.base = path.base(import_.name, false)
}
- append(&imports, import_);
+ append(&imports, import_)
}
}
- document.imports = imports[:];
+ document.imports = imports[:]
- return current_errors[:], true;
+ return current_errors[:], true
}
diff --git a/src/server/format.odin b/src/server/format.odin
index 1bf4892..5829793 100644
--- a/src/server/format.odin
+++ b/src/server/format.odin
@@ -19,39 +19,39 @@ DocumentFormattingParams :: struct {
get_complete_format :: proc(document: ^common.Document, config: ^common.Config) -> ([]TextEdit, bool) {
- style := printer.default_style;
- style.max_characters = config.formatter.characters;
- style.tabs = config.formatter.tabs;
+ style := printer.default_style
+ style.max_characters = config.formatter.characters
+ style.tabs = config.formatter.tabs
- prnt := printer.make_printer(style, context.temp_allocator);
+ prnt := printer.make_printer(style, context.temp_allocator)
if document.ast.syntax_error_count > 0 {
- return {}, true;
+ return {}, true
}
if len(document.text) == 0 {
- return {}, true;
+ return {}, true
}
- src := printer.print(&prnt, &document.ast);
+ src := printer.print(&prnt, &document.ast)
- end_line := 0;
- end_charcter := 0;
+ end_line := 0
+ end_charcter := 0
- last := document.text[0];
- line := 0;
+ last := document.text[0]
+ line := 0
for current_index := 0; current_index < len(document.text); current_index += 1 {
- current := document.text[current_index];
+ current := document.text[current_index]
if last == '\r' && current == '\n' {
- line += 1;
- current_index += 1;
+ line += 1
+ current_index += 1
} else if current == '\n' {
- line += 1;
+ line += 1
}
- last = current;
+ last = current
}
edit := TextEdit {
@@ -66,11 +66,11 @@ get_complete_format :: proc(document: ^common.Document, config: ^common.Config)
line = line+1,
},
},
- };
+ }
- edits := make([dynamic]TextEdit, context.temp_allocator);
+ edits := make([dynamic]TextEdit, context.temp_allocator)
- append(&edits, edit);
+ append(&edits, edit)
- return edits[:], true;
+ return edits[:], true
}
diff --git a/src/server/hover.odin b/src/server/hover.odin
index e7c5dba..5dd6acf 100644
--- a/src/server/hover.odin
+++ b/src/server/hover.odin
@@ -18,158 +18,158 @@ import "shared:index"
import "shared:analysis"
write_hover_content :: proc(ast_context: ^analysis.AstContext, symbol: index.Symbol) -> MarkupContent {
- using analysis;
+ using analysis
- content: MarkupContent;
+ content: MarkupContent
- symbol := symbol;
+ symbol := symbol
if untyped, ok := symbol.value.(index.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"
}
}
- build_procedure_symbol_signature(&symbol);
+ build_procedure_symbol_signature(&symbol)
- cat := concatenate_symbol_information(ast_context, symbol, false);
+ cat := concatenate_symbol_information(ast_context, symbol, false)
if cat != "" {
- content.kind = "markdown";
- content.value = fmt.tprintf("```odin\n %v\n```\n%v", cat, symbol.doc);
+ content.kind = "markdown"
+ content.value = fmt.tprintf("```odin\n %v\n```\n%v", cat, symbol.doc)
} else {
- content.kind = "plaintext";
+ content.kind = "plaintext"
}
- return content;
+ return content
}
get_hover_information :: proc(document: ^common.Document, position: common.Position) -> (Hover, bool) {
- using analysis;
+ using analysis
hover := Hover {
contents = {
kind = "plaintext",
},
- };
+ }
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri);
+ ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri)
- 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);
+ 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 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);
- return hover, true;
+ hover.contents.kind = "plaintext"
+ hover.range = common.get_token_range(position_context.identifier^, ast_context.file.src)
+ return hover, 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;
+ 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);
+ ident := position_context.identifier.derived.(^ast.Ident)^
if ident.name == base.name {
if resolved, ok := resolve_type_identifier(&ast_context, ident); ok {
- resolved.signature = get_signature(&ast_context, ident, resolved);
- resolved.name = ident.name;
+ resolved.signature = get_signature(&ast_context, ident, resolved)
+ resolved.name = ident.name
if resolved.type == .Variable {
- resolved.pkg = ast_context.document_package;
+ resolved.pkg = ast_context.document_package
}
- hover.contents = write_hover_content(&ast_context, resolved);
- return hover, true;
+ hover.contents = write_hover_content(&ast_context, resolved)
+ return hover, true
}
}
}
- selector: index.Symbol;
- selector, ok = resolve_type_expression(&ast_context, position_context.selector);
+ selector: index.Symbol
+ selector, ok = resolve_type_expression(&ast_context, position_context.selector)
if !ok {
- return hover, true;
+ return hover, true
}
- field: string;
+ field: string
if position_context.field != nil {
- switch v in position_context.field.derived {
- case ast.Ident:
- field = v.name;
+ #partial switch v in position_context.field.derived {
+ case ^ast.Ident:
+ field = v.name
}
}
- hover.range = common.get_token_range(position_context.identifier^, document.ast.src);
+ hover.range = common.get_token_range(position_context.identifier^, document.ast.src)
#partial switch v in selector.value {
case index.SymbolStructValue:
for name, i in v.names {
if strings.compare(name, field) == 0 {
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);
- return hover, true;
+ 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)
+ return hover, true
}
}
}
case index.SymbolPackageValue:
if position_context.field != nil {
- if ident, ok := position_context.field.derived.(ast.Ident); ok {
- ast_context.current_package = selector.pkg;
- if symbol, ok := resolve_type_identifier(&ast_context, ident); ok {
- hover.contents = write_hover_content(&ast_context, symbol);
- return hover, true;
+ if ident, ok := position_context.field.derived.(^ast.Ident); ok {
+ ast_context.current_package = selector.pkg
+ if symbol, ok := resolve_type_identifier(&ast_context, ident^); ok {
+ hover.contents = write_hover_content(&ast_context, symbol)
+ return hover, true
}
}
}
}
} else if position_context.identifier != nil {
- ast_context.use_locals = true;
- ast_context.use_globals = true;
- ast_context.current_package = ast_context.document_package;
+ ast_context.use_locals = true
+ ast_context.use_globals = true
+ ast_context.current_package = ast_context.document_package
- ident := position_context.identifier.derived.(ast.Ident);
+ 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 {
- resolved.signature = get_signature(&ast_context, ident, resolved);
- resolved.name = ident.name;
+ resolved.signature = get_signature(&ast_context, ident, resolved)
+ resolved.name = ident.name
if resolved.type == .Variable {
- resolved.pkg = ast_context.document_package;
+ resolved.pkg = ast_context.document_package
}
- hover.contents = write_hover_content(&ast_context, resolved);
- return hover, true;
+ hover.contents = write_hover_content(&ast_context, resolved)
+ return hover, true
}
}
- return hover, true;
+ return hover, true
}
diff --git a/src/server/inlay_hints.odin b/src/server/inlay_hints.odin
index 1e7d2c3..ae3d9a0 100644
--- a/src/server/inlay_hints.odin
+++ b/src/server/inlay_hints.odin
@@ -9,11 +9,11 @@ import "shared:index"
//document
get_inlay_hints :: proc(document: ^common.Document, symbols: map[uintptr]index.Symbol) -> ([]InlayHint, bool) {
- using analysis;
+ using analysis
- hints := make([dynamic]InlayHint, context.temp_allocator);
+ hints := make([dynamic]InlayHint, context.temp_allocator)
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri);
+ ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri)
Visit_Data :: struct {
calls: [dynamic]^ast.Node,
@@ -21,20 +21,20 @@ get_inlay_hints :: proc(document: ^common.Document, symbols: map[uintptr]index.S
data := Visit_Data {
calls = make([dynamic]^ast.Node, context.temp_allocator),
- };
+ }
visit :: proc(visitor: ^ast.Visitor, node: ^ast.Node) -> ^ast.Visitor {
if node == nil || visitor == nil {
- return nil;
+ return nil
}
- data := cast(^Visit_Data)visitor.data;
+ data := cast(^Visit_Data)visitor.data
- if call, ok := node.derived.(ast.Call_Expr); ok {
- append(&data.calls, node);
+ if call, ok := node.derived.(^ast.Call_Expr); ok {
+ append(&data.calls, node)
}
- return visitor;
+ return visitor
}
visitor := ast.Visitor {
@@ -43,17 +43,17 @@ get_inlay_hints :: proc(document: ^common.Document, symbols: map[uintptr]index.S
}
for decl in document.ast.decls {
- ast.walk(&visitor, decl);
+ ast.walk(&visitor, decl)
}
loop: for node_call in &data.calls {
symbol_arg_count := 0
- call := node_call.derived.(ast.Call_Expr);
+ call := node_call.derived.(^ast.Call_Expr)
for arg in call.args {
- if _, ok := arg.derived.(ast.Field); ok {
- continue loop;
+ if _, ok := arg.derived.(^ast.Field); ok {
+ continue loop
}
}
@@ -62,23 +62,23 @@ get_inlay_hints :: proc(document: ^common.Document, symbols: map[uintptr]index.S
for arg in symbol_call.arg_types {
for name in arg.names {
if symbol_arg_count >= len(call.args) {
- continue loop;
+ continue loop
}
- if ident, ok := name.derived.(ast.Ident); ok {
+ if ident, ok := name.derived.(^ast.Ident); ok {
hint := InlayHint {
kind = "parameter",
label = fmt.tprintf("%v = ", ident.name),
range = common.get_token_range(call.args[symbol_arg_count], string(document.text)),
}
- append(&hints, hint);
+ append(&hints, hint)
}
- symbol_arg_count += 1;
+ symbol_arg_count += 1
}
}
}
}
}
- return hints[:], true;
+ return hints[:], true
} \ No newline at end of file
diff --git a/src/server/lens.odin b/src/server/lens.odin
index 9d80d0c..93827f5 100644
--- a/src/server/lens.odin
+++ b/src/server/lens.odin
@@ -22,22 +22,22 @@ CodeLens :: struct {
get_code_lenses :: proc(document: ^common.Document, position: common.Position) -> ([]CodeLens, bool) {
- using analysis;
+ using analysis
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri);
+ ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri)
- get_globals(document.ast, &ast_context);
+ get_globals(document.ast, &ast_context)
- symbols := make([dynamic]CodeLens, context.temp_allocator);
+ symbols := make([dynamic]CodeLens, context.temp_allocator)
if len(document.ast.decls) == 0 {
- return {}, true;
+ return {}, true
}
for name, global in ast_context.globals {
- if proc_lit, ok := global.expr.derived.(ast.Proc_Lit); ok {
+ if proc_lit, ok := global.expr.derived.(^ast.Proc_Lit); ok {
@@ -47,7 +47,7 @@ get_code_lenses :: proc(document: ^common.Document, position: common.Position) -
}
- return {}, false;
+ return {}, false
}
diff --git a/src/server/log.odin b/src/server/log.odin
index cf83979..7ed3da9 100644
--- a/src/server/log.odin
+++ b/src/server/log.odin
@@ -12,27 +12,27 @@ Default_Console_Logger_Opts :: log.Options {
.Short_File_Path,
.Line,
.Procedure,
-} | log.Full_Timestamp_Opts;
+} | 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 {
- data := new(Lsp_Logger_Data);
- data.writer = writer;
- return log.Logger {lsp_logger_proc, data, lowest, opt};
+ data := new(Lsp_Logger_Data)
+ data.writer = writer
+ return log.Logger {lsp_logger_proc, data, lowest, opt}
}
destroy_lsp_logger :: proc(log: ^log.Logger) {
- free(log.data);
+ free(log.data)
}
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;
+ data := cast(^Lsp_Logger_Data)logger_data
- message := fmt.tprintf("%s", text);
+ message := fmt.tprintf("%s", text)
notification := Notification {
jsonrpc = "2.0",
@@ -41,7 +41,7 @@ lsp_logger_proc :: proc(logger_data: rawptr, level: log.Level, text: string, opt
type = 1,
message = message,
},
- };
+ }
- send_notification(notification, data.writer);
+ send_notification(notification, data.writer)
}
diff --git a/src/server/reader.odin b/src/server/reader.odin
index a05e147..be0d4ae 100644
--- a/src/server/reader.odin
+++ b/src/server/reader.odin
@@ -4,7 +4,7 @@ import "core:os"
import "core:mem"
import "core:strings"
-ReaderFn :: proc(_: rawptr, _: []byte) -> (int, int);
+ReaderFn :: proc(_: rawptr, _: []byte) -> (int, int)
Reader :: struct {
reader_fn: ReaderFn,
@@ -12,61 +12,61 @@ 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) {
- value: [1]byte;
+ value: [1]byte
- read, err := reader.reader_fn(reader.reader_context, value[:]);
+ read, err := reader.reader_fn(reader.reader_context, value[:])
if (err != 0 || read != 1) {
- return 0, false;
+ return 0, false
}
- return value[0], true;
+ return value[0], true
}
read_until_delimiter :: proc(reader: ^Reader, delimiter: u8, builder: ^strings.Builder) -> bool {
for true {
- value, success := read_u8(reader);
+ value, success := read_u8(reader)
if (!success) {
- return false;
+ return false
}
- strings.write_byte(builder, value);
+ strings.write_byte(builder, value)
if (value == delimiter) {
- break;
+ break
}
}
- return true;
+ return true
}
read_sized :: proc(reader: ^Reader, data: []u8) -> (ok: bool) {
- ok = true;
- size := len(data);
- n := 0;
+ ok = true
+ size := len(data)
+ n := 0
for n < size && ok {
- read: int;
- err_code: int;
+ read: int
+ err_code: int
- read, err_code = reader.reader_fn(reader.reader_context, data[n:]);
+ read, err_code = reader.reader_fn(reader.reader_context, data[n:])
- ok = err_code == 0;
+ ok = err_code == 0
- n += read;
+ n += read
}
if n >= size {
- ok = true;
+ ok = true
}
- return;
+ return
}
diff --git a/src/server/requests.odin b/src/server/requests.odin
index b06f4cd..00af132 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -63,7 +63,7 @@ make_response_message :: proc (id: RequestId, params: ResponseParams) -> Respons
jsonrpc = "2.0",
id = id,
result = params,
- };
+ }
}
make_response_message_error :: proc (id: RequestId, error: ResponseError) -> ResponseMessageError {
@@ -72,7 +72,7 @@ make_response_message_error :: proc (id: RequestId, error: ResponseError) -> Res
jsonrpc = "2.0",
id = id,
error = error,
- };
+ }
}
RequestThreadData :: struct {
@@ -87,157 +87,157 @@ Request :: struct {
}
-requests_sempahore: sync.Semaphore;
-requests_mutex: sync.Mutex;
+requests_sempahore: sync.Semaphore
+requests_mutex: sync.Mutex
-requests: [dynamic]Request;
-deletings: [dynamic]Request;
+requests: [dynamic]Request
+deletings: [dynamic]Request
thread_request_main :: proc(data: rawptr) {
- request_data := cast(^RequestThreadData)data;
+ request_data := cast(^RequestThreadData)data
for common.config.running {
- header, success := read_and_parse_header(request_data.reader);
+ header, success := read_and_parse_header(request_data.reader)
if (!success) {
- log.error("Failed to read and parse header");
- return;
+ log.error("Failed to read and parse header")
+ return
}
- value: json.Value;
- value, success = read_and_parse_body(request_data.reader, header);
+ value: json.Value
+ value, success = read_and_parse_body(request_data.reader, header)
if (!success) {
- log.error("Failed to read and parse body");
- return;
+ log.error("Failed to read and parse body")
+ return
}
- root, ok := value.(json.Object);
+ root, ok := value.(json.Object)
if !ok {
- log.error("No root object");
- return;
+ log.error("No root object")
+ return
}
- id: RequestId;
- id_value: json.Value;
- id_value, ok = root["id"];
+ id: RequestId
+ id_value: json.Value
+ id_value, ok = root["id"]
if ok {
#partial switch v in id_value {
case json.String:
- id = v;
+ id = v
case json.Integer:
- id = v;
+ id = v
case:
- id = 0;
+ id = 0
}
}
- sync.mutex_lock(&requests_mutex);
+ sync.mutex_lock(&requests_mutex)
- method := root["method"].(json.String);
+ method := root["method"].(json.String)
if method == "$/cancelRequest" {
- append(&deletings, Request { id = id });
+ append(&deletings, Request { id = id })
} else if method in notification_map {
- append(&requests, Request { value = root, is_notification = true});
- sync.semaphore_post(&requests_sempahore);
+ append(&requests, Request { value = root, is_notification = true})
+ sync.semaphore_post(&requests_sempahore)
} else {
- append(&requests, Request { id = id, value = root});
- sync.semaphore_post(&requests_sempahore);
+ append(&requests, Request { id = id, value = root})
+ sync.semaphore_post(&requests_sempahore)
}
- sync.mutex_unlock(&requests_mutex);
+ sync.mutex_unlock(&requests_mutex)
- free_all(context.temp_allocator);
+ free_all(context.temp_allocator)
}
}
read_and_parse_header :: proc (reader: ^Reader) -> (Header, bool) {
- header: Header;
+ header: Header
- builder := strings.make_builder(context.temp_allocator);
+ builder := strings.make_builder(context.temp_allocator)
- found_content_length := false;
+ found_content_length := false
for true {
- strings.reset_builder(&builder);
+ strings.reset_builder(&builder)
if !read_until_delimiter(reader, '\n', &builder) {
- log.error("Failed to read with delimiter");
- return header, false;
+ log.error("Failed to read with delimiter")
+ return header, false
}
- message := strings.to_string(builder);
+ message := strings.to_string(builder)
if len(message) == 0 || message[len(message) - 2] != '\r' {
- log.error("No carriage return");
- return header, false;
+ log.error("No carriage return")
+ return header, false
}
if len(message) == 2 {
- break;
+ break
}
- index := strings.last_index_byte(message, ':');
+ index := strings.last_index_byte(message, ':')
if index == -1 {
- log.error("Failed to find semicolon");
- return header, false;
+ log.error("Failed to find semicolon")
+ return header, false
}
- header_name := message[0:index];
- header_value := message[len(header_name) + 2:len(message) - 2];
+ header_name := message[0:index]
+ header_value := message[len(header_name) + 2:len(message) - 2]
if strings.compare(header_name, "Content-Length") == 0 {
if len(header_value) == 0 {
- log.error("Header value has no length");
- return header, false;
+ log.error("Header value has no length")
+ return header, false
}
- value, ok := strconv.parse_int(header_value);
+ value, ok := strconv.parse_int(header_value)
if !ok {
- log.error("Failed to parse content length value");
- return header, false;
+ log.error("Failed to parse content length value")
+ return header, false
}
- header.content_length = value;
+ header.content_length = value
- found_content_length = true;
+ found_content_length = true
} else if strings.compare(header_name, "Content-Type") == 0 {
if len(header_value) == 0 {
- log.error("Header value has no length");
- return header, false;
+ log.error("Header value has no length")
+ return header, false
}
}
}
- return header, found_content_length;
+ return header, found_content_length
}
read_and_parse_body :: proc (reader: ^Reader, header: Header) -> (json.Value, bool) {
- value: json.Value;
+ value: json.Value
- data := make([]u8, header.content_length, context.temp_allocator);
+ data := make([]u8, header.content_length, context.temp_allocator)
if !read_sized(reader, data) {
- log.error("Failed to read body");
- return value, false;
+ log.error("Failed to read body")
+ return value, false
}
- err: json.Error;
+ 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");
- return value, false;
+ log.error("Failed to parse body")
+ return value, false
}
- return value, true;
+ return value, true
}
call_map : map [string] proc(json.Value, RequestId, ^common.Config, ^Writer) -> common.Error =
@@ -260,7 +260,7 @@ call_map : map [string] proc(json.Value, RequestId, ^common.Config, ^Writer) ->
"textDocument/formatting" = request_format_document,
"odin/inlayHints" = request_inlay_hint,
"textDocument/documentLink" = request_document_links,
-};
+}
notification_map: map [string] bool = {
"textDocument/didOpen" = true,
@@ -271,52 +271,52 @@ notification_map: map [string] bool = {
}
consume_requests :: proc (config: ^common.Config, writer: ^Writer) -> bool {
- temp_requests := make([dynamic]Request, 0, context.temp_allocator);
+ temp_requests := make([dynamic]Request, 0, context.temp_allocator)
- sync.mutex_lock(&requests_mutex);
+ sync.mutex_lock(&requests_mutex)
for d in deletings {
- delete_index := -1;
+ delete_index := -1
for request, i in requests {
if request.id == d.id {
- delete_index := i;
- break;
+ delete_index := i
+ break
}
}
if delete_index != -1 {
- cancel(requests[delete_index].value, requests[delete_index].id, writer, config);
- ordered_remove(&requests, delete_index);
+ cancel(requests[delete_index].value, requests[delete_index].id, writer, config)
+ ordered_remove(&requests, delete_index)
}
}
for request in requests {
- append(&temp_requests, request);
+ append(&temp_requests, request)
}
- sync.mutex_unlock(&requests_mutex);
+ sync.mutex_unlock(&requests_mutex)
- request_index := 0;
+ request_index := 0
for ; request_index < len(temp_requests); request_index += 1 {
- request := temp_requests[request_index];
- call(request.value, request.id, writer, config);
+ request := temp_requests[request_index]
+ call(request.value, request.id, writer, config)
}
- sync.mutex_lock(&requests_mutex);
+ sync.mutex_lock(&requests_mutex)
for i := 0; i < request_index; i += 1 {
- pop_front(&requests);
+ pop_front(&requests)
}
- sync.mutex_unlock(&requests_mutex);
+ sync.mutex_unlock(&requests_mutex)
if request_index != len(temp_requests) {
- sync.semaphore_post(&requests_sempahore);
+ sync.semaphore_post(&requests_sempahore)
}
- sync.semaphore_wait_for(&requests_sempahore);
+ sync.semaphore_wait_for(&requests_sempahore)
- return true;
+ return true
}
@@ -324,47 +324,47 @@ cancel :: proc(value: json.Value, id: RequestId, writer: ^Writer, config: ^commo
response := make_response_message(
id = id,
params = ResponseParams {},
- );
+ )
- send_response(response, writer);
+ send_response(response, writer)
}
call :: proc(value: json.Value, id: RequestId, writer: ^Writer, config: ^common.Config) {
- root := value.(json.Object);
- method := root["method"].(json.String);
+ root := value.(json.Object)
+ method := root["method"].(json.String)
if fn, ok := call_map[method]; !ok {
- response := make_response_message_error(id = id, error = ResponseError {code = .MethodNotFound, message = ""});
- send_error(response, writer);
+ response := make_response_message_error(id = id, error = ResponseError {code = .MethodNotFound, message = ""})
+ send_error(response, writer)
} else {
- err := fn(root["params"], id, config, writer);
+ err := fn(root["params"], id, config, writer)
if err != .None {
response := make_response_message_error(
id = id,
error = ResponseError {code = err, message = ""},
- );
- send_error(response, writer);
+ )
+ send_error(response, writer)
}
}
}
request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- initialize_params: RequestInitializeParams;
+ initialize_params: RequestInitializeParams
if unmarshal(params, initialize_params, context.temp_allocator) != .None {
- return .ParseError;
+ return .ParseError
}
- config.workspace_folders = make([dynamic]common.WorkspaceFolder);
+ config.workspace_folders = make([dynamic]common.WorkspaceFolder)
for s in initialize_params.workspaceFolders {
- append(&config.workspace_folders, s);
+ append(&config.workspace_folders, s)
}
read_ols_config :: proc(file: string, config: ^common.Config, uri: common.Uri) {
@@ -381,111 +381,111 @@ request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.C
if unmarshal(value, ols_config, context.temp_allocator) == .None {
- config.thread_count = ols_config.thread_pool_count;
- config.enable_document_symbols = ols_config.enable_document_symbols;
- config.enable_hover = ols_config.enable_hover;
+ config.thread_count = ols_config.thread_pool_count
+ config.enable_document_symbols = ols_config.enable_document_symbols
+ config.enable_hover = ols_config.enable_hover
config.enable_format = true // ols_config.enable_format;
- 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.verbose = ols_config.verbose;
- config.file_log = ols_config.file_log;
- config.formatter = ols_config.formatter;
- config.odin_command = strings.clone(ols_config.odin_command, context.allocator);
- config.checker_args = ols_config.checker_args;
- config.enable_inlay_hints = ols_config.enable_inlay_hints;
+ 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.verbose = ols_config.verbose
+ config.file_log = ols_config.file_log
+ config.formatter = ols_config.formatter
+ config.odin_command = strings.clone(ols_config.odin_command, context.allocator)
+ config.checker_args = ols_config.checker_args
+ config.enable_inlay_hints = ols_config.enable_inlay_hints
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)
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)
}
}
if ok := "" in config.collections; !ok {
- config.collections[""] = strings.clone(uri.path);
+ config.collections[""] = strings.clone(uri.path)
}
} else {
- log.errorf("Failed to unmarshal %v", file);
+ log.errorf("Failed to unmarshal %v", file)
}
} else {
- log.errorf("Failed to parse json %v", file);
+ log.errorf("Failed to parse json %v", file)
}
} else {
- log.errorf("Failed to read/find %v", file);
+ log.errorf("Failed to read/find %v", file)
}
}
- project_uri := "";
+ project_uri := ""
if len(config.workspace_folders) > 0 {
- project_uri = config.workspace_folders[0].uri;
+ project_uri = config.workspace_folders[0].uri
} else if initialize_params.rootUri != "" {
- project_uri = initialize_params.rootUri;
+ project_uri = initialize_params.rootUri
}
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);
- read_ols_config(ols_config_path, config, uri);
+ ols_config_path := path.join(elems = {uri.path, "ols.json"}, allocator = context.temp_allocator)
+ read_ols_config(ols_config_path, config, uri)
}
- when ODIN_OS == "windows" {
- odin_core_env := os.get_env("ODIN_ROOT", context.temp_allocator);
+ when ODIN_OS == .Windows {
+ odin_core_env := os.get_env("ODIN_ROOT", context.temp_allocator)
} else {
- odin_core_env, _ := os.getenv("ODIN_ROOT");
+ odin_core_env, _ := os.getenv("ODIN_ROOT")
}
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)
}
for format in initialize_params.capabilities.textDocument.hover.contentFormat {
if format == "markdown" {
- config.hover_support_md = true;
+ config.hover_support_md = true
}
}
for format in initialize_params.capabilities.textDocument.completion.documentationFormat {
if format == "markdown" {
- config.completion_support_md = true;
+ config.completion_support_md = true
}
}
- 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" {
- token_types[i] = "enumMember";
+ token_types[i] = "enumMember"
}
else {
- token_types[i] = strings.to_lower(name, context.temp_allocator);
+ token_types[i] = strings.to_lower(name, context.temp_allocator)
}
}
for name, i in token_modifier.names {
- token_modifiers[i] = strings.to_lower(name, context.temp_allocator);
+ token_modifiers[i] = strings.to_lower(name, context.temp_allocator)
}
response := make_response_message(
@@ -523,335 +523,335 @@ request_initialize :: proc (params: json.Value, id: RequestId, config: ^common.C
resolveProvider = false,
},
},
- }, id = id);
+ }, id = id)
- send_response(response, writer);
+ send_response(response, writer)
/*
Temp index here, but should be some background thread that starts the indexing
*/
- index.indexer.dynamic_index = index.make_memory_index(index.make_symbol_collection(context.allocator, config));
+ index.indexer.dynamic_index = index.make_memory_index(index.make_symbol_collection(context.allocator, config))
- index.build_static_index(context.allocator, config);
+ index.build_static_index(context.allocator, config)
/*
Add runtime package
*/
if core, ok := config.collections["core"]; ok {
- when ODIN_OS == "windows" {
- append(&index.indexer.builtin_packages, path.join(strings.to_lower(core, context.temp_allocator), "runtime"));
+ when ODIN_OS == .Windows {
+ append(&index.indexer.builtin_packages, path.join(strings.to_lower(core, context.temp_allocator), "runtime"))
} else {
- append(&index.indexer.builtin_packages, path.join(core, "runtime"));
+ append(&index.indexer.builtin_packages, path.join(core, "runtime"))
}
}
- log.info("Finished indexing");
+ log.info("Finished indexing")
- return .None;
+ return .None
}
request_initialized :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- return .None;
+ return .None
}
request_shutdown :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- response := make_response_message(params = nil, id = id);
+ response := make_response_message(params = nil, id = id)
- send_response(response, writer);
+ send_response(response, writer)
- return .None;
+ return .None
}
request_definition :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- definition_params: TextDocumentPositionParams;
+ definition_params: TextDocumentPositionParams
if unmarshal(params, definition_params, context.temp_allocator) != .None {
- return .ParseError;
+ return .ParseError
}
- document := document_get(definition_params.textDocument.uri);
+ document := document_get(definition_params.textDocument.uri)
if document == nil {
- return .InternalError;
+ 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");
+ log.warn("Failed to get definition location")
}
if len(locations) == 1 {
- response := make_response_message(params = locations[0], id = id);
- send_response(response, writer);
+ response := make_response_message(params = locations[0], id = id)
+ send_response(response, writer)
} else {
- response := make_response_message(params = locations, id = id);
- send_response(response, writer);
+ response := make_response_message(params = locations, id = id)
+ send_response(response, writer)
}
- return .None;
+ return .None
}
request_completion :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- completition_params: CompletionParams;
+ completition_params: CompletionParams
if unmarshal(params, completition_params, context.temp_allocator) != .None {
- log.error("Failed to unmarshal completion request");
- return .ParseError;
+ log.error("Failed to unmarshal completion request")
+ return .ParseError
}
- document := document_get(completition_params.textDocument.uri);
+ document := document_get(completition_params.textDocument.uri)
if document == nil {
- return .InternalError;
+ return .InternalError
}
- list: CompletionList;
- list, ok = get_completion_list(document, completition_params.position, completition_params.context_);
+ list: CompletionList
+ list, ok = get_completion_list(document, completition_params.position, completition_params.context_)
if !ok {
- return .InternalError;
+ return .InternalError
}
- response := make_response_message(params = list, id = id);
+ response := make_response_message(params = list, id = id)
- send_response(response, writer);
+ send_response(response, writer)
- return .None;
+ return .None
}
request_signature_help :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- signature_params: SignatureHelpParams;
+ signature_params: SignatureHelpParams
if unmarshal(params, signature_params, context.temp_allocator) != .None {
- return .ParseError;
+ return .ParseError
}
- document := document_get(signature_params.textDocument.uri);
+ document := document_get(signature_params.textDocument.uri)
if document == nil {
- return .InternalError;
+ return .InternalError
}
- help: SignatureHelp;
- help, ok = get_signature_information(document, signature_params.position);
+ help: SignatureHelp
+ help, ok = get_signature_information(document, signature_params.position)
if !ok {
- return .InternalError;
+ return .InternalError
}
- response := make_response_message(params = help, id = id);
+ response := make_response_message(params = help, id = id)
- send_response(response, writer);
+ send_response(response, writer)
- return .None;
+ return .None
}
request_format_document :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- format_params: DocumentFormattingParams;
+ format_params: DocumentFormattingParams
if unmarshal(params, format_params, context.temp_allocator) != .None {
- return .ParseError;
+ return .ParseError
}
- document := document_get(format_params.textDocument.uri);
+ document := document_get(format_params.textDocument.uri)
if document == nil {
- return .InternalError;
+ return .InternalError
}
- edit: []TextEdit;
- edit, ok = get_complete_format(document, config);
+ edit: []TextEdit
+ edit, ok = get_complete_format(document, config)
if !ok {
- return .InternalError;
+ return .InternalError
}
- response := make_response_message(params = edit, id = id);
+ response := make_response_message(params = edit, id = id)
- send_response(response, writer);
+ send_response(response, writer)
- return .None;
+ return .None
}
notification_exit :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- config.running = false;
- return .None;
+ config.running = false
+ return .None
}
notification_did_open :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- log.error("Failed to parse open document notification");
- return .ParseError;
+ log.error("Failed to parse open document notification")
+ return .ParseError
}
- open_params: DidOpenTextDocumentParams;
+ open_params: DidOpenTextDocumentParams
if unmarshal(params, open_params, context.allocator) != .None {
- log.error("Failed to parse open document notification");
- return .ParseError;
+ log.error("Failed to parse open document notification")
+ return .ParseError
}
if n := document_open(open_params.textDocument.uri, open_params.textDocument.text, config, writer); n != .None {
- return .InternalError;
+ return .InternalError
}
- return .None;
+ return .None
}
notification_did_change :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- change_params: DidChangeTextDocumentParams;
+ change_params: DidChangeTextDocumentParams
if unmarshal(params, change_params, context.temp_allocator) != .None {
- return .ParseError;
+ return .ParseError
}
- document_apply_changes(change_params.textDocument.uri, change_params.contentChanges, config, writer);
+ document_apply_changes(change_params.textDocument.uri, change_params.contentChanges, config, writer)
- return .None;
+ return .None
}
notification_did_close :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- close_params: DidCloseTextDocumentParams;
+ close_params: DidCloseTextDocumentParams
if unmarshal(params, close_params, context.temp_allocator) != .None {
- return .ParseError;
+ return .ParseError
}
if n := document_close(close_params.textDocument.uri); n != .None {
- return .InternalError;
+ return .InternalError
}
- return .None;
+ return .None
}
notification_did_save :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- save_params: DidSaveTextDocumentParams;
+ save_params: DidSaveTextDocumentParams
if unmarshal(params, save_params, context.temp_allocator) != .None {
- return .ParseError;
+ return .ParseError
}
- uri: common.Uri;
+ uri: common.Uri
if uri, ok = common.parse_uri(save_params.textDocument.uri, context.temp_allocator); !ok {
- return .ParseError;
+ return .ParseError
}
- fullpath := uri.path;
+ fullpath := uri.path
p := parser.Parser {
err = index.log_error_handler,
warn = index.log_warning_handler,
- };
+ }
- dir := filepath.base(filepath.dir(fullpath, context.temp_allocator));
+ dir := filepath.base(filepath.dir(fullpath, context.temp_allocator))
- pkg := new(ast.Package);
- pkg.kind = .Normal;
- pkg.fullpath = fullpath;
- pkg.name = dir;
+ pkg := new(ast.Package)
+ pkg.kind = .Normal
+ pkg.fullpath = fullpath
+ pkg.name = dir
if dir == "runtime" {
- pkg.kind = .Runtime;
+ pkg.kind = .Runtime
}
file := ast.File {
fullpath = fullpath,
src = save_params.text,
pkg = pkg,
- };
+ }
- ok = parser.parse_file(&p, &file);
+ ok = parser.parse_file(&p, &file)
if !ok {
- log.errorf("error in parse file for indexing %v", fullpath);
+ log.errorf("error in parse file for indexing %v", fullpath)
}
for key, value in index.indexer.dynamic_index.collection.symbols {
- when ODIN_OS == "windows"{
- uri := strings.to_lower(save_params.textDocument.uri, context.temp_allocator);
+ when ODIN_OS == .Windows {
+ uri := strings.to_lower(save_params.textDocument.uri, context.temp_allocator)
} else {
- uri := save_params.textDocument.uri;
+ uri := save_params.textDocument.uri
}
if value.uri == uri {
- index.free_symbol(value, context.allocator);
- index.indexer.dynamic_index.collection.symbols[key] = {};
+ index.free_symbol(value, context.allocator)
+ index.indexer.dynamic_index.collection.symbols[key] = {}
}
}
if ret := index.collect_symbols(&index.indexer.dynamic_index.collection, file, uri.uri); ret != .None {
- log.errorf("failed to collect symbols on save %v", ret);
+ log.errorf("failed to collect symbols on save %v", ret)
}
- check(uri, writer, config);
+ check(uri, writer, config)
- return .None;
+ return .None
}
request_semantic_token_full :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- semantic_params: SemanticTokensParams;
+ semantic_params: SemanticTokensParams
if unmarshal(params, semantic_params, context.temp_allocator) != .None {
- return .ParseError;
+ return .ParseError
}
- document := document_get(semantic_params.textDocument.uri);
+ document := document_get(semantic_params.textDocument.uri)
if document == nil {
- return .InternalError;
+ return .InternalError
}
range := common.Range {
@@ -861,184 +861,184 @@ request_semantic_token_full :: proc (params: json.Value, id: RequestId, config:
end = common.Position {
line = 9000000, //should be enough
},
- };
+ }
- symbols: SemanticTokens;
+ symbols: SemanticTokens
if config.enable_semantic_tokens {
if cache_symbols, ok := file_resolve_cache.files[document.uri.uri]; ok {
- symbols = get_semantic_tokens(document, range, cache_symbols);
+ symbols = get_semantic_tokens(document, range, cache_symbols)
}
}
- response := make_response_message(params = symbols, id = id);
+ response := make_response_message(params = symbols, id = id)
- send_response(response, writer);
+ send_response(response, writer)
- return .None;
+ return .None
}
request_semantic_token_range :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .None;
+ return .None
}
- semantic_params: SemanticTokensRangeParams;
+ semantic_params: SemanticTokensRangeParams
if unmarshal(params, semantic_params, context.temp_allocator) != .None {
- return .None;
+ return .None
}
- document := document_get(semantic_params.textDocument.uri);
+ document := document_get(semantic_params.textDocument.uri)
if document == nil {
- return .InternalError;
+ return .InternalError
}
- symbols: SemanticTokens;
+ symbols: SemanticTokens
if config.enable_semantic_tokens {
if cache_symbols, ok := file_resolve_cache.files[document.uri.uri]; ok {
- symbols = get_semantic_tokens(document, semantic_params.range, cache_symbols);
+ symbols = get_semantic_tokens(document, semantic_params.range, cache_symbols)
}
}
- response := make_response_message(params = symbols, id = id);
+ response := make_response_message(params = symbols, id = id)
- send_response(response, writer);
+ send_response(response, writer)
- return .None;
+ return .None
}
request_document_symbols :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- symbol_params: DocumentSymbolParams;
+ symbol_params: DocumentSymbolParams
if unmarshal(params, symbol_params, context.temp_allocator) != .None {
- return .ParseError;
+ return .ParseError
}
- document := document_get(symbol_params.textDocument.uri);
+ document := document_get(symbol_params.textDocument.uri)
if document == nil {
- return .InternalError;
+ return .InternalError
}
- symbols := get_document_symbols(document);
+ symbols := get_document_symbols(document)
- response := make_response_message(params = symbols, id = id);
+ response := make_response_message(params = symbols, id = id)
- send_response(response, writer);
+ send_response(response, writer)
- return .None;
+ return .None
}
request_hover :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- hover_params: HoverParams;
+ hover_params: HoverParams
if unmarshal(params, hover_params, context.temp_allocator) != .None {
- return .ParseError;
+ return .ParseError
}
- document := document_get(hover_params.textDocument.uri);
+ document := document_get(hover_params.textDocument.uri)
if document == nil {
- return .InternalError;
+ return .InternalError
}
- hover: Hover;
- hover, ok = get_hover_information(document, hover_params.position);
+ hover: Hover
+ hover, ok = get_hover_information(document, hover_params.position)
if !ok {
- return .InternalError;
+ return .InternalError
}
- response := make_response_message(params = hover, id = id);
+ response := make_response_message(params = hover, id = id)
- send_response(response, writer);
+ send_response(response, writer)
- return .None;
+ return .None
}
request_inlay_hint :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- inlay_params: InlayParams;
+ inlay_params: InlayParams
if unmarshal(params, inlay_params, context.temp_allocator) != .None {
- return .ParseError;
+ return .ParseError
}
- document := document_get(inlay_params.textDocument.uri);
+ document := document_get(inlay_params.textDocument.uri)
if document == nil {
- return .InternalError;
+ return .InternalError
}
- hints: []InlayHint;
+ hints: []InlayHint
if cache_symbols, ok := file_resolve_cache.files[document.uri.uri]; ok {
- hints, ok = get_inlay_hints(document, cache_symbols);
+ hints, ok = get_inlay_hints(document, cache_symbols)
}
if !ok {
- return .InternalError;
+ return .InternalError
}
- response := make_response_message(params = hints, id = id);
+ response := make_response_message(params = hints, id = id)
- send_response(response, writer);
+ send_response(response, writer)
- return .None;
+ return .None
}
request_document_links :: proc (params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
- params_object, ok := params.(json.Object);
+ params_object, ok := params.(json.Object)
if !ok {
- return .ParseError;
+ return .ParseError
}
- link_params: DocumentLinkParams;
+ link_params: DocumentLinkParams
if unmarshal(params, link_params, context.temp_allocator) != .None {
- return .ParseError;
+ return .ParseError
}
- document := document_get(link_params.textDocument.uri);
+ document := document_get(link_params.textDocument.uri)
if document == nil {
- return .InternalError;
+ return .InternalError
}
- links: []DocumentLink;
+ links: []DocumentLink
- links, ok = get_document_links(document);
+ links, ok = get_document_links(document)
if !ok {
- return .InternalError;
+ return .InternalError
}
- response := make_response_message(params = links, id = id);
+ response := make_response_message(params = links, id = id)
- send_response(response, writer);
+ send_response(response, writer)
- return .None;
+ return .None
} \ No newline at end of file
diff --git a/src/server/response.odin b/src/server/response.odin
index c132532..7c07f41 100644
--- a/src/server/response.odin
+++ b/src/server/response.odin
@@ -5,63 +5,63 @@ import "core:encoding/json"
send_notification :: proc (notification: Notification, writer: ^Writer) -> bool {
- data, error := json.marshal(notification, context.temp_allocator);
+ data, error := json.marshal(notification, context.temp_allocator)
- header := fmt.tprintf("Content-Length: %v\r\n\r\n", len(data));
+ header := fmt.tprintf("Content-Length: %v\r\n\r\n", len(data))
if error != .None {
- return false;
+ return false
}
if !write_sized(writer, transmute([]u8)header) {
- return false;
+ return false
}
if !write_sized(writer, data) {
- return false;
+ return false
}
- return true;
+ return true
}
send_response :: proc (response: ResponseMessage, writer: ^Writer) -> bool {
- data, error := json.marshal(response, context.temp_allocator);
+ data, error := json.marshal(response, context.temp_allocator)
- header := fmt.tprintf("Content-Length: %v\r\n\r\n", len(data));
+ header := fmt.tprintf("Content-Length: %v\r\n\r\n", len(data))
if error != .None {
- return false;
+ return false
}
if !write_sized(writer, transmute([]u8)header) {
- return false;
+ return false
}
if !write_sized(writer, data) {
- return false;
+ return false
}
- return true;
+ return true
}
send_error :: proc (response: ResponseMessageError, writer: ^Writer) -> bool {
- data, error := json.marshal(response, context.temp_allocator);
+ data, error := json.marshal(response, context.temp_allocator)
- header := fmt.tprintf("Content-Length: %v\r\n\r\n", len(data));
+ header := fmt.tprintf("Content-Length: %v\r\n\r\n", len(data))
if error != .None {
- return false;
+ return false
}
if !write_sized(writer, transmute([]u8)header) {
- return false;
+ return false
}
if !write_sized(writer, data) {
- return false;
+ return false
}
- return true;
+ return true
}
diff --git a/src/server/semantic_tokens.odin b/src/server/semantic_tokens.odin
index c0a117f..bd89bb3 100644
--- a/src/server/semantic_tokens.odin
+++ b/src/server/semantic_tokens.odin
@@ -85,56 +85,56 @@ SemanticTokenBuilder :: struct {
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[:],
- };
+ }
}
get_semantic_tokens :: proc(document: ^common.Document, range: common.Range, symbols: map[uintptr]index.Symbol) -> SemanticTokens {
- using analysis;
+ using analysis
- builder := make_token_builder();
+ 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);
+ ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri)
- builder.symbols = symbols;
+ builder.symbols = symbols
- ast_context.current_package = ast_context.document_package;
+ 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 {
- visit(decl, &builder, &ast_context);
+ visit(decl, &builder, &ast_context)
}
}
- return get_tokens(builder);
+ 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);
- 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);
- builder.current_start = node.pos.offset;
+ 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)
+ 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);
- builder.current_start = token.pos.offset;
+ 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);
- builder.current_start = pos.offset;
+ 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
}
visit :: proc {
@@ -142,207 +142,207 @@ visit :: proc {
visit_dynamic_array,
visit_array,
visit_stmt,
-};
+}
visit_array :: proc(array: $A/[]^$T, builder: ^SemanticTokenBuilder, ast_context: ^analysis.AstContext) {
for elem, i in array {
- visit(elem, builder, ast_context);
+ visit(elem, builder, ast_context)
}
}
visit_dynamic_array :: proc(array: $A/[dynamic]^$T, builder: ^SemanticTokenBuilder, ast_context: ^analysis.AstContext) {
for elem, i in array {
- visit(elem, builder, ast_context);
+ visit(elem, builder, ast_context)
}
}
visit_stmt :: proc(node: ^ast.Stmt, builder: ^SemanticTokenBuilder, ast_context: ^analysis.AstContext) {
- visit_node(node, builder, ast_context);
+ visit_node(node, builder, ast_context)
}
visit_node :: proc(node: ^ast.Node, builder: ^SemanticTokenBuilder, ast_context: ^analysis.AstContext) {
- using ast;
+ using ast
if node == nil {
- return;
+ return
}
- switch n in node.derived {
- case Ellipsis:
- write_semantic_string(builder, node.pos, "..", ast_context.file.src, .Operator, .None);
- visit(n.expr, builder, ast_context);
- case Ident:
+ #partial switch n in node.derived {
+ case ^Ellipsis:
+ write_semantic_string(builder, node.pos, "..", ast_context.file.src, .Operator, .None)
+ visit(n.expr, builder, ast_context)
+ case ^Ident:
if symbol, ok := builder.symbols[cast(uintptr)node]; ok {
if symbol.type == .Variable {
- write_semantic_node(builder, node, ast_context.file.src, .Variable, .None);
- return;
+ write_semantic_node(builder, node, ast_context.file.src, .Variable, .None)
+ return
}
#partial switch v in symbol.value {
case index.SymbolPackageValue:
- write_semantic_node(builder, node, ast_context.file.src, .Namespace, .None);
+ write_semantic_node(builder, node, ast_context.file.src, .Namespace, .None)
case index.SymbolStructValue:
- write_semantic_node(builder, node, ast_context.file.src, .Struct, .None);
+ write_semantic_node(builder, node, ast_context.file.src, .Struct, .None)
case index.SymbolEnumValue:
- write_semantic_node(builder, node, ast_context.file.src, .Enum, .None);
+ write_semantic_node(builder, node, ast_context.file.src, .Enum, .None)
case index.SymbolUnionValue:
- write_semantic_node(builder, node, ast_context.file.src, .Enum, .None);
+ write_semantic_node(builder, node, ast_context.file.src, .Enum, .None)
case index.SymbolProcedureValue:
- write_semantic_node(builder, node, ast_context.file.src, .Function, .None);
+ write_semantic_node(builder, node, ast_context.file.src, .Function, .None)
case index.SymbolProcedureGroupValue:
- write_semantic_node(builder, node, ast_context.file.src, .Function, .None);
+ write_semantic_node(builder, node, ast_context.file.src, .Function, .None)
case index.SymbolUntypedValue:
- write_semantic_node(builder, node, ast_context.file.src, .Type, .None);
+ write_semantic_node(builder, node, ast_context.file.src, .Type, .None)
case index.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));
}
}
- 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);
- 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);
- visit(n.elem, builder, ast_context);
- case Value_Decl:
- visit_value_decl(n, builder, ast_context);
- case Block_Stmt:
- visit(n.stmts, builder, ast_context);
- case Expr_Stmt:
- visit(n.expr, builder, ast_context);
- case Branch_Stmt:
- write_semantic_token(builder, n.tok, ast_context.file.src, .Type, .None);
- case Poly_Type:
- 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);
+ 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)
+ 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)
+ visit(n.elem, builder, ast_context)
+ case ^Value_Decl:
+ visit_value_decl(n^, builder, ast_context)
+ case ^Block_Stmt:
+ visit(n.stmts, builder, ast_context)
+ case ^Expr_Stmt:
+ visit(n.expr, builder, ast_context)
+ case ^Branch_Stmt:
+ write_semantic_token(builder, n.tok, ast_context.file.src, .Type, .None)
+ case ^Poly_Type:
+ 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)
for val in n.vals {
- if ident, ok := val.derived.(Ident); ok {
- write_semantic_node(builder, val, ast_context.file.src, .Variable, .None);
+ if ident, ok := val.derived.(^Ident); ok {
+ 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);
- 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);
- visit(n.init, builder, ast_context);
- visit(n.cond, builder, ast_context);
- visit(n.body, builder, ast_context);
+ 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)
+ 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);
- visit(n.else_stmt, builder, ast_context);
+ 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);
- 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);
- 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);
- visit(n.tag, builder, ast_context);
- visit(n.expr, builder, ast_context);
- visit(n.body, builder, ast_context);
- case Assign_Stmt:
+ case ^For_Stmt:
+ 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)
+ 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)
+ 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);
+ if ident, ok := l.derived.(^Ident); ok {
+ write_semantic_node(builder, l, ast_context.file.src, .Variable, .None)
} else {
- visit(l, builder, ast_context);
+ visit(l, builder, 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);
- 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);
- case Array_Type:
- visit(n.elem, builder, ast_context);
- case Binary_Expr:
- visit(n.left, builder, ast_context);
- visit_token_op(builder, n.op, ast_context.file.src);
- visit(n.right, builder, ast_context);
- case Comp_Lit:
- 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);
- 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);
- visit(n.type, builder, ast_context);
- visit(n.expr, builder, ast_context);
- case Paren_Expr:
- visit(n.expr, builder, 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);
- visit(n.results, builder, ast_context);
- case Dynamic_Array_Type:
- write_semantic_string(builder, n.dynamic_pos, "dynamic", 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);
+ 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)
+ 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)
+ case ^Array_Type:
+ visit(n.elem, builder, ast_context)
+ case ^Binary_Expr:
+ visit(n.left, builder, ast_context)
+ visit_token_op(builder, n.op, ast_context.file.src)
+ visit(n.right, builder, ast_context)
+ case ^Comp_Lit:
+ 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)
+ 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)
+ visit(n.type, builder, ast_context)
+ visit(n.expr, builder, ast_context)
+ case ^Paren_Expr:
+ visit(n.expr, builder, 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)
+ visit(n.results, builder, ast_context)
+ case ^Dynamic_Array_Type:
+ write_semantic_string(builder, n.dynamic_pos, "dynamic", 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)
}
- visit(n.value, builder, ast_context);
- case Index_Expr:
- visit(n.expr, builder, ast_context);
- visit(n.index, builder, ast_context);
- case Basic_Lit:
- visit_basic_lit(n, builder, ast_context);
- case Unary_Expr:
- visit(n.expr, builder, ast_context);
- case Implicit:
- 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);
- visit(n.list, builder, ast_context);
- case Map_Type:
- 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);
- visit(n.stmt, builder, ast_context);
- case Import_Decl:
- write_semantic_token(builder, n.import_tok, ast_context.file.src, .Keyword, .None);
+ visit(n.value, builder, ast_context)
+ case ^Index_Expr:
+ visit(n.expr, builder, ast_context)
+ visit(n.index, builder, ast_context)
+ case ^Basic_Lit:
+ visit_basic_lit(n^, builder, ast_context)
+ case ^Unary_Expr:
+ visit(n.expr, builder, ast_context)
+ case ^Implicit:
+ 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)
+ visit(n.list, builder, ast_context)
+ case ^Map_Type:
+ 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)
+ visit(n.stmt, builder, ast_context)
+ case ^Import_Decl:
+ 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:
//log.errorf("unhandled semantic token node %v", n);
//panic(fmt.tprintf("Missed semantic token handling %v", n));
@@ -350,179 +350,179 @@ visit_node :: proc(node: ^ast.Node, builder: ^SemanticTokenBuilder, ast_context:
}
visit_basic_lit :: proc(basic_lit: ast.Basic_Lit, builder: ^SemanticTokenBuilder, ast_context: ^analysis.AstContext) {
- using analysis;
+ using analysis
if symbol, ok := resolve_basic_lit(ast_context, basic_lit); ok {
if untyped, ok := symbol.value.(index.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: ^analysis.AstContext) {
- using ast;
+ 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);
+ visit(value_decl.type, builder, ast_context)
- return;
+ return
}
if len(value_decl.values) == 1 {
- 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);
- 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);
- 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);
- 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);
+ #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)
+ 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)
+ 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)
+ 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)
for arg in v.args {
- if ident, ok := arg.derived.(Ident); ok {
- write_semantic_node(builder, arg, ast_context.file.src, .Function, .None);
+ if ident, ok := arg.derived.(^Ident); ok {
+ 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);
- visit_proc_type(v.type, builder, ast_context);
+ 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)
+ visit_proc_type(v.type, builder, ast_context)
- visit(v.body, 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);
+ 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 {
- visit(value, builder, ast_context);
+ visit(value, builder, ast_context)
}
}
}
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: ^analysis.AstContext) {
- using ast;
+ using ast
if node == nil {
- return;
+ return
}
if node.params != nil {
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);
+ if ident, ok := name.derived.(^Ident); ok {
+ write_semantic_node(builder, name, ast_context.file.src, .Parameter, .None)
}
}
- visit(param.type, builder, ast_context);
+ visit(param.type, builder, ast_context)
}
}
if node.results != nil {
for result in node.results.list {
- visit(result.names, builder, ast_context);
- visit(result.type, builder, ast_context);
+ visit(result.names, builder, ast_context)
+ visit(result.type, builder, ast_context)
}
}
}
visit_enum_fields :: proc(node: ast.Enum_Type, builder: ^SemanticTokenBuilder, ast_context: ^analysis.AstContext) {
- using ast;
+ using ast
if node.fields == nil {
- return;
+ return
}
for field in node.fields {
- if ident, ok := field.derived.(Ident); ok {
- write_semantic_node(builder, field, ast_context.file.src, .EnumMember, .None);
+ 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 {
- if _, ok := f.field.derived.(Ident); ok {
- write_semantic_node(builder, f.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)
}
- visit(f.value, builder, ast_context);
+ visit(f.value, builder, ast_context)
}
}
}
visit_struct_fields :: proc(node: ast.Struct_Type, builder: ^SemanticTokenBuilder, ast_context: ^analysis.AstContext) {
- using ast;
+ using ast
if node.fields == nil {
- return;
+ return
}
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);
+ if ident, ok := name.derived.(^Ident); ok {
+ write_semantic_node(builder, name, ast_context.file.src, .Property, .None)
}
}
- visit(field.type, builder, ast_context);
+ visit(field.type, builder, ast_context)
}
}
visit_selector :: proc(selector: ^ast.Selector_Expr, builder: ^SemanticTokenBuilder, ast_context: ^analysis.AstContext) {
- if _, ok := selector.expr.derived.(ast.Selector_Expr); ok {
- visit_selector(cast(^ast.Selector_Expr)selector.expr, builder, ast_context);
+ if _, ok := selector.expr.derived.(^ast.Selector_Expr); ok {
+ visit_selector(cast(^ast.Selector_Expr)selector.expr, builder, ast_context)
} else {
- visit(selector.expr, builder, ast_context);
- builder.selector = true;
+ visit(selector.expr, builder, ast_context)
+ builder.selector = true
}
if symbol, ok := builder.symbols[cast(uintptr)selector]; ok {
if symbol.type == .Variable {
- write_semantic_node(builder, selector.field, ast_context.file.src, .Method, .None);
+ write_semantic_node(builder, selector.field, ast_context.file.src, .Method, .None)
}
#partial switch v in symbol.value {
case index.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 index.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 index.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 index.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 index.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 index.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 d187336..e8b3ae1 100644
--- a/src/server/signature.odin
+++ b/src/server/signature.odin
@@ -54,165 +54,165 @@ ParameterInformation :: struct {
*/
build_procedure_symbol_signature :: proc(symbol: ^index.Symbol) {
if value, ok := symbol.value.(index.SymbolProcedureValue); ok {
- builder := strings.make_builder(context.temp_allocator);
+ builder := strings.make_builder(context.temp_allocator)
- strings.write_string(&builder, "proc");
- strings.write_string(&builder, "(");
+ strings.write_string(&builder, "proc")
+ strings.write_string(&builder, "(")
for arg, i in value.arg_types {
- strings.write_string(&builder, common.node_to_string(arg));
+ strings.write_string(&builder, common.node_to_string(arg))
if i != len(value.arg_types) - 1 {
- strings.write_string(&builder, ", ");
+ strings.write_string(&builder, ", ")
}
}
- strings.write_string(&builder, ")");
+ strings.write_string(&builder, ")")
if len(value.return_types) != 0 {
- strings.write_string(&builder, " -> ");
+ strings.write_string(&builder, " -> ")
if len(value.return_types) > 1 {
- strings.write_string(&builder, "(");
+ strings.write_string(&builder, "(")
}
for arg, i in value.return_types {
- strings.write_string(&builder, common.node_to_string(arg));
+ strings.write_string(&builder, common.node_to_string(arg))
if i != len(value.return_types) - 1 {
- strings.write_string(&builder, ", ");
+ strings.write_string(&builder, ", ")
}
}
if len(value.return_types) > 1 {
- strings.write_string(&builder, ")");
+ strings.write_string(&builder, ")")
}
}
- symbol.signature = strings.to_string(builder);
+ symbol.signature = strings.to_string(builder)
} else if value, ok := symbol.value.(index.SymbolAggregateValue); ok {
- symbol.signature = "proc";
+ symbol.signature = "proc"
}
}
seperate_proc_field_arguments :: proc(procedure: ^index.Symbol) {
if value, ok := &procedure.value.(index.SymbolProcedureValue); ok {
- types := make([dynamic]^ast.Field, context.temp_allocator);
+ types := make([dynamic]^ast.Field, context.temp_allocator)
for arg, i in value.arg_types {
if len(arg.names) == 1 {
- append(&types, arg);
- continue;
+ append(&types, arg)
+ continue
}
for name in arg.names {
- field : ^ast.Field = index.new_type(ast.Field, {}, {}, context.temp_allocator);
- field.names = make([]^ast.Expr, 1, context.temp_allocator);
- field.names[0] = name;
- field.type = arg.type;
- append(&types, field);
+ field : ^ast.Field = index.new_type(ast.Field, {}, {}, context.temp_allocator)
+ field.names = make([]^ast.Expr, 1, context.temp_allocator)
+ field.names[0] = name
+ field.type = arg.type
+ append(&types, field)
}
}
- value.arg_types = types[:];
+ value.arg_types = types[:]
}
}
get_signature_information :: proc(document: ^common.Document, position: common.Position) -> (SignatureHelp, bool) {
- using analysis;
+ using analysis
- signature_help: SignatureHelp;
+ signature_help: SignatureHelp
- ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri);
+ ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri)
- 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;
+ return signature_help, true
}
//TODO(should probably not be an ast.Expr, but ast.Call_Expr)
if position_context.call == nil {
- return signature_help, true;
+ return signature_help, true
}
- get_globals(document.ast, &ast_context);
+ 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;
+ signature_help.activeParameter = i
}
}
- call: index.Symbol;
- call, ok = resolve_type_expression(&ast_context, position_context.call);
+ call: index.Symbol
+ 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);
+ 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.(index.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)
}
}
- parameters[i].label = common.node_to_string(arg);
+ parameters[i].label = common.node_to_string(arg)
}
- build_procedure_symbol_signature(&call);
+ build_procedure_symbol_signature(&call)
info := SignatureInformation {
label = concatenate_symbol_information(&ast_context, call, false),
documentation = call.doc,
parameters = parameters,
- };
- append(&signature_information, info);
+ }
+ append(&signature_information, info)
} else if value, ok := call.value.(index.SymbolAggregateValue); ok {
//function overloaded procedures
for symbol in value.symbols {
- symbol := symbol;
+ symbol := symbol
if value, ok := symbol.value.(index.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)
}
}
- parameters[i].label = common.node_to_string(arg);
- parameters[i].activeParameter = i;
+ parameters[i].label = common.node_to_string(arg)
+ parameters[i].activeParameter = i
}
- build_procedure_symbol_signature(&symbol);
+ build_procedure_symbol_signature(&symbol)
info := SignatureInformation {
label = concatenate_symbol_information(&ast_context, symbol, false),
documentation = symbol.doc,
parameters = parameters,
- };
+ }
- append(&signature_information, info);
+ append(&signature_information, info)
}
}
}
- signature_help.signatures = signature_information[:];
+ signature_help.signatures = signature_information[:]
- return signature_help, true;
+ return signature_help, true
} \ No newline at end of file
diff --git a/src/server/unmarshal.odin b/src/server/unmarshal.odin
index 0de3d53..c8a8071 100644
--- a/src/server/unmarshal.odin
+++ b/src/server/unmarshal.odin
@@ -12,33 +12,33 @@ import "core:fmt"
unmarshal :: proc(json_value: json.Value, v: any, allocator: mem.Allocator) -> json.Marshal_Error {
- using runtime;
+ using runtime
if v == nil {
- return .None;
+ return .None
}
if json_value == nil {
- return .None;
+ return .None
}
- type_info := type_info_base(type_info_of(v.id));
+ type_info := type_info_base(type_info_of(v.id))
#partial switch j in json_value {
case json.Object:
#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 != .None {
- return ret;
+ return ret
}
} else {
if ret := unmarshal(j[field], a, allocator); ret != .None {
- return ret;
+ return ret
}
}
@@ -50,59 +50,59 @@ unmarshal :: proc(json_value: json.Value, v: any, allocator: mem.Allocator) -> j
//Note(Daniel, THIS IS REALLY SCUFFED. Need to talk to gingerbill about unmarshalling unions)
//This only works for unions with one object - made to handle optionals
- tag_ptr := uintptr(v.data) + variant.tag_offset;
- tag_any := any {rawptr(tag_ptr), variant.tag_type.id};
+ tag_ptr := uintptr(v.data) + variant.tag_offset
+ tag_any := any {rawptr(tag_ptr), variant.tag_type.id}
- not_optional := 1;
+ 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;
+ 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);
+ 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.allocator = allocator;
+ 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;
+ return .Unsupported_Type
}
for i in 0..<array.len {
- a := any {rawptr(uintptr(array.data) + uintptr(variant.elem_size * i)), variant.elem.id};
+ a := any {rawptr(uintptr(array.data) + uintptr(variant.elem_size * i)), variant.elem.id}
if ret := unmarshal(j[i], a, allocator); ret != .None {
- return ret;
+ return ret
}
}
case:
- return .Unsupported_Type;
+ return .Unsupported_Type
}
case json.String:
#partial switch variant in type_info.variant {
case Type_Info_String:
- str := (^string)(v.data);
- str^ = strings.clone(j, allocator);
+ str := (^string)(v.data)
+ str^ = strings.clone(j, allocator)
case Type_Info_Enum:
for name, i in variant.names {
- lower_name := strings.to_lower(name, allocator);
- lower_j := strings.to_lower(string(j), allocator);
+ lower_name := strings.to_lower(name, 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));
+ mem.copy(v.data, &variant.values[i], size_of(variant.base))
}
- delete(lower_name, allocator);
- delete(lower_j, allocator);
+ delete(lower_name, allocator)
+ delete(lower_j, allocator)
}
}
case json.Integer:
@@ -110,48 +110,48 @@ unmarshal :: proc(json_value: json.Value, v: any, allocator: mem.Allocator) -> j
case Type_Info_Integer:
switch type_info.size {
case 8:
- tmp := i64(j);
- mem.copy(v.data, &tmp, type_info.size);
+ tmp := i64(j)
+ mem.copy(v.data, &tmp, type_info.size)
case 4:
- tmp := i32(j);
- mem.copy(v.data, &tmp, type_info.size);
+ tmp := i32(j)
+ mem.copy(v.data, &tmp, type_info.size)
case 2:
- tmp := i16(j);
- mem.copy(v.data, &tmp, type_info.size);
+ tmp := i16(j)
+ mem.copy(v.data, &tmp, type_info.size)
case 1:
- tmp := i8(j);
- mem.copy(v.data, &tmp, type_info.size);
+ tmp := i8(j)
+ mem.copy(v.data, &tmp, type_info.size)
case:
- return .Unsupported_Type;
+ return .Unsupported_Type
}
case Type_Info_Union:
- tag_ptr := uintptr(v.data) + variant.tag_offset;
+ tag_ptr := uintptr(v.data) + variant.tag_offset
}
case json.Float:
if _, ok := type_info.variant.(Type_Info_Float); ok {
switch type_info.size {
case 8:
- tmp := f64(j);
- mem.copy(v.data, &tmp, type_info.size);
+ tmp := f64(j)
+ mem.copy(v.data, &tmp, type_info.size)
case 4:
- tmp := f32(j);
- mem.copy(v.data, &tmp, type_info.size);
+ tmp := f32(j)
+ mem.copy(v.data, &tmp, type_info.size)
case:
- return .Unsupported_Type;
+ return .Unsupported_Type
}
}
case json.Null:
case json.Boolean:
if _, ok := type_info.variant.(Type_Info_Boolean); ok {
- tmp := bool(j);
- mem.copy(v.data, &tmp, type_info.size);
+ tmp := bool(j)
+ mem.copy(v.data, &tmp, type_info.size)
}
case:
- return .Unsupported_Type;
+ return .Unsupported_Type
}
- return .None;
+ return .None
}
diff --git a/src/server/writer.odin b/src/server/writer.odin
index 46a340e..4918f81 100644
--- a/src/server/writer.odin
+++ b/src/server/writer.odin
@@ -6,7 +6,7 @@ import "core:fmt"
import "core:strings"
import "core:sync"
-WriterFn :: proc(_: rawptr, _: []byte) -> (int, int);
+WriterFn :: proc(_: rawptr, _: []byte) -> (int, int)
Writer :: struct {
writer_fn: WriterFn,
@@ -15,21 +15,21 @@ Writer :: struct {
}
make_writer :: proc(writer_fn: WriterFn, writer_context: rawptr) -> Writer {
- writer := Writer {writer_context = writer_context, writer_fn = writer_fn};
- sync.mutex_init(&writer.writer_mutex);
- return writer;
+ writer := Writer {writer_context = writer_context, writer_fn = writer_fn}
+ sync.mutex_init(&writer.writer_mutex)
+ return writer
}
write_sized :: proc(writer: ^Writer, data: []byte) -> bool {
- sync.mutex_lock(&writer.writer_mutex);
- defer sync.mutex_unlock(&writer.writer_mutex);
+ sync.mutex_lock(&writer.writer_mutex)
+ defer sync.mutex_unlock(&writer.writer_mutex)
- written, err := writer.writer_fn(writer.writer_context, data);
+ written, err := writer.writer_fn(writer.writer_context, data)
if (err != 0) {
- return false;
+ return false
}
- return true;
+ return true
}
diff --git a/src/testing/testing.odin b/src/testing/testing.odin
index 4a40f16..d6c01c8 100644
--- a/src/testing/testing.odin
+++ b/src/testing/testing.odin
@@ -38,7 +38,7 @@ setup :: proc(src: ^Source) {
src.document.allocator = new(common.Scratch_Allocator);
src.document.package_name = "test";
- common.scratch_allocator_init(src.document.allocator, mem.kilobytes(20), context.temp_allocator);
+ common.scratch_allocator_init(src.document.allocator, mem.kilobytes(200), context.temp_allocator);
//no unicode in tests currently
current, last: u8;
@@ -111,7 +111,7 @@ setup :: proc(src: ^Source) {
if !ok || file.syntax_error_count > 0 {
panic("Parser error in test package source");
}
-
+
if ret := index.collect_symbols(&index.indexer.static_index.collection, file, uri.uri); ret != .None {
return;
}
diff --git a/tests/completions_test.odin b/tests/completions_test.odin
index 9933584..c7b0445 100644
--- a/tests/completions_test.odin
+++ b/tests/completions_test.odin
@@ -1288,34 +1288,19 @@ ast_index_proc_parameter_completion :: proc(t: ^testing.T) {
}
@(test)
-ast_implicit_completion_in_comp_lit :: proc(t: ^testing.T) {
+ast_implicit_completion_in_enum_array_comp_lit :: proc(t: ^testing.T) {
source := test.Source {
main = `package main
main :: proc() {
foo :: enum{ one, two }
bar := [foo]int{
.one = 1,
- .*two = 2, // When adding the '.' here
+ .*two = 2,
}
}
`,
};
- test.expect_completion_details(t, &source, ".", {"Not implemented - waiting for test system to work again"});
-}
-
-
-
-
-/*
- Should be the same, but just check after fixing this:
- E :: enum {
- A,
- B,
- C,
- }
-
- x := [E]int {
- .B = 1,
- }
-*/ \ No newline at end of file
+ //TODO(Add proper completion support, but right now it's just to ensure no crashes)
+ test.expect_completion_details(t, &source, ".", {});
+} \ No newline at end of file