support TYPEOF support typeof expressions, out ref parameters, and enum
authorJürg Billeter <j@bitron.ch>
Sun, 18 Jun 2006 12:01:46 +0000 (12:01 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sun, 18 Jun 2006 12:01:46 +0000 (12:01 +0000)
2006-06-18  Jürg Billeter  <j@bitron.ch>

* vala/scanner.l: support TYPEOF
* vala/parser.y: support typeof expressions, out ref parameters, and
  enum attributes
* vala/valacodevisitor.vala: add visit method for typeof expressions
* vala/valaattributeprocessor.vala: use non-null parameter types,
  support enums and properties
* vala/valasemanticanalyzer.vala: support floating references
* vala/valamemorymanager.vala: ignore signal connections
* vala/valacodegenerator.vala: reset temp variable id at beginning of
  each file, fix out parameters, support properties without accessor
  methods, support floating references, add typeof expression, support
  static signal handlers
* vala/valaclass.vala: use default arguments
* vala/valaenum.vala: support cname, cprefix, and cheader_filename
  attributes
* vala/valaenumvalue.vala: use Enum.get_cprefix ()
* vala/valamethod.vala: support FloatingReference attribute
* vala/valanamespace.vala: use default arguments
* vala/valaproperty.vala: support NoAccessorMethod attribute
* vala/valastruct.vala: support type_id
* vala/valatype.vala: add abstract get_type_id method
* vala/valatypeofexpression.vala
* vala/valatypereference.vala: add floating_reference property, correct
  to_string method signature
* vala/vala.h: update
* vala/Makefile.am: update
* vapi/glib-2.0.vala: add GInitiallyUnowned
* vapi/gtk+-2.0.vala: start of a GTK+ binding
* vapi/pango.vala: start of a Pango binding

svn path=/trunk/; revision=49

23 files changed:
vala/ChangeLog
vala/vala/Makefile.am
vala/vala/parser.y
vala/vala/scanner.l
vala/vala/vala.h
vala/vala/valaattributeprocessor.vala
vala/vala/valaclass.vala
vala/vala/valacodegenerator.vala
vala/vala/valacodevisitor.vala
vala/vala/valaenum.vala
vala/vala/valaenumvalue.vala
vala/vala/valamemorymanager.vala
vala/vala/valamethod.vala
vala/vala/valanamespace.vala
vala/vala/valaproperty.vala
vala/vala/valasemanticanalyzer.vala
vala/vala/valastruct.vala
vala/vala/valatype.vala
vala/vala/valatypeofexpression.vala [new file with mode: 0644]
vala/vala/valatypereference.vala
vala/vapi/glib-2.0.vala
vala/vapi/gtk+-2.0.vala [new file with mode: 0644]
vala/vapi/pango.vala [new file with mode: 0644]

index db9e839..930b033 100644 (file)
@@ -1,3 +1,35 @@
+2006-06-18  Jürg Billeter  <j@bitron.ch>
+
+       * vala/scanner.l: support TYPEOF
+       * vala/parser.y: support typeof expressions, out ref parameters, and
+         enum attributes
+       * vala/valacodevisitor.vala: add visit method for typeof expressions
+       * vala/valaattributeprocessor.vala: use non-null parameter types,
+         support enums and properties
+       * vala/valasemanticanalyzer.vala: support floating references
+       * vala/valamemorymanager.vala: ignore signal connections
+       * vala/valacodegenerator.vala: reset temp variable id at beginning of
+         each file, fix out parameters, support properties without accessor
+         methods, support floating references, add typeof expression, support
+         static signal handlers
+       * vala/valaclass.vala: use default arguments
+       * vala/valaenum.vala: support cname, cprefix, and cheader_filename
+         attributes
+       * vala/valaenumvalue.vala: use Enum.get_cprefix ()
+       * vala/valamethod.vala: support FloatingReference attribute
+       * vala/valanamespace.vala: use default arguments
+       * vala/valaproperty.vala: support NoAccessorMethod attribute
+       * vala/valastruct.vala: support type_id
+       * vala/valatype.vala: add abstract get_type_id method
+       * vala/valatypeofexpression.vala
+       * vala/valatypereference.vala: add floating_reference property, correct
+         to_string method signature
+       * vala/vala.h: update
+       * vala/Makefile.am: update
+       * vapi/glib-2.0.vala: add GInitiallyUnowned
+       * vapi/gtk+-2.0.vala: start of a GTK+ binding
+       * vapi/pango.vala: start of a Pango binding
+
 2006-06-17  Jürg Billeter  <j@bitron.ch>
 
        * vala/scanner.l: don't leak comment texts, support generic types with
index ff9da79..53388cf 100644 (file)
@@ -242,6 +242,9 @@ libvala_la_SOURCES = \
        valatypecheck.c \
        valatypecheck.h \
        valatypecheck.vala \
+       valatypeofexpression.c \
+       valatypeofexpression.h \
+       valatypeofexpression.vala \
        valatypeparameter.c \
        valatypeparameter.h \
        valatypeparameter.vala \
index 3673c22..39b9ad7 100644 (file)
@@ -174,6 +174,7 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %token STRUCT "struct"
 %token RETURN "return"
 %token VALA_TRUE "true"
+%token TYPEOF "typeof"
 %token USING "using"
 %token VAR "var"
 %token VIRTUAL "virtual"
@@ -203,6 +204,7 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %type <expression> post_increment_expression
 %type <expression> post_decrement_expression
 %type <expression> object_creation_expression
+%type <expression> typeof_expression
 %type <expression> unary_expression
 %type <expression> cast_expression
 %type <expression> multiplicative_expression
@@ -438,6 +440,15 @@ type
                        vala_type_reference_set_non_null ($$, TRUE);
                }
          }
+       | OUT REF type_name opt_op_neg
+         {
+               $$ = $3;
+               vala_type_reference_set_is_ref ($$, TRUE);
+               vala_type_reference_set_is_out ($$, TRUE);
+               if ($4) {
+                       vala_type_reference_set_non_null ($$, TRUE);
+               }
+         }
        | type array_qualifier
          {
                $$ = $1;
@@ -487,6 +498,7 @@ primary_expression
        | post_increment_expression
        | post_decrement_expression
        | object_creation_expression
+       | typeof_expression
        ;
 
 simple_name
@@ -574,6 +586,15 @@ object_creation_expression
          }
        ;
 
+typeof_expression
+       : TYPEOF OPEN_PARENS type_name CLOSE_PARENS
+         {
+               ValaSourceReference *src = src(@1);
+               $$ = VALA_EXPRESSION (vala_typeof_expression_new ($3, src));
+               g_object_unref ($3);
+               g_object_unref (src);
+         }
+
 unary_expression
        : primary_expression
        | PLUS unary_expression
@@ -1710,6 +1731,11 @@ fixed_parameters
 fixed_parameter
        : opt_attributes type IDENTIFIER
          {
+               if (vala_type_reference_get_is_ref ($2) && vala_type_reference_get_is_out ($2)) {
+                       vala_type_reference_set_is_lvalue_ref ($2, TRUE);
+                       vala_type_reference_set_is_ref ($2, FALSE);
+               }
+
                ValaSourceReference *src = src(@2);
                $$ = vala_formal_parameter_new ($3, $2, src);
                g_object_unref (src);
@@ -1718,6 +1744,11 @@ fixed_parameter
          }
        | opt_attributes type IDENTIFIER ASSIGN expression
          {
+               if (vala_type_reference_get_is_ref ($2) && vala_type_reference_get_is_out ($2)) {
+                       vala_type_reference_set_is_lvalue_ref ($2, TRUE);
+                       vala_type_reference_set_is_ref ($2, FALSE);
+               }
+
                ValaSourceReference *src = src(@2);
                $$ = vala_formal_parameter_new ($3, $2, src);
                g_object_unref (src);
@@ -1747,6 +1778,8 @@ property_declaration
                $$ = vala_property_new ($6, $5, $8, $9, src);
                g_object_unref (src);
 
+               VALA_CODE_NODE($$)->attributes = $2;
+
                g_object_unref ($5);
                g_free ($6);
                g_object_unref ($8);
@@ -2112,6 +2145,9 @@ enum_declaration
                ValaSourceReference *src = src_com(@5, $1);
                $$ = vala_enum_new ($5, src);
                g_object_unref (src);
+
+               VALA_CODE_NODE($$)->attributes = $2;
+
                if ($3 != 0) {
                        VALA_TYPE_($$)->access = $3;
                }
index febff4b..c3fd708 100644 (file)
@@ -143,6 +143,7 @@ literal                     ({literal_integer}|{literal_real}|{literal_character}|{literal_string}
 "struct"       { uploc; return STRUCT; }
 "return"       { uploc; return RETURN; }
 "true"         { uploc; return VALA_TRUE; }
+"typeof"       { uploc; return TYPEOF; }
 "using"                { uploc; return USING; }
 "var"          { uploc; return VAR; }
 "virtual"      { uploc; return VIRTUAL; }
index d9d8fba..009001c 100644 (file)
@@ -52,6 +52,7 @@
 #include <vala/valastringliteral.h>
 #include <vala/valastruct.h>
 #include <vala/valatypecheck.h>
+#include <vala/valatypeofexpression.h>
 #include <vala/valatypeparameter.h>
 #include <vala/valatypereference.h>
 #include <vala/valaunaryexpression.h>
index ebda038..6bcec09 100644 (file)
@@ -24,27 +24,35 @@ using GLib;
 
 namespace Vala {
        public class AttributeProcessor : CodeVisitor {
-               public void process (CodeContext context) {
+               public void process (CodeContext! context) {
                        context.accept (this);
                }
 
-               public override void visit_begin_namespace (Namespace ns) {
+               public override void visit_begin_namespace (Namespace! ns) {
                        ns.process_attributes ();
                }
        
-               public override void visit_begin_struct (Struct st) {
+               public override void visit_begin_struct (Struct! st) {
                        st.process_attributes ();
                }
        
-               public override void visit_begin_class (Class cl) {
+               public override void visit_begin_class (Class! cl) {
                        cl.process_attributes ();
                }
        
-               public override void visit_begin_method (Method m) {
+               public override void visit_begin_enum (Enum! en) {
+                       en.process_attributes ();
+               }
+       
+               public override void visit_begin_method (Method! m) {
                        m.process_attributes ();
                }
+
+               public override void visit_begin_property (Property! prop) {
+                       prop.process_attributes ();
+               }
        
-               public override void visit_field (Field f) {
+               public override void visit_field (Field! f) {
                        f.process_attributes ();
                }
        }
index 31c7b18..18486cf 100644 (file)
@@ -196,7 +196,7 @@ namespace Vala {
                                                var lit = ((LiteralExpression) arg.argument).literal;
                                                if (lit is StringLiteral) {
                                                        var val = ((StringLiteral) lit).eval ();
-                                                       foreach (string filename in val.split (",", 0)) {
+                                                       foreach (string filename in val.split (",")) {
                                                                cheader_filenames.append (filename);
                                                        }
                                                }
index 085914f..9e62282 100644 (file)
@@ -75,6 +75,8 @@ namespace Vala {
                        source_type_member_declaration = new CCodeFragment ();
                        source_type_member_definition = new CCodeFragment ();
                        
+                       next_temp_var_id = 0;
+                       
                        header_begin.append (new CCodeIncludeDirective (filename = "glib.h"));
                        source_include_directives.append (new CCodeIncludeDirective (filename = source_file.get_cheader_filename ()));
                        
@@ -754,7 +756,7 @@ namespace Vala {
                                        }
                                        foreach (FormalParameter param in m.parameters) {
                                                var t = param.type_reference.type;
-                                               if (t != null && (t is Class || t is Interface)) {
+                                               if (t != null && (t is Class || t is Interface) && !param.type_reference.is_out) {
                                                        cinit.append (create_type_check_statement (m, t, param.type_reference.non_null, param.name));
                                                }
                                        }
@@ -1016,7 +1018,9 @@ namespace Vala {
                
                private ref VariableDeclarator get_temp_variable_declarator (TypeReference! type) {
                        var decl = new VariableDeclarator (name = "__temp%d".printf (next_temp_var_id));
-                       decl.type_reference = type;
+                       decl.type_reference = type.copy ();
+                       decl.type_reference.is_ref = false;
+                       decl.type_reference.is_out = false;
                        
                        next_temp_var_id++;
                        
@@ -1298,19 +1302,24 @@ namespace Vala {
                        stmt.ccodenode = cfrag;
                }
                
-               private void append_local_free_expr (Symbol sym, CCodeCommaExpression ccomma, bool stop_at_loop) {
+               private bool append_local_free_expr (Symbol sym, CCodeCommaExpression ccomma, bool stop_at_loop) {
+                       var found = false;
+               
                        var b = (Block) sym.node;
 
                        var local_vars = b.get_local_variables ();
                        foreach (VariableDeclarator decl in local_vars) {
                                if (decl.symbol.active && decl.type_reference.type.is_reference_type () && decl.type_reference.is_lvalue_ref) {
+                                       found = true;
                                        ccomma.inner.append (get_unref_expression (new CCodeIdentifier (name = decl.name), decl.type_reference));
                                }
                        }
                        
                        if (sym.parent_symbol.node is Block) {
-                               append_local_free_expr (sym.parent_symbol, ccomma, stop_at_loop);
+                               found = found || append_local_free_expr (sym.parent_symbol, ccomma, stop_at_loop);
                        }
+                       
+                       return found;
                }
 
                private void create_local_free_expr (Expression expr) {
@@ -1319,15 +1328,19 @@ namespace Vala {
                        }
                        
                        var return_expr_decl = get_temp_variable_declarator (expr.static_type);
-                       expr.temp_vars.append (return_expr_decl);
                        
                        var ccomma = new CCodeCommaExpression ();
                        ccomma.inner.append (new CCodeAssignment (left = new CCodeIdentifier (name = return_expr_decl.name), right = expr.ccodenode));
 
-                       append_local_free_expr (current_symbol, ccomma, false);
+                       if (!append_local_free_expr (current_symbol, ccomma, false)) {
+                               /* no local variables need to be freed */
+                               return;
+                       }
 
                        ccomma.inner.append (new CCodeIdentifier (name = return_expr_decl.name));
+                       
                        expr.ccodenode = ccomma;
+                       expr.temp_vars.append (return_expr_decl);
                }
 
                public override void visit_return_statement (ReturnStatement! stmt) {
@@ -1425,7 +1438,11 @@ namespace Vala {
                                ref CCodeExpression typed_pub_inst = pub_inst;
 
                                /* cast if necessary */
-                               if (prop.symbol.parent_symbol.node != base_type) {
+                               if (prop.no_accessor_method) {
+                                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = "G_OBJECT"));
+                                       ccast.add_argument (pub_inst);
+                                       typed_pub_inst = ccast;
+                               } else if (prop.symbol.parent_symbol.node != base_type) {
                                        var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((Type_) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
                                        ccast.add_argument (pub_inst);
                                        typed_pub_inst = ccast;
@@ -1444,7 +1461,11 @@ namespace Vala {
                                if (p.name == "this") {
                                        expr.ccodenode = pub_inst;
                                } else {
-                                       expr.ccodenode = new CCodeIdentifier (name = p.name);
+                                       if (p.type_reference.is_out || p.type_reference.is_ref) {
+                                               expr.ccodenode = new CCodeIdentifier (name = "*%s".printf (p.name));
+                                       } else {
+                                               expr.ccodenode = new CCodeIdentifier (name = p.name);
+                                       }
                                }
                        }
                }
@@ -1619,6 +1640,18 @@ namespace Vala {
                }
                
                private void visit_expression (Expression! expr) {
+                       if (expr.static_type != null &&
+                           expr.static_type.is_ref &&
+                           expr.static_type.floating_reference) {
+                               /* constructor of GInitiallyUnowned subtype
+                                * returns floating reference, sink it
+                                */
+                               var csink = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_object_ref_sink"));
+                               csink.add_argument ((CCodeExpression) expr.ccodenode);
+                               
+                               expr.ccodenode = csink;
+                       }
+               
                        if (expr.ref_leaked) {
                                var decl = get_temp_variable_declarator (expr.static_type);
                                temp_vars.prepend (decl);
@@ -1645,6 +1678,10 @@ namespace Vala {
                        visit_expression (expr);
                }
 
+               public override void visit_typeof_expression (TypeofExpression! expr) {
+                       expr.ccodenode = new CCodeIdentifier (name = expr.type_reference.type.get_type_id ());
+               }
+
                public override void visit_unary_expression (UnaryExpression! expr) {
                        CCodeUnaryOperator op;
                        if (expr.operator == UnaryOperator.PLUS) {
@@ -1691,7 +1728,16 @@ namespace Vala {
                        if (a.left.symbol_reference.node is Property) {
                                var prop = (Property) a.left.symbol_reference.node;
                                var cl = (Class) prop.symbol.parent_symbol.node;
-                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name)));
+
+                               var set_func = "g_object_set";
+                               
+                               if (!prop.no_accessor_method) {
+                                       set_func = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
+                               }
+                               
+                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = set_func));
+
+                               /* target instance is first argument */
                                if (a.left is MemberAccess) {
                                        var expr = (MemberAccess) a.left;
                                        ccall.add_argument ((CCodeExpression) expr.inner.ccodenode);
@@ -1701,13 +1747,39 @@ namespace Vala {
                                        Report.error (a.source_reference, "unexpected lvalue in assignment");
                                        return;
                                }
-                               ccall.add_argument ((CCodeExpression) a.right.ccodenode);
+                                       
+                               ref CCodeExpression cexpr = (CCodeExpression) a.right.ccodenode;
+                               
+                               if (prop.no_accessor_method) {
+                                       /* property name is second argument of g_object_set */
+                                       ccall.add_argument (prop.get_canonical_cconstant ());
+                               } else if (prop.type_reference.type != null
+                                   && prop.type_reference.type.is_reference_type ()
+                                   && a.right.static_type.type != null
+                                   && prop.type_reference.type != a.right.static_type.type) {
+                                       /* cast is necessary */
+                                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = prop.type_reference.type.get_upper_case_cname (null)));
+                                       ccast.add_argument (cexpr);
+                                       cexpr = ccast;
+                               }
+                                       
+                               ccall.add_argument (cexpr);
+                               
+                               if (prop.no_accessor_method) {
+                                       ccall.add_argument (new CCodeConstant (name = "NULL"));
+                               }
+                               
                                a.ccodenode = ccall;
                        } else if (a.left.symbol_reference.node is Signal) {
                                var sig = (Signal) a.left.symbol_reference.node;
-                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_signal_connect_object"));
                                
                                var m = (Method) a.right.symbol_reference.node;
+                               var connect_func = "g_signal_connect_object";
+                               if (!m.instance) {
+                                       connect_func = "g_signal_connect";
+                               }
+
+                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = connect_func));
                        
                                if (a.left is MemberAccess) {
                                        var expr = (MemberAccess) a.left;
@@ -1723,17 +1795,21 @@ namespace Vala {
 
                                ccall.add_argument (new CCodeIdentifier (name = m.get_cname ()));
 
-                               if (a.right is MemberAccess) {
-                                       var expr = (MemberAccess) a.right;
-                                       ccall.add_argument ((CCodeExpression) expr.inner.ccodenode);
-                               } else if (a.right is SimpleName) {
-                                       ccall.add_argument (new CCodeIdentifier (name = "self"));
+                               if (m.instance) {
+                                       if (a.right is MemberAccess) {
+                                               var expr = (MemberAccess) a.right;
+                                               ccall.add_argument ((CCodeExpression) expr.inner.ccodenode);
+                                       } else if (a.right is SimpleName) {
+                                               ccall.add_argument (new CCodeIdentifier (name = "self"));
+                                       } else {
+                                               Report.error (a.source_reference, "unsupported expression for signal handler");
+                                               return;
+                                       }
+
+                                       ccall.add_argument (new CCodeConstant (name = "G_CONNECT_SWAPPED"));
                                } else {
-                                       Report.error (a.source_reference, "unsupported expression for signal handler");
-                                       return;
+                                       ccall.add_argument (new CCodeConstant (name = "NULL"));
                                }
-
-                               ccall.add_argument (new CCodeConstant (name = "G_CONNECT_SWAPPED"));
                                
                                a.ccodenode = ccall;
                        } else {
index bbcbeb4..7e568e8 100644 (file)
@@ -216,6 +216,9 @@ namespace Vala {
                public virtual void visit_object_creation_expression (ObjectCreationExpression! expr) {
                }
 
+               public virtual void visit_typeof_expression (TypeofExpression! expr) {
+               }
+
                public virtual void visit_unary_expression (UnaryExpression! expr) {
                }
 
index e19a221..1b58c49 100644 (file)
@@ -59,5 +59,62 @@ namespace Vala {
                public override bool is_reference_type () {
                        return false;
                }
+               
+               public void set_cname (string! cname) {
+                       this.cname = cname;
+               }
+               
+               string cprefix;
+               public string get_cprefix () {
+                       if (cprefix == null) {
+                               cprefix = "%s_".printf (get_upper_case_cname (null));
+                       }
+                       return cprefix;
+               }
+               
+               public void set_cprefix (string! cprefix) {
+                       this.cprefix = cprefix;
+               }
+               
+               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 == "cprefix") {
+                                       /* this will already be checked during semantic analysis */
+                                       if (arg.argument is LiteralExpression) {
+                                               var lit = ((LiteralExpression) arg.argument).literal;
+                                               if (lit is StringLiteral) {
+                                                       set_cprefix (((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 5f40a6f..ef0b606 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 (null), name);
+                               cname = "%s%s".printf (en.get_cprefix (), name);
                        }
                        return cname;
                }
index 4217850..0d2cf7d 100644 (file)
@@ -138,10 +138,13 @@ namespace Vala {
                }
 
                public override void visit_assignment (Assignment! a) {
-                       if (a.left.static_type.is_lvalue_ref) {
-                               visit_possibly_missing_copy_expression (a.right);
+                       if (a.left.symbol_reference.node is Signal) {
                        } else {
-                               visit_possibly_leaked_expression (a.right);
+                               if (a.left.static_type.is_lvalue_ref) {
+                                       visit_possibly_missing_copy_expression (a.right);
+                               } else {
+                                       visit_possibly_leaked_expression (a.right);
+                               }
                        }
                }
        }
index a432afd..f8a7a14 100644 (file)
@@ -128,6 +128,8 @@ namespace Vala {
                                        returns_modified_pointer = true;
                                } else if (a.name == "InstanceLast") {
                                        instance_last = true;
+                               } else if (a.name == "FloatingReference") {
+                                       return_type.floating_reference = true;
                                }
                        }
                }
index b11fa50..56a8a6f 100644 (file)
@@ -225,7 +225,7 @@ namespace Vala {
                                                var lit = ((LiteralExpression) arg.argument).literal;
                                                if (lit is StringLiteral) {
                                                        var val = ((StringLiteral) lit).eval ();
-                                                       foreach (string filename in val.split (",", 0)) {
+                                                       foreach (string filename in val.split (",")) {
                                                                cheader_filenames.append (filename);
                                                        }
                                                }
index 921a836..60a1e74 100644 (file)
@@ -31,6 +31,7 @@ namespace Vala {
                public SourceReference source_reference { get; construct; }
                public MemberAccessibility access;
                public FormalParameter this_parameter;
+               public bool no_accessor_method;
                
                public static ref Property new (string name, TypeReference type, PropertyAccessor get_accessor, PropertyAccessor set_accessor, SourceReference source) {
                        return (new Property (name = name, type_reference = type, get_accessor = get_accessor, set_accessor = set_accessor, source_reference = source));
@@ -75,5 +76,13 @@ namespace Vala {
                        
                        return new CCodeConstant (name = str.str);
                }
+               
+               public void process_attributes () {
+                       foreach (Attribute a in attributes) {
+                               if (a.name == "NoAccessorMethod") {
+                                       no_accessor_method = true;
+                               }
+                       }
+               }
        }
 }
index cf4e586..e2b044c 100644 (file)
@@ -34,6 +34,7 @@ namespace Vala {
                
                TypeReference bool_type;
                TypeReference string_type;
+               Type_ initially_unowned_type;
                
                public void analyze (CodeContext context) {
                        root_symbol = context.root;
@@ -43,6 +44,10 @@ namespace Vala {
 
                        string_type = new TypeReference ();
                        string_type.type = (Type_) root_symbol.lookup ("string").node;
+                       
+                       var glib_ns = root_symbol.lookup ("GLib");
+                       
+                       initially_unowned_type = (Type_) glib_ns.lookup ("InitiallyUnowned").node;
 
                        current_symbol = root_symbol;
                        context.accept (this);
@@ -384,6 +389,7 @@ namespace Vala {
                        if (expression_type.type == null &&
                            (expected_type.type_parameter != null ||
                             expected_type.type.is_reference_type () ||
+                            expected_type.is_ref ||
                             expected_type.array)) {
                                return true;
                        }
@@ -406,6 +412,11 @@ namespace Vala {
                                return true;
                        }
                        
+                       /* int may be implicitly casted to uint */
+                       if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("uint").node) {
+                               return true;
+                       }
+                       
                        /* int may be implicitly casted to double */
                        if (expression_type.type == root_symbol.lookup ("int").node && expected_type.type == root_symbol.lookup ("double").node) {
                                return true;
@@ -467,7 +478,7 @@ namespace Vala {
                                        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 ()));
+                                               Report.error (expr.source_reference, "Argument %d: Cannot convert from `%s' to `%s'".printf (i + 1, arg.static_type.to_string (), param.type_reference.to_string ()));
                                                return;
                                        }
                                        
@@ -491,8 +502,18 @@ namespace Vala {
                
                        current_source_file.add_symbol_dependency (expr.type_reference.type.symbol, SourceFileDependencyType.SOURCE);
 
-                       expr.static_type = expr.type_reference;
+                       expr.static_type = expr.type_reference.copy ();
                        expr.static_type.is_ref = true;
+                       
+                       var cl = (Class) expr.type_reference.type;
+                       while (cl != null) {
+                               if (cl == initially_unowned_type) {
+                                       expr.static_type.floating_reference = true;
+                                       break;
+                               }
+                       
+                               cl = cl.base_class;
+                       }
                }
 
                public override void visit_unary_expression (UnaryExpression! expr) {
index 007cfb2..fb79558 100644 (file)
@@ -32,6 +32,7 @@ namespace Vala {
                public string cname;
                public string ref_function;
                public string free_function;
+               public string type_id;
                public string lower_case_csuffix;
                bool reference_type;
                
@@ -169,6 +170,14 @@ namespace Vala {
                                                        set_free_function (((StringLiteral) lit).eval ());
                                                }
                                        }
+                               } else if (arg.name == "type_id") {
+                                       /* this will already be checked during semantic analysis */
+                                       if (arg.argument is LiteralExpression) {
+                                               var lit = ((LiteralExpression) arg.argument).literal;
+                                               if (lit is StringLiteral) {
+                                                       set_type_id (((StringLiteral) lit).eval ());
+                                               }
+                                       }
                                }
                        }
                }
@@ -208,5 +217,16 @@ namespace Vala {
                public void set_free_function (string! name) {
                        this.free_function = name;
                }
+               
+               public override string get_type_id () {
+                       if (type_id == null) {
+                               Report.error (source_reference, "The type `%s` doesn't declare a type id".printf (symbol.get_full_name ()));
+                       }
+                       return type_id;
+               }
+               
+               public void set_type_id (string! name) {
+                       this.type_id = name;
+               }
        }
 }
index 2ffd65a..19271c3 100644 (file)
@@ -34,6 +34,7 @@ namespace Vala {
                public abstract bool is_reference_counting ();
                public abstract string get_ref_function ();
                public abstract string get_free_function ();
+               public abstract string get_type_id ();
                
                public abstract ref string get_upper_case_cname (string infix);
                public abstract ref string get_lower_case_cname (string infix);
diff --git a/vala/vala/valatypeofexpression.vala b/vala/vala/valatypeofexpression.vala
new file mode 100644 (file)
index 0000000..100a64d
--- /dev/null
@@ -0,0 +1,39 @@
+/* valatypeofexpression.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 TypeofExpression : Expression {
+               public TypeReference type_reference { get; construct; }
+
+               public static ref TypeofExpression new (TypeReference type, SourceReference source) {
+                       return (new TypeofExpression (type_reference = type, source_reference = source));
+               }
+               
+               public override void accept (CodeVisitor visitor) {
+                       type_reference.accept (visitor);
+               
+                       visitor.visit_typeof_expression (this);
+               }
+       }
+}
index 09ec24d..65ff408 100644 (file)
@@ -36,6 +36,7 @@ namespace Vala {
                public bool non_null { get; set; }
                public weak Type_ type;
                public TypeParameter type_parameter;
+               public bool floating_reference { get; set; }
 
                List<TypeReference> type_argument_list;
 
@@ -127,7 +128,7 @@ namespace Vala {
                        return type.get_upper_case_cname (infix);
                }
                
-               public string to_string () {
+               public ref string to_string () {
                        if (type != null) {
                                return type.symbol.get_full_name ();
                        } else if (type_parameter != null) {
index 463949d..6ac45ab 100644 (file)
@@ -112,7 +112,7 @@ public struct unichar {
        public unichar tolower ();
 }
 
-[ReferenceType (ref_function = "g_strdup", free_function = "g_free")]
+[ReferenceType (ref_function = "g_strdup", free_function = "g_free", type_id = "G_TYPE_STRING")]
 [CCode (cname = "char", cheader_filename = "string.h,glib.h")]
 public struct string {
        [CCode (cname = "g_str_has_suffix")]
@@ -187,6 +187,9 @@ namespace GLib {
        public abstract class Object {
                public virtual Object constructor (Type type, uint n_construct_properties, ObjectConstructParam[] construct_properties);
        }
+       
+       public abstract class InitiallyUnowned : Object {
+       }
 
        [ReferenceType ()]
        public struct Error {
diff --git a/vala/vapi/gtk+-2.0.vala b/vala/vapi/gtk+-2.0.vala
new file mode 100644 (file)
index 0000000..b518868
--- /dev/null
@@ -0,0 +1,213 @@
+/* gtk+-2.0.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>
+ */
+
+[CCode (cheader_filename = "gtk/gtk.h")]
+namespace Gtk {
+       public static void init (ref int argc, out string[] argv);
+       public static void main ();
+       public static void main_quit ();
+       
+       [CCode (cprefix = "GTK_WINDOW_")]
+       public enum WindowType {
+               TOPLEVEL,
+               POPUP
+       }
+       
+       public class Dialog : Window {
+               [FloatingReference ()]
+               public static ref Widget new ();
+               [FloatingReference ()]
+               public static ref Widget new_with_buttons (string title, Window parent, DialogFlags @flags, string first_button_text, ...);
+               public int run ();
+               public void response (int response_id);
+               public Widget add_button (string button_text, int response_id);
+               public void add_buttons (string first_button_text, ...);
+       }
+       
+       public enum DialogFlags {
+               MODAL,
+               DESTROY_WITH_PARENT,
+               NO_SEPARATOR
+       }
+       
+       public class MessageDialog : Dialog {
+               [FloatingReference ()]
+               public static ref Widget new (Window parent, DialogFlags @flags, MessageType type, ButtonsType buttons, string message_format, ...);
+       }
+
+       public enum MessageType {
+               INFO,
+               WARNING,
+               QUESTION,
+               ERROR
+       }
+       
+       public enum ButtonsType {
+               NONE,
+               OK,
+               CLOSE,
+               CANCEL,
+               YES_NO,
+               OK_CANCEL
+       }
+       
+       public class Window : Container {
+               public string title { get; set construct; }
+               public WindowType type { get; construct; }
+       
+               public void set_title (string title);
+       }
+       
+       public class Label : Misc {
+               public string label { get; set; }
+               public bool use_markup { get; set; }
+       }
+       
+       public class Button : Container {
+               [FloatingReference ()]
+               public static ref Button new_with_label (string label);
+               
+               public string label { get; construct; }
+               
+               public signal void activate ();
+               public signal void clicked ();
+               public signal void enter ();
+       }
+       
+       public class Entry : Widget {
+               [FloatingReference ()]
+               public static ref Entry new ();
+       }
+       
+       public class TextBuffer {
+       }
+       
+       public class TextView : Container {
+       }
+       
+       public interface TreeModel {
+       }
+       
+       public struct TreeIter {
+               public int stamp;
+               public pointer user_data;
+               public pointer user_data2;
+               public pointer user_data3;
+       }
+       
+       public class TreeViewColumn : Object {
+               [FloatingReference ()]
+               public static ref TreeViewColumn new_with_attributes (string title, CellRenderer cell, ...);
+       }
+       
+       public class TreeView : Container {
+               public TreeModel model { get; set; }
+               
+               public int append_column (TreeViewColumn column);
+       }
+       
+       public abstract class CellRenderer : Object {
+       }
+       
+       public class CellRendererText : CellRenderer {
+               [NoAccessorMethod ()]
+               public Pango.Style style { get; set; }
+       }
+       
+       public class TreeStore : TreeModel {
+               public static ref TreeStore new (int n_columns, ...);
+               public void @set (ref TreeIter iter, ...);
+               public void append (ref TreeIter iter, ref TreeIter parent);
+       }
+       
+       public class Menu : MenuShell {
+               [FloatingReference ()]
+               public static ref Menu new ();
+       }
+       
+       public class MenuBar : MenuShell {
+               [FloatingReference ()]
+               public static ref MenuBar new ();
+       }
+       
+       public class MenuItem : Item {
+               [FloatingReference ()]
+               public static ref MenuItem new_with_label (string label);
+               public void set_submenu (Menu submenu);
+       }
+       
+       public abstract class MenuShell : Container {
+               public void append (MenuItem child);
+       }
+       
+       public class Toolbar : Container {
+               [FloatingReference ()]
+               public static ref Toolbar new ();
+       }
+       
+       public class HBox : Box {
+               [FloatingReference ()]
+               public static ref HBox new (bool homogeneous, int spacing);
+       }
+       
+       public class VBox : Box {
+               [FloatingReference ()]
+               public static ref VBox new (bool homogeneous, int spacing);
+       }
+       
+       public class Notebook : Container {
+               public int append_page (Widget child, Widget tab_label);
+       }
+       
+       public class ScrolledWindow : Bin {
+       }
+       
+       public abstract class Bin : Container {
+       }
+       
+       public abstract class Box : Container {
+               public bool homogeneous { get; set; }
+               public int spacing { get; set; }
+       
+               public void pack_start (Widget child, bool expand, bool fill, uint padding);
+               public void pack_start_defaults (Widget widget);
+       }
+       
+       public abstract class Container : Widget {
+               public void add (Widget w);
+       }
+       
+       public abstract class Item : Bin {
+       }
+       
+       public abstract class Misc : Widget {
+       }
+       
+       public abstract class Object : GLib.InitiallyUnowned {
+               public signal void destroy ();
+       }
+       
+       public abstract class Widget : Object {
+               public void show ();
+               public void show_all ();
+       }
+}
diff --git a/vala/vapi/pango.vala b/vala/vapi/pango.vala
new file mode 100644 (file)
index 0000000..9638e26
--- /dev/null
@@ -0,0 +1,30 @@
+/* pango.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>
+ */
+
+[CCode (cheader_filename = "pango/pango.h")]
+namespace Pango {
+       public enum Style {
+               NORMAL,
+               OBLIQUE,
+               ITALIC
+       }
+}