diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2025-07-23 11:01:48 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-23 11:01:48 +0200 |
| commit | d08d5e3fe533fef482281f660177ec3f6c86b495 (patch) | |
| tree | 6a6d651195671b9c802ad6ab39534175cbcefd2a /src | |
| parent | 2155d374c1466cc3e93d4c92b9c56878ba7de185 (diff) | |
| parent | 923e83bced40223abb3ff1be69f2a910b4d2c004 (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')
| -rw-r--r-- | src/server/analysis.odin | 28 | ||||
| -rw-r--r-- | src/server/clone.odin | 16 | ||||
| -rw-r--r-- | src/server/collector.odin | 26 | ||||
| -rw-r--r-- | src/server/documentation.odin | 73 | ||||
| -rw-r--r-- | src/server/symbol.odin | 16 |
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 { |