+++ /dev/null
-Index: vala/valablock.vala
-===================================================================
---- vala/valablock.vala (revision 1971)
-+++ vala/valablock.vala (revision 2004)
-@@ -90,4 +90,29 @@
- stmt.accept (visitor);
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ owner = analyzer.current_symbol.scope;
-+ analyzer.current_symbol = this;
-+
-+ accept_children (analyzer);
-+
-+ foreach (LocalVariable local in get_local_variables ()) {
-+ local.active = false;
-+ }
-+
-+ foreach (Statement stmt in get_statements()) {
-+ add_error_types (stmt.get_error_types ());
-+ }
-+
-+ analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+
-+ return !error;
-+ }
- }
-Index: vala/valalocalvariable.vala
-===================================================================
---- vala/valalocalvariable.vala (revision 1971)
-+++ vala/valalocalvariable.vala (revision 2004)
-@@ -98,4 +98,96 @@
- variable_type = new_type;
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ if (initializer != null) {
-+ initializer.target_type = variable_type;
-+ }
-+
-+ accept_children (analyzer);
-+
-+ if (variable_type == null) {
-+ /* var type */
-+
-+ if (initializer == null) {
-+ error = true;
-+ Report.error (source_reference, "var declaration not allowed without initializer");
-+ return false;
-+ }
-+ if (initializer.value_type == null) {
-+ error = true;
-+ Report.error (source_reference, "var declaration not allowed with non-typed initializer");
-+ return false;
-+ }
-+
-+ variable_type = initializer.value_type.copy ();
-+ variable_type.value_owned = true;
-+ variable_type.floating_reference = false;
-+
-+ initializer.target_type = variable_type;
-+ }
-+
-+ if (initializer != null) {
-+ if (initializer.value_type == null) {
-+ if (!(initializer is MemberAccess) && !(initializer is LambdaExpression)) {
-+ error = true;
-+ Report.error (source_reference, "expression type not allowed as initializer");
-+ return false;
-+ }
-+
-+ if (initializer.symbol_reference is Method &&
-+ variable_type is DelegateType) {
-+ var m = (Method) initializer.symbol_reference;
-+ var dt = (DelegateType) variable_type;
-+ var cb = dt.delegate_symbol;
-+
-+ /* check whether method matches callback type */
-+ if (!cb.matches_method (m)) {
-+ error = true;
-+ Report.error (source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
-+ return false;
-+ }
-+
-+ initializer.value_type = variable_type;
-+ } else {
-+ error = true;
-+ Report.error (source_reference, "expression type not allowed as initializer");
-+ return false;
-+ }
-+ }
-+
-+ if (!initializer.value_type.compatible (variable_type)) {
-+ error = true;
-+ Report.error (source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (initializer.value_type.to_string (), variable_type.to_string ()));
-+ return false;
-+ }
-+
-+ if (initializer.value_type.is_disposable ()) {
-+ /* rhs transfers ownership of the expression */
-+ if (!(variable_type is PointerType) && !variable_type.value_owned) {
-+ /* lhs doesn't own the value */
-+ error = true;
-+ Report.error (source_reference, "Invalid assignment from owned expression to unowned variable");
-+ return false;
-+ }
-+ }
-+ }
-+
-+ analyzer.current_source_file.add_type_dependency (variable_type, SourceFileDependencyType.SOURCE);
-+
-+ analyzer.current_symbol.scope.add (name, this);
-+
-+ var block = (Block) analyzer.current_symbol;
-+ block.add_local_variable (this);
-+
-+ active = true;
-+
-+ return !error;
-+ }
- }
-Index: vala/valainterface.vala
-===================================================================
---- vala/valainterface.vala (revision 1971)
-+++ vala/valainterface.vala (revision 2004)
-@@ -540,4 +540,61 @@
-
- return null;
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ var old_source_file = analyzer.current_source_file;
-+ var old_symbol = analyzer.current_symbol;
-+
-+ if (source_reference != null) {
-+ analyzer.current_source_file = source_reference.file;
-+ }
-+ analyzer.current_symbol = this;
-+
-+ foreach (DataType prerequisite_reference in get_prerequisites ()) {
-+ // check whether prerequisite is at least as accessible as the interface
-+ if (!analyzer.is_type_accessible (this, prerequisite_reference)) {
-+ error = true;
-+ Report.error (source_reference, "prerequisite `%s` is less accessible than interface `%s`".printf (prerequisite_reference.to_string (), get_full_name ()));
-+ return false;
-+ }
-+
-+ analyzer.current_source_file.add_type_dependency (prerequisite_reference, SourceFileDependencyType.HEADER_FULL);
-+ }
-+
-+ /* check prerequisites */
-+ Class prereq_class;
-+ foreach (DataType prereq in get_prerequisites ()) {
-+ TypeSymbol class_or_interface = prereq.data_type;
-+ /* skip on previous errors */
-+ if (class_or_interface == null) {
-+ error = true;
-+ continue;
-+ }
-+ /* interfaces are not allowed to have multiple instantiable prerequisites */
-+ if (class_or_interface is Class) {
-+ if (prereq_class != null) {
-+ error = true;
-+ Report.error (source_reference, "%s: Interfaces cannot have multiple instantiable prerequisites (`%s' and `%s')".printf (get_full_name (), class_or_interface.get_full_name (), prereq_class.get_full_name ()));
-+ return false;
-+ }
-+
-+ prereq_class = (Class) class_or_interface;
-+ }
-+ }
-+
-+ accept_children (analyzer);
-+
-+ analyzer.current_source_file = old_source_file;
-+ analyzer.current_symbol = old_symbol;
-+
-+ return !error;
-+ }
- }
-Index: vala/valamethod.vala
-===================================================================
---- vala/valamethod.vala (revision 1971)
-+++ vala/valamethod.vala (revision 2004)
-@@ -594,4 +594,152 @@
- }
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ if (is_abstract) {
-+ if (parent_symbol is Class) {
-+ var cl = (Class) parent_symbol;
-+ if (!cl.is_abstract) {
-+ error = true;
-+ Report.error (source_reference, "Abstract methods may not be declared in non-abstract classes");
-+ return false;
-+ }
-+ } else if (!(parent_symbol is Interface)) {
-+ error = true;
-+ Report.error (source_reference, "Abstract methods may not be declared outside of classes and interfaces");
-+ return false;
-+ }
-+ } else if (is_virtual) {
-+ if (!(parent_symbol is Class) && !(parent_symbol is Interface)) {
-+ error = true;
-+ Report.error (source_reference, "Virtual methods may not be declared outside of classes and interfaces");
-+ return false;
-+ }
-+
-+ if (parent_symbol is Class) {
-+ var cl = (Class) parent_symbol;
-+ if (cl.is_compact) {
-+ Report.error (source_reference, "Virtual methods may not be declared in compact classes");
-+ return false;
-+ }
-+ }
-+ } else if (overrides) {
-+ if (!(parent_symbol is Class)) {
-+ error = true;
-+ Report.error (source_reference, "Methods may not be overridden outside of classes");
-+ return false;
-+ }
-+ }
-+
-+ if (is_abstract && body != null) {
-+ Report.error (source_reference, "Abstract methods cannot have bodies");
-+ } else if (external && body != null) {
-+ Report.error (source_reference, "Extern methods cannot have bodies");
-+ } else if (!is_abstract && !external && !external_package && body == null) {
-+ Report.error (source_reference, "Non-abstract, non-extern methods must have bodies");
-+ }
-+
-+ var old_symbol = analyzer.current_symbol;
-+ var old_return_type = analyzer.current_return_type;
-+ analyzer.current_symbol = this;
-+ analyzer.current_return_type = return_type;
-+
-+ var init_attr = get_attribute ("ModuleInit");
-+ if (init_attr != null) {
-+ source_reference.file.context.module_init_method = this;
-+ }
-+
-+ if (!is_internal_symbol ()) {
-+ if (return_type is ValueType) {
-+ analyzer.current_source_file.add_type_dependency (return_type, SourceFileDependencyType.HEADER_FULL);
-+ } else {
-+ analyzer.current_source_file.add_type_dependency (return_type, SourceFileDependencyType.HEADER_SHALLOW);
-+ }
-+ }
-+ analyzer.current_source_file.add_type_dependency (return_type, SourceFileDependencyType.SOURCE);
-+
-+ accept_children (analyzer);
-+
-+ analyzer.current_symbol = old_symbol;
-+ analyzer.current_return_type = old_return_type;
-+
-+ if (analyzer.current_symbol.parent_symbol is Method) {
-+ /* lambda expressions produce nested methods */
-+ var up_method = (Method) analyzer.current_symbol.parent_symbol;
-+ analyzer.current_return_type = up_method.return_type;
-+ }
-+
-+ if (analyzer.current_symbol is Struct) {
-+ if (is_abstract || is_virtual || overrides) {
-+ Report.error (source_reference, "A struct member `%s' cannot be marked as override, virtual, or abstract".printf (get_full_name ()));
-+ return false;
-+ }
-+ } else if (overrides && base_method == null) {
-+ Report.error (source_reference, "%s: no suitable method found to override".printf (get_full_name ()));
-+ }
-+
-+ // check whether return type is at least as accessible as the method
-+ if (!analyzer.is_type_accessible (this, return_type)) {
-+ error = true;
-+ Report.error (source_reference, "return type `%s` is less accessible than method `%s`".printf (return_type.to_string (), get_full_name ()));
-+ return false;
-+ }
-+
-+ foreach (Expression precondition in get_preconditions ()) {
-+ if (precondition.error) {
-+ // if there was an error in the precondition, skip this check
-+ error = true;
-+ return false;
-+ }
-+
-+ if (!precondition.value_type.compatible (analyzer.bool_type)) {
-+ error = true;
-+ Report.error (precondition.source_reference, "Precondition must be boolean");
-+ return false;
-+ }
-+ }
-+
-+ foreach (Expression postcondition in get_postconditions ()) {
-+ if (postcondition.error) {
-+ // if there was an error in the postcondition, skip this check
-+ error = true;
-+ return false;
-+ }
-+
-+ if (!postcondition.value_type.compatible (analyzer.bool_type)) {
-+ error = true;
-+ Report.error (postcondition.source_reference, "Postcondition must be boolean");
-+ return false;
-+ }
-+ }
-+
-+ if (tree_can_fail && name == "main") {
-+ Report.error (source_reference, "\"main\" method cannot throw errors");
-+ }
-+
-+ // check that all errors that can be thrown in the method body are declared
-+ if (body != null) {
-+ foreach (DataType body_error_type in body.get_error_types ()) {
-+ bool can_propagate_error = false;
-+ foreach (DataType method_error_type in get_error_types ()) {
-+ if (body_error_type.compatible (method_error_type)) {
-+ can_propagate_error = true;
-+ }
-+ }
-+ if (!can_propagate_error) {
-+ Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string()));
-+ }
-+ }
-+ }
-+
-+ return !error;
-+ }
- }
-Index: vala/valafield.vala
-===================================================================
---- vala/valafield.vala (revision 1971)
-+++ vala/valafield.vala (revision 2004)
-@@ -195,4 +195,44 @@
- }
- attr.add_argument ("type", new StringLiteral ("\"%s\"".printf (ctype)));
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ if (initializer != null) {
-+ initializer.target_type = field_type;
-+ }
-+
-+ accept_children (analyzer);
-+
-+ if (binding == MemberBinding.INSTANCE && parent_symbol is Interface) {
-+ error = true;
-+ Report.error (source_reference, "Interfaces may not have instance fields");
-+ return false;
-+ }
-+
-+ if (!is_internal_symbol ()) {
-+ if (field_type is ValueType) {
-+ analyzer.current_source_file.add_type_dependency (field_type, SourceFileDependencyType.HEADER_FULL);
-+ } else {
-+ analyzer.current_source_file.add_type_dependency (field_type, SourceFileDependencyType.HEADER_SHALLOW);
-+ }
-+ } else {
-+ if (parent_symbol is Namespace) {
-+ error = true;
-+ Report.error (source_reference, "Namespaces may not have private members");
-+ return false;
-+ }
-+
-+ analyzer.current_source_file.add_type_dependency (field_type, SourceFileDependencyType.SOURCE);
-+ }
-+
-+ return !error;
-+ }
- }
-Index: vala/valadostatement.vala
-===================================================================
---- vala/valadostatement.vala (revision 1971)
-+++ vala/valadostatement.vala (revision 2004)
-@@ -86,4 +86,31 @@
- condition = new_node;
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ accept_children (analyzer);
-+
-+ if (condition.error) {
-+ /* if there was an error in the condition, skip this check */
-+ error = true;
-+ return false;
-+ }
-+
-+ if (!condition.value_type.compatible (analyzer.bool_type)) {
-+ error = true;
-+ Report.error (condition.source_reference, "Condition must be boolean");
-+ return false;
-+ }
-+
-+ add_error_types (condition.get_error_types ());
-+ add_error_types (body.get_error_types ());
-+
-+ return !error;
-+ }
- }
-Index: vala/valanamespace.vala
-===================================================================
---- vala/valanamespace.vala (revision 1971)
-+++ vala/valanamespace.vala (revision 2004)
-@@ -515,4 +515,16 @@
- }
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ return !error;
-+ }
- }
-Index: vala/valawhilestatement.vala
-===================================================================
---- vala/valawhilestatement.vala (revision 1971)
-+++ vala/valawhilestatement.vala (revision 2004)
-@@ -86,4 +86,31 @@
- condition = new_node;
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ accept_children (analyzer);
-+
-+ if (condition.error) {
-+ /* if there was an error in the condition, skip this check */
-+ error = true;
-+ return false;
-+ }
-+
-+ if (!condition.value_type.compatible (analyzer.bool_type)) {
-+ error = true;
-+ Report.error (condition.source_reference, "Condition must be boolean");
-+ return false;
-+ }
-+
-+ add_error_types (condition.get_error_types ());
-+ add_error_types (body.get_error_types ());
-+
-+ return !error;
-+ }
- }
-Index: vala/valaconstant.vala
-===================================================================
---- vala/valaconstant.vala (revision 1971)
-+++ vala/valaconstant.vala (revision 2004)
-@@ -150,4 +150,29 @@
- }
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ type_reference.accept (analyzer);
-+
-+ if (!external_package) {
-+ if (initializer == null) {
-+ error = true;
-+ Report.error (source_reference, "A const field requires a initializer to be provided");
-+ } else {
-+ initializer.target_type = type_reference;
-+
-+ initializer.accept (analyzer);
-+ }
-+ }
-+
-+ return !error;
-+ }
- }
-Index: vala/valadynamicproperty.vala
-===================================================================
---- vala/valadynamicproperty.vala (revision 1971)
-+++ vala/valadynamicproperty.vala (revision 2004)
-@@ -40,4 +40,7 @@
- return new ArrayList<string> ();
- }
-
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ return true;
-+ }
- }
-Index: vala/valaforeachstatement.vala
-===================================================================
---- vala/valaforeachstatement.vala (revision 1971)
-+++ vala/valaforeachstatement.vala (revision 2004)
-@@ -134,4 +134,119 @@
- type_reference = new_type;
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ // analyze collection expression first, used for type inference
-+ collection.accept (analyzer);
-+
-+ if (collection.error) {
-+ // ignore inner error
-+ error = true;
-+ return false;
-+ } else if (collection.value_type == null) {
-+ Report.error (collection.source_reference, "invalid collection expression");
-+ error = true;
-+ return false;
-+ }
-+
-+ var collection_type = collection.value_type.copy ();
-+ collection.target_type = collection_type.copy ();
-+
-+ DataType element_data_type = null;
-+ bool element_owned = false;
-+
-+ if (collection_type.is_array ()) {
-+ var array_type = (ArrayType) collection_type;
-+ element_data_type = array_type.element_type;
-+ } else if (collection_type.compatible (analyzer.glist_type) || collection_type.compatible (analyzer.gslist_type)) {
-+ if (collection_type.get_type_arguments ().size > 0) {
-+ element_data_type = (DataType) collection_type.get_type_arguments ().get (0);
-+ }
-+ } else if (analyzer.iterable_type != null && collection_type.compatible (analyzer.iterable_type)) {
-+ element_owned = true;
-+
-+ if (analyzer.list_type == null || !collection_type.compatible (new ObjectType (analyzer.list_type))) {
-+ // don't use iterator objects for lists for performance reasons
-+ var foreach_iterator_type = new ObjectType (analyzer.iterator_type);
-+ foreach_iterator_type.value_owned = true;
-+ foreach_iterator_type.add_type_argument (type_reference);
-+ iterator_variable = new LocalVariable (foreach_iterator_type, "%s_it".printf (variable_name));
-+
-+ add_local_variable (iterator_variable);
-+ iterator_variable.active = true;
-+ }
-+
-+ var it_method = (Method) analyzer.iterable_type.data_type.scope.lookup ("iterator");
-+ if (it_method.return_type.get_type_arguments ().size > 0) {
-+ var type_arg = it_method.return_type.get_type_arguments ().get (0);
-+ if (type_arg.type_parameter != null) {
-+ element_data_type = SemanticAnalyzer.get_actual_type (collection_type, it_method, type_arg, this);
-+ } else {
-+ element_data_type = type_arg;
-+ }
-+ }
-+ } else {
-+ error = true;
-+ Report.error (source_reference, "Gee.List not iterable");
-+ return false;
-+ }
-+
-+ if (element_data_type == null) {
-+ error = true;
-+ Report.error (collection.source_reference, "missing type argument for collection");
-+ return false;
-+ }
-+
-+ // analyze element type
-+ if (type_reference == null) {
-+ // var type
-+ type_reference = element_data_type.copy ();
-+ } else if (!element_data_type.compatible (type_reference)) {
-+ error = true;
-+ Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'".printf (element_data_type.to_string (), type_reference.to_string ()));
-+ return false;
-+ } else if (element_data_type.is_disposable () && element_owned && !type_reference.value_owned) {
-+ error = true;
-+ Report.error (source_reference, "Foreach: Invalid assignment from owned expression to unowned variable");
-+ return false;
-+ }
-+
-+ analyzer.current_source_file.add_type_dependency (type_reference, SourceFileDependencyType.SOURCE);
-+
-+ element_variable = new LocalVariable (type_reference, variable_name);
-+
-+ body.scope.add (variable_name, element_variable);
-+
-+ body.add_local_variable (element_variable);
-+ element_variable.active = true;
-+
-+ // analyze body
-+ owner = analyzer.current_symbol.scope;
-+ analyzer.current_symbol = this;
-+
-+ body.accept (analyzer);
-+
-+ foreach (LocalVariable local in get_local_variables ()) {
-+ local.active = false;
-+ }
-+
-+ analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+
-+ collection_variable = new LocalVariable (collection_type, "%s_collection".printf (variable_name));
-+
-+ add_local_variable (collection_variable);
-+ collection_variable.active = true;
-+
-+
-+ add_error_types (collection.get_error_types ());
-+ add_error_types (body.get_error_types ());
-+
-+ return !error;
-+ }
- }
-Index: vala/valadeclarationstatement.vala
-===================================================================
---- vala/valadeclarationstatement.vala (revision 1971)
-+++ vala/valadeclarationstatement.vala (revision 2004)
-@@ -48,4 +48,25 @@
-
- visitor.visit_declaration_statement (this);
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ var local = declaration as LocalVariable;
-+ if (local != null && local.initializer != null) {
-+ foreach (DataType error_type in local.initializer.get_error_types ()) {
-+ // ensure we can trace back which expression may throw errors of this type
-+ var initializer_error_type = error_type.copy ();
-+ initializer_error_type.source_reference = local.initializer.source_reference;
-+
-+ add_error_type (initializer_error_type);
-+ }
-+ }
-+
-+ return !error;
-+ }
- }
-Index: vala/valaelementaccess.vala
-===================================================================
---- vala/valaelementaccess.vala (revision 1971)
-+++ vala/valaelementaccess.vala (revision 2004)
-@@ -85,4 +85,127 @@
- }
- return container.is_pure ();
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ container.accept (analyzer);
-+
-+ if (container.value_type == null) {
-+ /* don't proceed if a child expression failed */
-+ error = true;
-+ return false;
-+ }
-+
-+ var container_type = container.value_type.data_type;
-+
-+ if (container is MemberAccess && container.symbol_reference is Signal) {
-+ // signal detail access
-+ if (get_indices ().size != 1) {
-+ error = true;
-+ Report.error (source_reference, "Element access with more than one dimension is not supported for signals");
-+ return false;
-+ }
-+ get_indices ().get (0).target_type = analyzer.string_type.copy ();
-+ }
-+
-+ foreach (Expression index in get_indices ()) {
-+ index.accept (analyzer);
-+ }
-+
-+ bool index_int_type_check = true;
-+
-+ var pointer_type = container.value_type as PointerType;
-+
-+ /* assign a value_type when possible */
-+ if (container.value_type is ArrayType) {
-+ var array_type = (ArrayType) container.value_type;
-+ value_type = array_type.element_type.copy ();
-+ if (!lvalue) {
-+ value_type.value_owned = false;
-+ }
-+ } else if (pointer_type != null && !pointer_type.base_type.is_reference_type_or_type_parameter ()) {
-+ value_type = pointer_type.base_type.copy ();
-+ } else if (container_type == analyzer.string_type.data_type) {
-+ if (get_indices ().size != 1) {
-+ error = true;
-+ Report.error (source_reference, "Element access with more than one dimension is not supported for strings");
-+ return false;
-+ }
-+
-+ value_type = analyzer.unichar_type;
-+ } else if (container_type != null && analyzer.list_type != null && analyzer.map_type != null &&
-+ (container_type.is_subtype_of (analyzer.list_type) || container_type.is_subtype_of (analyzer.map_type))) {
-+ Gee.List<Expression> indices = get_indices ();
-+ if (indices.size != 1) {
-+ error = true;
-+ Report.error (source_reference, "Element access with more than one dimension is not supported for the specified type");
-+ return false;
-+ }
-+ Iterator<Expression> indices_it = indices.iterator ();
-+ indices_it.next ();
-+ var index = indices_it.get ();
-+ index_int_type_check = false;
-+
-+ // lookup symbol in interface instead of class as implemented interface methods are not in VAPI files
-+ Symbol get_sym = null;
-+ if (container_type.is_subtype_of (analyzer.list_type)) {
-+ get_sym = analyzer.list_type.scope.lookup ("get");
-+ } else if (container_type.is_subtype_of (analyzer.map_type)) {
-+ get_sym = analyzer.map_type.scope.lookup ("get");
-+ }
-+ var get_method = (Method) get_sym;
-+ Gee.List<FormalParameter> get_params = get_method.get_parameters ();
-+ Iterator<FormalParameter> get_params_it = get_params.iterator ();
-+ get_params_it.next ();
-+ var get_param = get_params_it.get ();
-+
-+ var index_type = get_param.parameter_type;
-+ if (index_type.type_parameter != null) {
-+ index_type = analyzer.get_actual_type (container.value_type, get_method, get_param.parameter_type, this);
-+ }
-+
-+ if (!index.value_type.compatible (index_type)) {
-+ error = true;
-+ Report.error (source_reference, "index expression: Cannot convert from `%s' to `%s'".printf (index.value_type.to_string (), index_type.to_string ()));
-+ return false;
-+ }
-+
-+ value_type = analyzer.get_actual_type (container.value_type, get_method, get_method.return_type, this).copy ();
-+ if (lvalue) {
-+ // get () returns owned value, set () accepts unowned value
-+ value_type.value_owned = false;
-+ }
-+ } else if (container is MemberAccess && container.symbol_reference is Signal) {
-+ index_int_type_check = false;
-+
-+ symbol_reference = container.symbol_reference;
-+ value_type = container.value_type;
-+ } else {
-+ error = true;
-+ Report.error (source_reference, "The expression `%s' does not denote an Array".printf (container.value_type.to_string ()));
-+ }
-+
-+ if (index_int_type_check) {
-+ /* check if the index is of type integer */
-+ foreach (Expression e in get_indices ()) {
-+ /* don't proceed if a child expression failed */
-+ if (e.value_type == null) {
-+ return false;
-+ }
-+
-+ /* check if the index is of type integer */
-+ if (!(e.value_type.data_type is Struct) || !((Struct) e.value_type.data_type).is_integer_type ()) {
-+ error = true;
-+ Report.error (e.source_reference, "Expression of integer type expected");
-+ }
-+ }
-+ }
-+
-+ return !error;
-+ }
- }
-Index: vala/valacatchclause.vala
-===================================================================
---- vala/valacatchclause.vala (revision 1971)
-+++ vala/valacatchclause.vala (revision 2004)
-@@ -1,4 +1,4 @@
--/* valacatchclause.vala
-+/* valacatchvala
- *
- * Copyright (C) 2007-2008 Jürg Billeter
- *
-@@ -62,7 +62,7 @@
- private DataType _data_type;
-
- /**
-- * Creates a new catch clause.
-+ * Creates a new catch
- *
- * @param type_reference error type
- * @param variable_name error variable name
-@@ -94,4 +94,27 @@
- error_type = new_type;
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ if (error_type != null) {
-+ analyzer.current_source_file.add_type_dependency (error_type, SourceFileDependencyType.SOURCE);
-+
-+ error_variable = new LocalVariable (error_type.copy (), variable_name);
-+
-+ body.scope.add (variable_name, error_variable);
-+ body.add_local_variable (error_variable);
-+ } else {
-+ error_type = new ErrorType (null, null, source_reference);
-+ }
-+
-+ accept_children (analyzer);
-+
-+ return !error;
-+ }
- }
-Index: vala/valainitializerlist.vala
-===================================================================
---- vala/valainitializerlist.vala (revision 1971)
-+++ vala/valainitializerlist.vala (revision 2004)
-@@ -1,4 +1,4 @@
--/* valainitializerlist.vala
-+/* valainitializervala
- *
- * Copyright (C) 2006-2008 Jürg Billeter, Raffaele Sandrini
- *
-@@ -31,7 +31,7 @@
- private Gee.List<Expression> initializers = new ArrayList<Expression> ();
-
- /**
-- * Appends the specified expression to this initializer list.
-+ * Appends the specified expression to this initializer
- *
- * @param expr an expression
- */
-@@ -41,7 +41,7 @@
- }
-
- /**
-- * Returns a copy of the expression list.
-+ * Returns a copy of the expression
- *
- * @return expression list
- */
-@@ -50,14 +50,14 @@
- }
-
- /**
-- * Returns the initializer count in this initializer list.
-+ * Returns the initializer count in this initializer
- */
- public int size {
- get { return initializers.size; }
- }
-
- /**
-- * Creates a new initializer list.
-+ * Creates a new initializer
- *
- * @param source_reference reference to source code
- * @return newly created initializer list
-@@ -92,4 +92,80 @@
- }
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ if (target_type == null) {
-+ error = true;
-+ Report.error (source_reference, "initializer list used for unknown type");
-+ return false;
-+ } else if (target_type is ArrayType) {
-+ /* initializer is used as array initializer */
-+ var array_type = (ArrayType) target_type;
-+
-+ foreach (Expression e in get_initializers ()) {
-+ e.target_type = array_type.element_type.copy ();
-+ }
-+ } else if (target_type.data_type is Struct) {
-+ /* initializer is used as struct initializer */
-+ var st = (Struct) target_type.data_type;
-+
-+ var field_it = st.get_fields ().iterator ();
-+ foreach (Expression e in get_initializers ()) {
-+ Field field = null;
-+ while (field == null) {
-+ if (!field_it.next ()) {
-+ error = true;
-+ Report.error (e.source_reference, "too many expressions in initializer list for `%s'".printf (target_type.to_string ()));
-+ return false;
-+ }
-+ field = field_it.get ();
-+ if (field.binding != MemberBinding.INSTANCE) {
-+ // we only initialize instance fields
-+ field = null;
-+ }
-+ }
-+
-+ e.target_type = field.field_type.copy ();
-+ if (!target_type.value_owned) {
-+ e.target_type.value_owned = false;
-+ }
-+ }
-+ } else {
-+ error = true;
-+ Report.error (source_reference, "initializer list used for `%s', which is neither array nor struct".printf (target_type.to_string ()));
-+ return false;
-+ }
-+
-+ accept_children (analyzer);
-+
-+ bool error = false;
-+ foreach (Expression e in get_initializers ()) {
-+ if (e.value_type == null) {
-+ error = true;
-+ continue;
-+ }
-+
-+ var unary = e as UnaryExpression;
-+ if (unary != null && (unary.operator == UnaryOperator.REF || unary.operator == UnaryOperator.OUT)) {
-+ // TODO check type for ref and out expressions
-+ } else if (!e.value_type.compatible (e.target_type)) {
-+ error = true;
-+ e.error = true;
-+ Report.error (e.source_reference, "Expected initializer of type `%s' but got `%s'".printf (e.target_type.to_string (), e.value_type.to_string ()));
-+ }
-+ }
-+
-+ if (!error) {
-+ /* everything seems to be correct */
-+ value_type = target_type;
-+ }
-+
-+ return !error;
-+ }
- }
-Index: vala/valaproperty.vala
-===================================================================
---- vala/valaproperty.vala (revision 1971)
-+++ vala/valaproperty.vala (revision 2004)
-@@ -34,7 +34,9 @@
- get { return _data_type; }
- set {
- _data_type = value;
-- _data_type.parent_node = this;
-+ if (value != null) {
-+ _data_type.parent_node = this;
-+ }
- }
- }
-
-@@ -409,6 +411,8 @@
-
- checked = true;
-
-+ process_attributes ();
-+
- var old_source_file = analyzer.current_source_file;
- var old_symbol = analyzer.current_symbol;
-
-Index: vala/valaerrorcode.vala
-===================================================================
---- vala/valaerrorcode.vala (revision 1971)
-+++ vala/valaerrorcode.vala (revision 2004)
-@@ -72,4 +72,16 @@
- }
- return cname;
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ accept_children (analyzer);
-+
-+ return !error;
-+ }
- }
-Index: vala/valaformalparameter.vala
-===================================================================
---- vala/valaformalparameter.vala (revision 1971)
-+++ vala/valaformalparameter.vala (revision 2004)
-@@ -174,6 +174,8 @@
-
- checked = true;
-
-+ process_attributes ();
-+
- var old_source_file = analyzer.current_source_file;
- var old_symbol = analyzer.current_symbol;
-
-Index: vala/valadeletestatement.vala
-===================================================================
---- vala/valadeletestatement.vala (revision 1971)
-+++ vala/valadeletestatement.vala (revision 2004)
-@@ -43,4 +43,26 @@
- public override void accept_children (CodeVisitor visitor) {
- expression.accept (visitor);
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ accept_children (analyzer);
-+
-+ if (expression.error) {
-+ // if there was an error in the inner expression, skip this check
-+ return false;
-+ }
-+
-+ if (!(expression.value_type is PointerType)) {
-+ error = true;
-+ Report.error (source_reference, "delete operator not supported for `%s'".printf (expression.value_type.to_string ()));
-+ }
-+
-+ return !error;
-+ }
- }
-Index: vala/valadestructor.vala
-===================================================================
---- vala/valadestructor.vala (revision 1971)
-+++ vala/valadestructor.vala (revision 2004)
-@@ -60,4 +60,21 @@
- body.accept (visitor);
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ owner = analyzer.current_symbol.scope;
-+ analyzer.current_symbol = this;
-+
-+ accept_children (analyzer);
-+
-+ analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+
-+ return !error;
-+ }
- }
-Index: vala/valaassignment.vala
-===================================================================
---- vala/valaassignment.vala (revision 1971)
-+++ vala/valaassignment.vala (revision 2004)
-@@ -1,6 +1,6 @@
- /* valaassignment.vala
- *
-- * Copyright (C) 2006-2007 Jürg Billeter
-+ * Copyright (C) 2006-2008 Jürg Billeter
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
-@@ -97,6 +97,289 @@
- public override bool is_pure () {
- return false;
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ left.lvalue = true;
-+
-+ left.accept (analyzer);
-+
-+ if (left.error) {
-+ // skip on error in inner expression
-+ error = true;
-+ return false;
-+ }
-+
-+ if (left is MemberAccess) {
-+ var ma = (MemberAccess) left;
-+
-+ if (!(ma.symbol_reference is Signal || ma.symbol_reference is DynamicProperty) && ma.value_type == null) {
-+ error = true;
-+ Report.error (source_reference, "unsupported lvalue in assignment");
-+ return false;
-+ }
-+ if (ma.prototype_access) {
-+ error = true;
-+ Report.error (source_reference, "Access to instance member `%s' denied".printf (ma.symbol_reference.get_full_name ()));
-+ return false;
-+ }
-+
-+ if (ma.error || ma.symbol_reference == null) {
-+ error = true;
-+ /* if no symbol found, skip this check */
-+ return false;
-+ }
-+
-+ if (ma.symbol_reference is DynamicSignal) {
-+ // target_type not available for dynamic signals
-+ } else if (ma.symbol_reference is Signal) {
-+ var sig = (Signal) ma.symbol_reference;
-+ right.target_type = new DelegateType (sig.get_delegate (ma.inner.value_type));
-+ } else {
-+ right.target_type = ma.value_type;
-+ }
-+ } else if (left is ElementAccess) {
-+ var ea = (ElementAccess) left;
-+
-+ if (ea.container is MemberAccess && ea.container.symbol_reference is Signal) {
-+ var ma = (MemberAccess) ea.container;
-+ var sig = (Signal) ea.container.symbol_reference;
-+ right.target_type = new DelegateType (sig.get_delegate (ma.inner.value_type));
-+ } else {
-+ right.target_type = left.value_type;
-+ }
-+ } else if (left is PointerIndirection) {
-+ right.target_type = left.value_type;
-+ } else {
-+ error = true;
-+ Report.error (source_reference, "unsupported lvalue in assignment");
-+ return false;
-+ }
-+
-+ right.accept (analyzer);
-+
-+ if (right.error) {
-+ // skip on error in inner expression
-+ error = true;
-+ return false;
-+ }
-+
-+ if (operator != AssignmentOperator.SIMPLE && left is MemberAccess) {
-+ // transform into simple assignment
-+ // FIXME: only do this if the backend doesn't support
-+ // the assignment natively
-+
-+ var ma = (MemberAccess) left;
-+
-+ if (!(ma.symbol_reference is Signal)) {
-+ var old_value = new MemberAccess (ma.inner, ma.member_name);
-+
-+ var bin = new BinaryExpression (BinaryOperator.PLUS, old_value, new ParenthesizedExpression (right, right.source_reference));
-+ bin.target_type = right.target_type;
-+ right.target_type = right.target_type.copy ();
-+ right.target_type.value_owned = false;
-+
-+ if (operator == AssignmentOperator.BITWISE_OR) {
-+ bin.operator = BinaryOperator.BITWISE_OR;
-+ } else if (operator == AssignmentOperator.BITWISE_AND) {
-+ bin.operator = BinaryOperator.BITWISE_AND;
-+ } else if (operator == AssignmentOperator.BITWISE_XOR) {
-+ bin.operator = BinaryOperator.BITWISE_XOR;
-+ } else if (operator == AssignmentOperator.ADD) {
-+ bin.operator = BinaryOperator.PLUS;
-+ } else if (operator == AssignmentOperator.SUB) {
-+ bin.operator = BinaryOperator.MINUS;
-+ } else if (operator == AssignmentOperator.MUL) {
-+ bin.operator = BinaryOperator.MUL;
-+ } else if (operator == AssignmentOperator.DIV) {
-+ bin.operator = BinaryOperator.DIV;
-+ } else if (operator == AssignmentOperator.PERCENT) {
-+ bin.operator = BinaryOperator.MOD;
-+ } else if (operator == AssignmentOperator.SHIFT_LEFT) {
-+ bin.operator = BinaryOperator.SHIFT_LEFT;
-+ } else if (operator == AssignmentOperator.SHIFT_RIGHT) {
-+ bin.operator = BinaryOperator.SHIFT_RIGHT;
-+ }
-+
-+ right = bin;
-+ right.accept (analyzer);
-+
-+ operator = AssignmentOperator.SIMPLE;
-+ }
-+ }
-+
-+ if (left.symbol_reference is Signal) {
-+ var sig = (Signal) left.symbol_reference;
-+
-+ var m = right.symbol_reference as Method;
-+
-+ if (m == null) {
-+ error = true;
-+ Report.error (right.source_reference, "unsupported expression for signal handler");
-+ return false;
-+ }
-+
-+ var dynamic_sig = sig as DynamicSignal;
-+ if (dynamic_sig != null) {
-+ bool first = true;
-+ foreach (FormalParameter param in dynamic_sig.handler.value_type.get_parameters ()) {
-+ if (first) {
-+ // skip sender parameter
-+ first = false;
-+ } else {
-+ dynamic_sig.add_parameter (param.copy ());
-+ }
-+ }
-+ right.target_type = new DelegateType (sig.get_delegate (new ObjectType ((ObjectTypeSymbol) sig.parent_symbol)));
-+ } else if (!right.value_type.compatible (right.target_type)) {
-+ var delegate_type = (DelegateType) right.target_type;
-+
-+ error = true;
-+ Report.error (right.source_reference, "method `%s' is incompatible with signal `%s', expected `%s'".printf (right.value_type.to_string (), right.target_type.to_string (), delegate_type.delegate_symbol.get_prototype_string (m.name)));
-+ return false;
-+ }
-+ } else if (left is MemberAccess) {
-+ var ma = (MemberAccess) left;
-+
-+ if (ma.symbol_reference is Property) {
-+ var prop = (Property) ma.symbol_reference;
-+
-+ var dynamic_prop = prop as DynamicProperty;
-+ if (dynamic_prop != null) {
-+ dynamic_prop.property_type = right.value_type.copy ();
-+ left.value_type = dynamic_prop.property_type.copy ();
-+ }
-+
-+ if (prop.set_accessor == null
-+ || (!prop.set_accessor.writable && !(analyzer.find_current_method () is CreationMethod || analyzer.is_in_constructor ()))) {
-+ ma.error = true;
-+ Report.error (ma.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
-+ return false;
-+ }
-+ } else if (ma.symbol_reference is LocalVariable && right.value_type == null) {
-+ var local = (LocalVariable) ma.symbol_reference;
-+
-+ if (right.symbol_reference is Method &&
-+ local.variable_type is DelegateType) {
-+ var m = (Method) right.symbol_reference;
-+ var dt = (DelegateType) local.variable_type;
-+ var cb = dt.delegate_symbol;
-+
-+ /* check whether method matches callback type */
-+ if (!cb.matches_method (m)) {
-+ error = true;
-+ Report.error (source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
-+ return false;
-+ }
-+
-+ right.value_type = local.variable_type;
-+ } else {
-+ error = true;
-+ Report.error (source_reference, "Assignment: Invalid callback assignment attempt");
-+ return false;
-+ }
-+ } else if (ma.symbol_reference is Field && right.value_type == null) {
-+ var f = (Field) ma.symbol_reference;
-+
-+ if (right.symbol_reference is Method &&
-+ f.field_type is DelegateType) {
-+ var m = (Method) right.symbol_reference;
-+ var dt = (DelegateType) f.field_type;
-+ var cb = dt.delegate_symbol;
-+
-+ /* check whether method matches callback type */
-+ if (!cb.matches_method (m)) {
-+ f.error = true;
-+ Report.error (source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
-+ return false;
-+ }
-+
-+ right.value_type = f.field_type;
-+ } else {
-+ error = true;
-+ Report.error (source_reference, "Assignment: Invalid callback assignment attempt");
-+ return false;
-+ }
-+ } else if (left.value_type != null && right.value_type != null) {
-+ /* if there was an error on either side,
-+ * i.e. {left|right}.value_type == null, skip type check */
-+
-+ if (!right.value_type.compatible (left.value_type)) {
-+ error = true;
-+ Report.error (source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (right.value_type.to_string (), left.value_type.to_string ()));
-+ return false;
-+ }
-+
-+ if (right.value_type.is_disposable ()) {
-+ /* rhs transfers ownership of the expression */
-+ if (!(left.value_type is PointerType) && !left.value_type.value_owned) {
-+ /* lhs doesn't own the value */
-+ error = true;
-+ Report.error (source_reference, "Invalid assignment from owned expression to unowned variable");
-+ }
-+ } else if (left.value_type.value_owned) {
-+ /* lhs wants to own the value
-+ * rhs doesn't transfer the ownership
-+ * code generator needs to add reference
-+ * increment calls */
-+ }
-+ }
-+ } else if (left is ElementAccess) {
-+ var ea = (ElementAccess) left;
-+
-+ if (!right.value_type.compatible (left.value_type)) {
-+ error = true;
-+ Report.error (source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (right.value_type.to_string (), left.value_type.to_string ()));
-+ return false;
-+ }
-+
-+ if (right.value_type.is_disposable ()) {
-+ /* rhs transfers ownership of the expression */
-+
-+ DataType element_type;
-+
-+ if (ea.container.value_type is ArrayType) {
-+ var array_type = (ArrayType) ea.container.value_type;
-+ element_type = array_type.element_type;
-+ } else {
-+ var args = ea.container.value_type.get_type_arguments ();
-+ assert (args.size == 1);
-+ element_type = args.get (0);
-+ }
-+
-+ if (!(element_type is PointerType) && !element_type.value_owned) {
-+ /* lhs doesn't own the value */
-+ error = true;
-+ Report.error (source_reference, "Invalid assignment from owned expression to unowned variable");
-+ return false;
-+ }
-+ } else if (left.value_type.value_owned) {
-+ /* lhs wants to own the value
-+ * rhs doesn't transfer the ownership
-+ * code generator needs to add reference
-+ * increment calls */
-+ }
-+ } else {
-+ return false;
-+ }
-+
-+ if (left.value_type != null) {
-+ value_type = left.value_type.copy ();
-+ value_type.value_owned = false;
-+ } else {
-+ value_type = null;
-+ }
-+
-+ add_error_types (left.get_error_types ());
-+ add_error_types (right.get_error_types ());
-+
-+ return !error;
-+ }
- }
-
- public enum Vala.AssignmentOperator {
-Index: vala/valalockstatement.vala
-===================================================================
---- vala/valalockstatement.vala (revision 1971)
-+++ vala/valalockstatement.vala (revision 2004)
-@@ -47,4 +47,31 @@
- body.accept (visitor);
- visitor.visit_lock_statement (this);
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ /* resource must be a member access and denote a Lockable */
-+ if (!(resource is MemberAccess && resource.symbol_reference is Lockable)) {
-+ error = true;
-+ resource.error = true;
-+ Report.error (resource.source_reference, "Expression is either not a member access or does not denote a lockable member");
-+ return false;
-+ }
-+
-+ /* parent symbol must be the current class */
-+ if (resource.symbol_reference.parent_symbol != analyzer.current_class) {
-+ error = true;
-+ resource.error = true;
-+ Report.error (resource.source_reference, "Only members of the current class are lockable");
-+ }
-+
-+ ((Lockable) resource.symbol_reference).set_lock_used (true);
-+
-+ return !error;
-+ }
- }
-Index: vala/valathrowstatement.vala
-===================================================================
---- vala/valathrowstatement.vala (revision 1971)
-+++ vala/valathrowstatement.vala (revision 2004)
-@@ -72,4 +72,24 @@
- error_expression = new_node;
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ error_expression.target_type = new ErrorType (null, null, source_reference);
-+ error_expression.target_type.value_owned = true;
-+
-+ accept_children (analyzer);
-+
-+ var error_type = error_expression.value_type.copy ();
-+ error_type.source_reference = source_reference;
-+
-+ add_error_type (error_type);
-+
-+ return !error;
-+ }
- }
-Index: vala/valamemberaccess.vala
-===================================================================
---- vala/valamemberaccess.vala (revision 1971)
-+++ vala/valamemberaccess.vala (revision 2004)
-@@ -174,4 +174,355 @@
- return false;
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ Symbol base_symbol = null;
-+ FormalParameter this_parameter = null;
-+ bool may_access_instance_members = false;
-+
-+ symbol_reference = null;
-+
-+ if (qualified) {
-+ base_symbol = analyzer.root_symbol;
-+ symbol_reference = analyzer.root_symbol.scope.lookup (member_name);
-+ } else if (inner == null) {
-+ if (member_name == "this") {
-+ if (!analyzer.is_in_instance_method ()) {
-+ error = true;
-+ Report.error (source_reference, "This access invalid outside of instance methods");
-+ return false;
-+ }
-+ }
-+
-+ base_symbol = analyzer.current_symbol;
-+
-+ var sym = analyzer.current_symbol;
-+ while (sym != null && symbol_reference == null) {
-+ if (this_parameter == null) {
-+ if (sym is CreationMethod) {
-+ var cm = (CreationMethod) sym;
-+ this_parameter = cm.this_parameter;
-+ may_access_instance_members = true;
-+ } else if (sym is Property) {
-+ var prop = (Property) sym;
-+ this_parameter = prop.this_parameter;
-+ may_access_instance_members = true;
-+ } else if (sym is Constructor) {
-+ var c = (Constructor) sym;
-+ this_parameter = c.this_parameter;
-+ may_access_instance_members = true;
-+ } else if (sym is Destructor) {
-+ var d = (Destructor) sym;
-+ this_parameter = d.this_parameter;
-+ may_access_instance_members = true;
-+ } else if (sym is Method) {
-+ var m = (Method) sym;
-+ this_parameter = m.this_parameter;
-+ may_access_instance_members = (m.binding == MemberBinding.INSTANCE);
-+ }
-+ }
-+
-+ symbol_reference = analyzer.symbol_lookup_inherited (sym, member_name);
-+ sym = sym.parent_symbol;
-+ }
-+
-+ if (symbol_reference == null) {
-+ foreach (UsingDirective ns in analyzer.current_source_file.get_using_directives ()) {
-+ var local_sym = ns.namespace_symbol.scope.lookup (member_name);
-+ if (local_sym != null) {
-+ if (symbol_reference != null) {
-+ error = true;
-+ Report.error (source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (member_name, symbol_reference.get_full_name (), local_sym.get_full_name ()));
-+ return false;
-+ }
-+ symbol_reference = local_sym;
-+ }
-+ }
-+ }
-+ } else {
-+ if (inner.error) {
-+ /* if there was an error in the inner expression, skip this check */
-+ error = true;
-+ return false;
-+ }
-+
-+ if (pointer_member_access) {
-+ var pointer_type = inner.value_type as PointerType;
-+ if (pointer_type != null && pointer_type.base_type is ValueType) {
-+ // transform foo->bar to (*foo).bar
-+ inner = new PointerIndirection (inner, source_reference);
-+ inner.accept (analyzer);
-+ pointer_member_access = false;
-+ }
-+ }
-+
-+ if (inner is MemberAccess) {
-+ var ma = (MemberAccess) inner;
-+ if (ma.prototype_access) {
-+ error = true;
-+ Report.error (source_reference, "Access to instance member `%s' denied".printf (inner.symbol_reference.get_full_name ()));
-+ return false;
-+ }
-+ }
-+
-+ if (inner is MemberAccess || inner is BaseAccess) {
-+ base_symbol = inner.symbol_reference;
-+
-+ if (symbol_reference == null && (base_symbol is Namespace || base_symbol is TypeSymbol)) {
-+ symbol_reference = base_symbol.scope.lookup (member_name);
-+ if (inner is BaseAccess) {
-+ // inner expression is base access
-+ // access to instance members of the base type possible
-+ may_access_instance_members = true;
-+ }
-+ }
-+ }
-+
-+ if (symbol_reference == null && inner.value_type != null) {
-+ if (pointer_member_access) {
-+ symbol_reference = inner.value_type.get_pointer_member (member_name);
-+ } else {
-+ if (inner.value_type.data_type != null) {
-+ base_symbol = inner.value_type.data_type;
-+ }
-+ symbol_reference = inner.value_type.get_member (member_name);
-+ }
-+ if (symbol_reference != null) {
-+ // inner expression is variable, field, or parameter
-+ // access to instance members of the corresponding type possible
-+ may_access_instance_members = true;
-+ }
-+ }
-+
-+ if (symbol_reference == null && inner.value_type != null && inner.value_type.is_dynamic) {
-+ // allow late bound members for dynamic types
-+ var dynamic_object_type = (ObjectType) inner.value_type;
-+ if (parent_node is InvocationExpression) {
-+ var invoc = (InvocationExpression) parent_node;
-+ if (invoc.call == this) {
-+ // dynamic method
-+ DataType ret_type;
-+ if (invoc.target_type != null) {
-+ ret_type = invoc.target_type.copy ();
-+ ret_type.value_owned = true;
-+ } else if (invoc.parent_node is ExpressionStatement) {
-+ ret_type = new VoidType ();
-+ } else {
-+ // expect dynamic object of the same type
-+ ret_type = inner.value_type.copy ();
-+ }
-+ var m = new DynamicMethod (inner.value_type, member_name, ret_type, source_reference);
-+ m.invocation = invoc;
-+ m.add_error_type (new ErrorType (null, null));
-+ m.access = SymbolAccessibility.PUBLIC;
-+ m.add_parameter (new FormalParameter.with_ellipsis ());
-+ dynamic_object_type.type_symbol.scope.add (null, m);
-+ symbol_reference = m;
-+ }
-+ } else if (parent_node is Assignment) {
-+ var a = (Assignment) parent_node;
-+ if (a.left == this
-+ && (a.operator == AssignmentOperator.ADD
-+ || a.operator == AssignmentOperator.SUB)) {
-+ // dynamic signal
-+ var s = new DynamicSignal (inner.value_type, member_name, new VoidType (), source_reference);
-+ s.handler = a.right;
-+ s.access = SymbolAccessibility.PUBLIC;
-+ dynamic_object_type.type_symbol.scope.add (null, s);
-+ symbol_reference = s;
-+ } else if (a.left == this) {
-+ // dynamic property assignment
-+ var prop = new DynamicProperty (inner.value_type, member_name, source_reference);
-+ prop.access = SymbolAccessibility.PUBLIC;
-+ prop.set_accessor = new PropertyAccessor (false, true, false, null, prop.source_reference);
-+ prop.set_accessor.access = SymbolAccessibility.PUBLIC;
-+ prop.owner = inner.value_type.data_type.scope;
-+ dynamic_object_type.type_symbol.scope.add (null, prop);
-+ symbol_reference = prop;
-+ }
-+ }
-+ if (symbol_reference == null) {
-+ // dynamic property read access
-+ var prop = new DynamicProperty (inner.value_type, member_name, source_reference);
-+ if (target_type != null) {
-+ prop.property_type = target_type;
-+ } else {
-+ // expect dynamic object of the same type
-+ prop.property_type = inner.value_type.copy ();
-+ }
-+ prop.access = SymbolAccessibility.PUBLIC;
-+ prop.get_accessor = new PropertyAccessor (true, false, false, null, prop.source_reference);
-+ prop.get_accessor.access = SymbolAccessibility.PUBLIC;
-+ prop.owner = inner.value_type.data_type.scope;
-+ dynamic_object_type.type_symbol.scope.add (null, prop);
-+ symbol_reference = prop;
-+ }
-+ if (symbol_reference != null) {
-+ may_access_instance_members = true;
-+ }
-+ }
-+ }
-+
-+ if (symbol_reference == null) {
-+ error = true;
-+
-+ string base_type_name = "(null)";
-+ if (inner != null && inner.value_type != null) {
-+ base_type_name = inner.value_type.to_string ();
-+ } else if (base_symbol != null) {
-+ base_type_name = base_symbol.get_full_name ();
-+ }
-+
-+ Report.error (source_reference, "The name `%s' does not exist in the context of `%s'".printf (member_name, base_type_name));
-+ return false;
-+ }
-+
-+ var member = symbol_reference;
-+ var access = SymbolAccessibility.PUBLIC;
-+ bool instance = false;
-+ bool klass = false;
-+ if (member is Field) {
-+ var f = (Field) member;
-+ access = f.access;
-+ instance = (f.binding == MemberBinding.INSTANCE);
-+ klass = (f.binding == MemberBinding.CLASS);
-+ } else if (member is Method) {
-+ var m = (Method) member;
-+ access = m.access;
-+ if (!(m is CreationMethod)) {
-+ instance = (m.binding == MemberBinding.INSTANCE);
-+ }
-+ klass = (m.binding == MemberBinding.CLASS);
-+ } else if (member is Property) {
-+ var prop = (Property) member;
-+ if (!prop.check (analyzer)) {
-+ error = true;
-+ return false;
-+ }
-+ access = prop.access;
-+ if (lvalue) {
-+ if (prop.set_accessor == null) {
-+ error = true;
-+ Report.error (source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
-+ return false;
-+ }
-+ if (prop.access == SymbolAccessibility.PUBLIC) {
-+ access = prop.set_accessor.access;
-+ } else if (prop.access == SymbolAccessibility.PROTECTED
-+ && prop.set_accessor.access != SymbolAccessibility.PUBLIC) {
-+ access = prop.set_accessor.access;
-+ }
-+ } else {
-+ if (prop.get_accessor == null) {
-+ error = true;
-+ Report.error (source_reference, "Property `%s' is write-only".printf (prop.get_full_name ()));
-+ return false;
-+ }
-+ if (prop.access == SymbolAccessibility.PUBLIC) {
-+ access = prop.get_accessor.access;
-+ } else if (prop.access == SymbolAccessibility.PROTECTED
-+ && prop.get_accessor.access != SymbolAccessibility.PUBLIC) {
-+ access = prop.get_accessor.access;
-+ }
-+ }
-+ instance = (prop.binding == MemberBinding.INSTANCE);
-+ } else if (member is Signal) {
-+ instance = true;
-+ }
-+
-+ if (access == SymbolAccessibility.PRIVATE) {
-+ var target_type = member.parent_symbol;
-+
-+ bool in_target_type = false;
-+ for (Symbol this_symbol = analyzer.current_symbol; this_symbol != null; this_symbol = this_symbol.parent_symbol) {
-+ if (target_type == this_symbol) {
-+ in_target_type = true;
-+ break;
-+ }
-+ }
-+
-+ if (!in_target_type) {
-+ error = true;
-+ Report.error (source_reference, "Access to private member `%s' denied".printf (member.get_full_name ()));
-+ return false;
-+ }
-+ }
-+ if ((instance || klass) && !may_access_instance_members) {
-+ prototype_access = true;
-+
-+ if (symbol_reference is Method) {
-+ // also set static type for prototype access
-+ // required when using instance methods as delegates in constants
-+ // TODO replace by MethodPrototype
-+ value_type = analyzer.get_value_type_for_symbol (symbol_reference, lvalue);
-+ } else if (symbol_reference is Field) {
-+ value_type = new FieldPrototype ((Field) symbol_reference);
-+ }
-+ } else {
-+ // implicit this access
-+ if (instance && inner == null) {
-+ inner = new MemberAccess (null, "this", source_reference);
-+ inner.value_type = this_parameter.parameter_type.copy ();
-+ inner.symbol_reference = this_parameter;
-+ }
-+
-+ value_type = analyzer.get_value_type_for_symbol (symbol_reference, lvalue);
-+
-+ // resolve generic return values
-+ if (value_type != null && value_type.type_parameter != null) {
-+ if (inner != null) {
-+ value_type = analyzer.get_actual_type (inner.value_type, symbol_reference, value_type, this);
-+ if (value_type == null) {
-+ return false;
-+ }
-+ }
-+ }
-+
-+ if (symbol_reference is Method) {
-+ var m = (Method) symbol_reference;
-+
-+ Method base_method;
-+ if (m.base_method != null) {
-+ base_method = m.base_method;
-+ } else if (m.base_interface_method != null) {
-+ base_method = m.base_interface_method;
-+ } else {
-+ base_method = m;
-+ }
-+
-+ if (instance && base_method.parent_symbol != null) {
-+ inner.target_type = analyzer.get_data_type_for_symbol ((TypeSymbol) base_method.parent_symbol);
-+ }
-+ } else if (symbol_reference is Property) {
-+ var prop = (Property) symbol_reference;
-+
-+ Property base_property;
-+ if (prop.base_property != null) {
-+ base_property = prop.base_property;
-+ } else if (prop.base_interface_property != null) {
-+ base_property = prop.base_interface_property;
-+ } else {
-+ base_property = prop;
-+ }
-+
-+ if (instance && base_property.parent_symbol != null) {
-+ inner.target_type = analyzer.get_data_type_for_symbol ((TypeSymbol) base_property.parent_symbol);
-+ }
-+ } else if ((symbol_reference is Field
-+ || symbol_reference is Signal)
-+ && instance && symbol_reference.parent_symbol != null) {
-+ inner.target_type = analyzer.get_data_type_for_symbol ((TypeSymbol) symbol_reference.parent_symbol);
-+ }
-+ }
-+
-+ analyzer.current_source_file.add_symbol_dependency (symbol_reference, SourceFileDependencyType.SOURCE);
-+
-+ return !error;
-+ }
- }
-Index: vala/valaenumvalue.vala
-===================================================================
---- vala/valaenumvalue.vala (revision 1971)
-+++ vala/valaenumvalue.vala (revision 2004)
-@@ -128,4 +128,18 @@
- public void set_cname (string cname) {
- this.cname = cname;
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ accept_children (analyzer);
-+
-+ return !error;
-+ }
- }
-Index: vala/valabinaryexpression.vala
-===================================================================
---- vala/valabinaryexpression.vala (revision 1971)
-+++ vala/valabinaryexpression.vala (revision 2004)
-@@ -20,7 +20,7 @@
- * Jürg Billeter <j@bitron.ch>
- */
-
--using GLib;
-+using Gee;
-
- /**
- * Represents an expression with two operands in the source code.
-@@ -137,6 +137,169 @@
- public override bool is_non_null () {
- return left.is_non_null () && right.is_non_null ();
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ if (left.error || right.error) {
-+ /* if there were any errors in inner expressions, skip type check */
-+ error = true;
-+ return false;
-+ }
-+
-+ if (left.value_type == null) {
-+ Report.error (left.source_reference, "invalid left operand");
-+ error = true;
-+ return false;
-+ }
-+
-+ if (operator != BinaryOperator.IN && right.value_type == null) {
-+ Report.error (right.source_reference, "invalid right operand");
-+ error = true;
-+ return false;
-+ }
-+
-+ if (left.value_type.data_type == analyzer.string_type.data_type
-+ && operator == BinaryOperator.PLUS) {
-+ // string concatenation
-+
-+ if (right.value_type == null || right.value_type.data_type != analyzer.string_type.data_type) {
-+ error = true;
-+ Report.error (source_reference, "Operands must be strings");
-+ return false;
-+ }
-+
-+ value_type = analyzer.string_type.copy ();
-+ if (left.is_constant () && right.is_constant ()) {
-+ value_type.value_owned = false;
-+ } else {
-+ value_type.value_owned = true;
-+ }
-+ } else if (operator == BinaryOperator.PLUS
-+ || operator == BinaryOperator.MINUS
-+ || operator == BinaryOperator.MUL
-+ || operator == BinaryOperator.DIV) {
-+ // check for pointer arithmetic
-+ if (left.value_type is PointerType) {
-+ var offset_type = right.value_type.data_type as Struct;
-+ if (offset_type != null && offset_type.is_integer_type ()) {
-+ if (operator == BinaryOperator.PLUS
-+ || operator == BinaryOperator.MINUS) {
-+ // pointer arithmetic: pointer +/- offset
-+ value_type = left.value_type.copy ();
-+ }
-+ } else if (right.value_type is PointerType) {
-+ // pointer arithmetic: pointer - pointer
-+ value_type = analyzer.size_t_type;
-+ }
-+ }
-+
-+ if (value_type == null) {
-+ value_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
-+ }
-+
-+ if (value_type == null) {
-+ error = true;
-+ Report.error (source_reference, "Arithmetic operation not supported for types `%s' and `%s'".printf (left.value_type.to_string (), right.value_type.to_string ()));
-+ return false;
-+ }
-+ } else if (operator == BinaryOperator.MOD
-+ || operator == BinaryOperator.SHIFT_LEFT
-+ || operator == BinaryOperator.SHIFT_RIGHT
-+ || operator == BinaryOperator.BITWISE_XOR) {
-+ value_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
-+
-+ if (value_type == null) {
-+ error = true;
-+ Report.error (source_reference, "Arithmetic operation not supported for types `%s' and `%s'".printf (left.value_type.to_string (), right.value_type.to_string ()));
-+ return false;
-+ }
-+ } else if (operator == BinaryOperator.LESS_THAN
-+ || operator == BinaryOperator.GREATER_THAN
-+ || operator == BinaryOperator.LESS_THAN_OR_EQUAL
-+ || operator == BinaryOperator.GREATER_THAN_OR_EQUAL) {
-+ if (left.value_type.compatible (analyzer.string_type)
-+ && right.value_type.compatible (analyzer.string_type)) {
-+ // string comparison
-+ } else if (left.value_type is PointerType && right.value_type is PointerType) {
-+ // pointer arithmetic
-+ } else {
-+ var resulting_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
-+
-+ if (resulting_type == null) {
-+ error = true;
-+ Report.error (source_reference, "Relational operation not supported for types `%s' and `%s'".printf (left.value_type.to_string (), right.value_type.to_string ()));
-+ return false;
-+ }
-+ }
-+
-+ value_type = analyzer.bool_type;
-+ } else if (operator == BinaryOperator.EQUALITY
-+ || operator == BinaryOperator.INEQUALITY) {
-+ /* relational operation */
-+
-+ if (!right.value_type.compatible (left.value_type)
-+ && !left.value_type.compatible (right.value_type)) {
-+ Report.error (source_reference, "Equality operation: `%s' and `%s' are incompatible".printf (right.value_type.to_string (), left.value_type.to_string ()));
-+ error = true;
-+ return false;
-+ }
-+
-+ if (left.value_type.compatible (analyzer.string_type)
-+ && right.value_type.compatible (analyzer.string_type)) {
-+ // string comparison
-+ }
-+
-+ value_type = analyzer.bool_type;
-+ } else if (operator == BinaryOperator.BITWISE_AND
-+ || operator == BinaryOperator.BITWISE_OR) {
-+ // integer type or flags type
-+
-+ value_type = left.value_type;
-+ } else if (operator == BinaryOperator.AND
-+ || operator == BinaryOperator.OR) {
-+ if (!left.value_type.compatible (analyzer.bool_type) || !right.value_type.compatible (analyzer.bool_type)) {
-+ error = true;
-+ Report.error (source_reference, "Operands must be boolean");
-+ }
-+
-+ value_type = analyzer.bool_type;
-+ } else if (operator == BinaryOperator.IN) {
-+ // integer type or flags type or collection/map
-+
-+ /* handle collections and maps */
-+ var container_type = right.value_type.data_type;
-+
-+ if ((analyzer.collection_type != null && container_type.is_subtype_of (analyzer.collection_type))
-+ || (analyzer.map_type != null && container_type.is_subtype_of (analyzer.map_type))) {
-+ Symbol contains_sym = null;
-+ if (container_type.is_subtype_of (analyzer.collection_type)) {
-+ contains_sym = analyzer.collection_type.scope.lookup ("contains");
-+ } else if (container_type.is_subtype_of (analyzer.map_type)) {
-+ contains_sym = analyzer.map_type.scope.lookup ("contains");
-+ }
-+ var contains_method = (Method) contains_sym;
-+ Gee.List<FormalParameter> contains_params = contains_method.get_parameters ();
-+ Iterator<FormalParameter> contains_params_it = contains_params.iterator ();
-+ contains_params_it.next ();
-+ var contains_param = contains_params_it.get ();
-+
-+ var key_type = analyzer.get_actual_type (right.value_type, contains_method, contains_param.parameter_type, this);
-+ left.target_type = key_type;
-+ }
-+
-+ value_type = analyzer.bool_type;
-+
-+ } else {
-+ assert_not_reached ();
-+ }
-+
-+ return !error;
-+ }
- }
-
- public enum Vala.BinaryOperator {
-Index: vala/valacreationmethod.vala
-===================================================================
---- vala/valacreationmethod.vala (revision 1971)
-+++ vala/valacreationmethod.vala (revision 2004)
-@@ -114,4 +114,42 @@
- return "%s%s_%s".printf (parent.get_lower_case_cprefix (), infix, name);
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ if (type_name != null && type_name != analyzer.current_symbol.name) {
-+ // type_name is null for constructors generated by GIdlParser
-+ Report.error (source_reference, "missing return type in method `%s.%s´".printf (analyzer.current_symbol.get_full_name (), type_name));
-+ error = true;
-+ return false;
-+ }
-+
-+ analyzer.current_symbol = this;
-+ analyzer.current_return_type = return_type;
-+
-+ accept_children (analyzer);
-+
-+ analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+ analyzer.current_return_type = null;
-+
-+ if (analyzer.current_symbol.parent_symbol is Method) {
-+ /* lambda expressions produce nested methods */
-+ var up_method = (Method) analyzer.current_symbol.parent_symbol;
-+ analyzer.current_return_type = up_method.return_type;
-+ }
-+
-+ if (is_abstract || is_virtual || overrides) {
-+ Report.error (source_reference, "The creation method `%s' cannot be marked as override, virtual, or abstract".printf (get_full_name ()));
-+ return false;
-+ }
-+
-+ return !error;
-+ }
- }
-Index: vala/valadelegate.vala
-===================================================================
---- vala/valadelegate.vala (revision 1971)
-+++ vala/valadelegate.vala (revision 2004)
-@@ -327,4 +327,18 @@
-
- return str;
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ accept_children (analyzer);
-+
-+ return !error;
-+ }
- }
-Index: vala/valaobjectcreationexpression.vala
-===================================================================
---- vala/valaobjectcreationexpression.vala (revision 1971)
-+++ vala/valaobjectcreationexpression.vala (revision 2004)
-@@ -149,4 +149,201 @@
- type_reference = new_type;
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ if (member_name != null) {
-+ member_name.accept (analyzer);
-+ }
-+
-+ TypeSymbol type = null;
-+
-+ if (type_reference == null) {
-+ if (member_name == null) {
-+ error = true;
-+ Report.error (source_reference, "Incomplete object creation expression");
-+ return false;
-+ }
-+
-+ if (member_name.symbol_reference == null) {
-+ error = true;
-+ return false;
-+ }
-+
-+ var constructor_sym = member_name.symbol_reference;
-+ var type_sym = member_name.symbol_reference;
-+
-+ var type_args = member_name.get_type_arguments ();
-+
-+ if (constructor_sym is Method) {
-+ type_sym = constructor_sym.parent_symbol;
-+
-+ var constructor = (Method) constructor_sym;
-+ if (!(constructor_sym is CreationMethod)) {
-+ error = true;
-+ Report.error (source_reference, "`%s' is not a creation method".printf (constructor.get_full_name ()));
-+ return false;
-+ }
-+
-+ symbol_reference = constructor;
-+
-+ // inner expression can also be base access when chaining constructors
-+ var ma = member_name.inner as MemberAccess;
-+ if (ma != null) {
-+ type_args = ma.get_type_arguments ();
-+ }
-+ }
-+
-+ if (type_sym is Class) {
-+ type = (TypeSymbol) type_sym;
-+ type_reference = new ObjectType ((Class) type);
-+ } else if (type_sym is Struct) {
-+ type = (TypeSymbol) type_sym;
-+ type_reference = new ValueType (type);
-+ } else if (type_sym is ErrorCode) {
-+ type_reference = new ErrorType ((ErrorDomain) type_sym.parent_symbol, (ErrorCode) type_sym, source_reference);
-+ symbol_reference = type_sym;
-+ } else {
-+ error = true;
-+ Report.error (source_reference, "`%s' is not a class, struct, or error code".printf (type_sym.get_full_name ()));
-+ return false;
-+ }
-+
-+ foreach (DataType type_arg in type_args) {
-+ type_reference.add_type_argument (type_arg);
-+
-+ analyzer.current_source_file.add_type_dependency (type_arg, SourceFileDependencyType.SOURCE);
-+ }
-+ } else {
-+ type = type_reference.data_type;
-+ }
-+
-+ analyzer.current_source_file.add_symbol_dependency (type, SourceFileDependencyType.SOURCE);
-+
-+ value_type = type_reference.copy ();
-+ value_type.value_owned = true;
-+
-+ int given_num_type_args = type_reference.get_type_arguments ().size;
-+ int expected_num_type_args = 0;
-+
-+ if (type is Class) {
-+ var cl = (Class) type;
-+
-+ expected_num_type_args = cl.get_type_parameters ().size;
-+
-+ if (struct_creation) {
-+ error = true;
-+ Report.error (source_reference, "syntax error, use `new' to create new objects");
-+ return false;
-+ }
-+
-+ if (cl.is_abstract) {
-+ value_type = null;
-+ error = true;
-+ Report.error (source_reference, "Can't create instance of abstract class `%s'".printf (cl.get_full_name ()));
-+ return false;
-+ }
-+
-+ if (symbol_reference == null) {
-+ symbol_reference = cl.default_construction_method;
-+ }
-+
-+ while (cl != null) {
-+ if (cl == analyzer.initially_unowned_type) {
-+ value_type.floating_reference = true;
-+ break;
-+ }
-+
-+ cl = cl.base_class;
-+ }
-+ } else if (type is Struct) {
-+ var st = (Struct) type;
-+
-+ expected_num_type_args = st.get_type_parameters ().size;
-+
-+ if (!struct_creation) {
-+ Report.warning (source_reference, "deprecated syntax, don't use `new' to initialize structs");
-+ }
-+
-+ if (symbol_reference == null) {
-+ symbol_reference = st.default_construction_method;
-+ }
-+ }
-+
-+ if (expected_num_type_args > given_num_type_args) {
-+ error = true;
-+ Report.error (source_reference, "too few type arguments");
-+ return false;
-+ } else if (expected_num_type_args < given_num_type_args) {
-+ error = true;
-+ Report.error (source_reference, "too many type arguments");
-+ return false;
-+ }
-+
-+ if (symbol_reference == null && get_argument_list ().size != 0) {
-+ value_type = null;
-+ error = true;
-+ Report.error (source_reference, "No arguments allowed when constructing type `%s'".printf (type.get_full_name ()));
-+ return false;
-+ }
-+
-+ if (symbol_reference is Method) {
-+ var m = (Method) symbol_reference;
-+
-+ var args = get_argument_list ();
-+ Iterator<Expression> arg_it = args.iterator ();
-+ foreach (FormalParameter param in m.get_parameters ()) {
-+ if (param.ellipsis) {
-+ break;
-+ }
-+
-+ if (arg_it.next ()) {
-+ Expression arg = arg_it.get ();
-+
-+ /* store expected type for callback parameters */
-+ arg.target_type = param.parameter_type;
-+ }
-+ }
-+
-+ foreach (Expression arg in args) {
-+ arg.accept (analyzer);
-+ }
-+
-+ analyzer.check_arguments (this, new MethodType (m), m.get_parameters (), args);
-+
-+ foreach (DataType error_type in m.get_error_types ()) {
-+ // ensure we can trace back which expression may throw errors of this type
-+ var call_error_type = error_type.copy ();
-+ call_error_type.source_reference = source_reference;
-+
-+ add_error_type (call_error_type);
-+ }
-+ } else if (type_reference is ErrorType) {
-+ accept_children (analyzer);
-+
-+ if (get_argument_list ().size == 0) {
-+ error = true;
-+ Report.error (source_reference, "Too few arguments, errors need at least 1 argument");
-+ } else {
-+ Iterator<Expression> arg_it = get_argument_list ().iterator ();
-+ arg_it.next ();
-+ var ex = arg_it.get ();
-+ if (ex.value_type == null || !ex.value_type.compatible (analyzer.string_type)) {
-+ error = true;
-+ Report.error (source_reference, "Invalid type for argument 1");
-+ }
-+ }
-+ }
-+
-+ foreach (MemberInitializer init in get_object_initializer ()) {
-+ analyzer.visit_member_initializer (init, type_reference);
-+ }
-+
-+ return !error;
-+ }
- }
-Index: vala/valaerrordomain.vala
-===================================================================
---- vala/valaerrordomain.vala (revision 1971)
-+++ vala/valaerrordomain.vala (revision 2004)
-@@ -215,4 +215,18 @@
- public override string? get_set_value_function () {
- return "g_value_set_pointer";
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ accept_children (analyzer);
-+
-+ return !error;
-+ }
- }
-Index: vala/valaifstatement.vala
-===================================================================
---- vala/valaifstatement.vala (revision 1971)
-+++ vala/valaifstatement.vala (revision 2004)
-@@ -86,4 +86,35 @@
- condition = new_node;
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ accept_children (analyzer);
-+
-+ if (condition.error) {
-+ /* if there was an error in the condition, skip this check */
-+ error = true;
-+ return false;
-+ }
-+
-+ if (!condition.value_type.compatible (analyzer.bool_type)) {
-+ error = true;
-+ Report.error (condition.source_reference, "Condition must be boolean");
-+ return false;
-+ }
-+
-+ add_error_types (condition.get_error_types ());
-+ add_error_types (true_statement.get_error_types ());
-+
-+ if (false_statement != null) {
-+ add_error_types (false_statement.get_error_types ());
-+ }
-+
-+ return !error;
-+ }
- }
-Index: vala/valaswitchsection.vala
-===================================================================
---- vala/valaswitchsection.vala (revision 1971)
-+++ vala/valaswitchsection.vala (revision 2004)
-@@ -80,4 +80,31 @@
- st.accept (visitor);
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ foreach (SwitchLabel label in get_labels ()) {
-+ label.accept (analyzer);
-+ }
-+
-+ owner = analyzer.current_symbol.scope;
-+ analyzer.current_symbol = this;
-+
-+ foreach (Statement st in get_statements ()) {
-+ st.accept (analyzer);
-+ }
-+
-+ foreach (LocalVariable local in get_local_variables ()) {
-+ local.active = false;
-+ }
-+
-+ analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+
-+ return !error;
-+ }
- }
-Index: vala/valaenum.vala
-===================================================================
---- vala/valaenum.vala (revision 1971)
-+++ vala/valaenum.vala (revision 2004)
-@@ -289,4 +289,26 @@
- public override string? get_default_value () {
- return "0";
- }
-+
-+ public override string? get_type_signature () {
-+ if (is_flags) {
-+ return "u";
-+ } else {
-+ return "i";
-+ }
-+ }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ accept_children (analyzer);
-+
-+ return !error;
-+ }
- }
-Index: vala/valapropertyaccessor.vala
-===================================================================
---- vala/valapropertyaccessor.vala (revision 1971)
-+++ vala/valapropertyaccessor.vala (revision 2004)
-@@ -131,4 +131,55 @@
- }
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ var old_return_type = analyzer.current_return_type;
-+ if (readable) {
-+ analyzer.current_return_type = prop.property_type;
-+ } else {
-+ // void
-+ analyzer.current_return_type = new VoidType ();
-+ }
-+
-+ if (!prop.external_package) {
-+ if (body == null && !prop.interface_only && !prop.is_abstract) {
-+ /* no accessor body specified, insert default body */
-+
-+ if (prop.parent_symbol is Interface) {
-+ error = true;
-+ Report.error (source_reference, "Automatic properties can't be used in interfaces");
-+ return false;
-+ }
-+ automatic_body = true;
-+ body = new Block (source_reference);
-+ var ma = new MemberAccess.simple ("_%s".printf (prop.name), source_reference);
-+ if (readable) {
-+ body.add_statement (new ReturnStatement (ma, source_reference));
-+ } else {
-+ var assignment = new Assignment (ma, new MemberAccess.simple ("value", source_reference), AssignmentOperator.SIMPLE, source_reference);
-+ body.add_statement (new ExpressionStatement (assignment));
-+ }
-+ }
-+
-+ if (body != null && (writable || construction)) {
-+ var value_type = prop.property_type.copy ();
-+ value_parameter = new FormalParameter ("value", value_type, source_reference);
-+ body.scope.add (value_parameter.name, value_parameter);
-+ }
-+ }
-+
-+ accept_children (analyzer);
-+
-+ analyzer.current_return_type = old_return_type;
-+
-+ return !error;
-+ }
- }
-Index: vala/valaobjecttype.vala
-===================================================================
---- vala/valaobjecttype.vala (revision 1971)
-+++ vala/valaobjecttype.vala (revision 2004)
-@@ -98,4 +98,8 @@
- return null;
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ return type_symbol.check (analyzer);
-+ }
- }
-Index: vala/valasemanticanalyzer.vala
-===================================================================
---- vala/valasemanticanalyzer.vala (revision 1971)
-+++ vala/valasemanticanalyzer.vala (revision 2004)
-@@ -30,46 +30,44 @@
- public class Vala.SemanticAnalyzer : CodeVisitor {
- public CodeContext context { get; set; }
-
-- Symbol root_symbol;
-+ public Symbol root_symbol;
- public Symbol current_symbol { get; set; }
- public SourceFile current_source_file { get; set; }
-- DataType current_return_type;
-- Class current_class;
-- Struct current_struct;
-+ public DataType current_return_type;
-+ public Class current_class;
-+ public Struct current_struct;
-
-- Gee.List<UsingDirective> current_using_directives;
-+ public DataType bool_type;
-+ public DataType string_type;
-+ public DataType uchar_type;
-+ public DataType short_type;
-+ public DataType ushort_type;
-+ public DataType int_type;
-+ public DataType uint_type;
-+ public DataType long_type;
-+ public DataType ulong_type;
-+ public DataType size_t_type;
-+ public DataType ssize_t_type;
-+ public DataType int8_type;
-+ public DataType unichar_type;
-+ public DataType double_type;
-+ public DataType type_type;
-+ public Class object_type;
-+ public TypeSymbol initially_unowned_type;
-+ public DataType glist_type;
-+ public DataType gslist_type;
-+ public Class gerror_type;
-+ public DataType iterable_type;
-+ public Interface iterator_type;
-+ public Interface list_type;
-+ public Interface collection_type;
-+ public Interface map_type;
-
-- DataType bool_type;
-- DataType string_type;
-- DataType uchar_type;
-- DataType short_type;
-- DataType ushort_type;
-- DataType int_type;
-- DataType uint_type;
-- DataType long_type;
-- DataType ulong_type;
-- DataType size_t_type;
-- DataType ssize_t_type;
-- DataType int8_type;
-- DataType unichar_type;
-- DataType double_type;
-- DataType type_type;
-- Class object_type;
-- TypeSymbol initially_unowned_type;
-- DataType glist_type;
-- DataType gslist_type;
-- Class gerror_type;
-- DataType iterable_type;
-- Interface iterator_type;
-- Interface list_type;
-- Interface collection_type;
-- Interface map_type;
--
- private int next_lambda_id = 0;
-
- // keep replaced alive to make sure they remain valid
- // for the whole execution of CodeNode.accept
-- Gee.List<CodeNode> replaced_nodes = new ArrayList<CodeNode> ();
-+ public Gee.List<CodeNode> replaced_nodes = new ArrayList<CodeNode> ();
-
- public SemanticAnalyzer () {
- }
-@@ -129,499 +127,65 @@
-
- public override void visit_source_file (SourceFile file) {
- current_source_file = file;
-- current_using_directives = file.get_using_directives ();
-
- next_lambda_id = 0;
-
- file.accept_children (this);
--
-- current_using_directives = null;
- }
-
- public override void visit_namespace (Namespace ns) {
-- ns.process_attributes ();
-+ ns.check (this);
- }
-
- public override void visit_class (Class cl) {
-- cl.process_attributes ();
--
-- current_symbol = cl;
-- current_class = cl;
--
-- foreach (DataType base_type_reference in cl.get_base_types ()) {
-- // check whether base type is at least as accessible as the class
-- if (!is_type_accessible (cl, base_type_reference)) {
-- cl.error = true;
-- Report.error (cl.source_reference, "base type `%s` is less accessible than class `%s`".printf (base_type_reference.to_string (), cl.get_full_name ()));
-- return;
-- }
--
-- current_source_file.add_type_dependency (base_type_reference, SourceFileDependencyType.HEADER_FULL);
-- }
--
-- cl.accept_children (this);
--
-- /* compact classes cannot implement interfaces */
-- if (cl.is_compact) {
-- foreach (DataType base_type in cl.get_base_types ()) {
-- if (base_type.data_type is Interface) {
-- cl.error = true;
-- Report.error (cl.source_reference, "compact classes `%s` may not implement interfaces".printf (cl.get_full_name ()));
-- }
-- }
-- }
--
-- /* gather all prerequisites */
-- Gee.List<TypeSymbol> prerequisites = new ArrayList<TypeSymbol> ();
-- foreach (DataType base_type in cl.get_base_types ()) {
-- if (base_type.data_type is Interface) {
-- get_all_prerequisites ((Interface) base_type.data_type, prerequisites);
-- }
-- }
-- /* check whether all prerequisites are met */
-- Gee.List<string> missing_prereqs = new ArrayList<string> ();
-- foreach (TypeSymbol prereq in prerequisites) {
-- if (!class_is_a (cl, prereq)) {
-- missing_prereqs.insert (0, prereq.get_full_name ());
-- }
-- }
-- /* report any missing prerequisites */
-- if (missing_prereqs.size > 0) {
-- cl.error = true;
--
-- string error_string = "%s: some prerequisites (".printf (cl.get_full_name ());
-- bool first = true;
-- foreach (string s in missing_prereqs) {
-- if (first) {
-- error_string = "%s`%s'".printf (error_string, s);
-- first = false;
-- } else {
-- error_string = "%s, `%s'".printf (error_string, s);
-- }
-- }
-- error_string += ") are not met";
-- Report.error (cl.source_reference, error_string);
-- }
--
-- /* VAPI classes don't have to specify overridden methods */
-- if (!cl.external_package) {
-- /* all abstract symbols defined in base types have to be at least defined (or implemented) also in this type */
-- foreach (DataType base_type in cl.get_base_types ()) {
-- if (base_type.data_type is Interface) {
-- Interface iface = (Interface) base_type.data_type;
--
-- if (cl.base_class != null && cl.base_class.is_subtype_of (iface)) {
-- // reimplementation of interface, class is not required to reimplement all methods
-- break;
-- }
--
-- /* We do not need to do expensive equality checking here since this is done
-- * already. We only need to guarantee the symbols are present.
-- */
--
-- /* check methods */
-- foreach (Method m in iface.get_methods ()) {
-- if (m.is_abstract) {
-- Symbol sym = null;
-- var base_class = cl;
-- while (base_class != null && !(sym is Method)) {
-- sym = base_class.scope.lookup (m.name);
-- base_class = base_class.base_class;
-- }
-- if (!(sym is Method)) {
-- cl.error = true;
-- Report.error (cl.source_reference, "`%s' does not implement interface method `%s'".printf (cl.get_full_name (), m.get_full_name ()));
-- }
-- }
-- }
--
-- /* check properties */
-- foreach (Property prop in iface.get_properties ()) {
-- if (prop.is_abstract) {
-- Symbol sym = null;
-- var base_class = cl;
-- while (base_class != null && !(sym is Property)) {
-- sym = base_class.scope.lookup (prop.name);
-- base_class = base_class.base_class;
-- }
-- if (!(sym is Property)) {
-- cl.error = true;
-- Report.error (cl.source_reference, "`%s' does not implement interface property `%s'".printf (cl.get_full_name (), prop.get_full_name ()));
-- }
-- }
-- }
-- }
-- }
--
-- /* all abstract symbols defined in base classes have to be implemented in non-abstract classes */
-- if (!cl.is_abstract) {
-- var base_class = cl.base_class;
-- while (base_class != null && base_class.is_abstract) {
-- foreach (Method base_method in base_class.get_methods ()) {
-- if (base_method.is_abstract) {
-- var override_method = symbol_lookup_inherited (cl, base_method.name) as Method;
-- if (override_method == null || !override_method.overrides) {
-- cl.error = true;
-- Report.error (cl.source_reference, "`%s' does not implement abstract method `%s'".printf (cl.get_full_name (), base_method.get_full_name ()));
-- }
-- }
-- }
-- foreach (Property base_property in base_class.get_properties ()) {
-- if (base_property.is_abstract) {
-- var override_property = symbol_lookup_inherited (cl, base_property.name) as Property;
-- if (override_property == null || !override_property.overrides) {
-- cl.error = true;
-- Report.error (cl.source_reference, "`%s' does not implement abstract property `%s'".printf (cl.get_full_name (), base_property.get_full_name ()));
-- }
-- }
-- }
-- base_class = base_class.base_class;
-- }
-- }
-- }
--
-- current_symbol = current_symbol.parent_symbol;
-- current_class = null;
-+ cl.check (this);
- }
-
-- private void get_all_prerequisites (Interface iface, Gee.List<TypeSymbol> list) {
-- foreach (DataType prereq in iface.get_prerequisites ()) {
-- TypeSymbol type = prereq.data_type;
-- /* skip on previous errors */
-- if (type == null) {
-- continue;
-- }
--
-- list.add (type);
-- if (type is Interface) {
-- get_all_prerequisites ((Interface) type, list);
--
-- }
-- }
-- }
--
-- private bool class_is_a (Class cl, TypeSymbol t) {
-- if (cl == t) {
-- return true;
-- }
--
-- foreach (DataType base_type in cl.get_base_types ()) {
-- if (base_type.data_type is Class) {
-- if (class_is_a ((Class) base_type.data_type, t)) {
-- return true;
-- }
-- } else if (base_type.data_type == t) {
-- return true;
-- }
-- }
--
-- return false;
-- }
--
- public override void visit_struct (Struct st) {
-- st.process_attributes ();
--
-- current_symbol = st;
-- current_struct = st;
--
-- st.accept_children (this);
--
-- if (!st.external && !st.external_package && st.get_base_types ().size == 0 && st.get_fields ().size == 0) {
-- Report.error (st.source_reference, "structs cannot be empty");
-- }
--
-- current_symbol = current_symbol.parent_symbol;
-- current_struct = null;
-+ st.check (this);
- }
-
- public override void visit_interface (Interface iface) {
-- iface.process_attributes ();
--
-- current_symbol = iface;
--
-- foreach (DataType prerequisite_reference in iface.get_prerequisites ()) {
-- // check whether prerequisite is at least as accessible as the interface
-- if (!is_type_accessible (iface, prerequisite_reference)) {
-- iface.error = true;
-- Report.error (iface.source_reference, "prerequisite `%s` is less accessible than interface `%s`".printf (prerequisite_reference.to_string (), iface.get_full_name ()));
-- return;
-- }
--
-- current_source_file.add_type_dependency (prerequisite_reference, SourceFileDependencyType.HEADER_FULL);
-- }
--
-- /* check prerequisites */
-- Class prereq_class;
-- foreach (DataType prereq in iface.get_prerequisites ()) {
-- TypeSymbol class_or_interface = prereq.data_type;
-- /* skip on previous errors */
-- if (class_or_interface == null) {
-- iface.error = true;
-- continue;
-- }
-- /* interfaces are not allowed to have multiple instantiable prerequisites */
-- if (class_or_interface is Class) {
-- if (prereq_class != null) {
-- iface.error = true;
-- Report.error (iface.source_reference, "%s: Interfaces cannot have multiple instantiable prerequisites (`%s' and `%s')".printf (iface.get_full_name (), class_or_interface.get_full_name (), prereq_class.get_full_name ()));
-- return;
-- }
--
-- prereq_class = (Class) class_or_interface;
-- }
-- }
--
-- iface.accept_children (this);
--
-- current_symbol = current_symbol.parent_symbol;
-+ iface.check (this);
- }
-
- public override void visit_enum (Enum en) {
-- en.process_attributes ();
--
-- en.accept_children (this);
-+ en.check (this);
- }
-
- public override void visit_enum_value (EnumValue ev) {
-- ev.process_attributes ();
--
-- ev.accept_children (this);
-+ ev.check (this);
- }
-
- public override void visit_error_domain (ErrorDomain ed) {
-- ed.process_attributes ();
-+ ed.check (this);
-+ }
-
-- ed.accept_children (this);
-+ public override void visit_error_code (ErrorCode ec) {
-+ ec.check (this);
- }
-
- public override void visit_delegate (Delegate d) {
-- d.process_attributes ();
--
-- d.accept_children (this);
-+ d.check (this);
- }
-
- public override void visit_constant (Constant c) {
-- c.process_attributes ();
--
-- c.type_reference.accept (this);
--
-- if (!c.external_package) {
-- if (c.initializer == null) {
-- c.error = true;
-- Report.error (c.source_reference, "A const field requires a initializer to be provided");
-- } else {
-- c.initializer.target_type = c.type_reference;
--
-- c.initializer.accept (this);
-- }
-- }
-+ c.check (this);
- }
-
- public override void visit_field (Field f) {
-- f.process_attributes ();
--
-- if (f.initializer != null) {
-- f.initializer.target_type = f.field_type;
-- }
--
-- f.accept_children (this);
--
-- if (f.binding == MemberBinding.INSTANCE && f.parent_symbol is Interface) {
-- f.error = true;
-- Report.error (f.source_reference, "Interfaces may not have instance fields");
-- return;
-- }
--
-- if (!f.is_internal_symbol ()) {
-- if (f.field_type is ValueType) {
-- current_source_file.add_type_dependency (f.field_type, SourceFileDependencyType.HEADER_FULL);
-- } else {
-- current_source_file.add_type_dependency (f.field_type, SourceFileDependencyType.HEADER_SHALLOW);
-- }
-- } else {
-- if (f.parent_symbol is Namespace) {
-- f.error = true;
-- Report.error (f.source_reference, "Namespaces may not have private members");
-- return;
-- }
--
-- current_source_file.add_type_dependency (f.field_type, SourceFileDependencyType.SOURCE);
-- }
-+ f.check (this);
- }
-
- public override void visit_method (Method m) {
-- m.process_attributes ();
--
-- if (m.is_abstract) {
-- if (m.parent_symbol is Class) {
-- var cl = (Class) m.parent_symbol;
-- if (!cl.is_abstract) {
-- m.error = true;
-- Report.error (m.source_reference, "Abstract methods may not be declared in non-abstract classes");
-- return;
-- }
-- } else if (!(m.parent_symbol is Interface)) {
-- m.error = true;
-- Report.error (m.source_reference, "Abstract methods may not be declared outside of classes and interfaces");
-- return;
-- }
-- } else if (m.is_virtual) {
-- if (!(m.parent_symbol is Class) && !(m.parent_symbol is Interface)) {
-- m.error = true;
-- Report.error (m.source_reference, "Virtual methods may not be declared outside of classes and interfaces");
-- return;
-- }
--
-- if (m.parent_symbol is Class) {
-- var cl = (Class) m.parent_symbol;
-- if (cl.is_compact) {
-- Report.error (m.source_reference, "Virtual methods may not be declared in compact classes");
-- return;
-- }
-- }
-- } else if (m.overrides) {
-- if (!(m.parent_symbol is Class)) {
-- m.error = true;
-- Report.error (m.source_reference, "Methods may not be overridden outside of classes");
-- return;
-- }
-- }
--
-- if (m.is_abstract && m.body != null) {
-- Report.error (m.source_reference, "Abstract methods cannot have bodies");
-- } else if (m.external && m.body != null) {
-- Report.error (m.source_reference, "Extern methods cannot have bodies");
-- } else if (!m.is_abstract && !m.external && !m.external_package && m.body == null) {
-- Report.error (m.source_reference, "Non-abstract, non-extern methods must have bodies");
-- }
--
-- var old_symbol = current_symbol;
-- var old_return_type = current_return_type;
-- current_symbol = m;
-- current_return_type = m.return_type;
--
-- var init_attr = m.get_attribute ("ModuleInit");
-- if (init_attr != null) {
-- m.source_reference.file.context.module_init_method = m;
-- }
--
-- if (!m.is_internal_symbol ()) {
-- if (m.return_type is ValueType) {
-- current_source_file.add_type_dependency (m.return_type, SourceFileDependencyType.HEADER_FULL);
-- } else {
-- current_source_file.add_type_dependency (m.return_type, SourceFileDependencyType.HEADER_SHALLOW);
-- }
-- }
-- current_source_file.add_type_dependency (m.return_type, SourceFileDependencyType.SOURCE);
--
-- m.accept_children (this);
--
-- current_symbol = old_symbol;
-- current_return_type = old_return_type;
--
-- if (current_symbol.parent_symbol is Method) {
-- /* lambda expressions produce nested methods */
-- var up_method = (Method) current_symbol.parent_symbol;
-- current_return_type = up_method.return_type;
-- }
--
-- if (current_symbol is Struct) {
-- if (m.is_abstract || m.is_virtual || m.overrides) {
-- Report.error (m.source_reference, "A struct member `%s' cannot be marked as override, virtual, or abstract".printf (m.get_full_name ()));
-- return;
-- }
-- } else if (m.overrides && m.base_method == null) {
-- Report.error (m.source_reference, "%s: no suitable method found to override".printf (m.get_full_name ()));
-- }
--
-- // check whether return type is at least as accessible as the method
-- if (!is_type_accessible (m, m.return_type)) {
-- m.error = true;
-- Report.error (m.source_reference, "return type `%s` is less accessible than method `%s`".printf (m.return_type.to_string (), m.get_full_name ()));
-- return;
-- }
--
-- foreach (Expression precondition in m.get_preconditions ()) {
-- if (precondition.error) {
-- // if there was an error in the precondition, skip this check
-- m.error = true;
-- return;
-- }
--
-- if (!precondition.value_type.compatible (bool_type)) {
-- m.error = true;
-- Report.error (precondition.source_reference, "Precondition must be boolean");
-- return;
-- }
-- }
--
-- foreach (Expression postcondition in m.get_postconditions ()) {
-- if (postcondition.error) {
-- // if there was an error in the postcondition, skip this check
-- m.error = true;
-- return;
-- }
--
-- if (!postcondition.value_type.compatible (bool_type)) {
-- m.error = true;
-- Report.error (postcondition.source_reference, "Postcondition must be boolean");
-- return;
-- }
-- }
--
-- if (m.tree_can_fail && m.name == "main") {
-- Report.error (m.source_reference, "\"main\" method cannot throw errors");
-- }
--
-- // check that all errors that can be thrown in the method body are declared
-- if (m.body != null) {
-- foreach (DataType body_error_type in m.body.get_error_types ()) {
-- bool can_propagate_error = false;
-- foreach (DataType method_error_type in m.get_error_types ()) {
-- if (body_error_type.compatible (method_error_type)) {
-- can_propagate_error = true;
-- }
-- }
-- if (!can_propagate_error) {
-- Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string()));
-- }
-- }
-- }
-+ m.check (this);
- }
-
- public override void visit_creation_method (CreationMethod m) {
-- m.process_attributes ();
--
-- if (m.type_name != null && m.type_name != current_symbol.name) {
-- // type_name is null for constructors generated by GIdlParser
-- Report.error (m.source_reference, "missing return type in method `%s.%s´".printf (current_symbol.get_full_name (), m.type_name));
-- m.error = true;
-- return;
-- }
--
-- current_symbol = m;
-- current_return_type = m.return_type;
--
-- m.accept_children (this);
--
-- current_symbol = current_symbol.parent_symbol;
-- current_return_type = null;
--
-- if (current_symbol.parent_symbol is Method) {
-- /* lambda expressions produce nested methods */
-- var up_method = (Method) current_symbol.parent_symbol;
-- current_return_type = up_method.return_type;
-- }
--
-- if (m.is_abstract || m.is_virtual || m.overrides) {
-- Report.error (m.source_reference, "The creation method `%s' cannot be marked as override, virtual, or abstract".printf (m.get_full_name ()));
-- return;
-- }
-+ m.check (this);
- }
-
- public override void visit_formal_parameter (FormalParameter p) {
-- p.process_attributes ();
--
- p.check (this);
- }
-
-@@ -640,562 +204,71 @@
- }
-
- public override void visit_property (Property prop) {
-- prop.process_attributes ();
--
- prop.check (this);
- }
-
- public override void visit_property_accessor (PropertyAccessor acc) {
-- acc.process_attributes ();
--
-- var old_return_type = current_return_type;
-- if (acc.readable) {
-- current_return_type = acc.prop.property_type;
-- } else {
-- // void
-- current_return_type = new VoidType ();
-- }
--
-- if (!acc.prop.external_package) {
-- if (acc.body == null && !acc.prop.interface_only && !acc.prop.is_abstract) {
-- /* no accessor body specified, insert default body */
--
-- if (acc.prop.parent_symbol is Interface) {
-- acc.error = true;
-- Report.error (acc.source_reference, "Automatic properties can't be used in interfaces");
-- return;
-- }
-- acc.automatic_body = true;
-- acc.body = new Block (acc.source_reference);
-- var ma = new MemberAccess.simple ("_%s".printf (acc.prop.name), acc.source_reference);
-- if (acc.readable) {
-- acc.body.add_statement (new ReturnStatement (ma, acc.source_reference));
-- } else {
-- var assignment = new Assignment (ma, new MemberAccess.simple ("value", acc.source_reference), AssignmentOperator.SIMPLE, acc.source_reference);
-- acc.body.add_statement (new ExpressionStatement (assignment));
-- }
-- }
--
-- if (acc.body != null && (acc.writable || acc.construction)) {
-- var value_type = acc.prop.property_type.copy ();
-- acc.value_parameter = new FormalParameter ("value", value_type, acc.source_reference);
-- acc.body.scope.add (acc.value_parameter.name, acc.value_parameter);
-- }
-- }
--
-- acc.accept_children (this);
--
-- current_return_type = old_return_type;
-+ acc.check (this);
- }
-
- public override void visit_signal (Signal sig) {
-- sig.process_attributes ();
--
-- sig.accept_children (this);
-+ sig.check (this);
- }
-
- public override void visit_constructor (Constructor c) {
-- c.this_parameter = new FormalParameter ("this", new ObjectType (current_class));
-- c.scope.add (c.this_parameter.name, c.this_parameter);
--
-- c.owner = current_symbol.scope;
-- current_symbol = c;
--
-- c.accept_children (this);
--
-- foreach (DataType body_error_type in c.body.get_error_types ()) {
-- Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string()));
-- }
--
-- current_symbol = current_symbol.parent_symbol;
-+ c.check (this);
- }
-
- public override void visit_destructor (Destructor d) {
-- d.owner = current_symbol.scope;
-- current_symbol = d;
--
-- d.accept_children (this);
--
-- current_symbol = current_symbol.parent_symbol;
-+ d.check (this);
- }
-
- public override void visit_block (Block b) {
-- b.owner = current_symbol.scope;
-- current_symbol = b;
--
-- b.accept_children (this);
--
-- foreach (LocalVariable local in b.get_local_variables ()) {
-- local.active = false;
-- }
--
-- foreach (Statement stmt in b.get_statements()) {
-- b.add_error_types (stmt.get_error_types ());
-- }
--
-- current_symbol = current_symbol.parent_symbol;
-+ b.check (this);
- }
-
- public override void visit_declaration_statement (DeclarationStatement stmt) {
-- var local = stmt.declaration as LocalVariable;
-- if (local != null && local.initializer != null) {
-- foreach (DataType error_type in local.initializer.get_error_types ()) {
-- // ensure we can trace back which expression may throw errors of this type
-- var initializer_error_type = error_type.copy ();
-- initializer_error_type.source_reference = local.initializer.source_reference;
--
-- stmt.add_error_type (initializer_error_type);
-- }
-- }
-+ stmt.check (this);
- }
-
- public override void visit_local_variable (LocalVariable local) {
-- if (local.initializer != null) {
-- local.initializer.target_type = local.variable_type;
-- }
--
-- local.accept_children (this);
--
-- if (local.variable_type == null) {
-- /* var type */
--
-- if (local.initializer == null) {
-- local.error = true;
-- Report.error (local.source_reference, "var declaration not allowed without initializer");
-- return;
-- }
-- if (local.initializer.value_type == null) {
-- local.error = true;
-- Report.error (local.source_reference, "var declaration not allowed with non-typed initializer");
-- return;
-- }
--
-- local.variable_type = local.initializer.value_type.copy ();
-- local.variable_type.value_owned = true;
-- local.variable_type.floating_reference = false;
--
-- local.initializer.target_type = local.variable_type;
-- }
--
-- if (local.initializer != null) {
-- if (local.initializer.value_type == null) {
-- if (!(local.initializer is MemberAccess) && !(local.initializer is LambdaExpression)) {
-- local.error = true;
-- Report.error (local.source_reference, "expression type not allowed as initializer");
-- return;
-- }
--
-- if (local.initializer.symbol_reference is Method &&
-- local.variable_type is DelegateType) {
-- var m = (Method) local.initializer.symbol_reference;
-- var dt = (DelegateType) local.variable_type;
-- var cb = dt.delegate_symbol;
--
-- /* check whether method matches callback type */
-- if (!cb.matches_method (m)) {
-- local.error = true;
-- Report.error (local.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
-- return;
-- }
--
-- local.initializer.value_type = local.variable_type;
-- } else {
-- local.error = true;
-- Report.error (local.source_reference, "expression type not allowed as initializer");
-- return;
-- }
-- }
--
-- if (!local.initializer.value_type.compatible (local.variable_type)) {
-- local.error = true;
-- Report.error (local.source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (local.initializer.value_type.to_string (), local.variable_type.to_string ()));
-- return;
-- }
--
-- if (local.initializer.value_type.is_disposable ()) {
-- /* rhs transfers ownership of the expression */
-- if (!(local.variable_type is PointerType) && !local.variable_type.value_owned) {
-- /* lhs doesn't own the value */
-- local.error = true;
-- Report.error (local.source_reference, "Invalid assignment from owned expression to unowned variable");
-- return;
-- }
-- }
-- }
--
-- current_source_file.add_type_dependency (local.variable_type, SourceFileDependencyType.SOURCE);
--
-- current_symbol.scope.add (local.name, local);
--
-- var block = (Block) current_symbol;
-- block.add_local_variable (local);
--
-- local.active = true;
-+ local.check (this);
- }
-
-- /**
-- * Visit operation called for initializer lists
-- *
-- * @param list an initializer list
-- */
- public override void visit_initializer_list (InitializerList list) {
-- if (list.target_type == null) {
-- list.error = true;
-- Report.error (list.source_reference, "initializer list used for unknown type");
-- return;
-- } else if (list.target_type is ArrayType) {
-- /* initializer is used as array initializer */
-- var array_type = (ArrayType) list.target_type;
--
-- foreach (Expression e in list.get_initializers ()) {
-- e.target_type = array_type.element_type.copy ();
-- }
-- } else if (list.target_type.data_type is Struct) {
-- /* initializer is used as struct initializer */
-- var st = (Struct) list.target_type.data_type;
--
-- var field_it = st.get_fields ().iterator ();
-- foreach (Expression e in list.get_initializers ()) {
-- Field field = null;
-- while (field == null) {
-- if (!field_it.next ()) {
-- list.error = true;
-- Report.error (e.source_reference, "too many expressions in initializer list for `%s'".printf (list.target_type.to_string ()));
-- return;
-- }
-- field = field_it.get ();
-- if (field.binding != MemberBinding.INSTANCE) {
-- // we only initialize instance fields
-- field = null;
-- }
-- }
--
-- e.target_type = field.field_type.copy ();
-- if (!list.target_type.value_owned) {
-- e.target_type.value_owned = false;
-- }
-- }
-- } else {
-- list.error = true;
-- Report.error (list.source_reference, "initializer list used for `%s', which is neither array nor struct".printf (list.target_type.to_string ()));
-- return;
-- }
--
-- list.accept_children (this);
--
-- bool error = false;
-- foreach (Expression e in list.get_initializers ()) {
-- if (e.value_type == null) {
-- error = true;
-- continue;
-- }
--
-- var unary = e as UnaryExpression;
-- if (unary != null && (unary.operator == UnaryOperator.REF || unary.operator == UnaryOperator.OUT)) {
-- // TODO check type for ref and out expressions
-- } else if (!e.value_type.compatible (e.target_type)) {
-- error = true;
-- e.error = true;
-- Report.error (e.source_reference, "Expected initializer of type `%s' but got `%s'".printf (e.target_type.to_string (), e.value_type.to_string ()));
-- }
-- }
--
-- if (!error) {
-- /* everything seems to be correct */
-- list.value_type = list.target_type;
-- }
-+ list.check (this);
- }
-
- public override void visit_expression_statement (ExpressionStatement stmt) {
-- if (stmt.expression.error) {
-- // ignore inner error
-- stmt.error = true;
-- return;
-- }
--
-- stmt.add_error_types (stmt.expression.get_error_types ());
-+ stmt.check (this);
- }
-
- public override void visit_if_statement (IfStatement stmt) {
-- stmt.accept_children (this);
--
-- if (stmt.condition.error) {
-- /* if there was an error in the condition, skip this check */
-- stmt.error = true;
-- return;
-- }
--
-- if (!stmt.condition.value_type.compatible (bool_type)) {
-- stmt.error = true;
-- Report.error (stmt.condition.source_reference, "Condition must be boolean");
-- return;
-- }
--
-- stmt.add_error_types (stmt.condition.get_error_types ());
-- stmt.add_error_types (stmt.true_statement.get_error_types ());
--
-- if (stmt.false_statement != null) {
-- stmt.add_error_types (stmt.false_statement.get_error_types ());
-- }
-+ stmt.check (this);
- }
-
- public override void visit_switch_section (SwitchSection section) {
-- foreach (SwitchLabel label in section.get_labels ()) {
-- label.accept (this);
-- }
--
-- section.owner = current_symbol.scope;
-- current_symbol = section;
--
-- foreach (Statement st in section.get_statements ()) {
-- st.accept (this);
-- }
--
-- foreach (LocalVariable local in section.get_local_variables ()) {
-- local.active = false;
-- }
--
-- current_symbol = current_symbol.parent_symbol;
-+ section.check (this);
- }
-
- public override void visit_while_statement (WhileStatement stmt) {
-- stmt.accept_children (this);
--
-- if (stmt.condition.error) {
-- /* if there was an error in the condition, skip this check */
-- stmt.error = true;
-- return;
-- }
--
-- if (!stmt.condition.value_type.compatible (bool_type)) {
-- stmt.error = true;
-- Report.error (stmt.condition.source_reference, "Condition must be boolean");
-- return;
-- }
--
-- stmt.add_error_types (stmt.condition.get_error_types ());
-- stmt.add_error_types (stmt.body.get_error_types ());
-+ stmt.check (this);
- }
-
- public override void visit_do_statement (DoStatement stmt) {
-- stmt.accept_children (this);
--
-- if (stmt.condition.error) {
-- /* if there was an error in the condition, skip this check */
-- stmt.error = true;
-- return;
-- }
--
-- if (!stmt.condition.value_type.compatible (bool_type)) {
-- stmt.error = true;
-- Report.error (stmt.condition.source_reference, "Condition must be boolean");
-- return;
-- }
--
-- stmt.add_error_types (stmt.condition.get_error_types ());
-- stmt.add_error_types (stmt.body.get_error_types ());
-+ stmt.check (this);
- }
-
- public override void visit_for_statement (ForStatement stmt) {
-- stmt.accept_children (this);
--
-- if (stmt.condition != null && stmt.condition.error) {
-- /* if there was an error in the condition, skip this check */
-- stmt.error = true;
-- return;
-- }
--
-- if (stmt.condition != null && !stmt.condition.value_type.compatible (bool_type)) {
-- stmt.error = true;
-- Report.error (stmt.condition.source_reference, "Condition must be boolean");
-- return;
-- }
--
-- if (stmt.condition != null) {
-- stmt.add_error_types (stmt.condition.get_error_types ());
-- }
--
-- stmt.add_error_types (stmt.body.get_error_types ());
-- foreach (Expression exp in stmt.get_initializer ()) {
-- stmt.add_error_types (exp.get_error_types ());
-- }
-- foreach (Expression exp in stmt.get_iterator ()) {
-- stmt.add_error_types (exp.get_error_types ());
-- }
-+ stmt.check (this);
- }
-
- public override void visit_foreach_statement (ForeachStatement stmt) {
-- // analyze collection expression first, used for type inference
-- stmt.collection.accept (this);
--
-- if (stmt.collection.error) {
-- // ignore inner error
-- stmt.error = true;
-- return;
-- } else if (stmt.collection.value_type == null) {
-- Report.error (stmt.collection.source_reference, "invalid collection expression");
-- stmt.error = true;
-- return;
-- }
--
-- var collection_type = stmt.collection.value_type.copy ();
-- stmt.collection.target_type = collection_type.copy ();
--
-- DataType element_data_type = null;
-- bool element_owned = false;
--
-- if (collection_type.is_array ()) {
-- var array_type = (ArrayType) collection_type;
-- element_data_type = array_type.element_type;
-- } else if (collection_type.compatible (glist_type) || collection_type.compatible (gslist_type)) {
-- if (collection_type.get_type_arguments ().size > 0) {
-- element_data_type = (DataType) collection_type.get_type_arguments ().get (0);
-- }
-- } else if (iterable_type != null && collection_type.compatible (iterable_type)) {
-- element_owned = true;
--
-- if (list_type == null || !collection_type.compatible (new ObjectType (list_type))) {
-- // don't use iterator objects for lists for performance reasons
-- var foreach_iterator_type = new ObjectType (iterator_type);
-- foreach_iterator_type.value_owned = true;
-- foreach_iterator_type.add_type_argument (stmt.type_reference);
-- stmt.iterator_variable = new LocalVariable (foreach_iterator_type, "%s_it".printf (stmt.variable_name));
--
-- stmt.add_local_variable (stmt.iterator_variable);
-- stmt.iterator_variable.active = true;
-- }
--
-- var it_method = (Method) iterable_type.data_type.scope.lookup ("iterator");
-- if (it_method.return_type.get_type_arguments ().size > 0) {
-- var type_arg = it_method.return_type.get_type_arguments ().get (0);
-- if (type_arg.type_parameter != null) {
-- element_data_type = SemanticAnalyzer.get_actual_type (collection_type, it_method, type_arg, stmt);
-- } else {
-- element_data_type = type_arg;
-- }
-- }
-- } else {
-- stmt.error = true;
-- Report.error (stmt.source_reference, "Gee.List not iterable");
-- return;
-- }
--
-- if (element_data_type == null) {
-- stmt.error = true;
-- Report.error (stmt.collection.source_reference, "missing type argument for collection");
-- return;
-- }
--
-- // analyze element type
-- if (stmt.type_reference == null) {
-- // var type
-- stmt.type_reference = element_data_type.copy ();
-- } else if (!element_data_type.compatible (stmt.type_reference)) {
-- stmt.error = true;
-- Report.error (stmt.source_reference, "Foreach: Cannot convert from `%s' to `%s'".printf (element_data_type.to_string (), stmt.type_reference.to_string ()));
-- return;
-- } else if (element_data_type.is_disposable () && element_owned && !stmt.type_reference.value_owned) {
-- stmt.error = true;
-- Report.error (stmt.source_reference, "Foreach: Invalid assignment from owned expression to unowned variable");
-- return;
-- }
--
-- current_source_file.add_type_dependency (stmt.type_reference, SourceFileDependencyType.SOURCE);
--
-- stmt.element_variable = new LocalVariable (stmt.type_reference, stmt.variable_name);
--
-- stmt.body.scope.add (stmt.variable_name, stmt.element_variable);
--
-- stmt.body.add_local_variable (stmt.element_variable);
-- stmt.element_variable.active = true;
--
-- // analyze body
-- stmt.owner = current_symbol.scope;
-- current_symbol = stmt;
--
-- stmt.body.accept (this);
--
-- foreach (LocalVariable local in stmt.get_local_variables ()) {
-- local.active = false;
-- }
--
-- current_symbol = current_symbol.parent_symbol;
--
-- stmt.collection_variable = new LocalVariable (collection_type, "%s_collection".printf (stmt.variable_name));
--
-- stmt.add_local_variable (stmt.collection_variable);
-- stmt.collection_variable.active = true;
--
--
-- stmt.add_error_types (stmt.collection.get_error_types ());
-- stmt.add_error_types (stmt.body.get_error_types ());
-+ stmt.check (this);
- }
-
- public override void visit_return_statement (ReturnStatement stmt) {
-- if (stmt.return_expression != null) {
-- stmt.return_expression.target_type = current_return_type;
-- }
--
-- stmt.accept_children (this);
--
-- if (stmt.return_expression != null && stmt.return_expression.error) {
-- // ignore inner error
-- stmt.error = true;
-- return;
-- }
--
-- if (current_return_type == null) {
-- stmt.error = true;
-- Report.error (stmt.source_reference, "Return not allowed in this context");
-- return;
-- }
--
-- if (stmt.return_expression == null) {
-- if (current_return_type is VoidType) {
-- return;
-- } else {
-- stmt.error = true;
-- Report.error (stmt.source_reference, "Return without value in non-void function");
-- return;
-- }
-- }
--
-- if (current_return_type is VoidType) {
-- Report.error (stmt.source_reference, "Return with value in void function");
-- return;
-- }
--
-- if (stmt.return_expression.value_type == null) {
-- stmt.error = true;
-- Report.error (stmt.source_reference, "Invalid expression in return value");
-- return;
-- }
--
-- if (!stmt.return_expression.value_type.compatible (current_return_type)) {
-- stmt.error = true;
-- Report.error (stmt.source_reference, "Return: Cannot convert from `%s' to `%s'".printf (stmt.return_expression.value_type.to_string (), current_return_type.to_string ()));
-- return;
-- }
--
-- if (stmt.return_expression.value_type.is_disposable () &&
-- !current_return_type.value_owned) {
-- stmt.error = true;
-- Report.error (stmt.source_reference, "Return value transfers ownership but method return type hasn't been declared to transfer ownership");
-- return;
-- }
--
-- if (stmt.return_expression.symbol_reference is LocalVariable &&
-- stmt.return_expression.value_type.is_disposable () &&
-- !current_return_type.value_owned) {
-- Report.warning (stmt.source_reference, "Local variable with strong reference used as return value and method return type hasn't been declared to transfer ownership");
-- }
--
-- if (context.non_null && stmt.return_expression is NullLiteral
-- && !current_return_type.nullable) {
-- Report.warning (stmt.source_reference, "`null' incompatible with return type `%s`".printf (current_return_type.to_string ()));
-- }
--
-- stmt.add_error_types (stmt.return_expression.get_error_types ());
-+ stmt.check (this);
- }
-
- public override void visit_yield_statement (YieldStatement stmt) {
-@@ -1203,178 +276,27 @@
- }
-
- public override void visit_throw_statement (ThrowStatement stmt) {
-- stmt.error_expression.target_type = new ErrorType (null, null, stmt.source_reference);
-- stmt.error_expression.target_type.value_owned = true;
--
-- stmt.accept_children (this);
--
-- var error_type = stmt.error_expression.value_type.copy ();
-- error_type.source_reference = stmt.source_reference;
--
-- stmt.add_error_type (error_type);
-+ stmt.check (this);
- }
-
- public override void visit_try_statement (TryStatement stmt) {
-- stmt.accept_children (this);
-+ stmt.check (this);
- }
-
- public override void visit_catch_clause (CatchClause clause) {
-- if (clause.error_type != null) {
-- current_source_file.add_type_dependency (clause.error_type, SourceFileDependencyType.SOURCE);
--
-- clause.error_variable = new LocalVariable (clause.error_type.copy (), clause.variable_name);
--
-- clause.body.scope.add (clause.variable_name, clause.error_variable);
-- clause.body.add_local_variable (clause.error_variable);
-- } else {
-- clause.error_type = new ErrorType (null, null, clause.source_reference);
-- }
--
-- clause.accept_children (this);
-+ clause.check (this);
- }
-
- public override void visit_lock_statement (LockStatement stmt) {
-- /* resource must be a member access and denote a Lockable */
-- if (!(stmt.resource is MemberAccess && stmt.resource.symbol_reference is Lockable)) {
-- stmt.error = true;
-- stmt.resource.error = true;
-- Report.error (stmt.resource.source_reference, "Expression is either not a member access or does not denote a lockable member");
-- return;
-- }
--
-- /* parent symbol must be the current class */
-- if (stmt.resource.symbol_reference.parent_symbol != current_class) {
-- stmt.error = true;
-- stmt.resource.error = true;
-- Report.error (stmt.resource.source_reference, "Only members of the current class are lockable");
-- }
--
-- ((Lockable) stmt.resource.symbol_reference).set_lock_used (true);
-+ stmt.check (this);
- }
-
- public override void visit_delete_statement (DeleteStatement stmt) {
-- stmt.accept_children (this);
--
-- if (stmt.expression.error) {
-- // if there was an error in the inner expression, skip this check
-- return;
-- }
--
-- if (!(stmt.expression.value_type is PointerType)) {
-- stmt.error = true;
-- Report.error (stmt.source_reference, "delete operator not supported for `%s'".printf (stmt.expression.value_type.to_string ()));
-- }
-+ stmt.check (this);
- }
-
-- private int create_sizes_from_initializer_list (InitializerList il, int rank, Gee.List<Literal> sl) {
-- var init = new IntegerLiteral (il.size.to_string (), il.source_reference);
-- init.accept (this);
-- sl.add (init);
--
-- int subsize = -1;
-- foreach (Expression e in il.get_initializers ()) {
-- if (e is InitializerList) {
-- if (rank == 1) {
-- il.error = true;
-- e.error = true;
-- Report.error (e.source_reference, "Expected array element, got array initializer list");
-- return -1;
-- }
-- int size = create_sizes_from_initializer_list ((InitializerList)e, rank - 1, sl);
-- if (size == -1) {
-- return -1;
-- }
-- if (subsize >= 0 && subsize != size) {
-- il.error = true;
-- Report.error (il.source_reference, "Expected initializer list of size %d, got size %d".printf (subsize, size));
-- return -1;
-- } else {
-- subsize = size;
-- }
-- } else {
-- if (rank != 1) {
-- il.error = true;
-- e.error = true;
-- Report.error (e.source_reference, "Expected array initializer list, got array element");
-- return -1;
-- }
-- }
-- }
-- return il.size;
-- }
--
-- /**
-- * Visit operations called for array creation expresions.
-- *
-- * @param expr an array creation expression
-- */
- public override void visit_array_creation_expression (ArrayCreationExpression expr) {
-- Gee.List<Expression> size = expr.get_sizes ();
-- var initlist = expr.initializer_list;
--
-- if (expr.element_type != null) {
-- expr.element_type.accept (this);
-- }
--
-- foreach (Expression e in size) {
-- e.accept (this);
-- }
--
-- var calc_sizes = new ArrayList<Literal> ();
-- if (initlist != null) {
-- initlist.target_type = new ArrayType (expr.element_type, expr.rank, expr.source_reference);
--
-- initlist.accept (this);
--
-- var ret = create_sizes_from_initializer_list (initlist, expr.rank, calc_sizes);
-- if (ret == -1) {
-- expr.error = true;
-- }
-- }
--
-- if (size.size > 0) {
-- /* check for errors in the size list */
-- foreach (Expression e in size) {
-- if (e.value_type == null) {
-- /* return on previous error */
-- return;
-- } else if (!(e.value_type.data_type is Struct) || !((Struct) e.value_type.data_type).is_integer_type ()) {
-- expr.error = true;
-- Report.error (e.source_reference, "Expression of integer type expected");
-- }
-- }
-- } else {
-- if (initlist == null) {
-- expr.error = true;
-- /* this is an internal error because it is already handeld by the parser */
-- Report.error (expr.source_reference, "internal error: initializer list expected");
-- } else {
-- foreach (Expression size in calc_sizes) {
-- expr.append_size (size);
-- }
-- }
-- }
--
-- if (expr.error) {
-- return;
-- }
--
-- /* check for wrong elements inside the initializer */
-- if (expr.initializer_list != null && expr.initializer_list.value_type == null) {
-- return;
-- }
--
-- /* try to construct the type of the array */
-- if (expr.element_type == null) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Cannot determine the element type of the created array");
-- return;
-- }
--
-- expr.element_type.value_owned = true;
--
-- expr.value_type = new ArrayType (expr.element_type, expr.rank, expr.source_reference);
-- expr.value_type.value_owned = true;
-+ expr.check (this);
- }
-
- public override void visit_boolean_literal (BooleanLiteral expr) {
-@@ -1401,7 +323,7 @@
- expr.value_type = new NullType (expr.source_reference);
- }
-
-- private DataType? get_value_type_for_symbol (Symbol sym, bool lvalue) {
-+ public DataType? get_value_type_for_symbol (Symbol sym, bool lvalue) {
- if (sym is Field) {
- var f = (Field) sym;
- var type = f.field_type.copy ();
-@@ -1525,346 +447,7 @@
- }
-
- public override void visit_member_access (MemberAccess expr) {
-- Symbol base_symbol = null;
-- FormalParameter this_parameter = null;
-- bool may_access_instance_members = false;
--
-- expr.symbol_reference = null;
--
-- if (expr.qualified) {
-- base_symbol = root_symbol;
-- expr.symbol_reference = root_symbol.scope.lookup (expr.member_name);
-- } else if (expr.inner == null) {
-- if (expr.member_name == "this") {
-- if (!is_in_instance_method ()) {
-- expr.error = true;
-- Report.error (expr.source_reference, "This access invalid outside of instance methods");
-- return;
-- }
-- }
--
-- base_symbol = current_symbol;
--
-- var sym = current_symbol;
-- while (sym != null && expr.symbol_reference == null) {
-- if (this_parameter == null) {
-- if (sym is CreationMethod) {
-- var cm = (CreationMethod) sym;
-- this_parameter = cm.this_parameter;
-- may_access_instance_members = true;
-- } else if (sym is Property) {
-- var prop = (Property) sym;
-- this_parameter = prop.this_parameter;
-- may_access_instance_members = true;
-- } else if (sym is Constructor) {
-- var c = (Constructor) sym;
-- this_parameter = c.this_parameter;
-- may_access_instance_members = true;
-- } else if (sym is Destructor) {
-- var d = (Destructor) sym;
-- this_parameter = d.this_parameter;
-- may_access_instance_members = true;
-- } else if (sym is Method) {
-- var m = (Method) sym;
-- this_parameter = m.this_parameter;
-- may_access_instance_members = (m.binding == MemberBinding.INSTANCE);
-- }
-- }
--
-- expr.symbol_reference = symbol_lookup_inherited (sym, expr.member_name);
-- sym = sym.parent_symbol;
-- }
--
-- if (expr.symbol_reference == null) {
-- foreach (UsingDirective ns in current_using_directives) {
-- var local_sym = ns.namespace_symbol.scope.lookup (expr.member_name);
-- if (local_sym != null) {
-- if (expr.symbol_reference != null) {
-- expr.error = true;
-- Report.error (expr.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (expr.member_name, expr.symbol_reference.get_full_name (), local_sym.get_full_name ()));
-- return;
-- }
-- expr.symbol_reference = local_sym;
-- }
-- }
-- }
-- } else {
-- if (expr.inner.error) {
-- /* if there was an error in the inner expression, skip this check */
-- expr.error = true;
-- return;
-- }
--
-- if (expr.pointer_member_access) {
-- var pointer_type = expr.inner.value_type as PointerType;
-- if (pointer_type != null && pointer_type.base_type is ValueType) {
-- // transform foo->bar to (*foo).bar
-- expr.inner = new PointerIndirection (expr.inner, expr.source_reference);
-- expr.inner.accept (this);
-- expr.pointer_member_access = false;
-- }
-- }
--
-- if (expr.inner is MemberAccess) {
-- var ma = (MemberAccess) expr.inner;
-- if (ma.prototype_access) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Access to instance member `%s' denied".printf (expr.inner.symbol_reference.get_full_name ()));
-- return;
-- }
-- }
--
-- if (expr.inner is MemberAccess || expr.inner is BaseAccess) {
-- base_symbol = expr.inner.symbol_reference;
--
-- if (expr.symbol_reference == null && (base_symbol is Namespace || base_symbol is TypeSymbol)) {
-- expr.symbol_reference = base_symbol.scope.lookup (expr.member_name);
-- if (expr.inner is BaseAccess) {
-- // inner expression is base access
-- // access to instance members of the base type possible
-- may_access_instance_members = true;
-- }
-- }
-- }
--
-- if (expr.symbol_reference == null && expr.inner.value_type != null) {
-- if (expr.pointer_member_access) {
-- expr.symbol_reference = expr.inner.value_type.get_pointer_member (expr.member_name);
-- } else {
-- if (expr.inner.value_type.data_type != null) {
-- base_symbol = expr.inner.value_type.data_type;
-- }
-- expr.symbol_reference = expr.inner.value_type.get_member (expr.member_name);
-- }
-- if (expr.symbol_reference != null) {
-- // inner expression is variable, field, or parameter
-- // access to instance members of the corresponding type possible
-- may_access_instance_members = true;
-- }
-- }
--
-- if (expr.symbol_reference == null && expr.inner.value_type != null && expr.inner.value_type.is_dynamic) {
-- // allow late bound members for dynamic types
-- var dynamic_object_type = (ObjectType) expr.inner.value_type;
-- if (expr.parent_node is InvocationExpression) {
-- var invoc = (InvocationExpression) expr.parent_node;
-- if (invoc.call == expr) {
-- // dynamic method
-- DataType ret_type;
-- if (invoc.target_type != null) {
-- ret_type = invoc.target_type.copy ();
-- ret_type.value_owned = true;
-- } else if (invoc.parent_node is ExpressionStatement) {
-- ret_type = new VoidType ();
-- } else {
-- // expect dynamic object of the same type
-- ret_type = expr.inner.value_type.copy ();
-- }
-- var m = new DynamicMethod (expr.inner.value_type, expr.member_name, ret_type, expr.source_reference);
-- m.invocation = invoc;
-- m.add_error_type (new ErrorType (null, null));
-- m.access = SymbolAccessibility.PUBLIC;
-- m.add_parameter (new FormalParameter.with_ellipsis ());
-- dynamic_object_type.type_symbol.scope.add (null, m);
-- expr.symbol_reference = m;
-- }
-- } else if (expr.parent_node is Assignment) {
-- var a = (Assignment) expr.parent_node;
-- if (a.left == expr
-- && (a.operator == AssignmentOperator.ADD
-- || a.operator == AssignmentOperator.SUB)) {
-- // dynamic signal
-- var s = new DynamicSignal (expr.inner.value_type, expr.member_name, new VoidType (), expr.source_reference);
-- s.handler = a.right;
-- s.access = SymbolAccessibility.PUBLIC;
-- dynamic_object_type.type_symbol.scope.add (null, s);
-- expr.symbol_reference = s;
-- } else if (a.left == expr) {
-- // dynamic property assignment
-- var prop = new DynamicProperty (expr.inner.value_type, expr.member_name, expr.source_reference);
-- prop.access = SymbolAccessibility.PUBLIC;
-- prop.set_accessor = new PropertyAccessor (false, true, false, null, null);
-- prop.set_accessor.access = SymbolAccessibility.PUBLIC;
-- prop.owner = expr.inner.value_type.data_type.scope;
-- dynamic_object_type.type_symbol.scope.add (null, prop);
-- expr.symbol_reference = prop;
-- }
-- }
-- if (expr.symbol_reference == null) {
-- // dynamic property read access
-- var prop = new DynamicProperty (expr.inner.value_type, expr.member_name, expr.source_reference);
-- if (expr.target_type != null) {
-- prop.property_type = expr.target_type;
-- } else {
-- // expect dynamic object of the same type
-- prop.property_type = expr.inner.value_type.copy ();
-- }
-- prop.access = SymbolAccessibility.PUBLIC;
-- prop.get_accessor = new PropertyAccessor (true, false, false, null, null);
-- prop.get_accessor.access = SymbolAccessibility.PUBLIC;
-- prop.owner = expr.inner.value_type.data_type.scope;
-- dynamic_object_type.type_symbol.scope.add (null, prop);
-- expr.symbol_reference = prop;
-- }
-- if (expr.symbol_reference != null) {
-- may_access_instance_members = true;
-- }
-- }
-- }
--
-- if (expr.symbol_reference == null) {
-- expr.error = true;
--
-- string base_type_name = "(null)";
-- if (expr.inner != null && expr.inner.value_type != null) {
-- base_type_name = expr.inner.value_type.to_string ();
-- } else if (base_symbol != null) {
-- base_type_name = base_symbol.get_full_name ();
-- }
--
-- Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.member_name, base_type_name));
-- return;
-- }
--
-- var member = expr.symbol_reference;
-- var access = SymbolAccessibility.PUBLIC;
-- bool instance = false;
-- bool klass = false;
-- if (member is Field) {
-- var f = (Field) member;
-- access = f.access;
-- instance = (f.binding == MemberBinding.INSTANCE);
-- klass = (f.binding == MemberBinding.CLASS);
-- } else if (member is Method) {
-- var m = (Method) member;
-- access = m.access;
-- if (!(m is CreationMethod)) {
-- instance = (m.binding == MemberBinding.INSTANCE);
-- }
-- klass = (m.binding == MemberBinding.CLASS);
-- } else if (member is Property) {
-- var prop = (Property) member;
-- if (!prop.check (this)) {
-- expr.error = true;
-- return;
-- }
-- access = prop.access;
-- if (expr.lvalue) {
-- if (prop.set_accessor == null) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
-- return;
-- }
-- if (prop.access == SymbolAccessibility.PUBLIC) {
-- access = prop.set_accessor.access;
-- } else if (prop.access == SymbolAccessibility.PROTECTED
-- && prop.set_accessor.access != SymbolAccessibility.PUBLIC) {
-- access = prop.set_accessor.access;
-- }
-- } else {
-- if (prop.get_accessor == null) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Property `%s' is write-only".printf (prop.get_full_name ()));
-- return;
-- }
-- if (prop.access == SymbolAccessibility.PUBLIC) {
-- access = prop.get_accessor.access;
-- } else if (prop.access == SymbolAccessibility.PROTECTED
-- && prop.get_accessor.access != SymbolAccessibility.PUBLIC) {
-- access = prop.get_accessor.access;
-- }
-- }
-- instance = (prop.binding == MemberBinding.INSTANCE);
-- } else if (member is Signal) {
-- instance = true;
-- }
--
-- if (access == SymbolAccessibility.PRIVATE) {
-- var target_type = member.parent_symbol;
--
-- bool in_target_type = false;
-- for (Symbol this_symbol = current_symbol; this_symbol != null; this_symbol = this_symbol.parent_symbol) {
-- if (target_type == this_symbol) {
-- in_target_type = true;
-- break;
-- }
-- }
--
-- if (!in_target_type) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Access to private member `%s' denied".printf (member.get_full_name ()));
-- return;
-- }
-- }
-- if ((instance || klass) && !may_access_instance_members) {
-- expr.prototype_access = true;
--
-- if (expr.symbol_reference is Method) {
-- // also set static type for prototype access
-- // required when using instance methods as delegates in constants
-- // TODO replace by MethodPrototype
-- expr.value_type = get_value_type_for_symbol (expr.symbol_reference, expr.lvalue);
-- } else if (expr.symbol_reference is Field) {
-- expr.value_type = new FieldPrototype ((Field) expr.symbol_reference);
-- }
-- } else {
-- // implicit this access
-- if (instance && expr.inner == null) {
-- expr.inner = new MemberAccess (null, "this", expr.source_reference);
-- expr.inner.value_type = this_parameter.parameter_type.copy ();
-- expr.inner.symbol_reference = this_parameter;
-- }
--
-- expr.value_type = get_value_type_for_symbol (expr.symbol_reference, expr.lvalue);
--
-- // resolve generic return values
-- if (expr.value_type != null && expr.value_type.type_parameter != null) {
-- if (expr.inner != null) {
-- expr.value_type = get_actual_type (expr.inner.value_type, expr.symbol_reference, expr.value_type, expr);
-- if (expr.value_type == null) {
-- return;
-- }
-- }
-- }
--
-- if (expr.symbol_reference is Method) {
-- var m = (Method) expr.symbol_reference;
--
-- Method base_method;
-- if (m.base_method != null) {
-- base_method = m.base_method;
-- } else if (m.base_interface_method != null) {
-- base_method = m.base_interface_method;
-- } else {
-- base_method = m;
-- }
--
-- if (instance && base_method.parent_symbol != null) {
-- expr.inner.target_type = get_data_type_for_symbol ((TypeSymbol) base_method.parent_symbol);
-- }
-- } else if (expr.symbol_reference is Property) {
-- var prop = (Property) expr.symbol_reference;
--
-- Property base_property;
-- if (prop.base_property != null) {
-- base_property = prop.base_property;
-- } else if (prop.base_interface_property != null) {
-- base_property = prop.base_interface_property;
-- } else {
-- base_property = prop;
-- }
--
-- if (instance && base_property.parent_symbol != null) {
-- expr.inner.target_type = get_data_type_for_symbol ((TypeSymbol) base_property.parent_symbol);
-- }
-- } else if ((expr.symbol_reference is Field
-- || expr.symbol_reference is Signal)
-- && instance && expr.symbol_reference.parent_symbol != null) {
-- expr.inner.target_type = get_data_type_for_symbol ((TypeSymbol) expr.symbol_reference.parent_symbol);
-- }
-- }
--
-- current_source_file.add_symbol_dependency (expr.symbol_reference, SourceFileDependencyType.SOURCE);
-+ expr.check (this);
- }
-
- public static DataType get_data_type_for_symbol (TypeSymbol sym) {
-@@ -1889,300 +472,10 @@
- }
-
- public override void visit_invocation_expression (InvocationExpression expr) {
-- expr.call.accept (this);
--
-- if (expr.call.error) {
-- /* if method resolving didn't succeed, skip this check */
-- expr.error = true;
-- return;
-- }
--
-- if (expr.call is MemberAccess) {
-- var ma = (MemberAccess) expr.call;
-- if (ma.prototype_access) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Access to instance member `%s' denied".printf (expr.call.symbol_reference.get_full_name ()));
-- return;
-- }
-- }
--
-- var mtype = expr.call.value_type;
--
-- if (mtype is ObjectType) {
-- // constructor chain-up
-- var cm = find_current_method () as CreationMethod;
-- assert (cm != null);
-- if (cm.chain_up) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Multiple constructor calls in the same constructor are not permitted");
-- return;
-- }
-- cm.chain_up = true;
-- }
--
-- // check for struct construction
-- if (expr.call is MemberAccess &&
-- ((expr.call.symbol_reference is CreationMethod
-- && expr.call.symbol_reference.parent_symbol is Struct)
-- || expr.call.symbol_reference is Struct)) {
-- var struct_creation_expression = new ObjectCreationExpression ((MemberAccess) expr.call, expr.source_reference);
-- struct_creation_expression.struct_creation = true;
-- foreach (Expression arg in expr.get_argument_list ()) {
-- struct_creation_expression.add_argument (arg);
-- }
-- struct_creation_expression.target_type = expr.target_type;
-- replaced_nodes.add (expr);
-- expr.parent_node.replace_expression (expr, struct_creation_expression);
-- struct_creation_expression.accept (this);
-- return;
-- } else if (expr.call is MemberAccess
-- && expr.call.symbol_reference is CreationMethod) {
-- // constructor chain-up
-- var cm = find_current_method () as CreationMethod;
-- assert (cm != null);
-- if (cm.chain_up) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Multiple constructor calls in the same constructor are not permitted");
-- return;
-- }
-- cm.chain_up = true;
-- }
--
-- Gee.List<FormalParameter> params;
--
-- if (mtype != null && mtype.is_invokable ()) {
-- params = mtype.get_parameters ();
-- } else {
-- expr.error = true;
-- Report.error (expr.source_reference, "invocation not supported in this context");
-- return;
-- }
--
-- Expression last_arg = null;
--
-- var args = expr.get_argument_list ();
-- Iterator<Expression> arg_it = args.iterator ();
-- foreach (FormalParameter param in params) {
-- if (param.ellipsis) {
-- break;
-- }
--
-- if (arg_it.next ()) {
-- Expression arg = arg_it.get ();
--
-- /* store expected type for callback parameters */
-- arg.target_type = param.parameter_type;
--
-- // resolve generic type parameters
-- var ma = expr.call as MemberAccess;
-- if (arg.target_type.type_parameter != null) {
-- if (ma != null && ma.inner != null) {
-- arg.target_type = get_actual_type (ma.inner.value_type, ma.symbol_reference, arg.target_type, arg);
-- assert (arg.target_type != null);
-- }
-- }
--
-- last_arg = arg;
-- }
-- }
--
-- // printf arguments
-- if (mtype is MethodType && ((MethodType) mtype).method_symbol.printf_format) {
-- StringLiteral format_literal = null;
-- if (last_arg != null) {
-- // use last argument as format string
-- format_literal = last_arg as StringLiteral;
-- } else {
-- // use instance as format string for string.printf (...)
-- var ma = expr.call as MemberAccess;
-- if (ma != null) {
-- format_literal = ma.inner as StringLiteral;
-- }
-- }
-- if (format_literal != null) {
-- string format = format_literal.eval ();
--
-- bool unsupported_format = false;
--
-- weak string format_it = format;
-- unichar c = format_it.get_char ();
-- while (c != '\0') {
-- if (c != '%') {
-- format_it = format_it.next_char ();
-- c = format_it.get_char ();
-- continue;
-- }
--
-- format_it = format_it.next_char ();
-- c = format_it.get_char ();
-- // flags
-- while (c == '#' || c == '0' || c == '-' || c == ' ' || c == '+') {
-- format_it = format_it.next_char ();
-- c = format_it.get_char ();
-- }
-- // field width
-- while (c >= '0' && c <= '9') {
-- format_it = format_it.next_char ();
-- c = format_it.get_char ();
-- }
-- // precision
-- if (c == '.') {
-- format_it = format_it.next_char ();
-- c = format_it.get_char ();
-- while (c >= '0' && c <= '9') {
-- format_it = format_it.next_char ();
-- c = format_it.get_char ();
-- }
-- }
-- // length modifier
-- int length = 0;
-- if (c == 'h') {
-- length = -1;
-- format_it = format_it.next_char ();
-- c = format_it.get_char ();
-- if (c == 'h') {
-- length = -2;
-- format_it = format_it.next_char ();
-- c = format_it.get_char ();
-- }
-- } else if (c == 'l') {
-- length = 1;
-- format_it = format_it.next_char ();
-- c = format_it.get_char ();
-- } else if (c == 'z') {
-- length = 2;
-- format_it = format_it.next_char ();
-- c = format_it.get_char ();
-- }
-- // conversion specifier
-- DataType param_type = null;
-- if (c == 'd' || c == 'i' || c == 'c') {
-- // integer
-- if (length == -2) {
-- param_type = int8_type;
-- } else if (length == -1) {
-- param_type = short_type;
-- } else if (length == 0) {
-- param_type = int_type;
-- } else if (length == 1) {
-- param_type = long_type;
-- } else if (length == 2) {
-- param_type = ssize_t_type;
-- }
-- } else if (c == 'o' || c == 'u' || c == 'x' || c == 'X') {
-- // unsigned integer
-- if (length == -2) {
-- param_type = uchar_type;
-- } else if (length == -1) {
-- param_type = ushort_type;
-- } else if (length == 0) {
-- param_type = uint_type;
-- } else if (length == 1) {
-- param_type = ulong_type;
-- } else if (length == 2) {
-- param_type = size_t_type;
-- }
-- } else if (c == 'e' || c == 'E' || c == 'f' || c == 'F'
-- || c == 'g' || c == 'G' || c == 'a' || c == 'A') {
-- // double
-- param_type = double_type;
-- } else if (c == 's') {
-- // string
-- param_type = string_type;
-- } else if (c == 'p') {
-- // pointer
-- param_type = new PointerType (new VoidType ());
-- } else if (c == '%') {
-- // literal %
-- } else {
-- unsupported_format = true;
-- break;
-- }
-- if (c != '\0') {
-- format_it = format_it.next_char ();
-- c = format_it.get_char ();
-- }
-- if (param_type != null) {
-- if (arg_it.next ()) {
-- Expression arg = arg_it.get ();
--
-- arg.target_type = param_type;
-- } else {
-- Report.error (expr.source_reference, "Too few arguments for specified format");
-- return;
-- }
-- }
-- }
-- if (!unsupported_format && arg_it.next ()) {
-- Report.error (expr.source_reference, "Too many arguments for specified format");
-- return;
-- }
-- }
-- }
--
-- foreach (Expression arg in expr.get_argument_list ()) {
-- arg.accept (this);
-- }
--
-- DataType ret_type;
--
-- ret_type = mtype.get_return_type ();
-- params = mtype.get_parameters ();
--
-- if (ret_type is VoidType) {
-- // void return type
-- if (!(expr.parent_node is ExpressionStatement)
-- && !(expr.parent_node is ForStatement)
-- && !(expr.parent_node is YieldStatement)) {
-- // A void method invocation can be in the initializer or
-- // iterator of a for statement
-- expr.error = true;
-- Report.error (expr.source_reference, "invocation of void method not allowed as expression");
-- return;
-- }
-- }
--
-- // resolve generic return values
-- var ma = expr.call as MemberAccess;
-- if (ret_type.type_parameter != null) {
-- if (ma != null && ma.inner != null) {
-- ret_type = get_actual_type (ma.inner.value_type, ma.symbol_reference, ret_type, expr);
-- if (ret_type == null) {
-- return;
-- }
-- }
-- }
-- Gee.List<DataType> resolved_type_args = new ArrayList<DataType> ();
-- foreach (DataType type_arg in ret_type.get_type_arguments ()) {
-- if (type_arg.type_parameter != null && ma != null && ma.inner != null) {
-- resolved_type_args.add (get_actual_type (ma.inner.value_type, ma.symbol_reference, type_arg, expr));
-- } else {
-- resolved_type_args.add (type_arg);
-- }
-- }
-- ret_type = ret_type.copy ();
-- ret_type.remove_all_type_arguments ();
-- foreach (DataType resolved_type_arg in resolved_type_args) {
-- ret_type.add_type_argument (resolved_type_arg);
-- }
--
-- if (mtype is MethodType) {
-- var m = ((MethodType) mtype).method_symbol;
-- foreach (DataType error_type in m.get_error_types ()) {
-- // ensure we can trace back which expression may throw errors of this type
-- var call_error_type = error_type.copy ();
-- call_error_type.source_reference = expr.source_reference;
--
-- expr.add_error_type (call_error_type);
-- }
-- }
--
-- expr.value_type = ret_type;
--
-- check_arguments (expr, mtype, params, expr.get_argument_list ());
-+ expr.check (this);
- }
-
-- private bool check_arguments (Expression expr, DataType mtype, Gee.List<FormalParameter> params, Gee.List<Expression> args) {
-+ public bool check_arguments (Expression expr, DataType mtype, Gee.List<FormalParameter> params, Gee.List<Expression> args) {
- Expression prev_arg = null;
- Iterator<Expression> arg_it = args.iterator ();
-
-@@ -2480,121 +773,10 @@
- }
-
- public override void visit_element_access (ElementAccess expr) {
-- expr.container.accept (this);
--
-- if (expr.container.value_type == null) {
-- /* don't proceed if a child expression failed */
-- expr.error = true;
-- return;
-- }
--
-- var container_type = expr.container.value_type.data_type;
--
-- if (expr.container is MemberAccess && expr.container.symbol_reference is Signal) {
-- // signal detail access
-- if (expr.get_indices ().size != 1) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Element access with more than one dimension is not supported for signals");
-- return;
-- }
-- expr.get_indices ().get (0).target_type = string_type.copy ();
-- }
--
-- foreach (Expression index in expr.get_indices ()) {
-- index.accept (this);
-- }
--
-- bool index_int_type_check = true;
--
-- var pointer_type = expr.container.value_type as PointerType;
--
-- /* assign a value_type when possible */
-- if (expr.container.value_type is ArrayType) {
-- var array_type = (ArrayType) expr.container.value_type;
-- expr.value_type = array_type.element_type.copy ();
-- if (!expr.lvalue) {
-- expr.value_type.value_owned = false;
-- }
-- } else if (pointer_type != null && !pointer_type.base_type.is_reference_type_or_type_parameter ()) {
-- expr.value_type = pointer_type.base_type.copy ();
-- } else if (container_type == string_type.data_type) {
-- if (expr.get_indices ().size != 1) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Element access with more than one dimension is not supported for strings");
-- return;
-- }
--
-- expr.value_type = unichar_type;
-- } else if (container_type != null && list_type != null && map_type != null &&
-- (container_type.is_subtype_of (list_type) || container_type.is_subtype_of (map_type))) {
-- Gee.List<Expression> indices = expr.get_indices ();
-- if (indices.size != 1) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Element access with more than one dimension is not supported for the specified type");
-- return;
-- }
-- Iterator<Expression> indices_it = indices.iterator ();
-- indices_it.next ();
-- var index = indices_it.get ();
-- index_int_type_check = false;
--
-- // lookup symbol in interface instead of class as implemented interface methods are not in VAPI files
-- Symbol get_sym = null;
-- if (container_type.is_subtype_of (list_type)) {
-- get_sym = list_type.scope.lookup ("get");
-- } else if (container_type.is_subtype_of (map_type)) {
-- get_sym = map_type.scope.lookup ("get");
-- }
-- var get_method = (Method) get_sym;
-- Gee.List<FormalParameter> get_params = get_method.get_parameters ();
-- Iterator<FormalParameter> get_params_it = get_params.iterator ();
-- get_params_it.next ();
-- var get_param = get_params_it.get ();
--
-- var index_type = get_param.parameter_type;
-- if (index_type.type_parameter != null) {
-- index_type = get_actual_type (expr.container.value_type, get_method, get_param.parameter_type, expr);
-- }
--
-- if (!index.value_type.compatible (index_type)) {
-- expr.error = true;
-- Report.error (expr.source_reference, "index expression: Cannot convert from `%s' to `%s'".printf (index.value_type.to_string (), index_type.to_string ()));
-- return;
-- }
--
-- expr.value_type = get_actual_type (expr.container.value_type, get_method, get_method.return_type, expr).copy ();
-- if (expr.lvalue) {
-- // get () returns owned value, set () accepts unowned value
-- expr.value_type.value_owned = false;
-- }
-- } else if (expr.container is MemberAccess && expr.container.symbol_reference is Signal) {
-- index_int_type_check = false;
--
-- expr.symbol_reference = expr.container.symbol_reference;
-- expr.value_type = expr.container.value_type;
-- } else {
-- expr.error = true;
-- Report.error (expr.source_reference, "The expression `%s' does not denote an Array".printf (expr.container.value_type.to_string ()));
-- }
--
-- if (index_int_type_check) {
-- /* check if the index is of type integer */
-- foreach (Expression e in expr.get_indices ()) {
-- /* don't proceed if a child expression failed */
-- if (e.value_type == null) {
-- return;
-- }
--
-- /* check if the index is of type integer */
-- if (!(e.value_type.data_type is Struct) || !((Struct) e.value_type.data_type).is_integer_type ()) {
-- expr.error = true;
-- Report.error (e.source_reference, "Expression of integer type expected");
-- }
-- }
-- }
-+ expr.check (this);
- }
-
-- private bool is_in_instance_method () {
-+ public bool is_in_instance_method () {
- var sym = current_symbol;
- while (sym != null) {
- if (sym is CreationMethod) {
-@@ -2652,195 +834,10 @@
- }
-
- public override void visit_object_creation_expression (ObjectCreationExpression expr) {
-- if (expr.member_name != null) {
-- expr.member_name.accept (this);
-- }
--
-- TypeSymbol type = null;
--
-- if (expr.type_reference == null) {
-- if (expr.member_name == null) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Incomplete object creation expression");
-- return;
-- }
--
-- if (expr.member_name.symbol_reference == null) {
-- expr.error = true;
-- return;
-- }
--
-- var constructor_sym = expr.member_name.symbol_reference;
-- var type_sym = expr.member_name.symbol_reference;
--
-- var type_args = expr.member_name.get_type_arguments ();
--
-- if (constructor_sym is Method) {
-- type_sym = constructor_sym.parent_symbol;
--
-- var constructor = (Method) constructor_sym;
-- if (!(constructor_sym is CreationMethod)) {
-- expr.error = true;
-- Report.error (expr.source_reference, "`%s' is not a creation method".printf (constructor.get_full_name ()));
-- return;
-- }
--
-- expr.symbol_reference = constructor;
--
-- // inner expression can also be base access when chaining constructors
-- var ma = expr.member_name.inner as MemberAccess;
-- if (ma != null) {
-- type_args = ma.get_type_arguments ();
-- }
-- }
--
-- if (type_sym is Class) {
-- type = (TypeSymbol) type_sym;
-- expr.type_reference = new ObjectType ((Class) type);
-- } else if (type_sym is Struct) {
-- type = (TypeSymbol) type_sym;
-- expr.type_reference = new ValueType (type);
-- } else if (type_sym is ErrorCode) {
-- expr.type_reference = new ErrorType ((ErrorDomain) type_sym.parent_symbol, (ErrorCode) type_sym, expr.source_reference);
-- expr.symbol_reference = type_sym;
-- } else {
-- expr.error = true;
-- Report.error (expr.source_reference, "`%s' is not a class, struct, or error code".printf (type_sym.get_full_name ()));
-- return;
-- }
--
-- foreach (DataType type_arg in type_args) {
-- expr.type_reference.add_type_argument (type_arg);
--
-- current_source_file.add_type_dependency (type_arg, SourceFileDependencyType.SOURCE);
-- }
-- } else {
-- type = expr.type_reference.data_type;
-- }
--
-- current_source_file.add_symbol_dependency (type, SourceFileDependencyType.SOURCE);
--
-- expr.value_type = expr.type_reference.copy ();
-- expr.value_type.value_owned = true;
--
-- int given_num_type_args = expr.type_reference.get_type_arguments ().size;
-- int expected_num_type_args = 0;
--
-- if (type is Class) {
-- var cl = (Class) type;
--
-- expected_num_type_args = cl.get_type_parameters ().size;
--
-- if (expr.struct_creation) {
-- expr.error = true;
-- Report.error (expr.source_reference, "syntax error, use `new' to create new objects");
-- return;
-- }
--
-- if (cl.is_abstract) {
-- expr.value_type = null;
-- expr.error = true;
-- Report.error (expr.source_reference, "Can't create instance of abstract class `%s'".printf (cl.get_full_name ()));
-- return;
-- }
--
-- if (expr.symbol_reference == null) {
-- expr.symbol_reference = cl.default_construction_method;
-- }
--
-- while (cl != null) {
-- if (cl == initially_unowned_type) {
-- expr.value_type.floating_reference = true;
-- break;
-- }
--
-- cl = cl.base_class;
-- }
-- } else if (type is Struct) {
-- var st = (Struct) type;
--
-- expected_num_type_args = st.get_type_parameters ().size;
--
-- if (!expr.struct_creation) {
-- Report.warning (expr.source_reference, "deprecated syntax, don't use `new' to initialize structs");
-- }
--
-- if (expr.symbol_reference == null) {
-- expr.symbol_reference = st.default_construction_method;
-- }
-- }
--
-- if (expected_num_type_args > given_num_type_args) {
-- expr.error = true;
-- Report.error (expr.source_reference, "too few type arguments");
-- return;
-- } else if (expected_num_type_args < given_num_type_args) {
-- expr.error = true;
-- Report.error (expr.source_reference, "too many type arguments");
-- return;
-- }
--
-- if (expr.symbol_reference == null && expr.get_argument_list ().size != 0) {
-- expr.value_type = null;
-- expr.error = true;
-- Report.error (expr.source_reference, "No arguments allowed when constructing type `%s'".printf (type.get_full_name ()));
-- return;
-- }
--
-- if (expr.symbol_reference is Method) {
-- var m = (Method) expr.symbol_reference;
--
-- var args = expr.get_argument_list ();
-- Iterator<Expression> arg_it = args.iterator ();
-- foreach (FormalParameter param in m.get_parameters ()) {
-- if (param.ellipsis) {
-- break;
-- }
--
-- if (arg_it.next ()) {
-- Expression arg = arg_it.get ();
--
-- /* store expected type for callback parameters */
-- arg.target_type = param.parameter_type;
-- }
-- }
--
-- foreach (Expression arg in args) {
-- arg.accept (this);
-- }
--
-- check_arguments (expr, new MethodType (m), m.get_parameters (), args);
--
-- foreach (DataType error_type in m.get_error_types ()) {
-- // ensure we can trace back which expression may throw errors of this type
-- var call_error_type = error_type.copy ();
-- call_error_type.source_reference = expr.source_reference;
--
-- expr.add_error_type (call_error_type);
-- }
-- } else if (expr.type_reference is ErrorType) {
-- expr.accept_children (this);
--
-- if (expr.get_argument_list ().size == 0) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Too few arguments, errors need at least 1 argument");
-- } else {
-- Iterator<Expression> arg_it = expr.get_argument_list ().iterator ();
-- arg_it.next ();
-- var ex = arg_it.get ();
-- if (ex.value_type == null || !ex.value_type.compatible (string_type)) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Invalid type for argument 1");
-- }
-- }
-- }
--
-- foreach (MemberInitializer init in expr.get_object_initializer ()) {
-- visit_member_initializer (init, expr.type_reference);
-- }
-+ expr.check (this);
- }
-
-- void visit_member_initializer (MemberInitializer init, DataType type) {
-+ public void visit_member_initializer (MemberInitializer init, DataType type) {
- init.accept (this);
-
- init.symbol_reference = symbol_lookup_inherited (type.data_type, init.name);
-@@ -3084,7 +1081,7 @@
- expr.value_type.value_owned = true;
- }
-
-- private DataType? get_arithmetic_result_type (DataType left_type, DataType right_type) {
-+ public DataType? get_arithmetic_result_type (DataType left_type, DataType right_type) {
- if (!(left_type.data_type is Struct) || !(right_type.data_type is Struct)) {
- // at least one operand not struct
- return null;
-@@ -3117,158 +1114,7 @@
- }
-
- public override void visit_binary_expression (BinaryExpression expr) {
-- if (expr.left.error || expr.right.error) {
-- /* if there were any errors in inner expressions, skip type check */
-- expr.error = true;
-- return;
-- }
--
-- if (expr.left.value_type == null) {
-- Report.error (expr.left.source_reference, "invalid left operand");
-- expr.error = true;
-- return;
-- }
--
-- if (expr.operator != BinaryOperator.IN && expr.right.value_type == null) {
-- Report.error (expr.right.source_reference, "invalid right operand");
-- expr.error = true;
-- return;
-- }
--
-- if (expr.left.value_type.data_type == string_type.data_type
-- && expr.operator == BinaryOperator.PLUS) {
-- // string concatenation
--
-- if (expr.right.value_type == null || expr.right.value_type.data_type != string_type.data_type) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Operands must be strings");
-- return;
-- }
--
-- expr.value_type = string_type.copy ();
-- if (expr.left.is_constant () && expr.right.is_constant ()) {
-- expr.value_type.value_owned = false;
-- } else {
-- expr.value_type.value_owned = true;
-- }
-- } else if (expr.operator == BinaryOperator.PLUS
-- || expr.operator == BinaryOperator.MINUS
-- || expr.operator == BinaryOperator.MUL
-- || expr.operator == BinaryOperator.DIV) {
-- // check for pointer arithmetic
-- if (expr.left.value_type is PointerType) {
-- var offset_type = expr.right.value_type.data_type as Struct;
-- if (offset_type != null && offset_type.is_integer_type ()) {
-- if (expr.operator == BinaryOperator.PLUS
-- || expr.operator == BinaryOperator.MINUS) {
-- // pointer arithmetic: pointer +/- offset
-- expr.value_type = expr.left.value_type.copy ();
-- }
-- } else if (expr.right.value_type is PointerType) {
-- // pointer arithmetic: pointer - pointer
-- expr.value_type = size_t_type;
-- }
-- }
--
-- if (expr.value_type == null) {
-- expr.value_type = get_arithmetic_result_type (expr.left.value_type, expr.right.value_type);
-- }
--
-- if (expr.value_type == null) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Arithmetic operation not supported for types `%s' and `%s'".printf (expr.left.value_type.to_string (), expr.right.value_type.to_string ()));
-- return;
-- }
-- } else if (expr.operator == BinaryOperator.MOD
-- || expr.operator == BinaryOperator.SHIFT_LEFT
-- || expr.operator == BinaryOperator.SHIFT_RIGHT
-- || expr.operator == BinaryOperator.BITWISE_XOR) {
-- expr.value_type = get_arithmetic_result_type (expr.left.value_type, expr.right.value_type);
--
-- if (expr.value_type == null) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Arithmetic operation not supported for types `%s' and `%s'".printf (expr.left.value_type.to_string (), expr.right.value_type.to_string ()));
-- return;
-- }
-- } else if (expr.operator == BinaryOperator.LESS_THAN
-- || expr.operator == BinaryOperator.GREATER_THAN
-- || expr.operator == BinaryOperator.LESS_THAN_OR_EQUAL
-- || expr.operator == BinaryOperator.GREATER_THAN_OR_EQUAL) {
-- if (expr.left.value_type.compatible (string_type)
-- && expr.right.value_type.compatible (string_type)) {
-- // string comparison
-- } else if (expr.left.value_type is PointerType && expr.right.value_type is PointerType) {
-- // pointer arithmetic
-- } else {
-- var resulting_type = get_arithmetic_result_type (expr.left.value_type, expr.right.value_type);
--
-- if (resulting_type == null) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Relational operation not supported for types `%s' and `%s'".printf (expr.left.value_type.to_string (), expr.right.value_type.to_string ()));
-- return;
-- }
-- }
--
-- expr.value_type = bool_type;
-- } else if (expr.operator == BinaryOperator.EQUALITY
-- || expr.operator == BinaryOperator.INEQUALITY) {
-- /* relational operation */
--
-- if (!expr.right.value_type.compatible (expr.left.value_type)
-- && !expr.left.value_type.compatible (expr.right.value_type)) {
-- Report.error (expr.source_reference, "Equality operation: `%s' and `%s' are incompatible".printf (expr.right.value_type.to_string (), expr.left.value_type.to_string ()));
-- expr.error = true;
-- return;
-- }
--
-- if (expr.left.value_type.compatible (string_type)
-- && expr.right.value_type.compatible (string_type)) {
-- // string comparison
-- }
--
-- expr.value_type = bool_type;
-- } else if (expr.operator == BinaryOperator.BITWISE_AND
-- || expr.operator == BinaryOperator.BITWISE_OR) {
-- // integer type or flags type
--
-- expr.value_type = expr.left.value_type;
-- } else if (expr.operator == BinaryOperator.AND
-- || expr.operator == BinaryOperator.OR) {
-- if (!expr.left.value_type.compatible (bool_type) || !expr.right.value_type.compatible (bool_type)) {
-- expr.error = true;
-- Report.error (expr.source_reference, "Operands must be boolean");
-- }
--
-- expr.value_type = bool_type;
-- } else if (expr.operator == BinaryOperator.IN) {
-- // integer type or flags type or collection/map
--
-- /* handle collections and maps */
-- var container_type = expr.right.value_type.data_type;
--
-- if ((collection_type != null && container_type.is_subtype_of (collection_type))
-- || (map_type != null && container_type.is_subtype_of (map_type))) {
-- Symbol contains_sym = null;
-- if (container_type.is_subtype_of (collection_type)) {
-- contains_sym = collection_type.scope.lookup ("contains");
-- } else if (container_type.is_subtype_of (map_type)) {
-- contains_sym = map_type.scope.lookup ("contains");
-- }
-- var contains_method = (Method) contains_sym;
-- Gee.List<FormalParameter> contains_params = contains_method.get_parameters ();
-- Iterator<FormalParameter> contains_params_it = contains_params.iterator ();
-- contains_params_it.next ();
-- var contains_param = contains_params_it.get ();
--
-- var key_type = get_actual_type (expr.right.value_type, contains_method, contains_param.parameter_type, expr);
-- expr.left.target_type = key_type;
-- }
--
-- expr.value_type = bool_type;
--
-- } else {
-- assert_not_reached ();
-- }
-+ expr.check (this);
- }
-
- public override void visit_type_check (TypeCheck expr) {
-@@ -3314,7 +1160,7 @@
- return result;
- }
-
-- private Method? find_current_method () {
-+ public Method? find_current_method () {
- var sym = current_symbol;
- while (sym != null) {
- if (sym is Method) {
-@@ -3325,7 +1171,7 @@
- return null;
- }
-
-- private bool is_in_constructor () {
-+ public bool is_in_constructor () {
- var sym = current_symbol;
- while (sym != null) {
- if (sym is Constructor) {
-@@ -3405,277 +1251,6 @@
- }
-
- public override void visit_assignment (Assignment a) {
-- a.left.lvalue = true;
--
-- a.left.accept (this);
--
-- if (a.left.error) {
-- // skip on error in inner expression
-- a.error = true;
-- return;
-- }
--
-- if (a.left is MemberAccess) {
-- var ma = (MemberAccess) a.left;
--
-- if (!(ma.symbol_reference is Signal || ma.symbol_reference is DynamicProperty) && ma.value_type == null) {
-- a.error = true;
-- Report.error (a.source_reference, "unsupported lvalue in assignment");
-- return;
-- }
-- if (ma.prototype_access) {
-- a.error = true;
-- Report.error (a.source_reference, "Access to instance member `%s' denied".printf (ma.symbol_reference.get_full_name ()));
-- return;
-- }
--
-- if (ma.error || ma.symbol_reference == null) {
-- a.error = true;
-- /* if no symbol found, skip this check */
-- return;
-- }
--
-- if (ma.symbol_reference is DynamicSignal) {
-- // target_type not available for dynamic signals
-- } else if (ma.symbol_reference is Signal) {
-- var sig = (Signal) ma.symbol_reference;
-- a.right.target_type = new DelegateType (sig.get_delegate (ma.inner.value_type));
-- } else {
-- a.right.target_type = ma.value_type;
-- }
-- } else if (a.left is ElementAccess) {
-- var ea = (ElementAccess) a.left;
--
-- if (ea.container is MemberAccess && ea.container.symbol_reference is Signal) {
-- var ma = (MemberAccess) ea.container;
-- var sig = (Signal) ea.container.symbol_reference;
-- a.right.target_type = new DelegateType (sig.get_delegate (ma.inner.value_type));
-- } else {
-- a.right.target_type = a.left.value_type;
-- }
-- } else if (a.left is PointerIndirection) {
-- a.right.target_type = a.left.value_type;
-- } else {
-- a.error = true;
-- Report.error (a.source_reference, "unsupported lvalue in assignment");
-- return;
-- }
--
-- a.right.accept (this);
--
-- if (a.right.error) {
-- // skip on error in inner expression
-- a.error = true;
-- return;
-- }
--
-- if (a.operator != AssignmentOperator.SIMPLE && a.left is MemberAccess) {
-- // transform into simple assignment
-- // FIXME: only do this if the backend doesn't support
-- // the assignment natively
--
-- var ma = (MemberAccess) a.left;
--
-- if (!(ma.symbol_reference is Signal)) {
-- var old_value = new MemberAccess (ma.inner, ma.member_name);
--
-- var bin = new BinaryExpression (BinaryOperator.PLUS, old_value, new ParenthesizedExpression (a.right, a.right.source_reference));
-- bin.target_type = a.right.target_type;
-- a.right.target_type = a.right.target_type.copy ();
-- a.right.target_type.value_owned = false;
--
-- if (a.operator == AssignmentOperator.BITWISE_OR) {
-- bin.operator = BinaryOperator.BITWISE_OR;
-- } else if (a.operator == AssignmentOperator.BITWISE_AND) {
-- bin.operator = BinaryOperator.BITWISE_AND;
-- } else if (a.operator == AssignmentOperator.BITWISE_XOR) {
-- bin.operator = BinaryOperator.BITWISE_XOR;
-- } else if (a.operator == AssignmentOperator.ADD) {
-- bin.operator = BinaryOperator.PLUS;
-- } else if (a.operator == AssignmentOperator.SUB) {
-- bin.operator = BinaryOperator.MINUS;
-- } else if (a.operator == AssignmentOperator.MUL) {
-- bin.operator = BinaryOperator.MUL;
-- } else if (a.operator == AssignmentOperator.DIV) {
-- bin.operator = BinaryOperator.DIV;
-- } else if (a.operator == AssignmentOperator.PERCENT) {
-- bin.operator = BinaryOperator.MOD;
-- } else if (a.operator == AssignmentOperator.SHIFT_LEFT) {
-- bin.operator = BinaryOperator.SHIFT_LEFT;
-- } else if (a.operator == AssignmentOperator.SHIFT_RIGHT) {
-- bin.operator = BinaryOperator.SHIFT_RIGHT;
-- }
--
-- a.right = bin;
-- a.right.accept (this);
--
-- a.operator = AssignmentOperator.SIMPLE;
-- }
-- }
--
-- if (a.left.symbol_reference is Signal) {
-- var sig = (Signal) a.left.symbol_reference;
--
-- var m = a.right.symbol_reference as Method;
--
-- if (m == null) {
-- a.error = true;
-- Report.error (a.right.source_reference, "unsupported expression for signal handler");
-- return;
-- }
--
-- var dynamic_sig = sig as DynamicSignal;
-- if (dynamic_sig != null) {
-- bool first = true;
-- foreach (FormalParameter param in dynamic_sig.handler.value_type.get_parameters ()) {
-- if (first) {
-- // skip sender parameter
-- first = false;
-- } else {
-- dynamic_sig.add_parameter (param.copy ());
-- }
-- }
-- a.right.target_type = new DelegateType (sig.get_delegate (new ObjectType ((ObjectTypeSymbol) sig.parent_symbol)));
-- } else if (!a.right.value_type.compatible (a.right.target_type)) {
-- var delegate_type = (DelegateType) a.right.target_type;
--
-- a.error = true;
-- Report.error (a.right.source_reference, "method `%s' is incompatible with signal `%s', expected `%s'".printf (a.right.value_type.to_string (), a.right.target_type.to_string (), delegate_type.delegate_symbol.get_prototype_string (m.name)));
-- return;
-- }
-- } else if (a.left is MemberAccess) {
-- var ma = (MemberAccess) a.left;
--
-- if (ma.symbol_reference is Property) {
-- var prop = (Property) ma.symbol_reference;
--
-- var dynamic_prop = prop as DynamicProperty;
-- if (dynamic_prop != null) {
-- dynamic_prop.property_type = a.right.value_type.copy ();
-- a.left.value_type = dynamic_prop.property_type.copy ();
-- }
--
-- if (prop.set_accessor == null
-- || (!prop.set_accessor.writable && !(find_current_method () is CreationMethod || is_in_constructor ()))) {
-- ma.error = true;
-- Report.error (ma.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
-- return;
-- }
-- } else if (ma.symbol_reference is LocalVariable && a.right.value_type == null) {
-- var local = (LocalVariable) ma.symbol_reference;
--
-- if (a.right.symbol_reference is Method &&
-- local.variable_type is DelegateType) {
-- var m = (Method) a.right.symbol_reference;
-- var dt = (DelegateType) local.variable_type;
-- var cb = dt.delegate_symbol;
--
-- /* check whether method matches callback type */
-- if (!cb.matches_method (m)) {
-- a.error = true;
-- Report.error (a.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
-- return;
-- }
--
-- a.right.value_type = local.variable_type;
-- } else {
-- a.error = true;
-- Report.error (a.source_reference, "Assignment: Invalid callback assignment attempt");
-- return;
-- }
-- } else if (ma.symbol_reference is Field && a.right.value_type == null) {
-- var f = (Field) ma.symbol_reference;
--
-- if (a.right.symbol_reference is Method &&
-- f.field_type is DelegateType) {
-- var m = (Method) a.right.symbol_reference;
-- var dt = (DelegateType) f.field_type;
-- var cb = dt.delegate_symbol;
--
-- /* check whether method matches callback type */
-- if (!cb.matches_method (m)) {
-- f.error = true;
-- Report.error (a.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.get_full_name (), cb.get_full_name ()));
-- return;
-- }
--
-- a.right.value_type = f.field_type;
-- } else {
-- a.error = true;
-- Report.error (a.source_reference, "Assignment: Invalid callback assignment attempt");
-- return;
-- }
-- } else if (a.left.value_type != null && a.right.value_type != null) {
-- /* if there was an error on either side,
-- * i.e. a.{left|right}.value_type == null, skip type check */
--
-- if (!a.right.value_type.compatible (a.left.value_type)) {
-- a.error = true;
-- Report.error (a.source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (a.right.value_type.to_string (), a.left.value_type.to_string ()));
-- return;
-- }
--
-- if (a.right.value_type.is_disposable ()) {
-- /* rhs transfers ownership of the expression */
-- if (!(a.left.value_type is PointerType) && !a.left.value_type.value_owned) {
-- /* lhs doesn't own the value */
-- a.error = true;
-- Report.error (a.source_reference, "Invalid assignment from owned expression to unowned variable");
-- }
-- } else if (a.left.value_type.value_owned) {
-- /* lhs wants to own the value
-- * rhs doesn't transfer the ownership
-- * code generator needs to add reference
-- * increment calls */
-- }
-- }
-- } else if (a.left is ElementAccess) {
-- var ea = (ElementAccess) a.left;
--
-- if (!a.right.value_type.compatible (a.left.value_type)) {
-- a.error = true;
-- Report.error (a.source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (a.right.value_type.to_string (), a.left.value_type.to_string ()));
-- return;
-- }
--
-- if (a.right.value_type.is_disposable ()) {
-- /* rhs transfers ownership of the expression */
--
-- DataType element_type;
--
-- if (ea.container.value_type is ArrayType) {
-- var array_type = (ArrayType) ea.container.value_type;
-- element_type = array_type.element_type;
-- } else {
-- var args = ea.container.value_type.get_type_arguments ();
-- assert (args.size == 1);
-- element_type = args.get (0);
-- }
--
-- if (!(element_type is PointerType) && !element_type.value_owned) {
-- /* lhs doesn't own the value */
-- a.error = true;
-- Report.error (a.source_reference, "Invalid assignment from owned expression to unowned variable");
-- return;
-- }
-- } else if (a.left.value_type.value_owned) {
-- /* lhs wants to own the value
-- * rhs doesn't transfer the ownership
-- * code generator needs to add reference
-- * increment calls */
-- }
-- } else {
-- return;
-- }
--
-- if (a.left.value_type != null) {
-- a.value_type = a.left.value_type.copy ();
-- a.value_type.value_owned = false;
-- } else {
-- a.value_type = null;
-- }
--
-- a.add_error_types (a.left.get_error_types ());
-- a.add_error_types (a.right.get_error_types ());
-+ a.check (this);
- }
- }
-Index: vala/valasignal.vala
-===================================================================
---- vala/valasignal.vala (revision 1971)
-+++ vala/valasignal.vala (revision 2004)
-@@ -218,5 +218,19 @@
-
- return generated_method;
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ accept_children (analyzer);
-+
-+ return !error;
-+ }
- }
-
-Index: vala/valaexpressionstatement.vala
-===================================================================
---- vala/valaexpressionstatement.vala (revision 1971)
-+++ vala/valaexpressionstatement.vala (revision 2004)
-@@ -1,6 +1,6 @@
- /* valaexpressionstatement.vala
- *
-- * Copyright (C) 2006-2007 Jürg Billeter
-+ * Copyright (C) 2006-2008 Jürg Billeter
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
-@@ -85,4 +85,22 @@
-
- return null;
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ if (expression.error) {
-+ // ignore inner error
-+ error = true;
-+ return false;
-+ }
-+
-+ add_error_types (expression.get_error_types ());
-+
-+ return !error;
-+ }
- }
-Index: vala/valainvocationexpression.vala
-===================================================================
---- vala/valainvocationexpression.vala (revision 1971)
-+++ vala/valainvocationexpression.vala (revision 2004)
-@@ -120,4 +120,306 @@
- public override bool is_pure () {
- return false;
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ call.accept (analyzer);
-+
-+ if (call.error) {
-+ /* if method resolving didn't succeed, skip this check */
-+ error = true;
-+ return false;
-+ }
-+
-+ if (call is MemberAccess) {
-+ var ma = (MemberAccess) call;
-+ if (ma.prototype_access) {
-+ error = true;
-+ Report.error (source_reference, "Access to instance member `%s' denied".printf (call.symbol_reference.get_full_name ()));
-+ return false;
-+ }
-+ }
-+
-+ var mtype = call.value_type;
-+
-+ if (mtype is ObjectType) {
-+ // constructor chain-up
-+ var cm = analyzer.find_current_method () as CreationMethod;
-+ assert (cm != null);
-+ if (cm.chain_up) {
-+ error = true;
-+ Report.error (source_reference, "Multiple constructor calls in the same constructor are not permitted");
-+ return false;
-+ }
-+ cm.chain_up = true;
-+ }
-+
-+ // check for struct construction
-+ if (call is MemberAccess &&
-+ ((call.symbol_reference is CreationMethod
-+ && call.symbol_reference.parent_symbol is Struct)
-+ || call.symbol_reference is Struct)) {
-+ var struct_creation_expression = new ObjectCreationExpression ((MemberAccess) call, source_reference);
-+ struct_creation_expression.struct_creation = true;
-+ foreach (Expression arg in get_argument_list ()) {
-+ struct_creation_expression.add_argument (arg);
-+ }
-+ struct_creation_expression.target_type = target_type;
-+ analyzer.replaced_nodes.add (this);
-+ parent_node.replace_expression (this, struct_creation_expression);
-+ struct_creation_expression.accept (analyzer);
-+ return false;
-+ } else if (call is MemberAccess
-+ && call.symbol_reference is CreationMethod) {
-+ // constructor chain-up
-+ var cm = analyzer.find_current_method () as CreationMethod;
-+ assert (cm != null);
-+ if (cm.chain_up) {
-+ error = true;
-+ Report.error (source_reference, "Multiple constructor calls in the same constructor are not permitted");
-+ return false;
-+ }
-+ cm.chain_up = true;
-+ }
-+
-+ Gee.List<FormalParameter> params;
-+
-+ if (mtype != null && mtype.is_invokable ()) {
-+ params = mtype.get_parameters ();
-+ } else {
-+ error = true;
-+ Report.error (source_reference, "invocation not supported in this context");
-+ return false;
-+ }
-+
-+ Expression last_arg = null;
-+
-+ var args = get_argument_list ();
-+ Iterator<Expression> arg_it = args.iterator ();
-+ foreach (FormalParameter param in params) {
-+ if (param.ellipsis) {
-+ break;
-+ }
-+
-+ if (arg_it.next ()) {
-+ Expression arg = arg_it.get ();
-+
-+ /* store expected type for callback parameters */
-+ arg.target_type = param.parameter_type;
-+
-+ // resolve generic type parameters
-+ var ma = call as MemberAccess;
-+ if (arg.target_type.type_parameter != null) {
-+ if (ma != null && ma.inner != null) {
-+ arg.target_type = analyzer.get_actual_type (ma.inner.value_type, ma.symbol_reference, arg.target_type, arg);
-+ assert (arg.target_type != null);
-+ }
-+ }
-+
-+ last_arg = arg;
-+ }
-+ }
-+
-+ // printf arguments
-+ if (mtype is MethodType && ((MethodType) mtype).method_symbol.printf_format) {
-+ StringLiteral format_literal = null;
-+ if (last_arg != null) {
-+ // use last argument as format string
-+ format_literal = last_arg as StringLiteral;
-+ } else {
-+ // use instance as format string for string.printf (...)
-+ var ma = call as MemberAccess;
-+ if (ma != null) {
-+ format_literal = ma.inner as StringLiteral;
-+ }
-+ }
-+ if (format_literal != null) {
-+ string format = format_literal.eval ();
-+
-+ bool unsupported_format = false;
-+
-+ weak string format_it = format;
-+ unichar c = format_it.get_char ();
-+ while (c != '\0') {
-+ if (c != '%') {
-+ format_it = format_it.next_char ();
-+ c = format_it.get_char ();
-+ continue;
-+ }
-+
-+ format_it = format_it.next_char ();
-+ c = format_it.get_char ();
-+ // flags
-+ while (c == '#' || c == '0' || c == '-' || c == ' ' || c == '+') {
-+ format_it = format_it.next_char ();
-+ c = format_it.get_char ();
-+ }
-+ // field width
-+ while (c >= '0' && c <= '9') {
-+ format_it = format_it.next_char ();
-+ c = format_it.get_char ();
-+ }
-+ // precision
-+ if (c == '.') {
-+ format_it = format_it.next_char ();
-+ c = format_it.get_char ();
-+ while (c >= '0' && c <= '9') {
-+ format_it = format_it.next_char ();
-+ c = format_it.get_char ();
-+ }
-+ }
-+ // length modifier
-+ int length = 0;
-+ if (c == 'h') {
-+ length = -1;
-+ format_it = format_it.next_char ();
-+ c = format_it.get_char ();
-+ if (c == 'h') {
-+ length = -2;
-+ format_it = format_it.next_char ();
-+ c = format_it.get_char ();
-+ }
-+ } else if (c == 'l') {
-+ length = 1;
-+ format_it = format_it.next_char ();
-+ c = format_it.get_char ();
-+ } else if (c == 'z') {
-+ length = 2;
-+ format_it = format_it.next_char ();
-+ c = format_it.get_char ();
-+ }
-+ // conversion specifier
-+ DataType param_type = null;
-+ if (c == 'd' || c == 'i' || c == 'c') {
-+ // integer
-+ if (length == -2) {
-+ param_type = analyzer.int8_type;
-+ } else if (length == -1) {
-+ param_type = analyzer.short_type;
-+ } else if (length == 0) {
-+ param_type = analyzer.int_type;
-+ } else if (length == 1) {
-+ param_type = analyzer.long_type;
-+ } else if (length == 2) {
-+ param_type = analyzer.ssize_t_type;
-+ }
-+ } else if (c == 'o' || c == 'u' || c == 'x' || c == 'X') {
-+ // unsigned integer
-+ if (length == -2) {
-+ param_type = analyzer.uchar_type;
-+ } else if (length == -1) {
-+ param_type = analyzer.ushort_type;
-+ } else if (length == 0) {
-+ param_type = analyzer.uint_type;
-+ } else if (length == 1) {
-+ param_type = analyzer.ulong_type;
-+ } else if (length == 2) {
-+ param_type = analyzer.size_t_type;
-+ }
-+ } else if (c == 'e' || c == 'E' || c == 'f' || c == 'F'
-+ || c == 'g' || c == 'G' || c == 'a' || c == 'A') {
-+ // double
-+ param_type = analyzer.double_type;
-+ } else if (c == 's') {
-+ // string
-+ param_type = analyzer.string_type;
-+ } else if (c == 'p') {
-+ // pointer
-+ param_type = new PointerType (new VoidType ());
-+ } else if (c == '%') {
-+ // literal %
-+ } else {
-+ unsupported_format = true;
-+ break;
-+ }
-+ if (c != '\0') {
-+ format_it = format_it.next_char ();
-+ c = format_it.get_char ();
-+ }
-+ if (param_type != null) {
-+ if (arg_it.next ()) {
-+ Expression arg = arg_it.get ();
-+
-+ arg.target_type = param_type;
-+ } else {
-+ Report.error (source_reference, "Too few arguments for specified format");
-+ return false;
-+ }
-+ }
-+ }
-+ if (!unsupported_format && arg_it.next ()) {
-+ Report.error (source_reference, "Too many arguments for specified format");
-+ return false;
-+ }
-+ }
-+ }
-+
-+ foreach (Expression arg in get_argument_list ()) {
-+ arg.accept (analyzer);
-+ }
-+
-+ DataType ret_type;
-+
-+ ret_type = mtype.get_return_type ();
-+ params = mtype.get_parameters ();
-+
-+ if (ret_type is VoidType) {
-+ // void return type
-+ if (!(parent_node is ExpressionStatement)
-+ && !(parent_node is ForStatement)
-+ && !(parent_node is YieldStatement)) {
-+ // A void method invocation can be in the initializer or
-+ // iterator of a for statement
-+ error = true;
-+ Report.error (source_reference, "invocation of void method not allowed as expression");
-+ return false;
-+ }
-+ }
-+
-+ // resolve generic return values
-+ var ma = call as MemberAccess;
-+ if (ret_type.type_parameter != null) {
-+ if (ma != null && ma.inner != null) {
-+ ret_type = analyzer.get_actual_type (ma.inner.value_type, ma.symbol_reference, ret_type, this);
-+ if (ret_type == null) {
-+ return false;
-+ }
-+ }
-+ }
-+ Gee.List<DataType> resolved_type_args = new ArrayList<DataType> ();
-+ foreach (DataType type_arg in ret_type.get_type_arguments ()) {
-+ if (type_arg.type_parameter != null && ma != null && ma.inner != null) {
-+ resolved_type_args.add (analyzer.get_actual_type (ma.inner.value_type, ma.symbol_reference, type_arg, this));
-+ } else {
-+ resolved_type_args.add (type_arg);
-+ }
-+ }
-+ ret_type = ret_type.copy ();
-+ ret_type.remove_all_type_arguments ();
-+ foreach (DataType resolved_type_arg in resolved_type_args) {
-+ ret_type.add_type_argument (resolved_type_arg);
-+ }
-+
-+ if (mtype is MethodType) {
-+ var m = ((MethodType) mtype).method_symbol;
-+ foreach (DataType error_type in m.get_error_types ()) {
-+ // ensure we can trace back which expression may throw errors of this type
-+ var call_error_type = error_type.copy ();
-+ call_error_type.source_reference = source_reference;
-+
-+ add_error_type (call_error_type);
-+ }
-+ }
-+
-+ value_type = ret_type;
-+
-+ analyzer.check_arguments (this, mtype, params, get_argument_list ());
-+
-+ return !error;
-+ }
- }
-Index: vala/valatrystatement.vala
-===================================================================
---- vala/valatrystatement.vala (revision 1971)
-+++ vala/valatrystatement.vala (revision 2004)
-@@ -86,4 +86,16 @@
- finally_body.accept (visitor);
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ accept_children (analyzer);
-+
-+ return !error;
-+ }
- }
-Index: vala/valareturnstatement.vala
-===================================================================
---- vala/valareturnstatement.vala (revision 1971)
-+++ vala/valareturnstatement.vala (revision 2004)
-@@ -70,4 +70,77 @@
- return_expression = new_node;
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ if (return_expression != null) {
-+ return_expression.target_type = analyzer.current_return_type;
-+ }
-+
-+ accept_children (analyzer);
-+
-+ if (return_expression != null && return_expression.error) {
-+ // ignore inner error
-+ error = true;
-+ return false;
-+ }
-+
-+ if (analyzer.current_return_type == null) {
-+ error = true;
-+ Report.error (source_reference, "Return not allowed in this context");
-+ return false;
-+ }
-+
-+ if (return_expression == null) {
-+ if (!(analyzer.current_return_type is VoidType)) {
-+ error = true;
-+ Report.error (source_reference, "Return without value in non-void function");
-+ }
-+ return !error;
-+ }
-+
-+ if (analyzer.current_return_type is VoidType) {
-+ Report.error (source_reference, "Return with value in void function");
-+ return false;
-+ }
-+
-+ if (return_expression.value_type == null) {
-+ error = true;
-+ Report.error (source_reference, "Invalid expression in return value");
-+ return false;
-+ }
-+
-+ if (!return_expression.value_type.compatible (analyzer.current_return_type)) {
-+ error = true;
-+ Report.error (source_reference, "Return: Cannot convert from `%s' to `%s'".printf (return_expression.value_type.to_string (), analyzer.current_return_type.to_string ()));
-+ return false;
-+ }
-+
-+ if (return_expression.value_type.is_disposable () &&
-+ !analyzer.current_return_type.value_owned) {
-+ error = true;
-+ Report.error (source_reference, "Return value transfers ownership but method return type hasn't been declared to transfer ownership");
-+ return false;
-+ }
-+
-+ if (return_expression.symbol_reference is LocalVariable &&
-+ return_expression.value_type.is_disposable () &&
-+ !analyzer.current_return_type.value_owned) {
-+ Report.warning (source_reference, "Local variable with strong reference used as return value and method return type hasn't been declared to transfer ownership");
-+ }
-+
-+ if (analyzer.context.non_null && return_expression is NullLiteral
-+ && !analyzer.current_return_type.nullable) {
-+ Report.warning (source_reference, "`null' incompatible with return type `%s`".printf (analyzer.current_return_type.to_string ()));
-+ }
-+
-+ add_error_types (return_expression.get_error_types ());
-+
-+ return !error;
-+ }
- }
-Index: vala/valaclass.vala
-===================================================================
---- vala/valaclass.vala (revision 1971)
-+++ vala/valaclass.vala (revision 2004)
-@@ -814,5 +814,202 @@
- }
- }
- }
-+
-+ private void get_all_prerequisites (Interface iface, Gee.List<TypeSymbol> list) {
-+ foreach (DataType prereq in iface.get_prerequisites ()) {
-+ TypeSymbol type = prereq.data_type;
-+ /* skip on previous errors */
-+ if (type == null) {
-+ continue;
-+ }
-+
-+ list.add (type);
-+ if (type is Interface) {
-+ get_all_prerequisites ((Interface) type, list);
-+
-+ }
-+ }
-+ }
-+
-+ private bool class_is_a (Class cl, TypeSymbol t) {
-+ if (cl == t) {
-+ return true;
-+ }
-+
-+ foreach (DataType base_type in cl.get_base_types ()) {
-+ if (base_type.data_type is Class) {
-+ if (class_is_a ((Class) base_type.data_type, t)) {
-+ return true;
-+ }
-+ } else if (base_type.data_type == t) {
-+ return true;
-+ }
-+ }
-+
-+ return false;
-+ }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ var old_source_file = analyzer.current_source_file;
-+ var old_symbol = analyzer.current_symbol;
-+ var old_class = analyzer.current_class;
-+
-+ if (source_reference != null) {
-+ analyzer.current_source_file = source_reference.file;
-+ }
-+ analyzer.current_symbol = this;
-+ analyzer.current_class = this;
-+
-+ foreach (DataType base_type_reference in get_base_types ()) {
-+ if (!base_type_reference.check (analyzer)) {
-+ error = true;
-+ return false;
-+ }
-+
-+ // check whether base type is at least as accessible as the class
-+ if (!analyzer.is_type_accessible (this, base_type_reference)) {
-+ error = true;
-+ Report.error (source_reference, "base type `%s` is less accessible than class `%s`".printf (base_type_reference.to_string (), get_full_name ()));
-+ return false;
-+ }
-+
-+ analyzer.current_source_file.add_type_dependency (base_type_reference, SourceFileDependencyType.HEADER_FULL);
-+ }
-+
-+ accept_children (analyzer);
-+
-+ /* compact classes cannot implement interfaces */
-+ if (is_compact) {
-+ foreach (DataType base_type in get_base_types ()) {
-+ if (base_type.data_type is Interface) {
-+ error = true;
-+ Report.error (source_reference, "compact classes `%s` may not implement interfaces".printf (get_full_name ()));
-+ }
-+ }
-+ }
-+
-+ /* gather all prerequisites */
-+ Gee.List<TypeSymbol> prerequisites = new ArrayList<TypeSymbol> ();
-+ foreach (DataType base_type in get_base_types ()) {
-+ if (base_type.data_type is Interface) {
-+ get_all_prerequisites ((Interface) base_type.data_type, prerequisites);
-+ }
-+ }
-+ /* check whether all prerequisites are met */
-+ Gee.List<string> missing_prereqs = new ArrayList<string> ();
-+ foreach (TypeSymbol prereq in prerequisites) {
-+ if (!class_is_a (this, prereq)) {
-+ missing_prereqs.insert (0, prereq.get_full_name ());
-+ }
-+ }
-+ /* report any missing prerequisites */
-+ if (missing_prereqs.size > 0) {
-+ error = true;
-+
-+ string error_string = "%s: some prerequisites (".printf (get_full_name ());
-+ bool first = true;
-+ foreach (string s in missing_prereqs) {
-+ if (first) {
-+ error_string = "%s`%s'".printf (error_string, s);
-+ first = false;
-+ } else {
-+ error_string = "%s, `%s'".printf (error_string, s);
-+ }
-+ }
-+ error_string += ") are not met";
-+ Report.error (source_reference, error_string);
-+ }
-+
-+ /* VAPI classes don't have to specify overridden methods */
-+ if (!external_package) {
-+ /* all abstract symbols defined in base types have to be at least defined (or implemented) also in this type */
-+ foreach (DataType base_type in get_base_types ()) {
-+ if (base_type.data_type is Interface) {
-+ Interface iface = (Interface) base_type.data_type;
-+
-+ if (base_class != null && base_class.is_subtype_of (iface)) {
-+ // reimplementation of interface, class is not required to reimplement all methods
-+ break;
-+ }
-+
-+ /* We do not need to do expensive equality checking here since this is done
-+ * already. We only need to guarantee the symbols are present.
-+ */
-+
-+ /* check methods */
-+ foreach (Method m in iface.get_methods ()) {
-+ if (m.is_abstract) {
-+ Symbol sym = null;
-+ var base_class = this;
-+ while (base_class != null && !(sym is Method)) {
-+ sym = base_class.scope.lookup (m.name);
-+ base_class = base_class.base_class;
-+ }
-+ if (!(sym is Method)) {
-+ error = true;
-+ Report.error (source_reference, "`%s' does not implement interface method `%s'".printf (get_full_name (), m.get_full_name ()));
-+ }
-+ }
-+ }
-+
-+ /* check properties */
-+ foreach (Property prop in iface.get_properties ()) {
-+ if (prop.is_abstract) {
-+ Symbol sym = null;
-+ var base_class = this;
-+ while (base_class != null && !(sym is Property)) {
-+ sym = base_class.scope.lookup (prop.name);
-+ base_class = base_class.base_class;
-+ }
-+ if (!(sym is Property)) {
-+ error = true;
-+ Report.error (source_reference, "`%s' does not implement interface property `%s'".printf (get_full_name (), prop.get_full_name ()));
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ /* all abstract symbols defined in base classes have to be implemented in non-abstract classes */
-+ if (!is_abstract) {
-+ var base_class = base_class;
-+ while (base_class != null && base_class.is_abstract) {
-+ foreach (Method base_method in base_class.get_methods ()) {
-+ if (base_method.is_abstract) {
-+ var override_method = analyzer.symbol_lookup_inherited (this, base_method.name) as Method;
-+ if (override_method == null || !override_method.overrides) {
-+ error = true;
-+ Report.error (source_reference, "`%s' does not implement abstract method `%s'".printf (get_full_name (), base_method.get_full_name ()));
-+ }
-+ }
-+ }
-+ foreach (Property base_property in base_class.get_properties ()) {
-+ if (base_property.is_abstract) {
-+ var override_property = analyzer.symbol_lookup_inherited (this, base_property.name) as Property;
-+ if (override_property == null || !override_property.overrides) {
-+ error = true;
-+ Report.error (source_reference, "`%s' does not implement abstract property `%s'".printf (get_full_name (), base_property.get_full_name ()));
-+ }
-+ }
-+ }
-+ base_class = base_class.base_class;
-+ }
-+ }
-+ }
-+
-+ analyzer.current_source_file = old_source_file;
-+ analyzer.current_symbol = old_symbol;
-+ analyzer.current_class = old_class;
-+
-+ return !error;
-+ }
- }
-
-Index: vala/valaforstatement.vala
-===================================================================
---- vala/valaforstatement.vala (revision 1971)
-+++ vala/valaforstatement.vala (revision 2004)
-@@ -156,4 +156,40 @@
- }
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ accept_children (analyzer);
-+
-+ if (condition != null && condition.error) {
-+ /* if there was an error in the condition, skip this check */
-+ error = true;
-+ return false;
-+ }
-+
-+ if (condition != null && !condition.value_type.compatible (analyzer.bool_type)) {
-+ error = true;
-+ Report.error (condition.source_reference, "Condition must be boolean");
-+ return false;
-+ }
-+
-+ if (condition != null) {
-+ add_error_types (condition.get_error_types ());
-+ }
-+
-+ add_error_types (body.get_error_types ());
-+ foreach (Expression exp in get_initializer ()) {
-+ add_error_types (exp.get_error_types ());
-+ }
-+ foreach (Expression exp in get_iterator ()) {
-+ add_error_types (exp.get_error_types ());
-+ }
-+
-+ return !error;
-+ }
- }
-Index: vala/valaarraycreationexpression.vala
-===================================================================
---- vala/valaarraycreationexpression.vala (revision 1971)
-+++ vala/valaarraycreationexpression.vala (revision 2004)
-@@ -106,4 +106,118 @@
- element_type = new_type;
- }
- }
-+
-+ private int create_sizes_from_initializer_list (SemanticAnalyzer analyzer, InitializerList il, int rank, Gee.List<Literal> sl) {
-+ var init = new IntegerLiteral (il.size.to_string (), il.source_reference);
-+ init.accept (analyzer);
-+ sl.add (init);
-+
-+ int subsize = -1;
-+ foreach (Expression e in il.get_initializers ()) {
-+ if (e is InitializerList) {
-+ if (rank == 1) {
-+ il.error = true;
-+ e.error = true;
-+ Report.error (e.source_reference, "Expected array element, got array initializer list");
-+ return -1;
-+ }
-+ int size = create_sizes_from_initializer_list (analyzer, (InitializerList) e, rank - 1, sl);
-+ if (size == -1) {
-+ return -1;
-+ }
-+ if (subsize >= 0 && subsize != size) {
-+ il.error = true;
-+ Report.error (il.source_reference, "Expected initializer list of size %d, got size %d".printf (subsize, size));
-+ return -1;
-+ } else {
-+ subsize = size;
-+ }
-+ } else {
-+ if (rank != 1) {
-+ il.error = true;
-+ e.error = true;
-+ Report.error (e.source_reference, "Expected array initializer list, got array element");
-+ return -1;
-+ }
-+ }
-+ }
-+ return il.size;
-+ }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ Gee.List<Expression> size = get_sizes ();
-+ var initlist = initializer_list;
-+
-+ if (element_type != null) {
-+ element_type.accept (analyzer);
-+ }
-+
-+ foreach (Expression e in size) {
-+ e.accept (analyzer);
-+ }
-+
-+ var calc_sizes = new ArrayList<Literal> ();
-+ if (initlist != null) {
-+ initlist.target_type = new ArrayType (element_type, rank, source_reference);
-+
-+ initlist.accept (analyzer);
-+
-+ var ret = create_sizes_from_initializer_list (analyzer, initlist, rank, calc_sizes);
-+ if (ret == -1) {
-+ error = true;
-+ }
-+ }
-+
-+ if (size.size > 0) {
-+ /* check for errors in the size list */
-+ foreach (Expression e in size) {
-+ if (e.value_type == null) {
-+ /* return on previous error */
-+ return false;
-+ } else if (!(e.value_type.data_type is Struct) || !((Struct) e.value_type.data_type).is_integer_type ()) {
-+ error = true;
-+ Report.error (e.source_reference, "Expression of integer type expected");
-+ }
-+ }
-+ } else {
-+ if (initlist == null) {
-+ error = true;
-+ /* this is an internal error because it is already handeld by the parser */
-+ Report.error (source_reference, "internal error: initializer list expected");
-+ } else {
-+ foreach (Expression size in calc_sizes) {
-+ append_size (size);
-+ }
-+ }
-+ }
-+
-+ if (error) {
-+ return false;
-+ }
-+
-+ /* check for wrong elements inside the initializer */
-+ if (initializer_list != null && initializer_list.value_type == null) {
-+ return false;
-+ }
-+
-+ /* try to construct the type of the array */
-+ if (element_type == null) {
-+ error = true;
-+ Report.error (source_reference, "Cannot determine the element type of the created array");
-+ return false;
-+ }
-+
-+ element_type.value_owned = true;
-+
-+ value_type = new ArrayType (element_type, rank, source_reference);
-+ value_type.value_owned = true;
-+
-+ return !error;
-+ }
- }
-Index: vala/valastruct.vala
-===================================================================
---- vala/valastruct.vala (revision 1971)
-+++ vala/valastruct.vala (revision 2004)
-@@ -605,4 +605,28 @@
-
- return false;
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ process_attributes ();
-+
-+ analyzer.current_symbol = this;
-+ analyzer.current_struct = this;
-+
-+ accept_children (analyzer);
-+
-+ if (!external && !external_package && get_base_types ().size == 0 && get_fields ().size == 0) {
-+ Report.error (source_reference, "structs cannot be empty");
-+ }
-+
-+ analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+ analyzer.current_struct = null;
-+
-+ return !error;
-+ }
- }
-Index: vala/valaconstructor.vala
-===================================================================
---- vala/valaconstructor.vala (revision 1971)
-+++ vala/valaconstructor.vala (revision 2004)
-@@ -60,4 +60,28 @@
- body.accept (visitor);
- }
- }
-+
-+ public override bool check (SemanticAnalyzer analyzer) {
-+ if (checked) {
-+ return !error;
-+ }
-+
-+ checked = true;
-+
-+ this_parameter = new FormalParameter ("this", new ObjectType (analyzer.current_class));
-+ scope.add (this_parameter.name, this_parameter);
-+
-+ owner = analyzer.current_symbol.scope;
-+ analyzer.current_symbol = this;
-+
-+ accept_children (analyzer);
-+
-+ foreach (DataType body_error_type in body.get_error_types ()) {
-+ Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string()));
-+ }
-+
-+ analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
-+
-+ return !error;
-+ }
- }
-Index: ChangeLog
-===================================================================
---- ChangeLog (revision 1971)
-+++ ChangeLog (revision 2004)
-@@ -1,5 +1,273 @@
-+2008-11-09 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valaclass.vala:
-+ * vala/valainterface.vala:
-+ * vala/valamemberaccess.vala:
-+ * vala/valaobjecttype.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Ensure attributes of base types are processed before querying
-+ C header filenames
-+
-+2008-11-07 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valablock.vala:
-+ * vala/valacatchclause.vala:
-+ * vala/valadeclarationstatement.vala:
-+ * vala/valadeletestatement.vala:
-+ * vala/valadostatement.vala:
-+ * vala/valaexpressionstatement.vala:
-+ * vala/valaforstatement.vala:
-+ * vala/valaifstatement.vala:
-+ * vala/valainitializerlist.vala:
-+ * vala/valalocalvariable.vala:
-+ * vala/valalockstatement.vala:
-+ * vala/valasemanticanalyzer.vala:
-+ * vala/valaswitchsection.vala:
-+ * vala/valatrystatement.vala:
-+ * vala/valawhilestatement.vala:
-+
-+ Move statement checking to code nodes
-+
-+2008-11-07 Jürg Billeter <j@bitron.ch>
-+
-+ * vapi/glib-2.0.vapi:
-+
-+ Add g_rmdir binding
-+
-+2008-11-07 Jürg Billeter <j@bitron.ch>
-+
-+ * gobject/valadbusclientmodule.vala:
-+
-+ Fix D-Bus methods with out parameters but no return value
-+
-+2008-11-07 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valaconstant.vala:
-+ * vala/valaconstructor.vala:
-+ * vala/valacreationmethod.vala:
-+ * vala/valadestructor.vala:
-+ * vala/valafield.vala:
-+ * vala/valaformalparameter.vala:
-+ * vala/valaproperty.vala:
-+ * vala/valapropertyaccessor.vala:
-+ * vala/valasemanticanalyzer.vala:
-+ * vala/valasignal.vala:
-+
-+ Move member checking to code nodes
-+
-+2008-11-07 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valadelegate.vala:
-+ * vala/valaenum.vala:
-+ * vala/valaenumvalue.vala:
-+ * vala/valaerrorcode.vala:
-+ * vala/valaerrordomain.vala:
-+ * vala/valainterface.vala:
-+ * vala/valanamespace.vala:
-+ * vala/valasemanticanalyzer.vala:
-+ * vala/valastruct.vala:
-+
-+ Move type symbol checking to code nodes
-+
-+2008-11-07 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valaarraycreationexpression.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Move array creation expression checking to
-+ ArrayCreationExpression.check
-+
-+2008-11-07 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valasemanticanalyzer.vala:
-+ * vala/valathrowstatement.vala:
-+
-+ Move throw statement checking to ThrowStatement.check
-+
-+2008-11-07 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valareturnstatement.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Move return statement checking to ReturnStatement.check
-+
-+2008-11-07 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valaforeachstatement.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Move foreach statement checking to ForeachStatement.check
-+
-+2008-11-07 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valaelementaccess.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Move element access checking to ElementAccess.check
-+
-+2008-11-07 Jürg Billeter <j@bitron.ch>
-+
-+ * vapigen/valagirparser.vala:
-+
-+ Set source_reference in parsed nodes
-+
-+2008-11-06 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valamethod.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Move method checking to Method.check
-+
-+2008-11-06 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valaclass.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Move class checking to Class.check
-+
-+2008-11-06 Jürg Billeter <j@bitron.ch>
-+
-+ * gobject/Makefile.am:
-+ * gobject/valaccodedynamicsignalmodule.vala:
-+ * gobject/valaccodegenerator.vala:
-+ * gobject/valadbusclientmodule.vala:
-+ * gobject/valagerrormodule.vala:
-+ * gobject/valagobjectmodule.vala:
-+
-+ Move dynamic signal generation to GObjectModule and
-+ DBusClientModule
-+
-+2008-11-06 Jürg Billeter <j@bitron.ch>
-+
-+ * gobject/Makefile.am:
-+ * gobject/valaccodedynamicpropertymodule.vala:
-+ * gobject/valaccodedynamicsignalmodule.vala:
-+ * gobject/valaccodegenerator.vala:
-+ * gobject/valadbusclientmodule.vala:
-+ * gobject/valagobjectmodule.vala:
-+
-+ Move dynamic property generation to GObjectModule and
-+ DBusClientModule
-+
-+2008-11-06 Jürg Billeter <j@bitron.ch>
-+
-+ * gobject/valaccodebasemodule.vala:
-+ * gobject/valagobjectmodule.vala:
-+
-+ Move constructor code generation to GObjectModule
-+
-+2008-11-05 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valainvocationexpression.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Move invocation expression checking to InvocationExpression.check
-+
-+2008-11-05 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valamemberaccess.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Move member access checking to MemberAccess.check
-+
-+2008-11-05 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valabinaryexpression.vala:
-+ * vala/valaobjectcreationexpression.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Move object creation expression checking to
-+ ObjectCreationExpression.check
-+
-+2008-11-05 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valabinaryexpression.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Move binary expression checking to BinaryExpression.check
-+
-+2008-11-05 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valaassignment.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Move assignment checking to Assignment.check
-+
-+2008-11-05 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valaenum.vala:
-+ * gobject/valadbusclientmodule.vala:
-+ * gobject/valagsignalmodule.vala:
-+
-+ Support enums in D-Bus clients and servers, fixes bug 534105
-+
-+2008-11-05 Jürg Billeter <j@bitron.ch>
-+
-+ * gobject/Makefile.am:
-+ * gobject/valaccodebasemodule.vala:
-+ * gobject/valaccodecontrolflowmodule.vala:
-+ * gobject/valaccodegenerator.vala:
-+ * gobject/valaccodememberaccessmodule.vala:
-+
-+ Add CCodeControlFlowModule
-+
-+2008-11-04 Jürg Billeter <j@bitron.ch>
-+
-+ * vala/valadynamicproperty.vala:
-+ * vala/valaproperty.vala:
-+ * vala/valasemanticanalyzer.vala:
-+
-+ Fix crash when using dynamic properties, fixes bug 559304
-+
-+2008-11-04 Jürg Billeter <j@bitron.ch>
-+
-+ * gobject/valaccodememberaccessmodule.vala:
-+ * gobject/valagsignalmodule.vala:
-+
-+ Move signal emission to GSignalModule
-+
-+2008-11-04 Jürg Billeter <j@bitron.ch>
-+
-+ * gobject/valaccodebasemodule.vala:
-+ * gobject/valaccodedelegatemodule.vala:
-+
-+ Move delegate wrapper generation to CCodeDelegateModule
-+
-+2008-11-04 Jürg Billeter <j@bitron.ch>
-+
-+ * gobject/valaccodearraymodule.vala:
-+ * gobject/valaccodebasemodule.vala:
-+
-+ Move array dup wrapper generation to CCodeArrayModule
-+
-+2008-11-04 Jürg Billeter <j@bitron.ch>
-+
-+ * gobject/valaccodebasemodule.vala:
-+ * gobject/valagobjectmodule.vala:
-+
-+ Move construct property assignment to GObjectModule
-+
-+2008-11-04 Jürg Billeter <j@bitron.ch>
-+
-+ * gobject/valaccodeassignmentmodule.vala:
-+ * gobject/valagsignalmodule.vala:
-+
-+ Move signal connection and disconnection to GSignalModule
-+
-+2008-11-04 Jürg Billeter <j@bitron.ch>
-+
-+ * gobject/valaccodearraymodule.vala:
-+ * gobject/valagsignalmodule.vala:
-+
-+ Move detailed signal emission to GSignalModule
-+
- 2008-11-03 Jürg Billeter <j@bitron.ch>
-
-+ * configure.ac: Post-release version bump
-+
-+2008-11-03 Jürg Billeter <j@bitron.ch>
-+
- * NEWS: update for 0.5.1 release
-
- 2008-11-03 Jürg Billeter <j@bitron.ch>
-Index: vapigen/valagirparser.vala
-===================================================================
---- vapigen/valagirparser.vala (revision 1971)
-+++ vapigen/valagirparser.vala (revision 2004)
-@@ -153,7 +153,10 @@
- ns = new Namespace (namespace_name);
- new_namespace = true;
- } else {
-- ns.source_reference = new SourceReference (current_source_file);
-+ if (ns.external_package) {
-+ ns.attributes = null;
-+ ns.source_reference = get_current_src ();
-+ }
- }
-
- string cheader = get_attribute (ns.name, "c:header-filename");
-@@ -221,7 +224,7 @@
-
- Struct parse_alias () {
- start_element ("alias");
-- var st = new Struct (reader.get_attribute ("name"));
-+ var st = new Struct (reader.get_attribute ("name"), get_current_src ());
- st.access = SymbolAccessibility.PUBLIC;
- st.add_base_type (parse_type_from_name (reader.get_attribute ("target")));
- next ();
-@@ -231,7 +234,7 @@
-
- Enum parse_enumeration () {
- start_element ("enumeration");
-- var en = new Enum (reader.get_attribute ("name"));
-+ var en = new Enum (reader.get_attribute ("name"), get_current_src ());
- en.access = SymbolAccessibility.PUBLIC;
- next ();
-
-@@ -274,7 +277,7 @@
-
- Enum parse_bitfield () {
- start_element ("bitfield");
-- var en = new Enum (reader.get_attribute ("name"));
-+ var en = new Enum (reader.get_attribute ("name"), get_current_src ());
- en.access = SymbolAccessibility.PUBLIC;
- next ();
- while (current_token == MarkupTokenType.START_ELEMENT) {
-@@ -308,7 +311,7 @@
- } else {
- return_type = new VoidType ();
- }
-- var m = new Method (name, return_type);
-+ var m = new Method (name, return_type, get_current_src ());
- m.access = SymbolAccessibility.PUBLIC;
- m.binding = MemberBinding.STATIC;
- var parameters = new ArrayList<FormalParameter> ();
-@@ -360,14 +363,14 @@
- if (reader.name == "varargs") {
- start_element ("varargs");
- next ();
-- param = new FormalParameter.with_ellipsis ();
-+ param = new FormalParameter.with_ellipsis (get_current_src ());
- end_element ("varargs");
- } else {
- var type = parse_type (out array_length_idx);
- if (transfer == "full") {
- type.value_owned = true;
- }
-- param = new FormalParameter (name, type);
-+ param = new FormalParameter (name, type, get_current_src ());
- if (direction == "out") {
- param.direction = ParameterDirection.OUT;
- } else if (direction == "inout") {
-@@ -455,7 +458,7 @@
-
- Struct parse_record () {
- start_element ("record");
-- var st = new Struct (reader.get_attribute ("name"));
-+ var st = new Struct (reader.get_attribute ("name"), get_current_src ());
- st.access = SymbolAccessibility.PUBLIC;
- next ();
- while (current_token == MarkupTokenType.START_ELEMENT) {
-@@ -479,7 +482,7 @@
-
- Class parse_class () {
- start_element ("class");
-- var cl = new Class (reader.get_attribute ("name"));
-+ var cl = new Class (reader.get_attribute ("name"), get_current_src ());
- cl.access = SymbolAccessibility.PUBLIC;
-
- string parent = reader.get_attribute ("parent");
-@@ -575,7 +578,7 @@
-
- Interface parse_interface () {
- start_element ("interface");
-- var iface = new Interface (reader.get_attribute ("name"));
-+ var iface = new Interface (reader.get_attribute ("name"), get_current_src ());
- iface.access = SymbolAccessibility.PUBLIC;
- next ();
- var methods = new ArrayList<Method> ();
-@@ -619,7 +622,7 @@
- string name = reader.get_attribute ("name");
- next ();
- var type = parse_type ();
-- var field = new Field (name, type, null);
-+ var field = new Field (name, type, null, get_current_src ());
- field.access = SymbolAccessibility.PUBLIC;
- end_element ("field");
- return field;
-@@ -630,7 +633,7 @@
- string name = string.joinv ("_", reader.get_attribute ("name").split ("-"));
- next ();
- var type = parse_type ();
-- var prop = new Property (name, type, null, null);
-+ var prop = new Property (name, type, null, null, get_current_src ());
- prop.access = SymbolAccessibility.PUBLIC;
- prop.get_accessor = new PropertyAccessor (true, false, false, null, null);
- prop.set_accessor = new PropertyAccessor (false, true, false, null, null);
-@@ -648,7 +651,7 @@
- } else {
- return_type = new VoidType ();
- }
-- var d = new Delegate (name, return_type);
-+ var d = new Delegate (name, return_type, get_current_src ());
- d.access = SymbolAccessibility.PUBLIC;
- if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "parameters") {
- start_element ("parameters");
-@@ -669,7 +672,7 @@
-
- var return_type = parse_return_value ();
-
-- var m = new CreationMethod (null, name);
-+ var m = new CreationMethod (null, name, get_current_src ());
- m.access = SymbolAccessibility.PUBLIC;
- m.has_construct_function = false;
- if (m.name.has_prefix ("new_")) {
-@@ -698,7 +701,7 @@
- } else {
- return_type = new VoidType ();
- }
-- var m = new Method (name, return_type);
-+ var m = new Method (name, return_type, get_current_src ());
- m.access = SymbolAccessibility.PUBLIC;
- if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "parameters") {
- start_element ("parameters");
-@@ -726,7 +729,7 @@
- } else {
- return_type = new VoidType ();
- }
-- var m = new Method (name, return_type);
-+ var m = new Method (name, return_type, get_current_src ());
- m.access = SymbolAccessibility.PUBLIC;
- m.is_virtual = true;
- if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "parameters") {
-@@ -828,7 +831,7 @@
- string name = reader.get_attribute ("name");
- next ();
- var type = parse_type ();
-- var c = new Constant (name, type, null, null);
-+ var c = new Constant (name, type, null, get_current_src ());
- c.access = SymbolAccessibility.PUBLIC;
- end_element ("constant");
- return c;
-Index: vapi/glib-2.0.vapi
-===================================================================
---- vapi/glib-2.0.vapi (revision 1971)
-+++ vapi/glib-2.0.vapi (revision 2004)
-@@ -2205,6 +2205,8 @@
- public static int create_with_parents (string pathname, int mode);
- [CCode (cname = "mkdtemp")]
- public static weak string mkdtemp (string template);
-+ [CCode (cname = "g_rmdir")]
-+ public static int remove (string filename);
- }
-
- [Compact]
-Index: configure.ac
-===================================================================
---- configure.ac (revision 1971)
-+++ configure.ac (revision 2004)
-@@ -1,4 +1,4 @@
--AC_INIT([vala], [0.5.1], [j@bitron.ch], [vala])
-+AC_INIT([vala], [0.5.2], [j@bitron.ch], [vala])
- AC_CONFIG_SRCDIR([Makefile.am])
- AC_CONFIG_HEADERS(config.h)
- AM_INIT_AUTOMAKE([dist-bzip2])
-Index: gobject/valaccodedynamicpropertymodule.vala
-===================================================================
---- gobject/valaccodedynamicpropertymodule.vala (revision 1971)
-+++ gobject/valaccodedynamicpropertymodule.vala (revision 2004)
-@@ -1,238 +0,0 @@
--/* valaccodedynamicpropertymodule.vala
-- *
-- * Copyright (C) 2008 Jürg Billeter
-- *
-- * This library is free software; you can redistribute it and/or
-- * modify it under the terms of the GNU Lesser General Public
-- * License as published by the Free Software Foundation; either
-- * version 2.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>
-- */
--
--using GLib;
--using Gee;
--
--/**
-- * The link between a dynamic property and generated code.
-- */
--public class Vala.CCodeDynamicPropertyModule : CCodeDelegateModule {
-- int dynamic_property_id;
--
-- public CCodeDynamicPropertyModule (CCodeGenerator codegen, CCodeModule? next) {
-- base (codegen, next);
-- }
--
-- public override string get_dynamic_property_getter_cname (DynamicProperty node) {
-- string getter_cname = "_dynamic_get_%s%d".printf (node.name, dynamic_property_id++);
--
-- var dynamic_property = (DynamicProperty) node;
--
-- var func = new CCodeFunction (getter_cname, node.property_type.get_cname ());
-- func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
--
-- func.add_parameter (new CCodeFormalParameter ("obj", dynamic_property.dynamic_type.get_cname ()));
--
-- var block = new CCodeBlock ();
-- if (dynamic_property.dynamic_type.data_type == dbus_object_type) {
-- generate_dbus_property_getter_wrapper (node, block);
-- } else if (dynamic_property.dynamic_type.data_type != null
-- && dynamic_property.dynamic_type.data_type.is_subtype_of (gobject_type)) {
-- generate_gobject_property_getter_wrapper (node, block);
-- } else {
-- Report.error (node.source_reference, "dynamic properties are not supported for `%s'".printf (dynamic_property.dynamic_type.to_string ()));
-- }
--
-- // append to C source file
-- source_type_member_declaration.append (func.copy ());
--
-- func.block = block;
-- source_type_member_definition.append (func);
--
-- return getter_cname;
-- }
--
-- public override string get_dynamic_property_setter_cname (DynamicProperty node) {
-- string setter_cname = "_dynamic_set_%s%d".printf (node.name, dynamic_property_id++);
--
-- var dynamic_property = (DynamicProperty) node;
--
-- var func = new CCodeFunction (setter_cname, "void");
-- func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
--
-- func.add_parameter (new CCodeFormalParameter ("obj", dynamic_property.dynamic_type.get_cname ()));
-- func.add_parameter (new CCodeFormalParameter ("value", node.property_type.get_cname ()));
--
-- var block = new CCodeBlock ();
-- if (dynamic_property.dynamic_type.data_type == dbus_object_type) {
-- generate_dbus_property_setter_wrapper (node, block);
-- } else if (dynamic_property.dynamic_type.data_type != null
-- && dynamic_property.dynamic_type.data_type.is_subtype_of (gobject_type)) {
-- generate_gobject_property_setter_wrapper (node, block);
-- } else {
-- Report.error (node.source_reference, "dynamic properties are not supported for `%s'".printf (dynamic_property.dynamic_type.to_string ()));
-- }
--
-- // append to C source file
-- source_type_member_declaration.append (func.copy ());
--
-- func.block = block;
-- source_type_member_definition.append (func);
--
-- return setter_cname;
-- }
--
-- void generate_gobject_property_getter_wrapper (DynamicProperty node, CCodeBlock block) {
-- var cdecl = new CCodeDeclaration (node.property_type.get_cname ());
-- cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
-- block.add_statement (cdecl);
--
-- var call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get"));
-- call.add_argument (new CCodeIdentifier ("obj"));
-- call.add_argument (node.get_canonical_cconstant ());
-- call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
-- call.add_argument (new CCodeConstant ("NULL"));
--
-- block.add_statement (new CCodeExpressionStatement (call));
--
-- block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
-- }
--
-- void generate_gobject_property_setter_wrapper (DynamicProperty node, CCodeBlock block) {
-- var call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_set"));
-- call.add_argument (new CCodeIdentifier ("obj"));
-- call.add_argument (node.get_canonical_cconstant ());
-- call.add_argument (new CCodeIdentifier ("value"));
-- call.add_argument (new CCodeConstant ("NULL"));
--
-- block.add_statement (new CCodeExpressionStatement (call));
-- }
--
-- void create_dbus_property_proxy (DynamicProperty node, CCodeBlock block) {
-- var prop_proxy_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_new_from_proxy"));
-- prop_proxy_call.add_argument (new CCodeIdentifier ("obj"));
-- prop_proxy_call.add_argument (new CCodeConstant ("DBUS_INTERFACE_PROPERTIES"));
-- prop_proxy_call.add_argument (new CCodeConstant ("NULL"));
--
-- var prop_proxy_decl = new CCodeDeclaration ("DBusGProxy*");
-- prop_proxy_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("property_proxy", prop_proxy_call));
-- block.add_statement (prop_proxy_decl);
-- }
--
-- void generate_dbus_property_getter_wrapper (DynamicProperty node, CCodeBlock block) {
-- create_dbus_property_proxy (node, block);
--
-- // initialize GValue
-- var cvalinit = new CCodeInitializerList ();
-- cvalinit.append (new CCodeConstant ("0"));
--
-- var cval_decl = new CCodeDeclaration ("GValue");
-- cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("gvalue", cvalinit));
-- block.add_statement (cval_decl);
--
-- var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue"));
--
-- // call Get method on property proxy
-- var cdecl = new CCodeDeclaration (node.property_type.get_cname ());
-- cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
-- block.add_statement (cdecl);
--
-- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call"));
-- ccall.add_argument (new CCodeIdentifier ("property_proxy"));
-- ccall.add_argument (new CCodeConstant ("\"Get\""));
-- ccall.add_argument (new CCodeConstant ("NULL"));
--
-- ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
-- var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface"));
-- get_iface.add_argument (new CCodeIdentifier ("obj"));
-- ccall.add_argument (get_iface);
--
-- ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
-- ccall.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name))));
--
-- ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
--
-- ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE"));
-- ccall.add_argument (val_ptr);
--
-- ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
--
-- block.add_statement (new CCodeExpressionStatement (ccall));
--
-- // unref property proxy
-- var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
-- prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy"));
-- block.add_statement (new CCodeExpressionStatement (prop_proxy_unref));
--
-- // assign value to result variable
-- var cget_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_get_value_function ()));
-- cget_call.add_argument (val_ptr);
-- var assign = new CCodeAssignment (new CCodeIdentifier ("result"), cget_call);
-- block.add_statement (new CCodeExpressionStatement (assign));
--
-- // return result
-- block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
-- }
--
-- void generate_dbus_property_setter_wrapper (DynamicProperty node, CCodeBlock block) {
-- create_dbus_property_proxy (node, block);
--
-- // initialize GValue
-- var cvalinit = new CCodeInitializerList ();
-- cvalinit.append (new CCodeConstant ("0"));
--
-- var cval_decl = new CCodeDeclaration ("GValue");
-- cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("gvalue", cvalinit));
-- block.add_statement (cval_decl);
--
-- var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue"));
--
-- var cinit_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
-- cinit_call.add_argument (val_ptr);
-- cinit_call.add_argument (new CCodeIdentifier (node.property_type.data_type.get_type_id ()));
-- block.add_statement (new CCodeExpressionStatement (cinit_call));
--
-- var cset_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_set_value_function ()));
-- cset_call.add_argument (val_ptr);
-- cset_call.add_argument (new CCodeIdentifier ("value"));
-- block.add_statement (new CCodeExpressionStatement (cset_call));
--
-- // call Set method on property proxy
-- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call"));
-- ccall.add_argument (new CCodeIdentifier ("property_proxy"));
-- ccall.add_argument (new CCodeConstant ("\"Set\""));
-- ccall.add_argument (new CCodeConstant ("NULL"));
--
-- ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
-- var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface"));
-- get_iface.add_argument (new CCodeIdentifier ("obj"));
-- ccall.add_argument (get_iface);
--
-- ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
-- ccall.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name))));
--
-- ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE"));
-- ccall.add_argument (val_ptr);
--
-- ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
--
-- ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
--
-- block.add_statement (new CCodeExpressionStatement (ccall));
--
-- // unref property proxy
-- var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
-- prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy"));
-- block.add_statement (new CCodeExpressionStatement (prop_proxy_unref));
-- }
--}
-Index: gobject/valaccodedynamicsignalmodule.vala
-===================================================================
---- gobject/valaccodedynamicsignalmodule.vala (revision 1971)
-+++ gobject/valaccodedynamicsignalmodule.vala (revision 2004)
-@@ -1,195 +0,0 @@
--/* valaccodedynamicsignalmodule.vala
-- *
-- * Copyright (C) 2007-2008 Jürg Billeter
-- *
-- * This library is free software; you can redistribute it and/or
-- * modify it under the terms of the GNU Lesser General Public
-- * License as published by the Free Software Foundation; either
-- * version 2.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>
-- */
--
--using GLib;
--using Gee;
--
--/**
-- * The link between a dynamic signal and generated code.
-- */
--public class Vala.CCodeDynamicSignalModule : CCodeDynamicPropertyModule {
-- public CCodeDynamicSignalModule (CCodeGenerator codegen, CCodeModule? next) {
-- base (codegen, next);
-- }
--
-- int signal_wrapper_id;
--
-- public override string get_dynamic_signal_cname (DynamicSignal node) {
-- return "dynamic_%s%d_".printf (node.name, signal_wrapper_id++);
-- }
--
-- public override string get_dynamic_signal_connect_wrapper_name (DynamicSignal node) {
-- var dynamic_signal = (DynamicSignal) node;
--
-- string connect_wrapper_name = "_%sconnect".printf (get_dynamic_signal_cname (node));
-- var func = new CCodeFunction (connect_wrapper_name, "void");
-- func.add_parameter (new CCodeFormalParameter ("obj", "gpointer"));
-- func.add_parameter (new CCodeFormalParameter ("signal_name", "const char *"));
-- func.add_parameter (new CCodeFormalParameter ("handler", "GCallback"));
-- func.add_parameter (new CCodeFormalParameter ("data", "gpointer"));
-- var block = new CCodeBlock ();
-- if (dynamic_signal.dynamic_type.data_type == dbus_object_type) {
-- generate_dbus_connect_wrapper (node, block);
-- } else if (dynamic_signal.dynamic_type.data_type != null
-- && dynamic_signal.dynamic_type.data_type.is_subtype_of (gobject_type)) {
-- generate_gobject_connect_wrapper (node, block);
-- } else {
-- Report.error (node.source_reference, "dynamic signals are not supported for `%s'".printf (dynamic_signal.dynamic_type.to_string ()));
-- }
--
-- // append to C source file
-- source_type_member_declaration.append (func.copy ());
--
-- func.block = block;
-- source_type_member_definition.append (func);
--
-- return connect_wrapper_name;
-- }
--
-- public override string get_dynamic_signal_disconnect_wrapper_name (DynamicSignal node) {
-- var dynamic_signal = (DynamicSignal) node;
--
-- string disconnect_wrapper_name = "_%sdisconnect".printf (get_dynamic_signal_cname (node));
-- var func = new CCodeFunction (disconnect_wrapper_name, "void");
-- func.add_parameter (new CCodeFormalParameter ("obj", "gpointer"));
-- func.add_parameter (new CCodeFormalParameter ("signal_name", "const char *"));
-- func.add_parameter (new CCodeFormalParameter ("handler", "GCallback"));
-- func.add_parameter (new CCodeFormalParameter ("data", "gpointer"));
-- var block = new CCodeBlock ();
-- if (dynamic_signal.dynamic_type.data_type == dbus_object_type) {
-- generate_dbus_disconnect_wrapper (node, block);
-- } else {
-- Report.error (node.source_reference, "dynamic signals are not supported for `%s'".printf (dynamic_signal.dynamic_type.to_string ()));
-- }
--
-- // append to C source file
-- source_type_member_declaration.append (func.copy ());
--
-- func.block = block;
-- source_type_member_definition.append (func);
--
-- return disconnect_wrapper_name;
-- }
--
-- void generate_gobject_connect_wrapper (DynamicSignal node, CCodeBlock block) {
-- var dynamic_signal = (DynamicSignal) node;
--
-- var m = (Method) dynamic_signal.handler.symbol_reference;
--
-- node.accept (codegen);
--
-- string connect_func = "g_signal_connect_object";
-- if (m.binding != MemberBinding.INSTANCE) {
-- connect_func = "g_signal_connect";
-- }
--
-- var call = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
-- call.add_argument (new CCodeIdentifier ("obj"));
-- call.add_argument (new CCodeIdentifier ("signal_name"));
-- call.add_argument (new CCodeIdentifier ("handler"));
-- call.add_argument (new CCodeIdentifier ("data"));
--
-- if (m.binding == MemberBinding.INSTANCE) {
-- call.add_argument (new CCodeConstant ("0"));
-- }
--
-- block.add_statement (new CCodeExpressionStatement (call));
-- }
--
-- void generate_dbus_connect_wrapper (DynamicSignal node, CCodeBlock block) {
-- var dynamic_signal = (DynamicSignal) node;
--
-- var m = (Method) dynamic_signal.handler.symbol_reference;
--
-- node.accept (codegen);
--
-- // FIXME should only be done once per marshaller
-- var register_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_object_register_marshaller"));
-- head.generate_marshaller (node.get_parameters (), node.return_type, true);
-- register_call.add_argument (new CCodeIdentifier (head.get_marshaller_function (node.get_parameters (), node.return_type, null, true)));
-- register_call.add_argument (new CCodeIdentifier ("G_TYPE_NONE"));
--
-- var add_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_add_signal"));
-- add_call.add_argument (new CCodeIdentifier ("obj"));
-- add_call.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name))));
--
-- bool first = true;
-- foreach (FormalParameter param in m.get_parameters ()) {
-- if (first) {
-- // skip sender parameter
-- first = false;
-- continue;
-- }
--
-- var array_type = param.parameter_type as ArrayType;
-- if (array_type != null) {
-- if (array_type.element_type.data_type == string_type.data_type) {
-- register_call.add_argument (new CCodeIdentifier ("G_TYPE_STRV"));
-- add_call.add_argument (new CCodeIdentifier ("G_TYPE_STRV"));
-- } else {
-- if (array_type.element_type.data_type.get_type_id () == null) {
-- Report.error (param.source_reference, "unsupported parameter type for D-Bus signals");
-- return;
-- }
--
-- var carray_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_collection"));
-- carray_type.add_argument (new CCodeConstant ("\"GArray\""));
-- carray_type.add_argument (new CCodeIdentifier (array_type.element_type.data_type.get_type_id ()));
-- register_call.add_argument (carray_type);
-- add_call.add_argument (carray_type);
-- }
-- } else {
-- if (param.parameter_type.get_type_id () == null) {
-- Report.error (param.source_reference, "unsupported parameter type for D-Bus signals");
-- return;
-- }
--
-- register_call.add_argument (new CCodeIdentifier (param.parameter_type.get_type_id ()));
-- add_call.add_argument (new CCodeIdentifier (param.parameter_type.get_type_id ()));
-- }
-- }
-- register_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-- add_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
--
-- block.add_statement (new CCodeExpressionStatement (register_call));
-- block.add_statement (new CCodeExpressionStatement (add_call));
--
-- var call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_connect_signal"));
-- call.add_argument (new CCodeIdentifier ("obj"));
-- call.add_argument (new CCodeIdentifier ("signal_name"));
-- call.add_argument (new CCodeIdentifier ("handler"));
-- call.add_argument (new CCodeIdentifier ("data"));
-- call.add_argument (new CCodeConstant ("NULL"));
-- block.add_statement (new CCodeExpressionStatement (call));
-- }
--
-- void generate_dbus_disconnect_wrapper (DynamicSignal node, CCodeBlock block) {
-- var dynamic_signal = (DynamicSignal) node;
--
-- var call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_disconnect_signal"));
-- call.add_argument (new CCodeIdentifier ("obj"));
-- call.add_argument (new CCodeIdentifier ("signal_name"));
-- call.add_argument (new CCodeIdentifier ("handler"));
-- call.add_argument (new CCodeIdentifier ("data"));
-- block.add_statement (new CCodeExpressionStatement (call));
-- }
--}
-Index: gobject/valagsignalmodule.vala
-===================================================================
---- gobject/valagsignalmodule.vala (revision 1971)
-+++ gobject/valagsignalmodule.vala (revision 2004)
-@@ -47,6 +47,17 @@
- return ("VOID");
- } else if (dbus && t.get_type_signature ().has_prefix ("(")) {
- return ("BOXED");
-+ } else if (t.data_type is Enum) {
-+ var en = (Enum) t.data_type;
-+ if (dbus) {
-+ if (en.is_flags) {
-+ return ("UINT");
-+ } else {
-+ return ("INT");
-+ }
-+ } else {
-+ return en.get_marshaller_type_name ();
-+ }
- } else {
- return t.data_type.get_marshaller_type_name ();
- }
-@@ -266,6 +277,13 @@
- get_value_function = "g_value_get_pointer";
- } else if (dbus && p.parameter_type.get_type_signature ().has_prefix ("(")) {
- get_value_function = "g_value_get_boxed";
-+ } else if (dbus && p.parameter_type.data_type is Enum) {
-+ var en = (Enum) p.parameter_type.data_type;
-+ if (en.is_flags) {
-+ get_value_function = "g_value_get_uint";
-+ } else {
-+ get_value_function = "g_value_get_int";
-+ }
- } else {
- get_value_function = p.parameter_type.data_type.get_get_value_function ();
- }
-@@ -306,6 +324,13 @@
- set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_object"));
- } else if (dbus && return_type.get_type_signature ().has_prefix ("(")) {
- set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_boxed"));
-+ } else if (dbus && return_type.data_type is Enum) {
-+ var en = (Enum) return_type.data_type;
-+ if (en.is_flags) {
-+ set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_uint"));
-+ } else {
-+ set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_int"));
-+ }
- } else {
- set_fc = new CCodeFunctionCall (new CCodeIdentifier (return_type.data_type.get_set_value_function ()));
- }
-@@ -378,5 +403,228 @@
-
- return csignew;
- }
-+
-+ public override void visit_element_access (ElementAccess expr) {
-+ if (expr.container is MemberAccess && expr.container.symbol_reference is Signal) {
-+ // detailed signal emission
-+ var sig = (Signal) expr.symbol_reference;
-+ var ma = (MemberAccess) expr.container;
-+
-+ expr.accept_children (codegen);
-+
-+ var detail_expr = expr.get_indices ().get (0) as StringLiteral;
-+ string signal_detail = detail_expr.eval ();
-+
-+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
-+
-+ // FIXME: use C cast if debugging disabled
-+ var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
-+ ccast.add_argument ((CCodeExpression) ma.inner.ccodenode);
-+ ccall.add_argument (ccast);
-+
-+ ccall.add_argument (sig.get_canonical_cconstant (signal_detail));
-+
-+ expr.ccodenode = ccall;
-+ } else {
-+ base.visit_element_access (expr);
-+ }
-+ }
-+
-+ CCodeExpression? emit_signal_assignment (Assignment assignment) {
-+ var sig = (Signal) assignment.left.symbol_reference;
-+
-+ var m = (Method) assignment.right.symbol_reference;
-+
-+ string connect_func;
-+ bool disconnect = false;
-+
-+ if (assignment.operator == AssignmentOperator.ADD) {
-+ if (sig is DynamicSignal) {
-+ connect_func = head.get_dynamic_signal_connect_wrapper_name ((DynamicSignal) sig);
-+ } else {
-+ connect_func = "g_signal_connect_object";
-+ if (m.binding != MemberBinding.INSTANCE) {
-+ connect_func = "g_signal_connect";
-+ }
-+ }
-+ } else if (assignment.operator == AssignmentOperator.SUB) {
-+ if (sig is DynamicSignal) {
-+ connect_func = head.get_dynamic_signal_disconnect_wrapper_name ((DynamicSignal) sig);
-+ } else {
-+ connect_func = "g_signal_handlers_disconnect_matched";
-+ }
-+ disconnect = true;
-+ } else {
-+ assignment.error = true;
-+ Report.error (assignment.source_reference, "Specified compound assignment type for signals not supported.");
-+ return null;
-+ }
-+
-+ var ccall = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
-+
-+ string signal_detail = null;
-+
-+ // first argument: instance of sender
-+ MemberAccess ma;
-+ if (assignment.left is ElementAccess) {
-+ var ea = (ElementAccess) assignment.left;
-+ ma = (MemberAccess) ea.container;
-+ var detail_expr = ea.get_indices ().get (0) as StringLiteral;
-+ if (detail_expr == null) {
-+ assignment.error = true;
-+ Report.error (detail_expr.source_reference, "internal error: only literal string details supported");
-+ return null;
-+ }
-+ signal_detail = detail_expr.eval ();
-+ } else {
-+ ma = (MemberAccess) assignment.left;
-+ }
-+ if (ma.inner != null) {
-+ ccall.add_argument ((CCodeExpression) get_ccodenode (ma.inner));
-+ } else {
-+ ccall.add_argument (new CCodeIdentifier ("self"));
-+ }
-+
-+ if (sig is DynamicSignal) {
-+ // dynamic_signal_connect or dynamic_signal_disconnect
-+
-+ // second argument: signal name
-+ ccall.add_argument (new CCodeConstant ("\"%s\"".printf (sig.name)));
-+ } else if (!disconnect) {
-+ // g_signal_connect_object or g_signal_connect
-+
-+ // second argument: signal name
-+ ccall.add_argument (sig.get_canonical_cconstant (signal_detail));
-+ } else {
-+ // g_signal_handlers_disconnect_matched
-+
-+ // second argument: mask
-+ if (signal_detail == null) {
-+ ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
-+ } else {
-+ ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
-+ }
-+
-+ // get signal id
-+ var ccomma = new CCodeCommaExpression ();
-+ var temp_decl = get_temp_variable (uint_type);
-+ temp_vars.insert (0, temp_decl);
-+ var parse_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_parse_name"));
-+ parse_call.add_argument (sig.get_canonical_cconstant (signal_detail));
-+ var decl_type = (TypeSymbol) sig.parent_symbol;
-+ parse_call.add_argument (new CCodeIdentifier (decl_type.get_type_id ()));
-+ parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name)));
-+ if (signal_detail == null) {
-+ parse_call.add_argument (new CCodeConstant ("NULL"));
-+ } else {
-+ var detail_temp_decl = get_temp_variable (gquark_type);
-+ temp_vars.insert (0, detail_temp_decl);
-+ parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (detail_temp_decl.name)));
-+ }
-+ parse_call.add_argument (new CCodeConstant ("FALSE"));
-+ ccomma.append_expression (parse_call);
-+ ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
-+
-+ // third argument: signal_id
-+ ccall.add_argument (ccomma);
-+
-+ // fourth argument: detail
-+ ccall.add_argument (new CCodeConstant ("0"));
-+ // fifth argument: closure
-+ ccall.add_argument (new CCodeConstant ("NULL"));
-+ }
-+
-+ // third resp. sixth argument: handler
-+ ccall.add_argument (new CCodeCastExpression ((CCodeExpression) assignment.right.ccodenode, "GCallback"));
-+
-+ if (m.binding == MemberBinding.INSTANCE) {
-+ // g_signal_connect_object or g_signal_handlers_disconnect_matched
-+ // or dynamic_signal_connect or dynamic_signal_disconnect
-+
-+ // fourth resp. seventh argument: object/user_data
-+ if (assignment.right is MemberAccess) {
-+ var right_ma = (MemberAccess) assignment.right;
-+ if (right_ma.inner != null) {
-+ ccall.add_argument ((CCodeExpression) right_ma.inner.ccodenode);
-+ } else {
-+ ccall.add_argument (new CCodeIdentifier ("self"));
-+ }
-+ } else if (assignment.right is LambdaExpression) {
-+ ccall.add_argument (new CCodeIdentifier ("self"));
-+ }
-+ if (!disconnect && !(sig is DynamicSignal)) {
-+ // g_signal_connect_object
-+
-+ // fifth argument: connect_flags
-+ ccall.add_argument (new CCodeConstant ("0"));
-+ }
-+ } else {
-+ // g_signal_connect or g_signal_handlers_disconnect_matched
-+ // or dynamic_signal_connect or dynamic_signal_disconnect
-+
-+ // fourth resp. seventh argument: user_data
-+ ccall.add_argument (new CCodeConstant ("NULL"));
-+ }
-+
-+ return ccall;
-+ }
-+
-+ public override void visit_assignment (Assignment assignment) {
-+ if (assignment.left.symbol_reference is Signal) {
-+ assignment.right.accept (codegen);
-+
-+ if (assignment.left.error || assignment.right.error) {
-+ assignment.error = true;
-+ return;
-+ }
-+
-+ assignment.ccodenode = emit_signal_assignment (assignment);
-+ } else {
-+ base.visit_assignment (assignment);
-+ }
-+ }
-+
-+ public override void visit_member_access (MemberAccess expr) {
-+ CCodeExpression pub_inst = null;
-+
-+ if (expr.inner != null) {
-+ pub_inst = (CCodeExpression) expr.inner.ccodenode;
-+ }
-+
-+ if (expr.symbol_reference is Signal) {
-+ var sig = (Signal) expr.symbol_reference;
-+ var cl = (TypeSymbol) sig.parent_symbol;
-+
-+ if (expr.inner is BaseAccess && sig.is_virtual) {
-+ var m = sig.get_method_handler ();
-+ var base_class = (Class) m.parent_symbol;
-+ var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (base_class.get_upper_case_cname (null))));
-+ vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (current_class.get_lower_case_cname (null))));
-+
-+ expr.ccodenode = new CCodeMemberAccess.pointer (vcast, m.name);
-+ return;
-+ }
-+
-+ if (sig.has_emitter) {
-+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_%s".printf (cl.get_lower_case_cname (null), sig.name)));
-+
-+ ccall.add_argument (pub_inst);
-+ expr.ccodenode = ccall;
-+ } else {
-+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
-+
-+ // FIXME: use C cast if debugging disabled
-+ var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
-+ ccast.add_argument (pub_inst);
-+ ccall.add_argument (ccast);
-+
-+ ccall.add_argument (sig.get_canonical_cconstant ());
-+
-+ expr.ccodenode = ccall;
-+ }
-+ } else {
-+ base.visit_member_access (expr);
-+ }
-+ }
- }
-
-Index: gobject/valaccodememberaccessmodule.vala
-===================================================================
---- gobject/valaccodememberaccessmodule.vala (revision 1971)
-+++ gobject/valaccodememberaccessmodule.vala (revision 2004)
-@@ -23,12 +23,23 @@
-
- using GLib;
-
--public class Vala.CCodeMemberAccessModule : CCodeMethodModule {
-+public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
- public CCodeMemberAccessModule (CCodeGenerator codegen, CCodeModule? next) {
- base (codegen, next);
- }
-
-- private void process_cmember (MemberAccess expr, CCodeExpression? pub_inst, DataType? base_type) {
-+ public override void visit_member_access (MemberAccess expr) {
-+ CCodeExpression pub_inst = null;
-+ DataType base_type = null;
-+
-+ if (expr.inner != null) {
-+ pub_inst = (CCodeExpression) expr.inner.ccodenode;
-+
-+ if (expr.inner.value_type != null) {
-+ base_type = expr.inner.value_type;
-+ }
-+ }
-+
- if (expr.symbol_reference is Method) {
- var m = (Method) expr.symbol_reference;
-
-@@ -259,53 +270,7 @@
- }
- }
- }
-- } else if (expr.symbol_reference is Signal) {
-- var sig = (Signal) expr.symbol_reference;
-- var cl = (TypeSymbol) sig.parent_symbol;
--
-- if (expr.inner is BaseAccess && sig.is_virtual) {
-- var m = sig.get_method_handler ();
-- var base_class = (Class) m.parent_symbol;
-- var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (base_class.get_upper_case_cname (null))));
-- vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (current_class.get_lower_case_cname (null))));
--
-- expr.ccodenode = new CCodeMemberAccess.pointer (vcast, m.name);
-- return;
-- }
--
-- if (sig.has_emitter) {
-- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_%s".printf (cl.get_lower_case_cname (null), sig.name)));
--
-- ccall.add_argument (pub_inst);
-- expr.ccodenode = ccall;
-- } else {
-- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
--
-- // FIXME: use C cast if debugging disabled
-- var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
-- ccast.add_argument (pub_inst);
-- ccall.add_argument (ccast);
--
-- ccall.add_argument (sig.get_canonical_cconstant ());
--
-- expr.ccodenode = ccall;
-- }
- }
- }
--
-- public override void visit_member_access (MemberAccess expr) {
-- CCodeExpression pub_inst = null;
-- DataType base_type = null;
--
-- if (expr.inner != null) {
-- pub_inst = (CCodeExpression) expr.inner.ccodenode;
--
-- if (expr.inner.value_type != null) {
-- base_type = expr.inner.value_type;
-- }
-- }
--
-- process_cmember (expr, pub_inst, base_type);
-- }
- }
-
-Index: gobject/valadbusclientmodule.vala
-===================================================================
---- gobject/valadbusclientmodule.vala (revision 1971)
-+++ gobject/valadbusclientmodule.vala (revision 2004)
-@@ -29,6 +29,8 @@
- * The link between a dynamic method and generated code.
- */
- public class Vala.DBusClientModule : GAsyncModule {
-+ int dynamic_property_id;
-+
- public DBusClientModule (CCodeGenerator codegen, CCodeModule? next) {
- base (codegen, next);
- }
-@@ -433,6 +435,10 @@
- block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
- }
- } else {
-+ if (found_out) {
-+ ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+ }
-+
- block.add_statement (new CCodeExpressionStatement (ccall));
-
- // don't access result when error occured
-@@ -460,6 +466,13 @@
- }
- carray_type.add_argument (get_dbus_g_type (array_type.element_type));
- return carray_type;
-+ } else if (data_type.data_type is Enum) {
-+ var en = (Enum) data_type.data_type;
-+ if (en.is_flags) {
-+ return new CCodeIdentifier ("G_TYPE_UINT");
-+ } else {
-+ return new CCodeIdentifier ("G_TYPE_INT");
-+ }
- } else if (data_type.data_type == null) {
- critical ("Internal error during DBus type generation with: %s", data_type.to_string ());
- return new CCodeIdentifier ("G_TYPE_NONE");
-@@ -502,4 +515,291 @@
- return true;
- }
- }
-+
-+ public override string get_dynamic_property_getter_cname (DynamicProperty prop) {
-+ if (prop.dynamic_type.data_type != dbus_object_type) {
-+ return base.get_dynamic_property_getter_cname (prop);
-+ }
-+
-+ string getter_cname = "_dynamic_get_%s%d".printf (prop.name, dynamic_property_id++);
-+
-+ var func = new CCodeFunction (getter_cname, prop.property_type.get_cname ());
-+ func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
-+
-+ func.add_parameter (new CCodeFormalParameter ("obj", prop.dynamic_type.get_cname ()));
-+
-+ var block = new CCodeBlock ();
-+ generate_dbus_property_getter_wrapper (prop, block);
-+
-+ // append to C source file
-+ source_type_member_declaration.append (func.copy ());
-+
-+ func.block = block;
-+ source_type_member_definition.append (func);
-+
-+ return getter_cname;
-+ }
-+
-+ public override string get_dynamic_property_setter_cname (DynamicProperty prop) {
-+ if (prop.dynamic_type.data_type != dbus_object_type) {
-+ return base.get_dynamic_property_setter_cname (prop);
-+ }
-+
-+ string setter_cname = "_dynamic_set_%s%d".printf (prop.name, dynamic_property_id++);
-+
-+ var func = new CCodeFunction (setter_cname, "void");
-+ func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
-+
-+ func.add_parameter (new CCodeFormalParameter ("obj", prop.dynamic_type.get_cname ()));
-+ func.add_parameter (new CCodeFormalParameter ("value", prop.property_type.get_cname ()));
-+
-+ var block = new CCodeBlock ();
-+ generate_dbus_property_setter_wrapper (prop, block);
-+
-+ // append to C source file
-+ source_type_member_declaration.append (func.copy ());
-+
-+ func.block = block;
-+ source_type_member_definition.append (func);
-+
-+ return setter_cname;
-+ }
-+
-+ void create_dbus_property_proxy (DynamicProperty node, CCodeBlock block) {
-+ var prop_proxy_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_new_from_proxy"));
-+ prop_proxy_call.add_argument (new CCodeIdentifier ("obj"));
-+ prop_proxy_call.add_argument (new CCodeConstant ("DBUS_INTERFACE_PROPERTIES"));
-+ prop_proxy_call.add_argument (new CCodeConstant ("NULL"));
-+
-+ var prop_proxy_decl = new CCodeDeclaration ("DBusGProxy*");
-+ prop_proxy_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("property_proxy", prop_proxy_call));
-+ block.add_statement (prop_proxy_decl);
-+ }
-+
-+ void generate_dbus_property_getter_wrapper (DynamicProperty node, CCodeBlock block) {
-+ create_dbus_property_proxy (node, block);
-+
-+ // initialize GValue
-+ var cvalinit = new CCodeInitializerList ();
-+ cvalinit.append (new CCodeConstant ("0"));
-+
-+ var cval_decl = new CCodeDeclaration ("GValue");
-+ cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("gvalue", cvalinit));
-+ block.add_statement (cval_decl);
-+
-+ var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue"));
-+
-+ // call Get method on property proxy
-+ var cdecl = new CCodeDeclaration (node.property_type.get_cname ());
-+ cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
-+ block.add_statement (cdecl);
-+
-+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call"));
-+ ccall.add_argument (new CCodeIdentifier ("property_proxy"));
-+ ccall.add_argument (new CCodeConstant ("\"Get\""));
-+ ccall.add_argument (new CCodeConstant ("NULL"));
-+
-+ ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
-+ var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface"));
-+ get_iface.add_argument (new CCodeIdentifier ("obj"));
-+ ccall.add_argument (get_iface);
-+
-+ ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
-+ ccall.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name))));
-+
-+ ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+
-+ ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE"));
-+ ccall.add_argument (val_ptr);
-+
-+ ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+
-+ block.add_statement (new CCodeExpressionStatement (ccall));
-+
-+ // unref property proxy
-+ var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
-+ prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy"));
-+ block.add_statement (new CCodeExpressionStatement (prop_proxy_unref));
-+
-+ // assign value to result variable
-+ var cget_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_get_value_function ()));
-+ cget_call.add_argument (val_ptr);
-+ var assign = new CCodeAssignment (new CCodeIdentifier ("result"), cget_call);
-+ block.add_statement (new CCodeExpressionStatement (assign));
-+
-+ // return result
-+ block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
-+ }
-+
-+ void generate_dbus_property_setter_wrapper (DynamicProperty node, CCodeBlock block) {
-+ create_dbus_property_proxy (node, block);
-+
-+ // initialize GValue
-+ var cvalinit = new CCodeInitializerList ();
-+ cvalinit.append (new CCodeConstant ("0"));
-+
-+ var cval_decl = new CCodeDeclaration ("GValue");
-+ cval_decl.add_declarator (new CCodeVariableDeclarator.with_initializer ("gvalue", cvalinit));
-+ block.add_statement (cval_decl);
-+
-+ var val_ptr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("gvalue"));
-+
-+ var cinit_call = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
-+ cinit_call.add_argument (val_ptr);
-+ cinit_call.add_argument (new CCodeIdentifier (node.property_type.data_type.get_type_id ()));
-+ block.add_statement (new CCodeExpressionStatement (cinit_call));
-+
-+ var cset_call = new CCodeFunctionCall (new CCodeIdentifier (node.property_type.data_type.get_set_value_function ()));
-+ cset_call.add_argument (val_ptr);
-+ cset_call.add_argument (new CCodeIdentifier ("value"));
-+ block.add_statement (new CCodeExpressionStatement (cset_call));
-+
-+ // call Set method on property proxy
-+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_call"));
-+ ccall.add_argument (new CCodeIdentifier ("property_proxy"));
-+ ccall.add_argument (new CCodeConstant ("\"Set\""));
-+ ccall.add_argument (new CCodeConstant ("NULL"));
-+
-+ ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
-+ var get_iface = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_interface"));
-+ get_iface.add_argument (new CCodeIdentifier ("obj"));
-+ ccall.add_argument (get_iface);
-+
-+ ccall.add_argument (new CCodeIdentifier ("G_TYPE_STRING"));
-+ ccall.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (node.name))));
-+
-+ ccall.add_argument (new CCodeIdentifier ("G_TYPE_VALUE"));
-+ ccall.add_argument (val_ptr);
-+
-+ ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+
-+ ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+
-+ block.add_statement (new CCodeExpressionStatement (ccall));
-+
-+ // unref property proxy
-+ var prop_proxy_unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
-+ prop_proxy_unref.add_argument (new CCodeIdentifier ("property_proxy"));
-+ block.add_statement (new CCodeExpressionStatement (prop_proxy_unref));
-+ }
-+
-+ public override string get_dynamic_signal_connect_wrapper_name (DynamicSignal sig) {
-+ if (sig.dynamic_type.data_type != dbus_object_type) {
-+ return base.get_dynamic_signal_connect_wrapper_name (sig);
-+ }
-+
-+ string connect_wrapper_name = "_%sconnect".printf (get_dynamic_signal_cname (sig));
-+ var func = new CCodeFunction (connect_wrapper_name, "void");
-+ func.add_parameter (new CCodeFormalParameter ("obj", "gpointer"));
-+ func.add_parameter (new CCodeFormalParameter ("signal_name", "const char *"));
-+ func.add_parameter (new CCodeFormalParameter ("handler", "GCallback"));
-+ func.add_parameter (new CCodeFormalParameter ("data", "gpointer"));
-+ var block = new CCodeBlock ();
-+ generate_dbus_connect_wrapper (sig, block);
-+
-+ // append to C source file
-+ source_type_member_declaration.append (func.copy ());
-+
-+ func.block = block;
-+ source_type_member_definition.append (func);
-+
-+ return connect_wrapper_name;
-+ }
-+
-+ public override string get_dynamic_signal_disconnect_wrapper_name (DynamicSignal sig) {
-+ if (sig.dynamic_type.data_type != dbus_object_type) {
-+ return base.get_dynamic_signal_disconnect_wrapper_name (sig);
-+ }
-+
-+ string disconnect_wrapper_name = "_%sdisconnect".printf (get_dynamic_signal_cname (sig));
-+ var func = new CCodeFunction (disconnect_wrapper_name, "void");
-+ func.add_parameter (new CCodeFormalParameter ("obj", "gpointer"));
-+ func.add_parameter (new CCodeFormalParameter ("signal_name", "const char *"));
-+ func.add_parameter (new CCodeFormalParameter ("handler", "GCallback"));
-+ func.add_parameter (new CCodeFormalParameter ("data", "gpointer"));
-+ var block = new CCodeBlock ();
-+ generate_dbus_disconnect_wrapper (sig, block);
-+
-+ // append to C source file
-+ source_type_member_declaration.append (func.copy ());
-+
-+ func.block = block;
-+ source_type_member_definition.append (func);
-+
-+ return disconnect_wrapper_name;
-+ }
-+
-+ void generate_dbus_connect_wrapper (DynamicSignal sig, CCodeBlock block) {
-+ var m = (Method) sig.handler.symbol_reference;
-+
-+ sig.accept (codegen);
-+
-+ // FIXME should only be done once per marshaller
-+ var register_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_object_register_marshaller"));
-+ head.generate_marshaller (sig.get_parameters (), sig.return_type, true);
-+ register_call.add_argument (new CCodeIdentifier (head.get_marshaller_function (sig.get_parameters (), sig.return_type, null, true)));
-+ register_call.add_argument (new CCodeIdentifier ("G_TYPE_NONE"));
-+
-+ var add_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_add_signal"));
-+ add_call.add_argument (new CCodeIdentifier ("obj"));
-+ add_call.add_argument (new CCodeConstant ("\"%s\"".printf (Symbol.lower_case_to_camel_case (sig.name))));
-+
-+ bool first = true;
-+ foreach (FormalParameter param in m.get_parameters ()) {
-+ if (first) {
-+ // skip sender parameter
-+ first = false;
-+ continue;
-+ }
-+
-+ var array_type = param.parameter_type as ArrayType;
-+ if (array_type != null) {
-+ if (array_type.element_type.data_type == string_type.data_type) {
-+ register_call.add_argument (new CCodeIdentifier ("G_TYPE_STRV"));
-+ add_call.add_argument (new CCodeIdentifier ("G_TYPE_STRV"));
-+ } else {
-+ if (array_type.element_type.data_type.get_type_id () == null) {
-+ Report.error (param.source_reference, "unsupported parameter type for D-Bus signals");
-+ return;
-+ }
-+
-+ var carray_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_collection"));
-+ carray_type.add_argument (new CCodeConstant ("\"GArray\""));
-+ carray_type.add_argument (new CCodeIdentifier (array_type.element_type.data_type.get_type_id ()));
-+ register_call.add_argument (carray_type);
-+ add_call.add_argument (carray_type);
-+ }
-+ } else {
-+ if (param.parameter_type.get_type_id () == null) {
-+ Report.error (param.source_reference, "unsupported parameter type for D-Bus signals");
-+ return;
-+ }
-+
-+ register_call.add_argument (new CCodeIdentifier (param.parameter_type.get_type_id ()));
-+ add_call.add_argument (new CCodeIdentifier (param.parameter_type.get_type_id ()));
-+ }
-+ }
-+ register_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+ add_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
-+
-+ block.add_statement (new CCodeExpressionStatement (register_call));
-+ block.add_statement (new CCodeExpressionStatement (add_call));
-+
-+ var call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_connect_signal"));
-+ call.add_argument (new CCodeIdentifier ("obj"));
-+ call.add_argument (new CCodeIdentifier ("signal_name"));
-+ call.add_argument (new CCodeIdentifier ("handler"));
-+ call.add_argument (new CCodeIdentifier ("data"));
-+ call.add_argument (new CCodeConstant ("NULL"));
-+ block.add_statement (new CCodeExpressionStatement (call));
-+ }
-+
-+ void generate_dbus_disconnect_wrapper (DynamicSignal sig, CCodeBlock block) {
-+ var call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_disconnect_signal"));
-+ call.add_argument (new CCodeIdentifier ("obj"));
-+ call.add_argument (new CCodeIdentifier ("signal_name"));
-+ call.add_argument (new CCodeIdentifier ("handler"));
-+ call.add_argument (new CCodeIdentifier ("data"));
-+ block.add_statement (new CCodeExpressionStatement (call));
-+ }
- }
-Index: gobject/valagerrormodule.vala
-===================================================================
---- gobject/valagerrormodule.vala (revision 1971)
-+++ gobject/valagerrormodule.vala (revision 2004)
-@@ -23,7 +23,7 @@
- using GLib;
- using Gee;
-
--public class Vala.GErrorModule : CCodeDynamicSignalModule {
-+public class Vala.GErrorModule : CCodeDelegateModule {
- private int current_try_id = 0;
- private int next_try_id = 0;
-
-Index: gobject/valaccodeassignmentmodule.vala
-===================================================================
---- gobject/valaccodeassignmentmodule.vala (revision 1971)
-+++ gobject/valaccodeassignmentmodule.vala (revision 2004)
-@@ -89,145 +89,6 @@
- }
- }
-
-- CCodeExpression? emit_signal_assignment (Assignment assignment) {
-- var sig = (Signal) assignment.left.symbol_reference;
--
-- var m = (Method) assignment.right.symbol_reference;
--
-- string connect_func;
-- bool disconnect = false;
--
-- if (assignment.operator == AssignmentOperator.ADD) {
-- if (sig is DynamicSignal) {
-- connect_func = head.get_dynamic_signal_connect_wrapper_name ((DynamicSignal) sig);
-- } else {
-- connect_func = "g_signal_connect_object";
-- if (m.binding != MemberBinding.INSTANCE) {
-- connect_func = "g_signal_connect";
-- }
-- }
-- } else if (assignment.operator == AssignmentOperator.SUB) {
-- if (sig is DynamicSignal) {
-- connect_func = head.get_dynamic_signal_disconnect_wrapper_name ((DynamicSignal) sig);
-- } else {
-- connect_func = "g_signal_handlers_disconnect_matched";
-- }
-- disconnect = true;
-- } else {
-- assignment.error = true;
-- Report.error (assignment.source_reference, "Specified compound assignment type for signals not supported.");
-- return null;
-- }
--
-- var ccall = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
--
-- string signal_detail = null;
--
-- // first argument: instance of sender
-- MemberAccess ma;
-- if (assignment.left is ElementAccess) {
-- var ea = (ElementAccess) assignment.left;
-- ma = (MemberAccess) ea.container;
-- var detail_expr = ea.get_indices ().get (0) as StringLiteral;
-- if (detail_expr == null) {
-- assignment.error = true;
-- Report.error (detail_expr.source_reference, "internal error: only literal string details supported");
-- return null;
-- }
-- signal_detail = detail_expr.eval ();
-- } else {
-- ma = (MemberAccess) assignment.left;
-- }
-- if (ma.inner != null) {
-- ccall.add_argument ((CCodeExpression) get_ccodenode (ma.inner));
-- } else {
-- ccall.add_argument (new CCodeIdentifier ("self"));
-- }
--
-- if (sig is DynamicSignal) {
-- // dynamic_signal_connect or dynamic_signal_disconnect
--
-- // second argument: signal name
-- ccall.add_argument (new CCodeConstant ("\"%s\"".printf (sig.name)));
-- } else if (!disconnect) {
-- // g_signal_connect_object or g_signal_connect
--
-- // second argument: signal name
-- ccall.add_argument (sig.get_canonical_cconstant (signal_detail));
-- } else {
-- // g_signal_handlers_disconnect_matched
--
-- // second argument: mask
-- if (signal_detail == null) {
-- ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
-- } else {
-- ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
-- }
--
-- // get signal id
-- var ccomma = new CCodeCommaExpression ();
-- var temp_decl = get_temp_variable (uint_type);
-- temp_vars.insert (0, temp_decl);
-- var parse_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_parse_name"));
-- parse_call.add_argument (sig.get_canonical_cconstant (signal_detail));
-- var decl_type = (TypeSymbol) sig.parent_symbol;
-- parse_call.add_argument (new CCodeIdentifier (decl_type.get_type_id ()));
-- parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name)));
-- if (signal_detail == null) {
-- parse_call.add_argument (new CCodeConstant ("NULL"));
-- } else {
-- var detail_temp_decl = get_temp_variable (gquark_type);
-- temp_vars.insert (0, detail_temp_decl);
-- parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (detail_temp_decl.name)));
-- }
-- parse_call.add_argument (new CCodeConstant ("FALSE"));
-- ccomma.append_expression (parse_call);
-- ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
--
-- // third argument: signal_id
-- ccall.add_argument (ccomma);
--
-- // fourth argument: detail
-- ccall.add_argument (new CCodeConstant ("0"));
-- // fifth argument: closure
-- ccall.add_argument (new CCodeConstant ("NULL"));
-- }
--
-- // third resp. sixth argument: handler
-- ccall.add_argument (new CCodeCastExpression ((CCodeExpression) assignment.right.ccodenode, "GCallback"));
--
-- if (m.binding == MemberBinding.INSTANCE) {
-- // g_signal_connect_object or g_signal_handlers_disconnect_matched
-- // or dynamic_signal_connect or dynamic_signal_disconnect
--
-- // fourth resp. seventh argument: object/user_data
-- if (assignment.right is MemberAccess) {
-- var right_ma = (MemberAccess) assignment.right;
-- if (right_ma.inner != null) {
-- ccall.add_argument ((CCodeExpression) right_ma.inner.ccodenode);
-- } else {
-- ccall.add_argument (new CCodeIdentifier ("self"));
-- }
-- } else if (assignment.right is LambdaExpression) {
-- ccall.add_argument (new CCodeIdentifier ("self"));
-- }
-- if (!disconnect && !(sig is DynamicSignal)) {
-- // g_signal_connect_object
--
-- // fifth argument: connect_flags
-- ccall.add_argument (new CCodeConstant ("0"));
-- }
-- } else {
-- // g_signal_connect or g_signal_handlers_disconnect_matched
-- // or dynamic_signal_connect or dynamic_signal_disconnect
--
-- // fourth resp. seventh argument: user_data
-- ccall.add_argument (new CCodeConstant ("NULL"));
-- }
--
-- return ccall;
-- }
--
- private CCodeExpression? emit_non_array_element_access (Assignment assignment) {
- // custom element access
- CCodeExpression rhs = (CCodeExpression) assignment.right.ccodenode;
-@@ -373,8 +234,6 @@
-
- if (assignment.left.symbol_reference is Property) {
- assignment.ccodenode = emit_property_assignment (assignment);
-- } else if (assignment.left.symbol_reference is Signal) {
-- assignment.ccodenode = emit_signal_assignment (assignment);
- } else if (assignment.left is ElementAccess
- && !(((ElementAccess) assignment.left).container.value_type is ArrayType)
- && !(((ElementAccess) assignment.left).container.value_type is PointerType)) {
-Index: gobject/valaccodecontrolflowmodule.vala
-===================================================================
---- gobject/valaccodecontrolflowmodule.vala (revision 0)
-+++ gobject/valaccodecontrolflowmodule.vala (revision 2004)
-@@ -0,0 +1,572 @@
-+/* valaccodecontrolflowmodule.vala
-+ *
-+ * Copyright (C) 2006-2008 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 <raffaele@sandrini.ch>
-+ */
-+
-+using GLib;
-+using Gee;
-+
-+public class Vala.CCodeControlFlowModule : CCodeMethodModule {
-+ public CCodeControlFlowModule (CCodeGenerator codegen, CCodeModule? next) {
-+ base (codegen, next);
-+ }
-+
-+ public override void visit_if_statement (IfStatement stmt) {
-+ stmt.accept_children (codegen);
-+
-+ if (stmt.false_statement != null) {
-+ stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode, (CCodeStatement) stmt.false_statement.ccodenode);
-+ } else {
-+ stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode);
-+ }
-+
-+ create_temp_decl (stmt, stmt.condition.temp_vars);
-+ }
-+
-+ void visit_string_switch_statement (SwitchStatement stmt) {
-+ // we need a temporary variable to save the property value
-+ var temp_var = get_temp_variable (stmt.expression.value_type, true, stmt);
-+ stmt.expression.temp_vars.insert (0, temp_var);
-+
-+ var ctemp = new CCodeIdentifier (temp_var.name);
-+ var cinit = new CCodeAssignment (ctemp, (CCodeExpression) stmt.expression.ccodenode);
-+ var czero = new CCodeConstant ("0");
-+
-+ var cswitchblock = new CCodeFragment ();
-+ stmt.ccodenode = cswitchblock;
-+
-+ var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeConstant ("NULL"), ctemp);
-+ var cquark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
-+ cquark.add_argument (ctemp);
-+
-+ var ccond = new CCodeConditionalExpression (cisnull, new CCodeConstant ("0"), cquark);
-+
-+ temp_var = get_temp_variable (gquark_type);
-+ stmt.expression.temp_vars.insert (0, temp_var);
-+
-+ int label_count = 0;
-+
-+ foreach (SwitchSection section in stmt.get_sections ()) {
-+ if (section.has_default_label ()) {
-+ continue;
-+ }
-+
-+ foreach (SwitchLabel label in section.get_labels ()) {
-+ var cexpr = (CCodeExpression) label.expression.ccodenode;
-+
-+ if (is_constant_ccode_expression (cexpr)) {
-+ var cname = "%s_label%d".printf (temp_var.name, label_count++);
-+ var cdecl = new CCodeDeclaration (gquark_type.get_cname ());
-+
-+ cdecl.modifiers = CCodeModifiers.STATIC;
-+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (cname, czero));
-+
-+ cswitchblock.append (cdecl);
-+ }
-+ }
-+ }
-+
-+ cswitchblock.append (new CCodeExpressionStatement (cinit));
-+
-+ ctemp = new CCodeIdentifier (temp_var.name);
-+ cinit = new CCodeAssignment (ctemp, ccond);
-+
-+ cswitchblock.append (new CCodeExpressionStatement (cinit));
-+ create_temp_decl (stmt, stmt.expression.temp_vars);
-+
-+ Gee.List<Statement> default_statements = null;
-+ label_count = 0;
-+
-+ // generate nested if statements
-+ CCodeStatement ctopstmt = null;
-+ CCodeIfStatement coldif = null;
-+
-+ foreach (SwitchSection section in stmt.get_sections ()) {
-+ if (section.has_default_label ()) {
-+ default_statements = section.get_statements ();
-+ continue;
-+ }
-+
-+ CCodeBinaryExpression cor = null;
-+ foreach (SwitchLabel label in section.get_labels ()) {
-+ var cexpr = (CCodeExpression) label.expression.ccodenode;
-+
-+ if (is_constant_ccode_expression (cexpr)) {
-+ var cname = new CCodeIdentifier ("%s_label%d".printf (temp_var.name, label_count++));
-+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, czero, cname);
-+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
-+ var cinit = new CCodeParenthesizedExpression (new CCodeAssignment (cname, ccall));
-+
-+ ccall.add_argument (cexpr);
-+
-+ cexpr = new CCodeConditionalExpression (ccond, cname, cinit);
-+ } else {
-+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
-+ ccall.add_argument (cexpr);
-+ cexpr = ccall;
-+ }
-+
-+ var ccmp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, cexpr);
-+
-+ if (cor == null) {
-+ cor = ccmp;
-+ } else {
-+ cor = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cor, ccmp);
-+ }
-+ }
-+
-+ var cblock = new CCodeBlock ();
-+ foreach (CodeNode body_stmt in section.get_statements ()) {
-+ if (body_stmt.ccodenode is CCodeFragment) {
-+ foreach (CCodeNode cstmt in ((CCodeFragment) body_stmt.ccodenode).get_children ()) {
-+ cblock.add_statement (cstmt);
-+ }
-+ } else {
-+ cblock.add_statement (body_stmt.ccodenode);
-+ }
-+ }
-+
-+ var cdo = new CCodeDoStatement (cblock, new CCodeConstant ("0"));
-+ var cif = new CCodeIfStatement (cor, cdo);
-+
-+ if (coldif != null) {
-+ coldif.false_statement = cif;
-+ } else {
-+ ctopstmt = cif;
-+ }
-+
-+ coldif = cif;
-+ }
-+
-+ if (default_statements != null) {
-+ var cblock = new CCodeBlock ();
-+ foreach (CodeNode body_stmt in default_statements) {
-+ cblock.add_statement (body_stmt.ccodenode);
-+ }
-+
-+ var cdo = new CCodeDoStatement (cblock, new CCodeConstant ("0"));
-+
-+ if (coldif == null) {
-+ // there is only one section and that section
-+ // contains a default label
-+ ctopstmt = cdo;
-+ } else {
-+ coldif.false_statement = cdo;
-+ }
-+ }
-+
-+ cswitchblock.append (ctopstmt);
-+ }
-+
-+ public override void visit_switch_statement (SwitchStatement stmt) {
-+ if (stmt.expression.value_type.compatible (string_type)) {
-+ visit_string_switch_statement (stmt);
-+ return;
-+ }
-+
-+ var cswitch = new CCodeSwitchStatement ((CCodeExpression) stmt.expression.ccodenode);
-+ stmt.ccodenode = cswitch;
-+
-+ foreach (SwitchSection section in stmt.get_sections ()) {
-+ if (section.has_default_label ()) {
-+ cswitch.add_statement (new CCodeLabel ("default"));
-+ var cdefaultblock = new CCodeBlock ();
-+ cswitch.add_statement (cdefaultblock);
-+ foreach (CodeNode default_stmt in section.get_statements ()) {
-+ cdefaultblock.add_statement (default_stmt.ccodenode);
-+ }
-+ continue;
-+ }
-+
-+ foreach (SwitchLabel label in section.get_labels ()) {
-+ cswitch.add_statement (new CCodeCaseStatement ((CCodeExpression) label.expression.ccodenode));
-+ }
-+
-+ var cblock = new CCodeBlock ();
-+ cswitch.add_statement (cblock);
-+ foreach (CodeNode body_stmt in section.get_statements ()) {
-+ cblock.add_statement (body_stmt.ccodenode);
-+ }
-+ }
-+ }
-+
-+ public override void visit_switch_section (SwitchSection section) {
-+ visit_block (section);
-+ }
-+
-+ public override void visit_while_statement (WhileStatement stmt) {
-+ stmt.accept_children (codegen);
-+
-+ stmt.ccodenode = new CCodeWhileStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.body.ccodenode);
-+
-+ create_temp_decl (stmt, stmt.condition.temp_vars);
-+ }
-+
-+ public override void visit_do_statement (DoStatement stmt) {
-+ stmt.accept_children (codegen);
-+
-+ stmt.ccodenode = new CCodeDoStatement ((CCodeStatement) stmt.body.ccodenode, (CCodeExpression) stmt.condition.ccodenode);
-+
-+ create_temp_decl (stmt, stmt.condition.temp_vars);
-+ }
-+
-+ public override void visit_for_statement (ForStatement stmt) {
-+ stmt.accept_children (codegen);
-+
-+ CCodeExpression ccondition = null;
-+ if (stmt.condition != null) {
-+ ccondition = (CCodeExpression) stmt.condition.ccodenode;
-+ }
-+
-+ var cfor = new CCodeForStatement (ccondition, (CCodeStatement) stmt.body.ccodenode);
-+ stmt.ccodenode = cfor;
-+
-+ foreach (Expression init_expr in stmt.get_initializer ()) {
-+ cfor.add_initializer ((CCodeExpression) init_expr.ccodenode);
-+ create_temp_decl (stmt, init_expr.temp_vars);
-+ }
-+
-+ foreach (Expression it_expr in stmt.get_iterator ()) {
-+ cfor.add_iterator ((CCodeExpression) it_expr.ccodenode);
-+ create_temp_decl (stmt, it_expr.temp_vars);
-+ }
-+
-+ if (stmt.condition != null) {
-+ create_temp_decl (stmt, stmt.condition.temp_vars);
-+ }
-+ }
-+
-+ public override void visit_foreach_statement (ForeachStatement stmt) {
-+ stmt.element_variable.active = true;
-+ stmt.collection_variable.active = true;
-+ if (stmt.iterator_variable != null) {
-+ stmt.iterator_variable.active = true;
-+ }
-+
-+ visit_block (stmt);
-+
-+ var cblock = new CCodeBlock ();
-+ // sets #line
-+ stmt.ccodenode = cblock;
-+
-+ var cfrag = new CCodeFragment ();
-+ append_temp_decl (cfrag, stmt.collection.temp_vars);
-+ cblock.add_statement (cfrag);
-+
-+ var collection_backup = stmt.collection_variable;
-+ var collection_type = collection_backup.variable_type.copy ();
-+ var ccoldecl = new CCodeDeclaration (collection_type.get_cname ());
-+ var ccolvardecl = new CCodeVariableDeclarator.with_initializer (collection_backup.name, (CCodeExpression) stmt.collection.ccodenode);
-+ ccolvardecl.line = cblock.line;
-+ ccoldecl.add_declarator (ccolvardecl);
-+ cblock.add_statement (ccoldecl);
-+
-+ if (stmt.tree_can_fail && stmt.collection.tree_can_fail) {
-+ // exception handling
-+ var cfrag = new CCodeFragment ();
-+ head.add_simple_check (stmt.collection, cfrag);
-+ cblock.add_statement (cfrag);
-+ }
-+
-+ if (stmt.collection.value_type is ArrayType) {
-+ var array_type = (ArrayType) stmt.collection.value_type;
-+
-+ var array_len = head.get_array_length_cexpression (stmt.collection);
-+
-+ // store array length for use by _vala_array_free
-+ var clendecl = new CCodeDeclaration ("int");
-+ clendecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_length_cname (collection_backup.name, 1), array_len));
-+ cblock.add_statement (clendecl);
-+
-+ if (array_len is CCodeConstant) {
-+ // the array has no length parameter i.e. it is NULL-terminated array
-+
-+ var it_name = "%s_it".printf (stmt.variable_name);
-+
-+ var citdecl = new CCodeDeclaration (collection_type.get_cname ());
-+ citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
-+ cblock.add_statement (citdecl);
-+
-+ var cbody = new CCodeBlock ();
-+
-+ CCodeExpression element_expr = new CCodeIdentifier ("*%s".printf (it_name));
-+
-+ var element_type = array_type.element_type.copy ();
-+ element_type.value_owned = false;
-+ element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
-+
-+ var cfrag = new CCodeFragment ();
-+ append_temp_decl (cfrag, temp_vars);
-+ cbody.add_statement (cfrag);
-+ temp_vars.clear ();
-+
-+ var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr));
-+ cbody.add_statement (cdecl);
-+
-+ // add array length variable for stacked arrays
-+ if (stmt.type_reference is ArrayType) {
-+ var inner_array_type = (ArrayType) stmt.type_reference;
-+ for (int dim = 1; dim <= inner_array_type.rank; dim++) {
-+ cdecl = new CCodeDeclaration ("int");
-+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_length_cname (stmt.variable_name, dim), new CCodeConstant ("-1")));
-+ cbody.add_statement (cdecl);
-+ }
-+ }
-+
-+ cbody.add_statement (stmt.body.ccodenode);
-+
-+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("*%s".printf (it_name)), new CCodeConstant ("NULL"));
-+
-+ var cfor = new CCodeForStatement (ccond, cbody);
-+
-+ cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeIdentifier (collection_backup.name)));
-+
-+ cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
-+ cblock.add_statement (cfor);
-+ } else {
-+ // the array has a length parameter
-+
-+ var it_name = (stmt.variable_name + "_it");
-+
-+ var citdecl = new CCodeDeclaration ("int");
-+ citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
-+ cblock.add_statement (citdecl);
-+
-+ var cbody = new CCodeBlock ();
-+
-+ CCodeExpression element_expr = new CCodeElementAccess (new CCodeIdentifier (collection_backup.name), new CCodeIdentifier (it_name));
-+
-+ var element_type = array_type.element_type.copy ();
-+ element_type.value_owned = false;
-+ element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
-+
-+ var cfrag = new CCodeFragment ();
-+ append_temp_decl (cfrag, temp_vars);
-+ cbody.add_statement (cfrag);
-+ temp_vars.clear ();
-+
-+ var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr));
-+ cbody.add_statement (cdecl);
-+
-+ // add array length variable for stacked arrays
-+ if (stmt.type_reference is ArrayType) {
-+ var inner_array_type = (ArrayType) stmt.type_reference;
-+ for (int dim = 1; dim <= inner_array_type.rank; dim++) {
-+ cdecl = new CCodeDeclaration ("int");
-+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_length_cname (stmt.variable_name, dim), new CCodeConstant ("-1")));
-+ cbody.add_statement (cdecl);
-+ }
-+ }
-+
-+ cbody.add_statement (stmt.body.ccodenode);
-+
-+ var ccond_ind1 = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, array_len, new CCodeConstant ("-1"));
-+ var ccond_ind2 = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier (it_name), array_len);
-+ var ccond_ind = new CCodeBinaryExpression (CCodeBinaryOperator.AND, ccond_ind1, ccond_ind2);
-+
-+ /* only check for null if the containers elements are of reference-type */
-+ CCodeBinaryExpression ccond;
-+ if (array_type.element_type.is_reference_type_or_type_parameter ()) {
-+ var ccond_term1 = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, array_len, new CCodeConstant ("-1"));
-+ var ccond_term2 = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeElementAccess (new CCodeIdentifier (collection_backup.name), new CCodeIdentifier (it_name)), new CCodeConstant ("NULL"));
-+ var ccond_term = new CCodeBinaryExpression (CCodeBinaryOperator.AND, ccond_term1, ccond_term2);
-+
-+ ccond = new CCodeBinaryExpression (CCodeBinaryOperator.OR, new CCodeParenthesizedExpression (ccond_ind), new CCodeParenthesizedExpression (ccond_term));
-+ } else {
-+ /* assert when trying to iterate over value-type arrays of unknown length */
-+ var cassert = new CCodeFunctionCall (new CCodeIdentifier ("g_assert"));
-+ cassert.add_argument (ccond_ind1);
-+ cblock.add_statement (new CCodeExpressionStatement (cassert));
-+
-+ ccond = ccond_ind2;
-+ }
-+
-+ var cfor = new CCodeForStatement (ccond, cbody);
-+ cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeConstant ("0")));
-+ cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
-+ cblock.add_statement (cfor);
-+ }
-+ } else if (stmt.collection.value_type.compatible (new ObjectType (glist_type)) || stmt.collection.value_type.compatible (new ObjectType (gslist_type))) {
-+ // iterating over a GList or GSList
-+
-+ var it_name = "%s_it".printf (stmt.variable_name);
-+
-+ var citdecl = new CCodeDeclaration (collection_type.get_cname ());
-+ var citvardecl = new CCodeVariableDeclarator (it_name);
-+ citvardecl.line = cblock.line;
-+ citdecl.add_declarator (citvardecl);
-+ cblock.add_statement (citdecl);
-+
-+ var cbody = new CCodeBlock ();
-+
-+ CCodeExpression element_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "data");
-+
-+ if (collection_type.get_type_arguments ().size != 1) {
-+ Report.error (stmt.source_reference, "internal error: missing generic type argument");
-+ stmt.error = true;
-+ return;
-+ }
-+
-+ var element_data_type = collection_type.get_type_arguments ().get (0).copy ();
-+ element_data_type.value_owned = false;
-+ element_data_type.is_type_argument = true;
-+ element_expr = transform_expression (element_expr, element_data_type, stmt.type_reference);
-+
-+ var cfrag = new CCodeFragment ();
-+ append_temp_decl (cfrag, temp_vars);
-+ cbody.add_statement (cfrag);
-+ temp_vars.clear ();
-+
-+ var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-+ var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
-+ cvardecl.line = cblock.line;
-+ cdecl.add_declarator (cvardecl);
-+ cbody.add_statement (cdecl);
-+
-+ cbody.add_statement (stmt.body.ccodenode);
-+
-+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier (it_name), new CCodeConstant ("NULL"));
-+
-+ var cfor = new CCodeForStatement (ccond, cbody);
-+
-+ cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeIdentifier (collection_backup.name)));
-+
-+ cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "next")));
-+ cblock.add_statement (cfor);
-+ } else if (list_type != null && stmt.collection.value_type.compatible (new ObjectType (list_type))) {
-+ // iterating over a Gee.List, use integer to avoid the cost of an iterator object
-+
-+ var it_name = "%s_it".printf (stmt.variable_name);
-+
-+ var citdecl = new CCodeDeclaration ("int");
-+ citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
-+ cblock.add_statement (citdecl);
-+
-+ var cbody = new CCodeBlock ();
-+
-+ var get_method = (Method) list_type.scope.lookup ("get");
-+ var get_ccall = new CCodeFunctionCall (new CCodeIdentifier (get_method.get_cname ()));
-+ get_ccall.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), list_type));
-+ get_ccall.add_argument (new CCodeIdentifier (it_name));
-+ CCodeExpression element_expr = get_ccall;
-+
-+ var element_type = SemanticAnalyzer.get_actual_type (stmt.collection.value_type, get_method, get_method.return_type, stmt);
-+
-+ element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
-+
-+ var cfrag = new CCodeFragment ();
-+ append_temp_decl (cfrag, temp_vars);
-+ cbody.add_statement (cfrag);
-+ temp_vars.clear ();
-+
-+ var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-+ var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
-+ cvardecl.line = cblock.line;
-+ cdecl.add_declarator (cvardecl);
-+ cbody.add_statement (cdecl);
-+
-+ cbody.add_statement (stmt.body.ccodenode);
-+
-+ var list_len = new CCodeFunctionCall (new CCodeIdentifier ("gee_collection_get_size"));
-+ list_len.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), this.collection_type));
-+
-+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier (it_name), list_len);
-+
-+ var cfor = new CCodeForStatement (ccond, cbody);
-+ cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeConstant ("0")));
-+ cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
-+ cfor.line = cblock.line;
-+ cblock.add_statement (cfor);
-+ } else if (iterable_type != null && stmt.collection.value_type.compatible (new ObjectType (iterable_type))) {
-+ // iterating over a Gee.Iterable, use iterator
-+
-+ var it_name = "%s_it".printf (stmt.variable_name);
-+
-+ var citdecl = new CCodeDeclaration (iterator_type.get_cname () + "*");
-+ var it_method = (Method) iterable_type.scope.lookup ("iterator");
-+ var it_ccall = new CCodeFunctionCall (new CCodeIdentifier (it_method.get_cname ()));
-+ it_ccall.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), iterable_type));
-+ var citvardecl = new CCodeVariableDeclarator.with_initializer (it_name, it_ccall);
-+ citvardecl.line = cblock.line;
-+ citdecl.add_declarator (citvardecl);
-+ cblock.add_statement (citdecl);
-+
-+ var cbody = new CCodeBlock ();
-+
-+ var get_method = (Method) iterator_type.scope.lookup ("get");
-+ var get_ccall = new CCodeFunctionCall (new CCodeIdentifier (get_method.get_cname ()));
-+ get_ccall.add_argument (new CCodeIdentifier (it_name));
-+ CCodeExpression element_expr = get_ccall;
-+
-+ Iterator<DataType> type_arg_it = it_method.return_type.get_type_arguments ().iterator ();
-+ type_arg_it.next ();
-+ var it_type = SemanticAnalyzer.get_actual_type (stmt.collection.value_type, it_method, type_arg_it.get (), stmt);
-+
-+ element_expr = transform_expression (element_expr, it_type, stmt.type_reference);
-+
-+ var cfrag = new CCodeFragment ();
-+ append_temp_decl (cfrag, temp_vars);
-+ cbody.add_statement (cfrag);
-+ temp_vars.clear ();
-+
-+ var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-+ var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
-+ cvardecl.line = cblock.line;
-+ cdecl.add_declarator (cvardecl);
-+ cbody.add_statement (cdecl);
-+
-+ cbody.add_statement (stmt.body.ccodenode);
-+
-+ var next_method = (Method) iterator_type.scope.lookup ("next");
-+ var next_ccall = new CCodeFunctionCall (new CCodeIdentifier (next_method.get_cname ()));
-+ next_ccall.add_argument (new CCodeIdentifier (it_name));
-+
-+ var cwhile = new CCodeWhileStatement (next_ccall, cbody);
-+ cwhile.line = cblock.line;
-+ cblock.add_statement (cwhile);
-+ }
-+
-+ foreach (LocalVariable local in stmt.get_local_variables ()) {
-+ if (requires_destroy (local.variable_type)) {
-+ var ma = new MemberAccess.simple (local.name);
-+ ma.symbol_reference = local;
-+ var cunref = new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (get_variable_cname (local.name)), local.variable_type, ma));
-+ cunref.line = cblock.line;
-+ cblock.add_statement (cunref);
-+ }
-+ }
-+ }
-+
-+ public override void visit_break_statement (BreakStatement stmt) {
-+ stmt.ccodenode = new CCodeBreakStatement ();
-+
-+ create_local_free (stmt, true);
-+ }
-+
-+ public override void visit_continue_statement (ContinueStatement stmt) {
-+ stmt.ccodenode = new CCodeContinueStatement ();
-+
-+ create_local_free (stmt, true);
-+ }
-+}
-+
-Index: gobject/valaccodebasemodule.vala
-===================================================================
---- gobject/valaccodebasemodule.vala (revision 1971)
-+++ gobject/valaccodebasemodule.vala (revision 2004)
-@@ -78,7 +78,6 @@
- public Gee.Set<string> c_keywords;
-
- public int next_temp_var_id = 0;
-- private int next_array_dup_id = 0;
- public bool in_creation_method = false;
- public bool in_constructor = false;
- public bool in_static_or_class_ctor = false;
-@@ -213,36 +212,6 @@
- }
- }
-
-- public override CCodeExpression get_construct_property_assignment (CCodeConstant canonical_cconstant, DataType property_type, CCodeExpression value) {
-- // this property is used as a construction parameter
-- var cpointer = new CCodeIdentifier ("__params_it");
--
-- var ccomma = new CCodeCommaExpression ();
-- // set name in array for current parameter
-- var cnamemember = new CCodeMemberAccess.pointer (cpointer, "name");
-- var cnameassign = new CCodeAssignment (cnamemember, canonical_cconstant);
-- ccomma.append_expression (cnameassign);
--
-- var gvaluearg = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (cpointer, "value"));
--
-- // initialize GValue in array for current parameter
-- var cvalueinit = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
-- cvalueinit.add_argument (gvaluearg);
-- cvalueinit.add_argument (new CCodeIdentifier (property_type.get_type_id ()));
-- ccomma.append_expression (cvalueinit);
--
-- // set GValue for current parameter
-- var cvalueset = new CCodeFunctionCall (get_value_setter_function (property_type));
-- cvalueset.add_argument (gvaluearg);
-- cvalueset.add_argument (value);
-- ccomma.append_expression (cvalueset);
--
-- // move pointer to next parameter in array
-- ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, cpointer));
--
-- return ccomma;
-- }
--
- private CCodeIncludeDirective get_internal_include (string filename) {
- return new CCodeIncludeDirective (filename, context.library == null);
- }
-@@ -939,7 +908,7 @@
- }
- }
-
-- private bool is_constant_ccode_expression (CCodeExpression cexpr) {
-+ public bool is_constant_ccode_expression (CCodeExpression cexpr) {
- if (cexpr is CCodeConstant) {
- return true;
- } else if (cexpr is CCodeBinaryExpression) {
-@@ -1208,133 +1177,6 @@
- current_return_type = null;
- }
-
-- public override void visit_constructor (Constructor c) {
-- current_method_inner_error = false;
-- in_constructor = true;
--
-- if (c.binding == MemberBinding.CLASS || c.binding == MemberBinding.STATIC) {
-- in_static_or_class_ctor = true;
-- }
-- c.accept_children (codegen);
-- in_static_or_class_ctor = false;
--
-- in_constructor = false;
--
-- var cl = (Class) c.parent_symbol;
--
-- if (c.binding == MemberBinding.INSTANCE) {
-- function = new CCodeFunction ("%s_constructor".printf (cl.get_lower_case_cname (null)), "GObject *");
-- function.modifiers = CCodeModifiers.STATIC;
--
-- function.add_parameter (new CCodeFormalParameter ("type", "GType"));
-- function.add_parameter (new CCodeFormalParameter ("n_construct_properties", "guint"));
-- function.add_parameter (new CCodeFormalParameter ("construct_properties", "GObjectConstructParam *"));
--
-- source_type_member_declaration.append (function.copy ());
--
--
-- var cblock = new CCodeBlock ();
-- var cdecl = new CCodeDeclaration ("GObject *");
-- cdecl.add_declarator (new CCodeVariableDeclarator ("obj"));
-- cblock.add_statement (cdecl);
--
-- cdecl = new CCodeDeclaration ("%sClass *".printf (cl.get_cname ()));
-- cdecl.add_declarator (new CCodeVariableDeclarator ("klass"));
-- cblock.add_statement (cdecl);
--
-- cdecl = new CCodeDeclaration ("GObjectClass *");
-- cdecl.add_declarator (new CCodeVariableDeclarator ("parent_class"));
-- cblock.add_statement (cdecl);
--
--
-- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek"));
-- ccall.add_argument (new CCodeIdentifier (cl.get_type_id ()));
-- var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (cl.get_upper_case_cname (null))));
-- ccast.add_argument (ccall);
-- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("klass"), ccast)));
--
-- ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
-- ccall.add_argument (new CCodeIdentifier ("klass"));
-- ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
-- ccast.add_argument (ccall);
-- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_class"), ccast)));
--
--
-- ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier ("parent_class"), "constructor"));
-- ccall.add_argument (new CCodeIdentifier ("type"));
-- ccall.add_argument (new CCodeIdentifier ("n_construct_properties"));
-- ccall.add_argument (new CCodeIdentifier ("construct_properties"));
-- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("obj"), ccall)));
--
--
-- ccall = new InstanceCast (new CCodeIdentifier ("obj"), cl);
--
-- cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
-- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
--
-- cblock.add_statement (cdecl);
--
-- if (current_method_inner_error) {
-- /* always separate error parameter and inner_error local variable
-- * as error may be set to NULL but we're always interested in inner errors
-- */
-- var cdecl = new CCodeDeclaration ("GError *");
-- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
-- cblock.add_statement (cdecl);
-- }
--
--
-- cblock.add_statement (c.body.ccodenode);
--
-- cblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("obj")));
--
-- function.block = cblock;
--
-- if (c.source_reference.comment != null) {
-- source_type_member_definition.append (new CCodeComment (c.source_reference.comment));
-- }
-- source_type_member_definition.append (function);
-- } else if (c.binding == MemberBinding.CLASS) {
-- // class constructor
--
-- var base_init = new CCodeFunction ("%s_base_init".printf (cl.get_lower_case_cname (null)), "void");
-- base_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
-- base_init.modifiers = CCodeModifiers.STATIC;
--
-- source_type_member_declaration.append (base_init.copy ());
--
-- var block = (CCodeBlock) c.body.ccodenode;
-- if (current_method_inner_error) {
-- /* always separate error parameter and inner_error local variable
-- * as error may be set to NULL but we're always interested in inner errors
-- */
-- var cdecl = new CCodeDeclaration ("GError *");
-- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
-- block.prepend_statement (cdecl);
-- }
--
-- base_init.block = block;
--
-- source_type_member_definition.append (base_init);
-- } else if (c.binding == MemberBinding.STATIC) {
-- // static class constructor
-- // add to class_init
--
-- if (current_method_inner_error) {
-- /* always separate error parameter and inner_error local variable
-- * as error may be set to NULL but we're always interested in inner errors
-- */
-- var cdecl = new CCodeDeclaration ("GError *");
-- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
-- class_init_fragment.append (cdecl);
-- }
--
-- class_init_fragment.append (c.body.ccodenode);
-- } else {
-- Report.error (c.source_reference, "internal error: constructors must have instance, class, or static binding");
-- }
-- }
--
- public override void visit_destructor (Destructor d) {
- current_method_inner_error = false;
-
-@@ -1600,12 +1442,12 @@
- }
- }
-
-- public CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference) {
-- var cl = type.data_type as Class;
-+ public virtual CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference) {
- if (type is ErrorType) {
- return new CCodeIdentifier ("g_error_copy");
- } else if (type.data_type != null) {
- string dup_function;
-+ var cl = type.data_type as Class;
- if (type.data_type.is_reference_counting ()) {
- dup_function = type.data_type.get_ref_function ();
- if (type.data_type is Interface && dup_function == null) {
-@@ -1631,8 +1473,6 @@
- } else if (type.type_parameter != null && current_type_symbol is Class) {
- string func_name = "%s_dup_func".printf (type.type_parameter.name.down ());
- return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
-- } else if (type is ArrayType) {
-- return new CCodeIdentifier (generate_array_dup_wrapper ((ArrayType) type));
- } else if (type is PointerType) {
- var pointer_type = (PointerType) type;
- return get_dup_func_expression (pointer_type.base_type, source_reference);
-@@ -1641,78 +1481,6 @@
- }
- }
-
-- string generate_array_dup_wrapper (ArrayType array_type) {
-- string dup_func = "_vala_array_dup%d".printf (++next_array_dup_id);
--
-- if (!add_wrapper (dup_func)) {
-- // wrapper already defined
-- return dup_func;
-- }
--
-- // declaration
--
-- var function = new CCodeFunction (dup_func, array_type.get_cname ());
-- function.modifiers = CCodeModifiers.STATIC;
--
-- function.add_parameter (new CCodeFormalParameter ("self", array_type.get_cname ()));
-- // total length over all dimensions
-- function.add_parameter (new CCodeFormalParameter ("length", "int"));
--
-- // definition
--
-- var block = new CCodeBlock ();
--
-- if (requires_copy (array_type.element_type)) {
-- var old_temp_vars = temp_vars;
--
-- var cdecl = new CCodeDeclaration (array_type.get_cname ());
-- var cvardecl = new CCodeVariableDeclarator ("result");
-- cdecl.add_declarator (cvardecl);
-- var gnew = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
-- gnew.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
-- gnew.add_argument (new CCodeIdentifier ("length"));
-- cvardecl.initializer = gnew;
-- block.add_statement (cdecl);
--
-- var idx_decl = new CCodeDeclaration ("int");
-- idx_decl.add_declarator (new CCodeVariableDeclarator ("i"));
-- block.add_statement (idx_decl);
--
-- var loop_body = new CCodeBlock ();
-- loop_body.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("result"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type))));
--
-- var cfor = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("length")), loop_body);
-- cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
-- cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
-- block.add_statement (cfor);
--
-- block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
--
-- var cfrag = new CCodeFragment ();
-- append_temp_decl (cfrag, temp_vars);
-- block.add_statement (cfrag);
-- temp_vars = old_temp_vars;
-- } else {
-- var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_memdup"));
-- dup_call.add_argument (new CCodeIdentifier ("self"));
--
-- var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
-- sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
-- dup_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeIdentifier ("length"), sizeof_call));
--
-- block.add_statement (new CCodeReturnStatement (dup_call));
-- }
--
-- // append to file
--
-- source_type_member_declaration.append (function.copy ());
--
-- function.block = block;
-- source_type_member_definition.append (function);
--
-- return dup_func;
-- }
--
- private string generate_struct_dup_wrapper (ValueType value_type) {
- string dup_func = "_%sdup".printf (value_type.type_symbol.get_lower_case_cprefix ());
-
-@@ -2084,546 +1852,6 @@
- ((CodeNode) stmt).ccodenode = cfrag;
- }
-
-- public override void visit_if_statement (IfStatement stmt) {
-- stmt.accept_children (codegen);
--
-- if (stmt.false_statement != null) {
-- stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode, (CCodeStatement) stmt.false_statement.ccodenode);
-- } else {
-- stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode);
-- }
--
-- create_temp_decl (stmt, stmt.condition.temp_vars);
-- }
--
-- void visit_string_switch_statement (SwitchStatement stmt) {
-- // we need a temporary variable to save the property value
-- var temp_var = get_temp_variable (stmt.expression.value_type, true, stmt);
-- stmt.expression.temp_vars.insert (0, temp_var);
--
-- var ctemp = new CCodeIdentifier (temp_var.name);
-- var cinit = new CCodeAssignment (ctemp, (CCodeExpression) stmt.expression.ccodenode);
-- var czero = new CCodeConstant ("0");
--
-- var cswitchblock = new CCodeFragment ();
-- stmt.ccodenode = cswitchblock;
--
-- var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeConstant ("NULL"), ctemp);
-- var cquark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
-- cquark.add_argument (ctemp);
--
-- var ccond = new CCodeConditionalExpression (cisnull, new CCodeConstant ("0"), cquark);
--
-- temp_var = get_temp_variable (gquark_type);
-- stmt.expression.temp_vars.insert (0, temp_var);
--
-- int label_count = 0;
--
-- foreach (SwitchSection section in stmt.get_sections ()) {
-- if (section.has_default_label ()) {
-- continue;
-- }
--
-- foreach (SwitchLabel label in section.get_labels ()) {
-- var cexpr = (CCodeExpression) label.expression.ccodenode;
--
-- if (is_constant_ccode_expression (cexpr)) {
-- var cname = "%s_label%d".printf (temp_var.name, label_count++);
-- var cdecl = new CCodeDeclaration (gquark_type.get_cname ());
--
-- cdecl.modifiers = CCodeModifiers.STATIC;
-- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (cname, czero));
--
-- cswitchblock.append (cdecl);
-- }
-- }
-- }
--
-- cswitchblock.append (new CCodeExpressionStatement (cinit));
--
-- ctemp = new CCodeIdentifier (temp_var.name);
-- cinit = new CCodeAssignment (ctemp, ccond);
--
-- cswitchblock.append (new CCodeExpressionStatement (cinit));
-- create_temp_decl (stmt, stmt.expression.temp_vars);
--
-- Gee.List<Statement> default_statements = null;
-- label_count = 0;
--
-- // generate nested if statements
-- CCodeStatement ctopstmt = null;
-- CCodeIfStatement coldif = null;
--
-- foreach (SwitchSection section in stmt.get_sections ()) {
-- if (section.has_default_label ()) {
-- default_statements = section.get_statements ();
-- continue;
-- }
--
-- CCodeBinaryExpression cor = null;
-- foreach (SwitchLabel label in section.get_labels ()) {
-- var cexpr = (CCodeExpression) label.expression.ccodenode;
--
-- if (is_constant_ccode_expression (cexpr)) {
-- var cname = new CCodeIdentifier ("%s_label%d".printf (temp_var.name, label_count++));
-- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, czero, cname);
-- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
-- var cinit = new CCodeParenthesizedExpression (new CCodeAssignment (cname, ccall));
--
-- ccall.add_argument (cexpr);
--
-- cexpr = new CCodeConditionalExpression (ccond, cname, cinit);
-- } else {
-- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
-- ccall.add_argument (cexpr);
-- cexpr = ccall;
-- }
--
-- var ccmp = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, cexpr);
--
-- if (cor == null) {
-- cor = ccmp;
-- } else {
-- cor = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cor, ccmp);
-- }
-- }
--
-- var cblock = new CCodeBlock ();
-- foreach (CodeNode body_stmt in section.get_statements ()) {
-- if (body_stmt.ccodenode is CCodeFragment) {
-- foreach (CCodeNode cstmt in ((CCodeFragment) body_stmt.ccodenode).get_children ()) {
-- cblock.add_statement (cstmt);
-- }
-- } else {
-- cblock.add_statement (body_stmt.ccodenode);
-- }
-- }
--
-- var cdo = new CCodeDoStatement (cblock, new CCodeConstant ("0"));
-- var cif = new CCodeIfStatement (cor, cdo);
--
-- if (coldif != null) {
-- coldif.false_statement = cif;
-- } else {
-- ctopstmt = cif;
-- }
--
-- coldif = cif;
-- }
--
-- if (default_statements != null) {
-- var cblock = new CCodeBlock ();
-- foreach (CodeNode body_stmt in default_statements) {
-- cblock.add_statement (body_stmt.ccodenode);
-- }
--
-- var cdo = new CCodeDoStatement (cblock, new CCodeConstant ("0"));
--
-- if (coldif == null) {
-- // there is only one section and that section
-- // contains a default label
-- ctopstmt = cdo;
-- } else {
-- coldif.false_statement = cdo;
-- }
-- }
--
-- cswitchblock.append (ctopstmt);
-- }
--
-- public override void visit_switch_statement (SwitchStatement stmt) {
-- if (stmt.expression.value_type.compatible (string_type)) {
-- visit_string_switch_statement (stmt);
-- return;
-- }
--
-- var cswitch = new CCodeSwitchStatement ((CCodeExpression) stmt.expression.ccodenode);
-- stmt.ccodenode = cswitch;
--
-- foreach (SwitchSection section in stmt.get_sections ()) {
-- if (section.has_default_label ()) {
-- cswitch.add_statement (new CCodeLabel ("default"));
-- var cdefaultblock = new CCodeBlock ();
-- cswitch.add_statement (cdefaultblock);
-- foreach (CodeNode default_stmt in section.get_statements ()) {
-- cdefaultblock.add_statement (default_stmt.ccodenode);
-- }
-- continue;
-- }
--
-- foreach (SwitchLabel label in section.get_labels ()) {
-- cswitch.add_statement (new CCodeCaseStatement ((CCodeExpression) label.expression.ccodenode));
-- }
--
-- var cblock = new CCodeBlock ();
-- cswitch.add_statement (cblock);
-- foreach (CodeNode body_stmt in section.get_statements ()) {
-- cblock.add_statement (body_stmt.ccodenode);
-- }
-- }
-- }
--
-- public override void visit_switch_section (SwitchSection section) {
-- visit_block (section);
-- }
--
-- public override void visit_while_statement (WhileStatement stmt) {
-- stmt.accept_children (codegen);
--
-- stmt.ccodenode = new CCodeWhileStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.body.ccodenode);
--
-- create_temp_decl (stmt, stmt.condition.temp_vars);
-- }
--
-- public override void visit_do_statement (DoStatement stmt) {
-- stmt.accept_children (codegen);
--
-- stmt.ccodenode = new CCodeDoStatement ((CCodeStatement) stmt.body.ccodenode, (CCodeExpression) stmt.condition.ccodenode);
--
-- create_temp_decl (stmt, stmt.condition.temp_vars);
-- }
--
-- public override void visit_for_statement (ForStatement stmt) {
-- stmt.accept_children (codegen);
--
-- CCodeExpression ccondition = null;
-- if (stmt.condition != null) {
-- ccondition = (CCodeExpression) stmt.condition.ccodenode;
-- }
--
-- var cfor = new CCodeForStatement (ccondition, (CCodeStatement) stmt.body.ccodenode);
-- stmt.ccodenode = cfor;
--
-- foreach (Expression init_expr in stmt.get_initializer ()) {
-- cfor.add_initializer ((CCodeExpression) init_expr.ccodenode);
-- create_temp_decl (stmt, init_expr.temp_vars);
-- }
--
-- foreach (Expression it_expr in stmt.get_iterator ()) {
-- cfor.add_iterator ((CCodeExpression) it_expr.ccodenode);
-- create_temp_decl (stmt, it_expr.temp_vars);
-- }
--
-- if (stmt.condition != null) {
-- create_temp_decl (stmt, stmt.condition.temp_vars);
-- }
-- }
--
-- public override void visit_foreach_statement (ForeachStatement stmt) {
-- stmt.element_variable.active = true;
-- stmt.collection_variable.active = true;
-- if (stmt.iterator_variable != null) {
-- stmt.iterator_variable.active = true;
-- }
--
-- visit_block (stmt);
--
-- var cblock = new CCodeBlock ();
-- // sets #line
-- stmt.ccodenode = cblock;
--
-- var cfrag = new CCodeFragment ();
-- append_temp_decl (cfrag, stmt.collection.temp_vars);
-- cblock.add_statement (cfrag);
--
-- var collection_backup = stmt.collection_variable;
-- var collection_type = collection_backup.variable_type.copy ();
-- var ccoldecl = new CCodeDeclaration (collection_type.get_cname ());
-- var ccolvardecl = new CCodeVariableDeclarator.with_initializer (collection_backup.name, (CCodeExpression) stmt.collection.ccodenode);
-- ccolvardecl.line = cblock.line;
-- ccoldecl.add_declarator (ccolvardecl);
-- cblock.add_statement (ccoldecl);
--
-- if (stmt.tree_can_fail && stmt.collection.tree_can_fail) {
-- // exception handling
-- var cfrag = new CCodeFragment ();
-- head.add_simple_check (stmt.collection, cfrag);
-- cblock.add_statement (cfrag);
-- }
--
-- if (stmt.collection.value_type is ArrayType) {
-- var array_type = (ArrayType) stmt.collection.value_type;
--
-- var array_len = head.get_array_length_cexpression (stmt.collection);
--
-- // store array length for use by _vala_array_free
-- var clendecl = new CCodeDeclaration ("int");
-- clendecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_length_cname (collection_backup.name, 1), array_len));
-- cblock.add_statement (clendecl);
--
-- if (array_len is CCodeConstant) {
-- // the array has no length parameter i.e. it is NULL-terminated array
--
-- var it_name = "%s_it".printf (stmt.variable_name);
--
-- var citdecl = new CCodeDeclaration (collection_type.get_cname ());
-- citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
-- cblock.add_statement (citdecl);
--
-- var cbody = new CCodeBlock ();
--
-- CCodeExpression element_expr = new CCodeIdentifier ("*%s".printf (it_name));
--
-- var element_type = array_type.element_type.copy ();
-- element_type.value_owned = false;
-- element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
--
-- var cfrag = new CCodeFragment ();
-- append_temp_decl (cfrag, temp_vars);
-- cbody.add_statement (cfrag);
-- temp_vars.clear ();
--
-- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr));
-- cbody.add_statement (cdecl);
--
-- // add array length variable for stacked arrays
-- if (stmt.type_reference is ArrayType) {
-- var inner_array_type = (ArrayType) stmt.type_reference;
-- for (int dim = 1; dim <= inner_array_type.rank; dim++) {
-- cdecl = new CCodeDeclaration ("int");
-- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_length_cname (stmt.variable_name, dim), new CCodeConstant ("-1")));
-- cbody.add_statement (cdecl);
-- }
-- }
--
-- cbody.add_statement (stmt.body.ccodenode);
--
-- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("*%s".printf (it_name)), new CCodeConstant ("NULL"));
--
-- var cfor = new CCodeForStatement (ccond, cbody);
--
-- cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeIdentifier (collection_backup.name)));
--
-- cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
-- cblock.add_statement (cfor);
-- } else {
-- // the array has a length parameter
--
-- var it_name = (stmt.variable_name + "_it");
--
-- var citdecl = new CCodeDeclaration ("int");
-- citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
-- cblock.add_statement (citdecl);
--
-- var cbody = new CCodeBlock ();
--
-- CCodeExpression element_expr = new CCodeElementAccess (new CCodeIdentifier (collection_backup.name), new CCodeIdentifier (it_name));
--
-- var element_type = array_type.element_type.copy ();
-- element_type.value_owned = false;
-- element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
--
-- var cfrag = new CCodeFragment ();
-- append_temp_decl (cfrag, temp_vars);
-- cbody.add_statement (cfrag);
-- temp_vars.clear ();
--
-- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr));
-- cbody.add_statement (cdecl);
--
-- // add array length variable for stacked arrays
-- if (stmt.type_reference is ArrayType) {
-- var inner_array_type = (ArrayType) stmt.type_reference;
-- for (int dim = 1; dim <= inner_array_type.rank; dim++) {
-- cdecl = new CCodeDeclaration ("int");
-- cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_length_cname (stmt.variable_name, dim), new CCodeConstant ("-1")));
-- cbody.add_statement (cdecl);
-- }
-- }
--
-- cbody.add_statement (stmt.body.ccodenode);
--
-- var ccond_ind1 = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, array_len, new CCodeConstant ("-1"));
-- var ccond_ind2 = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier (it_name), array_len);
-- var ccond_ind = new CCodeBinaryExpression (CCodeBinaryOperator.AND, ccond_ind1, ccond_ind2);
--
-- /* only check for null if the containers elements are of reference-type */
-- CCodeBinaryExpression ccond;
-- if (array_type.element_type.is_reference_type_or_type_parameter ()) {
-- var ccond_term1 = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, array_len, new CCodeConstant ("-1"));
-- var ccond_term2 = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeElementAccess (new CCodeIdentifier (collection_backup.name), new CCodeIdentifier (it_name)), new CCodeConstant ("NULL"));
-- var ccond_term = new CCodeBinaryExpression (CCodeBinaryOperator.AND, ccond_term1, ccond_term2);
--
-- ccond = new CCodeBinaryExpression (CCodeBinaryOperator.OR, new CCodeParenthesizedExpression (ccond_ind), new CCodeParenthesizedExpression (ccond_term));
-- } else {
-- /* assert when trying to iterate over value-type arrays of unknown length */
-- var cassert = new CCodeFunctionCall (new CCodeIdentifier ("g_assert"));
-- cassert.add_argument (ccond_ind1);
-- cblock.add_statement (new CCodeExpressionStatement (cassert));
--
-- ccond = ccond_ind2;
-- }
--
-- var cfor = new CCodeForStatement (ccond, cbody);
-- cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeConstant ("0")));
-- cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
-- cblock.add_statement (cfor);
-- }
-- } else if (stmt.collection.value_type.compatible (new ObjectType (glist_type)) || stmt.collection.value_type.compatible (new ObjectType (gslist_type))) {
-- // iterating over a GList or GSList
--
-- var it_name = "%s_it".printf (stmt.variable_name);
--
-- var citdecl = new CCodeDeclaration (collection_type.get_cname ());
-- var citvardecl = new CCodeVariableDeclarator (it_name);
-- citvardecl.line = cblock.line;
-- citdecl.add_declarator (citvardecl);
-- cblock.add_statement (citdecl);
--
-- var cbody = new CCodeBlock ();
--
-- CCodeExpression element_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "data");
--
-- if (collection_type.get_type_arguments ().size != 1) {
-- Report.error (stmt.source_reference, "internal error: missing generic type argument");
-- stmt.error = true;
-- return;
-- }
--
-- var element_data_type = collection_type.get_type_arguments ().get (0).copy ();
-- element_data_type.value_owned = false;
-- element_data_type.is_type_argument = true;
-- element_expr = transform_expression (element_expr, element_data_type, stmt.type_reference);
--
-- var cfrag = new CCodeFragment ();
-- append_temp_decl (cfrag, temp_vars);
-- cbody.add_statement (cfrag);
-- temp_vars.clear ();
--
-- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-- var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
-- cvardecl.line = cblock.line;
-- cdecl.add_declarator (cvardecl);
-- cbody.add_statement (cdecl);
--
-- cbody.add_statement (stmt.body.ccodenode);
--
-- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier (it_name), new CCodeConstant ("NULL"));
--
-- var cfor = new CCodeForStatement (ccond, cbody);
--
-- cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeIdentifier (collection_backup.name)));
--
-- cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "next")));
-- cblock.add_statement (cfor);
-- } else if (list_type != null && stmt.collection.value_type.compatible (new ObjectType (list_type))) {
-- // iterating over a Gee.List, use integer to avoid the cost of an iterator object
--
-- var it_name = "%s_it".printf (stmt.variable_name);
--
-- var citdecl = new CCodeDeclaration ("int");
-- citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
-- cblock.add_statement (citdecl);
--
-- var cbody = new CCodeBlock ();
--
-- var get_method = (Method) list_type.scope.lookup ("get");
-- var get_ccall = new CCodeFunctionCall (new CCodeIdentifier (get_method.get_cname ()));
-- get_ccall.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), list_type));
-- get_ccall.add_argument (new CCodeIdentifier (it_name));
-- CCodeExpression element_expr = get_ccall;
--
-- var element_type = SemanticAnalyzer.get_actual_type (stmt.collection.value_type, get_method, get_method.return_type, stmt);
--
-- element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
--
-- var cfrag = new CCodeFragment ();
-- append_temp_decl (cfrag, temp_vars);
-- cbody.add_statement (cfrag);
-- temp_vars.clear ();
--
-- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-- var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
-- cvardecl.line = cblock.line;
-- cdecl.add_declarator (cvardecl);
-- cbody.add_statement (cdecl);
--
-- cbody.add_statement (stmt.body.ccodenode);
--
-- var list_len = new CCodeFunctionCall (new CCodeIdentifier ("gee_collection_get_size"));
-- list_len.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), this.collection_type));
--
-- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier (it_name), list_len);
--
-- var cfor = new CCodeForStatement (ccond, cbody);
-- cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeConstant ("0")));
-- cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier (it_name), new CCodeConstant ("1"))));
-- cfor.line = cblock.line;
-- cblock.add_statement (cfor);
-- } else if (iterable_type != null && stmt.collection.value_type.compatible (new ObjectType (iterable_type))) {
-- // iterating over a Gee.Iterable, use iterator
--
-- var it_name = "%s_it".printf (stmt.variable_name);
--
-- var citdecl = new CCodeDeclaration (iterator_type.get_cname () + "*");
-- var it_method = (Method) iterable_type.scope.lookup ("iterator");
-- var it_ccall = new CCodeFunctionCall (new CCodeIdentifier (it_method.get_cname ()));
-- it_ccall.add_argument (new InstanceCast (new CCodeIdentifier (collection_backup.name), iterable_type));
-- var citvardecl = new CCodeVariableDeclarator.with_initializer (it_name, it_ccall);
-- citvardecl.line = cblock.line;
-- citdecl.add_declarator (citvardecl);
-- cblock.add_statement (citdecl);
--
-- var cbody = new CCodeBlock ();
--
-- var get_method = (Method) iterator_type.scope.lookup ("get");
-- var get_ccall = new CCodeFunctionCall (new CCodeIdentifier (get_method.get_cname ()));
-- get_ccall.add_argument (new CCodeIdentifier (it_name));
-- CCodeExpression element_expr = get_ccall;
--
-- Iterator<DataType> type_arg_it = it_method.return_type.get_type_arguments ().iterator ();
-- type_arg_it.next ();
-- var it_type = SemanticAnalyzer.get_actual_type (stmt.collection.value_type, it_method, type_arg_it.get (), stmt);
--
-- element_expr = transform_expression (element_expr, it_type, stmt.type_reference);
--
-- var cfrag = new CCodeFragment ();
-- append_temp_decl (cfrag, temp_vars);
-- cbody.add_statement (cfrag);
-- temp_vars.clear ();
--
-- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
-- var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
-- cvardecl.line = cblock.line;
-- cdecl.add_declarator (cvardecl);
-- cbody.add_statement (cdecl);
--
-- cbody.add_statement (stmt.body.ccodenode);
--
-- var next_method = (Method) iterator_type.scope.lookup ("next");
-- var next_ccall = new CCodeFunctionCall (new CCodeIdentifier (next_method.get_cname ()));
-- next_ccall.add_argument (new CCodeIdentifier (it_name));
--
-- var cwhile = new CCodeWhileStatement (next_ccall, cbody);
-- cwhile.line = cblock.line;
-- cblock.add_statement (cwhile);
-- }
--
-- foreach (LocalVariable local in stmt.get_local_variables ()) {
-- if (requires_destroy (local.variable_type)) {
-- var ma = new MemberAccess.simple (local.name);
-- ma.symbol_reference = local;
-- var cunref = new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (get_variable_cname (local.name)), local.variable_type, ma));
-- cunref.line = cblock.line;
-- cblock.add_statement (cunref);
-- }
-- }
-- }
--
-- public override void visit_break_statement (BreakStatement stmt) {
-- stmt.ccodenode = new CCodeBreakStatement ();
--
-- create_local_free (stmt, true);
-- }
--
-- public override void visit_continue_statement (ContinueStatement stmt) {
-- stmt.ccodenode = new CCodeContinueStatement ();
--
-- create_local_free (stmt, true);
-- }
--
- public void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop) {
- var b = (Block) sym;
-
-@@ -2661,7 +1889,7 @@
- }
- }
-
-- private void create_local_free (CodeNode stmt, bool stop_at_loop = false) {
-+ public void create_local_free (CodeNode stmt, bool stop_at_loop = false) {
- var cfrag = new CCodeFragment ();
-
- append_local_free (current_symbol, cfrag, stop_at_loop);
-@@ -2992,7 +2220,7 @@
- return true;
- }
-
-- private CCodeExpression? get_ref_cexpression (DataType expression_type, CCodeExpression cexpr, Expression? expr, CodeNode node) {
-+ public CCodeExpression? get_ref_cexpression (DataType expression_type, CCodeExpression cexpr, Expression? expr, CodeNode node) {
- if (expression_type is ValueType && !expression_type.nullable) {
- // normal value type, no null check
- // (copy (&expr, &temp), temp)
-@@ -3785,7 +3013,7 @@
- return cexpr;
- }
-
-- private CCodeExpression get_implicit_cast_expression (CCodeExpression source_cexpr, DataType? expression_type, DataType? target_type, Expression? expr = null) {
-+ public virtual CCodeExpression get_implicit_cast_expression (CCodeExpression source_cexpr, DataType? expression_type, DataType? target_type, Expression? expr = null) {
- var cexpr = source_cexpr;
-
- if (expression_type.data_type != null && expression_type.data_type == target_type.data_type) {
-@@ -3811,180 +3039,11 @@
- } else {
- return cexpr;
- }
-- } else if (target_type is DelegateType && expression_type is MethodType) {
-- var dt = (DelegateType) target_type;
-- var mt = (MethodType) expression_type;
--
-- var method = mt.method_symbol;
-- if (method.base_method != null) {
-- method = method.base_method;
-- } else if (method.base_interface_method != null) {
-- method = method.base_interface_method;
-- }
--
-- return new CCodeIdentifier (generate_delegate_wrapper (method, dt.delegate_symbol));
- } else {
- return cexpr;
- }
- }
-
-- private string generate_delegate_wrapper (Method m, Delegate d) {
-- string delegate_name;
-- var sig = d.parent_symbol as Signal;
-- var dynamic_sig = sig as DynamicSignal;
-- if (dynamic_sig != null) {
-- delegate_name = head.get_dynamic_signal_cname (dynamic_sig);
-- } else if (sig != null) {
-- delegate_name = sig.parent_symbol.get_lower_case_cprefix () + sig.get_cname ();
-- } else {
-- delegate_name = Symbol.camel_case_to_lower_case (d.get_cname ());
-- }
--
-- string wrapper_name = "_%s_%s".printf (m.get_cname (), delegate_name);
--
-- if (!add_wrapper (wrapper_name)) {
-- // wrapper already defined
-- return wrapper_name;
-- }
--
-- // declaration
--
-- var function = new CCodeFunction (wrapper_name, m.return_type.get_cname ());
-- function.modifiers = CCodeModifiers.STATIC;
-- m.ccodenode = function;
--
-- var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
--
-- if (d.has_target) {
-- var cparam = new CCodeFormalParameter ("self", "gpointer");
-- cparam_map.set (get_param_pos (d.cinstance_parameter_position), cparam);
-- }
--
-- var d_params = d.get_parameters ();
-- foreach (FormalParameter param in d_params) {
-- // ensure that C code node has been generated
-- param.accept (codegen);
--
-- cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
--
-- // handle array parameters
-- if (!param.no_array_length && param.parameter_type is ArrayType) {
-- var array_type = (ArrayType) param.parameter_type;
--
-- var length_ctype = "int";
-- if (param.direction != ParameterDirection.IN) {
-- length_ctype = "int*";
-- }
--
-- for (int dim = 1; dim <= array_type.rank; dim++) {
-- var cparam = new CCodeFormalParameter (head.get_array_length_cname (param.name, dim), length_ctype);
-- cparam_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), cparam);
-- }
-- }
--
-- }
--
-- if (m.get_error_types ().size > 0) {
-- var cparam = new CCodeFormalParameter ("error", "GError**");
-- cparam_map.set (get_param_pos (-1), cparam);
-- }
--
-- // append C parameters in the right order
-- int last_pos = -1;
-- int min_pos;
-- while (true) {
-- min_pos = -1;
-- foreach (int pos in cparam_map.get_keys ()) {
-- if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
-- min_pos = pos;
-- }
-- }
-- if (min_pos == -1) {
-- break;
-- }
-- function.add_parameter (cparam_map.get (min_pos));
-- last_pos = min_pos;
-- }
--
--
-- // definition
--
-- var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
--
-- int i = 0;
-- if (m.binding == MemberBinding.INSTANCE) {
-- CCodeExpression arg;
-- if (d.has_target) {
-- arg = new CCodeIdentifier ("self");
-- } else {
-- // use first delegate parameter as instance
-- arg = new CCodeIdentifier ((d_params.get (0).ccodenode as CCodeFormalParameter).name);
-- i = 1;
-- }
-- carg_map.set (get_param_pos (m.cinstance_parameter_position), arg);
-- }
--
-- foreach (FormalParameter param in m.get_parameters ()) {
-- CCodeExpression arg;
-- arg = new CCodeIdentifier ((d_params.get (i).ccodenode as CCodeFormalParameter).name);
-- carg_map.set (get_param_pos (param.cparameter_position), arg);
--
-- // handle array arguments
-- if (!param.no_array_length && param.parameter_type is ArrayType) {
-- var array_type = (ArrayType) param.parameter_type;
-- for (int dim = 1; dim <= array_type.rank; dim++) {
-- CCodeExpression clength;
-- if (d_params.get (i).no_array_length) {
-- clength = new CCodeConstant ("-1");
-- } else {
-- clength = new CCodeIdentifier (head.get_array_length_cname (d_params.get (i).name, dim));
-- }
-- carg_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), clength);
-- }
-- }
--
-- i++;
-- }
--
-- if (m.get_error_types ().size > 0) {
-- carg_map.set (get_param_pos (-1), new CCodeIdentifier ("error"));
-- }
--
-- var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
--
-- // append C arguments in the right order
-- last_pos = -1;
-- while (true) {
-- min_pos = -1;
-- foreach (int pos in carg_map.get_keys ()) {
-- if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
-- min_pos = pos;
-- }
-- }
-- if (min_pos == -1) {
-- break;
-- }
-- ccall.add_argument (carg_map.get (min_pos));
-- last_pos = min_pos;
-- }
--
-- var block = new CCodeBlock ();
-- if (m.return_type is VoidType) {
-- block.add_statement (new CCodeExpressionStatement (ccall));
-- } else {
-- block.add_statement (new CCodeReturnStatement (ccall));
-- }
--
-- // append to file
--
-- source_type_member_declaration.append (function.copy ());
--
-- function.block = block;
-- source_type_member_definition.append (function);
--
-- return wrapper_name;
-- }
--
- public CCodeFunctionCall get_property_set_call (Property prop, MemberAccess ma, CCodeExpression cexpr) {
- if (ma.inner is BaseAccess) {
- if (prop.base_property != null) {
-Index: gobject/valaccodedelegatemodule.vala
-===================================================================
---- gobject/valaccodedelegatemodule.vala (revision 1971)
-+++ gobject/valaccodedelegatemodule.vala (revision 2004)
-@@ -21,7 +21,7 @@
- * Raffaele Sandrini <raffaele@sandrini.ch>
- */
-
--using GLib;
-+using Gee;
-
- /**
- * The link between an assignment and generated code.
-@@ -166,4 +166,179 @@
- public override string get_delegate_target_destroy_notify_cname (string delegate_cname) {
- return "%s_target_destroy_notify".printf (delegate_cname);
- }
-+
-+ public override CCodeExpression get_implicit_cast_expression (CCodeExpression source_cexpr, DataType? expression_type, DataType? target_type, Expression? expr = null) {
-+ if (target_type is DelegateType && expression_type is MethodType) {
-+ var dt = (DelegateType) target_type;
-+ var mt = (MethodType) expression_type;
-+
-+ var method = mt.method_symbol;
-+ if (method.base_method != null) {
-+ method = method.base_method;
-+ } else if (method.base_interface_method != null) {
-+ method = method.base_interface_method;
-+ }
-+
-+ return new CCodeIdentifier (generate_delegate_wrapper (method, dt.delegate_symbol));
-+ } else {
-+ return base.get_implicit_cast_expression (source_cexpr, expression_type, target_type, expr);
-+ }
-+ }
-+
-+ private string generate_delegate_wrapper (Method m, Delegate d) {
-+ string delegate_name;
-+ var sig = d.parent_symbol as Signal;
-+ var dynamic_sig = sig as DynamicSignal;
-+ if (dynamic_sig != null) {
-+ delegate_name = head.get_dynamic_signal_cname (dynamic_sig);
-+ } else if (sig != null) {
-+ delegate_name = sig.parent_symbol.get_lower_case_cprefix () + sig.get_cname ();
-+ } else {
-+ delegate_name = Symbol.camel_case_to_lower_case (d.get_cname ());
-+ }
-+
-+ string wrapper_name = "_%s_%s".printf (m.get_cname (), delegate_name);
-+
-+ if (!add_wrapper (wrapper_name)) {
-+ // wrapper already defined
-+ return wrapper_name;
-+ }
-+
-+ // declaration
-+
-+ var function = new CCodeFunction (wrapper_name, m.return_type.get_cname ());
-+ function.modifiers = CCodeModifiers.STATIC;
-+ m.ccodenode = function;
-+
-+ var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
-+
-+ if (d.has_target) {
-+ var cparam = new CCodeFormalParameter ("self", "gpointer");
-+ cparam_map.set (get_param_pos (d.cinstance_parameter_position), cparam);
-+ }
-+
-+ var d_params = d.get_parameters ();
-+ foreach (FormalParameter param in d_params) {
-+ // ensure that C code node has been generated
-+ param.accept (codegen);
-+
-+ cparam_map.set (get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
-+
-+ // handle array parameters
-+ if (!param.no_array_length && param.parameter_type is ArrayType) {
-+ var array_type = (ArrayType) param.parameter_type;
-+
-+ var length_ctype = "int";
-+ if (param.direction != ParameterDirection.IN) {
-+ length_ctype = "int*";
-+ }
-+
-+ for (int dim = 1; dim <= array_type.rank; dim++) {
-+ var cparam = new CCodeFormalParameter (head.get_array_length_cname (param.name, dim), length_ctype);
-+ cparam_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), cparam);
-+ }
-+ }
-+
-+ }
-+
-+ if (m.get_error_types ().size > 0) {
-+ var cparam = new CCodeFormalParameter ("error", "GError**");
-+ cparam_map.set (get_param_pos (-1), cparam);
-+ }
-+
-+ // append C parameters in the right order
-+ int last_pos = -1;
-+ int min_pos;
-+ while (true) {
-+ min_pos = -1;
-+ foreach (int pos in cparam_map.get_keys ()) {
-+ if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
-+ min_pos = pos;
-+ }
-+ }
-+ if (min_pos == -1) {
-+ break;
-+ }
-+ function.add_parameter (cparam_map.get (min_pos));
-+ last_pos = min_pos;
-+ }
-+
-+
-+ // definition
-+
-+ var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
-+
-+ int i = 0;
-+ if (m.binding == MemberBinding.INSTANCE) {
-+ CCodeExpression arg;
-+ if (d.has_target) {
-+ arg = new CCodeIdentifier ("self");
-+ } else {
-+ // use first delegate parameter as instance
-+ arg = new CCodeIdentifier ((d_params.get (0).ccodenode as CCodeFormalParameter).name);
-+ i = 1;
-+ }
-+ carg_map.set (get_param_pos (m.cinstance_parameter_position), arg);
-+ }
-+
-+ foreach (FormalParameter param in m.get_parameters ()) {
-+ CCodeExpression arg;
-+ arg = new CCodeIdentifier ((d_params.get (i).ccodenode as CCodeFormalParameter).name);
-+ carg_map.set (get_param_pos (param.cparameter_position), arg);
-+
-+ // handle array arguments
-+ if (!param.no_array_length && param.parameter_type is ArrayType) {
-+ var array_type = (ArrayType) param.parameter_type;
-+ for (int dim = 1; dim <= array_type.rank; dim++) {
-+ CCodeExpression clength;
-+ if (d_params.get (i).no_array_length) {
-+ clength = new CCodeConstant ("-1");
-+ } else {
-+ clength = new CCodeIdentifier (head.get_array_length_cname (d_params.get (i).name, dim));
-+ }
-+ carg_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), clength);
-+ }
-+ }
-+
-+ i++;
-+ }
-+
-+ if (m.get_error_types ().size > 0) {
-+ carg_map.set (get_param_pos (-1), new CCodeIdentifier ("error"));
-+ }
-+
-+ var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
-+
-+ // append C arguments in the right order
-+ last_pos = -1;
-+ while (true) {
-+ min_pos = -1;
-+ foreach (int pos in carg_map.get_keys ()) {
-+ if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
-+ min_pos = pos;
-+ }
-+ }
-+ if (min_pos == -1) {
-+ break;
-+ }
-+ ccall.add_argument (carg_map.get (min_pos));
-+ last_pos = min_pos;
-+ }
-+
-+ var block = new CCodeBlock ();
-+ if (m.return_type is VoidType) {
-+ block.add_statement (new CCodeExpressionStatement (ccall));
-+ } else {
-+ block.add_statement (new CCodeReturnStatement (ccall));
-+ }
-+
-+ // append to file
-+
-+ source_type_member_declaration.append (function.copy ());
-+
-+ function.block = block;
-+ source_type_member_definition.append (function);
-+
-+ return wrapper_name;
-+ }
- }
-Index: gobject/valaccodearraymodule.vala
-===================================================================
---- gobject/valaccodearraymodule.vala (revision 1971)
-+++ gobject/valaccodearraymodule.vala (revision 2004)
-@@ -28,6 +28,8 @@
- * The link between an assignment and generated code.
- */
- public class Vala.CCodeArrayModule : CCodeInvocationExpressionModule {
-+ private int next_array_dup_id = 0;
-+
- public CCodeArrayModule (CCodeGenerator codegen, CCodeModule? next) {
- base (codegen, next);
- }
-@@ -280,26 +282,6 @@
- get_ccall.add_argument (cindex);
-
- expr.ccodenode = convert_from_generic_pointer (get_ccall, expr.value_type);
-- } else if (expr.container is MemberAccess && expr.container.symbol_reference is Signal) {
-- // should be moved to the GSignal module
--
-- // detailed signal emission
-- var sig = (Signal) expr.symbol_reference;
-- var ma = (MemberAccess) expr.container;
--
-- var detail_expr = expr.get_indices ().get (0) as StringLiteral;
-- string signal_detail = detail_expr.eval ();
--
-- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
--
-- // FIXME: use C cast if debugging disabled
-- var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
-- ccast.add_argument ((CCodeExpression) ma.inner.ccodenode);
-- ccall.add_argument (ccast);
--
-- ccall.add_argument (sig.get_canonical_cconstant (signal_detail));
--
-- expr.ccodenode = ccall;
- } else {
- // access to element in an array
- for (int i = 1; i < rank; i++) {
-@@ -416,4 +398,84 @@
-
- source_type_member_definition.append (fun);
- }
-+
-+ public override CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference) {
-+ if (type is ArrayType) {
-+ return new CCodeIdentifier (generate_array_dup_wrapper ((ArrayType) type));
-+ } else {
-+ return base.get_dup_func_expression (type, source_reference);
-+ }
-+ }
-+
-+ string generate_array_dup_wrapper (ArrayType array_type) {
-+ string dup_func = "_vala_array_dup%d".printf (++next_array_dup_id);
-+
-+ if (!add_wrapper (dup_func)) {
-+ // wrapper already defined
-+ return dup_func;
-+ }
-+
-+ // declaration
-+
-+ var function = new CCodeFunction (dup_func, array_type.get_cname ());
-+ function.modifiers = CCodeModifiers.STATIC;
-+
-+ function.add_parameter (new CCodeFormalParameter ("self", array_type.get_cname ()));
-+ // total length over all dimensions
-+ function.add_parameter (new CCodeFormalParameter ("length", "int"));
-+
-+ // definition
-+
-+ var block = new CCodeBlock ();
-+
-+ if (requires_copy (array_type.element_type)) {
-+ var old_temp_vars = temp_vars;
-+
-+ var cdecl = new CCodeDeclaration (array_type.get_cname ());
-+ var cvardecl = new CCodeVariableDeclarator ("result");
-+ cdecl.add_declarator (cvardecl);
-+ var gnew = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
-+ gnew.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
-+ gnew.add_argument (new CCodeIdentifier ("length"));
-+ cvardecl.initializer = gnew;
-+ block.add_statement (cdecl);
-+
-+ var idx_decl = new CCodeDeclaration ("int");
-+ idx_decl.add_declarator (new CCodeVariableDeclarator ("i"));
-+ block.add_statement (idx_decl);
-+
-+ var loop_body = new CCodeBlock ();
-+ loop_body.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("result"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type))));
-+
-+ var cfor = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("length")), loop_body);
-+ cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
-+ cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
-+ block.add_statement (cfor);
-+
-+ block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
-+
-+ var cfrag = new CCodeFragment ();
-+ append_temp_decl (cfrag, temp_vars);
-+ block.add_statement (cfrag);
-+ temp_vars = old_temp_vars;
-+ } else {
-+ var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_memdup"));
-+ dup_call.add_argument (new CCodeIdentifier ("self"));
-+
-+ var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
-+ sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
-+ dup_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeIdentifier ("length"), sizeof_call));
-+
-+ block.add_statement (new CCodeReturnStatement (dup_call));
-+ }
-+
-+ // append to file
-+
-+ source_type_member_declaration.append (function.copy ());
-+
-+ function.block = block;
-+ source_type_member_definition.append (function);
-+
-+ return dup_func;
-+ }
- }
-Index: gobject/Makefile.am
-===================================================================
---- gobject/Makefile.am (revision 1971)
-+++ gobject/Makefile.am (revision 2004)
-@@ -16,9 +16,8 @@
- valaccodeassignmentmodule.vala \
- valaccodebasemodule.vala \
- valaccodecompiler.vala \
-+ valaccodecontrolflowmodule.vala \
- valaccodedelegatemodule.vala \
-- valaccodedynamicpropertymodule.vala \
-- valaccodedynamicsignalmodule.vala \
- valaccodegenerator.vala \
- valaccodeinvocationexpressionmodule.vala \
- valaccodememberaccessmodule.vala \
-Index: gobject/valagobjectmodule.vala
-===================================================================
---- gobject/valagobjectmodule.vala (revision 1971)
-+++ gobject/valagobjectmodule.vala (revision 2004)
-@@ -24,6 +24,9 @@
- using GLib;
-
- public class Vala.GObjectModule : GTypeModule {
-+ int dynamic_property_id;
-+ int signal_wrapper_id;
-+
- public GObjectModule (CCodeGenerator codegen, CCodeModule? next) {
- base (codegen, next);
- }
-@@ -1453,5 +1456,290 @@
-
- return cspec;
- }
-+
-+ public override CCodeExpression get_construct_property_assignment (CCodeConstant canonical_cconstant, DataType property_type, CCodeExpression value) {
-+ // this property is used as a construction parameter
-+ var cpointer = new CCodeIdentifier ("__params_it");
-+
-+ var ccomma = new CCodeCommaExpression ();
-+ // set name in array for current parameter
-+ var cnamemember = new CCodeMemberAccess.pointer (cpointer, "name");
-+ var cnameassign = new CCodeAssignment (cnamemember, canonical_cconstant);
-+ ccomma.append_expression (cnameassign);
-+
-+ var gvaluearg = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (cpointer, "value"));
-+
-+ // initialize GValue in array for current parameter
-+ var cvalueinit = new CCodeFunctionCall (new CCodeIdentifier ("g_value_init"));
-+ cvalueinit.add_argument (gvaluearg);
-+ cvalueinit.add_argument (new CCodeIdentifier (property_type.get_type_id ()));
-+ ccomma.append_expression (cvalueinit);
-+
-+ // set GValue for current parameter
-+ var cvalueset = new CCodeFunctionCall (get_value_setter_function (property_type));
-+ cvalueset.add_argument (gvaluearg);
-+ cvalueset.add_argument (value);
-+ ccomma.append_expression (cvalueset);
-+
-+ // move pointer to next parameter in array
-+ ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, cpointer));
-+
-+ return ccomma;
-+ }
-+
-+ public override void visit_constructor (Constructor c) {
-+ current_method_inner_error = false;
-+ in_constructor = true;
-+
-+ if (c.binding == MemberBinding.CLASS || c.binding == MemberBinding.STATIC) {
-+ in_static_or_class_ctor = true;
-+ }
-+ c.accept_children (codegen);
-+ in_static_or_class_ctor = false;
-+
-+ in_constructor = false;
-+
-+ var cl = (Class) c.parent_symbol;
-+
-+ if (c.binding == MemberBinding.INSTANCE) {
-+ function = new CCodeFunction ("%s_constructor".printf (cl.get_lower_case_cname (null)), "GObject *");
-+ function.modifiers = CCodeModifiers.STATIC;
-+
-+ function.add_parameter (new CCodeFormalParameter ("type", "GType"));
-+ function.add_parameter (new CCodeFormalParameter ("n_construct_properties", "guint"));
-+ function.add_parameter (new CCodeFormalParameter ("construct_properties", "GObjectConstructParam *"));
-+
-+ source_type_member_declaration.append (function.copy ());
-+
-+
-+ var cblock = new CCodeBlock ();
-+ var cdecl = new CCodeDeclaration ("GObject *");
-+ cdecl.add_declarator (new CCodeVariableDeclarator ("obj"));
-+ cblock.add_statement (cdecl);
-+
-+ cdecl = new CCodeDeclaration ("%sClass *".printf (cl.get_cname ()));
-+ cdecl.add_declarator (new CCodeVariableDeclarator ("klass"));
-+ cblock.add_statement (cdecl);
-+
-+ cdecl = new CCodeDeclaration ("GObjectClass *");
-+ cdecl.add_declarator (new CCodeVariableDeclarator ("parent_class"));
-+ cblock.add_statement (cdecl);
-+
-+
-+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek"));
-+ ccall.add_argument (new CCodeIdentifier (cl.get_type_id ()));
-+ var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (cl.get_upper_case_cname (null))));
-+ ccast.add_argument (ccall);
-+ cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("klass"), ccast)));
-+
-+ ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
-+ ccall.add_argument (new CCodeIdentifier ("klass"));
-+ ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
-+ ccast.add_argument (ccall);
-+ cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_class"), ccast)));
-+
-+
-+ ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier ("parent_class"), "constructor"));
-+ ccall.add_argument (new CCodeIdentifier ("type"));
-+ ccall.add_argument (new CCodeIdentifier ("n_construct_properties"));
-+ ccall.add_argument (new CCodeIdentifier ("construct_properties"));
-+ cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("obj"), ccall)));
-+
-+
-+ ccall = new InstanceCast (new CCodeIdentifier ("obj"), cl);
-+
-+ cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
-+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
-+
-+ cblock.add_statement (cdecl);
-+
-+ if (current_method_inner_error) {
-+ /* always separate error parameter and inner_error local variable
-+ * as error may be set to NULL but we're always interested in inner errors
-+ */
-+ var cdecl = new CCodeDeclaration ("GError *");
-+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
-+ cblock.add_statement (cdecl);
-+ }
-+
-+
-+ cblock.add_statement (c.body.ccodenode);
-+
-+ cblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("obj")));
-+
-+ function.block = cblock;
-+
-+ if (c.source_reference.comment != null) {
-+ source_type_member_definition.append (new CCodeComment (c.source_reference.comment));
-+ }
-+ source_type_member_definition.append (function);
-+ } else if (c.binding == MemberBinding.CLASS) {
-+ // class constructor
-+
-+ var base_init = new CCodeFunction ("%s_base_init".printf (cl.get_lower_case_cname (null)), "void");
-+ base_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
-+ base_init.modifiers = CCodeModifiers.STATIC;
-+
-+ source_type_member_declaration.append (base_init.copy ());
-+
-+ var block = (CCodeBlock) c.body.ccodenode;
-+ if (current_method_inner_error) {
-+ /* always separate error parameter and inner_error local variable
-+ * as error may be set to NULL but we're always interested in inner errors
-+ */
-+ var cdecl = new CCodeDeclaration ("GError *");
-+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
-+ block.prepend_statement (cdecl);
-+ }
-+
-+ base_init.block = block;
-+
-+ source_type_member_definition.append (base_init);
-+ } else if (c.binding == MemberBinding.STATIC) {
-+ // static class constructor
-+ // add to class_init
-+
-+ if (current_method_inner_error) {
-+ /* always separate error parameter and inner_error local variable
-+ * as error may be set to NULL but we're always interested in inner errors
-+ */
-+ var cdecl = new CCodeDeclaration ("GError *");
-+ cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
-+ class_init_fragment.append (cdecl);
-+ }
-+
-+ class_init_fragment.append (c.body.ccodenode);
-+ } else {
-+ Report.error (c.source_reference, "internal error: constructors must have instance, class, or static binding");
-+ }
-+ }
-+
-+ public override string get_dynamic_property_getter_cname (DynamicProperty prop) {
-+ if (prop.dynamic_type.data_type == null
-+ || !prop.dynamic_type.data_type.is_subtype_of (gobject_type)) {
-+ return base.get_dynamic_property_getter_cname (prop);
-+ }
-+
-+ string getter_cname = "_dynamic_get_%s%d".printf (prop.name, dynamic_property_id++);
-+
-+ var func = new CCodeFunction (getter_cname, prop.property_type.get_cname ());
-+ func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
-+
-+ func.add_parameter (new CCodeFormalParameter ("obj", prop.dynamic_type.get_cname ()));
-+
-+ var block = new CCodeBlock ();
-+ generate_gobject_property_getter_wrapper (prop, block);
-+
-+ // append to C source file
-+ source_type_member_declaration.append (func.copy ());
-+
-+ func.block = block;
-+ source_type_member_definition.append (func);
-+
-+ return getter_cname;
-+ }
-+
-+ public override string get_dynamic_property_setter_cname (DynamicProperty prop) {
-+ if (prop.dynamic_type.data_type == null
-+ || !prop.dynamic_type.data_type.is_subtype_of (gobject_type)) {
-+ return base.get_dynamic_property_setter_cname (prop);
-+ }
-+
-+ string setter_cname = "_dynamic_set_%s%d".printf (prop.name, dynamic_property_id++);
-+
-+ var func = new CCodeFunction (setter_cname, "void");
-+ func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
-+
-+ func.add_parameter (new CCodeFormalParameter ("obj", prop.dynamic_type.get_cname ()));
-+ func.add_parameter (new CCodeFormalParameter ("value", prop.property_type.get_cname ()));
-+
-+ var block = new CCodeBlock ();
-+ generate_gobject_property_setter_wrapper (prop, block);
-+
-+ // append to C source file
-+ source_type_member_declaration.append (func.copy ());
-+
-+ func.block = block;
-+ source_type_member_definition.append (func);
-+
-+ return setter_cname;
-+ }
-+
-+ void generate_gobject_property_getter_wrapper (DynamicProperty node, CCodeBlock block) {
-+ var cdecl = new CCodeDeclaration (node.property_type.get_cname ());
-+ cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
-+ block.add_statement (cdecl);
-+
-+ var call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get"));
-+ call.add_argument (new CCodeIdentifier ("obj"));
-+ call.add_argument (node.get_canonical_cconstant ());
-+ call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
-+ call.add_argument (new CCodeConstant ("NULL"));
-+
-+ block.add_statement (new CCodeExpressionStatement (call));
-+
-+ block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
-+ }
-+
-+ void generate_gobject_property_setter_wrapper (DynamicProperty node, CCodeBlock block) {
-+ var call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_set"));
-+ call.add_argument (new CCodeIdentifier ("obj"));
-+ call.add_argument (node.get_canonical_cconstant ());
-+ call.add_argument (new CCodeIdentifier ("value"));
-+ call.add_argument (new CCodeConstant ("NULL"));
-+
-+ block.add_statement (new CCodeExpressionStatement (call));
-+ }
-+
-+ public override string get_dynamic_signal_cname (DynamicSignal node) {
-+ return "dynamic_%s%d_".printf (node.name, signal_wrapper_id++);
-+ }
-+
-+ public override string get_dynamic_signal_connect_wrapper_name (DynamicSignal sig) {
-+ if (sig.dynamic_type.data_type == null
-+ || !sig.dynamic_type.data_type.is_subtype_of (gobject_type)) {
-+ return base.get_dynamic_signal_connect_wrapper_name (sig);
-+ }
-+
-+ string connect_wrapper_name = "_%sconnect".printf (get_dynamic_signal_cname (sig));
-+ var func = new CCodeFunction (connect_wrapper_name, "void");
-+ func.add_parameter (new CCodeFormalParameter ("obj", "gpointer"));
-+ func.add_parameter (new CCodeFormalParameter ("signal_name", "const char *"));
-+ func.add_parameter (new CCodeFormalParameter ("handler", "GCallback"));
-+ func.add_parameter (new CCodeFormalParameter ("data", "gpointer"));
-+ var block = new CCodeBlock ();
-+ generate_gobject_connect_wrapper (sig, block);
-+
-+ // append to C source file
-+ source_type_member_declaration.append (func.copy ());
-+
-+ func.block = block;
-+ source_type_member_definition.append (func);
-+
-+ return connect_wrapper_name;
-+ }
-+
-+ void generate_gobject_connect_wrapper (DynamicSignal sig, CCodeBlock block) {
-+ var m = (Method) sig.handler.symbol_reference;
-+
-+ sig.accept (codegen);
-+
-+ string connect_func = "g_signal_connect_object";
-+ if (m.binding != MemberBinding.INSTANCE) {
-+ connect_func = "g_signal_connect";
-+ }
-+
-+ var call = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
-+ call.add_argument (new CCodeIdentifier ("obj"));
-+ call.add_argument (new CCodeIdentifier ("signal_name"));
-+ call.add_argument (new CCodeIdentifier ("handler"));
-+ call.add_argument (new CCodeIdentifier ("data"));
-+
-+ if (m.binding == MemberBinding.INSTANCE) {
-+ call.add_argument (new CCodeConstant ("0"));
-+ }
-+
-+ block.add_statement (new CCodeExpressionStatement (call));
-+ }
- }
-
-Index: gobject/valaccodegenerator.vala
-===================================================================
---- gobject/valaccodegenerator.vala (revision 1971)
-+++ gobject/valaccodegenerator.vala (revision 2004)
-@@ -35,13 +35,12 @@
- head = new CCodeBaseModule (this, head);
- head = new CCodeStructModule (this, head);
- head = new CCodeMethodModule (this, head);
-+ head = new CCodeControlFlowModule (this, head);
- head = new CCodeMemberAccessModule (this, head);
- head = new CCodeAssignmentModule (this, head);
- head = new CCodeInvocationExpressionModule (this, head);
- head = new CCodeArrayModule (this, head);
- head = new CCodeDelegateModule (this, head);
-- head = new CCodeDynamicPropertyModule (this, head);
-- head = new CCodeDynamicSignalModule (this, head);
- head = new GErrorModule (this, head);
- head = new GTypeModule (this, head);
- head = new GObjectModule (this, head);