move unresolved type information from DataType into new UnresolvedType
authorJuerg Billeter <j@bitron.ch>
Sun, 2 Dec 2007 22:21:56 +0000 (22:21 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sun, 2 Dec 2007 22:21:56 +0000 (22:21 +0000)
2007-12-02  Juerg Billeter  <j@bitron.ch>

* vala/Makefile.am, vala/parser.y, vala/vala.h,
  vala/valaarraycreationexpression.vala, vala/valacallback.vala,
  vala/valacastexpression.vala, vala/valacatchclause.vala,
  vala/valaclass.vala, vala/valacodenode.vala,
  vala/valacodevisitor.vala, vala/valaconstant.vala,
  vala/valadatatype.vala, vala/valafield.vala,
  vala/valaforeachstatement.vala, vala/valaformalparameter.vala,
  vala/valainterface.vala, vala/valainterfacewriter.vala,
  vala/valalocalvariabledeclaration.vala, vala/valamemberaccess.vala,
  vala/valamemorymanager.vala, vala/valamethod.vala,
  vala/valaobjectcreationexpression.vala, vala/valaproperty.vala,
  vala/valasignal.vala, vala/valastruct.vala,
  vala/valasymbolresolver.vala, vala/valatypecheck.vala,
  vala/valaunresolvedtype.vala, vala/valavariabledeclarator.vala,
  gobject/valaccodegenerator.vala, vapigen/valagidlparser.vala: move
  unresolved type information from DataType into new UnresolvedType
  class, replace UnresolvedType instance by resolved DataType in
  SymbolResolver

svn path=/trunk/; revision=749

33 files changed:
ChangeLog
gobject/valaccodegenerator.vala
tests/Makefile.am
vala/Makefile.am
vala/parser.y
vala/vala.h
vala/valaarraycreationexpression.vala
vala/valacallback.vala
vala/valacastexpression.vala
vala/valacatchclause.vala
vala/valaclass.vala
vala/valacodenode.vala
vala/valacodevisitor.vala
vala/valaconstant.vala
vala/valadatatype.vala
vala/valafield.vala
vala/valaforeachstatement.vala
vala/valaformalparameter.vala
vala/valainterface.vala
vala/valainterfacewriter.vala
vala/valalocalvariabledeclaration.vala
vala/valamemberaccess.vala
vala/valamemorymanager.vala
vala/valamethod.vala
vala/valaobjectcreationexpression.vala
vala/valaproperty.vala
vala/valasignal.vala
vala/valastruct.vala
vala/valasymbolresolver.vala
vala/valatypecheck.vala
vala/valaunresolvedtype.vala [new file with mode: 0644]
vala/valavariabledeclarator.vala
vapigen/valagidlparser.vala

index 099df45..528bd74 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
 2007-12-02  Jürg Billeter  <j@bitron.ch>
 
+       * vala/Makefile.am, vala/parser.y, vala/vala.h,
+         vala/valaarraycreationexpression.vala, vala/valacallback.vala,
+         vala/valacastexpression.vala, vala/valacatchclause.vala,
+         vala/valaclass.vala, vala/valacodenode.vala,
+         vala/valacodevisitor.vala, vala/valaconstant.vala,
+         vala/valadatatype.vala, vala/valafield.vala,
+         vala/valaforeachstatement.vala, vala/valaformalparameter.vala,
+         vala/valainterface.vala, vala/valainterfacewriter.vala,
+         vala/valalocalvariabledeclaration.vala, vala/valamemberaccess.vala,
+         vala/valamemorymanager.vala, vala/valamethod.vala,
+         vala/valaobjectcreationexpression.vala, vala/valaproperty.vala,
+         vala/valasignal.vala, vala/valastruct.vala,
+         vala/valasymbolresolver.vala, vala/valatypecheck.vala,
+         vala/valaunresolvedtype.vala, vala/valavariabledeclarator.vala,
+         gobject/valaccodegenerator.vala, vapigen/valagidlparser.vala: move
+         unresolved type information from DataType into new UnresolvedType
+         class, replace UnresolvedType instance by resolved DataType in
+         SymbolResolver
+
+2007-12-02  Jürg Billeter  <j@bitron.ch>
+
        * vala/valaaddressofexpression.vala, vala/valaassignment.vala,
          vala/valabinaryexpression.vala, vala/valacastexpression.vala,
          vala/valacodenode.vala, vala/valadostatement.vala,
index ef29c5e..11fcd63 100644 (file)
@@ -527,7 +527,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                p.accept_children (this);
 
                if (!p.ellipsis) {
-                       string ctypename = p.type_reference.get_cname (false, !p.type_reference.takes_ownership);
+                       string ctypename = p.type_reference.get_cname (false, !p.type_reference.transfers_ownership);
                        string cname = p.name;
 
                        // pass non-simple structs always by reference
index 0f5ddaf..c5d1f90 100644 (file)
@@ -57,7 +57,7 @@ EXTRA_DIST = \
        \
        hello.exp \
        expressions-relational.exp \
-       expressions-conditional.vala \
+       expressions-conditional.exp \
        expressions-assignments.exp \
        statements-selection.exp \
        statements-jump.exp \
index 3b92f60..1d78a87 100644 (file)
@@ -114,6 +114,7 @@ libvalacore_la_VALASOURCES = \
        valatypeparameter.vala \
        valatypesymbol.vala \
        valaunaryexpression.vala \
+       valaunresolvedtype.vala \
        valavariabledeclarator.vala \
        valawhilestatement.vala \
        $(NULL)
index e2458f7..0ccf94f 100644 (file)
@@ -461,11 +461,11 @@ type_name
          {
                GList *l;
                ValaSourceReference *src = src(@1);
-               $$ = vala_data_type_new_from_name (NULL, $1, src);
+               $$ = VALA_DATA_TYPE (vala_unresolved_type_new_from_name (NULL, $1, src));
                g_free ($1);
                g_object_unref (src);
                for (l = $2; l != NULL; l = l->next) {
-                       vala_data_type_add_type_argument ($$, l->data);
+                       vala_data_type_add_type_argument (VALA_DATA_TYPE ($$), l->data);
                        g_object_unref (l->data);
                }
                g_list_free ($2);
@@ -474,12 +474,12 @@ type_name
          {
                GList *l;
                ValaSourceReference *src = src(@1);
-               $$ = vala_data_type_new_from_name ($1, $3, src);
+               $$ = VALA_DATA_TYPE (vala_unresolved_type_new_from_name ($1, $3, src));
                g_free ($1);
                g_free ($3);
                g_object_unref (src);
                for (l = $4; l != NULL; l = l->next) {
-                       vala_data_type_add_type_argument ($$, l->data);
+                       vala_data_type_add_type_argument (VALA_DATA_TYPE ($$), l->data);
                        g_object_unref (l->data);
                }
                g_list_free ($4);
@@ -501,64 +501,64 @@ type
        : type_name opt_rank_specifier opt_op_neg
          {
                $$ = $1;
-               vala_data_type_set_array_rank ($$, $2);
+               vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $2);
                if ($3) {
-                       vala_data_type_set_non_null ($$, TRUE);
+                       vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
                }
          }
        | WEAK type_name opt_rank_specifier opt_op_neg
          {
                $$ = $2;
-               vala_data_type_set_is_weak ($$, TRUE);
-               vala_data_type_set_array_rank ($$, $3);
+               vala_unresolved_type_set_is_weak (VALA_UNRESOLVED_TYPE ($$), TRUE);
+               vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
                if ($4) {
-                       vala_data_type_set_non_null ($$, TRUE);
+                       vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
                }
          }
        | type_name opt_rank_specifier opt_op_neg HASH
          {
                $$ = $1;
-               vala_data_type_set_takes_ownership ($$, TRUE);
-               vala_data_type_set_array_rank ($$, $2);
+               vala_unresolved_type_set_transfers_ownership (VALA_UNRESOLVED_TYPE ($$), TRUE);
+               vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $2);
                if ($3) {
-                       vala_data_type_set_non_null ($$, TRUE);
+                       vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
                }
          }
        | REF type_name opt_rank_specifier opt_op_neg
          {
                $$ = $2;
-               vala_data_type_set_is_ref ($$, TRUE);
-               vala_data_type_set_array_rank ($$, $3);
+               vala_unresolved_type_set_is_ref (VALA_UNRESOLVED_TYPE ($$), TRUE);
+               vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
                if ($4) {
-                       vala_data_type_set_non_null ($$, TRUE);
+                       vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
                }
          }
        | OUT type_name opt_rank_specifier opt_op_neg
          {
                $$ = $2;
-               vala_data_type_set_is_out ($$, TRUE);
-               vala_data_type_set_array_rank ($$, $3);
+               vala_unresolved_type_set_is_out (VALA_UNRESOLVED_TYPE ($$), TRUE);
+               vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
                if ($4) {
-                       vala_data_type_set_non_null ($$, TRUE);
+                       vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
                }
          }
        | OUT WEAK type_name opt_rank_specifier opt_op_neg
          {
                $$ = $3;
-               vala_data_type_set_is_weak ($$, TRUE);
-               vala_data_type_set_is_out ($$, TRUE);
-               vala_data_type_set_array_rank ($$, $4);
+               vala_unresolved_type_set_is_weak (VALA_UNRESOLVED_TYPE ($$), TRUE);
+               vala_unresolved_type_set_is_out (VALA_UNRESOLVED_TYPE ($$), TRUE);
+               vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $4);
                if ($5) {
-                       vala_data_type_set_non_null ($$, TRUE);
+                       vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
                }
          }
        | type_name stars opt_rank_specifier opt_op_neg
          {
                $$ = $1;
-               vala_data_type_set_pointer_level ($$, $2);
-               vala_data_type_set_array_rank ($$, $3);
+               vala_unresolved_type_set_pointer_level (VALA_UNRESOLVED_TYPE ($$), $2);
+               vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
                if ($4) {
-                       vala_data_type_set_non_null ($$, TRUE);
+                       vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
                }
          }
        ;
@@ -596,7 +596,7 @@ array_creation_expression
          {
                GList *l;
                ValaSourceReference *src = src(@2);
-               ValaDataType *t = vala_data_type_new_from_expression (VALA_EXPRESSION ($2));
+               ValaDataType *t = VALA_DATA_TYPE (vala_unresolved_type_new_from_expression (VALA_EXPRESSION ($2)));
                $$ = VALA_EXPRESSION (vala_code_context_create_array_creation_expression (context, t, g_list_length ($3),  VALA_INITIALIZER_LIST ($4), src));
                g_object_unref (t);
                for (l = $3; l != NULL; l = l->next) {
@@ -613,7 +613,7 @@ array_creation_expression
        | NEW member_name rank_specifier initializer
          {
                ValaSourceReference *src = src(@2);
-               ValaDataType *t = vala_data_type_new_from_expression (VALA_EXPRESSION ($2));
+               ValaDataType *t = VALA_DATA_TYPE (vala_unresolved_type_new_from_expression (VALA_EXPRESSION ($2)));
                $$ = VALA_EXPRESSION (vala_code_context_create_array_creation_expression (context, t, $3, VALA_INITIALIZER_LIST ($4), src));
                g_object_unref (t);
                g_object_unref (src);
@@ -1821,32 +1821,32 @@ local_variable_type
        : primary_expression opt_bracket_pair opt_op_neg
          {
                ValaSourceReference *src = src(@1);
-               $$ = vala_data_type_new_from_expression ($1);
+               $$ = VALA_DATA_TYPE (vala_unresolved_type_new_from_expression ($1));
                g_object_unref ($1);
                g_object_unref (src);
-               vala_data_type_set_takes_ownership ($$, TRUE);
-               vala_data_type_set_array_rank ($$, $2);
+               vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($$), TRUE);
+               vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $2);
                if ($3) {
-                       vala_data_type_set_non_null ($$, TRUE);
+                       vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
                }
          }
        | primary_expression stars
          {
                ValaSourceReference *src = src(@1);
-               $$ = vala_data_type_new_from_expression ($1);
+               $$ = VALA_DATA_TYPE (vala_unresolved_type_new_from_expression ($1));
                g_object_unref ($1);
                g_object_unref (src);
-               vala_data_type_set_pointer_level ($$, $2);
+               vala_unresolved_type_set_pointer_level (VALA_UNRESOLVED_TYPE ($$), $2);
          }
        | WEAK primary_expression opt_bracket_pair opt_op_neg
          {
                ValaSourceReference *src = src(@2);
-               $$ = vala_data_type_new_from_expression ($2);
+               $$ = VALA_DATA_TYPE (vala_unresolved_type_new_from_expression ($2));
                g_object_unref ($2);
                g_object_unref (src);
-               vala_data_type_set_array_rank ($$, $3);
+               vala_unresolved_type_set_array_rank (VALA_UNRESOLVED_TYPE ($$), $3);
                if ($4) {
-                       vala_data_type_set_non_null ($$, TRUE);
+                       vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
                }
          }
        ;
@@ -2152,8 +2152,8 @@ foreach_statement
        : FOREACH OPEN_PARENS type identifier IN expression CLOSE_PARENS embedded_statement
          {
                ValaSourceReference *src = src(@3);
-               if (!vala_data_type_get_is_weak ($3)) {
-                       vala_data_type_set_takes_ownership ($3, TRUE);
+               if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($3))) {
+                       vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($3), TRUE);
                }
                $$ = VALA_STATEMENT (vala_code_context_create_foreach_statement (context, $3, $4, $6, $8, src));
                g_object_unref ($3);
@@ -2772,11 +2772,11 @@ field_declaration
 
                src = src_com(@5, $1);
 
-               if (vala_data_type_get_is_ref ($5) || vala_data_type_get_is_out ($5)) {
+               if (vala_unresolved_type_get_is_ref (VALA_UNRESOLVED_TYPE ($5)) || vala_unresolved_type_get_is_out (VALA_UNRESOLVED_TYPE ($5))) {
                        vala_report_error (src, "`ref' and `out' may only be used for parameters.");
                }
-               if (!vala_data_type_get_is_weak ($5)) {
-                       vala_data_type_set_takes_ownership ($5, TRUE);
+               if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($5))) {
+                       vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($5), TRUE);
                }
 
                $$ = vala_code_context_create_field (context, vala_symbol_get_name (VALA_SYMBOL ($6)), $5, vala_variable_declarator_get_initializer ($6), src);
@@ -2920,11 +2920,11 @@ method_header
 
                src = src_com(@6, $1);
 
-               if (vala_data_type_get_is_ref ($5) || vala_data_type_get_is_out ($5)) {
+               if (vala_unresolved_type_get_is_ref (VALA_UNRESOLVED_TYPE ($5)) || vala_unresolved_type_get_is_out (VALA_UNRESOLVED_TYPE ($5))) {
                        vala_report_error (src, "`ref' and `out' may only be used for parameters.");
                }
-               if (!vala_data_type_get_is_weak ($5)) {
-                       vala_data_type_set_transfers_ownership ($5, TRUE);
+               if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($5))) {
+                       vala_unresolved_type_set_transfers_ownership (VALA_UNRESOLVED_TYPE ($5), TRUE);
                }
 
                $$ = vala_code_context_create_method (context, $6, $5, src);
@@ -3064,6 +3064,18 @@ fixed_parameter
                ValaSourceReference *src;
 
                src = src(@3);
+               if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($3))) {
+                       vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($3), TRUE);
+               }
+
+               if (!vala_unresolved_type_get_is_ref (VALA_UNRESOLVED_TYPE ($3))
+                       && !vala_unresolved_type_get_is_out (VALA_UNRESOLVED_TYPE ($3))
+                       && !vala_unresolved_type_get_transfers_ownership (VALA_UNRESOLVED_TYPE ($3))) {
+                       /* FIXME take_ownership for in parameters that don't transfer ownership is not supported yet
+                        * this may require an additional local variable per parameter */
+                       vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($3), FALSE);
+               }
+
                $$ = vala_code_context_create_formal_parameter (context, $4, $3, src);
                g_object_unref (src);
                vala_formal_parameter_set_construct_parameter ($$, $2);
@@ -3075,6 +3087,18 @@ fixed_parameter
                ValaSourceReference *src;
 
                src = src(@3);
+               if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($3))) {
+                       vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($3), TRUE);
+               }
+
+               if (!vala_unresolved_type_get_is_ref (VALA_UNRESOLVED_TYPE ($3))
+                       && !vala_unresolved_type_get_is_out (VALA_UNRESOLVED_TYPE ($3))
+                       && !vala_unresolved_type_get_transfers_ownership (VALA_UNRESOLVED_TYPE ($3))) {
+                       /* FIXME take_ownership for in parameters that don't transfer ownership is not supported yet
+                        * this may require an additional local variable per parameter */
+                       vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($3), FALSE);
+               }
+
                $$ = vala_code_context_create_formal_parameter (context, $4, $3, src);
                g_object_unref (src);
                vala_formal_parameter_set_default_expression ($$, $6);
@@ -3105,15 +3129,8 @@ property_declaration
          {
                ValaSourceReference *src;
 
-               /* HASH in property type context has the meaning of transferring
-                * ownership instead of taking it */
-               if (vala_data_type_get_takes_ownership ($5)) {
-                       vala_data_type_set_transfers_ownership ($5, TRUE);
-                       vala_data_type_set_takes_ownership ($5, FALSE);
-               }
-
-               if (!vala_data_type_get_is_weak ($5)) {
-                       vala_data_type_set_takes_ownership ($5, TRUE);
+               if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($5))) {
+                       vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($5), TRUE);
                }
 
                src = src_com(@5, $1);
@@ -3145,15 +3162,8 @@ property_declaration
          {
                ValaSourceReference *src;
 
-               /* HASH in property type context has the meaning of transferring
-                * ownership instead of taking it */
-               if (vala_data_type_get_takes_ownership ($5)) {
-                       vala_data_type_set_transfers_ownership ($5, TRUE);
-                       vala_data_type_set_takes_ownership ($5, FALSE);
-               }
-
-               if (!vala_data_type_get_is_weak ($5)) {
-                       vala_data_type_set_takes_ownership ($5, TRUE);
+               if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($5))) {
+                       vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($5), TRUE);
                }
 
                src = src_com(@5, $1);
@@ -3883,8 +3893,8 @@ type_argument
        : type
          {
                $$ = $1;
-               if (!vala_data_type_get_is_weak ($$)) {
-                       vala_data_type_set_takes_ownership ($$, TRUE);
+               if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($$))) {
+                       vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($$), TRUE);
                }
          }
        ;
index 5fd2b84..40a2af0 100644 (file)
@@ -77,5 +77,6 @@
 #include <vala/valatypeparameter.h>
 #include <vala/valatypesymbol.h>
 #include <vala/valaunaryexpression.h>
+#include <vala/valaunresolvedtype.h>
 #include <vala/valavariabledeclarator.h>
 #include <vala/valawhilestatement.h>
index 6cfd2aa..0ac0d96 100644 (file)
@@ -31,7 +31,13 @@ public class Vala.ArrayCreationExpression : Expression {
        /**
         * The type of the elements of the array.
         */
-       public DataType element_type { get; set construct; }
+       public DataType element_type {
+               get { return _element_type; }
+               set {
+                       _element_type = value;
+                       _element_type.parent_node = this;
+               }
+       }
        
        /**
         * The rank of the array.
@@ -47,7 +53,9 @@ public class Vala.ArrayCreationExpression : Expression {
         * The root array initializer list.
         */
        public InitializerList initializer_list { get; set construct; }
-       
+
+       private DataType _element_type;
+
        /**
         * Add a size expression.
         */
@@ -86,4 +94,10 @@ public class Vala.ArrayCreationExpression : Expression {
        public override bool is_pure () {
                return false;
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (element_type == old_type) {
+                       element_type = new_type;
+               }
+       }
 }
index ce358f2..2c28d06 100644 (file)
@@ -30,8 +30,14 @@ public class Vala.Callback : Typesymbol {
        /**
         * The return type of this callback.
         */
-       public DataType return_type { get; set; }
-       
+       public DataType return_type {
+               get { return _return_type; }
+               set {
+                       _return_type = value;
+                       _return_type.parent_node = this;
+               }
+       }
+
        /**
         * Specifies whether callback supports calling instance methods.
         * The reference to the object instance will be appended to the end of
@@ -43,7 +49,9 @@ public class Vala.Callback : Typesymbol {
 
        private Gee.List<FormalParameter> parameters = new ArrayList<FormalParameter> ();
        private string cname;
-       
+
+       private DataType _return_type;
+
        /**
         * Creates a new callback.
         *
@@ -197,4 +205,10 @@ public class Vala.Callback : Typesymbol {
        public override string get_set_value_function () {
                return "g_value_set_pointer";
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (return_type == old_type) {
+                       return_type = new_type;
+               }
+       }
 }
index a42ddcd..64ae38c 100644 (file)
@@ -42,7 +42,13 @@ public class Vala.CastExpression : Expression {
        /**
         * The target type.
         */
-       public DataType! type_reference { get; set construct; }
+       public DataType! type_reference {
+               get { return _data_type; }
+               set {
+                       _data_type = value;
+                       _data_type.parent_node = this;
+               }
+       }
 
        /**
         * Checked casts return NULL instead of raising an error.
@@ -51,6 +57,8 @@ public class Vala.CastExpression : Expression {
 
        private Expression! _inner;
 
+       private DataType _data_type;
+
        /**
         * Creates a new cast expression.
         *
@@ -77,4 +85,10 @@ public class Vala.CastExpression : Expression {
        public override bool is_pure () {
                return inner.is_pure ();
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (type_reference == old_type) {
+                       type_reference = new_type;
+               }
+       }
 }
index db6375d..b96b35b 100644 (file)
@@ -29,7 +29,13 @@ public class Vala.CatchClause : CodeNode {
        /**
         * Specifies the error type.
         */
-       public DataType type_reference { get; set; }
+       public DataType type_reference {
+               get { return _data_type; }
+               set {
+                       _data_type = value;
+                       _data_type.parent_node = this;
+               }
+       }
        
        /**
         * Specifies the error variable name.
@@ -46,6 +52,8 @@ public class Vala.CatchClause : CodeNode {
         */
        public VariableDeclarator variable_declarator { get; set; }
 
+       private DataType _data_type;
+
        /**
         * Creates a new catch clause.
         *
@@ -66,4 +74,10 @@ public class Vala.CatchClause : CodeNode {
                type_reference.accept (visitor);
                body.accept (visitor);
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (type_reference == old_type) {
+                       type_reference = new_type;
+               }
+       }
 }
index 404fb1e..0b089c6 100644 (file)
@@ -116,6 +116,7 @@ public class Vala.Class : Typesymbol {
         */
        public void add_base_type (DataType! type) {
                base_types.add (type);
+               type.parent_node = this;
        }
 
        /**
@@ -164,7 +165,7 @@ public class Vala.Class : Typesymbol {
         */
        public void add_field (Field! f) {
                // non_null fields not yet supported due to initialization issues
-               f.type_reference.non_null = false;
+               ((UnresolvedType) f.type_reference).non_null = false;
                fields.add (f);
                if (f.access == SymbolAccessibility.PRIVATE && f.instance) {
                        _has_private_fields = true;
@@ -232,7 +233,7 @@ public class Vala.Class : Typesymbol {
                        /* automatic property accessor body generation */
                        var field_type = prop.type_reference.copy ();
                        // non_null fields not yet supported due to initialization issues
-                       field_type.non_null = false;
+                       ((UnresolvedType) field_type).non_null = false;
                        var f = new Field ("_%s".printf (prop.name), field_type, null, prop.source_reference);
                        f.access = SymbolAccessibility.PRIVATE;
                        add_field (f);
@@ -600,5 +601,14 @@ public class Vala.Class : Typesymbol {
                }
                return -1;
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               for (int i = 0; i < base_types.size; i++) {
+                       if (base_types[i] == old_type) {
+                               base_types[i] = new_type;
+                               return;
+                       }
+               }
+       }
 }
 
index c360567..d47aefd 100644 (file)
@@ -94,6 +94,9 @@ public abstract class Vala.CodeNode : Object {
        public virtual void accept_children (CodeVisitor! visitor) {
        }
 
+       public virtual void replace_type (DataType! old_type, DataType! new_type) {
+       }
+
        public virtual void replace_expression (Expression! old_node, Expression! new_node) {
        }
 
index 6f268c9..f674104 100644 (file)
@@ -208,7 +208,7 @@ public abstract class Vala.CodeVisitor : Object {
         *
         * @param type a type reference
         */
-       public virtual void visit_type_reference (DataType! type) {
+       public virtual void visit_data_type (DataType! type) {
        }
 
        /**
index ec1d5f3..007341f 100644 (file)
@@ -29,7 +29,13 @@ public class Vala.Constant : Member, Lockable {
        /**
         * The data type of this constant.
         */
-       public DataType! type_reference { get; set; }
+       public DataType! type_reference {
+               get { return _data_type; }
+               set {
+                       _data_type = value;
+                       _data_type.parent_node = this;
+               }
+       }
 
        /**
         * The value of this constant.
@@ -40,6 +46,8 @@ public class Vala.Constant : Member, Lockable {
        
        private bool lock_used = false;
 
+       private DataType _data_type;
+
        /**
         * Creates a new constant.
         *
@@ -90,4 +98,10 @@ public class Vala.Constant : Member, Lockable {
        public void set_lock_used (bool used) {
                lock_used = used;
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (type_reference == old_type) {
+                       type_reference = new_type;
+               }
+       }
 }
index 46227da..75bb38a 100644 (file)
@@ -1,4 +1,4 @@
-/* valatypereference.vala
+/* valadatatype.vala
  *
  * Copyright (C) 2006-2007  Jürg Billeter, Raffaele Sandrini
  *
@@ -69,105 +69,25 @@ public class Vala.DataType : CodeNode {
         * Specifies that the expression transfers a floating reference.
         */
        public bool floating_reference { get; set; }
-       
-       /**
-        * The name of the namespace containing the referred data type. May only
-        * be used with unresolved type references.
-        */
-       public string namespace_name { get; set; }
-       
-       /**
-        * The name of the referred data type. May only be used with unresolved
-        * type references.
-        */
-       public string type_name { get; set; }
-       
-       /**
-        * Specifies the rank of the array this reference is possibly referring to. "0" indicates no array.
-        * WARNING: This property may only be set by the parser and only be read by the symbol resolver.
-        */
-       public int array_rank { get; set; }
-
-       /**
-        * Specifies the level of the pointer if this is a pointer-type. "0" indicates no pointer-type.
-        * WARNING: This property may only be set by the parser and only be read by the symbol resolver.
-        */
-       public int pointer_level { get; set; }
 
        /**
         * Specifies that the expression is a reference used in ref parameters.
         */
        public bool is_ref { get; set; }
 
-       /**
-        * The weak modifier has been specified. May only be used with
-        * unresolved type references.
-        */
-       public bool is_weak { get; set; }
-
-       private ArrayList<DataType> type_argument_list = new ArrayList<DataType> ();
+       private Gee.List<DataType> type_argument_list = new ArrayList<DataType> ();
        
        public DataType () {
        }
 
        /**
-        * Creates a new type reference.
-        *
-        * @param ns        optional namespace name
-        * @param type_name type symbol name
-        * @param source    reference to source code
-        * @return          newly created type reference
-        */
-       public DataType.from_name (string ns, string! type, SourceReference source = null) {
-               namespace_name = ns;
-               type_name = type;
-               source_reference = source;
-       }
-
-       /**
-        * Creates a new type reference from a code expression.
-        *
-        * @param expr   member access expression
-        * @param source reference to source code
-        * @return       newly created type reference
-        */
-       public static DataType new_from_expression (Expression! expr) {
-               string ns = null;
-               string type_name = null;
-               if (expr is MemberAccess) {
-                       DataType type_ref = null;
-               
-                       MemberAccess ma = (MemberAccess) expr;
-                       if (ma.inner != null) {
-                               if (ma.inner is MemberAccess) {
-                                       var simple = (MemberAccess) ma.inner;
-                                       type_ref = new DataType.from_name (simple.member_name, ma.member_name, ma.source_reference);
-                               }
-                       } else {
-                               type_ref = new DataType.from_name (null, ma.member_name, ma.source_reference);
-                       }
-                       
-                       if (type_ref != null) {
-                               var type_args = ma.get_type_arguments ();
-                               foreach (DataType arg in type_args) {
-                                       type_ref.add_type_argument (arg);
-                               }
-                               
-                               return type_ref;
-                       }
-               }
-               
-               Report.error (expr.source_reference, "Type reference must be simple name or member access expression");
-               return null;
-       }
-       
-       /**
         * Appends the specified type as generic type argument.
         *
         * @param arg a type reference
         */
        public void add_type_argument (DataType! arg) {
                type_argument_list.add (arg);
+               arg.parent_node = this;
        }
        
        /**
@@ -187,13 +107,13 @@ public class Vala.DataType : CodeNode {
        }
 
        public override void accept (CodeVisitor! visitor) {
-               if (((Gee.List<DataType>) type_argument_list).size > 0) {
+               if (type_argument_list.size > 0) {
                        foreach (DataType type_arg in type_argument_list) {
                                type_arg.accept (visitor);
                        }
                }
        
-               visitor.visit_type_reference (this);
+               visitor.visit_data_type (this);
        }
 
        /**
@@ -278,7 +198,7 @@ public class Vala.DataType : CodeNode {
         *
         * @return copy of this type reference
         */
-       public DataType! copy () {
+       public virtual DataType! copy () {
                var result = new DataType ();
                result.source_reference = source_reference;
                result.transfers_ownership = transfers_ownership;
@@ -288,12 +208,7 @@ public class Vala.DataType : CodeNode {
                result.data_type = data_type;
                result.type_parameter = type_parameter;
                result.floating_reference = floating_reference;
-               result.namespace_name = namespace_name;
-               result.type_name = type_name;
-               result.array_rank = array_rank;
-               result.pointer_level = pointer_level;
                result.is_ref = is_ref;
-               result.is_weak = is_weak;
                
                foreach (DataType arg in type_argument_list) {
                        result.type_argument_list.add (arg.copy ());
@@ -383,4 +298,13 @@ public class Vala.DataType : CodeNode {
                
                return true;
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               for (int i = 0; i < type_argument_list.size; i++) {
+                       if (type_argument_list[i] == old_type) {
+                               type_argument_list[i] = new_type;
+                               return;
+                       }
+               }
+       }
 }
index d7df138..164e5b6 100644 (file)
@@ -30,7 +30,13 @@ public class Vala.Field : Member, Invokable, Lockable {
        /**
         * The data type of this field.
         */
-       public DataType! type_reference { get; set; }
+       public DataType! type_reference {
+               get { return _data_type; }
+               set {
+                       _data_type = value;
+                       _data_type.parent_node = this;
+               }
+       }
 
        /**
         * Specifies the expression to be used to initialize this field.
@@ -62,7 +68,9 @@ public class Vala.Field : Member, Invokable, Lockable {
        private bool _instance = true;
        
        private bool lock_used = false;
-       
+
+       private DataType _data_type;
+
        /**
         * Creates a new field.
         *
@@ -172,4 +180,10 @@ public class Vala.Field : Member, Invokable, Lockable {
        public void set_lock_used (bool used) {
                lock_used = used;
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (type_reference == old_type) {
+                       type_reference = new_type;
+               }
+       }
 }
index c384df1..3c93e3c 100644 (file)
@@ -30,7 +30,13 @@ public class Vala.ForeachStatement : Block {
        /**
         * Specifies the element type.
         */
-       public DataType! type_reference { get; set construct; }
+       public DataType! type_reference {
+               get { return _data_type; }
+               set {
+                       _data_type = value;
+                       _data_type.parent_node = this;
+               }
+       }
        
        /**
         * Specifies the element variable name.
@@ -81,6 +87,8 @@ public class Vala.ForeachStatement : Block {
        private Expression! _collection;
        private Block _body;
 
+       private DataType _data_type;
+
        /**
         * Creates a new foreach statement.
         *
@@ -111,4 +119,10 @@ public class Vala.ForeachStatement : Block {
                        collection = new_node;
                }
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (type_reference == old_type) {
+                       type_reference = new_type;
+               }
+       }
 }
index d055961..7dc466b 100644 (file)
@@ -31,7 +31,13 @@ public class Vala.FormalParameter : Symbol, Invokable {
        /**
         * The parameter type.
         */
-       public DataType type_reference { get; set; }
+       public DataType type_reference {
+               get { return _data_type; }
+               set {
+                       _data_type = value;
+                       _data_type.parent_node = this;
+               }
+       }
        
        /**
         * Specifies whether the methods accepts an indefinite number of
@@ -56,7 +62,9 @@ public class Vala.FormalParameter : Symbol, Invokable {
         * construct property. This is only allowed in CreationMethod headers.
         */
        public bool construct_parameter { get; set; }
-       
+
+       private DataType _data_type;
+
        /**
         * Creates a new formal parameter.
         *
@@ -119,4 +127,10 @@ public class Vala.FormalParameter : Symbol, Invokable {
        public bool is_invokable () {
                return (type_reference.data_type is Callback);
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (type_reference == old_type) {
+                       type_reference = new_type;
+               }
+       }
 }
index b330ab3..82df7d2 100644 (file)
@@ -87,6 +87,7 @@ public class Vala.Interface : Typesymbol {
         */
        public void add_prerequisite (DataType! type) {
                prerequisites.add (type);
+               type.parent_node = this;
        }
 
        /**
@@ -396,4 +397,13 @@ public class Vala.Interface : Typesymbol {
                }
                return -1;
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               for (int i = 0; i < prerequisites.size; i++) {
+                       if (prerequisites[i] == old_type) {
+                               prerequisites[i] = new_type;
+                               return;
+                       }
+               }
+       }
 }
index eadad28..6fefe40 100644 (file)
@@ -407,15 +407,20 @@ public class Vala.InterfaceWriter : CodeVisitor {
                                continue;
                        }
                        
-                       if (param.type_reference.is_ref) {
-                               write_string ("ref ");
-                       } else if (param.type_reference.is_out) {
-                               write_string ("out ");
+                       if (param.type_reference.is_ref || param.type_reference.is_out) {
+                               if (param.type_reference.is_ref) {
+                                       write_string ("ref ");
+                               } else if (param.type_reference.is_out) {
+                                       write_string ("out ");
+                               }
+                               if (param.type_reference.data_type != null && param.type_reference.data_type.is_reference_type () && !param.type_reference.takes_ownership) {
+                                       write_string ("weak ");
+                               }
                        }
 
                        write_type (param.type_reference);
 
-                       if (param.type_reference.takes_ownership) {
+                       if (param.type_reference.transfers_ownership) {
                                write_string ("#");
                        }
 
index 55a6525..13ff54b 100644 (file)
@@ -30,7 +30,15 @@ public class Vala.LocalVariableDeclaration : CodeNode {
        /**
         * The type of the local variable.
         */
-       public DataType type_reference { get; set; }
+       public DataType! type_reference {
+               get { return _data_type; }
+               set {
+                       _data_type = value;
+                       _data_type.parent_node = this;
+               }
+       }
+
+       private DataType _data_type;
 
        private Gee.List<VariableDeclarator> variable_declarators = new ArrayList<VariableDeclarator> ();
        
@@ -85,4 +93,10 @@ public class Vala.LocalVariableDeclaration : CodeNode {
        
                visitor.visit_local_variable_declaration (this);
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (type_reference == old_type) {
+                       type_reference = new_type;
+               }
+       }
 }
index d464d2a..5a2d468 100644 (file)
@@ -82,6 +82,7 @@ public class Vala.MemberAccess : Expression {
         */
        public void add_type_argument (DataType! arg) {
                type_argument_list.add (arg);
+               arg.parent_node = this;
        }
        
        /**
@@ -123,4 +124,13 @@ public class Vala.MemberAccess : Expression {
                // accessing property could have side-effects
                return (inner == null || inner.is_pure ()) && !(symbol_reference is Property);
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               for (int i = 0; i < type_argument_list.size; i++) {
+                       if (type_argument_list[i] == old_type) {
+                               type_argument_list[i] = new_type;
+                               return;
+                       }
+               }
+       }
 }
index 9399d22..2449c83 100644 (file)
@@ -216,7 +216,7 @@ public class Vala.MemoryManager : CodeVisitor {
                                    && ((param.type_reference.data_type != null
                                    && param.type_reference.data_type.is_reference_type ())
                                    || param.type_reference.type_parameter != null)) {
-                                       bool is_ref = param.type_reference.takes_ownership;
+                                       bool is_ref = param.type_reference.transfers_ownership;
                                        if (is_ref && param.type_reference.type_parameter != null) {
                                                if (expr.call is MemberAccess) {
                                                        var ma = (MemberAccess) expr.call;
@@ -259,7 +259,7 @@ public class Vala.MemoryManager : CodeVisitor {
                                    && ((param.type_reference.data_type != null
                                    && param.type_reference.data_type.is_reference_type ())
                                    || param.type_reference.type_parameter != null)) {
-                                       bool is_ref = param.type_reference.takes_ownership;
+                                       bool is_ref = param.type_reference.transfers_ownership;
                                        if (is_ref && param.type_reference.type_parameter != null) {
                                                var param_type = SemanticAnalyzer.get_actual_type (expr.type_reference, msym, param.type_reference, expr);
                                                if (param_type != null) {
index b170494..22cb69c 100644 (file)
@@ -33,7 +33,13 @@ public class Vala.Method : Member, Invokable {
        /**
         * The return type of this method.
         */
-       public DataType return_type { get; set; }
+       public DataType return_type {
+               get { return _return_type; }
+               set {
+                       _return_type = value;
+                       _return_type.parent_node = this;
+               }
+       }
        
        public Block body { get; set; }
        
@@ -164,6 +170,7 @@ public class Vala.Method : Member, Invokable {
        private string _sentinel;
        private bool _no_array_length;
        private Gee.List<DataType> error_domains = new ArrayList<DataType> ();
+       private DataType _return_type;
 
        /**
         * Creates a new method.
@@ -367,6 +374,7 @@ public class Vala.Method : Member, Invokable {
         */
        public void add_error_domain (DataType! error_domain) {
                error_domains.add (error_domain);
+               error_domain.parent_node = this;
        }
 
        /**
@@ -377,4 +385,17 @@ public class Vala.Method : Member, Invokable {
        public Collection<DataType> get_error_domains () {
                return new ReadOnlyCollection<DataType> (error_domains);
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (return_type == old_type) {
+                       return_type = new_type;
+                       return;
+               }
+               for (int i = 0; i < error_domains.size; i++) {
+                       if (error_domains[i] == old_type) {
+                               error_domains[i] = new_type;
+                               return;
+                       }
+               }
+       }
 }
index 62ea314..6b5aa67 100644 (file)
@@ -30,7 +30,13 @@ public class Vala.ObjectCreationExpression : Expression {
        /**
         * The object type to create.
         */
-       public DataType type_reference { get; set; }
+       public DataType! type_reference {
+               get { return _data_type; }
+               set {
+                       _data_type = value;
+                       _data_type.parent_node = this;
+               }
+       }
 
        /**
         * The construction method to use. May be null to indicate that
@@ -48,6 +54,8 @@ public class Vala.ObjectCreationExpression : Expression {
 
        private Gee.List<MemberInitializer> object_initializer = new ArrayList<MemberInitializer> ();
 
+       private DataType _data_type;
+
        /**
         * Creates a new object creation expression.
         *
@@ -129,4 +137,10 @@ public class Vala.ObjectCreationExpression : Expression {
        public override bool is_pure () {
                return false;
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (type_reference == old_type) {
+                       type_reference = new_type;
+               }
+       }
 }
index 69aeef3..fea3a46 100644 (file)
@@ -29,7 +29,13 @@ public class Vala.Property : Member, Lockable {
        /**
         * The property type.
         */
-       public DataType! type_reference { get; set construct; }
+       public DataType! type_reference {
+               get { return _data_type; }
+               set {
+                       _data_type = value;
+                       _data_type.parent_node = this;
+               }
+       }
        
        /**
         * The get accessor of this property if available.
@@ -96,7 +102,9 @@ public class Vala.Property : Member, Lockable {
        public Property base_interface_property { get; set; }
        
        private bool lock_used = false;
-       
+
+       private DataType _data_type;
+
        /**
         * Creates a new property.
         *
@@ -224,4 +232,10 @@ public class Vala.Property : Member, Lockable {
 
                return true;
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (type_reference == old_type) {
+                       type_reference = new_type;
+               }
+       }
 }
index 90ce8fc..bf8e20f 100644 (file)
@@ -30,8 +30,14 @@ public class Vala.Signal : Member, Invokable, Lockable {
        /**
         * The return type of handlers of this signal.
         */
-       public DataType! return_type { get; set; }
-       
+       public DataType! return_type {
+               get { return _return_type; }
+               set {
+                       _return_type = value;
+                       _return_type.parent_node = this;
+               }
+       }
+
        /**
         * Specifies whether this signal has an emitter wrapper function.
         */
@@ -44,6 +50,8 @@ public class Vala.Signal : Member, Invokable, Lockable {
        
        private bool lock_used = false;
 
+       private DataType _return_type;
+
        /**
         * Creates a new signal.
         *
@@ -174,4 +182,10 @@ public class Vala.Signal : Member, Invokable, Lockable {
        public void set_lock_used (bool used) {
                lock_used = used;
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (return_type == old_type) {
+                       return_type = new_type;
+               }
+       }
 }
index e8ada43..2e806e4 100644 (file)
@@ -364,6 +364,7 @@ public class Vala.Struct : Typesymbol {
         */
        public void add_base_type (DataType! type) {
                base_types.add (type);
+               type.parent_node = this;
        }
 
        /**
@@ -401,4 +402,13 @@ public class Vala.Struct : Typesymbol {
                }
                return simple_type;
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               for (int i = 0; i < base_types.size; i++) {
+                       if (base_types[i] == old_type) {
+                               base_types[i] = new_type;
+                               return;
+                       }
+               }
+       }
 }
index e26a5d7..c183c1a 100644 (file)
@@ -180,18 +180,27 @@ public class Vala.SymbolResolver : CodeVisitor {
                }
        }
 
-       public override void visit_type_reference (DataType! type) {
-               if (type.type_name == null || type.type_name == "void") {
-                       // reset transfers_ownership
-                       type.transfers_ownership = false;
-                       return;
+       private DataType resolve_type (UnresolvedType! unresolved_type) {
+               var type = new DataType ();
+               type.source_reference = unresolved_type.source_reference;
+               type.takes_ownership = unresolved_type.takes_ownership;
+               type.transfers_ownership = unresolved_type.transfers_ownership;
+               type.is_ref = unresolved_type.is_ref;
+               type.is_out = unresolved_type.is_out;
+               type.non_null = unresolved_type.non_null;
+               foreach (DataType type_arg in unresolved_type.get_type_arguments ()) {
+                       type.add_type_argument (type_arg);
+               }
+
+               if (unresolved_type.type_name == null || unresolved_type.type_name == "void") {
+                       return type;
                }
                
-               if (type.namespace_name == null) {
+               if (unresolved_type.namespace_name == null) {
                        Symbol sym = null;
                        Scope scope = current_scope;
                        while (sym == null && scope != null) {
-                               sym = scope.lookup (type.type_name);
+                               sym = scope.lookup (unresolved_type.type_name);
                                scope = scope.parent_scope;
                                if (sym != null && !(sym is Typesymbol) && !(sym is TypeParameter)) {
                                        // ignore non-type symbols
@@ -204,19 +213,19 @@ public class Vala.SymbolResolver : CodeVisitor {
                                                continue;
                                        }
 
-                                       var local_sym = ns.namespace_symbol.scope.lookup (type.type_name);
+                                       var local_sym = ns.namespace_symbol.scope.lookup (unresolved_type.type_name);
                                        if (local_sym != null) {
                                                if (sym != null) {
-                                                       Report.error (type.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (type.type_name, sym.get_full_name (), local_sym.get_full_name ()));
-                                                       return;
+                                                       Report.error (type.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (unresolved_type.type_name, sym.get_full_name (), local_sym.get_full_name ()));
+                                                       return null;
                                                }
                                                sym = local_sym;
                                        }
                                }
                        }
                        if (sym == null) {
-                               Report.error (type.source_reference, "The type name `%s' could not be found".printf (type.type_name));
-                               return;
+                               Report.error (type.source_reference, "The type name `%s' could not be found".printf (unresolved_type.type_name));
+                               return null;
                        }
                        if (sym is TypeParameter) {
                                type.type_parameter = (TypeParameter) sym;
@@ -224,50 +233,47 @@ public class Vala.SymbolResolver : CodeVisitor {
                                type.data_type = (Typesymbol) sym;
                        } else {
                                Report.error (type.source_reference, "`%s' is not a type".printf (sym.get_full_name ()));
-                               return;
+                               return null;
                        }
                } else {
-                       var ns_symbol = root_symbol.scope.lookup (type.namespace_name);
+                       var ns_symbol = root_symbol.scope.lookup (unresolved_type.namespace_name);
                        if (ns_symbol == null) {
                                type.error = true;
-                               Report.error (type.source_reference, "The namespace name `%s' could not be found".printf (type.namespace_name));
-                               return;
+                               Report.error (type.source_reference, "The namespace name `%s' could not be found".printf (unresolved_type.namespace_name));
+                               return null;
                        }
                        
-                       var sym = ns_symbol.scope.lookup (type.type_name);
+                       var sym = ns_symbol.scope.lookup (unresolved_type.type_name);
                        if (sym == null) {
-                               Report.error (type.source_reference, "The type name `%s' does not exist in the namespace `%s'".printf (type.type_name, type.namespace_name));
-                               return;
+                               Report.error (type.source_reference, "The type name `%s' does not exist in the namespace `%s'".printf (unresolved_type.type_name, unresolved_type.namespace_name));
+                               return null;
                        }
                        if (sym is Typesymbol) {
                                type.data_type = (Typesymbol) sym;
                        } else {
                                Report.error (type.source_reference, "`%s' is not a type".printf (sym.get_full_name ()));
-                               return;
+                               return null;
                        }
                }
 
-               if (type.pointer_level > 0) {
+               if (unresolved_type.pointer_level > 0) {
                        if (type.data_type == null) {
                                type.error = true;
-                               Report.error (type.source_reference, "Pointer to `%s' not supported".printf (type.type_name));
-                               return;
+                               Report.error (type.source_reference, "Pointer to `%s' not supported".printf (unresolved_type.type_name));
+                               return null;
                        }
                        var referent_type = new DataType ();
                        referent_type.data_type = type.data_type;
-                       referent_type.pointer_level = type.pointer_level - 1;
 
                        if (type.data_type.is_reference_type ()) {
                                referent_type.takes_ownership = type.takes_ownership;
                        }
                        type.data_type = referent_type.data_type.get_pointer ();
                        type.add_type_argument (referent_type);
-                       
-                       visit_type_reference (referent_type);
                }
 
                /* check for array */
-               if (type.array_rank > 0) {
+               if (unresolved_type.array_rank > 0) {
                        var element_type = new DataType ();
                        element_type.data_type = type.data_type;
                        element_type.type_parameter = type.type_parameter;
@@ -280,10 +286,10 @@ public class Vala.SymbolResolver : CodeVisitor {
                                if (type.data_type.is_reference_type ()) {
                                        element_type.takes_ownership = type.takes_ownership;
                                }
-                               type.data_type = element_type.data_type.get_array (type.array_rank);
+                               type.data_type = element_type.data_type.get_array (unresolved_type.array_rank);
                        } else {
                                element_type.takes_ownership = type.takes_ownership;
-                               type.data_type = element_type.type_parameter.get_array (type.array_rank);
+                               type.data_type = element_type.type_parameter.get_array (unresolved_type.array_rank);
                                type.type_parameter = null;
                        }
                        type.add_type_argument (element_type);
@@ -297,6 +303,19 @@ public class Vala.SymbolResolver : CodeVisitor {
                        type.takes_ownership = false;
                        type.transfers_ownership = false;
                }
+
+               return type;
+       }
+
+       public override void visit_data_type (DataType! data_type) {
+               if (!(data_type is UnresolvedType)) {
+                       return;
+               }
+
+               var unresolved_type = (UnresolvedType) data_type;
+
+               var type = resolve_type (unresolved_type);
+               unresolved_type.parent_node.replace_type (unresolved_type, type);
        }
 
        public override void visit_variable_declarator (VariableDeclarator! decl) {
index 5f87e1c..d276f82 100644 (file)
@@ -34,7 +34,15 @@ public class Vala.TypeCheck : Expression {
        /**
         * The type to be matched against.
         */
-       public DataType! type_reference { get; set construct; }
+       public DataType! type_reference {
+               get { return _data_type; }
+               set {
+                       _data_type = value;
+                       _data_type.parent_node = this;
+               }
+       }
+
+       private DataType _data_type;
 
        /**
         * Creates a new type check expression.
@@ -61,4 +69,10 @@ public class Vala.TypeCheck : Expression {
        public override bool is_pure () {
                return expression.is_pure ();
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (type_reference == old_type) {
+                       type_reference = new_type;
+               }
+       }
 }
diff --git a/vala/valaunresolvedtype.vala b/vala/valaunresolvedtype.vala
new file mode 100644 (file)
index 0000000..528d0f6
--- /dev/null
@@ -0,0 +1,158 @@
+/* valaunresolvedtype.vala
+ *
+ * Copyright (C) 2006-2007  Jürg Billeter, Raffaele Sandrini
+ *
+ * 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.1 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>
+ *     Raffaele Sandrini <rasa@gmx.ch>
+ */
+
+using GLib;
+using Gee;
+
+/**
+ * An unresolved reference to a data type.
+ */
+public class Vala.UnresolvedType : DataType {
+       /**
+        * The name of the namespace containing the referred data type.
+        */
+       public string namespace_name { get; set; }
+       
+       /**
+        * The name of the referred data type.
+        */
+       public string type_name { get; set; }
+       
+       /**
+        * Specifies the rank of the array this reference is possibly referring
+        * to. "0" indicates no array.
+        */
+       public int array_rank { get; set; }
+
+       /**
+        * Specifies the level of the pointer if this is a pointer-type. "0"
+        * indicates no pointer-type.
+        */
+       public int pointer_level { get; set; }
+       
+       /**
+        * Specifies that the expression transfers ownership of its value.
+        */
+       public bool transfers_ownership { get; set; }
+       
+       /**
+        * Specifies that the expression assumes ownership if used as an lvalue
+        * in an assignment.
+        */
+       public bool takes_ownership { get; set; }
+
+       /**
+        * The weak modifier has been specified.
+        */
+       public bool is_weak { get; set; }
+
+       /**
+        * Specifies that the expression is a reference used in ref parameters.
+        */
+       public bool is_ref { get; set; }
+
+       /**
+        * Specifies that the expression is a reference used in out parameters.
+        */
+       public bool is_out { get; set; }
+       
+       /**
+        * Specifies that the expression is guaranteed not to be null.
+        */
+       public bool non_null { get; set; }
+
+       public UnresolvedType () {
+       }
+
+       /**
+        * Creates a new type reference.
+        *
+        * @param ns        optional namespace name
+        * @param type_name type symbol name
+        * @param source    reference to source code
+        * @return          newly created type reference
+        */
+       public UnresolvedType.from_name (string ns, string! type, SourceReference source = null) {
+               namespace_name = ns;
+               type_name = type;
+               source_reference = source;
+       }
+
+       /**
+        * Creates a new type reference from a code expression.
+        *
+        * @param expr   member access expression
+        * @param source reference to source code
+        * @return       newly created type reference
+        */
+       public static UnresolvedType new_from_expression (Expression! expr) {
+               string ns = null;
+               string type_name = null;
+               if (expr is MemberAccess) {
+                       UnresolvedType type_ref = null;
+               
+                       MemberAccess ma = (MemberAccess) expr;
+                       if (ma.inner != null) {
+                               if (ma.inner is MemberAccess) {
+                                       var simple = (MemberAccess) ma.inner;
+                                       type_ref = new UnresolvedType.from_name (simple.member_name, ma.member_name, ma.source_reference);
+                               }
+                       } else {
+                               type_ref = new UnresolvedType.from_name (null, ma.member_name, ma.source_reference);
+                       }
+                       
+                       if (type_ref != null) {
+                               var type_args = ma.get_type_arguments ();
+                               foreach (DataType arg in type_args) {
+                                       type_ref.add_type_argument (arg);
+                               }
+                               
+                               return type_ref;
+                       }
+               }
+               
+               Report.error (expr.source_reference, "Type reference must be simple name or member access expression");
+               return null;
+       }
+
+       public override DataType! copy () {
+               var result = new UnresolvedType ();
+               result.source_reference = source_reference;
+               result.transfers_ownership = transfers_ownership;
+               result.takes_ownership = takes_ownership;
+               result.is_out = is_out;
+               result.non_null = non_null;
+               result.namespace_name = namespace_name;
+               result.type_name = type_name;
+               result.array_rank = array_rank;
+               result.pointer_level = pointer_level;
+               result.is_ref = is_ref;
+               result.is_weak = is_weak;
+               
+               foreach (DataType arg in get_type_arguments ()) {
+                       result.add_type_argument (arg.copy ());
+               }
+               
+               return result;
+       }
+}
index dc5822e..bea885a 100644 (file)
@@ -45,9 +45,16 @@ public class Vala.VariableDeclarator : Symbol, Invokable {
        /**
         * The variable type.
         */
-       public DataType type_reference { get; set; }
+       public DataType! type_reference {
+               get { return _data_type; }
+               set {
+                       _data_type = value;
+                       _data_type.parent_node = this;
+               }
+       }
 
        private Expression _initializer;
+       private DataType _data_type;
 
        /**
         * Creates a new variable declarator.
@@ -103,4 +110,10 @@ public class Vala.VariableDeclarator : Symbol, Invokable {
                        initializer = new_node;
                }
        }
+
+       public override void replace_type (DataType! old_type, DataType! new_type) {
+               if (type_reference == old_type) {
+                       type_reference = new_type;
+               }
+       }
 }
index 817549f..c83eb38 100644 (file)
@@ -495,7 +495,7 @@ public class Vala.GIdlParser : CodeVisitor {
                                current_source_file.add_node (cl);
                        }
 
-                       var parent = new DataType ();
+                       var parent = new UnresolvedType ();
                        parent.namespace_name = "GLib";
                        parent.type_name = "Boxed";
                        cl.add_base_type (parent);
@@ -616,22 +616,22 @@ public class Vala.GIdlParser : CodeVisitor {
                }
 
                if (base_class != null) {
-                       var parent = new DataType ();
+                       var parent = new UnresolvedType ();
                        parse_type_string (parent, base_class);
                        cl.add_base_type (parent);
                } else if (node.parent != null) {
-                       var parent = new DataType ();
+                       var parent = new UnresolvedType ();
                        parse_type_string (parent, node.parent);
                        cl.add_base_type (parent);
                } else {
-                       var parent = new DataType ();
+                       var parent = new UnresolvedType ();
                        parent.namespace_name = "GLib";
                        parent.type_name = "Object";
                        cl.add_base_type (parent);
                }
                
                foreach (string iface_name in node.interfaces) {
-                       var iface = new DataType ();
+                       var iface = new UnresolvedType ();
                        parse_type_string (iface, iface_name);
                        cl.add_base_type (iface);
                }
@@ -716,7 +716,7 @@ public class Vala.GIdlParser : CodeVisitor {
                        }
                        
                        foreach (string prereq_name in node.prerequisites) {
-                               var prereq = new DataType ();
+                               var prereq = new UnresolvedType ();
                                parse_type_string (prereq, prereq_name);
                                iface.add_prerequisite (prereq);
                        }
@@ -753,8 +753,8 @@ public class Vala.GIdlParser : CodeVisitor {
                current_data_type = null;
        }
        
-       private DataType parse_type (IdlNodeType! type_node) {
-               var type = new DataType ();
+       private UnresolvedType parse_type (IdlNodeType! type_node) {
+               var type = new UnresolvedType ();
                if (type_node.tag == TypeTag.VOID) {
                        if (type_node.is_pointer) {
                                type.type_name = "pointer";
@@ -911,7 +911,7 @@ public class Vala.GIdlParser : CodeVisitor {
                return false;
        }
        
-       private void parse_type_string (DataType! type, string! n) {
+       private void parse_type_string (UnresolvedType! type, string! n) {
                var dt = cname_type_map[n];
                if (dt != null) {
                        type.namespace_name = dt.parent_symbol.name;
@@ -988,7 +988,7 @@ public class Vala.GIdlParser : CodeVisitor {
                }
        }
        
-       private DataType parse_param (IdlNodeParam! param) {
+       private UnresolvedType parse_param (IdlNodeParam! param) {
                var type = parse_type (param.type);
 
                // disable for now as null_ok not yet correctly set
@@ -1004,7 +1004,7 @@ public class Vala.GIdlParser : CodeVisitor {
                        return null;
                }
        
-               DataType return_type = null;
+               UnresolvedType return_type = null;
                if (f.result != null) {
                        return_type = parse_param (f.result);
                }
@@ -1080,6 +1080,7 @@ public class Vala.GIdlParser : CodeVisitor {
                
                bool first = true;
                FormalParameter last_param = null;
+               UnresolvedType last_param_type = null;
                foreach (weak IdlNodeParam param in f.parameters) {
                        weak IdlNode param_node = (IdlNode) param;
                        
@@ -1102,8 +1103,9 @@ public class Vala.GIdlParser : CodeVisitor {
                                m.add_error_domain (parse_type (param.type));
                                continue;
                        }
-                       
-                       var p = new FormalParameter (param_node.name, parse_param (param));
+
+                       var param_type = parse_param (param);
+                       var p = new FormalParameter (param_node.name, param_type);
                        m.add_parameter (p);
 
                        var attributes = get_attributes ("%s.%s".printf (f.symbol, param_node.name));
@@ -1112,12 +1114,12 @@ public class Vala.GIdlParser : CodeVisitor {
                                        var nv = attr.split ("=", 2);
                                        if (nv[0] == "is_array") {
                                                if (eval (nv[1]) == "1") {
-                                                       p.type_reference.array_rank = 1;
-                                                       p.type_reference.is_out = false;
+                                                       param_type.array_rank = 1;
+                                                       param_type.is_out = false;
                                                }
                                        } else if (nv[0] == "is_out") {
                                                if (eval (nv[1]) == "1") {
-                                                       p.type_reference.is_out = true;
+                                                       param_type.is_out = true;
                                                }
                                        }
                                }
@@ -1125,11 +1127,12 @@ public class Vala.GIdlParser : CodeVisitor {
 
                        if (last_param != null && p.name == "n_" + last_param.name) {
                                // last_param is array, p is array length
-                               last_param.type_reference.array_rank = 1;
-                               last_param.type_reference.is_out = false;
+                               last_param_type.array_rank = 1;
+                               last_param_type.is_out = false;
                        }
 
                        last_param = p;
+                       last_param_type = param_type;
                }
                
                if (first) {