diff options
| author | Damian Tarnawski <gthetarnav@gmail.com> | 2024-05-09 15:16:45 +0200 |
|---|---|---|
| committer | Damian Tarnawski <gthetarnav@gmail.com> | 2024-05-09 15:16:45 +0200 |
| commit | 5167c028c2825441df1080f250ee1e5510b85965 (patch) | |
| tree | 28827591d4608c3e5fd10c4352e1a3c21b02bfd6 | |
| parent | 3a2b74f601cb1baeab192218daa7c79f33150396 (diff) | |
Fix variable names in value declarations not having symbols
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | src/server/analysis.odin | 61 | ||||
| -rw-r--r-- | tests/definition_test.odin | 36 |
3 files changed, 63 insertions, 35 deletions
@@ -13,5 +13,6 @@ *node_modules /ols /odinfmt +tests/tests ols.json .vscode/settings.json diff --git a/src/server/analysis.odin b/src/server/analysis.odin index b52890b..2f6f20e 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -1219,31 +1219,22 @@ clear_local_group :: proc(ast_context: ^AstContext, id: int) { } get_local :: proc( - ast_context: ^AstContext, - offset: int, - name: string, + ast_context: AstContext, + ident: ast.Ident, ) -> ( DocumentLocal, bool, ) { - for _, locals in &ast_context.locals { - if local_stack, ok := locals[name]; ok { - for i := len(local_stack) - 1; i >= 0; i -= 1 { - if local_stack[i].offset <= offset || - local_stack[i].local_global { - if i < 0 { - return {}, false - } else { - ret := local_stack[i].rhs - if ident, ok := ret.derived.(^ast.Ident); - ok && ident.name == name { - if i - 1 < 0 { - return {}, false - } - } - return local_stack[i], true - } - } + for _, locals in ast_context.locals { + local_stack := locals[ident.name] or_continue + + #reverse for local in local_stack { + if local.offset <= ident.pos.offset || + local.local_global || + local.lhs.pos.offset == ident.pos.offset { + // checking equal offsets is a hack to allow matching lhs ident in var decls + // because otherwise minimal offset begins after the decl + return local, true } } } @@ -1313,23 +1304,23 @@ internal_resolve_type_identifier :: proc( return {}, false case "true", "false": return { - type = .Keyword, - signature = node.name, - pkg = ast_context.current_package, - value = SymbolUntypedValue{type = .Bool}, + type = .Keyword, + signature = node.name, + pkg = ast_context.current_package, + value = SymbolUntypedValue{type = .Bool}, }, true case: return { - type = .Keyword, - signature = node.name, - name = ident.name, - pkg = ast_context.current_package, - value = SymbolBasicValue{ident = ident}, + type = .Keyword, + signature = node.name, + name = ident.name, + pkg = ast_context.current_package, + value = SymbolBasicValue{ident = ident}, }, true } } - if local, ok := get_local(ast_context, node.pos.offset, node.name); + if local, ok := get_local(ast_context^, node); ok && ast_context.use_locals { is_distinct := false @@ -1858,9 +1849,9 @@ resolve_implicit_selector :: proc( proc_value.arg_types[parameter_index].type, ) } else if enum_value, ok := symbol.value.(SymbolEnumValue); - ok { - return symbol, true - } + ok { + return symbol, true + } } } } @@ -2170,7 +2161,7 @@ resolve_location_identifier :: proc( ) { symbol: Symbol - if local, ok := get_local(ast_context, node.pos.offset, node.name); ok { + if local, ok := get_local(ast_context^, node); ok { symbol.range = common.get_token_range(local.lhs, ast_context.file.src) uri := common.create_uri(local.lhs.pos.file, ast_context.allocator) symbol.pkg = ast_context.document_package diff --git a/tests/definition_test.odin b/tests/definition_test.odin index d98d92f..41bdbc4 100644 --- a/tests/definition_test.odin +++ b/tests/definition_test.odin @@ -172,3 +172,39 @@ ast_goto_bit_field_field_in_proc :: proc(t: ^testing.T) { test.expect_definition_locations(t, &source, {location}) } + +@(test) +ast_goto_shadowed_value_decls :: proc(t: ^testing.T) { + source0 := test.Source { + main = `package test + main :: proc() { + foo := 1 + + { + fo{*}o := 2 + } + } + `, + packages = {}, + } + source1 := test.Source { + main = `package test + main :: proc() { + foo := 1 + + { + foo := 2 + fo{*}o + } + } + `, + packages = {}, + } + + location := common.Location { + range = {{line = 5, character = 5}, {line = 5, character = 8}}, + } + + test.expect_definition_locations(t, &source0, {location}) + test.expect_definition_locations(t, &source1, {location}) +} |