]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
support implicit namespace specification in struct, interface, enum, and
authorJürg Billeter <j@bitron.ch>
Mon, 3 Jul 2006 18:43:15 +0000 (18:43 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Mon, 3 Jul 2006 18:43:15 +0000 (18:43 +0000)
2006-07-03  Jürg Billeter  <j@bitron.ch>

* vala/parser.y: support implicit namespace specification in struct,
  interface, enum, and flags declaration
* vala/valasymbolbuilder.vala: report error when declaring non-static
  namespace methods
* vala/valasemanticanalyzer.vala: analyze return statements
* vala/valacodegenerator.vala: correctly set GParamFlags for properties,
  initialize static variables, add preconditions to property accessors,
  support namespace methods
* vala/valaassignment.vala, vala/valaattribute.vala: add interface
  documentation, use implicit namespace specification
* tests/test-001.vala, tests/test-002.vala, tests/test-003.vala,
  tests/test-004.vala, tests/test-005.vala, tests/test-006.vala,
  tests/test-007.vala, tests/test-008.vala, tests/test-009.vala:
  update test cases to print test values

svn path=/trunk/; revision=60

16 files changed:
vala/ChangeLog
vala/tests/test-001.vala
vala/tests/test-002.vala
vala/tests/test-003.vala
vala/tests/test-004.vala
vala/tests/test-005.vala
vala/tests/test-006.vala
vala/tests/test-007.vala
vala/tests/test-008.vala
vala/tests/test-009.vala
vala/vala/parser.y
vala/vala/valaassignment.vala
vala/vala/valaattribute.vala
vala/vala/valacodegenerator.vala
vala/vala/valasemanticanalyzer.vala
vala/vala/valasymbolbuilder.vala

index 19df051302b818231607c1fa4ce30b54451dc1d1..2810b04390068b1f38fb4b88c1f3a8c0f64a6fb6 100644 (file)
@@ -1,3 +1,20 @@
+2006-07-03  Jürg Billeter  <j@bitron.ch>
+
+       * vala/parser.y: support implicit namespace specification in struct,
+         interface, enum, and flags declaration
+       * vala/valasymbolbuilder.vala: report error when declaring non-static
+         namespace methods
+       * vala/valasemanticanalyzer.vala: analyze return statements
+       * vala/valacodegenerator.vala: correctly set GParamFlags for properties,
+         initialize static variables, add preconditions to property accessors,
+         support namespace methods
+       * vala/valaassignment.vala, vala/valaattribute.vala: add interface
+         documentation, use implicit namespace specification
+       * tests/test-001.vala, tests/test-002.vala, tests/test-003.vala,
+         tests/test-004.vala, tests/test-005.vala, tests/test-006.vala,
+         tests/test-007.vala, tests/test-008.vala, tests/test-009.vala:
+         update test cases to print test values
+
 2006-06-30  Jürg Billeter  <j@bitron.ch>
 
        * vala/valacodenode.vala, vala/valadatatype.vala,
index 53ffd9b175b38434007bdbe1a26a514c7adb215e..c8382098721c104750588c88b1635d5d28fa2bf4 100644 (file)
@@ -1,3 +1,8 @@
+using GLib;
+
 namespace Maman {
+       static int main (int argc, string[] argv) {
+               stdout.printf ("Namespace Test\n");
+               return 0;
+       }
 }
-
index 740504d581de94ca21901d116d838346d5a8e66b..5c8c30796e634682faa9d6bd9eef87e52a3968c2 100644 (file)
@@ -1,5 +1,11 @@
+using GLib;
+
 namespace Maman {
        class Bar {
+               static int main (int argc, string[] argv) {
+                       stdout.printf ("Class in Namespace Test\n");
+                       return 0;
+               }
        }
 }
 
index 054fd3b0adccfd62235e1a9eedd8ab080eadf643..a4a6769873347553ab1c4b3dcc5be13085899095 100644 (file)
@@ -1,7 +1,11 @@
-namespace Maman {
-       class Bar {
-       }
-       
-       class SubBar : Bar {
+using GLib;
+
+class Maman.Bar {
+}
+
+class Maman.SubBar : Bar {
+       static int main (int argc, string[] argv) {
+               stdout.printf ("Subtype Test\n");
+               return 0;
        }
 }
index 73755686a11cdac99903a3eebdd8db3f3da71b66..f8c39ba3c8196c191cb6a3e9815779a2a70e0a20 100644 (file)
@@ -1,9 +1,20 @@
-namespace Maman {
-       class Bar {
-               public void do_action () {
-               }
+using GLib;
+
+class Maman.Bar {
+       public void do_action () {
+               stdout.printf (" 2");
        }
+}
+
+class Maman.SubBar : Bar {
+       static int main (int argc, string[] argv) {
+               stdout.printf ("Inheritance Test: 1");
+
+               var bar = new SubBar ();
+               bar.do_action ();
+               
+               stdout.printf (" 3\n");
        
-       class SubBar : Bar {
+               return 0;
        }
 }
index ab2ef53de4b50217606ad28ad00d7fd103c2b8c2..026e12277ab04d8309252f253c572984af021ca6 100644 (file)
@@ -1,14 +1,19 @@
-namespace Maman {
-       class Bar {
-               public static int do_action (int i) {
-                       return (i + 42);
-               }
+using GLib;
+
+class Maman.Bar {
+       public static void do_action () {
+               stdout.printf (" 2");
        }
+}
+
+class Maman.SubBar : Bar {
+       static int main (int argc, string[] argv) {
+               stdout.printf ("Static Inheritance Test: 1");
+
+               do_action ();
+               
+               stdout.printf (" 3\n");
        
-       class SubBar : Bar {
-               public static int main (int argc, string[] argv) {
-                       int i = do_action (42);
-                       return (argc + i);
-               }
+               return 0;
        }
 }
index 0d3aa97069113cd34b44d4e59af152d9a9bcaa0c..b0488d319a908eb38fcf01c40a727facf3dfcdbe 100644 (file)
@@ -1,32 +1,16 @@
-namespace Maman {
-       class Bar {
-               public int do_action (int i) {
-                       return (i + 42);
+using GLib;
+
+class Maman.Bar {
+       static int main (int argc, string[] argv) {
+               stdout.printf ("For Test: 1");
+
+               int i;
+               for (i = 2; i < 7; i++) {
+                       stdout.printf (" %d", i);
                }
-       }
-       
-       class SubBar : Bar {
-               void init () {
-                       do_action (42);
-               }
-       
-               public static int main (int argc, string[] argv) {
-                       SubBar subbar = new SubBar ();
                
-                       int i;
-                       int j;
-                       
-                       for (i = 0; i < argc; i++) {
-                               subbar.do_action (i);
-                       }
-                       
-                       if (i == 1) {
-                               j = 42;
-                       } else {
-                               j = argc;
-                       }
-                       
-                       return (i * j);
-               }
+               stdout.printf (" 7\n");
+
+               return 0;
        }
 }
index 0187db9965a01cf8384810145ea86848ffb7e189..74db7212b3e917c5d210a1b61902ab2bcb319bc2 100644 (file)
@@ -1,19 +1,24 @@
-namespace Maman {
-       class Bar {
-               public virtual string do_action (int i) {
-                       return 1;
-               }
+using GLib;
+
+class Maman.Bar {
+       public virtual void do_action () {
+               stdout.printf (" BAD");
        }
+}
+
+class Maman.SubBar : Bar {
+       public override void do_action () {
+               stdout.printf (" 2");
+       }
+
+       static int main (int argc, string[] argv) {
+               stdout.printf ("Virtual Method Test: 1");
+
+               Bar bar = new SubBar ();
+               bar.do_action ();
        
-       class SubBar : Bar {
-               public override string do_action (int i) {
-                       return 2;
-               }
-       
-               public static int main (int argc, string[] argv) {
-                       Bar bar = new SubBar ();
-               
-                       return bar.do_action (1);
-               }
+               stdout.printf (" 3\n");
+
+               return 0;
        }
 }
index 58cd9b0342a40439ce25c35e9e8ff484f817ab2a..0b6ab1e6e42d7fa0c88aade372905e2d1a54223e 100644 (file)
@@ -1,22 +1,33 @@
-namespace Maman {
-       class Foo {
-               public int foo_a = 5;
-               public static int foo_b = 6;
+using GLib;
+
+class Maman.Foo {
+       public int public_base_field = 2;
+}
+
+class Maman.Bar : Foo {
+       public int public_field = 3;
+       private int private_field = 4;
+       private static int private_static_field = 5;
+       
+       void do_action () {
+               stdout.printf (" %d %d %d %d", public_base_field, public_field,
+                              private_field, private_static_field);
+               public_base_field = 6;
+               public_field = 7;
+               private_field = 8;
+               private_static_field = 9;
+               stdout.printf (" %d %d %d %d", public_base_field, public_field,
+                              private_field, private_static_field);
        }
-       class Bar : Foo {
-               public int a = 1;
-               private int b = 2;
-               public static int c = 3;
-               private static int d = 4;
-               static int e = 5;
-               int f = 6;
-               int g;
+
+       static int main (int argc, string[] argv) {
+               stdout.printf ("Field Test: 1");
                
-               public void test () {
-                       int aa = 6;
-                       a = 3 + b;
-                       c = a + 5 + aa + foo_a + foo_b;
-               }
+               var bar = new Bar ();
+               bar.do_action ();
+               
+               stdout.printf (" 10\n");
+               
+               return 0;
        }
 }
-
index bf40c6c03b25ffae4531a5ba776ce8defb78eb00..934864a7feb74c0b5206161ee9dd0eb6bdcbd2e4 100644 (file)
@@ -1,14 +1,43 @@
-namespace Maman {
-       class Bar {
-               private int _a;
-               public int a {
-                       get {
-                               return _a;
-                       }
-                       set {
-                               _a = value;
-                       }
+using GLib;
+
+class Maman.Foo {
+       private int _public_base_property = 2;
+       public int public_base_property {
+               get {
+                       return _public_base_property;
+               }
+               set {
+                       _public_base_property = value;
                }
        }
 }
 
+class Maman.Bar : Foo {
+       private int _public_property = 3;
+       public int public_property {
+               get {
+                       return _public_property;
+               }
+               set {
+                       _public_property = value;
+               }
+       }
+       
+       void do_action () {
+               stdout.printf (" %d %d", public_base_property, public_property);
+               public_base_property = 4;
+               public_property = 5;
+               stdout.printf (" %d %d", public_base_property, public_property);
+       }
+
+       static int main (int argc, string[] argv) {
+               stdout.printf ("Property Test: 1");
+               
+               var bar = new Bar ();
+               bar.do_action ();
+               
+               stdout.printf (" 6\n");
+               
+               return 0;
+       }
+}
index 76c53993fdf004093b89e184fdd532c378098d5e..6c3fdcc2f0388b1a1566b5a297758fc805bdad26 100644 (file)
@@ -1371,6 +1371,12 @@ namespace_member_declaration
                        vala_namespace_add_struct (current_namespace, $1);
                        g_object_unref ($1);
                }
+
+               if (current_namespace_implicit) {
+                       /* current namespace has been declared implicitly */
+                       current_namespace = vala_source_file_get_global_namespace (current_source_file);
+                       current_namespace_implicit = FALSE;
+               }
          }
        | interface_declaration
          {
@@ -1379,6 +1385,12 @@ namespace_member_declaration
                        vala_namespace_add_interface (current_namespace, $1);
                        g_object_unref ($1);
                }
+
+               if (current_namespace_implicit) {
+                       /* current namespace has been declared implicitly */
+                       current_namespace = vala_source_file_get_global_namespace (current_source_file);
+                       current_namespace_implicit = FALSE;
+               }
          }
        | enum_declaration
          {
@@ -1387,6 +1399,12 @@ namespace_member_declaration
                        vala_namespace_add_enum (current_namespace, $1);
                        g_object_unref ($1);
                }
+
+               if (current_namespace_implicit) {
+                       /* current namespace has been declared implicitly */
+                       current_namespace = vala_source_file_get_global_namespace (current_source_file);
+                       current_namespace_implicit = FALSE;
+               }
          }
        | flags_declaration
          {
@@ -1395,6 +1413,12 @@ namespace_member_declaration
                        vala_namespace_add_flags (current_namespace, $1);
                        g_object_unref ($1);
                }
+
+               if (current_namespace_implicit) {
+                       /* current namespace has been declared implicitly */
+                       current_namespace = vala_source_file_get_global_namespace (current_source_file);
+                       current_namespace_implicit = FALSE;
+               }
          }
        | callback_declaration
          {
@@ -1440,7 +1464,6 @@ class_declaration
                        name = $7;
                }
                
-               
                GList *l;
                ValaSourceReference *src = src_com(@6, $1);
                current_class = vala_class_new (name, src);
@@ -2020,21 +2043,35 @@ struct_declaration
        ;
 
 struct_header
-       : comment opt_attributes opt_access_modifier STRUCT IDENTIFIER opt_type_parameter_list
+       : comment opt_attributes opt_access_modifier STRUCT IDENTIFIER opt_name_specifier opt_type_parameter_list
          {
+               char *name = $5;
+         
+               if ($6 != NULL) {
+                       ValaSourceReference *ns_src = src(@5);
+                       current_namespace = vala_namespace_new ($5, ns_src);
+                       g_free ($5);
+                       g_object_unref (ns_src);
+                       current_namespace_implicit = TRUE;
+
+                       vala_source_file_add_namespace (current_source_file, current_namespace);
+                       g_object_unref (current_namespace);
+                       
+                       name = $6;
+               }
+               
                GList *l;
                ValaSourceReference *src = src_com(@5, $1);
-               $$ = vala_struct_new ($5, src);
+               $$ = vala_struct_new (name, src);
+               g_free (name);
                g_object_unref (src);
-               for (l = $6; l != NULL; l = l->next) {
+               for (l = $7; l != NULL; l = l->next) {
                        vala_struct_add_type_parameter ($$, l->data);
                }
                VALA_CODE_NODE($$)->attributes = $2;
                if ($3 != 0) {
                        VALA_DATA_TYPE($$)->access = $3;
                }
-               
-               g_free ($5);
          }
        ;
 
@@ -2072,12 +2109,27 @@ struct_member_declaration
        ;
 
 interface_declaration
-       : comment opt_attributes opt_access_modifier INTERFACE IDENTIFIER
+       : comment opt_attributes opt_access_modifier INTERFACE IDENTIFIER opt_name_specifier
          {
+               char *name = $5;
+         
+               if ($6 != NULL) {
+                       ValaSourceReference *ns_src = src(@5);
+                       current_namespace = vala_namespace_new ($5, ns_src);
+                       g_free ($5);
+                       g_object_unref (ns_src);
+                       current_namespace_implicit = TRUE;
+
+                       vala_source_file_add_namespace (current_source_file, current_namespace);
+                       g_object_unref (current_namespace);
+                       
+                       name = $6;
+               }
+               
                ValaSourceReference *src = src_com(@5, $1);
-               current_interface = vala_interface_new ($5, src);
+               current_interface = vala_interface_new (name, src);
+               g_free (name);
                g_object_unref (src);
-               g_free ($5);
          }
          interface_body
          {
@@ -2127,11 +2179,27 @@ interface_member_declaration
        ;
 
 enum_declaration
-       : comment opt_attributes opt_access_modifier ENUM IDENTIFIER enum_body
+       : comment opt_attributes opt_access_modifier ENUM IDENTIFIER opt_name_specifier enum_body
          {
+               char *name = $5;
+         
+               if ($6 != NULL) {
+                       ValaSourceReference *ns_src = src(@5);
+                       current_namespace = vala_namespace_new ($5, ns_src);
+                       g_free ($5);
+                       g_object_unref (ns_src);
+                       current_namespace_implicit = TRUE;
+
+                       vala_source_file_add_namespace (current_source_file, current_namespace);
+                       g_object_unref (current_namespace);
+                       
+                       name = $6;
+               }
+               
                GList *l;
                ValaSourceReference *src = src_com(@5, $1);
-               $$ = vala_enum_new ($5, src);
+               $$ = vala_enum_new (name, src);
+               g_free (name);
                g_object_unref (src);
 
                VALA_CODE_NODE($$)->attributes = $2;
@@ -2139,12 +2207,10 @@ enum_declaration
                if ($3 != 0) {
                        VALA_DATA_TYPE($$)->access = $3;
                }
-               for (l = $6; l != NULL; l = l->next) {
+               for (l = $7; l != NULL; l = l->next) {
                        vala_enum_add_value ($$, l->data);
                        g_object_unref (l->data);
                }
-
-               g_free ($5);
          }
        ;
 
@@ -2183,10 +2249,26 @@ enum_member_declaration
        ;
 
 flags_declaration
-       : comment opt_attributes opt_access_modifier FLAGS IDENTIFIER flags_body
+       : comment opt_attributes opt_access_modifier FLAGS IDENTIFIER opt_name_specifier flags_body
          {
+               char *name = $5;
+         
+               if ($6 != NULL) {
+                       ValaSourceReference *ns_src = src(@5);
+                       current_namespace = vala_namespace_new ($5, ns_src);
+                       g_free ($5);
+                       g_object_unref (ns_src);
+                       current_namespace_implicit = TRUE;
+
+                       vala_source_file_add_namespace (current_source_file, current_namespace);
+                       g_object_unref (current_namespace);
+                       
+                       name = $6;
+               }
+               
                ValaSourceReference *src = src_com(@5, $1);
-               $$ = vala_flags_new ($5, src);
+               $$ = vala_flags_new (name, src);
+               g_free (name);
                g_object_unref (src);
          }
        ;
index ae3e0e9e40e3f4a8d2f46c6a49a36f496af97f49..b09f38d57df43fb4a9acd08e9e1ad847f430294e 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class Assignment : Expression {
-               public Expression! left { get; set construct; }
-               public AssignmentOperator operator { get; set construct; }
-               public Expression! right { get; set construct; }
-               
-               public static ref Assignment! new (Expression! left, AssignmentOperator op, Expression! right, SourceReference source) {
-                       return (new Assignment (left = left, operator = op, right = right, source_reference = source));
-               }
-               
-               public override void accept (CodeVisitor! visitor) {
-                       left.accept (visitor);
-                       right.accept (visitor);
+/**
+ * Represents an assignment expression in the source code.
+ */
+public class Vala.Assignment : Expression {
+       /**
+        * Left hand side of the assignment.
+        */
+       public Expression! left { get; set construct; }
+       
+       /**
+        * Assignment operator.
+        */
+       public AssignmentOperator operator { get; set construct; }
+       
+       /**
+        * Right hand side of the assignment.
+        */
+       public Expression! right { get; set construct; }
+       
+       /**
+        * Creates a new assignment.
+        *
+        * @param left left hand side
+        * @param op assignment operator
+        * @param right right hand side
+        * @param source reference to source code
+        */
+       public static ref Assignment! new (Expression! left, AssignmentOperator op, Expression! right, SourceReference source) {
+               return (new Assignment (left = left, operator = op, right = right, source_reference = source));
+       }
+       
+       public override void accept (CodeVisitor! visitor) {
+               left.accept (visitor);
+               right.accept (visitor);
 
-                       visitor.visit_assignment (this);
-               }
+               visitor.visit_assignment (this);
        }
+}
        
+namespace Vala {
        public enum AssignmentOperator {
                SIMPLE,
                BITWISE_OR,
index 648b44d10cfb3c8f17eed99827811ffe09094c88..a8d79b3b7ac03bce33f8f5abff448893208516fd 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class Attribute : CodeNode {
-               public string! name { get; set construct; }
+/**
+ * Represents an attribute specified in the source code.
+ */
+public class Vala.Attribute : CodeNode {
+       /**
+        * The name of the attribute type.
+        */
+       public string! name { get; set construct; }
 
-               public List<NamedArgument> args;
-               
-               public static ref Attribute! new (string! name, SourceReference source) {
-                       return (new Attribute (name = name, source_reference = source));
-               }
+       /**
+        * Contains all specified attribute arguments.
+        */
+       public List<NamedArgument> args;
+       
+       /**
+        * Creates a new attribute.
+        *
+        * @param name attribute type name
+        * @param source reference to source code
+        */
+       public static ref Attribute! new (string! name, SourceReference source) {
+               return (new Attribute (name = name, source_reference = source));
+       }
 
-               public void add_argument (NamedArgument! arg) {
-                       args.append (arg);
-               }
+       /**
+        * Adds an attribute argument.
+        *
+        * @param arg named argument
+        */
+       public void add_argument (NamedArgument! arg) {
+               args.append (arg);
        }
 }
index 05acccaa8d9686fdcfa029a829f842fb6d34051e..275fb3aa77e311f7d227df7647711be0313575b0 100644 (file)
@@ -263,6 +263,8 @@ namespace Vala {
                        type_fun.init_from_type ();
                        header_type_member_declaration.append (type_fun.get_declaration ());
                        source_type_member_definition.append (type_fun);
+
+                       current_type_symbol = null;
                }
                
                private void add_class_init_function (Class! cl) {
@@ -337,7 +339,22 @@ namespace Vala {
                                } else {
                                        cspec.call = new CCodeIdentifier (name = "g_param_spec_pointer");
                                }
-                               cspec.add_argument (new CCodeConstant (name = "G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB"));
+                               
+                               var pflags = "G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB";
+                               if (prop.get_accessor != null) {
+                                       pflags = "%s%s".printf (pflags, " | G_PARAM_READABLE");
+                               }
+                               if (prop.set_accessor != null) {
+                                       pflags = "%s%s".printf (pflags, " | G_PARAM_WRITABLE");
+                                       if (prop.set_accessor.construct_) {
+                                               if (prop.set_accessor.writable) {
+                                                       pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT");
+                                               } else {
+                                                       pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT_ONLY");
+                                               }
+                                       }
+                               }
+                               cspec.add_argument (new CCodeConstant (name = pflags));
                                cinst.add_argument (cspec);
                                
                                init_block.add_statement (new CCodeExpressionStatement (expression = cinst));
@@ -597,6 +614,8 @@ namespace Vala {
                        type_fun.init_from_type ();
                        header_type_member_declaration.append (type_fun.get_declaration ());
                        source_type_member_definition.append (type_fun);
+
+                       current_type_symbol = null;
                }
                
                public override void visit_begin_enum (Enum! en) {
@@ -636,7 +655,11 @@ namespace Vala {
                                        if (f.symbol.parent_symbol.node is DataType) {
                                                var t = (DataType) f.symbol.parent_symbol.node;
                                                var cdecl = new CCodeDeclaration (type_name = f.type_reference.get_cname ());
-                                               cdecl.add_declarator (new CCodeVariableDeclarator (name = "%s_%s".printf (t.get_lower_case_cname (null), f.get_cname ())));
+                                               var var_decl = new CCodeVariableDeclarator (name = "%s_%s".printf (t.get_lower_case_cname (null), f.get_cname ()));
+                                               if (f.initializer != null) {
+                                                       var_decl.initializer = (CCodeExpression) f.initializer.ccodenode;
+                                               }
+                                               cdecl.add_declarator (var_decl);
                                                cdecl.modifiers = CCodeModifiers.STATIC;
                                                source_type_member_declaration.append (cdecl);
                                        }
@@ -644,7 +667,19 @@ namespace Vala {
                        }
                }
                
-               private ref CCodeStatement create_type_check_statement (Method! m, DataType! t, bool non_null, string! var_name) {
+               private ref CCodeStatement create_method_type_check_statement (Method! m, DataType! t, bool non_null, string! var_name) {
+                       return create_type_check_statement (m, m.return_type.type, t, non_null, var_name);
+               }
+               
+               private ref CCodeStatement create_property_type_check_statement (Property! prop, bool getter, DataType! t, bool non_null, string! var_name) {
+                       if (getter) {
+                               return create_type_check_statement (prop, prop.type_reference.type, t, non_null, var_name);
+                       } else {
+                               return create_type_check_statement (prop, null, t, non_null, var_name);
+                       }
+               }
+               
+               private ref CCodeStatement create_type_check_statement (CodeNode! method_node, DataType ret_type, DataType! t, bool non_null, string! var_name) {
                        var ccheck = new CCodeFunctionCall ();
                        
                        var ctype_check = new CCodeFunctionCall (call = new CCodeIdentifier (name = t.get_upper_case_cname ("IS_")));
@@ -658,21 +693,20 @@ namespace Vala {
                        }
                        ccheck.add_argument (cexpr);
                        
-                       if (m.return_type.type == null) {
+                       if (ret_type == null) {
                                /* void function */
                                ccheck.call = new CCodeIdentifier (name = "g_return_if_fail");
                        } else {
                                ccheck.call = new CCodeIdentifier (name = "g_return_val_if_fail");
                                
-                               var ret_type = m.return_type.type;
                                if (ret_type.is_reference_type ()) {
                                        ccheck.add_argument (new CCodeConstant (name = "NULL"));
                                } else if (ret_type.name == "bool") {
                                        ccheck.add_argument (new CCodeConstant (name = "FALSE"));
-                               } else if (ret_type.name == "int") {
+                               } else if (ret_type.name == "int" || ret_type is Enum || ret_type is Flags) {
                                        ccheck.add_argument (new CCodeConstant (name = "0"));
                                } else {
-                                       Report.error (m.source_reference, "not supported return type for runtime type checks");
+                                       Report.error (method_node.source_reference, "not supported return type for runtime type checks");
                                        return null;
                                }
                        }
@@ -753,13 +787,13 @@ namespace Vala {
                                                        
                                                        cinit.append (cdecl);
                                                } else if (m.instance) {
-                                                       cinit.append (create_type_check_statement (m, cl, true, "self"));
+                                                       cinit.append (create_method_type_check_statement (m, cl, true, "self"));
                                                }
                                        }
                                        foreach (FormalParameter param in m.parameters) {
                                                var t = param.type_reference.type;
                                                if (t != null && (t is Class || t is Interface) && !param.type_reference.is_out) {
-                                                       cinit.append (create_type_check_statement (m, t, param.type_reference.non_null, param.name));
+                                                       cinit.append (create_method_type_check_statement (m, t, param.type_reference.non_null, param.name));
                                                }
                                        }
 
@@ -850,6 +884,8 @@ namespace Vala {
                        
                        if (acc.body != null) {
                                function.block = (CCodeBlock) acc.body.ccodenode;
+
+                               function.block.prepend_statement (create_property_type_check_statement (prop, acc.readable, cl, true, "self"));
                        }
                        
                        source_type_member_definition.append (function);
@@ -1480,7 +1516,12 @@ namespace Vala {
                
                public override void visit_simple_name (SimpleName! expr) {
                        var pub_inst = new CCodeIdentifier (name = "self");
-                       var base_type = (DataType) current_type_symbol.node;
+
+                       DataType base_type = null;
+                       if (current_type_symbol != null) {
+                               /* base type is available if this is a type method */
+                               base_type = (DataType) current_type_symbol.node;
+                       }
                        
                        process_cmember (expr, pub_inst, base_type);
 
index 143e019128e6f0273a3c55e11863733523e6dd67..afa5d66d3ebc59ef8ff3326ac1b87b88c4660eb3 100644 (file)
@@ -29,6 +29,7 @@ namespace Vala {
                Symbol root_symbol;
                Symbol current_symbol;
                SourceFile current_source_file;
+               TypeReference current_return_type;
                
                List<weak NamespaceReference> current_using_directives;
                
@@ -106,6 +107,7 @@ namespace Vala {
 
                public override void visit_begin_method (Method! m) {
                        current_symbol = m.symbol;
+                       current_return_type = m.return_type;
                        
                        if (m.return_type.type != null) {
                                /* is null if it is void or a reference to a type parameter */
@@ -115,6 +117,7 @@ namespace Vala {
 
                public override void visit_end_method (Method! m) {
                        current_symbol = current_symbol.parent_symbol;
+                       current_return_type = null;
                        
                        if (m.is_virtual || m.is_override) {
                                if (current_symbol.node is Class) {
@@ -176,6 +179,18 @@ namespace Vala {
                        }
                }
 
+               public override void visit_begin_property_accessor (PropertyAccessor! acc) {
+                       var prop = (Property) acc.symbol.parent_symbol.node;
+                       
+                       if (acc.readable) {
+                               current_return_type = prop.type_reference;
+                       }
+               }
+
+               public override void visit_end_property_accessor (PropertyAccessor! acc) {
+                       current_return_type = null;
+               }
+
                public override void visit_begin_constructor (Constructor! c) {
                        current_symbol = c.symbol;
                }
@@ -260,6 +275,30 @@ namespace Vala {
                        current_symbol.add (stmt.variable_name, stmt.variable_declarator.symbol);
                }
 
+               public override void visit_return_statement (ReturnStatement! stmt) {
+                       if (current_return_type == null) {
+                               Report.error (stmt.source_reference, "Return not allowed in this context");
+                               return;
+                       }
+                       
+                       if (stmt.return_expression == null && current_return_type.type != null) {
+                               Report.error (stmt.source_reference, "Return with value in void function");
+                               return;
+                       }
+                       
+                       if (stmt.return_expression != null && current_return_type.type == null) {
+                               Report.error (stmt.source_reference, "Return without value in non-void function");
+                               return;
+                       }
+                       
+                       if (stmt.return_expression != null &&
+                            !is_type_compatible (stmt.return_expression.static_type, current_return_type)) {
+                               Report.error (stmt.source_reference, "Return: Cannot convert from `%s' to `%s'".printf (stmt.return_expression.static_type.to_string (), current_return_type.to_string ()));
+                               return;
+                       }
+                       
+               }
+
                public override void visit_boolean_literal (BooleanLiteral! expr) {
                        expr.static_type = bool_type;
                }
@@ -669,7 +708,7 @@ namespace Vala {
                                if (!is_type_compatible (expr.right.static_type, expr.left.static_type)
                                    && !is_type_compatible (expr.left.static_type, expr.right.static_type)) {
                                        Report.error (expr.source_reference, "Equality operation: `%s' and `%s' are incompatible, comparison would always evaluate to false".printf (expr.right.static_type.to_string (), expr.left.static_type.to_string ()));
-                                       return false;
+                                       return;
                                }
                                
                                if (expr.left.static_type.type == string_type.type
index dc7d8e8735dc7784655f3c5812d0007843a7b58c..dac696517f9f5ee1407b70668e948ea2d501c2cd 100644 (file)
@@ -168,14 +168,21 @@ namespace Vala {
                                return;
                        }
                        
-                       current_symbol = m.symbol;
-                       
                        if (m.instance) {
+                               if (!(m.symbol.parent_symbol.node is DataType)) {
+                                       Report.error (m.source_reference, "instance methods not allowed outside of data types");
+                               
+                                       m.error = true;
+                                       return;
+                               }
+                       
                                m.this_parameter = new FormalParameter (name = "this", type_reference = new TypeReference ());
                                m.this_parameter.type_reference.type = (DataType) m.symbol.parent_symbol.node;
                                m.this_parameter.symbol = new Symbol (node = m.this_parameter);
                                current_symbol.add (m.this_parameter.name, m.this_parameter.symbol);
                        }
+                       
+                       current_symbol = m.symbol;
                }
                
                public override void visit_end_method (Method! m) {