From 954c87683103130224cf5fe876f26a5fa3dc810e Mon Sep 17 00:00:00 2001 From: DanielGavin Date: Sun, 6 Oct 2024 00:08:50 +0200 Subject: [PATCH] Fix #332 --- src/server/analysis.odin | 31 +++++++++++++++++++++++-------- 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 @@ -1209,6 +1209,24 @@ ast_value_decl_multiple_name_same_type :: proc(t: ^testing.T) { test.expect_completion_details(t, &source, "", {"test.yaaaa: string"}) } +@(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 {