[vala/switch-to-gir] girparser: Autoreparent static methods to the best-matching symbol
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/switch-to-gir] girparser: Autoreparent static methods to the best-matching symbol
- Date: Fri, 27 Aug 2010 21:59:47 +0000 (UTC)
commit 6b3556ff30673f5b27384dc83215874acc0b4019
Author: Luca Bruno <lethalman88 gmail com>
Date: Fri Aug 27 23:59:26 2010 +0200
girparser: Autoreparent static methods to the best-matching symbol
vala/valagirparser.vala | 98 +++++++++++++++++++++++++++++++++++++++++------
1 files changed, 86 insertions(+), 12 deletions(-)
---
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index a3b7665..95e6b0a 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -256,14 +256,6 @@ public class Vala.GirParser : CodeVisitor {
return ((string) begin.pos).ndup ((end.pos - begin.pos));
}
- inline bool accept (TokenType type) {
- if (current == type) {
- next ();
- return true;
- }
- return false;
- }
-
MetadataType? parse_metadata_access () {
switch (current) {
case TokenType.DOT:
@@ -486,6 +478,7 @@ public class Vala.GirParser : CodeVisitor {
HashMap<UnresolvedSymbol,Symbol> symbols_map = new HashMap<UnresolvedSymbol,Symbol> (unresolved_symbol_hash, unresolved_symbol_equal);
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);
+ HashMap<Namespace,ArrayList<Method>> namespace_methods = new HashMap<Namespace,ArrayList<Method>> ();
HashMap<CallbackScope,ArrayList<Delegate>> gtype_callbacks = new HashMap<CallbackScope,ArrayList<Delegate>> (callback_scope_hash, callback_scope_equal);
ArrayList<Alias> aliases = new ArrayList<Alias> ();
@@ -506,6 +499,7 @@ public class Vala.GirParser : CodeVisitor {
postprocess_reparenting ();
postprocess_gtype_callbacks ();
postprocess_aliases ();
+ postprocess_namespace_methods ();
}
public override void visit_source_file (SourceFile source_file) {
@@ -823,7 +817,7 @@ public class Vala.GirParser : CodeVisitor {
int element_get_integer (string attribute_name, ArgumentType arg_type, int default_value = -1) {
var value = default_value;
- var str = reader.get_attribute ("length");
+ var str = reader.get_attribute (attribute_name);
if (str != null) {
value = str.to_int ();
}
@@ -919,7 +913,7 @@ public class Vala.GirParser : CodeVisitor {
if (sym is Property) {
// assume getter for property
((Property) sym).no_accessor_method = false;
- return true;
+ break;
}
}
}
@@ -1106,6 +1100,11 @@ public class Vala.GirParser : CodeVisitor {
}
next ();
+ var current_namespace_methods = namespace_methods[ns];
+ if (current_namespace_methods == null) {
+ current_namespace_methods = new ArrayList<Method> ();
+ namespace_methods[ns] = current_namespace_methods;
+ }
while (current_token == MarkupTokenType.START_ELEMENT) {
if (!push_metadata ()) {
skip_element ();
@@ -1125,7 +1124,7 @@ public class Vala.GirParser : CodeVisitor {
} else if (reader.name == "bitfield") {
sym = parse_bitfield ();
} else if (reader.name == "function") {
- sym = parse_method ("function");
+ current_namespace_methods.add (parse_method ("function"));
} else if (reader.name == "callback") {
sym = parse_callback ();
} else if (reader.name == "record") {
@@ -1612,7 +1611,6 @@ public class Vala.GirParser : CodeVisitor {
continue;
}
- Symbol sym = null;
if (reader.name == "implements") {
start_element ("implements");
cl.add_base_type (parse_type_from_gir_name (reader.get_attribute ("name")));
@@ -1774,6 +1772,7 @@ public class Vala.GirParser : CodeVisitor {
next ();
var type = parse_type ();
+ type = element_get_type (type, true);
if (type is DelegateType && current_gtype_struct_for != null) {
// virtual
var callback_scope = new CallbackScope ();
@@ -2464,6 +2463,81 @@ public class Vala.GirParser : CodeVisitor {
}
}
+ void find_static_method_parent (string cname, Symbol current, ref Symbol best, ref double match, double match_char) {
+ var old_best = best;
+ if (current.scope.get_symbol_table () != null) {
+ foreach (var child in current.scope.get_symbol_table().get_values ()) {
+ if (child is Struct || child is ObjectTypeSymbol || child is Namespace) {
+ find_static_method_parent (cname, child, ref best, ref match, match_char);
+ }
+ }
+ }
+ if (best != old_best) {
+ // child is better
+ return;
+ }
+
+ var current_cprefix = current.get_lower_case_cprefix ();
+ if (cname.has_prefix (current_cprefix)) {
+ var current_match = match_char * current_cprefix.length;
+ if (current_match > match) {
+ match = current_match;
+ best = current;
+ }
+ }
+ }
+
+ 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 */
+ foreach (var ns in namespace_methods.get_keys ()) {
+ var ns_cprefix = ns.get_lower_case_cprefix ();
+ var methods = namespace_methods[ns];
+ foreach (var method in methods) {
+ if (method.parent_node != null) {
+ // fixed earlier by metadata
+ continue;
+ }
+
+ var cname = method.get_cname ();
+
+ FormalParameter first_param = null;
+ if (method.get_parameters ().size > 0) {
+ first_param = method.get_parameters()[0];
+ }
+ if (first_param != null && first_param.variable_type is UnresolvedType) {
+ // check if it's a missed instance method (often happens for structs)
+ var parent = resolve_symbol (ns.scope, ((UnresolvedType) first_param.variable_type).unresolved_symbol);
+ if (parent != null && (parent is Struct || parent is ObjectTypeSymbol || parent is Namespace)
+ && cname.has_prefix (parent.get_lower_case_cprefix ())) {
+ // instance method
+ var new_name = method.name.offset (parent.get_lower_case_cprefix().length-ns_cprefix.length);
+ if (parent.scope.lookup (new_name) == null) {
+ method.name = new_name;
+ method.get_parameters().remove_at (0);
+ method.binding = MemberBinding.INSTANCE;
+ add_symbol_to_container (parent, method);
+ } else {
+ ns.add_method (method);
+ }
+ continue;
+ }
+ }
+
+ double match = 0;
+ Symbol parent = ns;
+ find_static_method_parent (cname, ns, ref parent, ref match, 1.0/cname.length);
+ var new_name = method.name.offset (parent.get_lower_case_cprefix().length-ns_cprefix.length);
+ if (parent.scope.lookup (new_name) == null) {
+ method.name = new_name;
+ add_symbol_to_container (parent, method);
+ } else {
+ ns.add_method (method);
+ }
+ }
+ }
+ }
+
/* Reporting */
void report_unused_metadata (Metadata metadata) {
if (metadata == Metadata.empty) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]