aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2025-07-23 11:01:48 +0200
committerGitHub <noreply@github.com>2025-07-23 11:01:48 +0200
commitd08d5e3fe533fef482281f660177ec3f6c86b495 (patch)
tree6a6d651195671b9c802ad6ab39534175cbcefd2a /src/server
parent2155d374c1466cc3e93d4c92b9c56878ba7de185 (diff)
parent923e83bced40223abb3ff1be69f2a910b4d2c004 (diff)
Merge pull request #762 from BradLewis/feat/add-calling-convention-attributes-proc-hover
Add proc directives, calling convention and attributes to the hover information
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin28
-rw-r--r--src/server/clone.odin16
-rw-r--r--src/server/collector.odin26
-rw-r--r--src/server/documentation.odin73
-rw-r--r--src/server/symbol.odin16
5 files changed, 133 insertions, 26 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 2edae61..c4d62b6 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -380,7 +380,7 @@ are_symbol_untyped_basic_same_typed :: proc(a, b: Symbol) -> (bool, bool) {
switch untyped.type {
case .Integer:
switch basic.ident.name {
- case "int", "uint", "u32", "i32", "u8", "i8", "u64", "u16", "i16":
+ case "int", "uint", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "u128", "i128":
return true, true
case:
return false, true
@@ -1038,7 +1038,7 @@ internal_resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Ex
case ^Map_Type:
return make_symbol_map_from_ast(ast_context, v^, ast_context.field_name), true
case ^Proc_Type:
- return make_symbol_procedure_from_ast(ast_context, node, v^, ast_context.field_name, {}, true), true
+ return make_symbol_procedure_from_ast(ast_context, node, v^, ast_context.field_name, {}, true, .None), true
case ^Bit_Field_Type:
return make_symbol_bit_field_from_ast(ast_context, v, ast_context.field_name, true), true
case ^Basic_Directive:
@@ -1518,11 +1518,11 @@ internal_resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ide
if !ok && !ast_context.overloading {
return_symbol, ok =
- make_symbol_procedure_from_ast(ast_context, local.rhs, v.type^, node, {}, false), true
+ make_symbol_procedure_from_ast(ast_context, local.rhs, v.type^, node, {}, false, v.inlining), true
}
} else {
return_symbol, ok =
- make_symbol_procedure_from_ast(ast_context, local.rhs, v.type^, node, {}, false), true
+ make_symbol_procedure_from_ast(ast_context, local.rhs, v.type^, node, {}, false, v.inlining), true
}
case ^Proc_Group:
return_symbol, ok = resolve_function_overload(ast_context, v^)
@@ -1655,12 +1655,13 @@ internal_resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ide
node,
global.attributes,
false,
+ v.inlining,
),
true
}
} else {
return_symbol, ok =
- make_symbol_procedure_from_ast(ast_context, global.expr, v.type^, node, global.attributes, false),
+ make_symbol_procedure_from_ast(ast_context, global.expr, v.type^, node, global.attributes, false, v.inlining),
true
}
case ^Proc_Group:
@@ -2763,6 +2764,7 @@ make_symbol_procedure_from_ast :: proc(
name: ast.Ident,
attributes: []^ast.Attribute,
type: bool,
+ inlining: ast.Proc_Inlining,
) -> Symbol {
symbol := Symbol {
range = common.get_token_range(name, ast_context.file.src),
@@ -2794,12 +2796,16 @@ make_symbol_procedure_from_ast :: proc(
}
symbol.value = SymbolProcedureValue {
- return_types = return_types[:],
- orig_return_types = return_types[:],
- arg_types = arg_types[:],
- orig_arg_types = arg_types[:],
- generic = v.generic,
- diverging = v.diverging,
+ return_types = return_types[:],
+ orig_return_types = return_types[:],
+ arg_types = arg_types[:],
+ orig_arg_types = arg_types[:],
+ generic = v.generic,
+ diverging = v.diverging,
+ calling_convention = v.calling_convention,
+ tags = v.tags,
+ attributes = attributes,
+ inlining = inlining,
}
if _, ok := get_attribute_objc_name(attributes); ok {
diff --git a/src/server/clone.odin b/src/server/clone.odin
index 7baec58..3fdebdb 100644
--- a/src/server/clone.odin
+++ b/src/server/clone.odin
@@ -300,3 +300,19 @@ clone_comment_group :: proc(
) -> ^ast.Comment_Group {
return cast(^ast.Comment_Group)clone_node(node, allocator, unique_strings)
}
+
+clone_calling_convention :: proc(
+ cc: ast.Proc_Calling_Convention, allocator: mem.Allocator, unique_strings: ^map[string]string,
+) -> ast.Proc_Calling_Convention {
+ if cc == nil {
+ return nil
+ }
+
+ switch v in cc {
+ case string:
+ return get_index_unique_string(unique_strings, allocator, v)
+ case ast.Proc_Calling_Convention_Extra:
+ return v
+ }
+ return nil
+}
diff --git a/src/server/collector.odin b/src/server/collector.odin
index 1995d54..6bad491 100644
--- a/src/server/collector.odin
+++ b/src/server/collector.odin
@@ -84,9 +84,11 @@ collect_procedure_fields :: proc(
return_list: ^ast.Field_List,
package_map: map[string]string,
attributes: []^ast.Attribute,
+ inlining: ast.Proc_Inlining,
) -> 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,13 +106,23 @@ 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[:],
- arg_types = args[:],
- orig_arg_types = args[:],
- generic = is_procedure_generic(proc_type),
- diverging = proc_type.diverging,
+ return_types = returns[:],
+ orig_return_types = returns[:],
+ arg_types = args[:],
+ orig_arg_types = args[:],
+ generic = is_procedure_generic(proc_type),
+ diverging = proc_type.diverging,
+ calling_convention = clone_calling_convention(proc_type.calling_convention, collection.allocator, &collection.unique_strings),
+ tags = proc_type.tags,
+ attributes = attrs[:],
+ inlining = inlining,
}
return value
@@ -501,6 +513,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
v.type.results,
package_map,
expr.attributes,
+ v.inlining,
)
}
@@ -520,6 +533,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
v.results,
package_map,
expr.attributes,
+ .None,
)
case ^ast.Proc_Group:
token = v^
diff --git a/src/server/documentation.odin b/src/server/documentation.odin
index cd22b90..c57e078 100644
--- a/src/server/documentation.odin
+++ b/src/server/documentation.odin
@@ -233,12 +233,20 @@ get_signature :: proc(ast_context: ^AstContext, symbol: ^Symbol) -> string {
for symbol in v.symbols {
if value, ok := symbol.value.(SymbolProcedureValue); ok {
fmt.sbprintf(&sb, "\t%s :: ", symbol.name)
- write_procedure_symbol_signature(&sb, value)
+ write_procedure_symbol_signature(&sb, value, detailed_signature=false)
strings.write_string(&sb, ",\n")
}
}
strings.write_string(&sb, "}")
return strings.to_string(sb)
+ case SymbolProcedureValue:
+ sb := strings.builder_make(ast_context.allocator)
+ if symbol.type_pkg != "" && symbol.type_name != "" {
+ pkg_name := get_pkg_name(ast_context, symbol.type_pkg)
+ fmt.sbprintf(&sb, "%s%s.%s :: ", pointer_prefix, pkg_name, symbol.type_name)
+ }
+ write_procedure_symbol_signature(&sb, v, detailed_signature=true)
+ return strings.to_string(sb)
case SymbolBitFieldValue:
sb := strings.builder_make(ast_context.allocator)
if is_variable {
@@ -342,7 +350,7 @@ get_short_signature :: proc(ast_context: ^AstContext, symbol: ^Symbol) -> string
pkg_name := get_pkg_name(ast_context, symbol.type_pkg)
fmt.sbprintf(&sb, "%s%s.%s :: ", pointer_prefix, pkg_name, symbol.type_name)
}
- write_procedure_symbol_signature(&sb, v)
+ write_procedure_symbol_signature(&sb, v, detailed_signature=false)
return strings.to_string(sb)
case SymbolAggregateValue:
return "proc"
@@ -463,8 +471,18 @@ write_symbol_type_information :: proc(ast_context: ^AstContext, sb: ^strings.Bui
}
}
-write_procedure_symbol_signature :: proc(sb: ^strings.Builder, value: SymbolProcedureValue) {
+write_procedure_symbol_signature :: proc(sb: ^strings.Builder, value: SymbolProcedureValue, detailed_signature: bool) {
+ if detailed_signature {
+ if value.inlining == .Inline {
+ strings.write_string(sb, "#force_inline ")
+ } else if value.inlining == .No_Inline {
+ strings.write_string(sb, "#force_no_inline ")
+ }
+ }
strings.write_string(sb, "proc")
+ if s, ok := value.calling_convention.(string); ok && detailed_signature {
+ fmt.sbprintf(sb, " %s ", s)
+ }
strings.write_string(sb, "(")
for arg, i in value.orig_arg_types {
build_string_node(arg, sb, false)
@@ -494,6 +512,23 @@ write_procedure_symbol_signature :: proc(sb: ^strings.Builder, value: SymbolProc
} else if value.diverging {
strings.write_string(sb, " -> !")
}
+ if detailed_signature {
+ for tag in value.tags {
+ s := ""
+ switch tag {
+ case .Optional_Ok:
+ s = "#optional_ok"
+ case .Optional_Allocator_Error:
+ s = "#optional_allocator_error"
+ case .Bounds_Check:
+ s = "#bounds_check"
+ case .No_Bounds_Check:
+ s = "#no_bounds_check"
+ }
+
+ fmt.sbprintf(sb, " %s", s)
+ }
+ }
}
write_struct_hover :: proc(ast_context: ^AstContext, sb: ^strings.Builder, v: SymbolStructValue) {
@@ -625,6 +660,38 @@ 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)
+ 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 b65349c..9d95ca1 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -51,12 +51,16 @@ SymbolPackageValue :: struct {
}
SymbolProcedureValue :: struct {
- return_types: []^ast.Field,
- arg_types: []^ast.Field,
- orig_return_types: []^ast.Field, //When generics have overloaded the types, we store the original version here.
- orig_arg_types: []^ast.Field, //When generics have overloaded the types, we store the original version here.
- generic: bool,
- diverging: bool,
+ return_types: []^ast.Field,
+ arg_types: []^ast.Field,
+ orig_return_types: []^ast.Field, //When generics have overloaded the types, we store the original version here.
+ orig_arg_types: []^ast.Field, //When generics have overloaded the types, we store the original version here.
+ generic: bool,
+ diverging: bool,
+ calling_convention: ast.Proc_Calling_Convention,
+ tags: ast.Proc_Tags,
+ attributes: []^ast.Attribute,
+ inlining: ast.Proc_Inlining,
}
SymbolProcedureGroupValue :: struct {