aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-07-19 20:10:50 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-07-22 18:48:36 -0400
commitdc8fdcb3d55d613dc71044e7a549b15b00e12cc7 (patch)
tree952fa71105631f61758072c96a03873d578403ba
parentddd6485f6ea68e445ee893721b2696aa2ab91bc4 (diff)
Add proc attribute to hover information
-rw-r--r--src/server/analysis.odin1
-rw-r--r--src/server/collector.odin8
-rw-r--r--src/server/documentation.odin35
-rw-r--r--src/server/symbol.odin1
-rw-r--r--tests/completions_test.odin6
-rw-r--r--tests/hover_test.odin24
-rw-r--r--tests/objc_test.odin14
-rw-r--r--tests/signatures_test.odin2
8 files changed, 80 insertions, 11 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 8b4e3f9..53f42c2 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -2802,6 +2802,7 @@ make_symbol_procedure_from_ast :: proc(
diverging = v.diverging,
calling_convention = v.calling_convention,
tags = v.tags,
+ attributes = attributes,
}
if _, ok := get_attribute_objc_name(attributes); ok {
diff --git a/src/server/collector.odin b/src/server/collector.odin
index fc4f603..ffff688 100644
--- a/src/server/collector.odin
+++ b/src/server/collector.odin
@@ -87,6 +87,7 @@ collect_procedure_fields :: proc(
) -> SymbolProcedureValue {
returns := make([dynamic]^ast.Field, 0, collection.allocator)
args := make([dynamic]^ast.Field, 0, collection.allocator)
+ attrs := make([dynamic]^ast.Attribute, 0, collection.allocator)
if return_list != nil {
for ret in return_list.list {
@@ -104,6 +105,12 @@ collect_procedure_fields :: proc(
}
}
+ for attr in attributes {
+ cloned := cast(^ast.Attribute)clone_type(attr, collection.allocator, &collection.unique_strings)
+ append(&attrs, cloned)
+ }
+
+
value := SymbolProcedureValue {
return_types = returns[:],
orig_return_types = returns[:],
@@ -113,6 +120,7 @@ collect_procedure_fields :: proc(
diverging = proc_type.diverging,
calling_convention = clone_calling_convention(proc_type.calling_convention, collection.allocator, &collection.unique_strings),
tags = proc_type.tags,
+ attributes = attrs[:],
}
return value
diff --git a/src/server/documentation.odin b/src/server/documentation.odin
index 1698d61..301d7e1 100644
--- a/src/server/documentation.odin
+++ b/src/server/documentation.odin
@@ -643,6 +643,41 @@ concatenate_symbol_information :: proc {
}
concatenate_raw_symbol_information :: proc(ast_context: ^AstContext, symbol: Symbol) -> string {
+ if v, ok := symbol.value.(SymbolProcedureValue); ok {
+ pkg := path.base(symbol.pkg, false, context.temp_allocator)
+ sb := strings.builder_make(context.temp_allocator)
+ if symbol.comment != "" {
+ fmt.sbprintf(&sb, "%s\n", symbol.comment)
+ }
+ for attribute in v.attributes {
+ if len(attribute.elems) == 0 {
+ strings.write_string(&sb, "@()\n")
+ continue
+ }
+ strings.write_string(&sb, "@(")
+ for elem, i in attribute.elems {
+ if directive, ok := elem.derived.(^ast.Field_Value); ok {
+ build_string_node(directive.field, &sb, false)
+ strings.write_string(&sb, "=")
+ build_string_node(directive.value, &sb, false)
+ } else {
+ build_string_node(elem, &sb, false)
+ }
+ if i != len(attribute.elems) - 1 {
+ strings.write_string(&sb, ", ")
+ }
+
+ }
+ strings.write_string(&sb, ")\n")
+ }
+
+ fmt.sbprintf(&sb, "%v.%v", pkg, symbol.name)
+ if symbol.signature != "" {
+ fmt.sbprintf(&sb, ": %v", symbol.signature)
+ }
+ return strings.to_string(sb)
+ }
+
return concatenate_raw_string_information(
ast_context,
symbol.pkg,
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 3cff104..141d4d4 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -59,6 +59,7 @@ SymbolProcedureValue :: struct {
diverging: bool,
calling_convention: ast.Proc_Calling_Convention,
tags: ast.Proc_Tags,
+ attributes: []^ast.Attribute,
}
SymbolProcedureGroupValue :: struct {
diff --git a/tests/completions_test.odin b/tests/completions_test.odin
index a138849..a7df752 100644
--- a/tests/completions_test.odin
+++ b/tests/completions_test.odin
@@ -3391,9 +3391,9 @@ ast_completion_vtable_using :: proc(t: ^testing.T) {
&source,
"->",
{
- `IUnknown.QueryInterface: proc(This: ^IUnknown, riid: REFIID, ppvObject: ^rawptr) -> HRESULT`,
- `IUnknown.AddRef: proc(This: ^IUnknown) -> ULONG`,
- `IUnknown.Release: proc(This: ^IUnknown) -> ULONG`,
+ `IUnknown.QueryInterface: proc "system" (This: ^IUnknown, riid: REFIID, ppvObject: ^rawptr) -> HRESULT`,
+ `IUnknown.AddRef: proc "system" (This: ^IUnknown) -> ULONG`,
+ `IUnknown.Release: proc "system" (This: ^IUnknown) -> ULONG`,
},
)
}
diff --git a/tests/hover_test.odin b/tests/hover_test.odin
index 4f81238..6c49bcf 100644
--- a/tests/hover_test.odin
+++ b/tests/hover_test.odin
@@ -2813,6 +2813,30 @@ ast_hover_proc_directives :: proc(t: ^testing.T) {
}
test.expect_hover(t, &source, "test.foo: proc(a: int) #no_bounds_check")
}
+
+@(test)
+ast_hover_proc_attributes :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ @(require_results) f{*}oo :: proc(a: int) -> int {
+ return 0
+ }
+ `,
+ }
+ test.expect_hover(t, &source, "@(require_results)\ntest.foo: proc(a: int) -> int")
+}
+
+@(test)
+ast_hover_proc_attributes_key_value :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ @(disabled=false) f{*}oo :: proc(a: int) -> int {
+ return 0
+ }
+ `,
+ }
+ test.expect_hover(t, &source, "@(disabled=false)\ntest.foo: proc(a: int) -> int")
+}
/*
Waiting for odin fix
diff --git a/tests/objc_test.odin b/tests/objc_test.odin
index 9d41377..412dc12 100644
--- a/tests/objc_test.odin
+++ b/tests/objc_test.odin
@@ -14,7 +14,7 @@ objc_return_type_with_selector_expression :: proc(t: ^testing.T) {
&packages,
test.Package {
pkg = "my_package",
- source = `package my_package
+ source = `package my_package
@(objc_class="NSWindow")
Window :: struct { dummy: int}
@@ -43,7 +43,7 @@ objc_return_type_with_selector_expression :: proc(t: ^testing.T) {
t,
&source,
"->",
- {"Window.initWithContentRect: my_package.Window_initWithContentRect :: proc(self: ^Window, contentRect: Rect, styleMask: WindowStyleMask, backing: BackingStoreType, doDefer: BOOL) -> ^Window"},
+ {"@(objc_type=Window, objc_name=\"initWithContentRect\")\nWindow.initWithContentRect: my_package.Window_initWithContentRect :: proc(self: ^Window, contentRect: Rect, styleMask: WindowStyleMask, backing: BackingStoreType, doDefer: BOOL) -> ^Window"},
)
}
@@ -55,7 +55,7 @@ objc_return_type_with_selector_expression_2 :: proc(t: ^testing.T) {
&packages,
test.Package {
pkg = "my_package",
- source = `package my_package
+ source = `package my_package
@(objc_class="NSWindow")
Window :: struct { dummy: int}
@@ -91,7 +91,7 @@ objc_return_type_with_selector_expression_2 :: proc(t: ^testing.T) {
t,
&source,
"->",
- {"Window.initWithContentRect: my_package.Window_initWithContentRect :: proc(self: ^Window, contentRect: Rect, styleMask: WindowStyleMask, backing: BackingStoreType, doDefer: BOOL) -> ^Window"},
+ {"@(objc_type=Window, objc_name=\"initWithContentRect\")\nWindow.initWithContentRect: my_package.Window_initWithContentRect :: proc(self: ^Window, contentRect: Rect, styleMask: WindowStyleMask, backing: BackingStoreType, doDefer: BOOL) -> ^Window"},
)
}
@@ -104,7 +104,7 @@ objc_hover_chained_selector :: proc(t: ^testing.T) {
&packages,
test.Package {
pkg = "my_package",
- source = `package my_package
+ source = `package my_package
@(objc_class="NSWindow")
Window :: struct { dummy: int}
@@ -141,7 +141,7 @@ objc_hover_chained_selector :: proc(t: ^testing.T) {
test.expect_hover(
t,
&source,
- "Window.initWithContentRect: my_package.Window_initWithContentRect :: proc(self: ^Window, contentRect: Rect, styleMask: WindowStyleMask, backing: BackingStoreType, doDefer: BOOL) -> ^Window",
+ "@(objc_type=Window, objc_name=\"initWithContentRect\")\nWindow.initWithContentRect: my_package.Window_initWithContentRect :: proc(self: ^Window, contentRect: Rect, styleMask: WindowStyleMask, backing: BackingStoreType, doDefer: BOOL) -> ^Window",
)
}
@@ -153,7 +153,7 @@ objc_implicit_enum_completion :: proc(t: ^testing.T) {
&packages,
test.Package {
pkg = "my_package",
- source = `package my_package
+ source = `package my_package
My_Enum :: enum {
Regular = 0,
Accessory = 1,
diff --git a/tests/signatures_test.odin b/tests/signatures_test.odin
index 32e5e17..4362d32 100644
--- a/tests/signatures_test.odin
+++ b/tests/signatures_test.odin
@@ -401,7 +401,7 @@ ast_index_builtin_len_proc :: proc(t: ^testing.T) {
test.expect_signature_labels(
t,
&source,
- {"$builtin.len: proc(array: Array_Type) -> int"},
+ {"@(builtin)\n$builtin.len: proc(array: Array_Type) -> int"},
)
}