aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2021-03-12 15:19:11 +0100
committerDanielGavin <danielgavin5@hotmail.com>2021-03-12 15:19:11 +0100
commit3cad55d25758b7d7af4e34aee62484835111c3bd (patch)
tree17ad80d97e2e818081e7d5be1f05c0c0a2c36edb /src/server
parent311ec5b188e332d9b0a4dddfa1ee4c5cbe150e3d (diff)
completion infer on enum switch
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin16
-rw-r--r--src/server/completion.odin50
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 {