diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2023-05-18 18:10:11 +0200 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2023-05-18 18:10:11 +0200 |
| commit | adfb252f6a0283a565fc5cd801baa1b8c7161d3d (patch) | |
| tree | 7c4808d78c459fcd8089c555f1e7b3f32cb9b330 /src | |
| parent | 2b0dccaa496fd809e36e7d979995e843bca28bfb (diff) | |
Add support for gotos on comp literal fields
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/analysis.odin | 114 | ||||
| -rw-r--r-- | src/server/definition.odin | 11 | ||||
| -rw-r--r-- | src/testing/testing.odin | 4 |
3 files changed, 103 insertions, 26 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 5a04a3a..5d9fbe6 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -362,20 +362,13 @@ resolve_type_comp_literal :: proc( return {}, nil, false } - element_index := 0 prev_package := ast_context.current_package ast_context.current_package = current_symbol.pkg defer ast_context.current_package = prev_package - for elem, i in current_comp_lit.elems { - if position_in_node(elem, position_context.position) { - element_index = i - } - } - - for elem in current_comp_lit.elems { + for elem, element_index in current_comp_lit.elems { if !position_in_node(elem, position_context.position) { continue } @@ -409,7 +402,8 @@ resolve_type_comp_literal :: proc( } } } else if comp_value, ok := elem.derived.(^ast.Comp_Lit); ok { //indexed - if s, ok := current_symbol.value.(SymbolStructValue); ok { + #partial switch s in current_symbol.value { + case SymbolStructValue: if len(s.types) <= element_index { return {}, {}, false } @@ -429,6 +423,38 @@ resolve_type_comp_literal :: proc( comp_value, ) } + case SymbolSliceValue: + if symbol, ok := resolve_type_expression(ast_context, s.expr); + ok { + return resolve_type_comp_literal( + ast_context, + position_context, + symbol, + comp_value, + ) + } + + case SymbolDynamicArrayValue: + if symbol, ok := resolve_type_expression(ast_context, s.expr); + ok { + return resolve_type_comp_literal( + ast_context, + position_context, + symbol, + comp_value, + ) + } + + case SymbolFixedArrayValue: + if symbol, ok := resolve_type_expression(ast_context, s.expr); + ok { + return resolve_type_comp_literal( + ast_context, + position_context, + symbol, + comp_value, + ) + } } } } @@ -1957,6 +1983,28 @@ expand_struct_usings :: proc( return {names = names[:], types = types[:], ranges = ranges[:]} } +resolve_comp_literal :: proc( + ast_context: ^AstContext, + position_context: ^DocumentPositionContext, +) -> ( + symbol: Symbol, + ok: bool, +) { + symbol = resolve_type_expression( + ast_context, + position_context.parent_comp_lit.type, + ) or_return + + symbol, _ = resolve_type_comp_literal( + ast_context, + position_context, + symbol, + position_context.parent_comp_lit, + ) or_return + + return symbol, true +} + resolve_implicit_selector :: proc( ast_context: ^AstContext, position_context: ^DocumentPositionContext, @@ -2290,28 +2338,50 @@ resolve_location_identifier :: proc( return {}, false } +resolve_location_comp_lit_field :: proc( + ast_context: ^AstContext, + position_context: ^DocumentPositionContext, +) -> ( + symbol: Symbol, + ok: bool, +) { + reset_ast_context(ast_context) + + ast_context.current_package = ast_context.document_package + + symbol = resolve_comp_literal(ast_context, position_context) or_return + + field := position_context.field_value.field.derived.(^ast.Ident) or_return + + if struct_value, ok := symbol.value.(SymbolStructValue); ok { + for name, i in struct_value.names { + if name == field.name { + symbol.range = struct_value.ranges[i] + } + + } + } + + return symbol, true +} resolve_location_implicit_selector :: proc( ast_context: ^AstContext, position_context: ^DocumentPositionContext, implicit_selector: ^ast.Implicit_Selector_Expr, ) -> ( - Symbol, - bool, + symbol: Symbol, + ok: bool, ) { reset_ast_context(ast_context) ast_context.current_package = ast_context.document_package - symbol, ok := resolve_implicit_selector( + symbol = resolve_implicit_selector( ast_context, position_context, implicit_selector, - ) - - if !ok { - return {}, false - } + ) or_return #partial switch v in symbol.value { case SymbolEnumValue: @@ -2329,17 +2399,13 @@ resolve_location_selector :: proc( ast_context: ^AstContext, selector: ^ast.Selector_Expr, ) -> ( - Symbol, - bool, + symbol: Symbol, + ok: bool, ) { reset_ast_context(ast_context) ast_context.current_package = ast_context.document_package - symbol, ok := resolve_type_expression(ast_context, selector.expr) - - if !ok { - return {}, false - } + symbol = resolve_type_expression(ast_context, selector.expr) or_return field: string diff --git a/src/server/definition.odin b/src/server/definition.odin index 68cfac2..4c712eb 100644 --- a/src/server/definition.odin +++ b/src/server/definition.odin @@ -131,6 +131,17 @@ get_definition_location :: proc( location.range = resolved.range uri = resolved.uri } + } else if position_context.field_value != nil && + position_context.comp_lit != nil { + if resolved, ok := resolve_location_comp_lit_field( + &ast_context, + &position_context, + ); ok { + location.range = resolved.range + uri = resolved.uri + } else { + return {}, false + } } else if position_context.implicit_selector_expr != nil { if resolved, ok := resolve_location_implicit_selector( &ast_context, diff --git a/src/testing/testing.odin b/src/testing/testing.odin index 0d97870..2e020e1 100644 --- a/src/testing/testing.odin +++ b/src/testing/testing.odin @@ -366,7 +366,7 @@ expect_definition_locations :: proc( for expect_location, i in expect_locations { for location, j in locations { - if location == expect_location { + if location.range == expect_location.range { flags[i] += 1 } } @@ -377,7 +377,7 @@ expect_definition_locations :: proc( testing.errorf( t, "Expected location %v, but received %v", - expect_locations[i], + expect_locations[i].range, locations, ) } |