diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2021-03-24 19:58:33 +0100 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2021-03-24 19:58:33 +0100 |
| commit | 930e3072c44d73920526ebade9c42292fef082fd (patch) | |
| tree | 67f8832ad59e1f45adade74525752dab654fa28f /src | |
| parent | 8e666ce195e89e86038783bd17a598779df11c3b (diff) | |
more enum completion
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/analysis.odin | 40 | ||||
| -rw-r--r-- | src/server/completion.odin | 63 |
2 files changed, 85 insertions, 18 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 3165312..fb65a06 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -1043,6 +1043,21 @@ resolve_first_symbol_from_binary_expression :: proc(ast_context: ^AstContext, bi return {}, false; } +find_position_in_call_param :: proc(ast_context: ^AstContext, call: ast.Call_Expr) -> (int, bool) { + + if call.args == nil { + return 0, false; + } + + for arg, i in call.args { + if position_in_node(arg, ast_context.position) { + return i, true; + } + } + + return len(call.args) - 1, true; +} + 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; @@ -1675,8 +1690,6 @@ get_locals :: proc(file: ast.File, function: ^ast.Node, ast_context: ^AstContext ast_context.variables[str] = true; ast_context.parameters[str] = true; - log.info(arg.flags); - if .Using in arg.flags { using_stmt: ast.Using_Stmt; using_stmt.list = make([]^ast.Expr, 1, context.temp_allocator); @@ -1688,6 +1701,21 @@ get_locals :: proc(file: ast.File, function: ^ast.Node, ast_context: ^AstContext } } + if proc_lit.type != nil && proc_lit.type.results != nil { + + for result in proc_lit.type.results.list { + + for name in result.names { + if result.type != nil { + str := common.get_ast_node_string(name, file.src); + store_local(ast_context, result.type, name.pos.offset, str); + ast_context.variables[str] = true; + ast_context.parameters[str] = true; + } + } + } + } + block: ast.Block_Stmt; block, ok = proc_lit.body.derived.(ast.Block_Stmt); @@ -2045,7 +2073,9 @@ get_document_position_context :: proc(document: ^Document, position: common.Posi if hint == .Completion && position_context.selector == nil && position_context.field == nil { fallback_position_context_completion(document, position, &position_context); - } else if hint == .SignatureHelp && position_context.call == nil { + } + + if (hint == .SignatureHelp || hint == .Completion) && position_context.call == nil { fallback_position_context_signature(document, position, &position_context); } @@ -2291,6 +2321,8 @@ fallback_position_context_signature :: proc(document: ^Document, position: commo e := parser.parse_expr(&p, true); + //log.error(string(position_context.file.src[begin_offset:end_offset])); + position_context.call = e; } @@ -2374,7 +2406,7 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP case Paren_Expr: get_document_position(n.expr, position_context); case Call_Expr: - if position_context.hint == .SignatureHelp { + if position_context.hint == .SignatureHelp || position_context.hint == .Completion { position_context.call = cast(^Expr)node; } get_document_position(n.expr, position_context); diff --git a/src/server/completion.odin b/src/server/completion.odin index d389409..f51fc83 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -385,6 +385,10 @@ get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^Doc unwrap_enum :: proc(ast_context: ^AstContext, node: ^ast.Expr) -> (index.SymbolEnumValue, bool) { + if node == nil { + return {}, false; + } + if enum_symbol, ok := resolve_type_expression(ast_context, node); ok { if enum_value, ok := enum_symbol.value.(index.SymbolEnumValue); ok { @@ -688,28 +692,59 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc if len(position_context.function.type.results.list) > return_index { - if return_symbol, ok := resolve_type_expression(ast_context, position_context.function.type.results.list[return_index].type); ok { - - #partial switch v in return_symbol.value { - case index.SymbolEnumValue: - for name in v.names { + if enum_value, ok := unwrap_enum(ast_context, position_context.function.type.results.list[return_index].type); ok { - item := CompletionItem { - label = name, - kind = .EnumMember, - detail = name, - }; + for name in enum_value.names { - append(&items, item); - } + item := CompletionItem { + label = name, + kind = .EnumMember, + detail = name, + }; - list.items = items[:]; - return; + append(&items, item); } + + list.items = items[:]; + return; } } } + if position_context.call != nil { + + if call, ok := position_context.call.derived.(ast.Call_Expr); ok { + + parameter_index, parameter_ok := find_position_in_call_param(ast_context, call); + + if symbol, ok := resolve_type_expression(ast_context, call.expr); ok && parameter_ok { + + if proc_value, ok := symbol.value.(index.SymbolProcedureValue); ok { + + log.error("procedure symbol"); + + if enum_value, ok := unwrap_enum(ast_context, proc_value.arg_types[parameter_index].type); ok { + + log.error("unwrap"); + + for name in enum_value.names { + item := CompletionItem { + label = name, + kind = .EnumMember, + detail = name, + }; + + append(&items, item); + } + + + list.items = items[:]; + return; + } + } + } + } + } } get_identifier_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) { |