aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2021-03-24 19:58:33 +0100
committerDanielGavin <danielgavin5@hotmail.com>2021-03-24 19:58:33 +0100
commit930e3072c44d73920526ebade9c42292fef082fd (patch)
tree67f8832ad59e1f45adade74525752dab654fa28f /src
parent8e666ce195e89e86038783bd17a598779df11c3b (diff)
more enum completion
Diffstat (limited to 'src')
-rw-r--r--src/server/analysis.odin40
-rw-r--r--src/server/completion.odin63
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) {