diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2021-03-12 15:19:11 +0100 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2021-03-12 15:19:11 +0100 |
| commit | 3cad55d25758b7d7af4e34aee62484835111c3bd (patch) | |
| tree | 17ad80d97e2e818081e7d5be1f05c0c0a2c36edb /src/server | |
| parent | 311ec5b188e332d9b0a4dddfa1ee4c5cbe150e3d (diff) | |
completion infer on enum switch
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/analysis.odin | 16 | ||||
| -rw-r--r-- | src/server/completion.odin | 50 |
2 files changed, 57 insertions, 9 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 961f25c..d9b9dc2 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -49,7 +49,10 @@ DocumentPositionContext :: struct { arrow: bool, binary: ^ast.Binary_Expr, //used for completion assign: ^ast.Assign_Stmt, //used for completion - value_decl: ^ast.Value_Decl, + switch_stmt: ^ast.Switch_Stmt, //used for completion + switch_type_stmt: ^ast.Type_Switch_Stmt, //used for completion + case_clause: ^ast.Case_Clause, //used for completion + value_decl: ^ast.Value_Decl, //used for completion hint: DocumentPositionContextHint, }; @@ -693,7 +696,7 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (i return index.Symbol {}, false; } case: - log.errorf("default node kind, resolve_type_expression: %T", v); + log.warnf("default node kind, resolve_type_expression: %T", v); if v == nil { return {}, false; @@ -1488,7 +1491,6 @@ get_locals_value_decl :: proc(file: ast.File, value_decl: ast.Value_Decl, ast_co ast_context.in_package[str] = get_package_from_node(results[i]); store_local(ast_context, results[i], name.pos.offset, str); ast_context.variables[str] = value_decl.is_mutable; - log.error(name); } } @@ -2331,7 +2333,6 @@ fallback_position_context_completion :: proc(document: ^Document, position: comm 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. - log.error(bad_expr); src_with_dot := string(position_context.file.src[0:end_offset+1]); last_dot := strings.last_index(src_with_dot, "."); @@ -2357,6 +2358,10 @@ fallback_position_context_completion :: proc(document: ^Document, position: comm e := parser.parse_expr(&p, true); + if e == nil { + return; + } + position_context.selector = e; ident := index.new_type(ast.Ident, e.pos, e.end, context.temp_allocator); @@ -2623,14 +2628,17 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP get_document_position(n.expr, position_context); get_document_position(n.body, position_context); case Case_Clause: + position_context.case_clause = cast(^Case_Clause)node; 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); diff --git a/src/server/completion.odin b/src/server/completion.odin index 7acbadf..2bd56ec 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -45,7 +45,7 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> ( get_selector_completion(&ast_context, &position_context, &list); } - else { + else if position_context.identifier != nil { get_identifier_completion(&ast_context, &position_context, &list); } @@ -416,9 +416,51 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc ast_context.current_package = ast_context.document_package; } - //bitsets - if position_context.comp_lit != nil && position_context.binary != nil && (position_context.binary.op.text == "&" ) { + //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); + + 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 { + + for name in case_clause.list { + + if implicit, ok := name.derived.(ast.Implicit_Selector_Expr); ok { + used_enums[implicit.field.name] = true; + } + } + } + } + } + + 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; + } + + item := CompletionItem { + label = name, + kind = .EnumMember, + detail = name, + }; + + append(&items, item); + + } + + } + + } + + else if position_context.comp_lit != nil && position_context.binary != nil && (position_context.binary.op.text == "&" ) { + //bitsets context_node: ^ast.Expr; bitset_node: ^ast.Expr; @@ -436,8 +478,6 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc if _, ok := context_node.derived.(ast.Comp_Lit); ok { - log.error(bitset_node.derived); - if value, ok := unwrap_bitset(ast_context, bitset_node); ok { for name in value.names { |