From: Juerg Billeter Date: Wed, 23 Apr 2008 20:14:12 +0000 (+0000) Subject: Add support for class constructors, class fields, and class methods, fixes X-Git-Tag: VALA_0_3_2~74 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2df554acaa41c5314b5409757a73938eb6dd67a3;p=thirdparty%2Fvala.git Add support for class constructors, class fields, and class methods, fixes 2008-04-23 Juerg Billeter Add support for class constructors, class fields, and class methods, fixes bug 507136 svn path=/trunk/; revision=1309 --- diff --git a/ChangeLog b/ChangeLog index 9e3cf3ae3..0ab546ea3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-04-23 Jürg Billeter + + Add support for class constructors, class fields, and class + methods, fixes bug 507136 + 2008-04-23 Jürg Billeter * vala/valaparser.vala: diff --git a/gobject/valaccodeassignmentbinding.vala b/gobject/valaccodeassignmentbinding.vala index c9b24f537..ec56259b4 100644 --- a/gobject/valaccodeassignmentbinding.vala +++ b/gobject/valaccodeassignmentbinding.vala @@ -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 (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) { diff --git a/gobject/valaccodeclassbinding.vala b/gobject/valaccodeclassbinding.vala index 7a938fe3b..786480a54 100644 --- a/gobject/valaccodeclassbinding.vala +++ b/gobject/valaccodeclassbinding.vala @@ -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; } diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala index 9908be609..75ecbb050 100644 --- a/gobject/valaccodegenerator.vala +++ b/gobject/valaccodegenerator.vala @@ -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 (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 (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) { diff --git a/gobject/valaccodeinvocationexpressionbinding.vala b/gobject/valaccodeinvocationexpressionbinding.vala index d70e29dd9..0207266db 100644 --- a/gobject/valaccodeinvocationexpressionbinding.vala +++ b/gobject/valaccodeinvocationexpressionbinding.vala @@ -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 */ diff --git a/gobject/valaccodememberaccessbinding.vala b/gobject/valaccodememberaccessbinding.vala index cd31c1723..67c5891a5 100644 --- a/gobject/valaccodememberaccessbinding.vala +++ b/gobject/valaccodememberaccessbinding.vala @@ -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)"); diff --git a/gobject/valaccodemethodbinding.vala b/gobject/valaccodemethodbinding.vala index 9bef1157f..b3633b2e4 100644 --- a/gobject/valaccodemethodbinding.vala +++ b/gobject/valaccodemethodbinding.vala @@ -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 (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; } diff --git a/gobject/valaclassregisterfunction.vala b/gobject/valaclassregisterfunction.vala index d07402659..6a7112256 100644 --- a/gobject/valaclassregisterfunction.vala +++ b/gobject/valaclassregisterfunction.vala @@ -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 () { diff --git a/gobject/valagidlwriter.vala b/gobject/valagidlwriter.vala index 1b2d0b833..da14caa33 100644 --- a/gobject/valagidlwriter.vala +++ b/gobject/valagidlwriter.vala @@ -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 ("\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); } diff --git a/vala/Makefile.am b/vala/Makefile.am index c951a22f9..378df4a23 100644 --- a/vala/Makefile.am +++ b/vala/Makefile.am @@ -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 \ diff --git a/vala/valaclass.vala b/vala/valaclass.vala index c388e7ea4..b77bdc49e 100644 --- a/vala/valaclass.vala +++ b/vala/valaclass.vala @@ -90,6 +90,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. */ @@ -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 index 000000000..cbe7d4108 --- /dev/null +++ b/vala/valaclassinstancetype.vala @@ -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 + */ + +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; + } +} diff --git a/vala/valaclasstype.vala b/vala/valaclasstype.vala index 0bd7159dc..de611b5bc 100644 --- a/vala/valaclasstype.vala +++ b/vala/valaclasstype.vala @@ -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 ()); + } } diff --git a/vala/valaconstructor.vala b/vala/valaconstructor.vala index 9c23bb8e8..e4e3e5d32 100644 --- a/vala/valaconstructor.vala +++ b/vala/valaconstructor.vala @@ -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. diff --git a/vala/valadelegate.vala b/vala/valadelegate.vala index cc0630883..055977cc1 100644 --- a/vala/valadelegate.vala +++ b/vala/valadelegate.vala @@ -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; } diff --git a/vala/valadestructor.vala b/vala/valadestructor.vala index fe08a0e4b..780cb8a93 100644 --- a/vala/valadestructor.vala +++ b/vala/valadestructor.vala @@ -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. diff --git a/vala/valaenum.vala b/vala/valaenum.vala index 4d63e0b0c..eb982e5d8 100644 --- a/vala/valaenum.vala +++ b/vala/valaenum.vala @@ -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); } diff --git a/vala/valaerrordomain.vala b/vala/valaerrordomain.vala index 6b9b9cdb6..8f2f3256f 100644 --- a/vala/valaerrordomain.vala +++ b/vala/valaerrordomain.vala @@ -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); } diff --git a/vala/valafield.vala b/vala/valafield.vala index fb0daef2f..32b74b517 100644 --- a/vala/valafield.vala +++ b/vala/valafield.vala @@ -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; diff --git a/vala/valainterface.vala b/vala/valainterface.vala index fa09b047a..7433815ac 100644 --- a/vala/valainterface.vala +++ b/vala/valainterface.vala @@ -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 index 000000000..32cb2843c --- /dev/null +++ b/vala/valainterfaceinstancetype.vala @@ -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 + */ + +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; + } +} diff --git a/vala/valainterfacetype.vala b/vala/valainterfacetype.vala index bc389a9d7..6a3d02209 100644 --- a/vala/valainterfacetype.vala +++ b/vala/valainterfacetype.vala @@ -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 ()); + } } diff --git a/vala/valainterfacewriter.vala b/vala/valainterfacewriter.vala index 1206daa18..ebc79feb4 100644 --- a/vala/valainterfacewriter.vala +++ b/vala/valainterfacewriter.vala @@ -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 "); diff --git a/vala/valamember.vala b/vala/valamember.vala index f19ccd6c5..480885659 100644 --- a/vala/valamember.vala +++ b/vala/valamember.vala @@ -59,3 +59,10 @@ public class Vala.Member : Symbol { cheader_filenames.add (filename); } } + +public enum MemberBinding { + INSTANCE, + CLASS, + STATIC +} + diff --git a/vala/valamethod.vala b/vala/valamethod.vala index cf3fa03e9..bda8b9d5a 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -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 parameters = new ArrayList (); private string cname; private string _vfunc_name; diff --git a/vala/valanamespace.vala b/vala/valanamespace.vala index 254684049..96e538922 100644 --- a/vala/valanamespace.vala +++ b/vala/valanamespace.vala @@ -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; diff --git a/vala/valanullchecker.vala b/vala/valanullchecker.vala index ab6f43426..3a5f987c7 100644 --- a/vala/valanullchecker.vala +++ b/vala/valanullchecker.vala @@ -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 { diff --git a/vala/valaparser.vala b/vala/valaparser.vala index b8adc605e..e63d6b840 100644 --- a/vala/valaparser.vala +++ b/vala/valaparser.vala @@ -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); diff --git a/vala/valaproperty.vala b/vala/valaproperty.vala index c0b5b33de..1b3035c77 100644 --- a/vala/valaproperty.vala +++ b/vala/valaproperty.vala @@ -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; diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index ce6a9b809..7a2328f5c 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -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 (); diff --git a/vala/valasignal.vala b/vala/valasignal.vala index f97b06e4d..f8adb525a 100644 --- a/vala/valasignal.vala +++ b/vala/valasignal.vala @@ -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); diff --git a/vala/valastruct.vala b/vala/valastruct.vala index 397a8b2a5..36794b6a2 100644 --- a/vala/valastruct.vala +++ b/vala/valastruct.vala @@ -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); } diff --git a/vala/valasymbolresolver.vala b/vala/valasymbolresolver.vala index 3f1b68634..d08c0a3cd 100644 --- a/vala/valasymbolresolver.vala +++ b/vala/valasymbolresolver.vala @@ -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) { diff --git a/vapigen/valagidlparser.vala b/vapigen/valagidlparser.vala index ad7cac5ee..52490eb02 100644 --- a/vapigen/valagidlparser.vala +++ b/vapigen/valagidlparser.vala @@ -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;