diff options
| author | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-06-30 22:30:49 -0400 |
|---|---|---|
| committer | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-07-02 07:54:29 -0400 |
| commit | f93d79f81f8e724e5d3553171c64253c1d5aca4e (patch) | |
| tree | 967facdfd0e496ba13dd4c07264dbedc0ebda57c /src | |
| parent | de9bacba2cf724401e04fd5a2572053754817f9c (diff) | |
Add tests for prepare rename and improve prepare rename resolution
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/references.odin | 23 | ||||
| -rw-r--r-- | src/server/rename.odin | 88 | ||||
| -rw-r--r-- | src/testing/testing.odin | 19 |
3 files changed, 79 insertions, 51 deletions
diff --git a/src/server/references.odin b/src/server/references.odin index 9002756..d20298e 100644 --- a/src/server/references.odin +++ b/src/server/references.odin @@ -50,15 +50,13 @@ prepare_references :: proc( ok = false pkg := "" - if position_context.label != nil { - return - } else if position_context.struct_type != nil { + if position_context.struct_type != nil { found := false done_struct: for field in position_context.struct_type.fields.list { for name in field.names { if position_in_node(name, position_context.position) { symbol = Symbol { - range = common.get_token_range(name, string(document.text)), + range = common.get_token_range(name, ast_context.file.src), } found = true resolve_flag = .Field @@ -75,6 +73,15 @@ prepare_references :: proc( found = true resolve_flag = .Identifier break done_struct + } else if selector, ok := field.type.derived.(^ast.Selector_Expr); ok { + symbol, ok = resolve_location_identifier(ast_context, ident^) + if !ok { + return + } + + found = true + resolve_flag = .Identifier + break done_struct } } } @@ -87,7 +94,7 @@ prepare_references :: proc( if ident, ok := field.derived.(^ast.Ident); ok { if position_in_node(ident, position_context.position) { symbol = Symbol { - range = common.get_token_range(ident, string(document.text)), + range = common.get_token_range(ident, ast_context.file.src), } found = true resolve_flag = .Field @@ -96,7 +103,7 @@ prepare_references :: proc( } else if value, ok := field.derived.(^ast.Field_Value); ok { if position_in_node(value.field, position_context.position) { symbol = Symbol { - range = common.get_token_range(value.field, string(document.text)), + range = common.get_token_range(value.field, ast_context.file.src), } found = true resolve_flag = .Field @@ -317,7 +324,7 @@ resolve_references :: proc( node_uri := common.create_uri(v.node.pos.file, ast_context.allocator) location := common.Location { - range = common.get_token_range(v.node^, string(document.text)), + range = common.get_token_range(v.node^, ast_context.file.src), uri = strings.clone(node_uri.uri, ast_context.allocator), } append(&locations, location) @@ -336,7 +343,7 @@ resolve_references :: proc( if (v.symbol.uri == symbol.uri || v.symbol.uri == "") && v.symbol.range == symbol.range { node_uri := common.create_uri(v.node.pos.file, ast_context.allocator) - range := common.get_token_range(v.node^, string(document.text)) + range := common.get_token_range(v.node^, ast_context.file.src) //We don't have to have the `.` with, otherwise it renames the dot. if _, ok := v.node.derived.(^ast.Implicit_Selector_Expr); ok { diff --git a/src/server/rename.odin b/src/server/rename.odin index b1d7d14..95d53a5 100644 --- a/src/server/rename.odin +++ b/src/server/rename.odin @@ -106,27 +106,34 @@ prepare_rename :: proc( ok = false pkg := "" - if position_context.label != nil { - return - } else if position_context.struct_type != nil { + if position_context.struct_type != nil { found := false done_struct: for field in position_context.struct_type.fields.list { for name in field.names { if position_in_node(name, position_context.position) { symbol = Symbol { - range = common.get_token_range(name, string(document.text)), + range = common.get_token_range(name, ast_context.file.src), } found = true break done_struct } } if position_in_node(field.type, position_context.position) { - symbol = Symbol { - range = common.get_token_range(field.type, string(document.text)), - } + if ident, ok := field.type.derived.(^ast.Ident); ok { + symbol = Symbol { + range = common.get_token_range(field.type, ast_context.file.src), + } - found = true - break done_struct + found = true + break done_struct + } else if selector, ok := field.type.derived.(^ast.Selector_Expr); ok { + symbol = Symbol { + range = common.get_token_range(selector.field, ast_context.file.src), + } + + found = true + break done_struct + } } } if !found { @@ -138,13 +145,26 @@ prepare_rename :: proc( if ident, ok := field.derived.(^ast.Ident); ok { if position_in_node(ident, position_context.position) { symbol = Symbol { - range = common.get_token_range(ident, string(document.text)), + range = common.get_token_range(ident, ast_context.file.src), + } + found = true + break done_enum + } + } else if value, ok := field.derived.(^ast.Field_Value); ok { + if position_in_node(value.field, position_context.position) { + symbol = Symbol { + range = common.get_token_range(value.field, ast_context.file.src), + } + found = true + break done_enum + } else if position_in_node(value.value, position_context.position) { + symbol = Symbol { + range = common.get_token_range(value.value, ast_context.file.src), } found = true break done_enum } } - } if !found { return @@ -155,19 +175,11 @@ prepare_rename :: proc( found := false for variant in position_context.union_type.variants { if position_in_node(variant, position_context.position) { - if ident, ok := variant.derived.(^ast.Ident); ok { - symbol, ok = resolve_location_identifier(ast_context, ident^) - - if !ok { - return - } - - found = true - - break - } else { - return + symbol = Symbol { + range = common.get_token_range(variant, ast_context.file.src), } + found = true + break } } if !found { @@ -178,12 +190,9 @@ prepare_rename :: proc( position_context.comp_lit != nil && !is_expr_basic_lit(position_context.field_value.field) && position_in_node(position_context.field_value.field, position_context.position) { - symbol, ok = resolve_location_comp_lit_field(ast_context, position_context) - - if !ok { - return + symbol = Symbol { + range = common.get_token_range(position_context.field_value.field, ast_context.file.src) } - } else if position_context.selector_expr != nil { if position_in_node(position_context.selector, position_context.position) && position_context.identifier != nil { @@ -194,33 +203,26 @@ prepare_rename :: proc( if !ok { return } - } else { symbol, ok = resolve_location_selector(ast_context, position_context.selector_expr) - symbol.flags -= {.Local} if selector, ok := position_context.selector_expr.derived.(^ast.Selector_Expr); ok { symbol.range = common.get_token_range(selector.field.expr_base, ast_context.file.src) } } } else if position_context.implicit { - symbol, ok = resolve_location_implicit_selector( - ast_context, - position_context, - position_context.implicit_selector_expr, - ) - - if !ok { - return + range := common.get_token_range(position_context.implicit_selector_expr, ast_context.file.src) + // Skip the `.` + range.start.character += 1 + symbol = Symbol{ + range = range, } + } else if position_context.identifier != nil { ident := position_context.identifier.derived.(^ast.Ident) - symbol, ok = resolve_location_identifier(ast_context, ident^) - symbol.range = common.get_token_range(position_context.identifier^, string(document.text)) - - if !ok { - return + symbol = Symbol { + range = common.get_token_range(position_context.identifier^, ast_context.file.src) } } else { return diff --git a/src/testing/testing.odin b/src/testing/testing.odin index 4500676..0b7ca1d 100644 --- a/src/testing/testing.odin +++ b/src/testing/testing.odin @@ -356,6 +356,25 @@ expect_reference_locations :: proc(t: ^testing.T, src: ^Source, expect_locations } } +expect_prepare_rename_range :: proc(t: ^testing.T, src: ^Source, expect_range: common.Range) { + setup(src) + defer teardown(src) + + range, ok := server.get_prepare_rename(src.document, src.position) + if !ok { + log.error("Failed to find range") + } + + if range != expect_range { + ok = false + log.errorf("Failed to match with range: %v", expect_range) + } + + if !ok { + log.error("Received: %v\n", range) + } +} + expect_semantic_tokens :: proc(t: ^testing.T, src: ^Source, expected: []server.SemanticToken) { setup(src) defer teardown(src) |