support interfaces, adapt to Class/Struct/Type changes, improve error
authorJürg Billeter <j@bitron.ch>
Wed, 31 May 2006 09:56:04 +0000 (09:56 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Wed, 31 May 2006 09:56:04 +0000 (09:56 +0000)
2006-05-31  Jürg Billeter  <j@bitron.ch>

* vala/parser.y: support interfaces, adapt to Class/Struct/Type changes,
  improve error handling
* vala/valacodevisitor.vala: support interfaces
* vala/valasymbolbuilder.vala: improve error handling
* vala/valasymbolresolver.vala: use operators to compare strings
* vala/valasemanticanalyzer.vala: improve error handling, convert method
  argument and type mismatch warnings to errors, add skeleton for
  expressoin type checks, support string comparison operators
* vala/valacodegenerator.vala: fix warning, create structs for
  interfaces, adapt to Class/Struct/Type changes, refactor and fix code
  in visit_simple_name and visit_member_access, use operators to compare
  strings
* vala/valainterfacewriter.vala: use operators to compare strings
* vala/valasourcefile.vala: fix warnings
* vala/valaclass.vala: don't inherit from Struct
* vala/valacodenode.vala: add error flag
* vala/valaconstant.vala: add get_cname method
* vala/valaenum.vala: override get_upper_case_cname method
* vala/valaenumvalue.vala: adapt to Class/Struct/Type changes
* vala/valafield.vala: use operators to compare strings
* vala/valainterface.vala
* vala/valainvocationexpression.vala: add add_argument method
* vala/valamethod.vala: adapt to Class/Struct/Type changes, use
  operators to compare strings
* vala/valanamespace.vala: support interfaces, use operators to compare
  strings
* vala/valastringliteral.vala: fix warning
* vala/valastruct.vala: inline visit_children method, use operators to
  compare strings
* vala/valatype.vala: add abstract get_lower_case_cname method
* vala/valatypereference.vala: add to_string method
* vala/vala.h: update
* vala/Makefile.am: update
* vapi/glib-2.0.vala: small fixes

svn path=/trunk/; revision=38

26 files changed:
vala/ChangeLog
vala/vala/Makefile.am
vala/vala/parser.y
vala/vala/vala.h
vala/vala/valaclass.vala
vala/vala/valacodegenerator.vala
vala/vala/valacodenode.vala
vala/vala/valacodevisitor.vala
vala/vala/valaconstant.vala
vala/vala/valaenum.vala
vala/vala/valaenumvalue.vala
vala/vala/valafield.vala
vala/vala/valainterface.vala [new file with mode: 0644]
vala/vala/valainterfacewriter.vala
vala/vala/valainvocationexpression.vala
vala/vala/valamethod.vala
vala/vala/valanamespace.vala
vala/vala/valasemanticanalyzer.vala
vala/vala/valasourcefile.vala
vala/vala/valastringliteral.vala
vala/vala/valastruct.vala
vala/vala/valasymbolbuilder.vala
vala/vala/valasymbolresolver.vala
vala/vala/valatype.vala
vala/vala/valatypereference.vala
vala/vapi/glib-2.0.vala

index 08ed9c1..fd504e5 100644 (file)
@@ -1,3 +1,40 @@
+2006-05-31  Jürg Billeter  <j@bitron.ch>
+
+       * vala/parser.y: support interfaces, adapt to Class/Struct/Type changes,
+         improve error handling
+       * vala/valacodevisitor.vala: support interfaces
+       * vala/valasymbolbuilder.vala: improve error handling
+       * vala/valasymbolresolver.vala: use operators to compare strings
+       * vala/valasemanticanalyzer.vala: improve error handling, convert method
+         argument and type mismatch warnings to errors, add skeleton for
+         expressoin type checks, support string comparison operators
+       * vala/valacodegenerator.vala: fix warning, create structs for
+         interfaces, adapt to Class/Struct/Type changes, refactor and fix code
+         in visit_simple_name and visit_member_access, use operators to compare
+         strings
+       * vala/valainterfacewriter.vala: use operators to compare strings
+       * vala/valasourcefile.vala: fix warnings
+       * vala/valaclass.vala: don't inherit from Struct
+       * vala/valacodenode.vala: add error flag
+       * vala/valaconstant.vala: add get_cname method
+       * vala/valaenum.vala: override get_upper_case_cname method
+       * vala/valaenumvalue.vala: adapt to Class/Struct/Type changes
+       * vala/valafield.vala: use operators to compare strings
+       * vala/valainterface.vala
+       * vala/valainvocationexpression.vala: add add_argument method
+       * vala/valamethod.vala: adapt to Class/Struct/Type changes, use
+         operators to compare strings
+       * vala/valanamespace.vala: support interfaces, use operators to compare
+         strings
+       * vala/valastringliteral.vala: fix warning
+       * vala/valastruct.vala: inline visit_children method, use operators to
+         compare strings
+       * vala/valatype.vala: add abstract get_lower_case_cname method
+       * vala/valatypereference.vala: add to_string method
+       * vala/vala.h: update
+       * vala/Makefile.am: update
+       * vapi/glib-2.0.vala: small fixes
+
 2006-05-26  Jürg Billeter  <j@bitron.ch>
 
        * vala/valasemanticanalyzer.vala: fix member access to namespaces
index 89d7904..26b833b 100644 (file)
@@ -107,6 +107,9 @@ libvala_la_SOURCES = \
        valaintegerliteral.c \
        valaintegerliteral.h \
        valaintegerliteral.vala \
+       valainterface.c \
+       valainterface.h \
+       valainterface.vala \
        valainterfacewriter.c \
        valainterfacewriter.h \
        valainterfacewriter.vala \
index 4b3d925..50ea90b 100644 (file)
@@ -40,7 +40,9 @@
 
 static ValaSourceFile *current_source_file;
 static ValaNamespace *current_namespace;
+static ValaClass *current_class;
 static ValaStruct *current_struct;
+static ValaInterface *current_interface;
 
 typedef enum {
        VALA_MODIFIER_NONE,
@@ -71,6 +73,7 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
        ValaNamespace *namespace;
        ValaClass *class;
        ValaStruct *struct_;
+       ValaInterface *interface;
        ValaEnum *enum_;
        ValaEnumValue *enum_value;
        ValaConstant *constant;
@@ -251,6 +254,12 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %type <property_accessor> set_accessor_declaration
 %type <struct_> struct_declaration
 %type <struct_> struct_header
+%type <interface> interface_declaration
+%type <method> interface_method_declaration
+%type <property> interface_property_declaration
+%type <property_accessor> interface_get_accessor_declaration
+%type <property_accessor> opt_interface_set_accessor_declaration
+%type <property_accessor> interface_set_accessor_declaration
 %type <enum_> enum_declaration
 %type <list> enum_body
 %type <list> opt_enum_member_declarations
@@ -670,6 +679,10 @@ opt_expression
 expression
        : conditional_expression
        | assignment
+       | error
+         {
+               $$ = NULL;
+         }
        ;
 
 statement
@@ -929,25 +942,46 @@ namespace_member_declarations
 namespace_member_declaration
        : class_declaration
          {
-               vala_namespace_add_class (current_namespace, $1);
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_namespace_add_class (current_namespace, $1);
+               }
          }
        | struct_declaration
          {
-               vala_namespace_add_struct (current_namespace, $1);
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_namespace_add_struct (current_namespace, $1);
+               }
          }
        | interface_declaration
+         {
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_namespace_add_interface (current_namespace, $1);
+               }
+         }
        | enum_declaration
          {
-               vala_namespace_add_enum (current_namespace, $1);
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_namespace_add_enum (current_namespace, $1);
+               }
          }
        | flags_declaration
        | field_declaration
          {
-               vala_namespace_add_field (current_namespace, $1);
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_namespace_add_field (current_namespace, $1);
+               }
          }
        | method_declaration
          {
-               vala_namespace_add_method (current_namespace, $1);
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_namespace_add_method (current_namespace, $1);
+               }
          }
        ;
 
@@ -955,22 +989,22 @@ class_declaration
        : comment opt_attributes opt_access_modifier opt_modifiers CLASS IDENTIFIER opt_type_parameter_list opt_class_base
          {
                GList *l;
-               current_struct = VALA_STRUCT (vala_class_new ($6, src_com (@6, $1)));
-               VALA_CODE_NODE(current_struct)->attributes = $2;
+               current_class = vala_class_new ($6, src_com (@6, $1));
+               VALA_CODE_NODE(current_class)->attributes = $2;
                if ($3 != 0) {
-                       VALA_TYPE_(current_struct)->access = $3;
+                       VALA_TYPE_(current_class)->access = $3;
                }
                for (l = $7; l != NULL; l = l->next) {
-                       vala_struct_add_type_parameter (current_struct, l->data);
+                       vala_class_add_type_parameter (current_class, l->data);
                }
                for (l = $8; l != NULL; l = l->next) {
-                       vala_class_add_base_type (VALA_CLASS (current_struct), l->data);
+                       vala_class_add_base_type (current_class, l->data);
                }
          }
          class_body
          {
-               $$ = VALA_CLASS (current_struct);
-               current_struct = NULL;
+               $$ = current_class;
+               current_class = NULL;
          }
        ;
 
@@ -1074,19 +1108,31 @@ class_member_declarations
 class_member_declaration
        : constant_declaration
          {
-               vala_struct_add_constant (current_struct, $1);
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_class_add_constant (current_class, $1);
+               }
          }
        | field_declaration
          {
-               vala_struct_add_field (current_struct, $1);
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_class_add_field (current_class, $1);
+               }
          }
        | method_declaration
          {
-               vala_struct_add_method (current_struct, $1);
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_class_add_method (current_class, $1);
+               }
          }
        | property_declaration
          {
-               vala_class_add_property (VALA_CLASS (current_struct), $1);
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_class_add_property (current_class, $1);
+               }
          }
        ;
 
@@ -1348,16 +1394,29 @@ struct_member_declarations
 struct_member_declaration
        : field_declaration
          {
-               vala_struct_add_field (current_struct, $1);
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_struct_add_field (current_struct, $1);
+               }
          }
        | method_declaration
          {
-               vala_struct_add_method (current_struct, $1);
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_struct_add_method (current_struct, $1);
+               }
          }
        ;
 
 interface_declaration
-       : comment opt_attributes opt_access_modifier INTERFACE IDENTIFIER interface_body
+       : comment opt_attributes opt_access_modifier INTERFACE IDENTIFIER
+         {
+               current_interface = vala_interface_new ($5, src_com (@5, $1));
+         }
+         interface_body
+         {
+               $$ = current_interface;
+         }
        ;
 
 interface_body
@@ -1375,7 +1434,77 @@ interface_member_declarations
        ;
 
 interface_member_declaration
-       : method_declaration
+       : interface_method_declaration
+         {
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_interface_add_method (current_interface, $1);
+               }
+         }
+       | interface_property_declaration
+         {
+               /* skip declarations with errors */
+               if ($1 != NULL) {
+                       vala_interface_add_property (current_interface, $1);
+               }
+         }
+       ;
+
+interface_method_declaration
+       : comment opt_attributes opt_ref type identifier_or_new OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS SEMICOLON
+         {
+               GList *l;
+               
+               $$ = vala_method_new ($5, $4, src_com (@5, $1));
+               $$->access = VALA_MEMBER_ACCESSIBILITY_PUBLIC;
+               $$->is_abstract = TRUE;
+               VALA_CODE_NODE($$)->attributes = $2;
+               
+               for (l = $7; l != NULL; l = l->next) {
+                       vala_method_add_parameter ($$, l->data);
+               }       
+         }
+       ;
+
+interface_property_declaration
+       : comment opt_attributes opt_ref type IDENTIFIER OPEN_BRACE interface_get_accessor_declaration opt_interface_set_accessor_declaration CLOSE_BRACE
+         {
+               $$ = vala_property_new ($5, $4, $7, $8, src_com (@4, $1));
+         }
+       | comment opt_attributes opt_ref type IDENTIFIER OPEN_BRACE interface_set_accessor_declaration CLOSE_BRACE
+         {
+               $$ = vala_property_new ($5, $4, NULL, $7, src_com (@4, $1));
+         }
+       ;
+
+interface_get_accessor_declaration
+       : opt_attributes GET SEMICOLON
+         {
+               $$ = vala_property_accessor_new (TRUE, FALSE, FALSE, NULL, src (@2));
+         }
+       ;
+
+opt_interface_set_accessor_declaration
+       : /* empty */
+         {
+               $$ = NULL;
+         }
+       | interface_set_accessor_declaration
+       ;
+
+interface_set_accessor_declaration
+       : opt_attributes SET SEMICOLON
+         {
+               $$ = vala_property_accessor_new (FALSE, TRUE, FALSE, NULL, src (@2));
+         }
+       | opt_attributes SET CONSTRUCT SEMICOLON
+         {
+               $$ = vala_property_accessor_new (FALSE, TRUE, TRUE, NULL, src (@2));
+         }
+       | opt_attributes CONSTRUCT SEMICOLON
+         {
+               $$ = vala_property_accessor_new (FALSE, FALSE, TRUE, NULL, src (@2));
+         }
        ;
 
 enum_declaration
@@ -1606,7 +1735,8 @@ extern int yylineno;
 static void
 yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg)
 {
-       printf ("%s:%d.%d-%d.%d: %s\n", vala_source_file_get_filename (current_source_file), locp->first_line, locp->first_column, locp->last_line, locp->last_column, msg);
+       ValaSourceReference *source_reference = vala_source_reference_new (current_source_file, locp->first_line, locp->first_column, locp->last_line, locp->last_column);
+       vala_report_error (source_reference, msg);
 }
 
 void
index 83d3a5a..fdfdca9 100644 (file)
@@ -24,6 +24,7 @@
 #include <vala/valaifstatement.h>
 #include <vala/valainitializerlist.h>
 #include <vala/valaintegerliteral.h>
+#include <vala/valainterface.h>
 #include <vala/valainvocationexpression.h>
 #include <vala/valaliteral.h>
 #include <vala/valaliteralexpression.h>
index 2e34029..e7128cb 100644 (file)
 using GLib;
 
 namespace Vala {
-       public class Class : Struct {
+       public class Class : Type_ {
+               List<string> type_parameters;
                public List<TypeReference> base_types;
                public Class base_class;
                public bool is_abstract;
                
+               List<Constant> constants;
+               List<Field> fields;
+               List<Method> methods;
                List<Property> properties;
+               
+               public string cname;
+               public string lower_case_csuffix;
+               public bool has_private_fields;
+               
+               public static ref Class new (string name, SourceReference source) {
+                       return (new Class (name = name, source_reference = source));
+               }
 
                public void add_base_type (TypeReference type) {
                        base_types.append (type);
                }
+
+               public void add_type_parameter (TypeParameter p) {
+                       type_parameters.append (p);
+                       p.type = this;
+               }
                
-               public static ref Class new (string name, SourceReference source) {
-                       return (new Class (name = name, source_reference = source));
+               public void add_constant (Constant c) {
+                       constants.append (c);
+               }
+               
+               public void add_field (Field f) {
+                       fields.append (f);
+                       if (f.access == MemberAccessibility.PRIVATE) {
+                               has_private_fields = true;
+                       }
+               }
+               
+               public ref List<Field> get_fields () {
+                       return fields.copy ();
+               }
+               
+               public void add_method (Method m) {
+                       return_if_fail (m != null);
+                       
+                       methods.append (m);
+               }
+               
+               public ref List<Method> get_methods () {
+                       return methods.copy ();
                }
                
                public void add_property (Property prop) {
@@ -60,7 +98,21 @@ namespace Vala {
                                type.accept (visitor);
                        }
 
-                       visit_children (visitor);                       
+                       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);
+                       }
                        
                        foreach (Property prop in properties) {
                                prop.accept (visitor);
@@ -68,9 +120,75 @@ namespace Vala {
 
                        visitor.visit_end_class (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 ());
+               }
+               
+               public override ref string get_upper_case_cname (string infix) {
+                       return get_lower_case_cname (infix).up (-1);
+               }
 
                public override bool is_reference_type () {
                        return true;
                }
+               
+               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)) {
+                                                               cheader_filenames.append (filename);
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+               
+               public void process_attributes () {
+                       foreach (Attribute a in attributes) {
+                               if (a.name == "CCode") {
+                                       process_ccode_attribute (a);
+                               }
+                       }
+               }
        }
 }
index 2aca867..27410aa 100644 (file)
@@ -36,7 +36,7 @@ namespace Vala {
                CCodeFragment source_type_member_definition;
                
                CCodeStruct instance_struct;
-               CCodeStruct class_struct;
+               CCodeStruct type_struct;
                CCodeStruct instance_priv_struct;
                CCodeEnum prop_enum;
                CCodeEnum cenum;
@@ -110,7 +110,8 @@ namespace Vala {
                        var i = filename;
                        while (i.len (-1) > 0) {
                                var c = i.get_char ();
-                               if (c.isalnum  () && c < 128) {
+                               /* FIXME: remove explicit cast when implicit cast works */
+                               if (c.isalnum  () && c < (unichar) 128) {
                                        define.append_unichar (c.toupper ());
                                } else {
                                        define.append_c ('_');
@@ -184,7 +185,7 @@ namespace Vala {
                        current_symbol = cl.symbol;
 
                        instance_struct = new CCodeStruct (name = "_%s".printf (cl.get_cname ()));
-                       class_struct = new CCodeStruct (name = "_%sClass".printf (cl.get_cname ()));
+                       type_struct = new CCodeStruct (name = "_%sClass".printf (cl.get_cname ()));
                        instance_priv_struct = new CCodeStruct (name = "_%sPrivate".printf (cl.get_cname ()));
                        prop_enum = new CCodeEnum ();
                        prop_enum.add_value ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null)), null);
@@ -213,19 +214,19 @@ namespace Vala {
 
                        if (cl.source_reference.file.cycle == null) {
                                header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (instance_struct.name), typedef_name = cl.get_cname ()));
-                               header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (class_struct.name), typedef_name = "%sClass".printf (cl.get_cname ())));
+                               header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (type_struct.name), typedef_name = "%sClass".printf (cl.get_cname ())));
                        }
                        header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (instance_priv_struct.name), typedef_name = "%sPrivate".printf (cl.get_cname ())));
                        
                        instance_struct.add_field (cl.base_class.get_cname (), "parent");
                        instance_struct.add_field ("%sPrivate *".printf (cl.get_cname ()), "priv");
-                       class_struct.add_field ("%sClass".printf (cl.base_class.get_cname ()), "parent");
+                       type_struct.add_field ("%sClass".printf (cl.base_class.get_cname ()), "parent");
 
                        if (cl.source_reference.comment != null) {
                                header_type_definition.append (new CCodeComment (text = cl.source_reference.comment));
                        }
                        header_type_definition.append (instance_struct);
-                       header_type_definition.append (class_struct);
+                       header_type_definition.append (type_struct);
                        source_type_member_declaration.append (instance_priv_struct);
                        macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
                        source_type_member_declaration.append (new CCodeMacroReplacement (name = "%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), replacement = macro));
@@ -312,15 +313,16 @@ namespace Vala {
                                if (prop.type_reference.type is Class) {
                                        cspec.call = new CCodeIdentifier (name = "g_param_spec_object");
                                        cspec.add_argument (new CCodeIdentifier (name = prop.type_reference.type.get_upper_case_cname ("TYPE_")));
-                               } else if (prop.type_reference.type_name.collate ("string") == 0) {
+                               } else if (prop.type_reference.type_name == "string") {
                                        cspec.call = new CCodeIdentifier (name = "g_param_spec_string");
                                        cspec.add_argument (new CCodeConstant (name = "NULL"));
-                               } else if (prop.type_reference.type_name.collate ("int") == 0 || prop.type_reference.type is Enum) {
+                               } else if (prop.type_reference.type_name == "int"
+                                          || prop.type_reference.type is Enum) {
                                        cspec.call = new CCodeIdentifier (name = "g_param_spec_int");
                                        cspec.add_argument (new CCodeConstant (name = "G_MININT"));
                                        cspec.add_argument (new CCodeConstant (name = "G_MAXINT"));
                                        cspec.add_argument (new CCodeConstant (name = "0"));
-                               } else if (prop.type_reference.type_name.collate ("bool") == 0) {
+                               } else if (prop.type_reference.type_name == "bool") {
                                        cspec.call = new CCodeIdentifier (name = "g_param_spec_boolean");
                                        cspec.add_argument (new CCodeConstant (name = "FALSE"));
                                } else {
@@ -399,11 +401,12 @@ namespace Vala {
                                var csetcall = new CCodeFunctionCall ();
                                if (prop.type_reference.type is Class) {
                                        csetcall.call = new CCodeIdentifier (name = "g_value_set_object");
-                               } else if (prop.type_reference.type_name.collate ("string") == 0) {
+                               } else if (prop.type_reference.type_name == "string") {
                                        csetcall.call = new CCodeIdentifier (name = "g_value_set_string");
-                               } else if (prop.type_reference.type_name.collate ("int") == 0 || prop.type_reference.type is Enum) {
+                               } else if (prop.type_reference.type_name == "int"
+                                          || prop.type_reference.type is Enum) {
                                        csetcall.call = new CCodeIdentifier (name = "g_value_set_int");
-                               } else if (prop.type_reference.type_name.collate ("bool") == 0) {
+                               } else if (prop.type_reference.type_name == "bool") {
                                        csetcall.call = new CCodeIdentifier (name = "g_value_set_boolean");
                                } else {
                                        csetcall.call = new CCodeIdentifier (name = "g_value_set_pointer");
@@ -444,11 +447,12 @@ namespace Vala {
                                var cgetcall = new CCodeFunctionCall ();
                                if (prop.type_reference.type is Class) {
                                        cgetcall.call = new CCodeIdentifier (name = "g_value_get_object");
-                               } else if (prop.type_reference.type_name.collate ("string") == 0) {
+                               } else if (prop.type_reference.type_name == "string") {
                                        cgetcall.call = new CCodeIdentifier (name = "g_value_dup_string");
-                               } else if (prop.type_reference.type_name.collate ("int") == 0 || prop.type_reference.type is Enum) {
+                               } else if (prop.type_reference.type_name == "int"
+                                         || prop.type_reference.type is Enum) {
                                        cgetcall.call = new CCodeIdentifier (name = "g_value_get_int");
-                               } else if (prop.type_reference.type_name.collate ("bool") == 0) {
+                               } else if (prop.type_reference.type_name == "bool") {
                                        cgetcall.call = new CCodeIdentifier (name = "g_value_get_boolean");
                                } else {
                                        cgetcall.call = new CCodeIdentifier (name = "g_value_get_pointer");
@@ -474,6 +478,42 @@ namespace Vala {
                        }
                        header_type_definition.append (instance_struct);
                }
+
+               public override void visit_begin_interface (Interface iface) {
+                       current_symbol = iface.symbol;
+
+                       type_struct = new CCodeStruct (name = "_%sInterface".printf (iface.get_cname ()));
+                       
+                       header_type_declaration.append (new CCodeNewline ());
+                       var macro = "(%s_get_type ())".printf (iface.get_lower_case_cname (null));
+                       header_type_declaration.append (new CCodeMacroReplacement (name = iface.get_upper_case_cname ("TYPE_"), replacement = macro));
+
+                       macro = "(G_TYPE_CHECK_INSTANCE_CAST ((obj), %s, %s))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_cname ());
+                       header_type_declaration.append (new CCodeMacroReplacement (name = "%s(obj)".printf (iface.get_upper_case_cname (null)), replacement = macro));
+
+                       macro = "(G_TYPE_CHECK_INSTANCE_TYPE ((obj), %s))".printf (iface.get_upper_case_cname ("TYPE_"));
+                       header_type_declaration.append (new CCodeMacroReplacement (name = "%s(obj)".printf (iface.get_upper_case_cname ("IS_")), replacement = macro));
+
+                       macro = "(G_TYPE_INSTANCE_GET_INTERFACE ((obj), %s, %sInterface))".printf (iface.get_upper_case_cname ("TYPE_"), iface.get_cname ());
+                       header_type_declaration.append (new CCodeMacroReplacement (name = "%s_GET_INTERFACE(obj)".printf (iface.get_upper_case_cname (null)), replacement = macro));
+                       header_type_declaration.append (new CCodeNewline ());
+
+
+                       if (iface.source_reference.file.cycle == null) {
+                               header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct _%s".printf (iface.get_cname ()), typedef_name = iface.get_cname ()));
+                               header_type_declaration.append (new CCodeTypeDefinition (type_name = "struct %s".printf (type_struct.name), typedef_name = "%sInterface".printf (iface.get_cname ())));
+                       }
+                       
+                       type_struct.add_field ("GTypeInterface", "parent");
+
+                       if (iface.source_reference.comment != null) {
+                               header_type_definition.append (new CCodeComment (text = iface.source_reference.comment));
+                       }
+                       header_type_definition.append (type_struct);
+               }
+
+               public override void visit_end_interface (Interface iface) {
+               }
                
                public override void visit_begin_enum (Enum en) {
                        cenum = new CCodeEnum (name = en.get_cname ());
@@ -489,8 +529,8 @@ namespace Vala {
                }
 
                public override void visit_constant (Constant c) {
-                       if (c.symbol.parent_symbol.node is Struct) {
-                               var t = (Struct) c.symbol.parent_symbol.node;
+                       if (c.symbol.parent_symbol.node is Type_) {
+                               var t = (Type_) c.symbol.parent_symbol.node;
                                var cdecl = new CCodeDeclaration (type_name = c.type_reference.get_const_cname ());
                                var arr = "";
                                if (c.type_reference.array) {
@@ -509,8 +549,8 @@ namespace Vala {
                                if (f.instance) {
                                        instance_priv_struct.add_field (f.type_reference.get_cname (), f.get_cname ());
                                } else {
-                                       if (f.symbol.parent_symbol.node is Struct) {
-                                               var t = (Struct) f.symbol.parent_symbol.node;
+                                       if (f.symbol.parent_symbol.node is Type_) {
+                                               var t = (Type_) 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 ())));
                                                cdecl.modifiers = CCodeModifiers.STATIC;
@@ -521,7 +561,7 @@ namespace Vala {
                }
                
                public override void visit_end_method (Method m) {
-                       if (m.name.collate ("init") == 0) {
+                       if (m.name == "init") {
                                
                                return;
                        }
@@ -530,9 +570,8 @@ namespace Vala {
                        CCodeFunctionDeclarator vdeclarator = null;
                        
                        if (m.instance) {
-                               var st = (Struct) m.symbol.parent_symbol.node;
                                var this_type = new TypeReference ();
-                               this_type.type = st;
+                               this_type.type = (Type_) m.symbol.parent_symbol.node;
                                if (!m.is_override) {
                                        var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
                                        function.add_parameter (cparam);
@@ -546,7 +585,7 @@ namespace Vala {
                                        var vdecl = new CCodeDeclaration (type_name = m.return_type.get_cname ());
                                        vdeclarator = new CCodeFunctionDeclarator (name = m.name);
                                        vdecl.add_declarator (vdeclarator);
-                                       class_struct.add_declaration (vdecl);
+                                       type_struct.add_declaration (vdecl);
 
                                        var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
                                        vdeclarator.add_parameter (cparam);
@@ -601,9 +640,8 @@ namespace Vala {
 
                                var vfunc = new CCodeFunction (name = m.get_cname (), return_type = m.return_type.get_cname ());
 
-                               var st = (Struct) m.symbol.parent_symbol.node;
                                var this_type = new TypeReference ();
-                               this_type.type = st;
+                               this_type.type = (Type_) m.symbol.parent_symbol.node;
 
                                var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
                                vfunc.add_parameter (cparam);
@@ -630,7 +668,7 @@ namespace Vala {
                                source_type_member_definition.append (vfunc);
                        }
                        
-                       if (m.name.collate ("main") == 0) {
+                       if (m.name == "main") {
                                var cmain = new CCodeFunction (name = "main", return_type = "int");
                                cmain.add_parameter (new CCodeFormalParameter (type_name = "int", name = "argc"));
                                cmain.add_parameter (new CCodeFormalParameter (type_name = "char **", name = "argv"));
@@ -651,16 +689,10 @@ namespace Vala {
                        }
                }
 
-               public override void visit_begin_property (Property prop) {
-               }
-
                public override void visit_end_property (Property prop) {
                        prop_enum.add_value (prop.get_upper_case_cname (), null);
                }
 
-               public override void visit_begin_property_accessor (PropertyAccessor acc) {
-               }
-
                public override void visit_end_property_accessor (PropertyAccessor acc) {
                        var prop = (Property) acc.symbol.parent_symbol.node;
                        var cl = (Class) prop.symbol.parent_symbol.node;
@@ -798,7 +830,7 @@ namespace Vala {
                                cfor.add_initializer (new CCodeAssignment (left = new CCodeIdentifier (name = it_name), right = (CCodeExpression) stmt.collection.ccodenode));
                                cfor.add_iterator (new CCodeAssignment (left = new CCodeIdentifier (name = it_name), right = new CCodeBinaryExpression (operator = CCodeBinaryOperator.PLUS, left = new CCodeIdentifier (name = it_name), right = new CCodeConstant (name = "1"))));
                                cblock.add_statement (cfor);
-                       } else if (stmt.collection.static_type.type.name.collate ("List") == 0) {
+                       } else if (stmt.collection.static_type.type.name == "List") {
                                var it_name = "%s_it".printf (stmt.variable_name);
                        
                                var citdecl = new CCodeDeclaration (type_name = "GList *");
@@ -868,18 +900,19 @@ namespace Vala {
                        expr.ccodenode = expr.literal.ccodenode;
                }
                
-               public override void visit_simple_name (SimpleName expr) {
-                       if (expr.name.collate ("this") == 0) {
-                               expr.ccodenode = new CCodeIdentifier (name = "self");
-                       } else if (expr.symbol_reference.node is Method) {
+               private void process_cmember (Expression expr, CCodeIdentifier pub_inst, Type_ base_type) {
+                       if (expr.symbol_reference.node is Method) {
                                var m = (Method) expr.symbol_reference.node;
-                               expr.ccodenode = new CCodeIdentifier (name = m.get_cname ());
+                               if (!m.is_override) {
+                                       expr.ccodenode = new CCodeIdentifier (name = m.get_cname ());
+                               } else {
+                                       expr.ccodenode = new CCodeIdentifier (name = m.base_method.get_cname ());
+                               }
                        } else if (expr.symbol_reference.node is Field) {
                                var f = (Field) expr.symbol_reference.node;
                                if (f.instance) {
-                                       var pub_inst = new CCodeIdentifier (name = "self");
                                        ref CCodeExpression typed_inst;
-                                       if (f.symbol.parent_symbol != current_symbol) {
+                                       if (f.symbol.parent_symbol.node != base_type) {
                                                typed_inst = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((Type_) f.symbol.parent_symbol.node).get_upper_case_cname (null)));
                                                ((CCodeFunctionCall) typed_inst).add_argument (pub_inst);
                                        } else {
@@ -893,8 +926,8 @@ namespace Vala {
                                        }
                                        expr.ccodenode = new CCodeMemberAccess (inner = inst, member_name = f.get_cname (), is_pointer = true);
                                } else {
-                                       if (f.symbol.parent_symbol.node is Struct) {
-                                               var t = (Struct) f.symbol.parent_symbol.node;
+                                       if (f.symbol.parent_symbol.node is Type_) {
+                                               var t = (Type_) f.symbol.parent_symbol.node;
                                                expr.ccodenode = new CCodeIdentifier (name = "%s_%s".printf (t.get_lower_case_cname (null), f.get_cname ()));
                                        } else {
                                                expr.ccodenode = new CCodeIdentifier (name = f.get_cname ());
@@ -902,64 +935,48 @@ namespace Vala {
                                }
                        } else if (expr.symbol_reference.node is Constant) {
                                var c = (Constant) expr.symbol_reference.node;
-                               if (c.symbol.parent_symbol.node is Struct) {
-                                       var t = (Struct) c.symbol.parent_symbol.node;
-                                       expr.ccodenode = new CCodeIdentifier (name = "%s_%s".printf (t.get_lower_case_cname (null), expr.name));
-                               } else {
-                                       expr.ccodenode = new CCodeIdentifier (name = expr.name);
-                               }
+                               expr.ccodenode = new CCodeIdentifier (name = c.get_cname ());
                        } else if (expr.symbol_reference.node is Property) {
                                var prop = (Property) expr.symbol_reference.node;
                                var cl = (Class) prop.symbol.parent_symbol.node;
                                var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_get_%s".printf (cl.get_lower_case_cname (null), prop.name)));
-                               ccall.add_argument (new CCodeIdentifier (name = "self"));
+                               ccall.add_argument (pub_inst);
                                expr.ccodenode = ccall;
-                       } else {
-                               expr.ccodenode = new CCodeIdentifier (name = expr.name);
+                       } else if (expr.symbol_reference.node is EnumValue) {
+                               var ev = (EnumValue) expr.symbol_reference.node;
+                               expr.ccodenode = new CCodeConstant (name = ev.get_cname ());
+                       } else if (expr.symbol_reference.node is VariableDeclarator) {
+                               var decl = (VariableDeclarator) expr.symbol_reference.node;
+                               expr.ccodenode = new CCodeIdentifier (name = decl.name);
+                       } else if (expr.symbol_reference.node is FormalParameter) {
+                               var p = (FormalParameter) expr.symbol_reference.node;
+                               if (p.name == "this") {
+                                       expr.ccodenode = pub_inst;
+                               } else {
+                                       expr.ccodenode = new CCodeIdentifier (name = p.name);
+                               }
                        }
                }
+               
+               public override void visit_simple_name (SimpleName expr) {
+                       var pub_inst = new CCodeIdentifier (name = "self");
+                       var base_type = (Type_) current_symbol.node;
+                       
+                       process_cmember (expr, pub_inst, base_type);
+               }
 
                public override void visit_parenthesized_expression (ParenthesizedExpression expr) {
                        expr.ccodenode = new CCodeParenthesizedExpression (inner = (CCodeExpression) expr.inner.ccodenode);
                }
 
                public override void visit_member_access (MemberAccess expr) {
-                       if (expr.symbol_reference.node is Method) {
-                               var m = (Method) expr.symbol_reference.node;
-                               if (!m.is_override) {
-                                       expr.ccodenode = new CCodeIdentifier (name = m.get_cname ());
-                               } else {
-                                       expr.ccodenode = new CCodeIdentifier (name = m.base_method.get_cname ());
-                               }
-                       } else if (expr.symbol_reference.node is Field) {
-                               var f = (Field) expr.symbol_reference.node;
-                               var pub_inst = expr.inner.ccodenode;
-                               ref CCodeExpression typed_inst;
-                               if (f.symbol.parent_symbol.node != expr.inner.static_type.type) {
-                                       typed_inst = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((Type_) f.symbol.parent_symbol.node).get_upper_case_cname (null)));
-                                       ((CCodeFunctionCall) typed_inst).add_argument (pub_inst);
-                               } else {
-                                       typed_inst = pub_inst;
-                               }
-                               ref CCodeExpression inst;
-                               if (f.access == MemberAccessibility.PRIVATE) {
-                                       inst = new CCodeMemberAccess (inner = typed_inst, member_name = "priv", is_pointer = true);
-                               } else {
-                                       inst = typed_inst;
-                               }
-                               expr.ccodenode = new CCodeMemberAccess (inner = inst, member_name = f.get_cname (), is_pointer = true);
-                       } else if (expr.symbol_reference.node is Property) {
-                               var prop = (Property) expr.symbol_reference.node;
-                               var cl = (Class) prop.symbol.parent_symbol.node;
-                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_get_%s".printf (cl.get_lower_case_cname (null), prop.name)));
-                               ccall.add_argument (expr.inner.ccodenode);
-                               expr.ccodenode = ccall;
-                       } else if (expr.symbol_reference.node is EnumValue) {
-                               var ev = (EnumValue) expr.symbol_reference.node;
-                               expr.ccodenode = new CCodeConstant (name = ev.get_cname ());
-                       } else {
-                               expr.ccodenode = new CCodeMemberAccess (inner = (CCodeExpression) expr.inner.ccodenode, member_name = expr.member_name, is_pointer = true);
+                       var pub_inst = expr.inner.ccodenode;
+                       Type_ base_type = null;
+                       if (expr.inner.static_type != null) {
+                               base_type = expr.inner.static_type.type;
                        }
+
+                       process_cmember (expr, pub_inst, base_type);
                }
 
                public override void visit_invocation_expression (InvocationExpression expr) {
index 88af771..a194caa 100644 (file)
@@ -27,6 +27,7 @@ namespace Vala {
                public Symbol symbol;
                public List<Attribute> attributes;
                public CCodeNode ccodenode;
+               public bool error;
        
                public abstract void accept (CodeVisitor visitor);
        }
index e64f4ce..d5165c6 100644 (file)
@@ -48,6 +48,12 @@ namespace Vala {
                public virtual void visit_end_struct (Struct st) {
                }
 
+               public virtual void visit_begin_interface (Interface iface) {
+               }
+
+               public virtual void visit_end_interface (Interface iface) {
+               }
+
                public virtual void visit_begin_enum (Enum en) {
                }
 
index 9378dc5..80de1d7 100644 (file)
@@ -40,5 +40,19 @@ namespace Vala {
 
                        visitor.visit_constant (this);
                }
+               
+               string cname;
+               public string get_cname () {
+                       if (cname == null) {
+                               if (symbol.parent_symbol.node is Type_) {
+                                       var t = (Type_) symbol.parent_symbol.node;
+                                       cname = "%s_%s".printf (t.get_upper_case_cname (null), name);
+                               } else {
+                                       var ns = (Namespace) symbol.parent_symbol.node;
+                                       cname = "%s%s".printf (ns.get_cprefix ().up (-1), name);
+                               }
+                       }
+                       return cname;
+               }
        }
 }
index fd34dd4..9a8f54c 100644 (file)
@@ -52,7 +52,7 @@ namespace Vala {
                        return cname;
                }
                
-               public string get_upper_case_cname () {
+               public override string get_upper_case_cname (string infix) {
                        return "%s%s".printf (@namespace.get_lower_case_cprefix (), Namespace.camel_case_to_lower_case (name)).up (-1);
                }
 
index babacc7..5f40a6f 100644 (file)
@@ -44,7 +44,7 @@ namespace Vala {
                public string get_cname () {
                        if (cname == null) {
                                var en = (Enum) symbol.parent_symbol.node;
-                               cname = "%s_%s".printf (en.get_upper_case_cname (), name);
+                               cname = "%s_%s".printf (en.get_upper_case_cname (null), name);
                        }
                        return cname;
                }
index 4827dfe..77d6afd 100644 (file)
@@ -59,7 +59,7 @@ namespace Vala {
                
                void process_ccode_attribute (Attribute a) {
                        foreach (NamedArgument arg in a.args) {
-                               if (arg.name.collate ("cname") == 0) {
+                               if (arg.name == "cname") {
                                        /* this will already be checked during semantic analysis */
                                        if (arg.argument is LiteralExpression) {
                                                var lit = ((LiteralExpression) arg.argument).literal;
@@ -73,7 +73,7 @@ namespace Vala {
                
                public void process_attributes () {
                        foreach (Attribute a in attributes) {
-                               if (a.name.collate ("CCode") == 0) {
+                               if (a.name == "CCode") {
                                        process_ccode_attribute (a);
                                }
                        }
diff --git a/vala/vala/valainterface.vala b/vala/vala/valainterface.vala
new file mode 100644 (file)
index 0000000..2b2c54c
--- /dev/null
@@ -0,0 +1,122 @@
+/* valainterface.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;
+
+namespace Vala {
+       public class Interface : Type_ {
+               List<string> type_parameters;
+               public List<TypeReference> base_types;
+
+               List<Method> methods;
+               List<Property> properties;
+               
+               public static ref Interface new (string name, SourceReference source) {
+                       return (new Interface (name = name, source_reference = source));
+               }
+
+               public void add_type_parameter (TypeParameter p) {
+                       type_parameters.append (p);
+                       p.type = this;
+               }
+
+               public void add_base_type (TypeReference type) {
+                       base_types.append (type);
+               }
+               
+               public void add_method (Method m) {
+                       return_if_fail (m.instance && m.is_abstract && !m.is_virtual && !m.is_override);
+               
+                       methods.append (m);
+               }
+               
+               public ref List<Method> get_methods () {
+                       return methods.copy ();
+               }
+               
+               public void add_property (Property prop) {
+                       properties.append (prop);
+               }
+               
+               public ref List<Property> get_properties () {
+                       return properties.copy ();
+               }
+               
+               private string cname;
+               private string lower_case_csuffix;
+               
+               public override string get_cname () {
+                       if (cname == null) {
+                               cname = "%s%s".printf (@namespace.get_cprefix (), name);
+                       }
+                       return 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 ());
+               }
+               
+               public override ref string get_upper_case_cname (string infix) {
+                       return get_lower_case_cname (infix).up (-1);
+               }
+               
+               public override void accept (CodeVisitor visitor) {
+                       visitor.visit_begin_interface (this);
+                       
+                       foreach (TypeReference type in base_types) {
+                               type.accept (visitor);
+                       }
+
+                       foreach (TypeParameter p in type_parameters) {
+                               p.accept (visitor);
+                       }
+                       
+                       foreach (Method m in methods) {
+                               m.accept (visitor);
+                       }
+                       
+                       foreach (Property prop in properties) {
+                               prop.accept (visitor);
+                       }
+
+                       visitor.visit_end_interface (this);
+               }
+
+               public override bool is_reference_type () {
+                       return true;
+               }
+       }
+}
index 6709f5f..5f84583 100644 (file)
@@ -259,7 +259,7 @@ namespace Vala {
                }
                
                private void write_identifier (string s) {
-                       if (s.collate ("namespace") == 0) {
+                       if (s == "namespace") {
                                stream.putc ('@');
                        }
                        write_string (s);
index 79ff1c9..322ad18 100644 (file)
@@ -32,6 +32,10 @@ namespace Vala {
                        return (new InvocationExpression (call = call, argument_list = argument_list, source_reference = source));
                }
                
+               public void add_argument (Expression arg) {
+                       _argument_list.append (arg);
+               }
+               
                public override void accept (CodeVisitor visitor) {
                        call.accept (visitor);
                        foreach (Expression expr in argument_list) {
index ab07d06..9c4c927 100644 (file)
@@ -78,8 +78,8 @@ namespace Vala {
                public string get_cname () {
                        if (cname == null) {
                                var parent = symbol.parent_symbol.node;
-                               if (parent is Struct) {
-                                       cname = "%s_%s".printf (((Struct) parent).get_lower_case_cname (null), name);
+                               if (parent is Type_) {
+                                       cname = "%s_%s".printf (((Type_) parent).get_lower_case_cname (null), name);
                                } else if (parent is Namespace) {
                                        cname = "%s%s".printf (((Namespace) parent).get_lower_case_cprefix (), name);
                                } else {
@@ -104,7 +104,7 @@ namespace Vala {
                
                void process_ccode_attribute (Attribute a) {
                        foreach (NamedArgument arg in a.args) {
-                               if (arg.name.collate ("cname") == 0) {
+                               if (arg.name == "cname") {
                                        /* this will already be checked during semantic analysis */
                                        if (arg.argument is LiteralExpression) {
                                                var lit = ((LiteralExpression) arg.argument).literal;
@@ -118,11 +118,11 @@ namespace Vala {
                
                public void process_attributes () {
                        foreach (Attribute a in attributes) {
-                               if (a.name.collate ("CCode") == 0) {
+                               if (a.name == "CCode") {
                                        process_ccode_attribute (a);
-                               } else if (a.name.collate ("ReturnsModifiedPointer") == 0) {
+                               } else if (a.name == "ReturnsModifiedPointer") {
                                        returns_modified_pointer = true;
-                               } else if (a.name.collate ("InstanceLast") == 0) {
+                               } else if (a.name == "InstanceLast") {
                                        instance_last = true;
                                }
                        }
index 6704b33..c4e73d7 100644 (file)
@@ -28,6 +28,7 @@ namespace Vala {
                public SourceReference source_reference { get; construct; }
 
                List<Class> classes;
+               List<Interface> interfaces;
                List<Struct> structs;
                List<Enum> enums;
                List<Field> fields;
@@ -50,6 +51,11 @@ namespace Vala {
                        cl.@namespace = null;
                }
                
+               public void add_interface (Interface iface) {
+                       interfaces.append (iface);
+                       iface.@namespace = this;
+               }
+               
                public void add_struct (Struct st) {
                        structs.append (st);
                        st.@namespace = this;
@@ -88,6 +94,10 @@ namespace Vala {
                                cl.accept (visitor);
                        }
 
+                       foreach (Interface iface in interfaces) {
+                               iface.accept (visitor);
+                       }
+
                        foreach (Struct st in structs) {
                                st.accept (visitor);
                        }
@@ -183,7 +193,7 @@ namespace Vala {
                
                void process_ccode_attribute (Attribute a) {
                        foreach (NamedArgument arg in a.args) {
-                               if (arg.name.collate ("cprefix") == 0) {
+                               if (arg.name == "cprefix") {
                                        /* this will already be checked during semantic analysis */
                                        if (arg.argument is LiteralExpression) {
                                                var lit = ((LiteralExpression) arg.argument).literal;
@@ -191,7 +201,7 @@ namespace Vala {
                                                        set_cprefix (((StringLiteral) lit).eval ());
                                                }
                                        }
-                               } else if (arg.name.collate ("lower_case_cprefix") == 0) {
+                               } else if (arg.name == "lower_case_cprefix") {
                                        /* this will already be checked during semantic analysis */
                                        if (arg.argument is LiteralExpression) {
                                                var lit = ((LiteralExpression) arg.argument).literal;
@@ -199,7 +209,7 @@ namespace Vala {
                                                        set_lower_case_cprefix (((StringLiteral) lit).eval ());
                                                }
                                        }
-                               } else if (arg.name.collate ("cheader_filename") == 0) {
+                               } 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;
@@ -216,7 +226,7 @@ namespace Vala {
                
                public void process_attributes () {
                        foreach (Attribute a in attributes) {
-                               if (a.name.collate ("CCode") == 0) {
+                               if (a.name == "CCode") {
                                        process_ccode_attribute (a);
                                }
                        }
index 3ff0cdd..986fa07 100644 (file)
@@ -29,9 +29,19 @@ namespace Vala {
                SourceFile current_source_file;
                
                List<NamespaceReference> current_using_directives;
-       
+               
+               TypeReference bool_type;
+               TypeReference string_type;
+               
                public void analyze (CodeContext context) {
                        root_symbol = context.root;
+
+                       bool_type = new TypeReference ();
+                       bool_type.type = (Type_) root_symbol.lookup ("bool").node;
+
+                       string_type = new TypeReference ();
+                       string_type.type = (Type_) root_symbol.lookup ("string").node;
+
                        current_symbol = root_symbol;
                        context.accept (this);
                }
@@ -109,7 +119,7 @@ namespace Vala {
                                                        var base_method = (Method) sym.node;
                                                        if (base_method.is_abstract || base_method.is_virtual) {
                                                                m.base_method = base_method;
-                                                               //break;
+                                                               break;
                                                        }
                                                }
                                        }
@@ -168,14 +178,16 @@ namespace Vala {
                        if (stmt.type_reference.type != null) {
                                current_source_file.add_symbol_dependency (stmt.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
                        }
+                       
+                       var decl = new VariableDeclarator (name = stmt.variable_name);
+                       decl.type_reference = stmt.type_reference;
                
-                       stmt.symbol = new Symbol (node = stmt.type_reference);
+                       stmt.symbol = new Symbol (node = decl);
                        current_symbol.add (stmt.variable_name, stmt.symbol);
                }
 
                public override void visit_boolean_literal (BooleanLiteral expr) {
-                       expr.static_type = new TypeReference ();
-                       expr.static_type.type = (Type_) root_symbol.lookup ("bool").node;
+                       expr.static_type = bool_type;
                }
 
                public override void visit_character_literal (CharacterLiteral expr) {
@@ -189,11 +201,12 @@ namespace Vala {
                }
 
                public override void visit_string_literal (StringLiteral expr) {
-                       expr.static_type = new TypeReference ();
-                       expr.static_type.type = (Type_) root_symbol.lookup ("string").node;
+                       expr.static_type = string_type;
                }
 
                public override void visit_null_literal (NullLiteral expr) {
+                       /* empty TypeReference represents null */
+                       
                        expr.static_type = new TypeReference ();
                }
 
@@ -271,6 +284,12 @@ namespace Vala {
                }
 
                public override void visit_member_access (MemberAccess expr) {
+                       if (expr.inner.static_type == null
+                           && expr.inner.symbol_reference == null) {
+                               /* if there was an error in the inner expression, skip this check */
+                               return;
+                       }
+               
                        if (expr.inner.static_type == null) {
                                if (expr.inner.symbol_reference.node is Namespace || expr.inner.symbol_reference.node is Type_) {
                                        expr.symbol_reference = expr.inner.symbol_reference.lookup (expr.member_name);
@@ -285,7 +304,7 @@ namespace Vala {
                                if (expr.inner.static_type == null) {
                                        Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.member_name, expr.inner.symbol_reference.get_full_name ()));
                                } else {
-                                       Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.member_name, expr.inner.static_type.type.symbol.get_full_name ()));
+                                       Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.member_name, expr.inner.static_type.to_string ()));
                                }
                                return;
                        }
@@ -319,7 +338,7 @@ namespace Vala {
                                return true;
                        }
                        
-                       /* int may be implicitly casted to long */
+                       /* char may be implicitly casted to unichar */
                        if (expression_type.type == root_symbol.lookup ("char").node && expected_type.type == root_symbol.lookup ("unichar").node) {
                                return true;
                        }
@@ -342,6 +361,11 @@ namespace Vala {
                }
 
                public override void visit_invocation_expression (InvocationExpression expr) {
+                       if (expr.call.symbol_reference == null) {
+                               /* if method resolving didn't succeed, skip this check */
+                               return;
+                       }
+               
                        var m = (Method) expr.call.symbol_reference.node;
                        expr.static_type = m.return_type;
                        
@@ -362,8 +386,10 @@ namespace Vala {
                                }
                                
                                var arg = (Expression) arg_it.data;
-                               if (!is_type_compatible (arg.static_type, param.type_reference)) {
-                                       Report.warning (expr.source_reference, "Argument %d: Cannot convert from `%s' to `%s'".printf (i + 1, arg.static_type.type.symbol.get_full_name (), param.type_reference.type.symbol.get_full_name ()));
+                               if (arg.static_type != null && !is_type_compatible (arg.static_type, param.type_reference)) {
+                                       /* if there was an error in the argument,
+                                        * i.e. arg.static_type == null, skip type check */
+                                       Report.error (expr.source_reference, "Argument %d: Cannot convert from `%s' to `%s'".printf (i + 1, arg.static_type.type.symbol.get_full_name (), param.type_reference.to_string ()));
                                        return;
                                }
                                
@@ -373,36 +399,181 @@ namespace Vala {
                        }
                        
                        if (!ellipsis && arg_it != null) {
-                               Report.warning (expr.source_reference, "Method `%s' does not take %d arguments".printf (m.symbol.get_full_name (), expr.argument_list.length ()));
+                               Report.error (expr.source_reference, "Method `%s' does not take %d arguments".printf (m.symbol.get_full_name (), expr.argument_list.length ()));
                                return;
                        }
                }
 
                public override void visit_object_creation_expression (ObjectCreationExpression expr) {
+                       if (expr.type_reference.type == null) {
+                               /* if type resolving didn't succeed, skip this check */
+                               return;
+                       }
+               
                        current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
 
                        expr.static_type = expr.type_reference;
                }
 
                public override void visit_unary_expression (UnaryExpression expr) {
-                       expr.static_type = expr.inner.static_type;
+                       if (expr.inner.static_type == null) {
+                               /* if there was an error in the inner expression, skip type check */
+                               return;
+                       }
+               
+                       if (expr.operator == UnaryOperator.PLUS || expr.operator == UnaryOperator.MINUS) {
+                               // integer or floating point type
+
+                               expr.static_type = expr.inner.static_type;
+                       } else if (expr.operator == UnaryOperator.LOGICAL_NEGATION) {
+                               // boolean type
+
+                               expr.static_type = expr.inner.static_type;
+                       } else if (expr.operator == UnaryOperator.BITWISE_COMPLEMENT) {
+                               // integer type
+
+                               expr.static_type = expr.inner.static_type;
+                       } else if (expr.operator == UnaryOperator.REF) {
+                               // value type
+
+                               expr.static_type = expr.inner.static_type;
+                       } else if (expr.operator == UnaryOperator.OUT) {
+                               // reference type
+
+                               expr.static_type = expr.inner.static_type;
+                       } else {
+                               assert_not_reached ();
+                       }
                }
 
                public override void visit_cast_expression (CastExpression expr) {
+                       if (expr.type_reference.type == null) {
+                               /* if type resolving didn't succeed, skip this check */
+                               return;
+                       }
+               
                        current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
 
                        expr.static_type = expr.type_reference;
                }
-
+               
+               private bool check_binary_type (BinaryExpression expr, string operation) {
+                       if (!is_type_compatible (expr.right.static_type, expr.left.static_type)) {
+                               Report.error (expr.source_reference, "%s: Cannot convert from `%s' to `%s'".printf (operation, expr.right.static_type.to_string (), expr.left.static_type.to_string ()));
+                               return false;
+                       }
+                       
+                       return true;
+               }
+               
                public override void visit_binary_expression (BinaryExpression expr) {
-                       expr.static_type = expr.left.static_type;
+                       if (expr.left.static_type == null
+                           || expr.right.static_type == null) {
+                               /* if there were any errors in inner expressions, skip type check */
+                               return;
+                       }
+               
+                       if (expr.left.static_type.type == string_type.type
+                           && expr.operator == BinaryOperator.PLUS) {
+                               if (expr.right.static_type.type != string_type.type) {
+                                       Report.error (expr.source_reference, "Operands must be strings");
+                               }
+
+                               expr.static_type = string_type;
+                       } else if (expr.operator == BinaryOperator.PLUS
+                                  || expr.operator == BinaryOperator.MINUS
+                                  || expr.operator == BinaryOperator.MUL
+                                  || expr.operator == BinaryOperator.DIV) {
+                               // TODO: check for integer or floating point type in expr.left
+
+                               if (!check_binary_type (expr, "Arithmetic operation")) {
+                                       return;
+                               }
+
+                               expr.static_type = expr.left.static_type;
+                       } else if (expr.operator == BinaryOperator.MOD
+                                  || expr.operator == BinaryOperator.SHIFT_LEFT
+                                  || expr.operator == BinaryOperator.SHIFT_RIGHT
+                                  || expr.operator == BinaryOperator.BITWISE_XOR) {
+                               // TODO: check for integer type in expr.left
+
+                               if (!check_binary_type (expr, "Arithmetic operation")) {
+                                       return;
+                               }
+
+                               expr.static_type = expr.left.static_type;
+                       } else if (expr.operator == BinaryOperator.LESS_THAN
+                                  || expr.operator == BinaryOperator.GREATER_THAN
+                                  || expr.operator == BinaryOperator.LESS_THAN_OR_EQUAL
+                                  || expr.operator == BinaryOperator.GREATER_THAN_OR_EQUAL) {
+                               if (expr.left.static_type.type == string_type.type
+                                   && expr.right.static_type.type == string_type.type) {
+                                       /* string comparison: convert to a.collate (b) OP 0 */
+                                       
+                                       var cmp_call = new InvocationExpression (call = new MemberAccess (inner = expr.left, member_name = "collate"));
+                                       cmp_call.add_argument (expr.right);
+                                       expr.left = cmp_call;
+                                       
+                                       expr.right = new LiteralExpression (literal = new IntegerLiteral (value = "0"));
+                                       
+                                       expr.left.accept (this);
+                               } else {
+                                       /* TODO: check for integer or floating point type in expr.left */
+
+                                       if (!check_binary_type (expr, "Relational operation")) {
+                                               return;
+                                       }
+                               }
+                               
+                               expr.static_type = bool_type;
+                       } else if (expr.operator == BinaryOperator.EQUALITY
+                                  || expr.operator == BinaryOperator.INEQUALITY) {
+                               /* relational operation */
+
+                               if (!check_binary_type (expr, "Equality operation")) {
+                                       return;
+                               }
+                               
+                               if (expr.left.static_type.type == string_type.type
+                                   && expr.right.static_type.type == string_type.type) {
+                                       /* string comparison: convert to a.collate (b) OP 0 */
+                                       
+                                       var cmp_call = new InvocationExpression (call = new MemberAccess (inner = expr.left, member_name = "collate"));
+                                       cmp_call.add_argument (expr.right);
+                                       expr.left = cmp_call;
+                                       
+                                       expr.right = new LiteralExpression (literal = new IntegerLiteral (value = "0"));
+                                       
+                                       expr.left.accept (this);
+                               }
+
+                               expr.static_type = bool_type;
+                       } else if (expr.operator == BinaryOperator.BITWISE_AND
+                                  || expr.operator == BinaryOperator.BITWISE_OR) {
+                               // integer type or flags type
+
+                               expr.static_type = expr.left.static_type;
+                       } else if (expr.operator == BinaryOperator.AND
+                                  || expr.operator == BinaryOperator.OR) {
+                               if (expr.left.static_type.type != bool_type.type || expr.right.static_type.type != bool_type.type) {
+                                       Report.error (expr.source_reference, "Operands must be boolean");
+                               }
+
+                               expr.static_type = bool_type;
+                       } else {
+                               assert_not_reached ();
+                       }
                }
 
                public override void visit_type_check (TypeCheck expr) {
+                       if (expr.type_reference.type == null) {
+                               /* if type resolving didn't succeed, skip this check */
+                               return;
+                       }
+               
                        current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
 
-                       expr.static_type = new TypeReference ();
-                       expr.static_type.type = (Type_) root_symbol.lookup ("bool").node;
+                       expr.static_type = bool_type;
                }
        }
 }
index 4806fd1..2108773 100644 (file)
@@ -77,7 +77,7 @@ namespace Vala {
                
                public string get_cheader_filename () {
                        if (cheader_filename == null) {
-                               var basename = filename.ndup (filename.len (-1) - ".vala".len (-1));
+                               var basename = filename.ndup ((uint) (filename.len (-1) - ".vala".len (-1)));
                                cheader_filename = "%s.h".printf (basename);
                        }
                        return cheader_filename;
@@ -87,7 +87,7 @@ namespace Vala {
                
                public string get_csource_filename () {
                        if (csource_filename == null) {
-                               var basename = filename.ndup (filename.len (-1) - ".vala".len (-1));
+                               var basename = filename.ndup ((uint) (filename.len (-1) - ".vala".len (-1)));
                                csource_filename = "%s.c".printf (basename);
                        }
                        return csource_filename;
index c1ffa1f..2551e4b 100644 (file)
@@ -33,7 +33,7 @@ namespace Vala {
                
                public ref string eval () {
                        /* remove quotes */
-                       var noquotes = value.offset (1).ndup (value.len (-1) - 2);
+                       var noquotes = value.offset (1).ndup ((uint) (value.len (-1) - 2));
                        /* unescape string */
                        return noquotes.compress ();
                }
index f7346bd..8ee7cc1 100644 (file)
@@ -32,7 +32,6 @@ namespace Vala {
                public string cname;
                public string lower_case_csuffix;
                bool reference_type;
-               public bool has_private_fields;
                
                public static ref Struct new (string name, SourceReference source) {
                        return (new Struct (name = name, source_reference = source));
@@ -49,9 +48,6 @@ namespace Vala {
                
                public void add_field (Field f) {
                        fields.append (f);
-                       if (f.access == MemberAccessibility.PRIVATE) {
-                               has_private_fields = true;
-                       }
                }
                
                public ref List<Field> get_fields () {
@@ -71,12 +67,6 @@ namespace Vala {
                public override void accept (CodeVisitor visitor) {
                        visitor.visit_begin_struct (this);
                        
-                       visit_children (visitor);
-
-                       visitor.visit_end_struct (this);
-               }
-               
-               public void visit_children (CodeVisitor visitor) {
                        foreach (TypeParameter p in type_parameters) {
                                p.accept (visitor);
                        }
@@ -92,6 +82,8 @@ namespace Vala {
                        foreach (Method m in methods) {
                                m.accept (visitor);
                        }
+
+                       visitor.visit_end_struct (this);
                }
                
                public override string get_cname () {
@@ -116,7 +108,7 @@ namespace Vala {
                        this.lower_case_csuffix = csuffix;
                }
                
-               public ref string get_lower_case_cname (string infix) {
+               public override ref string get_lower_case_cname (string infix) {
                        if (infix == null) {
                                infix = "";
                        }
@@ -133,7 +125,7 @@ namespace Vala {
                
                void process_ccode_attribute (Attribute a) {
                        foreach (NamedArgument arg in a.args) {
-                               if (arg.name.collate ("cname") == 0) {
+                               if (arg.name == "cname") {
                                        /* this will already be checked during semantic analysis */
                                        if (arg.argument is LiteralExpression) {
                                                var lit = ((LiteralExpression) arg.argument).literal;
@@ -141,7 +133,7 @@ namespace Vala {
                                                        set_cname (((StringLiteral) lit).eval ());
                                                }
                                        }
-                               } else if (arg.name.collate ("cheader_filename") == 0) {
+                               } 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;
@@ -158,9 +150,9 @@ namespace Vala {
                
                public void process_attributes () {
                        foreach (Attribute a in attributes) {
-                               if (a.name.collate ("CCode") == 0) {
+                               if (a.name == "CCode") {
                                        process_ccode_attribute (a);
-                               } else if (a.name.collate ("ReferenceType") == 0) {
+                               } else if (a.name == "ReferenceType") {
                                        reference_type = true;
                                }
                        }
index 96e8290..e731a7a 100644 (file)
@@ -54,6 +54,7 @@ namespace Vala {
        
                public override void visit_begin_class (Class cl) {
                        if (cl.@namespace.symbol.lookup (cl.name) != null) {
+                               cl.error = true;
                                Report.error (cl.source_reference, "The namespace `%s' already contains a definition for `%s'".printf (cl.@namespace.symbol.get_full_name (), cl.name));
                                return;
                        }
@@ -64,11 +65,17 @@ namespace Vala {
                }
                
                public override void visit_end_class (Class cl) {
+                       if (cl.error) {
+                               /* skip classes with errors */
+                               return;
+                       }
+                       
                        current_symbol = current_symbol.parent_symbol;
                }
                
                public override void visit_begin_struct (Struct st) {
                        if (st.@namespace.symbol.lookup (st.name) != null) {
+                               st.error = true;
                                Report.error (st.source_reference, "The namespace `%s' already contains a definition for `%s'".printf (st.@namespace.symbol.get_full_name (), st.name));
                                return;
                        }
@@ -79,11 +86,38 @@ namespace Vala {
                }
                
                public override void visit_end_struct (Struct st) {
+                       if (st.error) {
+                               /* skip structs with errors */
+                               return;
+                       }
+                       
+                       current_symbol = current_symbol.parent_symbol;
+               }
+       
+               public override void visit_begin_interface (Interface iface) {
+                       if (iface.@namespace.symbol.lookup (iface.name) != null) {
+                               iface.error = true;
+                               Report.error (iface.source_reference, "The namespace `%s' already contains a definition for `%s'".printf (iface.@namespace.symbol.get_full_name (), iface.name));
+                               return;
+                       }
+                       iface.symbol = new Symbol (node = iface);
+                       iface.@namespace.symbol.add (iface.name, iface.symbol);
+                       
+                       current_symbol = iface.symbol;
+               }
+               
+               public override void visit_end_interface (Interface iface) {
+                       if (iface.error) {
+                               /* skip interfaces with errors */
+                               return;
+                       }
+                       
                        current_symbol = current_symbol.parent_symbol;
                }
                
                public override void visit_begin_enum (Enum en) {
                        if (en.@namespace.symbol.lookup (en.name) != null) {
+                               en.error = true;
                                Report.error (en.source_reference, "The namespace `%s' already contains a definition for `%s'".printf (en.@namespace.symbol.get_full_name (), en.name));
                                return;
                        }
@@ -93,6 +127,11 @@ namespace Vala {
                }
                
                public override void visit_end_enum (Enum en) {
+                       if (en.error) {
+                               /* skip enums with errors */
+                               return;
+                       }
+                       
                        current_symbol = current_symbol.parent_symbol;
                }
 
@@ -103,6 +142,7 @@ namespace Vala {
 
                public override void visit_constant (Constant c) {
                        if (current_symbol.lookup (c.name) != null) {
+                               c.error = true;
                                Report.error (c.source_reference, "The type `%s' already contains a definition for `%s'".printf (current_symbol.get_full_name (), c.name));
                                return;
                        }
@@ -112,6 +152,7 @@ namespace Vala {
                
                public override void visit_field (Field f) {
                        if (current_symbol.lookup (f.name) != null) {
+                               f.error = true;
                                Report.error (f.source_reference, "The type `%s' already contains a definition for `%s'".printf (current_symbol.get_full_name (), f.name));
                                return;
                        }
@@ -121,6 +162,7 @@ namespace Vala {
                
                public override void visit_begin_method (Method m) {
                        if (current_symbol.lookup (m.name) != null) {
+                               m.error = true;
                                Report.error (m.source_reference, "The type `%s' already contains a definition for `%s'".printf (current_symbol.get_full_name (), m.name));
                                return;
                        }
@@ -129,13 +171,18 @@ namespace Vala {
                        current_symbol = m.symbol;
                        
                        if (m.instance) {
-                               var type = new TypeReference ();
-                               type.type = (Type_) m.symbol.parent_symbol.node;
-                               current_symbol.add ("this", new Symbol (node = type));
+                               var decl = new FormalParameter (name = "this", type_reference = new TypeReference ());
+                               decl.type_reference.type = (Type_) m.symbol.parent_symbol.node;
+                               current_symbol.add (decl.name, new Symbol (node = decl));
                        }
                }
                
                public override void visit_end_method (Method m) {
+                       if (m.error) {
+                               /* skip methods with errors */
+                               return;
+                       }
+                       
                        current_symbol = current_symbol.parent_symbol;
                }
 
@@ -148,6 +195,7 @@ namespace Vala {
                
                public override void visit_begin_property (Property prop) {
                        if (current_symbol.lookup (prop.name) != null) {
+                               prop.error = true;
                                Report.error (prop.source_reference, "The type `%s' already contains a definition for `%s'".printf (current_symbol.get_full_name (), prop.name));
                                return;
                        }
@@ -155,12 +203,17 @@ namespace Vala {
                        current_symbol.add (prop.name, prop.symbol);
                        current_symbol = prop.symbol;
                        
-                       var type = new TypeReference ();
-                       type.type = (Type_) prop.symbol.parent_symbol.node;
-                       current_symbol.add ("this", new Symbol (node = type));
+                       var decl = new FormalParameter (name = "this", type_reference = new TypeReference ());
+                       decl.type_reference.type = (Type_) prop.symbol.parent_symbol.node;
+                       current_symbol.add (decl.name, new Symbol (node = decl));
                }
                
                public override void visit_end_property (Property prop) {
+                       if (prop.error) {
+                               /* skip properties with errors */
+                               return;
+                       }
+                       
                        current_symbol = current_symbol.parent_symbol;
                }
                
@@ -170,7 +223,10 @@ namespace Vala {
                        current_symbol = acc.symbol;
 
                        if (acc.writable || acc.construct_) {
-                               current_symbol.add ("value", new Symbol (node = ((Property) current_symbol.parent_symbol.node).type_reference));
+                               var decl = new VariableDeclarator (name = "value");
+                               decl.type_reference = ((Property) current_symbol.parent_symbol.node).type_reference;
+                               
+                               current_symbol.add ("value", new Symbol (node = decl));
                        }
 
                        if (acc.body == null) {
index 18880a9..1378b58 100644 (file)
@@ -64,7 +64,7 @@ namespace Vala {
                                        cl.base_class = type.type;
                                }
                        }
-                       if (cl.base_class == null && (cl.name.collate ("Object") != 0 || cl.@namespace.name.collate ("GLib") != 0)) {
+                       if (cl.base_class == null && (cl.name != "Object" || cl.@namespace.name != "GLib")) {
                                cl.base_class = (Class) root_symbol.lookup ("GLib").lookup ("Object").node;
                        }
                
@@ -88,7 +88,7 @@ namespace Vala {
                }
 
                public override void visit_type_reference (TypeReference type) {
-                       if (type.type_name.collate ("void") == 0) {
+                       if (type.type_name == "void") {
                                return;
                        }
                        
index 6c8e71b..31ba732 100644 (file)
@@ -32,6 +32,7 @@ namespace Vala {
                public abstract string get_cname ();
                public abstract bool is_reference_type ();
                public abstract string get_upper_case_cname (string infix);
+               public abstract string get_lower_case_cname (string infix);
                
                public List<string> cheader_filenames;
                public ref List<string> get_cheader_filenames () {
index edf8dc1..7579246 100644 (file)
@@ -136,5 +136,15 @@ namespace Vala {
                public ref string get_upper_case_cname (string infix) {
                        return type.get_upper_case_cname (infix);
                }
+               
+               public string to_string () {
+                       if (type != null) {
+                               return type.symbol.get_full_name ();
+                       } else if (type_parameter != null) {
+                               return type_parameter.name;
+                       } else {
+                               return "null";
+                       }
+               }
        }
 }
index ac5e55f..9338360 100644 (file)
@@ -140,7 +140,7 @@ public struct string {
        [CCode (cname = "g_strconcat")]
        public ref string concat (string string2, ...);
        [CCode (cname = "g_strndup")]
-       public ref string ndup (int n);
+       public ref string ndup (uint n); /* FIXME: only UTF-8 */
        [CCode (cname = "g_strcompress")]
        public ref string compress ();
        [CCode (cname = "g_strsplit")]
@@ -158,12 +158,12 @@ public struct string {
        [CCode (cname = "g_utf8_prev_char")]
        public string prev_char ();
        [CCode (cname = "g_utf8_strlen")]
-       public long len (long max /*= -1*/);
+       public long len (int max /*= -1*/);
        [CCode (cname = "g_utf8_strchr")]
-       public string chr (long len, unichar c);
+       public string chr (int len, unichar c);
        
        [CCode (cname = "g_utf8_strup")]
-       public ref string up (long len /*= -1*/);
+       public ref string up (int len /*= -1*/);
        [CCode (cname = "g_utf8_collate")]
        public int collate (string str2);
 }
@@ -192,6 +192,7 @@ namespace GLib {
        public struct Error {
        }
        
+       public static void assert_not_reached ();
        public static void return_if_fail (bool expr);
        
        public enum FileTest {