aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-06-12 18:06:21 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-06-13 15:23:36 -0400
commit20b4d31f49be2f74a3a34d3177f018d358ef2cf8 (patch)
tree16c27a841e3f24ab32d4b24dadd25c9872134a3e
parent8816d531da666959b7df0c64401b8fa064b0cd3d (diff)
Correctly handle pointer types
-rw-r--r--src/server/analysis.odin16
-rw-r--r--tests/type_definition_test.odin122
2 files changed, 133 insertions, 5 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 9e43467..5cd290d 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -813,8 +813,7 @@ resolve_location_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Ex
return {}, false
}
- // TODO: there is likely more of these that will be needed as well.
- // I think we'll need a better way to manage this all
+ // TODO: there is likely more of these that will need to be added
#partial switch n in node.derived {
case ^ast.Ident:
if _, ok := common.keyword_map[n.name]; ok {
@@ -825,6 +824,10 @@ resolve_location_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Ex
return {}, true
case ^ast.Array_Type:
return resolve_location_type_expression(ast_context, n.elem)
+ case ^ast.Pointer_Type:
+ return resolve_location_type_expression(ast_context, n.elem)
+ case ^ast.Comp_Lit:
+ return resolve_location_type_expression(ast_context, n.type)
}
return resolve_type_expression(ast_context, node)
}
@@ -2024,8 +2027,7 @@ resolve_unresolved_symbol :: proc(ast_context: ^AstContext, symbol: ^Symbol) ->
// Resolves the location of the underlying type of the identifier
resolve_location_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (Symbol, bool) {
- // TODO: will likely need to clean this up and find a way for this flow to make sense.
- // Ideally we need a way to extract the full symbol of a global
+ // TODO: Will also likely need to add more cases here as they come up
if local, ok := get_local(ast_context^, node); ok {
#partial switch n in local.rhs.derived {
case ^ast.Ident:
@@ -2038,8 +2040,14 @@ resolve_location_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ide
}
case ^ast.Selector_Expr:
return resolve_selector_expression(ast_context, n)
+ case ^ast.Pointer_Type:
+ return resolve_location_type_expression(ast_context, n.elem)
+ case ^ast.Unary_Expr:
+ return resolve_location_type_expression(ast_context, n.expr)
}
} else if global, ok := ast_context.globals[node.name]; ok {
+ // Ideally we'd have a way to extract the full symbol of a global, but for now
+ // this seems to work. We may need to add more cases though.
if v, ok := global.expr.derived.(^ast.Proc_Lit); ok {
if symbol, ok := resolve_type_expression(ast_context, global.name_expr); ok {
return symbol, ok
diff --git a/tests/type_definition_test.odin b/tests/type_definition_test.odin
index 851c2f4..4c0ef58 100644
--- a/tests/type_definition_test.odin
+++ b/tests/type_definition_test.odin
@@ -73,7 +73,7 @@ ast_type_definition_struct_field_definition_from_use :: proc(t: ^testing.T) {
main :: proc() {
bar := Bar{}
- bar.ba{*}r = "Test"
+ bar.ba{*}r = Foo{}
}
`,
}
@@ -89,6 +89,126 @@ ast_type_definition_struct_field_definition_from_use :: proc(t: ^testing.T) {
}
@(test)
+ast_type_definition_struct_from_rhs_use :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ Bar :: struct {
+ bar: Foo,
+ }
+
+ main :: proc() {
+ bar := Bar{}
+
+ foo := b{*}ar.bar
+ }
+ `,
+ }
+
+ location := common.Location {
+ range = {
+ start = {line = 5, character = 2},
+ end = {line = 5, character = 5},
+ },
+ }
+
+ test.expect_type_definition_locations(t, &source, {location})
+}
+
+@(test)
+ast_type_definition_struct_field_from_rhs_use :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ Bar :: struct {
+ bar: Foo,
+ }
+
+ main :: proc() {
+ bar := Bar{}
+
+ foo := bar.b{*}ar
+ }
+ `,
+ }
+
+ location := common.Location {
+ range = {
+ start = {line = 1, character = 2},
+ end = {line = 1, character = 5},
+ },
+ }
+
+ test.expect_type_definition_locations(t, &source, {location})
+}
+
+@(test)
+ast_type_definition_struct_field_pointer_from_rhs_use :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ Bar :: struct {
+ bar: ^Foo,
+ }
+
+ main :: proc() {
+ bar := Bar{}
+
+ foo := bar.b{*}ar
+ }
+ `,
+ }
+
+ location := common.Location {
+ range = {
+ start = {line = 1, character = 2},
+ end = {line = 1, character = 5},
+ },
+ }
+
+ test.expect_type_definition_locations(t, &source, {location})
+}
+
+@(test)
+ast_type_definition_local_pointer_from_rhs_use :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ Bar :: struct {
+ bar: ^Foo,
+ }
+
+ main :: proc() {
+ bar := &Bar{}
+
+ foo := b{*}ar.bar
+ }
+ `,
+ }
+
+ location := common.Location {
+ range = {
+ start = {line = 5, character = 2},
+ end = {line = 5, character = 5},
+ },
+ }
+
+ test.expect_type_definition_locations(t, &source, {location})
+}
+
+@(test)
ast_type_definition_struct_variable :: proc(t: ^testing.T) {
source := test.Source{
main = `package test