diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2021-03-16 23:55:47 +0100 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2021-03-16 23:55:47 +0100 |
| commit | 8b2eef8af0a50f22b06af603fc6e4f09b218f25c (patch) | |
| tree | 8f40705154be5b5171275ce255bdc002650fe5da /src | |
| parent | 5efc0f77c5e81897984ed12f82414d63594f37c1 (diff) | |
better completion for bitset operations
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/analysis.odin | 41 | ||||
| -rw-r--r-- | src/server/completion.odin | 78 |
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 +} |