Commit b2fd797b authored by Rico Tzschichholz's avatar Rico Tzschichholz

codegen: Add "error_pos" CCode attribute and use it as needed

This makes it possible to use non-standard error parameter positions
within the vala source.

Fixes #728
parent 704188bf
......@@ -276,6 +276,10 @@ namespace Vala {
}
}
public static double get_ccode_error_pos (Callable c) {
return c.get_attribute_double ("CCode", "error_pos", -1);
}
public static bool get_ccode_array_length (CodeNode node) {
return get_ccode_attribute(node).array_length;
}
......
......@@ -94,7 +94,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
}
if (d.tree_can_fail) {
var cparam = new CCodeParameter ("error", "GError**");
cparam_map.set (get_param_pos (-1), cparam);
cparam_map.set (get_param_pos (get_ccode_error_pos (d)), cparam);
}
// append C parameters in the right order
......@@ -258,7 +258,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
if (m.tree_can_fail) {
var cparam = new CCodeParameter ("error", "GError**");
cparam_map.set (get_param_pos (-1), cparam);
cparam_map.set (get_param_pos (get_ccode_error_pos (d)), cparam);
}
// append C parameters in the right order
......@@ -381,7 +381,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
}
if (m.tree_can_fail) {
carg_map.set (get_param_pos (-1), new CCodeIdentifier ("error"));
carg_map.set (get_param_pos (get_ccode_error_pos (m)), new CCodeIdentifier ("error"));
}
var ccall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_name (m)));
......
......@@ -631,10 +631,10 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
// method can fail
current_method_inner_error = true;
// add &inner_error before the ellipsis arguments
out_arg_map.set (get_param_pos (-1), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression ("_inner_error_")));
out_arg_map.set (get_param_pos (get_ccode_error_pos ((Callable) m ?? deleg)), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression ("_inner_error_")));
} else if (m != null && m.has_error_type_parameter () && async_call != ccall) {
// inferred error argument from base method
out_arg_map.set (get_param_pos (-1), new CCodeConstant ("NULL"));
out_arg_map.set (get_param_pos (get_ccode_error_pos (m)), new CCodeConstant ("NULL"));
}
if (ellipsis) {
......
......@@ -116,9 +116,9 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
}
var cparam = new CCodeParameter ("error", "GError**");
cparam_map.set (get_param_pos (-1), cparam);
cparam_map.set (get_param_pos (get_ccode_error_pos (m)), cparam);
if (carg_map != null) {
carg_map.set (get_param_pos (-1), new CCodeIdentifier (cparam.name));
carg_map.set (get_param_pos (get_ccode_error_pos (m)), new CCodeIdentifier (cparam.name));
}
}
}
......
......@@ -234,6 +234,7 @@ TESTS = \
delegates/delegate_only.vala \
delegates/delegates.vala \
delegates/delegates-error.test \
delegates/error-pos.vala \
delegates/fields.vala \
delegates/fields-no-target.vala \
delegates/instance-method-to-no-target.test \
......
errordomain FooError {
BAR;
}
[CCode (error_pos = 1.8, instance_pos = 1.9)]
delegate string FooFunc (int i) throws FooError;
class Bar {
[CCode (error_pos = 0.8)]
public string foo (int i) throws FooError {
assert (this is Bar);
return "%i".printf (i);
}
[CCode (error_pos = 0.8)]
public string faz (int i) throws FooError {
assert (this is Bar);
throw new FooError.BAR ("%i".printf (i));
}
}
void foo (FooFunc f) {
try {
assert (f (23) == "23");
} catch {
assert_not_reached ();
}
}
void main () {
try {
var bar = new Bar ();
assert (bar.foo (42) == "42");
foo (bar.foo);
} catch {
assert_not_reached ();
}
try {
var bar = new Bar ();
bar.faz (42);
} catch (FooError.BAR e) {
assert (e.message == "42");
} catch {
assert_not_reached ();
}
}
......@@ -40,7 +40,7 @@ public class Vala.UsedAttr : CodeVisitor {
"array_length_type", "array_length", "array_length_cname", "array_length_cexpr", "array_null_terminated",
"vfunc_name", "finish_vfunc_name", "finish_name", "free_function_address_of", "pos", "delegate_target", "delegate_target_cname",
"array_length_pos", "delegate_target_pos", "destroy_notify_pos", "ctype", "has_new_function", "notify", "finish_instance",
"use_inplace", "feature_test_macro", "default_value_on_error", "async_result_pos", "",
"use_inplace", "feature_test_macro", "default_value_on_error", "async_result_pos", "error_pos", "",
"Immutable", "",
"SingleInstance", "",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment