diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2021-02-11 19:58:44 +0100 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2021-02-11 19:58:44 +0100 |
| commit | 34954ee4c360ff0027713abe5c85606acafef0d7 (patch) | |
| tree | 43c408094a4d97ecc862b5ac978a145bd2ae1766 /src | |
| parent | 2c06910cf4e8fc8ce7818aabb8c013be4856ea23 (diff) | |
add bitsets and bitfields
Diffstat (limited to 'src')
| -rw-r--r-- | src/index/collector.odin | 59 | ||||
| -rw-r--r-- | src/index/symbol.odin | 4 | ||||
| -rw-r--r-- | src/server/analysis.odin | 66 | ||||
| -rw-r--r-- | src/server/completion.odin | 33 |
4 files changed, 157 insertions, 5 deletions
diff --git a/src/index/collector.odin b/src/index/collector.odin index c9d21f2..52d6ceb 100644 --- a/src/index/collector.odin +++ b/src/index/collector.odin @@ -8,6 +8,7 @@ import "core:fmt" import "core:path/filepath" import "core:path" import "core:log" +import "core:strconv" import "shared:common" @@ -174,6 +175,48 @@ collect_union_fields :: proc(collection: ^SymbolCollection, union_type: ast.Unio return value; } +collect_bitset_field :: proc(collection: ^SymbolCollection, bitset_type: ast.Bit_Set_Type, package_map: map [string] string) -> SymbolBitSetValue { + + value := SymbolBitSetValue { + expr = clone_type(bitset_type.elem, collection.allocator, &collection.unique_strings), + }; + + return value; +} + +collect_bit_fields :: proc(collection: ^SymbolCollection, bitfield_type: ast.Bit_Field_Type, package_map: map [string] string) -> SymbolBitFieldValue { + + names := make([dynamic] string, 0, collection.allocator); + bits := make([dynamic] int, 0, collection.allocator); + + for n in bitfield_type.fields { + + if ident, ok := n.field.derived.(ast.Ident); ok { + append(&names, get_index_unique_string(collection, ident.name)); + } + + if basic_lit, ok := n.value.derived.(ast.Basic_Lit); ok { + + if v, ok := strconv.parse_int(basic_lit.tok.text); ok { + append(&bits, v); + } + + else { + append(&bits, 0); + } + + } + + } + + value := SymbolBitFieldValue { + bits = bits[:], + names = names[:], + }; + + return value; +} + collect_generic :: proc(collection: ^SymbolCollection, expr: ^ast.Expr, package_map: map [string] string) -> SymbolGenericValue { cloned := clone_type(expr, collection.allocator, &collection.unique_strings); @@ -212,6 +255,12 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri } } + if dist, ok := col_expr.derived.(ast.Distinct_Type); ok { + if dist.type != nil { + col_expr = dist.type; + } + } + switch v in col_expr.derived { case ast.Proc_Lit: token = v; @@ -267,9 +316,15 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri 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.Bit_Field_Type: - + token = v; + token_type = .Enum; + symbol.value = collect_bit_fields(collection, v, package_map); + symbol.signature = "bitfield"; case ast.Basic_Lit: token = v; symbol.value = collect_generic(collection, col_expr, package_map); diff --git a/src/index/symbol.odin b/src/index/symbol.odin index a0fab6d..09b1cce 100644 --- a/src/index/symbol.odin +++ b/src/index/symbol.odin @@ -100,7 +100,9 @@ SymbolType :: enum { free_symbol :: proc(symbol: Symbol, allocator: mem.Allocator) { - if symbol.signature != "" && symbol.signature != "struct" && symbol.signature != "union" && symbol.signature != "enum" { + if symbol.signature != "" && symbol.signature != "struct" && + symbol.signature != "union" && symbol.signature != "enum" && + symbol.signature != "bitset" && symbol.signature != "bitfield" { delete(symbol.signature, allocator); } diff --git a/src/server/analysis.odin b/src/server/analysis.odin index f2a5779..fae5aa4 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -836,6 +836,10 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (i return make_symbol_enum_from_ast(ast_context, v, node), true; case Struct_Type: return make_symbol_struct_from_ast(ast_context, v, node), true; + case Bit_Field_Type: + return make_symbol_bitfield_from_ast(ast_context, v, node), true; + case Bit_Set_Type: + return make_symbol_bitset_from_ast(ast_context, v, node), true; case Proc_Lit: if !v.type.generic { return make_symbol_procedure_from_ast(ast_context, v, node.name), true; @@ -870,6 +874,10 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (i return resolve_type_identifier(ast_context, v); case Struct_Type: return make_symbol_struct_from_ast(ast_context, v, node), true; + case Bit_Field_Type: + return make_symbol_bitfield_from_ast(ast_context, v, node), true; + case Bit_Set_Type: + return make_symbol_bitset_from_ast(ast_context, v, node), true; case Union_Type: return make_symbol_union_from_ast(ast_context, v, node), true; case Enum_Type: @@ -1285,6 +1293,62 @@ make_symbol_enum_from_ast :: proc(ast_context: ^AstContext, v: ast.Enum_Type, id return symbol; } +make_symbol_bitfield_from_ast :: proc(ast_context: ^AstContext, bitfield_type: ast.Bit_Field_Type, ident: ast.Ident) -> index.Symbol { + + symbol := index.Symbol { + range = common.get_token_range(bitfield_type, ast_context.file.src), + type = .Enum, + name = ident.name, + pkg = get_package_from_node(bitfield_type.node), + }; + + names := make([dynamic] string, 0, context.temp_allocator); + bits := make([dynamic] int, 0, context.temp_allocator); + + for n in bitfield_type.fields { + + if ident, ok := n.field.derived.(ast.Ident); ok { + append(&names, ident.name); + } + + if basic_lit, ok := n.value.derived.(ast.Basic_Lit); ok { + + if v, ok := strconv.parse_int(basic_lit.tok.text); ok { + append(&bits, v); + } + + else { + append(&bits, 0); + } + + } + + } + + symbol.value = index.SymbolBitFieldValue { + bits = bits[:], + names = names[:], + }; + + return symbol; +} + +make_symbol_bitset_from_ast :: proc(ast_context: ^AstContext, v: ast.Bit_Set_Type, ident: ast.Ident) -> index.Symbol { + + symbol := index.Symbol { + range = common.get_token_range(v, ast_context.file.src), + type = .Enum, + name = ident.name, + pkg = get_package_from_node(v.node), + }; + + symbol.value = index.SymbolBitSetValue { + expr = v.elem, + }; + + return symbol; +} + make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type, ident: ast.Ident) -> index.Symbol { symbol := index.Symbol { @@ -1320,8 +1384,6 @@ make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type usings = usings, }; - log.infof("poly %v", v); - if v.poly_params != nil { resolve_poly_struct(ast_context, v, &symbol); } diff --git a/src/server/completion.odin b/src/server/completion.odin index 026c97d..e1733bf 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -265,12 +265,45 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc #partial switch v in selector.value { + case index.SymbolBitSetValue: + list.isIncomplete = false; + + if elem, ok := resolve_type_expression(ast_context, v.expr); ok { + + if enum_value, ok := elem.value.(index.SymbolEnumValue); ok { + + for name in enum_value.names { + symbol: index.Symbol; + symbol.name = name; + symbol.pkg = selector.name; + symbol.type = .EnumMember; + append(&symbols, symbol); + } + + } + + } + + + case index.SymbolBitFieldValue: + list.isIncomplete = false; + + for name, i in v.names { + symbol: index.Symbol; + symbol.name = name; + symbol.type = .EnumMember; + symbol.signature = fmt.aprint(v.bits[i]); + symbol.pkg = selector.name; + append(&symbols, symbol); + } + case index.SymbolEnumValue: list.isIncomplete = false; for name in v.names { symbol: index.Symbol; symbol.name = name; + symbol.pkg = selector.name; symbol.type = .EnumMember; append(&symbols, symbol); } |