aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2021-03-16 23:55:47 +0100
committerDanielGavin <danielgavin5@hotmail.com>2021-03-16 23:55:47 +0100
commit8b2eef8af0a50f22b06af603fc6e4f09b218f25c (patch)
tree8f40705154be5b5171275ce255bdc002650fe5da /src/server
parent5efc0f77c5e81897984ed12f82414d63594f37c1 (diff)
better completion for bitset operations
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin41
-rw-r--r--src/server/completion.odin78
2 files changed, 71 insertions, 48 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 0745944..8c3f93f 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -48,6 +48,7 @@ DocumentPositionContext :: struct {
implicit: bool, //used for completion
arrow: bool,
binary: ^ast.Binary_Expr, //used for completion
+ parent_binary: ^ast.Binary_Expr, //used for completion
assign: ^ast.Assign_Stmt, //used for completion
switch_stmt: ^ast.Switch_Stmt, //used for completion
switch_type_stmt: ^ast.Type_Switch_Stmt, //used for completion
@@ -1010,6 +1011,43 @@ resolve_location_identifier :: proc (ast_context: ^AstContext, node: ast.Ident)
return index.lookup(node.name, ast_context.document_package);
}
+resolve_first_symbol_from_binary_expression :: proc (ast_context: ^AstContext, binary: ^ast.Binary_Expr) -> (index.Symbol, bool) {
+
+ //Fairly simple function to find the earliest identifier symbol in binary expression.
+
+ if binary.left != nil && binary.left.derived != nil {
+
+ 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 {
+ if s, ok := resolve_first_symbol_from_binary_expression(ast_context, cast(^ast.Binary_Expr)binary.left); ok {
+ return s, ok;
+ }
+ }
+
+ }
+
+ if binary.right != nil && binary.right.derived != nil {
+ 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 {
+ if s, ok := resolve_first_symbol_from_binary_expression(ast_context, cast(^ast.Binary_Expr)binary.right); ok {
+ return s, ok;
+ }
+ }
+ }
+
+ return {}, false;
+}
+
make_pointer_ast :: proc (elem: ^ast.Expr) -> ^ast.Pointer_Type {
pointer := index.new_type(ast.Pointer_Type, elem.pos, elem.end, context.temp_allocator);
pointer.elem = elem;
@@ -2309,6 +2347,9 @@ get_document_position_node :: proc (node: ^ast.Node, position_context: ^Document
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);
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 8d0a4df..34fc9bf 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -93,6 +93,10 @@ field_exists_in_comp_lit :: proc (comp_lit: ^ast.Comp_Lit, name: string) -> bool
return false;
}
+get_attribute_completion :: proc (ast_context: ^AstContext, postition_context: ^DocumentPositionContext, list: ^CompletionList) {
+
+}
+
get_directive_completion :: proc (ast_context: ^AstContext, postition_context: ^DocumentPositionContext, list: ^CompletionList) {
list.isIncomplete = false;
@@ -129,11 +133,13 @@ get_directive_completion :: proc (ast_context: ^AstContext, postition_context: ^
item := CompletionItem {
detail = elem,
label = elem,
- kind = .EnumMember,
+ kind = .Constant,
};
append(&items, item);
}
+
+ list.items = items[:];
}
get_comp_lit_completion :: proc (ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) {
@@ -347,17 +353,12 @@ unwrap_union :: proc (ast_context: ^AstContext, node: ^ast.Expr) -> (index.Symbo
return {}, false;
}
-unwrap_bitset :: proc (ast_context: ^AstContext, node: ^ast.Expr) -> (index.SymbolEnumValue, bool) {
-
- if bitset_symbol, ok := resolve_type_expression(ast_context, node); ok {
-
- if bitset_value, ok := bitset_symbol.value.(index.SymbolBitSetValue); ok {
-
- if enum_symbol, ok := resolve_type_expression(ast_context, bitset_value.expr); ok {
+unwrap_bitset :: proc (ast_context: ^AstContext, bitset_symbol: index.Symbol) -> (index.SymbolEnumValue, bool) {
- if enum_value, ok := enum_symbol.value.(index.SymbolEnumValue); ok {
- return enum_value, true;
- }
+ 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;
}
}
}
@@ -420,35 +421,21 @@ get_implicit_completion :: proc (ast_context: ^AstContext, position_context: ^Do
append(&items, item);
}
}
- } else if position_context.comp_lit != nil && position_context.binary != nil && is_bitset_binary_operator(position_context.binary.op.text) {
+ } else if position_context.comp_lit != nil && position_context.parent_binary != nil && is_bitset_binary_operator(position_context.binary.op.text) {
//bitsets
- context_node: ^ast.Expr;
- bitset_node: ^ast.Expr;
-
- if position_in_node(position_context.binary.right, position_context.position) {
- context_node = position_context.binary.right;
- bitset_node = position_context.binary.left;
- } else if position_in_node(position_context.binary.left, position_context.position) {
- context_node = position_context.binary.left;
- bitset_node = position_context.binary.right;
- }
+ if symbol, ok := resolve_first_symbol_from_binary_expression(ast_context, position_context.parent_binary); ok {
- if context_node != nil && bitset_node != nil {
+ if value, ok := unwrap_bitset(ast_context, symbol); ok {
- if _, ok := context_node.derived.(ast.Comp_Lit); ok {
+ for name in value.names {
- if value, ok := unwrap_bitset(ast_context, bitset_node); ok {
-
- for name in value.names {
-
- item := CompletionItem {
- label = name,
- kind = .EnumMember,
- detail = name,
- };
+ item := CompletionItem {
+ label = name,
+ kind = .EnumMember,
+ detail = name,
+ };
- append(&items, item);
- }
+ append(&items, item);
}
}
}
@@ -815,19 +802,14 @@ get_type_switch_Completion :: proc (ast_context: ^AstContext, position_context:
list.items = items[:];
}
-bitset_operators: map[string]bool = {
- "|" = true,
- "&" = true,
- "&~" = true,
- "~" = true,
- "==" = true,
- "!=" = true,
- "<=" = true,
- "<" = true,
- ">=" = true,
- ">" = true,
+bitset_operators: map[string]bool = {
+ "|" = true,
+ "&" = true,
+ "~" = true,
+ "<" = true,
+ ">" = true,
};
-is_bitset_binary_operator :: proc(op: string) -> bool {
+is_bitset_binary_operator :: proc (op: string) -> bool {
return op in bitset_operators;
-} \ No newline at end of file
+}