diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2024-10-06 00:08:50 +0200 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2024-10-06 00:08:50 +0200 |
| commit | 954c87683103130224cf5fe876f26a5fa3dc810e (patch) | |
| tree | e3f53987800b1e304e4cea9632fce35d5d2fdbb6 | |
| parent | e872aec330a4dc5ef8a5ee6f85669b41ff52fc49 (diff) | |
Fix #332
| -rw-r--r-- | src/server/analysis.odin | 31 | ||||
| -rw-r--r-- | tests/completions_test.odin | 18 |
2 files changed, 41 insertions, 8 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 6319e47..cae3fd2 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -2682,12 +2682,19 @@ get_globals :: proc(file: ast.File, ast_context: ^AstContext) { } } +GetGenericAssignmentFlag :: enum { + SameLhsRhsCount, +} + +GetGenericAssignmentFlags :: bit_set[GetGenericAssignmentFlag] + get_generic_assignment :: proc( file: ast.File, value: ^ast.Expr, ast_context: ^AstContext, results: ^[dynamic]^ast.Expr, calls: ^map[int]bool, + flags: GetGenericAssignmentFlags, ) { using ast @@ -2695,11 +2702,11 @@ get_generic_assignment :: proc( #partial switch v in value.derived { case ^Or_Return_Expr: - get_generic_assignment(file, v.expr, ast_context, results, calls) + get_generic_assignment(file, v.expr, ast_context, results, calls, flags) case ^Or_Else_Expr: - get_generic_assignment(file, v.x, ast_context, results, calls) + get_generic_assignment(file, v.x, ast_context, results, calls, flags) case ^Or_Branch_Expr: - get_generic_assignment(file, v.expr, ast_context, results, calls) + get_generic_assignment(file, v.expr, ast_context, results, calls, flags) case ^Call_Expr: old_call := ast_context.call ast_context.call = cast(^ast.Call_Expr)value @@ -2759,8 +2766,11 @@ get_generic_assignment :: proc( } case ^ast.Index_Expr: append(results, v) - b := make_bool_ast(ast_context, v.expr.pos, v.expr.end) - append(results, b) + //In order to prevent having to actually resolve the expression, we make the assumption that we need to always add a bool node, if the lhs and rhs don't match. + if .SameLhsRhsCount not_in flags { + b := make_bool_ast(ast_context, v.expr.pos, v.expr.end) + append(results, b) + } case ^Type_Assertion: if v.type != nil { if unary, ok := v.type.derived.(^ast.Unary_Expr); ok && unary.op.kind == .Question { @@ -2774,7 +2784,6 @@ get_generic_assignment :: proc( append(results, b) } case: - //log.debugf("default node get_generic_assignment %v", v); append(results, value) } } @@ -2819,8 +2828,14 @@ get_locals_value_decl :: proc(file: ast.File, value_decl: ast.Value_Decl, ast_co results := make([dynamic]^Expr, context.temp_allocator) calls := make(map[int]bool, 0, context.temp_allocator) //Have to track the calls, since they disallow use of variables afterwards + flags: GetGenericAssignmentFlags + + if len(value_decl.names) == len(value_decl.values) { + flags |= {.SameLhsRhsCount} + } + for value in value_decl.values { - get_generic_assignment(file, value, ast_context, &results, &calls) + get_generic_assignment(file, value, ast_context, &results, &calls, flags) } if len(results) == 0 { @@ -3010,7 +3025,7 @@ get_locals_assign_stmt :: proc(file: ast.File, stmt: ast.Assign_Stmt, ast_contex calls := make(map[int]bool, 0, context.temp_allocator) for rhs in stmt.rhs { - get_generic_assignment(file, rhs, ast_context, &results, &calls) + get_generic_assignment(file, rhs, ast_context, &results, &calls, {}) } if len(stmt.lhs) != len(results) { diff --git a/tests/completions_test.odin b/tests/completions_test.odin index 49ac50f..f25fba5 100644 --- a/tests/completions_test.odin +++ b/tests/completions_test.odin @@ -1210,6 +1210,24 @@ ast_value_decl_multiple_name_same_type :: proc(t: ^testing.T) { } @(test) +ast_value_decl_multi_variable :: proc(t: ^testing.T) { + source := test.Source { + main = `package main + main :: proc() { + x: []int + y: []int + xzz, yzz := x[0], y[0] + + yz{*} + } + `, + } + + test.expect_completion_details(t, &source, "", {"test.yzz: int"}) +} + + +@(test) ast_value_decl_comp_lit :: proc(t: ^testing.T) { source := test.Source { main = `package main |