Add support for class constructors, class fields, and class methods, fixes
authorJuerg Billeter <j@bitron.ch>
Wed, 23 Apr 2008 20:14:12 +0000 (20:14 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Wed, 23 Apr 2008 20:14:12 +0000 (20:14 +0000)
2008-04-23  Juerg Billeter  <j@bitron.ch>

Add support for class constructors, class fields, and class
methods, fixes bug 507136

svn path=/trunk/; revision=1309

34 files changed:
ChangeLog
gobject/valaccodeassignmentbinding.vala
gobject/valaccodeclassbinding.vala
gobject/valaccodegenerator.vala
gobject/valaccodeinvocationexpressionbinding.vala
gobject/valaccodememberaccessbinding.vala
gobject/valaccodemethodbinding.vala
gobject/valaclassregisterfunction.vala
gobject/valagidlwriter.vala
vala/Makefile.am
vala/valaclass.vala
vala/valaclassinstancetype.vala [new file with mode: 0644]
vala/valaclasstype.vala
vala/valaconstructor.vala
vala/valadelegate.vala
vala/valadestructor.vala
vala/valaenum.vala
vala/valaerrordomain.vala
vala/valafield.vala
vala/valainterface.vala
vala/valainterfaceinstancetype.vala [new file with mode: 0644]
vala/valainterfacetype.vala
vala/valainterfacewriter.vala
vala/valamember.vala
vala/valamethod.vala
vala/valanamespace.vala
vala/valanullchecker.vala
vala/valaparser.vala
vala/valaproperty.vala
vala/valasemanticanalyzer.vala
vala/valasignal.vala
vala/valastruct.vala
vala/valasymbolresolver.vala
vapigen/valagidlparser.vala

index 9e3cf3a..0ab546e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2008-04-23  Jürg Billeter  <j@bitron.ch>
 
+       Add support for class constructors, class fields, and class
+       methods, fixes bug 507136
+
+2008-04-23  Jürg Billeter  <j@bitron.ch>
+
        * vala/valaparser.vala:
        Fix nested namespaces
 
index c9b24f5..ec56259 100644 (file)
@@ -110,7 +110,7 @@ public class Vala.CCodeAssignmentBinding : CCodeExpressionBinding {
                                connect_func = codegen.dynamic_signal_binding ((DynamicSignal) sig).get_connect_wrapper_name ();
                        } else {
                                connect_func = "g_signal_connect_object";
-                               if (!m.instance) {
+                               if (m.binding != MemberBinding.INSTANCE) {
                                        connect_func = "g_signal_connect";
                                }
                        }
@@ -184,7 +184,7 @@ public class Vala.CCodeAssignmentBinding : CCodeExpressionBinding {
                        ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (generate_signal_handler_wrapper (m, sig)), "GCallback"));
                }
 
-               if (m.instance) {
+               if (m.binding == MemberBinding.INSTANCE) {
                        // g_signal_connect_object or g_signal_handlers_disconnect_matched
                        // or dynamic_signal_connect or dynamic_signal_disconnect
 
@@ -268,7 +268,7 @@ public class Vala.CCodeAssignmentBinding : CCodeExpressionBinding {
 
                var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
 
-               if (m.instance) {
+               if (m.binding == MemberBinding.INSTANCE) {
                        carg_map.set (codegen.get_param_pos (m.cinstance_parameter_position), new CCodeIdentifier ("self"));
                }
 
@@ -378,7 +378,7 @@ public class Vala.CCodeAssignmentBinding : CCodeExpressionBinding {
                        array = !(codegen.get_array_length_cexpression (assignment.left, 1) is CCodeConstant);
                } else if (assignment.left.static_type is DelegateType) {
                        var delegate_type = (DelegateType) assignment.left.static_type;
-                       instance_delegate = delegate_type.delegate_symbol.instance;
+                       instance_delegate = delegate_type.delegate_symbol.has_target;
                }
                
                if (unref_old || array || instance_delegate) {
index 7a938fe..786480a 100644 (file)
@@ -764,7 +764,7 @@ public class Vala.CCodeClassBinding : CCodeTypesymbolBinding {
                int method_count = 0;
                long blob_len = 0;
                foreach (Method m in cl.get_methods ()) {
-                       if (m is CreationMethod || !m.instance) {
+                       if (m is CreationMethod || m.binding != MemberBinding.INSTANCE) {
                                continue;
                        }
 
index 9908be6..75ecbb0 100644 (file)
@@ -218,7 +218,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                uint64_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("uint64"));
                float_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("float"));
                double_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("double"));
-               string_type = new ClassType ((Class) root_symbol.scope.lookup ("string"));
+               string_type = new ClassInstanceType ((Class) root_symbol.scope.lookup ("string"));
                substring_method = (Method) string_type.data_type.scope.lookup ("substring");
 
                var glib_ns = root_symbol.scope.lookup ("GLib");
@@ -233,7 +233,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                garray_type = (Typesymbol) glib_ns.scope.lookup ("Array");
 
                gquark_type = new ValueType ((Typesymbol) glib_ns.scope.lookup ("Quark"));
-               mutex_type = new ClassType ((Class) glib_ns.scope.lookup ("Mutex"));
+               mutex_type = new ClassInstanceType ((Class) glib_ns.scope.lookup ("Mutex"));
                
                type_module_type = (Typesymbol) glib_ns.scope.lookup ("TypeModule");
 
@@ -435,7 +435,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                foreach (FormalParameter param in d.get_parameters ()) {
                        cfundecl.add_parameter ((CCodeFormalParameter) param.ccodenode);
                }
-               if (d.instance) {
+               if (d.has_target) {
                        var cparam = new CCodeFormalParameter ("user_data", "void*");
                        cfundecl.add_parameter (cparam);
                }
@@ -517,9 +517,12 @@ public class Vala.CCodeGenerator : CodeGenerator {
                }
 
                if (f.access != SymbolAccessibility.PRIVATE) {
-                       st = instance_struct;
-                       if (f.instance) {
+                       if (f.binding == MemberBinding.INSTANCE) {
+                               st = instance_struct;
+
                                lhs = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), f.get_cname ());
+                       } else if (f.binding == MemberBinding.CLASS) {
+                               st = type_struct;
                        } else {
                                var cdecl = new CCodeDeclaration (field_ctype);
                                cdecl.add_declarator (new CCodeVariableDeclarator (f.get_cname ()));
@@ -544,7 +547,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                                lhs = new CCodeIdentifier (f.get_cname ());
                        }
                } else if (f.access == SymbolAccessibility.PRIVATE) {
-                       if (f.instance) {
+                       if (f.binding == MemberBinding.INSTANCE) {
                                if (is_gtypeinstance) {
                                        st = instance_priv_struct;
                                        lhs = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), f.get_cname ());
@@ -569,7 +572,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                        }
                }
 
-               if (f.instance)  {
+               if (f.binding == MemberBinding.INSTANCE)  {
                        st.add_field (field_ctype, f.get_cname ());
                        if (f.type_reference is ArrayType && !f.no_array_length) {
                                // create fields to store array dimensions
@@ -582,7 +585,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                                }
                        } else if (f.type_reference is DelegateType) {
                                var delegate_type = (DelegateType) f.type_reference;
-                               if (delegate_type.delegate_symbol.instance) {
+                               if (delegate_type.delegate_symbol.has_target) {
                                        // create field to store delegate target
                                        st.add_field ("gpointer", get_delegate_target_cname (f.name));
                                }
@@ -614,6 +617,8 @@ public class Vala.CCodeGenerator : CodeGenerator {
                                ma.symbol_reference = f;
                                instance_dispose_fragment.append (new CCodeExpressionStatement (get_unref_expression (lhs, f.type_reference, ma)));
                        }
+               } else if (f.binding == MemberBinding.CLASS)  {
+                       st.add_field (field_ctype, f.get_cname ());
                } else {
                        /* add array length fields where necessary */
                        if (f.type_reference is ArrayType && !f.no_array_length) {
@@ -634,7 +639,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                                }
                        } else if (f.type_reference is DelegateType) {
                                var delegate_type = (DelegateType) f.type_reference;
-                               if (delegate_type.delegate_symbol.instance) {
+                               if (delegate_type.delegate_symbol.has_target) {
                                        // create field to store delegate target
                                        var cdecl = new CCodeDeclaration ("gpointer");
                                        cdecl.add_declarator (new CCodeVariableDeclarator (get_delegate_target_cname  (f.get_cname ())));
@@ -764,9 +769,9 @@ public class Vala.CCodeGenerator : CodeGenerator {
 
                ReferenceType this_type;
                if (t is Class) {
-                       this_type = new ClassType ((Class) t);
+                       this_type = new ClassInstanceType ((Class) t);
                } else {
-                       this_type = new InterfaceType ((Interface) t);
+                       this_type = new InterfaceInstanceType ((Interface) t);
                }
                var cselfparam = new CCodeFormalParameter ("self", this_type.get_cname ());
                var cvalueparam = new CCodeFormalParameter ("value", prop.type_reference.get_cname (false, true));
@@ -925,7 +930,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
 
                var cl = (Class) c.parent_symbol;
 
-               if (c.instance) {
+               if (c.binding == MemberBinding.INSTANCE) {
                        function = new CCodeFunction ("%s_constructor".printf (cl.get_lower_case_cname (null)), "GObject *");
                        function.modifiers = CCodeModifiers.STATIC;
                
@@ -997,7 +1002,19 @@ public class Vala.CCodeGenerator : CodeGenerator {
                                source_type_member_definition.append (new CCodeComment (c.source_reference.comment));
                        }
                        source_type_member_definition.append (function);
-               } else {
+               } 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 ());
+
+                       base_init.block = (CCodeBlock) c.body.ccodenode;
+               
+                       source_type_member_definition.append (base_init);
+               } else if (c.binding == MemberBinding.STATIC) {
                        // static class constructor
                        // add to class_init
 
@@ -1011,6 +1028,8 @@ public class Vala.CCodeGenerator : CodeGenerator {
                        }
 
                        class_init_fragment.append (c.body.ccodenode);
+               } else {
+                       Report.error (c.source_reference, "internal error: constructors must have instance, class, or static binding");
                }
        }
 
@@ -1107,7 +1126,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                } else if (local.variable_type is DelegateType) {
                        var deleg_type = (DelegateType) local.variable_type;
                        var d = deleg_type.delegate_symbol;
-                       if (d.instance) {
+                       if (d.has_target) {
                                // create variable to store delegate target
                                var target_var = new LocalVariable (new PointerType (new VoidType ()), get_delegate_target_cname (local.name));
                                temp_vars.insert (0, target_var);
@@ -1140,7 +1159,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                        } else if (local.variable_type is DelegateType) {
                                var deleg_type = (DelegateType) local.variable_type;
                                var d = deleg_type.delegate_symbol;
-                               if (d.instance) {
+                               if (d.has_target) {
                                        var ccomma = new CCodeCommaExpression ();
 
                                        var temp_var = get_temp_variable (local.variable_type, true, local);
@@ -1898,7 +1917,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                                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.static_type.compatible (new ClassType (glist_type)) || stmt.collection.static_type.compatible (new ClassType (gslist_type))) {
+               } else if (stmt.collection.static_type.compatible (new ClassInstanceType (glist_type)) || stmt.collection.static_type.compatible (new ClassInstanceType (gslist_type))) {
                        var it_name = "%s_it".printf (stmt.variable_name);
                
                        var citdecl = new CCodeDeclaration (collection_type.get_cname ());
@@ -1950,7 +1969,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
 
                        cfor.add_iterator (new CCodeAssignment (new CCodeIdentifier (it_name), new CCodeMemberAccess.pointer (new CCodeIdentifier (it_name), "next")));
                        cblock.add_statement (cfor);
-               } else if (iterable_type != null && stmt.collection.static_type.compatible (new InterfaceType (iterable_type))) {
+               } else if (iterable_type != null && stmt.collection.static_type.compatible (new InterfaceInstanceType (iterable_type))) {
                        var it_name = "%s_it".printf (stmt.variable_name);
 
                        var citdecl = new CCodeDeclaration (iterator_type.get_cname () + "*");
@@ -2484,7 +2503,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                                                }
                                        }
 
-                                       if (field.instance) {
+                                       if (field.binding == MemberBinding.INSTANCE) {
                                                var length_cname = get_array_length_cname (field.name, dim);
                                                var instance_expression_type = get_data_type_for_symbol (base_type);
                                                var instance_target_type = get_data_type_for_symbol ((Typesymbol) field.parent_symbol);
@@ -2553,7 +2572,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                        var invocation_expr = (InvocationExpression) delegate_expr;
                        return invocation_expr.delegate_target;
                } else if (delegate_expr is LambdaExpression) {
-                       if ((current_method != null && current_method.instance) || in_constructor) {
+                       if ((current_method != null && current_method.binding == MemberBinding.INSTANCE) || in_constructor) {
                                return new CCodeIdentifier ("self");
                        } else {
                                return new CCodeConstant ("NULL");
@@ -2605,7 +2624,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                                        }
                                }
 
-                               if (field.instance) {
+                               if (field.binding == MemberBinding.INSTANCE) {
                                        var instance_expression_type = get_data_type_for_symbol (base_type);
                                        var instance_target_type = get_data_type_for_symbol ((Typesymbol) field.parent_symbol);
                                        CCodeExpression typed_inst = get_implicit_cast_expression (pub_inst, instance_expression_type, instance_target_type);
@@ -2633,7 +2652,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                        } else if (delegate_expr.symbol_reference is Method) {
                                var ma = (MemberAccess) delegate_expr;
                                if (ma.inner == null) {
-                                       if ((current_method != null && current_method.instance) || in_constructor) {
+                                       if ((current_method != null && current_method.binding == MemberBinding.INSTANCE) || in_constructor) {
                                                return new CCodeIdentifier ("self");
                                        } else {
                                                return new CCodeConstant ("NULL");
@@ -2929,7 +2948,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                                if (param != null && param.type_reference is DelegateType) {
                                        var deleg_type = (DelegateType) param.type_reference;
                                        var d = deleg_type.delegate_symbol;
-                                       if (d.instance) {
+                                       if (d.has_target) {
                                                creation_call.add_argument (get_delegate_target_cexpression (arg));
                                        }
                                }
@@ -3348,7 +3367,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
 
                var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
 
-               if (d.instance) {
+               if (d.has_target) {
                        var cparam = new CCodeFormalParameter ("self", "gpointer");
                        cparam_map.set (get_param_pos (d.cinstance_parameter_position), cparam);
                }
@@ -3405,9 +3424,9 @@ public class Vala.CCodeGenerator : CodeGenerator {
                var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
 
                int i = 0;
-               if (m.instance) {
+               if (m.binding == MemberBinding.INSTANCE) {
                        CCodeExpression arg;
-                       if (d.instance) {
+                       if (d.has_target) {
                                arg = new CCodeIdentifier ("self");
                        } else {
                                // use first delegate parameter as instance
@@ -3578,9 +3597,9 @@ public class Vala.CCodeGenerator : CodeGenerator {
                DataType type = null;
 
                if (sym is Class) {
-                       type = new ClassType ((Class) sym);
+                       type = new ClassInstanceType ((Class) sym);
                } else if (sym is Interface) {
-                       type = new InterfaceType ((Interface) sym);
+                       type = new InterfaceInstanceType ((Interface) sym);
                } else if (sym is Struct) {
                        type = new ValueType ((Struct) sym);
                } else if (sym is Enum) {
index d70e29d..0207266 100644 (file)
@@ -73,7 +73,7 @@ public class Vala.CCodeInvocationExpressionBinding : CCodeExpressionBinding {
                }
 
                CCodeExpression instance;
-               if (m != null && m.instance) {
+               if (m != null && m.binding == MemberBinding.INSTANCE) {
                        var base_method = m;
                        if (m.base_method != null) {
                                base_method = m.base_method;
@@ -117,6 +117,12 @@ public class Vala.CCodeInvocationExpressionBinding : CCodeExpressionBinding {
                        }
 
                        carg_map.set (codegen.get_param_pos (m.cinstance_parameter_position), instance);
+               } else if (m != null && m.binding == MemberBinding.CLASS) {
+                       var cl = (Class) m.parent_symbol;
+                       var cast = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null) + "_CLASS"));
+                       cast.add_argument (new CCodeIdentifier ("klass"));
+
+                       carg_map.set (codegen.get_param_pos (m.cinstance_parameter_position), cast);
                }
 
                if (m is ArrayMoveMethod) {
@@ -179,7 +185,7 @@ public class Vala.CCodeInvocationExpressionBinding : CCodeExpressionBinding {
                                        } else if (param.type_reference is DelegateType) {
                                                var deleg_type = (DelegateType) param.type_reference;
                                                var d = deleg_type.delegate_symbol;
-                                               if (d.instance) {
+                                               if (d.has_target) {
                                                        carg_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), codegen.get_delegate_target_cexpression (arg));
                                                        multiple_cargs = true;
                                                }
@@ -324,7 +330,7 @@ public class Vala.CCodeInvocationExpressionBinding : CCodeExpressionBinding {
                } else if (m != null && m.return_type is DelegateType) {
                        var deleg_type = (DelegateType) m.return_type;
                        var d = deleg_type.delegate_symbol;
-                       if (d.instance) {
+                       if (d.has_target) {
                                var temp_var = codegen.get_temp_variable (new PointerType (new VoidType ()));
                                var temp_ref = new CCodeIdentifier (temp_var.name);
 
@@ -352,7 +358,7 @@ public class Vala.CCodeInvocationExpressionBinding : CCodeExpressionBinding {
                } else if (itype is DelegateType) {
                        var deleg_type = (DelegateType) itype;
                        var d = deleg_type.delegate_symbol;
-                       if (d.instance) {
+                       if (d.has_target) {
                                carg_map.set (codegen.get_param_pos (d.cinstance_parameter_position), codegen.get_delegate_target_cexpression (expr.call));
                        }
                }
@@ -374,7 +380,7 @@ public class Vala.CCodeInvocationExpressionBinding : CCodeExpressionBinding {
                        last_pos = min_pos;
                }
 
-               if (m != null && m.instance && m.returns_modified_pointer) {
+               if (m != null && m.binding == MemberBinding.INSTANCE && m.returns_modified_pointer) {
                        expr.ccodenode = new CCodeAssignment (instance, ccall_expr);
                } else {
                        /* cast pointer to actual type if this is a generic method return value */
index cd31c17..67c5891 100644 (file)
@@ -81,7 +81,7 @@ public class Vala.CCodeMemberAccessBinding : CCodeExpressionBinding {
                        expr.ccodenode = codegen.get_array_length_cexpression (expr.inner, 1);
                } else if (expr.symbol_reference is Field) {
                        var f = (Field) expr.symbol_reference;
-                       if (f.instance) {
+                       if (f.binding == MemberBinding.INSTANCE) {
                                var instance_expression_type = base_type;
                                var instance_target_type = codegen.get_data_type_for_symbol ((Typesymbol) f.parent_symbol);
                                CCodeExpression typed_inst = codegen.get_implicit_cast_expression (pub_inst, instance_expression_type, instance_target_type);
@@ -99,6 +99,11 @@ public class Vala.CCodeMemberAccessBinding : CCodeExpressionBinding {
                                } else {
                                        expr.ccodenode = new CCodeMemberAccess (inst, f.get_cname ());
                                }
+                       } else if (f.binding == MemberBinding.CLASS) {
+                               var cl = (Class) f.parent_symbol;
+                               var cast = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null) + "_CLASS"));
+                               cast.add_argument (new CCodeIdentifier ("klass"));
+                               expr.ccodenode = new CCodeMemberAccess.pointer (cast, f.get_cname ());
                        } else {
                                expr.ccodenode = new CCodeIdentifier (f.get_cname ());
                        }
@@ -242,9 +247,9 @@ public class Vala.CCodeMemberAccessBinding : CCodeExpressionBinding {
                        if (codegen.current_type_symbol != null) {
                                /* base type is available if this is a type method */
                                if (codegen.current_type_symbol is Class) {
-                                       base_type = new ClassType ((Class) codegen.current_type_symbol);
+                                       base_type = new ClassInstanceType ((Class) codegen.current_type_symbol);
                                } else if (codegen.current_type_symbol is Interface) {
-                                       base_type = new InterfaceType ((Interface) codegen.current_type_symbol);
+                                       base_type = new InterfaceInstanceType ((Interface) codegen.current_type_symbol);
                                } else {
                                        base_type = new ValueType (codegen.current_type_symbol);
                                        pub_inst = new CCodeIdentifier ("(*self)");
index 9bef115..b3633b2 100644 (file)
@@ -70,7 +70,7 @@ public class Vala.CCodeMethodBinding : CCodeBinding {
                        }
 
                        if (cl != null) {
-                               creturn_type = new ClassType (cl);
+                               creturn_type = new ClassInstanceType (cl);
                        }
                }
 
@@ -138,23 +138,23 @@ public class Vala.CCodeMethodBinding : CCodeBinding {
 
                CCodeFunctionDeclarator vdeclarator = null;
 
-               if (m.instance || (m.parent_symbol is Struct && m is CreationMethod)) {
+               if (m.binding == MemberBinding.INSTANCE || (m.parent_symbol is Struct && m is CreationMethod)) {
                        Typesymbol parent_type = find_parent_type (m);
                        DataType this_type;
                        if (parent_type is Class) {
-                               this_type = new ClassType ((Class) parent_type);
+                               this_type = new ClassInstanceType ((Class) parent_type);
                        } else if (parent_type is Interface) {
-                               this_type = new InterfaceType ((Interface) parent_type);
+                               this_type = new InterfaceInstanceType ((Interface) parent_type);
                        } else {
                                this_type = new ValueType (parent_type);
                        }
 
                        CCodeFormalParameter instance_param = null;
                        if (m.base_interface_method != null && !m.is_abstract && !m.is_virtual) {
-                               var base_type = new InterfaceType ((Interface) m.base_interface_method.parent_symbol);
+                               var base_type = new InterfaceInstanceType ((Interface) m.base_interface_method.parent_symbol);
                                instance_param = new CCodeFormalParameter ("base", base_type.get_cname ());
                        } else if (m.overrides) {
-                               var base_type = new ClassType ((Class) m.base_method.parent_symbol);
+                               var base_type = new ClassInstanceType ((Class) m.base_method.parent_symbol);
                                instance_param = new CCodeFormalParameter ("base", base_type.get_cname ());
                        } else {
                                if (m.parent_symbol is Struct && !((Struct) m.parent_symbol).is_simple_type ()) {
@@ -171,6 +171,12 @@ public class Vala.CCodeMethodBinding : CCodeBinding {
                                vdecl.add_declarator (vdeclarator);
                                codegen.type_struct.add_declaration (vdecl);
                        }
+               } else if (m.binding == MemberBinding.CLASS) {
+                       Typesymbol parent_type = find_parent_type (m);
+                       DataType this_type;
+                       this_type = new ClassType ((Class) parent_type);
+                       var class_param = new CCodeFormalParameter ("klass", this_type.get_cname ());
+                       cparam_map.set (codegen.get_param_pos (m.cinstance_parameter_position), class_param);
                }
 
                if (in_fundamental_creation_method) {
@@ -222,19 +228,19 @@ public class Vala.CCodeMethodBinding : CCodeBinding {
                                                ReferenceType base_expression_type;
                                                if (m.overrides) {
                                                        base_method = m.base_method;
-                                                       base_expression_type = new ClassType ((Class) base_method.parent_symbol);
+                                                       base_expression_type = new ClassInstanceType ((Class) base_method.parent_symbol);
                                                } else {
                                                        base_method = m.base_interface_method;
-                                                       base_expression_type = new InterfaceType ((Interface) base_method.parent_symbol);
+                                                       base_expression_type = new InterfaceInstanceType ((Interface) base_method.parent_symbol);
                                                }
-                                               var self_target_type = new ClassType (cl);
+                                               var self_target_type = new ClassInstanceType (cl);
                                                CCodeExpression cself = codegen.get_implicit_cast_expression (new CCodeIdentifier ("base"), base_expression_type, self_target_type);
 
                                                var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
                                                cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", cself));
                                                
                                                cinit.append (cdecl);
-                                       } else if (m.instance) {
+                                       } else if (m.binding == MemberBinding.INSTANCE) {
                                                var ccheckstmt = create_method_type_check_statement (m, creturn_type, cl, true, "self");
                                                ccheckstmt.line = codegen.function.line;
                                                cinit.append (ccheckstmt);
@@ -363,9 +369,9 @@ public class Vala.CCodeMethodBinding : CCodeBinding {
 
                        ReferenceType this_type;
                        if (m.parent_symbol is Class) {
-                               this_type = new ClassType ((Class) m.parent_symbol);
+                               this_type = new ClassInstanceType ((Class) m.parent_symbol);
                        } else {
-                               this_type = new InterfaceType ((Interface) m.parent_symbol);
+                               this_type = new InterfaceInstanceType ((Interface) m.parent_symbol);
                        }
 
                        cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
@@ -418,7 +424,7 @@ public class Vala.CCodeMethodBinding : CCodeBinding {
                                if (param.type_reference is DelegateType) {
                                        var deleg_type = (DelegateType) param.type_reference;
                                        var d = deleg_type.delegate_symbol;
-                                       if (d.instance) {
+                                       if (d.has_target) {
                                                var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname (param.name), "void*");
                                                cparam_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), cparam);
                                                carg_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), new CCodeIdentifier (cparam.name));
@@ -439,7 +445,7 @@ public class Vala.CCodeMethodBinding : CCodeBinding {
                                // return delegate target if appropriate
                                var deleg_type = (DelegateType) creturn_type;
                                var d = deleg_type.delegate_symbol;
-                               if (d.instance) {
+                               if (d.has_target) {
                                        var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname ("result"), "void*");
                                        cparam_map.set (codegen.get_param_pos (m.cdelegate_target_parameter_position), cparam);
                                        carg_map.set (codegen.get_param_pos (m.cdelegate_target_parameter_position), new CCodeIdentifier (cparam.name));
@@ -601,7 +607,7 @@ public class Vala.CCodeMethodBinding : CCodeBinding {
                        if (param.type_reference is DelegateType) {
                                var deleg_type = (DelegateType) param.type_reference;
                                var d = deleg_type.delegate_symbol;
-                               if (d.instance) {
+                               if (d.has_target) {
                                        var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname (param.name), "void*");
                                        cparam_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), cparam);
                                }
@@ -623,7 +629,7 @@ public class Vala.CCodeMethodBinding : CCodeBinding {
                        // return delegate target if appropriate
                        var deleg_type = (DelegateType) creturn_type;
                        var d = deleg_type.delegate_symbol;
-                       if (d.instance) {
+                       if (d.has_target) {
                                var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname ("result"), "void*");
                                cparam_map.set (codegen.get_param_pos (m.cdelegate_target_parameter_position), cparam);
                        }
@@ -705,7 +711,7 @@ public class Vala.CCodeMethodBinding : CCodeBinding {
                        return false;
                }
                
-               if (m.instance) {
+               if (m.binding == MemberBinding.INSTANCE) {
                        // method must be static
                        return false;
                }
index d074026..6a71122 100644 (file)
@@ -1,6 +1,6 @@
 /* valaclassregisterfunction.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
@@ -50,7 +50,11 @@ public class Vala.ClassRegisterFunction : TypeRegisterFunction {
        }
 
        public override string get_base_init_func_name () {
-               return "NULL";
+               if (class_reference.class_constructor != null) {
+                       return "%s_base_init".printf (class_reference.get_lower_case_cname (null));
+               } else {
+                       return "NULL";
+               }
        }
 
        public override string get_class_init_func_name () {
index 1b2d0b8..da14caa 100644 (file)
@@ -105,7 +105,7 @@ public class Vala.GIdlWriter : CodeVisitor {
                        // write implemented interfaces
                        bool first = true;
                        foreach (DataType base_type in cl.get_base_types ()) {
-                               var iface_type = base_type as InterfaceType;
+                               var iface_type = base_type as InterfaceInstanceType;
                                if (iface_type != null) {
                                        if (first) {
                                                write_indent ();
@@ -185,8 +185,8 @@ public class Vala.GIdlWriter : CodeVisitor {
                        indent++;
 
                        foreach (DataType base_type in iface.get_prerequisites ()) {
-                               var class_type = base_type as ClassType;
-                               var iface_type = base_type as InterfaceType;
+                               var class_type = base_type as ClassInstanceType;
+                               var iface_type = base_type as InterfaceInstanceType;
                                if (class_type != null) {
                                        write_indent ();
                                        stream.printf ("<object name=\"%s\"/>\n", class_type.class_symbol.get_full_name ());
@@ -385,7 +385,7 @@ public class Vala.GIdlWriter : CodeVisitor {
                indent++;
 
                DataType instance_type = null;
-               if (m.instance) {
+               if (m.binding == MemberBinding.INSTANCE) {
                        instance_type = CCodeGenerator.get_data_type_for_symbol ((Typesymbol) m.parent_symbol);
                }
 
index c951a22..378df4a 100644 (file)
@@ -34,6 +34,7 @@ libvalacore_la_VALASOURCES = \
        valacfgbuilder.vala \
        valacharacterliteral.vala \
        valaclass.vala \
+       valaclassinstancetype.vala \
        valaclasstype.vala \
        valacodebinding.vala \
        valacodecontext.vala \
@@ -73,6 +74,7 @@ libvalacore_la_VALASOURCES = \
        valaintegerliteral.vala \
        valaintegertype.vala \
        valainterface.vala \
+       valainterfaceinstancetype.vala \
        valainterfacetype.vala \
        valainterfacewriter.vala \
        valainvalidtype.vala \
index c388e7e..b77bdc4 100644 (file)
@@ -91,6 +91,11 @@ public class Vala.Class : Typesymbol {
        public Constructor constructor { get; set; }
 
        /**
+        * Specifies the class constructor.
+        */
+       public Constructor class_constructor { get; set; }
+
+       /**
         * Specifies the static class constructor.
         */
        public Constructor static_constructor { get; set; }
@@ -106,7 +111,7 @@ public class Vala.Class : Typesymbol {
                                if (_destructor.this_parameter != null) {
                                        _destructor.scope.remove (_destructor.this_parameter.name);
                                }
-                               _destructor.this_parameter = new FormalParameter ("this", new ClassType (this));
+                               _destructor.this_parameter = new FormalParameter ("this", new ClassInstanceType (this));
                                _destructor.scope.add (_destructor.this_parameter.name, _destructor.this_parameter);
                        }
                }
@@ -188,7 +193,7 @@ public class Vala.Class : Typesymbol {
         */
        public void add_field (Field f) {
                fields.add (f);
-               if (f.access == SymbolAccessibility.PRIVATE && f.instance) {
+               if (f.access == SymbolAccessibility.PRIVATE && f.binding == MemberBinding.INSTANCE) {
                        has_private_fields = true;
                }
                scope.add (f.name, f);
@@ -209,11 +214,11 @@ public class Vala.Class : Typesymbol {
         * @param m a method
         */
        public void add_method (Method m) {
-               if (m.instance || m is CreationMethod) {
+               if (m.binding == MemberBinding.INSTANCE || m is CreationMethod) {
                        if (m.this_parameter != null) {
                                m.scope.remove (m.this_parameter.name);
                        }
-                       m.this_parameter = new FormalParameter ("this", new ClassType (this));
+                       m.this_parameter = new FormalParameter ("this", new ClassInstanceType (this));
                        m.scope.add (m.this_parameter.name, m.this_parameter);
                }
                if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
@@ -262,7 +267,7 @@ public class Vala.Class : Typesymbol {
                properties.add (prop);
                scope.add (prop.name, prop);
 
-               prop.this_parameter = new FormalParameter ("this", new ClassType (this));
+               prop.this_parameter = new FormalParameter ("this", new ClassInstanceType (this));
                prop.scope.add (prop.this_parameter.name, prop.this_parameter);
                
                if (!no_field && !external_package) {
@@ -395,6 +400,10 @@ public class Vala.Class : Typesymbol {
                        constructor.accept (visitor);
                }
 
+               if (class_constructor != null) {
+                       class_constructor.accept (visitor);
+               }
+
                if (static_constructor != null) {
                        static_constructor.accept (visitor);
                }
diff --git a/vala/valaclassinstancetype.vala b/vala/valaclassinstancetype.vala
new file mode 100644 (file)
index 0000000..cbe7d41
--- /dev/null
@@ -0,0 +1,54 @@
+/* valaclassinstancetype.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;
+
+/**
+ * A class type.
+ */
+public class Vala.ClassInstanceType : ReferenceType {
+       /**
+        * The referred class.
+        */
+       public weak Class class_symbol { get; set; }
+
+       public ClassInstanceType (Class class_symbol) {
+               this.class_symbol = class_symbol;
+               data_type = class_symbol;
+       }
+
+       public override DataType copy () {
+               var result = new ClassInstanceType (class_symbol);
+               result.source_reference = source_reference;
+               result.transfers_ownership = transfers_ownership;
+               result.takes_ownership = takes_ownership;
+               result.nullable = nullable;
+               result.is_dynamic = is_dynamic;
+               result.floating_reference = floating_reference;
+               
+               foreach (DataType arg in get_type_arguments ()) {
+                       result.add_type_argument (arg.copy ());
+               }
+               
+               return result;
+       }
+}
index 0bd7159..de611b5 100644 (file)
@@ -33,7 +33,6 @@ public class Vala.ClassType : ReferenceType {
 
        public ClassType (Class class_symbol) {
                this.class_symbol = class_symbol;
-               data_type = class_symbol;
        }
 
        public override DataType copy () {
@@ -51,4 +50,8 @@ public class Vala.ClassType : ReferenceType {
                
                return result;
        }
+
+       public override string? get_cname (bool var_type, bool const_type) {
+               return "%sClass*".printf (class_symbol.get_cname ());
+       }
 }
index 9c23bb8..e4e3e5d 100644 (file)
@@ -39,7 +39,7 @@ public class Vala.Constructor : Symbol {
        /**
         * Specifies whether this is an instance or a class constructor.
         */
-       public bool instance { get; set; default = true; }
+       public MemberBinding binding { get; set; default = MemberBinding.INSTANCE; }
        
        /**
         * Creates a new constructor.
index cc06308..055977c 100644 (file)
@@ -43,7 +43,7 @@ public class Vala.Delegate : Typesymbol {
         * The reference to the object instance will be appended to the end of
         * the argument list in the generated C code.
         */
-       public bool instance { get; set; }
+       public bool has_target { get; set; }
 
        /**
         * Specifies the position of the instance parameter in the C function.
@@ -165,7 +165,7 @@ public class Vala.Delegate : Typesymbol {
                         * an instance method is being compared to a static
                         * callback
                         */
-                       if (first && m.instance && !instance) {
+                       if (first && m.binding == MemberBinding.INSTANCE && !has_target) {
                                first = false;
                                continue;
                        }
index fe08a0e..780cb8a 100644 (file)
@@ -39,7 +39,7 @@ public class Vala.Destructor : Symbol {
        /**
         * Specifies whether this is an instance or a class destructor.
         */
-       public bool instance { get; set; default = true; }
+       public MemberBinding binding { get; set; default = MemberBinding.INSTANCE; }
 
        /**
         * Creates a new destructor.
index 4d63e0b..eb982e5 100644 (file)
@@ -79,7 +79,7 @@ public class Vala.Enum : Typesymbol {
                        m.error = true;
                        return;
                }
-               if (m.instance) {
+               if (m.binding == MemberBinding.INSTANCE) {
                        m.this_parameter = new FormalParameter ("this", new ValueType (this));
                        m.scope.add (m.this_parameter.name, m.this_parameter);
                }
index 6b9b9cd..8f2f325 100644 (file)
@@ -68,7 +68,7 @@ public class Vala.ErrorDomain : Typesymbol {
                        m.error = true;
                        return;
                }
-               if (m.instance) {
+               if (m.binding == MemberBinding.INSTANCE) {
                        m.this_parameter = new FormalParameter ("this", new ValueType (this));
                        m.scope.add (m.this_parameter.name, m.this_parameter);
                }
index fb0daef..32b74b5 100644 (file)
@@ -47,10 +47,7 @@ public class Vala.Field : Member, Lockable {
         * Specifies whether this field may only be accessed with an instance of
         * the contained type.
         */
-       public bool instance {
-               get { return _instance; }
-               set { _instance = value; }
-       }
+       public MemberBinding binding { get; set; default = MemberBinding.INSTANCE; }
 
        /**
         * Specifies whether the field is volatile. Volatile fields are
@@ -65,7 +62,6 @@ public class Vala.Field : Member, Lockable {
        public bool no_array_length { get; set; }
 
        private string cname;
-       private bool _instance = true;
        
        private bool lock_used = false;
 
@@ -128,7 +124,7 @@ public class Vala.Field : Member, Lockable {
         * @return the name to be used in C code by default
         */
        public string get_default_cname () {
-               if (!instance) {
+               if (binding == MemberBinding.STATIC) {
                        return parent_symbol.get_lower_case_cprefix () + name;
                } else {
                        return name;
index fa09b04..7433815 100644 (file)
@@ -127,8 +127,8 @@ public class Vala.Interface : Typesymbol {
                        m.error = true;
                        return;
                }
-               if (m.instance) {
-                       m.this_parameter = new FormalParameter ("this", new InterfaceType (this));
+               if (m.binding == MemberBinding.INSTANCE) {
+                       m.this_parameter = new FormalParameter ("this", new InterfaceInstanceType (this));
                        m.scope.add (m.this_parameter.name, m.this_parameter);
                }
                if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
diff --git a/vala/valainterfaceinstancetype.vala b/vala/valainterfaceinstancetype.vala
new file mode 100644 (file)
index 0000000..32cb284
--- /dev/null
@@ -0,0 +1,54 @@
+/* valainterfaceinstancetype.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;
+
+/**
+ * An interface type.
+ */
+public class Vala.InterfaceInstanceType : ReferenceType {
+       /**
+        * The referred interface.
+        */
+       public weak Interface interface_symbol { get; set; }
+
+       public InterfaceInstanceType (Interface interface_symbol) {
+               this.interface_symbol = interface_symbol;
+               data_type = interface_symbol;
+       }
+
+       public override DataType copy () {
+               var result = new InterfaceInstanceType (interface_symbol);
+               result.source_reference = source_reference;
+               result.transfers_ownership = transfers_ownership;
+               result.takes_ownership = takes_ownership;
+               result.nullable = nullable;
+               result.is_dynamic = is_dynamic;
+               result.floating_reference = floating_reference;
+               
+               foreach (DataType arg in get_type_arguments ()) {
+                       result.add_type_argument (arg.copy ());
+               }
+               
+               return result;
+       }
+}
index bc389a9..6a3d022 100644 (file)
@@ -33,7 +33,6 @@ public class Vala.InterfaceType : ReferenceType {
 
        public InterfaceType (Interface interface_symbol) {
                this.interface_symbol = interface_symbol;
-               data_type = interface_symbol;
        }
 
        public override DataType copy () {
@@ -51,4 +50,8 @@ public class Vala.InterfaceType : ReferenceType {
                
                return result;
        }
+
+       public override string? get_cname (bool var_type, bool const_type) {
+               return "%sIface*".printf (interface_symbol.get_cname ());
+       }
 }
index 1206daa..ebc79fe 100644 (file)
@@ -567,7 +567,7 @@ public class Vala.InterfaceWriter : CodeVisitor {
                write_indent ();
 
                write_accessibility (cb);
-               if (!cb.instance) {
+               if (!cb.has_target) {
                        write_string ("static ");
                }
                write_string ("delegate ");
@@ -665,7 +665,7 @@ public class Vala.InterfaceWriter : CodeVisitor {
                        write_identifier (datatype.name);
                        write_identifier (m.name.offset (".new".len ()));
                        write_string (" ");
-               } else if (!m.instance) {
+               } else if (m.binding == MemberBinding.STATIC) {
                        write_string ("static ");
                } else if (m.is_abstract) {
                        write_string ("abstract ");
index f19ccd6..4808856 100644 (file)
@@ -59,3 +59,10 @@ public class Vala.Member : Symbol {
                cheader_filenames.add (filename);
        }
 }
+
+public enum MemberBinding {
+       INSTANCE,
+       CLASS,
+       STATIC
+}
+
index cf3fa03..bda8b9d 100644 (file)
@@ -59,14 +59,7 @@ public class Vala.Method : Member {
         * Specifies whether this method may only be called with an instance of
         * the contained type.
         */
-       public bool instance {
-               get {
-                       return _instance;
-               }
-               set {
-                       _instance = value;
-               }
-       }
+       public MemberBinding binding { get; set; default = MemberBinding.INSTANCE; }
 
        /**
         * The name of the vfunc of this method as it is used in C code.
@@ -191,7 +184,6 @@ public class Vala.Method : Member {
         */
        public bool printf_format { get; set; }
 
-       private bool _instance = true;
        private Gee.List<FormalParameter> parameters = new ArrayList<FormalParameter> ();
        private string cname;
        private string _vfunc_name;
index 2546840..96e5389 100644 (file)
@@ -249,7 +249,7 @@ public class Vala.Namespace : Symbol {
                        m.error = true;
                        return;
                }
-               if (m.instance) {
+               if (m.binding == MemberBinding.INSTANCE) {
                        Report.error (m.source_reference, "instance methods not allowed outside of data types");
 
                        m.error = true;
index ab6f434..3a5f987 100644 (file)
@@ -195,7 +195,7 @@ public class Vala.NullChecker : CodeVisitor {
 
                var mtype = expr.call.static_type as MethodType;
                var ma = expr.call as MemberAccess;
-               if (mtype != null && mtype.method_symbol.instance && ma != null) {
+               if (mtype != null && mtype.method_symbol.binding == MemberBinding.INSTANCE && ma != null) {
                        if (ma.inner == null) {
                                // implicit this call, always non-null
                        } else {
index b8adc60..e63d6b8 100644 (file)
@@ -1880,11 +1880,11 @@ public class Vala.Parser : CodeVisitor {
                        ns.add_delegate ((Delegate) sym);
                } else if (sym is Method) {
                        var method = (Method) sym;
-                       method.instance = false;
+                       method.binding = MemberBinding.STATIC;
                        ns.add_method (method);
                } else if (sym is Field) {
                        var field = (Field) sym;
-                       field.instance = false;
+                       field.binding = MemberBinding.STATIC;
                        ns.add_field (field);
                } else if (sym is Constant) {
                        ns.add_constant ((Constant) sym);
@@ -1948,7 +1948,7 @@ public class Vala.Parser : CodeVisitor {
                    && !cl.is_static
                    && cl.default_construction_method == null) {
                        var m = new CreationMethod (cl.name, null, cl.source_reference);
-                       m.instance = false;
+                       m.binding = MemberBinding.STATIC;
                        m.access = SymbolAccessibility.PUBLIC;
                        m.body = new Block (cl.source_reference);
                        cl.add_method (m);
@@ -1991,8 +1991,10 @@ public class Vala.Parser : CodeVisitor {
                        cl.add_property ((Property) sym);
                } else if (sym is Constructor) {
                        var c = (Constructor) sym;
-                       if (c.instance) {
+                       if (c.binding == MemberBinding.INSTANCE) {
                                cl.constructor = c;
+                       } else if (c.binding == MemberBinding.CLASS) {
+                               cl.class_constructor = c;
                        } else {
                                cl.static_constructor = c;
                        }
@@ -2038,7 +2040,9 @@ public class Vala.Parser : CodeVisitor {
                f.access = access;
                set_attributes (f, attrs);
                if (ModifierFlags.STATIC in flags) {
-                       f.instance = false;
+                       f.binding = MemberBinding.STATIC;
+               } else if (ModifierFlags.CLASS in flags) {
+                       f.binding = MemberBinding.CLASS;
                }
                if (accept (TokenType.ASSIGN)) {
                        f.initializer = parse_expression ();
@@ -2085,7 +2089,9 @@ public class Vala.Parser : CodeVisitor {
                method.access = access;
                set_attributes (method, attrs);
                if (ModifierFlags.STATIC in flags) {
-                       method.instance = false;
+                       method.binding = MemberBinding.STATIC;
+               } else if (ModifierFlags.CLASS in flags) {
+                       method.binding = MemberBinding.CLASS;
                }
                if (ModifierFlags.ABSTRACT in flags) {
                        method.is_abstract = true;
@@ -2227,7 +2233,9 @@ public class Vala.Parser : CodeVisitor {
                expect (TokenType.CONSTRUCT);
                var c = new Constructor (get_src_com (begin));
                if (ModifierFlags.STATIC in flags) {
-                       c.instance = false;
+                       c.binding = MemberBinding.STATIC;
+               } else if (ModifierFlags.CLASS in flags) {
+                       c.binding = MemberBinding.CLASS;
                }
                c.body = parse_block ();
                return c;
@@ -2624,7 +2632,7 @@ public class Vala.Parser : CodeVisitor {
                }
                method.access = access;
                set_attributes (method, attrs);
-               method.instance = false;
+               method.binding = MemberBinding.STATIC;
                if (!accept (TokenType.SEMICOLON)) {
                        method.body = parse_block ();
                }
@@ -2647,7 +2655,7 @@ public class Vala.Parser : CodeVisitor {
                d.access = access;
                set_attributes (d, attrs);
                if (!(ModifierFlags.STATIC in flags)) {
-                       d.instance = true;
+                       d.has_target = true;
                }
                foreach (TypeParameter type_param in type_param_list) {
                        d.add_type_parameter (type_param);
index c0b5b33..1b3035c 100644 (file)
@@ -98,10 +98,7 @@ public class Vala.Property : Member, Lockable {
         * Specifies whether this field may only be accessed with an instance of
         * the contained type.
         */
-       public bool instance {
-               get { return _instance; }
-               set { _instance = value; }
-       }
+       public MemberBinding binding { get; set; default = MemberBinding.INSTANCE; }
 
        /**
         * Specifies the virtual or abstract property this property overrides.
@@ -149,7 +146,6 @@ public class Vala.Property : Member, Lockable {
        private bool lock_used = false;
 
        private DataType _data_type;
-       private bool _instance = true;
 
        private string? _nick;
        private string? _blurb;
index ce6a9b8..7a2328f 100644 (file)
@@ -73,7 +73,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                root_symbol = context.root;
 
                bool_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("bool"));
-               string_type = new ClassType ((Class) root_symbol.scope.lookup ("string"));
+               string_type = new ClassInstanceType ((Class) root_symbol.scope.lookup ("string"));
 
                int_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("int"));
                uint_type = new ValueType ((Typesymbol) root_symbol.scope.lookup ("uint"));
@@ -89,15 +89,15 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
 
                        type_type = new ValueType ((Typesymbol) glib_ns.scope.lookup ("Type"));
 
-                       glist_type = new ClassType ((Class) glib_ns.scope.lookup ("List"));
-                       gslist_type = new ClassType ((Class) glib_ns.scope.lookup ("SList"));
+                       glist_type = new ClassInstanceType ((Class) glib_ns.scope.lookup ("List"));
+                       gslist_type = new ClassInstanceType ((Class) glib_ns.scope.lookup ("SList"));
 
                        gerror_type = (Class) glib_ns.scope.lookup ("Error");
                }
 
                var gee_ns = root_symbol.scope.lookup ("Gee");
                if (gee_ns != null) {
-                       iterable_type = new InterfaceType ((Interface) gee_ns.scope.lookup ("Iterable"));
+                       iterable_type = new InterfaceInstanceType ((Interface) gee_ns.scope.lookup ("Iterable"));
                        iterator_type = (Interface) gee_ns.scope.lookup ("Iterator");
                        list_type = (Interface) gee_ns.scope.lookup ("List");
                        map_type = (Interface) gee_ns.scope.lookup ("Map");
@@ -332,7 +332,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        public override void visit_field (Field f) {
                f.accept_children (this);
 
-               if (f.instance && f.parent_symbol is Interface) {
+               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;
@@ -641,7 +641,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        public override void visit_property (Property prop) {
                current_symbol = prop;
 
-               if (!prop.instance) {
+               if (prop.binding != MemberBinding.INSTANCE) {
                        Report.error (prop.source_reference, "static properties are not yet supported");
                        prop.error = true;
                        return;
@@ -750,7 +750,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        }
 
        public override void visit_constructor (Constructor c) {
-               c.this_parameter = new FormalParameter ("this", new ClassType (current_class));
+               c.this_parameter = new FormalParameter ("this", new ClassInstanceType (current_class));
                c.scope.add (c.this_parameter.name, c.this_parameter);
 
                c.owner = current_symbol.scope;
@@ -895,7 +895,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                                return;
                                        }
                                        field = field_it.get ();
-                                       if (!field.instance) {
+                                       if (field.binding != MemberBinding.INSTANCE) {
                                                // we only initialize instance fields
                                                field = null;
                                        }
@@ -1083,7 +1083,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                need_type_check = true;
                        }
                } else if (iterable_type != null && collection_type.compatible (iterable_type)) {
-                       var foreach_iterator_type = new InterfaceType (iterator_type);
+                       var foreach_iterator_type = new InterfaceInstanceType (iterator_type);
                        foreach_iterator_type.takes_ownership = true;
                        foreach_iterator_type.add_type_argument (stmt.type_reference);
                        stmt.iterator_variable = new LocalVariable (foreach_iterator_type, "%s_it".printf (stmt.variable_name));
@@ -1506,7 +1506,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                        may_access_instance_members = true;
                                } else if (sym is Method) {
                                        var m = (Method) sym;
-                                       may_access_instance_members = m.instance;
+                                       may_access_instance_members = (m.binding == MemberBinding.INSTANCE);
                                }
 
                                expr.symbol_reference = symbol_lookup_inherited (sym, expr.member_name);
@@ -1637,11 +1637,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                if (member is Field) {
                        var f = (Field) member;
                        access = f.access;
-                       instance = f.instance;
+                       instance = (f.binding == MemberBinding.INSTANCE);
                } else if (member is Method) {
                        var m = (Method) member;
                        access = m.access;
-                       instance = m.instance;
+                       instance = (m.binding == MemberBinding.INSTANCE);
                } else if (member is Property) {
                        var prop = (Property) member;
                        access = prop.access;
@@ -1670,7 +1670,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                        access = prop.get_accessor.access;
                                }
                        }
-                       instance = prop.instance;
+                       instance = (prop.binding == MemberBinding.INSTANCE);
                } else if (member is Signal) {
                        instance = true;
                }
@@ -1954,9 +1954,9 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                // construct a new type reference for the base type with correctly linked type arguments
                ReferenceType instance_base_type;
                if (base_type.data_type is Class) {
-                       instance_base_type = new ClassType ((Class) base_type.data_type);
+                       instance_base_type = new ClassInstanceType ((Class) base_type.data_type);
                } else {
-                       instance_base_type = new InterfaceType ((Interface) base_type.data_type);
+                       instance_base_type = new InterfaceInstanceType ((Interface) base_type.data_type);
                }
                foreach (DataType type_arg in base_type.get_type_arguments ()) {
                        if (type_arg.type_parameter != null) {
@@ -2186,10 +2186,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                return true;
                        } else if (sym is Method) {
                                var m = (Method) sym;
-                               return m.instance;
+                               return m.binding == MemberBinding.INSTANCE;
                        } else if (sym is Constructor) {
                                var c = (Constructor) sym;
-                               return c.instance;
+                               return c.binding == MemberBinding.INSTANCE;
                        } else if (sym is Destructor) {
                                return true;
                        } else if (sym is Property) {
@@ -2226,7 +2226,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        Report.error (expr.source_reference, "Base access invalid without base class");
                        return;
                } else {
-                       expr.static_type = new ClassType (current_class.base_class);
+                       expr.static_type = new ClassInstanceType (current_class.base_class);
                }
 
                expr.symbol_reference = expr.static_type.data_type;
@@ -2281,7 +2281,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
 
                        if (type_sym is Class) {
                                type = (Typesymbol) type_sym;
-                               expr.type_reference = new ClassType ((Class) type);
+                               expr.type_reference = new ClassInstanceType ((Class) type);
                        } else if (type_sym is Struct) {
                                type = (Typesymbol) type_sym;
                                expr.type_reference = new ValueType (type);
@@ -2594,8 +2594,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        return;
                }
                if (!(expr.inner.static_type is ValueType
-                     || expr.inner.static_type is ClassType
-                     || expr.inner.static_type is InterfaceType
+                     || expr.inner.static_type is ClassInstanceType
+                     || expr.inner.static_type is InterfaceInstanceType
                      || expr.inner.static_type is PointerType)) {
                        expr.error = true;
                        Report.error (expr.source_reference, "Address-of operator not supported for this expression");
@@ -2870,14 +2870,16 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                bool in_instance_method = false;
                var current_method = find_current_method ();
                if (current_method != null) {
-                       in_instance_method = current_method.instance;
+                       in_instance_method = (current_method.binding == MemberBinding.INSTANCE);
                } else {
                        in_instance_method = is_in_constructor ();
                }
 
                var cb = (Delegate) ((DelegateType) l.expected_type).delegate_symbol;
                l.method = new Method (get_lambda_name (), cb.return_type);
-               l.method.instance = cb.instance && in_instance_method;
+               if (!cb.has_target || !in_instance_method) {
+                       l.method.binding = MemberBinding.STATIC;
+               }
                l.method.owner = current_symbol.scope;
 
                var lambda_params = l.get_parameters ();
index f97b06e..f8adb52 100644 (file)
@@ -94,13 +94,13 @@ public class Vala.Signal : Member, Lockable {
                // parent_symbol is null for D-Bus signals
                if (generated_delegate == null && parent_symbol != null) {
                        generated_delegate = new Delegate (null, return_type);
-                       generated_delegate.instance = true;
+                       generated_delegate.has_target = true;
                        
                        ReferenceType sender_type;
                        if (parent_symbol is Class) {
-                               sender_type = new ClassType ((Class) parent_symbol);
+                               sender_type = new ClassInstanceType ((Class) parent_symbol);
                        } else {
-                               sender_type = new InterfaceType ((Interface) parent_symbol);
+                               sender_type = new InterfaceInstanceType ((Interface) parent_symbol);
                        }
                        var sender_param = new FormalParameter ("sender", sender_type);
                        generated_delegate.add_parameter (sender_param);
index 397a8b2..36794b6 100644 (file)
@@ -116,7 +116,7 @@ public class Vala.Struct : Typesymbol {
        public void add_method (Method m) {
                return_if_fail (m != null);
                
-               if (m.instance) {
+               if (m.binding == MemberBinding.INSTANCE) {
                        m.this_parameter = new FormalParameter ("this", new ValueType (this));
                        m.scope.add (m.this_parameter.name, m.this_parameter);
                }
index 3f1b686..d08c0a3 100644 (file)
@@ -245,10 +245,10 @@ public class Vala.SymbolResolver : CodeVisitor {
                                if (cl.is_error_base) {
                                        type = new ErrorType (null, unresolved_type.source_reference);
                                } else {
-                                       type = new ClassType (cl);
+                                       type = new ClassInstanceType (cl);
                                }
                        } else if (sym is Interface) {
-                               type = new InterfaceType ((Interface) sym);
+                               type = new InterfaceInstanceType ((Interface) sym);
                        } else if (sym is Struct) {
                                type = new ValueType ((Struct) sym);
                        } else if (sym is Enum) {
index ad7cac5..52490eb 100644 (file)
@@ -267,7 +267,7 @@ public class Vala.GIdlParser : CodeVisitor {
                        } else if (node.type == IdlNodeTypeId.FUNCTION) {
                                var m = parse_function ((IdlNodeFunction) node);
                                if (m != null) {
-                                       m.instance = false;
+                                       m.binding = MemberBinding.STATIC;
                                        ns.add_method (m);
                                        current_source_file.add_node (m);
                                }
@@ -308,7 +308,7 @@ public class Vala.GIdlParser : CodeVisitor {
 
                        if (remaining_params == 1 && (param_node.name == "user_data" || param_node.name == "data")) {
                                // hide user_data parameter for instance delegates
-                               cb.instance = true;
+                               cb.has_target = true;
                        } else {
                                string param_name = param_node.name;
                                if (param_name == "string") {
@@ -1311,7 +1311,7 @@ public class Vala.GIdlParser : CodeVisitor {
                                        continue;
                                } else {
                                        // static method
-                                       m.instance = false;
+                                       m.binding = MemberBinding.STATIC;
                                }
                        }
 
@@ -1423,7 +1423,7 @@ public class Vala.GIdlParser : CodeVisitor {
                
                if (first) {
                        // no parameters => static method
-                       m.instance = false;
+                       m.binding = MemberBinding.STATIC;
                }
 
                if (last_param != null && last_param.name.has_prefix ("first_")) {
@@ -1466,7 +1466,7 @@ public class Vala.GIdlParser : CodeVisitor {
 
                Method m = create_method (node.name, symbol, v.result, func != null ? func.parameters : v.parameters, false, is_interface);
                if (m != null) {
-                       m.instance = true;
+                       m.binding = MemberBinding.INSTANCE;
                        m.is_virtual = !is_interface;
                        m.is_abstract = is_interface;