[vala] girparser: Auto detect real-non-null-struct out parameter as return type
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] girparser: Auto detect real-non-null-struct out parameter as return type
- Date: Fri, 22 Apr 2011 14:13:39 +0000 (UTC)
commit 54216a6e4a17a452c20cff0b1b1706ba07732b0c
Author: Luca Bruno <lucabru src gnome org>
Date: Fri Apr 22 15:02:08 2011 +0200
girparser: Auto detect real-non-null-struct out parameter as return type
vala/valagirparser.vala | 280 +++++++++++++++++++++++++++++------------------
vapi/json-glib-1.0.vapi | 2 +-
2 files changed, 174 insertions(+), 108 deletions(-)
---
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index bde8186..8090b17 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -35,6 +35,7 @@ using GLib;
* 5) Process callbacks/virtual
* 6) Process aliases
* 7) Autoreparent static methods
+ * 8) Process callables
*
* Best hacking practices:
* - Keep GIR parsing bloat-free, it must contain the logic
@@ -519,6 +520,7 @@ public class Vala.GirParser : CodeVisitor {
ArrayList<UnresolvedSymbol> unresolved_gir_symbols = new ArrayList<UnresolvedSymbol> ();
HashMap<UnresolvedSymbol,ArrayList<Symbol>> symbol_reparent_map = new HashMap<UnresolvedSymbol,ArrayList<Symbol>> (unresolved_symbol_hash, unresolved_symbol_equal);
+ ArrayList<CallableInfo> callable_info_list = new ArrayList<CallableInfo> ();
HashMap<Namespace,ArrayList<Method>> namespace_methods = new HashMap<Namespace,ArrayList<Method>> ();
ArrayList<Alias> aliases = new ArrayList<Alias> ();
ArrayList<Interface> interfaces = new ArrayList<Interface> ();
@@ -542,6 +544,7 @@ public class Vala.GirParser : CodeVisitor {
postprocess_reparenting ();
postprocess_aliases ();
postprocess_namespace_methods ();
+ postprocess_callables ();
}
public override void visit_source_file (SourceFile source_file) {
@@ -2237,6 +2240,22 @@ public class Vala.GirParser : CodeVisitor {
return parse_function ("constructor") as CreationMethod;
}
+ class CallableInfo {
+ public Symbol symbol;
+ public List<ParameterInfo> parameters;
+ public Metadata metadata;
+
+ public ArrayList<int> array_length_parameters = new ArrayList<int> ();
+ public ArrayList<int> closure_parameters = new ArrayList<int> ();
+ public ArrayList<int> destroy_parameters = new ArrayList<int> ();
+
+ public CallableInfo (Symbol symbol, List<ParameterInfo> parameters, Metadata metadata) {
+ this.symbol = symbol;
+ this.parameters = parameters;
+ this.metadata = metadata;
+ }
+ }
+
class ParameterInfo {
public ParameterInfo (Parameter param, int array_length_idx, int closure_idx, int destroy_idx) {
this.param = param;
@@ -2341,10 +2360,13 @@ public class Vala.GirParser : CodeVisitor {
}
}
+ if (throws_string == "1") {
+ s.add_error_type (new ErrorType (null, null));
+ }
+
var parameters = new ArrayList<ParameterInfo> ();
- var array_length_parameters = new ArrayList<int> ();
- var closure_parameters = new ArrayList<int> ();
- var destroy_parameters = new ArrayList<int> ();
+ var callable = new CallableInfo (s, parameters, metadata);
+ callable_info_list.add (callable);
if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "parameters") {
start_element ("parameters");
next ();
@@ -2361,16 +2383,16 @@ public class Vala.GirParser : CodeVisitor {
default_param_name = "arg%d".printf (parameters.size);
var param = parse_parameter (out array_length_idx, out closure_idx, out destroy_idx, out scope, default_param_name);
if (array_length_idx != -1) {
- array_length_parameters.add (array_length_idx);
+ callable.array_length_parameters.add (array_length_idx);
}
if (closure_idx != -1) {
- closure_parameters.add (closure_idx);
+ callable.closure_parameters.add (closure_idx);
}
if (destroy_idx != -1) {
- destroy_parameters.add (destroy_idx);
+ callable.destroy_parameters.add (destroy_idx);
}
- var info = new ParameterInfo(param, array_length_idx, closure_idx, destroy_idx);
+ var info = new ParameterInfo (param, array_length_idx, closure_idx, destroy_idx);
if (s is Method && scope == "async") {
var unresolved_type = param.variable_type as UnresolvedType;
@@ -2386,107 +2408,7 @@ public class Vala.GirParser : CodeVisitor {
}
end_element ("parameters");
}
- var array_length_idx = -1;
- if (return_type is ArrayType && metadata.has_argument (ArgumentType.ARRAY_LENGTH_IDX)) {
- array_length_idx = metadata.get_integer (ArgumentType.ARRAY_LENGTH_IDX);
- parameters[array_length_idx].keep = false;
- array_length_parameters.add (array_length_idx);
- }
-
- int i = 0, j=1;
-
- int last = -1;
- foreach (ParameterInfo info in parameters) {
- if (s is Delegate && info.closure_idx == i) {
- var d = (Delegate) s;
- d.has_target = true;
- d.cinstance_parameter_position = (float) j - 0.1;
- info.keep = false;
- } else if (info.keep
- && !array_length_parameters.contains (i)
- && !closure_parameters.contains (i)
- && !destroy_parameters.contains (i)) {
- info.vala_idx = (float) j;
- info.keep = true;
-
- /* interpolate for vala_idx between this and last*/
- float last_idx = 0.0F;
- if (last != -1) {
- last_idx = parameters[last].vala_idx;
- }
- for (int k=last+1; k < i; k++) {
- parameters[k].vala_idx = last_idx + (((j - last_idx) / (i-last)) * (k-last));
- }
- last = i;
- j++;
- } else {
- info.keep = false;
- // make sure that vala_idx is always set
- // the above if branch does not set vala_idx for
- // hidden parameters at the end of the parameter list
- info.vala_idx = (j - 1) + (i - last) * 0.1F;
- }
- i++;
- }
- foreach (ParameterInfo info in parameters) {
- if (info.keep) {
-
- /* add_parameter sets carray_length_parameter_position and cdelegate_target_parameter_position
- so do it first*/
- if (s is Method) {
- ((Method) s).add_parameter (info.param);
- } else if (s is Delegate) {
- ((Delegate) s).add_parameter (info.param);
- } else if (s is Signal) {
- ((Signal) s).add_parameter (info.param);
- }
-
- if (info.array_length_idx != -1) {
- if ((info.array_length_idx) >= parameters.size) {
- Report.error (get_current_src (), "invalid array_length index");
- continue;
- }
- set_array_ccode (info.param, parameters[info.array_length_idx]);
- }
-
- if (info.closure_idx != -1) {
- if ((info.closure_idx) >= parameters.size) {
- Report.error (get_current_src (), "invalid closure index");
- continue;
- }
- info.param.cdelegate_target_parameter_position = parameters[info.closure_idx].vala_idx;
- }
- if (info.destroy_idx != -1) {
- if (info.destroy_idx >= parameters.size) {
- Report.error (get_current_src (), "invalid destroy index");
- continue;
- }
- info.param.cdestroy_notify_parameter_position = parameters[info.destroy_idx].vala_idx;
- }
- }
- }
- if (array_length_idx != -1) {
- if (array_length_idx >= parameters.size) {
- Report.error (get_current_src (), "invalid array_length index");
- } else {
- set_array_ccode (s, parameters[array_length_idx]);
- }
- } else if (return_type is ArrayType) {
- if (s is Method) {
- var m = (Method) s;
- m.no_array_length = true;
- m.array_null_terminated = true;
- } else if (s is Delegate) {
- var d = (Delegate) s;
- d.no_array_length = true;
- d.array_null_terminated = true;
- }
- }
-
- if (throws_string == "1") {
- s.add_error_type (new ErrorType (null, null));
- }
end_element (element_name);
return s;
}
@@ -2871,6 +2793,150 @@ public class Vala.GirParser : CodeVisitor {
}
}
+ void postprocess_callables () {
+ foreach (var callable in callable_info_list) {
+ var s = callable.symbol;
+ List<ParameterInfo> parameters = callable.parameters;
+ Metadata metadata = callable.metadata;
+
+ DataType return_type = null;
+ if (s is Method) {
+ return_type = ((Method) s).return_type;
+ } else if (s is Delegate) {
+ return_type = ((Delegate) s).return_type;
+ } else if (s is Signal) {
+ return_type = ((Signal) s).return_type;
+ }
+
+ var array_length_idx = -1;
+ if (return_type is ArrayType && metadata.has_argument (ArgumentType.ARRAY_LENGTH_IDX)) {
+ array_length_idx = metadata.get_integer (ArgumentType.ARRAY_LENGTH_IDX);
+ parameters[array_length_idx].keep = false;
+ callable.array_length_parameters.add (array_length_idx);
+ } else if (return_type is VoidType && parameters.size > 0) {
+ int n_out_parameters = 0;
+ foreach (var info in parameters) {
+ if (info.param.direction == ParameterDirection.OUT) {
+ n_out_parameters++;
+ }
+ }
+
+ if (n_out_parameters == 1) {
+ ParameterInfo last_param = parameters[parameters.size-1];
+ if (last_param.param.direction == ParameterDirection.OUT) {
+ // use last out real-non-null-struct parameter as return type
+ if (last_param.param.variable_type is UnresolvedType) {
+ var st = resolve_symbol (s.parent_symbol.scope, ((UnresolvedType) last_param.param.variable_type).unresolved_symbol) as Struct;
+ if (st != null && !st.is_simple_type () && !last_param.param.variable_type.nullable) {
+ last_param.keep = false;
+ return_type = last_param.param.variable_type.copy ();
+ }
+ }
+ }
+ }
+ }
+
+ int i = 0, j=1;
+
+ int last = -1;
+ foreach (ParameterInfo info in parameters) {
+ if (s is Delegate && info.closure_idx == i) {
+ var d = (Delegate) s;
+ d.has_target = true;
+ d.cinstance_parameter_position = (float) j - 0.1;
+ info.keep = false;
+ } else if (info.keep
+ && !callable.array_length_parameters.contains (i)
+ && !callable.closure_parameters.contains (i)
+ && !callable.destroy_parameters.contains (i)) {
+ info.vala_idx = (float) j;
+ info.keep = true;
+
+ /* interpolate for vala_idx between this and last*/
+ float last_idx = 0.0F;
+ if (last != -1) {
+ last_idx = parameters[last].vala_idx;
+ }
+ for (int k=last+1; k < i; k++) {
+ parameters[k].vala_idx = last_idx + (((j - last_idx) / (i-last)) * (k-last));
+ }
+ last = i;
+ j++;
+ } else {
+ info.keep = false;
+ // make sure that vala_idx is always set
+ // the above if branch does not set vala_idx for
+ // hidden parameters at the end of the parameter list
+ info.vala_idx = (j - 1) + (i - last) * 0.1F;
+ }
+ i++;
+ }
+
+ foreach (ParameterInfo info in parameters) {
+ if (info.keep) {
+
+ /* add_parameter sets carray_length_parameter_position and cdelegate_target_parameter_position
+ so do it first*/
+ if (s is Method) {
+ ((Method) s).add_parameter (info.param);
+ } else if (s is Delegate) {
+ ((Delegate) s).add_parameter (info.param);
+ } else if (s is Signal) {
+ ((Signal) s).add_parameter (info.param);
+ }
+
+ if (info.array_length_idx != -1) {
+ if ((info.array_length_idx) >= parameters.size) {
+ Report.error (get_current_src (), "invalid array_length index");
+ continue;
+ }
+ set_array_ccode (info.param, parameters[info.array_length_idx]);
+ }
+
+ if (info.closure_idx != -1) {
+ if ((info.closure_idx) >= parameters.size) {
+ Report.error (get_current_src (), "invalid closure index");
+ continue;
+ }
+ info.param.cdelegate_target_parameter_position = parameters[info.closure_idx].vala_idx;
+ }
+ if (info.destroy_idx != -1) {
+ if (info.destroy_idx >= parameters.size) {
+ Report.error (get_current_src (), "invalid destroy index");
+ continue;
+ }
+ info.param.cdestroy_notify_parameter_position = parameters[info.destroy_idx].vala_idx;
+ }
+ }
+ }
+ if (array_length_idx != -1) {
+ if (array_length_idx >= parameters.size) {
+ Report.error (get_current_src (), "invalid array_length index");
+ } else {
+ set_array_ccode (s, parameters[array_length_idx]);
+ }
+ } else if (return_type is ArrayType) {
+ if (s is Method) {
+ var m = (Method) s;
+ m.no_array_length = true;
+ m.array_null_terminated = true;
+ } else if (s is Delegate) {
+ var d = (Delegate) s;
+ d.no_array_length = true;
+ d.array_null_terminated = true;
+ }
+ }
+
+ if (s is Method) {
+ ((Method) s).return_type = return_type;
+ } else if (s is Delegate) {
+ ((Delegate) s).return_type = return_type;
+ } else if (s is Signal) {
+ ((Signal) s).return_type = return_type;
+ }
+ }
+ }
+
void postprocess_namespace_methods () {
/* transform static methods into instance methods if possible.
In most of cases this is a .gir fault we are going to fix */
diff --git a/vapi/json-glib-1.0.vapi b/vapi/json-glib-1.0.vapi
index 76295ff..716f4cc 100644
--- a/vapi/json-glib-1.0.vapi
+++ b/vapi/json-glib-1.0.vapi
@@ -86,7 +86,7 @@ namespace Json {
public unowned Json.Object get_object ();
public unowned Json.Node get_parent ();
public unowned string get_string ();
- public void get_value (out GLib.Value value);
+ public GLib.Value get_value ();
public GLib.Type get_value_type ();
public bool is_null ();
public void set_array (Json.Array array);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]