From c73cd35812dfb0fc0075f036290436fbd28fd1d5 Mon Sep 17 00:00:00 2001 From: Juerg Billeter Date: Sun, 2 Dec 2007 22:21:56 +0000 Subject: [PATCH] move unresolved type information from DataType into new UnresolvedType 2007-12-02 Juerg Billeter * 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 --- ChangeLog | 21 +++++ gobject/valaccodegenerator.vala | 2 +- tests/Makefile.am | 2 +- vala/Makefile.am | 1 + vala/parser.y | 138 +++++++++++++++------------- vala/vala.h | 1 + vala/valaarraycreationexpression.vala | 18 +++- vala/valacallback.vala | 20 ++++- vala/valacastexpression.vala | 16 +++- vala/valacatchclause.vala | 16 +++- vala/valaclass.vala | 14 ++- vala/valacodenode.vala | 3 + vala/valacodevisitor.vala | 2 +- vala/valaconstant.vala | 16 +++- vala/valadatatype.vala | 106 ++++------------------ vala/valafield.vala | 18 +++- vala/valaforeachstatement.vala | 16 +++- vala/valaformalparameter.vala | 18 +++- vala/valainterface.vala | 10 +++ vala/valainterfacewriter.vala | 15 ++-- vala/valalocalvariabledeclaration.vala | 16 +++- vala/valamemberaccess.vala | 10 +++ vala/valamemorymanager.vala | 4 +- vala/valamethod.vala | 23 ++++- vala/valaobjectcreationexpression.vala | 16 +++- vala/valaproperty.vala | 18 +++- vala/valasignal.vala | 18 +++- vala/valastruct.vala | 10 +++ vala/valasymbolresolver.vala | 77 ++++++++++------ vala/valatypecheck.vala | 16 +++- vala/valaunresolvedtype.vala | 158 +++++++++++++++++++++++++++++++++ vala/valavariabledeclarator.vala | 15 +++- vapigen/valagidlparser.vala | 39 ++++---- 33 files changed, 637 insertions(+), 236 deletions(-) create mode 100644 vala/valaunresolvedtype.vala diff --git a/ChangeLog b/ChangeLog index 099df45..528bd74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,26 @@ 2007-12-02 Jürg Billeter + * 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 + * vala/valaaddressofexpression.vala, vala/valaassignment.vala, vala/valabinaryexpression.vala, vala/valacastexpression.vala, vala/valacodenode.vala, vala/valadostatement.vala, diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala index ef29c5e..11fcd63 100644 --- a/gobject/valaccodegenerator.vala +++ b/gobject/valaccodegenerator.vala @@ -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 diff --git a/tests/Makefile.am b/tests/Makefile.am index 0f5ddaf..c5d1f90 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 \ diff --git a/vala/Makefile.am b/vala/Makefile.am index 3b92f60..1d78a87 100644 --- a/vala/Makefile.am +++ b/vala/Makefile.am @@ -114,6 +114,7 @@ libvalacore_la_VALASOURCES = \ valatypeparameter.vala \ valatypesymbol.vala \ valaunaryexpression.vala \ + valaunresolvedtype.vala \ valavariabledeclarator.vala \ valawhilestatement.vala \ $(NULL) diff --git a/vala/parser.y b/vala/parser.y index e2458f7..0ccf94f 100644 --- a/vala/parser.y +++ b/vala/parser.y @@ -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); } } ; diff --git a/vala/vala.h b/vala/vala.h index 5fd2b84..40a2af0 100644 --- a/vala/vala.h +++ b/vala/vala.h @@ -77,5 +77,6 @@ #include #include #include +#include #include #include diff --git a/vala/valaarraycreationexpression.vala b/vala/valaarraycreationexpression.vala index 6cfd2aa..0ac0d96 100644 --- a/vala/valaarraycreationexpression.vala +++ b/vala/valaarraycreationexpression.vala @@ -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; + } + } } diff --git a/vala/valacallback.vala b/vala/valacallback.vala index ce358f2..2c28d06 100644 --- a/vala/valacallback.vala +++ b/vala/valacallback.vala @@ -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 parameters = new ArrayList (); 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; + } + } } diff --git a/vala/valacastexpression.vala b/vala/valacastexpression.vala index a42ddcd..64ae38c 100644 --- a/vala/valacastexpression.vala +++ b/vala/valacastexpression.vala @@ -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; + } + } } diff --git a/vala/valacatchclause.vala b/vala/valacatchclause.vala index db6375d..b96b35b 100644 --- a/vala/valacatchclause.vala +++ b/vala/valacatchclause.vala @@ -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; + } + } } diff --git a/vala/valaclass.vala b/vala/valaclass.vala index 404fb1e..0b089c6 100644 --- a/vala/valaclass.vala +++ b/vala/valaclass.vala @@ -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; + } + } + } } diff --git a/vala/valacodenode.vala b/vala/valacodenode.vala index c360567..d47aefd 100644 --- a/vala/valacodenode.vala +++ b/vala/valacodenode.vala @@ -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) { } diff --git a/vala/valacodevisitor.vala b/vala/valacodevisitor.vala index 6f268c9..f674104 100644 --- a/vala/valacodevisitor.vala +++ b/vala/valacodevisitor.vala @@ -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) { } /** diff --git a/vala/valaconstant.vala b/vala/valaconstant.vala index ec1d5f3..007341f 100644 --- a/vala/valaconstant.vala +++ b/vala/valaconstant.vala @@ -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; + } + } } diff --git a/vala/valadatatype.vala b/vala/valadatatype.vala index 46227da..75bb38a 100644 --- a/vala/valadatatype.vala +++ b/vala/valadatatype.vala @@ -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 type_argument_list = new ArrayList (); + private Gee.List type_argument_list = new ArrayList (); 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) 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; + } + } + } } diff --git a/vala/valafield.vala b/vala/valafield.vala index d7df138..164e5b6 100644 --- a/vala/valafield.vala +++ b/vala/valafield.vala @@ -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; + } + } } diff --git a/vala/valaforeachstatement.vala b/vala/valaforeachstatement.vala index c384df1..3c93e3c 100644 --- a/vala/valaforeachstatement.vala +++ b/vala/valaforeachstatement.vala @@ -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; + } + } } diff --git a/vala/valaformalparameter.vala b/vala/valaformalparameter.vala index d055961..7dc466b 100644 --- a/vala/valaformalparameter.vala +++ b/vala/valaformalparameter.vala @@ -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; + } + } } diff --git a/vala/valainterface.vala b/vala/valainterface.vala index b330ab3..82df7d2 100644 --- a/vala/valainterface.vala +++ b/vala/valainterface.vala @@ -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; + } + } + } } diff --git a/vala/valainterfacewriter.vala b/vala/valainterfacewriter.vala index eadad28..6fefe40 100644 --- a/vala/valainterfacewriter.vala +++ b/vala/valainterfacewriter.vala @@ -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 ("#"); } diff --git a/vala/valalocalvariabledeclaration.vala b/vala/valalocalvariabledeclaration.vala index 55a6525..13ff54b 100644 --- a/vala/valalocalvariabledeclaration.vala +++ b/vala/valalocalvariabledeclaration.vala @@ -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 variable_declarators = new ArrayList (); @@ -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; + } + } } diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala index d464d2a..5a2d468 100644 --- a/vala/valamemberaccess.vala +++ b/vala/valamemberaccess.vala @@ -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; + } + } + } } diff --git a/vala/valamemorymanager.vala b/vala/valamemorymanager.vala index 9399d22..2449c83 100644 --- a/vala/valamemorymanager.vala +++ b/vala/valamemorymanager.vala @@ -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) { diff --git a/vala/valamethod.vala b/vala/valamethod.vala index b170494..22cb69c 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -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 error_domains = new ArrayList (); + 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 get_error_domains () { return new ReadOnlyCollection (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; + } + } + } } diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala index 62ea314..6b5aa67 100644 --- a/vala/valaobjectcreationexpression.vala +++ b/vala/valaobjectcreationexpression.vala @@ -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 object_initializer = new ArrayList (); + 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; + } + } } diff --git a/vala/valaproperty.vala b/vala/valaproperty.vala index 69aeef3..fea3a46 100644 --- a/vala/valaproperty.vala +++ b/vala/valaproperty.vala @@ -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; + } + } } diff --git a/vala/valasignal.vala b/vala/valasignal.vala index 90ce8fc..bf8e20f 100644 --- a/vala/valasignal.vala +++ b/vala/valasignal.vala @@ -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; + } + } } diff --git a/vala/valastruct.vala b/vala/valastruct.vala index e8ada43..2e806e4 100644 --- a/vala/valastruct.vala +++ b/vala/valastruct.vala @@ -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; + } + } + } } diff --git a/vala/valasymbolresolver.vala b/vala/valasymbolresolver.vala index e26a5d7..c183c1a 100644 --- a/vala/valasymbolresolver.vala +++ b/vala/valasymbolresolver.vala @@ -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) { diff --git a/vala/valatypecheck.vala b/vala/valatypecheck.vala index 5f87e1c..d276f82 100644 --- a/vala/valatypecheck.vala +++ b/vala/valatypecheck.vala @@ -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 index 0000000..528d0f6 --- /dev/null +++ b/vala/valaunresolvedtype.vala @@ -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 + * Raffaele Sandrini + */ + +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; + } +} diff --git a/vala/valavariabledeclarator.vala b/vala/valavariabledeclarator.vala index dc5822e..bea885a 100644 --- a/vala/valavariabledeclarator.vala +++ b/vala/valavariabledeclarator.vala @@ -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; + } + } } diff --git a/vapigen/valagidlparser.vala b/vapigen/valagidlparser.vala index 817549f..c83eb38 100644 --- a/vapigen/valagidlparser.vala +++ b/vapigen/valagidlparser.vala @@ -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) { -- 2.7.4