]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
GIR parser: Fix virtual method and signal parsing 859b3872843ed2671f043b48e3cbf26fd6d7be21
authorDidier 'Ptitjes <ptitjes@free.fr>
Wed, 29 Apr 2009 10:58:57 +0000 (12:58 +0200)
committerJürg Billeter <j@bitron.ch>
Thu, 7 May 2009 16:38:25 +0000 (18:38 +0200)
Signed-off-by: Didier 'Ptitjes <ptitjes@free.fr>
vapigen/valagirparser.vala

index 8a475e55be17e0a441be5caa5d9522c95f7e7cc6..5b9b3e27f26f7ef525a483a13e730c2786887a7f 100644 (file)
@@ -43,6 +43,8 @@ public class Vala.GirParser : CodeVisitor {
 
        HashMap<string,string> attributes_map = new HashMap<string,string> (str_hash, str_equal);
 
+       HashMap<string,ArrayList<Method>> gtype_callbacks = new HashMap<string,ArrayList<Method>> (str_hash, str_equal);
+
        /**
         * Parses all .gir source files in the specified code
         * context and builds a code tree.
@@ -242,6 +244,8 @@ public class Vala.GirParser : CodeVisitor {
                }
                end_element ("namespace");
 
+               postprocess_gtype_callbacks (ns);
+
                if (!new_namespace) {
                        ns = null;
                }
@@ -486,13 +490,25 @@ public class Vala.GirParser : CodeVisitor {
        Struct parse_record () {
                start_element ("record");
                var st = new Struct (reader.get_attribute ("name"), get_current_src ());
+
+               string glib_is_gtype_struct_for = reader.get_attribute ("glib:is-gtype-struct-for");
+
                st.access = SymbolAccessibility.PUBLIC;
                next ();
                while (current_token == MarkupTokenType.START_ELEMENT) {
                        if (reader.name == "field") {
                                st.add_field (parse_field ());
                        } else if (reader.name == "callback") {
-                               parse_callback ();
+                               if (glib_is_gtype_struct_for != null) {
+                                       ArrayList<Method> callbacks = gtype_callbacks.get (glib_is_gtype_struct_for);
+                                       if (callbacks == null) {
+                                               callbacks = new ArrayList<Method> ();
+                                               gtype_callbacks.set (glib_is_gtype_struct_for, callbacks);
+                                       }
+                                       callbacks.add (parse_method ("callback"));
+                               } else {
+                                       parse_callback ();
+                               }
                        } else if (reader.name == "constructor") {
                                parse_constructor ();
                        } else if (reader.name == "method") {
@@ -507,6 +523,31 @@ public class Vala.GirParser : CodeVisitor {
                return st;
        }
 
+       void postprocess_gtype_callbacks (Namespace ns) {
+               foreach (string gtype_name in gtype_callbacks.get_keys ()) {
+                       var gtype = ns.scope.lookup (gtype_name) as ObjectTypeSymbol;
+                       ArrayList<Method> callbacks = gtype_callbacks.get (gtype_name);
+                       foreach (Method m in callbacks) {
+                               var symbol = gtype.scope.lookup (m.name);
+                               if (symbol == null) {
+                                       continue;
+                               } else if (symbol is Method)  {
+                                       var meth = (Method) symbol;
+                                       if (gtype is Class) {
+                                               meth.is_virtual = true;
+                                       } else if (gtype is Interface) {
+                                               meth.is_abstract = true;
+                                       }
+                               } else if (symbol is Signal) {
+                                       var sig = (Signal) symbol;
+                                       sig.is_virtual = true;
+                               } else {
+                                       Report.error (get_current_src (), "unknown member type `%s' in `%s'".printf (m.name, gtype.name));
+                               }
+                       }
+               }
+       }
+
        Class parse_class () {
                start_element ("class");
                var cl = new Class (reader.get_attribute ("name"), get_current_src ());
@@ -545,8 +586,8 @@ public class Vala.GirParser : CodeVisitor {
                                methods.add (parse_method ("function"));
                        } else if (reader.name == "method") {
                                methods.add (parse_method ("method"));
-                       } else if (reader.name == "callback") {
-                               vmethods.add (parse_method ("callback"));
+                       } else if (reader.name == "virtual-method") {
+                               vmethods.add (parse_method ("virtual-method"));
                        } else if (reader.name == "glib:signal") {
                                signals.add (parse_signal ());
                        } else {
@@ -635,8 +676,8 @@ public class Vala.GirParser : CodeVisitor {
                                parse_field ();
                        } else if (reader.name == "property") {
                                iface.add_property (parse_property ());
-                       } else if (reader.name == "callback") {
-                               vmethods.add (parse_method ("callback"));
+                       } else if (reader.name == "virtual-method") {
+                               vmethods.add (parse_method ("virtual-method"));
                        } else if (reader.name == "function") {
                                methods.add (parse_method ("function"));
                        } else if (reader.name == "method") {
@@ -775,6 +816,7 @@ public class Vala.GirParser : CodeVisitor {
                start_element (element_name);
                string name = reader.get_attribute ("name");
                string throws_string = reader.get_attribute ("throws");
+               string invoker = reader.get_attribute ("invoker");
                next ();
                DataType return_type;
                if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "return-value") {
@@ -785,8 +827,11 @@ public class Vala.GirParser : CodeVisitor {
                var m = new Method (name, return_type, get_current_src ());
                m.access = SymbolAccessibility.PUBLIC;
 
-               if (element_name == "callback") {
+               if (element_name == "virtual-method" || element_name == "callback") {
                        m.is_virtual = true;
+                       if (invoker != null){
+                               m.name = invoker;
+                       }
                } else if (element_name == "function") {
                        m.binding = MemberBinding.STATIC;
                }