aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-06-09 14:32:59 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-06-13 15:23:36 -0400
commit8816d531da666959b7df0c64401b8fa064b0cd3d (patch)
tree893cf9b15bb610f13b2c6cf3c2c3148166341ed4 /tests
parent023c8a0fd1d8d8e54b38bf990a74816a31dee68e (diff)
Add textDocument/typeDefinition support
Diffstat (limited to 'tests')
-rw-r--r--tests/definition_test.odin26
-rw-r--r--tests/hover_test.odin43
-rw-r--r--tests/type_definition_test.odin695
3 files changed, 764 insertions, 0 deletions
diff --git a/tests/definition_test.odin b/tests/definition_test.odin
index 1c51b8e..5025666 100644
--- a/tests/definition_test.odin
+++ b/tests/definition_test.odin
@@ -34,6 +34,32 @@ ast_goto_comp_lit_field :: proc(t: ^testing.T) {
}
@(test)
+ast_goto_struct_definition :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ Point :: struct {
+ x, y, z : f32,
+ }
+
+ main :: proc() {
+ point := Po{*}int {
+ x = 2, y = 5, z = 0,
+ }
+ }
+ `,
+ }
+
+ location := common.Location {
+ range = {
+ start = {line = 1, character = 8},
+ end = {line = 1, character = 13},
+ },
+ }
+
+ test.expect_definition_locations(t, &source, {location})
+}
+
+@(test)
ast_goto_comp_lit_field_indexed :: proc(t: ^testing.T) {
source := test.Source {
main = `package test
diff --git a/tests/hover_test.odin b/tests/hover_test.odin
index cb46473..1171f07 100644
--- a/tests/hover_test.odin
+++ b/tests/hover_test.odin
@@ -894,6 +894,49 @@ ast_hover_proc_overload_definition :: proc(t: ^testing.T) {
}
@(test)
+ast_hover_distinguish_names_correctly :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+
+ Bar :: struct {
+ bar: string
+ }
+
+ main :: proc() {
+ bar := Bar {
+ b{*}ar = "Hello, World",
+ }
+ }
+ `
+ }
+
+ test.expect_hover(t, &source, "Bar.bar: string")
+}
+
+@(test)
+ast_hover_distinguish_names_correctly_variable_assignment :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+
+ Foo :: struct {
+ bar: ^Bar,
+ }
+
+ Bar :: struct {
+ bar: int,
+ }
+
+ main :: proc() {
+ foo := &Foo{}
+ bar := foo.ba{*}r
+ }
+ `
+ }
+
+ test.expect_hover(t, &source, "Foo.bar: ^test.Bar :: struct {\n\tbar: int,\n}")
+}
+
+@(test)
ast_hover_sub_string_slices :: proc(t: ^testing.T) {
source := test.Source {
main = `package test
diff --git a/tests/type_definition_test.odin b/tests/type_definition_test.odin
new file mode 100644
index 0000000..851c2f4
--- /dev/null
+++ b/tests/type_definition_test.odin
@@ -0,0 +1,695 @@
+package tests
+
+import "core:testing"
+
+import "src:common"
+
+import test "src:testing"
+
+@(test)
+ast_type_definition_struct_definition :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Bar :: struct {
+ bar: int,
+ }
+
+ main :: proc() {
+ b{*}ar := Bar{}
+ }
+ `,
+ }
+
+ 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_definition :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+ Bar :: struct {
+ bar: Foo,
+ }
+
+ main :: proc() {
+ bar := Bar{
+ ba{*}r = Foo{},
+ }
+ }
+ `,
+ }
+
+ 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_definition_from_use :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ Bar :: struct {
+ bar: Foo,
+ }
+
+ main :: proc() {
+ bar := Bar{}
+ bar.ba{*}r = "Test"
+ }
+ `,
+ }
+
+ 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_variable :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ Bar :: struct {
+ bar: Foo,
+ }
+
+ main :: proc() {
+ bar := Bar{}
+ ba{*}r.bar = "Test"
+ }
+ `,
+ }
+
+ 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_definition_from_declaration :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ Bar :: struct {
+ f{*}oo: Foo,
+ }
+ `,
+ }
+
+ 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_procedure_return_value :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ bar :: proc() -> Foo {
+ return Foo{}
+ }
+
+ main :: proc() {
+ f{*}oo := bar()
+ }
+ `,
+ }
+
+ 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_procedure_mulitple_return_first_value :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ Bar :: struct {
+ bar: int,
+ }
+
+ new_foo_bar :: proc() -> (Foo, Bar) {
+ return Foo{}, Bar{}
+ }
+
+ main :: proc() {
+ fo{*}o, bar := new_foo_bar()
+ }
+ `,
+ }
+
+ 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_procedure_mulitple_return_second_value :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ Bar :: struct {
+ bar: int,
+ }
+
+ new_foo_bar :: proc() -> (Foo, Bar) {
+ return Foo{}, Bar{}
+ }
+
+ main :: proc() {
+ foo, ba{*}r := new_foo_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_builtin_type :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+
+ main :: proc() {
+ f{*}oo := "Hello, World!"
+ }
+ `,
+ }
+
+ test.expect_type_definition_locations(t, &source, {})
+}
+
+@(test)
+ast_type_definition_struct_field_builtin_type :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ main :: proc() {
+ foo := Foo{
+ f{*}oo = "Hello, World!"
+ }
+ }
+ `,
+ }
+
+ test.expect_type_definition_locations(t, &source, {})
+}
+
+@(test)
+ast_type_definition_struct_field_definition_from_declaration_builtin_type :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ f{*}oo: string,
+ }
+ `,
+ }
+
+ test.expect_type_definition_locations(t, &source, {})
+}
+
+@(test)
+ast_type_definition_on_proc_with_multiple_return_goto_first_return :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ foo :: proc() -> (Foo, bool) {
+ return Foo{}, true
+ }
+
+ main :: proc() {
+ my_foo, ok := f{*}oo()
+ }
+ `,
+ }
+
+ 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_proc_first_return :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ foo :: proc() -> (Foo, bool) {
+ return Foo{}, true
+ }
+
+ main :: proc() {
+ my_foo, ok := f{*}oo()
+ }
+ `,
+ }
+
+ 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_proc_with_no_return :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ foo :: proc() {
+ }
+
+ main :: proc() {
+ f{*}oo()
+ }
+ `,
+ }
+
+ test.expect_type_definition_locations(t, &source, {})
+}
+
+@(test)
+ast_type_definition_variable_array_type :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ my_int: int,
+ }
+
+ Bar :: struct {
+ foo: Foo,
+ }
+
+ main :: proc() {
+ bars: [2]Bar
+
+ b{*}ars[0].foo = Foo{}
+ }
+ `,
+ }
+
+ 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_proc_from_definition :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ fo{*}o :: proc() -> (Foo, bool) {
+ return Foo{}, true
+ }
+
+ main :: proc() {
+ my_foo, ok := foo()
+ }
+ `,
+ }
+
+ 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_proc_with_slice_return :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ fo{*}o :: proc() -> ([]Foo, bool) {
+ return {}, true
+ }
+
+ main :: proc() {
+ my_foo, ok := foo()
+ }
+ `,
+ }
+
+ 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_param_of_proc :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: struct {
+ foo: string,
+ }
+
+ do_foo :: proc(f: Foo) {
+ }
+
+ main :: proc() {
+ foo := Foo{}
+ do_foo(f{*}oo)
+ }
+ `,
+ }
+
+ 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_enum :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: enum {
+ Foo1,
+ Foo2,
+ }
+
+ get_foo :: proc() -> Foo {
+ return .Foo1
+ }
+
+ main :: proc() {
+ f{*}oo := get_foo()
+ }
+ `,
+ }
+
+ 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_predeclared_variable :: proc(t: ^testing.T) {
+ source := test.Source{
+ main = `package test
+ Foo :: union {
+ i64,
+ f64,
+ }
+
+ get_foo :: proc() -> Foo {
+ return 0
+ }
+
+ main :: proc() {
+ foo: Foo
+
+ f{*}oo = get_foo()
+ }
+ `,
+ }
+
+ 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_external_package :: proc(t: ^testing.T) {
+ packages := make([dynamic]test.Package, context.temp_allocator)
+
+ append(
+ &packages,
+ test.Package {
+ pkg = "my_package",
+ source = `package my_package
+ My_Struct :: struct {
+ one: int,
+ two: int,
+ three: int,
+ }
+ `,
+ },
+ )
+ source := test.Source {
+ main = `package test
+ import "my_package"
+
+ main :: proc() {
+ cool: my_package.My_Struct
+ cool{*}
+ }
+ `,
+ packages = packages[:],
+ }
+
+ location := common.Location {
+ uri = "file://test/my_package/package.odin",
+ range = {
+ start = {line = 1, character = 2},
+ end = {line = 1, character = 11},
+ },
+ }
+
+ test.expect_type_definition_locations(t, &source, {location})
+}
+
+@(test)
+ast_type_definition_external_package_from_proc :: proc(t: ^testing.T) {
+ packages := make([dynamic]test.Package, context.temp_allocator)
+
+ append(
+ &packages,
+ test.Package {
+ pkg = "my_package",
+ source = `package my_package
+ My_Struct :: struct {
+ one: int,
+ two: int,
+ three: int,
+ }
+ `,
+ },
+ )
+ source := test.Source {
+ main = `package test
+ import "my_package"
+
+ get_my_struct :: proc() -> my_package.My_Struct {
+ return my_package.My_Struct{}
+ }
+
+ main :: proc() {
+ my_struct := ge{*}t_my_struct()
+ }
+ `,
+ packages = packages[:],
+ }
+
+ location := common.Location {
+ uri = "file://test/my_package/package.odin",
+ range = {
+ start = {line = 1, character = 2},
+ end = {line = 1, character = 11},
+ },
+ }
+
+ test.expect_type_definition_locations(t, &source, {location})
+}
+
+@(test)
+ast_type_definition_external_package_from_proc_slice_return :: proc(t: ^testing.T) {
+ packages := make([dynamic]test.Package, context.temp_allocator)
+
+ append(
+ &packages,
+ test.Package {
+ pkg = "my_package",
+ source = `package my_package
+ My_Struct :: struct {
+ one: int,
+ two: int,
+ three: int,
+ }
+ `,
+ },
+ )
+ source := test.Source {
+ main = `package test
+ import "my_package"
+
+ get_my_struct :: proc() -> []my_package.My_Struct {
+ return {}
+ }
+
+ main :: proc() {
+ my_struct := ge{*}t_my_struct()
+ }
+ `,
+ packages = packages[:],
+ }
+
+ location := common.Location {
+ uri = "file://test/my_package/package.odin",
+ range = {
+ start = {line = 1, character = 2},
+ end = {line = 1, character = 11},
+ },
+ }
+
+ test.expect_type_definition_locations(t, &source, {location})
+}
+
+@(test)
+ast_type_definition_external_package_from_external_proc :: proc(t: ^testing.T) {
+ packages := make([dynamic]test.Package, context.temp_allocator)
+
+ append(
+ &packages,
+ test.Package {
+ pkg = "my_package",
+ source = `package my_package
+ My_Struct :: struct {
+ one: int,
+ two: int,
+ three: int,
+ }
+
+ get_my_struct :: proc() -> My_Struct {
+ return My_Struct{}
+ }
+ `,
+ },
+ )
+ source := test.Source {
+ main = `package test
+ import "my_package"
+
+ main :: proc() {
+ my_struct := my_package.ge{*}t_my_struct()
+ }
+ `,
+ packages = packages[:],
+ }
+
+ location := common.Location {
+ uri = "file://test/my_package/package.odin",
+ range = {
+ start = {line = 1, character = 2},
+ end = {line = 1, character = 11},
+ },
+ }
+
+ test.expect_type_definition_locations(t, &source, {location})
+}