]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
adapt to Method API changes support signals, mark private signal handlers
authorJürg Billeter <j@bitron.ch>
Sat, 8 Jul 2006 09:26:16 +0000 (09:26 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sat, 8 Jul 2006 09:26:16 +0000 (09:26 +0000)
2006-07-08  Jürg Billeter  <j@bitron.ch>

* vala/parser.y: adapt to Method API changes
* vala/valasemanticanalyzer.vala: support signals, mark private signal
  handlers as instance_last
* vala/valamemorymanager.vala: support signals
* vala/valacodegenerator.vala: support signals, methods with
  instance_last
* vala/valaclass.vala: add get_type_id and get_marshaller_type_name
  methods
* vala/valadatatype.vala: add get_marshaller_type_name method
* vala/valastruct.vala: move type_id attribute to CCode, support
  marshaller_type_name attribute
* vala/valainterfacewriter.vala, vala/valamethod.vala,
  vala/valastruct.vala, ccode/valaccodeexpression.vala,
  ccode/valaccodenode.vala: add interface documentation, use implicit
  namespace specification
* vala/valacallback.vala, vala/valasignal.vala: improve documentation
* ccode/valaccodecastexpression.vala: type cast in C code
* ccode/Makefile.am: update
* tests/test-018.vala: test signals
* tests/Makefile.am: update
* vapi/glib-2.0.vala: add type_id and marshaller_type_name attributes

svn path=/trunk/; revision=71

19 files changed:
vala/ChangeLog
vala/ccode/Makefile.am
vala/ccode/valaccodecastexpression.vala [new file with mode: 0644]
vala/ccode/valaccodeexpression.vala
vala/ccode/valaccodenode.vala
vala/tests/Makefile.am
vala/tests/test-018.vala [new file with mode: 0644]
vala/vala/parser.y
vala/vala/valacallback.vala
vala/vala/valaclass.vala
vala/vala/valacodegenerator.vala
vala/vala/valadatatype.vala
vala/vala/valainterfacewriter.vala
vala/vala/valamemorymanager.vala
vala/vala/valamethod.vala
vala/vala/valasemanticanalyzer.vala
vala/vala/valasignal.vala
vala/vala/valastruct.vala
vala/vapi/glib-2.0.vala

index 9c09d651b87cd81e32820a5e1eec9de546d863c7..b79b6ed62ad4313ff484f71f7723390a3a6c2bed 100644 (file)
@@ -1,3 +1,27 @@
+2006-07-08  Jürg Billeter  <j@bitron.ch>
+
+       * vala/parser.y: adapt to Method API changes
+       * vala/valasemanticanalyzer.vala: support signals, mark private signal
+         handlers as instance_last
+       * vala/valamemorymanager.vala: support signals
+       * vala/valacodegenerator.vala: support signals, methods with
+         instance_last
+       * vala/valaclass.vala: add get_type_id and get_marshaller_type_name
+         methods
+       * vala/valadatatype.vala: add get_marshaller_type_name method
+       * vala/valastruct.vala: move type_id attribute to CCode, support
+         marshaller_type_name attribute
+       * vala/valainterfacewriter.vala, vala/valamethod.vala,
+         vala/valastruct.vala, ccode/valaccodeexpression.vala,
+         ccode/valaccodenode.vala: add interface documentation, use implicit
+         namespace specification
+       * vala/valacallback.vala, vala/valasignal.vala: improve documentation
+       * ccode/valaccodecastexpression.vala: type cast in C code
+       * ccode/Makefile.am: update
+       * tests/test-018.vala: test signals
+       * tests/Makefile.am: update
+       * vapi/glib-2.0.vala: add type_id and marshaller_type_name attributes
+
 2006-07-07  Jürg Billeter  <j@bitron.ch>
 
        * vala/valacodegenerator.vala, vala/valaclassregisterfunction.vala:
index 6b5f945d077322b4e4b7ea79bf5e0b7a50b2dd4e..3f1acbdebe02fd24d33b43857bcdd31e83c68898 100644 (file)
@@ -30,6 +30,9 @@ libvalaccode_la_SOURCES = \
        valaccodecasestatement.c \
        valaccodecasestatement.h \
        valaccodecasestatement.vala \
+       valaccodecastexpression.c \
+       valaccodecastexpression.h \
+       valaccodecastexpression.vala \
        valaccodecommaexpression.c \
        valaccodecommaexpression.h \
        valaccodecommaexpression.vala \
diff --git a/vala/ccode/valaccodecastexpression.vala b/vala/ccode/valaccodecastexpression.vala
new file mode 100644 (file)
index 0000000..fcf6e2e
--- /dev/null
@@ -0,0 +1,46 @@
+/* valaccodecastexpression.vala
+ *
+ * Copyright (C) 2006  Jürg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+
+/**
+ * Represents a type cast in the generated C code.
+ */
+public class Vala.CCodeCastExpression : CCodeExpression {
+       /**
+        * The expression to be casted.
+        */
+       public CCodeExpression! inner { get; set construct; }
+       
+       /**
+        * The target type.
+        */
+       public string! type_name { get; set construct; }
+       
+       public override void write (CCodeWriter! writer) {
+               writer.write_string ("(");
+               writer.write_string (type_name);
+               writer.write_string (") ");
+
+               inner.write (writer);
+       }
+}
index 2298b7ed52848bf32cf7b572668c8666066300b1..0dec866faf92ec9b4c995e61723e6e5b33190442 100644 (file)
@@ -22,7 +22,8 @@
 
 using GLib;
 
-namespace Vala {
-       public abstract class CCodeExpression : CCodeNode {
-       }
+/**
+ * Represents an expression node in the C code tree.
+ */
+public abstract class Vala.CCodeExpression : CCodeNode {
 }
index eeb3e5cb1533a089de36cda46829ae4d5912c108..d577cb426c8309c3ecb9de26b631a28686397043 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public abstract class CCodeNode {
-               public abstract void write (CCodeWriter writer);
-       }
+/**
+ * Represents a node in the C code tree.
+ */
+public abstract class Vala.CCodeNode {
+       /**
+        * Writes this code node and all children with the specified C code
+        * writer.
+        *
+        * @param writer a C code writer
+        */
+       public abstract void write (CCodeWriter! writer);
 }
index 97a567d397b8f2d059fe9505508c938098ffc85a..20ef3f46d8ba433d4cdb4c677496a3f135361698 100644 (file)
@@ -18,4 +18,5 @@ EXTRA_DIST = \
        test-015.vala \
        test-016.vala \
        test-017.vala \
+       test-018.vala \
        $(NULL)
diff --git a/vala/tests/test-018.vala b/vala/tests/test-018.vala
new file mode 100644 (file)
index 0000000..bacd259
--- /dev/null
@@ -0,0 +1,52 @@
+using GLib;
+
+class Maman.Foo {
+       public signal void activated (bool b);
+
+       public void do_action () {
+               activated (false);
+       }
+}
+
+class Maman.Bar {
+       void activated (Foo foo, bool b) {
+               if (b) {
+                       stdout.printf (" BAD");
+               } else {
+                       stdout.printf (" 5");
+               }
+       }
+
+       public void run () {
+               stdout.printf (" 2");
+               
+               var foo = new Foo ();
+               
+               foo.activated += (foo, b) => {
+                       if (b) {
+                               stdout.printf (" BAD");
+                       } else {
+                               stdout.printf (" 4");
+                       }
+               };
+
+               foo.activated += activated;
+
+               stdout.printf (" 3");
+               
+               foo.do_action ();
+
+               stdout.printf (" 6");
+       }
+
+       static int main (int argc, string[] argv) {
+               stdout.printf ("Signal Test: 1");
+               
+               var bar = new Bar ();
+               bar.run ();
+       
+               stdout.printf (" 7\n");
+
+               return 0;
+       }
+}
index c79df977f1d360e0934e65af09cb1c936c01db72..da436f0df3c090912dafc1ca3af786b72bff5d41 100644 (file)
@@ -1818,16 +1818,16 @@ method_header
                        $$->access = $3;
                }
                if (($4 & VALA_MODIFIER_STATIC) == VALA_MODIFIER_STATIC) {
-                       $$->instance = FALSE;
+                       vala_method_set_instance ($$, FALSE);
                }
                if (($4 & VALA_MODIFIER_ABSTRACT) == VALA_MODIFIER_ABSTRACT) {
-                       $$->is_abstract = TRUE;
+                       vala_method_set_is_abstract ($$, TRUE);
                }
                if (($4 & VALA_MODIFIER_VIRTUAL) == VALA_MODIFIER_VIRTUAL) {
-                       $$->is_virtual = TRUE;
+                       vala_method_set_is_virtual ($$, TRUE);
                }
                if (($4 & VALA_MODIFIER_OVERRIDE) == VALA_MODIFIER_OVERRIDE) {
-                       $$->is_override = TRUE;
+                       vala_method_set_overrides ($$, TRUE);
                }
                VALA_CODE_NODE($$)->attributes = $2;
                
index 96cdd67f777daa5f70ac8c754602b730fb7c3af2..ab4fed2a58e2f9ad9daeb8751db46121bb8354ca 100644 (file)
@@ -54,7 +54,7 @@ public class Vala.Callback : DataType {
        }
        
        /**
-        * Append paramater to this callback function.
+        * Appends paramater to this callback function.
         *
         * @param param a formal parameter
         */
index 476710fe58fc5d319f889ca1161fe77ba84fff28..2da1d1958d8aefb45679af80ad9f464fd5e5537d 100644 (file)
@@ -48,6 +48,7 @@ public class Vala.Class : DataType {
        
        private string cname;
        private string lower_case_csuffix;
+       private string type_id;
        
        private bool _has_private_fields;
        
@@ -334,6 +335,18 @@ public class Vala.Class : DataType {
                }
        }
 
+       public override string get_type_id () {
+               if (type_id == null) {
+                       type_id = get_upper_case_cname ("TYPE_");
+               }
+               
+               return type_id;
+       }
+
+       public override string get_marshaller_type_name () {
+               return "G_TYPE_OBJECT";
+       }
+
        public override bool is_reference_counting () {
                return true;
        }
index f1f12b82ddf67e93ebabf57a63ac2f4f1e17eea8..86b94bb6852fb8f9711e5b0618a4577190c6f7ce 100644 (file)
@@ -31,6 +31,7 @@ public class Vala.CodeGenerator : CodeVisitor {
         */
        public bool memory_management { get; set; }
        
+       Symbol root_symbol;
        Symbol current_symbol;
        Symbol current_type_symbol;
 
@@ -58,6 +59,9 @@ public class Vala.CodeGenerator : CodeVisitor {
        
        private int next_temp_var_id = 0;
 
+       TypeReference bool_type;
+       TypeReference string_type;
+
        /**
         * Generate and emit C code for the specified code context.
         *
@@ -65,6 +69,14 @@ public class Vala.CodeGenerator : CodeVisitor {
         */
        public void emit (CodeContext! context) {
                context.find_header_cycles ();
+
+               root_symbol = context.get_root ();
+
+               bool_type = new TypeReference ();
+               bool_type.type = (DataType) root_symbol.lookup ("bool").node;
+
+               string_type = new TypeReference ();
+               string_type.type = (DataType) root_symbol.lookup ("string").node;
        
                /* we're only interested in non-pkg source files */
                var source_files = context.get_source_files ();
@@ -320,7 +332,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                
                var methods = cl.get_methods ();
                foreach (Method m in methods) {
-                       if (!m.is_virtual && !m.is_override) {
+                       if (!m.is_virtual && !m.overrides) {
                                continue;
                        }
                        
@@ -382,6 +394,41 @@ public class Vala.CodeGenerator : CodeVisitor {
                        init_block.add_statement (new CCodeExpressionStatement (expression = cinst));
                }
                
+               foreach (Signal sig in cl.get_signals ()) {
+                       var csignew = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_signal_new"));
+                       csignew.add_argument (new CCodeConstant (name = "\"%s\"".printf (sig.name)));
+                       csignew.add_argument (new CCodeIdentifier (name = cl.get_upper_case_cname ("TYPE_")));
+                       csignew.add_argument (new CCodeConstant (name = "G_SIGNAL_RUN_LAST"));
+                       csignew.add_argument (new CCodeConstant (name = "0"));
+                       csignew.add_argument (new CCodeConstant (name = "NULL"));
+                       csignew.add_argument (new CCodeConstant (name = "NULL"));
+                       
+                       /* TODO: generate marshallers */
+                       string marshaller = "g_cclosure_marshal";
+                       
+                       var marshal_arg = new CCodeIdentifier (name = marshaller);
+                       csignew.add_argument (marshal_arg);
+                       
+                       var params = sig.get_parameters ();
+                       var params_len = params.length ();
+                       if (sig.return_type.type == null) {
+                               marshaller = "%s_VOID_".printf (marshaller);
+                               csignew.add_argument (new CCodeConstant (name = "G_TYPE_NONE"));
+                       } else {
+                               marshaller = "%s_%s_".printf (marshaller, sig.return_type.type.get_marshaller_type_name ());
+                               csignew.add_argument (new CCodeConstant (name = sig.return_type.type.get_type_id ()));
+                       }
+                       csignew.add_argument (new CCodeConstant (name = "%d".printf (params_len)));
+                       foreach (FormalParameter param in params) {
+                               marshaller = "%s_%s".printf (marshaller, param.type_reference.type.get_marshaller_type_name ());
+                               csignew.add_argument (new CCodeConstant (name = param.type_reference.type.get_type_id ()));
+                       }
+                       
+                       marshal_arg.name = marshaller;
+                       
+                       init_block.add_statement (new CCodeExpressionStatement (expression = csignew));
+               }
+               
                source_type_member_definition.append (class_init);
        }
        
@@ -397,7 +444,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                
                var methods = cl.get_methods ();
                foreach (Method m in methods) {
-                       if (!m.is_override) {
+                       if (!m.overrides) {
                                continue;
                        }
                        
@@ -815,26 +862,29 @@ public class Vala.CodeGenerator : CodeVisitor {
                function = new CCodeFunction (name = m.get_real_cname (), return_type = m.return_type.get_cname ());
                CCodeFunctionDeclarator vdeclarator = null;
                
+               CCodeFormalParameter instance_param = null;
+               
                if (m.instance) {
                        var this_type = new TypeReference ();
                        this_type.type = find_parent_type (m);
-                       if (!m.is_override) {
-                               var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
-                               function.add_parameter (cparam);
+                       if (!m.overrides) {
+                               instance_param = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
                        } else {
                                var base_type = new TypeReference ();
                                base_type.type = (DataType) m.base_method.symbol.parent_symbol.node;
-                               var cparam = new CCodeFormalParameter (type_name = base_type.get_cname (), name = "base");
-                               function.add_parameter (cparam);
+                               instance_param = new CCodeFormalParameter (type_name = base_type.get_cname (), name = "base");
+                       }
+                       if (!m.instance_last) {
+                               function.add_parameter (instance_param);
                        }
+                       
                        if (m.is_abstract || m.is_virtual) {
                                var vdecl = new CCodeDeclaration (type_name = m.return_type.get_cname ());
                                vdeclarator = new CCodeFunctionDeclarator (name = m.name);
                                vdecl.add_declarator (vdeclarator);
                                type_struct.add_declaration (vdecl);
 
-                               var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
-                               vdeclarator.add_parameter (cparam);
+                               vdeclarator.add_parameter (instance_param);
                        }
                }
                
@@ -846,10 +896,14 @@ public class Vala.CodeGenerator : CodeVisitor {
                        }
                }
                
+               if (m.instance && m.instance_last) {
+                       function.add_parameter (instance_param);
+               }
+
                /* real function declaration and definition not needed
                 * for abstract methods */
                if (!m.is_abstract) {
-                       if (m.access == MemberAccessibility.PUBLIC && !(m.is_virtual || m.is_override)) {
+                       if (m.access == MemberAccessibility.PUBLIC && !(m.is_virtual || m.overrides)) {
                                /* public methods need function declaration in
                                 * header file except virtual/overridden methods */
                                header_type_member_declaration.append (function.copy ());
@@ -870,7 +924,7 @@ public class Vala.CodeGenerator : CodeVisitor {
 
                                if (m.symbol.parent_symbol.node is Class) {
                                        var cl = (Class) m.symbol.parent_symbol.node;
-                                       if (m.is_override) {
+                                       if (m.overrides) {
                                                var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = cl.get_upper_case_cname (null)));
                                                ccall.add_argument (new CCodeIdentifier (name = "base"));
                                                
@@ -882,7 +936,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                                                cinit.append (create_method_type_check_statement (m, cl, true, "self"));
                                        }
                                }
-                               foreach (FormalParameter param in m.parameters) {
+                               foreach (FormalParameter param in m.get_parameters ()) {
                                        var t = param.type_reference.type;
                                        if (t != null && (t is Class || t is Interface) && !param.type_reference.is_out) {
                                                cinit.append (create_method_type_check_statement (m, t, param.type_reference.non_null, param.name));
@@ -1537,7 +1591,7 @@ public class Vala.CodeGenerator : CodeVisitor {
        private void process_cmember (MemberAccess! expr, CCodeExpression pub_inst, DataType base_type) {
                if (expr.symbol_reference.node is Method) {
                        var m = (Method) expr.symbol_reference.node;
-                       if (!m.is_override) {
+                       if (!m.overrides) {
                                expr.ccodenode = new CCodeIdentifier (name = m.get_cname ());
                        } else {
                                expr.ccodenode = new CCodeIdentifier (name = m.base_method.get_cname ());
@@ -1610,6 +1664,18 @@ public class Vala.CodeGenerator : CodeVisitor {
                                        expr.ccodenode = new CCodeIdentifier (name = p.name);
                                }
                        }
+               } else if (expr.symbol_reference.node is Signal) {
+                       var sig = (Signal) expr.symbol_reference.node;
+                       
+                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_signal_emit_by_name"));
+
+                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT"));
+                       ccast.add_argument (pub_inst);
+                       ccall.add_argument (ccast);
+
+                       ccall.add_argument (new CCodeConstant (name = "\"%s\"".printf (sig.name)));
+                       
+                       expr.ccodenode = ccall;
                }
        }
        
@@ -1665,9 +1731,14 @@ public class Vala.CodeGenerator : CodeVisitor {
                        var param = (FormalParameter) expr.call.symbol_reference.node;
                        var cb = (Callback) param.type_reference.type;
                        params = cb.get_parameters ();
-               } else {
+               } else if (expr.call.symbol_reference.node is Method) {
                        m = (Method) expr.call.symbol_reference.node;
                        params = m.get_parameters ();
+               } else {
+                       var sig = (Signal) expr.call.symbol_reference.node;
+                       params = sig.get_parameters ();
+                       
+                       ccall = (CCodeFunctionCall) expr.call.ccodenode;
                }
                
                /* explicitly use strong reference as ccall gets unrefed
@@ -1676,7 +1747,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                ref CCodeExpression instance;
                if (m != null && m.instance) {
                        var base_method = m;
-                       if (m.is_override) {
+                       if (m.overrides) {
                                base_method = m.base_method;
                        }
 
@@ -1684,7 +1755,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                        if (ma.inner == null) {
                                instance = new CCodeIdentifier (name = "self");
                                /* require casts for overriden and inherited methods */
-                               req_cast = m.is_override || (m.symbol.parent_symbol != current_type_symbol);
+                               req_cast = m.overrides || (m.symbol.parent_symbol != current_type_symbol);
                        } else {
                                instance = (CCodeExpression) ma.inner.ccodenode;
                                /* reqiure casts if the type of the used instance is
@@ -1967,12 +2038,6 @@ public class Vala.CodeGenerator : CodeVisitor {
                } else if (a.left.symbol_reference.node is Signal) {
                        var sig = (Signal) a.left.symbol_reference.node;
                        
-                       if (a.right.symbol_reference == null) {
-                               a.right.error = true;
-                               Report.error (a.right.source_reference, "unsupported expression for signal handler");
-                               return;
-                       }
-                       
                        var m = (Method) a.right.symbol_reference.node;
                        var connect_func = "g_signal_connect_object";
                        if (!m.instance) {
@@ -1989,7 +2054,7 @@ public class Vala.CodeGenerator : CodeVisitor {
 
                        ccall.add_argument (new CCodeConstant (name = "\"%s\"".printf (sig.name)));
 
-                       ccall.add_argument (new CCodeIdentifier (name = m.get_cname ()));
+                       ccall.add_argument (new CCodeCastExpression (inner = new CCodeIdentifier (name = m.get_cname ()), type_name = "GCallback"));
 
                        if (m.instance) {
                                if (a.right is MemberAccess) {
@@ -2002,8 +2067,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                                } else if (a.right is LambdaExpression) {
                                        ccall.add_argument (new CCodeIdentifier (name = "self"));
                                }
-
-                               ccall.add_argument (new CCodeConstant (name = "G_CONNECT_SWAPPED"));
+                               ccall.add_argument (new CCodeConstant (name = "0"));
                        } else {
                                ccall.add_argument (new CCodeConstant (name = "NULL"));
                        }
index 44d6c19946e14e520284b80e2afec989857ebc3c..7d618350f00d0f365e57799465679e61258069c3 100644 (file)
@@ -134,6 +134,15 @@ public abstract class Vala.DataType : CodeNode {
                return null;
        }
        
+       /**
+        * Returns the name of this data type as used in C code marshallers
+        *
+        * @return type name for marshallers
+        */
+       public virtual string get_marshaller_type_name () {
+               return null;
+       }
+       
        /**
         * Returns the C name of this data type in upper case. Words are
         * separated by underscores. The upper case C name of the namespace is
index 2923fe9d923f4b32f85c7f787efeb8ef10e1153d..0dacb688dfd2aec9e72da9ca7279d0e37a6fb2e3 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class InterfaceWriter : CodeVisitor {
-               File stream;
-               
-               int indent;
-               /* at begin of line */
-               bool bol = true;
-               
-               bool internal_scope = false;
-               
-               string current_cheader_filename;
+/**
+ * Code visitor generating Vala API file for the public interface.
+ */
+public class Vala.InterfaceWriter : CodeVisitor {
+       File stream;
+       
+       int indent;
+       /* at begin of line */
+       bool bol = true;
+       
+       bool internal_scope = false;
+       
+       string current_cheader_filename;
 
-               public void write_file (CodeContext context, string filename) {
-                       stream = File.open (filename, "w");
-               
-                       /* we're only interested in non-pkg source files */
-                       foreach (SourceFile file in context.get_source_files ()) {
-                               if (!file.pkg) {
-                                       file.accept (this);
-                               }
-                       }
-                       
-                       stream = null;
-               }
+       /**
+        * Writes the public interface of the specified code context into the
+        * specified file.
+        *
+        * @param context  a code context
+        * @param filename a relative or absolute filename
+        */
+       public void write_file (CodeContext! context, string! filename) {
+               stream = File.open (filename, "w");
        
-               public override void visit_begin_source_file (SourceFile source_file) {
-                       current_cheader_filename = source_file.get_cheader_filename ();
+               /* we're only interested in non-pkg source files */
+               foreach (SourceFile file in context.get_source_files ()) {
+                       if (!file.pkg) {
+                               file.accept (this);
+                       }
                }
+               
+               stream = null;
+       }
 
-               public override void visit_begin_namespace (Namespace ns) {
-                       if (ns.name == null)  {
-                               return;
-                       }
-                       
-                       write_indent ();
-                       write_string ("[CCode (cheader_filename = \"%s\")]".printf (current_cheader_filename));
-                       write_newline ();
+       public override void visit_begin_source_file (SourceFile source_file) {
+               current_cheader_filename = source_file.get_cheader_filename ();
+       }
 
-                       write_indent ();
-                       write_string ("namespace ");
-                       write_identifier (ns.name);
-                       write_begin_block ();
+       public override void visit_begin_namespace (Namespace ns) {
+               if (ns.name == null)  {
+                       return;
                }
+               
+               write_indent ();
+               write_string ("[CCode (cheader_filename = \"%s\")]".printf (current_cheader_filename));
+               write_newline ();
 
-               public override void visit_end_namespace (Namespace ns) {
-                       if (ns.name == null)  {
-                               return;
-                       }
-                       
-                       write_end_block ();
-                       write_newline ();
+               write_indent ();
+               write_string ("namespace ");
+               write_identifier (ns.name);
+               write_begin_block ();
+       }
+
+       public override void visit_end_namespace (Namespace ns) {
+               if (ns.name == null)  {
+                       return;
                }
+               
+               write_end_block ();
+               write_newline ();
+       }
 
-               public override void visit_begin_class (Class cl) {
-                       if (cl.access != MemberAccessibility.PUBLIC) {
-                               internal_scope = true;
-                               return;
-                       }
-                       
-                       write_indent ();
-                       write_string ("public ");
-                       if (cl.is_abstract) {
-                               write_string ("abstract ");
-                       }
-                       write_string ("class ");
-                       write_identifier (cl.name);
-                       
-                       var base_types = cl.get_base_types ();
-                       if (base_types != null) {
-                               write_string (" : ");
-                       
-                               bool first = true;
-                               foreach (TypeReference base_type in base_types) {
-                                       if (!first) {
-                                               write_string (", ");
-                                       } else {
-                                               first = false;
-                                       }
-                                       write_string (base_type.type.symbol.get_full_name ());
+       public override void visit_begin_class (Class cl) {
+               if (cl.access != MemberAccessibility.PUBLIC) {
+                       internal_scope = true;
+                       return;
+               }
+               
+               write_indent ();
+               write_string ("public ");
+               if (cl.is_abstract) {
+                       write_string ("abstract ");
+               }
+               write_string ("class ");
+               write_identifier (cl.name);
+               
+               var base_types = cl.get_base_types ();
+               if (base_types != null) {
+                       write_string (" : ");
+               
+                       bool first = true;
+                       foreach (TypeReference base_type in base_types) {
+                               if (!first) {
+                                       write_string (", ");
+                               } else {
+                                       first = false;
                                }
+                               write_string (base_type.type.symbol.get_full_name ());
                        }
-                       write_begin_block ();
                }
+               write_begin_block ();
+       }
 
-               public override void visit_end_class (Class cl) {
-                       if (cl.access != MemberAccessibility.PUBLIC) {
-                               internal_scope = false;
-                               return;
-                       }
-                       
-                       write_end_block ();
-                       write_newline ();
+       public override void visit_end_class (Class cl) {
+               if (cl.access != MemberAccessibility.PUBLIC) {
+                       internal_scope = false;
+                       return;
                }
+               
+               write_end_block ();
+               write_newline ();
+       }
 
-               public override void visit_begin_struct (Struct st) {
-                       if (st.access != MemberAccessibility.PUBLIC) {
-                               internal_scope = true;
-                               return;
-                       }
-                       
-                       write_indent ();
-                       write_string ("public struct ");
-                       write_identifier (st.name);
-                       write_begin_block ();
+       public override void visit_begin_struct (Struct st) {
+               if (st.access != MemberAccessibility.PUBLIC) {
+                       internal_scope = true;
+                       return;
                }
+               
+               write_indent ();
+               write_string ("public struct ");
+               write_identifier (st.name);
+               write_begin_block ();
+       }
 
-               public override void visit_end_struct (Struct st) {
-                       if (st.access != MemberAccessibility.PUBLIC) {
-                               internal_scope = false;
-                               return;
-                       }
-                       
-                       write_end_block ();
-                       write_newline ();
+       public override void visit_end_struct (Struct st) {
+               if (st.access != MemberAccessibility.PUBLIC) {
+                       internal_scope = false;
+                       return;
                }
+               
+               write_end_block ();
+               write_newline ();
+       }
 
-               public override void visit_begin_enum (Enum en) {
-                       if (en.access != MemberAccessibility.PUBLIC) {
-                               internal_scope = true;
-                               return;
-                       }
-                       
-                       write_indent ();
-                       write_string ("public enum ");
-                       write_identifier (en.name);
-                       write_begin_block ();
+       public override void visit_begin_enum (Enum en) {
+               if (en.access != MemberAccessibility.PUBLIC) {
+                       internal_scope = true;
+                       return;
                }
+               
+               write_indent ();
+               write_string ("public enum ");
+               write_identifier (en.name);
+               write_begin_block ();
+       }
 
-               public override void visit_end_enum (Enum en) {
-                       if (en.access != MemberAccessibility.PUBLIC) {
-                               internal_scope = false;
-                               return;
-                       }
-                       
-                       write_end_block ();
-                       write_newline ();
+       public override void visit_end_enum (Enum en) {
+               if (en.access != MemberAccessibility.PUBLIC) {
+                       internal_scope = false;
+                       return;
                }
+               
+               write_end_block ();
+               write_newline ();
+       }
 
-               public override void visit_enum_value (EnumValue ev) {
-                       if (internal_scope) {
-                               return;
-                       }
-                       
-                       write_indent ();
-                       write_identifier (ev.name);
-                       write_string (",");
-                       write_newline ();
+       public override void visit_enum_value (EnumValue ev) {
+               if (internal_scope) {
+                       return;
                }
+               
+               write_indent ();
+               write_identifier (ev.name);
+               write_string (",");
+               write_newline ();
+       }
 
-               public override void visit_constant (Constant c) {
-               }
+       public override void visit_constant (Constant c) {
+       }
 
-               public override void visit_field (Field f) {
-                       if (internal_scope || f.access != MemberAccessibility.PUBLIC) {
-                               return;
-                       }
+       public override void visit_field (Field f) {
+               if (internal_scope || f.access != MemberAccessibility.PUBLIC) {
+                       return;
+               }
+               
+               write_indent ();
+               write_string ("public ");
+               if (f.type_reference.is_weak) {
+                       write_string ("weak ");
+               }
+               write_string (f.type_reference.type.symbol.get_full_name ());
                        
-                       write_indent ();
-                       write_string ("public ");
-                       if (f.type_reference.is_weak) {
-                               write_string ("weak ");
-                       }
-                       write_string (f.type_reference.type.symbol.get_full_name ());
-                               
-                       var type_args = f.type_reference.get_type_arguments ();
-                       if (type_args != null) {
-                               write_string ("<");
-                               foreach (TypeReference type_arg in type_args) {
-                                       if (type_arg.is_weak) {
-                                               write_string ("weak ");
-                                       }
-                                       write_string (type_arg.type.symbol.get_full_name ());
+               var type_args = f.type_reference.get_type_arguments ();
+               if (type_args != null) {
+                       write_string ("<");
+                       foreach (TypeReference type_arg in type_args) {
+                               if (type_arg.is_weak) {
+                                       write_string ("weak ");
                                }
-                               write_string (">");
+                               write_string (type_arg.type.symbol.get_full_name ());
                        }
-                               
-                       write_string (" ");
-                       write_identifier (f.name);
-                       write_string (";");
-                       write_newline ();
+                       write_string (">");
                }
-
-               public override void visit_begin_method (Method m) {
-                       if (internal_scope || m.access != MemberAccessibility.PUBLIC || m.is_override) {
-                               return;
-                       }
                        
-                       write_indent ();
-                       write_string ("public ");
-                       
-                       if (!m.instance) {
-                               write_string ("static ");
-                       } else if (m.is_abstract) {
-                               write_string ("abstract ");
-                       } else if (m.is_virtual) {
-                               write_string ("virtual ");
+               write_string (" ");
+               write_identifier (f.name);
+               write_string (";");
+               write_newline ();
+       }
+
+       public override void visit_begin_method (Method m) {
+               if (internal_scope || m.access != MemberAccessibility.PUBLIC || m.overrides) {
+                       return;
+               }
+               
+               write_indent ();
+               write_string ("public ");
+               
+               if (!m.instance) {
+                       write_string ("static ");
+               } else if (m.is_abstract) {
+                       write_string ("abstract ");
+               } else if (m.is_virtual) {
+                       write_string ("virtual ");
+               }
+               
+               var type = m.return_type.type;
+               if (type == null) {
+                       write_string ("void");
+               } else {
+                       if (m.return_type.is_ref) {
+                               write_string ("ref ");
                        }
-                       
-                       var type = m.return_type.type;
-                       if (type == null) {
-                               write_string ("void");
+                       write_string (m.return_type.type.symbol.get_full_name ());
+               }
+               
+               write_string (" ");
+               write_identifier (m.name);
+               write_string (" (");
+               
+               bool first = true;
+               foreach (FormalParameter param in m.get_parameters ()) {
+                       if (!first) {
+                               write_string (", ");
                        } else {
-                               if (m.return_type.is_ref) {
-                                       write_string ("ref ");
-                               }
-                               write_string (m.return_type.type.symbol.get_full_name ());
-                       }
-                       
-                       write_string (" ");
-                       write_identifier (m.name);
-                       write_string (" (");
-                       
-                       bool first = true;
-                       foreach (FormalParameter param in m.parameters) {
-                               if (!first) {
-                                       write_string (", ");
-                               } else {
-                                       first = false;
-                               }
-                               
-                               if (param.type_reference.is_ref) {
-                                       write_string ("ref ");
-                               } else if (param.type_reference.is_out) {
-                                       write_string ("out ");
-                               }
-                               write_string (param.type_reference.type.symbol.get_full_name ());
-                               
-                               var type_args = param.type_reference.get_type_arguments ();
-                               if (type_args != null) {
-                                       write_string ("<");
-                                       foreach (TypeReference type_arg in type_args) {
-                                               if (type_arg.is_ref) {
-                                                       write_string ("ref ");
-                                               }
-                                               write_string (type_arg.type.symbol.get_full_name ());
-                                       }
-                                       write_string (">");
-                               }
-                               
-                               write_string (" ");
-                               write_identifier (param.name);
+                               first = false;
                        }
                        
-                       write_string (");");
-                       write_newline ();
-               }
-
-               public override void visit_begin_property (Property prop) {
-                       if (internal_scope) {
-                               return;
+                       if (param.type_reference.is_ref) {
+                               write_string ("ref ");
+                       } else if (param.type_reference.is_out) {
+                               write_string ("out ");
                        }
+                       write_string (param.type_reference.type.symbol.get_full_name ());
                        
-                       write_indent ();
-                       write_string ("public ");
-                       if (prop.type_reference.is_weak) {
-                               write_string ("weak ");
-                       }
-                       write_string (prop.type_reference.type.symbol.get_full_name ());
-                               
-                       var type_args = prop.type_reference.get_type_arguments ();
+                       var type_args = param.type_reference.get_type_arguments ();
                        if (type_args != null) {
                                write_string ("<");
                                foreach (TypeReference type_arg in type_args) {
-                                       if (type_arg.is_weak) {
-                                               write_string ("weak ");
+                                       if (type_arg.is_ref) {
+                                               write_string ("ref ");
                                        }
                                        write_string (type_arg.type.symbol.get_full_name ());
                                }
                                write_string (">");
                        }
-                               
+                       
                        write_string (" ");
-                       write_identifier (prop.name);
-                       write_string (" { get; set construct; }");
-                       write_newline ();
+                       write_identifier (param.name);
                }
+               
+               write_string (");");
+               write_newline ();
+       }
 
-               private void write_indent () {
-                       int i;
-                       
-                       if (!bol) {
-                               stream.putc ('\n');
-                       }
-                       
-                       for (i = 0; i < indent; i++) {
-                               stream.putc ('\t');
-                       }
-                       
-                       bol = false;
+       public override void visit_begin_property (Property prop) {
+               if (internal_scope) {
+                       return;
                }
                
-               private void write_identifier (string s) {
-                       if (s == "namespace") {
-                               stream.putc ('@');
-                       }
-                       write_string (s);
+               write_indent ();
+               write_string ("public ");
+               if (prop.type_reference.is_weak) {
+                       write_string ("weak ");
                }
-               
-               private void write_string (string s) {
-                       stream.printf ("%s", s);
-                       bol = false;
+               write_string (prop.type_reference.type.symbol.get_full_name ());
+                       
+               var type_args = prop.type_reference.get_type_arguments ();
+               if (type_args != null) {
+                       write_string ("<");
+                       foreach (TypeReference type_arg in type_args) {
+                               if (type_arg.is_weak) {
+                                       write_string ("weak ");
+                               }
+                               write_string (type_arg.type.symbol.get_full_name ());
+                       }
+                       write_string (">");
                }
+                       
+               write_string (" ");
+               write_identifier (prop.name);
+               write_string (" { get; set construct; }");
+               write_newline ();
+       }
+
+       private void write_indent () {
+               int i;
                
-               private void write_newline () {
+               if (!bol) {
                        stream.putc ('\n');
-                       bol = true;
                }
                
-               private void write_begin_block () {
-                       if (!bol) {
-                               stream.putc (' ');
-                       } else {
-                               write_indent ();
-                       }
-                       stream.putc ('{');
-                       write_newline ();
-                       indent++;
+               for (i = 0; i < indent; i++) {
+                       stream.putc ('\t');
                }
                
-               private void write_end_block () {
-                       indent--;
+               bol = false;
+       }
+       
+       private void write_identifier (string s) {
+               if (s == "namespace") {
+                       stream.putc ('@');
+               }
+               write_string (s);
+       }
+       
+       private void write_string (string s) {
+               stream.printf ("%s", s);
+               bol = false;
+       }
+       
+       private void write_newline () {
+               stream.putc ('\n');
+               bol = true;
+       }
+       
+       private void write_begin_block () {
+               if (!bol) {
+                       stream.putc (' ');
+               } else {
                        write_indent ();
-                       stream.printf ("}");
                }
+               stream.putc ('{');
+               write_newline ();
+               indent++;
+       }
+       
+       private void write_end_block () {
+               indent--;
+               write_indent ();
+               stream.printf ("}");
        }
 }
index 7ac01d390e06ae64eb1b6015df1766ad673560a8..91775d79d90cc9b6a9df215147025771f401bec3 100644 (file)
@@ -117,9 +117,12 @@ public class Vala.MemoryManager : CodeVisitor {
                        var param = (FormalParameter) msym.node;
                        var cb = (Callback) param.type_reference.type;
                        params = cb.get_parameters ();
-               } else {
+               } else if (msym.node is Method) {
                        var m = (Method) msym.node;
                        params = m.get_parameters ();
+               } else {
+                       var sig = (Signal) msym.node;
+                       params = sig.get_parameters ();
                }
                foreach (Expression arg in expr.argument_list) {
                        if (params != null) {
index d318cab56026cf36540fa55a1bc9aeb71b153616..196cc7249f230a04e197fee7329ce52749583ac7 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class Method : CodeNode {
-               public string name { get; construct; }
-               public TypeReference return_type { get; construct; }
-               Statement _body;
-               public Statement body {
-                       get {
-                               return _body;
-                       }
-                       set {
-                               _body = value;
-                       }
+/**
+ * Represents a type or namespace method.
+ */
+public class Vala.Method : CodeNode {
+       /**
+        * The symbol name of this method.
+        */
+       public string! name { get; set construct; }
+
+       /**
+        * The return type of this method.
+        */
+       public TypeReference! return_type { get; set construct; }
+       
+       public Statement body { get; set; }
+       
+       /**
+        * Specifies the accessibility of this method. Public accessibility
+        * doesn't limit access. Default accessibility limits access to this
+        * program or library. Private accessibility limits access to instances
+        * of the contained type.
+        */
+       public MemberAccessibility access;
+       
+       /**
+        * Specifies whether this method may only be called with an instance of
+        * the contained type.
+        */
+       public bool instance {
+               get {
+                       return _instance;
                }
-               public MemberAccessibility access;
-               public bool instance = true;
-               public bool is_abstract;
-               public bool is_virtual;
-               public bool is_override;
-               public List<FormalParameter> parameters;
-               public string cname;
-               public bool returns_modified_pointer;
-               public bool instance_last;
-               
-               /* reference must be weak as virtual methods set base_method to themselves */
-               public weak Method base_method;
-               
-               public FormalParameter this_parameter;
-               
-               public static ref Method new (string name, TypeReference return_type, SourceReference source) {
-                       return (new Method (name = name, return_type = return_type, source_reference = source));
+               set {
+                       _instance = value;
                }
+       }
+       
+       /**
+        * Specifies whether this method is abstract. Abstract methods have no
+        * body, may only be specified within abstract classes, and must be
+        * overriden by derived non-abstract classes.
+        */
+       public bool is_abstract { get; set; }
+       
+       /**
+        * Specifies whether this method is virtual. Virtual methods may be
+        * overridden by derived classes.
+        */
+       public bool is_virtual { get; set; }
+       
+       /**
+        * Specifies whether this method overrides a virtual or abstract method
+        * of a base type.
+        */
+       public bool overrides { get; set; }
+
+       /**
+        * Specifies whether the C method returns a new instance pointer which
+        * may be different from the previous instance pointer. Only valid for
+        * imported methods.
+        */
+       public bool returns_modified_pointer { get; set; }
+       
+       /**
+        * Specifies whether the instance pointer should be passed as the first
+        * or as the last argument in C code. Defaults to first.
+        */
+       public bool instance_last { get; set; }
+       
+       /**
+        * Specifies the virtual or abstract method this method overrides.
+        * Reference must be weak as virtual methods set base_method to
+        * themselves.
+        */
+       public weak Method base_method { get; set; }
+       
+       /**
+        * Specifies the generated `this' parameter for instance methods.
+        */
+       public FormalParameter this_parameter { get; set; }
+
+       private bool _instance = true;
+       private List<FormalParameter> parameters;
+       private string cname;
+       
+       /**
+        * Creates a new method.
+        *
+        * @param name        method name
+        * @param return_type method return type
+        * @param source      reference to source code
+        * @return            newly created method
+        */
+       public static ref Method! new (string! name, TypeReference! return_type, SourceReference source) {
+               return (new Method (name = name, return_type = return_type, source_reference = source));
+       }
+       
+       /**
+        * Appends parameter to this method.
+        *
+        * @param param a formal parameter
+        */
+       public void add_parameter (FormalParameter! param) {
+               parameters.append (param);
+       }
+       
+       /**
+        * Returns copy of the list of method parameters.
+        *
+        * @return parameter list
+        */
+       public ref List<FormalParameter> get_parameters () {
+               return parameters.copy ();
+       }
+       
+       public override void accept (CodeVisitor visitor) {
+               visitor.visit_begin_method (this);
                
-               public void add_parameter (FormalParameter param) {
-                       parameters.append (param);
-               }
+               return_type.accept (visitor);
                
-               public ref List<FormalParameter> get_parameters () {
-                       return parameters.copy ();
+               foreach (FormalParameter param in parameters) {
+                       param.accept (visitor);
                }
                
-               public override void accept (CodeVisitor visitor) {
-                       visitor.visit_begin_method (this);
-                       
-                       return_type.accept (visitor);
-                       
-                       foreach (FormalParameter param in parameters) {
-                               param.accept (visitor);
-                       }
-                       
-                       if (body != null) {
-                               body.accept (visitor);
-                       }
-
-                       visitor.visit_end_method (this);
+               if (body != null) {
+                       body.accept (visitor);
                }
 
-               public string get_cname () {
-                       if (cname == null) {
-                               var parent = symbol.parent_symbol.node;
-                               if (parent is DataType) {
-                                       cname = "%s_%s".printf (((DataType) parent).get_lower_case_cname (null), name);
-                               } else if (parent is Namespace) {
-                                       cname = "%s%s".printf (((Namespace) parent).get_lower_case_cprefix (), name);
-                               } else {
-                                       cname = name;
-                               }
-                       }
-                       return cname;
-               }
+               visitor.visit_end_method (this);
+       }
 
-               public ref string get_real_cname () {
-                       if (is_virtual || is_override) {
-                               var parent = (Class) symbol.parent_symbol.node;
-                               return "%s_real_%s".printf (parent.get_lower_case_cname (null), name);
+       /**
+        * Returns the interface name of this method as it is used in C code.
+        *
+        * @return the name to be used in C code
+        */
+       public string! get_cname () {
+               if (cname == null) {
+                       var parent = symbol.parent_symbol.node;
+                       if (parent is DataType) {
+                               cname = "%s_%s".printf (((DataType) parent).get_lower_case_cname (null), name);
+                       } else if (parent is Namespace) {
+                               cname = "%s%s".printf (((Namespace) parent).get_lower_case_cprefix (), name);
                        } else {
-                               return get_cname ();
+                               cname = name;
                        }
                }
-               
-               public void set_cname (string cname) {
-                       this.cname = cname;
+               return cname;
+       }
+
+       /**
+        * Returns the implementation name of this data type as it is used in C
+        * code.
+        *
+        * @return the name to be used in C code
+        */
+       public ref string! get_real_cname () {
+               if (is_virtual || overrides) {
+                       var parent = (Class) symbol.parent_symbol.node;
+                       return "%s_real_%s".printf (parent.get_lower_case_cname (null), name);
+               } else {
+                       return get_cname ();
                }
-               
-               void process_ccode_attribute (Attribute a) {
-                       foreach (NamedArgument arg in a.args) {
-                               if (arg.name == "cname") {
-                                       /* this will already be checked during semantic analysis */
-                                       if (arg.argument is LiteralExpression) {
-                                               var lit = ((LiteralExpression) arg.argument).literal;
-                                               if (lit is StringLiteral) {
-                                                       set_cname (((StringLiteral) lit).eval ());
-                                               }
+       }
+       
+       private void set_cname (string cname) {
+               this.cname = cname;
+       }
+       
+       private void process_ccode_attribute (Attribute a) {
+               foreach (NamedArgument arg in a.args) {
+                       if (arg.name == "cname") {
+                               /* this will already be checked during semantic analysis */
+                               if (arg.argument is LiteralExpression) {
+                                       var lit = ((LiteralExpression) arg.argument).literal;
+                                       if (lit is StringLiteral) {
+                                               set_cname (((StringLiteral) lit).eval ());
                                        }
                                }
                        }
                }
-               
-               public void process_attributes () {
-                       foreach (Attribute a in attributes) {
-                               if (a.name == "CCode") {
-                                       process_ccode_attribute (a);
-                               } else if (a.name == "ReturnsModifiedPointer") {
-                                       returns_modified_pointer = true;
-                               } else if (a.name == "InstanceLast") {
-                                       instance_last = true;
-                               } else if (a.name == "FloatingReference") {
-                                       return_type.floating_reference = true;
-                               }
+       }
+       
+       /**
+        * Process all associated attributes.
+        */
+       public void process_attributes () {
+               foreach (Attribute a in attributes) {
+                       if (a.name == "CCode") {
+                               process_ccode_attribute (a);
+                       } else if (a.name == "ReturnsModifiedPointer") {
+                               returns_modified_pointer = true;
+                       } else if (a.name == "InstanceLast") {
+                               instance_last = true;
+                       } else if (a.name == "FloatingReference") {
+                               return_type.floating_reference = true;
                        }
                }
        }
index a88804dcb3e4ff66433be6f0c3e1eff7749c1fcc..73286ba62a90078bbc98a91b8d54a73e18f4aa22 100644 (file)
@@ -139,7 +139,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        current_return_type = up_method.return_type;
                }
                
-               if (m.is_virtual || m.is_override) {
+               if (m.is_virtual || m.overrides) {
                        if (current_symbol.node is Class) {
                                var cl = (Class) current_symbol.node;
                                Class base_class;
@@ -614,7 +614,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        }
                } else if (msym.node is Method) {
                        var m = (Method) msym.node;
-                       params = m.parameters;
+                       params = m.get_parameters ();
+               } else if (msym.node is Signal) {
+                       var sig = (Signal) msym.node;
+                       params = sig.get_parameters ();
                } else {
                        expr.error = true;
                        Report.error (expr.source_reference, "invocation not supported in this context");
@@ -661,7 +664,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                } else if (msym.node is Method) {
                        var m = (Method) msym.node;
                        ret_type = m.return_type;
-                       params = m.parameters;
+                       params = m.get_parameters ();
+               } else if (msym.node is Signal) {
+                       var sig = (Signal) msym.node;
+                       ret_type = sig.return_type;
+                       params = sig.get_parameters ();
                }
        
                expr.static_type = ret_type;
@@ -683,7 +690,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
 
                        if (arg_it == null) {
                                if (param.default_expression == null) {
-                                       Report.error (expr.source_reference, "Method `%s' does not take %d arguments".printf (msym.get_full_name (), expr.argument_list.length ()));
+                                       Report.error (expr.source_reference, "Too few arguments, method `%s' does not take %d arguments".printf (msym.get_full_name (), expr.argument_list.length ()));
                                        return;
                                }
                        } else {
@@ -702,7 +709,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                }
                
                if (!ellipsis && arg_it != null) {
-                       Report.error (expr.source_reference, "Method `%s' does not take %d arguments".printf (msym.get_full_name (), expr.argument_list.length ()));
+                       Report.error (expr.source_reference, "Too many arguments, method `%s' does not take %d arguments".printf (msym.get_full_name (), expr.argument_list.length ()));
                        return;
                }
        }
@@ -978,7 +985,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        l.method.body = block;
                } else {
                        l.method.body = l.statement_body;
-                       l.method.body.symbol = new Symbol (node = l.method.body);
                        l.method.body.symbol.parent_symbol = l.method.symbol;
                }
                
@@ -1008,6 +1014,32 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                
                if (ma.symbol_reference.node is Signal) {
                        var sig = (Signal) ma.symbol_reference.node;
+
+                       if (a.right.symbol_reference == null) {
+                               a.right.error = true;
+                               Report.error (a.right.source_reference, "unsupported expression for signal handler");
+                               return;
+                       }
+                       
+                       var m = (Method) a.right.symbol_reference.node;
+                       
+                       if (m.instance && m.access == MemberAccessibility.PUBLIC) {
+                               /* TODO: generate wrapper function */
+                               
+                               ma.error = true;
+                               Report.error (a.right.source_reference, "public instance methods not yet supported as signal handlers");
+                               return;
+                       }
+                       
+                       if (m.instance) {
+                               /* instance signal handlers must have the self
+                                * parameter at the end
+                                * do not use G_CONNECT_SWAPPED as this would
+                                * rearrange the parameters for instance
+                                * methods and non-instance methods
+                                */
+                               m.instance_last = true;
+                       }
                } else if (ma.symbol_reference.node is Property) {
                        var prop = (Property) ma.symbol_reference.node;
                } else if (ma.symbol_reference.node is VariableDeclarator && a.right.static_type == null) {
index f8f6ac2b248e3b7b6f924f6398f500a2e743c865..e8c1e6728f21b20f9c419a39b5b31a7465d05fc9 100644 (file)
@@ -58,7 +58,7 @@ public class Vala.Signal : CodeNode {
        }
        
        /**
-        * Append parameter to signal handler.
+        * Appends parameter to signal handler.
         *
         * @param param a formal parameter
         */
index ef8d40ffd953f47a5c010381eb73b16a925b924b..4397e6df7ab0f3a11a3ac954cedd88a1ccd40759 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class Struct : DataType {
-               List<TypeParameter> type_parameters;
-               List<Constant> constants;
-               List<Field> fields;
-               List<Method> methods;
-               
-               string cname;
-               string dup_function;
-               string free_function;
-               string type_id;
-               string lower_case_csuffix;
-               bool reference_type;
-               
-               public static ref Struct new (string! name, SourceReference source) {
-                       return (new Struct (name = name, source_reference = source));
-               }
+/**
+ * Represents a struct declaration in the source code.
+ */
+public class Vala.Struct : DataType {
+       List<TypeParameter> type_parameters;
+       List<Constant> constants;
+       List<Field> fields;
+       List<Method> methods;
+       
+       string cname;
+       string dup_function;
+       string free_function;
+       string type_id;
+       string lower_case_csuffix;
+       bool reference_type;
+       string marshaller_type_name;
+       
+       /**
+        * Creates a new struct.
+        *
+        * @param name   type name
+        * @param source reference to source code
+        * @return       newly created struct
+        */
+       public static ref Struct! new (string! name, SourceReference source) {
+               return (new Struct (name = name, source_reference = source));
+       }
 
-               public void add_type_parameter (TypeParameter! p) {
-                       type_parameters.append (p);
-                       p.type = this;
-               }
+       /**
+        * Appends the specified parameter to the list of type parameters.
+        *
+        * @param p a type parameter
+        */
+       public void add_type_parameter (TypeParameter! p) {
+               type_parameters.append (p);
+               p.type = this;
+       }
+       
+       /**
+        * Adds the specified constant as a member to this struct.
+        *
+        * @param c a constant
+        */
+       public void add_constant (Constant! c) {
+               constants.append (c);
+       }
+       
+       /**
+        * Adds the specified field as a member to this struct.
+        *
+        * @param f a field
+        */
+       public void add_field (Field! f) {
+               fields.append (f);
+       }
+       
+       /**
+        * Returns a copy of the list of fields.
+        *
+        * @return list of fields
+        */
+       public ref List<Field> get_fields () {
+               return fields.copy ();
+       }
+       
+       /**
+        * Adds the specified method as a member to this struct.
+        *
+        * @param m a method
+        */
+       public void add_method (Method! m) {
+               return_if_fail (m != null);
                
-               public void add_constant (Constant! c) {
-                       constants.append (c);
-               }
+               methods.append (m);
+       }
+       
+       /**
+        * Returns a copy of the list of methods.
+        *
+        * @return list of methods
+        */
+       public ref List<Method> get_methods () {
+               return methods.copy ();
+       }
+       
+       public override void accept (CodeVisitor! visitor) {
+               visitor.visit_begin_struct (this);
                
-               public void add_field (Field! f) {
-                       fields.append (f);
+               foreach (TypeParameter p in type_parameters) {
+                       p.accept (visitor);
                }
                
-               public ref List<Field> get_fields () {
-                       return fields.copy ();
+               foreach (Field f in fields) {
+                       f.accept (visitor);
                }
                
-               public void add_method (Method! m) {
-                       return_if_fail (m != null);
-                       
-                       methods.append (m);
+               foreach (Constant c in constants) {
+                       c.accept (visitor);
                }
                
-               public ref List<Method> get_methods () {
-                       return methods.copy ();
+               foreach (Method m in methods) {
+                       m.accept (visitor);
                }
-               
-               public override void accept (CodeVisitor! visitor) {
-                       visitor.visit_begin_struct (this);
-                       
-                       foreach (TypeParameter p in type_parameters) {
-                               p.accept (visitor);
-                       }
-                       
-                       foreach (Field f in fields) {
-                               f.accept (visitor);
-                       }
-                       
-                       foreach (Constant c in constants) {
-                               c.accept (visitor);
-                       }
-                       
-                       foreach (Method m in methods) {
-                               m.accept (visitor);
-                       }
 
-                       visitor.visit_end_struct (this);
-               }
-               
-               public override string get_cname () {
-                       if (cname == null) {
-                               cname = "%s%s".printf (@namespace.get_cprefix (), name);
-                       }
-                       return cname;
-               }
-               
-               public void set_cname (string! cname) {
-                       this.cname = cname;
-               }
-               
-               public string get_lower_case_csuffix () {
-                       if (lower_case_csuffix == null) {
-                               lower_case_csuffix = Namespace.camel_case_to_lower_case (name);
-                       }
-                       return lower_case_csuffix;
-               }
-               
-               public void set_lower_case_csuffix (string! csuffix) {
-                       this.lower_case_csuffix = csuffix;
-               }
-               
-               public override ref string get_lower_case_cname (string infix) {
-                       if (infix == null) {
-                               infix = "";
-                       }
-                       return "%s%s%s".printf (@namespace.get_lower_case_cprefix (), infix, get_lower_case_csuffix ());
+               visitor.visit_end_struct (this);
+       }
+       
+       public override string get_cname () {
+               if (cname == null) {
+                       cname = "%s%s".printf (@namespace.get_cprefix (), name);
                }
-               
-               public override ref string get_upper_case_cname (string infix) {
-                       return get_lower_case_cname (infix).up ();
+               return cname;
+       }
+       
+       private void set_cname (string! cname) {
+               this.cname = cname;
+       }
+       
+       private string get_lower_case_csuffix () {
+               if (lower_case_csuffix == null) {
+                       lower_case_csuffix = Namespace.camel_case_to_lower_case (name);
                }
-               
-               public override bool is_reference_type () {
-                       return reference_type;
+               return lower_case_csuffix;
+       }
+       
+       private void set_lower_case_csuffix (string! csuffix) {
+               this.lower_case_csuffix = csuffix;
+       }
+       
+       public override ref string get_lower_case_cname (string infix) {
+               if (infix == null) {
+                       infix = "";
                }
-               
-               private void process_ccode_attribute (Attribute! a) {
-                       foreach (NamedArgument arg in a.args) {
-                               if (arg.name == "cname") {
-                                       /* this will already be checked during semantic analysis */
-                                       if (arg.argument is LiteralExpression) {
-                                               var lit = ((LiteralExpression) arg.argument).literal;
-                                               if (lit is StringLiteral) {
-                                                       set_cname (((StringLiteral) lit).eval ());
-                                               }
-                                       }
-                               } else if (arg.name == "cheader_filename") {
-                                       /* this will already be checked during semantic analysis */
-                                       if (arg.argument is LiteralExpression) {
-                                               var lit = ((LiteralExpression) arg.argument).literal;
-                                               if (lit is StringLiteral) {
-                                                       var val = ((StringLiteral) lit).eval ();
-                                                       foreach (string filename in val.split (",", 0)) {
-                                                               add_cheader_filename (filename);
-                                                       }
-                                               }
+               return "%s%s%s".printf (@namespace.get_lower_case_cprefix (), infix, get_lower_case_csuffix ());
+       }
+       
+       public override ref string get_upper_case_cname (string infix) {
+               return get_lower_case_cname (infix).up ();
+       }
+       
+       public override bool is_reference_type () {
+               return reference_type;
+       }
+       
+       private void process_ccode_attribute (Attribute! a) {
+               foreach (NamedArgument arg in a.args) {
+                       if (arg.name == "cname") {
+                               /* this will already be checked during semantic analysis */
+                               if (arg.argument is LiteralExpression) {
+                                       var lit = ((LiteralExpression) arg.argument).literal;
+                                       if (lit is StringLiteral) {
+                                               set_cname (((StringLiteral) lit).eval ());
                                        }
                                }
-                       }
-               }
-               
-               private void process_ref_type_attribute (Attribute! a) {
-                       reference_type = true;
-                       foreach (NamedArgument arg in a.args) {
-                               if (arg.name == "dup_function") {
-                                       /* this will already be checked during semantic analysis */
-                                       if (arg.argument is LiteralExpression) {
-                                               var lit = ((LiteralExpression) arg.argument).literal;
-                                               if (lit is StringLiteral) {
-                                                       set_dup_function (((StringLiteral) lit).eval ());
+                       } else if (arg.name == "cheader_filename") {
+                               /* this will already be checked during semantic analysis */
+                               if (arg.argument is LiteralExpression) {
+                                       var lit = ((LiteralExpression) arg.argument).literal;
+                                       if (lit is StringLiteral) {
+                                               var val = ((StringLiteral) lit).eval ();
+                                               foreach (string filename in val.split (",", 0)) {
+                                                       add_cheader_filename (filename);
                                                }
                                        }
-                               } else if (arg.name == "free_function") {
-                                       /* this will already be checked during semantic analysis */
-                                       if (arg.argument is LiteralExpression) {
-                                               var lit = ((LiteralExpression) arg.argument).literal;
-                                               if (lit is StringLiteral) {
-                                                       set_free_function (((StringLiteral) lit).eval ());
-                                               }
+                               }
+                       } else if (arg.name == "type_id") {
+                               /* this will already be checked during semantic analysis */
+                               if (arg.argument is LiteralExpression) {
+                                       var lit = ((LiteralExpression) arg.argument).literal;
+                                       if (lit is StringLiteral) {
+                                               set_type_id (((StringLiteral) lit).eval ());
                                        }
-                               } else if (arg.name == "type_id") {
-                                       /* this will already be checked during semantic analysis */
-                                       if (arg.argument is LiteralExpression) {
-                                               var lit = ((LiteralExpression) arg.argument).literal;
-                                               if (lit is StringLiteral) {
-                                                       set_type_id (((StringLiteral) lit).eval ());
-                                               }
+                               }
+                       } else if (arg.name == "marshaller_type_name") {
+                               /* this will already be checked during semantic analysis */
+                               if (arg.argument is LiteralExpression) {
+                                       var lit = ((LiteralExpression) arg.argument).literal;
+                                       if (lit is StringLiteral) {
+                                               set_marshaller_type_name (((StringLiteral) lit).eval ());
                                        }
                                }
                        }
                }
-               
-               public void process_attributes () {
-                       foreach (Attribute a in attributes) {
-                               if (a.name == "CCode") {
-                                       process_ccode_attribute (a);
-                               } else if (a.name == "ReferenceType") {
-                                       process_ref_type_attribute (a);
+       }
+       
+       private void process_ref_type_attribute (Attribute! a) {
+               reference_type = true;
+               foreach (NamedArgument arg in a.args) {
+                       if (arg.name == "dup_function") {
+                               /* this will already be checked during semantic analysis */
+                               if (arg.argument is LiteralExpression) {
+                                       var lit = ((LiteralExpression) arg.argument).literal;
+                                       if (lit is StringLiteral) {
+                                               set_dup_function (((StringLiteral) lit).eval ());
+                                       }
+                               }
+                       } else if (arg.name == "free_function") {
+                               /* this will already be checked during semantic analysis */
+                               if (arg.argument is LiteralExpression) {
+                                       var lit = ((LiteralExpression) arg.argument).literal;
+                                       if (lit is StringLiteral) {
+                                               set_free_function (((StringLiteral) lit).eval ());
+                                       }
                                }
                        }
                }
-
-               public override bool is_reference_counting () {
-                       return false;
-               }
-               
-               public override string get_dup_function () {
-                       if (dup_function == null) {
-                               Report.error (source_reference, "The type `%s` doesn't contain a copy function".printf (symbol.get_full_name ()));
+       }
+       
+       /**
+        * Process all associated attributes.
+        */
+       public void process_attributes () {
+               foreach (Attribute a in attributes) {
+                       if (a.name == "CCode") {
+                               process_ccode_attribute (a);
+                       } else if (a.name == "ReferenceType") {
+                               process_ref_type_attribute (a);
                        }
-                       return dup_function;
-               }
-               
-               public void set_dup_function (string! name) {
-                       this.dup_function = name;
                }
-               
-               public override string get_free_function () {
-                       if (free_function == null) {
-                               Report.error (source_reference, "The type `%s` doesn't contain a free function".printf (symbol.get_full_name ()));
-                       }
-                       return free_function;
+       }
+
+       public override bool is_reference_counting () {
+               return false;
+       }
+       
+       public override string get_dup_function () {
+               if (dup_function == null) {
+                       Report.error (source_reference, "The type `%s` doesn't contain a copy function".printf (symbol.get_full_name ()));
                }
-               
-               public void set_free_function (string! name) {
-                       this.free_function = name;
+               return dup_function;
+       }
+       
+       public void set_dup_function (string! name) {
+               this.dup_function = name;
+       }
+       
+       public override string get_free_function () {
+               if (free_function == null) {
+                       Report.error (source_reference, "The type `%s` doesn't contain a free function".printf (symbol.get_full_name ()));
                }
-               
-               public override string get_type_id () {
-                       if (type_id == null) {
-                               Report.error (source_reference, "The type `%s` doesn't declare a type id".printf (symbol.get_full_name ()));
-                       }
-                       return type_id;
+               return free_function;
+       }
+       
+       private void set_free_function (string! name) {
+               this.free_function = name;
+       }
+       
+       public override string get_type_id () {
+               if (type_id == null) {
+                       Report.error (source_reference, "The type `%s` doesn't declare a type id".printf (symbol.get_full_name ()));
                }
-               
-               public void set_type_id (string! name) {
-                       this.type_id = name;
+               return type_id;
+       }
+       
+       private void set_type_id (string! name) {
+               this.type_id = name;
+       }
+
+       public override string get_marshaller_type_name () {
+               if (marshaller_type_name == null) {
+                       Report.error (source_reference, "The type `%s` doesn't declare a marshaller type name".printf (symbol.get_full_name ()));
                }
+               return marshaller_type_name;
+       }
+       
+       private void set_marshaller_type_name (string! name) {
+               this.marshaller_type_name = name;
        }
 }
index 9bf68abcb9ed95421b2e255bfd14c312f3055c5b..aa8188afd8762df25c923f7246db9b6edaea18e8 100644 (file)
  *     Jürg Billeter <j@bitron.ch>
  */
 
-[CCode (cname = "gboolean", cheader_filename = "glib.h")]
+[CCode (cname = "gboolean", cheader_filename = "glib.h", type_id = "G_TYPE_BOOLEAN", marshaller_type_name = "BOOLEAN")]
 public struct bool {
 }
 
-[CCode (cname = "gpointer", cheader_filename = "glib.h")]
+[CCode (cname = "gpointer", cheader_filename = "glib.h", type_id = "G_TYPE_POINTER", marshaller_type_name = "POINTER")]
 public struct pointer {
 }
 
-[CCode (cheader_filename = "glib.h")]
+[CCode (cheader_filename = "glib.h", type_id = "G_TYPE_CHAR", marshaller_type_name = "CHAR")]
 public struct char {
 }
 
-[CCode (cname = "unsigned char", cheader_filename = "glib.h")]
+[CCode (cname = "unsigned char", cheader_filename = "glib.h", type_id = "G_TYPE_UCHAR", marshaller_type_name = "UCHAR")]
 public struct uchar {
 }
 
-[CCode (cheader_filename = "glib.h")]
+[CCode (cheader_filename = "glib.h", type_id = "G_TYPE_INT", marshaller_type_name = "INT")]
 public struct int {
 }
 
-[CCode (cname = "unsigned int", cheader_filename = "glib.h")]
+[CCode (cname = "unsigned int", cheader_filename = "glib.h", type_id = "G_TYPE_UINT", marshaller_type_name = "UINT")]
 public struct uint {
 }
 
@@ -52,11 +52,11 @@ public struct short {
 public struct ushort {
 }
 
-[CCode (cheader_filename = "glib.h")]
+[CCode (cheader_filename = "glib.h", type_id = "G_TYPE_LONG", marshaller_type_name = "LONG")]
 public struct long {
 }
 
-[CCode (cname = "unsigned long", cheader_filename = "glib.h")]
+[CCode (cname = "unsigned long", cheader_filename = "glib.h", type_id = "G_TYPE_ULONG", marshaller_type_name = "ULONG")]
 public struct ulong {
 }
 
@@ -84,19 +84,19 @@ public struct int32 {
 public struct uint32 {
 }
 
-[CCode (cname = "gint64", cheader_filename = "glib.h")]
+[CCode (cname = "gint64", cheader_filename = "glib.h", type_id = "G_TYPE_INT64", marshaller_type_name = "INT64")]
 public struct int64 {
 }
 
-[CCode (cname = "guint64", cheader_filename = "glib.h")]
+[CCode (cname = "guint64", cheader_filename = "glib.h", type_id = "G_TYPE_UINT64", marshaller_type_name = "UINT64")]
 public struct uint64 {
 }
 
-[CCode (cname = "float", cheader_filename = "glib.h")]
+[CCode (cname = "float", cheader_filename = "glib.h", type_id = "G_TYPE_FLOAT", marshaller_type_name = "FLOAT")]
 public struct float {
 }
 
-[CCode (cname = "double", cheader_filename = "glib.h")]
+[CCode (cname = "double", cheader_filename = "glib.h", type_id = "G_TYPE_DOUBLE", marshaller_type_name = "DOUBLE")]
 public struct double {
 }
 
@@ -113,7 +113,7 @@ public struct unichar {
 }
 
 [ReferenceType (dup_function = "g_strdup", free_function = "g_free", type_id = "G_TYPE_STRING", ref_function = "g_strdup")]
-[CCode (cname = "char", cheader_filename = "string.h,glib.h")]
+[CCode (cname = "char", cheader_filename = "string.h,glib.h", type_id = "G_TYPE_STRING", marshaller_type_name = "STRING")]
 public struct string {
        [CCode (cname = "g_str_has_suffix")]
        public bool has_suffix (string suffix);