adapt to Vala.Signal change process signal attributes manage memory of
authorJürg Billeter <j@bitron.ch>
Wed, 9 Aug 2006 15:46:25 +0000 (15:46 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Wed, 9 Aug 2006 15:46:25 +0000 (15:46 +0000)
2006-08-09  Jürg Billeter  <j@bitron.ch>

* vala/parser.y: adapt to Vala.Signal change
* vala/valaattributeprocessor.vala: process signal attributes
* vala/valacodegenerator.vala: manage memory of element access
  expressions, mark get_property and set_property functions static,
  support signal emitter functions
* vala/valacodecontext.vala: use get_cinclude_filename method
* vala/valainterfacewriter.vala: use C header filename of namespace,
  support signals, support NoAccessorMethod attribute
* vala/valadatatype.vala: add default arguments
* vala/valaenum.vala: make set_cprefix method public
* vala/valanamespace.vala: add get_cheader_filename and
  set_cheader_filename methods
* vala/valasignal.vala: add has_emitter property, add process_attributes
  method
* vala/valasourcefile.vala: add get_cinclude_filename method
* compiler/valacompiler.vala: adapt to SourceFile changes

svn path=/trunk/; revision=93

12 files changed:
vala/ChangeLog
vala/compiler/valacompiler.vala
vala/vala/parser.y
vala/vala/valaattributeprocessor.vala
vala/vala/valacodecontext.vala
vala/vala/valacodegenerator.vala
vala/vala/valadatatype.vala
vala/vala/valaenum.vala
vala/vala/valainterfacewriter.vala
vala/vala/valanamespace.vala
vala/vala/valasignal.vala
vala/vala/valasourcefile.vala

index 86781b2..e92b906 100644 (file)
@@ -1,3 +1,22 @@
+2006-08-09  Jürg Billeter  <j@bitron.ch>
+
+       * vala/parser.y: adapt to Vala.Signal change
+       * vala/valaattributeprocessor.vala: process signal attributes
+       * vala/valacodegenerator.vala: manage memory of element access
+         expressions, mark get_property and set_property functions static,
+         support signal emitter functions
+       * vala/valacodecontext.vala: use get_cinclude_filename method
+       * vala/valainterfacewriter.vala: use C header filename of namespace,
+         support signals, support NoAccessorMethod attribute
+       * vala/valadatatype.vala: add default arguments
+       * vala/valaenum.vala: make set_cprefix method public
+       * vala/valanamespace.vala: add get_cheader_filename and
+         set_cheader_filename methods
+       * vala/valasignal.vala: add has_emitter property, add process_attributes
+         method
+       * vala/valasourcefile.vala: add get_cinclude_filename method
+       * compiler/valacompiler.vala: adapt to SourceFile changes
+
 2006-08-05  Jürg Billeter  <j@bitron.ch>
 
        * vala/valaparser.vala: only parse .vala source files
index 90d4e09..17562fb 100644 (file)
@@ -85,7 +85,7 @@ class Vala.Compiler {
                        return false;
                }
                
-               context.add_source_file (new SourceFile (package_path, true));
+               context.add_source_file (new SourceFile (context, package_path, true));
                
                return true;
        }
@@ -115,7 +115,7 @@ class Vala.Compiler {
                
                foreach (string source in sources) {
                        if (File.test (source, FileTest.EXISTS)) {
-                               context.add_source_file (new SourceFile (source));
+                               context.add_source_file (new SourceFile (context, source));
                        } else {
                                Report.error (null, "%s not found".printf (source));
                        }
index 79a5354..109e52a 100644 (file)
@@ -2346,7 +2346,7 @@ signal_declaration
                $$ = vala_signal_new ($6, $5, src);
                g_object_unref (src);
                if ($3 != 0) {
-                       $$->access = $3;
+                       vala_signal_set_access ($$, $3);
                }
                VALA_CODE_NODE($$)->attributes = $2;
                
index efecfbe..20178ff 100644 (file)
@@ -62,4 +62,8 @@ public class Vala.AttributeProcessor : CodeVisitor {
        public override void visit_field (Field! f) {
                f.process_attributes ();
        }
+
+       public override void visit_begin_signal (Signal! sig) {
+               sig.process_attributes ();
+       }
 }
index 7366362..a9d0957 100644 (file)
@@ -115,11 +115,11 @@ public class Vala.CodeContext {
                                        /* in the same cycle */
                                        if (!file2.is_cycle_head) {
                                                /* include header of cycle head */
-                                               file2.add_header_internal_include (file2.cycle.head.get_cheader_filename ());
+                                               file2.add_header_internal_include (file2.cycle.head.get_cinclude_filename ());
                                        }
                                } else {
                                        /* we can just include the headers if they are not in a cycle or not in the same cycle as the current file */
-                                       file2.add_header_internal_include (dep.get_cheader_filename ());
+                                       file2.add_header_internal_include (dep.get_cinclude_filename ());
                                }
                        }
                }
index ff8d5f2..d9b0583 100644 (file)
@@ -101,11 +101,7 @@ public class Vala.CodeGenerator : CodeVisitor {
        }
        
        private ref CCodeIncludeDirective get_internal_include (string! filename) {
-               if (context.library != null) {
-                       return new CCodeIncludeDirective ("%s/%s".printf (context.library, filename));
-               } else {
-                       return new CCodeIncludeDirective (filename, true);
-               }
+               return new CCodeIncludeDirective (filename, context.library == null);
        }
 
        public override void visit_begin_source_file (SourceFile! source_file) {
@@ -617,6 +613,7 @@ public class Vala.CodeGenerator : CodeVisitor {
        
        private void add_get_property_function (Class! cl) {
                var get_prop = new CCodeFunction ("%s_get_property".printf (cl.get_lower_case_cname (null)), "void");
+               get_prop.modifiers = CCodeModifiers.STATIC;
                get_prop.add_parameter (new CCodeFormalParameter ("object", "GObject *"));
                get_prop.add_parameter (new CCodeFormalParameter ("property_id", "guint"));
                get_prop.add_parameter (new CCodeFormalParameter ("value", "GValue *"));
@@ -657,6 +654,7 @@ public class Vala.CodeGenerator : CodeVisitor {
        
        private void add_set_property_function (Class! cl) {
                var set_prop = new CCodeFunction ("%s_set_property".printf (cl.get_lower_case_cname (null)), "void");
+               set_prop.modifiers = CCodeModifiers.STATIC;
                set_prop.add_parameter (new CCodeFormalParameter ("object", "GObject *"));
                set_prop.add_parameter (new CCodeFormalParameter ("property_id", "guint"));
                set_prop.add_parameter (new CCodeFormalParameter ("value", "const GValue *"));
@@ -1736,8 +1734,8 @@ public class Vala.CodeGenerator : CodeVisitor {
                                ref CCodeExpression typed_pub_inst = pub_inst;
 
                                /* cast if necessary */
-                               if (prop.symbol.parent_symbol.node != base_type) {
-                                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (((DataType) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
+                               if (cl != base_type) {
+                                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
                                        ccast.add_argument (pub_inst);
                                        typed_pub_inst = ccast;
                                }
@@ -1789,16 +1787,36 @@ public class Vala.CodeGenerator : CodeVisitor {
                        }
                } else if (expr.symbol_reference.node is Signal) {
                        var sig = (Signal) expr.symbol_reference.node;
+                       var cl = (Class) sig.symbol.parent_symbol.node;
                        
-                       var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
+                       if (sig.has_emitter) {
+                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_%s".printf (cl.get_lower_case_cname (null), sig.name)));
+                               
+                               /* explicitly use strong reference as ccast
+                                * gets unrefed at the end of the inner block
+                                */
+                               ref CCodeExpression typed_pub_inst = pub_inst;
 
-                       var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
-                       ccast.add_argument (pub_inst);
-                       ccall.add_argument (ccast);
+                               /* cast if necessary */
+                               if (cl != base_type) {
+                                       var ccast = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
+                                       ccast.add_argument (pub_inst);
+                                       typed_pub_inst = ccast;
+                               }
 
-                       ccall.add_argument (new CCodeConstant ("\"%s\"".printf (sig.name)));
-                       
-                       expr.ccodenode = ccall;
+                               ccall.add_argument (typed_pub_inst);
+                               expr.ccodenode = ccall;
+                       } else {
+                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
+
+                               var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
+                               ccast.add_argument (pub_inst);
+                               ccall.add_argument (ccast);
+
+                               ccall.add_argument (sig.get_canonical_cconstant ());
+                               
+                               expr.ccodenode = ccall;
+                       }
                }
        }
        
@@ -1966,6 +1984,8 @@ public class Vala.CodeGenerator : CodeVisitor {
        public override void visit_element_access (ElementAccess! expr)
        {
                expr.ccodenode = new CCodeElementAccess ((CCodeExpression) expr.container.ccodenode, (CCodeExpression) expr.index.ccodenode);
+
+               visit_expression (expr);
        }
 
        public override void visit_postfix_expression (PostfixExpression! expr) {
index ba84acb..f5eb489 100644 (file)
@@ -156,7 +156,7 @@ public abstract class Vala.DataType : CodeNode {
         *              name or null
         * @return      the upper case name to be used in C code
         */
-       public abstract ref string get_upper_case_cname (string infix);
+       public abstract ref string get_upper_case_cname (string infix = null);
        
        /**
         * Returns the C name of this data type in lower case. Words are
@@ -167,7 +167,7 @@ public abstract class Vala.DataType : CodeNode {
         *              name or null
         * @return      the lower case name to be used in C code
         */
-       public abstract ref string get_lower_case_cname (string infix);
+       public abstract ref string get_lower_case_cname (string infix = null);
        
        /**
         * Returns a list of C header filenames users of this data type must
index a7c67d0..696fcd8 100644 (file)
@@ -93,7 +93,13 @@ public class Vala.Enum : DataType {
                return cprefix;
        }
        
-       private void set_cprefix (string! cprefix) {
+       /**
+        * Sets the string to be prepended to the name of members of this enum
+        * when used in C code.
+        *
+        * @param cprefix the prefix to be used in C code
+        */
+       public void set_cprefix (string! cprefix) {
                this.cprefix = cprefix;
        }
        
index 12c42ce..a5e1576 100644 (file)
@@ -60,18 +60,12 @@ public class Vala.InterfaceWriter : CodeVisitor {
                stream = null;
        }
 
-       public override void visit_begin_source_file (SourceFile! source_file) {
-               current_cheader_filename = source_file.get_cheader_filename ();
-
-               if (context.library != null) {
-                       current_cheader_filename = "%s/%s".printf (context.library, current_cheader_filename);
-               }
-       }
-
        public override void visit_begin_namespace (Namespace! ns) {
                if (ns.name == null)  {
                        return;
                }
+
+               current_cheader_filename = ns.get_cheader_filename ();
                
                write_indent ();
                write_string ("[CCode (cheader_filename = \"%s\")]".printf (current_cheader_filename));
@@ -186,6 +180,9 @@ public class Vala.InterfaceWriter : CodeVisitor {
                }
                
                write_indent ();
+               write_string ("[CCode (cprefix = \"%s\")]".printf (en.get_cprefix ()));
+               
+               write_indent ();
                write_string ("public enum ");
                write_identifier (en.name);
                write_begin_block ();
@@ -240,6 +237,10 @@ public class Vala.InterfaceWriter : CodeVisitor {
                }
                        
                write_string (" ");
+               if (f.name == "callback" || f.name == "flags" ||
+                   f.name == "out") {
+                       write_string ("@");
+               }
                write_identifier (f.name);
                write_string (";");
                write_newline ();
@@ -385,6 +386,11 @@ public class Vala.InterfaceWriter : CodeVisitor {
                        return;
                }
                
+               if (prop.no_accessor_method) {
+                       write_indent ();
+                       write_string ("[NoAccessorMethod ()]");
+               }
+               
                write_indent ();
                write_string ("public ");
                if (!prop.type_reference.takes_ownership) {
@@ -423,6 +429,44 @@ public class Vala.InterfaceWriter : CodeVisitor {
                write_newline ();
        }
 
+       public override void visit_begin_signal (Signal! sig) {
+               if (internal_scope || sig.access != MemberAccessibility.PUBLIC) {
+                       return;
+               }
+               
+               if (sig.has_emitter) {
+                       write_indent ();
+                       write_string ("[HasEmitter ()]");
+               }
+               
+               write_indent ();
+               write_string ("public signal ");
+               
+               var type = sig.return_type.data_type;
+               if (type == null) {
+                       write_string ("void");
+               } else {
+                       if (sig.return_type.transfers_ownership) {
+                               write_string ("ref ");
+                       }
+                       write_string (sig.return_type.data_type.symbol.get_full_name ());
+                       if (sig.return_type.non_null) {
+                               write_string ("!");
+                       }
+               }
+               
+               write_string (" ");
+               write_identifier (sig.name);
+               
+               write_string (" ");
+               
+               write_params (sig.get_parameters ());
+
+               write_string (";");
+
+               write_newline ();
+       }
+
        private void write_indent () {
                int i;
                
index 59cc2ea..63b3825 100644 (file)
@@ -282,11 +282,41 @@ public class Vala.Namespace : CodeNode {
         */
        public ref List<string> get_cheader_filenames () {
                if (cheader_filenames == null) {
-                       cheader_filenames.append (source_reference.file.get_cheader_filename ());
+                       cheader_filenames.append (source_reference.file.get_cinclude_filename ());
                }
                return cheader_filenames.copy ();
        }
        
+       /**
+        * Returns the C header filename of this namespace.
+        *
+        * @return header filename
+        */
+       public ref string get_cheader_filename () {
+               var s = new String ();
+               bool first = true;
+               foreach (string cheader_filename in get_cheader_filenames ()) {
+                       if (first) {
+                               first = false;
+                       } else {
+                               s.append_c (',');
+                       }
+                       s.append (cheader_filename);
+               }
+               return s.str;
+       }
+       
+       /**
+        * Sets the C header filename of this namespace to the specified
+        * filename.
+        *
+        * @param cheader_filename header filename
+        */
+       public void set_cheader_filename (string! cheader_filename) {
+               cheader_filenames = null;
+               cheader_filenames.append (cheader_filename);
+       }
+       
        private void process_ccode_attribute (Attribute! a) {
                foreach (NamedArgument arg in a.args) {
                        if (arg.name == "cprefix") {
index bdf90dd..846bfc5 100644 (file)
@@ -40,7 +40,12 @@ public class Vala.Signal : CodeNode {
         * Specifies the accessibility of the signal. Currently only public
         * accessibility is supported for signals.
         */
-       public MemberAccessibility access;
+       public MemberAccessibility access { get; set; }
+       
+       /**
+        * Specifies whether this signal has an emitter wrapper function.
+        */
+       public bool has_emitter { get; set; }
 
        private List<FormalParameter> parameters;
        private Callback generated_callback;
@@ -155,4 +160,15 @@ public class Vala.Signal : CodeNode {
 
                visitor.visit_end_signal (this);
        }
+       
+       /**
+        * Process all associated attributes.
+        */
+       public void process_attributes () {
+               foreach (Attribute a in attributes) {
+                       if (a.name == "HasEmitter") {
+                               has_emitter = true;
+                       }
+               }
+       }
 }
index 5d1e5eb..8c1ac6b 100644 (file)
@@ -63,14 +63,19 @@ public class Vala.SourceFile {
         */
        public int mark { get; set; }
        
+       /**
+        * The context this source file belongs to.
+        */
+       public weak CodeContext context { get; set; }
+       
        private List<NamespaceReference> using_directives;
 
        private Namespace global_namespace;
        private List<Namespace> namespaces;
        
        private string cheader_filename = null;
-       
        private string csource_filename = null;
+       private string cinclude_filename = null;
        
        private List<weak string> header_external_includes;
        private List<weak string> header_internal_includes;
@@ -87,7 +92,8 @@ public class Vala.SourceFile {
         * @param pkg      true if this is a VAPI package file
         * @return         newly created source file
         */
-       public construct (string! _filename, bool _pkg =  false) {
+       public construct (CodeContext! _context, string! _filename, bool _pkg =  false) {
+               context = _context;
                filename = _filename;
                pkg = _pkg;
        }
@@ -190,6 +196,24 @@ public class Vala.SourceFile {
        }
 
        /**
+        * Returns the filename to use when including the generated C header
+        * file.
+        *
+        * @return C header filename to include
+        */
+       public string! get_cinclude_filename () {
+               if (cinclude_filename == null) {
+                       var basename = filename.ndup ((uint) (filename.len () - ".vala".len ()));
+                       if (context.library != null) {
+                               cinclude_filename = "%s/%s.h".printf (context.library, basename);
+                       } else {
+                               cinclude_filename = "%s.h".printf (basename);
+                       }
+               }
+               return cinclude_filename;
+       }
+       
+       /**
         * Adds the specified symbol to the list of symbols code in this source
         * file depends on.
         *