Although setting them is not supported yet.
Fixes https://gitlab.gnome.org/GNOME/vala/issues/636
bool capturing_parameter_in_coroutine = capturing_parameter && is_in_coroutine ();
+ if (capturing_parameter_in_coroutine && param.sync_arg) {
+ Report.error (source_reference, "Assigning synchronous out-parameters of async methods is not supported yet.");
+ return;
+ }
+
var param_type = param.variable_type.copy ();
if (param.captured || is_in_coroutine ()) {
if (!param_type.value_owned && !no_implicit_copy (param_type)) {
param = params_it.get ();
ellipsis = param.ellipsis;
if (!ellipsis) {
- if (param.direction == ParameterDirection.OUT) {
+ if (param.direction == ParameterDirection.OUT && !param.sync_arg) {
carg_map = out_arg_map;
}
CCodeParameter? prev_cparam = null;
foreach (Parameter param in m.get_parameters ()) {
- if (param.direction != ParameterDirection.OUT) {
+ if (param.direction != ParameterDirection.OUT || param.sync_arg) {
if ((direction & 1) == 0) {
// no in parameters
continue;
}
- } else {
+ } else if (!param.sync_arg) {
if ((direction & 2) == 0) {
// no out parameters
continue;
}
foreach (Parameter param in m.get_parameters ()) {
+ if (param.direction == ParameterDirection.OUT && param.sync_arg) {
+ continue;
+ }
+
bool is_unowned_delegate = param.variable_type is DelegateType && !param.variable_type.value_owned;
var param_type = param.variable_type.copy ();
emit_context.push_symbol (m);
foreach (Parameter param in m.get_parameters ()) {
- if (param.direction != ParameterDirection.IN) {
+ if (param.direction != ParameterDirection.IN && !param.sync_arg) {
return_out_parameter (param);
if (!(param.variable_type is ValueType) || param.variable_type.nullable) {
ccode.add_assignment (new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)), new CCodeConstant ("NULL"));
asynchronous/bug793158.vala \
asynchronous/closures.vala \
asynchronous/generator.vala \
+ asynchronous/sync-args.vala \
asynchronous/yield.vala \
generics/bug694765-1.vala \
generics/bug694765-2.vala \
--- /dev/null
+public interface IFoo : Object {
+ public abstract async string ifunc (int i, out int out_j, string s) throws Error;
+}
+
+public class Foo : Object, IFoo {
+ public async string ifunc (int i, out int out_j, string s) throws Error {
+ assert (i == 23);
+ assert (s == "ifoo");
+ return "result_ifoo";
+ }
+
+ public virtual async string vfunc (int i, out int out_j, string s) throws Error {
+ assert (i == 42);
+ assert (s == "vfoo");
+ return "result_vfoo";
+ }
+
+ public async string func (int i, string s, [SyncArg] out int out_j) throws Error {
+ assert (i == 4711);
+ assert (s == "foo");
+ return "result_foo";
+ }
+}
+
+async void run () {
+ var foo = new Foo ();
+ int i;
+ foo.ifunc.begin (23, out i, "ifoo", (o, r) => {
+ var result = ((Foo) o).ifunc.end (r);
+ assert (result == "result_ifoo");
+ });
+ foo.vfunc.begin (42, out i, "vfoo", (o, r) => {
+ var result = ((Foo) o).ifunc.end (r);
+ assert (result == "result_vfoo");
+ });
+ foo.func.begin (4711, "foo", out i, (o, r) => {
+ var result = ((Foo) o).ifunc.end (r);
+ assert (result == "result_foo");
+ });
+}
+
+void main () {
+ run.begin ();
+}
Method method = m;
+ if (m.coroutine) {
+ var parameters = m.get_parameters ();
+ bool requires_explicit_attribute = true;
+ for (int i = parameters.size - 1; i >= 0; i--) {
+ var param = parameters[i];
+ if (param.direction == ParameterDirection.IN) {
+ requires_explicit_attribute = false;
+ } else {
+ param.sync_arg = true;
+ if (requires_explicit_attribute) {
+ param.set_attribute ("SyncArg", true);
+ requires_explicit_attribute = false;
+ }
+ }
+ }
+ }
+
if (finish_method_node != null && finish_method_node.symbol is Method) {
finish_method_node.process (this);
var finish_method = (Method) finish_method_node.symbol;
Report.error (parameters[0].source_reference, "Named parameter required before `...'");
}
+ // implicitly mark synchronous out-parameter as such
+ if (coroutine) {
+ bool requires_attribute = false;
+ for (int i = parameters.size - 1; i >= 0; i--) {
+ var param = parameters[i];
+ if (param.direction == ParameterDirection.IN) {
+ requires_attribute = true;
+ } else if (requires_attribute) {
+ param.sync_arg = true;
+ }
+ }
+ }
+
var optional_param = false;
foreach (Parameter param in parameters) {
param.check (context);
foreach (var param in parameters) {
if (param.ellipsis) {
ellipsis = param;
- } else if (param.direction == ParameterDirection.IN) {
+ } else if (param.direction == ParameterDirection.IN || param.sync_arg) {
params.add (param);
}
}
params.add (result_param);
foreach (var param in parameters) {
- if (param.direction == ParameterDirection.OUT) {
+ if (param.direction == ParameterDirection.OUT && !param.sync_arg) {
params.add (param);
}
}
}
}
+ public bool sync_arg {
+ get {
+ return _sync_arg || get_attribute ("SyncArg") != null || (base_parameter != null && base_parameter.sync_arg);
+ }
+ set {
+ if (!value) {
+ set_attribute ("SyncArg", false);
+ _sync_arg = false;
+ } else if (direction != ParameterDirection.IN) {
+ _sync_arg = true;
+ }
+ }
+ }
+
/**
* The base parameter of this parameter relative to the base method.
*/
public Parameter base_parameter { get; set; }
+
+ bool _sync_arg = false;
+
/**
* Creates a new formal parameter.
*
"PrintfFormat", "",
"ScanfFormat", "",
"FormatArg", "",
+ "SyncArg", "",
"GtkChild", "name", "internal", "",
"GtkTemplate", "ui", "",