c argument names in bindings

This commit is contained in:
2026-06-25 08:28:30 +02:00
parent 9d1130b359
commit c08bc6d0cc
9 changed files with 84 additions and 19 deletions
+34 -3
View File
@@ -5814,7 +5814,8 @@ translate_c_emits_native_bindings_and_round_trips :: proc(t: ^testing.T) {
append(&result.aliases, cimport.Alias{name = "Mapper", type = cimport.Type_Id(4)})
add_params := []cimport.Type_Id{cimport.Type_Id(0), cimport.Type_Id(0)}
append(&result.functions, cimport.Function{name = "imported_add", params = add_params, result = cimport.Type_Id(0)})
add_param_names := []string{"a", "b"}
append(&result.functions, cimport.Function{name = "imported_add", params = add_params, param_names = add_param_names, result = cimport.Type_Id(0)})
append(&result.macros, cimport.Macro_Constant{
name = "MAX_LEN",
@@ -5844,8 +5845,10 @@ translate_c_emits_native_bindings_and_round_trips :: proc(t: ^testing.T) {
testing.expect(t, strings.contains(output, "\tleft c_int"))
testing.expect(t, strings.contains(output, "\tright c_int"))
testing.expect(t, strings.contains(output, "Size :: alias c_ulong"))
testing.expect(t, strings.contains(output, "Mapper :: alias ?*c_func(arg0 c_int) c_int"))
testing.expect(t, strings.contains(output, "imported_add :: c_func(arg0 c_int, arg1 c_int) c_int"))
// Function-pointer types carry no parameter names, so the callback renders `_`.
testing.expect(t, strings.contains(output, "Mapper :: alias ?*c_func(_ c_int) c_int"))
// Real C parameter names are used when present.
testing.expect(t, strings.contains(output, "imported_add :: c_func(a c_int, b c_int) c_int"))
testing.expect(t, strings.contains(output, "MAX_LEN c_int :: 256"))
testing.expect(t, strings.contains(output, "# unsupported in bindings: C union 'Choice'"))
testing.expect(t, strings.contains(output, "# unsupported in bindings: external variable 'some_global'"))
@@ -5864,3 +5867,31 @@ translate_c_emits_native_bindings_and_round_trips :: proc(t: ^testing.T) {
defer ast.destroy_module(&module)
testing.expect_value(t, len(diagnostics.items), 0)
}
@(test)
sink_named_parameters_are_allowed_and_not_duplicates :: proc(t: ^testing.T) {
// Generated bindings use `_` for unnamed C params; the parser must accept it and
// the checker must not flag repeated `_` as duplicate parameters.
text := `foo :: c_func(_ c_int, _ c_int) c_int
main :: func() void {
_ = foo(1, 2)
}
`
source_file := source.Source{path = "test.bro", text = text}
diagnostics := source.init_diagnostics(&source_file)
defer source.destroy_diagnostics(&diagnostics)
symbols := symbol.init_table()
defer symbol.destroy_table(&symbols)
stream := lexer.lex(&source_file, &diagnostics, &symbols)
defer delete(stream.items)
ast_module := parser.parse(&stream, &source_file, &diagnostics)
defer ast.destroy_module(&ast_module)
hir_module := checker.check(&ast_module, &diagnostics, &symbols)
defer hir.destroy_module(&hir_module)
for diagnostic in diagnostics.items {
testing.expect(t, !strings.contains(diagnostic.message, "duplicate parameter"))
testing.expect(t, !strings.contains(diagnostic.message, "expected parameter name"))
}
testing.expect_value(t, len(diagnostics.items), 0)
}