aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2021-02-11 19:58:44 +0100
committerDanielGavin <danielgavin5@hotmail.com>2021-02-11 19:58:44 +0100
commit34954ee4c360ff0027713abe5c85606acafef0d7 (patch)
tree43c408094a4d97ecc862b5ac978a145bd2ae1766 /src
parent2c06910cf4e8fc8ce7818aabb8c013be4856ea23 (diff)
add bitsets and bitfields
Diffstat (limited to 'src')
-rw-r--r--src/index/collector.odin59
-rw-r--r--src/index/symbol.odin4
-rw-r--r--src/server/analysis.odin66
-rw-r--r--src/server/completion.odin33
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);
}