aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2025-07-16 00:39:54 +0200
committerGitHub <noreply@github.com>2025-07-16 00:39:54 +0200
commit38089237530bad6b009df5d73d787bd077b38b93 (patch)
treec0c3d4ad8b90651e710fa6e1ba8caffff6f9fc7c /src/server
parent5dcf2252629655d45ea4e3169f003b4010665fd6 (diff)
parentc44d3222d470f5a83637260cd8f9a06fd52d7f03 (diff)
Merge pull request #751 from BradLewis/feat/resolve-named-parameters
Resolve named procedure params
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin97
-rw-r--r--src/server/completion.odin2
-rw-r--r--src/server/definition.odin20
-rw-r--r--src/server/documentation.odin8
-rw-r--r--src/server/file_resolve.odin8
-rw-r--r--src/server/hover.odin50
-rw-r--r--src/server/references.odin15
-rw-r--r--src/server/symbol.odin50
-rw-r--r--src/server/type_definition.odin66
9 files changed, 225 insertions, 91 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 0c3178a..2bd6717 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -649,31 +649,6 @@ get_unnamed_arg_count :: proc(args: []^ast.Expr) -> int {
return total
}
-get_procedure_arg_count :: proc(v: SymbolProcedureValue) -> int {
- total := 0
- for proc_arg in v.arg_types {
- for name in proc_arg.names {
- total += 1
- }
- }
- return total
-}
-
-// Gets the call argument type at the specified index
-get_proc_call_argument_type :: proc(value: SymbolProcedureValue, parameter_index: int) -> (^ast.Field, bool) {
- index := 0
- for arg in value.arg_types {
- for name in arg.names {
- if index == parameter_index {
- return arg, true
- }
- index += 1
- }
- }
-
- return nil, false
-}
-
/*
Figure out which function the call expression is using out of the list from proc group
*/
@@ -712,7 +687,7 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
named := false
if !resolve_all_possibilities {
- arg_count := get_procedure_arg_count(procedure)
+ arg_count := get_proc_arg_count(procedure)
if call_expr != nil && arg_count < call_unnamed_arg_count {
break next_fn
}
@@ -2238,6 +2213,76 @@ resolve_location_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -
return {}, false
}
+resolve_location_proc_param_name :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+) -> (
+ symbol: Symbol,
+ ok: bool,
+) {
+ ident := position_context.field_value.field.derived.(^ast.Ident) or_return
+ call := position_context.call.derived.(^ast.Call_Expr) or_return
+ symbol = resolve_type_expression(ast_context, call) or_return
+
+ reset_ast_context(ast_context)
+ if value, ok := symbol.value.(SymbolProcedureValue); ok {
+ if arg_name, ok := get_proc_arg_name_from_name(value, ident.name); ok {
+ symbol.range = common.get_token_range(arg_name, ast_context.file.src)
+ }
+ }
+ return symbol, true
+}
+
+resolve_type_location_proc_param_name :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+) -> (
+ call_symbol: Symbol,
+ ok: bool,
+) {
+ ident := position_context.field_value.field.derived.(^ast.Ident) or_return
+ call := position_context.call.derived.(^ast.Call_Expr) or_return
+ call_symbol = resolve_type_expression(ast_context, call) or_return
+
+ reset_ast_context(ast_context)
+ if value, ok := call_symbol.value.(SymbolProcedureValue); ok {
+ if symbol, ok := resolve_type_expression(ast_context, position_context.field_value.value); ok {
+ symbol.type_pkg = symbol.pkg
+ symbol.type_name = symbol.name
+ symbol.pkg = call_symbol.name
+ symbol.name = ident.name
+ return symbol, true
+ }
+ }
+ return call_symbol, false
+}
+
+// resolves the underlying location of type of the named param
+resolve_location_proc_param_name_type :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+) -> (
+ call_symbol: Symbol,
+ ok: bool,
+) {
+ ident := position_context.field_value.field.derived.(^ast.Ident) or_return
+ call := position_context.call.derived.(^ast.Call_Expr) or_return
+ call_symbol = resolve_type_expression(ast_context, call) or_return
+
+ reset_ast_context(ast_context)
+ if value, ok := call_symbol.value.(SymbolProcedureValue); ok {
+ if arg_type, ok := get_proc_arg_type_from_name(value, ident.name); ok {
+ if symbol, ok := resolve_location_type_expression(ast_context, arg_type.type); ok {
+ return symbol, true
+ }
+ }
+ if symbol, ok := resolve_location_type_expression(ast_context, position_context.field_value.value); ok {
+ return symbol, true
+ }
+ }
+ return call_symbol, false
+}
+
resolve_location_comp_lit_field :: proc(
ast_context: ^AstContext,
position_context: ^DocumentPositionContext,
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 1381967..59f6a6c 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -1171,7 +1171,7 @@ get_implicit_completion :: proc(
}
if proc_value, ok := symbol.value.(SymbolProcedureValue); ok {
- arg_type, arg_type_ok := get_proc_call_argument_type(proc_value, parameter_index)
+ arg_type, arg_type_ok := get_proc_arg_type_from_index(proc_value, parameter_index)
if !arg_type_ok {
return
}
diff --git a/src/server/definition.odin b/src/server/definition.odin
index ffd6cc0..c793f32 100644
--- a/src/server/definition.odin
+++ b/src/server/definition.odin
@@ -106,14 +106,22 @@ get_definition_location :: proc(document: ^Document, position: common.Position)
return {}, false
}
} else if position_context.field_value != nil &&
- position_context.comp_lit != nil &&
!is_expr_basic_lit(position_context.field_value.field) &&
position_in_node(position_context.field_value.field, position_context.position) {
- if resolved, ok := resolve_location_comp_lit_field(&ast_context, &position_context); ok {
- location.range = resolved.range
- uri = resolved.uri
- } else {
- return {}, false
+ if position_context.comp_lit != nil {
+ if resolved, ok := resolve_location_comp_lit_field(&ast_context, &position_context); ok {
+ location.range = resolved.range
+ uri = resolved.uri
+ } else {
+ return {}, false
+ }
+ } else if position_context.call != nil {
+ if resolved, ok := resolve_location_proc_param_name(&ast_context, &position_context); ok {
+ location.range = resolved.range
+ uri = resolved.uri
+ } else {
+ return {}, false
+ }
}
} else if position_context.implicit_selector_expr != nil {
if resolved, ok := resolve_location_implicit_selector(
diff --git a/src/server/documentation.odin b/src/server/documentation.odin
index 86dfe81..417815a 100644
--- a/src/server/documentation.odin
+++ b/src/server/documentation.odin
@@ -149,16 +149,16 @@ get_signature :: proc(ast_context: ^AstContext, symbol: Symbol) -> string {
return strings.to_string(sb)
case SymbolStructValue:
sb := strings.builder_make(ast_context.allocator)
- if is_variable {
- append_variable_full_name(&sb, ast_context, symbol, pointer_prefix)
- strings.write_string(&sb, " :: ")
- } else if symbol.type_name != "" {
+ if symbol.type_name != "" {
if symbol.type_pkg == "" {
fmt.sbprintf(&sb, "%s%s :: ", pointer_prefix, symbol.type_name)
} else {
pkg_name := get_pkg_name(ast_context, symbol.type_pkg)
fmt.sbprintf(&sb, "%s%s.%s :: ", pointer_prefix, pkg_name, symbol.type_name)
}
+ } else if is_variable {
+ append_variable_full_name(&sb, ast_context, symbol, pointer_prefix)
+ strings.write_string(&sb, " :: ")
}
if len(v.names) == 0 {
strings.write_string(&sb, "struct {}")
diff --git a/src/server/file_resolve.odin b/src/server/file_resolve.odin
index 70a4b99..e930f9d 100644
--- a/src/server/file_resolve.odin
+++ b/src/server/file_resolve.odin
@@ -229,6 +229,14 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) {
}
resolve_node(n.value, data)
+ } else if data.flag != .None && data.position_context.call != nil {
+ if symbol, ok := resolve_location_proc_param_name(data.ast_context, data.position_context); ok {
+ data.symbols[cast(uintptr)node] = SymbolAndNode {
+ node = n.field,
+ symbol = symbol,
+ }
+ }
+ resolve_node(n.value, data)
} else {
resolve_node(n.field, data)
resolve_node(n.value, data)
diff --git a/src/server/hover.odin b/src/server/hover.odin
index 9d8519c..f23bc23 100644
--- a/src/server/hover.odin
+++ b/src/server/hover.odin
@@ -201,10 +201,8 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
symbol.type_pkg = symbol.pkg
symbol.pkg = bit_field_symbol.name
symbol.name = identifier.name
- if value, ok := bit_field_symbol.value.(SymbolBitFieldValue); ok {
- symbol.comment = get_comment(value.comments[i])
- symbol.doc = get_doc(value.docs[i], context.temp_allocator)
- }
+ symbol.comment = get_comment(value.comments[i])
+ symbol.doc = get_doc(value.docs[i], context.temp_allocator)
symbol.signature = get_bit_field_field_signature(value, i)
hover.contents = write_hover_content(&ast_context, symbol)
return hover, true, true
@@ -217,11 +215,25 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
}
}
- if position_context.field_value != nil && position_context.comp_lit != nil {
- if comp_symbol, ok := resolve_comp_literal(&ast_context, &position_context); ok {
- if field, ok := position_context.field_value.field.derived.(^ast.Ident); ok {
- if position_in_node(field, position_context.position) {
- if v, ok := comp_symbol.value.(SymbolStructValue); ok {
+ if position_context.field_value != nil && position_in_node(position_context.field_value.field, position_context.position) {
+ if position_context.comp_lit != nil {
+ if comp_symbol, ok := resolve_comp_literal(&ast_context, &position_context); ok {
+ if field, ok := position_context.field_value.field.derived.(^ast.Ident); ok {
+ if position_in_node(field, position_context.position) {
+ if v, ok := comp_symbol.value.(SymbolStructValue); ok {
+ for name, i in v.names {
+ if name == field.name {
+ if symbol, ok := resolve_type_expression(&ast_context, v.types[i]); ok {
+ symbol.name = name
+ symbol.pkg = comp_symbol.name
+ symbol.signature = node_to_string(v.types[i])
+ hover.contents = write_hover_content(&ast_context, symbol)
+ return hover, true, true
+ }
+ }
+ }
+ }
+ } else if v, ok := comp_symbol.value.(SymbolBitFieldValue); ok {
for name, i in v.names {
if name == field.name {
if symbol, ok := resolve_type_expression(&ast_context, v.types[i]); ok {
@@ -234,21 +246,17 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
}
}
}
- } else if v, ok := comp_symbol.value.(SymbolBitFieldValue); ok {
- for name, i in v.names {
- if name == field.name {
- if symbol, ok := resolve_type_expression(&ast_context, v.types[i]); ok {
- symbol.name = name
- symbol.pkg = comp_symbol.name
- symbol.signature = node_to_string(v.types[i])
- hover.contents = write_hover_content(&ast_context, symbol)
- return hover, true, true
- }
- }
- }
}
}
}
+
+ if position_context.call != nil {
+ if symbol, ok := resolve_type_location_proc_param_name(&ast_context, &position_context); ok {
+ symbol.signature = get_signature(&ast_context, symbol)
+ hover.contents = write_hover_content(&ast_context, symbol)
+ return hover, true, true
+ }
+ }
}
if position_context.selector != nil &&
diff --git a/src/server/references.odin b/src/server/references.odin
index 7e791b8..230243a 100644
--- a/src/server/references.odin
+++ b/src/server/references.odin
@@ -145,13 +145,18 @@ prepare_references :: proc(
}
} else if position_context.field_value != nil &&
- position_context.comp_lit != nil &&
!is_expr_basic_lit(position_context.field_value.field) &&
position_in_node(position_context.field_value.field, position_context.position) {
- symbol, ok = resolve_location_comp_lit_field(ast_context, position_context)
-
- if !ok {
- return
+ if position_context.comp_lit != nil {
+ symbol, ok = resolve_location_comp_lit_field(ast_context, position_context)
+ if !ok {
+ return
+ }
+ } else if position_context.call != nil {
+ symbol, ok = resolve_location_proc_param_name(ast_context, position_context)
+ if !ok {
+ return
+ }
}
resolve_flag = .Field
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 08a6788..b65349c 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -525,6 +525,56 @@ expand_objc :: proc(ast_context: ^AstContext, b: ^SymbolStructValueBuilder) {
}
}
+get_proc_arg_count :: proc(v: SymbolProcedureValue) -> int {
+ total := 0
+ for proc_arg in v.arg_types {
+ for name in proc_arg.names {
+ total += 1
+ }
+ }
+ return total
+}
+
+// Gets the call argument type at the specified index
+get_proc_arg_type_from_index :: proc(value: SymbolProcedureValue, parameter_index: int) -> (^ast.Field, bool) {
+ index := 0
+ for arg in value.arg_types {
+ for name in arg.names {
+ if index == parameter_index {
+ return arg, true
+ }
+ index += 1
+ }
+ }
+ return nil, false
+}
+
+get_proc_arg_type_from_name :: proc(v: SymbolProcedureValue, name: string) -> (^ast.Field, bool) {
+ for arg in v.arg_types {
+ for arg_name in arg.names {
+ if ident, ok := arg_name.derived.(^ast.Ident); ok {
+ if name == ident.name {
+ return arg, true
+ }
+ }
+ }
+ }
+ return nil, false
+}
+
+get_proc_arg_name_from_name :: proc(v: SymbolProcedureValue, name: string) -> (^ast.Ident, bool) {
+ for arg in v.arg_types {
+ for arg_name in arg.names {
+ if ident, ok := arg_name.derived.(^ast.Ident); ok {
+ if name == ident.name {
+ return ident, true
+ }
+ }
+ }
+ }
+ return nil, false
+}
+
new_clone_symbol :: proc(data: Symbol, allocator := context.allocator) -> ^Symbol {
new_symbol := new(Symbol, allocator)
new_symbol^ = data
diff --git a/src/server/type_definition.odin b/src/server/type_definition.odin
index 900c060..94fb211 100644
--- a/src/server/type_definition.odin
+++ b/src/server/type_definition.odin
@@ -66,6 +66,44 @@ get_type_definition_locations :: proc(document: ^Document, position: common.Posi
}
}
+ if position_context.field_value != nil && position_in_node(position_context.field_value.field, position_context.position) {
+ if position_context.comp_lit != nil {
+ if comp_symbol, ok := resolve_comp_literal(&ast_context, &position_context); ok {
+ if field, ok := position_context.field_value.field.derived.(^ast.Ident); ok {
+ if position_in_node(field, position_context.position) {
+ if v, ok := comp_symbol.value.(SymbolStructValue); ok {
+ for name, i in v.names {
+ if name == field.name {
+ if symbol, ok := resolve_location_type_expression(&ast_context, v.types[i]); ok {
+ append_symbol_to_locations(&locations, document, symbol)
+ return locations[:], true
+ }
+ }
+ }
+ }
+ } else if v, ok := comp_symbol.value.(SymbolBitFieldValue); ok {
+ for name, i in v.names {
+ if name == field.name {
+ if symbol, ok := resolve_type_expression(&ast_context, v.types[i]); ok {
+ append_symbol_to_locations(&locations, document, symbol)
+ return locations[:], true
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if position_context.call != nil {
+ if symbol, ok := resolve_location_proc_param_name_type(&ast_context, &position_context); ok {
+ append_symbol_to_locations(&locations, document, symbol)
+ return locations[:], true
+ }
+ }
+ }
+
+
if position_context.call != nil {
if call, ok := position_context.call.derived.(^ast.Call_Expr); ok {
if !position_in_exprs(call.args, position_context.position) {
@@ -97,34 +135,6 @@ get_type_definition_locations :: proc(document: ^Document, position: common.Posi
}
}
- if position_context.field_value != nil && position_context.comp_lit != nil {
- if comp_symbol, ok := resolve_comp_literal(&ast_context, &position_context); ok {
- if field, ok := position_context.field_value.field.derived.(^ast.Ident); ok {
- if position_in_node(field, position_context.position) {
- if v, ok := comp_symbol.value.(SymbolStructValue); ok {
- for name, i in v.names {
- if name == field.name {
- if symbol, ok := resolve_location_type_expression(&ast_context, v.types[i]); ok {
- append_symbol_to_locations(&locations, document, symbol)
- return locations[:], true
- }
- }
- }
- }
- } else if v, ok := comp_symbol.value.(SymbolBitFieldValue); ok {
- for name, i in v.names {
- if name == field.name {
- if symbol, ok := resolve_type_expression(&ast_context, v.types[i]); ok {
- append_symbol_to_locations(&locations, document, symbol)
- return locations[:], true
- }
- }
- }
- }
- }
- }
- }
-
if position_context.selector != nil &&
position_context.identifier != nil &&
position_context.field == position_context.identifier {